Skip to content

Commit d5404fd

Browse files
committed
HHH-17335 Add array_contains quantified functions
1 parent d46fcf1 commit d5404fd

27 files changed

+840
-20
lines changed

documentation/src/main/asciidoc/userguide/chapters/query/hql/QueryLanguage.adoc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,6 +1195,52 @@ include::{array-example-dir-hql}/ArrayConcatTest.java[tags=hql-array-concat-exam
11951195
----
11961196
====
11971197
1198+
[[hql-array-contains-quantified-functions]]
1199+
===== `array_contains_all()` and `array_contains_any()`
1200+
1201+
Checks if the first array argument contains all or any of the elements of the second array argument.
1202+
Returns `null` if either of the arguments is `null`. The result of the functions
1203+
is undefined when the second array argument contains a `null`.
1204+
1205+
[[hql-array-contains-all-example]]
1206+
====
1207+
[source, JAVA, indent=0]
1208+
----
1209+
include::{array-example-dir-hql}/ArrayContainsAllTest.java[tags=hql-array-contains-all-example]
1210+
----
1211+
====
1212+
1213+
[[hql-array-contains-any-example]]
1214+
====
1215+
[source, JAVA, indent=0]
1216+
----
1217+
include::{array-example-dir-hql}/ArrayContainsAnyTest.java[tags=hql-array-contains-any-example]
1218+
----
1219+
====
1220+
1221+
[[hql-array-contains-quantified-functions]]
1222+
===== `array_contains_all_nullable()` & `array_contains_any_nullable()`
1223+
1224+
Checks if the first array argument contains all or any of the elements of the second array argument.
1225+
Returns `null` if either of the arguments is `null`. Contrary to `array_contains_all()` and `array_contains_any()`,
1226+
these functions use the `distinct from` operator to also support searching for `null` elements.
1227+
1228+
[[hql-array-contains-all-nullable-example]]
1229+
====
1230+
[source, JAVA, indent=0]
1231+
----
1232+
include::{array-example-dir-hql}/ArrayContainsAllTest.java[tags=hql-array-contains-all-nullable-example]
1233+
----
1234+
====
1235+
1236+
[[hql-array-contains-any-nullable-example]]
1237+
====
1238+
[source, JAVA, indent=0]
1239+
----
1240+
include::{array-example-dir-hql}/ArrayContainsAnyTest.java[tags=hql-array-contains-any-nullable-example]
1241+
----
1242+
====
1243+
11981244
[[hql-user-defined-functions]]
11991245
==== Native and user-defined functions
12001246

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,10 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
468468
functionFactory.arrayPosition_postgresql();
469469
functionFactory.arrayLength_cardinality();
470470
functionFactory.arrayConcat_postgresql();
471+
functionFactory.arrayContainsAll_operator();
472+
functionFactory.arrayContainsAny_operator();
473+
functionFactory.arrayContainsAllNullable_operator();
474+
functionFactory.arrayContainsAnyNullable_operator();
471475

472476
functionContributions.getFunctionRegistry().register(
473477
"trunc",

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacyDialect.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
376376
functionFactory.arrayContainsNull();
377377
functionFactory.arrayLength_cardinality();
378378
functionFactory.arrayConcat_operator();
379+
functionFactory.arrayContainsAll_h2();
380+
functionFactory.arrayContainsAny_h2();
381+
functionFactory.arrayContainsAllNullable_h2();
382+
functionFactory.arrayContainsAnyNullable_h2();
379383
}
380384
else {
381385
// Use group_concat until 2.x as listagg was buggy

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacyDialect.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
254254
functionFactory.arrayPosition_hsql();
255255
functionFactory.arrayLength_cardinality();
256256
functionFactory.arrayConcat_operator();
257+
functionFactory.arrayContainsAll_hsql();
258+
functionFactory.arrayContainsAny_hsql();
259+
functionFactory.arrayContainsAllNullable_hsql();
260+
functionFactory.arrayContainsAnyNullable_hsql();
257261
}
258262

259263
@Override

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacyDialect.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
290290
functionFactory.arrayPosition_oracle();
291291
functionFactory.arrayLength_oracle();
292292
functionFactory.arrayConcat_oracle();
293+
functionFactory.arrayContainsAll_oracle();
294+
functionFactory.arrayContainsAny_oracle();
295+
functionFactory.arrayContainsAllNullable_oracle();
296+
functionFactory.arrayContainsAnyNullable_oracle();
293297
}
294298

