diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/SqlFunction.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/SqlFunction.java index 047456bc8e48..ab3303249b89 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/SqlFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/SqlFunction.java @@ -5,16 +5,22 @@ package org.hibernate.dialect.function; import java.util.List; +import java.util.function.Supplier; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.metamodel.model.domain.ReturnableType; import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor; +import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver; import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators; -import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers; +import org.hibernate.query.sqm.sql.SqmToSqlAstConverter; +import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.sql.ast.SqlAstTranslator; import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.sql.ast.tree.SqlAstNode; import org.hibernate.sql.ast.tree.expression.QueryLiteral; import org.hibernate.type.JavaObjectType; +import org.hibernate.type.spi.TypeConfiguration; /** * A function to pass through a SQL fragment. @@ -28,7 +34,24 @@ public SqlFunction() { super( "sql", StandardArgumentsValidators.min( 1 ), - StandardFunctionReturnTypeResolvers.invariant( JavaObjectType.INSTANCE ), + new FunctionReturnTypeResolver() { + @Override + public ReturnableType resolveFunctionReturnType( + ReturnableType impliedType, + @Nullable SqmToSqlAstConverter converter, + List> arguments, + TypeConfiguration typeConfiguration) { + return impliedType != null + ? impliedType + : typeConfiguration.getBasicTypeForJavaType( Object.class ); + } + + @Override + public BasicValuedMapping resolveFunctionReturnType(Supplier impliedTypeAccess, List arguments) { + final BasicValuedMapping impliedType = impliedTypeAccess.get(); + return impliedType != null ? impliedType : JavaObjectType.INSTANCE; + } + }, null ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java index ccacc8d58916..00767e558a4f 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeQueryImpl.java @@ -1005,13 +1005,10 @@ public static int determineBindValueMaxCount(boolean paddingEnabled, int inExprL } private SelectInterpretationsKey selectInterpretationsKey(ResultSetMapping resultSetMapping) { - final QueryOptions options = getQueryOptions(); return new SelectInterpretationsKey( getQueryString(), resultSetMapping, - getSynchronizedQuerySpaces(), - options.getTupleTransformer(), - options.getResultListTransformer() + getSynchronizedQuerySpaces() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/SelectInterpretationsKey.java b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/SelectInterpretationsKey.java index 77be9276835b..da7c3864f1ec 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/spi/SelectInterpretationsKey.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/spi/SelectInterpretationsKey.java @@ -20,21 +20,25 @@ public class SelectInterpretationsKey implements QueryInterpretationCache.Key { private final String sql; private final JdbcValuesMappingProducer jdbcValuesMappingProducer; private final Collection querySpaces; - private final TupleTransformer tupleTransformer; - private final ResultListTransformer resultListTransformer; private final int hash; + @Deprecated(forRemoval = true) public SelectInterpretationsKey( String sql, JdbcValuesMappingProducer jdbcValuesMappingProducer, Collection querySpaces, TupleTransformer tupleTransformer, ResultListTransformer resultListTransformer) { + this( sql, jdbcValuesMappingProducer, querySpaces ); + } + + public SelectInterpretationsKey( + String sql, + JdbcValuesMappingProducer jdbcValuesMappingProducer, + Collection querySpaces) { this.sql = sql; this.jdbcValuesMappingProducer = jdbcValuesMappingProducer; this.querySpaces = querySpaces; - this.tupleTransformer = tupleTransformer; - this.resultListTransformer = resultListTransformer; this.hash = generateHashCode(); } @@ -42,14 +46,10 @@ private SelectInterpretationsKey( String sql, JdbcValuesMappingProducer jdbcValuesMappingProducer, Collection querySpaces, - TupleTransformer tupleTransformer, - ResultListTransformer resultListTransformer, int hash) { this.sql = sql; this.jdbcValuesMappingProducer = jdbcValuesMappingProducer; this.querySpaces = querySpaces; - this.tupleTransformer = tupleTransformer; - this.resultListTransformer = resultListTransformer; this.hash = hash; } @@ -64,8 +64,6 @@ public QueryInterpretationCache.Key prepareForStore() { sql, jdbcValuesMappingProducer.cacheKeyInstance(), new HashSet<>( querySpaces ), - tupleTransformer, - resultListTransformer, hash ); } @@ -89,8 +87,6 @@ public boolean equals(Object o) { } return sql.equals( that.sql ) && Objects.equals( jdbcValuesMappingProducer, that.jdbcValuesMappingProducer ) - && Objects.equals( querySpaces, that.querySpaces ) - && Objects.equals( tupleTransformer, that.tupleTransformer ) - && Objects.equals( resultListTransformer, that.resultListTransformer ); + && Objects.equals( querySpaces, that.querySpaces ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java index aa1f876fd69c..1fdd79ec3585 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/ConcreteSqmSelectQueryPlan.java @@ -75,7 +75,6 @@ public class ConcreteSqmSelectQueryPlan implements SelectQueryPlan { private final SqmSelectStatement sqm; private final DomainParameterXref domainParameterXref; - private final RowTransformer rowTransformer; private final SqmInterpreter> executeQueryInterpreter; private final SqmInterpreter, Void> listInterpreter; private final SqmInterpreter, ScrollMode> scrollInterpreter; @@ -92,8 +91,6 @@ public ConcreteSqmSelectQueryPlan( this.sqm = sqm; this.domainParameterXref = domainParameterXref; - this.rowTransformer = determineRowTransformer( sqm, resultType, tupleMetadata, queryOptions ); - final ListResultsConsumer.UniqueSemantic uniqueSemantic = sqm.producesUniqueResults() && !containsCollectionFetches( queryOptions ) ? ListResultsConsumer.UniqueSemantic.NONE @@ -118,7 +115,7 @@ public ConcreteSqmSelectQueryPlan( jdbcSelect, jdbcParameterBindings, listInterpreterExecutionContext( hql, executionContext, jdbcSelect, subSelectFetchKeyHandler ), - rowTransformer, + determineRowTransformer( sqm, resultType, tupleMetadata, executionContext.getQueryOptions() ), null, resultCountEstimate, resultsConsumer @@ -150,7 +147,7 @@ public ConcreteSqmSelectQueryPlan( jdbcSelect, jdbcParameterBindings, listInterpreterExecutionContext( hql, executionContext, jdbcSelect, subSelectFetchKeyHandler ), - rowTransformer, + determineRowTransformer( sqm, resultType, tupleMetadata, executionContext.getQueryOptions() ), (Class) executionContext.getResultType(), uniqueSemantic, resultCountEstimate @@ -186,7 +183,7 @@ public ConcreteSqmSelectQueryPlan( scrollMode, jdbcParameterBindings, new SqmJdbcExecutionContextAdapter( executionContext, jdbcSelect ), - rowTransformer, + determineRowTransformer( sqm, resultType, tupleMetadata, executionContext.getQueryOptions() ), resultCountEstimate ); } 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 4cc6212eafc2..3db3cb126864 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 @@ -9,8 +9,6 @@ import java.util.Set; import org.hibernate.LockOptions; -import org.hibernate.query.ResultListTransformer; -import org.hibernate.query.TupleTransformer; import org.hibernate.query.spi.QueryInterpretationCache; import org.hibernate.query.sqm.spi.InterpretationsKeySource; @@ -28,8 +26,6 @@ public static SqmInterpretationsKey createInterpretationsKey(InterpretationsKeyS query.hashCode(), keySource.getResultType(), keySource.getQueryOptions().getLockOptions(), - keySource.getQueryOptions().getTupleTransformer(), - keySource.getQueryOptions().getResultListTransformer(), memoryEfficientDefensiveSetCopy( keySource.getLoadQueryInfluencers().getEnabledFetchProfileNames() ) ); } @@ -86,8 +82,6 @@ public static QueryInterpretationCache.Key generateNonSelectKey(InterpretationsK private final Object query; private final Class resultType; private final LockOptions lockOptions; - private final TupleTransformer tupleTransformer; - private final ResultListTransformer resultListTransformer; private final Collection enabledFetchProfiles; private final int hashCode; @@ -96,15 +90,11 @@ private SqmInterpretationsKey( int hash, Class resultType, LockOptions lockOptions, - TupleTransformer tupleTransformer, - ResultListTransformer resultListTransformer, Collection enabledFetchProfiles) { this.query = query; this.hashCode = hash; this.resultType = resultType; this.lockOptions = lockOptions; - this.tupleTransformer = tupleTransformer; - this.resultListTransformer = resultListTransformer; this.enabledFetchProfiles = enabledFetchProfiles; } @@ -116,8 +106,6 @@ public QueryInterpretationCache.Key prepareForStore() { resultType, // Since lock options might be mutable, we need a copy for the cache key lockOptions.makeDefensiveCopy(), - tupleTransformer, - resultListTransformer, enabledFetchProfiles ); } @@ -139,8 +127,6 @@ public boolean equals(Object other) { && this.query.equals( that.query ) && Objects.equals( this.resultType, that.resultType ) && Objects.equals( this.lockOptions, that.lockOptions ) - && Objects.equals( this.tupleTransformer, that.tupleTransformer ) - && Objects.equals( this.resultListTransformer, that.resultListTransformer ) && Objects.equals( this.enabledFetchProfiles, that.enabledFetchProfiles ); }