HHH-17375 Overload position function with array_position semantics on array input

This commit is contained in:
Christian Beikov 2024-05-07 11:17:15 +02:00
parent 35102836c7
commit 8ec90b8fb1
3 changed files with 41 additions and 8 deletions

View File

@ -1244,7 +1244,7 @@ include::{array-example-dir-hql}/ArrayAggregateTest.java[tags=hql-array-agg-exam
====
[[hql-array-position-functions]]
===== `array_position()`
===== `array_position()` or `position()`
Returns the 1-based position of an element in the array. Returns 0 if the element is not found and `null` if the array is `null`.
@ -1256,6 +1256,17 @@ include::{array-example-dir-hql}/ArrayPositionTest.java[tags=hql-array-position-
----
====
Alternatively, it is also possible to use the `position()` function,
which is overloaded to also accept an array argument.
[[hql-array-position-hql-example]]
====
[source, JAVA, indent=0]
----
include::{array-example-dir-hql}/ArrayPositionTest.java[tags=hql-array-position-hql-example]
----
====
[[hql-array-positions-functions]]
===== `array_positions()` and `array_positions_list()`

View File

@ -4566,14 +4566,24 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
@Override
public Object visitPositionFunction(HqlParser.PositionFunctionContext ctx) {
final SqmExpression<?> pattern = (SqmExpression<?>) ctx.positionFunctionPatternArgument().accept( this );
final SqmExpression<?> string = (SqmExpression<?>) ctx.positionFunctionStringArgument().accept( this );
final SqmExpression<?> patternOrElement = (SqmExpression<?>) ctx.positionFunctionPatternArgument().accept( this );
final SqmExpression<?> stringOrArray = (SqmExpression<?>) ctx.positionFunctionStringArgument().accept( this );
return getFunctionDescriptor("position").generateSqmExpression(
asList( pattern, string ),
null,
creationContext.getQueryEngine()
);
final SqmExpressible<?> stringOrArrayExpressible = stringOrArray.getExpressible();
if ( stringOrArrayExpressible != null && stringOrArrayExpressible.getSqmType() instanceof BasicPluralType<?, ?> ) {
return getFunctionDescriptor( "array_position" ).generateSqmExpression(
asList( stringOrArray, patternOrElement ),
null,
creationContext.getQueryEngine()
);
}
else {
return getFunctionDescriptor( "position" ).generateSqmExpression(
asList( patternOrElement, stringOrArray ),
null,
creationContext.getQueryEngine()
);
}
}
@Override

View File

@ -134,4 +134,16 @@ public class ArrayPositionTest {
} );
}
@Test
public void testPositionOverload(SessionFactoryScope scope) {
scope.inSession( em -> {
//tag::hql-array-position-hql-example[]
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where position('abc' in e.theArray) = 1", EntityWithArrays.class )
.getResultList();
//end::hql-array-position-hql-example[]
assertEquals( 1, results.size() );
assertEquals( 2L, results.get( 0 ).getId() );
} );
}
}