📄 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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Encapsulates the creation of FromElements and JoinSequences.
*
* @author josh Oct 12, 2004 4:54:25 AM
*/
class FromElementFactory implements SqlTokenTypes {
private static final Log log = LogFactory.getLog( 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 + -