From 68bd6c77f696c00ab74f5a80e6e31ad8c38f9c6e Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Fri, 11 Apr 2025 17:03:12 +0200 Subject: [PATCH] HHH-17002 Query plan caching for CriteriaQuery based on query structure --- .../SessionFactoryOptionsBuilder.java | 7 +++ ...stractDelegatingSessionFactoryOptions.java | 5 ++ .../boot/spi/SessionFactoryOptions.java | 6 +++ .../java/org/hibernate/cfg/QuerySettings.java | 15 ++++++ .../engine/spi/SessionDelegatorBaseImpl.java | 10 ++++ .../spi/SharedSessionContractImplementor.java | 4 ++ .../spi/SharedSessionDelegatorBaseImpl.java | 10 ++++ .../AbstractSharedSessionContract.java | 12 +++++ .../FullyQualifiedReflectivePathTerminal.java | 3 +- .../query/sqm/DiscriminatorSqmPath.java | 5 +- .../SelfRenderingSqmAggregateFunction.java | 11 ++-- ...nderingSqmOrderedSetAggregateFunction.java | 15 +++--- .../SelfRenderingSqmWindowFunction.java | 11 ++-- .../query/sqm/internal/QuerySqmImpl.java | 20 +++++++ .../sqm/internal/SimpleSqmRenderContext.java | 36 +++++++++++++ .../sqm/internal/SqmInterpretationsKey.java | 6 +-- .../sqm/internal/SqmSelectionQueryImpl.java | 27 ++++++++++ .../sqm/tree/AbstractSqmDmlStatement.java | 4 +- .../AbstractSqmRestrictedDmlStatement.java | 4 +- .../query/sqm/tree/SqmRenderContext.java | 32 ++++++++++++ .../query/sqm/tree/SqmVisitableNode.java | 4 +- .../query/sqm/tree/cte/SqmCteStatement.java | 11 ++-- .../sqm/tree/delete/SqmDeleteStatement.java | 13 ++--- .../sqm/tree/domain/AbstractSqmFrom.java | 11 ++-- .../tree/domain/AbstractSqmSimplePath.java | 5 +- .../domain/SqmElementAggregateFunction.java | 5 +- .../sqm/tree/domain/SqmFkExpression.java | 5 +- .../sqm/tree/domain/SqmFunctionPath.java | 5 +- .../domain/SqmIndexAggregateFunction.java | 5 +- .../SqmIndexedCollectionAccessPath.java | 7 +-- .../sqm/tree/domain/SqmMapEntryReference.java | 5 +- .../query/sqm/tree/domain/SqmPath.java | 13 ----- .../sqm/tree/domain/SqmTreatedBagJoin.java | 5 +- .../sqm/tree/domain/SqmTreatedCrossJoin.java | 5 +- .../SqmTreatedEmbeddedValuedSimplePath.java | 5 +- .../sqm/tree/domain/SqmTreatedEntityJoin.java | 5 +- .../SqmTreatedEntityValuedSimplePath.java | 5 +- .../sqm/tree/domain/SqmTreatedListJoin.java | 5 +- .../sqm/tree/domain/SqmTreatedMapJoin.java | 5 +- .../tree/domain/SqmTreatedPluralPartJoin.java | 5 +- .../query/sqm/tree/domain/SqmTreatedRoot.java | 5 +- .../sqm/tree/domain/SqmTreatedSetJoin.java | 5 +- .../sqm/tree/domain/SqmTreatedSimplePath.java | 5 +- .../tree/domain/SqmTreatedSingularJoin.java | 5 +- .../AbstractSqmJsonPathExpression.java | 5 +- .../expression/AsWrapperSqmExpression.java | 5 +- .../tree/expression/JpaCriteriaParameter.java | 10 +++- .../tree/expression/SqmAliasedNodeRef.java | 3 +- .../query/sqm/tree/expression/SqmAny.java | 5 +- .../expression/SqmAnyDiscriminatorValue.java | 3 +- .../tree/expression/SqmBinaryArithmetic.java | 7 +-- .../query/sqm/tree/expression/SqmByUnit.java | 5 +- .../sqm/tree/expression/SqmCaseSearched.java | 9 ++-- .../sqm/tree/expression/SqmCaseSimple.java | 11 ++-- .../sqm/tree/expression/SqmCastTarget.java | 3 +- .../sqm/tree/expression/SqmCoalesce.java | 7 +-- .../sqm/tree/expression/SqmCollation.java | 3 +- .../tree/expression/SqmCollectionSize.java | 5 +- .../sqm/tree/expression/SqmDistinct.java | 5 +- .../sqm/tree/expression/SqmDurationUnit.java | 3 +- .../sqm/tree/expression/SqmEnumLiteral.java | 3 +- .../query/sqm/tree/expression/SqmEvery.java | 5 +- .../sqm/tree/expression/SqmExtractUnit.java | 3 +- .../sqm/tree/expression/SqmFieldLiteral.java | 3 +- .../query/sqm/tree/expression/SqmFormat.java | 3 +- .../sqm/tree/expression/SqmFunction.java | 47 +++++++++-------- .../tree/expression/SqmHqlNumericLiteral.java | 5 +- .../SqmJpaCriteriaParameterWrapper.java | 5 +- .../expression/SqmJsonExistsExpression.java | 9 ++-- .../tree/expression/SqmJsonNullBehavior.java | 3 +- .../SqmJsonObjectAggUniqueKeysBehavior.java | 3 +- .../expression/SqmJsonQueryExpression.java | 9 ++-- .../tree/expression/SqmJsonTableFunction.java | 29 ++++++----- .../expression/SqmJsonValueExpression.java | 15 +++--- .../query/sqm/tree/expression/SqmLiteral.java | 21 +++++--- .../expression/SqmLiteralEmbeddableType.java | 3 +- .../tree/expression/SqmLiteralEntityType.java | 3 +- .../sqm/tree/expression/SqmLiteralNull.java | 3 +- .../SqmModifiedSubQueryExpression.java | 5 +- .../tree/expression/SqmNamedExpression.java | 5 +- .../tree/expression/SqmNamedParameter.java | 3 +- .../query/sqm/tree/expression/SqmOver.java | 7 +-- .../sqm/tree/expression/SqmOverflow.java | 7 +-- .../SqmParameterizedEntityType.java | 5 +- .../expression/SqmPositionalParameter.java | 3 +- .../SqmSelfRenderingExpression.java | 3 +- .../expression/SqmSetReturningFunction.java | 7 +-- .../query/sqm/tree/expression/SqmStar.java | 3 +- .../sqm/tree/expression/SqmSummarization.java | 7 +-- .../sqm/tree/expression/SqmToDuration.java | 5 +- .../tree/expression/SqmTrimSpecification.java | 3 +- .../query/sqm/tree/expression/SqmTuple.java | 7 +-- .../tree/expression/SqmUnaryOperation.java | 5 +- .../query/sqm/tree/expression/SqmWindow.java | 23 ++++---- .../SqmXmlAttributesExpression.java | 5 +- .../expression/SqmXmlElementExpression.java | 7 +-- .../tree/expression/SqmXmlTableFunction.java | 27 +++++----- .../ValueBindJpaCriteriaParameter.java | 7 +-- .../query/sqm/tree/from/SqmFrom.java | 8 +++ .../query/sqm/tree/from/SqmFromClause.java | 52 ++++++++++--------- .../insert/AbstractSqmInsertStatement.java | 9 ++-- .../sqm/tree/insert/SqmConflictClause.java | 5 +- .../tree/insert/SqmConflictUpdateAction.java | 7 +-- .../tree/insert/SqmInsertSelectStatement.java | 11 ++-- .../tree/insert/SqmInsertValuesStatement.java | 17 +++--- .../tree/predicate/SqmBetweenPredicate.java | 9 ++-- .../SqmBooleanExpressionPredicate.java | 5 +- .../predicate/SqmComparisonPredicate.java | 7 +-- .../tree/predicate/SqmEmptinessPredicate.java | 5 +- .../tree/predicate/SqmExistsPredicate.java | 5 +- .../tree/predicate/SqmGroupedPredicate.java | 5 +- .../tree/predicate/SqmInListPredicate.java | 9 ++-- .../predicate/SqmInSubQueryPredicate.java | 7 +-- .../tree/predicate/SqmJunctionPredicate.java | 15 +++--- .../sqm/tree/predicate/SqmLikePredicate.java | 9 ++-- .../tree/predicate/SqmMemberOfPredicate.java | 7 +-- .../tree/predicate/SqmNegatedPredicate.java | 5 +- .../tree/predicate/SqmNullnessPredicate.java | 5 +- .../tree/predicate/SqmTruthnessPredicate.java | 5 +- .../tree/select/AbstractSqmSelectQuery.java | 7 +-- .../tree/select/SqmDynamicInstantiation.java | 7 +-- .../SqmDynamicInstantiationArgument.java | 5 +- .../tree/select/SqmJpaCompoundSelection.java | 7 +-- .../query/sqm/tree/select/SqmQueryGroup.java | 13 ++--- .../query/sqm/tree/select/SqmQueryPart.java | 11 ++-- .../query/sqm/tree/select/SqmQuerySpec.java | 19 +++---- .../query/sqm/tree/select/SqmSelection.java | 5 +- .../sqm/tree/select/SqmSortSpecification.java | 5 +- .../query/sqm/tree/select/SqmSubQuery.java | 5 +- .../query/sqm/tree/update/SqmSetClause.java | 13 ++--- .../sqm/tree/update/SqmUpdateStatement.java | 15 +++--- .../test/query/hql/QueryPlanCachingTest.java | 23 ++++++++ 132 files changed, 730 insertions(+), 409 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleSqmRenderContext.java create mode 100644 hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmRenderContext.java diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java index e4f5f6164c97..e1467bde05c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java @@ -230,6 +230,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions { private TimeZone jdbcTimeZone; private final ValueHandlingMode criteriaValueHandlingMode; private final boolean criteriaCopyTreeEnabled; + private final boolean criteriaPlanCacheEnabled; private final boolean nativeJdbcParametersIgnored; private final ImmutableEntityUpdateQueryHandlingMode immutableEntityUpdateQueryHandlingMode; // These two settings cannot be modified from the builder, @@ -488,6 +489,7 @@ public SessionFactoryOptionsBuilder(StandardServiceRegistry serviceRegistry, Boo criteriaValueHandlingMode = ValueHandlingMode.interpret( settings.get( CRITERIA_VALUE_HANDLING_MODE ) ); criteriaCopyTreeEnabled = getBoolean( AvailableSettings.CRITERIA_COPY_TREE, settings, jpaBootstrap ); + criteriaPlanCacheEnabled = getBoolean( AvailableSettings.CRITERIA_PLAN_CACHE_ENABLED, settings, false ); nativeJdbcParametersIgnored = getBoolean( AvailableSettings.NATIVE_IGNORE_JDBC_PARAMETERS, settings, false ); @@ -1126,6 +1128,11 @@ public boolean isCriteriaCopyTreeEnabled() { return criteriaCopyTreeEnabled; } + @Override + public boolean isCriteriaPlanCacheEnabled() { + return criteriaPlanCacheEnabled; + } + @Override public boolean getNativeJdbcParametersIgnored() { return nativeJdbcParametersIgnored; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java index 81c203d221e5..84b3c12a978d 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java @@ -394,6 +394,11 @@ public boolean isCriteriaCopyTreeEnabled() { return delegate.isCriteriaCopyTreeEnabled(); } + @Override + public boolean isCriteriaPlanCacheEnabled() { + return delegate.isCriteriaPlanCacheEnabled(); + } + public boolean getNativeJdbcParametersIgnored() { return delegate.getNativeJdbcParametersIgnored(); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java index e40fd34beead..4b95b792322b 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java @@ -393,6 +393,12 @@ default ValueHandlingMode getCriteriaValueHandlingMode() { default boolean isCriteriaCopyTreeEnabled() { return false; } + /** + * @see org.hibernate.cfg.AvailableSettings#CRITERIA_PLAN_CACHE_ENABLED + */ + default boolean isCriteriaPlanCacheEnabled() { + return false; + } /** * @see org.hibernate.cfg.AvailableSettings#NATIVE_IGNORE_JDBC_PARAMETERS diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/QuerySettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/QuerySettings.java index ecbbdebe71da..1b9189ef877f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/QuerySettings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/QuerySettings.java @@ -156,6 +156,21 @@ public interface QuerySettings { */ String CRITERIA_COPY_TREE = "hibernate.criteria.copy_tree"; + /** + * When enabled, specifies that {@linkplain org.hibernate.query.Query queries} + * created via {@link jakarta.persistence.EntityManager#createQuery(CriteriaQuery)}, + * {@link jakarta.persistence.EntityManager#createQuery(CriteriaUpdate)} or + * {@link jakarta.persistence.EntityManager#createQuery(CriteriaDelete)} cache + * their interpretations in the query plan cache. + *

+ * If disabled, queries are interpreted on first access without caching. + * + * @settingDefault {@code false} (disabled) - criteria queries do not use query plan caching. + * + * @since 7.0 + */ + String CRITERIA_PLAN_CACHE_ENABLED = "hibernate.criteria.plan_cache_enabled"; + /** * When enabled, ordinal parameters (represented by the {@code ?} placeholder) in * native queries will be ignored. diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java index fe44d888a12a..f07aa5e17e57 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java @@ -248,6 +248,16 @@ public boolean isCriteriaCopyTreeEnabled() { return delegate.isCriteriaCopyTreeEnabled(); } + @Override + public boolean isCriteriaPlanCacheEnabled() { + return delegate.isCriteriaPlanCacheEnabled(); + } + + @Override + public void setCriteriaPlanCacheEnabled(boolean jpaCriteriaCacheEnabled) { + delegate.setCriteriaPlanCacheEnabled( jpaCriteriaCacheEnabled ); + } + @Override public boolean getNativeJdbcParametersIgnored() { return delegate.getNativeJdbcParametersIgnored(); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java index b58a56c7842a..98411c51f3c0 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java @@ -381,6 +381,10 @@ default String bestGuessEntityName(Object object, EntityEntry entry) { boolean isCriteriaCopyTreeEnabled(); + void setCriteriaPlanCacheEnabled(boolean jpaCriteriaCacheEnabled); + + boolean isCriteriaPlanCacheEnabled(); + boolean getNativeJdbcParametersIgnored(); void setNativeJdbcParametersIgnored(boolean nativeJdbcParametersIgnored); diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionDelegatorBaseImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionDelegatorBaseImpl.java index 920ff90b6a77..a4db0e69012c 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionDelegatorBaseImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionDelegatorBaseImpl.java @@ -498,6 +498,16 @@ public boolean isCriteriaCopyTreeEnabled() { return delegate.isCriteriaCopyTreeEnabled(); } + @Override + public boolean isCriteriaPlanCacheEnabled() { + return delegate.isCriteriaPlanCacheEnabled(); + } + + @Override + public void setCriteriaPlanCacheEnabled(boolean jpaCriteriaCacheEnabled) { + delegate.setCriteriaPlanCacheEnabled( jpaCriteriaCacheEnabled ); + } + @Override public boolean getNativeJdbcParametersIgnored() { return delegate.getNativeJdbcParametersIgnored(); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java index ea3479b4dbad..ead2e369e25e 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java @@ -167,6 +167,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont private Integer jdbcBatchSize; private boolean criteriaCopyTreeEnabled; + private boolean criteriaPlanCacheEnabled; private boolean nativeJdbcParametersIgnored; @@ -194,6 +195,7 @@ public AbstractSharedSessionContract(SessionFactoryImpl factory, SessionCreation entityNameResolver = new CoordinatingEntityNameResolver( factory, interceptor ); setCriteriaCopyTreeEnabled( factoryOptions.isCriteriaCopyTreeEnabled() ); + setCriteriaPlanCacheEnabled( factoryOptions.isCriteriaPlanCacheEnabled() ); setNativeJdbcParametersIgnored( factoryOptions.getNativeJdbcParametersIgnored() ); setCacheMode( factoryOptions.getInitialSessionCacheMode() ); @@ -803,6 +805,16 @@ public boolean isCriteriaCopyTreeEnabled() { return criteriaCopyTreeEnabled; } + @Override + public boolean isCriteriaPlanCacheEnabled() { + return criteriaPlanCacheEnabled; + } + + @Override + public void setCriteriaPlanCacheEnabled(boolean criteriaPlanCacheEnabled) { + this.criteriaPlanCacheEnabled = criteriaPlanCacheEnabled; + } + @Override public boolean getNativeJdbcParametersIgnored() { return nativeJdbcParametersIgnored; diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/FullyQualifiedReflectivePathTerminal.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/FullyQualifiedReflectivePathTerminal.java index 657a914018a2..c28c863b0004 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/FullyQualifiedReflectivePathTerminal.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/FullyQualifiedReflectivePathTerminal.java @@ -21,6 +21,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.spi.SqmCreationContext; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmEnumLiteral; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.expression.SqmFieldLiteral; @@ -156,7 +157,7 @@ public void applyInferableType(@Nullable SqmExpressible type) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( getParent().getFullPath() ); hql.append( '.' ); hql.append( getLocalName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/DiscriminatorSqmPath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/DiscriminatorSqmPath.java index 048bbb0a9845..004bf16c8828 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/DiscriminatorSqmPath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/DiscriminatorSqmPath.java @@ -8,6 +8,7 @@ import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.query.PathException; import org.hibernate.query.hql.spi.SqmCreationState; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmTreatedPath; @@ -18,9 +19,9 @@ */ public interface DiscriminatorSqmPath extends SqmPath { @Override - default void appendHqlString(StringBuilder hql) { + default void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "type(" ); - getLhs().appendHqlString( hql ); + getLhs().appendHqlString( hql, context ); hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmAggregateFunction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmAggregateFunction.java index b9e0372907ca..724a93b69823 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmAggregateFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmAggregateFunction.java @@ -13,6 +13,7 @@ import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.expression.SqmAggregateFunction; import org.hibernate.query.sqm.tree.expression.SqmDistinct; @@ -97,28 +98,28 @@ public SqmPredicate getFilter() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { final List> arguments = getArguments(); hql.append( getFunctionName() ); hql.append( '(' ); int i = 1; if ( arguments.get( 0 ) instanceof SqmDistinct ) { - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); if ( arguments.size() > 1 ) { hql.append( ' ' ); - arguments.get( 1 ).appendHqlString( hql ); + arguments.get( 1 ).appendHqlString( hql, context ); i = 2; } } for ( ; i < arguments.size(); i++ ) { hql.append(", "); - arguments.get( i ).appendHqlString( hql ); + arguments.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); if ( filter != null ) { hql.append( " filter (where " ); - filter.appendHqlString( hql ); + filter.appendHqlString( hql, context ); hql.append( ')' ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmOrderedSetAggregateFunction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmOrderedSetAggregateFunction.java index bfab79ebf517..2cd720d3308e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmOrderedSetAggregateFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmOrderedSetAggregateFunction.java @@ -14,6 +14,7 @@ import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.expression.SqmDistinct; import org.hibernate.query.sqm.tree.expression.SqmOrderedSetAggregateFunction; @@ -133,39 +134,39 @@ public SqmOrderByClause getWithinGroup() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { final List> arguments = getArguments(); hql.append( getFunctionName() ); hql.append( '(' ); int i = 1; if ( arguments.get( 0 ) instanceof SqmDistinct ) { - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); if ( arguments.size() > 1 ) { hql.append( ' ' ); - arguments.get( 1 ).appendHqlString( hql ); + arguments.get( 1 ).appendHqlString( hql, context ); i = 2; } } for ( ; i < arguments.size(); i++ ) { hql.append(", "); - arguments.get( i ).appendHqlString( hql ); + arguments.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); if ( withinGroup != null ) { hql.append( " within group (order by " ); final List sortSpecifications = withinGroup.getSortSpecifications(); - sortSpecifications.get( 0 ).appendHqlString( hql ); + sortSpecifications.get( 0 ).appendHqlString( hql, context ); for ( int j = 1; j < sortSpecifications.size(); j++ ) { hql.append( ", " ); - sortSpecifications.get( j ).appendHqlString( hql ); + sortSpecifications.get( j ).appendHqlString( hql, context ); } hql.append( ')' ); } if ( getFilter() != null ) { hql.append( " filter (where " ); - getFilter().appendHqlString( hql ); + getFilter().appendHqlString( hql, context ); hql.append( ')' ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmWindowFunction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmWindowFunction.java index 5cebcefa164c..a9b474046fdc 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmWindowFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingSqmWindowFunction.java @@ -13,6 +13,7 @@ import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.expression.SqmDistinct; import org.hibernate.query.sqm.tree.expression.SqmWindowFunction; @@ -115,22 +116,22 @@ public Boolean getFromFirst() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { final List> arguments = getArguments(); hql.append( getFunctionName() ); hql.append( '(' ); int i = 1; if ( arguments.get( 0 ) instanceof SqmDistinct ) { - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); if ( arguments.size() > 1 ) { hql.append( ' ' ); - arguments.get( 1 ).appendHqlString( hql ); + arguments.get( 1 ).appendHqlString( hql, context ); i = 2; } } for ( ; i < arguments.size(); i++ ) { hql.append(", "); - arguments.get( i ).appendHqlString( hql ); + arguments.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); @@ -152,7 +153,7 @@ public void appendHqlString(StringBuilder hql) { } if ( filter != null ) { hql.append( " filter (where " ); - filter.appendHqlString( hql ); + filter.appendHqlString( hql, context ); hql.append( ')' ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java index ec9b1eadd8dd..2b745cbfe339 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java @@ -121,6 +121,7 @@ public class QuerySqmImpl implements SqmQueryImplementor, InterpretationsKeySource, DomainQueryExecutionContext { private final String hql; + private final Object queryStringCacheKey; private SqmStatement sqm; private final ParameterMetadataImplementor parameterMetadata; @@ -170,6 +171,7 @@ public QuerySqmImpl( SharedSessionContractImplementor session) { super( session ); this.hql = hql; + this.queryStringCacheKey = hql; this.resultType = resultType; sqm = hqlInterpretation.getSqmStatement(); @@ -200,9 +202,22 @@ public QuerySqmImpl( hql = CRITERIA_HQL_STRING; if ( producer.isCriteriaCopyTreeEnabled() ) { sqm = criteria.copy( SqmCopyContext.simpleContext() ); + if ( producer.isCriteriaPlanCacheEnabled() ) { + queryStringCacheKey = sqm.toHqlString(); + setQueryPlanCacheable( true ); + } + else { + queryStringCacheKey = sqm; + } } else { sqm = criteria; + if ( producer.isCriteriaPlanCacheEnabled() ) { + queryStringCacheKey = sqm.toHqlString(); + } + else { + queryStringCacheKey = sqm; + } // Cache immutable query plans by default setQueryPlanCacheable( true ); } @@ -261,6 +276,11 @@ public String getQueryString() { return hql; } + @Override + public Object getQueryStringCacheKey() { + return queryStringCacheKey; + } + @Override public SqmStatement getSqmStatement() { return sqm; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleSqmRenderContext.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleSqmRenderContext.java new file mode 100644 index 000000000000..130e5c75cbc7 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SimpleSqmRenderContext.java @@ -0,0 +1,36 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.query.sqm.internal; + +import org.hibernate.query.sqm.tree.SqmRenderContext; +import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter; +import org.hibernate.query.sqm.tree.from.SqmFrom; + +import java.util.IdentityHashMap; + +public class SimpleSqmRenderContext implements SqmRenderContext { + + private final IdentityHashMap, String> fromAliases = new IdentityHashMap<>(); + private final IdentityHashMap, String> parameterNames = new IdentityHashMap<>(); + private int fromId; + private int parameterId; + + public SimpleSqmRenderContext() { + } + + @Override + public String resolveAlias(SqmFrom from) { + final String explicitAlias = from.getExplicitAlias(); + if ( explicitAlias != null ) { + return explicitAlias; + } + return fromAliases.computeIfAbsent( from, f -> "alias_" + (fromId++) ); + } + + @Override + public String resolveParameterName(JpaCriteriaParameter parameter) { + return parameterNames.computeIfAbsent( parameter, p -> "__param_" + (parameterId++) ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmInterpretationsKey.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmInterpretationsKey.java index ee238f8f49c6..2cd846358ff3 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmInterpretationsKey.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmInterpretationsKey.java @@ -19,7 +19,6 @@ import org.hibernate.query.sqm.tree.SqmStatement; import static java.lang.Boolean.TRUE; -import static org.hibernate.query.spi.AbstractSelectionQuery.CRITERIA_HQL_STRING; /** * @author Steve Ebersole @@ -28,6 +27,7 @@ public final class SqmInterpretationsKey implements QueryInterpretationCache.Key public interface CacheabilityInfluencers { boolean isQueryPlanCacheable(); String getQueryString(); + Object getQueryStringCacheKey(); SqmStatement getSqmStatement(); QueryOptions getQueryOptions(); LoadQueryInfluencers getLoadQueryInfluencers(); @@ -40,9 +40,7 @@ public interface InterpretationsKeySource extends CacheabilityInfluencers { public static SqmInterpretationsKey createInterpretationsKey(InterpretationsKeySource keySource) { if ( isCacheable ( keySource ) ) { - final Object query = CRITERIA_HQL_STRING.equals( keySource.getQueryString() ) - ? keySource.getSqmStatement() - : keySource.getQueryString(); + final Object query = keySource.getQueryStringCacheKey(); return new SqmInterpretationsKey( query, query.hashCode(), diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java index 923cf059498a..b883c547908b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmSelectionQueryImpl.java @@ -89,6 +89,7 @@ public class SqmSelectionQueryImpl extends AbstractSqmSelectionQuery implements SqmSelectionQueryImplementor, InterpretationsKeySource { private final String hql; + private final Object queryStringCacheKey; private SqmSelectStatement sqm; private final ParameterMetadataImplementor parameterMetadata; @@ -109,6 +110,7 @@ public SqmSelectionQueryImpl( SharedSessionContractImplementor session) { super( session ); this.hql = hql; + this.queryStringCacheKey = hql; SqmUtil.verifyIsSelectStatement( hqlInterpretation.getSqmStatement(), hql ); this.sqm = (SqmSelectStatement) hqlInterpretation.getSqmStatement(); @@ -166,9 +168,22 @@ public SqmSelectionQueryImpl( hql = CRITERIA_HQL_STRING; if ( session.isCriteriaCopyTreeEnabled() ) { sqm = criteria.copy( SqmCopyContext.simpleContext() ); + if ( session.isCriteriaPlanCacheEnabled() ) { + queryStringCacheKey = sqm.toHqlString(); + setQueryPlanCacheable( true ); + } + else { + queryStringCacheKey = sqm; + } } else { sqm = criteria; + if ( session.isCriteriaPlanCacheEnabled() ) { + queryStringCacheKey = sqm.toHqlString(); + } + else { + queryStringCacheKey = sqm; + } // Cache immutable query plans by default setQueryPlanCacheable( true ); } @@ -221,6 +236,13 @@ SqmSelectionQueryImpl(AbstractSqmSelectionQuery original, KeyedPage ke .copy( noParamCopyContext( SqmQuerySource.CRITERIA ) ), original.getSqmStatement().nodeBuilder() ); + if ( getSession().isCriteriaPlanCacheEnabled() ) { + queryStringCacheKey = sqm.toHqlString(); + setQueryPlanCacheable( true ); + } + else { + queryStringCacheKey = sqm; + } hql = CRITERIA_HQL_STRING; domainParameterXref = DomainParameterXref.from( sqm ); @@ -356,6 +378,11 @@ public String getQueryString() { return hql; } + @Override + public Object getQueryStringCacheKey() { + return queryStringCacheKey; + } + @Override public SqmSelectionQuery setTupleTransformer(TupleTransformer transformer) { getQueryOptions().setTupleTransformer( transformer ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmDmlStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmDmlStatement.java index 44528e12f4fc..2036817c5757 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmDmlStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmDmlStatement.java @@ -195,11 +195,11 @@ public SqmSubQuery subquery(Class type) { return new SqmSubQuery<>( this, type, nodeBuilder() ); } - protected void appendHqlCteString(StringBuilder sb) { + protected void appendHqlCteString(StringBuilder sb, SqmRenderContext context) { if ( !cteStatements.isEmpty() ) { sb.append( "with " ); for ( SqmCteStatement value : cteStatements.values() ) { - value.appendHqlString( sb ); + value.appendHqlString( sb, context ); sb.append( ", " ); } sb.setLength( sb.length() - 2 ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmRestrictedDmlStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmRestrictedDmlStatement.java index 962965db13c3..ee82efebd0c9 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmRestrictedDmlStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/AbstractSqmRestrictedDmlStatement.java @@ -131,10 +131,10 @@ protected void setWhere(Predicate... restrictions) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { if ( whereClause != null && whereClause.getPredicate() != null ) { hql.append( " where " ); - whereClause.getPredicate().appendHqlString( hql ); + whereClause.getPredicate().appendHqlString( hql, context ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmRenderContext.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmRenderContext.java new file mode 100644 index 000000000000..1833a9e3428a --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmRenderContext.java @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.query.sqm.tree; + +import org.hibernate.query.sqm.internal.SimpleSqmRenderContext; +import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter; +import org.hibernate.query.sqm.tree.from.SqmFrom; + +/** + * Context used while rendering SQM nodes to HQL. + * + * @see SqmVisitableNode#appendHqlString(StringBuilder, SqmRenderContext) + * @since 7.0 + */ +public interface SqmRenderContext { + + /** + * Returns an alias for the given from node. + * + * @param from The from element + * @return The resolved alias + */ + String resolveAlias(SqmFrom from); + + String resolveParameterName(JpaCriteriaParameter parameter); + + static SqmRenderContext simpleContext() { + return new SimpleSqmRenderContext(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmVisitableNode.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmVisitableNode.java index 57b6f5b7483e..8ff0876f9e9b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmVisitableNode.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/SqmVisitableNode.java @@ -18,11 +18,11 @@ public interface SqmVisitableNode extends SqmNode { */ X accept(SemanticQueryWalker walker); - void appendHqlString(StringBuilder hql); + void appendHqlString(StringBuilder hql, SqmRenderContext context); default String toHqlString() { final StringBuilder hql = new StringBuilder(); - appendHqlString( hql ); + appendHqlString( hql, SqmRenderContext.simpleContext() ); return hql.toString(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/cte/SqmCteStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/cte/SqmCteStatement.java index 01bdca16252a..d2c8831ac838 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/cte/SqmCteStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/cte/SqmCteStatement.java @@ -14,6 +14,7 @@ import org.hibernate.query.criteria.JpaCteCriteriaType; import org.hibernate.query.criteria.JpaSearchOrder; import org.hibernate.query.SortDirection; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.expression.SqmLiteral; import org.hibernate.query.sqm.tree.select.SqmSelectQuery; @@ -320,7 +321,7 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { if ( cteTable.getName() == null ) { hql.append( "generated_" ); } @@ -339,11 +340,11 @@ public void appendHqlString(StringBuilder hql) { hql.append( getMaterialization() ).append( ' ' ); } if ( getCteDefinition() instanceof SqmSubQuery ) { - ( (SqmSubQuery) getCteDefinition() ).appendHqlString( hql ); + ( (SqmSubQuery) getCteDefinition() ).appendHqlString( hql, context ); } else { hql.append( '(' ); - ( (SqmSelectStatement) getCteDefinition() ).appendHqlString( hql ); + ( (SqmSelectStatement) getCteDefinition() ).appendHqlString( hql, context ); hql.append( ')' ); } String separator; @@ -394,9 +395,9 @@ public void appendHqlString(StringBuilder hql) { hql.append( " set " ); hql.append( getCycleMarkAttributeName() ); hql.append( " to " ); - getCycleLiteral().appendHqlString( hql ); + getCycleLiteral().appendHqlString( hql, context ); hql.append( " default " ); - getNoCycleLiteral().appendHqlString( hql ); + getNoCycleLiteral().appendHqlString( hql, context ); if ( getCyclePathAttributeName() != null ) { hql.append( " using " ); hql.append( getCyclePathAttributeName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/delete/SqmDeleteStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/delete/SqmDeleteStatement.java index 634761211dcb..d83384b86210 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/delete/SqmDeleteStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/delete/SqmDeleteStatement.java @@ -14,6 +14,7 @@ import org.hibernate.query.sqm.tree.AbstractSqmRestrictedDmlStatement; import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.SqmDeleteOrUpdateStatement; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.hibernate.query.sqm.tree.from.SqmFromClause; @@ -101,15 +102,15 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - appendHqlCteString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + appendHqlCteString( hql, context ); hql.append( "delete from " ); final SqmRoot root = getTarget(); hql.append( root.getEntityName() ); - hql.append( ' ' ).append( root.resolveAlias() ); - SqmFromClause.appendJoins( root, hql ); - SqmFromClause.appendTreatJoins( root, hql ); - super.appendHqlString( hql ); + hql.append( ' ' ).append( root.resolveAlias( context ) ); + SqmFromClause.appendJoins( root, hql, context ); + SqmFromClause.appendTreatJoins( root, hql, context ); + super.appendHqlString( hql, context ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java index 489fa67331a0..5cedaf440b36 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmFrom.java @@ -35,6 +35,7 @@ import org.hibernate.query.sqm.spi.SqmCreationHelper; import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.SqmJoinType; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; import org.hibernate.query.sqm.tree.expression.SqmSetReturningFunction; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; @@ -937,14 +938,8 @@ public SqmTreatedFrom treatAs(EntityDomainType treatTarg } @Override - public void appendHqlString(StringBuilder hql) { - if ( alias == null ) { - // If we don't have an alias, this is the best we can do to at least ensure uniqueness - hql.append( "alias_" ).append( System.identityHashCode( this ) ); - } - else { - hql.append( alias ); - } + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + hql.append( resolveAlias( context ) ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmSimplePath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmSimplePath.java index 1a343ac776dd..2fcda0050a96 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmSimplePath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmSimplePath.java @@ -4,6 +4,7 @@ */ package org.hibernate.query.sqm.tree.domain; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.spi.NavigablePath; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SqmPathSource; @@ -33,9 +34,9 @@ public AbstractSqmSimplePath( } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { if ( getLhs() != null ) { - getLhs().appendHqlString( hql ); + getLhs().appendHqlString( hql, context ); hql.append( '.' ); } hql.append( getReferencedPathSource().getPathName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmElementAggregateFunction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmElementAggregateFunction.java index c445808e17f0..6bc793795c46 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmElementAggregateFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmElementAggregateFunction.java @@ -13,6 +13,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.type.descriptor.java.JavaType; /** @@ -112,9 +113,9 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append(functionName).append( "(" ); - getLhs().appendHqlString( hql ); + getLhs().appendHqlString( hql, context ); hql.append( ')' ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmFkExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmFkExpression.java index 407c39e9ecfa..5ba4960ff4ac 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmFkExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmFkExpression.java @@ -13,6 +13,7 @@ import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.TreatException; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.spi.NavigablePath; /** @@ -54,9 +55,9 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "fk(" ); - getLhs().appendHqlString( hql ); + getLhs().appendHqlString( hql, context ); hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmFunctionPath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmFunctionPath.java index 949567a3161a..cb4692fe51c5 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmFunctionPath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmFunctionPath.java @@ -17,6 +17,7 @@ import org.hibernate.query.sqm.TreatException; import org.hibernate.query.sqm.function.SelfRenderingSqmFunction; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.expression.SqmFunction; import org.hibernate.query.sqm.tree.from.SqmFrom; @@ -146,8 +147,8 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - function.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + function.appendHqlString( hql, context ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmIndexAggregateFunction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmIndexAggregateFunction.java index e2d363d343f0..c2e785471680 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmIndexAggregateFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmIndexAggregateFunction.java @@ -14,6 +14,7 @@ import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.type.descriptor.java.JavaType; /** @@ -116,9 +117,9 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append(functionName).append( "(" ); - getLhs().appendHqlString( hql ); + getLhs().appendHqlString( hql, context ); hql.append( ')' ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmIndexedCollectionAccessPath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmIndexedCollectionAccessPath.java index d45e38caaa39..f11205be63c3 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmIndexedCollectionAccessPath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmIndexedCollectionAccessPath.java @@ -6,6 +6,7 @@ import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.metamodel.model.domain.PluralPersistentAttribute; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.spi.NavigablePath; import org.hibernate.query.PathException; import org.hibernate.query.sqm.SemanticQueryWalker; @@ -92,10 +93,10 @@ public SqmTreatedPath treatAs(EntityDomainType treatTarge } @Override - public void appendHqlString(StringBuilder hql) { - getLhs().appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + getLhs().appendHqlString( hql, context ); hql.append( '[' ); - selectorExpression.appendHqlString( hql ); + selectorExpression.appendHqlString( hql, context ); hql.append( ']' ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmMapEntryReference.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmMapEntryReference.java index 3b4c81a9d02b..328c0db73493 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmMapEntryReference.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmMapEntryReference.java @@ -15,6 +15,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.select.SqmSelectableNode; import org.hibernate.type.descriptor.java.JavaType; @@ -133,9 +134,9 @@ public NodeBuilder nodeBuilder() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "entry(" ); - mapPath.appendHqlString( hql ); + mapPath.appendHqlString( hql, context ); hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java index f0dcb0374235..91fc9dd1179f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmPath.java @@ -60,19 +60,6 @@ public interface SqmPath extends SqmExpression, SemanticPathPart, JpaPath< */ void setExplicitAlias(String explicitAlias); - /** - * Retrieve the explicit alias, if one, otherwise return a generated one and set that as explicit alias. - */ - default String resolveAlias() { - final String explicitAlias = getExplicitAlias(); - if ( explicitAlias != null ) { - return explicitAlias; - } - final String generatedAlias = "alias_" + System.identityHashCode( this ); - setExplicitAlias( generatedAlias ); - return generatedAlias; - } - /** * Get the left-hand side of this path - may be null, indicating a * root, cross-join or entity-join diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedBagJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedBagJoin.java index f76c1c8cf8d8..aa9428a2b761 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedBagJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedBagJoin.java @@ -10,6 +10,7 @@ import org.hibernate.query.criteria.JpaPredicate; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin; import org.hibernate.spi.NavigablePath; @@ -117,9 +118,9 @@ public SqmPathSource getResolvedModel() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getTypeName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedCrossJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedCrossJoin.java index 98bb1edbf4e7..53030e3db6f5 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedCrossJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedCrossJoin.java @@ -7,6 +7,7 @@ import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.from.SqmCrossJoin; import org.hibernate.spi.NavigablePath; @@ -90,9 +91,9 @@ public SqmPathSource getResolvedModel() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEmbeddedValuedSimplePath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEmbeddedValuedSimplePath.java index 1b941ae0bbc2..52e6aa4409af 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEmbeddedValuedSimplePath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEmbeddedValuedSimplePath.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.spi.NavigablePath; /** @@ -108,9 +109,9 @@ public SqmPath resolvePathPart(String name, boolean isTerminal, SqmCreationSt } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getTypeName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEntityJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEntityJoin.java index 887d263fd355..a044b2f49f60 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEntityJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEntityJoin.java @@ -7,6 +7,7 @@ import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.from.SqmEntityJoin; import org.hibernate.spi.NavigablePath; @@ -96,9 +97,9 @@ public SqmEntityDomainType getReferencedPathSource() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEntityValuedSimplePath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEntityValuedSimplePath.java index ff9f3266bef2..de89aaee56fd 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEntityValuedSimplePath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedEntityValuedSimplePath.java @@ -9,6 +9,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.spi.NavigablePath; /** @@ -133,9 +134,9 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedListJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedListJoin.java index 9801e9e6c93c..b81825f3b191 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedListJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedListJoin.java @@ -11,6 +11,7 @@ import org.hibernate.query.hql.spi.SqmCreationState; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin; import org.hibernate.spi.NavigablePath; @@ -148,9 +149,9 @@ public SqmTreatedListJoin on(Predicate... restrictions) { @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getTypeName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedMapJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedMapJoin.java index 340a7515e86b..7f825fd1625b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedMapJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedMapJoin.java @@ -11,6 +11,7 @@ import org.hibernate.query.criteria.JpaPredicate; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin; import org.hibernate.spi.NavigablePath; @@ -157,9 +158,9 @@ public SqmTreatedMapJoin on(Predicate... restrictions) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getTypeName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedPluralPartJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedPluralPartJoin.java index c03e83878302..ce7826659fb1 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedPluralPartJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedPluralPartJoin.java @@ -7,6 +7,7 @@ import org.hibernate.metamodel.model.domain.EntityDomainType; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.spi.NavigablePath; /** @@ -136,9 +137,9 @@ public SqmTreatedPluralPartJoin treatAs(EntityDomainType treatTarget, String ali @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedRoot.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedRoot.java index 755330fba01c..f0c84989ebc9 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedRoot.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedRoot.java @@ -9,6 +9,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.from.SqmRoot; import org.hibernate.spi.NavigablePath; @@ -116,9 +117,9 @@ public SqmPath resolvePathPart( } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSetJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSetJoin.java index 3edc0c94183f..061a3280e781 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSetJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSetJoin.java @@ -10,6 +10,7 @@ import org.hibernate.query.criteria.JpaPredicate; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin; import org.hibernate.spi.NavigablePath; @@ -117,9 +118,9 @@ public SqmPathSource getResolvedModel() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getTypeName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSimplePath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSimplePath.java index 1059850ddc43..462fc821a5c0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSimplePath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSimplePath.java @@ -9,6 +9,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.spi.NavigablePath; /** @@ -134,9 +135,9 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSingularJoin.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSingularJoin.java index 6f3a3f226c42..68e95ea646ee 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSingularJoin.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/SqmTreatedSingularJoin.java @@ -10,6 +10,7 @@ import org.hibernate.query.criteria.JpaPredicate; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.from.SqmTreatedAttributeJoin; import org.hibernate.spi.NavigablePath; @@ -120,9 +121,9 @@ public SqmPathSource getResolvedModel() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "treat(" ); - wrappedPath.appendHqlString( hql ); + wrappedPath.appendHqlString( hql, context ); hql.append( " as " ); hql.append( treatTarget.getTypeName() ); hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/AbstractSqmJsonPathExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/AbstractSqmJsonPathExpression.java index a95905e1f37c..336bc5d228b0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/AbstractSqmJsonPathExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/AbstractSqmJsonPathExpression.java @@ -20,6 +20,7 @@ import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.sql.ast.tree.expression.Expression; import org.hibernate.sql.ast.tree.expression.JsonPathPassingClause; @@ -113,11 +114,11 @@ protected Map> copyPassingExpressions(SqmCopyContext co return new JsonPathPassingClause( converted ); } - protected void appendPassingExpressionHqlString(StringBuilder sb) { + protected void appendPassingExpressionHqlString(StringBuilder sb, SqmRenderContext context) { if ( passingExpressions != null && !passingExpressions.isEmpty() ) { sb.append( " passing " ); for ( Map.Entry> entry : passingExpressions.entrySet() ) { - entry.getValue().appendHqlString( sb ); + entry.getValue().appendHqlString( sb, context ); sb.append( " as " ); QuotingHelper.appendDoubleQuoteEscapedString( sb, entry.getKey() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/AsWrapperSqmExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/AsWrapperSqmExpression.java index 815712b0d190..e9278c3fda66 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/AsWrapperSqmExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/AsWrapperSqmExpression.java @@ -7,6 +7,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.type.BasicType; public class AsWrapperSqmExpression extends AbstractSqmExpression { @@ -23,9 +24,9 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "wrap(" ); - expression.appendHqlString( hql ); + expression.appendHqlString( hql, context ); hql.append( " as " ); hql.append( getNodeType().getReturnedClassName() ); hql.append( ")" ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/JpaCriteriaParameter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/JpaCriteriaParameter.java index 2407470e8403..d6f6e7eec1a9 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/JpaCriteriaParameter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/JpaCriteriaParameter.java @@ -15,6 +15,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * {@link JpaParameterExpression} created via JPA {@link jakarta.persistence.criteria.CriteriaBuilder}. @@ -138,8 +139,13 @@ public NamedCallableQueryMemento.ParameterMemento toMemento() { } @Override - public void appendHqlString(StringBuilder hql) { - hql.append( ':' ).append( getName() ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + if ( getName() == null ) { + hql.append( ':' ).append( context.resolveParameterName( this ) ); + } + else { + hql.append( ':' ).append( getName() ); + } } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAliasedNodeRef.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAliasedNodeRef.java index 0efd8fe0117e..2b6a200ba16f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAliasedNodeRef.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAliasedNodeRef.java @@ -4,6 +4,7 @@ */ package org.hibernate.query.sqm.tree.expression; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.spi.NavigablePath; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; @@ -70,7 +71,7 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { if ( navigablePath == null ) { hql.append( position ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAny.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAny.java index 6bee9c341526..8b04cb11a358 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAny.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAny.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.select.SqmSubQuery; import org.checkerframework.checker.nullness.qual.Nullable; @@ -61,9 +62,9 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "any " ); - subquery.appendHqlString( hql ); + subquery.appendHqlString( hql, context ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAnyDiscriminatorValue.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAnyDiscriminatorValue.java index 91b0f553cb05..b420692f5242 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAnyDiscriminatorValue.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmAnyDiscriminatorValue.java @@ -11,6 +11,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.select.SqmSelectableNode; import org.hibernate.type.BasicType; @@ -91,7 +92,7 @@ public SqmPath resolveIndexedAccess( } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( getEntityValue().getName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmBinaryArithmetic.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmBinaryArithmetic.java index 0ee3a11958e6..ded2dfa1c4e6 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmBinaryArithmetic.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmBinaryArithmetic.java @@ -10,6 +10,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.select.SqmSelectableNode; import static org.hibernate.query.sqm.BinaryArithmeticOperator.ADD; @@ -134,12 +135,12 @@ public String asLoggableText() { } @Override - public void appendHqlString(StringBuilder hql) { - lhsOperand.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + lhsOperand.appendHqlString( hql, context ); hql.append( ' ' ); hql.append( operator.getOperatorSqlText() ); hql.append( ' ' ); - rhsOperand.appendHqlString( hql ); + rhsOperand.appendHqlString( hql, context ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmByUnit.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmByUnit.java index 764d45370ef6..5e06d4429808 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmByUnit.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmByUnit.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Gavin King @@ -58,8 +59,8 @@ public X accept(SemanticQueryWalker walker) { return walker.visitByUnit( this ); } @Override - public void appendHqlString(StringBuilder hql) { - duration.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + duration.appendHqlString( hql, context ); hql.append( " by " ); hql.append( unit.getUnit() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCaseSearched.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCaseSearched.java index acbd2fb7dff9..9669f37e5fca 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCaseSearched.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCaseSearched.java @@ -13,6 +13,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.predicate.SqmPredicate; import jakarta.persistence.criteria.Expression; @@ -140,18 +141,18 @@ public SqmExpression getResult() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "case" ); for ( WhenFragment whenFragment : whenFragments ) { hql.append( " when " ); - whenFragment.predicate.appendHqlString( hql ); + whenFragment.predicate.appendHqlString( hql, context ); hql.append( " then " ); - whenFragment.result.appendHqlString( hql ); + whenFragment.result.appendHqlString( hql, context ); } if ( otherwise != null ) { hql.append( " else " ); - otherwise.appendHqlString( hql ); + otherwise.appendHqlString( hql, context ); } hql.append( " end" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCaseSimple.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCaseSimple.java index c2e28b7b089a..19fe31985da2 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCaseSimple.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCaseSimple.java @@ -16,6 +16,7 @@ import org.hibernate.query.sqm.tree.SqmCopyContext; import jakarta.persistence.criteria.Expression; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Steve Ebersole @@ -153,19 +154,19 @@ public SqmExpression getResult() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "case " ); - fixture.appendHqlString( hql ); + fixture.appendHqlString( hql, context ); for ( WhenFragment whenFragment : whenFragments ) { hql.append( " when " ); - whenFragment.checkValue.appendHqlString( hql ); + whenFragment.checkValue.appendHqlString( hql, context ); hql.append( " then " ); - whenFragment.result.appendHqlString( hql ); + whenFragment.result.appendHqlString( hql, context ); } if ( otherwise != null ) { hql.append( " else " ); - otherwise.appendHqlString( hql ); + otherwise.appendHqlString( hql, context ); } hql.append( " end" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCastTarget.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCastTarget.java index 8d1f24cc471c..76e26de492fd 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCastTarget.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCastTarget.java @@ -12,6 +12,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.AbstractSqmNode; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; @@ -93,7 +94,7 @@ public SqmExpressible getNodeType() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( type.getTypeName() ); if ( precision != null ) { hql.append( '(' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCoalesce.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCoalesce.java index 9cbedbc9fb10..bbdff81be7bb 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCoalesce.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCoalesce.java @@ -17,6 +17,7 @@ import org.hibernate.query.sqm.tree.SqmCopyContext; import jakarta.persistence.criteria.Expression; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Steve Ebersole @@ -86,12 +87,12 @@ public String asLoggableText() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "coalesce(" ); - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < arguments.size(); i++ ) { hql.append(", "); - arguments.get( i ).appendHqlString( hql ); + arguments.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCollation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCollation.java index 8d18626d4fea..c6b0443339ff 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCollation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCollation.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Christian Beikov @@ -37,7 +38,7 @@ public R accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( getLiteralValue() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCollectionSize.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCollectionSize.java index b55129b65647..0515e8926665 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCollectionSize.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmCollectionSize.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmPath; /** @@ -61,9 +62,9 @@ public String asLoggableText() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "size(" ); - pluralPath.appendHqlString( hql ); + pluralPath.appendHqlString( hql, context ); hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmDistinct.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmDistinct.java index 4373a309d19d..54ca72178e52 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmDistinct.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmDistinct.java @@ -9,6 +9,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.AbstractSqmNode; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; /** @@ -53,8 +54,8 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "distinct " ); - expression.appendHqlString( hql ); + expression.appendHqlString( hql, context ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmDurationUnit.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmDurationUnit.java index 3745a5fc66ec..ddbc38823ffa 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmDurationUnit.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmDurationUnit.java @@ -11,6 +11,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.AbstractSqmNode; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; /** @@ -50,7 +51,7 @@ public SqmExpressible getNodeType() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( unit ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java index 610418340b8d..ff86340d4bec 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEnumLiteral.java @@ -15,6 +15,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.UnknownPathException; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmDomainType; import org.hibernate.type.descriptor.java.EnumJavaType; @@ -160,7 +161,7 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( enumValue.getDeclaringClass().getTypeName() ); hql.append( '.' ); hql.append( enumValueName ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEvery.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEvery.java index 1ec9d129a607..87d7a1665c88 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEvery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmEvery.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.select.SqmSubQuery; import org.checkerframework.checker.nullness.qual.Nullable; @@ -57,9 +58,9 @@ public X accept(SemanticQueryWalker walker) { return walker.visitEvery( this ); } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "all " ); - subquery.appendHqlString( hql ); + subquery.appendHqlString( hql, context ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmExtractUnit.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmExtractUnit.java index 42bffb0399b7..a8433d90d2db 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmExtractUnit.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmExtractUnit.java @@ -11,6 +11,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.AbstractSqmNode; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; /** @@ -50,7 +51,7 @@ public SqmExpressible getNodeType() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( unit ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFieldLiteral.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFieldLiteral.java index d3b70b0067a7..e7511e2f8f44 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFieldLiteral.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFieldLiteral.java @@ -20,6 +20,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.UnknownPathException; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmDomainType; import org.hibernate.query.sqm.tree.predicate.SqmPredicate; @@ -138,7 +139,7 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { SqmLiteral.appendHqlString( hql, getJavaTypeDescriptor(), getValue() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFormat.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFormat.java index 65a661e8f8ee..3b3b3c3e3710 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFormat.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFormat.java @@ -11,6 +11,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * Effectively a query-literal but we want to handle it specially in the SQM to SQL AST conversion @@ -74,7 +75,7 @@ public R accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( getLiteralValue() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFunction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFunction.java index 7ad239b70832..c8117e8eca0a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmFunction.java @@ -14,6 +14,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.function.SqmFunctionDescriptor; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.domain.SqmFunctionPath; import org.hibernate.query.sqm.tree.domain.SqmPath; @@ -68,44 +69,44 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { // Special case a few functions with special syntax for rendering... // Unless we introduce dedicated SqmXXX classes that override this method, we have to render it this way switch ( functionName ) { case "cast": { hql.append( "cast(" ); - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); hql.append( " as " ); - arguments.get( 1 ).appendHqlString( hql ); + arguments.get( 1 ).appendHqlString( hql, context ); hql.append( ')' ); break; } case "extract": { hql.append( "extract(" ); - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); hql.append( " from " ); - arguments.get( 1 ).appendHqlString( hql ); + arguments.get( 1 ).appendHqlString( hql, context ); hql.append( ')' ); break; } case "format": { hql.append( "format(" ); - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); hql.append( " as " ); - arguments.get( 1 ).appendHqlString( hql ); + arguments.get( 1 ).appendHqlString( hql, context ); hql.append( ')' ); break; } case "overlay": { hql.append( "overlay(" ); - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); hql.append( " placing " ); - arguments.get( 1 ).appendHqlString( hql ); + arguments.get( 1 ).appendHqlString( hql, context ); hql.append( " from " ); - arguments.get( 2 ).appendHqlString( hql ); + arguments.get( 2 ).appendHqlString( hql, context ); if ( arguments.size() == 4 ) { hql.append( " for " ); - arguments.get( 3 ).appendHqlString( hql ); + arguments.get( 3 ).appendHqlString( hql, context ); } hql.append( ')' ); break; @@ -114,19 +115,19 @@ public void appendHqlString(StringBuilder hql) { hql.append( "trim(" ); switch ( arguments.size() ) { case 1: - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); break; case 2: - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); hql.append( " from " ); - arguments.get( 1 ).appendHqlString( hql ); + arguments.get( 1 ).appendHqlString( hql, context ); break; case 3: - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); hql.append( ' ' ); - arguments.get( 1 ).appendHqlString( hql ); + arguments.get( 1 ).appendHqlString( hql, context ); hql.append( " from " ); - arguments.get( 3 ).appendHqlString( hql ); + arguments.get( 3 ).appendHqlString( hql, context ); break; } hql.append( ')' ); @@ -134,20 +135,20 @@ public void appendHqlString(StringBuilder hql) { } case "pad": { hql.append( "pad(" ); - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); hql.append( " with" ); for ( int i = 1; i < arguments.size(); i++ ) { hql.append( ' ' ); - arguments.get( i ).appendHqlString( hql ); + arguments.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); break; } case "position": { hql.append( "position(" ); - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); hql.append( " in " ); - arguments.get( 1 ).appendHqlString( hql ); + arguments.get( 1 ).appendHqlString( hql, context ); hql.append( ')' ); break; } @@ -160,10 +161,10 @@ public void appendHqlString(StringBuilder hql) { return; } hql.append( '(' ); - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < arguments.size(); i++ ) { hql.append( ", " ); - arguments.get( i ).appendHqlString( hql ); + arguments.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmHqlNumericLiteral.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmHqlNumericLiteral.java index 11888f6755ea..7bd1eda1a0ab 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmHqlNumericLiteral.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmHqlNumericLiteral.java @@ -14,6 +14,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.type.descriptor.java.JavaType; /** @@ -74,7 +75,7 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( literalValue ); switch ( typeCategory ) { @@ -103,7 +104,7 @@ public void appendHqlString(StringBuilder hql) { @Override public String asLoggableText() { final StringBuilder stringBuilder = new StringBuilder(); - appendHqlString( stringBuilder ); + appendHqlString( stringBuilder, SqmRenderContext.simpleContext() ); return stringBuilder.toString(); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJpaCriteriaParameterWrapper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJpaCriteriaParameterWrapper.java index e9a0d69d8d9d..aa5f2a4512b2 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJpaCriteriaParameterWrapper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJpaCriteriaParameterWrapper.java @@ -10,6 +10,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.select.SqmSelectableNode; import org.hibernate.sql.ast.tree.expression.JdbcParameter; @@ -117,8 +118,8 @@ public void visitSubSelectableNodes(Consumer> jpaSelectionC } @Override - public void appendHqlString(StringBuilder hql) { - jpaCriteriaParameter.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + jpaCriteriaParameter.appendHqlString( hql, context ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonExistsExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonExistsExpression.java index 98164e53c0c7..0b823c537db4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonExistsExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonExistsExpression.java @@ -19,6 +19,7 @@ import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.sql.ast.tree.SqlAstNode; import org.hibernate.sql.ast.tree.expression.Expression; @@ -172,13 +173,13 @@ public Expression convertToSqlAst(SqmToSqlAstConverter walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "json_exists(" ); - getArguments().get( 0 ).appendHqlString( hql ); + getArguments().get( 0 ).appendHqlString( hql, context ); hql.append( ',' ); - getArguments().get( 1 ).appendHqlString( hql ); + getArguments().get( 1 ).appendHqlString( hql, context ); - appendPassingExpressionHqlString( hql ); + appendPassingExpressionHqlString( hql, context ); switch ( errorBehavior ) { case ERROR -> hql.append( " error on error" ); case TRUE -> hql.append( " true on error" ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonNullBehavior.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonNullBehavior.java index fd78585f7f07..aa64251342de 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonNullBehavior.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonNullBehavior.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.sql.ast.tree.expression.JsonNullBehavior; @@ -50,7 +51,7 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { if ( this == NULL ) { hql.append( " null on null" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonObjectAggUniqueKeysBehavior.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonObjectAggUniqueKeysBehavior.java index ca6042513d2e..70230c2331db 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonObjectAggUniqueKeysBehavior.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonObjectAggUniqueKeysBehavior.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.sql.ast.tree.expression.JsonObjectAggUniqueKeysBehavior; @@ -50,7 +51,7 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { if ( this == WITH ) { hql.append( " with unique keys" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonQueryExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonQueryExpression.java index be790fb7cfbc..b899ac0490c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonQueryExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonQueryExpression.java @@ -19,6 +19,7 @@ import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.sql.ast.tree.SqlAstNode; import org.hibernate.sql.ast.tree.expression.Expression; @@ -264,13 +265,13 @@ public Expression convertToSqlAst(SqmToSqlAstConverter walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "json_query(" ); - getArguments().get( 0 ).appendHqlString( hql ); + getArguments().get( 0 ).appendHqlString( hql, context ); hql.append( ',' ); - getArguments().get( 1 ).appendHqlString( hql ); + getArguments().get( 1 ).appendHqlString( hql, context ); - appendPassingExpressionHqlString( hql ); + appendPassingExpressionHqlString( hql, context ); switch ( wrapMode ) { case WITH_WRAPPER -> hql.append( " with wrapper" ); case WITHOUT_WRAPPER -> hql.append( " without wrapper" ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonTableFunction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonTableFunction.java index 68f957642de1..261e787673ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonTableFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonTableFunction.java @@ -14,6 +14,7 @@ import org.hibernate.query.criteria.JpaJsonTableColumnsNode; import org.hibernate.query.criteria.JpaJsonTableFunction; import org.hibernate.query.criteria.JpaJsonValueNode; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tuple.internal.AnonymousTupleType; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; @@ -289,7 +290,7 @@ sealed interface ColumnDefinition { JsonTableColumnDefinition convertToSqlAst(SqmToSqlAstConverter walker); - void appendHqlString(StringBuilder sb); + void appendHqlString(StringBuilder sb, SqmRenderContext context); int populateTupleType(int offset, String[] componentNames, SqmExpressible[] componentTypes); } @@ -334,7 +335,7 @@ public JsonTableColumnDefinition convertToSqlAst(SqmToSqlAstConverter walker) { } @Override - public void appendHqlString(StringBuilder sb) { + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { sb.append( name ); sb.append( " exists" ); @@ -446,7 +447,7 @@ public JsonTableColumnDefinition convertToSqlAst(SqmToSqlAstConverter walker) { } @Override - public void appendHqlString(StringBuilder sb) { + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { sb.append( name ); sb.append( " json" ); switch ( wrapMode ) { @@ -652,10 +653,10 @@ public JsonTableColumnDefinition convertToSqlAst(SqmToSqlAstConverter walker) { } @Override - public void appendHqlString(StringBuilder sb) { + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { sb.append( name ); sb.append( ' ' ); - type.appendHqlString( sb ); + type.appendHqlString( sb, context ); if ( jsonPath != null ) { sb.append( " path " ); QuotingHelper.appendSingleQuoteEscapedString( sb, jsonPath ); @@ -666,7 +667,7 @@ public void appendHqlString(StringBuilder sb) { case DEFAULT -> { assert errorDefaultExpression != null; sb.append( " default " ); - errorDefaultExpression.appendHqlString( sb ); + errorDefaultExpression.appendHqlString( sb, context ); sb.append( " on error" ); } } @@ -676,7 +677,7 @@ public void appendHqlString(StringBuilder sb) { case DEFAULT -> { assert emptyDefaultExpression != null; sb.append( " default " ); - emptyDefaultExpression.appendHqlString( sb ); + emptyDefaultExpression.appendHqlString( sb, context ); sb.append( " on empty" ); } } @@ -780,7 +781,7 @@ public JsonTableColumnDefinition convertToSqlAst(SqmToSqlAstConverter walker) { } @Override - public void appendHqlString(StringBuilder sb) { + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { sb.append( name ); sb.append( " for ordinality" ); } @@ -836,17 +837,17 @@ public JsonTableColumnDefinition convertToSqlAst(SqmToSqlAstConverter walker) { } @Override - public void appendHqlString(StringBuilder sb) { + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { sb.append( "nested " ); QuotingHelper.appendSingleQuoteEscapedString( sb, jsonPath ); - appendColumnsToHqlString( sb ); + appendColumnsToHqlString( sb, context ); } - void appendColumnsToHqlString(StringBuilder sb) { + void appendColumnsToHqlString(StringBuilder sb, SqmRenderContext context) { String separator = " columns ("; for ( ColumnDefinition columnDefinition : columnDefinitions ) { sb.append( separator ); - columnDefinition.appendHqlString( sb ); + columnDefinition.appendHqlString( sb, context ); separator = ", "; } sb.append( ')' ); @@ -990,8 +991,8 @@ public NodeBuilder nodeBuilder() { } @Override - public void appendHqlString(StringBuilder hql) { - appendColumnsToHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + appendColumnsToHqlString( hql, context ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonValueExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonValueExpression.java index 6f9133541e2a..e263c41ddf5a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonValueExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmJsonValueExpression.java @@ -20,6 +20,7 @@ import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver; import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.sql.ast.tree.SqlAstNode; import org.hibernate.sql.ast.tree.expression.Expression; @@ -244,23 +245,23 @@ public Expression convertToSqlAst(SqmToSqlAstConverter walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "json_value(" ); - getArguments().get( 0 ).appendHqlString( hql ); + getArguments().get( 0 ).appendHqlString( hql, context ); hql.append( ',' ); - getArguments().get( 1 ).appendHqlString( hql ); + getArguments().get( 1 ).appendHqlString( hql, context ); - appendPassingExpressionHqlString( hql ); + appendPassingExpressionHqlString( hql, context ); if ( getArguments().size() > 2 ) { hql.append( " returning " ); - getArguments().get( 2 ).appendHqlString( hql ); + getArguments().get( 2 ).appendHqlString( hql, context ); } switch ( errorBehavior ) { case NULL -> hql.append( " null on error" ); case ERROR -> hql.append( " error on error" ); case DEFAULT -> { hql.append( " default " ); - errorDefaultExpression.appendHqlString( hql ); + errorDefaultExpression.appendHqlString( hql, context ); hql.append( " on error" ); } } @@ -269,7 +270,7 @@ public void appendHqlString(StringBuilder hql) { case ERROR -> hql.append( " error on empty" ); case DEFAULT -> { hql.append( " default " ); - emptyDefaultExpression.appendHqlString( hql ); + emptyDefaultExpression.appendHqlString( hql, context ); hql.append( " on empty" ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteral.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteral.java index 962facb8de63..ff8fb72e80f0 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteral.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteral.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.type.descriptor.java.JavaType; import org.checkerframework.checker.nullness.qual.Nullable; @@ -71,21 +72,29 @@ public String asLoggableText() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { appendHqlString( hql, getJavaTypeDescriptor(), getLiteralValue() ); } - public static void appendHqlString(StringBuilder sb, JavaType javaType, @Nullable T value) { + public static void appendHqlString(StringBuilder sb, @Nullable JavaType javaType, @Nullable T value) { if ( value == null ) { sb.append( "null" ); } else { - final String string = javaType.toString( value ); - if ( javaType.getJavaTypeClass() == String.class ) { - appendSingleQuoteEscapedString( sb, string ); + if ( javaType == null ) { + throw new IllegalArgumentException( "Can't render value because java type is null" ); + } + if ( value instanceof Number || value instanceof Boolean ) { + // We know these are safe to render + sb.append( value ); + } + else if ( value instanceof Enum enumValue ) { + sb.append( enumValue.getDeclaringClass().getTypeName() ).append( "." ).append( enumValue.name() ); } else { - sb.append( string ); + // Even if this is not 100% correct, our goal with this implementation is to provide + // a cache key or insight into the query structure, not necessarily produce an executable query + appendSingleQuoteEscapedString( sb, javaType.toString( value ) ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralEmbeddableType.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralEmbeddableType.java index c5e3201707be..1c5f2a7de197 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralEmbeddableType.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralEmbeddableType.java @@ -12,6 +12,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmEmbeddableDomainType; import org.hibernate.query.sqm.tree.select.SqmSelectableNode; @@ -83,7 +84,7 @@ public SqmPath resolveIndexedAccess( } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( embeddableDomainType.getTypeName() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralEntityType.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralEntityType.java index 00440f21b8d0..93c80c3df705 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralEntityType.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralEntityType.java @@ -11,6 +11,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmEntityDomainType; import org.hibernate.query.sqm.tree.select.SqmSelectableNode; @@ -94,7 +95,7 @@ public SqmPath resolveIndexedAccess( } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( entityType.getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralNull.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralNull.java index b794105ec0c0..5662bf215e8d 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralNull.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmLiteralNull.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Steve Ebersole @@ -53,7 +54,7 @@ public String asLoggableText() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "null" ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmModifiedSubQueryExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmModifiedSubQueryExpression.java index 4f7a8e3e6041..3525e679e501 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmModifiedSubQueryExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmModifiedSubQueryExpression.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.select.SqmSubQuery; /** @@ -81,10 +82,10 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( modifier ); hql.append( " (" ); - subQuery.appendHqlString( hql ); + subQuery.appendHqlString( hql, context ); hql.append( ')' ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmNamedExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmNamedExpression.java index 42d34be5dd5d..95439793fc66 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmNamedExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmNamedExpression.java @@ -7,6 +7,7 @@ import org.hibernate.Incubating; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * A named expression. Used when the name of the expression matters @@ -54,8 +55,8 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - expression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + expression.appendHqlString( hql, context ); hql.append( " as " ); hql.append( name ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmNamedParameter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmNamedParameter.java index a759944a5666..fd3bfd3d1c8e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmNamedParameter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmNamedParameter.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * Represents a named query parameter in the SQM tree. @@ -75,7 +76,7 @@ public SqmParameter copy() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( ':' ); hql.append( getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmOver.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmOver.java index 48bbca11a2e3..d89b0bb4704b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmOver.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmOver.java @@ -12,6 +12,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.select.SqmSortSpecification; import org.checkerframework.checker.nullness.qual.Nullable; @@ -96,10 +97,10 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - expression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + expression.appendHqlString( hql, context ); hql.append( " over (" ); - window.appendHqlString( hql ); + window.appendHqlString( hql, context ); hql.append( ')' ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmOverflow.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmOverflow.java index e0e76d9c5e0d..00bd8fb99619 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmOverflow.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmOverflow.java @@ -6,6 +6,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Christian Beikov @@ -59,15 +60,15 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - separatorExpression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + separatorExpression.appendHqlString( hql, context ); hql.append( " on overflow " ); if ( fillerExpression == null ) { hql.append( "error" ); } else { hql.append( "truncate " ); - fillerExpression.appendHqlString( hql ); + fillerExpression.appendHqlString( hql, context ); if ( withCount ) { hql.append( " with count" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmParameterizedEntityType.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmParameterizedEntityType.java index c32fcb1f1a37..91f348058ac3 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmParameterizedEntityType.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmParameterizedEntityType.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.select.SqmSelectableNode; /** @@ -58,9 +59,9 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "type(" ); - discriminatorSource.appendHqlString( hql ); + discriminatorSource.appendHqlString( hql, context ); hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmPositionalParameter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmPositionalParameter.java index e5cb57ba62e1..c78bcc0bc0cf 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmPositionalParameter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmPositionalParameter.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * Models a positional parameter expression @@ -78,7 +79,7 @@ public String asLoggableText() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( '?' ); hql.append( getPosition() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSelfRenderingExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSelfRenderingExpression.java index 9aa8043a5a65..a588469bebea 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSelfRenderingExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSelfRenderingExpression.java @@ -10,6 +10,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.sql.ast.tree.expression.Expression; /** @@ -47,7 +48,7 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { throw new UnsupportedOperationException(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSetReturningFunction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSetReturningFunction.java index e2d897a6f6c2..97f9153d7fac 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSetReturningFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSetReturningFunction.java @@ -8,6 +8,7 @@ import org.hibernate.Incubating; import org.hibernate.query.criteria.JpaSetReturningFunction; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tuple.internal.AnonymousTupleType; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; @@ -78,17 +79,17 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( functionName ); if ( arguments.isEmpty() ) { hql.append( "()" ); return; } hql.append( '(' ); - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < arguments.size(); i++ ) { hql.append( ", " ); - arguments.get( i ).appendHqlString( hql ); + arguments.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmStar.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmStar.java index 3e79e6d811f4..bd3816509716 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmStar.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmStar.java @@ -7,6 +7,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Gavin King @@ -31,7 +32,7 @@ public X accept(SemanticQueryWalker walker) { return walker.visitStar( this ); } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "*" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSummarization.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSummarization.java index ea3b6758cd30..7c245f81bfca 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSummarization.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmSummarization.java @@ -10,6 +10,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Christian Beikov @@ -65,13 +66,13 @@ public enum Kind { CUBE } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( kind ); hql.append( " (" ); - groupings.get( 0 ).appendHqlString( hql ); + groupings.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < groupings.size(); i++ ) { hql.append(", "); - groupings.get( i ).appendHqlString( hql ); + groupings.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmToDuration.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmToDuration.java index d35d033d898e..0f8e261e219b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmToDuration.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmToDuration.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Gavin King @@ -64,8 +65,8 @@ public String asLoggableText() { } @Override - public void appendHqlString(StringBuilder hql) { - magnitude.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + magnitude.appendHqlString( hql, context ); hql.append( ' ' ); hql.append( unit.getUnit() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTrimSpecification.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTrimSpecification.java index 85362f16519a..dfa0a69e9984 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTrimSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTrimSpecification.java @@ -10,6 +10,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.AbstractSqmNode; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; /** @@ -51,7 +52,7 @@ public SqmExpressible getNodeType() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( specification ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTuple.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTuple.java index b03dc9f670c2..9cf74d74c824 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTuple.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmTuple.java @@ -15,6 +15,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.select.SqmJpaCompoundSelection; /** @@ -83,12 +84,12 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( '(' ); - groupedExpressions.get( 0 ).appendHqlString( hql ); + groupedExpressions.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < groupedExpressions.size(); i++ ) { hql.append(", "); - groupedExpressions.get( i ).appendHqlString( hql ); + groupedExpressions.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmUnaryOperation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmUnaryOperation.java index 4203d37c50bf..d468a9e85872 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmUnaryOperation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmUnaryOperation.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.UnaryArithmeticOperator; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.select.SqmSelectableNode; /** @@ -72,8 +73,8 @@ public String asLoggableText() { return ( operation == UnaryArithmeticOperator.UNARY_MINUS ? '-' : '+' ) + operand.asLoggableText(); } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( operation == UnaryArithmeticOperator.UNARY_MINUS ? '-' : '+' ); - operand.appendHqlString( hql ); + operand.appendHqlString( hql, context ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmWindow.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmWindow.java index 858ab411c82a..0d8b61084b9c 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmWindow.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmWindow.java @@ -17,6 +17,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.AbstractSqmNode; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmVisitableNode; import org.hibernate.query.sqm.tree.select.SqmSortSpecification; @@ -198,15 +199,15 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { boolean needsWhitespace = false; if ( !this.partitions.isEmpty() ) { needsWhitespace = true; hql.append( "partition by " ); - this.partitions.get( 0 ).appendHqlString( hql ); + this.partitions.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < this.partitions.size(); i++ ) { hql.append( ',' ); - this.partitions.get( i ).appendHqlString( hql ); + this.partitions.get( i ).appendHqlString( hql, context ); } } if ( !orderList.isEmpty() ) { @@ -215,10 +216,10 @@ public void appendHqlString(StringBuilder hql) { } needsWhitespace = true; hql.append( "order by " ); - orderList.get( 0 ).appendHqlString( hql ); + orderList.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < orderList.size(); i++ ) { hql.append( ',' ); - orderList.get( i ).appendHqlString( hql ); + orderList.get( i ).appendHqlString( hql, context ); } } if ( mode == RANGE && startKind == UNBOUNDED_PRECEDING && endKind == CURRENT_ROW && exclusion == NO_OTHERS ) { @@ -240,13 +241,13 @@ public void appendHqlString(StringBuilder hql) { break; } if ( endKind == CURRENT_ROW ) { - renderFrameKind( hql, startKind, startExpression ); + renderFrameKind( hql, startKind, startExpression, context ); } else { hql.append( "between " ); - renderFrameKind( hql, startKind, startExpression ); + renderFrameKind( hql, startKind, startExpression, context ); hql.append( " and " ); - renderFrameKind( hql, endKind, endExpression ); + renderFrameKind( hql, endKind, endExpression, context ); } switch ( exclusion ) { case TIES: @@ -262,7 +263,7 @@ public void appendHqlString(StringBuilder hql) { } } - private static void renderFrameKind(StringBuilder sb, FrameKind kind, SqmExpression expression) { + private static void renderFrameKind(StringBuilder sb, FrameKind kind, SqmExpression expression, SqmRenderContext context) { switch ( kind ) { case CURRENT_ROW: sb.append( "current row" ); @@ -274,11 +275,11 @@ private static void renderFrameKind(StringBuilder sb, FrameKind kind, SqmExpress sb.append( "unbounded following" ); break; case OFFSET_PRECEDING: - expression.appendHqlString( sb ); + expression.appendHqlString( sb, context ); sb.append( " preceding" ); break; case OFFSET_FOLLOWING: - expression.appendHqlString( sb ); + expression.appendHqlString( sb, context ); sb.append( " following" ); break; default: diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlAttributesExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlAttributesExpression.java index f1b0dc7f7f3b..983b7cd42222 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlAttributesExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlAttributesExpression.java @@ -12,6 +12,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.sql.ast.tree.expression.XmlAttributes; @@ -80,11 +81,11 @@ public SqmXmlAttributesExpression copy(SqmCopyContext context) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { String separator = "xmlattributes("; for ( Map.Entry> entry : attributes.entrySet() ) { hql.append( separator ); - entry.getValue().appendHqlString( hql ); + entry.getValue().appendHqlString( hql, context ); hql.append( " as " ); hql.append( entry.getKey() ); separator = ", "; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlElementExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlElementExpression.java index 8b7dfe28e563..2d18df52c84b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlElementExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlElementExpression.java @@ -18,6 +18,7 @@ import org.hibernate.query.sqm.produce.function.ArgumentsValidator; import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import jakarta.persistence.criteria.Expression; @@ -115,13 +116,13 @@ public SqmXmlElementExpression copy(SqmCopyContext context) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { final List> arguments = getArguments(); hql.append( "xmlelement(name " ); - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < arguments.size(); i++ ) { hql.append( ',' ); - arguments.get( i ).appendHqlString( hql ); + arguments.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlTableFunction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlTableFunction.java index 57a4077ffb87..b7e9436cf007 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlTableFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/SqmXmlTableFunction.java @@ -10,6 +10,7 @@ import org.hibernate.query.criteria.JpaCastTarget; import org.hibernate.query.criteria.JpaXmlTableColumnNode; import org.hibernate.query.criteria.JpaXmlTableFunction; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tuple.internal.AnonymousTupleType; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; @@ -170,12 +171,12 @@ public SqmXmlTableFunction ordinalityColumn(String columnName) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "xmltable(" ); - getArguments().get( 0 ).appendHqlString( hql ); + getArguments().get( 0 ).appendHqlString( hql, context ); hql.append( " passing " ); - getArguments().get( 1 ).appendHqlString( hql ); - columns.appendHqlString( hql ); + getArguments().get( 1 ).appendHqlString( hql, context ); + columns.appendHqlString( hql, context ); hql.append( ')' ); } @@ -194,7 +195,7 @@ sealed interface ColumnDefinition { XmlTableColumnDefinition convertToSqlAst(SqmToSqlAstConverter walker); - void appendHqlString(StringBuilder sb); + void appendHqlString(StringBuilder sb, SqmRenderContext context); int populateTupleType(int offset, String[] componentNames, SqmExpressible[] componentTypes); } @@ -257,7 +258,7 @@ public JpaXmlTableColumnNode defaultExpression(Expression expres } @Override - public void appendHqlString(StringBuilder sb) { + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { sb.append( name ); sb.append( " xml" ); if ( xpath != null ) { @@ -266,7 +267,7 @@ public void appendHqlString(StringBuilder sb) { } if ( defaultExpression != null ) { sb.append( " default " ); - defaultExpression.appendHqlString( sb ); + defaultExpression.appendHqlString( sb, context ); } } @@ -342,17 +343,17 @@ public JpaXmlTableColumnNode defaultExpression(Expression expression) { } @Override - public void appendHqlString(StringBuilder sb) { + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { sb.append( name ); sb.append( ' ' ); - type.appendHqlString( sb ); + type.appendHqlString( sb, context ); if ( xpath != null ) { sb.append( " path " ); QuotingHelper.appendSingleQuoteEscapedString( sb, xpath ); } if ( defaultExpression != null ) { sb.append( " default " ); - defaultExpression.appendHqlString( sb ); + defaultExpression.appendHqlString( sb, context ); } } @@ -382,7 +383,7 @@ public XmlTableColumnDefinition convertToSqlAst(SqmToSqlAstConverter walker) { } @Override - public void appendHqlString(StringBuilder sb) { + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { sb.append( name ); sb.append( " for ordinality" ); } @@ -445,11 +446,11 @@ private void addColumn(ColumnDefinition columnDefinition) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { String separator = " columns "; for ( ColumnDefinition columnDefinition : columnDefinitions ) { hql.append( separator ); - columnDefinition.appendHqlString( hql ); + columnDefinition.appendHqlString( hql, context ); separator = ", "; } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/ValueBindJpaCriteriaParameter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/ValueBindJpaCriteriaParameter.java index a356d51dd060..712366ea5a63 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/ValueBindJpaCriteriaParameter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/expression/ValueBindJpaCriteriaParameter.java @@ -7,13 +7,14 @@ import org.hibernate.query.BindableType; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * It is a JpaCriteriaParameter created from a value when ValueHandlingMode is equal to BIND * * @see org.hibernate.query.criteria.ValueHandlingMode */ -public class ValueBindJpaCriteriaParameter extends JpaCriteriaParameter{ +public class ValueBindJpaCriteriaParameter extends JpaCriteriaParameter { private final T value; public ValueBindJpaCriteriaParameter(BindableType type, T value, NodeBuilder nodeBuilder) { @@ -40,8 +41,8 @@ public T getValue() { } @Override - public void appendHqlString(StringBuilder hql) { - hql.append( value ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + SqmLiteral.appendHqlString( hql, getJavaTypeDescriptor(), value ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmFrom.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmFrom.java index 278b72ce9ec0..860cebb71cf1 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmFrom.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmFrom.java @@ -19,6 +19,7 @@ import org.hibernate.query.criteria.JpaFrom; import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmVisitableNode; import org.hibernate.query.sqm.tree.domain.SqmBagJoin; import org.hibernate.query.sqm.tree.domain.SqmListJoin; @@ -48,6 +49,13 @@ public interface SqmFrom extends SqmVisitableNode, SqmPath, JpaFrom getReferencedPathSource(); + /** + * Retrieve the explicit alias, if one, otherwise return a generated one. + */ + default String resolveAlias(SqmRenderContext context) { + return context.resolveAlias( this ); + } + boolean hasJoins(); /** diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmFromClause.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmFromClause.java index 05b2b22070b1..5a6b65c6cb30 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmFromClause.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/from/SqmFromClause.java @@ -11,6 +11,7 @@ import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmTreatedPath; import static java.util.Collections.emptyList; @@ -91,32 +92,32 @@ public int getNumberOfRoots() { } } - public void appendHqlString(StringBuilder sb) { + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { String separator = " "; for ( SqmRoot root : getRoots() ) { sb.append( separator ); if ( root.isCorrelated() ) { if ( root.containsOnlyInnerJoins() ) { - appendJoins( root, root.getCorrelationParent().resolveAlias(), sb ); + appendJoins( root, root.getCorrelationParent().resolveAlias( context ), sb, context ); } else { - sb.append( root.getCorrelationParent().resolveAlias() ); - sb.append( ' ' ).append( root.resolveAlias() ); - appendJoins( root, sb ); - appendTreatJoins( root, sb ); + sb.append( root.getCorrelationParent().resolveAlias( context ) ); + sb.append( ' ' ).append( root.resolveAlias( context ) ); + appendJoins( root, sb, context ); + appendTreatJoins( root, sb, context ); } } else { sb.append( root.getEntityName() ); - sb.append( ' ' ).append( root.resolveAlias() ); - appendJoins( root, sb ); - appendTreatJoins( root, sb ); + sb.append( ' ' ).append( root.resolveAlias( context ) ); + appendJoins( root, sb, context ); + appendTreatJoins( root, sb, context ); } separator = ", "; } } - public static void appendJoins(SqmFrom sqmFrom, StringBuilder sb) { + public static void appendJoins(SqmFrom sqmFrom, StringBuilder sb, SqmRenderContext context) { for ( SqmJoin sqmJoin : sqmFrom.getSqmJoins() ) { switch ( sqmJoin.getSqmJoinType() ) { case LEFT: @@ -138,33 +139,34 @@ public static void appendJoins(SqmFrom sqmFrom, StringBuilder sb) { if ( sqmJoin instanceof SqmAttributeJoin attributeJoin ) { if ( sqmFrom instanceof SqmTreatedPath treatedPath ) { sb.append( "treat(" ); - sb.append( treatedPath.getWrappedPath().resolveAlias() ); + treatedPath.getWrappedPath().appendHqlString( sb, context ); +// sb.append( treatedPath.getWrappedPath().resolveAlias( context ) ); sb.append( " as " ).append( treatedPath.getTreatTarget().getTypeName() ).append( ')' ); } else { - sb.append( sqmFrom.resolveAlias() ); + sb.append( sqmFrom.resolveAlias( context ) ); } sb.append( '.' ).append( ( attributeJoin ).getAttribute().getName() ); - sb.append( ' ' ).append( sqmJoin.resolveAlias() ); + sb.append( ' ' ).append( sqmJoin.resolveAlias( context ) ); if ( attributeJoin.getJoinPredicate() != null ) { sb.append( " on " ); - attributeJoin.getJoinPredicate().appendHqlString( sb ); + attributeJoin.getJoinPredicate().appendHqlString( sb, context ); } - appendJoins( sqmJoin, sb ); + appendJoins( sqmJoin, sb, context ); } else if ( sqmJoin instanceof SqmCrossJoin sqmCrossJoin ) { sb.append( sqmCrossJoin.getEntityName() ); - sb.append( ' ' ).append( sqmCrossJoin.resolveAlias() ); - appendJoins( sqmJoin, sb ); + sb.append( ' ' ).append( sqmCrossJoin.resolveAlias( context ) ); + appendJoins( sqmJoin, sb, context ); } else if ( sqmJoin instanceof SqmEntityJoin sqmEntityJoin ) { sb.append( ( sqmEntityJoin ).getEntityName() ); - sb.append( ' ' ).append( sqmJoin.resolveAlias() ); + sb.append( ' ' ).append( sqmJoin.resolveAlias( context ) ); if ( sqmEntityJoin.getJoinPredicate() != null ) { sb.append( " on " ); - sqmEntityJoin.getJoinPredicate().appendHqlString( sb ); + sqmEntityJoin.getJoinPredicate().appendHqlString( sb, context ); } - appendJoins( sqmJoin, sb ); + appendJoins( sqmJoin, sb, context ); } else { throw new UnsupportedOperationException( "Unsupported join: " + sqmJoin ); @@ -172,22 +174,22 @@ else if ( sqmJoin instanceof SqmEntityJoin sqmEntityJoin ) { } } - private void appendJoins(SqmFrom sqmFrom, String correlationPrefix, StringBuilder sb) { + private void appendJoins(SqmFrom sqmFrom, String correlationPrefix, StringBuilder sb, SqmRenderContext context) { String separator = ""; for ( SqmJoin sqmJoin : sqmFrom.getSqmJoins() ) { assert sqmJoin instanceof SqmAttributeJoin; sb.append( separator ); sb.append( correlationPrefix ).append( '.' ); sb.append( ( (SqmAttributeJoin) sqmJoin ).getAttribute().getName() ); - sb.append( ' ' ).append( sqmJoin.resolveAlias() ); - appendJoins( sqmJoin, sb ); + sb.append( ' ' ).append( sqmJoin.resolveAlias( context ) ); + appendJoins( sqmJoin, sb, context ); separator = ", "; } } - public static void appendTreatJoins(SqmFrom sqmFrom, StringBuilder sb) { + public static void appendTreatJoins(SqmFrom sqmFrom, StringBuilder sb, SqmRenderContext context) { for ( SqmFrom sqmTreat : sqmFrom.getSqmTreats() ) { - appendJoins( sqmTreat, sb ); + appendJoins( sqmTreat, sb, context ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/AbstractSqmInsertStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/AbstractSqmInsertStatement.java index 6f013f295622..d1747a1b2eac 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/AbstractSqmInsertStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/AbstractSqmInsertStatement.java @@ -20,6 +20,7 @@ import org.hibernate.query.sqm.SqmQuerySource; import org.hibernate.query.sqm.tree.AbstractSqmDmlStatement; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; import org.hibernate.query.sqm.tree.domain.SqmPath; @@ -178,16 +179,16 @@ public JpaCriteriaInsert onConflict(@Nullable JpaConflictClause conflictCl } @Override - public void appendHqlString(StringBuilder hql) { - appendHqlCteString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + appendHqlCteString( hql, context ); hql.append( "insert into " ); hql.append( getTarget().getEntityName() ); if ( insertionTargetPaths != null && !insertionTargetPaths.isEmpty() ) { hql.append( '(' ); - insertionTargetPaths.get( 0 ).appendHqlString( hql ); + insertionTargetPaths.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < insertionTargetPaths.size(); i++ ) { hql.append( ", " ); - insertionTargetPaths.get( i ).appendHqlString( hql ); + insertionTargetPaths.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmConflictClause.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmConflictClause.java index b8221afd9efc..7ed156101a8b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmConflictClause.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmConflictClause.java @@ -14,6 +14,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmVisitableNode; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.from.SqmRoot; @@ -177,7 +178,7 @@ public X accept(SemanticQueryWalker walker) { return walker.visitConflictClause( this ); } - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( " on conflict" ); if ( constraintName != null ) { hql.append( " on constraint " ); @@ -196,7 +197,7 @@ else if ( !constraintPaths.isEmpty() ) { hql.append( " do nothing" ); } else { - updateAction.appendHqlString( hql ); + updateAction.appendHqlString( hql, context ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmConflictUpdateAction.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmConflictUpdateAction.java index 87ab4e4b6537..93543750dbd8 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmConflictUpdateAction.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmConflictUpdateAction.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.SqmNode; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.from.SqmRoot; @@ -156,13 +157,13 @@ private SqmRoot getTarget() { return insertStatement.getTarget(); } - public void appendHqlString(StringBuilder sb) { + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { sb.append( " do update" ); - setClause.appendHqlString( sb ); + setClause.appendHqlString( sb, context ); if ( whereClause != null && whereClause.getPredicate() != null ) { sb.append( " where " ); - whereClause.getPredicate().appendHqlString( sb ); + whereClause.getPredicate().appendHqlString( sb, context ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertSelectStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertSelectStatement.java index b72810a691fb..b1880dd02388 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertSelectStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertSelectStatement.java @@ -17,6 +17,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmQuerySource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.expression.SqmParameter; @@ -171,13 +172,13 @@ public SqmInsertSelectStatement onConflict(JpaConflictClause conflictClaus } @Override - public void appendHqlString(StringBuilder hql) { - super.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + super.appendHqlString( hql, context ); hql.append( ' ' ); - selectQueryPart.appendHqlString( hql ); - final SqmConflictClause conflictClause = getConflictClause(); + selectQueryPart.appendHqlString( hql, context ); + final SqmConflictClause conflictClause = getConflictClause(); if ( conflictClause != null ) { - conflictClause.appendHqlString( hql ); + conflictClause.appendHqlString( hql, context ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertValuesStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertValuesStatement.java index ad21e44d7ab6..c46c9deb4b64 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertValuesStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/insert/SqmInsertValuesStatement.java @@ -20,6 +20,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmQuerySource; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.expression.SqmExpression; @@ -190,29 +191,29 @@ public SqmInsertValuesStatement onConflict(JpaConflictClause conflictClaus } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { assert valuesList != null; - super.appendHqlString( hql ); + super.appendHqlString( hql, context ); hql.append( " values (" ); - appendValues( valuesList.get( 0 ), hql ); + appendValues( valuesList.get( 0 ), hql, context ); for ( int i = 1; i < valuesList.size(); i++ ) { hql.append( ", " ); - appendValues( valuesList.get( i ), hql ); + appendValues( valuesList.get( i ), hql, context ); } hql.append( ')' ); final SqmConflictClause conflictClause = getConflictClause(); if ( conflictClause != null ) { - conflictClause.appendHqlString( hql ); + conflictClause.appendHqlString( hql, context ); } } - private static void appendValues(SqmValues sqmValues, StringBuilder sb) { + private static void appendValues(SqmValues sqmValues, StringBuilder sb, SqmRenderContext context) { final List> expressions = sqmValues.getExpressions(); sb.append( '(' ); - expressions.get( 0 ).appendHqlString( sb ); + expressions.get( 0 ).appendHqlString( sb, context ); for ( int i = 1; i < expressions.size(); i++ ) { sb.append( ", " ); - expressions.get( i ).appendHqlString( sb ); + expressions.get( i ).appendHqlString( sb, context ); } sb.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmBetweenPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmBetweenPredicate.java index 899d011307a9..779610718d5a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmBetweenPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmBetweenPredicate.java @@ -9,6 +9,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; import static org.hibernate.query.sqm.internal.TypecheckUtil.assertComparable; @@ -84,15 +85,15 @@ public T accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - expression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + expression.appendHqlString( hql, context ); if ( isNegated() ) { hql.append( " not" ); } hql.append( " between " ); - lowerBound.appendHqlString( hql ); + lowerBound.appendHqlString( hql, context ); hql.append( " and " ); - upperBound.appendHqlString( hql ); + upperBound.appendHqlString( hql, context ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmBooleanExpressionPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmBooleanExpressionPredicate.java index b97a1e8c7289..5d6a40806ed1 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmBooleanExpressionPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmBooleanExpressionPredicate.java @@ -10,6 +10,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; import jakarta.persistence.criteria.Expression; @@ -77,8 +78,8 @@ public List> getExpressions() { } @Override - public void appendHqlString(StringBuilder hql) { - booleanExpression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + booleanExpression.appendHqlString( hql, context ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmComparisonPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmComparisonPredicate.java index b13ebdbe40d5..86f6b4931756 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmComparisonPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmComparisonPredicate.java @@ -10,6 +10,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; import static org.hibernate.query.sqm.internal.TypecheckUtil.assertComparable; @@ -108,11 +109,11 @@ public T accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - leftHandExpression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + leftHandExpression.appendHqlString( hql, context ); hql.append( ' ' ); hql.append( operator.sqlText() ); hql.append( ' ' ); - rightHandExpression.appendHqlString( hql ); + rightHandExpression.appendHqlString( hql, context ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmEmptinessPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmEmptinessPredicate.java index c7eb1d530adc..aff4553c57b9 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmEmptinessPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmEmptinessPredicate.java @@ -7,6 +7,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath; /** @@ -51,8 +52,8 @@ public T accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - pluralPath.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + pluralPath.appendHqlString( hql, context ); if ( isNegated() ) { hql.append( " is not empty" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmExistsPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmExistsPredicate.java index 2b3eafed0467..2212490da458 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmExistsPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmExistsPredicate.java @@ -7,6 +7,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; /** @@ -59,14 +60,14 @@ public T accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { if ( isNegated() ) { hql.append( "not exists " ); } else { hql.append( "exists " ); } - expression.appendHqlString( hql ); + expression.appendHqlString( hql, context ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmGroupedPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmGroupedPredicate.java index b3d2f5ba4513..53983d86c534 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmGroupedPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmGroupedPredicate.java @@ -12,6 +12,7 @@ import org.hibernate.query.sqm.tree.SqmCopyContext; import jakarta.persistence.criteria.Expression; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Steve Ebersole @@ -67,9 +68,9 @@ public SqmPredicate not() { return new SqmNegatedPredicate( this, nodeBuilder() ); } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( '(' ); - subPredicate.appendHqlString( hql ); + subPredicate.appendHqlString( hql, context ); hql.append( ')' ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmInListPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmInListPredicate.java index 2110276eec41..f26a653a1551 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmInListPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmInListPredicate.java @@ -14,6 +14,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; import jakarta.persistence.criteria.Expression; @@ -146,16 +147,16 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - testExpression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + testExpression.appendHqlString( hql, context ); if ( isNegated() ) { hql.append( " not" ); } hql.append( " in (" ); - listExpressions.get( 0 ).appendHqlString( hql ); + listExpressions.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < listExpressions.size(); i++ ) { hql.append( ", " ); - listExpressions.get( i ).appendHqlString( hql ); + listExpressions.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmInSubQueryPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmInSubQueryPredicate.java index cec49c3b55f9..e4e0b9b8b96e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmInSubQueryPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmInSubQueryPredicate.java @@ -10,6 +10,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.select.SqmSubQuery; @@ -105,13 +106,13 @@ public SqmInPredicate value(JpaExpression value) { } @Override - public void appendHqlString(StringBuilder hql) { - testExpression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + testExpression.appendHqlString( hql, context ); if ( isNegated() ) { hql.append( " not" ); } hql.append( " in " ); - subQueryExpression.appendHqlString( hql ); + subQueryExpression.appendHqlString( hql, context ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmJunctionPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmJunctionPredicate.java index 3668ed1739ce..418fc48399ed 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmJunctionPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmJunctionPredicate.java @@ -13,6 +13,7 @@ import org.hibernate.query.sqm.tree.SqmCopyContext; import jakarta.persistence.criteria.Expression; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Steve Ebersole @@ -103,32 +104,32 @@ public SqmPredicate not() { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { final String separator = booleanOperator == BooleanOperator.AND ? " and " : " or "; - appendJunctionHqlString( predicates.get( 0 ), hql ); + appendJunctionHqlString( predicates.get( 0 ), hql, context ); for ( int i = 1; i < predicates.size(); i++ ) { hql.append( separator ); - appendJunctionHqlString( predicates.get( i ), hql ); + appendJunctionHqlString( predicates.get( i ), hql, context ); } } - private void appendJunctionHqlString(SqmPredicate p, StringBuilder sb) { + private void appendJunctionHqlString(SqmPredicate p, StringBuilder sb, SqmRenderContext context) { if ( p instanceof SqmJunctionPredicate junction ) { // If we have the same nature, or if this is a disjunction and the operand is a conjunction, // then we don't need parenthesis, because the AND operator binds stronger if ( booleanOperator == junction.getOperator() || booleanOperator == BooleanOperator.OR ) { - junction.appendHqlString( sb ); + junction.appendHqlString( sb, context ); } else { sb.append( '(' ); - junction.appendHqlString( sb ); + junction.appendHqlString( sb, context ); sb.append( ')' ); } } else { - p.appendHqlString( sb ); + p.appendHqlString( sb, context ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmLikePredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmLikePredicate.java index b16a86805eb0..e81663f7b3ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmLikePredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmLikePredicate.java @@ -9,6 +9,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; import static org.hibernate.query.sqm.internal.TypecheckUtil.assertString; @@ -126,16 +127,16 @@ public T accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - matchExpression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + matchExpression.appendHqlString( hql, context ); if ( isNegated() ) { hql.append( " not" ); } hql.append( " like " ); - pattern.appendHqlString( hql ); + pattern.appendHqlString( hql, context ); if ( escapeCharacter != null ) { hql.append( " escape " ); - escapeCharacter.appendHqlString( hql ); + escapeCharacter.appendHqlString( hql, context ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmMemberOfPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmMemberOfPredicate.java index 1946a3eb7db5..795e7c2e6b3b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmMemberOfPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmMemberOfPredicate.java @@ -9,6 +9,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath; import org.hibernate.query.sqm.tree.expression.SqmExpression; @@ -85,13 +86,13 @@ public T accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - leftHandExpression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + leftHandExpression.appendHqlString( hql, context ); if ( isNegated() ) { hql.append( " not" ); } hql.append( " member of " ); - pluralPath.appendHqlString( hql ); + pluralPath.appendHqlString( hql, context ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmNegatedPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmNegatedPredicate.java index 5e02b035f086..9b22d8f36eb4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmNegatedPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmNegatedPredicate.java @@ -12,6 +12,7 @@ import org.hibernate.query.sqm.tree.SqmCopyContext; import jakarta.persistence.criteria.Expression; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * @author Steve Ebersole @@ -67,9 +68,9 @@ public T accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "not (" ); - wrappedPredicate.appendHqlString( hql ); + wrappedPredicate.appendHqlString( hql, context ); hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmNullnessPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmNullnessPredicate.java index 64ff613d42c8..d8324031e365 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmNullnessPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmNullnessPredicate.java @@ -7,6 +7,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; /** @@ -52,8 +53,8 @@ public T accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - expression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + expression.appendHqlString( hql, context ); if ( isNegated() ) { hql.append( " is not null" ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmTruthnessPredicate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmTruthnessPredicate.java index 4c7c522df2c2..bd377c34a4db 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmTruthnessPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/predicate/SqmTruthnessPredicate.java @@ -7,6 +7,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; /** @@ -55,8 +56,8 @@ public T accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - expression.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + expression.appendHqlString( hql, context ); hql.append(" is "); if ( isNegated() ) { hql.append( "not " ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/AbstractSqmSelectQuery.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/AbstractSqmSelectQuery.java index f00f4410a65e..347938dd3d15 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/AbstractSqmSelectQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/AbstractSqmSelectQuery.java @@ -22,6 +22,7 @@ import org.hibernate.query.sqm.spi.SqmCreationHelper; import org.hibernate.query.sqm.tree.AbstractSqmNode; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; import org.hibernate.query.sqm.tree.domain.SqmCteRoot; import org.hibernate.query.sqm.tree.domain.SqmDerivedRoot; @@ -403,16 +404,16 @@ public SqmSelectQuery having(Predicate... predicates) { return this; } - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { if ( !cteStatements.isEmpty() ) { hql.append( "with " ); for ( SqmCteStatement value : cteStatements.values() ) { - value.appendHqlString( hql ); + value.appendHqlString( hql, context ); hql.append( ", " ); } hql.setLength( hql.length() - 2 ); } - sqmQueryPart.appendHqlString( hql ); + sqmQueryPart.appendHqlString( hql, context ); } @SuppressWarnings("unchecked") diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmDynamicInstantiation.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmDynamicInstantiation.java index ef1b151ab332..2c40219f9908 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmDynamicInstantiation.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmDynamicInstantiation.java @@ -15,6 +15,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.domain.SqmDomainType; import org.hibernate.query.sqm.tree.jpa.AbstractJpaSelection; @@ -272,7 +273,7 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( "new " ); if ( instantiationTarget.getNature() == LIST ) { hql.append( "list" ); @@ -284,10 +285,10 @@ else if ( instantiationTarget.getNature() == MAP ) { hql.append( instantiationTarget.getTargetTypeDescriptor().getJavaTypeClass().getTypeName() ); } hql.append( '(' ); - arguments.get( 0 ).appendHqlString( hql ); + arguments.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < arguments.size(); i++ ) { hql.append(", "); - arguments.get( i ).appendHqlString( hql ); + arguments.get( i ).appendHqlString( hql, context ); } hql.append( ')' ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmDynamicInstantiationArgument.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmDynamicInstantiationArgument.java index 24012a43de57..02c04eb8ccce 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmDynamicInstantiationArgument.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmDynamicInstantiationArgument.java @@ -7,6 +7,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * Represents an individual argument to a dynamic instantiation. @@ -56,8 +57,8 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - selectableNode.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + selectableNode.appendHqlString( hql, context ); if ( alias != null ) { hql.append( " as " ).append( alias ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmJpaCompoundSelection.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmJpaCompoundSelection.java index 194b95565897..8dc32cb0012b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmJpaCompoundSelection.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmJpaCompoundSelection.java @@ -14,6 +14,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.AbstractSqmExpression; import org.hibernate.query.sqm.tree.domain.SqmDomainType; import org.hibernate.type.descriptor.java.JavaType; @@ -136,11 +137,11 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - selectableNodes.get( 0 ).appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + selectableNodes.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < selectableNodes.size(); i++ ) { hql.append(", "); - selectableNodes.get( i ).appendHqlString( hql ); + selectableNodes.get( i ).appendHqlString( hql, context ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQueryGroup.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQueryGroup.java index 93af8b7a26ba..45dddd6d054d 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQueryGroup.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQueryGroup.java @@ -19,6 +19,7 @@ import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.from.SqmAttributeJoin; import org.hibernate.query.sqm.tree.from.SqmFrom; @@ -221,23 +222,23 @@ private void validateFetchesMatch(SqmFrom firstFrom, SqmFrom from) { } @Override - public void appendHqlString(StringBuilder hql) { - appendQueryPart( queryParts.get( 0 ), hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + appendQueryPart( queryParts.get( 0 ), hql, context ); for ( int i = 1; i < queryParts.size(); i++ ) { hql.append( ' ' ); hql.append( setOperator.sqlString() ); hql.append( ' ' ); - appendQueryPart( queryParts.get( i ), hql ); + appendQueryPart( queryParts.get( i ), hql, context ); } - super.appendHqlString( hql ); + super.appendHqlString( hql, context ); } - private static void appendQueryPart(SqmQueryPart queryPart, StringBuilder sb) { + private static void appendQueryPart(SqmQueryPart queryPart, StringBuilder sb, SqmRenderContext context) { final boolean needsParenthesis = !queryPart.isSimpleQueryPart(); if ( needsParenthesis ) { sb.append( '(' ); } - queryPart.appendHqlString( sb ); + queryPart.appendHqlString( sb, context ); if ( needsParenthesis ) { sb.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQueryPart.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQueryPart.java index eae28709a7e9..df3a77fece26 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQueryPart.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQueryPart.java @@ -12,6 +12,7 @@ import org.hibernate.query.criteria.JpaQueryPart; import org.hibernate.query.sqm.NodeBuilder; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.SqmVisitableNode; import org.hibernate.query.sqm.tree.expression.SqmExpression; @@ -173,26 +174,26 @@ public JpaQueryPart setFetch(JpaExpression fetch, FetchClau public abstract void validateQueryStructureAndFetchOwners(); - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { if ( orderByClause == null || orderByClause.getSortSpecifications().isEmpty() ) { return; } hql.append( " order by " ); final List sortSpecifications = orderByClause.getSortSpecifications(); - sortSpecifications.get( 0 ).appendHqlString( hql ); + sortSpecifications.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < sortSpecifications.size(); i++ ) { hql.append( ", " ); - sortSpecifications.get( i ).appendHqlString( hql ); + sortSpecifications.get( i ).appendHqlString( hql, context ); } if ( offsetExpression != null ) { hql.append( " offset " ); - offsetExpression.appendHqlString( hql ); + offsetExpression.appendHqlString( hql, context ); hql.append( " rows " ); } if ( fetchExpression != null ) { hql.append( " fetch first " ); - fetchExpression.appendHqlString( hql ); + fetchExpression.appendHqlString( hql, context ); switch ( fetchClauseType ) { case ROWS_ONLY: hql.append( " rows only" ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQuerySpec.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQuerySpec.java index a4c2c54bda04..d6b45f9dbba1 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQuerySpec.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmQuerySpec.java @@ -28,6 +28,7 @@ import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.SqmNode; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath; import org.hibernate.query.sqm.tree.expression.SqmAliasedNodeRef; @@ -587,41 +588,41 @@ private void assertEmbeddableCollections(NavigablePath navigablePath, Embeddable } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { if ( selectClause != null ) { hql.append( "select " ); if ( selectClause.isDistinct() ) { hql.append( "distinct " ); } final List> selections = selectClause.getSelections(); - selections.get( 0 ).appendHqlString( hql ); + selections.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < selections.size(); i++ ) { hql.append( ", " ); - selections.get( i ).appendHqlString( hql ); + selections.get( i ).appendHqlString( hql, context ); } } if ( fromClause != null ) { hql.append( " from" ); - fromClause.appendHqlString( hql ); + fromClause.appendHqlString( hql, context ); } if ( whereClause != null && whereClause.getPredicate() != null ) { hql.append( " where " ); - whereClause.getPredicate().appendHqlString( hql ); + whereClause.getPredicate().appendHqlString( hql, context ); } if ( !groupByClauseExpressions.isEmpty() ) { hql.append( " group by " ); - groupByClauseExpressions.get( 0 ).appendHqlString( hql ); + groupByClauseExpressions.get( 0 ).appendHqlString( hql, context ); for ( int i = 1; i < groupByClauseExpressions.size(); i++ ) { hql.append( ", " ); - groupByClauseExpressions.get( i ).appendHqlString( hql ); + groupByClauseExpressions.get( i ).appendHqlString( hql, context ); } } if ( havingClausePredicate != null ) { hql.append( " having " ); - havingClausePredicate.appendHqlString( hql ); + havingClausePredicate.appendHqlString( hql, context ); } - super.appendHqlString( hql ); + super.appendHqlString( hql, context ); } @Internal diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelection.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelection.java index 49edde8edd75..97c0113845c9 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelection.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSelection.java @@ -8,6 +8,7 @@ import org.hibernate.query.sqm.SemanticQueryWalker; import org.hibernate.query.sqm.tree.AbstractSqmNode; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; /** * Represents an individual selection within a select clause. @@ -61,8 +62,8 @@ public X accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { - selectableNode.appendHqlString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + selectableNode.appendHqlString( hql, context ); if ( alias != null ) { hql.append( " as " ).append( alias ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSortSpecification.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSortSpecification.java index fa8fc4611541..66319c5dfc83 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSortSpecification.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSortSpecification.java @@ -11,6 +11,7 @@ import org.hibernate.query.criteria.JpaExpression; import org.hibernate.query.criteria.JpaOrder; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.expression.SqmExpression; import jakarta.persistence.criteria.Nulls; @@ -115,8 +116,8 @@ public boolean isAscending() { return sortOrder == SortDirection.ASCENDING; } - public void appendHqlString(StringBuilder sb) { - sortExpression.appendHqlString( sb ); + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { + sortExpression.appendHqlString( sb, context ); if ( sortOrder == SortDirection.DESCENDING ) { sb.append( " desc" ); if ( nullPrecedence != null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSubQuery.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSubQuery.java index e46d8f3cc5e4..37063efacade 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSubQuery.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/select/SqmSubQuery.java @@ -30,6 +30,7 @@ import org.hibernate.query.sqm.SqmExpressible; import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.SqmQuery; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.cte.SqmCteContainer; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; import org.hibernate.query.sqm.tree.domain.SqmBagJoin; @@ -764,9 +765,9 @@ public T1 accept(SemanticQueryWalker walker) { } @Override - public void appendHqlString(StringBuilder hql) { + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { hql.append( '(' ); - super.appendHqlString( hql ); + super.appendHqlString( hql, context ); hql.append( ')' ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmSetClause.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmSetClause.java index 84a12fe2366d..6b7c3f6f7c40 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmSetClause.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmSetClause.java @@ -9,6 +9,7 @@ import java.util.List; import org.hibernate.query.sqm.tree.SqmCopyContext; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.expression.SqmExpression; @@ -46,18 +47,18 @@ public void addAssignment(SqmPath targetPath, SqmExpression addAssignment( new SqmAssignment<>( targetPath, value ) ); } - public void appendHqlString(StringBuilder sb) { + public void appendHqlString(StringBuilder sb, SqmRenderContext context) { sb.append( " set " ); - appendAssignment( assignments.get( 0 ), sb ); + appendAssignment( assignments.get( 0 ), sb, context ); for ( int i = 1; i < assignments.size(); i++ ) { sb.append( ", " ); - appendAssignment( assignments.get( i ), sb ); + appendAssignment( assignments.get( i ), sb, context ); } } - private static void appendAssignment(SqmAssignment sqmAssignment, StringBuilder sb) { - sqmAssignment.getTargetPath().appendHqlString( sb ); + private static void appendAssignment(SqmAssignment sqmAssignment, StringBuilder sb, SqmRenderContext context) { + sqmAssignment.getTargetPath().appendHqlString( sb, context ); sb.append( " = " ); - sqmAssignment.getValue().appendHqlString( sb ); + sqmAssignment.getValue().appendHqlString( sb, context ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmUpdateStatement.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmUpdateStatement.java index 160d771fcfaa..2d2aef82d27d 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmUpdateStatement.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/update/SqmUpdateStatement.java @@ -24,6 +24,7 @@ import org.hibernate.query.sqm.tree.AbstractSqmRestrictedDmlStatement; import org.hibernate.query.sqm.tree.SqmCopyContext; import org.hibernate.query.sqm.tree.SqmDeleteOrUpdateStatement; +import org.hibernate.query.sqm.tree.SqmRenderContext; import org.hibernate.query.sqm.tree.cte.SqmCteStatement; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPolymorphicRootDescriptor; @@ -271,19 +272,19 @@ public void applyAssignment(SqmAssignment assignment) { } @Override - public void appendHqlString(StringBuilder hql) { - appendHqlCteString( hql ); + public void appendHqlString(StringBuilder hql, SqmRenderContext context) { + appendHqlCteString( hql, context ); hql.append( "update " ); if ( versioned ) { hql.append( "versioned " ); } final SqmRoot root = getTarget(); hql.append( root.getEntityName() ); - hql.append( ' ' ).append( root.resolveAlias() ); - SqmFromClause.appendJoins( root, hql ); - SqmFromClause.appendTreatJoins( root, hql ); - setClause.appendHqlString( hql ); + hql.append( ' ' ).append( root.resolveAlias( context ) ); + SqmFromClause.appendJoins( root, hql, context ); + SqmFromClause.appendTreatJoins( root, hql, context ); + setClause.appendHqlString( hql, context ); - super.appendHqlString( hql ); + super.appendHqlString( hql, context ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/QueryPlanCachingTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/QueryPlanCachingTest.java index d316663586dc..848dc8d2d0f3 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/QueryPlanCachingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/QueryPlanCachingTest.java @@ -4,8 +4,12 @@ */ package org.hibernate.orm.test.query.hql; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.orm.test.mapping.SmokeTests; +import org.hibernate.query.criteria.HibernateCriteriaBuilder; +import org.hibernate.query.criteria.JpaCriteriaQuery; +import org.hibernate.query.criteria.JpaRoot; import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.SessionFactory; @@ -28,4 +32,23 @@ public void testHqlTranslationCaching(SessionFactoryScope scope) { } ); } + + @Test + public void testCriteriaTranslationCaching(SessionFactoryScope scope) { + scope.inTransaction( + session -> { + session.setCriteriaPlanCacheEnabled( true ); + session.createQuery( constructCriteriaQuery( session ) ).list(); + session.createQuery( constructCriteriaQuery( session ) ).list(); + } + ); + } + + private static JpaCriteriaQuery constructCriteriaQuery(SessionImplementor session) { + final HibernateCriteriaBuilder cb = session.getCriteriaBuilder(); + final JpaCriteriaQuery query = cb.createQuery( SmokeTests.SimpleEntity.class ); + final JpaRoot root = query.from( SmokeTests.SimpleEntity.class ); + query.select( root ); + return query; + } }