Skip to content

Commit d46fcf1

Browse files
committed
HHH-17335 Add array_concat function
1 parent 36b7374 commit d46fcf1

23 files changed

+453
-0
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,7 @@ The following functions deal with SQL array types, which are not supported on ev
11221122
| `array_contains_null()` | Whether an array contains a null
11231123
| `array_position()` | Determines the position of an element in an array
11241124
| `array_length()` | Determines the length of an array
1125+
| `array_concat()` | Concatenates array with each other in order
11251126
|===
11261127
11271128
===== `array()`
@@ -1181,6 +1182,19 @@ include::{array-example-dir-hql}/ArrayLengthTest.java[tags=hql-array-length-exam
11811182
----
11821183
====
11831184
1185+
[[hql-array-concat-functions]]
1186+
===== `array_concat()`
1187+
1188+
Concatenates arrays with each other in order. Returns `null` if one of the arguments is `null`.
1189+
1190+
[[hql-array-concat-example]]
1191+
====
1192+
[source, JAVA, indent=0]
1193+
----
1194+
include::{array-example-dir-hql}/ArrayConcatTest.java[tags=hql-array-concat-example]
1195+
----
1196+
====
1197+
11841198
[[hql-user-defined-functions]]
11851199
==== Native and user-defined functions
11861200

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
467467
functionFactory.arrayContainsNull_array_position();
468468
functionFactory.arrayPosition_postgresql();
469469
functionFactory.arrayLength_cardinality();
470+
functionFactory.arrayConcat_postgresql();
470471

471472
functionContributions.getFunctionRegistry().register(
472473
"trunc",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
375375
functionFactory.arrayContains();
376376
functionFactory.arrayContainsNull();
377377
functionFactory.arrayLength_cardinality();
378+
functionFactory.arrayConcat_operator();
378379
}
379380
else {
380381
// Use group_concat until 2.x as listagg was buggy

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
253253
functionFactory.arrayContainsNull_hsql();
254254
functionFactory.arrayPosition_hsql();
255255
functionFactory.arrayLength_cardinality();
256+
functionFactory.arrayConcat_operator();
256257
}
257258

258259
@Override

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
289289
functionFactory.arrayContainsNull_oracle();
290290
functionFactory.arrayPosition_oracle();
291291
functionFactory.arrayLength_oracle();
292+
functionFactory.arrayConcat_oracle();
292293
}
293294

294295
@Override

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
587587
functionFactory.arrayContainsNull_array_position();
588588
functionFactory.arrayPosition_postgresql();
589589
functionFactory.arrayLength_cardinality();
590+
functionFactory.arrayConcat_postgresql();
590591

591592
if ( getVersion().isSameOrAfter( 9, 4 ) ) {
592593
functionFactory.makeDateTimeTimestamp();

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
454454
functionFactory.arrayContainsNull_array_position();
455455
functionFactory.arrayPosition_postgresql();
456456
functionFactory.arrayLength_cardinality();
457+
functionFactory.arrayConcat_postgresql();
457458

458459
functionContributions.getFunctionRegistry().register(
459460
"trunc",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
315315
functionFactory.arrayContains();
316316
functionFactory.arrayContainsNull();
317317
functionFactory.arrayLength_cardinality();
318+
functionFactory.arrayConcat_operator();
318319
}
319320

320321
@Override

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
193193
functionFactory.arrayContainsNull_hsql();
194194
functionFactory.arrayPosition_hsql();
195195
functionFactory.arrayLength_cardinality();
196+
functionFactory.arrayConcat_operator();
196197
}
197198

198199
@Override

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,48 @@ public void addAuxiliaryDatabaseObjects(
272272
false
273273
)
274274
);
275+
database.addAuxiliaryDatabaseObject(
276+
new NamedAuxiliaryDatabaseObject(
277+
arrayTypeName + "_concat",
278+
database.getDefaultNamespace(),
279+
new String[]{ createOrReplaceConcatFunction( arrayTypeName ) },
280+
new String[] { "drop function " + arrayTypeName + "_concat" },
281+
emptySet(),
282+
false
283+
)
284+
);
285+
}
286+
287+
protected String createOrReplaceConcatFunction(String arrayTypeName) {
288+
// Since Oracle has no builtin concat function for varrays and doesn't support varargs,
289+
// we have to create a function with a fixed amount of arguments with default that fits "most" cases.
290+
// Let's just use 5 for the time being until someone requests more.
291+
return createOrReplaceConcatFunction( arrayTypeName, 5 );
292+
}
293+
294+
protected String createOrReplaceConcatFunction(String arrayTypeName, int maxConcatParams) {
295+
final StringBuilder sb = new StringBuilder();
296+
sb.append( "create or replace function " ).append( arrayTypeName ).append( "_concat(" );
297+
sb.append( "arr0 in " ).append( arrayTypeName ).append( ",arr1 in " ).append( arrayTypeName );
298+
for ( int i = 2; i < maxConcatParams; i++ ) {
299+
sb.append( ",arr" ).append( i ).append( " in " ).append( arrayTypeName )
300+
.append( " default " ).append( arrayTypeName ).append( "()" );
301+
}
302+
sb.append( ") return " ).append( arrayTypeName ).append( " deterministic is res " ).append( arrayTypeName )
303+
.append( "; begin if " );
304+
String separator = "";
305+
for ( int i = 0; i < maxConcatParams; i++ ) {
306+
sb.append( separator ).append( "arr" ).append( i ).append( " is null" );
307+
separator = " or ";
308+
}
309+
sb.append( " then return null; end if; " );
310+
sb.append( "select * bulk collect into res from (" );
311+
separator = "";
312+
for ( int i = 0; i < maxConcatParams; i++ ) {
313+
sb.append( separator ).append( "select * from table(arr" ).append( i ).append( ')' );
314+
separator = " union all ";
315+
}
316+
return sb.append( "); return res; end;" ).toString();
275317
}
276318

277319
private static String getRawTypeName(String typeName) {

0 commit comments

Comments
 (0)