295299
@Override

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/PostgreSQLLegacyDialect.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,10 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
588588
functionFactory.arrayPosition_postgresql();
589589
functionFactory.arrayLength_cardinality();
590590
functionFactory.arrayConcat_postgresql();
591+
functionFactory.arrayContainsAll_operator();
592+
functionFactory.arrayContainsAny_operator();
593+
functionFactory.arrayContainsAllNullable_operator();
594+
functionFactory.arrayContainsAnyNullable_operator();
591595

592596
if ( getVersion().isSameOrAfter( 9, 4 ) ) {
593597
functionFactory.makeDateTimeTimestamp();

hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,10 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
455455
functionFactory.arrayPosition_postgresql();
456456
functionFactory.arrayLength_cardinality();
457457
functionFactory.arrayConcat_postgresql();
458+
functionFactory.arrayContainsAll_operator();
459+
functionFactory.arrayContainsAny_operator();
460+
functionFactory.arrayContainsAllNullable_operator();
461+
functionFactory.arrayContainsAnyNullable_operator();
458462

459463
functionContributions.getFunctionRegistry().register(
460464
"trunc",

hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
316316
functionFactory.arrayContainsNull();
317317
functionFactory.arrayLength_cardinality();
318318
functionFactory.arrayConcat_operator();
319+
functionFactory.arrayContainsAll_h2();
320+
functionFactory.arrayContainsAny_h2();
321+
functionFactory.arrayContainsAllNullable_h2();
322+
functionFactory.arrayContainsAnyNullable_h2();
319323
}
320324

321325
@Override

hibernate-core/src/main/java/org/hibernate/dialect/HSQLDialect.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
194194
functionFactory.arrayPosition_hsql();
195195
functionFactory.arrayLength_cardinality();
196196
functionFactory.arrayConcat_operator();
197+
functionFactory.arrayContainsAll_hsql();
198+
functionFactory.arrayContainsAny_hsql();
199+
functionFactory.arrayContainsAllNullable_hsql();
200+
functionFactory.arrayContainsAnyNullable_hsql();
197201
}
198202

199203
@Override

hibernate-core/src/main/java/org/hibernate/dialect/OracleArrayJdbcType.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,51 @@ public void addAuxiliaryDatabaseObjects(
282282
false
283283
)
284284
);
285+
database.addAuxiliaryDatabaseObject(
286+
new NamedAuxiliaryDatabaseObject(
287+
arrayTypeName + "_contains_all",
288+
database.getDefaultNamespace(),
289+
new String[]{
290+
"create or replace function " + arrayTypeName + "_contains_all(haystack in " + arrayTypeName +
291+
", needle in " + arrayTypeName + ", nullable in number) return number deterministic is found number(1,0); begin " +
292+
"if haystack is null or needle is null then return null; end if; " +
293+
"for i in 1 .. needle.count loop " +
294+
"found := 0; " +
295+
"for j in 1 .. haystack.count loop " +
296+
"if nullable = 1 and needle(i) is null and haystack(j) is null or needle(i)=haystack(j) then found := 1; exit; end if; " +
297+
"end loop; " +
298+
"if found = 0 then return 0; end if;" +
299+
"end loop; " +
300+
"return 1; " +
301+
"end;"
302+
},
303+
new String[] { "drop function " + arrayTypeName + "_contains_all" },
304+
emptySet(),
305+
false
306+
)
307+
);
308+
database.addAuxiliaryDatabaseObject(
309+
new NamedAuxiliaryDatabaseObject(
310+
arrayTypeName + "_contains_any",
311+
database.getDefaultNamespace(),
312+
new String[]{
313+
"create or replace function " + arrayTypeName + "_contains_any(haystack in " + arrayTypeName +
314+
", needle in " + arrayTypeName + ", nullable in number) return number deterministic is begin " +
315+
"if haystack is null or needle is null then return null; end if; " +
316+
"if needle.count = 0 then return 1; end if; " +
317+
"for i in 1 .. needle.count loop " +
318+
"for j in 1 .. haystack.count loop " +
319+
"if nullable = 1 and needle(i) is null and haystack(j) is null or needle(i)=haystack(j) then return 1; end if; " +
320+
"end loop; " +
321+
"end loop; " +
322+
"return 0; " +
323+
"end;"
324+
},
325+
new String[] { "drop function " + arrayTypeName + "_contains_any" },
326+
emptySet(),
327+
false
328+
)
329+
);
285330
}
286331

287332
protected String createOrReplaceConcatFunction(String arrayTypeName) {

0 commit comments

Comments
 (0)