return toColumns( tableAlias, path, inSelect, false );
}
String[] toColumns(String tableAlias, String path, boolean inSelect, boolean forceAlias) {
checkInitialized();
PropertyMapping propertyMapping = getPropertyMapping( path );
if ( !inSelect && queryableCollection != null && CollectionProperties.isCollectionProperty( path ) ) {
// If this from element is a collection and the path is a collection property (maxIndex, etc.)
// requiring a sub-query then generate a sub-query.
//h
// Unless we are in the select clause, because some dialects do not support
// Note however, that some dialects do not However, in the case of this being a collection property reference being in the select, not generating the subquery
// will not generally work. The specific cases I am thinking about are the minIndex, maxIndex
// (most likely minElement, maxElement as well) cases.
// todo : if ^^ is the case we should thrown an exception here rather than waiting for the sql error
// if the dialect supports select-clause subqueries we could go ahead and generate the subquery also
Map enabledFilters = fromElement.getWalker().getEnabledFilters();
String subquery = CollectionSubqueryFactory.createCollectionSubquery(
joinSequence.copy().setUseThetaStyle( true ),
enabledFilters,
propertyMapping.toColumns( tableAlias, path )
);
LOG.debugf( "toColumns(%s,%s) : subquery = %s", tableAlias, path, subquery );
return new String[]{"(" + subquery + ")"};
}
if (forceAlias) {
return propertyMapping.toColumns(tableAlias, path);
}
if (fromElement.getWalker().getStatementType() == HqlSqlTokenTypes.SELECT) {
return propertyMapping.toColumns(tableAlias, path);
}
if (fromElement.getWalker().getCurrentClauseType() == HqlSqlTokenTypes.SELECT) {
return propertyMapping.toColumns(tableAlias, path);
}
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);
}
return propertyMapping.toColumns(extractTableName(), path);
}
return propertyMapping.toColumns(tableAlias, path);
}
if ( isManipulationQuery() && isMultiTable() && inWhereClause() ) {
// the actual where-clause will end up being ripped out the update/delete and used in
// a select to populate the temp table, so its ok to use the table alias to qualify the table refs
// and safer to do so to protect from same-named columns
return propertyMapping.toColumns( tableAlias, path );
}
String[] columns = propertyMapping.toColumns( path );
LOG.tracev( "Using non-qualified column reference [{0} -> ({1})]", path, ArrayHelper.toString( columns ) );
return columns;
}