diff --git a/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc b/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc index cf5b733441..f6d7dd928e 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc @@ -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()` diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java index eb338bec52..658a06c2b5 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java @@ -4566,14 +4566,24 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor 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 diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/function/array/ArrayPositionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/function/array/ArrayPositionTest.java index be357b8f07..65bac84066 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/function/array/ArrayPositionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/function/array/ArrayPositionTest.java @@ -134,4 +134,16 @@ public class ArrayPositionTest { } ); } + @Test + public void testPositionOverload(SessionFactoryScope scope) { + scope.inSession( em -> { + //tag::hql-array-position-hql-example[] + List 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() ); + } ); + } + }