HHH-10463 Implement function argument type inference
This commit is contained in:
parent
260c738a5a
commit
dc6ad33cfc
|
@ -173,7 +173,8 @@ public class CacheDialect extends Dialect {
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
||||||
"$find(?2,?1)",
|
"$find(?2,?1)",
|
||||||
"$find(?2,?1,?3)",
|
"$find(?2,?1,?3)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER,
|
||||||
|
queryEngine.getTypeConfiguration()
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
functionFactory.bitLength_pattern( "($length(?1)*8)" );
|
functionFactory.bitLength_pattern( "($length(?1)*8)" );
|
||||||
|
|
||||||
|
|
|
@ -284,7 +284,8 @@ public class FirebirdDialect extends Dialect {
|
||||||
integerType,
|
integerType,
|
||||||
"position(?1 in ?2)",
|
"position(?1 in ?2)",
|
||||||
"position(?1,?2,?3)",
|
"position(?1,?2,?3)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER,
|
||||||
|
queryEngine.getTypeConfiguration()
|
||||||
).setArgumentListSignature( "(pattern, string[, start])" );
|
).setArgumentListSignature( "(pattern, string[, start])" );
|
||||||
functionRegistry.namedDescriptorBuilder( "ascii_val" )
|
functionRegistry.namedDescriptorBuilder( "ascii_val" )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
|
|
|
@ -288,7 +288,8 @@ public class IngresDialect extends Dialect {
|
||||||
integerType,
|
integerType,
|
||||||
"position(?1 in ?2)",
|
"position(?1 in ?2)",
|
||||||
"(position(?1 in substring(?2 from ?3))+(?3)-1)",
|
"(position(?1 in substring(?2 from ?3))+(?3)-1)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER,
|
||||||
|
queryEngine.getTypeConfiguration()
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().registerPattern( "extract", "date_part('?1',?2)", integerType );
|
queryEngine.getSqmFunctionRegistry().registerPattern( "extract", "date_part('?1',?2)", integerType );
|
||||||
|
|
|
@ -168,7 +168,8 @@ public class MaxDBDialect extends Dialect {
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
integerType, "index(?2,?1)", "index(?2,?1,?3)",
|
integerType, "index(?2,?1)", "index(?2,?1,?3)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER,
|
||||||
|
queryEngine.getTypeConfiguration()
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -277,21 +277,24 @@ public class SQLiteDialect extends Dialect {
|
||||||
integerType,
|
integerType,
|
||||||
"instr(?2,?1)",
|
"instr(?2,?1)",
|
||||||
"instr(?2,?1,?3)",
|
"instr(?2,?1,?3)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER,
|
||||||
|
queryEngine.getTypeConfiguration()
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"lpad",
|
"lpad",
|
||||||
stringType,
|
stringType,
|
||||||
"(substr(replace(hex(zeroblob(?2)),'00',' '),1,?2-length(?1))||?1)",
|
"(substr(replace(hex(zeroblob(?2)),'00',' '),1,?2-length(?1))||?1)",
|
||||||
"(substr(replace(hex(zeroblob(?2)),'00',?3),1,?2-length(?1))||?1)",
|
"(substr(replace(hex(zeroblob(?2)),'00',?3),1,?2-length(?1))||?1)",
|
||||||
STRING, INTEGER, STRING
|
STRING, INTEGER, STRING,
|
||||||
|
queryEngine.getTypeConfiguration()
|
||||||
).setArgumentListSignature("(string, length[, padding])");
|
).setArgumentListSignature("(string, length[, padding])");
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"rpad",
|
"rpad",
|
||||||
stringType,
|
stringType,
|
||||||
"(?1||substr(replace(hex(zeroblob(?2)),'00',' '),1,?2-length(?1)))",
|
"(?1||substr(replace(hex(zeroblob(?2)),'00',' '),1,?2-length(?1)))",
|
||||||
"(?1||substr(replace(hex(zeroblob(?2)),'00',?3),1,?2-length(?1)))",
|
"(?1||substr(replace(hex(zeroblob(?2)),'00',?3),1,?2-length(?1)))",
|
||||||
STRING, INTEGER, STRING
|
STRING, INTEGER, STRING,
|
||||||
|
queryEngine.getTypeConfiguration()
|
||||||
).setArgumentListSignature("(string, length[, padding])");
|
).setArgumentListSignature("(string, length[, padding])");
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder("format", "strftime")
|
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder("format", "strftime")
|
||||||
|
|
|
@ -168,7 +168,8 @@ public class TimesTenDialect extends Dialect {
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
||||||
"instr(?2,?1)",
|
"instr(?2,?1)",
|
||||||
"instr(?2,?1,?3)",
|
"instr(?2,?1,?3)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER,
|
||||||
|
queryEngine.getTypeConfiguration()
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ import java.util.regex.Pattern;
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstract base class for SAP HANA dialects.
|
* An abstract base class for SAP HANA dialects.
|
||||||
|
@ -274,13 +275,15 @@ public abstract class AbstractHANADialect extends Dialect {
|
||||||
@Override
|
@Override
|
||||||
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
||||||
super.initializeFunctionRegistry( queryEngine );
|
super.initializeFunctionRegistry( queryEngine );
|
||||||
|
final TypeConfiguration typeConfiguration = queryEngine.getTypeConfiguration();
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
||||||
"locate(?2,?1)",
|
"locate(?2,?1)",
|
||||||
"locate(?2,?1,?3)",
|
"locate(?2,?1,?3)",
|
||||||
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER
|
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER,
|
||||||
|
typeConfiguration
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
|
|
||||||
CommonFunctionFactory functionFactory = new CommonFunctionFactory(queryEngine);
|
CommonFunctionFactory functionFactory = new CommonFunctionFactory(queryEngine);
|
||||||
|
@ -317,7 +320,7 @@ public abstract class AbstractHANADialect extends Dialect {
|
||||||
functionFactory.hypotheticalOrderedSetAggregates_windowEmulation();
|
functionFactory.hypotheticalOrderedSetAggregates_windowEmulation();
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().register( "timestampadd",
|
queryEngine.getSqmFunctionRegistry().register( "timestampadd",
|
||||||
new IntegralTimestampaddFunction( this, queryEngine.getTypeConfiguration() ) );
|
new IntegralTimestampaddFunction( this, typeConfiguration ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -142,7 +142,6 @@ public abstract class AbstractTransactSQLDialect extends Dialect {
|
||||||
functionFactory.yearMonthDay();
|
functionFactory.yearMonthDay();
|
||||||
functionFactory.ascii();
|
functionFactory.ascii();
|
||||||
functionFactory.chr_char();
|
functionFactory.chr_char();
|
||||||
functionFactory.concat_plusOperator();
|
|
||||||
functionFactory.trim1();
|
functionFactory.trim1();
|
||||||
functionFactory.repeat_replicate();
|
functionFactory.repeat_replicate();
|
||||||
functionFactory.characterLength_len();
|
functionFactory.characterLength_len();
|
||||||
|
|
|
@ -160,6 +160,7 @@ import org.hibernate.type.descriptor.jdbc.NCharJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.NClobJdbcType;
|
import org.hibernate.type.descriptor.jdbc.NClobJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.NVarcharJdbcType;
|
import org.hibernate.type.descriptor.jdbc.NVarcharJdbcType;
|
||||||
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
|
@ -769,7 +770,8 @@ public abstract class Dialect implements ConversionContext {
|
||||||
* same names.
|
* same names.
|
||||||
*/
|
*/
|
||||||
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
||||||
final BasicTypeRegistry basicTypeRegistry = queryEngine.getTypeConfiguration().getBasicTypeRegistry();
|
final TypeConfiguration typeConfiguration = queryEngine.getTypeConfiguration();
|
||||||
|
final BasicTypeRegistry basicTypeRegistry = typeConfiguration.getBasicTypeRegistry();
|
||||||
final BasicType<Date> timestampType = basicTypeRegistry.resolve( StandardBasicTypes.TIMESTAMP );
|
final BasicType<Date> timestampType = basicTypeRegistry.resolve( StandardBasicTypes.TIMESTAMP );
|
||||||
final BasicType<Date> dateType = basicTypeRegistry.resolve( StandardBasicTypes.DATE );
|
final BasicType<Date> dateType = basicTypeRegistry.resolve( StandardBasicTypes.DATE );
|
||||||
final BasicType<Date> timeType = basicTypeRegistry.resolve( StandardBasicTypes.TIME );
|
final BasicType<Date> timeType = basicTypeRegistry.resolve( StandardBasicTypes.TIME );
|
||||||
|
@ -842,20 +844,20 @@ public abstract class Dialect implements ConversionContext {
|
||||||
//define it here as an alias for locate()
|
//define it here as an alias for locate()
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().register( "position",
|
queryEngine.getSqmFunctionRegistry().register( "position",
|
||||||
new LocatePositionEmulation( queryEngine.getTypeConfiguration() ) );
|
new LocatePositionEmulation( typeConfiguration ) );
|
||||||
|
|
||||||
//very few databases support ANSI-style overlay() function, so emulate
|
//very few databases support ANSI-style overlay() function, so emulate
|
||||||
//it here in terms of either insert() or concat()/substring()
|
//it here in terms of either insert() or concat()/substring()
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().register( "overlay",
|
queryEngine.getSqmFunctionRegistry().register( "overlay",
|
||||||
new InsertSubstringOverlayEmulation( queryEngine.getTypeConfiguration(), false ) );
|
new InsertSubstringOverlayEmulation( typeConfiguration, false ) );
|
||||||
|
|
||||||
//ANSI SQL trim() function is supported on almost all of the databases
|
//ANSI SQL trim() function is supported on almost all of the databases
|
||||||
//we care about, but on some it must be emulated using ltrim(), rtrim(),
|
//we care about, but on some it must be emulated using ltrim(), rtrim(),
|
||||||
//and replace()
|
//and replace()
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().register( "trim",
|
queryEngine.getSqmFunctionRegistry().register( "trim",
|
||||||
new TrimFunction( this, queryEngine.getTypeConfiguration() ) );
|
new TrimFunction( this, typeConfiguration ) );
|
||||||
|
|
||||||
//ANSI SQL cast() function is supported on the databases we care most
|
//ANSI SQL cast() function is supported on the databases we care most
|
||||||
//about but in certain cases it doesn't allow some useful typecasts,
|
//about but in certain cases it doesn't allow some useful typecasts,
|
||||||
|
@ -883,7 +885,7 @@ public abstract class Dialect implements ConversionContext {
|
||||||
//a very dialect-specific way
|
//a very dialect-specific way
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().register( "extract",
|
queryEngine.getSqmFunctionRegistry().register( "extract",
|
||||||
new ExtractFunction( this ) );
|
new ExtractFunction( this, typeConfiguration ) );
|
||||||
|
|
||||||
//comparison functions supported on most databases, emulated on others
|
//comparison functions supported on most databases, emulated on others
|
||||||
//using a case expression
|
//using a case expression
|
||||||
|
@ -905,13 +907,13 @@ public abstract class Dialect implements ConversionContext {
|
||||||
//pad() is a function we've designed to look like ANSI trim()
|
//pad() is a function we've designed to look like ANSI trim()
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().register( "pad",
|
queryEngine.getSqmFunctionRegistry().register( "pad",
|
||||||
new LpadRpadPadEmulation( queryEngine.getTypeConfiguration() ) );
|
new LpadRpadPadEmulation( typeConfiguration ) );
|
||||||
|
|
||||||
//legacy Hibernate convenience function for casting to string, defined
|
//legacy Hibernate convenience function for casting to string, defined
|
||||||
//here as an alias for cast(arg as String)
|
//here as an alias for cast(arg as String)
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().register( "str",
|
queryEngine.getSqmFunctionRegistry().register( "str",
|
||||||
new CastStrEmulation( queryEngine.getTypeConfiguration() ) );
|
new CastStrEmulation( typeConfiguration ) );
|
||||||
|
|
||||||
//format() function for datetimes, emulated on many databases using the
|
//format() function for datetimes, emulated on many databases using the
|
||||||
//Oracle-style to_char() function, and on others using their native
|
//Oracle-style to_char() function, and on others using their native
|
||||||
|
@ -923,9 +925,9 @@ public abstract class Dialect implements ConversionContext {
|
||||||
//since there is a great variety of different ways to emulate them
|
//since there is a great variety of different ways to emulate them
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().register( "timestampadd",
|
queryEngine.getSqmFunctionRegistry().register( "timestampadd",
|
||||||
new TimestampaddFunction( this ) );
|
new TimestampaddFunction( this, typeConfiguration ) );
|
||||||
queryEngine.getSqmFunctionRegistry().register( "timestampdiff",
|
queryEngine.getSqmFunctionRegistry().register( "timestampdiff",
|
||||||
new TimestampdiffFunction( this, queryEngine.getTypeConfiguration() ) );
|
new TimestampdiffFunction( this, typeConfiguration ) );
|
||||||
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "dateadd", "timestampadd" );
|
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "dateadd", "timestampadd" );
|
||||||
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "datediff", "timestampdiff" );
|
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "datediff", "timestampdiff" );
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.dialect.temptable.TemporaryTableKind;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
|
||||||
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.ANY;
|
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.ANY;
|
||||||
|
|
||||||
|
@ -102,20 +103,22 @@ public class HANAColumnStoreDialect extends AbstractHANADialect {
|
||||||
@Override
|
@Override
|
||||||
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
||||||
super.initializeFunctionRegistry( queryEngine );
|
super.initializeFunctionRegistry( queryEngine );
|
||||||
|
final TypeConfiguration typeConfiguration = queryEngine.getTypeConfiguration();
|
||||||
|
|
||||||
// full-text search functions
|
// full-text search functions
|
||||||
queryEngine.getSqmFunctionRegistry().registerNamed(
|
queryEngine.getSqmFunctionRegistry().registerNamed(
|
||||||
"score",
|
"score",
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.DOUBLE )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.DOUBLE )
|
||||||
);
|
);
|
||||||
queryEngine.getSqmFunctionRegistry().registerNamed( "snippets" );
|
queryEngine.getSqmFunctionRegistry().registerNamed( "snippets" );
|
||||||
queryEngine.getSqmFunctionRegistry().registerNamed( "highlighted" );
|
queryEngine.getSqmFunctionRegistry().registerNamed( "highlighted" );
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"contains",
|
"contains",
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN ),
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN ),
|
||||||
"contains(?1,?2)",
|
"contains(?1,?2)",
|
||||||
"contains(?1,?2,?3)",
|
"contains(?1,?2,?3)",
|
||||||
ANY, ANY, ANY
|
ANY, ANY, ANY,
|
||||||
|
typeConfiguration
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,8 @@ import static org.hibernate.query.sqm.TemporalUnit.SECOND;
|
||||||
import static org.hibernate.query.sqm.TemporalUnit.YEAR;
|
import static org.hibernate.query.sqm.TemporalUnit.YEAR;
|
||||||
|
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import static org.hibernate.type.SqlTypes.*;
|
import static org.hibernate.type.SqlTypes.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,6 +138,7 @@ public class OracleDialect extends Dialect {
|
||||||
@Override
|
@Override
|
||||||
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
public void initializeFunctionRegistry(QueryEngine queryEngine) {
|
||||||
super.initializeFunctionRegistry( queryEngine );
|
super.initializeFunctionRegistry( queryEngine );
|
||||||
|
final TypeConfiguration typeConfiguration = queryEngine.getTypeConfiguration();
|
||||||
|
|
||||||
CommonFunctionFactory functionFactory = new CommonFunctionFactory(queryEngine);
|
CommonFunctionFactory functionFactory = new CommonFunctionFactory(queryEngine);
|
||||||
functionFactory.cosh();
|
functionFactory.cosh();
|
||||||
|
@ -185,10 +188,11 @@ public class OracleDialect extends Dialect {
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
||||||
"instr(?2,?1)",
|
"instr(?2,?1)",
|
||||||
"instr(?2,?1,?3)",
|
"instr(?2,?1,?3)",
|
||||||
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER
|
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER,
|
||||||
|
typeConfiguration
|
||||||
).setArgumentListSignature("(pattern, string[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
// The within group clause became optional in 18
|
// The within group clause became optional in 18
|
||||||
if ( getVersion().isSameOrAfter( 18 ) ) {
|
if ( getVersion().isSameOrAfter( 18 ) ) {
|
||||||
|
@ -203,7 +207,7 @@ public class OracleDialect extends Dialect {
|
||||||
// Oracle has a regular aggregate function named stats_mode
|
// Oracle has a regular aggregate function named stats_mode
|
||||||
queryEngine.getSqmFunctionRegistry().register(
|
queryEngine.getSqmFunctionRegistry().register(
|
||||||
"mode",
|
"mode",
|
||||||
new ModeStatsModeEmulation( queryEngine.getTypeConfiguration() )
|
new ModeStatsModeEmulation( typeConfiguration )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,9 @@ import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescript
|
||||||
import org.hibernate.query.sqm.function.FunctionKind;
|
import org.hibernate.query.sqm.function.FunctionKind;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
@ -49,7 +51,8 @@ public class AvgFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 1 ), NUMERIC ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 1 ), NUMERIC ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.DOUBLE )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.DOUBLE )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, NUMERIC )
|
||||||
);
|
);
|
||||||
this.defaultArgumentRenderingMode = defaultArgumentRenderingMode;
|
this.defaultArgumentRenderingMode = defaultArgumentRenderingMode;
|
||||||
doubleType = typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.DOUBLE );
|
doubleType = typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.DOUBLE );
|
||||||
|
@ -80,8 +83,10 @@ public class AvgFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
arg = (Expression) sqlAstArguments.get( 0 );
|
arg = (Expression) sqlAstArguments.get( 0 );
|
||||||
}
|
}
|
||||||
if ( caseWrapper ) {
|
if ( caseWrapper ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( "case when " );
|
sqlAppender.appendSql( "case when " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( " then " );
|
sqlAppender.appendSql( " then " );
|
||||||
renderArgument( sqlAppender, translator, arg );
|
renderArgument( sqlAppender, translator, arg );
|
||||||
sqlAppender.appendSql( " else null end)" );
|
sqlAppender.appendSql( " else null end)" );
|
||||||
|
@ -90,9 +95,11 @@ public class AvgFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
renderArgument( sqlAppender, translator, arg );
|
renderArgument( sqlAppender, translator, arg );
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
if ( filter != null ) {
|
if ( filter != null ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( " filter (where " );
|
sqlAppender.appendSql( " filter (where " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
@ -33,7 +34,8 @@ public class CaseLeastGreatestEmulation
|
||||||
super(
|
super(
|
||||||
least ? "least" : "greatest",
|
least ? "least" : "greatest",
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.min( 2 ), COMPARABLE, COMPARABLE ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.min( 2 ), COMPARABLE, COMPARABLE ),
|
||||||
StandardFunctionReturnTypeResolvers.useFirstNonNull()
|
StandardFunctionReturnTypeResolvers.useFirstNonNull(),
|
||||||
|
StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE
|
||||||
);
|
);
|
||||||
this.operator = least ? "<=" : ">=";
|
this.operator = least ? "<=" : ">=";
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||||
import org.hibernate.query.sqm.CastType;
|
import org.hibernate.query.sqm.CastType;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
@ -38,7 +39,8 @@ public class CastFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
super(
|
super(
|
||||||
"cast",
|
"cast",
|
||||||
StandardArgumentsValidators.exactly( 2 ),
|
StandardArgumentsValidators.exactly( 2 ),
|
||||||
StandardFunctionReturnTypeResolvers.useArgType( 2 )
|
StandardFunctionReturnTypeResolvers.useArgType( 2 ),
|
||||||
|
StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE
|
||||||
);
|
);
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
this.booleanCastType = getBooleanCastType( preferredSqlTypeCodeForBoolean );
|
this.booleanCastType = getBooleanCastType( preferredSqlTypeCodeForBoolean );
|
||||||
|
|
|
@ -37,7 +37,8 @@ public class CastStrEmulation
|
||||||
StandardArgumentsValidators.exactly( 1 ),
|
StandardArgumentsValidators.exactly( 1 ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ public class CastStrEmulation
|
||||||
String name,
|
String name,
|
||||||
ArgumentsValidator argumentsValidator,
|
ArgumentsValidator argumentsValidator,
|
||||||
FunctionReturnTypeResolver returnTypeResolver) {
|
FunctionReturnTypeResolver returnTypeResolver) {
|
||||||
super( name, argumentsValidator, returnTypeResolver );
|
super( name, argumentsValidator, returnTypeResolver, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.query.sqm.CastType;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
|
@ -42,10 +43,11 @@ public class CastingConcatFunction extends AbstractSqmSelfRenderingFunctionDescr
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
super(
|
super(
|
||||||
"concat",
|
"concat",
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.min( 1 ), STRING ),
|
StandardArgumentsValidators.min( 1 ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.impliedOrInvariant( typeConfiguration, STRING )
|
||||||
);
|
);
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
this.concatOperator = concatOperator;
|
this.concatOperator = concatOperator;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
@ -25,7 +26,8 @@ public class CoalesceIfnullEmulation
|
||||||
public CoalesceIfnullEmulation() {
|
public CoalesceIfnullEmulation() {
|
||||||
super(
|
super(
|
||||||
"ifnull",
|
"ifnull",
|
||||||
StandardArgumentsValidators.exactly( 2 )
|
StandardArgumentsValidators.exactly( 2 ),
|
||||||
|
StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
import org.hibernate.type.BasicTypeRegistry;
|
import org.hibernate.type.BasicTypeRegistry;
|
||||||
|
@ -454,14 +455,16 @@ public class CommonFunctionFactory {
|
||||||
stringType,
|
stringType,
|
||||||
"lpad(?1,?2,' ')",
|
"lpad(?1,?2,' ')",
|
||||||
"lpad(?1,?2,?3)",
|
"lpad(?1,?2,?3)",
|
||||||
STRING, INTEGER, STRING
|
STRING, INTEGER, STRING,
|
||||||
|
typeConfiguration
|
||||||
).setArgumentListSignature( "(string, length[, padding])" );
|
).setArgumentListSignature( "(string, length[, padding])" );
|
||||||
functionRegistry.registerBinaryTernaryPattern(
|
functionRegistry.registerBinaryTernaryPattern(
|
||||||
"rpad",
|
"rpad",
|
||||||
stringType,
|
stringType,
|
||||||
"rpad(?1,?2,' ')",
|
"rpad(?1,?2,' ')",
|
||||||
"rpad(?1,?2,?3)",
|
"rpad(?1,?2,?3)",
|
||||||
STRING, INTEGER, STRING
|
STRING, INTEGER, STRING,
|
||||||
|
typeConfiguration
|
||||||
).setArgumentListSignature( "(string, length[, padding])" );
|
).setArgumentListSignature( "(string, length[, padding])" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,14 +477,16 @@ public class CommonFunctionFactory {
|
||||||
stringType,
|
stringType,
|
||||||
"(space(?2-len(?1))+?1)",
|
"(space(?2-len(?1))+?1)",
|
||||||
"(replicate(?3,?2-len(?1))+?1)",
|
"(replicate(?3,?2-len(?1))+?1)",
|
||||||
STRING, INTEGER, STRING
|
STRING, INTEGER, STRING,
|
||||||
|
typeConfiguration
|
||||||
).setArgumentListSignature( "(string, length[, padding])" );
|
).setArgumentListSignature( "(string, length[, padding])" );
|
||||||
functionRegistry.registerBinaryTernaryPattern(
|
functionRegistry.registerBinaryTernaryPattern(
|
||||||
"rpad",
|
"rpad",
|
||||||
stringType,
|
stringType,
|
||||||
"(?1+space(?2-len(?1)))",
|
"(?1+space(?2-len(?1)))",
|
||||||
"(?1+replicate(?3,?2-len(?1)))",
|
"(?1+replicate(?3,?2-len(?1)))",
|
||||||
STRING, INTEGER, STRING
|
STRING, INTEGER, STRING,
|
||||||
|
typeConfiguration
|
||||||
).setArgumentListSignature( "(string, length[, padding])" );
|
).setArgumentListSignature( "(string, length[, padding])" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,14 +496,16 @@ public class CommonFunctionFactory {
|
||||||
stringType,
|
stringType,
|
||||||
"(repeat(' ',?2-character_length(?1))||?1)",
|
"(repeat(' ',?2-character_length(?1))||?1)",
|
||||||
"(repeat(?3,?2-character_length(?1))||?1)",
|
"(repeat(?3,?2-character_length(?1))||?1)",
|
||||||
STRING, INTEGER, STRING
|
STRING, INTEGER, STRING,
|
||||||
|
typeConfiguration
|
||||||
).setArgumentListSignature( "(string, length[, padding])" );
|
).setArgumentListSignature( "(string, length[, padding])" );
|
||||||
functionRegistry.registerBinaryTernaryPattern(
|
functionRegistry.registerBinaryTernaryPattern(
|
||||||
"rpad",
|
"rpad",
|
||||||
stringType,
|
stringType,
|
||||||
"(?1||repeat(' ',?2-character_length(?1)))",
|
"(?1||repeat(' ',?2-character_length(?1)))",
|
||||||
"(?1||repeat(?3,?2-character_length(?1)))",
|
"(?1||repeat(?3,?2-character_length(?1)))",
|
||||||
STRING, INTEGER, STRING
|
STRING, INTEGER, STRING,
|
||||||
|
typeConfiguration
|
||||||
).setArgumentListSignature( "(string, length[, padding])" );
|
).setArgumentListSignature( "(string, length[, padding])" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,14 +518,16 @@ public class CommonFunctionFactory {
|
||||||
stringType,
|
stringType,
|
||||||
"lfill(?1,' ',?2)",
|
"lfill(?1,' ',?2)",
|
||||||
"lfill(?1,?3,?2)",
|
"lfill(?1,?3,?2)",
|
||||||
STRING, INTEGER, STRING
|
STRING, INTEGER, STRING,
|
||||||
|
typeConfiguration
|
||||||
).setArgumentListSignature( "(string, length[, padding])" );
|
).setArgumentListSignature( "(string, length[, padding])" );
|
||||||
functionRegistry.registerBinaryTernaryPattern(
|
functionRegistry.registerBinaryTernaryPattern(
|
||||||
"rpad",
|
"rpad",
|
||||||
stringType,
|
stringType,
|
||||||
"rfill(?1,' ',?2)",
|
"rfill(?1,' ',?2)",
|
||||||
"rfill(?1,?3,?2)",
|
"rfill(?1,?3,?2)",
|
||||||
STRING, INTEGER, STRING
|
STRING, INTEGER, STRING,
|
||||||
|
typeConfiguration
|
||||||
).setArgumentListSignature( "(string, length[, padding])" );
|
).setArgumentListSignature( "(string, length[, padding])" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,6 +615,7 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.namedDescriptorBuilder( "md5" )
|
functionRegistry.namedDescriptorBuilder( "md5" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,6 +623,7 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.namedDescriptorBuilder( "initcap" )
|
functionRegistry.namedDescriptorBuilder( "initcap" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,30 +649,35 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.namedDescriptorBuilder( "translate" )
|
functionRegistry.namedDescriptorBuilder( "translate" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
.setExactArgumentCount( 3 )
|
.setExactArgumentCount( 3 )
|
||||||
|
.setParameterTypes( STRING, STRING, STRING )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bitand() {
|
public void bitand() {
|
||||||
functionRegistry.namedDescriptorBuilder( "bitand" )
|
functionRegistry.namedDescriptorBuilder( "bitand" )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bitor() {
|
public void bitor() {
|
||||||
functionRegistry.namedDescriptorBuilder( "bitor" )
|
functionRegistry.namedDescriptorBuilder( "bitor" )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bitxor() {
|
public void bitxor() {
|
||||||
functionRegistry.namedDescriptorBuilder( "bitxor" )
|
functionRegistry.namedDescriptorBuilder( "bitxor" )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bitnot() {
|
public void bitnot() {
|
||||||
functionRegistry.namedDescriptorBuilder( "bitnot" )
|
functionRegistry.namedDescriptorBuilder( "bitnot" )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -671,21 +687,25 @@ public class CommonFunctionFactory {
|
||||||
public void bitandorxornot_bitAndOrXorNot() {
|
public void bitandorxornot_bitAndOrXorNot() {
|
||||||
functionRegistry.namedDescriptorBuilder( "bit_and" )
|
functionRegistry.namedDescriptorBuilder( "bit_and" )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.registerAlternateKey( "bitand", "bit_and" );
|
functionRegistry.registerAlternateKey( "bitand", "bit_and" );
|
||||||
|
|
||||||
functionRegistry.namedDescriptorBuilder( "bit_or" )
|
functionRegistry.namedDescriptorBuilder( "bit_or" )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.registerAlternateKey( "bitor", "bit_or" );
|
functionRegistry.registerAlternateKey( "bitor", "bit_or" );
|
||||||
|
|
||||||
functionRegistry.namedDescriptorBuilder( "bit_xor" )
|
functionRegistry.namedDescriptorBuilder( "bit_xor" )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.registerAlternateKey( "bitxor", "bit_xor" );
|
functionRegistry.registerAlternateKey( "bitxor", "bit_xor" );
|
||||||
|
|
||||||
functionRegistry.namedDescriptorBuilder( "bit_not" )
|
functionRegistry.namedDescriptorBuilder( "bit_not" )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.registerAlternateKey( "bitnot", "bit_not" );
|
functionRegistry.registerAlternateKey( "bitnot", "bit_not" );
|
||||||
}
|
}
|
||||||
|
@ -696,21 +716,25 @@ public class CommonFunctionFactory {
|
||||||
public void bitandorxornot_binAndOrXorNot() {
|
public void bitandorxornot_binAndOrXorNot() {
|
||||||
functionRegistry.namedDescriptorBuilder( "bin_and" )
|
functionRegistry.namedDescriptorBuilder( "bin_and" )
|
||||||
.setMinArgumentCount( 1 )
|
.setMinArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.registerAlternateKey( "bitand", "bin_and" );
|
functionRegistry.registerAlternateKey( "bitand", "bin_and" );
|
||||||
|
|
||||||
functionRegistry.namedDescriptorBuilder( "bin_or" )
|
functionRegistry.namedDescriptorBuilder( "bin_or" )
|
||||||
.setMinArgumentCount( 1 )
|
.setMinArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.registerAlternateKey( "bitor", "bin_or" );
|
functionRegistry.registerAlternateKey( "bitor", "bin_or" );
|
||||||
|
|
||||||
functionRegistry.namedDescriptorBuilder( "bin_xor" )
|
functionRegistry.namedDescriptorBuilder( "bin_xor" )
|
||||||
.setMinArgumentCount( 1 )
|
.setMinArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.registerAlternateKey( "bitxor", "bin_xor" );
|
functionRegistry.registerAlternateKey( "bitxor", "bin_xor" );
|
||||||
|
|
||||||
functionRegistry.namedDescriptorBuilder( "bin_not" )
|
functionRegistry.namedDescriptorBuilder( "bin_not" )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.registerAlternateKey( "bitnot", "bin_not" );
|
functionRegistry.registerAlternateKey( "bitnot", "bin_not" );
|
||||||
}
|
}
|
||||||
|
@ -721,18 +745,22 @@ public class CommonFunctionFactory {
|
||||||
public void bitandorxornot_operator() {
|
public void bitandorxornot_operator() {
|
||||||
functionRegistry.patternDescriptorBuilder( "bitand", "(?1&?2)" )
|
functionRegistry.patternDescriptorBuilder( "bitand", "(?1&?2)" )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
functionRegistry.patternDescriptorBuilder( "bitor", "(?1|?2)" )
|
functionRegistry.patternDescriptorBuilder( "bitor", "(?1|?2)" )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
functionRegistry.patternDescriptorBuilder( "bitxor", "(?1^?2)" )
|
functionRegistry.patternDescriptorBuilder( "bitxor", "(?1^?2)" )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
functionRegistry.patternDescriptorBuilder( "bitnot", "~?1" )
|
functionRegistry.patternDescriptorBuilder( "bitnot", "~?1" )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -742,10 +770,12 @@ public class CommonFunctionFactory {
|
||||||
public void bitAndOr() {
|
public void bitAndOr() {
|
||||||
functionRegistry.namedAggregateDescriptorBuilder( "bit_and" )
|
functionRegistry.namedAggregateDescriptorBuilder( "bit_and" )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
functionRegistry.namedAggregateDescriptorBuilder( "bit_or" )
|
functionRegistry.namedAggregateDescriptorBuilder( "bit_or" )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
//MySQL has it but how is that even useful?
|
//MySQL has it but how is that even useful?
|
||||||
|
@ -978,21 +1008,25 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.namedDescriptorBuilder( "to_number" )
|
functionRegistry.namedDescriptorBuilder( "to_number" )
|
||||||
//always 1 arg on HSQL and Cache, always 2 on Postgres
|
//always 1 arg on HSQL and Cache, always 2 on Postgres
|
||||||
.setArgumentCountBetween( 1, 3 )
|
.setArgumentCountBetween( 1, 3 )
|
||||||
|
.setParameterTypes( STRING, STRING, STRING )
|
||||||
.setInvariantType(doubleType)
|
.setInvariantType(doubleType)
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.namedDescriptorBuilder( "to_char" )
|
functionRegistry.namedDescriptorBuilder( "to_char" )
|
||||||
.setArgumentCountBetween( 1, 3 )
|
.setArgumentCountBetween( 1, 3 )
|
||||||
|
.setParameterTypes( ANY, STRING, STRING )
|
||||||
//always 2 args on HSQL and Postgres
|
//always 2 args on HSQL and Postgres
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.namedDescriptorBuilder( "to_date" )
|
functionRegistry.namedDescriptorBuilder( "to_date" )
|
||||||
//always 2 args on HSQL and Postgres
|
//always 2 args on HSQL and Postgres
|
||||||
.setArgumentCountBetween( 1, 3 )
|
.setArgumentCountBetween( 1, 3 )
|
||||||
|
.setParameterTypes( STRING, STRING, STRING )
|
||||||
.setInvariantType(dateType)
|
.setInvariantType(dateType)
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.namedDescriptorBuilder( "to_timestamp" )
|
functionRegistry.namedDescriptorBuilder( "to_timestamp" )
|
||||||
//always 2 args on HSQL and Postgres
|
//always 2 args on HSQL and Postgres
|
||||||
.setArgumentCountBetween( 1, 3 )
|
.setArgumentCountBetween( 1, 3 )
|
||||||
|
.setParameterTypes( STRING, STRING, STRING )
|
||||||
.setInvariantType(timestampType)
|
.setInvariantType(timestampType)
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
@ -1073,19 +1107,9 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.patternDescriptorBuilder( "concat", "(?1||?2...)" )
|
functionRegistry.patternDescriptorBuilder( "concat", "(?1||?2...)" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
.setMinArgumentCount( 1 )
|
.setMinArgumentCount( 1 )
|
||||||
.setParameterTypes(STRING)
|
.setArgumentTypeResolver(
|
||||||
.setArgumentListSignature( "(STRING string0[, STRING string1[, ...]])" )
|
StandardFunctionArgumentTypeResolvers.impliedOrInvariant( typeConfiguration, STRING )
|
||||||
.register();
|
)
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transact SQL-style
|
|
||||||
*/
|
|
||||||
public void concat_plusOperator() {
|
|
||||||
functionRegistry.patternDescriptorBuilder( "concat", "(?1+?2...)" )
|
|
||||||
.setInvariantType(stringType)
|
|
||||||
.setMinArgumentCount( 1 )
|
|
||||||
.setParameterTypes(STRING)
|
|
||||||
.setArgumentListSignature( "(STRING string0[, STRING string1[, ...]])" )
|
.setArgumentListSignature( "(STRING string0[, STRING string1[, ...]])" )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
@ -1297,6 +1321,7 @@ public class CommonFunctionFactory {
|
||||||
public void coalesce() {
|
public void coalesce() {
|
||||||
functionRegistry.namedDescriptorBuilder( "coalesce" )
|
functionRegistry.namedDescriptorBuilder( "coalesce" )
|
||||||
.setMinArgumentCount( 1 )
|
.setMinArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1306,6 +1331,7 @@ public class CommonFunctionFactory {
|
||||||
public void coalesce_value() {
|
public void coalesce_value() {
|
||||||
functionRegistry.namedDescriptorBuilder( "value" )
|
functionRegistry.namedDescriptorBuilder( "value" )
|
||||||
.setMinArgumentCount( 1 )
|
.setMinArgumentCount( 1 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.registerAlternateKey( "coalesce", "value" );
|
functionRegistry.registerAlternateKey( "coalesce", "value" );
|
||||||
}
|
}
|
||||||
|
@ -1313,6 +1339,7 @@ public class CommonFunctionFactory {
|
||||||
public void nullif() {
|
public void nullif() {
|
||||||
functionRegistry.namedDescriptorBuilder( "nullif" )
|
functionRegistry.namedDescriptorBuilder( "nullif" )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1420,7 +1447,8 @@ public class CommonFunctionFactory {
|
||||||
"locate",
|
"locate",
|
||||||
integerType,
|
integerType,
|
||||||
"position(?1 in ?2)", "(position(?1 in substring(?2 from ?3))+(?3)-1)",
|
"position(?1 in ?2)", "(position(?1 in substring(?2 from ?3))+(?3)-1)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER,
|
||||||
|
typeConfiguration
|
||||||
)
|
)
|
||||||
.setArgumentListSignature( "(STRING pattern, STRING string[, INTEGER start])" );
|
.setArgumentListSignature( "(STRING pattern, STRING string[, INTEGER start])" );
|
||||||
}
|
}
|
||||||
|
@ -1432,7 +1460,8 @@ public class CommonFunctionFactory {
|
||||||
"substring",
|
"substring",
|
||||||
stringType,
|
stringType,
|
||||||
"substring(?1 from ?2)", "substring(?1 from ?2 for ?3)",
|
"substring(?1 from ?2)", "substring(?1 from ?2 for ?3)",
|
||||||
STRING, INTEGER, INTEGER
|
STRING, INTEGER, INTEGER,
|
||||||
|
typeConfiguration
|
||||||
)
|
)
|
||||||
.setArgumentListSignature( "(STRING string{ from|,} INTEGER start[{ for|,} INTEGER length])" );
|
.setArgumentListSignature( "(STRING string{ from|,} INTEGER start[{ for|,} INTEGER length])" );
|
||||||
}
|
}
|
||||||
|
@ -1459,7 +1488,8 @@ public class CommonFunctionFactory {
|
||||||
stringType,
|
stringType,
|
||||||
"substring(?1,?2,len(?1)-?2+1)",
|
"substring(?1,?2,len(?1)-?2+1)",
|
||||||
"substring(?1,?2,?3)",
|
"substring(?1,?2,?3)",
|
||||||
STRING, INTEGER, INTEGER
|
STRING, INTEGER, INTEGER,
|
||||||
|
typeConfiguration
|
||||||
)
|
)
|
||||||
.setArgumentListSignature( "(STRING string{ from|,} INTEGER start[{ for|,} INTEGER length])" );
|
.setArgumentListSignature( "(STRING string{ from|,} INTEGER start[{ for|,} INTEGER length])" );
|
||||||
}
|
}
|
||||||
|
@ -1508,7 +1538,8 @@ public class CommonFunctionFactory {
|
||||||
stringType,
|
stringType,
|
||||||
"overlay(?1 placing ?2 from ?3)",
|
"overlay(?1 placing ?2 from ?3)",
|
||||||
"overlay(?1 placing ?2 from ?3 for ?4)",
|
"overlay(?1 placing ?2 from ?3 for ?4)",
|
||||||
STRING, STRING, INTEGER, INTEGER
|
STRING, STRING, INTEGER, INTEGER,
|
||||||
|
typeConfiguration
|
||||||
)
|
)
|
||||||
.setArgumentListSignature( "(string placing replacement from start[ for length])" );
|
.setArgumentListSignature( "(string placing replacement from start[ for length])" );
|
||||||
}
|
}
|
||||||
|
@ -1524,7 +1555,8 @@ public class CommonFunctionFactory {
|
||||||
//because DB2 doesn't like "length(?)"
|
//because DB2 doesn't like "length(?)"
|
||||||
"overlay(?1 placing ?2 from ?3 for character_length(?2))",
|
"overlay(?1 placing ?2 from ?3 for character_length(?2))",
|
||||||
"overlay(?1 placing ?2 from ?3 for ?4)",
|
"overlay(?1 placing ?2 from ?3 for ?4)",
|
||||||
STRING, STRING, INTEGER, INTEGER
|
STRING, STRING, INTEGER, INTEGER,
|
||||||
|
typeConfiguration
|
||||||
)
|
)
|
||||||
.setArgumentListSignature( "(string placing replacement from start[ for length])" );
|
.setArgumentListSignature( "(string placing replacement from start[ for length])" );
|
||||||
}
|
}
|
||||||
|
@ -1555,7 +1587,9 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.namedDescriptorBuilder( "concat" )
|
functionRegistry.namedDescriptorBuilder( "concat" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
.setMinArgumentCount( 1 )
|
.setMinArgumentCount( 1 )
|
||||||
.setParameterTypes(STRING)
|
.setArgumentTypeResolver(
|
||||||
|
StandardFunctionArgumentTypeResolvers.impliedOrInvariant( typeConfiguration, STRING )
|
||||||
|
)
|
||||||
.setArgumentListSignature( "(STRING string0[, STRING string1[, ...]])" )
|
.setArgumentListSignature( "(STRING string0[, STRING string1[, ...]])" )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
@ -1644,10 +1678,12 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.namedDescriptorBuilder( "least" )
|
functionRegistry.namedDescriptorBuilder( "least" )
|
||||||
.setMinArgumentCount( 2 )
|
.setMinArgumentCount( 2 )
|
||||||
.setParameterTypes(COMPARABLE, COMPARABLE)
|
.setParameterTypes(COMPARABLE, COMPARABLE)
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.namedDescriptorBuilder( "greatest" )
|
functionRegistry.namedDescriptorBuilder( "greatest" )
|
||||||
.setMinArgumentCount( 2 )
|
.setMinArgumentCount( 2 )
|
||||||
.setParameterTypes(COMPARABLE, COMPARABLE)
|
.setParameterTypes(COMPARABLE, COMPARABLE)
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1655,10 +1691,12 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.namedDescriptorBuilder( "least", "min" )
|
functionRegistry.namedDescriptorBuilder( "least", "min" )
|
||||||
.setMinArgumentCount( 2 )
|
.setMinArgumentCount( 2 )
|
||||||
.setParameterTypes(COMPARABLE, COMPARABLE)
|
.setParameterTypes(COMPARABLE, COMPARABLE)
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.namedDescriptorBuilder( "greatest", "max" )
|
functionRegistry.namedDescriptorBuilder( "greatest", "max" )
|
||||||
.setMinArgumentCount( 2 )
|
.setMinArgumentCount( 2 )
|
||||||
.setParameterTypes(COMPARABLE, COMPARABLE)
|
.setParameterTypes(COMPARABLE, COMPARABLE)
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1666,10 +1704,12 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.namedDescriptorBuilder( "least", "minvalue" )
|
functionRegistry.namedDescriptorBuilder( "least", "minvalue" )
|
||||||
.setMinArgumentCount( 2 )
|
.setMinArgumentCount( 2 )
|
||||||
.setParameterTypes(COMPARABLE, COMPARABLE)
|
.setParameterTypes(COMPARABLE, COMPARABLE)
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.namedDescriptorBuilder( "greatest", "maxvalue" )
|
functionRegistry.namedDescriptorBuilder( "greatest", "maxvalue" )
|
||||||
.setMinArgumentCount( 2 )
|
.setMinArgumentCount( 2 )
|
||||||
.setParameterTypes(COMPARABLE, COMPARABLE)
|
.setParameterTypes(COMPARABLE, COMPARABLE)
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1682,12 +1722,14 @@ public class CommonFunctionFactory {
|
||||||
.setArgumentRenderingMode( inferenceArgumentRenderingMode )
|
.setArgumentRenderingMode( inferenceArgumentRenderingMode )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
.setParameterTypes(COMPARABLE)
|
.setParameterTypes(COMPARABLE)
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
functionRegistry.namedAggregateDescriptorBuilder( "min" )
|
functionRegistry.namedAggregateDescriptorBuilder( "min" )
|
||||||
.setArgumentRenderingMode( inferenceArgumentRenderingMode )
|
.setArgumentRenderingMode( inferenceArgumentRenderingMode )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
.setParameterTypes(COMPARABLE)
|
.setParameterTypes(COMPARABLE)
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE )
|
||||||
.register();
|
.register();
|
||||||
|
|
||||||
functionRegistry.namedAggregateDescriptorBuilder( "sum" )
|
functionRegistry.namedAggregateDescriptorBuilder( "sum" )
|
||||||
|
@ -1835,26 +1877,43 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.namedWindowDescriptorBuilder( "lag" )
|
functionRegistry.namedWindowDescriptorBuilder( "lag" )
|
||||||
.setArgumentCountBetween( 1, 3 )
|
.setArgumentCountBetween( 1, 3 )
|
||||||
.setParameterTypes( ANY, INTEGER, ANY )
|
.setParameterTypes( ANY, INTEGER, ANY )
|
||||||
|
.setArgumentTypeResolver(
|
||||||
|
StandardFunctionArgumentTypeResolvers.composite(
|
||||||
|
StandardFunctionArgumentTypeResolvers.argumentsOrImplied( 2 ),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, INTEGER ),
|
||||||
|
StandardFunctionArgumentTypeResolvers.argumentsOrImplied( 0 )
|
||||||
|
)
|
||||||
|
)
|
||||||
.setArgumentListSignature( "ANY value[, INTEGER offset[, ANY default]]" )
|
.setArgumentListSignature( "ANY value[, INTEGER offset[, ANY default]]" )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.namedWindowDescriptorBuilder( "lead" )
|
functionRegistry.namedWindowDescriptorBuilder( "lead" )
|
||||||
.setArgumentCountBetween( 1, 3 )
|
.setArgumentCountBetween( 1, 3 )
|
||||||
.setParameterTypes( ANY, INTEGER, ANY )
|
.setParameterTypes( ANY, INTEGER, ANY )
|
||||||
|
.setArgumentTypeResolver(
|
||||||
|
StandardFunctionArgumentTypeResolvers.composite(
|
||||||
|
StandardFunctionArgumentTypeResolvers.argumentsOrImplied( 2 ),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, INTEGER ),
|
||||||
|
StandardFunctionArgumentTypeResolvers.argumentsOrImplied( 0 )
|
||||||
|
)
|
||||||
|
)
|
||||||
.setArgumentListSignature( "ANY value[, INTEGER offset[, ANY default]]" )
|
.setArgumentListSignature( "ANY value[, INTEGER offset[, ANY default]]" )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.namedWindowDescriptorBuilder( "first_value" )
|
functionRegistry.namedWindowDescriptorBuilder( "first_value" )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
.setParameterTypes( ANY )
|
.setParameterTypes( ANY )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE )
|
||||||
.setArgumentListSignature( "ANY value" )
|
.setArgumentListSignature( "ANY value" )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.namedWindowDescriptorBuilder( "last_value" )
|
functionRegistry.namedWindowDescriptorBuilder( "last_value" )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
.setParameterTypes( ANY )
|
.setParameterTypes( ANY )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE )
|
||||||
.setArgumentListSignature( "ANY value" )
|
.setArgumentListSignature( "ANY value" )
|
||||||
.register();
|
.register();
|
||||||
functionRegistry.namedWindowDescriptorBuilder( "nth_value" )
|
functionRegistry.namedWindowDescriptorBuilder( "nth_value" )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
.setParameterTypes( ANY, INTEGER )
|
.setParameterTypes( ANY, INTEGER )
|
||||||
|
.setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE )
|
||||||
.setArgumentListSignature( "ANY value, INTEGER nth" )
|
.setArgumentListSignature( "ANY value, INTEGER nth" )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
@ -1969,6 +2028,7 @@ public class CommonFunctionFactory {
|
||||||
public void crc32() {
|
public void crc32() {
|
||||||
functionRegistry.namedDescriptorBuilder( "crc32" )
|
functionRegistry.namedDescriptorBuilder( "crc32" )
|
||||||
.setInvariantType(integerType)
|
.setInvariantType(integerType)
|
||||||
|
.setParameterTypes( STRING )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
@ -1976,6 +2036,7 @@ public class CommonFunctionFactory {
|
||||||
public void sha1() {
|
public void sha1() {
|
||||||
functionRegistry.namedDescriptorBuilder( "sha1" )
|
functionRegistry.namedDescriptorBuilder( "sha1" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
|
.setParameterTypes( STRING )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
@ -1983,6 +2044,7 @@ public class CommonFunctionFactory {
|
||||||
public void sha2() {
|
public void sha2() {
|
||||||
functionRegistry.namedDescriptorBuilder( "sha2" )
|
functionRegistry.namedDescriptorBuilder( "sha2" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
|
.setParameterTypes( STRING, INTEGER )
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
@ -1990,6 +2052,7 @@ public class CommonFunctionFactory {
|
||||||
public void sha() {
|
public void sha() {
|
||||||
functionRegistry.namedDescriptorBuilder( "sha" )
|
functionRegistry.namedDescriptorBuilder( "sha" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
|
.setParameterTypes( STRING )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
@ -2156,6 +2219,7 @@ public class CommonFunctionFactory {
|
||||||
public void format_formatdatetime() {
|
public void format_formatdatetime() {
|
||||||
functionRegistry.namedDescriptorBuilder( "format", "formatdatetime" )
|
functionRegistry.namedDescriptorBuilder( "format", "formatdatetime" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
|
.setParameterTypes( TEMPORAL, STRING )
|
||||||
.setArgumentsValidator( formatValidator() )
|
.setArgumentsValidator( formatValidator() )
|
||||||
.setArgumentListSignature( "(TEMPORAL datetime as STRING pattern)" )
|
.setArgumentListSignature( "(TEMPORAL datetime as STRING pattern)" )
|
||||||
.register();
|
.register();
|
||||||
|
@ -2169,6 +2233,7 @@ public class CommonFunctionFactory {
|
||||||
public void format_toChar() {
|
public void format_toChar() {
|
||||||
functionRegistry.namedDescriptorBuilder( "format", "to_char" )
|
functionRegistry.namedDescriptorBuilder( "format", "to_char" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
|
.setParameterTypes( TEMPORAL, STRING )
|
||||||
.setArgumentsValidator( formatValidator() )
|
.setArgumentsValidator( formatValidator() )
|
||||||
.setArgumentListSignature( "(TEMPORAL datetime as STRING pattern)" )
|
.setArgumentListSignature( "(TEMPORAL datetime as STRING pattern)" )
|
||||||
.register();
|
.register();
|
||||||
|
@ -2182,6 +2247,7 @@ public class CommonFunctionFactory {
|
||||||
public void format_dateFormat() {
|
public void format_dateFormat() {
|
||||||
functionRegistry.namedDescriptorBuilder( "format", "date_format" )
|
functionRegistry.namedDescriptorBuilder( "format", "date_format" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
|
.setParameterTypes( TEMPORAL, STRING )
|
||||||
.setArgumentsValidator( formatValidator() )
|
.setArgumentsValidator( formatValidator() )
|
||||||
.setArgumentListSignature( "(TEMPORAL datetime as STRING pattern)" )
|
.setArgumentListSignature( "(TEMPORAL datetime as STRING pattern)" )
|
||||||
.register();
|
.register();
|
||||||
|
@ -2195,6 +2261,7 @@ public class CommonFunctionFactory {
|
||||||
public void format_toVarchar() {
|
public void format_toVarchar() {
|
||||||
functionRegistry.namedDescriptorBuilder( "format", "to_varchar" )
|
functionRegistry.namedDescriptorBuilder( "format", "to_varchar" )
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
|
.setParameterTypes( TEMPORAL, STRING )
|
||||||
.setArgumentsValidator( formatValidator() )
|
.setArgumentsValidator( formatValidator() )
|
||||||
.setArgumentListSignature( "(TEMPORAL datetime as STRING pattern)" )
|
.setArgumentListSignature( "(TEMPORAL datetime as STRING pattern)" )
|
||||||
.register();
|
.register();
|
||||||
|
@ -2223,7 +2290,7 @@ public class CommonFunctionFactory {
|
||||||
functionRegistry.patternDescriptorBuilder("collate", "(?1 collate '?2')")
|
functionRegistry.patternDescriptorBuilder("collate", "(?1 collate '?2')")
|
||||||
.setInvariantType(stringType)
|
.setInvariantType(stringType)
|
||||||
.setExactArgumentCount( 2 )
|
.setExactArgumentCount( 2 )
|
||||||
.setParameterTypes(STRING, ANY)
|
.setParameterTypes(STRING, COLLATION)
|
||||||
.setArgumentListSignature("(STRING string as COLLATION collation)")
|
.setArgumentListSignature("(STRING string as COLLATION collation)")
|
||||||
.register();
|
.register();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
||||||
import org.hibernate.query.sqm.sql.internal.AbstractSqmPathInterpretation;
|
import org.hibernate.query.sqm.sql.internal.AbstractSqmPathInterpretation;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
@ -58,7 +59,8 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
StandardArgumentsValidators.exactly( 1 ),
|
StandardArgumentsValidators.exactly( 1 ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.LONG )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.LONG )
|
||||||
)
|
),
|
||||||
|
null
|
||||||
);
|
);
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
this.defaultArgumentRenderingMode = defaultArgumentRenderingMode;
|
this.defaultArgumentRenderingMode = defaultArgumentRenderingMode;
|
||||||
|
@ -102,9 +104,11 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
// In the end, the expression looks like the following:
|
// In the end, the expression looks like the following:
|
||||||
// count(distinct coalesce(nullif(coalesce(col1 || '', '\0'), ''), '\01') || '\0' || coalesce(nullif(coalesce(col2 || '', '\0'), ''), '\02'))
|
// count(distinct coalesce(nullif(coalesce(col1 || '', '\0'), ''), '\01') || '\0' || coalesce(nullif(coalesce(col2 || '', '\0'), ''), '\02'))
|
||||||
if ( caseWrapper ) {
|
if ( caseWrapper ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( "case when " );
|
sqlAppender.appendSql( "case when " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( " then " );
|
sqlAppender.appendSql( " then " );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( "coalesce(nullif(coalesce(" );
|
sqlAppender.appendSql( "coalesce(nullif(coalesce(" );
|
||||||
renderCastedArgument( sqlAppender, translator, expressions.get( 0 ) );
|
renderCastedArgument( sqlAppender, translator, expressions.get( 0 ) );
|
||||||
|
@ -162,7 +166,9 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
else if ( !dialect.supportsTupleCounts() ) {
|
else if ( !dialect.supportsTupleCounts() ) {
|
||||||
sqlAppender.appendSql( "case when " );
|
sqlAppender.appendSql( "case when " );
|
||||||
if ( caseWrapper ) {
|
if ( caseWrapper ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( " and " );
|
sqlAppender.appendSql( " and " );
|
||||||
}
|
}
|
||||||
translator.render( expressions.get( 0 ), defaultArgumentRenderingMode );
|
translator.render( expressions.get( 0 ), defaultArgumentRenderingMode );
|
||||||
|
@ -193,9 +199,11 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
if ( filter != null && !caseWrapper ) {
|
if ( filter != null && !caseWrapper ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( " filter (where " );
|
sqlAppender.appendSql( " filter (where " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +258,10 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
boolean caseWrapper,
|
boolean caseWrapper,
|
||||||
SqlAstNode realArg) {
|
SqlAstNode realArg) {
|
||||||
if ( caseWrapper ) {
|
if ( caseWrapper ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( "case when " );
|
sqlAppender.appendSql( "case when " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( " then " );
|
sqlAppender.appendSql( " then " );
|
||||||
if ( realArg instanceof Star ) {
|
if ( realArg instanceof Star ) {
|
||||||
sqlAppender.appendSql( "1" );
|
sqlAppender.appendSql( "1" );
|
||||||
|
|
|
@ -31,7 +31,8 @@ public class CurrentFunction
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
StandardArgumentsValidators.NO_ARGS,
|
StandardArgumentsValidators.NO_ARGS,
|
||||||
StandardFunctionReturnTypeResolvers.invariant( type )
|
StandardFunctionReturnTypeResolvers.invariant( type ),
|
||||||
|
null
|
||||||
);
|
);
|
||||||
this.sql = sql;
|
this.sql = sql;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
||||||
|
|
||||||
import org.hibernate.dialect.OracleDialect;
|
import org.hibernate.dialect.OracleDialect;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
@ -20,6 +21,9 @@ import org.hibernate.type.spi.TypeConfiguration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import jakarta.persistence.TemporalType;
|
import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
|
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
|
||||||
|
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEMPORAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DB2's varchar_format() can't handle quoted literal strings in
|
* DB2's varchar_format() can't handle quoted literal strings in
|
||||||
* the format pattern. So just split the pattern into bits, call
|
* the format pattern. So just split the pattern into bits, call
|
||||||
|
@ -37,7 +41,8 @@ public class DB2FormatEmulation
|
||||||
CommonFunctionFactory.formatValidator(),
|
CommonFunctionFactory.formatValidator(),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, TEMPORAL, STRING )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
@ -36,7 +37,8 @@ public class DerbyLpadEmulation
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, INTEGER ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, INTEGER ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, STRING, INTEGER )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
@ -36,7 +37,8 @@ public class DerbyRpadEmulation
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, INTEGER ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, INTEGER ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, STRING, INTEGER )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,9 @@ import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescript
|
||||||
import org.hibernate.query.sqm.function.FunctionKind;
|
import org.hibernate.query.sqm.function.FunctionKind;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
@ -43,7 +45,8 @@ public class EveryAnyEmulation extends AbstractSqmSelfRenderingFunctionDescripto
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 1 ), BOOLEAN ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 1 ), BOOLEAN ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, BOOLEAN )
|
||||||
);
|
);
|
||||||
this.every = every;
|
this.every = every;
|
||||||
}
|
}
|
||||||
|
@ -56,7 +59,9 @@ public class EveryAnyEmulation extends AbstractSqmSelfRenderingFunctionDescripto
|
||||||
SqlAstTranslator<?> walker) {
|
SqlAstTranslator<?> walker) {
|
||||||
sqlAppender.appendSql( "(sum(case when " );
|
sqlAppender.appendSql( "(sum(case when " );
|
||||||
if ( filter != null ) {
|
if ( filter != null ) {
|
||||||
|
walker.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
filter.accept( walker );
|
filter.accept( walker );
|
||||||
|
walker.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( " then case when " );
|
sqlAppender.appendSql( " then case when " );
|
||||||
sqlAstArguments.get( 0 ).accept( walker );
|
sqlAstArguments.get( 0 ).accept( walker );
|
||||||
if ( every ) {
|
if ( every ) {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.expression.*;
|
import org.hibernate.query.sqm.tree.expression.*;
|
||||||
|
@ -44,14 +45,15 @@ public class ExtractFunction
|
||||||
|
|
||||||
private final Dialect dialect;
|
private final Dialect dialect;
|
||||||
|
|
||||||
public ExtractFunction(Dialect dialect) {
|
public ExtractFunction(Dialect dialect, TypeConfiguration typeConfiguration) {
|
||||||
super(
|
super(
|
||||||
"extract",
|
"extract",
|
||||||
new ArgumentTypesValidator(
|
new ArgumentTypesValidator(
|
||||||
StandardArgumentsValidators.exactly( 2 ),
|
StandardArgumentsValidators.exactly( 2 ),
|
||||||
TEMPORAL_UNIT, TEMPORAL
|
TEMPORAL_UNIT, TEMPORAL
|
||||||
),
|
),
|
||||||
StandardFunctionReturnTypeResolvers.useArgType( 1 )
|
StandardFunctionReturnTypeResolvers.useArgType( 1 ),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, TEMPORAL_UNIT, TEMPORAL )
|
||||||
);
|
);
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.List;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.function.FunctionKind;
|
import org.hibernate.query.sqm.function.FunctionKind;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
@ -32,7 +33,8 @@ public class HypotheticalSetFunction extends AbstractSqmSelfRenderingFunctionDes
|
||||||
null,
|
null,
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( returnType )
|
typeConfiguration.getBasicTypeRegistry().resolve( returnType )
|
||||||
)
|
),
|
||||||
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +76,7 @@ public class HypotheticalSetFunction extends AbstractSqmSelfRenderingFunctionDes
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WITHIN_GROUP );
|
||||||
sqlAppender.appendSql( " within group (order by " );
|
sqlAppender.appendSql( " within group (order by " );
|
||||||
withinGroup.get( 0 ).accept( translator );
|
withinGroup.get( 0 ).accept( translator );
|
||||||
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
||||||
|
@ -81,11 +84,14 @@ public class HypotheticalSetFunction extends AbstractSqmSelfRenderingFunctionDes
|
||||||
withinGroup.get( i ).accept( translator );
|
withinGroup.get( i ).accept( translator );
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
if ( filter != null ) {
|
if ( filter != null ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( " filter (where " );
|
sqlAppender.appendSql( " filter (where " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
|
import org.hibernate.query.sqm.tree.expression.SqmBinaryArithmetic;
|
||||||
|
@ -54,7 +55,8 @@ public class InsertSubstringOverlayEmulation
|
||||||
),
|
),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, STRING, STRING, INTEGER, INTEGER )
|
||||||
);
|
);
|
||||||
this.strictSubstring = strictSubstring;
|
this.strictSubstring = strictSubstring;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class IntegralTimestampaddFunction
|
||||||
private final BasicType<Integer> integerType;
|
private final BasicType<Integer> integerType;
|
||||||
|
|
||||||
public IntegralTimestampaddFunction(Dialect dialect, TypeConfiguration typeConfiguration) {
|
public IntegralTimestampaddFunction(Dialect dialect, TypeConfiguration typeConfiguration) {
|
||||||
super( dialect );
|
super( dialect, typeConfiguration );
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
this.integerType = typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER );
|
this.integerType = typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER );
|
||||||
//This is kinda wrong, we're supposed to use findFunctionDescriptor("cast"), not instantiate CastFunction
|
//This is kinda wrong, we're supposed to use findFunctionDescriptor("cast"), not instantiate CastFunction
|
||||||
|
|
|
@ -20,10 +20,12 @@ import org.hibernate.query.sqm.function.SelfRenderingSqmOrderedSetAggregateFunct
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmOrderByClause;
|
import org.hibernate.query.sqm.tree.select.SqmOrderByClause;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
@ -44,7 +46,10 @@ public class InverseDistributionFunction extends AbstractSqmSelfRenderingFunctio
|
||||||
parameterType == null
|
parameterType == null
|
||||||
? StandardArgumentsValidators.exactly( 0 )
|
? StandardArgumentsValidators.exactly( 0 )
|
||||||
: new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 1 ), parameterType ),
|
: new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 1 ), parameterType ),
|
||||||
null
|
null,
|
||||||
|
parameterType == null
|
||||||
|
? null
|
||||||
|
: StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, parameterType )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +108,7 @@ public class InverseDistributionFunction extends AbstractSqmSelfRenderingFunctio
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WITHIN_GROUP );
|
||||||
sqlAppender.appendSql( " within group (order by " );
|
sqlAppender.appendSql( " within group (order by " );
|
||||||
withinGroup.get( 0 ).accept( translator );
|
withinGroup.get( 0 ).accept( translator );
|
||||||
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
||||||
|
@ -110,11 +116,14 @@ public class InverseDistributionFunction extends AbstractSqmSelfRenderingFunctio
|
||||||
withinGroup.get( i ).accept( translator );
|
withinGroup.get( i ).accept( translator );
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
if ( filter != null ) {
|
if ( filter != null ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( " filter (where " );
|
sqlAppender.appendSql( " filter (where " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,9 @@ import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescript
|
||||||
import org.hibernate.query.sqm.function.FunctionKind;
|
import org.hibernate.query.sqm.function.FunctionKind;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
@ -40,7 +42,8 @@ public class ListaggFunction extends AbstractSqmSelfRenderingFunctionDescriptor
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, STRING ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, STRING ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, STRING, STRING )
|
||||||
);
|
);
|
||||||
this.emptyWithinReplacement = emptyWithinReplacement;
|
this.emptyWithinReplacement = emptyWithinReplacement;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +85,9 @@ public class ListaggFunction extends AbstractSqmSelfRenderingFunctionDescriptor
|
||||||
}
|
}
|
||||||
if ( caseWrapper ) {
|
if ( caseWrapper ) {
|
||||||
sqlAppender.appendSql( "case when " );
|
sqlAppender.appendSql( "case when " );
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( " then " );
|
sqlAppender.appendSql( " then " );
|
||||||
arg.accept( translator );
|
arg.accept( translator );
|
||||||
sqlAppender.appendSql( " else null end" );
|
sqlAppender.appendSql( " else null end" );
|
||||||
|
@ -96,6 +101,7 @@ public class ListaggFunction extends AbstractSqmSelfRenderingFunctionDescriptor
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WITHIN_GROUP );
|
||||||
sqlAppender.appendSql( " within group (order by " );
|
sqlAppender.appendSql( " within group (order by " );
|
||||||
withinGroup.get( 0 ).accept( translator );
|
withinGroup.get( 0 ).accept( translator );
|
||||||
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
||||||
|
@ -103,15 +109,18 @@ public class ListaggFunction extends AbstractSqmSelfRenderingFunctionDescriptor
|
||||||
withinGroup.get( i ).accept( translator );
|
withinGroup.get( i ).accept( translator );
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
else if ( emptyWithinReplacement != null ) {
|
else if ( emptyWithinReplacement != null ) {
|
||||||
sqlAppender.appendSql( ' ' );
|
sqlAppender.appendSql( ' ' );
|
||||||
sqlAppender.appendSql( emptyWithinReplacement );
|
sqlAppender.appendSql( emptyWithinReplacement );
|
||||||
}
|
}
|
||||||
if ( !caseWrapper && filter != null ) {
|
if ( !caseWrapper && filter != null ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( " filter (where " );
|
sqlAppender.appendSql( " filter (where " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,9 @@ import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescript
|
||||||
import org.hibernate.query.sqm.function.FunctionKind;
|
import org.hibernate.query.sqm.function.FunctionKind;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
@ -41,7 +43,8 @@ public class ListaggGroupConcatEmulation extends AbstractSqmSelfRenderingFunctio
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, STRING ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, STRING ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, STRING, STRING )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,22 +84,26 @@ public class ListaggGroupConcatEmulation extends AbstractSqmSelfRenderingFunctio
|
||||||
arg = (Expression) firstArg;
|
arg = (Expression) firstArg;
|
||||||
}
|
}
|
||||||
if ( caseWrapper ) {
|
if ( caseWrapper ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( "case when " );
|
sqlAppender.appendSql( "case when " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( " then " );
|
sqlAppender.appendSql( " then " );
|
||||||
arg.accept( translator );
|
arg.accept( translator );
|
||||||
sqlAppender.appendSql( " else null end" );
|
sqlAppender.appendSql( " else null end" );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
arg.accept( translator );
|
arg.accept( translator );
|
||||||
}
|
}
|
||||||
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WITHIN_GROUP );
|
||||||
sqlAppender.appendSql( " order by " );
|
sqlAppender.appendSql( " order by " );
|
||||||
withinGroup.get( 0 ).accept( translator );
|
withinGroup.get( 0 ).accept( translator );
|
||||||
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
||||||
sqlAppender.appendSql( ',' );
|
sqlAppender.appendSql( ',' );
|
||||||
withinGroup.get( i ).accept( translator );
|
withinGroup.get( i ).accept( translator );
|
||||||
}
|
}
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
if ( sqlAstArguments.size() != 1 ) {
|
if ( sqlAstArguments.size() != 1 ) {
|
||||||
SqlAstNode separator = sqlAstArguments.get( 1 );
|
SqlAstNode separator = sqlAstArguments.get( 1 );
|
||||||
|
@ -109,9 +116,11 @@ public class ListaggGroupConcatEmulation extends AbstractSqmSelfRenderingFunctio
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
if ( !caseWrapper && filter != null ) {
|
if ( !caseWrapper && filter != null ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( " filter (where " );
|
sqlAppender.appendSql( " filter (where " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,9 @@ import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescript
|
||||||
import org.hibernate.query.sqm.function.FunctionKind;
|
import org.hibernate.query.sqm.function.FunctionKind;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
@ -51,7 +53,8 @@ public class ListaggStringAggEmulation extends AbstractSqmSelfRenderingFunctionD
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, STRING ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, STRING ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, STRING, STRING )
|
||||||
);
|
);
|
||||||
this.functionName = functionName;
|
this.functionName = functionName;
|
||||||
this.stringType = stringType;
|
this.stringType = stringType;
|
||||||
|
@ -95,11 +98,13 @@ public class ListaggStringAggEmulation extends AbstractSqmSelfRenderingFunctionD
|
||||||
arg = (Expression) firstArg;
|
arg = (Expression) firstArg;
|
||||||
}
|
}
|
||||||
if ( caseWrapper ) {
|
if ( caseWrapper ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( "case when " );
|
sqlAppender.appendSql( "case when " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( " then " );
|
sqlAppender.appendSql( " then " );
|
||||||
renderAsString( sqlAppender, translator, arg );
|
renderAsString( sqlAppender, translator, arg );
|
||||||
sqlAppender.appendSql( " else null end" );
|
sqlAppender.appendSql( " else null end" );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
renderAsString( sqlAppender, translator, arg );
|
renderAsString( sqlAppender, translator, arg );
|
||||||
|
@ -113,16 +118,19 @@ public class ListaggStringAggEmulation extends AbstractSqmSelfRenderingFunctionD
|
||||||
sqlAppender.appendSql( ',' );
|
sqlAppender.appendSql( ',' );
|
||||||
separator.accept( translator );
|
separator.accept( translator );
|
||||||
if ( !withinGroupClause && withinGroup != null && !withinGroup.isEmpty() ) {
|
if ( !withinGroupClause && withinGroup != null && !withinGroup.isEmpty() ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WITHIN_GROUP );
|
||||||
sqlAppender.appendSql( " order by " );
|
sqlAppender.appendSql( " order by " );
|
||||||
withinGroup.get( 0 ).accept( translator );
|
withinGroup.get( 0 ).accept( translator );
|
||||||
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
||||||
sqlAppender.appendSql( ',' );
|
sqlAppender.appendSql( ',' );
|
||||||
withinGroup.get( i ).accept( translator );
|
withinGroup.get( i ).accept( translator );
|
||||||
}
|
}
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
if ( withinGroupClause && withinGroup != null && !withinGroup.isEmpty() ) {
|
if ( withinGroupClause && withinGroup != null && !withinGroup.isEmpty() ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WITHIN_GROUP );
|
||||||
sqlAppender.appendSql( " within group (order by " );
|
sqlAppender.appendSql( " within group (order by " );
|
||||||
withinGroup.get( 0 ).accept( translator );
|
withinGroup.get( 0 ).accept( translator );
|
||||||
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
||||||
|
@ -130,11 +138,14 @@ public class ListaggStringAggEmulation extends AbstractSqmSelfRenderingFunctionD
|
||||||
withinGroup.get( i ).accept( translator );
|
withinGroup.get( i ).accept( translator );
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
if ( !caseWrapper && filter != null ) {
|
if ( !caseWrapper && filter != null ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( " filter (where " );
|
sqlAppender.appendSql( " filter (where " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
|
@ -34,7 +35,8 @@ public class LocatePositionEmulation extends AbstractSqmFunctionDescriptor {
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, STRING ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 2 ), STRING, STRING ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, STRING, STRING )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmTrimSpecification;
|
import org.hibernate.query.sqm.tree.expression.SqmTrimSpecification;
|
||||||
|
@ -47,7 +48,8 @@ public class LpadRpadPadEmulation
|
||||||
),
|
),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, STRING, INTEGER, TRIM_SPEC, STRING )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,9 @@ import org.hibernate.query.sqm.function.FunctionKind;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
@ -41,7 +43,8 @@ public class MinMaxCaseEveryAnyEmulation extends AbstractSqmSelfRenderingFunctio
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 1 ), FunctionParameterType.BOOLEAN ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 1 ), FunctionParameterType.BOOLEAN ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, FunctionParameterType.BOOLEAN )
|
||||||
);
|
);
|
||||||
this.every = every;
|
this.every = every;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +62,9 @@ public class MinMaxCaseEveryAnyEmulation extends AbstractSqmSelfRenderingFunctio
|
||||||
sqlAppender.appendSql( "max(case when " );
|
sqlAppender.appendSql( "max(case when " );
|
||||||
}
|
}
|
||||||
if ( filter != null ) {
|
if ( filter != null ) {
|
||||||
|
walker.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
filter.accept( walker );
|
filter.accept( walker );
|
||||||
|
walker.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( " then case when " );
|
sqlAppender.appendSql( " then case when " );
|
||||||
sqlAstArguments.get( 0 ).accept( walker );
|
sqlAstArguments.get( 0 ).accept( walker );
|
||||||
sqlAppender.appendSql( " then 1 else 0 end else null end)" );
|
sqlAppender.appendSql( " then 1 else 0 end else null end)" );
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.dialect.function;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
@ -43,19 +44,27 @@ public class ModeStatsModeEmulation extends InverseDistributionFunction {
|
||||||
throw new IllegalArgumentException( "MODE function requires a WITHIN GROUP clause with exactly one order by item!" );
|
throw new IllegalArgumentException( "MODE function requires a WITHIN GROUP clause with exactly one order by item!" );
|
||||||
}
|
}
|
||||||
if ( caseWrapper ) {
|
if ( caseWrapper ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( "case when " );
|
sqlAppender.appendSql( "case when " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( " then " );
|
sqlAppender.appendSql( " then " );
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WITHIN_GROUP );
|
||||||
withinGroup.get( 0 ).accept( translator );
|
withinGroup.get( 0 ).accept( translator );
|
||||||
sqlAppender.appendSql( " else null end)" );
|
sqlAppender.appendSql( " else null end)" );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WITHIN_GROUP );
|
||||||
withinGroup.get( 0 ).accept( translator );
|
withinGroup.get( 0 ).accept( translator );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
if ( filter != null ) {
|
if ( filter != null ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( " filter (where " );
|
sqlAppender.appendSql( " filter (where " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||||
|
@ -35,7 +36,8 @@ public class NvlCoalesceEmulation
|
||||||
super(
|
super(
|
||||||
"coalesce",
|
"coalesce",
|
||||||
StandardArgumentsValidators.min( 2 ),
|
StandardArgumentsValidators.min( 2 ),
|
||||||
StandardFunctionReturnTypeResolvers.useFirstNonNull()
|
StandardFunctionReturnTypeResolvers.useFirstNonNull(),
|
||||||
|
StandardFunctionArgumentTypeResolvers.IMPLIED_RESULT_TYPE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
@ -32,7 +33,8 @@ public class QuantifiedLeastGreatestEmulation
|
||||||
super(
|
super(
|
||||||
least ? "least" : "greatest",
|
least ? "least" : "greatest",
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.min( 2 ), COMPARABLE, COMPARABLE ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.min( 2 ), COMPARABLE, COMPARABLE ),
|
||||||
StandardFunctionReturnTypeResolvers.useFirstNonNull()
|
StandardFunctionReturnTypeResolvers.useFirstNonNull(),
|
||||||
|
StandardFunctionArgumentTypeResolvers.ARGUMENT_OR_IMPLIED_RESULT_TYPE
|
||||||
);
|
);
|
||||||
this.operator = least ? "<=" : ">=";
|
this.operator = least ? "<=" : ">=";
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,11 @@ import java.util.List;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.function.FunctionKind;
|
import org.hibernate.query.sqm.function.FunctionKind;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
|
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
@ -42,7 +45,8 @@ public class SQLServerEveryAnyEmulation extends AbstractSqmSelfRenderingFunction
|
||||||
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 1 ), BOOLEAN ),
|
new ArgumentTypesValidator( StandardArgumentsValidators.exactly( 1 ), BOOLEAN ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, FunctionParameterType.BOOLEAN )
|
||||||
);
|
);
|
||||||
this.every = every;
|
this.every = every;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +64,9 @@ public class SQLServerEveryAnyEmulation extends AbstractSqmSelfRenderingFunction
|
||||||
sqlAppender.appendSql( "max(iif(" );
|
sqlAppender.appendSql( "max(iif(" );
|
||||||
}
|
}
|
||||||
if ( filter != null ) {
|
if ( filter != null ) {
|
||||||
|
walker.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
filter.accept( walker );
|
filter.accept( walker );
|
||||||
|
walker.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( ",iif(" );
|
sqlAppender.appendSql( ",iif(" );
|
||||||
sqlAstArguments.get( 0 ).accept( walker );
|
sqlAstArguments.get( 0 ).accept( walker );
|
||||||
sqlAppender.appendSql( ",1,0),null))" );
|
sqlAppender.appendSql( ",1,0),null))" );
|
||||||
|
|
|
@ -11,6 +11,7 @@ import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
import org.hibernate.dialect.SQLServerDialect;
|
import org.hibernate.dialect.SQLServerDialect;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
@ -20,6 +21,9 @@ import org.hibernate.sql.ast.tree.expression.Format;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
|
||||||
|
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEMPORAL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQL Server behaves strangely when the first argument to format is of the type time, so we cast to datetime.
|
* SQL Server behaves strangely when the first argument to format is of the type time, so we cast to datetime.
|
||||||
*
|
*
|
||||||
|
@ -35,7 +39,8 @@ public class SQLServerFormatEmulation extends AbstractSqmSelfRenderingFunctionDe
|
||||||
CommonFunctionFactory.formatValidator(),
|
CommonFunctionFactory.formatValidator(),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, TEMPORAL, STRING )
|
||||||
);
|
);
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,8 @@ public class SqlFunction
|
||||||
super(
|
super(
|
||||||
"sql",
|
"sql",
|
||||||
StandardArgumentsValidators.min( 1 ),
|
StandardArgumentsValidators.min( 1 ),
|
||||||
StandardFunctionReturnTypeResolvers.invariant( JavaObjectType.INSTANCE )
|
StandardFunctionReturnTypeResolvers.invariant( JavaObjectType.INSTANCE ),
|
||||||
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescript
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
@ -22,6 +23,7 @@ import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.sql.ast.tree.expression.DurationUnit;
|
import org.hibernate.sql.ast.tree.expression.DurationUnit;
|
||||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -46,14 +48,15 @@ public class TimestampaddFunction
|
||||||
|
|
||||||
private final Dialect dialect;
|
private final Dialect dialect;
|
||||||
|
|
||||||
public TimestampaddFunction(Dialect dialect) {
|
public TimestampaddFunction(Dialect dialect, TypeConfiguration typeConfiguration) {
|
||||||
super(
|
super(
|
||||||
"timestampadd",
|
"timestampadd",
|
||||||
new ArgumentTypesValidator(
|
new ArgumentTypesValidator(
|
||||||
StandardArgumentsValidators.exactly( 3 ),
|
StandardArgumentsValidators.exactly( 3 ),
|
||||||
TEMPORAL_UNIT, INTEGER, TEMPORAL
|
TEMPORAL_UNIT, INTEGER, TEMPORAL
|
||||||
),
|
),
|
||||||
StandardFunctionReturnTypeResolvers.useArgType( 3 )
|
StandardFunctionReturnTypeResolvers.useArgType( 3 ),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, TEMPORAL_UNIT, INTEGER, TEMPORAL )
|
||||||
);
|
);
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.dialect.function;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import jakarta.persistence.TemporalType;
|
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.sqm.TemporalUnit;
|
import org.hibernate.query.sqm.TemporalUnit;
|
||||||
|
@ -16,6 +15,7 @@ import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescript
|
||||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
@ -26,6 +26,8 @@ import org.hibernate.sql.ast.tree.expression.Expression;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
import jakarta.persistence.TemporalType;
|
||||||
|
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEMPORAL;
|
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEMPORAL;
|
||||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEMPORAL_UNIT;
|
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.TEMPORAL_UNIT;
|
||||||
|
@ -54,7 +56,8 @@ public class TimestampdiffFunction
|
||||||
),
|
),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.LONG )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.LONG )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, TEMPORAL_UNIT, TEMPORAL, TEMPORAL )
|
||||||
);
|
);
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.hibernate.query.sqm.TrimSpec;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
|
@ -50,7 +51,8 @@ public class TrimFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
||||||
),
|
),
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING )
|
||||||
)
|
),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, TRIM_SPEC, STRING, STRING )
|
||||||
);
|
);
|
||||||
this.dialect = dialect;
|
this.dialect = dialect;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3191,7 +3191,8 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
null,
|
null,
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
resolveExpressibleTypeBasic( Object.class )
|
resolveExpressibleTypeBasic( Object.class )
|
||||||
)
|
),
|
||||||
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return functionTemplate.generateSqmExpression(
|
return functionTemplate.generateSqmExpression(
|
||||||
|
@ -3262,6 +3263,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
||||||
StandardFunctionReturnTypeResolvers.invariant(
|
StandardFunctionReturnTypeResolvers.invariant(
|
||||||
resolveExpressibleTypeBasic( Object.class )
|
resolveExpressibleTypeBasic( Object.class )
|
||||||
),
|
),
|
||||||
|
null,
|
||||||
functionName,
|
functionName,
|
||||||
functionKind,
|
functionKind,
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -6,45 +6,52 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.query.sqm.function;
|
package org.hibernate.query.sqm.function;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||||
|
import org.hibernate.query.sqm.produce.function.FunctionArgumentTypeResolver;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.query.sqm.tree.select.SqmOrderByClause;
|
import org.hibernate.query.sqm.tree.select.SqmOrderByClause;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescriptor {
|
public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescriptor {
|
||||||
private final ArgumentsValidator argumentsValidator;
|
private final ArgumentsValidator argumentsValidator;
|
||||||
private final FunctionReturnTypeResolver returnTypeResolver;
|
private final FunctionReturnTypeResolver returnTypeResolver;
|
||||||
|
private final FunctionArgumentTypeResolver functionArgumentTypeResolver;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
public AbstractSqmFunctionDescriptor(String name) {
|
public AbstractSqmFunctionDescriptor(String name) {
|
||||||
this( name, null, null );
|
this( name, null, null, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractSqmFunctionDescriptor(String name, ArgumentsValidator argumentsValidator) {
|
public AbstractSqmFunctionDescriptor(
|
||||||
this( name, argumentsValidator, null );
|
String name,
|
||||||
|
ArgumentsValidator argumentsValidator) {
|
||||||
|
this( name, argumentsValidator, null, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractSqmFunctionDescriptor(
|
public AbstractSqmFunctionDescriptor(
|
||||||
String name,
|
String name,
|
||||||
ArgumentsValidator argumentsValidator,
|
ArgumentsValidator argumentsValidator,
|
||||||
FunctionReturnTypeResolver returnTypeResolver) {
|
FunctionArgumentTypeResolver argumentTypeResolver) {
|
||||||
|
this( name, argumentsValidator, null, argumentTypeResolver );
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractSqmFunctionDescriptor(
|
||||||
|
String name,
|
||||||
|
ArgumentsValidator argumentsValidator,
|
||||||
|
FunctionReturnTypeResolver returnTypeResolver,
|
||||||
|
FunctionArgumentTypeResolver argumentTypeResolver) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.argumentsValidator = argumentsValidator == null
|
this.argumentsValidator = argumentsValidator == null
|
||||||
? StandardArgumentsValidators.NONE
|
? StandardArgumentsValidators.NONE
|
||||||
|
@ -52,6 +59,9 @@ public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescri
|
||||||
this.returnTypeResolver = returnTypeResolver == null
|
this.returnTypeResolver = returnTypeResolver == null
|
||||||
? StandardFunctionReturnTypeResolvers.useFirstNonNull()
|
? StandardFunctionReturnTypeResolvers.useFirstNonNull()
|
||||||
: returnTypeResolver;
|
: returnTypeResolver;
|
||||||
|
this.functionArgumentTypeResolver = argumentTypeResolver == null
|
||||||
|
? StandardFunctionArgumentTypeResolvers.NULL
|
||||||
|
: argumentTypeResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -71,6 +81,10 @@ public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescri
|
||||||
return returnTypeResolver;
|
return returnTypeResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FunctionArgumentTypeResolver getArgumentTypeResolver() {
|
||||||
|
return functionArgumentTypeResolver;
|
||||||
|
}
|
||||||
|
|
||||||
public String getReturnSignature() {
|
public String getReturnSignature() {
|
||||||
String result = returnTypeResolver.getReturnType();
|
String result = returnTypeResolver.getReturnType();
|
||||||
return result.isEmpty() ? "" : result + " ";
|
return result.isEmpty() ? "" : result + " ";
|
||||||
|
@ -81,23 +95,6 @@ public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescri
|
||||||
return alwaysIncludesParentheses() ? args : "()".equals(args) ? "" : "[" + args + "]";
|
return alwaysIncludesParentheses() ? args : "()".equals(args) ? "" : "[" + args + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SqlAstNode toSqlAstNode(Object arg, SqmToSqlAstConverter walker) {
|
|
||||||
return (SqlAstNode) arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static List<SqlAstNode> resolveSqlAstArguments(List<? extends SqmTypedNode<?>> sqmArguments, SqmToSqlAstConverter walker) {
|
|
||||||
if ( sqmArguments == null || sqmArguments.isEmpty() ) {
|
|
||||||
return emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
final ArrayList<SqlAstNode> sqlAstArguments = new ArrayList<>();
|
|
||||||
for ( SqmTypedNode<?> sqmArgument : sqmArguments ) {
|
|
||||||
sqlAstArguments.add( toSqlAstNode( ((SqmVisitableNode) sqmArgument).accept( walker ), walker ) );
|
|
||||||
}
|
|
||||||
return sqlAstArguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final <T> SelfRenderingSqmFunction<T> generateSqmExpression(
|
public final <T> SelfRenderingSqmFunction<T> generateSqmExpression(
|
||||||
List<? extends SqmTypedNode<?>> arguments,
|
List<? extends SqmTypedNode<?>> arguments,
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.query.sqm.function;
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||||
|
import org.hibernate.query.sqm.produce.function.FunctionArgumentTypeResolver;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
|
@ -33,8 +34,9 @@ public abstract class AbstractSqmSelfRenderingFunctionDescriptor
|
||||||
public AbstractSqmSelfRenderingFunctionDescriptor(
|
public AbstractSqmSelfRenderingFunctionDescriptor(
|
||||||
String name,
|
String name,
|
||||||
ArgumentsValidator argumentsValidator,
|
ArgumentsValidator argumentsValidator,
|
||||||
FunctionReturnTypeResolver returnTypeResolver) {
|
FunctionReturnTypeResolver returnTypeResolver,
|
||||||
super( name, argumentsValidator, returnTypeResolver );
|
FunctionArgumentTypeResolver argumentTypeResolver) {
|
||||||
|
super( name, argumentsValidator, returnTypeResolver, argumentTypeResolver );
|
||||||
this.functionKind = FunctionKind.NORMAL;
|
this.functionKind = FunctionKind.NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,8 +44,9 @@ public abstract class AbstractSqmSelfRenderingFunctionDescriptor
|
||||||
String name,
|
String name,
|
||||||
FunctionKind functionKind,
|
FunctionKind functionKind,
|
||||||
ArgumentsValidator argumentsValidator,
|
ArgumentsValidator argumentsValidator,
|
||||||
FunctionReturnTypeResolver returnTypeResolver) {
|
FunctionReturnTypeResolver returnTypeResolver,
|
||||||
super( name, argumentsValidator, returnTypeResolver );
|
FunctionArgumentTypeResolver argumentTypeResolver) {
|
||||||
|
super( name, argumentsValidator, returnTypeResolver, argumentTypeResolver );
|
||||||
this.functionKind = functionKind;
|
this.functionKind = functionKind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
|
@ -60,6 +61,7 @@ public class MultipatternSqmFunctionDescriptor extends AbstractSqmFunctionDescri
|
||||||
String name,
|
String name,
|
||||||
SqmFunctionDescriptor[] functions,
|
SqmFunctionDescriptor[] functions,
|
||||||
BasicType<?> type,
|
BasicType<?> type,
|
||||||
|
TypeConfiguration typeConfiguration,
|
||||||
FunctionParameterType... parameterTypes) {
|
FunctionParameterType... parameterTypes) {
|
||||||
super(
|
super(
|
||||||
name,
|
name,
|
||||||
|
@ -70,7 +72,8 @@ public class MultipatternSqmFunctionDescriptor extends AbstractSqmFunctionDescri
|
||||||
),
|
),
|
||||||
parameterTypes
|
parameterTypes
|
||||||
),
|
),
|
||||||
StandardFunctionReturnTypeResolvers.invariant( type )
|
StandardFunctionReturnTypeResolvers.invariant( type ),
|
||||||
|
StandardFunctionArgumentTypeResolvers.invariant( typeConfiguration, parameterTypes )
|
||||||
);
|
);
|
||||||
this.functions = functions;
|
this.functions = functions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
package org.hibernate.query.sqm.function;
|
package org.hibernate.query.sqm.function;
|
||||||
|
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||||
|
import org.hibernate.query.sqm.produce.function.FunctionArgumentTypeResolver;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
@ -47,6 +49,7 @@ public class NamedSqmFunctionDescriptor
|
||||||
useParenthesesWhenNoArgs,
|
useParenthesesWhenNoArgs,
|
||||||
argumentsValidator,
|
argumentsValidator,
|
||||||
returnTypeResolver,
|
returnTypeResolver,
|
||||||
|
null,
|
||||||
functionName,
|
functionName,
|
||||||
FunctionKind.NORMAL,
|
FunctionKind.NORMAL,
|
||||||
null,
|
null,
|
||||||
|
@ -59,11 +62,31 @@ public class NamedSqmFunctionDescriptor
|
||||||
boolean useParenthesesWhenNoArgs,
|
boolean useParenthesesWhenNoArgs,
|
||||||
ArgumentsValidator argumentsValidator,
|
ArgumentsValidator argumentsValidator,
|
||||||
FunctionReturnTypeResolver returnTypeResolver,
|
FunctionReturnTypeResolver returnTypeResolver,
|
||||||
|
FunctionArgumentTypeResolver argumentTypeResolver) {
|
||||||
|
this(
|
||||||
|
functionName,
|
||||||
|
useParenthesesWhenNoArgs,
|
||||||
|
argumentsValidator,
|
||||||
|
returnTypeResolver,
|
||||||
|
argumentTypeResolver,
|
||||||
|
functionName,
|
||||||
|
FunctionKind.NORMAL,
|
||||||
|
null,
|
||||||
|
SqlAstNodeRenderingMode.DEFAULT
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamedSqmFunctionDescriptor(
|
||||||
|
String functionName,
|
||||||
|
boolean useParenthesesWhenNoArgs,
|
||||||
|
ArgumentsValidator argumentsValidator,
|
||||||
|
FunctionReturnTypeResolver returnTypeResolver,
|
||||||
|
FunctionArgumentTypeResolver argumentTypeResolver,
|
||||||
String name,
|
String name,
|
||||||
FunctionKind functionKind,
|
FunctionKind functionKind,
|
||||||
String argumentListSignature,
|
String argumentListSignature,
|
||||||
SqlAstNodeRenderingMode argumentRenderingMode) {
|
SqlAstNodeRenderingMode argumentRenderingMode) {
|
||||||
super( name, functionKind, argumentsValidator, returnTypeResolver );
|
super( name, functionKind, argumentsValidator, returnTypeResolver, argumentTypeResolver );
|
||||||
|
|
||||||
this.functionName = functionName;
|
this.functionName = functionName;
|
||||||
this.useParenthesesWhenNoArgs = useParenthesesWhenNoArgs;
|
this.useParenthesesWhenNoArgs = useParenthesesWhenNoArgs;
|
||||||
|
@ -150,8 +173,10 @@ public class NamedSqmFunctionDescriptor
|
||||||
sqlAppender.appendSql( "," );
|
sqlAppender.appendSql( "," );
|
||||||
}
|
}
|
||||||
if ( caseWrapper && !( arg instanceof Distinct ) ) {
|
if ( caseWrapper && !( arg instanceof Distinct ) ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( "case when " );
|
sqlAppender.appendSql( "case when " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( " then " );
|
sqlAppender.appendSql( " then " );
|
||||||
if ( ( arg instanceof Star ) ) {
|
if ( ( arg instanceof Star ) ) {
|
||||||
sqlAppender.appendSql( "1" );
|
sqlAppender.appendSql( "1" );
|
||||||
|
@ -172,6 +197,7 @@ public class NamedSqmFunctionDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WITHIN_GROUP );
|
||||||
sqlAppender.appendSql( " within group (order by" );
|
sqlAppender.appendSql( " within group (order by" );
|
||||||
translator.render( withinGroup.get( 0 ), argumentRenderingMode );
|
translator.render( withinGroup.get( 0 ), argumentRenderingMode );
|
||||||
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
||||||
|
@ -179,6 +205,7 @@ public class NamedSqmFunctionDescriptor
|
||||||
translator.render( withinGroup.get( 0 ), argumentRenderingMode );
|
translator.render( withinGroup.get( 0 ), argumentRenderingMode );
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( fromFirst != null ) {
|
if ( fromFirst != null ) {
|
||||||
|
@ -199,9 +226,11 @@ public class NamedSqmFunctionDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( filter != null && !caseWrapper ) {
|
if ( filter != null && !caseWrapper ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( " filter (where " );
|
sqlAppender.appendSql( " filter (where " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
package org.hibernate.query.sqm.function;
|
package org.hibernate.query.sqm.function;
|
||||||
|
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||||
|
import org.hibernate.query.sqm.produce.function.FunctionArgumentTypeResolver;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||||
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
||||||
|
@ -48,6 +49,7 @@ public class PatternBasedSqmFunctionDescriptor
|
||||||
PatternRenderer renderer,
|
PatternRenderer renderer,
|
||||||
ArgumentsValidator argumentsValidator,
|
ArgumentsValidator argumentsValidator,
|
||||||
FunctionReturnTypeResolver returnTypeResolver,
|
FunctionReturnTypeResolver returnTypeResolver,
|
||||||
|
FunctionArgumentTypeResolver argumentTypeResolver,
|
||||||
String name,
|
String name,
|
||||||
FunctionKind functionKind,
|
FunctionKind functionKind,
|
||||||
String argumentListSignature) {
|
String argumentListSignature) {
|
||||||
|
@ -63,7 +65,8 @@ public class PatternBasedSqmFunctionDescriptor
|
||||||
: renderer.hasVarargs()
|
: renderer.hasVarargs()
|
||||||
? StandardArgumentsValidators.min( renderer.getParamCount() )
|
? StandardArgumentsValidators.min( renderer.getParamCount() )
|
||||||
: StandardArgumentsValidators.exactly( renderer.getParamCount() ),
|
: StandardArgumentsValidators.exactly( renderer.getParamCount() ),
|
||||||
returnTypeResolver
|
returnTypeResolver,
|
||||||
|
argumentTypeResolver
|
||||||
);
|
);
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
this.argumentListSignature = argumentListSignature;
|
this.argumentListSignature = argumentListSignature;
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.query.sqm.function;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||||
|
@ -16,7 +17,9 @@ import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.sqm.NodeBuilder;
|
import org.hibernate.query.sqm.NodeBuilder;
|
||||||
import org.hibernate.query.sqm.SqmExpressible;
|
import org.hibernate.query.sqm.SqmExpressible;
|
||||||
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
|
||||||
|
import org.hibernate.query.sqm.produce.function.FunctionArgumentTypeResolver;
|
||||||
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
|
||||||
|
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||||
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
|
@ -97,14 +100,38 @@ public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
|
||||||
return returnTypeResolver;
|
return returnTypeResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static List<SqlAstNode> resolveSqlAstArguments(List<? extends SqmTypedNode<?>> sqmArguments, SqmToSqlAstConverter walker) {
|
protected List<SqlAstNode> resolveSqlAstArguments(List<? extends SqmTypedNode<?>> sqmArguments, SqmToSqlAstConverter walker) {
|
||||||
if ( sqmArguments == null || sqmArguments.isEmpty() ) {
|
if ( sqmArguments == null || sqmArguments.isEmpty() ) {
|
||||||
return emptyList();
|
return emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final FunctionArgumentTypeResolver argumentTypeResolver;
|
||||||
|
if ( getFunctionDescriptor() instanceof AbstractSqmFunctionDescriptor ) {
|
||||||
|
argumentTypeResolver = ( (AbstractSqmFunctionDescriptor) getFunctionDescriptor() ).getArgumentTypeResolver();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
argumentTypeResolver = null;
|
||||||
|
}
|
||||||
|
if ( argumentTypeResolver == null ) {
|
||||||
|
final ArrayList<SqlAstNode> sqlAstArguments = new ArrayList<>( sqmArguments.size() );
|
||||||
|
for ( int i = 0; i < sqmArguments.size(); i++ ) {
|
||||||
|
sqlAstArguments.add(
|
||||||
|
(SqlAstNode) ( (SqmVisitableNode) sqmArguments.get( i ) ).accept( walker )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return sqlAstArguments;
|
||||||
|
}
|
||||||
|
final FunctionArgumentTypeResolverTypeAccess typeAccess = new FunctionArgumentTypeResolverTypeAccess(
|
||||||
|
walker,
|
||||||
|
this,
|
||||||
|
argumentTypeResolver
|
||||||
|
);
|
||||||
final ArrayList<SqlAstNode> sqlAstArguments = new ArrayList<>( sqmArguments.size() );
|
final ArrayList<SqlAstNode> sqlAstArguments = new ArrayList<>( sqmArguments.size() );
|
||||||
for ( SqmTypedNode<?> sqmArgument : sqmArguments ) {
|
for ( int i = 0; i < sqmArguments.size(); i++ ) {
|
||||||
sqlAstArguments.add( (SqlAstNode) ( (SqmVisitableNode) sqmArgument ).accept( walker ) );
|
typeAccess.argumentIndex = i;
|
||||||
|
sqlAstArguments.add(
|
||||||
|
(SqlAstNode) walker.visitWithInferredType( (SqmVisitableNode) sqmArguments.get( i ), typeAccess )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return sqlAstArguments;
|
return sqlAstArguments;
|
||||||
}
|
}
|
||||||
|
@ -184,4 +211,26 @@ public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class FunctionArgumentTypeResolverTypeAccess implements Supplier<MappingModelExpressible<?>> {
|
||||||
|
|
||||||
|
private final SqmToSqlAstConverter converter;
|
||||||
|
private final SqmFunction<?> function;
|
||||||
|
private final FunctionArgumentTypeResolver argumentTypeResolver;
|
||||||
|
private int argumentIndex;
|
||||||
|
|
||||||
|
public FunctionArgumentTypeResolverTypeAccess(
|
||||||
|
SqmToSqlAstConverter converter,
|
||||||
|
SqmFunction<?> function,
|
||||||
|
FunctionArgumentTypeResolver argumentTypeResolver) {
|
||||||
|
this.converter = converter;
|
||||||
|
this.function = function;
|
||||||
|
this.argumentTypeResolver = argumentTypeResolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappingModelExpressible<?> get() {
|
||||||
|
return argumentTypeResolver.resolveFunctionArgumentType( function, argumentIndex, converter );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ public class SelfRenderingSqmOrderedSetAggregateFunction<T> extends SelfRenderin
|
||||||
withinGroup = Collections.emptyList();
|
withinGroup = Collections.emptyList();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
walker.getCurrentClauseStack().push( Clause.ORDER );
|
walker.getCurrentClauseStack().push( Clause.WITHIN_GROUP );
|
||||||
try {
|
try {
|
||||||
final List<SqmSortSpecification> sortSpecifications = this.withinGroup.getSortSpecifications();
|
final List<SqmSortSpecification> sortSpecifications = this.withinGroup.getSortSpecifications();
|
||||||
withinGroup = new ArrayList<>( sortSpecifications.size() );
|
withinGroup = new ArrayList<>( sortSpecifications.size() );
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.query.sqm.produce.function.FunctionParameterType;
|
||||||
import org.hibernate.query.sqm.produce.function.NamedFunctionDescriptorBuilder;
|
import org.hibernate.query.sqm.produce.function.NamedFunctionDescriptorBuilder;
|
||||||
import org.hibernate.query.sqm.produce.function.PatternFunctionDescriptorBuilder;
|
import org.hibernate.query.sqm.produce.function.PatternFunctionDescriptorBuilder;
|
||||||
import org.hibernate.type.BasicType;
|
import org.hibernate.type.BasicType;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
@ -305,8 +306,16 @@ public class SqmFunctionRegistry {
|
||||||
BasicType type,
|
BasicType type,
|
||||||
String pattern0,
|
String pattern0,
|
||||||
String pattern1,
|
String pattern1,
|
||||||
FunctionParameterType parameterType) {
|
FunctionParameterType parameterType,
|
||||||
return registerPatterns( name, type, new FunctionParameterType[]{parameterType}, pattern0, pattern1 );
|
TypeConfiguration typeConfiguration) {
|
||||||
|
return registerPatterns(
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
new FunctionParameterType[] { parameterType },
|
||||||
|
typeConfiguration,
|
||||||
|
pattern0,
|
||||||
|
pattern1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -320,10 +329,17 @@ public class SqmFunctionRegistry {
|
||||||
String pattern1,
|
String pattern1,
|
||||||
String pattern2,
|
String pattern2,
|
||||||
FunctionParameterType parameterType1,
|
FunctionParameterType parameterType1,
|
||||||
FunctionParameterType parameterType2) {
|
FunctionParameterType parameterType2,
|
||||||
return registerPatterns( name, type,
|
TypeConfiguration typeConfiguration) {
|
||||||
new FunctionParameterType[]{parameterType1,parameterType2},
|
return registerPatterns(
|
||||||
null, pattern1, pattern2 );
|
name,
|
||||||
|
type,
|
||||||
|
new FunctionParameterType[] { parameterType1, parameterType2 },
|
||||||
|
typeConfiguration,
|
||||||
|
null,
|
||||||
|
pattern1,
|
||||||
|
pattern2
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -338,10 +354,18 @@ public class SqmFunctionRegistry {
|
||||||
String pattern3,
|
String pattern3,
|
||||||
FunctionParameterType parameterType1,
|
FunctionParameterType parameterType1,
|
||||||
FunctionParameterType parameterType2,
|
FunctionParameterType parameterType2,
|
||||||
FunctionParameterType parameterType3) {
|
FunctionParameterType parameterType3,
|
||||||
return registerPatterns( name, type,
|
TypeConfiguration typeConfiguration) {
|
||||||
new FunctionParameterType[]{parameterType1,parameterType2,parameterType3},
|
return registerPatterns(
|
||||||
null, null, pattern2, pattern3 );
|
name,
|
||||||
|
type,
|
||||||
|
new FunctionParameterType[] { parameterType1, parameterType2, parameterType3 },
|
||||||
|
typeConfiguration,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
pattern2,
|
||||||
|
pattern3
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -357,16 +381,31 @@ public class SqmFunctionRegistry {
|
||||||
FunctionParameterType parameterType1,
|
FunctionParameterType parameterType1,
|
||||||
FunctionParameterType parameterType2,
|
FunctionParameterType parameterType2,
|
||||||
FunctionParameterType parameterType3,
|
FunctionParameterType parameterType3,
|
||||||
FunctionParameterType parameterType4) {
|
FunctionParameterType parameterType4,
|
||||||
return registerPatterns( name, type,
|
TypeConfiguration typeConfiguration) {
|
||||||
new FunctionParameterType[]{parameterType1,parameterType2,parameterType3, parameterType4},
|
return registerPatterns(
|
||||||
null, null, null, pattern3, pattern4 );
|
name,
|
||||||
|
type,
|
||||||
|
new FunctionParameterType[] {
|
||||||
|
parameterType1,
|
||||||
|
parameterType2,
|
||||||
|
parameterType3,
|
||||||
|
parameterType4
|
||||||
|
},
|
||||||
|
typeConfiguration,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
pattern3,
|
||||||
|
pattern4
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MultipatternSqmFunctionDescriptor registerPatterns(
|
private MultipatternSqmFunctionDescriptor registerPatterns(
|
||||||
String name,
|
String name,
|
||||||
BasicType<?> type,
|
BasicType<?> type,
|
||||||
FunctionParameterType[] parameterTypes,
|
FunctionParameterType[] parameterTypes,
|
||||||
|
TypeConfiguration typeConfiguration,
|
||||||
String... patterns) {
|
String... patterns) {
|
||||||
SqmFunctionDescriptor[] descriptors =
|
SqmFunctionDescriptor[] descriptors =
|
||||||
new SqmFunctionDescriptor[patterns.length];
|
new SqmFunctionDescriptor[patterns.length];
|
||||||
|
@ -383,7 +422,7 @@ public class SqmFunctionRegistry {
|
||||||
}
|
}
|
||||||
|
|
||||||
MultipatternSqmFunctionDescriptor function =
|
MultipatternSqmFunctionDescriptor function =
|
||||||
new MultipatternSqmFunctionDescriptor( name, descriptors, type, parameterTypes );
|
new MultipatternSqmFunctionDescriptor( name, descriptors, type, typeConfiguration, parameterTypes );
|
||||||
register( name, function );
|
register( name, function );
|
||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1340,7 +1340,8 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
||||||
name,
|
name,
|
||||||
true,
|
true,
|
||||||
null,
|
null,
|
||||||
StandardFunctionReturnTypeResolvers.invariant( resultType )
|
StandardFunctionReturnTypeResolvers.invariant( resultType ),
|
||||||
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -402,18 +402,18 @@ public class SqmUtil {
|
||||||
List<SqmParameter<?>> sqmParameters,
|
List<SqmParameter<?>> sqmParameters,
|
||||||
SqmParameterMappingModelResolutionAccess mappingModelResolutionAccess,
|
SqmParameterMappingModelResolutionAccess mappingModelResolutionAccess,
|
||||||
SessionFactoryImplementor sessionFactory) {
|
SessionFactoryImplementor sessionFactory) {
|
||||||
if ( binding.getType() != null ) {
|
if ( binding.getBindType() instanceof Bindable ) {
|
||||||
return binding.getType();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( binding.getBindType() != null && binding.getBindType() instanceof Bindable ) {
|
|
||||||
return (Bindable) binding.getBindType();
|
return (Bindable) binding.getBindType();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( parameter.getHibernateType() != null && parameter.getHibernateType() instanceof Bindable ) {
|
if ( parameter.getHibernateType() instanceof Bindable ) {
|
||||||
return (Bindable) parameter.getHibernateType();
|
return (Bindable) parameter.getHibernateType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( binding.getType() != null ) {
|
||||||
|
return binding.getType();
|
||||||
|
}
|
||||||
|
|
||||||
for ( int i = 0; i < sqmParameters.size(); i++ ) {
|
for ( int i = 0; i < sqmParameters.size(); i++ ) {
|
||||||
final MappingModelExpressible<?> mappingModelType = mappingModelResolutionAccess
|
final MappingModelExpressible<?> mappingModelType = mappingModelResolutionAccess
|
||||||
.getResolvedMappingModelType( sqmParameters.get( i ) );
|
.getResolvedMappingModelType( sqmParameters.get( i ) );
|
||||||
|
@ -425,8 +425,7 @@ public class SqmUtil {
|
||||||
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
|
final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration();
|
||||||
|
|
||||||
// assume we have (or can create) a mapping for the parameter's Java type
|
// assume we have (or can create) a mapping for the parameter's Java type
|
||||||
BasicType basicType = typeConfiguration.standardBasicTypeForJavaType( parameter.getParameterType() );
|
return typeConfiguration.standardBasicTypeForJavaType( parameter.getParameterType() );
|
||||||
return basicType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SqmStatement.ParameterResolutions resolveParameters(SqmStatement<?> statement) {
|
public static SqmStatement.ParameterResolutions resolveParameters(SqmStatement<?> statement) {
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* 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.query.sqm.produce.function;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||||
|
import org.hibernate.query.sqm.sql.SqmToSqlAstConverter;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pluggable strategy for resolving a function argument type for a specific call.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public interface FunctionArgumentTypeResolver {
|
||||||
|
/**
|
||||||
|
* Resolve the argument type for a function given its context-implied return type.
|
||||||
|
* <p/>
|
||||||
|
* NOTE : the _context-implied_ type is the type implied by where the function's
|
||||||
|
* occurs in the query. E.g., for an equality predicate (`something = some_function`)
|
||||||
|
* the implied type would be defined by the type of `something`.
|
||||||
|
*
|
||||||
|
* @return The resolved type.
|
||||||
|
*/
|
||||||
|
MappingModelExpressible<?> resolveFunctionArgumentType(
|
||||||
|
SqmFunction<?> function,
|
||||||
|
int argumentIndex,
|
||||||
|
SqmToSqlAstConverter converter);
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ public class NamedFunctionDescriptorBuilder {
|
||||||
|
|
||||||
private ArgumentsValidator argumentsValidator;
|
private ArgumentsValidator argumentsValidator;
|
||||||
private FunctionReturnTypeResolver returnTypeResolver;
|
private FunctionReturnTypeResolver returnTypeResolver;
|
||||||
|
private FunctionArgumentTypeResolver argumentTypeResolver;
|
||||||
|
|
||||||
private boolean useParenthesesWhenNoArgs = true;
|
private boolean useParenthesesWhenNoArgs = true;
|
||||||
private String argumentListSignature;
|
private String argumentListSignature;
|
||||||
|
@ -47,6 +48,11 @@ public class NamedFunctionDescriptorBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NamedFunctionDescriptorBuilder setArgumentTypeResolver(FunctionArgumentTypeResolver argumentTypeResolver) {
|
||||||
|
this.argumentTypeResolver = argumentTypeResolver;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public NamedFunctionDescriptorBuilder setArgumentCountBetween(int min, int max) {
|
public NamedFunctionDescriptorBuilder setArgumentCountBetween(int min, int max) {
|
||||||
return setArgumentsValidator( StandardArgumentsValidators.between( min, max ) );
|
return setArgumentsValidator( StandardArgumentsValidators.between( min, max ) );
|
||||||
}
|
}
|
||||||
|
@ -71,6 +77,7 @@ public class NamedFunctionDescriptorBuilder {
|
||||||
|
|
||||||
public NamedFunctionDescriptorBuilder setParameterTypes(FunctionParameterType... types) {
|
public NamedFunctionDescriptorBuilder setParameterTypes(FunctionParameterType... types) {
|
||||||
setArgumentsValidator( new ArgumentTypesValidator(argumentsValidator, types) );
|
setArgumentsValidator( new ArgumentTypesValidator(argumentsValidator, types) );
|
||||||
|
setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.invariant( types ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +106,7 @@ public class NamedFunctionDescriptorBuilder {
|
||||||
useParenthesesWhenNoArgs,
|
useParenthesesWhenNoArgs,
|
||||||
argumentsValidator,
|
argumentsValidator,
|
||||||
returnTypeResolver,
|
returnTypeResolver,
|
||||||
|
argumentTypeResolver,
|
||||||
registrationKey,
|
registrationKey,
|
||||||
functionKind,
|
functionKind,
|
||||||
argumentListSignature,
|
argumentListSignature,
|
||||||
|
|
|
@ -26,6 +26,7 @@ public class PatternFunctionDescriptorBuilder {
|
||||||
|
|
||||||
private ArgumentsValidator argumentsValidator;
|
private ArgumentsValidator argumentsValidator;
|
||||||
private FunctionReturnTypeResolver returnTypeResolver;
|
private FunctionReturnTypeResolver returnTypeResolver;
|
||||||
|
private FunctionArgumentTypeResolver argumentTypeResolver;
|
||||||
private SqlAstNodeRenderingMode argumentRenderingMode = SqlAstNodeRenderingMode.DEFAULT;
|
private SqlAstNodeRenderingMode argumentRenderingMode = SqlAstNodeRenderingMode.DEFAULT;
|
||||||
|
|
||||||
public PatternFunctionDescriptorBuilder(
|
public PatternFunctionDescriptorBuilder(
|
||||||
|
@ -44,8 +45,14 @@ public class PatternFunctionDescriptorBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PatternFunctionDescriptorBuilder setArgumentTypeResolver(FunctionArgumentTypeResolver argumentTypeResolver) {
|
||||||
|
this.argumentTypeResolver = argumentTypeResolver;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public PatternFunctionDescriptorBuilder setParameterTypes(FunctionParameterType... types) {
|
public PatternFunctionDescriptorBuilder setParameterTypes(FunctionParameterType... types) {
|
||||||
setArgumentsValidator( new ArgumentTypesValidator(argumentsValidator, types) );
|
setArgumentsValidator( new ArgumentTypesValidator(argumentsValidator, types) );
|
||||||
|
setArgumentTypeResolver( StandardFunctionArgumentTypeResolvers.invariant( types ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +69,7 @@ public class PatternFunctionDescriptorBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PatternFunctionDescriptorBuilder setInvariantType(BasicType invariantType) {
|
public PatternFunctionDescriptorBuilder setInvariantType(BasicType<?> invariantType) {
|
||||||
setReturnTypeResolver( StandardFunctionReturnTypeResolvers.invariant( invariantType ) );
|
setReturnTypeResolver( StandardFunctionReturnTypeResolvers.invariant( invariantType ) );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -86,6 +93,7 @@ public class PatternFunctionDescriptorBuilder {
|
||||||
new PatternRenderer( pattern, argumentRenderingMode ),
|
new PatternRenderer( pattern, argumentRenderingMode ),
|
||||||
argumentsValidator,
|
argumentsValidator,
|
||||||
returnTypeResolver,
|
returnTypeResolver,
|
||||||
|
argumentTypeResolver,
|
||||||
registrationKey,
|
registrationKey,
|
||||||
functionKind,
|
functionKind,
|
||||||
argumentListSignature
|
argumentListSignature
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* 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.query.sqm.produce.function;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.Date;
|
||||||
|
import java.sql.Time;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||||
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public final class StandardFunctionArgumentTypeResolvers {
|
||||||
|
/**
|
||||||
|
* Disallow instantiation
|
||||||
|
*/
|
||||||
|
private StandardFunctionArgumentTypeResolvers() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final FunctionArgumentTypeResolver NULL = (function, argumentIndex, converter) -> {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final FunctionArgumentTypeResolver IMPLIED_RESULT_TYPE = (function, argumentIndex, converter) -> {
|
||||||
|
return converter.resolveFunctionImpliedReturnType();
|
||||||
|
};
|
||||||
|
|
||||||
|
public static final FunctionArgumentTypeResolver ARGUMENT_OR_IMPLIED_RESULT_TYPE = (function, argumentIndex, converter) -> {
|
||||||
|
final List<? extends SqmTypedNode<?>> arguments = function.getArguments();
|
||||||
|
final int argumentsSize = arguments.size();
|
||||||
|
for ( int i = 0 ; i < argumentIndex; i++ ) {
|
||||||
|
final SqmTypedNode<?> node = arguments.get( i );
|
||||||
|
if ( node instanceof SqmExpression<?> ) {
|
||||||
|
final MappingModelExpressible<?> expressible = converter.determineValueMapping( (SqmExpression<?>) node );
|
||||||
|
if ( expressible != null ) {
|
||||||
|
return expressible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( int i = argumentIndex + 1 ; i < argumentsSize; i++ ) {
|
||||||
|
final SqmTypedNode<?> node = arguments.get( i );
|
||||||
|
if ( node instanceof SqmExpression<?> ) {
|
||||||
|
final MappingModelExpressible<?> expressible = converter.determineValueMapping( (SqmExpression<?>) node );
|
||||||
|
if ( expressible != null ) {
|
||||||
|
return expressible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return converter.resolveFunctionImpliedReturnType();
|
||||||
|
};
|
||||||
|
|
||||||
|
public static FunctionArgumentTypeResolver invariant(
|
||||||
|
TypeConfiguration typeConfiguration,
|
||||||
|
FunctionParameterType type) {
|
||||||
|
final MappingModelExpressible<?> expressible = getMappingModelExpressible( typeConfiguration, type );
|
||||||
|
return (function, argumentIndex, converter) -> expressible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FunctionArgumentTypeResolver invariant(
|
||||||
|
TypeConfiguration typeConfiguration,
|
||||||
|
FunctionParameterType... types) {
|
||||||
|
final MappingModelExpressible<?>[] expressibles = new MappingModelExpressible[types.length];
|
||||||
|
for ( int i = 0; i < types.length; i++ ) {
|
||||||
|
expressibles[i] = getMappingModelExpressible( typeConfiguration, types[i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
return (function, argumentIndex, converter) -> expressibles[argumentIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FunctionArgumentTypeResolver invariant(FunctionParameterType... types) {
|
||||||
|
return (function, argumentIndex, converter) -> getMappingModelExpressible(
|
||||||
|
function.nodeBuilder().getTypeConfiguration(),
|
||||||
|
types[argumentIndex]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FunctionArgumentTypeResolver impliedOrInvariant(
|
||||||
|
TypeConfiguration typeConfiguration,
|
||||||
|
FunctionParameterType type) {
|
||||||
|
final MappingModelExpressible<?> expressible = getMappingModelExpressible( typeConfiguration, type );
|
||||||
|
return (function, argumentIndex, converter) -> {
|
||||||
|
final MappingModelExpressible<?> mappingModelExpressible = converter.resolveFunctionImpliedReturnType();
|
||||||
|
if ( mappingModelExpressible != null ) {
|
||||||
|
return mappingModelExpressible;
|
||||||
|
}
|
||||||
|
return expressible;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FunctionArgumentTypeResolver argumentsOrImplied(int... indices) {
|
||||||
|
return (function, argumentIndex, converter) -> {
|
||||||
|
final List<? extends SqmTypedNode<?>> arguments = function.getArguments();
|
||||||
|
final int argumentsSize = arguments.size();
|
||||||
|
for ( int index : indices ) {
|
||||||
|
if ( index >= argumentIndex || index >= argumentsSize ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
final SqmTypedNode<?> node = arguments.get( index );
|
||||||
|
if ( node instanceof SqmExpression<?> ) {
|
||||||
|
final MappingModelExpressible<?> expressible = converter.determineValueMapping( (SqmExpression<?>) node );
|
||||||
|
if ( expressible != null ) {
|
||||||
|
return expressible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( int index : indices ) {
|
||||||
|
if ( index <= argumentIndex || index >= argumentsSize ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
final SqmTypedNode<?> node = arguments.get( index );
|
||||||
|
if ( node instanceof SqmExpression<?> ) {
|
||||||
|
final MappingModelExpressible<?> expressible = converter.determineValueMapping( (SqmExpression<?>) node );
|
||||||
|
if ( expressible != null ) {
|
||||||
|
return expressible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return converter.resolveFunctionImpliedReturnType();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FunctionArgumentTypeResolver composite(FunctionArgumentTypeResolver... resolvers) {
|
||||||
|
return (function, argumentIndex, converter) -> {
|
||||||
|
return resolvers[argumentIndex].resolveFunctionArgumentType( function, argumentIndex, converter );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MappingModelExpressible<?> getMappingModelExpressible(
|
||||||
|
TypeConfiguration typeConfiguration,
|
||||||
|
FunctionParameterType type) {
|
||||||
|
switch ( type ) {
|
||||||
|
case STRING:
|
||||||
|
return typeConfiguration.getBasicTypeForJavaType( String.class );
|
||||||
|
case NUMERIC:
|
||||||
|
return typeConfiguration.getBasicTypeForJavaType( BigDecimal.class );
|
||||||
|
case INTEGER:
|
||||||
|
return typeConfiguration.getBasicTypeForJavaType( Integer.class );
|
||||||
|
case TEMPORAL:
|
||||||
|
return typeConfiguration.getBasicTypeForJavaType( Timestamp.class );
|
||||||
|
case DATE:
|
||||||
|
return typeConfiguration.getBasicTypeForJavaType( Date.class );
|
||||||
|
case TIME:
|
||||||
|
return typeConfiguration.getBasicTypeForJavaType( Time.class );
|
||||||
|
case BOOLEAN:
|
||||||
|
return typeConfiguration.getBasicTypeForJavaType( Boolean.class );
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ package org.hibernate.query.sqm.produce.function.internal;
|
||||||
|
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
|
import org.hibernate.sql.ast.Clause;
|
||||||
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
import org.hibernate.sql.ast.SqlAstNodeRenderingMode;
|
||||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||||
|
@ -189,8 +190,10 @@ public class PatternRenderer {
|
||||||
if ( arg != null ) {
|
if ( arg != null ) {
|
||||||
sqlAppender.appendSql( chunks[i] );
|
sqlAppender.appendSql( chunks[i] );
|
||||||
if ( caseWrapper && !( arg instanceof Distinct ) && !( arg instanceof Star ) ) {
|
if ( caseWrapper && !( arg instanceof Distinct ) && !( arg instanceof Star ) ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( "case when " );
|
sqlAppender.appendSql( "case when " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( " then " );
|
sqlAppender.appendSql( " then " );
|
||||||
translator.render( arg, argumentRenderingMode );
|
translator.render( arg, argumentRenderingMode );
|
||||||
sqlAppender.appendSql( " else null end" );
|
sqlAppender.appendSql( " else null end" );
|
||||||
|
@ -209,8 +212,10 @@ public class PatternRenderer {
|
||||||
}
|
}
|
||||||
if ( arg != null ) {
|
if ( arg != null ) {
|
||||||
if ( caseWrapper && !( arg instanceof Distinct ) && !( arg instanceof Star ) ) {
|
if ( caseWrapper && !( arg instanceof Distinct ) && !( arg instanceof Star ) ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( "case when " );
|
sqlAppender.appendSql( "case when " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
sqlAppender.appendSql( " then " );
|
sqlAppender.appendSql( " then " );
|
||||||
translator.render( arg, argumentRenderingMode );
|
translator.render( arg, argumentRenderingMode );
|
||||||
sqlAppender.appendSql( " else null end" );
|
sqlAppender.appendSql( " else null end" );
|
||||||
|
@ -226,6 +231,7 @@ public class PatternRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
if ( withinGroup != null && !withinGroup.isEmpty() ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WITHIN_GROUP );
|
||||||
sqlAppender.appendSql( " within group (order by" );
|
sqlAppender.appendSql( " within group (order by" );
|
||||||
translator.render( withinGroup.get( 0 ), argumentRenderingMode );
|
translator.render( withinGroup.get( 0 ), argumentRenderingMode );
|
||||||
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
for ( int i = 1; i < withinGroup.size(); i++ ) {
|
||||||
|
@ -233,6 +239,7 @@ public class PatternRenderer {
|
||||||
translator.render( withinGroup.get( 0 ), argumentRenderingMode );
|
translator.render( withinGroup.get( 0 ), argumentRenderingMode );
|
||||||
}
|
}
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( fromFirst != null ) {
|
if ( fromFirst != null ) {
|
||||||
|
@ -253,9 +260,11 @@ public class PatternRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( filter != null && !caseWrapper ) {
|
if ( filter != null && !caseWrapper ) {
|
||||||
|
translator.getCurrentClauseStack().push( Clause.WHERE );
|
||||||
sqlAppender.appendSql( " filter (where " );
|
sqlAppender.appendSql( " filter (where " );
|
||||||
filter.accept( translator );
|
filter.accept( translator );
|
||||||
sqlAppender.appendSql( ')' );
|
sqlAppender.appendSql( ')' );
|
||||||
|
translator.getCurrentClauseStack().pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,7 @@ import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation;
|
||||||
import org.hibernate.query.sqm.tree.SqmJoinType;
|
import org.hibernate.query.sqm.tree.SqmJoinType;
|
||||||
import org.hibernate.query.sqm.tree.SqmStatement;
|
import org.hibernate.query.sqm.tree.SqmStatement;
|
||||||
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
|
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
||||||
import org.hibernate.query.sqm.tree.cte.SqmCteContainer;
|
import org.hibernate.query.sqm.tree.cte.SqmCteContainer;
|
||||||
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
|
import org.hibernate.query.sqm.tree.cte.SqmCteStatement;
|
||||||
import org.hibernate.query.sqm.tree.cte.SqmCteTable;
|
import org.hibernate.query.sqm.tree.cte.SqmCteTable;
|
||||||
|
@ -393,6 +394,8 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
private final QueryOptions queryOptions;
|
private final QueryOptions queryOptions;
|
||||||
private final LoadQueryInfluencers loadQueryInfluencers;
|
private final LoadQueryInfluencers loadQueryInfluencers;
|
||||||
|
|
||||||
|
private final Map<SqmParameter<?>, List<List<JdbcParameter>>> jdbcParamsBySqmParam = new IdentityHashMap<>();
|
||||||
|
private final JdbcParameters jdbcParameters = new JdbcParametersImpl();
|
||||||
private final DomainParameterXref domainParameterXref;
|
private final DomainParameterXref domainParameterXref;
|
||||||
private final QueryParameterBindings domainParameterBindings;
|
private final QueryParameterBindings domainParameterBindings;
|
||||||
private final Map<SqmParameter<?>, MappingModelExpressible<?>> sqmParameterMappingModelTypes = new LinkedHashMap<>();
|
private final Map<SqmParameter<?>, MappingModelExpressible<?>> sqmParameterMappingModelTypes = new LinkedHashMap<>();
|
||||||
|
@ -407,6 +410,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
private ForeignKeyDescriptor.Nature currentlyResolvingForeignKeySide;
|
private ForeignKeyDescriptor.Nature currentlyResolvingForeignKeySide;
|
||||||
private SqmQueryPart<?> currentSqmQueryPart;
|
private SqmQueryPart<?> currentSqmQueryPart;
|
||||||
private boolean containsCollectionFetches;
|
private boolean containsCollectionFetches;
|
||||||
|
private boolean trackSelectionsForGroup;
|
||||||
|
|
||||||
private final Map<String, PredicateCollector> collectionFilterPredicates = new HashMap<>();
|
private final Map<String, PredicateCollector> collectionFilterPredicates = new HashMap<>();
|
||||||
private List<Map.Entry<OrderByFragment, TableGroup>> orderByFragments;
|
private List<Map.Entry<OrderByFragment, TableGroup>> orderByFragments;
|
||||||
|
@ -436,6 +440,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
);
|
);
|
||||||
private final Stack<List<QueryTransformer>> queryTransformers = new StandardStack<>();
|
private final Stack<List<QueryTransformer>> queryTransformers = new StandardStack<>();
|
||||||
private boolean inTypeInference;
|
private boolean inTypeInference;
|
||||||
|
private Supplier<MappingModelExpressible<?>> functionImpliedResultTypeAccess;
|
||||||
|
|
||||||
private SqmByUnit appliedByUnit;
|
private SqmByUnit appliedByUnit;
|
||||||
private Expression adjustedTimestamp;
|
private Expression adjustedTimestamp;
|
||||||
|
@ -1573,8 +1578,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
return cteContainer;
|
return cteContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean trackSelectionsForGroup;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryPart visitQueryPart(SqmQueryPart<?> queryPart) {
|
public QueryPart visitQueryPart(SqmQueryPart<?> queryPart) {
|
||||||
return (QueryPart) super.visitQueryPart( queryPart );
|
return (QueryPart) super.visitQueryPart( queryPart );
|
||||||
|
@ -4079,6 +4082,17 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
return inferredType;
|
return inferredType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappingModelExpressible<?> resolveFunctionImpliedReturnType() {
|
||||||
|
if ( inTypeInference || functionImpliedResultTypeAccess == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
inTypeInference = true;
|
||||||
|
final MappingModelExpressible<?> inferredType = functionImpliedResultTypeAccess.get();
|
||||||
|
inTypeInference = false;
|
||||||
|
return inferredType;
|
||||||
|
}
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// General expressions
|
// General expressions
|
||||||
|
|
||||||
|
@ -4284,9 +4298,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<SqmParameter<?>, List<List<JdbcParameter>>> jdbcParamsBySqmParam = new IdentityHashMap<>();
|
|
||||||
private final JdbcParameters jdbcParameters = new JdbcParametersImpl();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<SqmParameter<?>, List<List<JdbcParameter>>> getJdbcParamsBySqmParam() {
|
public Map<SqmParameter<?>, List<List<JdbcParameter>>> getJdbcParamsBySqmParam() {
|
||||||
return jdbcParamsBySqmParam;
|
return jdbcParamsBySqmParam;
|
||||||
|
@ -4434,7 +4445,8 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MappingModelExpressible<?> determineValueMapping(SqmExpression<?> sqmExpression) {
|
@Override
|
||||||
|
public MappingModelExpressible<?> determineValueMapping(SqmExpression<?> sqmExpression) {
|
||||||
if ( sqmExpression instanceof SqmParameter ) {
|
if ( sqmExpression instanceof SqmParameter ) {
|
||||||
return determineValueMapping( (SqmParameter<?>) sqmExpression );
|
return determineValueMapping( (SqmParameter<?>) sqmExpression );
|
||||||
}
|
}
|
||||||
|
@ -4562,16 +4574,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
final QueryParameterImplementor<?> queryParameter = domainParameterXref.getQueryParameter( sqmParameter );
|
final QueryParameterImplementor<?> queryParameter = domainParameterXref.getQueryParameter( sqmParameter );
|
||||||
final QueryParameterBinding<?> binding = domainParameterBindings.getBinding( queryParameter );
|
final QueryParameterBinding<?> binding = domainParameterBindings.getBinding( queryParameter );
|
||||||
|
|
||||||
if ( sqmParameter.getAnticipatedType() == null ) {
|
|
||||||
// this should indicate the condition that the user query did not define an
|
|
||||||
// explicit type in regard to this parameter. Here we should prefer the
|
|
||||||
// inferrable type and fallback to the binding type
|
|
||||||
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
|
|
||||||
if ( inferredValueMapping != null ) {
|
|
||||||
return inferredValueMapping;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BindableType<?> paramType = binding.getBindType();
|
BindableType<?> paramType = binding.getBindType();
|
||||||
if ( paramType == null ) {
|
if ( paramType == null ) {
|
||||||
paramType = queryParameter.getHibernateType();
|
paramType = queryParameter.getHibernateType();
|
||||||
|
@ -4581,12 +4583,25 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( paramType == null ) {
|
if ( paramType == null ) {
|
||||||
|
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
|
||||||
|
if ( inferredValueMapping != null ) {
|
||||||
|
return inferredValueMapping;
|
||||||
|
}
|
||||||
// Default to the Object type
|
// Default to the Object type
|
||||||
return basicType( Object.class );
|
return basicType( Object.class );
|
||||||
}
|
}
|
||||||
else if ( paramType instanceof MappingModelExpressible<?> && paramType.getBindableJavaType() == Object.class ) {
|
else if ( paramType instanceof MappingModelExpressible<?> ) {
|
||||||
return (MappingModelExpressible<?>) paramType;
|
return (MappingModelExpressible<?>) paramType;
|
||||||
}
|
}
|
||||||
|
else if ( sqmParameter.getAnticipatedType() == null ) {
|
||||||
|
// this should indicate the condition that the user query did not define an
|
||||||
|
// explicit type in regard to this parameter. Here we should prefer the
|
||||||
|
// inferrable type and fallback to resolving the binding type
|
||||||
|
final MappingModelExpressible<?> inferredValueMapping = getInferredValueMapping();
|
||||||
|
if ( inferredValueMapping != null ) {
|
||||||
|
return inferredValueMapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final SqmExpressible<?> paramSqmType = paramType.resolveExpressible( creationContext.getSessionFactory() );
|
final SqmExpressible<?> paramSqmType = paramType.resolveExpressible( creationContext.getSessionFactory() );
|
||||||
|
|
||||||
|
@ -4742,12 +4757,15 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Expression visitFunction(SqmFunction<?> sqmFunction) {
|
public Expression visitFunction(SqmFunction<?> sqmFunction) {
|
||||||
|
final Supplier<MappingModelExpressible<?>> oldFunctionImpliedResultTypeAccess = functionImpliedResultTypeAccess;
|
||||||
|
functionImpliedResultTypeAccess = inferrableTypeAccessStack.getCurrent();
|
||||||
inferrableTypeAccessStack.push( () -> null );
|
inferrableTypeAccessStack.push( () -> null );
|
||||||
try {
|
try {
|
||||||
return sqmFunction.convertToSqlAst( this );
|
return sqmFunction.convertToSqlAst( this );
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
inferrableTypeAccessStack.pop();
|
inferrableTypeAccessStack.pop();
|
||||||
|
functionImpliedResultTypeAccess = oldFunctionImpliedResultTypeAccess;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5426,35 +5444,18 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private <X> X visitWithLenientInferredType(SqmExpression<?> expression, SqmExpression<?> inferred) {
|
@Override
|
||||||
// inferrableTypeAccessStack.push(
|
public Object visitWithInferredType(
|
||||||
// () -> {
|
SqmVisitableNode node,
|
||||||
// MappingModelExpressible<?> definedType = creationContext
|
Supplier<MappingModelExpressible<?>> inferredTypeAccess) {
|
||||||
// .getDomainModel()
|
inferrableTypeAccessStack.push( inferredTypeAccess );
|
||||||
// .resolveMappingExpressible(
|
try {
|
||||||
// expression.getNodeType(),
|
return node.accept( this );
|
||||||
// getFromClauseIndex()::findTableGroup
|
}
|
||||||
// );
|
finally {
|
||||||
// if ( definedType != null ) {
|
inferrableTypeAccessStack.pop();
|
||||||
// return definedType;
|
}
|
||||||
// }
|
}
|
||||||
// definedType = creationContext
|
|
||||||
// .getDomainModel()
|
|
||||||
// .lenientlyResolveMappingExpressible(
|
|
||||||
// inferred.getNodeType(),
|
|
||||||
// getFromClauseIndex()::findTableGroup
|
|
||||||
// );
|
|
||||||
// return definedType;
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// try {
|
|
||||||
// return (X) expression.accept( this );
|
|
||||||
// }
|
|
||||||
// finally {
|
|
||||||
// inferrableTypeAccessStack.pop();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitAny(SqmAny<?> sqmAny) {
|
public Object visitAny(SqmAny<?> sqmAny) {
|
||||||
|
|
|
@ -7,10 +7,14 @@
|
||||||
package org.hibernate.query.sqm.sql;
|
package org.hibernate.query.sqm.sql;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.hibernate.LockMode;
|
import org.hibernate.LockMode;
|
||||||
import org.hibernate.internal.util.collections.Stack;
|
import org.hibernate.internal.util.collections.Stack;
|
||||||
|
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||||
import org.hibernate.query.sqm.spi.BaseSemanticQueryWalker;
|
import org.hibernate.query.sqm.spi.BaseSemanticQueryWalker;
|
||||||
|
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.sql.ast.Clause;
|
import org.hibernate.sql.ast.Clause;
|
||||||
|
@ -80,6 +84,23 @@ public class FakeSqmToSqlAstConverter extends BaseSemanticQueryWalker implements
|
||||||
public void registerQueryTransformer(QueryTransformer transformer) {
|
public void registerQueryTransformer(QueryTransformer transformer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappingModelExpressible<?> resolveFunctionImpliedReturnType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MappingModelExpressible<?> determineValueMapping(SqmExpression<?> sqmExpression) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object visitWithInferredType(
|
||||||
|
SqmVisitableNode node,
|
||||||
|
Supplier<MappingModelExpressible<?>> inferredTypeAccess) {
|
||||||
|
return node.accept( this );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Expression> expandSelfRenderingFunctionMultiValueParameter(SqmParameter<?> sqmParameter) {
|
public List<Expression> expandSelfRenderingFunctionMultiValueParameter(SqmParameter<?> sqmParameter) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -7,9 +7,13 @@
|
||||||
package org.hibernate.query.sqm.sql;
|
package org.hibernate.query.sqm.sql;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.hibernate.internal.util.collections.Stack;
|
import org.hibernate.internal.util.collections.Stack;
|
||||||
|
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||||
import org.hibernate.query.sqm.SemanticQueryWalker;
|
import org.hibernate.query.sqm.SemanticQueryWalker;
|
||||||
|
import org.hibernate.query.sqm.tree.SqmVisitableNode;
|
||||||
|
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||||
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
import org.hibernate.query.sqm.tree.expression.SqmParameter;
|
||||||
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
import org.hibernate.query.sqm.tree.predicate.SqmPredicate;
|
||||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||||
|
@ -28,6 +32,19 @@ public interface SqmToSqlAstConverter extends SemanticQueryWalker<Object>, SqlAs
|
||||||
|
|
||||||
void registerQueryTransformer(QueryTransformer transformer);
|
void registerQueryTransformer(QueryTransformer transformer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the function return type implied from the context within which it is used.
|
||||||
|
* If there is no current function being processed or no context implied type, the return is <code>null</code>.
|
||||||
|
*/
|
||||||
|
MappingModelExpressible<?> resolveFunctionImpliedReturnType();
|
||||||
|
|
||||||
|
MappingModelExpressible<?> determineValueMapping(SqmExpression<?> sqmExpression);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits the given node with the given inferred type access.
|
||||||
|
*/
|
||||||
|
Object visitWithInferredType(SqmVisitableNode node, Supplier<MappingModelExpressible<?>> inferredTypeAccess);
|
||||||
|
|
||||||
List<Expression> expandSelfRenderingFunctionMultiValueParameter(SqmParameter<?> sqmParameter);
|
List<Expression> expandSelfRenderingFunctionMultiValueParameter(SqmParameter<?> sqmParameter);
|
||||||
|
|
||||||
Predicate visitNestedTopLevelPredicate(SqmPredicate predicate);
|
Predicate visitNestedTopLevelPredicate(SqmPredicate predicate);
|
||||||
|
|
|
@ -52,6 +52,7 @@ public enum Clause {
|
||||||
FETCH,
|
FETCH,
|
||||||
FOR_UPDATE,
|
FOR_UPDATE,
|
||||||
OVER,
|
OVER,
|
||||||
|
WITHIN_GROUP,
|
||||||
PARTITION,
|
PARTITION,
|
||||||
CALL,
|
CALL,
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.sql.ast;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.hibernate.internal.util.collections.Stack;
|
||||||
import org.hibernate.query.spi.QueryOptions;
|
import org.hibernate.query.spi.QueryOptions;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
import org.hibernate.sql.ast.tree.select.QueryPart;
|
import org.hibernate.sql.ast.tree.select.QueryPart;
|
||||||
|
@ -34,6 +35,8 @@ public interface SqlAstTranslator<T extends JdbcOperation> extends SqlAstWalker
|
||||||
*/
|
*/
|
||||||
QueryPart getCurrentQueryPart();
|
QueryPart getCurrentQueryPart();
|
||||||
|
|
||||||
|
Stack<Clause> getCurrentClauseStack();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not the best spot for this. Its the table names collected while walking the SQL AST.
|
* Not the best spot for this. Its the table names collected while walking the SQL AST.
|
||||||
* Its ok here because the translator is consider a one-time-use. It just needs to be called
|
* Its ok here because the translator is consider a one-time-use. It just needs to be called
|
||||||
|
|
|
@ -587,11 +587,13 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
return ( (ComparisonPredicate) predicate ).getLeftHandExpression();
|
return ( (ComparisonPredicate) predicate ).getLeftHandExpression();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean inOverClause() {
|
protected boolean inOverOrWithinGroupClause() {
|
||||||
return clauseStack.findCurrentFirst(
|
return clauseStack.findCurrentFirst(
|
||||||
clause -> {
|
clause -> {
|
||||||
if ( clause == Clause.OVER ) {
|
switch ( clause ) {
|
||||||
return true;
|
case OVER:
|
||||||
|
case WITHIN_GROUP:
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -611,6 +613,11 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
return queryPartStack.getCurrent();
|
return queryPartStack.getCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stack<Clause> getCurrentClauseStack() {
|
||||||
|
return clauseStack;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T translate(JdbcParameterBindings jdbcParameterBindings, QueryOptions queryOptions) {
|
public T translate(JdbcParameterBindings jdbcParameterBindings, QueryOptions queryOptions) {
|
||||||
try {
|
try {
|
||||||
|
@ -2208,7 +2215,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
||||||
emulateSortSpecificationNullPrecedence( sortExpression, nullPrecedence );
|
emulateSortSpecificationNullPrecedence( sortExpression, nullPrecedence );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( inOverClause() ) {
|
if ( inOverOrWithinGroupClause() ) {
|
||||||
resolveAliasedExpression( sortExpression ).accept( this );
|
resolveAliasedExpression( sortExpression ).accept( this );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -62,7 +62,6 @@ public class CoalesceTest extends BaseCoreFunctionalTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SkipForDialect(jiraKey = "HHH-10463", value = PostgreSQLDialect.class)
|
|
||||||
public void HHH_10463_NullInCoalesce() {
|
public void HHH_10463_NullInCoalesce() {
|
||||||
doInHibernate( this::sessionFactory, session -> {
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
TypedQuery<Person> query = session.createQuery( "from Person p where p.name = coalesce(:name, p.name) ", Person.class );
|
TypedQuery<Person> query = session.createQuery( "from Person p where p.name = coalesce(:name, p.name) ", Person.class );
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class SubqueryTest extends BaseSessionFactoryFunctionalTest {
|
||||||
String name,
|
String name,
|
||||||
ArgumentsValidator argumentsValidator,
|
ArgumentsValidator argumentsValidator,
|
||||||
FunctionReturnTypeResolver returnTypeResolver) {
|
FunctionReturnTypeResolver returnTypeResolver) {
|
||||||
super( name, argumentsValidator, returnTypeResolver );
|
super( name, argumentsValidator, returnTypeResolver, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -54,7 +54,8 @@ public class OrderByFragmentFunction extends AbstractSqmFunctionDescriptor {
|
||||||
super(
|
super(
|
||||||
FUNCTION_NAME,
|
FUNCTION_NAME,
|
||||||
StandardArgumentsValidators.exactly( 2 ),
|
StandardArgumentsValidators.exactly( 2 ),
|
||||||
StandardFunctionReturnTypeResolvers.useArgType( 1 )
|
StandardFunctionReturnTypeResolvers.useArgType( 1 ),
|
||||||
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
@ -174,9 +175,6 @@ public class OrderByFragmentFunction extends AbstractSqmFunctionDescriptor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
|
public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
|
||||||
final ReturnableType<?> resultType = resolveResultType(
|
|
||||||
walker.getCreationContext().getMappingMetamodel().getTypeConfiguration()
|
|
||||||
);
|
|
||||||
final String sqmAlias = ( (SqmLiteral<String>) getArguments().get( 0 ) ).getLiteralValue();
|
final String sqmAlias = ( (SqmLiteral<String>) getArguments().get( 0 ) ).getLiteralValue();
|
||||||
final String attributeRole = ( (SqmLiteral<String>) getArguments().get( 1 ) ).getLiteralValue();
|
final String attributeRole = ( (SqmLiteral<String>) getArguments().get( 1 ) ).getLiteralValue();
|
||||||
final TableGroup tableGroup = ( (FromClauseIndex) walker.getFromClauseAccess() ).findTableGroup(
|
final TableGroup tableGroup = ( (FromClauseIndex) walker.getFromClauseAccess() ).findTableGroup(
|
||||||
|
|
Loading…
Reference in New Issue