HHH-17355 Unify array_contains and array_contains_all as well as deprecate FunctionRenderingSupport in favor of new FunctionRenderer contract
This commit is contained in:
parent
5506714611
commit
bfb9fcc0f6
|
@ -1233,7 +1233,7 @@ The result of `array_contains` is undefined when the second argument is an array
|
|||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{array-example-dir-hql}/ArrayContainsAllTest.java[tags=hql-array-contains-all-example]
|
||||
include::{array-example-dir-hql}/ArrayContainsArrayTest.java[tags=hql-array-contains-array-example]
|
||||
----
|
||||
====
|
||||
|
||||
|
@ -1243,7 +1243,7 @@ To search for `null` elements, the `array_contains_nullable` function must be us
|
|||
====
|
||||
[source, JAVA, indent=0]
|
||||
----
|
||||
include::{array-example-dir-hql}/ArrayContainsAllTest.java[tags=hql-array-contains-all-nullable-example]
|
||||
include::{array-example-dir-hql}/ArrayContainsArrayTest.java[tags=hql-array-contains-array-nullable-example]
|
||||
----
|
||||
====
|
||||
|
||||
|
|
|
@ -461,19 +461,15 @@ public class CockroachLegacyDialect extends Dialect {
|
|||
functionFactory.listagg_stringAgg( "string" );
|
||||
functionFactory.inverseDistributionOrderedSetAggregates();
|
||||
functionFactory.hypotheticalOrderedSetAggregates_windowEmulation();
|
||||
functionFactory.array_casting();
|
||||
functionFactory.array_postgresql();
|
||||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_operator();
|
||||
functionFactory.arrayContainsNull_array_position();
|
||||
functionFactory.arrayPosition_postgresql();
|
||||
functionFactory.arrayLength_cardinality();
|
||||
functionFactory.arrayConcat_postgresql();
|
||||
functionFactory.arrayPrepend_postgresql();
|
||||
functionFactory.arrayAppend_postgresql();
|
||||
functionFactory.arrayContainsAll_operator();
|
||||
functionFactory.arrayOverlaps_operator();
|
||||
functionFactory.arrayContainsAllNullable_operator();
|
||||
functionFactory.arrayOverlapsNullable_unnest();
|
||||
functionFactory.arrayContains_postgresql();
|
||||
functionFactory.arrayOverlaps_postgresql();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove();
|
||||
|
|
|
@ -372,22 +372,18 @@ public class H2LegacyDialect extends Dialect {
|
|||
functionFactory.listagg( null );
|
||||
functionFactory.array();
|
||||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains();
|
||||
functionFactory.arrayContainsNull();
|
||||
functionFactory.arrayLength_cardinality();
|
||||
functionFactory.arrayConcat_operator();
|
||||
functionFactory.arrayPrepend_operator();
|
||||
functionFactory.arrayAppend_operator();
|
||||
functionFactory.arrayContainsAll_h2();
|
||||
functionFactory.arrayOverlaps_h2();
|
||||
functionFactory.arrayContainsAllNullable_h2();
|
||||
functionFactory.arrayOverlapsNullable_h2();
|
||||
functionFactory.arrayContains_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayOverlaps_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayGet_h2();
|
||||
functionFactory.arraySet_h2();
|
||||
functionFactory.arrayRemove_h2();
|
||||
functionFactory.arrayRemoveIndex_h2();
|
||||
functionFactory.arraySet_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayRemove_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayRemoveIndex_h2( getMaximumArraySize() );
|
||||
functionFactory.arraySlice();
|
||||
functionFactory.arrayReplace_h2();
|
||||
functionFactory.arrayReplace_h2( getMaximumArraySize() );
|
||||
}
|
||||
else {
|
||||
// Use group_concat until 2.x as listagg was buggy
|
||||
|
@ -399,6 +395,16 @@ public class H2LegacyDialect extends Dialect {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
* but requires that {@code system_range} is fed with a "maximum array size".
|
||||
*/
|
||||
protected int getMaximumArraySize() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void augmentPhysicalTableTypes(List<String> tableTypesList) {
|
||||
if ( getVersion().isSameOrAfter( 2 ) ) {
|
||||
|
|
|
@ -247,19 +247,15 @@ public class HSQLLegacyDialect extends Dialect {
|
|||
functionFactory.rownum();
|
||||
}
|
||||
functionFactory.listagg_groupConcat();
|
||||
functionFactory.array();
|
||||
functionFactory.array_hsql();
|
||||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_hsql();
|
||||
functionFactory.arrayContainsNull_hsql();
|
||||
functionFactory.arrayPosition_hsql();
|
||||
functionFactory.arrayLength_cardinality();
|
||||
functionFactory.arrayConcat_operator();
|
||||
functionFactory.arrayPrepend_operator();
|
||||
functionFactory.arrayAppend_operator();
|
||||
functionFactory.arrayContainsAll_hsql();
|
||||
functionFactory.arrayContains_hsql();
|
||||
functionFactory.arrayOverlaps_hsql();
|
||||
functionFactory.arrayContainsAllNullable_hsql();
|
||||
functionFactory.arrayOverlapsNullable_unnest();
|
||||
functionFactory.arrayGet_unnest();
|
||||
functionFactory.arraySet_hsql();
|
||||
functionFactory.arrayRemove_hsql();
|
||||
|
|
|
@ -285,17 +285,13 @@ public class OracleLegacyDialect extends Dialect {
|
|||
|
||||
functionFactory.array_oracle();
|
||||
functionFactory.arrayAggregate_jsonArrayagg();
|
||||
functionFactory.arrayContains_oracle();
|
||||
functionFactory.arrayContainsNull_oracle();
|
||||
functionFactory.arrayPosition_oracle();
|
||||
functionFactory.arrayLength_oracle();
|
||||
functionFactory.arrayConcat_oracle();
|
||||
functionFactory.arrayPrepend_oracle();
|
||||
functionFactory.arrayAppend_oracle();
|
||||
functionFactory.arrayContainsAll_oracle();
|
||||
functionFactory.arrayContains_oracle();
|
||||
functionFactory.arrayOverlaps_oracle();
|
||||
functionFactory.arrayContainsAllNullable_oracle();
|
||||
functionFactory.arrayOverlapsNullable_oracle();
|
||||
functionFactory.arrayGet_oracle();
|
||||
functionFactory.arraySet_oracle();
|
||||
functionFactory.arrayRemove_oracle();
|
||||
|
|
|
@ -581,19 +581,15 @@ public class PostgreSQLLegacyDialect extends Dialect {
|
|||
functionFactory.locate_positionSubstring();
|
||||
functionFactory.windowFunctions();
|
||||
functionFactory.listagg_stringAgg( "varchar" );
|
||||
functionFactory.array_casting();
|
||||
functionFactory.array_postgresql();
|
||||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_operator();
|
||||
functionFactory.arrayContainsNull_array_position();
|
||||
functionFactory.arrayPosition_postgresql();
|
||||
functionFactory.arrayLength_cardinality();
|
||||
functionFactory.arrayConcat_postgresql();
|
||||
functionFactory.arrayPrepend_postgresql();
|
||||
functionFactory.arrayAppend_postgresql();
|
||||
functionFactory.arrayContainsAll_operator();
|
||||
functionFactory.arrayOverlaps_operator();
|
||||
functionFactory.arrayContainsAllNullable_operator();
|
||||
functionFactory.arrayOverlapsNullable_unnest();
|
||||
functionFactory.arrayContains_postgresql();
|
||||
functionFactory.arrayOverlaps_postgresql();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove();
|
||||
|
|
|
@ -448,19 +448,15 @@ public class CockroachDialect extends Dialect {
|
|||
functionFactory.listagg_stringAgg( "string" );
|
||||
functionFactory.inverseDistributionOrderedSetAggregates();
|
||||
functionFactory.hypotheticalOrderedSetAggregates_windowEmulation();
|
||||
functionFactory.array_casting();
|
||||
functionFactory.array_postgresql();
|
||||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_operator();
|
||||
functionFactory.arrayContainsNull_array_position();
|
||||
functionFactory.arrayPosition_postgresql();
|
||||
functionFactory.arrayLength_cardinality();
|
||||
functionFactory.arrayConcat_postgresql();
|
||||
functionFactory.arrayPrepend_postgresql();
|
||||
functionFactory.arrayAppend_postgresql();
|
||||
functionFactory.arrayContainsAll_operator();
|
||||
functionFactory.arrayOverlaps_operator();
|
||||
functionFactory.arrayContainsAllNullable_operator();
|
||||
functionFactory.arrayOverlapsNullable_unnest();
|
||||
functionFactory.arrayContains_postgresql();
|
||||
functionFactory.arrayOverlaps_postgresql();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove();
|
||||
|
|
|
@ -311,22 +311,28 @@ public class H2Dialect extends Dialect {
|
|||
functionFactory.hypotheticalOrderedSetAggregates();
|
||||
functionFactory.array();
|
||||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains();
|
||||
functionFactory.arrayContainsNull();
|
||||
functionFactory.arrayLength_cardinality();
|
||||
functionFactory.arrayConcat_operator();
|
||||
functionFactory.arrayPrepend_operator();
|
||||
functionFactory.arrayAppend_operator();
|
||||
functionFactory.arrayContainsAll_h2();
|
||||
functionFactory.arrayOverlaps_h2();
|
||||
functionFactory.arrayContainsAllNullable_h2();
|
||||
functionFactory.arrayOverlapsNullable_h2();
|
||||
functionFactory.arrayContains_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayOverlaps_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayGet_h2();
|
||||
functionFactory.arraySet_h2();
|
||||
functionFactory.arrayRemove_h2();
|
||||
functionFactory.arrayRemoveIndex_h2();
|
||||
functionFactory.arraySet_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayRemove_h2( getMaximumArraySize() );
|
||||
functionFactory.arrayRemoveIndex_h2( getMaximumArraySize() );
|
||||
functionFactory.arraySlice();
|
||||
functionFactory.arrayReplace_h2();
|
||||
functionFactory.arrayReplace_h2( getMaximumArraySize() );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
* but requires that {@code system_range} is fed with a "maximum array size".
|
||||
*/
|
||||
protected int getMaximumArraySize() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -187,19 +187,15 @@ public class HSQLDialect extends Dialect {
|
|||
// from v. 2.2.0 ROWNUM() is supported in all modes as the equivalent of Oracle ROWNUM
|
||||
functionFactory.rownum();
|
||||
functionFactory.listagg_groupConcat();
|
||||
functionFactory.array();
|
||||
functionFactory.array_hsql();
|
||||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_hsql();
|
||||
functionFactory.arrayContainsNull_hsql();
|
||||
functionFactory.arrayPosition_hsql();
|
||||
functionFactory.arrayLength_cardinality();
|
||||
functionFactory.arrayConcat_operator();
|
||||
functionFactory.arrayPrepend_operator();
|
||||
functionFactory.arrayAppend_operator();
|
||||
functionFactory.arrayContainsAll_hsql();
|
||||
functionFactory.arrayContains_hsql();
|
||||
functionFactory.arrayOverlaps_hsql();
|
||||
functionFactory.arrayContainsAllNullable_hsql();
|
||||
functionFactory.arrayOverlapsNullable_unnest();
|
||||
functionFactory.arrayGet_unnest();
|
||||
functionFactory.arraySet_hsql();
|
||||
functionFactory.arrayRemove_hsql();
|
||||
|
|
|
@ -284,10 +284,10 @@ public class OracleArrayJdbcType extends ArrayJdbcType {
|
|||
);
|
||||
database.addAuxiliaryDatabaseObject(
|
||||
new NamedAuxiliaryDatabaseObject(
|
||||
arrayTypeName + "_contains_all",
|
||||
arrayTypeName + "_contains",
|
||||
database.getDefaultNamespace(),
|
||||
new String[]{
|
||||
"create or replace function " + arrayTypeName + "_contains_all(haystack in " + arrayTypeName +
|
||||
"create or replace function " + arrayTypeName + "_contains(haystack in " + arrayTypeName +
|
||||
", needle in " + arrayTypeName + ", nullable in number) return number deterministic is found number(1,0); begin " +
|
||||
"if haystack is null or needle is null then return null; end if; " +
|
||||
"for i in 1 .. needle.count loop " +
|
||||
|
@ -300,7 +300,7 @@ public class OracleArrayJdbcType extends ArrayJdbcType {
|
|||
"return 1; " +
|
||||
"end;"
|
||||
},
|
||||
new String[] { "drop function " + arrayTypeName + "_contains_all" },
|
||||
new String[] { "drop function " + arrayTypeName + "_contains" },
|
||||
emptySet(),
|
||||
false
|
||||
)
|
||||
|
|
|
@ -314,17 +314,13 @@ public class OracleDialect extends Dialect {
|
|||
|
||||
functionFactory.array_oracle();
|
||||
functionFactory.arrayAggregate_jsonArrayagg();
|
||||
functionFactory.arrayContains_oracle();
|
||||
functionFactory.arrayContainsNull_oracle();
|
||||
functionFactory.arrayPosition_oracle();
|
||||
functionFactory.arrayLength_oracle();
|
||||
functionFactory.arrayConcat_oracle();
|
||||
functionFactory.arrayPrepend_oracle();
|
||||
functionFactory.arrayAppend_oracle();
|
||||
functionFactory.arrayContainsAll_oracle();
|
||||
functionFactory.arrayContains_oracle();
|
||||
functionFactory.arrayOverlaps_oracle();
|
||||
functionFactory.arrayContainsAllNullable_oracle();
|
||||
functionFactory.arrayOverlapsNullable_oracle();
|
||||
functionFactory.arrayGet_oracle();
|
||||
functionFactory.arraySet_oracle();
|
||||
functionFactory.arrayRemove_oracle();
|
||||
|
|
|
@ -629,19 +629,15 @@ public class PostgreSQLDialect extends Dialect {
|
|||
functionFactory.locate_positionSubstring();
|
||||
functionFactory.windowFunctions();
|
||||
functionFactory.listagg_stringAgg( "varchar" );
|
||||
functionFactory.array_casting();
|
||||
functionFactory.array_postgresql();
|
||||
functionFactory.arrayAggregate();
|
||||
functionFactory.arrayContains_operator();
|
||||
functionFactory.arrayContainsNull_array_position();
|
||||
functionFactory.arrayPosition_postgresql();
|
||||
functionFactory.arrayLength_cardinality();
|
||||
functionFactory.arrayConcat_postgresql();
|
||||
functionFactory.arrayPrepend_postgresql();
|
||||
functionFactory.arrayAppend_postgresql();
|
||||
functionFactory.arrayContainsAll_operator();
|
||||
functionFactory.arrayOverlaps_operator();
|
||||
functionFactory.arrayContainsAllNullable_operator();
|
||||
functionFactory.arrayOverlapsNullable_unnest();
|
||||
functionFactory.arrayContains_postgresql();
|
||||
functionFactory.arrayOverlaps_postgresql();
|
||||
functionFactory.arrayGet_bracket();
|
||||
functionFactory.arraySet_unnest();
|
||||
functionFactory.arrayRemove();
|
||||
|
|
|
@ -479,7 +479,7 @@ public class SpannerDialect extends Dialect {
|
|||
functionFactory.listagg_stringAgg( "string" );
|
||||
functionFactory.inverseDistributionOrderedSetAggregates();
|
||||
functionFactory.hypotheticalOrderedSetAggregates();
|
||||
functionFactory.array_withoutKeyword();
|
||||
functionFactory.array_spanner();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -129,7 +129,7 @@ public class AggregateWindowEmulationQueryTransformer implements QueryTransforme
|
|||
if ( expression == windowFunction ) {
|
||||
finalExpression = new SelfRenderingAggregateFunctionSqlAstExpression(
|
||||
"min",
|
||||
(sqlAppender, sqlAstArguments, walker1) -> {
|
||||
(sqlAppender, sqlAstArguments, returnType, walker1) -> {
|
||||
sqlAppender.appendSql( "min(" );
|
||||
sqlAstArguments.get( 0 ).accept( walker1 );
|
||||
sqlAppender.append( ')' );
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
|||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
|
@ -62,8 +63,12 @@ public class AvgFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, walker );
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -71,6 +76,7 @@ public class AvgFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
final boolean caseWrapper = filter != null && !translator.supportsFilterClause();
|
||||
sqlAppender.appendSql( "avg(" );
|
||||
|
@ -108,7 +114,12 @@ public class AvgFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
final JdbcMapping sourceMapping = realArg.getExpressionType().getSingleJdbcMapping();
|
||||
// Only cast to float/double if this is an integer
|
||||
if ( sourceMapping.getJdbcType().isInteger() ) {
|
||||
castFunction.render( sqlAppender, Arrays.asList( realArg, new CastTarget(doubleType) ), translator );
|
||||
castFunction.render(
|
||||
sqlAppender,
|
||||
Arrays.asList( realArg, new CastTarget( doubleType ) ),
|
||||
doubleType,
|
||||
translator
|
||||
);
|
||||
}
|
||||
else {
|
||||
translator.render( realArg, defaultArgumentRenderingMode );
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -44,6 +45,7 @@ public class CaseLeastGreatestEmulation
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final int numberOfArguments = arguments.size();
|
||||
if ( numberOfArguments > 1 ) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
|||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.CastType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -57,7 +58,11 @@ public class CastFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> arguments, SqlAstTranslator<?> walker) {
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression source = (Expression) arguments.get( 0 );
|
||||
final JdbcMapping sourceMapping = source.getExpressionType().getSingleJdbcMapping();
|
||||
final CastType sourceType = getCastType( sourceMapping );
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.List;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.Size;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.CastType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -64,7 +65,11 @@ public class CastingConcatFunction extends AbstractSqmSelfRenderingFunctionDescr
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
// Apache Derby and DB2 add up the sizes of operands for concat operations and has a limit of 4000/32k until
|
||||
// it changes the data type to long varchar, at which point problems start arising, because a long varchar
|
||||
// can't be compared with a regular varchar for some reason.
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||
|
@ -68,6 +69,7 @@ public class ChrLiteralEmulation extends AbstractSqmSelfRenderingFunctionDescrip
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final QueryLiteral<Number> literal = (QueryLiteral<Number>) arguments.get( 0 );
|
||||
|
|
|
@ -19,9 +19,10 @@ import org.hibernate.dialect.function.array.ArrayArgumentValidator;
|
|||
import org.hibernate.dialect.function.array.ArrayConcatElementFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayConcatFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayConstructorFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayContainsQuantifiedOperatorFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayContainsOperatorFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayContainsQuantifiedUnnestFunction;
|
||||
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.ArrayGetUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayRemoveIndexUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayReplaceUnnestFunction;
|
||||
|
@ -29,17 +30,18 @@ import org.hibernate.dialect.function.array.ArraySetUnnestFunction;
|
|||
import org.hibernate.dialect.function.array.ArraySliceUnnestFunction;
|
||||
import org.hibernate.dialect.function.array.ArrayViaArgumentReturnTypeResolver;
|
||||
import org.hibernate.dialect.function.array.ElementViaArrayArgumentReturnTypeResolver;
|
||||
import org.hibernate.dialect.function.array.H2ArrayContainsQuantifiedEmulation;
|
||||
import org.hibernate.dialect.function.array.H2ArrayContainsFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayOverlapsFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayRemoveFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayRemoveIndexFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArrayReplaceFunction;
|
||||
import org.hibernate.dialect.function.array.H2ArraySetFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayConstructorFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayPositionFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArrayRemoveFunction;
|
||||
import org.hibernate.dialect.function.array.HSQLArraySetFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayConcatElementFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayConcatFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayContainsAllFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayOverlapsFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayGetFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayLengthFunction;
|
||||
|
@ -52,11 +54,10 @@ import org.hibernate.dialect.function.array.OracleArraySliceFunction;
|
|||
import org.hibernate.dialect.function.array.PostgreSQLArrayConcatElementFunction;
|
||||
import org.hibernate.dialect.function.array.PostgreSQLArrayConcatFunction;
|
||||
import org.hibernate.dialect.function.array.PostgreSQLArrayPositionFunction;
|
||||
import org.hibernate.dialect.function.array.CastingArrayConstructorFunction;
|
||||
import org.hibernate.dialect.function.array.PostgreSQLArrayConstructorFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayAggEmulation;
|
||||
import org.hibernate.dialect.function.array.OracleArrayConstructorFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayContainsFunction;
|
||||
import org.hibernate.dialect.function.array.OracleArrayContainsNullFunction;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -2589,17 +2590,24 @@ public class CommonFunctionFactory {
|
|||
functionRegistry.register( "array", new ArrayConstructorFunction( true ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* H2, HSQL array() constructor function
|
||||
*/
|
||||
public void array_hsql() {
|
||||
functionRegistry.register( "array", new HSQLArrayConstructorFunction() );
|
||||
}
|
||||
|
||||
/**
|
||||
* CockroachDB and PostgreSQL array() constructor function
|
||||
*/
|
||||
public void array_casting() {
|
||||
functionRegistry.register( "array", new CastingArrayConstructorFunction() );
|
||||
public void array_postgresql() {
|
||||
functionRegistry.register( "array", new PostgreSQLArrayConstructorFunction() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Google Spanner array() constructor function
|
||||
*/
|
||||
public void array_withoutKeyword() {
|
||||
public void array_spanner() {
|
||||
functionRegistry.register( "array", new ArrayConstructorFunction( false ) );
|
||||
}
|
||||
|
||||
|
@ -2627,153 +2635,58 @@ public class CommonFunctionFactory {
|
|||
/**
|
||||
* H2 array_contains() function
|
||||
*/
|
||||
public void arrayContains() {
|
||||
functionRegistry.namedDescriptorBuilder( "array_contains" )
|
||||
.setReturnTypeResolver( StandardFunctionReturnTypeResolvers.invariant( booleanType ) )
|
||||
.setArgumentsValidator(
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 2 ),
|
||||
ArrayAndElementArgumentValidator.DEFAULT_INSTANCE
|
||||
)
|
||||
)
|
||||
.setArgumentTypeResolver( ArrayAndElementArgumentTypeResolver.DEFAULT_INSTANCE )
|
||||
.setArgumentListSignature( "(ARRAY array, OBJECT element)" )
|
||||
.register();
|
||||
public void arrayContains_h2(int maximumArraySize) {
|
||||
functionRegistry.register(
|
||||
"array_contains",
|
||||
new H2ArrayContainsFunction( false, maximumArraySize, typeConfiguration )
|
||||
);
|
||||
functionRegistry.register(
|
||||
"array_contains_nullable",
|
||||
new H2ArrayContainsFunction( true, maximumArraySize, typeConfiguration )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* HSQL array_contains() function
|
||||
*/
|
||||
public void arrayContains_hsql() {
|
||||
functionRegistry.patternDescriptorBuilder( "array_contains", "position_array(?2 in ?1)>0" )
|
||||
.setReturnTypeResolver( StandardFunctionReturnTypeResolvers.invariant( booleanType ) )
|
||||
.setArgumentsValidator(
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 2 ),
|
||||
ArrayAndElementArgumentValidator.DEFAULT_INSTANCE
|
||||
)
|
||||
)
|
||||
.setArgumentTypeResolver( ArrayAndElementArgumentTypeResolver.DEFAULT_INSTANCE )
|
||||
.setArgumentListSignature( "(ARRAY array, OBJECT element)" )
|
||||
.register();
|
||||
functionRegistry.register(
|
||||
"array_contains",
|
||||
new ArrayContainsUnnestFunction( false, typeConfiguration )
|
||||
);
|
||||
functionRegistry.register(
|
||||
"array_contains_nullable",
|
||||
new ArrayContainsUnnestFunction( true, typeConfiguration )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* CockroachDB and PostgreSQL array contains operator
|
||||
*/
|
||||
public void arrayContains_operator() {
|
||||
functionRegistry.register( "array_contains", new ArrayContainsOperatorFunction( typeConfiguration ) );
|
||||
public void arrayContains_postgresql() {
|
||||
functionRegistry.register( "array_contains", new ArrayContainsOperatorFunction( false, typeConfiguration ) );
|
||||
functionRegistry.register( "array_contains_nullable", new ArrayContainsOperatorFunction( true, typeConfiguration ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle array_contains() function
|
||||
*/
|
||||
public void arrayContains_oracle() {
|
||||
functionRegistry.register( "array_contains", new OracleArrayContainsFunction( typeConfiguration ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* H2, HSQL array_contains_null() function
|
||||
*/
|
||||
public void arrayContainsNull() {
|
||||
functionRegistry.patternDescriptorBuilder( "array_contains_null", "array_contains(?1,null)" )
|
||||
.setReturnTypeResolver( StandardFunctionReturnTypeResolvers.invariant( booleanType ) )
|
||||
.setArgumentsValidator(
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 1 ),
|
||||
ArrayArgumentValidator.DEFAULT_INSTANCE
|
||||
)
|
||||
)
|
||||
.setArgumentListSignature( "(ARRAY array)" )
|
||||
.register();
|
||||
}
|
||||
|
||||
/**
|
||||
* CockroachDB and PostgreSQL array contains null emulation
|
||||
*/
|
||||
public void arrayContainsNull_array_position() {
|
||||
functionRegistry.patternDescriptorBuilder( "array_contains_null", "array_position(?1,null) is not null" )
|
||||
.setReturnTypeResolver( StandardFunctionReturnTypeResolvers.invariant( booleanType ) )
|
||||
.setArgumentsValidator(
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 1 ),
|
||||
ArrayArgumentValidator.DEFAULT_INSTANCE
|
||||
)
|
||||
)
|
||||
.setArgumentListSignature( "(ARRAY array)" )
|
||||
.register();
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle array_contains() function
|
||||
*/
|
||||
public void arrayContainsNull_oracle() {
|
||||
functionRegistry.register( "array_contains_null", new OracleArrayContainsNullFunction( typeConfiguration ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* CockroachDB and PostgreSQL array contains null emulation
|
||||
*/
|
||||
public void arrayContainsNull_hsql() {
|
||||
functionRegistry.patternDescriptorBuilder( "array_contains_null", "exists(select 1 from unnest(?1) t(i) where t.i is null)" )
|
||||
.setReturnTypeResolver( StandardFunctionReturnTypeResolvers.invariant( booleanType ) )
|
||||
.setArgumentsValidator(
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 1 ),
|
||||
ArrayArgumentValidator.DEFAULT_INSTANCE
|
||||
)
|
||||
)
|
||||
.setArgumentListSignature( "(ARRAY array)" )
|
||||
.register();
|
||||
}
|
||||
|
||||
/**
|
||||
* H2 array_contains_all() function
|
||||
*/
|
||||
public void arrayContainsAll_h2() {
|
||||
functionRegistry.register(
|
||||
"array_contains_all",
|
||||
new H2ArrayContainsQuantifiedEmulation( typeConfiguration, true, false )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* HSQL array_contains_all() function
|
||||
*/
|
||||
public void arrayContainsAll_hsql() {
|
||||
functionRegistry.register(
|
||||
"array_contains_all",
|
||||
new ArrayContainsQuantifiedUnnestFunction( typeConfiguration, true, false )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* CockroachDB and PostgreSQL array contains all operator
|
||||
*/
|
||||
public void arrayContainsAll_operator() {
|
||||
functionRegistry.register(
|
||||
"array_contains_all",
|
||||
new ArrayContainsQuantifiedOperatorFunction( typeConfiguration, true, false )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle array_contains_all() function
|
||||
*/
|
||||
public void arrayContainsAll_oracle() {
|
||||
functionRegistry.register(
|
||||
"array_contains_all",
|
||||
new OracleArrayContainsAllFunction( typeConfiguration, false )
|
||||
);
|
||||
functionRegistry.register( "array_contains", new OracleArrayContainsFunction( false, typeConfiguration ) );
|
||||
functionRegistry.register( "array_contains_nullable", new OracleArrayContainsFunction( true, typeConfiguration ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* H2 array_overlaps() function
|
||||
*/
|
||||
public void arrayOverlaps_h2() {
|
||||
public void arrayOverlaps_h2(int maximumArraySize) {
|
||||
functionRegistry.register(
|
||||
"array_overlaps",
|
||||
new H2ArrayContainsQuantifiedEmulation( typeConfiguration, false, false )
|
||||
new H2ArrayOverlapsFunction( false, maximumArraySize, typeConfiguration )
|
||||
);
|
||||
functionRegistry.register(
|
||||
"array_overlaps_nullable",
|
||||
new H2ArrayOverlapsFunction( true, maximumArraySize, typeConfiguration )
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2783,15 +2696,20 @@ public class CommonFunctionFactory {
|
|||
public void arrayOverlaps_hsql() {
|
||||
functionRegistry.register(
|
||||
"array_overlaps",
|
||||
new ArrayContainsQuantifiedUnnestFunction( typeConfiguration, false, false )
|
||||
new ArrayOverlapsUnnestFunction( false, typeConfiguration )
|
||||
);
|
||||
functionRegistry.register(
|
||||
"array_overlaps_nullable",
|
||||
new ArrayOverlapsUnnestFunction( true, typeConfiguration )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* CockroachDB and PostgreSQL array overlaps operator
|
||||
*/
|
||||
public void arrayOverlaps_operator() {
|
||||
functionRegistry.register( "array_overlaps", new ArrayContainsQuantifiedOperatorFunction( typeConfiguration, false, false ) );
|
||||
public void arrayOverlaps_postgresql() {
|
||||
functionRegistry.register( "array_overlaps", new ArrayOverlapsOperatorFunction( false, typeConfiguration ) );
|
||||
functionRegistry.register( "array_overlaps_nullable", new ArrayOverlapsOperatorFunction( true, typeConfiguration ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2802,72 +2720,6 @@ public class CommonFunctionFactory {
|
|||
"array_overlaps",
|
||||
new OracleArrayOverlapsFunction( typeConfiguration, false )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* H2 array_contains_all_nullable() function
|
||||
*/
|
||||
public void arrayContainsAllNullable_h2() {
|
||||
functionRegistry.register(
|
||||
"array_contains_all_nullable",
|
||||
new H2ArrayContainsQuantifiedEmulation( typeConfiguration, true, true )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* HSQL array_contains_all_nullable() function
|
||||
*/
|
||||
public void arrayContainsAllNullable_hsql() {
|
||||
functionRegistry.register(
|
||||
"array_contains_all_nullable",
|
||||
new ArrayContainsQuantifiedUnnestFunction( typeConfiguration, true, true )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* CockroachDB and PostgreSQL array contains all nullable operator
|
||||
*/
|
||||
public void arrayContainsAllNullable_operator() {
|
||||
functionRegistry.register(
|
||||
"array_contains_all_nullable",
|
||||
new ArrayContainsQuantifiedOperatorFunction( typeConfiguration, true, true )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle array_contains_all_nullable() function
|
||||
*/
|
||||
public void arrayContainsAllNullable_oracle() {
|
||||
functionRegistry.register(
|
||||
"array_contains_all_nullable",
|
||||
new OracleArrayContainsAllFunction( typeConfiguration, true )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* H2 array_overlaps_nullable() function
|
||||
*/
|
||||
public void arrayOverlapsNullable_h2() {
|
||||
functionRegistry.register(
|
||||
"array_overlaps_nullable",
|
||||
new H2ArrayContainsQuantifiedEmulation( typeConfiguration, false, true )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* HSQL, CockroachDB and PostgreSQL array_overlaps_nullable() function
|
||||
*/
|
||||
public void arrayOverlapsNullable_unnest() {
|
||||
functionRegistry.register(
|
||||
"array_overlaps_nullable",
|
||||
new ArrayContainsQuantifiedUnnestFunction( typeConfiguration, false, true )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Oracle array_overlaps_nullable() function
|
||||
*/
|
||||
public void arrayOverlapsNullable_oracle() {
|
||||
functionRegistry.register(
|
||||
"array_overlaps_nullable",
|
||||
new OracleArrayOverlapsFunction( typeConfiguration, true )
|
||||
|
@ -3031,8 +2883,8 @@ public class CommonFunctionFactory {
|
|||
/**
|
||||
* H2 array_set() function
|
||||
*/
|
||||
public void arraySet_h2() {
|
||||
functionRegistry.register( "array_set", new H2ArraySetFunction() );
|
||||
public void arraySet_h2(int maximumArraySize) {
|
||||
functionRegistry.register( "array_set", new H2ArraySetFunction( maximumArraySize ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3075,8 +2927,8 @@ public class CommonFunctionFactory {
|
|||
/**
|
||||
* H2 array_remove() function
|
||||
*/
|
||||
public void arrayRemove_h2() {
|
||||
functionRegistry.register( "array_remove", new H2ArrayRemoveFunction() );
|
||||
public void arrayRemove_h2(int maximumArraySize) {
|
||||
functionRegistry.register( "array_remove", new H2ArrayRemoveFunction( maximumArraySize ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3096,8 +2948,8 @@ public class CommonFunctionFactory {
|
|||
/**
|
||||
* H2 array_remove_index() function
|
||||
*/
|
||||
public void arrayRemoveIndex_h2() {
|
||||
functionRegistry.register( "array_remove_index", new H2ArrayRemoveIndexFunction() );
|
||||
public void arrayRemoveIndex_h2(int maximumArraySize) {
|
||||
functionRegistry.register( "array_remove_index", new H2ArrayRemoveIndexFunction( maximumArraySize ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3175,8 +3027,8 @@ public class CommonFunctionFactory {
|
|||
/**
|
||||
* H2 array_replace() function
|
||||
*/
|
||||
public void arrayReplace_h2() {
|
||||
functionRegistry.register( "array_replace", new H2ArrayReplaceFunction() );
|
||||
public void arrayReplace_h2(int maximumArraySize) {
|
||||
functionRegistry.register( "array_replace", new H2ArrayReplaceFunction( maximumArraySize ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.dialect.function;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||
|
@ -48,6 +49,7 @@ public class ConcatPipeFunction extends AbstractSqmSelfRenderingFunctionDescript
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
String separator = "(";
|
||||
for ( int i = 0; i < sqlAstArguments.size(); i++ ) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.hibernate.dialect.Dialect;
|
|||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.CastType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
|
@ -133,8 +134,12 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, walker );
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -142,6 +147,7 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
final boolean caseWrapper = filter != null && !translator.supportsFilterClause();
|
||||
final SqlAstNode arg = sqlAstArguments.get( 0 );
|
||||
|
@ -207,15 +213,15 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
sqlAppender.appendSql( "''" );
|
||||
}
|
||||
sqlAppender.appendSql( SqlAppender.COMMA_SEPARATOR_CHAR );
|
||||
chr.render( sqlAppender, chrArguments, translator );
|
||||
chr.render( sqlAppender, chrArguments, returnType, translator );
|
||||
sqlAppender.appendSql( "),'')," );
|
||||
chr.render( sqlAppender, chrArguments, translator );
|
||||
chr.render( sqlAppender, chrArguments, returnType, translator );
|
||||
sqlAppender.appendSql( concatOperator );
|
||||
sqlAppender.appendSql( "'" );
|
||||
sqlAppender.appendSql( argumentNumber );
|
||||
sqlAppender.appendSql( "')" );
|
||||
sqlAppender.appendSql( concatOperator );
|
||||
chr.render( sqlAppender, chrArguments, translator );
|
||||
chr.render( sqlAppender, chrArguments, returnType, translator );
|
||||
sqlAppender.appendSql( concatOperator );
|
||||
sqlAppender.appendSql( "coalesce(nullif(coalesce(" );
|
||||
needsConcat = renderCastedArgument( sqlAppender, translator, expressions.get( i ) );
|
||||
|
@ -226,9 +232,9 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
sqlAppender.appendSql( "''" );
|
||||
}
|
||||
sqlAppender.appendSql( SqlAppender.COMMA_SEPARATOR_CHAR );
|
||||
chr.render( sqlAppender, chrArguments, translator );
|
||||
chr.render( sqlAppender, chrArguments, returnType, translator );
|
||||
sqlAppender.appendSql( "),'')," );
|
||||
chr.render( sqlAppender, chrArguments, translator );
|
||||
chr.render( sqlAppender, chrArguments, returnType, translator );
|
||||
sqlAppender.appendSql( concatOperator );
|
||||
sqlAppender.appendSql( "'" );
|
||||
sqlAppender.appendSql( argumentNumber );
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
package org.hibernate.dialect.function;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
|
@ -41,6 +42,7 @@ public class CurrentFunction
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
sqlAppender.appendSql( sql );
|
||||
}
|
||||
|
|
|
@ -8,20 +8,11 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.dialect.OracleDialect;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
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.sql.ast.tree.expression.Format;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
@ -49,6 +40,7 @@ public class DB2FormatEmulation extends FormatFunction {
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression datetime = (Expression) arguments.get( 0 );
|
||||
sqlAppender.appendSql( "varchar_format(" );
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -41,6 +42,7 @@ public class DB2PositionFunction extends AbstractSqmSelfRenderingFunctionDescrip
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final int argumentCount = arguments.size();
|
||||
sqlAppender.appendSql( "position(" );
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
||||
|
@ -43,6 +44,7 @@ public class DB2SubstringFunction extends AbstractSqmSelfRenderingFunctionDescri
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final int argumentCount = arguments.size();
|
||||
sqlAppender.appendSql( "substring(" );
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.hibernate.query.spi.QueryEngine;
|
|||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.TemporalUnit;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderer;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -39,7 +39,7 @@ import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEM
|
|||
*
|
||||
* @author Marco Belladelli
|
||||
*/
|
||||
public class DateTruncEmulation extends AbstractSqmFunctionDescriptor implements FunctionRenderingSupport {
|
||||
public class DateTruncEmulation extends AbstractSqmFunctionDescriptor implements FunctionRenderer {
|
||||
protected final String toDateFunction;
|
||||
private final SqmFormat sqmFormat;
|
||||
|
||||
|
@ -58,6 +58,7 @@ public class DateTruncEmulation extends AbstractSqmFunctionDescriptor implements
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
sqlAppender.appendSql( toDateFunction );
|
||||
sqlAppender.append( '(' );
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -46,6 +47,7 @@ public class DerbyLpadEmulation
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final SqlAstNode string = arguments.get( 0 );
|
||||
final SqlAstNode length = arguments.get( 1 );
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -46,6 +47,7 @@ public class DerbyRpadEmulation
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final SqlAstNode string = arguments.get( 0 );
|
||||
final SqlAstNode length = arguments.get( 1 );
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
|
@ -70,6 +71,7 @@ public class EveryAnyEmulation extends AbstractSqmSelfRenderingFunctionDescripto
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
if ( trueLiteral != null ) {
|
||||
sqlAppender.appendSql( "case when " );
|
||||
|
@ -108,7 +110,9 @@ public class EveryAnyEmulation extends AbstractSqmSelfRenderingFunctionDescripto
|
|||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
|
||||
this.render( sqlAppender, sqlAstArguments, null, walker );
|
||||
SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
this.render( sqlAppender, sqlAstArguments, null, returnType, walker );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import org.hibernate.query.sqm.TemporalUnit;
|
|||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderer;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -48,8 +48,7 @@ import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEM
|
|||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class ExtractFunction
|
||||
extends AbstractSqmFunctionDescriptor implements FunctionRenderingSupport {
|
||||
public class ExtractFunction extends AbstractSqmFunctionDescriptor implements FunctionRenderer {
|
||||
|
||||
private final Dialect dialect;
|
||||
|
||||
|
@ -70,6 +69,7 @@ public class ExtractFunction
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final ExtractUnit field = (ExtractUnit) sqlAstArguments.get( 0 );
|
||||
final TemporalUnit unit = field.getUnit();
|
||||
|
@ -100,7 +100,7 @@ public class ExtractFunction
|
|||
);
|
||||
return new SelfRenderingSqmFunction<>(
|
||||
this,
|
||||
(sqlAppender, sqlAstArguments, walker) -> sqlAstArguments.get( 0 ).accept( walker ),
|
||||
(sqlAppender, sqlAstArguments, returnType, walker) -> sqlAstArguments.get( 0 ).accept( walker ),
|
||||
Collections.singletonList( offsetPath ),
|
||||
null,
|
||||
null,
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.query.sqm.ComparisonOperator;
|
|||
import org.hibernate.query.sqm.TemporalUnit;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderer;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.MultipatternSqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
||||
|
@ -61,7 +62,7 @@ import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEM
|
|||
*
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
public class FormatFunction extends AbstractSqmFunctionDescriptor implements FunctionRenderingSupport {
|
||||
public class FormatFunction extends AbstractSqmFunctionDescriptor implements FunctionRenderer {
|
||||
|
||||
private final String nativeFunctionName;
|
||||
private final boolean reversedArguments;
|
||||
|
@ -103,6 +104,7 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
sqlAppender.appendSql( nativeFunctionName );
|
||||
sqlAppender.append( '(' );
|
||||
|
@ -171,6 +173,10 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
private final boolean supportsPatternLiterals;
|
||||
private final TypeConfiguration typeConfiguration;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #FormatSqmFunction(SqmFunctionDescriptor, FunctionRenderer, List, ReturnableType, ArgumentsValidator, FunctionReturnTypeResolver, boolean, QueryEngine)} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public FormatSqmFunction(
|
||||
SqmFunctionDescriptor descriptor,
|
||||
FunctionRenderingSupport renderingSupport,
|
||||
|
@ -194,6 +200,29 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
this.typeConfiguration = queryEngine.getTypeConfiguration();
|
||||
}
|
||||
|
||||
public FormatSqmFunction(
|
||||
SqmFunctionDescriptor descriptor,
|
||||
FunctionRenderer renderer,
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
ReturnableType<T> impliedResultType,
|
||||
ArgumentsValidator argumentsValidator,
|
||||
FunctionReturnTypeResolver returnTypeResolver,
|
||||
boolean supportsPatternLiterals,
|
||||
QueryEngine queryEngine) {
|
||||
super(
|
||||
descriptor,
|
||||
renderer,
|
||||
arguments,
|
||||
impliedResultType,
|
||||
argumentsValidator,
|
||||
returnTypeResolver,
|
||||
queryEngine.getCriteriaBuilder(),
|
||||
"format"
|
||||
);
|
||||
this.supportsPatternLiterals = supportsPatternLiterals;
|
||||
this.typeConfiguration = queryEngine.getTypeConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
|
||||
final List<SqlAstNode> arguments = resolveSqlAstArguments( getArguments(), walker );
|
||||
|
@ -293,7 +322,7 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
formatExpression,
|
||||
new SelfRenderingFunctionSqlAstExpression(
|
||||
getFunctionName(),
|
||||
getRenderingSupport(),
|
||||
getFunctionRenderer(),
|
||||
List.of(
|
||||
arguments.get( 0 ),
|
||||
new QueryLiteral<>( formatPart, stringType )
|
||||
|
@ -419,7 +448,7 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
formatExpression,
|
||||
new SelfRenderingFunctionSqlAstExpression(
|
||||
getFunctionName(),
|
||||
getRenderingSupport(),
|
||||
getFunctionRenderer(),
|
||||
List.of( arguments.get( 0 ), new Format( chunks[i] ) ),
|
||||
resultType,
|
||||
mappingModelExpressible
|
||||
|
@ -440,7 +469,7 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
}
|
||||
return new SelfRenderingFunctionSqlAstExpression(
|
||||
getFunctionName(),
|
||||
getRenderingSupport(),
|
||||
getFunctionRenderer(),
|
||||
arguments,
|
||||
resultType,
|
||||
mappingModelExpressible
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.dialect.function;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
|
@ -42,8 +43,9 @@ public class HypotheticalSetFunction extends AbstractSqmSelfRenderingFunctionDes
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -51,8 +53,9 @@ public class HypotheticalSetFunction extends AbstractSqmSelfRenderingFunctionDes
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,6 +64,7 @@ public class HypotheticalSetFunction extends AbstractSqmSelfRenderingFunctionDes
|
|||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
List<SortSpecification> withinGroup,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
if ( filter != null && !translator.supportsFilterClause() ) {
|
||||
throw new IllegalArgumentException( "Can't emulate filter clause for inverse distribution function [" + getName() + "]" );
|
||||
|
|
|
@ -101,7 +101,7 @@ public class HypotheticalSetWindowEmulation extends HypotheticalSetFunction {
|
|||
}
|
||||
final SelfRenderingFunctionSqlAstExpression function = new SelfRenderingOrderedSetAggregateFunctionSqlAstExpression(
|
||||
getFunctionName(),
|
||||
getRenderingSupport(),
|
||||
getFunctionRenderer(),
|
||||
Collections.emptyList(),
|
||||
getFilter() == null ? null : (Predicate) getFilter().accept( walker ),
|
||||
Collections.emptyList(),
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.BinaryArithmeticOperator;
|
||||
import org.hibernate.query.sqm.TemporalUnit;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
||||
|
@ -53,6 +54,7 @@ public class IntegralTimestampaddFunction
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
|
||||
final DurationUnit field = (DurationUnit) arguments.get( 0 );
|
||||
|
@ -64,7 +66,7 @@ public class IntegralTimestampaddFunction
|
|||
renderWithUnitConversion( sqlAppender, magnitude, to, walker, field, unit );
|
||||
}
|
||||
else {
|
||||
super.render( sqlAppender, arguments, walker );
|
||||
super.render( sqlAppender, arguments, returnType, walker );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,8 +75,9 @@ public class InverseDistributionFunction extends AbstractSqmSelfRenderingFunctio
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -84,8 +85,9 @@ public class InverseDistributionFunction extends AbstractSqmSelfRenderingFunctio
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,6 +96,7 @@ public class InverseDistributionFunction extends AbstractSqmSelfRenderingFunctio
|
|||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
List<SortSpecification> withinGroup,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
if ( filter != null && !translator.supportsFilterClause() ) {
|
||||
throw new IllegalArgumentException( "Can't emulate filter clause for inverse distribution function [" + getName() + "]" );
|
||||
|
|
|
@ -96,7 +96,7 @@ public class InverseDistributionWindowEmulation extends InverseDistributionFunct
|
|||
}
|
||||
final SelfRenderingFunctionSqlAstExpression function = new SelfRenderingOrderedSetAggregateFunctionSqlAstExpression(
|
||||
getFunctionName(),
|
||||
getRenderingSupport(),
|
||||
getFunctionRenderer(),
|
||||
arguments,
|
||||
getFilter() == null ? null : (Predicate) getFilter().accept( walker ),
|
||||
withinGroup,
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
||||
|
@ -54,6 +55,7 @@ public class LengthFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression expression = (Expression) sqlAstArguments.get( 0 );
|
||||
final JdbcType jdbcType = expression.getExpressionType().getSingleJdbcMapping().getJdbcType();
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.dialect.function;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
|
@ -52,8 +53,9 @@ public class ListaggFunction extends AbstractSqmSelfRenderingFunctionDescriptor
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,8 +63,9 @@ public class ListaggFunction extends AbstractSqmSelfRenderingFunctionDescriptor
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -71,6 +74,7 @@ public class ListaggFunction extends AbstractSqmSelfRenderingFunctionDescriptor
|
|||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
List<SortSpecification> withinGroup,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
final boolean caseWrapper = filter != null && !translator.supportsFilterClause();
|
||||
sqlAppender.appendSql( "listagg(" );
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.dialect.function;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
|
@ -52,8 +53,9 @@ public class ListaggGroupConcatEmulation extends AbstractSqmSelfRenderingFunctio
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,8 +63,9 @@ public class ListaggGroupConcatEmulation extends AbstractSqmSelfRenderingFunctio
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -71,6 +74,7 @@ public class ListaggGroupConcatEmulation extends AbstractSqmSelfRenderingFunctio
|
|||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
List<SortSpecification> withinGroup,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
final boolean caseWrapper = filter != null && !translator.supportsFilterClause();
|
||||
sqlAppender.appendSql( "group_concat(" );
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.CastType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
|
@ -65,8 +66,9 @@ public class ListaggStringAggEmulation extends AbstractSqmSelfRenderingFunctionD
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -74,8 +76,9 @@ public class ListaggStringAggEmulation extends AbstractSqmSelfRenderingFunctionD
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -84,6 +87,7 @@ public class ListaggStringAggEmulation extends AbstractSqmSelfRenderingFunctionD
|
|||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
List<SortSpecification> withinGroup,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
final boolean caseWrapper = filter != null && !translator.supportsFilterClause();
|
||||
sqlAppender.appendSql( functionName );
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
|
@ -54,6 +55,7 @@ public class MinMaxCaseEveryAnyEmulation extends AbstractSqmSelfRenderingFunctio
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
if ( every ) {
|
||||
sqlAppender.appendSql( "min(case when " );
|
||||
|
@ -77,7 +79,10 @@ public class MinMaxCaseEveryAnyEmulation extends AbstractSqmSelfRenderingFunctio
|
|||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
|
||||
this.render( sqlAppender, sqlAstArguments, null, walker );
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
this.render( sqlAppender, sqlAstArguments, null, returnType, walker );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.sql.ast.Clause;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
|
@ -37,6 +38,7 @@ public class ModeStatsModeEmulation extends InverseDistributionFunction {
|
|||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
List<SortSpecification> withinGroup,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
final boolean caseWrapper = filter != null && !translator.supportsFilterClause();
|
||||
sqlAppender.appendSql( "stats_mode(" );
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.List;
|
|||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.TemporalUnit;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderer;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||
|
@ -45,11 +46,11 @@ public class OracleTruncFunction extends TruncFunction {
|
|||
ReturnableType<T> impliedResultType,
|
||||
QueryEngine queryEngine) {
|
||||
final List<SqmTypedNode<?>> args = new ArrayList<>( arguments );
|
||||
final FunctionRenderingSupport renderingSupport;
|
||||
final FunctionRenderer renderer;
|
||||
final ArgumentsValidator argumentsValidator;
|
||||
if ( arguments.size() == 2 && arguments.get( 1 ) instanceof SqmExtractUnit ) {
|
||||
// datetime truncation
|
||||
renderingSupport = datetimeRenderingSupport;
|
||||
renderer = datetimeRenderingSupport;
|
||||
argumentsValidator = TruncArgumentsValidator.DATETIME_VALIDATOR;
|
||||
// the trunc() function requires translating the temporal_unit to a format string
|
||||
final TemporalUnit temporalUnit = ( (SqmExtractUnit<?>) arguments.get( 1 ) ).getUnit();
|
||||
|
@ -92,13 +93,13 @@ public class OracleTruncFunction extends TruncFunction {
|
|||
}
|
||||
else {
|
||||
// numeric truncation
|
||||
renderingSupport = numericRenderingSupport;
|
||||
renderer = numericRenderingSupport;
|
||||
argumentsValidator = TruncArgumentsValidator.NUMERIC_VALIDATOR;
|
||||
}
|
||||
|
||||
return new SelfRenderingSqmFunction<>(
|
||||
this,
|
||||
renderingSupport,
|
||||
renderer,
|
||||
args,
|
||||
impliedResultType,
|
||||
argumentsValidator,
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.dialect.function;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
|
@ -46,8 +47,12 @@ public class PostgreSQLMinMaxFunction extends AbstractSqmSelfRenderingFunctionDe
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, walker );
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -55,6 +60,7 @@ public class PostgreSQLMinMaxFunction extends AbstractSqmSelfRenderingFunctionDe
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
final boolean caseWrapper = filter != null && !translator.supportsFilterClause();
|
||||
sqlAppender.appendSql( getName() );
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
|||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderer;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
|
@ -46,7 +47,7 @@ import static org.hibernate.query.sqm.produce.function.FunctionParameterType.NUM
|
|||
* @author Marco Belladelli
|
||||
* @see <a href="https://www.postgresql.org/docs/current/functions-math.html">PostgreSQL documentation</a>
|
||||
*/
|
||||
public class PostgreSQLTruncRoundFunction extends AbstractSqmFunctionDescriptor implements FunctionRenderingSupport {
|
||||
public class PostgreSQLTruncRoundFunction extends AbstractSqmFunctionDescriptor implements FunctionRenderer {
|
||||
private final boolean supportsTwoArguments;
|
||||
|
||||
public PostgreSQLTruncRoundFunction(String name, boolean supportsTwoArguments) {
|
||||
|
@ -60,7 +61,11 @@ public class PostgreSQLTruncRoundFunction extends AbstractSqmFunctionDescriptor
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> arguments, SqlAstTranslator<?> walker) {
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final int numberOfArguments = arguments.size();
|
||||
final Expression firstArg = (Expression) arguments.get( 0 );
|
||||
final JdbcType jdbcType = firstArg.getExpressionType().getSingleJdbcMapping().getJdbcType();
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -43,6 +44,7 @@ public class QuantifiedLeastGreatestEmulation
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final int numberOfArguments = arguments.size();
|
||||
if ( numberOfArguments > 1 ) {
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
|
@ -56,6 +57,7 @@ public class SQLServerEveryAnyEmulation extends AbstractSqmSelfRenderingFunction
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
if ( every ) {
|
||||
sqlAppender.appendSql( "min(iif(" );
|
||||
|
@ -79,7 +81,10 @@ public class SQLServerEveryAnyEmulation extends AbstractSqmSelfRenderingFunction
|
|||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
|
||||
this.render( sqlAppender, sqlAstArguments, null, walker );
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
this.render( sqlAppender, sqlAstArguments, null, (ReturnableType<?>) null, walker );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.dialect.function;
|
|||
import java.util.List;
|
||||
import jakarta.persistence.TemporalType;
|
||||
|
||||
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;
|
||||
|
@ -31,6 +32,7 @@ public class SQLServerFormatEmulation extends FormatFunction {
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression datetime = (Expression) arguments.get(0);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
|
@ -38,6 +39,7 @@ public class SqlFunction
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final QueryLiteral<String> sqlFragmentLiteral = (QueryLiteral<String>) arguments.get( 0 );
|
||||
final String sqlFragment = sqlFragmentLiteral.getLiteralValue();
|
||||
|
|
|
@ -79,6 +79,7 @@ public class SqlServerConvertTruncFunction extends TruncFunction {
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
sqlAppender.appendSql( toDateFunction );
|
||||
sqlAppender.append( '(' );
|
||||
|
|
|
@ -87,6 +87,7 @@ public class SybaseTruncFunction extends TruncFunction {
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
sqlAppender.appendSql( toDateFunction );
|
||||
sqlAppender.append( '(' );
|
||||
|
|
|
@ -65,6 +65,7 @@ public class TimestampaddFunction
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
|
||||
final DurationUnit field = (DurationUnit) arguments.get( 0 );
|
||||
|
|
|
@ -74,6 +74,7 @@ public class TimestampdiffFunction
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
|
||||
final DurationUnit field = (DurationUnit) arguments.get( 0 );
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderer;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -28,7 +29,7 @@ import org.hibernate.type.spi.TypeConfiguration;
|
|||
*
|
||||
* @author Christian Beikov
|
||||
*/
|
||||
public class TransactSQLStrFunction extends CastStrEmulation implements FunctionRenderingSupport {
|
||||
public class TransactSQLStrFunction extends CastStrEmulation implements FunctionRenderer {
|
||||
|
||||
public TransactSQLStrFunction(TypeConfiguration typeConfiguration) {
|
||||
super(
|
||||
|
@ -66,7 +67,11 @@ public class TransactSQLStrFunction extends CastStrEmulation implements Function
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> arguments, SqlAstTranslator<?> walker) {
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
sqlAppender.appendSql( "str(" );
|
||||
arguments.get( 0 ).accept( walker );
|
||||
for ( int i = 1; i < arguments.size(); i++ ) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.dialect.function;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.TrimSpec;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
|
@ -58,7 +59,11 @@ public class TrimFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> sqlAstArguments, SqlAstTranslator<?> walker) {
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final TrimSpec specification = ( (TrimSpecification) sqlAstArguments.get( 0 ) ).getSpecification();
|
||||
final Object trimCharacter = ( (Literal) sqlAstArguments.get( 1 ) ).getLiteralValue();
|
||||
final Expression sourceExpr = (Expression) sqlAstArguments.get( 2 );
|
||||
|
|
|
@ -14,7 +14,7 @@ import org.hibernate.query.spi.QueryEngine;
|
|||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.TemporalUnit;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderer;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||
|
@ -100,7 +100,7 @@ public class TruncFunction extends AbstractSqmFunctionDescriptor {
|
|||
QueryEngine queryEngine) {
|
||||
final NodeBuilder nodeBuilder = queryEngine.getCriteriaBuilder();
|
||||
final List<SqmTypedNode<?>> args = new ArrayList<>( arguments );
|
||||
final FunctionRenderingSupport renderingSupport;
|
||||
final FunctionRenderer renderingSupport;
|
||||
final ArgumentsValidator argumentsValidator;
|
||||
if ( arguments.size() == 2 && arguments.get( 1 ) instanceof SqmExtractUnit ) {
|
||||
// datetime truncation
|
||||
|
@ -171,7 +171,7 @@ public class TruncFunction extends AbstractSqmFunctionDescriptor {
|
|||
);
|
||||
}
|
||||
|
||||
private static class TruncRenderingSupport implements FunctionRenderingSupport {
|
||||
protected static class TruncRenderingSupport implements FunctionRenderer {
|
||||
private final PatternRenderer truncPattern;
|
||||
private final PatternRenderer twoArgTruncPattern;
|
||||
|
||||
|
@ -184,6 +184,7 @@ public class TruncFunction extends AbstractSqmFunctionDescriptor {
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final PatternRenderer pattern;
|
||||
if ( twoArgTruncPattern != null && sqlAstArguments.size() == 2 ) {
|
||||
|
|
|
@ -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 org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* Encapsulates the validator, return type and argument type resolvers for the array_contains function.
|
||||
* Subclasses only have to implement the rendering.
|
||||
*/
|
||||
public abstract class AbstractArrayContainsFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
|
||||
protected final boolean nullable;
|
||||
|
||||
public AbstractArrayContainsFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
super(
|
||||
"array_contains" + ( nullable ? "_nullable" : "" ),
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 2 ),
|
||||
ArrayContainsArgumentValidator.INSTANCE
|
||||
),
|
||||
StandardFunctionReturnTypeResolvers.invariant( typeConfiguration.standardBasicTypeForJavaType( Boolean.class ) ),
|
||||
ArrayContainsArgumentTypeResolver.INSTANCE
|
||||
);
|
||||
this.nullable = nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgumentListSignature() {
|
||||
return "(ARRAY haystackArray, OBJECT needleElementOrArray)";
|
||||
}
|
||||
}
|
|
@ -13,25 +13,31 @@ 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 quantified array_contains functions.
|
||||
* Encapsulates the validator, return type and argument type resolvers for the array_overlaps function.
|
||||
* Subclasses only have to implement the rendering.
|
||||
*/
|
||||
public abstract class AbstractArrayContainsQuantifiedFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
public abstract class AbstractArrayOverlapsFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
|
||||
public AbstractArrayContainsQuantifiedFunction(String functionName, TypeConfiguration typeConfiguration) {
|
||||
protected final boolean nullable;
|
||||
|
||||
public AbstractArrayOverlapsFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
super(
|
||||
functionName,
|
||||
"array_overlaps" + ( nullable ? "_nullable" : "" ),
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 2 ),
|
||||
ArraysOfSameTypeArgumentValidator.INSTANCE
|
||||
),
|
||||
StandardFunctionReturnTypeResolvers.invariant( typeConfiguration.standardBasicTypeForJavaType( Boolean.class ) ),
|
||||
StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE
|
||||
StandardFunctionArgumentTypeResolvers.byArgument(
|
||||
StandardFunctionArgumentTypeResolvers.argumentsOrImplied( 1 ),
|
||||
StandardFunctionArgumentTypeResolvers.argumentsOrImplied( 0 )
|
||||
)
|
||||
);
|
||||
this.nullable = nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgumentListSignature() {
|
||||
return "(ARRAY haystackArray, ARRAY needleArray)";
|
||||
return "(ARRAY array0, OBJECT array1)";
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ package org.hibernate.dialect.function.array;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -50,8 +51,9 @@ public class ArrayAggFunction extends AbstractSqmSelfRenderingFunctionDescriptor
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -59,8 +61,9 @@ public class ArrayAggFunction extends AbstractSqmSelfRenderingFunctionDescriptor
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,6 +72,7 @@ public class ArrayAggFunction extends AbstractSqmSelfRenderingFunctionDescriptor
|
|||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
List<SortSpecification> withinGroup,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
final boolean caseWrapper = filter != null && ( !supportsFilter || !translator.supportsFilterClause() );
|
||||
sqlAppender.appendSql( functionName );
|
||||
|
|
|
@ -9,11 +9,10 @@ package org.hibernate.dialect.function.array;
|
|||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionArgumentTypeResolver;
|
||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
||||
import org.hibernate.type.BasicPluralType;
|
||||
|
||||
|
@ -40,21 +39,27 @@ public class ArrayAndElementArgumentTypeResolver implements FunctionArgumentType
|
|||
SqmToSqlAstConverter converter) {
|
||||
if ( argumentIndex == arrayIndex ) {
|
||||
for ( int elementIndex : elementIndexes ) {
|
||||
final SqmTypedNode<?> argument = function.getArguments().get( elementIndex );
|
||||
final DomainType<?> sqmType = argument.getExpressible().getSqmType();
|
||||
if ( sqmType instanceof ReturnableType<?> ) {
|
||||
final SqmTypedNode<?> node = function.getArguments().get( elementIndex );
|
||||
if ( node instanceof SqmExpression<?> ) {
|
||||
final MappingModelExpressible<?> expressible = converter.determineValueMapping( (SqmExpression<?>) node );
|
||||
if ( expressible != null ) {
|
||||
return DdlTypeHelper.resolveArrayType(
|
||||
sqmType,
|
||||
(DomainType<?>) expressible.getSingleJdbcMapping(),
|
||||
converter.getCreationContext().getSessionFactory().getTypeConfiguration()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( ArrayHelper.contains( elementIndexes, argumentIndex ) ) {
|
||||
final SqmTypedNode<?> argument = function.getArguments().get( arrayIndex );
|
||||
final SqmExpressible<?> sqmType = argument.getNodeType();
|
||||
if ( sqmType instanceof BasicPluralType<?, ?> ) {
|
||||
return ( (BasicPluralType<?, ?>) sqmType ).getElementType();
|
||||
final SqmTypedNode<?> node = function.getArguments().get( arrayIndex );
|
||||
if ( node instanceof SqmExpression<?> ) {
|
||||
final MappingModelExpressible<?> expressible = converter.determineValueMapping( (SqmExpression<?>) node );
|
||||
if ( expressible != null ) {
|
||||
if ( expressible.getSingleJdbcMapping() instanceof BasicPluralType<?, ?> ) {
|
||||
return ( (BasicPluralType<?, ?>) expressible.getSingleJdbcMapping() ).getElementType();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -44,7 +44,7 @@ public class ArrayArgumentValidator implements ArgumentsValidator {
|
|||
return getElementType( arrayIndex, arguments, functionName, typeConfiguration );
|
||||
}
|
||||
|
||||
protected BasicType<?> getElementType(
|
||||
protected BasicPluralType<?, ?> getPluralType(
|
||||
int arrayIndex,
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
String functionName,
|
||||
|
@ -64,6 +64,14 @@ public class ArrayArgumentValidator implements ArgumentsValidator {
|
|||
)
|
||||
);
|
||||
}
|
||||
return ( (BasicPluralType<?, ?>) arrayType ).getElementType();
|
||||
return (BasicPluralType<?, ?>) arrayType;
|
||||
}
|
||||
|
||||
protected BasicType<?> getElementType(
|
||||
int arrayIndex,
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
String functionName,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
return getPluralType( arrayIndex, arguments, functionName, typeConfiguration ).getElementType();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
|
@ -47,6 +48,7 @@ public class ArrayConcatElementFunction extends AbstractSqmSelfRenderingFunction
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final SqlAstNode firstArgument = sqlAstArguments.get( 0 );
|
||||
final SqlAstNode secondArgument = sqlAstArguments.get( 1 );
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||
|
@ -44,6 +45,7 @@ public class ArrayConcatFunction extends AbstractSqmSelfRenderingFunctionDescrip
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
sqlAppender.append( prefix );
|
||||
sqlAstArguments.get( 0 ).accept( walker );
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.internal.TypecheckUtil;
|
||||
|
@ -39,7 +40,11 @@ public class ArrayConstructorFunction extends AbstractSqmSelfRenderingFunctionDe
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(SqlAppender sqlAppender, List<? extends SqlAstNode> arguments, SqlAstTranslator<?> walker) {
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
if ( withKeyword ) {
|
||||
sqlAppender.append( "array" );
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.dialect.function.array;
|
||||
|
||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionArgumentTypeResolver;
|
||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
||||
import org.hibernate.type.BasicPluralType;
|
||||
|
||||
/**
|
||||
* A {@link FunctionArgumentTypeResolver} that resolves the argument types for the {@code array_contains} function.
|
||||
*/
|
||||
public class ArrayContainsArgumentTypeResolver implements FunctionArgumentTypeResolver {
|
||||
|
||||
public static final FunctionArgumentTypeResolver INSTANCE = new ArrayContainsArgumentTypeResolver();
|
||||
|
||||
@Override
|
||||
public MappingModelExpressible<?> resolveFunctionArgumentType(
|
||||
SqmFunction<?> function,
|
||||
int argumentIndex,
|
||||
SqmToSqlAstConverter converter) {
|
||||
if ( argumentIndex == 0 ) {
|
||||
final SqmTypedNode<?> node = function.getArguments().get( 1 );
|
||||
if ( node instanceof SqmExpression<?> ) {
|
||||
final MappingModelExpressible<?> expressible = converter.determineValueMapping( (SqmExpression<?>) node );
|
||||
if ( expressible != null ) {
|
||||
if ( expressible.getSingleJdbcMapping() instanceof BasicPluralType<?, ?> ) {
|
||||
return expressible;
|
||||
}
|
||||
else {
|
||||
return DdlTypeHelper.resolveArrayType(
|
||||
(DomainType<?>) expressible.getSingleJdbcMapping(),
|
||||
converter.getCreationContext().getSessionFactory().getTypeConfiguration()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( argumentIndex == 1 ) {
|
||||
final SqmTypedNode<?> node = function.getArguments().get( 0 );
|
||||
if ( node instanceof SqmExpression<?> ) {
|
||||
final MappingModelExpressible<?> expressible = converter.determineValueMapping( (SqmExpression<?>) node );
|
||||
if ( expressible != null ) {
|
||||
return expressible;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.sqm.SqmExpressible;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionArgumentException;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
import org.hibernate.type.BasicPluralType;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* A {@link ArgumentsValidator} that validates the arguments for the {@code array_contains} function.
|
||||
*/
|
||||
public class ArrayContainsArgumentValidator extends ArrayArgumentValidator {
|
||||
|
||||
public static final ArgumentsValidator INSTANCE = new ArrayContainsArgumentValidator();
|
||||
|
||||
protected ArrayContainsArgumentValidator() {
|
||||
super( 0 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
String functionName,
|
||||
TypeConfiguration typeConfiguration) {
|
||||
final BasicPluralType<?, ?> haystackType = getPluralType( 0, arguments, functionName, typeConfiguration );
|
||||
final SqmExpressible<?> expressible = arguments.get( 1 ).getExpressible();
|
||||
final SqmExpressible<?> needleType = expressible == null ? null : expressible.getSqmType();
|
||||
if ( needleType != null && !haystackType.equals( needleType ) && !haystackType.getElementType().equals( needleType ) ) {
|
||||
throw new FunctionArgumentException(
|
||||
String.format(
|
||||
"Parameter 1 of function '%s()' has type %s, but argument is of type '%s'",
|
||||
functionName,
|
||||
haystackType.getJavaTypeDescriptor().getTypeName(),
|
||||
needleType.getTypeName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,63 +8,78 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
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.BasicPluralType;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* Special array contains function that also applies a cast to the element argument. PostgreSQL needs this,
|
||||
* because by default it assumes a {@code text[]}, which is not compatible with {@code varchar[]}.
|
||||
*/
|
||||
public class ArrayContainsOperatorFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
public class ArrayContainsOperatorFunction extends ArrayContainsUnnestFunction {
|
||||
|
||||
public ArrayContainsOperatorFunction(TypeConfiguration typeConfiguration) {
|
||||
super(
|
||||
"array_contains",
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 2 ),
|
||||
ArrayAndElementArgumentValidator.DEFAULT_INSTANCE
|
||||
),
|
||||
StandardFunctionReturnTypeResolvers.invariant( typeConfiguration.standardBasicTypeForJavaType( Boolean.class ) ),
|
||||
ArrayAndElementArgumentTypeResolver.DEFAULT_INSTANCE
|
||||
);
|
||||
public ArrayContainsOperatorFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
super( nullable, 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 );
|
||||
arrayExpression.accept( walker );
|
||||
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression needleExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
final JdbcMappingContainer needleTypeContainer = needleExpression.getExpressionType();
|
||||
final JdbcMapping needleType = needleTypeContainer == null ? null : needleTypeContainer.getSingleJdbcMapping();
|
||||
if ( needleType == null || needleType instanceof BasicPluralType<?, ?> ) {
|
||||
if ( nullable ) {
|
||||
super.render( sqlAppender, sqlAstArguments, returnType, walker );
|
||||
}
|
||||
else {
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( "@>" );
|
||||
if ( needsArrayCasting( elementExpression ) ) {
|
||||
needleExpression.accept( walker );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( nullable ) {
|
||||
sqlAppender.append( "array_position(" );
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( ") is not null" );
|
||||
}
|
||||
else {
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( "@>" );
|
||||
if ( needsArrayCasting( needleExpression ) ) {
|
||||
sqlAppender.append( "cast(array[" );
|
||||
elementExpression.accept( walker );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( "] as " );
|
||||
sqlAppender.append( DdlTypeHelper.getCastTypeName( arrayExpression.getExpressionType(), walker ) );
|
||||
sqlAppender.append( DdlTypeHelper.getCastTypeName(
|
||||
haystackExpression.getExpressionType(),
|
||||
walker
|
||||
) );
|
||||
sqlAppender.append( ')' );
|
||||
}
|
||||
else {
|
||||
sqlAppender.append( "array[" );
|
||||
elementExpression.accept( walker );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( ']' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean needsArrayCasting(Expression elementExpression) {
|
||||
// PostgreSQL doesn't do implicit conversion between text[] and varchar[], so we need casting
|
||||
return elementExpression.getExpressionType().getSingleJdbcMapping().getJdbcType().isString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgumentListSignature() {
|
||||
return "(ARRAY array, OBJECT element)";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
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.BasicPluralType;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* Implement the array contains function by using {@code unnest}.
|
||||
*/
|
||||
public class ArrayContainsUnnestFunction extends AbstractArrayContainsFunction {
|
||||
|
||||
public ArrayContainsUnnestFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
super( nullable, typeConfiguration );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression needleExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
final JdbcMappingContainer needleTypeContainer = needleExpression.getExpressionType();
|
||||
final JdbcMapping needleType = needleTypeContainer == null ? null : needleTypeContainer.getSingleJdbcMapping();
|
||||
if ( needleType == null || needleType instanceof BasicPluralType<?, ?> ) {
|
||||
sqlAppender.append( '(' );
|
||||
if ( ArrayHelper.isNullable( haystackExpression ) ) {
|
||||
walker.render( haystackExpression, SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
|
||||
sqlAppender.append( " is not null and " );
|
||||
}
|
||||
if ( ArrayHelper.isNullable( needleExpression ) ) {
|
||||
walker.render( needleExpression, SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
|
||||
sqlAppender.append( " is not null and " );
|
||||
}
|
||||
if ( !nullable ) {
|
||||
sqlAppender.append( "not exists(select 1 from unnest(" );
|
||||
walker.render( needleExpression, SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
|
||||
sqlAppender.append( ") t(i) where t.i is null) and " );
|
||||
}
|
||||
sqlAppender.append( "not exists(select * from unnest(" );
|
||||
walker.render( needleExpression, SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
|
||||
sqlAppender.append( ") except select * from unnest(" );
|
||||
walker.render( haystackExpression, SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
|
||||
sqlAppender.append( ")))" );
|
||||
}
|
||||
else {
|
||||
sqlAppender.append( "exists(select 1 from unnest(" );
|
||||
walker.render( haystackExpression, SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
|
||||
sqlAppender.append( ") t(i) where t.i" );
|
||||
if ( nullable ) {
|
||||
sqlAppender.append( " is not distinct from " );
|
||||
}
|
||||
else {
|
||||
sqlAppender.append( '=' );
|
||||
}
|
||||
walker.render( needleExpression, SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
|
||||
sqlAppender.append( ")" );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -41,6 +42,7 @@ public class ArrayGetUnnestFunction extends AbstractSqmSelfRenderingFunctionDesc
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression indexExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect.function.array;
|
||||
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.sql.ast.tree.expression.FunctionExpression;
|
||||
|
||||
public class ArrayHelper {
|
||||
public static boolean isNullable(Expression expression) {
|
||||
if ( expression instanceof FunctionExpression ) {
|
||||
final FunctionExpression functionExpression = (FunctionExpression) expression;
|
||||
// An array function literal is never null
|
||||
return !"array".equals( functionExpression.getFunctionName() );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
@ -15,32 +16,27 @@ import org.hibernate.sql.ast.tree.expression.Expression;
|
|||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* Array contains all function that uses the PostgreSQL {@code @>} operator.
|
||||
* Array overlaps function that uses the PostgreSQL {@code &&} operator.
|
||||
*/
|
||||
public class ArrayContainsQuantifiedOperatorFunction extends ArrayContainsQuantifiedUnnestFunction {
|
||||
public class ArrayOverlapsOperatorFunction extends ArrayOverlapsUnnestFunction {
|
||||
|
||||
public ArrayContainsQuantifiedOperatorFunction(TypeConfiguration typeConfiguration, boolean all, boolean nullable) {
|
||||
super( typeConfiguration, all, nullable );
|
||||
public ArrayOverlapsOperatorFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
super( nullable, typeConfiguration );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
SqlAstTranslator<?> walker) {
|
||||
ReturnableType<?> returnType, SqlAstTranslator<?> walker) {
|
||||
if ( nullable ) {
|
||||
super.render( sqlAppender, sqlAstArguments, walker );
|
||||
super.render( sqlAppender, sqlAstArguments, returnType, walker );
|
||||
}
|
||||
else {
|
||||
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression needleExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
haystackExpression.accept( walker );
|
||||
if ( all ) {
|
||||
sqlAppender.append( "@>" );
|
||||
}
|
||||
else {
|
||||
sqlAppender.append( "&&" );
|
||||
}
|
||||
needleExpression.accept( walker );
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
@ -15,48 +16,40 @@ import org.hibernate.sql.ast.tree.expression.Expression;
|
|||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* Implement the contains all function by using {@code unnest}.
|
||||
* Implement the overlaps function by using {@code unnest}.
|
||||
*/
|
||||
public class ArrayContainsQuantifiedUnnestFunction extends AbstractArrayContainsQuantifiedFunction {
|
||||
public class ArrayOverlapsUnnestFunction extends AbstractArrayOverlapsFunction {
|
||||
|
||||
protected final boolean all;
|
||||
protected final boolean nullable;
|
||||
|
||||
public ArrayContainsQuantifiedUnnestFunction(TypeConfiguration typeConfiguration, boolean all, boolean nullable) {
|
||||
super( "array_contains_" + ( all ? "all" : "any" ), typeConfiguration );
|
||||
this.all = all;
|
||||
this.nullable = nullable;
|
||||
public ArrayOverlapsUnnestFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
super( nullable, typeConfiguration );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression needleExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
sqlAppender.append( '(' );
|
||||
if ( ArrayHelper.isNullable( haystackExpression ) ) {
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( " is not null and " );
|
||||
}
|
||||
if ( ArrayHelper.isNullable( needleExpression ) ) {
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( " is not null and " );
|
||||
}
|
||||
if ( !nullable ) {
|
||||
sqlAppender.append( "not exists(select 1 from unnest(" );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( ") t(i) where t.i is null) and " );
|
||||
}
|
||||
if ( all ) {
|
||||
sqlAppender.append( "not " );
|
||||
}
|
||||
sqlAppender.append( "exists(select * from unnest(" );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( ")" );
|
||||
if ( all ) {
|
||||
sqlAppender.append( " except " );
|
||||
}
|
||||
else {
|
||||
sqlAppender.append( " intersect " );
|
||||
}
|
||||
sqlAppender.append( "select * from unnest(" );
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( ")))" );
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -47,6 +48,7 @@ public class ArrayRemoveIndexUnnestFunction extends AbstractSqmSelfRenderingFunc
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression indexExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
|
@ -36,6 +37,7 @@ public class ArrayReplaceUnnestFunction extends AbstractSqmSelfRenderingFunction
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression oldExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -45,6 +46,7 @@ public class ArraySetUnnestFunction extends AbstractSqmSelfRenderingFunctionDesc
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression indexExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
|
@ -47,6 +48,7 @@ public class ArraySliceUnnestFunction extends AbstractSqmSelfRenderingFunctionDe
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression startIndexExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
/*
|
||||
* 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.engine.jdbc.Size;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
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.BasicPluralType;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.descriptor.sql.DdlType;
|
||||
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
* Special array constructor function that also applies a cast to the array literal,
|
||||
* based on the inferred result type. PostgreSQL needs this,
|
||||
* because by default it assumes a {@code text[]}, which is not compatible with {@code varchar[]}.
|
||||
*/
|
||||
public class CastingArrayConstructorFunction extends ArrayConstructorFunction {
|
||||
|
||||
public CastingArrayConstructorFunction() {
|
||||
super( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
ReturnableType<T> impliedResultType,
|
||||
QueryEngine queryEngine) {
|
||||
return new ArrayConstructorSqmFunction<>(
|
||||
this,
|
||||
this,
|
||||
arguments,
|
||||
impliedResultType,
|
||||
getArgumentsValidator(),
|
||||
getReturnTypeResolver(),
|
||||
queryEngine.getCriteriaBuilder(),
|
||||
getName()
|
||||
);
|
||||
}
|
||||
|
||||
protected static class ArrayConstructorSqmFunction<T> extends SelfRenderingSqmFunction<T> {
|
||||
public ArrayConstructorSqmFunction(
|
||||
CastingArrayConstructorFunction descriptor,
|
||||
FunctionRenderingSupport renderingSupport,
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
ReturnableType<T> impliedResultType,
|
||||
ArgumentsValidator argumentsValidator,
|
||||
FunctionReturnTypeResolver returnTypeResolver,
|
||||
NodeBuilder nodeBuilder,
|
||||
String name) {
|
||||
super(
|
||||
descriptor,
|
||||
renderingSupport,
|
||||
arguments,
|
||||
impliedResultType,
|
||||
argumentsValidator,
|
||||
returnTypeResolver,
|
||||
nodeBuilder,
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
|
||||
final ReturnableType<?> resultType = resolveResultType( walker );
|
||||
|
||||
List<SqlAstNode> arguments = resolveSqlAstArguments( getArguments(), walker );
|
||||
if ( getArgumentsValidator() != null ) {
|
||||
getArgumentsValidator().validateSqlTypes( arguments, getFunctionName() );
|
||||
}
|
||||
return new SelfRenderingFunctionSqlAstExpression(
|
||||
getFunctionName(),
|
||||
getRenderingSupport(),
|
||||
arguments,
|
||||
resultType,
|
||||
resultType == null ? null : getMappingModelExpressible( walker, resultType, arguments )
|
||||
) {
|
||||
@Override
|
||||
public void renderToSql(
|
||||
SqlAppender sqlAppender,
|
||||
SqlAstTranslator<?> walker,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
String arrayTypeName = null;
|
||||
if ( resultType != null ) {
|
||||
final DomainType<?> type = resultType.getSqmType();
|
||||
if ( type instanceof BasicPluralType<?, ?> ) {
|
||||
final BasicPluralType<?, ?> pluralType = (BasicPluralType<?, ?>) type;
|
||||
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
|
||||
final DdlTypeRegistry ddlTypeRegistry = typeConfiguration.getDdlTypeRegistry();
|
||||
final DdlType ddlType = ddlTypeRegistry.getDescriptor(
|
||||
pluralType.getJdbcType().getDdlTypeCode()
|
||||
);
|
||||
arrayTypeName = ddlType.getCastTypeName( Size.nil(), pluralType, ddlTypeRegistry );
|
||||
sqlAppender.append( "cast(" );
|
||||
}
|
||||
}
|
||||
super.renderToSql( sqlAppender, walker, sessionFactory );
|
||||
if ( arrayTypeName != null ) {
|
||||
sqlAppender.appendSql( " as " );
|
||||
sqlAppender.appendSql( arrayTypeName );
|
||||
sqlAppender.appendSql( ')' );
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ import org.hibernate.engine.jdbc.Size;
|
|||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.metamodel.mapping.SqlTypedMapping;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||
import org.hibernate.type.BasicPluralType;
|
||||
|
@ -59,13 +60,13 @@ public class DdlTypeHelper {
|
|||
return AbstractSqlAstTranslator.getCastTypeName( (SqlTypedMapping) type, walker.getSessionFactory() );
|
||||
}
|
||||
else {
|
||||
final BasicType<?> jdbcMapping = (BasicType<?>) type.getSingleJdbcMapping();
|
||||
final BasicType<?> basicType = (BasicType<?>) type.getSingleJdbcMapping();
|
||||
final TypeConfiguration typeConfiguration = walker.getSessionFactory().getTypeConfiguration();
|
||||
final DdlTypeRegistry ddlTypeRegistry = typeConfiguration.getDdlTypeRegistry();
|
||||
final DdlType ddlType = ddlTypeRegistry.getDescriptor(
|
||||
jdbcMapping.getJdbcType().getDdlTypeCode()
|
||||
basicType.getJdbcType().getDdlTypeCode()
|
||||
);
|
||||
return ddlType.getCastTypeName( Size.nil(), jdbcMapping, ddlTypeRegistry );
|
||||
return ddlType.getCastTypeName( Size.nil(), basicType, ddlTypeRegistry );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||
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.BasicPluralType;
|
||||
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 H2ArrayContainsFunction extends AbstractArrayContainsFunction {
|
||||
|
||||
private final int maximumArraySize;
|
||||
|
||||
public H2ArrayContainsFunction(boolean nullable, int maximumArraySize, TypeConfiguration typeConfiguration) {
|
||||
super( nullable, typeConfiguration );
|
||||
this.maximumArraySize = maximumArraySize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression needleExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
final JdbcMappingContainer needleTypeContainer = needleExpression.getExpressionType();
|
||||
final JdbcMapping needleType = needleTypeContainer == null ? null : needleTypeContainer.getSingleJdbcMapping();
|
||||
if ( needleType == null || needleType instanceof BasicPluralType<?, ?> ) {
|
||||
sqlAppender.append( '(' );
|
||||
if ( ArrayHelper.isNullable( haystackExpression ) ) {
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( " is not null and " );
|
||||
}
|
||||
if ( ArrayHelper.isNullable( needleExpression ) ) {
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( " is not null and " );
|
||||
}
|
||||
if ( !nullable ) {
|
||||
sqlAppender.append( "not array_contains(" );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( ",null) and " );
|
||||
}
|
||||
sqlAppender.append( "not " );
|
||||
sqlAppender.append( "exists(select array_get(" );
|
||||
walker.render( needleExpression, SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER );
|
||||
sqlAppender.append( ",t.i) from system_range(1," );
|
||||
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||
sqlAppender.append( ") t(i) where array_length(" );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( ")>=t.i" );
|
||||
sqlAppender.append( " except " );
|
||||
sqlAppender.append( "select array_get(" );
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( ",t.i) from system_range(1," );
|
||||
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||
sqlAppender.append( ") t(i) where array_length(" );
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( ")>=t.i))" );
|
||||
}
|
||||
else {
|
||||
sqlAppender.append( "array_contains(" );
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( ')' );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
@ -19,61 +20,52 @@ 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 H2ArrayContainsQuantifiedEmulation extends AbstractArrayContainsQuantifiedFunction {
|
||||
public class H2ArrayOverlapsFunction extends AbstractArrayOverlapsFunction {
|
||||
|
||||
private final boolean all;
|
||||
private final boolean nullable;
|
||||
private final int maximumArraySize;
|
||||
|
||||
public H2ArrayContainsQuantifiedEmulation(TypeConfiguration typeConfiguration, boolean all, boolean nullable) {
|
||||
super( "array_contains_" + ( all ? "all" : "any" ), typeConfiguration );
|
||||
this.all = all;
|
||||
this.nullable = nullable;
|
||||
public H2ArrayOverlapsFunction(boolean nullable, int maximumArraySize, TypeConfiguration typeConfiguration) {
|
||||
super( nullable, typeConfiguration );
|
||||
this.maximumArraySize = maximumArraySize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression needleExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
sqlAppender.append( '(' );
|
||||
if ( ArrayHelper.isNullable( haystackExpression ) ) {
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( " is not null and " );
|
||||
}
|
||||
if ( ArrayHelper.isNullable( needleExpression ) ) {
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( " is not null and " );
|
||||
}
|
||||
if ( !nullable ) {
|
||||
sqlAppender.append( "not array_contains(" );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( ",null) and " );
|
||||
}
|
||||
if ( all ) {
|
||||
sqlAppender.append( "not " );
|
||||
}
|
||||
sqlAppender.append( "exists(select array_get(" );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( ",t.i) from system_range(1," );
|
||||
sqlAppender.append( Integer.toString( getMaximumArraySize() ) );
|
||||
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||
sqlAppender.append( ") t(i) where array_length(" );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( ")>=t.i" );
|
||||
if ( all ) {
|
||||
sqlAppender.append( " except " );
|
||||
}
|
||||
else {
|
||||
sqlAppender.append( " intersect " );
|
||||
}
|
||||
sqlAppender.append( "select array_get(" );
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( ",t.i) from system_range(1," );
|
||||
sqlAppender.append( Integer.toString( getMaximumArraySize() ) );
|
||||
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||
sqlAppender.append( ") t(i) where array_length(" );
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( ")>=t.i))" );
|
||||
}
|
||||
|
||||
protected int getMaximumArraySize() {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
}
|
|
@ -8,23 +8,30 @@ 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;
|
||||
|
||||
/**
|
||||
* H2 array_remove function.
|
||||
* 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 H2ArrayRemoveFunction extends AbstractArrayRemoveFunction {
|
||||
|
||||
public H2ArrayRemoveFunction() {
|
||||
private final int maximumArraySize;
|
||||
|
||||
public H2ArrayRemoveFunction(int maximumArraySize) {
|
||||
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 );
|
||||
|
@ -33,7 +40,7 @@ public class H2ArrayRemoveFunction extends AbstractArrayRemoveFunction {
|
|||
sqlAppender.append( " is null then null else coalesce((select array_agg(array_get(");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append(",i.idx)) from system_range(1," );
|
||||
sqlAppender.append( Integer.toString( getMaximumArraySize() ) );
|
||||
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||
sqlAppender.append( ") i(idx) where i.idx<=coalesce(cardinality(");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append("),0) and array_get(");
|
||||
|
@ -42,8 +49,4 @@ public class H2ArrayRemoveFunction extends AbstractArrayRemoveFunction {
|
|||
elementExpression.accept( walker );
|
||||
sqlAppender.append( "),array[]) end" );
|
||||
}
|
||||
|
||||
protected int getMaximumArraySize() {
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,24 +8,31 @@ 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;
|
||||
|
||||
/**
|
||||
* H2 array_remove_index function.
|
||||
* 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 H2ArrayRemoveIndexFunction extends ArrayRemoveIndexUnnestFunction {
|
||||
|
||||
public H2ArrayRemoveIndexFunction() {
|
||||
private final int maximumArraySize;
|
||||
|
||||
public H2ArrayRemoveIndexFunction(int maximumArraySize) {
|
||||
super( false );
|
||||
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 indexExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
|
@ -34,15 +41,11 @@ public class H2ArrayRemoveIndexFunction extends ArrayRemoveIndexUnnestFunction {
|
|||
sqlAppender.append( " is null then null else coalesce((select array_agg(array_get(");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append(",i.idx)) from system_range(1," );
|
||||
sqlAppender.append( Integer.toString( getMaximumArraySize() ) );
|
||||
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||
sqlAppender.append( ") i(idx) where i.idx<=coalesce(cardinality(");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append("),0) and i.idx is distinct from " );
|
||||
indexExpression.accept( walker );
|
||||
sqlAppender.append( "),array[]) end" );
|
||||
}
|
||||
|
||||
protected int getMaximumArraySize() {
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,20 +8,30 @@ 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;
|
||||
|
||||
/**
|
||||
* H2 array_replace function.
|
||||
* 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 H2ArrayReplaceFunction extends ArrayReplaceUnnestFunction {
|
||||
|
||||
private final int maximumArraySize;
|
||||
|
||||
public H2ArrayReplaceFunction(int maximumArraySize) {
|
||||
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 oldExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
|
@ -37,13 +47,9 @@ public class H2ArrayReplaceFunction extends ArrayReplaceUnnestFunction {
|
|||
sqlAppender.append( " else array_get(" );
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append(",i.idx) end) from system_range(1," );
|
||||
sqlAppender.append( Integer.toString( getMaximumArraySize() ) );
|
||||
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||
sqlAppender.append( ") i(idx) where i.idx<=coalesce(cardinality(");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append("),0)),array[]) end" );
|
||||
}
|
||||
|
||||
protected int getMaximumArraySize() {
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,24 +8,30 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
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;
|
||||
|
||||
/**
|
||||
* H2 array_set function.
|
||||
* 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 H2ArraySetFunction extends ArraySetUnnestFunction {
|
||||
|
||||
public H2ArraySetFunction() {
|
||||
private final int maximumArraySize;
|
||||
|
||||
public H2ArraySetFunction(int maximumArraySize) {
|
||||
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 indexExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
|
@ -41,7 +47,7 @@ public class H2ArraySetFunction extends ArraySetUnnestFunction {
|
|||
sqlAppender.append(") then array_get(");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append(",i.idx) end) from system_range(1," );
|
||||
sqlAppender.append( Integer.toString( getMaximumArraySize() ) );
|
||||
sqlAppender.append( Integer.toString( maximumArraySize ) );
|
||||
sqlAppender.append( ") i(idx) where i.idx<=greatest(case when ");
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append(" is not null then cardinality(" );
|
||||
|
@ -50,8 +56,4 @@ public class H2ArraySetFunction extends ArraySetUnnestFunction {
|
|||
indexExpression.accept( walker );
|
||||
sqlAppender.append( "))" );
|
||||
}
|
||||
|
||||
protected int getMaximumArraySize() {
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.metamodel.mapping.SqlTypedMapping;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator;
|
||||
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.BottomType;
|
||||
|
||||
public class HSQLArrayConstructorFunction extends ArrayConstructorFunction {
|
||||
|
||||
public HSQLArrayConstructorFunction() {
|
||||
super( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> arguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final String castTypeName;
|
||||
if ( returnType != null && hasOnlyBottomArguments( arguments ) ) {
|
||||
if ( returnType instanceof SqlTypedMapping ) {
|
||||
castTypeName = AbstractSqlAstTranslator.getCastTypeName( (SqlTypedMapping) returnType, walker.getSessionFactory() );
|
||||
}
|
||||
else {
|
||||
castTypeName = DdlTypeHelper.getCastTypeName( (JdbcMappingContainer) returnType, walker );
|
||||
}
|
||||
sqlAppender.append( "cast(" );
|
||||
}
|
||||
else {
|
||||
castTypeName = null;
|
||||
}
|
||||
sqlAppender.append( "array" );
|
||||
final int size = arguments.size();
|
||||
if ( size == 0 ) {
|
||||
sqlAppender.append( '[' );
|
||||
}
|
||||
else {
|
||||
char separator = '[';
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
SqlAstNode argument = arguments.get( i );
|
||||
sqlAppender.append( separator );
|
||||
argument.accept( walker );
|
||||
separator = ',';
|
||||
}
|
||||
}
|
||||
sqlAppender.append( ']' );
|
||||
if ( castTypeName != null ) {
|
||||
sqlAppender.append( " as " );
|
||||
sqlAppender.append( castTypeName );
|
||||
sqlAppender.append( ')' );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasOnlyBottomArguments(List<? extends SqlAstNode> arguments) {
|
||||
for ( int i = 0; i < arguments.size(); i++ ) {
|
||||
final Expression argument = (Expression) arguments.get( i );
|
||||
if ( !( argument.getExpressionType().getSingleJdbcMapping() instanceof BottomType ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !arguments.isEmpty();
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
@ -27,6 +28,7 @@ public class HSQLArrayPositionFunction extends AbstractArrayPositionFunction {
|
|||
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 );
|
||||
|
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
@ -25,6 +26,7 @@ public class HSQLArrayRemoveFunction extends AbstractArrayRemoveFunction {
|
|||
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 );
|
||||
|
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
@ -25,6 +26,7 @@ public class HSQLArraySetFunction extends ArraySetUnnestFunction {
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression indexExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
|
@ -41,8 +43,4 @@ public class HSQLArraySetFunction extends ArraySetUnnestFunction {
|
|||
arrayExpression.accept( walker );
|
||||
sqlAppender.append( ") with ordinality t(val, idx) on i.idx=t.idx)" );
|
||||
}
|
||||
|
||||
protected int getMaximumArraySize() {
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,10 +18,9 @@ import org.hibernate.query.ReturnableType;
|
|||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.SqmExpressible;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderer;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingOrderedSetAggregateFunctionSqlAstExpression;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmOrderedSetAggregateFunction;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||
|
@ -38,7 +37,6 @@ 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.cte.CteContainer;
|
||||
import org.hibernate.sql.ast.tree.cte.CteStatement;
|
||||
import org.hibernate.sql.ast.tree.cte.SelfRenderingCteObject;
|
||||
import org.hibernate.sql.ast.tree.expression.Distinct;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
|
@ -73,8 +71,9 @@ public class OracleArrayAggEmulation extends AbstractSqmSelfRenderingFunctionDes
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, null, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -82,8 +81,9 @@ public class OracleArrayAggEmulation extends AbstractSqmSelfRenderingFunctionDes
|
|||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), walker );
|
||||
render( sqlAppender, sqlAstArguments, filter, Collections.emptyList(), returnType, walker );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -92,6 +92,7 @@ public class OracleArrayAggEmulation extends AbstractSqmSelfRenderingFunctionDes
|
|||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
List<SortSpecification> withinGroup,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
sqlAppender.appendSql( "json_arrayagg" );
|
||||
sqlAppender.appendSql( '(' );
|
||||
|
@ -154,7 +155,7 @@ public class OracleArrayAggEmulation extends AbstractSqmSelfRenderingFunctionDes
|
|||
protected static class OracleArrayAggSqmFunction<T> extends SelfRenderingSqmOrderedSetAggregateFunction<T> {
|
||||
public OracleArrayAggSqmFunction(
|
||||
OracleArrayAggEmulation descriptor,
|
||||
FunctionRenderingSupport renderingSupport,
|
||||
FunctionRenderer renderingSupport,
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
SqmPredicate filter,
|
||||
SqmOrderByClause withinGroupClause,
|
||||
|
@ -241,7 +242,7 @@ public class OracleArrayAggEmulation extends AbstractSqmSelfRenderingFunctionDes
|
|||
}
|
||||
final OracleArrayAggEmulationSqlAstExpression expression = new OracleArrayAggEmulationSqlAstExpression(
|
||||
getFunctionName(),
|
||||
getRenderingSupport(),
|
||||
getFunctionRenderer(),
|
||||
arguments,
|
||||
getFilter() == null ? null : walker.visitNestedTopLevelPredicate( getFilter() ),
|
||||
withinGroup,
|
||||
|
@ -261,7 +262,7 @@ public class OracleArrayAggEmulation extends AbstractSqmSelfRenderingFunctionDes
|
|||
|
||||
public OracleArrayAggEmulationSqlAstExpression(
|
||||
String functionName,
|
||||
FunctionRenderingSupport renderer,
|
||||
FunctionRenderer renderer,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
Predicate filter,
|
||||
List<SortSpecification> withinGroup,
|
||||
|
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
@ -26,6 +27,7 @@ public class OracleArrayConcatElementFunction extends ArrayConcatElementFunction
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression firstArgument = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression secondArgument = (Expression) sqlAstArguments.get( 1 );
|
||||
|
|
|
@ -9,10 +9,10 @@ package org.hibernate.dialect.function.array;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Oracle concatenation function for arrays.
|
||||
|
@ -27,18 +27,11 @@ public class OracleArrayConcatFunction extends ArrayConcatFunction {
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
JdbcMappingContainer expressionType = null;
|
||||
for ( SqlAstNode sqlAstArgument : sqlAstArguments ) {
|
||||
expressionType = ( (Expression) sqlAstArgument ).getExpressionType();
|
||||
if ( expressionType != null ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final String arrayTypeName = DdlTypeHelper.getTypeName( expressionType, walker );
|
||||
final String arrayTypeName = DdlTypeHelper.getTypeName( (JdbcMappingContainer) returnType, walker );
|
||||
sqlAppender.append( arrayTypeName );
|
||||
sqlAppender.append( "_concat" );
|
||||
super.render( sqlAppender, sqlAstArguments, walker );
|
||||
super.render( sqlAppender, sqlAstArguments, returnType, walker );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,28 +8,13 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.jdbc.Size;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.SemanticException;
|
||||
import org.hibernate.query.spi.QueryEngine;
|
||||
import org.hibernate.query.sqm.NodeBuilder;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||
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.BasicPluralType;
|
||||
import org.hibernate.type.descriptor.sql.DdlType;
|
||||
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
public class OracleArrayConstructorFunction extends ArrayConstructorFunction {
|
||||
|
||||
|
@ -38,92 +23,33 @@ public class OracleArrayConstructorFunction extends ArrayConstructorFunction {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
ReturnableType<T> impliedResultType,
|
||||
QueryEngine queryEngine) {
|
||||
return new ArrayConstructorSqmFunction<>(
|
||||
this,
|
||||
this,
|
||||
arguments,
|
||||
impliedResultType,
|
||||
getArgumentsValidator(),
|
||||
getReturnTypeResolver(),
|
||||
queryEngine.getCriteriaBuilder(),
|
||||
getName()
|
||||
);
|
||||
}
|
||||
|
||||
protected static class ArrayConstructorSqmFunction<T> extends SelfRenderingSqmFunction<T> {
|
||||
public ArrayConstructorSqmFunction(
|
||||
OracleArrayConstructorFunction descriptor,
|
||||
FunctionRenderingSupport renderingSupport,
|
||||
List<? extends SqmTypedNode<?>> arguments,
|
||||
ReturnableType<T> impliedResultType,
|
||||
ArgumentsValidator argumentsValidator,
|
||||
FunctionReturnTypeResolver returnTypeResolver,
|
||||
NodeBuilder nodeBuilder,
|
||||
String name) {
|
||||
super(
|
||||
descriptor,
|
||||
renderingSupport,
|
||||
arguments,
|
||||
impliedResultType,
|
||||
argumentsValidator,
|
||||
returnTypeResolver,
|
||||
nodeBuilder,
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
|
||||
final ReturnableType<?> resultType = resolveResultType( walker );
|
||||
|
||||
List<SqlAstNode> arguments = resolveSqlAstArguments( getArguments(), walker );
|
||||
if ( getArgumentsValidator() != null ) {
|
||||
getArgumentsValidator().validateSqlTypes( arguments, getFunctionName() );
|
||||
}
|
||||
if ( resultType == null ) {
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
if ( returnType == null ) {
|
||||
throw new SemanticException(
|
||||
"Oracle array constructor emulation requires knowledge about the return type, but resolved return type could not be determined"
|
||||
);
|
||||
}
|
||||
final DomainType<?> type = resultType.getSqmType();
|
||||
final DomainType<?> type = returnType.getSqmType();
|
||||
if ( !( type instanceof BasicPluralType<?, ?> ) ) {
|
||||
throw new SemanticException(
|
||||
"Oracle array constructor emulation requires a basic plural return type, but resolved return type was: " + type
|
||||
);
|
||||
}
|
||||
final BasicPluralType<?, ?> pluralType = (BasicPluralType<?, ?>) type;
|
||||
final TypeConfiguration typeConfiguration = walker.getCreationContext().getSessionFactory().getTypeConfiguration();
|
||||
final DdlTypeRegistry ddlTypeRegistry = typeConfiguration.getDdlTypeRegistry();
|
||||
final DdlType ddlType = ddlTypeRegistry.getDescriptor(
|
||||
pluralType.getJdbcType().getDdlTypeCode()
|
||||
);
|
||||
final String arrayTypeName = ddlType.getCastTypeName( Size.nil(), pluralType, ddlTypeRegistry );
|
||||
return new SelfRenderingFunctionSqlAstExpression(
|
||||
getFunctionName(),
|
||||
getRenderingSupport(),
|
||||
arguments,
|
||||
resultType,
|
||||
getMappingModelExpressible( walker, resultType, arguments )
|
||||
) {
|
||||
@Override
|
||||
public void renderToSql(
|
||||
SqlAppender sqlAppender,
|
||||
SqlAstTranslator<?> walker,
|
||||
SessionFactoryImplementor sessionFactory) {
|
||||
final String arrayTypeName = DdlTypeHelper.getCastTypeName( pluralType, walker );
|
||||
sqlAppender.appendSql( arrayTypeName );
|
||||
final List<? extends SqlAstNode> arguments = getArguments();
|
||||
final int size = arguments.size();
|
||||
final int size = sqlAstArguments.size();
|
||||
if ( size == 0 ) {
|
||||
sqlAppender.append( '(' );
|
||||
}
|
||||
else {
|
||||
char separator = '(';
|
||||
for ( int i = 0; i < size; i++ ) {
|
||||
SqlAstNode argument = arguments.get( i );
|
||||
SqlAstNode argument = sqlAstArguments.get( i );
|
||||
sqlAppender.append( separator );
|
||||
argument.accept( walker );
|
||||
separator = ',';
|
||||
|
@ -131,7 +57,4 @@ public class OracleArrayConstructorFunction extends ArrayConstructorFunction {
|
|||
}
|
||||
sqlAppender.append( ')' );
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect.function.array;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
public class OracleArrayContainsAllFunction extends AbstractArrayContainsQuantifiedFunction {
|
||||
|
||||
private final boolean nullable;
|
||||
|
||||
public OracleArrayContainsAllFunction(TypeConfiguration typeConfiguration, boolean nullable) {
|
||||
super( "array_contains_all", typeConfiguration );
|
||||
this.nullable = nullable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final String arrayTypeName = DdlTypeHelper.getTypeName( haystackExpression.getExpressionType(), walker );
|
||||
sqlAppender.appendSql( arrayTypeName );
|
||||
sqlAppender.append( "_contains_all(" );
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
sqlAstArguments.get( 1 ).accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
sqlAppender.append( nullable ? "1" : "0" );
|
||||
sqlAppender.append( ")>0" );
|
||||
}
|
||||
|
||||
}
|
|
@ -8,46 +8,49 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
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.BasicPluralType;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
public class OracleArrayContainsFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
public class OracleArrayContainsFunction extends AbstractArrayContainsFunction {
|
||||
|
||||
public OracleArrayContainsFunction(TypeConfiguration typeConfiguration) {
|
||||
super(
|
||||
"array_contains",
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 2 ),
|
||||
ArrayAndElementArgumentValidator.DEFAULT_INSTANCE
|
||||
),
|
||||
StandardFunctionReturnTypeResolvers.invariant( typeConfiguration.standardBasicTypeForJavaType( Boolean.class ) ),
|
||||
ArrayAndElementArgumentTypeResolver.DEFAULT_INSTANCE
|
||||
);
|
||||
public OracleArrayContainsFunction(boolean nullable, TypeConfiguration typeConfiguration) {
|
||||
super( nullable, 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 );
|
||||
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final Expression needleExpression = (Expression) sqlAstArguments.get( 1 );
|
||||
final JdbcMappingContainer needleTypeContainer = needleExpression.getExpressionType();
|
||||
final JdbcMapping needleType = needleTypeContainer == null ? null : needleTypeContainer.getSingleJdbcMapping();
|
||||
final String arrayTypeName = DdlTypeHelper.getTypeName( haystackExpression.getExpressionType(), walker );
|
||||
sqlAppender.appendSql( arrayTypeName );
|
||||
sqlAppender.append( "_position(" );
|
||||
arrayExpression.accept( walker );
|
||||
if ( needleType == null || needleType instanceof BasicPluralType<?, ?> ) {
|
||||
sqlAppender.append( "_contains(" );
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
sqlAstArguments.get( 1 ).accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
sqlAppender.append( nullable ? "1" : "0" );
|
||||
sqlAppender.append( ")>0" );
|
||||
}
|
||||
else {
|
||||
sqlAppender.append( "_position(" );
|
||||
haystackExpression.accept( walker );
|
||||
sqlAppender.append( ',' );
|
||||
needleExpression.accept( walker );
|
||||
sqlAppender.append( ")>0" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgumentListSignature() {
|
||||
return "(ARRAY array, OBJECT element)";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* 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.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
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 OracleArrayContainsNullFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||
|
||||
public OracleArrayContainsNullFunction(TypeConfiguration typeConfiguration) {
|
||||
super(
|
||||
"array_contains_null",
|
||||
StandardArgumentsValidators.composite(
|
||||
StandardArgumentsValidators.exactly( 1 ),
|
||||
ArrayArgumentValidator.DEFAULT_INSTANCE
|
||||
),
|
||||
StandardFunctionReturnTypeResolvers.invariant( typeConfiguration.standardBasicTypeForJavaType( Boolean.class ) ),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression arrayExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final String arrayTypeName = DdlTypeHelper.getTypeName( arrayExpression.getExpressionType(), walker );
|
||||
sqlAppender.appendSql( arrayTypeName );
|
||||
sqlAppender.append( "_position(" );
|
||||
arrayExpression.accept( walker );
|
||||
sqlAppender.append( ",null)>0" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArgumentListSignature() {
|
||||
return "(ARRAY array)";
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
@ -25,6 +26,7 @@ public class OracleArrayGetFunction extends ArrayGetUnnestFunction {
|
|||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final String arrayTypeName = DdlTypeHelper.getTypeName(
|
||||
( (Expression) sqlAstArguments.get( 0 ) ).getExpressionType(),
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function.array;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
|
@ -35,6 +36,7 @@ public class OracleArrayLengthFunction extends AbstractSqmSelfRenderingFunctionD
|
|||
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 );
|
||||
|
|
|
@ -8,25 +8,24 @@ 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 OracleArrayOverlapsFunction extends AbstractArrayContainsQuantifiedFunction {
|
||||
|
||||
private final boolean nullable;
|
||||
public class OracleArrayOverlapsFunction extends AbstractArrayOverlapsFunction {
|
||||
|
||||
public OracleArrayOverlapsFunction(TypeConfiguration typeConfiguration, boolean nullable) {
|
||||
super( "array_overlaps", typeConfiguration );
|
||||
this.nullable = nullable;
|
||||
super( nullable, typeConfiguration );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(
|
||||
SqlAppender sqlAppender,
|
||||
List<? extends SqlAstNode> sqlAstArguments,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final Expression haystackExpression = (Expression) sqlAstArguments.get( 0 );
|
||||
final String arrayTypeName = DdlTypeHelper.getTypeName( haystackExpression.getExpressionType(), walker );
|
||||
|
|
|
@ -8,6 +8,7 @@ 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;
|
||||
|
@ -24,6 +25,7 @@ public class OracleArrayPositionFunction extends AbstractArrayPositionFunction {
|
|||
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 );
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue