HHH-17335 Add array_position function
This commit is contained in:
parent
65fb449776
commit
7f10a48469
|
@ -1120,6 +1120,7 @@ The following functions deal with SQL array types, which are not supported on ev
|
|||
| `array()` | Creates an array based on the passed arguments
|
||||
| `array_contains()` | Whether an array contains an element
|
||||
| `array_contains_null()` | Whether an array contains a null
|
||||
| `array_position()` | Determines the position of an element in an array
|
||||
|===
|
||||
|
||||
===== `array()`
|
||||
|
@ -1153,6 +1154,19 @@ include::{array-example-dir-hql}/ArrayContainsTest.java[tags=hql-array-contains-
|
|||
----
|
||||
====
|
||||
|
||||
[[hql-array-position-functions]]
|
||||
===== `array_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`.
|
||||
|
||||
[[hql-array-position-example]]
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{array-example-dir-hql}/ArrayPositionTest.java[tags=hql-array-position-example]
|
||||
----
|
||||
====
|
||||
|
||||
[[hql-user-defined-functions]]
|
||||
==== Native and user-defined functions
|
||||
|
||||
|
|
|
@ -465,6 +465,7 @@ public class CockroachLegacyDialect extends Dialect {
|
|||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_operator();
|
||||
functionFactory.arrayContainsNull_array_position();
|
||||
functionFactory.arrayPosition_postgresql();
|
||||
|
||||
functionContributions.getFunctionRegistry().register(
|
||||
"trunc",
|
||||
|
|
|
@ -251,6 +251,7 @@ public class HSQLLegacyDialect extends Dialect {
|
|||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_hsql();
|
||||
functionFactory.arrayContainsNull_hsql();
|
||||
functionFactory.arrayPosition_hsql();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -287,6 +287,7 @@ public class OracleLegacyDialect extends Dialect {
|
|||
functionFactory.arrayAggregate_jsonArrayagg();
|
||||
functionFactory.arrayContains_oracle();
|
||||
functionFactory.arrayContainsNull_oracle();
|
||||
functionFactory.arrayPosition_oracle();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -585,6 +585,7 @@ public class PostgreSQLLegacyDialect extends Dialect {
|
|||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_operator();
|
||||
functionFactory.arrayContainsNull_array_position();
|
||||
functionFactory.arrayPosition_postgresql();
|
||||
|
||||
if ( getVersion().isSameOrAfter( 9, 4 ) ) {
|
||||
functionFactory.makeDateTimeTimestamp();
|
||||
|
|
|
@ -452,6 +452,7 @@ public class CockroachDialect extends Dialect {
|
|||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_operator();
|
||||
functionFactory.arrayContainsNull_array_position();
|
||||
functionFactory.arrayPosition_postgresql();
|
||||
|
||||
functionContributions.getFunctionRegistry().register(
|
||||
"trunc",
|
||||
|
|
|
@ -191,6 +191,7 @@ public class HSQLDialect extends Dialect {
|
|||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_hsql();
|
||||
functionFactory.arrayContainsNull_hsql();
|
||||
functionFactory.arrayPosition_hsql();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -233,19 +233,19 @@ public class OracleArrayJdbcType extends ArrayJdbcType {
|
|||
);
|
||||
database.addAuxiliaryDatabaseObject(
|
||||
new NamedAuxiliaryDatabaseObject(
|
||||
arrayTypeName + "_contains",
|
||||
arrayTypeName + "_position",
|
||||
database.getDefaultNamespace(),
|
||||
new String[]{
|
||||
"create or replace function " + arrayTypeName + "_contains(arr in " + arrayTypeName +
|
||||
", elem in " + getRawTypeName( elementType ) + ") return number deterministic is begin " +
|
||||
"create or replace function " + arrayTypeName + "_position(arr in " + arrayTypeName +
|
||||
", elem in " + getRawTypeName( elementType ) + ", startPos in number default 1) return number deterministic is begin " +
|
||||
"if arr is null then return null; end if; " +
|
||||
"if elem is null then " +
|
||||
"for i in 1 .. arr.count loop " +
|
||||
"if arr(i) is null then return 1; end if; " +
|
||||
"for i in startPos .. arr.count loop " +
|
||||
"if arr(i) is null then return i; end if; " +
|
||||
"end loop; " +
|
||||
"else " +
|
||||
"for i in 1 .. arr.count loop " +
|
||||
"if arr(i)=elem then return 1; end if; " +
|
||||
"for i in startPos .. arr.count loop " +
|
||||
"if arr(i)=elem then return i; end if; " +
|
||||
"end loop; " +
|
||||
"end if; " +
|
||||
"return 0; " +
|
||||
|
|
|
@ -316,6 +316,7 @@ public class OracleDialect extends Dialect {
|
|||
functionFactory.arrayAggregate_jsonArrayagg();
|
||||
functionFactory.arrayContains_oracle();
|
||||
functionFactory.arrayContainsNull_oracle();
|
||||
functionFactory.arrayPosition_oracle();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -633,6 +633,7 @@ public class PostgreSQLDialect extends Dialect {
|
|||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_operator();
|
||||
functionFactory.arrayContainsNull_array_position();
|
||||
functionFactory.arrayPosition_postgresql();
|
||||
|
||||
functionFactory.makeDateTimeTimestamp();
|
||||
// Note that PostgreSQL doesn't support the OVER clause for ordered set-aggregate functions
|
||||
|
|
|
@ -18,6 +18,9 @@ import org.hibernate.dialect.function.array.ArrayAndElementArgumentValidator;
|
|||
import org.hibernate.dialect.function.array.ArrayArgumentValidator;
|
||||
import org.hibernate.dialect.function.array.ArrayConstructorFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayContainsOperatorFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayPositionFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayPositionFunction;
|
||||
import org.hibernate.dialect.function.array.PostgreSQLArrayPositionFunction;
|
||||
import org.hibernate.dialect.function.array.CastingArrayConstructorFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayAggEmulation;
|
||||
import org.hibernate.dialect.function.array.OracleArrayConstructorFunction;
|
||||
|
@ -2691,4 +2694,25 @@ public class CommonFunctionFactory {
|
|||
.setArgumentListSignature( "(ARRAY array)" )
|
||||
.register();
|
||||
}
|
||||
|
||||
/**
|
||||
* CockroachDB and PostgreSQL array_position() function
|
||||
*/
|
||||
public void arrayPosition_postgresql() {
|
||||
functionRegistry.register( "array_position", new PostgreSQLArrayPositionFunction( typeConfiguration ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* HSQL array_position() function
|
||||
*/
|
||||
public void arrayPosition_hsql() {
|
||||
functionRegistry.register( "array_position", new HSQLArrayPositionFunction( typeConfiguration ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle array_position() function
|
||||
*/
|
||||
public void arrayPosition_oracle() {
|
||||
functionRegistry.register( "array_position", new OracleArrayPositionFunction( typeConfiguration ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect.function.array;
|
||||
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* Encapsulates the validator, return type and argument type resolvers for the array_position functions.
|
||||
* Subclasses only have to implement the rendering.
|
||||
*/
|
||||
public abstract class AbstractArrayPositionFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
|
||||
public AbstractArrayPositionFunction(TypeConfiguration typeConfiguration) {
|
||||
super(
|
||||
"array_position",
|
||||
new ArgumentTypesValidator(
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.between( 2, 3 ),
|
||||
ArrayAndElementArgumentValidator.DEFAULT_INSTANCE
|
||||
),
|
||||
FunctionParameterType.ANY,
|
||||
FunctionParameterType.ANY,
|
||||
FunctionParameterType.INTEGER
|
||||
),
|
||||
StandardFunctionReturnTypeResolvers.invariant( typeConfiguration.standardBasicTypeForJavaType( Integer.class ) ),
|
||||
(function, argumentIndex, converter) -> {
|
||||
if ( argumentIndex == 2 ) {
|
||||
return converter.getCreationContext()
|
||||
.getSessionFactory()
|
||||
.getTypeConfiguration()
|
||||
.standardBasicTypeForJavaType( Integer.class );
|
||||
}
|
||||
else {
|
||||
return ArrayAndElementArgumentTypeResolver.DEFAULT_INSTANCE.resolveFunctionArgumentType(
|
||||
function,
|
||||
argumentIndex,
|
||||
converter
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgumentListSignature() {
|
||||
return "(ARRAY array, OBJECT element[, INTEGER startPosition])";
|
||||
}
|
||||
}
|
|
@ -37,7 +37,7 @@ public class ArrayAndElementArgumentValidator extends ArrayArgumentValidator {
|
|||
final BasicType<?> expectedElementType = getElementType( arguments, functionName, typeConfiguration );
|
||||
final SqmTypedNode<?> elementArgument = arguments.get( elementIndex );
|
||||
final SqmExpressible<?> elementType = elementArgument.getExpressible().getSqmType();
|
||||
if ( expectedElementType != elementType ) {
|
||||
if ( expectedElementType != null && elementType != null && expectedElementType != elementType ) {
|
||||
throw new FunctionArgumentException(
|
||||
String.format(
|
||||
"Parameter %d of function '%s()' has type %s, but argument is of type '%s'",
|
||||
|
|
|
@ -43,7 +43,10 @@ public class ArrayArgumentValidator implements ArgumentsValidator {
|
|||
TypeConfiguration typeConfiguration) {
|
||||
final SqmTypedNode<?> arrayArgument = arguments.get( arrayIndex );
|
||||
final SqmExpressible<?> arrayType = arrayArgument.getExpressible().getSqmType();
|
||||
if ( !( arrayType instanceof BasicPluralType<?, ?> ) ) {
|
||||
if ( arrayType == null ) {
|
||||
return null;
|
||||
}
|
||||
else if ( !( arrayType instanceof BasicPluralType<?, ?> ) ) {
|
||||
throw new FunctionArgumentException(
|
||||
String.format(
|
||||
"Parameter %d of function '%s()' requires an array type, but argument is of type '%s'",
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect.function.array;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* HSQLDB has a special syntax.
|
||||
*/
|
||||
public class HSQLArrayPositionFunction extends AbstractArrayPositionFunction {
|
||||
|
||||
public HSQLArrayPositionFunction(TypeConfiguration typeConfiguration) {
|
||||
super( typeConfiguration );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression elementExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
sqlAppender.append( "position_array(" );
|
||||
elementExpression.accept( walker );
|
||||
sqlAppender.append( " in " );
|
||||
arrayExpression.accept( walker );
|
||||
if ( sqlAstArguments.size() > 2 ) {
|
||||
sqlAppender.append( " from " );
|
||||
sqlAstArguments.get( 2 ).accept( walker );
|
||||
}
|
||||
sqlAppender.append( ')' );
|
||||
}
|
||||
}
|
|
@ -39,11 +39,11 @@ public class OracleArrayContainsFunction extends AbstractSqmSelfRenderingFunctio
|
|||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final String arrayTypeName = ArrayTypeHelper.getArrayTypeName( arrayExpression.getExpressionType(), walker );
|
||||
sqlAppender.appendSql( arrayTypeName );
|
||||
sqlAppender.append( "_contains(" );
|
||||
sqlAppender.append( "_position(" );
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
sqlAstArguments.get( 1 ).accept( walker );
|
||||
sqlAppender.append( ")=1" );
|
||||
sqlAppender.append( ")>0" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,9 +39,9 @@ public class OracleArrayContainsNullFunction extends AbstractSqmSelfRenderingFun
|
|||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final String arrayTypeName = ArrayTypeHelper.getArrayTypeName( arrayExpression.getExpressionType(), walker );
|
||||
sqlAppender.appendSql( arrayTypeName );
|
||||
sqlAppender.append( "_contains(" );
|
||||
sqlAppender.append( "_position(" );
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append( ",null)=1" );
|
||||
sqlAppender.append( ",null)>0" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect.function.array;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
public class OracleArrayPositionFunction extends AbstractArrayPositionFunction {
|
||||
|
||||
public OracleArrayPositionFunction(TypeConfiguration typeConfiguration) {
|
||||
super( typeConfiguration );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final String arrayTypeName = ArrayTypeHelper.getArrayTypeName( arrayExpression.getExpressionType(), walker );
|
||||
sqlAppender.appendSql( arrayTypeName );
|
||||
sqlAppender.append( "_position(" );
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
sqlAstArguments.get( 1 ).accept( walker );
|
||||
if ( sqlAstArguments.size() > 2 ) {
|
||||
sqlAppender.append( ',' );
|
||||
sqlAstArguments.get( 2 ).accept( walker );
|
||||
}
|
||||
sqlAppender.append( ")" );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect.function.array;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* PostgreSQL variant of the function.
|
||||
*/
|
||||
public class PostgreSQLArrayPositionFunction extends AbstractArrayPositionFunction {
|
||||
|
||||
public PostgreSQLArrayPositionFunction(TypeConfiguration typeConfiguration) {
|
||||
super( typeConfiguration );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression elementExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
sqlAppender.append( "case when " );
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append( " is not null then coalesce(array_position(" );
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
elementExpression.accept( walker );
|
||||
if ( sqlAstArguments.size() > 2 ) {
|
||||
sqlAppender.append( ',' );
|
||||
sqlAstArguments.get( 2 ).accept( walker );
|
||||
}
|
||||
sqlAppender.append( "),0) end" );
|
||||
}
|
||||
}
|
|
@ -94,7 +94,7 @@ public class ArgumentTypesValidator implements ArgumentsValidator {
|
|||
JdbcTypeIndicators indicators = typeConfiguration.getCurrentBaseSqlTypeIndicators();
|
||||
SqmExpressible<?> nodeType = argument.getNodeType();
|
||||
FunctionParameterType type = count < types.length ? types[count++] : types[types.length - 1];
|
||||
if ( nodeType != null ) {
|
||||
if ( nodeType != null && type != FunctionParameterType.ANY ) {
|
||||
JavaType<?> javaType = nodeType.getRelationalJavaType();
|
||||
if (javaType != null) {
|
||||
checkArgumentType( functionName, count, argument, indicators, type, javaType );
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.orm.test.function.array;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.dialect.HSQLDialect;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.hibernate.testing.orm.junit.SkipForDialect;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
@DomainModel(annotatedClasses = EntityWithArrays.class)
|
||||
@SessionFactory
|
||||
@RequiresDialectFeature( feature = DialectFeatureChecks.SupportsStructuralArrays.class)
|
||||
// Make sure this stuff runs on a dedicated connection pool,
|
||||
// otherwise we might run into ORA-21700: object does not exist or is marked for delete
|
||||
// because the JDBC connection or database session caches something that should have been invalidated
|
||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.CONNECTION_PROVIDER, value = ""))
|
||||
@SkipForDialect(dialectClass = H2Dialect.class, reason = "H2 does not have an array_position function")
|
||||
public class ArrayPositionTest {
|
||||
|
||||
@BeforeEach
|
||||
public void prepareData(SessionFactoryScope scope) {
|
||||
scope.inTransaction( em -> {
|
||||
em.persist( new EntityWithArrays( 1L, new String[]{} ) );
|
||||
em.persist( new EntityWithArrays( 2L, new String[]{ "abc", null, "def" } ) );
|
||||
em.persist( new EntityWithArrays( 3L, null ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void cleanup(SessionFactoryScope scope) {
|
||||
scope.inTransaction( em -> {
|
||||
em.createMutationQuery( "delete from EntityWithArrays" ).executeUpdate();
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPosition(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
//tag::hql-array-position-example[]
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_position(e.theArray, 'abc') = 1", EntityWithArrays.class )
|
||||
.getResultList();
|
||||
//end::hql-array-position-example[]
|
||||
assertEquals( 1, results.size() );
|
||||
assertEquals( 2L, results.get( 0 ).getId() );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPositionZero(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_position(e.theArray, 'xyz') = 0", EntityWithArrays.class )
|
||||
.getResultList();
|
||||
assertEquals( 2, results.size() );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@SkipForDialect(dialectClass = HSQLDialect.class, reason = "See https://sourceforge.net/p/hsqldb/bugs/1692/")
|
||||
public void testPositionNull(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_position(e.theArray, null) = 2", EntityWithArrays.class )
|
||||
.getResultList();
|
||||
assertEquals( 1, results.size() );
|
||||
assertEquals( 2L, results.get( 0 ).getId() );
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue