private static void ValidateLhs(FromReferenceNode lhs) { // make sure the lhs is "assignable"... if (!lhs.IsResolved) { throw new NotSupportedException("cannot validate assignablity of unresolved node"); } if (lhs.DataType.IsCollectionType) { throw new QueryException("collections not assignable in update statements"); } else if (lhs.DataType.IsComponentType) { throw new QueryException("Components currently not assignable in update statements"); } else if (lhs.DataType.IsEntityType) { // currently allowed... } // TODO : why aren't these the same? if (lhs.GetImpliedJoin() != null || lhs.FromElement.IsImplied) { throw new QueryException("Implied join paths are not assignable in update statements"); } }
private IType PrepareLhs() { FromReferenceNode lhs = GetLhs(); lhs.PrepareForDot(_propertyName); return(GetDataType()); }
public override void PrepareForDot(string propertyName) { FromElement fromElement = FromElement; if (fromElement == null) { throw new InvalidOperationException("No FROM element for index operator!"); } IQueryableCollection queryableCollection = fromElement.QueryableCollection; if (queryableCollection != null && !queryableCollection.IsOneToMany) { FromReferenceNode collectionNode = ( FromReferenceNode )GetChild(0); String path = collectionNode.Path + "[]." + propertyName; if (Log.IsDebugEnabled) { Log.Debug("Creating join for many-to-many elements for " + path); } FromElementFactory factory = new FromElementFactory(fromElement.FromClause, fromElement, path); // This will add the new from element to the origin. FromElement elementJoin = factory.CreateElementJoin(queryableCollection); FromElement = elementJoin; } }
private void CheckLhsIsNotCollection() { FromReferenceNode lhs = GetLhs(); if (lhs.DataType != null && lhs.DataType.IsCollectionType) { throw BuildIllegalCollectionDereferenceException(_propertyName, lhs); } }
public FromReferenceNode GetLhs() { FromReferenceNode lhs = ((FromReferenceNode)GetChild(0)); if (lhs == null) { throw new InvalidOperationException("DOT node with no left-hand-side!"); } return(lhs); }
public void RecursiveResolve(int level, bool impliedAtRoot, string classAlias, IASTNode parent) { IASTNode lhs = GetFirstChild(); int nextLevel = level + 1; if (lhs != null) { FromReferenceNode n = ( FromReferenceNode )lhs; n.RecursiveResolve(nextLevel, impliedAtRoot, null, this); } ResolveFirstChild(); bool impliedJoin = !(level == RootLevel && !impliedAtRoot); Resolve(true, impliedJoin, classAlias, parent); }
private void HandleElements(FromReferenceNode collectionNode, String propertyName) { FromElement collectionFromElement = collectionNode.FromElement; IQueryableCollection queryableCollection = collectionFromElement.QueryableCollection; String path = collectionNode.Path + "[]." + propertyName; Log.Debug("Creating elements for {0}", path); _fromElement = collectionFromElement; if (!collectionFromElement.IsCollectionOfValuesOrComponents) { Walker.AddQuerySpaces(queryableCollection.ElementPersister); } DataType = queryableCollection.ElementType; _selectColumns = collectionFromElement.ToColumns(_fromElement.TableAlias, propertyName, _inSelect); }
private FromElement EvaluateFromElementPath(string path, string classAlias) { FromReferenceNode pathNode = (FromReferenceNode)PathHelper.ParsePath(path, _fromClause.ASTFactory); pathNode.RecursiveResolve(FromReferenceNode.RootLevel, // This is the root level node. false, // Generate an explicit from clause at the root. classAlias, null ); if (pathNode.GetImpliedJoin() != null) { return(pathNode.GetImpliedJoin()); } else { return(pathNode.FromElement); } }
public void ResolveCollectionProperty(IASTNode expr) { String propertyName = CollectionProperties.GetNormalizedPropertyName(_methodName); if (expr is FromReferenceNode) { FromReferenceNode collectionNode = ( FromReferenceNode )expr; // If this is 'elements' then create a new FROM element. if (CollectionPropertyNames.Elements == propertyName) { HandleElements(collectionNode, propertyName); } else { // Not elements(x) _fromElement = collectionNode.FromElement; DataType = _fromElement.GetPropertyType(propertyName, propertyName); _selectColumns = _fromElement.ToColumns(_fromElement.TableAlias, propertyName, _inSelect); } if (collectionNode is DotNode) { PrepareAnyImplicitJoins(( DotNode )collectionNode); } if (!_inSelect) { _fromElement.Text = ""; _fromElement.UseWhereFragment = false; } PrepareSelectColumns(_selectColumns); Text = _selectColumns[0]; Type = HqlSqlWalker.SQL_TOKEN; } else { throw new SemanticException( "Unexpected expression " + expr + " found for collection function " + propertyName ); } }
public void ResolveSelectExpression() { if (Walker.IsShallowQuery || Walker.CurrentFromClause.IsSubQuery) { Resolve(false, true); } else { Resolve(true, false); IType type = GetDataType(); if (type.IsEntityType) { FromElement fromElement = FromElement; fromElement.IncludeSubclasses = true; // Tell the destination fromElement to 'includeSubclasses'. if (UseThetaStyleImplicitJoins) { fromElement.JoinSequence.SetUseThetaStyle(true); // Use theta style (for regression) // Move the node up, after the origin node. FromElement origin = fromElement.Origin; if (origin != null) { ASTUtil.MakeSiblingOfParent(origin, fromElement); } } } } FromReferenceNode lhs = GetLhs(); while (lhs != null) { CheckSubclassOrSuperclassPropertyReference(lhs, lhs.NextSibling.Text); lhs = (FromReferenceNode)lhs.GetChild(0); } }
public override void Resolve(bool generateJoin, bool implicitJoin, string classAlias, IASTNode parent) { if (IsResolved) { return; } FromReferenceNode collectionNode = ( FromReferenceNode )GetChild(0); SessionFactoryHelperExtensions sessionFactoryHelper = SessionFactoryHelper; collectionNode.ResolveIndex(this); // Fully resolve the map reference, create implicit joins. IType type = collectionNode.DataType; if (!type.IsCollectionType) { throw new SemanticException("The [] operator cannot be applied to type " + type); } string collectionRole = (( CollectionType )type).Role; IQueryableCollection queryableCollection = sessionFactoryHelper.RequireQueryableCollection(collectionRole); if (!queryableCollection.HasIndex) { throw new QueryException("unindexed fromElement before []: " + collectionNode.Path); } // Generate the inner join -- The elements need to be joined to the collection they are in. FromElement fromElement = collectionNode.FromElement; String elementTable = fromElement.TableAlias; FromClause fromClause = fromElement.FromClause; String path = collectionNode.Path; FromElement elem = fromClause.FindCollectionJoin(path); if (elem == null) { FromElementFactory factory = new FromElementFactory(fromClause, fromElement, path); elem = factory.CreateCollectionElementsJoin(queryableCollection, elementTable); if (Log.IsDebugEnabled) { Log.Debug("No FROM element found for the elements of collection join path " + path + ", created " + elem); } } else { if (Log.IsDebugEnabled) { Log.Debug("FROM element found for collection join path " + path); } } // The 'from element' that represents the elements of the collection. FromElement = fromElement; // Add the condition to the join sequence that qualifies the indexed element. IASTNode selector = GetChild(1); if (selector == null) { throw new QueryException("No index value!"); } // Sometimes use the element table alias, sometimes use the... umm... collection table alias (many to many) String collectionTableAlias = elementTable; if (elem.CollectionTableAlias != null) { collectionTableAlias = elem.CollectionTableAlias; } // TODO: get SQL rendering out of here, create an AST for the join expressions. // Use the SQL generator grammar to generate the SQL text for the index expression. JoinSequence joinSequence = fromElement.JoinSequence; string[] indexCols = queryableCollection.IndexColumnNames; if (indexCols.Length != 1) { throw new QueryException("composite-index appears in []: " + collectionNode.Path); } SqlGenerator gen = new SqlGenerator(SessionFactoryHelper.Factory, new CommonTreeNodeStream(selector)); try { gen.simpleExpr(); //TODO: used to be exprNoParens! was this needed? } catch (RecognitionException e) { throw new QueryException(e.Message, e); } string selectorExpression = gen.GetSQL().ToString(); joinSequence.AddCondition(new SqlString(collectionTableAlias + '.' + indexCols[0] + " = " + selectorExpression)); //joinSequence.AddCondition(collectionTableAlias, new string[] { indexCols[0] }, selectorExpression, false); IList <IParameterSpecification> paramSpecs = gen.GetCollectedParameters(); if (paramSpecs != null) { switch (paramSpecs.Count) { case 0: // nothing to do break; case 1: IParameterSpecification paramSpec = paramSpecs[0]; paramSpec.ExpectedType = queryableCollection.IndexType; fromElement.SetIndexCollectionSelectorParamSpec(paramSpec); break; default: fromElement.SetIndexCollectionSelectorParamSpec( new AggregatedIndexCollectionSelectorParameterSpecifications(paramSpecs) ); break; } } // Now, set the text for this node. It should be the element columns. String[] elementColumns = queryableCollection.GetElementColumnNames(elementTable); Text = elementColumns[0]; IsResolved = true; }
private void HandleElements(FromReferenceNode collectionNode, String propertyName) { FromElement collectionFromElement = collectionNode.FromElement; IQueryableCollection queryableCollection = collectionFromElement.QueryableCollection; String path = collectionNode.Path + "[]." + propertyName; Log.Debug("Creating elements for " + path); _fromElement = collectionFromElement; if (!collectionFromElement.IsCollectionOfValuesOrComponents) { Walker.AddQuerySpaces(queryableCollection.ElementPersister.QuerySpaces); } DataType = queryableCollection.ElementType; _selectColumns = collectionFromElement.ToColumns(_fromElement.TableAlias, propertyName, _inSelect); }