HHH-17355 Add array_positions and array_positions_list functions
This commit is contained in:
parent
fe9289ba57
commit
c3e1815486
|
@ -1120,6 +1120,8 @@ The following functions deal with SQL array types, which are not supported on ev
|
||||||
| `array()` | Creates an array based on the passed arguments
|
| `array()` | Creates an array based on the passed arguments
|
||||||
| `array_agg()` | Aggregates row values into an array
|
| `array_agg()` | Aggregates row values into an array
|
||||||
| `array_position()` | Determines the position of an element in an array
|
| `array_position()` | Determines the position of an element in an array
|
||||||
|
| `array_positions()` | Determines all positions of an element in an array
|
||||||
|
| `array_positions_list()` | Like `array_positions`, but returns the result as `List<Integer>`
|
||||||
| `array_length()` | Determines the length of an array
|
| `array_length()` | Determines the length of an array
|
||||||
| `array_concat()` | Concatenates array with each other in order
|
| `array_concat()` | Concatenates array with each other in order
|
||||||
| `array_prepend()` | Prepends element to array
|
| `array_prepend()` | Prepends element to array
|
||||||
|
@ -1175,6 +1177,20 @@ include::{array-example-dir-hql}/ArrayPositionTest.java[tags=hql-array-position-
|
||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
|
[[hql-array-positions-functions]]
|
||||||
|
===== `array_positions()` and `array_positions_list()`
|
||||||
|
|
||||||
|
Returns an `int[]` of 1-based positions of matching elements in the array. Returns an empty array if the element is not found and `null` if the array is `null`.
|
||||||
|
To retrieve the result as `List<Integer>`, use the `array_positions_list()` function.
|
||||||
|
|
||||||
|
[[hql-array-positions-example]]
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{array-example-dir-hql}/ArrayPositionsTest.java[tags=hql-array-positions-example]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
[[hql-array-length-functions]]
|
[[hql-array-length-functions]]
|
||||||
===== `array_length()`
|
===== `array_length()`
|
||||||
|
|
||||||
|
|
|
@ -464,6 +464,7 @@ public class CockroachLegacyDialect extends Dialect {
|
||||||
functionFactory.array_postgresql();
|
functionFactory.array_postgresql();
|
||||||
functionFactory.arrayAggregate();
|
functionFactory.arrayAggregate();
|
||||||
functionFactory.arrayPosition_postgresql();
|
functionFactory.arrayPosition_postgresql();
|
||||||
|
functionFactory.arrayPositions_postgresql();
|
||||||
functionFactory.arrayLength_cardinality();
|
functionFactory.arrayLength_cardinality();
|
||||||
functionFactory.arrayConcat_postgresql();
|
functionFactory.arrayConcat_postgresql();
|
||||||
functionFactory.arrayPrepend_postgresql();
|
functionFactory.arrayPrepend_postgresql();
|
||||||
|
|
|
@ -372,6 +372,8 @@ public class H2LegacyDialect extends Dialect {
|
||||||
functionFactory.listagg( null );
|
functionFactory.listagg( null );
|
||||||
functionFactory.array();
|
functionFactory.array();
|
||||||
functionFactory.arrayAggregate();
|
functionFactory.arrayAggregate();
|
||||||
|
functionFactory.arrayPosition_h2( getMaximumArraySize() );
|
||||||
|
functionFactory.arrayPositions_h2( getMaximumArraySize() );
|
||||||
functionFactory.arrayLength_cardinality();
|
functionFactory.arrayLength_cardinality();
|
||||||
functionFactory.arrayConcat_operator();
|
functionFactory.arrayConcat_operator();
|
||||||
functionFactory.arrayPrepend_operator();
|
functionFactory.arrayPrepend_operator();
|
||||||
|
|
|
@ -250,6 +250,7 @@ public class HSQLLegacyDialect extends Dialect {
|
||||||
functionFactory.array_hsql();
|
functionFactory.array_hsql();
|
||||||
functionFactory.arrayAggregate();
|
functionFactory.arrayAggregate();
|
||||||
functionFactory.arrayPosition_hsql();
|
functionFactory.arrayPosition_hsql();
|
||||||
|
functionFactory.arrayPositions_hsql();
|
||||||
functionFactory.arrayLength_cardinality();
|
functionFactory.arrayLength_cardinality();
|
||||||
functionFactory.arrayConcat_operator();
|
functionFactory.arrayConcat_operator();
|
||||||
functionFactory.arrayPrepend_operator();
|
functionFactory.arrayPrepend_operator();
|
||||||
|
|
|
@ -286,6 +286,7 @@ public class OracleLegacyDialect extends Dialect {
|
||||||
functionFactory.array_oracle();
|
functionFactory.array_oracle();
|
||||||
functionFactory.arrayAggregate_jsonArrayagg();
|
functionFactory.arrayAggregate_jsonArrayagg();
|
||||||
functionFactory.arrayPosition_oracle();
|
functionFactory.arrayPosition_oracle();
|
||||||
|
functionFactory.arrayPositions_oracle();
|
||||||
functionFactory.arrayLength_oracle();
|
functionFactory.arrayLength_oracle();
|
||||||
functionFactory.arrayConcat_oracle();
|
functionFactory.arrayConcat_oracle();
|
||||||
functionFactory.arrayPrepend_oracle();
|
functionFactory.arrayPrepend_oracle();
|
||||||
|
|
|
@ -584,6 +584,7 @@ public class PostgreSQLLegacyDialect extends Dialect {
|
||||||
functionFactory.array_postgresql();
|
functionFactory.array_postgresql();
|
||||||
functionFactory.arrayAggregate();
|
functionFactory.arrayAggregate();
|
||||||
functionFactory.arrayPosition_postgresql();
|
functionFactory.arrayPosition_postgresql();
|
||||||
|
functionFactory.arrayPositions_postgresql();
|
||||||
functionFactory.arrayLength_cardinality();
|
functionFactory.arrayLength_cardinality();
|
||||||
functionFactory.arrayConcat_postgresql();
|
functionFactory.arrayConcat_postgresql();
|
||||||
functionFactory.arrayPrepend_postgresql();
|
functionFactory.arrayPrepend_postgresql();
|
||||||
|
|
|
@ -451,6 +451,7 @@ public class CockroachDialect extends Dialect {
|
||||||
functionFactory.array_postgresql();
|
functionFactory.array_postgresql();
|
||||||
functionFactory.arrayAggregate();
|
functionFactory.arrayAggregate();
|
||||||
functionFactory.arrayPosition_postgresql();
|
functionFactory.arrayPosition_postgresql();
|
||||||
|
functionFactory.arrayPositions_postgresql();
|
||||||
functionFactory.arrayLength_cardinality();
|
functionFactory.arrayLength_cardinality();
|
||||||
functionFactory.arrayConcat_postgresql();
|
functionFactory.arrayConcat_postgresql();
|
||||||
functionFactory.arrayPrepend_postgresql();
|
functionFactory.arrayPrepend_postgresql();
|
||||||
|
|
|
@ -311,6 +311,8 @@ public class H2Dialect extends Dialect {
|
||||||
functionFactory.hypotheticalOrderedSetAggregates();
|
functionFactory.hypotheticalOrderedSetAggregates();
|
||||||
functionFactory.array();
|
functionFactory.array();
|
||||||
functionFactory.arrayAggregate();
|
functionFactory.arrayAggregate();
|
||||||
|
functionFactory.arrayPosition_h2( getMaximumArraySize() );
|
||||||
|
functionFactory.arrayPositions_h2( getMaximumArraySize() );
|
||||||
functionFactory.arrayLength_cardinality();
|
functionFactory.arrayLength_cardinality();
|
||||||
functionFactory.arrayConcat_operator();
|
functionFactory.arrayConcat_operator();
|
||||||
functionFactory.arrayPrepend_operator();
|
functionFactory.arrayPrepend_operator();
|
||||||
|
|
|
@ -190,6 +190,7 @@ public class HSQLDialect extends Dialect {
|
||||||
functionFactory.array_hsql();
|
functionFactory.array_hsql();
|
||||||
functionFactory.arrayAggregate();
|
functionFactory.arrayAggregate();
|
||||||
functionFactory.arrayPosition_hsql();
|
functionFactory.arrayPosition_hsql();
|
||||||
|
functionFactory.arrayPositions_hsql();
|
||||||
functionFactory.arrayLength_cardinality();
|
functionFactory.arrayLength_cardinality();
|
||||||
functionFactory.arrayConcat_operator();
|
functionFactory.arrayConcat_operator();
|
||||||
functionFactory.arrayPrepend_operator();
|
functionFactory.arrayPrepend_operator();
|
||||||
|
|
|
@ -515,6 +515,32 @@ public class OracleArrayJdbcType extends ArrayJdbcType {
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
database.addAuxiliaryDatabaseObject(
|
||||||
|
new NamedAuxiliaryDatabaseObject(
|
||||||
|
arrayTypeName + "_positions",
|
||||||
|
database.getDefaultNamespace(),
|
||||||
|
new String[]{
|
||||||
|
"create or replace function " + arrayTypeName + "_positions(arr in " + arrayTypeName +
|
||||||
|
", elem in " + getRawTypeName( elementType ) + ") return sdo_ordinate_array deterministic is " +
|
||||||
|
"res sdo_ordinate_array:=sdo_ordinate_array(); begin " +
|
||||||
|
"if arr is null then return null; end if; " +
|
||||||
|
"if elem is null then " +
|
||||||
|
"for i in 1 .. arr.count loop " +
|
||||||
|
"if arr(i) is null then res.extend; res(res.last):=i; end if; " +
|
||||||
|
"end loop; " +
|
||||||
|
"else " +
|
||||||
|
"for i in 1 .. arr.count loop " +
|
||||||
|
"if arr(i)=elem then res.extend; res(res.last):=i; end if; " +
|
||||||
|
"end loop; " +
|
||||||
|
"end if; " +
|
||||||
|
"return res; " +
|
||||||
|
"end;"
|
||||||
|
},
|
||||||
|
new String[] { "drop function " + arrayTypeName + "_positions" },
|
||||||
|
emptySet(),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String createOrReplaceConcatFunction(String arrayTypeName) {
|
protected String createOrReplaceConcatFunction(String arrayTypeName) {
|
||||||
|
|
|
@ -315,6 +315,7 @@ public class OracleDialect extends Dialect {
|
||||||
functionFactory.array_oracle();
|
functionFactory.array_oracle();
|
||||||
functionFactory.arrayAggregate_jsonArrayagg();
|
functionFactory.arrayAggregate_jsonArrayagg();
|
||||||
functionFactory.arrayPosition_oracle();
|
functionFactory.arrayPosition_oracle();
|
||||||
|
functionFactory.arrayPositions_oracle();
|
||||||
functionFactory.arrayLength_oracle();
|
functionFactory.arrayLength_oracle();
|
||||||
functionFactory.arrayConcat_oracle();
|
functionFactory.arrayConcat_oracle();
|
||||||
functionFactory.arrayPrepend_oracle();
|
functionFactory.arrayPrepend_oracle();
|
||||||
|
|
|
@ -632,6 +632,7 @@ public class PostgreSQLDialect extends Dialect {
|
||||||
functionFactory.array_postgresql();
|
functionFactory.array_postgresql();
|
||||||
functionFactory.arrayAggregate();
|
functionFactory.arrayAggregate();
|
||||||
functionFactory.arrayPosition_postgresql();
|
functionFactory.arrayPosition_postgresql();
|
||||||
|
functionFactory.arrayPositions_postgresql();
|
||||||
functionFactory.arrayLength_cardinality();
|
functionFactory.arrayLength_cardinality();
|
||||||
functionFactory.arrayConcat_postgresql();
|
functionFactory.arrayConcat_postgresql();
|
||||||
functionFactory.arrayPrepend_postgresql();
|
functionFactory.arrayPrepend_postgresql();
|
||||||
|
|
|
@ -6,9 +6,12 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.dialect.function;
|
package org.hibernate.dialect.function;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.annotations.common.reflection.java.generics.ParameterizedTypeImpl;
|
||||||
import org.hibernate.boot.model.FunctionContributions;
|
import org.hibernate.boot.model.FunctionContributions;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
|
||||||
|
@ -33,6 +36,8 @@ import org.hibernate.dialect.function.array.ElementViaArrayArgumentReturnTypeRes
|
||||||
import org.hibernate.dialect.function.array.H2ArrayContainsFunction;
|
import org.hibernate.dialect.function.array.H2ArrayContainsFunction;
|
||||||
import org.hibernate.dialect.function.array.H2ArrayFillFunction;
|
import org.hibernate.dialect.function.array.H2ArrayFillFunction;
|
||||||
import org.hibernate.dialect.function.array.H2ArrayOverlapsFunction;
|
import org.hibernate.dialect.function.array.H2ArrayOverlapsFunction;
|
||||||
|
import org.hibernate.dialect.function.array.H2ArrayPositionFunction;
|
||||||
|
import org.hibernate.dialect.function.array.H2ArrayPositionsFunction;
|
||||||
import org.hibernate.dialect.function.array.H2ArrayRemoveFunction;
|
import org.hibernate.dialect.function.array.H2ArrayRemoveFunction;
|
||||||
import org.hibernate.dialect.function.array.H2ArrayRemoveIndexFunction;
|
import org.hibernate.dialect.function.array.H2ArrayRemoveIndexFunction;
|
||||||
import org.hibernate.dialect.function.array.H2ArrayReplaceFunction;
|
import org.hibernate.dialect.function.array.H2ArrayReplaceFunction;
|
||||||
|
@ -40,6 +45,7 @@ import org.hibernate.dialect.function.array.H2ArraySetFunction;
|
||||||
import org.hibernate.dialect.function.array.HSQLArrayConstructorFunction;
|
import org.hibernate.dialect.function.array.HSQLArrayConstructorFunction;
|
||||||
import org.hibernate.dialect.function.array.HSQLArrayFillFunction;
|
import org.hibernate.dialect.function.array.HSQLArrayFillFunction;
|
||||||
import org.hibernate.dialect.function.array.HSQLArrayPositionFunction;
|
import org.hibernate.dialect.function.array.HSQLArrayPositionFunction;
|
||||||
|
import org.hibernate.dialect.function.array.HSQLArrayPositionsFunction;
|
||||||
import org.hibernate.dialect.function.array.HSQLArrayRemoveFunction;
|
import org.hibernate.dialect.function.array.HSQLArrayRemoveFunction;
|
||||||
import org.hibernate.dialect.function.array.HSQLArraySetFunction;
|
import org.hibernate.dialect.function.array.HSQLArraySetFunction;
|
||||||
import org.hibernate.dialect.function.array.OracleArrayConcatElementFunction;
|
import org.hibernate.dialect.function.array.OracleArrayConcatElementFunction;
|
||||||
|
@ -49,6 +55,7 @@ import org.hibernate.dialect.function.array.OracleArrayOverlapsFunction;
|
||||||
import org.hibernate.dialect.function.array.OracleArrayGetFunction;
|
import org.hibernate.dialect.function.array.OracleArrayGetFunction;
|
||||||
import org.hibernate.dialect.function.array.OracleArrayLengthFunction;
|
import org.hibernate.dialect.function.array.OracleArrayLengthFunction;
|
||||||
import org.hibernate.dialect.function.array.OracleArrayPositionFunction;
|
import org.hibernate.dialect.function.array.OracleArrayPositionFunction;
|
||||||
|
import org.hibernate.dialect.function.array.OracleArrayPositionsFunction;
|
||||||
import org.hibernate.dialect.function.array.OracleArrayRemoveFunction;
|
import org.hibernate.dialect.function.array.OracleArrayRemoveFunction;
|
||||||
import org.hibernate.dialect.function.array.OracleArrayRemoveIndexFunction;
|
import org.hibernate.dialect.function.array.OracleArrayRemoveIndexFunction;
|
||||||
import org.hibernate.dialect.function.array.OracleArrayReplaceFunction;
|
import org.hibernate.dialect.function.array.OracleArrayReplaceFunction;
|
||||||
|
@ -63,6 +70,7 @@ import org.hibernate.dialect.function.array.PostgreSQLArrayConstructorFunction;
|
||||||
import org.hibernate.dialect.function.array.OracleArrayAggEmulation;
|
import org.hibernate.dialect.function.array.OracleArrayAggEmulation;
|
||||||
import org.hibernate.dialect.function.array.OracleArrayConstructorFunction;
|
import org.hibernate.dialect.function.array.OracleArrayConstructorFunction;
|
||||||
import org.hibernate.dialect.function.array.OracleArrayContainsFunction;
|
import org.hibernate.dialect.function.array.OracleArrayContainsFunction;
|
||||||
|
import org.hibernate.dialect.function.array.PostgreSQLArrayPositionsFunction;
|
||||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
@ -2738,6 +2746,13 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.register( "array_position", new PostgreSQLArrayPositionFunction( typeConfiguration ) );
|
functionRegistry.register( "array_position", new PostgreSQLArrayPositionFunction( typeConfiguration ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* H2 array_position() function
|
||||||
|
*/
|
||||||
|
public void arrayPosition_h2(int maximumArraySize) {
|
||||||
|
functionRegistry.register( "array_position", new H2ArrayPositionFunction( maximumArraySize, typeConfiguration ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HSQL array_position() function
|
* HSQL array_position() function
|
||||||
*/
|
*/
|
||||||
|
@ -2752,6 +2767,62 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.register( "array_position", new OracleArrayPositionFunction( typeConfiguration ) );
|
functionRegistry.register( "array_position", new OracleArrayPositionFunction( typeConfiguration ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CockroachDB and PostgreSQL array_positions() function
|
||||||
|
*/
|
||||||
|
public void arrayPositions_postgresql() {
|
||||||
|
functionRegistry.register(
|
||||||
|
"array_positions",
|
||||||
|
new PostgreSQLArrayPositionsFunction( false, typeConfiguration )
|
||||||
|
);
|
||||||
|
functionRegistry.register(
|
||||||
|
"array_positions_list",
|
||||||
|
new PostgreSQLArrayPositionsFunction( true, typeConfiguration )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* H2 array_positions() function
|
||||||
|
*/
|
||||||
|
public void arrayPositions_h2(int maximumArraySize) {
|
||||||
|
functionRegistry.register(
|
||||||
|
"array_positions",
|
||||||
|
new H2ArrayPositionsFunction( false, maximumArraySize, typeConfiguration )
|
||||||
|
);
|
||||||
|
functionRegistry.register(
|
||||||
|
"array_positions_list",
|
||||||
|
new H2ArrayPositionsFunction( true, maximumArraySize, typeConfiguration )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HSQL array_positions() function
|
||||||
|
*/
|
||||||
|
public void arrayPositions_hsql() {
|
||||||
|
functionRegistry.register(
|
||||||
|
"array_positions",
|
||||||
|
new HSQLArrayPositionsFunction( false, typeConfiguration )
|
||||||
|
);
|
||||||
|
functionRegistry.register(
|
||||||
|
"array_positions_list",
|
||||||
|
new HSQLArrayPositionsFunction( true, typeConfiguration )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Oracle array_positions() function
|
||||||
|
*/
|
||||||
|
public void arrayPositions_oracle() {
|
||||||
|
functionRegistry.register(
|
||||||
|
"array_positions",
|
||||||
|
new OracleArrayPositionsFunction( false, typeConfiguration )
|
||||||
|
);
|
||||||
|
functionRegistry.register(
|
||||||
|
"array_positions_list",
|
||||||
|
new OracleArrayPositionsFunction( true, typeConfiguration )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* H2, HSQLDB, CockroachDB and PostgreSQL array_length() function
|
* H2, HSQLDB, CockroachDB and PostgreSQL array_length() function
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* 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.lang.reflect.Type;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
|
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
|
import org.hibernate.type.internal.ParameterizedTypeImpl;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates the validator, return type and argument type resolvers for the array_positions functions.
|
||||||
|
* Subclasses only have to implement the rendering.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractArrayPositionsFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
|
|
||||||
|
public AbstractArrayPositionsFunction(boolean list, TypeConfiguration typeConfiguration) {
|
||||||
|
super(
|
||||||
|
"array_positions" + ( list ? "_list" : "" ),
|
||||||
|
new ArgumentTypesValidator(
|
||||||
|
StandardArgumentsValidators.composite(
|
||||||
|
StandardArgumentsValidators.exactly( 2 ),
|
||||||
|
ArrayAndElementArgumentValidator.DEFAULT_INSTANCE
|
||||||
|
),
|
||||||
|
FunctionParameterType.ANY,
|
||||||
|
FunctionParameterType.ANY
|
||||||
|
),
|
||||||
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
|
typeConfiguration.standardBasicTypeForJavaType(
|
||||||
|
list
|
||||||
|
? new ParameterizedTypeImpl( List.class, new Type[]{ Integer.class }, null )
|
||||||
|
: int[].class
|
||||||
|
)
|
||||||
|
),
|
||||||
|
ArrayAndElementArgumentTypeResolver.DEFAULT_INSTANCE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getArgumentListSignature() {
|
||||||
|
return "(ARRAY array, OBJECT element)";
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,7 +54,7 @@ public class ArrayRemoveIndexUnnestFunction extends AbstractSqmSelfRenderingFunc
|
||||||
final Expression indexExpression = (Expression) sqlAstArguments.get( 1 );
|
final Expression indexExpression = (Expression) sqlAstArguments.get( 1 );
|
||||||
sqlAppender.append( "case when ");
|
sqlAppender.append( "case when ");
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append( " is null then null else coalesce((select array_agg(t.val) from unnest(" );
|
sqlAppender.append( " is not null then coalesce((select array_agg(t.val) from unnest(" );
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append( ") with ordinality t(val,idx) where t.idx is distinct from " );
|
sqlAppender.append( ") with ordinality t(val,idx) where t.idx is distinct from " );
|
||||||
indexExpression.accept( walker );
|
indexExpression.accept( walker );
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class ArrayReplaceUnnestFunction extends AbstractSqmSelfRenderingFunction
|
||||||
final Expression newExpression = (Expression) sqlAstArguments.get( 2 );
|
final Expression newExpression = (Expression) sqlAstArguments.get( 2 );
|
||||||
sqlAppender.append( "case when ");
|
sqlAppender.append( "case when ");
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append( " is null then null else coalesce((select array_agg(case when t.val is not distinct from " );
|
sqlAppender.append( " is not null then coalesce((select array_agg(case when t.val is not distinct from " );
|
||||||
oldExpression.accept( walker );
|
oldExpression.accept( walker );
|
||||||
sqlAppender.append( " then " );
|
sqlAppender.append( " then " );
|
||||||
newExpression.accept( walker );
|
newExpression.accept( walker );
|
||||||
|
|
|
@ -55,11 +55,11 @@ public class ArraySliceUnnestFunction extends AbstractSqmSelfRenderingFunctionDe
|
||||||
final Expression endIndexExpression = (Expression) sqlAstArguments.get( 2 );
|
final Expression endIndexExpression = (Expression) sqlAstArguments.get( 2 );
|
||||||
sqlAppender.append( "case when ");
|
sqlAppender.append( "case when ");
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append( " is null or ");
|
sqlAppender.append( " is not null and ");
|
||||||
startIndexExpression.accept( walker );
|
startIndexExpression.accept( walker );
|
||||||
sqlAppender.append( " is null or ");
|
sqlAppender.append( " is not null and ");
|
||||||
endIndexExpression.accept( walker );
|
endIndexExpression.accept( walker );
|
||||||
sqlAppender.append( " is null then null else coalesce((select array_agg(t.val) from unnest(" );
|
sqlAppender.append( " is not null then coalesce((select array_agg(t.val) from unnest(" );
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append( ") with ordinality t(val,idx) where t.idx between " );
|
sqlAppender.append( ") with ordinality t(val,idx) where t.idx between " );
|
||||||
startIndexExpression.accept( walker );
|
startIndexExpression.accept( walker );
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* 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.query.ReturnableType;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* H2 requires a very special emulation, because {@code unnest} is pretty much useless,
|
||||||
|
* 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 H2ArrayPositionFunction extends AbstractArrayPositionFunction {
|
||||||
|
|
||||||
|
private final int maximumArraySize;
|
||||||
|
|
||||||
|
public H2ArrayPositionFunction(int maximumArraySize, TypeConfiguration typeConfiguration) {
|
||||||
|
super( typeConfiguration );
|
||||||
|
this.maximumArraySize = maximumArraySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(
|
||||||
|
SqlAppender sqlAppender,
|
||||||
|
List<? extends SqlAstNode> sqlAstArguments,
|
||||||
|
ReturnableType<?> returnType,
|
||||||
|
SqlAstTranslator<?> walker) {
|
||||||
|
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||||
|
final Expression elementExpression = (Expression) sqlAstArguments.get( 1 );
|
||||||
|
sqlAppender.append( "case when ");
|
||||||
|
arrayExpression.accept( walker );
|
||||||
|
sqlAppender.append( " is not null then coalesce((select i.idx from system_range(1," );
|
||||||
|
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||||
|
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 not distinct from " );
|
||||||
|
elementExpression.accept( walker );
|
||||||
|
sqlAppender.append( " order by i.idx fetch first 1 row only),0) end" );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* 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.query.ReturnableType;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* H2 requires a very special emulation, because {@code unnest} is pretty much useless,
|
||||||
|
* 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 H2ArrayPositionsFunction extends AbstractArrayPositionsFunction {
|
||||||
|
|
||||||
|
private final int maximumArraySize;
|
||||||
|
|
||||||
|
public H2ArrayPositionsFunction(boolean list, int maximumArraySize, TypeConfiguration typeConfiguration) {
|
||||||
|
super( list, typeConfiguration );
|
||||||
|
this.maximumArraySize = maximumArraySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(
|
||||||
|
SqlAppender sqlAppender,
|
||||||
|
List<? extends SqlAstNode> sqlAstArguments,
|
||||||
|
ReturnableType<?> returnType,
|
||||||
|
SqlAstTranslator<?> walker) {
|
||||||
|
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||||
|
final Expression elementExpression = (Expression) sqlAstArguments.get( 1 );
|
||||||
|
sqlAppender.append( "case when ");
|
||||||
|
arrayExpression.accept( walker );
|
||||||
|
sqlAppender.append( " is not null then coalesce((select array_agg(i.idx) from system_range(1," );
|
||||||
|
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||||
|
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 not distinct from " );
|
||||||
|
elementExpression.accept( walker );
|
||||||
|
sqlAppender.append( "),array[]) end" );
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,7 @@ public class H2ArrayRemoveFunction extends AbstractArrayRemoveFunction {
|
||||||
final Expression elementExpression = (Expression) sqlAstArguments.get( 1 );
|
final Expression elementExpression = (Expression) sqlAstArguments.get( 1 );
|
||||||
sqlAppender.append( "case when ");
|
sqlAppender.append( "case when ");
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append( " is null then null else coalesce((select array_agg(array_get(");
|
sqlAppender.append( " is not null then coalesce((select array_agg(array_get(");
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append(",i.idx)) from system_range(1," );
|
sqlAppender.append(",i.idx)) from system_range(1," );
|
||||||
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class H2ArrayRemoveIndexFunction extends ArrayRemoveIndexUnnestFunction {
|
||||||
final Expression indexExpression = (Expression) sqlAstArguments.get( 1 );
|
final Expression indexExpression = (Expression) sqlAstArguments.get( 1 );
|
||||||
sqlAppender.append( "case when ");
|
sqlAppender.append( "case when ");
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append( " is null then null else coalesce((select array_agg(array_get(");
|
sqlAppender.append( " is not null then coalesce((select array_agg(array_get(");
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append(",i.idx)) from system_range(1," );
|
sqlAppender.append(",i.idx)) from system_range(1," );
|
||||||
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class H2ArrayReplaceFunction extends ArrayReplaceUnnestFunction {
|
||||||
final Expression newExpression = (Expression) sqlAstArguments.get( 2 );
|
final Expression newExpression = (Expression) sqlAstArguments.get( 2 );
|
||||||
sqlAppender.append( "case when ");
|
sqlAppender.append( "case when ");
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append( " is null then null else coalesce((select array_agg(case when array_get(");
|
sqlAppender.append( " is not null then coalesce((select array_agg(case when array_get(");
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append(",i.idx) is not distinct from ");
|
sqlAppender.append(",i.idx) is not distinct from ");
|
||||||
oldExpression.accept( walker );
|
oldExpression.accept( walker );
|
||||||
|
|
|
@ -42,6 +42,6 @@ public class HSQLArrayPositionFunction extends AbstractArrayPositionFunction {
|
||||||
sqlAppender.append( " and t.idx>=" );
|
sqlAppender.append( " and t.idx>=" );
|
||||||
sqlAstArguments.get( 2 ).accept( walker );
|
sqlAstArguments.get( 2 ).accept( walker );
|
||||||
}
|
}
|
||||||
sqlAppender.append( "),0) end" );
|
sqlAppender.append( " order by t.idx fetch first 1 row only),0) end" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect.function.array;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.query.ReturnableType;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HSQLDB has a special syntax.
|
||||||
|
*/
|
||||||
|
public class HSQLArrayPositionsFunction extends AbstractArrayPositionsFunction {
|
||||||
|
|
||||||
|
public HSQLArrayPositionsFunction(boolean list, TypeConfiguration typeConfiguration) {
|
||||||
|
super( list, typeConfiguration );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(
|
||||||
|
SqlAppender sqlAppender,
|
||||||
|
List<? extends SqlAstNode> sqlAstArguments,
|
||||||
|
ReturnableType<?> returnType,
|
||||||
|
SqlAstTranslator<?> walker) {
|
||||||
|
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||||
|
final Expression elementExpression = (Expression) sqlAstArguments.get( 1 );
|
||||||
|
sqlAppender.append( "case when " );
|
||||||
|
arrayExpression.accept( walker );
|
||||||
|
sqlAppender.append( " is not null then coalesce((select array_agg(t.idx) from unnest(");
|
||||||
|
arrayExpression.accept( walker );
|
||||||
|
sqlAppender.append(") with ordinality t(val,idx) where t.val is not distinct from " );
|
||||||
|
elementExpression.accept( walker );
|
||||||
|
sqlAppender.append( "),cast(array[] as integer array)) end" );
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,7 @@ public class HSQLArrayRemoveFunction extends AbstractArrayRemoveFunction {
|
||||||
final Expression elementExpression = (Expression) sqlAstArguments.get( 1 );
|
final Expression elementExpression = (Expression) sqlAstArguments.get( 1 );
|
||||||
sqlAppender.append( "case when ");
|
sqlAppender.append( "case when ");
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append( " is null then null else coalesce((select array_agg(t.val) from unnest(" );
|
sqlAppender.append( " is not null then coalesce((select array_agg(t.val) from unnest(" );
|
||||||
arrayExpression.accept( walker );
|
arrayExpression.accept( walker );
|
||||||
sqlAppender.append( ") with ordinality t(val,idx) where t.val is distinct from " );
|
sqlAppender.append( ") with ordinality t(val,idx) where t.val is distinct from " );
|
||||||
elementExpression.accept( walker );
|
elementExpression.accept( walker );
|
||||||
|
|
|
@ -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.query.ReturnableType;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
public class OracleArrayPositionsFunction extends AbstractArrayPositionsFunction {
|
||||||
|
|
||||||
|
public OracleArrayPositionsFunction(boolean list, TypeConfiguration typeConfiguration) {
|
||||||
|
super( list, typeConfiguration );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(
|
||||||
|
SqlAppender sqlAppender,
|
||||||
|
List<? extends SqlAstNode> sqlAstArguments,
|
||||||
|
ReturnableType<?> returnType,
|
||||||
|
SqlAstTranslator<?> walker) {
|
||||||
|
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||||
|
final String arrayTypeName = DdlTypeHelper.getTypeName( arrayExpression.getExpressionType(), walker );
|
||||||
|
sqlAppender.appendSql( arrayTypeName );
|
||||||
|
sqlAppender.append( "_positions(" );
|
||||||
|
arrayExpression.accept( walker );
|
||||||
|
sqlAppender.append( ',' );
|
||||||
|
sqlAstArguments.get( 1 ).accept( walker );
|
||||||
|
sqlAppender.append( ")" );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.dialect.function.array;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.query.ReturnableType;
|
||||||
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PostgreSQL variant of the function.
|
||||||
|
*/
|
||||||
|
public class PostgreSQLArrayPositionsFunction extends AbstractArrayPositionsFunction {
|
||||||
|
|
||||||
|
public PostgreSQLArrayPositionsFunction(boolean list, TypeConfiguration typeConfiguration) {
|
||||||
|
super( list, typeConfiguration );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(
|
||||||
|
SqlAppender sqlAppender,
|
||||||
|
List<? extends SqlAstNode> sqlAstArguments,
|
||||||
|
ReturnableType<?> returnType,
|
||||||
|
SqlAstTranslator<?> walker) {
|
||||||
|
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||||
|
final Expression elementExpression = (Expression) sqlAstArguments.get( 1 );
|
||||||
|
sqlAppender.append( "array_positions(" );
|
||||||
|
arrayExpression.accept( walker );
|
||||||
|
sqlAppender.append( ',' );
|
||||||
|
elementExpression.accept( walker );
|
||||||
|
sqlAppender.append( ')' );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* 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.type.internal;
|
||||||
|
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
public class ParameterizedTypeImpl implements ParameterizedType {
|
||||||
|
|
||||||
|
private final Type[] substTypeArgs;
|
||||||
|
private final Type rawType;
|
||||||
|
private final Type ownerType;
|
||||||
|
|
||||||
|
public ParameterizedTypeImpl(Type rawType, Type[] substTypeArgs, Type ownerType) {
|
||||||
|
this.substTypeArgs = substTypeArgs;
|
||||||
|
this.rawType = rawType;
|
||||||
|
this.ownerType = ownerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type[] getActualTypeArguments() {
|
||||||
|
return substTypeArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getRawType() {
|
||||||
|
return rawType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getOwnerType() {
|
||||||
|
return ownerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if ( !( obj instanceof ParameterizedType ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ParameterizedType other = (ParameterizedType) obj;
|
||||||
|
return Objects.equals( getOwnerType(), other.getOwnerType() )
|
||||||
|
&& Objects.equals( getRawType(), other.getRawType() )
|
||||||
|
&& Arrays.equals( getActualTypeArguments(), other.getActualTypeArguments() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Arrays.hashCode( getActualTypeArguments() )
|
||||||
|
^ Objects.hashCode( getOwnerType() )
|
||||||
|
^ Objects.hashCode( getRawType() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
if ( ownerType != null ) {
|
||||||
|
sb.append( ownerType.getTypeName() );
|
||||||
|
|
||||||
|
sb.append( "$" );
|
||||||
|
|
||||||
|
if ( ownerType instanceof ParameterizedType ) {
|
||||||
|
// Find simple name of nested type by removing the
|
||||||
|
// shared prefix with owner.
|
||||||
|
sb.append(
|
||||||
|
rawType.getTypeName().replace(
|
||||||
|
( (ParameterizedType) ownerType ).getRawType().getTypeName() + "$",
|
||||||
|
""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if ( rawType instanceof Class<?> ) {
|
||||||
|
sb.append( ( (Class<?>) rawType ).getSimpleName() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sb.append( rawType.getTypeName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sb.append( rawType.getTypeName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( substTypeArgs != null ) {
|
||||||
|
final StringJoiner sj = new StringJoiner( ", ", "<", ">" );
|
||||||
|
sj.setEmptyValue( "" );
|
||||||
|
for ( Type t : substTypeArgs ) {
|
||||||
|
sj.add( t.getTypeName() );
|
||||||
|
}
|
||||||
|
sb.append( sj );
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,7 +37,6 @@ import org.hibernate.Internal;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.SessionFactoryObserver;
|
import org.hibernate.SessionFactoryObserver;
|
||||||
import org.hibernate.TimeZoneStorageStrategy;
|
import org.hibernate.TimeZoneStorageStrategy;
|
||||||
import org.hibernate.annotations.common.reflection.java.generics.ParameterizedTypeImpl;
|
|
||||||
import org.hibernate.boot.cfgxml.spi.CfgXmlAccessService;
|
import org.hibernate.boot.cfgxml.spi.CfgXmlAccessService;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.spi.BasicTypeRegistration;
|
import org.hibernate.boot.spi.BasicTypeRegistration;
|
||||||
|
@ -74,6 +73,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
|
||||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||||
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
|
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
|
||||||
import org.hibernate.type.internal.BasicTypeImpl;
|
import org.hibernate.type.internal.BasicTypeImpl;
|
||||||
|
import org.hibernate.type.internal.ParameterizedTypeImpl;
|
||||||
|
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
|
@ -716,6 +716,20 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BasicType<?> standardBasicTypeForJavaType(Type javaType) {
|
||||||
|
if ( javaType == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return standardBasicTypeForJavaType(
|
||||||
|
javaType,
|
||||||
|
javaTypeDescriptor -> new BasicTypeImpl<>(
|
||||||
|
javaTypeDescriptor,
|
||||||
|
javaTypeDescriptor.getRecommendedJdbcType( getCurrentBaseSqlTypeIndicators() )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public <J> BasicType<J> standardBasicTypeForJavaType(
|
public <J> BasicType<J> standardBasicTypeForJavaType(
|
||||||
Class<J> javaType,
|
Class<J> javaType,
|
||||||
Function<JavaType<J>, BasicType<J>> creator) {
|
Function<JavaType<J>, BasicType<J>> creator) {
|
||||||
|
|
|
@ -9,7 +9,6 @@ package org.hibernate.orm.test.function.array;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.dialect.H2Dialect;
|
|
||||||
|
|
||||||
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
import org.hibernate.testing.orm.junit.DialectFeatureChecks;
|
||||||
import org.hibernate.testing.orm.junit.DomainModel;
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
@ -18,7 +17,6 @@ import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
import org.hibernate.testing.orm.junit.Setting;
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
import org.hibernate.testing.orm.junit.SkipForDialect;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
@ -35,7 +33,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
// otherwise we might run into ORA-21700: object does not exist or is marked for delete
|
// 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
|
// because the JDBC connection or database session caches something that should have been invalidated
|
||||||
@ServiceRegistry(settings = @Setting(name = AvailableSettings.CONNECTION_PROVIDER, value = ""))
|
@ServiceRegistry(settings = @Setting(name = AvailableSettings.CONNECTION_PROVIDER, value = ""))
|
||||||
@SkipForDialect(dialectClass = H2Dialect.class, reason = "H2 does not have an array_position function")
|
|
||||||
public class ArrayPositionTest {
|
public class ArrayPositionTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* 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 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 ArrayPositionsTest {
|
||||||
|
|
||||||
|
@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", "abc" } ) );
|
||||||
|
em.persist( new EntityWithArrays( 3L, null ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void cleanup(SessionFactoryScope scope) {
|
||||||
|
scope.inTransaction( em -> {
|
||||||
|
em.createMutationQuery( "delete from EntityWithArrays" ).executeUpdate();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPositions(SessionFactoryScope scope) {
|
||||||
|
scope.inSession( em -> {
|
||||||
|
//tag::hql-array-positions-example[]
|
||||||
|
List<int[]> results = em.createQuery( "select array_positions(e.theArray, 'abc') from EntityWithArrays e order by e.id", int[].class )
|
||||||
|
.getResultList();
|
||||||
|
//end::hql-array-positions-example[]
|
||||||
|
assertEquals( 3, results.size() );
|
||||||
|
assertArrayEquals( new int[0], results.get( 0 ) );
|
||||||
|
assertArrayEquals( new int[]{ 1, 4 }, results.get( 1 ) );
|
||||||
|
assertNull( results.get( 2 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPositionsNotFound(SessionFactoryScope scope) {
|
||||||
|
scope.inSession( em -> {
|
||||||
|
List<int[]> results = em.createQuery( "select array_positions(e.theArray, 'xyz') from EntityWithArrays e order by e.id", int[].class )
|
||||||
|
.getResultList();
|
||||||
|
assertEquals( 3, results.size() );
|
||||||
|
assertArrayEquals( new int[0], results.get( 0 ) );
|
||||||
|
assertArrayEquals( new int[0], results.get( 1 ) );
|
||||||
|
assertNull( results.get( 2 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPositionsNull(SessionFactoryScope scope) {
|
||||||
|
scope.inSession( em -> {
|
||||||
|
List<int[]> results = em.createQuery( "select array_positions(e.theArray, null) from EntityWithArrays e order by e.id", int[].class )
|
||||||
|
.getResultList();
|
||||||
|
assertEquals( 3, results.size() );
|
||||||
|
assertArrayEquals( new int[0], results.get( 0 ) );
|
||||||
|
assertArrayEquals( new int[]{ 2 }, results.get( 1 ) );
|
||||||
|
assertNull( results.get( 2 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPositionsList(SessionFactoryScope scope) {
|
||||||
|
scope.inSession( em -> {
|
||||||
|
List<List<Integer>> results = em.createQuery( "select array_positions_list(e.theArray, null) from EntityWithArrays e order by e.id" )
|
||||||
|
.getResultList();
|
||||||
|
assertEquals( 3, results.size() );
|
||||||
|
assertEquals( List.of(), results.get( 0 ) );
|
||||||
|
assertEquals( List.of( 2 ), results.get( 1 ) );
|
||||||
|
assertNull( results.get( 2 ) );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue