📄 fromelementfactory.java
字号:
// $Id: FromElementFactory.java 9586 2006-03-09 21:11:44Z steve.ebersole@jboss.com $package org.hibernate.hql.ast.tree;import org.hibernate.engine.JoinSequence;import org.hibernate.hql.antlr.SqlTokenTypes;import org.hibernate.hql.ast.util.ASTUtil;import org.hibernate.hql.ast.util.AliasGenerator;import org.hibernate.hql.ast.util.PathHelper;import org.hibernate.hql.ast.util.SessionFactoryHelper;import org.hibernate.persister.collection.QueryableCollection;import org.hibernate.persister.entity.EntityPersister;import org.hibernate.persister.entity.Joinable;import org.hibernate.persister.entity.Queryable;import org.hibernate.sql.JoinFragment;import org.hibernate.type.AssociationType;import org.hibernate.type.CollectionType;import org.hibernate.type.EntityType;import org.hibernate.type.Type;import org.hibernate.util.StringHelper;import antlr.ASTFactory;import antlr.SemanticException;import antlr.collections.AST;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * Encapsulates the creation of FromElements and JoinSequences. * * @author josh Oct 12, 2004 4:54:25 AM */class FromElementFactory implements SqlTokenTypes { private static final Logger log = LoggerFactory.getLogger( FromElementFactory.class ); private FromClause fromClause; private FromElement origin; private String path; private String classAlias; private String[] columns; private boolean implied; private boolean inElementsFunction; private boolean collection; private QueryableCollection queryableCollection; private CollectionType collectionType; /** * Creates entity from elements. */ public FromElementFactory(FromClause fromClause, FromElement origin, String path) { this.fromClause = fromClause; this.origin = origin; this.path = path; collection = false; } /** * Creates collection from elements. */ public FromElementFactory( FromClause fromClause, FromElement origin, String path, String classAlias, String[] columns, boolean implied) { this( fromClause, origin, path ); this.classAlias = classAlias; this.columns = columns; this.implied = implied; collection = true; } FromElement addFromElement() throws SemanticException { FromClause parentFromClause = fromClause.getParentFromClause(); if ( parentFromClause != null ) { // Look up class name using the first identifier in the path. String pathAlias = PathHelper.getAlias( path ); FromElement parentFromElement = parentFromClause.getFromElement( pathAlias ); if ( parentFromElement != null ) { return createFromElementInSubselect( path, pathAlias, parentFromElement, classAlias ); } } EntityPersister entityPersister = fromClause.getSessionFactoryHelper().requireClassPersister( path ); FromElement elem = createAndAddFromElement( path, classAlias, entityPersister, ( EntityType ) ( ( Queryable ) entityPersister ).getType(), null ); // Add to the query spaces. fromClause.getWalker().addQuerySpaces( entityPersister.getQuerySpaces() ); return elem; } private FromElement createFromElementInSubselect( String path, String pathAlias, FromElement parentFromElement, String classAlias) throws SemanticException { if ( log.isDebugEnabled() ) { log.debug( "createFromElementInSubselect() : path = " + path ); } // Create an DotNode AST for the path and resolve it. FromElement fromElement = evaluateFromElementPath( path, classAlias ); EntityPersister entityPersister = fromElement.getEntityPersister(); // If the first identifier in the path referrs to the class alias (not the class name), then this // is a correlated subselect. If it's a correlated sub-select, use the existing table alias. Otherwise // generate a new one. String tableAlias = null; boolean correlatedSubselect = pathAlias.equals( parentFromElement.getClassAlias() ); if ( correlatedSubselect ) { tableAlias = fromElement.getTableAlias(); } else { tableAlias = null; } // If the from element isn't in the same clause, create a new from element. if ( fromElement.getFromClause() != fromClause ) { if ( log.isDebugEnabled() ) { log.debug( "createFromElementInSubselect() : creating a new FROM element..." ); } fromElement = createFromElement( entityPersister ); initializeAndAddFromElement( fromElement, path, classAlias, entityPersister, ( EntityType ) ( ( Queryable ) entityPersister ).getType(), tableAlias ); } if ( log.isDebugEnabled() ) { log.debug( "createFromElementInSubselect() : " + path + " -> " + fromElement ); } return fromElement; } private FromElement evaluateFromElementPath(String path, String classAlias) throws SemanticException { ASTFactory factory = fromClause.getASTFactory(); FromReferenceNode pathNode = ( FromReferenceNode ) PathHelper.parsePath( path, factory ); pathNode.recursiveResolve( FromReferenceNode.ROOT_LEVEL, // 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.getFromElement(); } } FromElement createCollectionElementsJoin( QueryableCollection queryableCollection, String collectionName) throws SemanticException { JoinSequence collectionJoinSequence = fromClause.getSessionFactoryHelper() .createCollectionJoinSequence( queryableCollection, collectionName ); this.queryableCollection = queryableCollection; return createCollectionJoin( collectionJoinSequence, null ); } FromElement createCollection( QueryableCollection queryableCollection, String role, int joinType, boolean fetchFlag, boolean indexed) throws SemanticException { if ( !collection ) { throw new IllegalStateException( "FromElementFactory not initialized for collections!" ); } this.inElementsFunction = indexed; FromElement elem; this.queryableCollection = queryableCollection; collectionType = queryableCollection.getCollectionType(); String roleAlias = fromClause.getAliasGenerator().createName( role ); // Correlated subqueries create 'special' implied from nodes // because correlated subselects can't use an ANSI-style join boolean explicitSubqueryFromElement = fromClause.isSubQuery() && !implied; if ( explicitSubqueryFromElement ) { String pathRoot = StringHelper.root( path ); FromElement origin = fromClause.getFromElement( pathRoot ); if ( origin == null || origin.getFromClause() != fromClause ) { implied = true; } } // super-duper-classic-parser-regression-testing-mojo-magic... if ( explicitSubqueryFromElement && DotNode.useThetaStyleImplicitJoins ) { implied = true; } Type elementType = queryableCollection.getElementType(); if ( elementType.isEntityType() ) { // A collection of entities... elem = createEntityAssociation( role, roleAlias, joinType ); } else if ( elementType.isComponentType() ) { // A collection of components... JoinSequence joinSequence = createJoinSequence( roleAlias, joinType ); elem = createCollectionJoin( joinSequence, roleAlias ); } else { // A collection of scalar elements... JoinSequence joinSequence = createJoinSequence( roleAlias, joinType ); elem = createCollectionJoin( joinSequence, roleAlias ); } elem.setRole( role ); elem.setQueryableCollection( queryableCollection ); // Don't include sub-classes for implied collection joins or subquery joins. if ( implied ) { elem.setIncludeSubclasses( false ); } if ( explicitSubqueryFromElement ) { elem.setInProjectionList( true ); // Treat explict from elements in sub-queries properly. } if ( fetchFlag ) { elem.setFetch( true ); } return elem; } FromElement createEntityJoin( String entityClass, String tableAlias, JoinSequence joinSequence, boolean fetchFlag, boolean inFrom, EntityType type) throws SemanticException { FromElement elem = createJoin( entityClass, tableAlias, joinSequence, type, false ); elem.setFetch( fetchFlag ); EntityPersister entityPersister = elem.getEntityPersister(); int numberOfTables = entityPersister.getQuerySpaces().length; if ( numberOfTables > 1 && implied && !elem.useFromFragment() ) { if ( log.isDebugEnabled() ) { log.debug( "createEntityJoin() : Implied multi-table entity join" ); } elem.setUseFromFragment( true ); } // If this is an implied join in a FROM clause, then use ANSI-style joining, and set the // flag on the FromElement that indicates that it was implied in the FROM clause itself.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -