HHH-18851 Fix parameter type inference issue when IN predicate is uses array_contains()

This commit is contained in:
Christian Beikov 2024-11-15 13:56:54 +01:00
parent 26ed1e29ff
commit 47f1a1207a
3 changed files with 33 additions and 6 deletions

View File

@ -43,10 +43,15 @@ public class ArrayContainsArgumentTypeResolver extends AbstractFunctionArgumentT
} }
} }
else if ( argumentIndex == 1 ) { else if ( argumentIndex == 1 ) {
final SqmTypedNode<?> nodeToResolve = arguments.get( 1 );
if ( nodeToResolve.getExpressible() instanceof MappingModelExpressible<?> ) {
// If the node already has suitable type, don't infer it to be treated as an array
return null;
}
final SqmTypedNode<?> node = arguments.get( 0 ); final SqmTypedNode<?> node = arguments.get( 0 );
if ( node instanceof SqmExpression<?> ) { if ( node instanceof SqmExpression<?> ) {
final MappingModelExpressible<?> expressible = converter.determineValueMapping( (SqmExpression<?>) node ); final MappingModelExpressible<?> expressible = converter.determineValueMapping( (SqmExpression<?>) node );
if ( expressible != null ) { if ( expressible instanceof BasicPluralType<?, ?> ) {
return expressible; return expressible;
} }
} }

View File

@ -3391,13 +3391,16 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
final SqmExpression<?> arrayExpr = (SqmExpression<?>) arrayInListContext.expression().accept( this ); final SqmExpression<?> arrayExpr = (SqmExpression<?>) arrayInListContext.expression().accept( this );
final SqmExpressible<?> arrayExpressible = arrayExpr.getExpressible(); final SqmExpressible<?> arrayExpressible = arrayExpr.getExpressible();
if ( arrayExpressible != null && !( arrayExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) { if ( arrayExpressible != null ) {
if ( !(arrayExpressible.getSqmType() instanceof BasicPluralType<?, ?> pluralType) ) {
throw new SemanticException( throw new SemanticException(
"Right operand for in-array predicate must be a basic plural type expression, but found: " "Right operand for in-array predicate must be a basic plural type expression, but found: "
+ arrayExpressible.getSqmType(), + arrayExpressible.getSqmType(),
query query
); );
} }
testExpression.applyInferableType( pluralType.getElementType() );
}
final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_contains" ).generateSqmExpression( final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_contains" ).generateSqmExpression(
asList( arrayExpr, testExpression ), asList( arrayExpr, testExpression ),
null, null,

View File

@ -15,6 +15,7 @@ import org.hibernate.testing.jdbc.SharedDriverManagerTypeCacheClearingIntegrator
import org.hibernate.testing.orm.junit.BootstrapServiceRegistry; import org.hibernate.testing.orm.junit.BootstrapServiceRegistry;
import org.hibernate.testing.orm.junit.DialectFeatureChecks; import org.hibernate.testing.orm.junit.DialectFeatureChecks;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.RequiresDialectFeature; import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope; import org.hibernate.testing.orm.junit.SessionFactoryScope;
@ -156,4 +157,22 @@ public class ArrayContainsTest {
} ); } );
} }
@Test
@JiraKey( "HHH-18851" )
public void testInArray(SessionFactoryScope scope) {
scope.inSession( em -> {
List<Tuple> results = em.createQuery(
"select e.id " +
"from EntityWithArrays e " +
"where :p in e.theArray",
Tuple.class
)
.setParameter( "p", "abc" )
.getResultList();
assertEquals( 1, results.size() );
assertEquals( 2L, results.get( 0 ).get( 0 ) );
} );
}
} }