HHH-17335 Add array_remove function
This commit is contained in:
parent
b8b8a874fd
commit
865365e6ec
|
@ -1129,6 +1129,7 @@ The following functions deal with SQL array types, which are not supported on ev
|
|||
| `array_contains_any_nullable()` | Determines if one array holds at least one element of another array, supporting null elements
|
||||
| `array_get()` | Accesses the element of an array by index
|
||||
| `array_set()` | Creates array copy with given element at given index
|
||||
| `array_remove()` | Creates array copy with given element removed
|
||||
|===
|
||||
|
||||
===== `array()`
|
||||
|
@ -1274,6 +1275,19 @@ include::{array-example-dir-hql}/ArraySetTest.java[tags=hql-array-set-example]
|
|||
----
|
||||
====
|
||||
|
||||
[[hql-array-remove-functions]]
|
||||
===== `array_remove()`
|
||||
|
||||
Returns an array copy with the given element removed from the array. Allows removal of `null` elements.
|
||||
|
||||
[[hql-array-remove-example]]
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{array-example-dir-hql}/ArrayRemoveTest.java[tags=hql-array-remove-example]
|
||||
----
|
||||
====
|
||||
|
||||
[[hql-user-defined-functions]]
|
||||
==== Native and user-defined functions
|
||||
|
||||
|
|
|
@ -474,6 +474,7 @@ public class CockroachLegacyDialect extends Dialect {
|
|||
functionFactory.arrayContainsAnyNullable_operator();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove_unnest();
|
||||
|
||||
functionContributions.getFunctionRegistry().register(
|
||||
"trunc",
|
||||
|
|
|
@ -382,6 +382,7 @@ public class H2LegacyDialect extends Dialect {
|
|||
functionFactory.arrayContainsAnyNullable_h2();
|
||||
functionFactory.arrayGet_h2();
|
||||
functionFactory.arraySet_h2();
|
||||
functionFactory.arrayRemove_h2();
|
||||
}
|
||||
else {
|
||||
// Use group_concat until 2.x as listagg was buggy
|
||||
|
|
|
@ -260,6 +260,7 @@ public class HSQLLegacyDialect extends Dialect {
|
|||
functionFactory.arrayContainsAnyNullable_hsql();
|
||||
functionFactory.arrayGet_unnest();
|
||||
functionFactory.arraySet_hsql();
|
||||
functionFactory.arrayRemove_hsql();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -296,6 +296,7 @@ public class OracleLegacyDialect extends Dialect {
|
|||
functionFactory.arrayContainsAnyNullable_oracle();
|
||||
functionFactory.arrayGet_oracle();
|
||||
functionFactory.arraySet_oracle();
|
||||
functionFactory.arrayRemove_oracle();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -594,6 +594,7 @@ public class PostgreSQLLegacyDialect extends Dialect {
|
|||
functionFactory.arrayContainsAnyNullable_operator();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove_unnest();
|
||||
|
||||
if ( getVersion().isSameOrAfter( 9, 4 ) ) {
|
||||
functionFactory.makeDateTimeTimestamp();
|
||||
|
|
|
@ -461,6 +461,7 @@ public class CockroachDialect extends Dialect {
|
|||
functionFactory.arrayContainsAnyNullable_operator();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove_unnest();
|
||||
|
||||
functionContributions.getFunctionRegistry().register(
|
||||
"trunc",
|
||||
|
|
|
@ -322,6 +322,7 @@ public class H2Dialect extends Dialect {
|
|||
functionFactory.arrayContainsAnyNullable_h2();
|
||||
functionFactory.arrayGet_h2();
|
||||
functionFactory.arraySet_h2();
|
||||
functionFactory.arrayRemove_h2();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -200,6 +200,7 @@ public class HSQLDialect extends Dialect {
|
|||
functionFactory.arrayContainsAnyNullable_hsql();
|
||||
functionFactory.arrayGet_unnest();
|
||||
functionFactory.arraySet_hsql();
|
||||
functionFactory.arrayRemove_hsql();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -373,6 +373,32 @@ public class OracleArrayJdbcType extends ArrayJdbcType {
|
|||
false
|
||||
)
|
||||
);
|
||||
database.addAuxiliaryDatabaseObject(
|
||||
new NamedAuxiliaryDatabaseObject(
|
||||
arrayTypeName + "_remove",
|
||||
database.getDefaultNamespace(),
|
||||
new String[]{
|
||||
"create or replace function " + arrayTypeName + "_remove(arr in " + arrayTypeName +
|
||||
", elem in " + getRawTypeName( elementType ) + ") return " + arrayTypeName + " deterministic is " +
|
||||
"res " + arrayTypeName + ":=" + arrayTypeName + "(); 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 not null then res.extend; res(res.last) := arr(i); end if; " +
|
||||
"end loop; " +
|
||||
"else " +
|
||||
"for i in 1 .. arr.count loop " +
|
||||
"if arr(i) is null or arr(i)<>elem then res.extend; res(res.last) := arr(i); end if; " +
|
||||
"end loop; " +
|
||||
"end if; " +
|
||||
"return res; " +
|
||||
"end;"
|
||||
},
|
||||
new String[] { "drop function " + arrayTypeName + "_remove" },
|
||||
emptySet(),
|
||||
false
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected String createOrReplaceConcatFunction(String arrayTypeName) {
|
||||
|
|
|
@ -325,6 +325,7 @@ public class OracleDialect extends Dialect {
|
|||
functionFactory.arrayContainsAnyNullable_oracle();
|
||||
functionFactory.arrayGet_oracle();
|
||||
functionFactory.arraySet_oracle();
|
||||
functionFactory.arrayRemove_oracle();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -642,6 +642,7 @@ public class PostgreSQLDialect extends Dialect {
|
|||
functionFactory.arrayContainsAnyNullable_operator();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove_unnest();
|
||||
|
||||
functionFactory.makeDateTimeTimestamp();
|
||||
// Note that PostgreSQL doesn't support the OVER clause for ordered set-aggregate functions
|
||||
|
|
|
@ -23,10 +23,13 @@ import org.hibernate.dialect.function.array.ArrayContainsOperatorFunction;
|
|||
import org.hibernate.dialect.function.array.ArrayContainsQuantifiedUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayGetUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArraySetUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayViaArgumentReturnTypeResolver;
|
||||
import org.hibernate.dialect.function.array.ElementViaArrayArgumentReturnTypeResolver;
|
||||
import org.hibernate.dialect.function.array.H2ArrayContainsQuantifiedEmulation;
|
||||
import org.hibernate.dialect.function.array.H2ArrayRemoveFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArraySetFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayPositionFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayRemoveFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArraySetFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayConcatFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayContainsAllFunction;
|
||||
|
@ -34,6 +37,7 @@ import org.hibernate.dialect.function.array.OracleArrayContainsAnyFunction;
|
|||
import org.hibernate.dialect.function.array.OracleArrayGetFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayLengthFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayPositionFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayRemoveFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArraySetFunction;
|
||||
import org.hibernate.dialect.function.array.PostgreSQLArrayConcatFunction;
|
||||
import org.hibernate.dialect.function.array.PostgreSQLArrayPositionFunction;
|
||||
|
@ -2996,7 +3000,7 @@ public class CommonFunctionFactory {
|
|||
}
|
||||
|
||||
/**
|
||||
* HSQL, CockroachDB and PostgreSQL array_set() function
|
||||
* CockroachDB and PostgreSQL array_set() function
|
||||
*/
|
||||
public void arraySet_unnest() {
|
||||
functionRegistry.register( "array_set", new ArraySetUnnestFunction() );
|
||||
|
@ -3008,4 +3012,41 @@ public class CommonFunctionFactory {
|
|||
public void arraySet_oracle() {
|
||||
functionRegistry.register( "array_set", new OracleArraySetFunction() );
|
||||
}
|
||||
|
||||
/**
|
||||
* H2 array_remove() function
|
||||
*/
|
||||
public void arrayRemove_h2() {
|
||||
functionRegistry.register( "array_remove", new H2ArrayRemoveFunction() );
|
||||
}
|
||||
|
||||
/**
|
||||
* HSQL array_remove() function
|
||||
*/
|
||||
public void arrayRemove_hsql() {
|
||||
functionRegistry.register( "array_remove", new HSQLArrayRemoveFunction() );
|
||||
}
|
||||
|
||||
/**
|
||||
* CockroachDB and PostgreSQL array_remove() function
|
||||
*/
|
||||
public void arrayRemove_unnest() {
|
||||
functionRegistry.namedDescriptorBuilder( "array_remove" )
|
||||
.setArgumentsValidator(
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 2 ),
|
||||
ArrayAndElementArgumentValidator.DEFAULT_INSTANCE
|
||||
)
|
||||
)
|
||||
.setReturnTypeResolver( ArrayViaArgumentReturnTypeResolver.DEFAULT_INSTANCE )
|
||||
.setArgumentTypeResolver( ArrayAndElementArgumentTypeResolver.DEFAULT_INSTANCE )
|
||||
.register();
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle array_remove() function
|
||||
*/
|
||||
public void arrayRemove_oracle() {
|
||||
functionRegistry.register( "array_remove", new OracleArrayRemoveFunction() );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.StandardArgumentsValidators;
|
||||
|
||||
/**
|
||||
* Encapsulates the validator, return type and argument type resolvers for the array_remove functions.
|
||||
* Subclasses only have to implement the rendering.
|
||||
*/
|
||||
public abstract class AbstractArrayRemoveFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
|
||||
public AbstractArrayRemoveFunction() {
|
||||
super(
|
||||
"array_remove",
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 2 ),
|
||||
ArrayAndElementArgumentValidator.DEFAULT_INSTANCE
|
||||
),
|
||||
ArrayViaArgumentReturnTypeResolver.DEFAULT_INSTANCE,
|
||||
ArrayAndElementArgumentTypeResolver.DEFAULT_INSTANCE
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* H2 array_remove function.
|
||||
*/
|
||||
public class H2ArrayRemoveFunction extends AbstractArrayRemoveFunction {
|
||||
|
||||
public H2ArrayRemoveFunction() {
|
||||
}
|
||||
|
||||
@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 null then null else coalesce((select array_agg(array_get(");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append(",i.idx)) from system_range(1," );
|
||||
sqlAppender.append( Integer.toString( getMaximumArraySize() ) );
|
||||
sqlAppender.append( ") i(idx) where i.idx<=coalesce(cardinality(");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append("),0) and array_get(");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append( ",i.idx) is distinct from " );
|
||||
elementExpression.accept( walker );
|
||||
sqlAppender.append( "),array[]) end" );
|
||||
}
|
||||
|
||||
protected int getMaximumArraySize() {
|
||||
return 1000;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* HSQLDB array_remove function.
|
||||
*/
|
||||
public class HSQLArrayRemoveFunction extends AbstractArrayRemoveFunction {
|
||||
|
||||
public HSQLArrayRemoveFunction() {
|
||||
}
|
||||
|
||||
@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 null then null else coalesce((select array_agg(t.val) from unnest(" );
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append( ") with ordinality t(val,idx) where t.val is distinct from " );
|
||||
elementExpression.accept( walker );
|
||||
sqlAppender.append( "),array[]) end" );
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
|
@ -27,15 +26,10 @@ public class OracleArrayGetFunction extends ArrayGetUnnestFunction {
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
SqlAstTranslator<?> walker) {
|
||||
JdbcMappingContainer expressionType = null;
|
||||
for ( SqlAstNode sqlAstArgument : sqlAstArguments ) {
|
||||
expressionType = ( (Expression) sqlAstArgument ).getExpressionType();
|
||||
if ( expressionType != null ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final String arrayTypeName = ArrayTypeHelper.getArrayTypeName( expressionType, walker );
|
||||
final String arrayTypeName = ArrayTypeHelper.getArrayTypeName(
|
||||
( (Expression) sqlAstArguments.get( 0 ) ).getExpressionType(),
|
||||
walker
|
||||
);
|
||||
sqlAppender.append( arrayTypeName );
|
||||
sqlAppender.append( "_get(" );
|
||||
sqlAstArguments.get( 0 ).accept( walker );
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Oracle array_remove function.
|
||||
*/
|
||||
public class OracleArrayRemoveFunction extends AbstractArrayRemoveFunction {
|
||||
|
||||
public OracleArrayRemoveFunction() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final String arrayTypeName = ArrayTypeHelper.getArrayTypeName(
|
||||
( (Expression) sqlAstArguments.get( 0 ) ).getExpressionType(),
|
||||
walker
|
||||
);
|
||||
sqlAppender.append( arrayTypeName );
|
||||
sqlAppender.append( "_remove(" );
|
||||
sqlAstArguments.get( 0 ).accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
sqlAstArguments.get( 1 ).accept( walker );
|
||||
sqlAppender.append( ')' );
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
|
@ -27,15 +26,10 @@ public class OracleArraySetFunction extends ArraySetUnnestFunction {
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
SqlAstTranslator<?> walker) {
|
||||
JdbcMappingContainer expressionType = null;
|
||||
for ( SqlAstNode sqlAstArgument : sqlAstArguments ) {
|
||||
expressionType = ( (Expression) sqlAstArgument ).getExpressionType();
|
||||
if ( expressionType != null ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final String arrayTypeName = ArrayTypeHelper.getArrayTypeName( expressionType, walker );
|
||||
final String arrayTypeName = ArrayTypeHelper.getArrayTypeName(
|
||||
( (Expression) sqlAstArguments.get( 0 ) ).getExpressionType(),
|
||||
walker
|
||||
);
|
||||
sqlAppender.append( arrayTypeName );
|
||||
sqlAppender.append( "_set(" );
|
||||
sqlAstArguments.get( 0 ).accept( walker );
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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.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.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Tuple;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
/**
|
||||
* @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 = ""))
|
||||
public class ArrayRemoveTest {
|
||||
|
||||
@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 testRemove(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
//tag::hql-array-remove-example[]
|
||||
List<Tuple> results = em.createQuery( "select e.id, array_remove(e.theArray, 'abc') from EntityWithArrays e order by e.id", Tuple.class )
|
||||
.getResultList();
|
||||
//end::hql-array-remove-example[]
|
||||
assertEquals( 3, results.size() );
|
||||
assertEquals( 1L, results.get( 0 ).get( 0 ) );
|
||||
assertArrayEquals( new String[] {}, results.get( 0 ).get( 1, String[].class ) );
|
||||
assertEquals( 2L, results.get( 1 ).get( 0 ) );
|
||||
assertArrayEquals( new String[] { null, "def" }, results.get( 1 ).get( 1, String[].class ) );
|
||||
assertEquals( 3L, results.get( 2 ).get( 0 ) );
|
||||
assertNull( results.get( 2 ).get( 1, String[].class ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveNullElement(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
List<Tuple> results = em.createQuery( "select e.id, array_remove(e.theArray, null) from EntityWithArrays e order by e.id", Tuple.class )
|
||||
.getResultList();
|
||||
assertEquals( 3, results.size() );
|
||||
assertEquals( 1L, results.get( 0 ).get( 0 ) );
|
||||
assertArrayEquals( new String[] {}, results.get( 0 ).get( 1, String[].class ) );
|
||||
assertEquals( 2L, results.get( 1 ).get( 0 ) );
|
||||
assertArrayEquals( new String[] { "abc", "def" }, results.get( 1 ).get( 1, String[].class ) );
|
||||
assertEquals( 3L, results.get( 2 ).get( 0 ) );
|
||||
assertNull( results.get( 2 ).get( 1, String[].class ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveNonExisting(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
List<Tuple> results = em.createQuery( "select e.id, array_remove(e.theArray, 'aaa') from EntityWithArrays e order by e.id", Tuple.class )
|
||||
.getResultList();
|
||||
assertEquals( 3, results.size() );
|
||||
assertEquals( 1L, results.get( 0 ).get( 0 ) );
|
||||
assertArrayEquals( new String[] {}, results.get( 0 ).get( 1, String[].class ) );
|
||||
assertEquals( 2L, results.get( 1 ).get( 0 ) );
|
||||
assertArrayEquals( new String[] { "abc", null, "def" }, results.get( 1 ).get( 1, String[].class ) );
|
||||
assertEquals( 3L, results.get( 2 ).get( 0 ) );
|
||||
assertNull( results.get( 2 ).get( 1, String[].class ) );
|
||||
} );
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue