/// <summary> /// Creates entity from elements. /// </summary> /// <param name="fromClause"></param> /// <param name="origin"></param> /// <param name="path"></param> public FromElementFactory(FromClause fromClause, FromElement origin, string path) { _fromClause = fromClause; _origin = origin; _path = path; _collection = false; }
/// <summary> /// Constructor form used to initialize <see cref="ComponentJoin"/>. /// </summary> /// <param name="fromClause">The FROM clause to which this element belongs.</param> /// <param name="origin">The origin (LHS) of this element.</param> /// <param name="alias">The alias applied to this element.</param> protected FromElement(FromClause fromClause,FromElement origin,string alias):this(origin._token) { _fromClause = fromClause; _origin = origin; _classAlias = alias; _tableAlias = origin.TableAlias; base.Initialize(fromClause.Walker); }
public void SetParentFromClause(FromClause parentFromClause) { _parentFromClause = parentFromClause; if (parentFromClause != null) { _level = parentFromClause.Level + 1; parentFromClause.AddChild(this); } }
public ComponentJoin(FromClause fromClause, FromElement origin, string alias, string componentPath, ComponentType componentType) : base(fromClause, origin, alias) { this.componentPath = componentPath; this.componentType = componentType; componentProperty = StringHelper.Unqualify(componentPath); fromClause.AddJoinByPathMap(componentPath, this); InitializeComponentJoin(new ComponentFromElementType(this)); string[] cols = origin.GetPropertyMapping("").ToColumns(TableAlias, componentProperty); columns = string.Join(", ", cols); }
/// <summary> /// Creates collection from elements. /// </summary> /// <param name="fromClause"></param> /// <param name="origin"></param> /// <param name="path"></param> /// <param name="classAlias"></param> /// <param name="columns"></param> /// <param name="implied"></param> public FromElementFactory( FromClause fromClause, FromElement origin, string path, string classAlias, string[] columns, bool implied) : this(fromClause, origin, path) { _classAlias = classAlias; _columns = columns; _implied = implied; _collection = true; }
public EntityJoinFromElement(FromClause fromClause, IQueryable entityPersister, JoinType joinType, string alias) : base(new CommonToken(HqlSqlWalker.ENTITY_JOIN, entityPersister.TableName)) { string tableAlias = fromClause.AliasGenerator.CreateName(entityPersister.EntityName); EntityType entityType = (EntityType)entityPersister.Type; InitializeEntity(fromClause, entityPersister.EntityName, entityPersister, entityType, alias, tableAlias); JoinSequence = new EntityJoinJoinSequenceImpl( SessionFactoryHelper.Factory, entityType, entityPersister.TableName, tableAlias, joinType); fromClause.Walker.AddQuerySpaces(entityPersister.QuerySpaces); }
public EntityJoinFromElement(FromClause fromClause, IQueryable entityPersister, JoinType joinType, string alias) : base(new CommonToken(HqlSqlWalker.ENTITY_JOIN, entityPersister.TableName)) { string tableAlias = fromClause.AliasGenerator.CreateName(entityPersister.EntityName); EntityType entityType = (EntityType)entityPersister.Type; InitializeEntity(fromClause, entityPersister.EntityName, entityPersister, entityType, alias, tableAlias); //NH Specific: hibernate uses special class EntityJoinJoinSequenceImpl JoinSequence = new JoinSequence(SessionFactoryHelper.Factory) { ForceFilter = true } .AddJoin(entityType, tableAlias, joinType, Array.Empty <string>()); fromClause.Walker.AddQuerySpaces(entityPersister.QuerySpaces); }
private void DoInitialize(FromClause fromClause, string tableAlias, string className, string classAlias, IEntityPersister persister, EntityType type) { if (_initialized) { throw new InvalidOperationException("Already initialized!!"); } _fromClause = fromClause; _tableAlias = tableAlias; _className = className; _classAlias = classAlias; _elementType = new FromElementType(this, persister, type); // Register the FromElement with the FROM clause, now that we have the names and aliases. fromClause.RegisterFromElement(this); if (Log.IsDebugEnabled) { Log.Debug(fromClause + " : " + className + " (" + (classAlias ?? "no alias") + ") -> " + tableAlias); } }
private void RenderNonScalarSelects(ISelectExpression[] selectExpressions, FromClause currentFromClause) { var appender = new ASTAppender(ASTFactory, this); var nonscalarSize = selectExpressions.Count(e => !e.IsScalar); int j = 0; foreach (var e in selectExpressions) { if (!e.IsScalar) { FromElement fromElement = e.FromElement; if (fromElement != null) { RenderNonScalarIdentifiers(fromElement, nonscalarSize, j, e, appender); j++; } } } if (!currentFromClause.IsSubQuery) { // Generate the property select tokens. int k = 0; foreach (var e in selectExpressions) { if (!e.IsScalar) { FromElement fromElement = e.FromElement; if (fromElement != null) { RenderNonScalarProperties(appender, fromElement, nonscalarSize, k); k++; } } } } }
public void SetOrigin(FromElement origin, bool manyToMany) { _origin = origin; origin.AddDestination(this); if (origin.FromClause == FromClause) { // TODO: Figure out a better way to get the FROM elements in a proper tree structure. // If this is not the destination of a many-to-many, add it as a child of the origin. if (manyToMany) { origin.AddSibling(this); } else { if (!Walker.IsInFrom && !Walker.IsInSelect) { FromClause.AddChild(this); } else { origin.AddChild(this); } } } else if (!Walker.IsInFrom) { // HHH-276 : implied joins in a subselect where clause - The destination needs to be added // to the destination's from clause. FromClause.AddChild(this); // Not sure if this is will fix everything, but it works. } else { // Otherwise, the destination node was implied by the FROM clause and the FROM clause processor // will automatically add it in the right place. } }
private void DereferenceEntityJoin(string classAlias, EntityType propertyType, bool impliedJoin, IASTNode parent) { _dereferenceType = DerefEntity; if (Log.IsDebugEnabled) { Log.Debug("dereferenceEntityJoin() : generating join for " + _propertyName + " in " + FromElement.ClassName + " " + ((classAlias == null) ? "{no alias}" : "(" + classAlias + ")") + " parent = " + ASTUtil.GetDebugstring(parent) ); } // Create a new FROM node for the referenced class. string associatedEntityName = propertyType.GetAssociatedEntityName(); string tableAlias = AliasGenerator.CreateName(associatedEntityName); string[] joinColumns = GetColumns(); string joinPath = Path; if (impliedJoin && Walker.IsInFrom) { _joinType = Walker.ImpliedJoinType; } FromClause currentFromClause = Walker.CurrentFromClause; FromElement elem = currentFromClause.FindJoinByPath(joinPath); /////////////////////////////////////////////////////////////////////////////// // // This is the piece which recognizes the condition where an implicit join path // resolved earlier in a correlated subquery is now being referenced in the // outer query. For 3.0final, we just let this generate a second join (which // is exactly how the old parser handles this). Eventually we need to add this // logic back in and complete the logic in FromClause.promoteJoin; however, // FromClause.promoteJoin has its own difficulties (see the comments in // FromClause.promoteJoin). // // if ( elem == null ) { // // see if this joinPath has been used in a "child" FromClause, and if so // // promote that element to the outer query // FromClause currentNodeOwner = getFromElement().getFromClause(); // FromClause currentJoinOwner = currentNodeOwner.locateChildFromClauseWithJoinByPath( joinPath ); // if ( currentJoinOwner != null && currentNodeOwner != currentJoinOwner ) { // elem = currentJoinOwner.findJoinByPathLocal( joinPath ); // if ( elem != null ) { // currentFromClause.promoteJoin( elem ); // // EARLY EXIT!!! // return; // } // } // } // /////////////////////////////////////////////////////////////////////////////// bool found = elem != null; // even though we might find a pre-existing element by join path, for FromElements originating in a from-clause // we should only ever use the found element if the aliases match (null != null here). Implied joins are // always (?) ok to reuse. bool useFoundFromElement = found && (elem.IsImplied || (AreSame(classAlias, elem.ClassAlias))); if (!useFoundFromElement) { // If this is an implied join in a from element, then use the impled join type which is part of the // tree parser's state (set by the gramamar actions). JoinSequence joinSequence = SessionFactoryHelper .CreateJoinSequence(impliedJoin, propertyType, tableAlias, _joinType, joinColumns); FromElementFactory factory = new FromElementFactory( currentFromClause, GetLhs().FromElement, joinPath, classAlias, joinColumns, impliedJoin ); elem = factory.CreateEntityJoin( associatedEntityName, tableAlias, joinSequence, _fetch, Walker.IsInFrom, propertyType ); } else { currentFromClause.AddDuplicateAlias(classAlias, elem); } SetImpliedJoin(elem); Walker.AddQuerySpaces(elem.EntityPersister.QuerySpaces); FromElement = elem; // This 'dot' expression now refers to the resulting from element. }
public void InitializeCollection(FromClause fromClause, string classAlias, string tableAlias) { DoInitialize(fromClause, tableAlias, null, classAlias, null, null); _initialized = true; }
private static void RenderScalarSelects(ISelectExpression[] se, FromClause currentFromClause) { if (!currentFromClause.IsSubQuery) { for (int i = 0; i < se.Length; i++) { ISelectExpression expr = se[i]; expr.SetScalarColumnText(i); // Create SQL_TOKEN nodes for the columns. } } }
private void DereferenceCollection(CollectionType collectionType, bool implicitJoin, bool indexed, string classAlias) { _dereferenceType = DerefCollection; string role = collectionType.Role; //foo.bars.size (also handles deprecated stuff like foo.bars.maxelement for backwardness) IASTNode sibling = NextSibling; bool isSizeProperty = sibling != null && CollectionProperties.IsAnyCollectionProperty(sibling.Text); if (isSizeProperty) { indexed = true; //yuck!} } IQueryableCollection queryableCollection = SessionFactoryHelper.RequireQueryableCollection(role); string propName = Path; FromClause currentFromClause = Walker.CurrentFromClause; if (Walker.StatementType != HqlSqlWalker.SELECT && indexed && classAlias == null) { // should indicate that we are processing an INSERT/UPDATE/DELETE // query with a subquery implied via a collection property // function. Here, we need to use the table name itself as the // qualification alias. // TODO : verify this works for all databases... // TODO : is this also the case in non-"indexed" scenarios? string alias = GetLhs().FromElement.Queryable.TableName; _columns = FromElement.ToColumns(alias, _propertyPath, false, true); } //We do not look for an existing join on the same path, because //it makes sense to join twice on the same collection role FromElementFactory factory = new FromElementFactory( currentFromClause, GetLhs().FromElement, propName, classAlias, GetColumns(), implicitJoin ); FromElement elem = factory.CreateCollection(queryableCollection, role, _joinType, _fetch, indexed); if (Log.IsDebugEnabled) { Log.Debug("dereferenceCollection() : Created new FROM element for " + propName + " : " + elem); } SetImpliedJoin(elem); FromElement = elem; // This 'dot' expression now refers to the resulting from element. if (isSizeProperty) { elem.Text = ""; elem.UseWhereFragment = false; } if (!implicitJoin) { IEntityPersister entityPersister = elem.EntityPersister; if (entityPersister != null) { Walker.AddQuerySpaces(entityPersister.QuerySpaces); } } Walker.AddQuerySpaces(queryableCollection.CollectionSpaces); // Always add the collection's query spaces. }
private void RenderNonScalarSelects(ISelectExpression[] selectExpressions, FromClause currentFromClause) { ASTAppender appender = new ASTAppender(ASTFactory, this); int size = selectExpressions.Length; int nonscalarSize = 0; for (int i = 0; i < size; i++) { if (!selectExpressions[i].IsScalar) { nonscalarSize++; } } int j = 0; for (int i = 0; i < size; i++) { if (!selectExpressions[i].IsScalar) { ISelectExpression expr = selectExpressions[i]; FromElement fromElement = expr.FromElement; if (fromElement != null) { RenderNonScalarIdentifiers(fromElement, nonscalarSize, j, expr, appender); j++; } } } if (!currentFromClause.IsSubQuery) { // Generate the property select tokens. int k = 0; for (int i = 0; i < size; i++) { if (!selectExpressions[i].IsScalar) { FromElement fromElement = selectExpressions[i].FromElement; if (fromElement != null) { RenderNonScalarProperties(appender, fromElement, nonscalarSize, k); k++; } } } } }
/// <summary> /// Prepares a derived (i.e., not explicitly defined in the query) select clause. /// </summary> /// <param name="fromClause">The from clause to which this select clause is linked.</param> public void InitializeDerivedSelectClause(FromClause fromClause) { if (_prepared) { throw new InvalidOperationException("SelectClause was already prepared!"); } //Used to be tested by the TCK but the test is no longer here // if ( getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() && !getWalker().isSubQuery() ) { // // NOTE : the isSubQuery() bit is a temporary hack... // throw new QuerySyntaxException( "JPA-QL compliance requires select clause" ); // } IList<IASTNode> fromElements = fromClause.GetProjectionList(); ASTAppender appender = new ASTAppender(ASTFactory, this); // Get ready to start adding nodes. int size = fromElements.Count; List<IType> sqlResultTypeList = new List<IType>(size); List<IType> queryReturnTypeList = new List<IType>(size); int k = 0; foreach (FromElement fromElement in fromElements) { IType type = fromElement.SelectType; AddCollectionFromElement(fromElement); if (type != null) { bool collectionOfElements = fromElement.IsCollectionOfValuesOrComponents; if (!collectionOfElements) { if (!fromElement.IsFetch) { // Add the type to the list of returned sqlResultTypes. queryReturnTypeList.Add(type); } _fromElementsForLoad.Add(fromElement); sqlResultTypeList.Add(type); // Generate the select expression. string text = fromElement.RenderIdentifierSelect(size, k); SelectExpressionImpl generatedExpr = (SelectExpressionImpl)appender.Append(HqlSqlWalker.SELECT_EXPR, text, false); if (generatedExpr != null) { generatedExpr.FromElement = fromElement; } } } k++; } // Get all the select expressions (that we just generated) and render the select. ISelectExpression[] selectExpressions = CollectSelectExpressions(); if (Walker.IsShallowQuery) { RenderScalarSelects(selectExpressions, fromClause); } else { RenderNonScalarSelects(selectExpressions, fromClause); } FinishInitialization( /*sqlResultTypeList,*/ queryReturnTypeList); }
public override object Create(IToken payload) { if (payload == null) { return(base.Create(payload)); } object ret; switch (payload.Type) { case HqlSqlWalker.SELECT: case HqlSqlWalker.QUERY: ret = new QueryNode(payload); break; case HqlSqlWalker.UPDATE: ret = new UpdateStatement(payload); break; case HqlSqlWalker.DELETE: ret = new DeleteStatement(payload); break; case HqlSqlWalker.INSERT: ret = new InsertStatement(payload); break; case HqlSqlWalker.INTO: ret = new IntoClause(payload); break; case HqlSqlWalker.FROM: ret = new FromClause(payload); break; case HqlSqlWalker.FROM_FRAGMENT: ret = new FromElement(payload); break; case HqlSqlWalker.IMPLIED_FROM: ret = new ImpliedFromElement(payload); break; case HqlSqlWalker.DOT: ret = new DotNode(payload); break; case HqlSqlWalker.INDEX_OP: ret = new IndexNode(payload); break; // Alias references and identifiers use the same node class. case HqlSqlWalker.ALIAS_REF: case HqlSqlWalker.IDENT: ret = new IdentNode(payload); break; case HqlSqlWalker.SQL_TOKEN: ret = new SqlFragment(payload); break; case HqlSqlWalker.METHOD_CALL: ret = new MethodNode(payload); break; case HqlSqlWalker.ELEMENTS: case HqlSqlWalker.INDICES: ret = new CollectionFunction(payload); break; case HqlSqlWalker.SELECT_CLAUSE: ret = new SelectClause(payload); break; case HqlSqlWalker.SELECT_EXPR: ret = new SelectExpressionImpl(payload); break; case HqlSqlWalker.AGGREGATE: ret = new AggregateNode(payload); break; case HqlSqlWalker.COUNT: ret = new CountNode(payload); break; case HqlSqlWalker.CONSTRUCTOR: ret = new ConstructorNode(payload); break; case HqlSqlWalker.NUM_INT: case HqlSqlWalker.NUM_FLOAT: case HqlSqlWalker.NUM_LONG: case HqlSqlWalker.NUM_DOUBLE: case HqlSqlWalker.QUOTED_String: ret = new LiteralNode(payload); break; case HqlSqlWalker.TRUE: case HqlSqlWalker.FALSE: ret = new BooleanLiteralNode(payload); break; case HqlSqlWalker.JAVA_CONSTANT: ret = new JavaConstantNode(payload); break; case HqlSqlWalker.ORDER: ret = new OrderByClause(payload); break; case HqlSqlWalker.PLUS: case HqlSqlWalker.MINUS: case HqlSqlWalker.STAR: case HqlSqlWalker.DIV: case HqlSqlWalker.BAND: case HqlSqlWalker.BOR: case HqlSqlWalker.BXOR: ret = new BinaryArithmeticOperatorNode(payload); break; case HqlSqlWalker.UNARY_MINUS: case HqlSqlWalker.UNARY_PLUS: case HqlSqlWalker.BNOT: ret = new UnaryArithmeticNode(payload); break; case HqlSqlWalker.CASE2: ret = new Case2Node(payload); break; case HqlSqlWalker.CASE: ret = new CaseNode(payload); break; case HqlSqlWalker.PARAM: case HqlSqlWalker.NAMED_PARAM: ret = new ParameterNode(payload); break; case HqlSqlWalker.EQ: case HqlSqlWalker.NE: case HqlSqlWalker.LT: case HqlSqlWalker.GT: case HqlSqlWalker.LE: case HqlSqlWalker.GE: case HqlSqlWalker.LIKE: case HqlSqlWalker.NOT_LIKE: ret = new BinaryLogicOperatorNode(payload); break; case HqlSqlWalker.IN: case HqlSqlWalker.NOT_IN: ret = new InLogicOperatorNode(payload); break; case HqlSqlWalker.BETWEEN: case HqlSqlWalker.NOT_BETWEEN: ret = new BetweenOperatorNode(payload); break; case HqlSqlWalker.IS_NULL: ret = new IsNullLogicOperatorNode(payload); break; case HqlSqlWalker.IS_NOT_NULL: ret = new IsNotNullLogicOperatorNode(payload); break; case HqlSqlWalker.EXISTS: ret = new UnaryLogicOperatorNode(payload); break; default: ret = new SqlNode(payload); break; } Initialise(ret); return(ret); }
/// <summary> /// Prepares an explicitly defined select clause. /// </summary> /// <param name="fromClause">The from clause linked to this select clause.</param> /// <exception cref="SemanticException"></exception> public void InitializeExplicitSelectClause(FromClause fromClause) { if (_prepared) { throw new InvalidOperationException("SelectClause was already prepared!"); } //explicit = true; // This is an explict Select. //ArrayList sqlResultTypeList = new ArrayList(); List<IType> queryReturnTypeList = new List<IType>(); // First, collect all of the select expressions. // NOTE: This must be done *before* invoking setScalarColumnText() because setScalarColumnText() // changes the AST!!! ISelectExpression[] selectExpressions = CollectSelectExpressions(); for (int i = 0; i < selectExpressions.Length; i++) { ISelectExpression expr = selectExpressions[i]; if (expr.IsConstructor) { _constructorNode = (ConstructorNode)expr; IList<IType> constructorArgumentTypeList = _constructorNode.ConstructorArgumentTypeList; //sqlResultTypeList.addAll( constructorArgumentTypeList ); queryReturnTypeList.AddRange(constructorArgumentTypeList); _scalarSelect = true; for (int j = 1; j < _constructorNode.ChildCount; j++) { ISelectExpression se = _constructorNode.GetChild(j) as ISelectExpression; if (se != null && IsReturnableEntity(se)) { _fromElementsForLoad.Add(se.FromElement); } } } else { IType type = expr.DataType; if (type == null && !(expr is ParameterNode)) { throw new QueryException("No data type for node: " + expr.GetType().Name + " " + new ASTPrinter().ShowAsString((IASTNode)expr, "")); } //sqlResultTypeList.add( type ); // If the data type is not an association type, it could not have been in the FROM clause. if (expr.IsScalar) { _scalarSelect = true; } if (IsReturnableEntity(expr)) { _fromElementsForLoad.Add(expr.FromElement); } // Always add the type to the return type list. queryReturnTypeList.Add(type); } } //init the aliases, after initing the constructornode InitAliases(selectExpressions); if (!Walker.IsShallowQuery) { // add the fetched entities IList<IASTNode> fromElements = fromClause.GetProjectionList(); ASTAppender appender = new ASTAppender(ASTFactory, this); // Get ready to start adding nodes. int size = fromElements.Count; int k = 0; foreach (FromElement fromElement in fromElements) { if (fromElement.IsFetch) { FromElement origin; if (fromElement.RealOrigin == null) { // work around that crazy issue where the tree contains // "empty" FromElements (no text); afaict, this is caused // by FromElementFactory.createCollectionJoin() if (fromElement.Origin == null) { throw new QueryException("Unable to determine origin of join fetch [" + fromElement.GetDisplayText() + "]"); } origin = fromElement.Origin; } else { origin = fromElement.RealOrigin; } // Only perform the fetch if its owner is included in the select if (!_fromElementsForLoad.Contains(origin)) { // NH-2846: Before 2012-01-18, we threw this exception. However, some // components using LINQ (e.g. paging) like to automatically append e.g. Count(). It // can then be difficult to avoid having a bogus fetch statement, so just ignore those. // An alternative solution may be to have the linq provider filter out the fetch instead. // throw new QueryException(string.Format(JoinFetchWithoutOwnerExceptionMsg, fromElement.GetDisplayText())); //throw away the fromElement. It's clearly redundant. fromElement.Parent.RemoveChild(fromElement); } else { IType type = fromElement.SelectType; AddCollectionFromElement(fromElement); if (type != null) { bool collectionOfElements = fromElement.IsCollectionOfValuesOrComponents; if (!collectionOfElements) { // Add the type to the list of returned sqlResultTypes. fromElement.IncludeSubclasses = true; _fromElementsForLoad.Add(fromElement); //sqlResultTypeList.add( type ); // Generate the select expression. String text = fromElement.RenderIdentifierSelect(size, k); SelectExpressionImpl generatedExpr = (SelectExpressionImpl)appender.Append(HqlSqlWalker.SELECT_EXPR, text, false); if (generatedExpr != null) { generatedExpr.FromElement = fromElement; } } } } } k++; } // generate id select fragment and then property select fragment for // each expression, just like generateSelectFragments(). RenderNonScalarSelects(CollectSelectExpressions(true), fromClause); } if (_scalarSelect || Walker.IsShallowQuery) { // If there are any scalars (non-entities) selected, render the select column aliases. RenderScalarSelects(selectExpressions, fromClause); } FinishInitialization( /*sqlResultTypeList,*/ queryReturnTypeList); }
private void AddChild(FromClause fromClause) { if (_childFromClauses == null) { _childFromClauses = new HashSet<FromClause>(); } _childFromClauses.Add(fromClause); }
/// <summary> /// Prepares an explicitly defined select clause. /// </summary> /// <param name="fromClause">The from clause linked to this select clause.</param> /// <exception cref="SemanticException"></exception> public void InitializeExplicitSelectClause(FromClause fromClause) { if (_prepared) { throw new InvalidOperationException("SelectClause was already prepared!"); } //explicit = true; // This is an explict Select. //ArrayList sqlResultTypeList = new ArrayList(); List <IType> queryReturnTypeList = new List <IType>(); // First, collect all of the select expressions. // NOTE: This must be done *before* invoking setScalarColumnText() because setScalarColumnText() // changes the AST!!! ISelectExpression[] selectExpressions = CollectSelectExpressions(); for (int i = 0; i < selectExpressions.Length; i++) { ISelectExpression expr = selectExpressions[i]; if (expr.IsConstructor) { _constructorNode = (ConstructorNode)expr; IList <IType> constructorArgumentTypeList = _constructorNode.ConstructorArgumentTypeList; //sqlResultTypeList.addAll( constructorArgumentTypeList ); queryReturnTypeList.AddRange(constructorArgumentTypeList); _scalarSelect = true; for (int j = 1; j < _constructorNode.ChildCount; j++) { ISelectExpression se = _constructorNode.GetChild(j) as ISelectExpression; if (se != null && IsReturnableEntity(se)) { _fromElementsForLoad.Add(se.FromElement); } } } else { IType type = expr.DataType; if (type == null && !(expr is ParameterNode)) { throw new QueryException("No data type for node: " + expr.GetType().Name + " " + new ASTPrinter().ShowAsString((IASTNode)expr, "")); } //sqlResultTypeList.add( type ); // If the data type is not an association type, it could not have been in the FROM clause. if (expr.IsScalar) { _scalarSelect = true; } if (IsReturnableEntity(expr)) { _fromElementsForLoad.Add(expr.FromElement); } // Always add the type to the return type list. queryReturnTypeList.Add(type); } } //init the aliases, after initing the constructornode InitAliases(selectExpressions); if (!Walker.IsShallowQuery) { // add the fetched entities IList <IASTNode> fromElements = fromClause.GetProjectionList(); ASTAppender appender = new ASTAppender(ASTFactory, this); // Get ready to start adding nodes. int size = fromElements.Count; int k = 0; foreach (FromElement fromElement in fromElements) { if (fromElement.IsFetch) { var origin = GetOrigin(fromElement); // Only perform the fetch if its owner is included in the select if (!_fromElementsForLoad.Contains(origin)) { // NH-2846: Before 2012-01-18, we threw this exception. However, some // components using LINQ (e.g. paging) like to automatically append e.g. Count(). It // can then be difficult to avoid having a bogus fetch statement, so just ignore those. // An alternative solution may be to have the linq provider filter out the fetch instead. // throw new QueryException(string.Format(JoinFetchWithoutOwnerExceptionMsg, fromElement.GetDisplayText())); //throw away the fromElement. It's clearly redundant. fromElement.Parent.RemoveChild(fromElement); } else { IType type = fromElement.SelectType; AddCollectionFromElement(fromElement); if (type != null) { bool collectionOfElements = fromElement.IsCollectionOfValuesOrComponents; if (!collectionOfElements) { // Add the type to the list of returned sqlResultTypes. fromElement.IncludeSubclasses = true; _fromElementsForLoad.Add(fromElement); //sqlResultTypeList.add( type ); // Generate the select expression. String text = fromElement.RenderIdentifierSelect(size, k); SelectExpressionImpl generatedExpr = (SelectExpressionImpl)appender.Append(HqlSqlWalker.SELECT_EXPR, text, false); if (generatedExpr != null) { generatedExpr.FromElement = fromElement; } } } } } k++; } // generate id select fragment and then property select fragment for // each expression, just like generateSelectFragments(). RenderNonScalarSelects(CollectSelectExpressions(true), fromClause); } if (_scalarSelect || Walker.IsShallowQuery) { // If there are any scalars (non-entities) selected, render the select column aliases. RenderScalarSelects(selectExpressions, fromClause); } FinishInitialization(/*sqlResultTypeList,*/ queryReturnTypeList); }
public void InitializeEntity(FromClause fromClause, string className, IEntityPersister persister, EntityType type, string classAlias, string tableAlias) { DoInitialize(fromClause, tableAlias, className, classAlias, persister, type); _initialized = true; }
/** * Prepares a derived (i.e., not explicitly defined in the query) select clause. * * @param fromClause The from clause to which this select clause is linked. */ public void InitializeDerivedSelectClause(FromClause fromClause) { if (_prepared) { throw new InvalidOperationException("SelectClause was already prepared!"); } //Used to be tested by the TCK but the test is no longer here // if ( getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() && !getWalker().isSubQuery() ) { // // NOTE : the isSubQuery() bit is a temporary hack... // throw new QuerySyntaxException( "JPA-QL compliance requires select clause" ); // } IList <IASTNode> fromElements = fromClause.GetProjectionList(); ASTAppender appender = new ASTAppender(ASTFactory, this); // Get ready to start adding nodes. int size = fromElements.Count; List <IType> sqlResultTypeList = new List <IType>(size); List <IType> queryReturnTypeList = new List <IType>(size); int k = 0; foreach (FromElement fromElement in fromElements) { IType type = fromElement.SelectType; AddCollectionFromElement(fromElement); if (type != null) { bool collectionOfElements = fromElement.IsCollectionOfValuesOrComponents; if (!collectionOfElements) { if (!fromElement.IsFetch) { // Add the type to the list of returned sqlResultTypes. queryReturnTypeList.Add(type); } _fromElementsForLoad.Add(fromElement); sqlResultTypeList.Add(type); // Generate the select expression. string text = fromElement.RenderIdentifierSelect(size, k); SelectExpressionImpl generatedExpr = ( SelectExpressionImpl )appender.Append(HqlSqlWalker.SELECT_EXPR, text, false); if (generatedExpr != null) { generatedExpr.FromElement = fromElement; } } } k++; } // Get all the select expressions (that we just generated) and render the select. ISelectExpression[] selectExpressions = CollectSelectExpressions(); if (Walker.IsShallowQuery) { RenderScalarSelects(selectExpressions, fromClause); } else { RenderNonScalarSelects(selectExpressions, fromClause); } FinishInitialization(/*sqlResultTypeList,*/ queryReturnTypeList); }
/** * Prepares an explicitly defined select clause. * * @param fromClause The from clause linked to this select clause. * @throws SemanticException */ public void InitializeExplicitSelectClause(FromClause fromClause) { if (_prepared) { throw new InvalidOperationException("SelectClause was already prepared!"); } //explicit = true; // This is an explict Select. //ArrayList sqlResultTypeList = new ArrayList(); List <IType> queryReturnTypeList = new List <IType>(); // First, collect all of the select expressions. // NOTE: This must be done *before* invoking setScalarColumnText() because setScalarColumnText() // changes the AST!!! ISelectExpression[] selectExpressions = CollectSelectExpressions(); for (int i = 0; i < selectExpressions.Length; i++) { ISelectExpression expr = selectExpressions[i]; if (expr.IsConstructor) { _constructorNode = ( ConstructorNode )expr; IList <IType> constructorArgumentTypeList = _constructorNode.ConstructorArgumentTypeList; //sqlResultTypeList.addAll( constructorArgumentTypeList ); queryReturnTypeList.AddRange(constructorArgumentTypeList); _scalarSelect = true; for (int j = 1; j < _constructorNode.ChildCount; j++) { ISelectExpression se = _constructorNode.GetChild(j) as ISelectExpression; if (se != null && IsReturnableEntity(se)) { _fromElementsForLoad.Add(se.FromElement); } } } else { IType type = expr.DataType; if (type == null) { throw new QueryException("No data type for node: " + expr.GetType().Name + " " + new ASTPrinter().ShowAsString((IASTNode)expr, "")); } //sqlResultTypeList.add( type ); // If the data type is not an association type, it could not have been in the FROM clause. if (expr.IsScalar) { _scalarSelect = true; } if (IsReturnableEntity(expr)) { _fromElementsForLoad.Add(expr.FromElement); } // Always add the type to the return type list. queryReturnTypeList.Add(type); } } //init the aliases, after initing the constructornode InitAliases(selectExpressions); if (!Walker.IsShallowQuery) { // add the fetched entities IList <IASTNode> fromElements = fromClause.GetProjectionList(); ASTAppender appender = new ASTAppender(ASTFactory, this); // Get ready to start adding nodes. int size = fromElements.Count; int k = 0; foreach (FromElement fromElement in fromElements) { if (fromElement.IsFetch) { FromElement origin; if (fromElement.RealOrigin == null) { // work around that crazy issue where the tree contains // "empty" FromElements (no text); afaict, this is caused // by FromElementFactory.createCollectionJoin() if (fromElement.Origin == null) { throw new QueryException("Unable to determine origin of join fetch [" + fromElement.GetDisplayText() + "]"); } origin = fromElement.Origin; } else { origin = fromElement.RealOrigin; } if (!_fromElementsForLoad.Contains(origin)) { throw new QueryException(string.Format(JoinFetchWithoutOwnerExceptionMsg, fromElement.GetDisplayText())); } IType type = fromElement.SelectType; AddCollectionFromElement(fromElement); if (type != null) { bool collectionOfElements = fromElement.IsCollectionOfValuesOrComponents; if (!collectionOfElements) { // Add the type to the list of returned sqlResultTypes. fromElement.IncludeSubclasses = true; _fromElementsForLoad.Add(fromElement); //sqlResultTypeList.add( type ); // Generate the select expression. String text = fromElement.RenderIdentifierSelect(size, k); SelectExpressionImpl generatedExpr = ( SelectExpressionImpl )appender.Append(HqlSqlWalker.SELECT_EXPR, text, false); if (generatedExpr != null) { generatedExpr.FromElement = fromElement; } } } } k++; } // generate id select fragment and then property select fragment for // each expression, just like generateSelectFragments(). RenderNonScalarSelects(CollectSelectExpressions(true), fromClause); } if (_scalarSelect || Walker.IsShallowQuery) { // If there are any scalars (non-entities) selected, render the select column aliases. RenderScalarSelects(selectExpressions, fromClause); } FinishInitialization(/*sqlResultTypeList,*/ queryReturnTypeList); }
internal JoinSequenceSelector(HqlSqlWalker walker, FromClause fromClause, FromElement fromElement) { _walker = walker; _fromClause = fromClause; _fromElement = fromElement; }
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; }
void PushFromClause(IASTNode fromNode) { FromClause newFromClause = (FromClause)fromNode; newFromClause.SetParentFromClause(_currentFromClause); _currentFromClause = newFromClause; }
public override object Create(IToken payload) { if (payload == null) { return base.Create(payload); } object ret; switch (payload.Type) { case HqlSqlWalker.SELECT: case HqlSqlWalker.QUERY: ret = new QueryNode(payload); break; case HqlSqlWalker.UPDATE: ret = new UpdateStatement(payload); break; case HqlSqlWalker.DELETE: ret = new DeleteStatement(payload); break; case HqlSqlWalker.INSERT: ret = new InsertStatement(payload); break; case HqlSqlWalker.INTO: ret = new IntoClause(payload); break; case HqlSqlWalker.FROM: ret = new FromClause(payload); break; case HqlSqlWalker.FROM_FRAGMENT: ret = new FromElement(payload); break; case HqlSqlWalker.IMPLIED_FROM: ret = new ImpliedFromElement(payload); break; case HqlSqlWalker.DOT: ret = new DotNode(payload); break; case HqlSqlWalker.INDEX_OP: ret = new IndexNode(payload); break; // Alias references and identifiers use the same node class. case HqlSqlWalker.ALIAS_REF: case HqlSqlWalker.IDENT: ret = new IdentNode(payload); break; case HqlSqlWalker.SQL_TOKEN: ret = new SqlFragment(payload); break; case HqlSqlWalker.METHOD_CALL: ret = new MethodNode(payload); break; case HqlSqlWalker.ELEMENTS: case HqlSqlWalker.INDICES: ret = new CollectionFunction(payload); break; case HqlSqlWalker.SELECT_CLAUSE: ret = new SelectClause(payload); break; case HqlSqlWalker.SELECT_EXPR: ret = new SelectExpressionImpl(payload); break; case HqlSqlWalker.AGGREGATE: ret = new AggregateNode(payload); break; case HqlSqlWalker.COUNT: ret = new CountNode(payload); break; case HqlSqlWalker.CONSTRUCTOR: ret = new ConstructorNode(payload); break; case HqlSqlWalker.NUM_INT: case HqlSqlWalker.NUM_FLOAT: case HqlSqlWalker.NUM_LONG: case HqlSqlWalker.NUM_DOUBLE: case HqlSqlWalker.NUM_DECIMAL: case HqlSqlWalker.QUOTED_String: ret = new LiteralNode(payload); break; case HqlSqlWalker.TRUE: case HqlSqlWalker.FALSE: ret = new BooleanLiteralNode(payload); break; case HqlSqlWalker.JAVA_CONSTANT: ret = new JavaConstantNode(payload); break; case HqlSqlWalker.ORDER: ret = new OrderByClause(payload); break; case HqlSqlWalker.PLUS: case HqlSqlWalker.MINUS: case HqlSqlWalker.STAR: case HqlSqlWalker.DIV: case HqlSqlWalker.BAND: case HqlSqlWalker.BOR: case HqlSqlWalker.BXOR: ret = new BinaryArithmeticOperatorNode(payload); break; case HqlSqlWalker.UNARY_MINUS: case HqlSqlWalker.UNARY_PLUS: case HqlSqlWalker.BNOT: ret = new UnaryArithmeticNode(payload); break; case HqlSqlWalker.CASE2: ret = new Case2Node(payload); break; case HqlSqlWalker.CASE: ret = new CaseNode(payload); break; case HqlSqlWalker.PARAM: case HqlSqlWalker.NAMED_PARAM: ret = new ParameterNode(payload); break; case HqlSqlWalker.EQ: case HqlSqlWalker.NE: case HqlSqlWalker.LT: case HqlSqlWalker.GT: case HqlSqlWalker.LE: case HqlSqlWalker.GE: case HqlSqlWalker.LIKE: case HqlSqlWalker.NOT_LIKE: ret = new BinaryLogicOperatorNode(payload); break; case HqlSqlWalker.IN: case HqlSqlWalker.NOT_IN: ret = new InLogicOperatorNode(payload); break; case HqlSqlWalker.BETWEEN: case HqlSqlWalker.NOT_BETWEEN: ret = new BetweenOperatorNode(payload); break; case HqlSqlWalker.IS_NULL: ret = new IsNullLogicOperatorNode(payload); break; case HqlSqlWalker.IS_NOT_NULL: ret = new IsNotNullLogicOperatorNode(payload); break; case HqlSqlWalker.EXISTS: ret = new UnaryLogicOperatorNode(payload); break; default: ret = new SqlNode(payload); break; } Initialise(ret); return ret; }
/// <summary> /// Returns to the previous 'FROM' context. /// </summary> private void PopFromClause() { _currentFromClause = _currentFromClause.ParentFromClause; }