Skip to content

Commit a956fda

Browse files
committed
HHH-17646 Optimize away real table group rendering if possible
1 parent 5fd74ad commit a956fda

File tree

42 files changed

+1489
-232
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1489
-232
lines changed

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ protected boolean supportsWithClauseInSubquery() {
7676
}
7777

7878
@Override
79-
protected void renderTableReferenceJoins(TableGroup tableGroup) {
79+
protected void renderTableReferenceJoins(TableGroup tableGroup, int swappedJoinIndex, boolean forceLeftJoin) {
8080
// When we are in a recursive CTE, we can't render joins on DB2...
8181
// See https://modern-sql.com/feature/with-recursive/db2/error-345-state-42836
8282
if ( isInRecursiveQueryPart() ) {
@@ -103,7 +103,7 @@ protected void renderTableReferenceJoins(TableGroup tableGroup) {
103103
}
104104
}
105105
else {
106-
super.renderTableReferenceJoins( tableGroup );
106+
super.renderTableReferenceJoins( tableGroup, swappedJoinIndex, forceLeftJoin );
107107
}
108108
}
109109

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacySqlAstTranslator.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -340,13 +340,9 @@ protected boolean renderPrimaryTableReference(TableGroup tableGroup, LockMode lo
340340
final TableReference tableRef = tableGroup.getPrimaryTableReference();
341341
// The H2 parser can't handle a sub-query as first element in a nested join
342342
// i.e. `join ( (select ...) alias join ... )`, so we have to introduce a dummy table reference
343-
if ( tableRef instanceof QueryPartTableReference || tableRef.getTableId().startsWith( "(select" ) ) {
344-
final boolean realTableGroup = tableGroup.isRealTableGroup()
345-
&& ( CollectionHelper.isNotEmpty( tableGroup.getTableReferenceJoins() )
346-
|| hasNestedTableGroupsToRender( tableGroup.getNestedTableGroupJoins() ) );
347-
if ( realTableGroup ) {
348-
appendSql( "dual cross join " );
349-
}
343+
if ( getSqlBuffer().charAt( getSqlBuffer().length() - 1 ) == '('
344+
&& ( tableRef instanceof QueryPartTableReference || tableRef.getTableId().startsWith( "(select" ) ) ) {
345+
appendSql( "dual cross join " );
350346
}
351347
return super.renderPrimaryTableReference( tableGroup, lockMode );
352348
}

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,14 @@
1212
import org.hibernate.engine.spi.SessionFactoryImplementor;
1313
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
1414
import org.hibernate.query.IllegalQueryOperationException;
15-
import org.hibernate.query.sqm.BinaryArithmeticOperator;
1615
import org.hibernate.query.sqm.ComparisonOperator;
1716
import org.hibernate.sql.ast.Clause;
1817
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
1918
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
2019
import org.hibernate.sql.ast.spi.SqlSelection;
21-
import org.hibernate.sql.ast.tree.MutationStatement;
2220
import org.hibernate.sql.ast.tree.Statement;
23-
import org.hibernate.sql.ast.tree.cte.CteStatement;
24-
import org.hibernate.sql.ast.tree.delete.DeleteStatement;
25-
import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
2621
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
2722
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
28-
import org.hibernate.sql.ast.tree.expression.ColumnReference;
2923
import org.hibernate.sql.ast.tree.expression.Expression;
3024
import org.hibernate.sql.ast.tree.expression.Literal;
3125
import org.hibernate.sql.ast.tree.expression.SqlTuple;
@@ -147,8 +141,7 @@ protected void visitRecursivePath(Expression recursivePath, int sizeEstimate) {
147141
protected void visitAnsiCaseSearchedExpression(
148142
CaseSearchedExpression expression,
149143
Consumer<Expression> resultRenderer) {
150-
if ( getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT && areAllResultsParameters( expression )
151-
|| areAllResultsPlainParametersOrLiterals( expression ) ) {
144+
if ( areAllResultsPlainParametersOrStringLiterals( expression ) ) {
152145
final List<CaseSearchedExpression.WhenFragment> whenFragments = expression.getWhenFragments();
153146
final Expression firstResult = whenFragments.get( 0 ).getResult();
154147
super.visitAnsiCaseSearchedExpression(
@@ -172,8 +165,7 @@ protected void visitAnsiCaseSearchedExpression(
172165
protected void visitAnsiCaseSimpleExpression(
173166
CaseSimpleExpression expression,
174167
Consumer<Expression> resultRenderer) {
175-
if ( getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT && areAllResultsParameters( expression )
176-
|| areAllResultsPlainParametersOrLiterals( expression ) ) {
168+
if ( areAllResultsPlainParametersOrStringLiterals( expression ) ) {
177169
final List<CaseSimpleExpression.WhenFragment> whenFragments = expression.getWhenFragments();
178170
final Expression firstResult = whenFragments.get( 0 ).getResult();
179171
super.visitAnsiCaseSimpleExpression(
@@ -193,19 +185,19 @@ protected void visitAnsiCaseSimpleExpression(
193185
}
194186
}
195187

196-
protected boolean areAllResultsPlainParametersOrLiterals(CaseSearchedExpression caseSearchedExpression) {
188+
protected boolean areAllResultsPlainParametersOrStringLiterals(CaseSearchedExpression caseSearchedExpression) {
197189
final List<CaseSearchedExpression.WhenFragment> whenFragments = caseSearchedExpression.getWhenFragments();
198190
final Expression firstResult = whenFragments.get( 0 ).getResult();
199191
if ( isParameter( firstResult ) && getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT
200-
|| isLiteral( firstResult ) ) {
192+
|| isStringLiteral( firstResult ) ) {
201193
for ( int i = 1; i < whenFragments.size(); i++ ) {
202194
final Expression result = whenFragments.get( i ).getResult();
203195
if ( isParameter( result ) ) {
204196
if ( getParameterRenderingMode() != SqlAstNodeRenderingMode.DEFAULT ) {
205197
return false;
206198
}
207199
}
208-
else if ( !isLiteral( result ) ) {
200+
else if ( !isStringLiteral( result ) ) {
209201
return false;
210202
}
211203
}
@@ -214,19 +206,19 @@ else if ( !isLiteral( result ) ) {
214206
return false;
215207
}
216208

217-
protected boolean areAllResultsPlainParametersOrLiterals(CaseSimpleExpression caseSimpleExpression) {
209+
protected boolean areAllResultsPlainParametersOrStringLiterals(CaseSimpleExpression caseSimpleExpression) {
218210
final List<CaseSimpleExpression.WhenFragment> whenFragments = caseSimpleExpression.getWhenFragments();
219211
final Expression firstResult = whenFragments.get( 0 ).getResult();
220212
if ( isParameter( firstResult ) && getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT
221-
|| isLiteral( firstResult ) ) {
213+
|| isStringLiteral( firstResult ) ) {
222214
for ( int i = 1; i < whenFragments.size(); i++ ) {
223215
final Expression result = whenFragments.get( i ).getResult();
224216
if ( isParameter( result ) ) {
225217
if ( getParameterRenderingMode() != SqlAstNodeRenderingMode.DEFAULT ) {
226218
return false;
227219
}
228220
}
229-
else if ( !isLiteral( result ) ) {
221+
else if ( !isStringLiteral( result ) ) {
230222
return false;
231223
}
232224
}
@@ -235,6 +227,13 @@ else if ( !isLiteral( result ) ) {
235227
return false;
236228
}
237229

230+
private boolean isStringLiteral( Expression expression ) {
231+
if ( expression instanceof Literal ) {
232+
return ( (Literal) expression ).getJdbcMapping().getJdbcType().isStringLike();
233+
}
234+
return false;
235+
}
236+
238237
@Override
239238
public boolean supportsFilterClause() {
240239
return true;

hibernate-core/src/main/java/org/hibernate/dialect/DB2SqlAstTranslator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ protected boolean supportsWithClauseInSubquery() {
7575
}
7676

7777
@Override
78-
protected void renderTableReferenceJoins(TableGroup tableGroup) {
78+
protected void renderTableReferenceJoins(TableGroup tableGroup, int swappedJoinIndex, boolean forceLeftJoin) {
7979
// When we are in a recursive CTE, we can't render joins on DB2...
8080
// See https://modern-sql.com/feature/with-recursive/db2/error-345-state-42836
8181
if ( isInRecursiveQueryPart() ) {
@@ -102,7 +102,7 @@ protected void renderTableReferenceJoins(TableGroup tableGroup) {
102102
}
103103
}
104104
else {
105-
super.renderTableReferenceJoins( tableGroup );
105+
super.renderTableReferenceJoins( tableGroup, swappedJoinIndex, forceLeftJoin );
106106
}
107107
}
108108

hibernate-core/src/main/java/org/hibernate/dialect/H2SqlAstTranslator.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -314,13 +314,9 @@ protected boolean renderPrimaryTableReference(TableGroup tableGroup, LockMode lo
314314
final TableReference tableRef = tableGroup.getPrimaryTableReference();
315315
// The H2 parser can't handle a sub-query as first element in a nested join
316316
// i.e. `join ( (select ...) alias join ... )`, so we have to introduce a dummy table reference
317-
if ( tableRef instanceof QueryPartTableReference || tableRef.getTableId().startsWith( "(select" ) ) {
318-
final boolean realTableGroup = tableGroup.isRealTableGroup()
319-
&& ( isNotEmpty( tableGroup.getTableReferenceJoins() )
320-
|| hasNestedTableGroupsToRender( tableGroup.getNestedTableGroupJoins() ) );
321-
if ( realTableGroup ) {
322-
appendSql( "dual cross join " );
323-
}
317+
if ( getSqlBuffer().charAt( getSqlBuffer().length() - 1 ) == '('
318+
&& ( tableRef instanceof QueryPartTableReference || tableRef.getTableId().startsWith( "(select" ) ) ) {
319+
appendSql( "dual cross join " );
324320
}
325321
return super.renderPrimaryTableReference( tableGroup, lockMode );
326322
}

hibernate-core/src/main/java/org/hibernate/dialect/HSQLSqlAstTranslator.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@
1212
import org.hibernate.engine.spi.SessionFactoryImplementor;
1313
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
1414
import org.hibernate.query.IllegalQueryOperationException;
15-
import org.hibernate.query.sqm.BinaryArithmeticOperator;
1615
import org.hibernate.query.sqm.ComparisonOperator;
1716
import org.hibernate.sql.ast.Clause;
1817
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
1918
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
2019
import org.hibernate.sql.ast.spi.SqlSelection;
2120
import org.hibernate.sql.ast.tree.Statement;
22-
import org.hibernate.sql.ast.tree.expression.BinaryArithmeticExpression;
2321
import org.hibernate.sql.ast.tree.expression.CaseSearchedExpression;
2422
import org.hibernate.sql.ast.tree.expression.CaseSimpleExpression;
2523
import org.hibernate.sql.ast.tree.expression.Expression;
@@ -152,8 +150,7 @@ protected void visitRecursivePath(Expression recursivePath, int sizeEstimate) {
152150
protected void visitAnsiCaseSearchedExpression(
153151
CaseSearchedExpression expression,
154152
Consumer<Expression> resultRenderer) {
155-
if ( getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT && areAllResultsParameters( expression )
156-
|| areAllResultsPlainParametersOrLiterals( expression ) ) {
153+
if ( areAllResultsPlainParametersOrStringLiterals( expression ) ) {
157154
final List<CaseSearchedExpression.WhenFragment> whenFragments = expression.getWhenFragments();
158155
final Expression firstResult = whenFragments.get( 0 ).getResult();
159156
super.visitAnsiCaseSearchedExpression(
@@ -177,8 +174,7 @@ protected void visitAnsiCaseSearchedExpression(
177174
protected void visitAnsiCaseSimpleExpression(
178175
CaseSimpleExpression expression,
179176
Consumer<Expression> resultRenderer) {
180-
if ( getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT && areAllResultsParameters( expression )
181-
|| areAllResultsPlainParametersOrLiterals( expression ) ) {
177+
if ( areAllResultsPlainParametersOrStringLiterals( expression ) ) {
182178
final List<CaseSimpleExpression.WhenFragment> whenFragments = expression.getWhenFragments();
183179
final Expression firstResult = whenFragments.get( 0 ).getResult();
184180
super.visitAnsiCaseSimpleExpression(
@@ -198,19 +194,19 @@ protected void visitAnsiCaseSimpleExpression(
198194
}
199195
}
200196

201-
protected boolean areAllResultsPlainParametersOrLiterals(CaseSearchedExpression caseSearchedExpression) {
197+
protected boolean areAllResultsPlainParametersOrStringLiterals(CaseSearchedExpression caseSearchedExpression) {
202198
final List<CaseSearchedExpression.WhenFragment> whenFragments = caseSearchedExpression.getWhenFragments();
203199
final Expression firstResult = whenFragments.get( 0 ).getResult();
204200
if ( isParameter( firstResult ) && getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT
205-
|| isLiteral( firstResult ) ) {
201+
|| isStringLiteral( firstResult ) ) {
206202
for ( int i = 1; i < whenFragments.size(); i++ ) {
207203
final Expression result = whenFragments.get( i ).getResult();
208204
if ( isParameter( result ) ) {
209205
if ( getParameterRenderingMode() != SqlAstNodeRenderingMode.DEFAULT ) {
210206
return false;
211207
}
212208
}
213-
else if ( !isLiteral( result ) ) {
209+
else if ( !isStringLiteral( result ) ) {
214210
return false;
215211
}
216212
}
@@ -219,19 +215,19 @@ else if ( !isLiteral( result ) ) {
219215
return false;
220216
}
221217

222-
protected boolean areAllResultsPlainParametersOrLiterals(CaseSimpleExpression caseSimpleExpression) {
218+
protected boolean areAllResultsPlainParametersOrStringLiterals(CaseSimpleExpression caseSimpleExpression) {
223219
final List<CaseSimpleExpression.WhenFragment> whenFragments = caseSimpleExpression.getWhenFragments();
224220
final Expression firstResult = whenFragments.get( 0 ).getResult();
225221
if ( isParameter( firstResult ) && getParameterRenderingMode() == SqlAstNodeRenderingMode.DEFAULT
226-
|| isLiteral( firstResult ) ) {
222+
|| isStringLiteral( firstResult ) ) {
227223
for ( int i = 1; i < whenFragments.size(); i++ ) {
228224
final Expression result = whenFragments.get( i ).getResult();
229225
if ( isParameter( result ) ) {
230226
if ( getParameterRenderingMode() != SqlAstNodeRenderingMode.DEFAULT ) {
231227
return false;
232228
}
233229
}
234-
else if ( !isLiteral( result ) ) {
230+
else if ( !isStringLiteral( result ) ) {
235231
return false;
236232
}
237233
}
@@ -240,6 +236,13 @@ else if ( !isLiteral( result ) ) {
240236
return false;
241237
}
242238

239+
private boolean isStringLiteral( Expression expression ) {
240+
if ( expression instanceof Literal ) {
241+
return ( (Literal) expression ).getJdbcMapping().getJdbcType().isStringLike();
242+
}
243+
return false;
244+
}
245+
243246
@Override
244247
public boolean supportsFilterClause() {
245248
return true;

hibernate-core/src/main/java/org/hibernate/metamodel/internal/AbstractCompositeIdentifierMapping.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableFetchImpl;
4949
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableResultImpl;
5050

51+
import org.checkerframework.checker.nullness.qual.Nullable;
52+
5153
/**
5254
* Base implementation for composite identifier mappings
5355
*
@@ -129,9 +131,9 @@ public Fetch generateFetch(
129131
public TableGroupJoin createTableGroupJoin(
130132
NavigablePath navigablePath,
131133
TableGroup lhs,
132-
String explicitSourceAlias,
133-
SqlAliasBase explicitSqlAliasBase,
134-
SqlAstJoinType requestedJoinType,
134+
@Nullable String explicitSourceAlias,
135+
@Nullable SqlAliasBase explicitSqlAliasBase,
136+
@Nullable SqlAstJoinType requestedJoinType,
135137
boolean fetched,
136138
boolean addsPredicate,
137139
SqlAstCreationState creationState) {
@@ -154,11 +156,11 @@ public TableGroupJoin createTableGroupJoin(
154156
public TableGroup createRootTableGroupJoin(
155157
NavigablePath navigablePath,
156158
TableGroup lhs,
157-
String explicitSourceAlias,
158-
SqlAliasBase explicitSqlAliasBase,
159-
SqlAstJoinType sqlAstJoinType,
159+
@Nullable String explicitSourceAlias,
160+
@Nullable SqlAliasBase explicitSqlAliasBase,
161+
@Nullable SqlAstJoinType sqlAstJoinType,
160162
boolean fetched,
161-
Consumer<Predicate> predicateConsumer,
163+
@Nullable Consumer<Predicate> predicateConsumer,
162164
SqlAstCreationState creationState) {
163165
return new StandardVirtualTableGroup( navigablePath, this, lhs, fetched );
164166
}

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,14 @@ default void pruneForSubclasses(TableGroup tableGroup, Map<String, EntityNameUse
292292
*/
293293
EntityIdentifierMapping getIdentifierMapping();
294294

295+
/**
296+
* Mapping details for the entity's identifier. This is shared across all
297+
* entity mappings within an inheritance hierarchy.
298+
*/
299+
default EntityIdentifierMapping getIdentifierMappingForJoin() {
300+
return getIdentifierMapping();
301+
}
302+
295303
/**
296304
* Mapping details for the entity's discriminator. This is shared across all
297305
* entity mappings within an inheritance hierarchy.

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CaseStatementDiscriminatorMappingImpl.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
*/
77
package org.hibernate.metamodel.mapping.internal;
88

9+
import java.util.ArrayList;
910
import java.util.LinkedHashMap;
11+
import java.util.List;
1012

1113
import org.hibernate.engine.FetchTiming;
1214
import org.hibernate.engine.spi.SessionFactoryImplementor;
@@ -255,6 +257,24 @@ public CaseStatementDiscriminatorExpression(TableGroup entityTableGroup) {
255257
this.entityTableGroup = entityTableGroup;
256258
}
257259

260+
public List<TableReference> getUsedTableReferences() {
261+
final ArrayList<TableReference> usedTableReferences = new ArrayList<>( tableDiscriminatorDetailsMap.size() );
262+
tableDiscriminatorDetailsMap.forEach(
263+
(tableName, tableDiscriminatorDetails) -> {
264+
final TableReference tableReference = entityTableGroup.getTableReference(
265+
entityTableGroup.getNavigablePath(),
266+
tableName,
267+
false
268+
);
269+
270+
if ( tableReference != null ) {
271+
usedTableReferences.add( tableReference );
272+
}
273+
}
274+
);
275+
return usedTableReferences;
276+
}
277+
258278
@Override
259279
public void renderToSql(
260280
SqlAppender sqlAppender,

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/DiscriminatedAssociationAttributeMapping.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
import org.hibernate.type.descriptor.java.JavaType;
5353
import org.hibernate.type.descriptor.java.MutabilityPlan;
5454

55+
import org.checkerframework.checker.nullness.qual.Nullable;
56+
5557
/**
5658
* Singular, any-valued attribute
5759
*
@@ -487,9 +489,9 @@ public Object assemble(Serializable cached, SharedSessionContract session) {
487489
public TableGroupJoin createTableGroupJoin(
488490
NavigablePath navigablePath,
489491
TableGroup lhs,
490-
String explicitSourceAlias,
491-
SqlAliasBase explicitSqlAliasBase,
492-
SqlAstJoinType requestedJoinType,
492+
@Nullable String explicitSourceAlias,
493+
@Nullable SqlAliasBase explicitSqlAliasBase,
494+
@Nullable SqlAstJoinType requestedJoinType,
493495
boolean fetched,
494496
boolean addsPredicate,
495497
SqlAstCreationState creationState) {
@@ -512,11 +514,11 @@ public TableGroupJoin createTableGroupJoin(
512514
public TableGroup createRootTableGroupJoin(
513515
NavigablePath navigablePath,
514516
TableGroup lhs,
515-
String explicitSourceAlias,
516-
SqlAliasBase explicitSqlAliasBase,
517-
SqlAstJoinType sqlAstJoinType,
517+
@Nullable String explicitSourceAlias,
518+
@Nullable SqlAliasBase explicitSqlAliasBase,
519+
@Nullable SqlAstJoinType sqlAstJoinType,
518520
boolean fetched,
519-
Consumer<Predicate> predicateConsumer,
521+
@Nullable Consumer<Predicate> predicateConsumer,
520522
SqlAstCreationState creationState) {
521523
return new StandardVirtualTableGroup( navigablePath, this, lhs, fetched );
522524
}

0 commit comments

Comments
 (0)