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 a26e5059fb
commit b5178d03ec
3 changed files with 33 additions and 6 deletions

View File

@ -47,10 +47,15 @@ public class ArrayContainsArgumentTypeResolver implements FunctionArgumentTypeRe
} }
} }
else if ( argumentIndex == 1 ) { else if ( argumentIndex == 1 ) {
final SqmTypedNode<?> nodeToResolve = function.getArguments().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 = function.getArguments().get( 0 ); final SqmTypedNode<?> node = function.getArguments().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

@ -2886,11 +2886,14 @@ 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 ) {
throw new SemanticException( if ( !(arrayExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) {
"Right operand for in-array predicate must be a basic plural type expression, but found: " + arrayExpressible.getSqmType(), throw new SemanticException(
query "Right operand for in-array predicate must be a basic plural type expression, but found: " + arrayExpressible.getSqmType(),
); query
);
}
testExpression.applyInferableType( ( (BasicPluralType<?, ?>) arrayExpressible.getSqmType() ).getElementType() );
} }
final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_contains" ).generateSqmExpression( final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_contains" ).generateSqmExpression(
asList( arrayExpr, testExpression ), asList( arrayExpr, testExpression ),

View File

@ -17,6 +17,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;
@ -157,4 +158,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 ) );
} );
}
} }