Skip to content

Commit dfaff4b

Browse files
committed
HHH-19334 fix CCE when tuple passed to HQL position() function
1 parent 47c0c49 commit dfaff4b

File tree

2 files changed

+47
-32
lines changed

2 files changed

+47
-32
lines changed

hibernate-core/src/main/java/org/hibernate/query/sqm/produce/function/ArgumentTypesValidator.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.hibernate.metamodel.MappingMetamodel;
1212
import org.hibernate.metamodel.mapping.JdbcMapping;
1313
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
14+
import org.hibernate.metamodel.model.domain.TupleType;
1415
import org.hibernate.query.BindingContext;
1516
import org.hibernate.query.sqm.SqmExpressible;
1617
import org.hibernate.query.sqm.tree.SqmTypedNode;
@@ -76,10 +77,13 @@ public void validate(
7677
int count = 0;
7778
for (SqmTypedNode<?> argument : arguments) {
7879
// JdbcTypeIndicators indicators = typeConfiguration.getCurrentBaseSqlTypeIndicators();
79-
SqmExpressible<?> nodeType = argument.getNodeType();
80-
FunctionParameterType type = count < types.length ? types[count++] : types[types.length - 1];
80+
final SqmExpressible<?> nodeType = argument.getNodeType();
81+
final FunctionParameterType type = count < types.length ? types[count++] : types[types.length - 1];
8182
if ( nodeType != null && type != FunctionParameterType.ANY ) {
82-
JavaType<?> javaType = nodeType.getRelationalJavaType();
83+
if ( nodeType instanceof TupleType<?> ) {
84+
throwTupleError(type, functionName, count);
85+
}
86+
final JavaType<?> javaType = nodeType.getRelationalJavaType();
8387
if (javaType != null) {
8488
checkArgumentType( functionName, count, argument, type, javaType );
8589
}
@@ -289,6 +293,18 @@ private static void throwError(
289293
}
290294
}
291295

296+
private static void throwTupleError(
297+
FunctionParameterType type, String functionName, int paramNumber) {
298+
throw new FunctionArgumentException(
299+
String.format(
300+
"Parameter %d of function '%s()' has type '%s', but argument is a tuple",
301+
paramNumber,
302+
functionName,
303+
type
304+
)
305+
);
306+
}
307+
292308
@Override
293309
public String getSignature() {
294310
String sig = delegate.getSignature();

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

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5965,8 +5965,8 @@ else if ( binaryArithmetic.getRightHandOperand().getNodeType() == nodeType ) {
59655965
protected MappingModelExpressible<?> getInferredValueMapping() {
59665966
final MappingModelExpressible<?> inferredMapping = resolveInferredType();
59675967
if ( inferredMapping != null ) {
5968-
if ( inferredMapping instanceof PluralAttributeMapping ) {
5969-
return ( (PluralAttributeMapping) inferredMapping ).getElementDescriptor();
5968+
if ( inferredMapping instanceof PluralAttributeMapping pluralAttributeMapping ) {
5969+
return pluralAttributeMapping.getElementDescriptor();
59705970
}
59715971
else if ( !( inferredMapping instanceof JavaObjectType ) ) {
59725972
// Never report back the "object type" as inferred type and instead rely on the value type
@@ -6070,8 +6070,8 @@ else if ( paramType instanceof EntityDomainType ) {
60706070
// Try to infer the value mapping since the other side apparently is a path source
60716071
final MappingModelExpressible<?> inferredMapping = resolveInferredType();
60726072
if ( inferredMapping != null ) {
6073-
if ( inferredMapping instanceof PluralAttributeMapping ) {
6074-
return resolveInferredValueMappingForParameter( ( (PluralAttributeMapping) inferredMapping ).getElementDescriptor() );
6073+
if ( inferredMapping instanceof PluralAttributeMapping pluralAttributeMapping ) {
6074+
return resolveInferredValueMappingForParameter( pluralAttributeMapping.getElementDescriptor() );
60756075
}
60766076
else if ( !( inferredMapping instanceof JavaObjectType ) ) {
60776077
// Do not report back the "object type" as inferred type and instead try to rely on the paramSqmType.getExpressibleJavaType()
@@ -6263,23 +6263,8 @@ public Object visitTuple(SqmTuple<?> sqmTuple) {
62636263
final List<SqmExpression<?>> groupedExpressions = sqmTuple.getGroupedExpressions();
62646264
final int size = groupedExpressions.size();
62656265
final List<Expression> expressions = new ArrayList<>( size );
6266-
final MappingModelExpressible<?> mappingModelExpressible = resolveInferredType();
6267-
final EmbeddableMappingType embeddableMappingType =
6268-
mappingModelExpressible instanceof ValueMapping valueMapping
6269-
? (EmbeddableMappingType) valueMapping.getMappedType()
6270-
: null;
6271-
if ( embeddableMappingType == null ) {
6272-
try {
6273-
inferrableTypeAccessStack.push( () -> null );
6274-
for ( int i = 0; i < size; i++ ) {
6275-
expressions.add( (Expression) groupedExpressions.get( i ).accept( this ) );
6276-
}
6277-
}
6278-
finally {
6279-
inferrableTypeAccessStack.pop();
6280-
}
6281-
}
6282-
else {
6266+
if ( resolveInferredType() instanceof ValueMapping valueMapping
6267+
&& valueMapping.getMappedType() instanceof EmbeddableMappingType embeddableMappingType ) {
62836268
for ( int i = 0; i < size; i++ ) {
62846269
final AttributeMapping attributeMapping = embeddableMappingType.getAttributeMapping( i );
62856270
inferrableTypeAccessStack.push( () -> attributeMapping );
@@ -6291,17 +6276,31 @@ public Object visitTuple(SqmTuple<?> sqmTuple) {
62916276
}
62926277
}
62936278
}
6294-
final MappingModelExpressible<?> valueMapping;
6295-
if ( mappingModelExpressible != null ) {
6296-
valueMapping = mappingModelExpressible;
6279+
else {
6280+
try {
6281+
inferrableTypeAccessStack.push( () -> null );
6282+
for ( int i = 0; i < size; i++ ) {
6283+
expressions.add( (Expression) groupedExpressions.get( i ).accept( this ) );
6284+
}
6285+
}
6286+
finally {
6287+
inferrableTypeAccessStack.pop();
6288+
}
6289+
}
6290+
return new SqlTuple( expressions, tupleValueMapping( sqmTuple ) );
6291+
}
6292+
6293+
private MappingModelExpressible<?> tupleValueMapping(SqmTuple<?> sqmTuple) {
6294+
final MappingModelExpressible<?> inferredType = resolveInferredType();
6295+
if ( inferredType != null ) {
6296+
return inferredType;
6297+
}
6298+
else if ( sqmTuple.getExpressible() instanceof MappingModelExpressible<?> modelExpressible ) {
6299+
return modelExpressible;
62976300
}
62986301
else {
6299-
valueMapping =
6300-
sqmTuple.getExpressible() instanceof MappingModelExpressible<?> modelExpressible
6301-
? modelExpressible
6302-
: null;
6302+
return null;
63036303
}
6304-
return new SqlTuple( expressions, valueMapping );
63056304
}
63066305

63076306
@Override

0 commit comments

Comments
 (0)