Skip to content

Commit 4da2659

Browse files
committed
HHH-18378 Check where clause before reusing existing joins for fetch
1 parent 0272fc7 commit 4da2659

File tree

3 files changed

+45
-11
lines changed

3 files changed

+45
-11
lines changed

hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
import org.hibernate.query.sqm.tree.from.SqmJoin;
7575
import org.hibernate.query.sqm.tree.from.SqmQualifiedJoin;
7676
import org.hibernate.query.sqm.tree.from.SqmRoot;
77+
import org.hibernate.query.sqm.tree.predicate.SqmWhereClause;
7778
import org.hibernate.query.sqm.tree.select.SqmOrderByClause;
7879
import org.hibernate.query.sqm.tree.select.SqmQueryGroup;
7980
import org.hibernate.query.sqm.tree.select.SqmQueryPart;
@@ -105,6 +106,7 @@
105106

106107
import static java.util.stream.Collectors.toList;
107108
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
109+
import static org.hibernate.internal.util.collections.CollectionHelper.arrayList;
108110
import static org.hibernate.query.sqm.tree.jpa.ParameterCollector.collectParameters;
109111

110112
/**
@@ -232,6 +234,15 @@ public static boolean isFkOptimizationAllowed(SqmPath<?> sqmPath) {
232234
return false;
233235
}
234236

237+
public static List<NavigablePath> getWhereClauseNavigablePaths(SqmQuerySpec<?> querySpec) {
238+
final SqmWhereClause where = querySpec.getWhereClause();
239+
if ( where == null || where.getPredicate() == null ) {
240+
return Collections.emptyList();
241+
}
242+
243+
return collectNavigablePaths( List.of( where.getPredicate() ) );
244+
}
245+
235246
public static List<NavigablePath> getGroupByNavigablePaths(SqmQuerySpec<?> querySpec) {
236247
final List<SqmExpression<?>> expressions = querySpec.getGroupByClauseExpressions();
237248
if ( expressions.isEmpty() ) {
@@ -255,7 +266,7 @@ public static List<NavigablePath> getOrderByNavigablePaths(SqmQuerySpec<?> query
255266
}
256267

257268
private static List<NavigablePath> collectNavigablePaths(final List<SqmExpression<?>> expressions) {
258-
final List<NavigablePath> navigablePaths = new ArrayList<>( expressions.size() );
269+
final List<NavigablePath> navigablePaths = arrayList( expressions.size() );
259270
final SqmPathVisitor pathVisitor = new SqmPathVisitor( path -> navigablePaths.add( path.getNavigablePath() ) );
260271
for ( final SqmExpression<?> expression : expressions ) {
261272
if ( expression instanceof SqmAliasedNodeRef ) {

hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8406,7 +8406,10 @@ else if ( getLoadQueryInfluencers().hasEnabledFetchProfiles() ) {
84068406
joinProducer,
84078407
joinProducer.determineSqlJoinType( lhs, null, true )
84088408
);
8409-
if ( compatibleTableGroup == null ) {
8409+
final SqmQueryPart<?> queryPart = getCurrentSqmQueryPart();
8410+
if ( compatibleTableGroup == null
8411+
// If the compatible table group is used in the where clause it cannot be reused for fetching
8412+
|| ( queryPart != null && queryPart.getFirstQuerySpec().whereClauseContains( compatibleTableGroup.getNavigablePath(), this ) ) ) {
84108413
final TableGroupJoin tableGroupJoin = joinProducer.createTableGroupJoin(
84118414
fetchablePath,
84128415
lhs,

hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQuerySpec.java

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -629,15 +629,26 @@ public void appendHqlString(StringBuilder sb) {
629629
super.appendHqlString( sb );
630630
}
631631

632+
@Internal
633+
public boolean whereClauseContains(NavigablePath navigablePath, SqmToSqlAstConverter sqlAstConverter) {
634+
if ( whereClause == null ) {
635+
return false;
636+
}
637+
return isSameOrParent(
638+
navigablePath,
639+
sqlAstConverter.resolveMetadata( this, SqmUtil::getWhereClauseNavigablePaths )
640+
);
641+
}
642+
632643
@Internal
633644
public boolean groupByClauseContains(NavigablePath navigablePath, SqmToSqlAstConverter sqlAstConverter) {
634645
if ( groupByClauseExpressions.isEmpty() ) {
635646
return false;
636647
}
637-
return navigablePathsContain( sqlAstConverter.resolveMetadata(
638-
this,
639-
SqmUtil::getGroupByNavigablePaths
640-
), navigablePath );
648+
return isSameOrChildren(
649+
navigablePath,
650+
sqlAstConverter.resolveMetadata( this, SqmUtil::getGroupByNavigablePaths )
651+
);
641652
}
642653

643654
@Internal
@@ -646,18 +657,27 @@ public boolean orderByClauseContains(NavigablePath navigablePath, SqmToSqlAstCon
646657
if ( orderByClause == null || orderByClause.getSortSpecifications().isEmpty() ) {
647658
return false;
648659
}
649-
return navigablePathsContain( sqlAstConverter.resolveMetadata(
650-
this,
651-
SqmUtil::getOrderByNavigablePaths
652-
), navigablePath );
660+
return isSameOrChildren(
661+
navigablePath,
662+
sqlAstConverter.resolveMetadata( this, SqmUtil::getOrderByNavigablePaths )
663+
);
653664
}
654665

655-
private boolean navigablePathsContain(List<NavigablePath> navigablePaths, NavigablePath navigablePath) {
666+
private boolean isSameOrChildren(NavigablePath navigablePath, List<NavigablePath> navigablePaths) {
656667
for ( NavigablePath path : navigablePaths ) {
657668
if ( path.isParentOrEqual( navigablePath ) ) {
658669
return true;
659670
}
660671
}
661672
return false;
662673
}
674+
675+
private boolean isSameOrParent(NavigablePath navigablePath, List<NavigablePath> navigablePaths) {
676+
for ( NavigablePath path : navigablePaths ) {
677+
if ( navigablePath.isParentOrEqual( path ) ) {
678+
return true;
679+
}
680+
}
681+
return false;
682+
}
663683
}

0 commit comments

Comments
 (0)