From: <ste...@us...> - 2006-02-13 15:50:36
|
Update of /cvsroot/hibernate/Hibernate3/src/org/hibernate/hql/ast/tree In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7842/src/org/hibernate/hql/ast/tree Modified Files: FromElementType.java Log Message: HHH-1419 Index: FromElementType.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate3/src/org/hibernate/hql/ast/tree/FromElementType.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- FromElementType.java 10 Feb 2006 17:30:19 -0000 1.6 +++ FromElementType.java 13 Feb 2006 15:50:27 -0000 1.7 @@ -5,6 +5,7 @@ import org.hibernate.MappingException; import org.hibernate.QueryException; +import org.hibernate.util.ArrayHelper; import org.hibernate.engine.JoinSequence; import org.hibernate.hql.CollectionProperties; import org.hibernate.hql.CollectionSubqueryFactory; @@ -308,20 +309,66 @@ return new String[]{"(" + subquery + ")"}; } else { - // decide if we need to use table-alias qualification - boolean useTableAlias = fromElement.getWalker().getStatementType() == HqlSqlTokenTypes.SELECT - || fromElement.getWalker().getCurrentClauseType() == HqlSqlTokenTypes.SELECT - || fromElement.getWalker().isSubQuery() - || forceAlias; - if ( useTableAlias ) { + if ( forceAlias ) { return propertyMapping.toColumns( tableAlias, path ); } + else if ( fromElement.getWalker().getStatementType() == HqlSqlTokenTypes.SELECT ) { + return propertyMapping.toColumns( tableAlias, path ); + } + else if ( fromElement.getWalker().getCurrentClauseType() == HqlSqlTokenTypes.SELECT ) { + return propertyMapping.toColumns( tableAlias, path ); + } + else if ( fromElement.getWalker().isSubQuery() ) { + // for a subquery, the alias to use depends on a few things (we + // already know this is not an overall SELECT): + // 1) if this FROM_ELEMENT represents a correlation to the + // outer-most query + // A) if the outer query represents a multi-table + // persister, we need to use the given alias + // in anticipation of one of the multi-table + // executors being used (as this subquery will + // actually be used in the "id select" phase + // of that multi-table executor) + // B) otherwise, we need to use the persister's + // table name as the column qualification + // 2) otherwise (not correlated), use the given alias + if ( isCorrelation() ) { + if ( isMultiTable() ) { + return propertyMapping.toColumns( tableAlias, path ); + } + else { + return propertyMapping.toColumns( extractTableName(), path ); + } + } + else { + return propertyMapping.toColumns( tableAlias, path ); + } + } else { - return propertyMapping.toColumns( path ); + String[] columns = propertyMapping.toColumns( path ); + log.warn( "Using non-qualified column reference [" + path + " -> (" + ArrayHelper.toString( columns ) + ")]" ); + return columns; } } } + private boolean isCorrelation() { + FromClause top = fromElement.getWalker().getFinalFromClause(); + return fromElement.getFromClause() != fromElement.getWalker().getCurrentFromClause() && + fromElement.getFromClause() == top; + } + + private boolean isMultiTable() { + // should be safe to only ever expect EntityPersister references here + return fromElement.getQueryable() != null && + fromElement.getQueryable().isMultiTable(); + } + + private String extractTableName() { + // should be safe to only ever expect EntityPersister references here + return fromElement.getQueryable().getTableName(); + } + PropertyMapping getPropertyMapping(String propertyName) { checkInitialized(); if ( queryableCollection == null ) { // Not a collection? |