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 3fe9ac9e32
commit e60d2c878b
3 changed files with 7 additions and 27 deletions

View File

@ -2058,9 +2058,9 @@ public class ToOneAttributeMapping
}
final TableGroupProducer tableGroupProducer;
if ( realParentTableGroup instanceof CorrelatedTableGroup ) {
// If the parent is a correlated table group, we can't refer to columns of the table in the outer query,
// because the context in which a column is used could be an aggregate function.
if ( requestedJoinType != null && realParentTableGroup instanceof CorrelatedTableGroup ) {
// If the parent is a correlated table group, and we're explicitly joining, we can't refer to columns of the
// 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
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
lazyTableGroup.getPrimaryTableReference();
}

View File

@ -208,13 +208,8 @@ public class EntityValuedPathInterpretation<T> extends AbstractSqmPathInterpreta
.findTableGroup( tableGroup.getNavigablePath().getParent() );
}
else {
if ( isCorrelated( tableGroup, sqlAstCreationState )
|| !tableGroup.getNavigablePath().isParentOrEqual( navigablePath ) ) {
// 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
if ( !tableGroup.getNavigablePath().isParentOrEqual( navigablePath ) ) {
// 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.
// 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`.
@ -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) {
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 );
}
}
else {
else if ( root.isInitialized() ) {
appendSql( separator );
renderRootTableGroup( root, null );
separator = COMA_SEPARATOR;