HHH-17231 Reintroduce support for entity path expansion in subqueries
This commit is contained in:
parent
8957a7ccf5
commit
d59ecb633b
|
@ -261,9 +261,9 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
|
||||||
SqmToSqlAstConverter sqlAstCreationState) {
|
SqmToSqlAstConverter sqlAstCreationState) {
|
||||||
final boolean expandToAllColumns;
|
final boolean expandToAllColumns;
|
||||||
final Clause currentClause = sqlAstCreationState.getCurrentClauseStack().getCurrent();
|
final Clause currentClause = sqlAstCreationState.getCurrentClauseStack().getCurrent();
|
||||||
if ( sqlAstCreationState.getCurrentProcessingState().isTopLevel() &&
|
if ( currentClause == Clause.GROUP || currentClause == Clause.ORDER ) {
|
||||||
( currentClause == Clause.GROUP || currentClause == Clause.ORDER ) ) {
|
assert sqlAstCreationState.getCurrentSqmQueryPart().isSimpleQueryPart();
|
||||||
final SqmQuerySpec<?> querySpec = (SqmQuerySpec<?>) sqlAstCreationState.getCurrentSqmQueryPart();
|
final SqmQuerySpec<?> querySpec = sqlAstCreationState.getCurrentSqmQueryPart().getFirstQuerySpec();
|
||||||
if ( currentClause == Clause.ORDER && !querySpec.groupByClauseContains( navigablePath ) ) {
|
if ( currentClause == Clause.ORDER && !querySpec.groupByClauseContains( navigablePath ) ) {
|
||||||
// We must ensure that the order by expression be expanded but only if the group by
|
// We must ensure that the order by expression be expanded but only if the group by
|
||||||
// contained the same expression, and that was expanded as well
|
// contained the same expression, and that was expanded as well
|
||||||
|
@ -272,7 +272,12 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
|
||||||
else {
|
else {
|
||||||
// When the table group is selected and the navigablePath is selected we need to expand
|
// When the table group is selected and the navigablePath is selected we need to expand
|
||||||
// to all columns, as we must make sure we include all columns present in the select clause
|
// to all columns, as we must make sure we include all columns present in the select clause
|
||||||
expandToAllColumns = isSelected( tableGroup, navigablePath, querySpec );
|
expandToAllColumns = isSelected(
|
||||||
|
tableGroup,
|
||||||
|
navigablePath,
|
||||||
|
querySpec,
|
||||||
|
sqlAstCreationState.getCurrentProcessingState().isTopLevel()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -351,38 +356,43 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSelected(TableGroup tableGroup, NavigablePath path, SqmQuerySpec<?> sqmQuerySpec) {
|
private static boolean isSelected(
|
||||||
// If the table group is selected (initialized), check if the entity valued
|
TableGroup tableGroup,
|
||||||
// navigable path or any child path appears in the select clause
|
NavigablePath path,
|
||||||
return tableGroup.isInitialized() && selectClauseContains( path, sqmQuerySpec );
|
SqmQuerySpec<?> sqmQuerySpec,
|
||||||
|
boolean isTopLevel) {
|
||||||
|
// If the table group is not initialized, i.e. not selected, no need to check selections
|
||||||
|
if ( !tableGroup.isInitialized() || sqmQuerySpec.getSelectClause() == null ) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
final NavigablePath tableGroupPath = isTopLevel ? null : tableGroup.getNavigablePath();
|
||||||
private static boolean selectClauseContains(NavigablePath path, SqmQuerySpec<?> sqmQuerySpec) {
|
for ( SqmSelection<?> selection : sqmQuerySpec.getSelectClause().getSelections() ) {
|
||||||
final List<SqmSelection<?>> selections = sqmQuerySpec.getSelectClause() == null
|
if ( selectionContains( selection.getSelectableNode(), path, tableGroupPath ) ) {
|
||||||
? Collections.emptyList()
|
|
||||||
: sqmQuerySpec.getSelectClause().getSelections();
|
|
||||||
for ( SqmSelection<?> selection : selections ) {
|
|
||||||
if ( selectionContains( selection.getSelectableNode(), path ) ) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean selectionContains(Selection<?> selection, NavigablePath path) {
|
private static boolean selectionContains(Selection<?> selection, NavigablePath path, NavigablePath tableGroupPath) {
|
||||||
if ( selection instanceof SqmPath && path.isParentOrEqual( ( (SqmPath<?>) selection ).getNavigablePath() ) ) {
|
if ( selection instanceof SqmPath<?> ) {
|
||||||
return true;
|
final SqmPath<?> sqmPath = (SqmPath<?>) selection;
|
||||||
|
// Expansion is needed if the table group is null, i.e. we're in a top level query where EVPs are always
|
||||||
|
// expanded to all columns, or if the selection is on the same table (lhs) as the group by expression ...
|
||||||
|
return ( tableGroupPath == null || sqmPath.getLhs().getNavigablePath().equals( tableGroupPath ) )
|
||||||
|
// ... and if the entity valued path is selected or any of its columns are
|
||||||
|
&& path.isParentOrEqual( sqmPath.getNavigablePath() );
|
||||||
}
|
}
|
||||||
else if ( selection.isCompoundSelection() ) {
|
else if ( selection.isCompoundSelection() ) {
|
||||||
for ( Selection<?> compoundSelection : selection.getCompoundSelectionItems() ) {
|
for ( Selection<?> compoundSelection : selection.getCompoundSelectionItems() ) {
|
||||||
if ( selectionContains( compoundSelection, path ) ) {
|
if ( selectionContains( compoundSelection, path, tableGroupPath ) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( selection instanceof SqmDynamicInstantiation ) {
|
else if ( selection instanceof SqmDynamicInstantiation ) {
|
||||||
for ( SqmDynamicInstantiationArgument<?> argument : ( (SqmDynamicInstantiation<?>) selection ).getArguments() ) {
|
for ( SqmDynamicInstantiationArgument<?> argument : ( (SqmDynamicInstantiation<?>) selection ).getArguments() ) {
|
||||||
if ( selectionContains( argument.getSelectableNode(), path ) ) {
|
if ( selectionContains( argument.getSelectableNode(), path, tableGroupPath ) ) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7084,12 +7084,13 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
this.queryPartForRowNumberingClauseDepth = -1;
|
this.queryPartForRowNumberingClauseDepth = -1;
|
||||||
this.needsSelectAliases = false;
|
this.needsSelectAliases = false;
|
||||||
queryPartStack.push( subQuery );
|
queryPartStack.push( subQuery );
|
||||||
appendSql( "exists (select 1" );
|
appendSql( "exists (" );
|
||||||
visitFromClause( subQuery.getFromClause() );
|
|
||||||
|
|
||||||
if ( !subQuery.getGroupByClauseExpressions().isEmpty()
|
if ( !subQuery.getGroupByClauseExpressions().isEmpty()
|
||||||
|| subQuery.getHavingClauseRestrictions() != null ) {
|
|| subQuery.getHavingClauseRestrictions() != null ) {
|
||||||
// If we have a group by or having clause, we have to move the tuple comparison emulation to the HAVING clause
|
// If we have a group by or having clause, we have to move the tuple comparison emulation to the HAVING clause.
|
||||||
|
// Also, we need to explicitly include the selections to avoid 'invalid HAVING clause' errors
|
||||||
|
visitSelectClause( subQuery.getSelectClause() );
|
||||||
|
visitFromClause( subQuery.getFromClause() );
|
||||||
visitWhereClause( subQuery.getWhereClauseRestrictions() );
|
visitWhereClause( subQuery.getWhereClauseRestrictions() );
|
||||||
visitGroupByClause( subQuery, SelectItemReferenceStrategy.EXPRESSION );
|
visitGroupByClause( subQuery, SelectItemReferenceStrategy.EXPRESSION );
|
||||||
|
|
||||||
|
@ -7114,6 +7115,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If we have no group by or having clause, we can move the tuple comparison emulation to the WHERE clause
|
// If we have no group by or having clause, we can move the tuple comparison emulation to the WHERE clause
|
||||||
|
appendSql( "select 1" );
|
||||||
|
visitFromClause( subQuery.getFromClause() );
|
||||||
appendSql( " where " );
|
appendSql( " where " );
|
||||||
clauseStack.push( Clause.WHERE );
|
clauseStack.push( Clause.WHERE );
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue