HHH-17375 Introduce intersects predicate for easy array_intersects, the replacement of array_overlaps
This commit is contained in:
parent
6c34a0a4a6
commit
5c6a2f4a7d
|
@ -1191,8 +1191,8 @@ The following functions deal with SQL array types, which are not supported on ev
|
|||
| `array_append()` | Appends element to array
|
||||
| `array_contains()` | Whether an array contains element(s)
|
||||
| `array_contains_nullable()` | Whether an array contains element(s), supporting `null` elements
|
||||
| `array_overlaps()` | Whether an array holds at least one element of another array
|
||||
| `array_overlaps_nullable()` | Whether an array holds at least one element of another array, supporting `null` elements
|
||||
| `array_intersects()` | Whether an array holds at least one element of another array
|
||||
| `array_intersects_nullable()` | Whether an 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
|
||||
|
@ -1421,26 +1421,41 @@ include::{array-example-dir-hql}/ArrayContainsArrayTest.java[tags=hql-array-cont
|
|||
====
|
||||
|
||||
[[hql-array-overlaps-functions]]
|
||||
===== `array_overlaps()` and `array_overlaps_nullable()`
|
||||
[[hql-array-intersects-functions]]
|
||||
===== `array_intersects()` and `array_intersects_nullable()`
|
||||
|
||||
Checks if the first array argument any of the elements of the second array argument.
|
||||
Returns `null` if either of the arguments is `null`. The result of `array_overlaps`
|
||||
Returns `null` if either of the arguments is `null`. The result of `array_intersects`
|
||||
is undefined when the second array argument contains a `null` array element.
|
||||
Only `array_overlaps_nullable` is guaranteed to produce correct results for `null` array elements.
|
||||
Only `array_intersects_nullable` is guaranteed to produce correct results for `null` array elements.
|
||||
|
||||
[[hql-array-overlaps-example]]
|
||||
[[hql-array-intersects-example]]
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{array-example-dir-hql}/ArrayOverlapsTest.java[tags=hql-array-overlaps-example]
|
||||
include::{array-example-dir-hql}/ArrayIntersectsTest.java[tags=hql-array-intersects-example]
|
||||
----
|
||||
====
|
||||
|
||||
[[hql-array-overlaps-nullable-example]]
|
||||
[[hql-array-intersects-nullable-example]]
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{array-example-dir-hql}/ArrayOverlapsTest.java[tags=hql-array-overlaps-nullable-example]
|
||||
include::{array-example-dir-hql}/ArrayIntersectsTest.java[tags=hql-array-intersects-nullable-example]
|
||||
----
|
||||
====
|
||||
|
||||
Alternatively, it's also possible to check for intersection with the `intersects` predicate.
|
||||
This is syntax sugar that translates to the `array_intersects` function.
|
||||
|
||||
[[hql-array-overlaps-hql-example]]
|
||||
[[hql-array-intersects-hql-example]]
|
||||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{array-example-dir-hql}/ArrayIntersectsTest.java[tags=hql-array-intersects-hql-example]
|
||||
----
|
||||
====
|
||||
|
||||
|
@ -1865,6 +1880,20 @@ include::{extrasdir}/predicate_contains_bnf.txt[]
|
|||
|
||||
For further details, refer to the <<hql-array-contains-example,`array_contains` section>>.
|
||||
|
||||
[[hql-intersects-predicate]]
|
||||
==== `intersects`
|
||||
|
||||
The `intersects` predicates evaluates to true if the value to its left has at least one element common with the value to its right.
|
||||
Currently, this predicate only works with an array typed expressions.
|
||||
|
||||
[[hql-intersects-predicate-bnf]]
|
||||
[source, antlrv4, indent=0]
|
||||
----
|
||||
include::{extrasdir}/predicate_intersects_bnf.txt[]
|
||||
----
|
||||
|
||||
For further details, refer to the <<hql-array-intersects-example,`array_intersects` section>>.
|
||||
|
||||
[[hql-relational-comparisons-subqueries]]
|
||||
==== Relational operators and subqueries
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
expression "NOT"? "INTERSECTS" expression
|
|
@ -62,7 +62,6 @@ import org.hibernate.sql.exec.spi.JdbcOperation;
|
|||
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
|
||||
import org.hibernate.type.JavaObjectType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeConstructor;
|
||||
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.VarbinaryJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.VarcharJdbcType;
|
||||
|
@ -468,7 +467,7 @@ public class CockroachLegacyDialect extends Dialect {
|
|||
functionFactory.arrayPrepend_postgresql();
|
||||
functionFactory.arrayAppend_postgresql();
|
||||
functionFactory.arrayContains_postgresql();
|
||||
functionFactory.arrayOverlaps_postgresql();
|
||||
functionFactory.arrayIntersects_postgresql();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove();
|
||||
|
|
|
@ -384,7 +384,7 @@ public class H2LegacyDialect extends Dialect {
|
|||
functionFactory.arrayPrepend_operator();
|
||||
functionFactory.arrayAppend_operator();
|
||||
functionFactory.arrayContains_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayOverlaps_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayIntersects_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayGet_h2();
|
||||
functionFactory.arraySet_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayRemove_h2( getMaximumArraySize() );
|
||||
|
|
|
@ -259,7 +259,7 @@ public class HSQLLegacyDialect extends Dialect {
|
|||
functionFactory.arrayPrepend_operator();
|
||||
functionFactory.arrayAppend_operator();
|
||||
functionFactory.arrayContains_hsql();
|
||||
functionFactory.arrayOverlaps_hsql();
|
||||
functionFactory.arrayIntersects_hsql();
|
||||
functionFactory.arrayGet_unnest();
|
||||
functionFactory.arraySet_hsql();
|
||||
functionFactory.arrayRemove_hsql();
|
||||
|
|
|
@ -101,7 +101,6 @@ import org.hibernate.type.NullType;
|
|||
import org.hibernate.type.SqlTypes;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.OracleJsonBlobJdbcType;
|
||||
|
@ -308,7 +307,7 @@ public class OracleLegacyDialect extends Dialect {
|
|||
functionFactory.arrayPrepend_oracle();
|
||||
functionFactory.arrayAppend_oracle();
|
||||
functionFactory.arrayContains_oracle();
|
||||
functionFactory.arrayOverlaps_oracle();
|
||||
functionFactory.arrayIntersects_oracle();
|
||||
functionFactory.arrayGet_oracle();
|
||||
functionFactory.arraySet_oracle();
|
||||
functionFactory.arrayRemove_oracle();
|
||||
|
|
|
@ -77,7 +77,6 @@ import org.hibernate.sql.exec.spi.JdbcOperation;
|
|||
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
|
||||
import org.hibernate.type.JavaObjectType;
|
||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
|
@ -600,7 +599,7 @@ public class PostgreSQLLegacyDialect extends Dialect {
|
|||
functionFactory.arrayPrepend_postgresql();
|
||||
functionFactory.arrayAppend_postgresql();
|
||||
functionFactory.arrayContains_postgresql();
|
||||
functionFactory.arrayOverlaps_postgresql();
|
||||
functionFactory.arrayIntersects_postgresql();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove();
|
||||
|
|
|
@ -216,6 +216,7 @@ INNER : [iI] [nN] [nN] [eE] [rR];
|
|||
INSERT : [iI] [nN] [sS] [eE] [rR] [tT];
|
||||
INSTANT : [iI] [nN] [sS] [tT] [aA] [nN] [tT];
|
||||
INTERSECT : [iI] [nN] [tT] [eE] [rR] [sS] [eE] [cC] [tT];
|
||||
INTERSECTS : [iI] [nN] [tT] [eE] [rR] [sS] [eE] [cC] [tT] [sS];
|
||||
INTO : [iI] [nN] [tT] [oO];
|
||||
IS : [iI] [sS];
|
||||
JOIN : [jJ] [oO] [iI] [nN];
|
||||
|
|
|
@ -674,6 +674,7 @@ predicate
|
|||
| expression NOT? BETWEEN expression AND expression # BetweenPredicate
|
||||
| expression NOT? (LIKE | ILIKE) expression likeEscape? # LikePredicate
|
||||
| expression NOT? CONTAINS expression # ContainsPredicate
|
||||
| expression NOT? INTERSECTS expression # IntersectsPredicate
|
||||
| expression comparisonOperator expression # ComparisonPredicate
|
||||
| EXISTS collectionQuantifier LEFT_PAREN simplePath RIGHT_PAREN # ExistsCollectionPartPredicate
|
||||
| EXISTS expression # ExistsPredicate
|
||||
|
@ -1706,6 +1707,7 @@ rollup
|
|||
| INSERT
|
||||
| INSTANT
|
||||
| INTERSECT
|
||||
| INTERSECTS
|
||||
| INTO
|
||||
| IS
|
||||
| JOIN
|
||||
|
|
|
@ -469,7 +469,7 @@ public class CockroachDialect extends Dialect {
|
|||
functionFactory.arrayPrepend_postgresql();
|
||||
functionFactory.arrayAppend_postgresql();
|
||||
functionFactory.arrayContains_postgresql();
|
||||
functionFactory.arrayOverlaps_postgresql();
|
||||
functionFactory.arrayIntersects_postgresql();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove();
|
||||
|
|
|
@ -322,7 +322,7 @@ public class H2Dialect extends Dialect {
|
|||
functionFactory.arrayPrepend_operator();
|
||||
functionFactory.arrayAppend_operator();
|
||||
functionFactory.arrayContains_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayOverlaps_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayIntersects_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayGet_h2();
|
||||
functionFactory.arraySet_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayRemove_h2( getMaximumArraySize() );
|
||||
|
|
|
@ -199,7 +199,7 @@ public class HSQLDialect extends Dialect {
|
|||
functionFactory.arrayPrepend_operator();
|
||||
functionFactory.arrayAppend_operator();
|
||||
functionFactory.arrayContains_hsql();
|
||||
functionFactory.arrayOverlaps_hsql();
|
||||
functionFactory.arrayIntersects_hsql();
|
||||
functionFactory.arrayGet_unnest();
|
||||
functionFactory.arraySet_hsql();
|
||||
functionFactory.arrayRemove_hsql();
|
||||
|
|
|
@ -84,7 +84,6 @@ import org.hibernate.type.JavaObjectType;
|
|||
import org.hibernate.type.NullType;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
|
@ -355,7 +354,7 @@ public class OracleDialect extends Dialect {
|
|||
functionFactory.arrayPrepend_oracle();
|
||||
functionFactory.arrayAppend_oracle();
|
||||
functionFactory.arrayContains_oracle();
|
||||
functionFactory.arrayOverlaps_oracle();
|
||||
functionFactory.arrayIntersects_oracle();
|
||||
functionFactory.arrayGet_oracle();
|
||||
functionFactory.arraySet_oracle();
|
||||
functionFactory.arrayRemove_oracle();
|
||||
|
|
|
@ -121,7 +121,7 @@ public class OracleUserDefinedTypeExporter extends StandardUserDefinedTypeExport
|
|||
"end loop; " +
|
||||
"return 1; " +
|
||||
"end;",
|
||||
"create or replace function " + arrayTypeName + "_overlaps(haystack in " + arrayTypeName +
|
||||
"create or replace function " + arrayTypeName + "_intersects(haystack in " + arrayTypeName +
|
||||
", needle in " + arrayTypeName + ", nullable in number) return number deterministic is begin " +
|
||||
"if haystack is null or needle is null then return null; end if; " +
|
||||
"if needle.count = 0 then return 1; end if; " +
|
||||
|
@ -296,7 +296,7 @@ public class OracleUserDefinedTypeExporter extends StandardUserDefinedTypeExport
|
|||
"drop function " + arrayTypeName + "_length",
|
||||
"drop function " + arrayTypeName + "_concat",
|
||||
"drop function " + arrayTypeName + "_contains",
|
||||
"drop function " + arrayTypeName + "_overlaps",
|
||||
"drop function " + arrayTypeName + "_intersects",
|
||||
"drop function " + arrayTypeName + "_get",
|
||||
"drop function " + arrayTypeName + "_set",
|
||||
"drop function " + arrayTypeName + "_remove",
|
||||
|
|
|
@ -79,7 +79,6 @@ import org.hibernate.sql.model.jdbc.OptionalTableUpdateOperation;
|
|||
import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation;
|
||||
import org.hibernate.type.JavaObjectType;
|
||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
|
@ -652,7 +651,7 @@ public class PostgreSQLDialect extends Dialect {
|
|||
functionFactory.arrayPrepend_postgresql();
|
||||
functionFactory.arrayAppend_postgresql();
|
||||
functionFactory.arrayContains_postgresql();
|
||||
functionFactory.arrayOverlaps_postgresql();
|
||||
functionFactory.arrayIntersects_postgresql();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove();
|
||||
|
|
|
@ -21,8 +21,8 @@ import org.hibernate.dialect.function.array.ArrayConcatFunction;
|
|||
import org.hibernate.dialect.function.array.ArrayConstructorFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayContainsOperatorFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayContainsUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayOverlapsOperatorFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayOverlapsUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayIntersectsOperatorFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayIntersectsUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayGetUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayRemoveIndexUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayReplaceUnnestFunction;
|
||||
|
@ -34,7 +34,7 @@ import org.hibernate.dialect.function.array.CockroachArrayFillFunction;
|
|||
import org.hibernate.dialect.function.array.ElementViaArrayArgumentReturnTypeResolver;
|
||||
import org.hibernate.dialect.function.array.H2ArrayContainsFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayFillFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayOverlapsFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayIntersectsFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayPositionFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayPositionsFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayRemoveFunction;
|
||||
|
@ -52,7 +52,7 @@ import org.hibernate.dialect.function.array.HSQLArrayToStringFunction;
|
|||
import org.hibernate.dialect.function.array.OracleArrayConcatElementFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayConcatFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayFillFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayOverlapsFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayIntersectsFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayGetFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayLengthFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayPositionFunction;
|
||||
|
@ -2714,53 +2714,61 @@ public class CommonFunctionFactory {
|
|||
}
|
||||
|
||||
/**
|
||||
* H2 array_overlaps() function
|
||||
* H2 array_intersects() function
|
||||
*/
|
||||
public void arrayOverlaps_h2(int maximumArraySize) {
|
||||
public void arrayIntersects_h2(int maximumArraySize) {
|
||||
functionRegistry.register(
|
||||
"array_overlaps",
|
||||
new H2ArrayOverlapsFunction( false, maximumArraySize, typeConfiguration )
|
||||
"array_intersects",
|
||||
new H2ArrayIntersectsFunction( false, maximumArraySize, typeConfiguration )
|
||||
);
|
||||
functionRegistry.register(
|
||||
"array_overlaps_nullable",
|
||||
new H2ArrayOverlapsFunction( true, maximumArraySize, typeConfiguration )
|
||||
"array_intersects_nullable",
|
||||
new H2ArrayIntersectsFunction( true, maximumArraySize, typeConfiguration )
|
||||
);
|
||||
functionRegistry.registerAlternateKey( "array_overlaps", "array_intersects" );
|
||||
functionRegistry.registerAlternateKey( "array_overlaps_nullable", "array_intersects_nullable" );
|
||||
}
|
||||
|
||||
/**
|
||||
* HSQL array_overlaps() function
|
||||
* HSQL array_intersects() function
|
||||
*/
|
||||
public void arrayOverlaps_hsql() {
|
||||
public void arrayIntersects_hsql() {
|
||||
functionRegistry.register(
|
||||
"array_overlaps",
|
||||
new ArrayOverlapsUnnestFunction( false, typeConfiguration )
|
||||
"array_intersects",
|
||||
new ArrayIntersectsUnnestFunction( false, typeConfiguration )
|
||||
);
|
||||
functionRegistry.register(
|
||||
"array_overlaps_nullable",
|
||||
new ArrayOverlapsUnnestFunction( true, typeConfiguration )
|
||||
"array_intersects_nullable",
|
||||
new ArrayIntersectsUnnestFunction( true, typeConfiguration )
|
||||
);
|
||||
functionRegistry.registerAlternateKey( "array_overlaps", "array_intersects" );
|
||||
functionRegistry.registerAlternateKey( "array_overlaps_nullable", "array_intersects_nullable" );
|
||||
}
|
||||
|
||||
/**
|
||||
* CockroachDB and PostgreSQL array overlaps operator
|
||||
* CockroachDB and PostgreSQL array intersects operator
|
||||
*/
|
||||
public void arrayOverlaps_postgresql() {
|
||||
functionRegistry.register( "array_overlaps", new ArrayOverlapsOperatorFunction( false, typeConfiguration ) );
|
||||
functionRegistry.register( "array_overlaps_nullable", new ArrayOverlapsOperatorFunction( true, typeConfiguration ) );
|
||||
public void arrayIntersects_postgresql() {
|
||||
functionRegistry.register( "array_intersects", new ArrayIntersectsOperatorFunction( false, typeConfiguration ) );
|
||||
functionRegistry.register( "array_intersects_nullable", new ArrayIntersectsOperatorFunction( true, typeConfiguration ) );
|
||||
functionRegistry.registerAlternateKey( "array_overlaps", "array_intersects" );
|
||||
functionRegistry.registerAlternateKey( "array_overlaps_nullable", "array_intersects_nullable" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle array_overlaps() function
|
||||
* Oracle array_intersects() function
|
||||
*/
|
||||
public void arrayOverlaps_oracle() {
|
||||
public void arrayIntersects_oracle() {
|
||||
functionRegistry.register(
|
||||
"array_overlaps",
|
||||
new OracleArrayOverlapsFunction( typeConfiguration, false )
|
||||
"array_intersects",
|
||||
new OracleArrayIntersectsFunction( typeConfiguration, false )
|
||||
);
|
||||
functionRegistry.register(
|
||||
"array_overlaps_nullable",
|
||||
new OracleArrayOverlapsFunction( typeConfiguration, true )
|
||||
"array_intersects_nullable",
|
||||
new OracleArrayIntersectsFunction( typeConfiguration, true )
|
||||
);
|
||||
functionRegistry.registerAlternateKey( "array_overlaps", "array_intersects" );
|
||||
functionRegistry.registerAlternateKey( "array_overlaps_nullable", "array_intersects_nullable" );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,16 +13,16 @@ import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolv
|
|||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* Encapsulates the validator, return type and argument type resolvers for the array_overlaps function.
|
||||
* Encapsulates the validator, return type and argument type resolvers for the array_intersects function.
|
||||
* Subclasses only have to implement the rendering.
|
||||
*/
|
||||
public abstract class AbstractArrayOverlapsFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
public abstract class AbstractArrayIntersectsFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
|
||||
protected final boolean nullable;
|
||||
|
||||
public AbstractArrayOverlapsFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
public AbstractArrayIntersectsFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
super(
|
||||
"array_overlaps" + ( nullable ? "_nullable" : "" ),
|
||||
"array_intersects" + ( nullable ? "_nullable" : "" ),
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 2 ),
|
||||
ArraysOfSameTypeArgumentValidator.INSTANCE
|
|
@ -16,11 +16,11 @@ import org.hibernate.sql.ast.tree.expression.Expression;
|
|||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* Array overlaps function that uses the PostgreSQL {@code &&} operator.
|
||||
* Array intersects function that uses the PostgreSQL {@code &&} operator.
|
||||
*/
|
||||
public class ArrayOverlapsOperatorFunction extends ArrayOverlapsUnnestFunction {
|
||||
public class ArrayIntersectsOperatorFunction extends ArrayIntersectsUnnestFunction {
|
||||
|
||||
public ArrayOverlapsOperatorFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
public ArrayIntersectsOperatorFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
super( nullable, typeConfiguration );
|
||||
}
|
||||
|
|
@ -16,11 +16,11 @@ import org.hibernate.sql.ast.tree.expression.Expression;
|
|||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* Implement the overlaps function by using {@code unnest}.
|
||||
* Implement the intersects function by using {@code unnest}.
|
||||
*/
|
||||
public class ArrayOverlapsUnnestFunction extends AbstractArrayOverlapsFunction {
|
||||
public class ArrayIntersectsUnnestFunction extends AbstractArrayIntersectsFunction {
|
||||
|
||||
public ArrayOverlapsUnnestFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
public ArrayIntersectsUnnestFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
super( nullable, typeConfiguration );
|
||||
}
|
||||
|
|
@ -20,11 +20,11 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
* due to https://github.com/h2database/h2database/issues/1815.
|
||||
* This emulation uses {@code array_get}, {@code array_length} and {@code system_range} functions to roughly achieve the same.
|
||||
*/
|
||||
public class H2ArrayOverlapsFunction extends AbstractArrayOverlapsFunction {
|
||||
public class H2ArrayIntersectsFunction extends AbstractArrayIntersectsFunction {
|
||||
|
||||
private final int maximumArraySize;
|
||||
|
||||
public H2ArrayOverlapsFunction(boolean nullable, int maximumArraySize, TypeConfiguration typeConfiguration) {
|
||||
public H2ArrayIntersectsFunction(boolean nullable, int maximumArraySize, TypeConfiguration typeConfiguration) {
|
||||
super( nullable, typeConfiguration );
|
||||
this.maximumArraySize = maximumArraySize;
|
||||
}
|
|
@ -15,9 +15,9 @@ import org.hibernate.sql.ast.tree.SqlAstNode;
|
|||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
public class OracleArrayOverlapsFunction extends AbstractArrayOverlapsFunction {
|
||||
public class OracleArrayIntersectsFunction extends AbstractArrayIntersectsFunction {
|
||||
|
||||
public OracleArrayOverlapsFunction(TypeConfiguration typeConfiguration, boolean nullable) {
|
||||
public OracleArrayIntersectsFunction(TypeConfiguration typeConfiguration, boolean nullable) {
|
||||
super( nullable, typeConfiguration );
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ public class OracleArrayOverlapsFunction extends AbstractArrayOverlapsFunction {
|
|||
walker.getSessionFactory().getTypeConfiguration()
|
||||
);
|
||||
sqlAppender.appendSql( arrayTypeName );
|
||||
sqlAppender.append( "_overlaps(" );
|
||||
sqlAppender.append( "_intersects(" );
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
sqlAstArguments.get( 1 ).accept( walker );
|
|
@ -2796,49 +2796,121 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder {
|
|||
* Whether one array has any elements common with another array.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #arrayIntersects(Expression, Expression)}
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayOverlaps(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <T> JpaPredicate arrayOverlaps(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2) {
|
||||
return arrayIntersects( arrayExpression1, arrayExpression2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one array has any elements common with another array.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #arrayIntersects(Expression, T[])}
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayOverlaps(Expression<T[]> arrayExpression1, T[] array2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <T> JpaPredicate arrayOverlaps(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return arrayIntersects( arrayExpression1, array2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one array has any elements common with another array.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #arrayIntersects(T[], Expression)}
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayOverlaps(T[] array1, Expression<T[]> arrayExpression2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <T> JpaPredicate arrayOverlaps(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return arrayIntersects( array1, arrayExpression2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one array has any elements common with another array, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #arrayIntersectsNullable(Expression, Expression)}
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayOverlapsNullable(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <T> JpaPredicate arrayOverlapsNullable(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2) {
|
||||
return arrayIntersectsNullable( arrayExpression1, arrayExpression2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one array has any elements common with another array, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #arrayIntersectsNullable(Expression, T[])}
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayOverlapsNullable(Expression<T[]> arrayExpression1, T[] array2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <T> JpaPredicate arrayOverlapsNullable(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return arrayIntersectsNullable( arrayExpression1, array2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one array has any elements common with another array, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #arrayIntersectsNullable(T[], Expression)}
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayOverlapsNullable(T[] array1, Expression<T[]> arrayExpression2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <T> JpaPredicate arrayOverlapsNullable(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return arrayIntersectsNullable( array1, arrayExpression2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one array has any elements common with another array.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayIntersects(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2);
|
||||
|
||||
/**
|
||||
* Whether one array has any elements common with another array.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayIntersects(Expression<T[]> arrayExpression1, T[] array2);
|
||||
|
||||
/**
|
||||
* Whether one array has any elements common with another array.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayIntersects(T[] array1, Expression<T[]> arrayExpression2);
|
||||
|
||||
/**
|
||||
* Whether one array has any elements common with another array, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayIntersectsNullable(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2);
|
||||
|
||||
/**
|
||||
* Whether one array has any elements common with another array, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayIntersectsNullable(Expression<T[]> arrayExpression1, T[] array2);
|
||||
|
||||
/**
|
||||
* Whether one array has any elements common with another array, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<T> JpaPredicate arrayIntersectsNullable(T[] array1, Expression<T[]> arrayExpression2);
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Array functions for collection types
|
||||
|
@ -3275,47 +3347,119 @@ public interface HibernateCriteriaBuilder extends CriteriaBuilder {
|
|||
* Whether one basic collection has any elements common with another basic collection.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #collectionIntersects(Expression, Expression)}
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionOverlaps(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <E> JpaPredicate collectionOverlaps(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return collectionIntersects( collectionExpression1, collectionExpression2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one basic collection has any elements common with another basic collection.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #collectionIntersects(Expression, Collection)}
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionOverlaps(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <E> JpaPredicate collectionOverlaps(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2) {
|
||||
return collectionIntersects( collectionExpression1, collection2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one basic collection has any elements common with another basic collection.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #collectionIntersects(Collection, Expression)}
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionOverlaps(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <E> JpaPredicate collectionOverlaps(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return collectionIntersects( collection1, collectionExpression2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one basic collection has any elements common with another basic collection, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #collectionIntersectsNullable(Expression, Expression)}
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionOverlapsNullable(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <E> JpaPredicate collectionOverlapsNullable(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return collectionIntersectsNullable( collectionExpression1, collectionExpression2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one basic collection has any elements common with another basic collection, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #collectionIntersectsNullable(Expression, Collection)}
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionOverlapsNullable(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <E> JpaPredicate collectionOverlapsNullable(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2) {
|
||||
return collectionIntersectsNullable( collectionExpression1, collection2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one basic collection has any elements common with another basic collection, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.4
|
||||
* @deprecated Replaced with {@link #collectionIntersectsNullable(Collection, Expression)}
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionOverlapsNullable(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
@Deprecated(forRemoval = true)
|
||||
default <E> JpaPredicate collectionOverlapsNullable(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return collectionIntersectsNullable( collection1, collectionExpression2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether one basic collection has any elements common with another basic collection.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionIntersects(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
|
||||
/**
|
||||
* Whether one basic collection has any elements common with another basic collection.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionIntersects(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2);
|
||||
|
||||
/**
|
||||
* Whether one basic collection has any elements common with another basic collection.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionIntersects(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
|
||||
/**
|
||||
* Whether one basic collection has any elements common with another basic collection, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionIntersectsNullable(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
|
||||
/**
|
||||
* Whether one basic collection has any elements common with another basic collection, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionIntersectsNullable(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2);
|
||||
|
||||
/**
|
||||
* Whether one basic collection has any elements common with another basic collection, supporting {@code null} elements.
|
||||
*
|
||||
* @since 6.6
|
||||
*/
|
||||
@Incubating
|
||||
<E> JpaPredicate collectionIntersectsNullable(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
}
|
||||
|
|
|
@ -2531,41 +2531,83 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
|
|||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayOverlaps(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2) {
|
||||
return criteriaBuilder.arrayOverlaps( arrayExpression1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayOverlaps(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return criteriaBuilder.arrayOverlaps( arrayExpression1, array2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayOverlaps(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return criteriaBuilder.arrayOverlaps( array1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayOverlapsNullable(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2) {
|
||||
return criteriaBuilder.arrayOverlapsNullable( arrayExpression1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayOverlapsNullable(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return criteriaBuilder.arrayOverlapsNullable( arrayExpression1, array2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayOverlapsNullable(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return criteriaBuilder.arrayOverlapsNullable( array1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayIntersects(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2) {
|
||||
return criteriaBuilder.arrayIntersects( arrayExpression1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayIntersects(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return criteriaBuilder.arrayIntersects( arrayExpression1, array2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayIntersects(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return criteriaBuilder.arrayIntersects( array1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayIntersectsNullable(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2) {
|
||||
return criteriaBuilder.arrayIntersectsNullable( arrayExpression1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayIntersectsNullable(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return criteriaBuilder.arrayIntersectsNullable( arrayExpression1, array2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <T> JpaPredicate arrayIntersectsNullable(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return criteriaBuilder.arrayIntersectsNullable( array1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <E, C extends Collection<E>> JpaExpression<C> collectionLiteral(E... elements) {
|
||||
|
@ -2985,6 +3027,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
|
|||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionOverlaps(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
|
@ -2993,6 +3036,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
|
|||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionOverlaps(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
|
@ -3001,6 +3045,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
|
|||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionOverlaps(
|
||||
Collection<E> collection1,
|
||||
|
@ -3009,6 +3054,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
|
|||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionOverlapsNullable(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
|
@ -3017,6 +3063,7 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
|
|||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionOverlapsNullable(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
|
@ -3025,10 +3072,59 @@ public class HibernateCriteriaBuilderDelegate implements HibernateCriteriaBuilde
|
|||
}
|
||||
|
||||
@Override
|
||||
@Deprecated(forRemoval = true)
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionOverlapsNullable(
|
||||
Collection<E> collection1,
|
||||
Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return criteriaBuilder.collectionOverlapsNullable( collection1, collectionExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionIntersects(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return criteriaBuilder.collectionIntersects( collectionExpression1, collectionExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionIntersects(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
Collection<? extends E> collection2) {
|
||||
return criteriaBuilder.collectionIntersects( collectionExpression1, collection2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionIntersects(
|
||||
Collection<E> collection1,
|
||||
Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return criteriaBuilder.collectionIntersects( collection1, collectionExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionIntersectsNullable(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return criteriaBuilder.collectionIntersectsNullable( collectionExpression1, collectionExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionIntersectsNullable(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
Collection<? extends E> collection2) {
|
||||
return criteriaBuilder.collectionIntersectsNullable( collectionExpression1, collection2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Incubating
|
||||
public <E> JpaPredicate collectionIntersectsNullable(
|
||||
Collection<E> collection1,
|
||||
Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return criteriaBuilder.collectionIntersectsNullable( collection1, collectionExpression2 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2661,6 +2661,26 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
return new SqmBooleanExpressionPredicate( contains, negated, creationContext.getNodeBuilder() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPredicate visitIntersectsPredicate(HqlParser.IntersectsPredicateContext ctx) {
|
||||
final boolean negated = ctx.NOT() != null;
|
||||
final SqmExpression<?> lhs = (SqmExpression<?>) ctx.expression( 0 ).accept( this );
|
||||
final SqmExpression<?> rhs = (SqmExpression<?>) ctx.expression( 1 ).accept( this );
|
||||
final SqmExpressible<?> lhsExpressible = lhs.getExpressible();
|
||||
if ( lhsExpressible != null && !( lhsExpressible.getSqmType() instanceof BasicPluralType<?, ?>) ) {
|
||||
throw new SemanticException(
|
||||
"First operand for intersects predicate must be a basic plural type expression, but found: " + lhsExpressible.getSqmType(),
|
||||
query
|
||||
);
|
||||
}
|
||||
final SelfRenderingSqmFunction<Boolean> contains = getFunctionDescriptor( "array_intersects" ).generateSqmExpression(
|
||||
asList( lhs, rhs ),
|
||||
null,
|
||||
creationContext.getQueryEngine()
|
||||
);
|
||||
return new SqmBooleanExpressionPredicate( contains, negated, creationContext.getNodeBuilder() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public SqmPredicate visitLikePredicate(HqlParser.LikePredicateContext ctx) {
|
||||
final boolean negated = ctx.NOT() != null;
|
||||
|
|
|
@ -283,22 +283,52 @@ public interface NodeBuilder extends HibernateCriteriaBuilder {
|
|||
<T> SqmPredicate arrayContainsAllNullable(T[] array, Expression<T[]> subArrayExpression);
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayOverlaps(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2);
|
||||
default <T> SqmPredicate arrayOverlaps(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2) {
|
||||
return arrayIntersects( arrayExpression1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayOverlaps(Expression<T[]> arrayExpression1, T[] array2);
|
||||
default <T> SqmPredicate arrayOverlaps(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return arrayIntersects( arrayExpression1, array2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayOverlaps(T[] array1, Expression<T[]> arrayExpression2);
|
||||
default <T> SqmPredicate arrayOverlaps(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return arrayIntersects( array1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayOverlapsNullable(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2);
|
||||
default <T> SqmPredicate arrayOverlapsNullable(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2) {
|
||||
return arrayIntersectsNullable( arrayExpression1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayOverlapsNullable(Expression<T[]> arrayExpression1, T[] array2);
|
||||
default <T> SqmPredicate arrayOverlapsNullable(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return arrayIntersectsNullable( arrayExpression1, array2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayOverlapsNullable(T[] array1, Expression<T[]> arrayExpression2);
|
||||
default <T> SqmPredicate arrayOverlapsNullable(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return arrayIntersectsNullable( array1, arrayExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayIntersects(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2);
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayIntersects(Expression<T[]> arrayExpression1, T[] array2);
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayIntersects(T[] array1, Expression<T[]> arrayExpression2);
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayIntersectsNullable(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2);
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayIntersectsNullable(Expression<T[]> arrayExpression1, T[] array2);
|
||||
|
||||
@Override
|
||||
<T> SqmPredicate arrayIntersectsNullable(T[] array1, Expression<T[]> arrayExpression2);
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Array functions for collection types
|
||||
|
@ -463,22 +493,52 @@ public interface NodeBuilder extends HibernateCriteriaBuilder {
|
|||
<E> SqmPredicate collectionContainsAllNullable(Collection<E> collection, Expression<? extends Collection<? extends E>> subCollectionExpression);
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionOverlaps(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
default <E> SqmPredicate collectionOverlaps(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return collectionIntersects( collectionExpression1, collectionExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionOverlaps(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2);
|
||||
default <E> SqmPredicate collectionOverlaps(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2) {
|
||||
return collectionIntersects( collectionExpression1, collection2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionOverlaps(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
default <E> SqmPredicate collectionOverlaps(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return collectionIntersects( collection1, collectionExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionOverlapsNullable(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
default <E> SqmPredicate collectionOverlapsNullable(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return collectionIntersectsNullable( collectionExpression1, collectionExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionOverlapsNullable(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2);
|
||||
default <E> SqmPredicate collectionOverlapsNullable(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2) {
|
||||
return collectionIntersectsNullable( collectionExpression1, collection2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionOverlapsNullable(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
default <E> SqmPredicate collectionOverlapsNullable(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return collectionIntersectsNullable( collection1, collectionExpression2 );
|
||||
}
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionIntersects(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionIntersects(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2);
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionIntersects(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionIntersectsNullable(Expression<? extends Collection<E>> collectionExpression1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionIntersectsNullable(Expression<? extends Collection<E>> collectionExpression1, Collection<? extends E> collection2);
|
||||
|
||||
@Override
|
||||
<E> SqmPredicate collectionIntersectsNullable(Collection<E> collection1, Expression<? extends Collection<? extends E>> collectionExpression2);
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Covariant overrides
|
||||
|
|
|
@ -3987,8 +3987,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> SqmPredicate arrayOverlaps(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps" ).generateSqmExpression(
|
||||
public <T> SqmPredicate arrayIntersects(Expression<T[]> arrayExpression1, Expression<T[]> arrayExpression2) {
|
||||
return isTrue( getFunctionDescriptor( "array_intersects" ).generateSqmExpression(
|
||||
asList( (SqmExpression<?>) arrayExpression1, (SqmExpression<?>) arrayExpression2 ),
|
||||
null,
|
||||
queryEngine
|
||||
|
@ -3996,8 +3996,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> SqmPredicate arrayOverlaps(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps" ).generateSqmExpression(
|
||||
public <T> SqmPredicate arrayIntersects(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return isTrue( getFunctionDescriptor( "array_intersects" ).generateSqmExpression(
|
||||
asList( (SqmExpression<?>) arrayExpression1, value( array2, (SqmExpression<?>) arrayExpression1 ) ),
|
||||
null,
|
||||
queryEngine
|
||||
|
@ -4005,8 +4005,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> SqmPredicate arrayOverlaps(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps" ).generateSqmExpression(
|
||||
public <T> SqmPredicate arrayIntersects(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return isTrue( getFunctionDescriptor( "array_intersects" ).generateSqmExpression(
|
||||
asList( value( array1, (SqmExpression<?>) arrayExpression2 ), (SqmExpression<?>) arrayExpression2 ),
|
||||
null,
|
||||
queryEngine
|
||||
|
@ -4014,10 +4014,10 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> SqmPredicate arrayOverlapsNullable(
|
||||
public <T> SqmPredicate arrayIntersectsNullable(
|
||||
Expression<T[]> arrayExpression1,
|
||||
Expression<T[]> arrayExpression2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps_nullable" ).generateSqmExpression(
|
||||
return isTrue( getFunctionDescriptor( "array_intersects_nullable" ).generateSqmExpression(
|
||||
asList( (SqmExpression<?>) arrayExpression1, (SqmExpression<?>) arrayExpression2 ),
|
||||
null,
|
||||
queryEngine
|
||||
|
@ -4025,8 +4025,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> SqmPredicate arrayOverlapsNullable(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps_nullable" ).generateSqmExpression(
|
||||
public <T> SqmPredicate arrayIntersectsNullable(Expression<T[]> arrayExpression1, T[] array2) {
|
||||
return isTrue( getFunctionDescriptor( "array_intersects_nullable" ).generateSqmExpression(
|
||||
asList( (SqmExpression<?>) arrayExpression1, value( array2, (SqmExpression<?>) arrayExpression1 ) ),
|
||||
null,
|
||||
queryEngine
|
||||
|
@ -4034,8 +4034,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> SqmPredicate arrayOverlapsNullable(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps_nullable" ).generateSqmExpression(
|
||||
public <T> SqmPredicate arrayIntersectsNullable(T[] array1, Expression<T[]> arrayExpression2) {
|
||||
return isTrue( getFunctionDescriptor( "array_intersects_nullable" ).generateSqmExpression(
|
||||
asList( value( array1, (SqmExpression<?>) arrayExpression2 ), (SqmExpression<?>) arrayExpression2 ),
|
||||
null,
|
||||
queryEngine
|
||||
|
@ -4614,10 +4614,10 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <E> SqmPredicate collectionOverlaps(
|
||||
public <E> SqmPredicate collectionIntersects(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps" ).generateSqmExpression(
|
||||
return isTrue( getFunctionDescriptor( "array_intersects" ).generateSqmExpression(
|
||||
asList( (SqmExpression<?>) collectionExpression1, (SqmExpression<?>) collectionExpression2 ),
|
||||
null,
|
||||
queryEngine
|
||||
|
@ -4625,10 +4625,10 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <E> SqmPredicate collectionOverlaps(
|
||||
public <E> SqmPredicate collectionIntersects(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
Collection<? extends E> collection2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps" ).generateSqmExpression(
|
||||
return isTrue( getFunctionDescriptor( "array_intersects" ).generateSqmExpression(
|
||||
asList( (SqmExpression<?>) collectionExpression1, value( collection2, (SqmExpression<?>) collectionExpression1 ) ),
|
||||
null,
|
||||
queryEngine
|
||||
|
@ -4636,10 +4636,10 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <E> SqmPredicate collectionOverlaps(
|
||||
public <E> SqmPredicate collectionIntersects(
|
||||
Collection<E> collection1,
|
||||
Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps" ).generateSqmExpression(
|
||||
return isTrue( getFunctionDescriptor( "array_intersects" ).generateSqmExpression(
|
||||
asList( value( collection1, (SqmExpression<?>) collectionExpression2 ), (SqmExpression<?>) collectionExpression2 ),
|
||||
null,
|
||||
queryEngine
|
||||
|
@ -4647,10 +4647,10 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <E> SqmPredicate collectionOverlapsNullable(
|
||||
public <E> SqmPredicate collectionIntersectsNullable(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps_nullable" ).generateSqmExpression(
|
||||
return isTrue( getFunctionDescriptor( "array_intersects_nullable" ).generateSqmExpression(
|
||||
asList( (SqmExpression<?>) collectionExpression1, (SqmExpression<?>) collectionExpression2 ),
|
||||
null,
|
||||
queryEngine
|
||||
|
@ -4658,10 +4658,10 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <E> SqmPredicate collectionOverlapsNullable(
|
||||
public <E> SqmPredicate collectionIntersectsNullable(
|
||||
Expression<? extends Collection<E>> collectionExpression1,
|
||||
Collection<? extends E> collection2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps_nullable" ).generateSqmExpression(
|
||||
return isTrue( getFunctionDescriptor( "array_intersects_nullable" ).generateSqmExpression(
|
||||
asList( (SqmExpression<?>) collectionExpression1, value( collection2, (SqmExpression<?>) collectionExpression1 ) ),
|
||||
null,
|
||||
queryEngine
|
||||
|
@ -4669,10 +4669,10 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
|||
}
|
||||
|
||||
@Override
|
||||
public <E> SqmPredicate collectionOverlapsNullable(
|
||||
public <E> SqmPredicate collectionIntersectsNullable(
|
||||
Collection<E> collection1,
|
||||
Expression<? extends Collection<? extends E>> collectionExpression2) {
|
||||
return isTrue( getFunctionDescriptor( "array_overlaps_nullable" ).generateSqmExpression(
|
||||
return isTrue( getFunctionDescriptor( "array_intersects_nullable" ).generateSqmExpression(
|
||||
asList( value( collection1, (SqmExpression<?>) collectionExpression2 ), (SqmExpression<?>) collectionExpression2 ),
|
||||
null,
|
||||
queryEngine
|
||||
|
|
|
@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
@RequiresDialectFeature( feature = DialectFeatureChecks.SupportsStructuralArrays.class)
|
||||
// Clear the type cache, otherwise we might run into ORA-21700: object does not exist or is marked for delete
|
||||
@BootstrapServiceRegistry(integrators = SharedDriverManagerTypeCacheClearingIntegrator.class)
|
||||
public class ArrayOverlapsTest {
|
||||
public class ArrayIntersectsTest {
|
||||
|
||||
@BeforeEach
|
||||
public void prepareData(SessionFactoryScope scope) {
|
||||
|
@ -55,30 +55,30 @@ public class ArrayOverlapsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testOverlapsFully(SessionFactoryScope scope) {
|
||||
public void testIntersectsFully(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
//tag::hql-array-overlaps-example[]
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_overlaps(e.theArray, array('abc', 'def'))", EntityWithArrays.class )
|
||||
//tag::hql-array-intersects-example[]
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_intersects(e.theArray, array('abc', 'def'))", EntityWithArrays.class )
|
||||
.getResultList();
|
||||
//end::hql-array-overlaps-example[]
|
||||
//end::hql-array-intersects-example[]
|
||||
assertEquals( 1, results.size() );
|
||||
assertEquals( 2L, results.get( 0 ).getId() );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesNotOverlap(SessionFactoryScope scope) {
|
||||
public void testDoesNotIntersect(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_overlaps(e.theArray, array('xyz'))", EntityWithArrays.class )
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_intersects(e.theArray, array('xyz'))", EntityWithArrays.class )
|
||||
.getResultList();
|
||||
assertEquals( 0, results.size() );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverlaps(SessionFactoryScope scope) {
|
||||
public void testIntersects(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_overlaps(e.theArray, array('abc','xyz'))", EntityWithArrays.class )
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_intersects(e.theArray, array('abc','xyz'))", EntityWithArrays.class )
|
||||
.getResultList();
|
||||
assertEquals( 1, results.size() );
|
||||
assertEquals( 2L, results.get( 0 ).getId() );
|
||||
|
@ -86,9 +86,9 @@ public class ArrayOverlapsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testOverlapsNullFully(SessionFactoryScope scope) {
|
||||
public void testIntersectsNullFully(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_overlaps_nullable(e.theArray, array(null))", EntityWithArrays.class )
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_intersects_nullable(e.theArray, array(null))", EntityWithArrays.class )
|
||||
.getResultList();
|
||||
assertEquals( 1, results.size() );
|
||||
assertEquals( 2L, results.get( 0 ).getId() );
|
||||
|
@ -96,12 +96,12 @@ public class ArrayOverlapsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testOverlapsNull(SessionFactoryScope scope) {
|
||||
public void testIntersectsNull(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
//tag::hql-array-overlaps-nullable-example[]
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_overlaps_nullable(e.theArray, array('xyz',null))", EntityWithArrays.class )
|
||||
//tag::hql-array-intersects-nullable-example[]
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where array_intersects_nullable(e.theArray, array('xyz',null))", EntityWithArrays.class )
|
||||
.getResultList();
|
||||
//end::hql-array-overlaps-nullable-example[]
|
||||
//end::hql-array-intersects-nullable-example[]
|
||||
assertEquals( 1, results.size() );
|
||||
assertEquals( 2L, results.get( 0 ).getId() );
|
||||
} );
|
||||
|
@ -115,24 +115,24 @@ public class ArrayOverlapsTest {
|
|||
final JpaRoot<EntityWithArrays> root = cq.from( EntityWithArrays.class );
|
||||
cq.multiselect(
|
||||
root.get( "id" ),
|
||||
cb.arrayOverlaps( root.get( "theArray" ), cb.arrayLiteral( "xyz" ) ),
|
||||
cb.arrayOverlaps( root.get( "theArray" ), new String[]{ "xyz" } ),
|
||||
cb.arrayOverlaps( new String[]{ "abc", "xyz" }, cb.arrayLiteral( "xyz" ) ),
|
||||
cb.arrayOverlapsNullable( root.get( "theArray" ), cb.arrayLiteral( "xyz" ) ),
|
||||
cb.arrayOverlapsNullable( root.get( "theArray" ), new String[]{ "xyz" } ),
|
||||
cb.arrayOverlapsNullable( new String[]{ "abc", "xyz" }, cb.arrayLiteral( "xyz" ) )
|
||||
cb.arrayIntersects( root.get( "theArray" ), cb.arrayLiteral( "xyz" ) ),
|
||||
cb.arrayIntersects( root.get( "theArray" ), new String[]{ "xyz" } ),
|
||||
cb.arrayIntersects( new String[]{ "abc", "xyz" }, cb.arrayLiteral( "xyz" ) ),
|
||||
cb.arrayIntersectsNullable( root.get( "theArray" ), cb.arrayLiteral( "xyz" ) ),
|
||||
cb.arrayIntersectsNullable( root.get( "theArray" ), new String[]{ "xyz" } ),
|
||||
cb.arrayIntersectsNullable( new String[]{ "abc", "xyz" }, cb.arrayLiteral( "xyz" ) )
|
||||
);
|
||||
em.createQuery( cq ).getResultList();
|
||||
|
||||
// Should all fail to compile
|
||||
// cb.arrayOverlaps( root.<Integer[]>get( "theArray" ), cb.arrayLiteral( "xyz" ) );
|
||||
// cb.arrayOverlaps( root.<Integer[]>get( "theArray" ), new String[]{ "xyz" } );
|
||||
// cb.arrayOverlaps( new String[0], cb.literal( 1 ) );
|
||||
// cb.arrayOverlaps( new Integer[0], cb.literal( "" ) );
|
||||
// cb.arrayOverlapsNullable( root.<Integer[]>get( "theArray" ), cb.arrayLiteral( "xyz" ) );
|
||||
// cb.arrayOverlapsNullable( root.<Integer[]>get( "theArray" ), new String[]{ "xyz" } );
|
||||
// cb.arrayOverlapsNullable( new String[0], cb.literal( 1 ) );
|
||||
// cb.arrayOverlapsNullable( new Integer[0], cb.literal( "" ) );
|
||||
// cb.arrayIntersects( root.<Integer[]>get( "theArray" ), cb.arrayLiteral( "xyz" ) );
|
||||
// cb.arrayIntersects( root.<Integer[]>get( "theArray" ), new String[]{ "xyz" } );
|
||||
// cb.arrayIntersects( new String[0], cb.literal( 1 ) );
|
||||
// cb.arrayIntersects( new Integer[0], cb.literal( "" ) );
|
||||
// cb.arrayIntersectsNullable( root.<Integer[]>get( "theArray" ), cb.arrayLiteral( "xyz" ) );
|
||||
// cb.arrayIntersectsNullable( root.<Integer[]>get( "theArray" ), new String[]{ "xyz" } );
|
||||
// cb.arrayIntersectsNullable( new String[0], cb.literal( 1 ) );
|
||||
// cb.arrayIntersectsNullable( new Integer[0], cb.literal( "" ) );
|
||||
} );
|
||||
}
|
||||
|
||||
|
@ -144,24 +144,36 @@ public class ArrayOverlapsTest {
|
|||
final JpaRoot<EntityWithArrays> root = cq.from( EntityWithArrays.class );
|
||||
cq.multiselect(
|
||||
root.get( "id" ),
|
||||
cb.collectionOverlaps( root.<Collection<String>>get( "theCollection" ), cb.collectionLiteral( "xyz" ) ),
|
||||
cb.collectionOverlaps( root.get( "theCollection" ), List.of( "xyz" ) ),
|
||||
cb.collectionOverlaps( List.of( "abc", "xyz" ), cb.collectionLiteral( "xyz" ) ),
|
||||
cb.collectionOverlapsNullable( root.<Collection<String>>get( "theCollection" ), cb.collectionLiteral( "xyz" ) ),
|
||||
cb.collectionOverlapsNullable( root.get( "theCollection" ), List.of( "xyz" ) ),
|
||||
cb.collectionOverlapsNullable( List.of( "abc", "xyz" ), cb.collectionLiteral( "xyz" ) )
|
||||
cb.collectionIntersects( root.<Collection<String>>get( "theCollection" ), cb.collectionLiteral( "xyz" ) ),
|
||||
cb.collectionIntersects( root.get( "theCollection" ), List.of( "xyz" ) ),
|
||||
cb.collectionIntersects( List.of( "abc", "xyz" ), cb.collectionLiteral( "xyz" ) ),
|
||||
cb.collectionIntersectsNullable( root.<Collection<String>>get( "theCollection" ), cb.collectionLiteral( "xyz" ) ),
|
||||
cb.collectionIntersectsNullable( root.get( "theCollection" ), List.of( "xyz" ) ),
|
||||
cb.collectionIntersectsNullable( List.of( "abc", "xyz" ), cb.collectionLiteral( "xyz" ) )
|
||||
);
|
||||
em.createQuery( cq ).getResultList();
|
||||
|
||||
// Should all fail to compile
|
||||
// cb.collectionOverlaps( root.<Collection<Integer>>get( "theCollection" ), cb.collectionLiteral( "xyz" ) );
|
||||
// cb.collectionOverlaps( root.<Collection<Integer>>get( "theCollection" ), List.of( "xyz" ) );
|
||||
// cb.collectionOverlaps( Collections.<String>emptyList(), cb.literal( 1 ) );
|
||||
// cb.collectionOverlaps( Collections.<Integer>emptyList(), cb.literal( "" ) );
|
||||
// cb.collectionOverlapsNullable( root.<Collection<Integer>>get( "theCollection" ), cb.collectionLiteral( "xyz" ) );
|
||||
// cb.collectionOverlapsNullable( root.<Collection<Integer>>get( "theCollection" ), List.of( "xyz" ) );
|
||||
// cb.collectionOverlapsNullable( Collections.<String>emptyList(), cb.literal( 1 ) );
|
||||
// cb.collectionOverlapsNullable( Collections.<Integer>emptyList(), cb.literal( "" ) );
|
||||
// cb.collectionIntersects( root.<Collection<Integer>>get( "theCollection" ), cb.collectionLiteral( "xyz" ) );
|
||||
// cb.collectionIntersects( root.<Collection<Integer>>get( "theCollection" ), List.of( "xyz" ) );
|
||||
// cb.collectionIntersects( Collections.<String>emptyList(), cb.literal( 1 ) );
|
||||
// cb.collectionIntersects( Collections.<Integer>emptyList(), cb.literal( "" ) );
|
||||
// cb.collectionIntersectsNullable( root.<Collection<Integer>>get( "theCollection" ), cb.collectionLiteral( "xyz" ) );
|
||||
// cb.collectionIntersectsNullable( root.<Collection<Integer>>get( "theCollection" ), List.of( "xyz" ) );
|
||||
// cb.collectionIntersectsNullable( Collections.<String>emptyList(), cb.literal( 1 ) );
|
||||
// cb.collectionIntersectsNullable( Collections.<Integer>emptyList(), cb.literal( "" ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntersectsSyntax(SessionFactoryScope scope) {
|
||||
scope.inSession( em -> {
|
||||
//tag::hql-array-intersects-hql-example[]
|
||||
List<EntityWithArrays> results = em.createQuery( "from EntityWithArrays e where e.theArray intersects ['abc','xyz']", EntityWithArrays.class )
|
||||
.getResultList();
|
||||
//end::hql-array-intersects-hql-example[]
|
||||
assertEquals( 1, results.size() );
|
||||
assertEquals( 2L, results.get( 0 ).getId() );
|
||||
} );
|
||||
}
|
||||
|
|
@ -98,3 +98,41 @@ class MyEmbeddable { ... }
|
|||
|
||||
----
|
||||
|
||||
[[array-syntax-sugar]]
|
||||
== Syntax sugar for array functions
|
||||
|
||||
Plenty of syntax sugar for array operations was added:
|
||||
|
||||
|
||||
|===
|
||||
|Function |Syntax sugar |
|
||||
|
||||
|`array(1, 2)`
|
||||
|`[1, 2]`
|
||||
|Shorthand bracket syntax for array construction
|
||||
|
||||
|`array_slice(array, 1, 2)`
|
||||
|`array[1:2]`
|
||||
|Shorthand bracket syntax for array slicing
|
||||
|
||||
|`array_length(array)`
|
||||
|`length(array)`
|
||||
|Overload length function with array_length semantics on array input
|
||||
|
||||
|`array_position(array, element)`
|
||||
|`position(element in array)`
|
||||
|Overload position function with array_position semantics on array input
|
||||
|
||||
|`array_to_string(array, ',', 'null')`
|
||||
|`cast(array as String)`
|
||||
|Support casting array to string
|
||||
|
||||
|`array_contains(array, element)`
|
||||
|`array contains element`
|
||||
|Contains predicate for containment check
|
||||
|
||||
|`array_intersects(array, array(1, 2))`
|
||||
|`array intersects [1, 2]`
|
||||
|Overlaps predicate for overlaps check
|
||||
|===
|
||||
|
||||
|
|
Loading…
Reference in New Issue