HHH-16397 Allow fk optimization for correlated paths in subqueries

This commit is contained in:
Marco Belladelli 2023-04-26 16:37:25 +02:00
parent 37aec59ba9
commit ea87b4a2ab
No known key found for this signature in database
GPG Key ID: D1D0C3030AE3AA35
3 changed files with 7 additions and 27 deletions

View File

@ -2058,9 +2058,9 @@ public class ToOneAttributeMapping
} }
final TableGroupProducer tableGroupProducer; final TableGroupProducer tableGroupProducer;
if ( realParentTableGroup instanceof CorrelatedTableGroup ) { if ( requestedJoinType != null && realParentTableGroup instanceof CorrelatedTableGroup ) {
// If the parent is a correlated table group, we can't refer to columns of the table in the outer query, // If the parent is a correlated table group, and we're explicitly joining, we can't refer to columns of the
// because the context in which a column is used could be an aggregate function. // table in the outer query, because the context in which a column is used could be an aggregate function.
// Using a parent column in such a case would lead to an error if the parent query lacks a proper group by // Using a parent column in such a case would lead to an error if the parent query lacks a proper group by
tableGroupProducer = entityMappingType; tableGroupProducer = entityMappingType;
} }
@ -2105,7 +2105,7 @@ public class ToOneAttributeMapping
); );
} }
if ( realParentTableGroup instanceof CorrelatedTableGroup ) { if ( requestedJoinType != null && realParentTableGroup instanceof CorrelatedTableGroup ) {
// Force initialization of the underlying table group join to retain cardinality // Force initialization of the underlying table group join to retain cardinality
lazyTableGroup.getPrimaryTableReference(); lazyTableGroup.getPrimaryTableReference();
} }

View File

@ -208,13 +208,8 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
.findTableGroup( tableGroup.getNavigablePath().getParent() ); .findTableGroup( tableGroup.getNavigablePath().getParent() );
} }
else { else {
if ( isCorrelated( tableGroup, sqlAstCreationState ) if ( !tableGroup.getNavigablePath().isParentOrEqual( navigablePath ) ) {
|| !tableGroup.getNavigablePath().isParentOrEqual( navigablePath ) ) { // Force the use of the FK target key if the navigable path for this entity valued path is
// Access to the parent table group is forbidden for correlated table groups. For more details,
// see: `ToOneAttributeMapping.createRootTableGroupJoin`
// Due to that, we forcefully use the model part to which this association points to i.e. the target
// Also force the use of the FK target key if the navigable path for this entity valued path is
// not equal to or a child of the table group navigable path. // not equal to or a child of the table group navigable path.
// This can happen when using an implicit join path e.g. `where root.association.id is null`, // This can happen when using an implicit join path e.g. `where root.association.id is null`,
// yet also an explicit join was made which is compatible e.g. `join fetch root.association`. // yet also an explicit join was made which is compatible e.g. `join fetch root.association`.
@ -261,21 +256,6 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
); );
} }
private static boolean isCorrelated(TableGroup tableGroup, SqmToSqlAstConverter sqlAstCreationState) {
final SqlAstProcessingState processingState = sqlAstCreationState.getCurrentProcessingState();
if ( !( processingState instanceof SqlAstQueryPartProcessingState )
|| ( (SqlAstQueryPartProcessingState) processingState ).getInflightQueryPart().isRoot() ) {
return false;
}
final FromClauseAccess fromClauseAccess = sqlAstCreationState.getFromClauseAccess();
TableGroup realParentTableGroup = fromClauseAccess.findTableGroup( tableGroup.getNavigablePath().getParent() );
while ( realParentTableGroup.getModelPart() instanceof EmbeddableValuedModelPart ) {
realParentTableGroup = fromClauseAccess.findTableGroup( realParentTableGroup.getNavigablePath().getParent() );
}
return realParentTableGroup instanceof CorrelatedTableGroup;
}
private static boolean hasNotFound(EntityValuedModelPart mapping) { private static boolean hasNotFound(EntityValuedModelPart mapping) {
return mapping instanceof ToOneAttributeMapping && ( (ToOneAttributeMapping) mapping ).hasNotFoundAction(); return mapping instanceof ToOneAttributeMapping && ( (ToOneAttributeMapping) mapping ).hasNotFoundAction();
} }

View File

@ -5128,7 +5128,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
separator = renderFromClauseRoot( tableGroupJoin.getJoinedGroup(), separator ); separator = renderFromClauseRoot( tableGroupJoin.getJoinedGroup(), separator );
} }
} }
else { else if ( root.isInitialized() ) {
appendSql( separator ); appendSql( separator );
renderRootTableGroup( root, null ); renderRootTableGroup( root, null );
separator = COMA_SEPARATOR; separator = COMA_SEPARATOR;