cleanups related to function registry
This commit is contained in:
parent
d269637f77
commit
f2f802645c
|
@ -32,7 +32,7 @@ class SessionFactoryObserverForNamedQueryValidation implements SessionFactoryObs
|
|||
|
||||
@Override
|
||||
public void sessionFactoryCreated(SessionFactory factory) {
|
||||
SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) factory;
|
||||
final SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) factory;
|
||||
final QueryEngine queryEngine = sessionFactory.getQueryEngine();
|
||||
queryEngine.getNamedObjectRepository().prepare( sessionFactory, metadata );
|
||||
if ( sessionFactory.getSessionFactoryOptions().isNamedQueryStartupCheckingEnabled() ) {
|
||||
|
|
|
@ -15,8 +15,8 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
|
|||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.CastType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderer;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||
|
@ -54,13 +54,10 @@ public class CastFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
}
|
||||
|
||||
private CastType getBooleanCastType(int preferredSqlTypeCodeForBoolean) {
|
||||
switch ( preferredSqlTypeCodeForBoolean ) {
|
||||
case Types.BIT:
|
||||
case Types.SMALLINT:
|
||||
case Types.TINYINT:
|
||||
return CastType.INTEGER_BOOLEAN;
|
||||
}
|
||||
return CastType.BOOLEAN;
|
||||
return switch (preferredSqlTypeCodeForBoolean) {
|
||||
case Types.BIT, Types.SMALLINT, Types.TINYINT -> CastType.INTEGER_BOOLEAN;
|
||||
default -> CastType.BOOLEAN;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,12 +91,12 @@ public class CastFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
Dialect dialect,
|
||||
SqlAstTranslator<?> walker) {
|
||||
final SessionFactoryImplementor sessionFactory = walker.getSessionFactory();
|
||||
final BasicType<?> stringType = sessionFactory.getTypeConfiguration()
|
||||
.getBasicTypeForJavaType( String.class );
|
||||
final SqmFunctionRegistry functionRegistry = sessionFactory.getQueryEngine()
|
||||
.getSqmFunctionRegistry();
|
||||
final SqmFunctionDescriptor concatDescriptor = functionRegistry.findFunctionDescriptor( "concat" );
|
||||
final SqmFunctionDescriptor arrayToStringDescriptor = functionRegistry.findFunctionDescriptor( "array_to_string" );
|
||||
final BasicType<?> stringType = sessionFactory.getTypeConfiguration().getBasicTypeForJavaType( String.class );
|
||||
final SqmFunctionRegistry functionRegistry = sessionFactory.getQueryEngine().getSqmFunctionRegistry();
|
||||
final FunctionRenderer concatDescriptor =
|
||||
(FunctionRenderer) functionRegistry.findFunctionDescriptor( "concat" );
|
||||
final FunctionRenderer arrayToStringDescriptor =
|
||||
(FunctionRenderer) functionRegistry.findFunctionDescriptor( "array_to_string" );
|
||||
final boolean caseWhen = dialect.isEmptyStringTreatedAsNull();
|
||||
if ( caseWhen ) {
|
||||
sqlAppender.append( "case when " );
|
||||
|
@ -107,13 +104,13 @@ public class CastFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
sqlAppender.append( " is null then null else " );
|
||||
}
|
||||
|
||||
( (AbstractSqmSelfRenderingFunctionDescriptor) concatDescriptor ).render(
|
||||
concatDescriptor.render(
|
||||
sqlAppender,
|
||||
List.of(
|
||||
new QueryLiteral<>( "[", stringType ),
|
||||
new SelfRenderingFunctionSqlAstExpression(
|
||||
"array_to_string",
|
||||
( (AbstractSqmSelfRenderingFunctionDescriptor) arrayToStringDescriptor ),
|
||||
arrayToStringDescriptor,
|
||||
List.of(
|
||||
arrayArgument,
|
||||
new QueryLiteral<>( ",", stringType ),
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.query.ReturnableType;
|
|||
import org.hibernate.query.sqm.CastType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionKind;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderer;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
|
||||
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
|
||||
|
@ -182,16 +183,15 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
// '' -> \0 + argumentNumber
|
||||
// In the end, the expression looks like the following:
|
||||
// count(distinct coalesce(nullif(coalesce(col1 || '', '\0'), ''), '\01') || '\0' || coalesce(nullif(coalesce(col2 || '', '\0'), ''), '\02'))
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor chr =
|
||||
(AbstractSqmSelfRenderingFunctionDescriptor) translator.getSessionFactory()
|
||||
.getQueryEngine()
|
||||
.getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( "chr" );
|
||||
final FunctionRenderer chrFunction =
|
||||
(FunctionRenderer)
|
||||
translator.getSessionFactory().getQueryEngine()
|
||||
.getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( "chr" );
|
||||
final List<Expression> chrArguments = List.of(
|
||||
new QueryLiteral<>(
|
||||
0,
|
||||
translator.getSessionFactory()
|
||||
.getTypeConfiguration()
|
||||
translator.getSessionFactory().getTypeConfiguration()
|
||||
.getBasicTypeForJavaType( Integer.class )
|
||||
)
|
||||
);
|
||||
|
@ -215,15 +215,15 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
sqlAppender.appendSql( "''" );
|
||||
}
|
||||
sqlAppender.appendSql( SqlAppender.COMMA_SEPARATOR_CHAR );
|
||||
chr.render( sqlAppender, chrArguments, returnType, translator );
|
||||
chrFunction.render( sqlAppender, chrArguments, returnType, translator );
|
||||
sqlAppender.appendSql( "),'')," );
|
||||
chr.render( sqlAppender, chrArguments, returnType, translator );
|
||||
chrFunction.render( sqlAppender, chrArguments, returnType, translator );
|
||||
sqlAppender.appendSql( concatOperator );
|
||||
sqlAppender.appendSql( "'" );
|
||||
sqlAppender.appendSql( argumentNumber );
|
||||
sqlAppender.appendSql( "')" );
|
||||
sqlAppender.appendSql( concatOperator );
|
||||
chr.render( sqlAppender, chrArguments, returnType, translator );
|
||||
chrFunction.render( sqlAppender, chrArguments, returnType, translator );
|
||||
sqlAppender.appendSql( concatOperator );
|
||||
sqlAppender.appendSql( "coalesce(nullif(coalesce(" );
|
||||
needsConcat = renderCastedArgument( sqlAppender, translator, expressions.get( i ) );
|
||||
|
@ -234,9 +234,9 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
sqlAppender.appendSql( "''" );
|
||||
}
|
||||
sqlAppender.appendSql( SqlAppender.COMMA_SEPARATOR_CHAR );
|
||||
chr.render( sqlAppender, chrArguments, returnType, translator );
|
||||
chrFunction.render( sqlAppender, chrArguments, returnType, translator );
|
||||
sqlAppender.appendSql( "),'')," );
|
||||
chr.render( sqlAppender, chrArguments, returnType, translator );
|
||||
chrFunction.render( sqlAppender, chrArguments, returnType, translator );
|
||||
sqlAppender.appendSql( concatOperator );
|
||||
sqlAppender.appendSql( "'" );
|
||||
sqlAppender.appendSql( argumentNumber );
|
||||
|
@ -424,8 +424,7 @@ public class CountFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
|
|||
|
||||
private boolean canReplaceWithStar(SqlAstNode arg, SqlAstTranslator<?> translator) {
|
||||
// To determine if we can replace the argument with a star, we must know if the argument is nullable
|
||||
if ( arg instanceof AbstractSqmPathInterpretation<?> ) {
|
||||
final AbstractSqmPathInterpretation<?> pathInterpretation = (AbstractSqmPathInterpretation<?>) arg;
|
||||
if ( arg instanceof AbstractSqmPathInterpretation<?> pathInterpretation ) {
|
||||
final TableGroup tableGroup = pathInterpretation.getTableGroup();
|
||||
final Expression sqlExpression = pathInterpretation.getSqlExpression();
|
||||
final JdbcMappingContainer expressionType = sqlExpression.getExpressionType();
|
||||
|
|
|
@ -10,7 +10,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
|
@ -47,6 +46,7 @@ import org.hibernate.type.SqlTypes;
|
|||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static org.hibernate.internal.util.StringHelper.splitFull;
|
||||
import static org.hibernate.query.sqm.BinaryArithmeticOperator.DIVIDE_PORTABLE;
|
||||
import static org.hibernate.query.sqm.BinaryArithmeticOperator.MODULO;
|
||||
import static org.hibernate.query.sqm.ComparisonOperator.GREATER_THAN_OR_EQUAL;
|
||||
|
@ -200,21 +200,17 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
public Expression convertToSqlAst(SqmToSqlAstConverter walker) {
|
||||
final List<SqlAstNode> arguments = resolveSqlAstArguments( getArguments(), walker );
|
||||
final ReturnableType<?> resultType = resolveResultType( walker );
|
||||
final MappingModelExpressible<?> mappingModelExpressible = resultType == null ? null : getMappingModelExpressible(
|
||||
walker,
|
||||
resultType,
|
||||
arguments
|
||||
);
|
||||
final MappingModelExpressible<?> mappingModelExpressible =
|
||||
resultType == null
|
||||
? null
|
||||
: getMappingModelExpressible( walker, resultType, arguments );
|
||||
final SqlAstNode expression = arguments.get( 0 );
|
||||
if ( expression instanceof SqlTupleContainer ) {
|
||||
// SqlTupleContainer means this is a composite temporal type i.e. uses `@TimeZoneStorage(COLUMN)`
|
||||
// The support for this kind of type requires that we inject the offset from the second column
|
||||
// as literal into the pattern, and apply the formatting on the date time part
|
||||
final SqlTuple sqlTuple = ( (SqlTupleContainer) expression ).getSqlTuple();
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor timestampaddFunction = getFunction(
|
||||
walker,
|
||||
"timestampadd"
|
||||
);
|
||||
final FunctionRenderer timestampaddFunction = getFunction( walker, "timestampadd" );
|
||||
final BasicType<Integer> integerType = typeConfiguration.getBasicTypeRegistry()
|
||||
.resolve( StandardBasicTypes.INTEGER );
|
||||
arguments.set( 0, getOffsetAdjusted( sqlTuple, timestampaddFunction, integerType ) );
|
||||
|
@ -224,21 +220,13 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
final Format format = (Format) arguments.get( 1 );
|
||||
// If the format contains a time zone or offset, we must replace that with the offset column
|
||||
if ( format.getFormat().contains( "x" ) || !supportsPatternLiterals ) {
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor concatFunction = getFunction(
|
||||
walker,
|
||||
"concat"
|
||||
);
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor substringFunction = getFunction(
|
||||
walker,
|
||||
"substring",
|
||||
3
|
||||
);
|
||||
final FunctionRenderer concatFunction = getFunction( walker, "concat" );
|
||||
final FunctionRenderer substringFunction = getFunction( walker, "substring", 3 );
|
||||
final BasicType<String> stringType = typeConfiguration.getBasicTypeRegistry()
|
||||
.resolve( StandardBasicTypes.STRING );
|
||||
final Dialect dialect = walker.getCreationContext()
|
||||
.getSessionFactory()
|
||||
.getJdbcServices()
|
||||
.getDialect();
|
||||
final Dialect dialect =
|
||||
walker.getCreationContext().getSessionFactory().getJdbcServices()
|
||||
.getDialect();
|
||||
Expression formatExpression = null;
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final StringBuilderSqlAppender sqlAppender = new StringBuilderSqlAppender( sb );
|
||||
|
@ -250,7 +238,7 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
else {
|
||||
delimiter = "";
|
||||
}
|
||||
final String[] chunks = StringHelper.splitFull( "'", format.getFormat() );
|
||||
final String[] chunks = splitFull( "'", format.getFormat() );
|
||||
final Expression offsetExpression = sqlTuple.getExpressions().get( 1 );
|
||||
// Splitting by `'` will put actual format pattern parts to even indices and literal pattern parts
|
||||
// to uneven indices. We will only replace the time zone and offset pattern in the format pattern parts
|
||||
|
@ -260,17 +248,17 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
// xxx stands for the full offset i.e. `+01:00`
|
||||
// xx stands for the medium offset i.e. `+0100`
|
||||
// x stands for the small offset i.e. `+01`
|
||||
final String[] fullParts = StringHelper.splitFull( "xxx", chunks[i] );
|
||||
final String[] fullParts = splitFull( "xxx", chunks[i] );
|
||||
for ( int j = 0; j < fullParts.length; j++ ) {
|
||||
if ( fullParts[j].isEmpty() ) {
|
||||
continue;
|
||||
}
|
||||
final String[] mediumParts = StringHelper.splitFull( "xx", fullParts[j] );
|
||||
final String[] mediumParts = splitFull( "xx", fullParts[j] );
|
||||
for ( int k = 0; k < mediumParts.length; k++ ) {
|
||||
if ( mediumParts[k].isEmpty() ) {
|
||||
continue;
|
||||
}
|
||||
final String[] smallParts = StringHelper.splitFull( "x", mediumParts[k] );
|
||||
final String[] smallParts = splitFull( "x", mediumParts[k] );
|
||||
for ( int l = 0; l < smallParts.length; l++ ) {
|
||||
if ( smallParts[l].isEmpty() ) {
|
||||
continue;
|
||||
|
@ -394,15 +382,12 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
}
|
||||
|
||||
if ( !supportsPatternLiterals ) {
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor concatFunction = getFunction(
|
||||
walker,
|
||||
"concat"
|
||||
);
|
||||
final FunctionRenderer concatFunction = getFunction( walker, "concat" );
|
||||
final BasicType<String> stringType = typeConfiguration.getBasicTypeRegistry()
|
||||
.resolve( StandardBasicTypes.STRING );
|
||||
Expression formatExpression = null;
|
||||
final Format format = (Format) arguments.get( 1 );
|
||||
final String[] chunks = StringHelper.splitFull( "'", format.getFormat() );
|
||||
final String[] chunks = splitFull( "'", format.getFormat() );
|
||||
// Splitting by `'` will put actual format pattern parts to even indices and literal pattern parts
|
||||
// to uneven indices. We need to apply the format parts and then concatenate because the pattern
|
||||
// doesn't support literals
|
||||
|
@ -441,31 +426,27 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
);
|
||||
}
|
||||
|
||||
private AbstractSqmSelfRenderingFunctionDescriptor getFunction(SqmToSqlAstConverter walker, String name) {
|
||||
return (AbstractSqmSelfRenderingFunctionDescriptor) walker.getCreationContext()
|
||||
.getSessionFactory()
|
||||
.getQueryEngine()
|
||||
.getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( name );
|
||||
private FunctionRenderer getFunction(SqmToSqlAstConverter walker, String name) {
|
||||
return (FunctionRenderer)
|
||||
walker.getCreationContext().getSessionFactory().getQueryEngine()
|
||||
.getSqmFunctionRegistry().findFunctionDescriptor( name );
|
||||
}
|
||||
|
||||
private AbstractSqmSelfRenderingFunctionDescriptor getFunction(SqmToSqlAstConverter walker, String name, int argumentCount) {
|
||||
final SqmFunctionDescriptor functionDescriptor = walker.getCreationContext()
|
||||
.getSessionFactory()
|
||||
.getQueryEngine()
|
||||
.getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( name );
|
||||
if ( functionDescriptor instanceof MultipatternSqmFunctionDescriptor ) {
|
||||
return (AbstractSqmSelfRenderingFunctionDescriptor)
|
||||
( (MultipatternSqmFunctionDescriptor) functionDescriptor )
|
||||
.getFunction( argumentCount );
|
||||
private FunctionRenderer getFunction(SqmToSqlAstConverter walker, String name, int argumentCount) {
|
||||
final SqmFunctionDescriptor functionDescriptor =
|
||||
walker.getCreationContext().getSessionFactory().getQueryEngine().getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( name );
|
||||
if ( functionDescriptor instanceof MultipatternSqmFunctionDescriptor multipatternSqmFunctionDescriptor ) {
|
||||
return (FunctionRenderer) multipatternSqmFunctionDescriptor.getFunction( argumentCount );
|
||||
}
|
||||
else {
|
||||
return (FunctionRenderer) functionDescriptor;
|
||||
}
|
||||
return (AbstractSqmSelfRenderingFunctionDescriptor) functionDescriptor;
|
||||
}
|
||||
|
||||
private SqlAstNode getOffsetAdjusted(
|
||||
SqlTuple sqlTuple,
|
||||
AbstractSqmSelfRenderingFunctionDescriptor timestampaddFunction,
|
||||
FunctionRenderer timestampaddFunction,
|
||||
BasicType<Integer> integerType) {
|
||||
final Expression instantExpression = sqlTuple.getExpressions().get( 0 );
|
||||
final Expression offsetExpression = sqlTuple.getExpressions().get( 1 );
|
||||
|
@ -484,7 +465,7 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
}
|
||||
|
||||
private Expression createFullOffset(
|
||||
AbstractSqmSelfRenderingFunctionDescriptor concatFunction,
|
||||
FunctionRenderer concatFunction,
|
||||
BasicType<String> stringType,
|
||||
BasicType<Integer> integerType,
|
||||
Expression offsetExpression) {
|
||||
|
@ -527,8 +508,8 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
}
|
||||
|
||||
private Expression createMediumOffset(
|
||||
AbstractSqmSelfRenderingFunctionDescriptor concatFunction,
|
||||
AbstractSqmSelfRenderingFunctionDescriptor substringFunction,
|
||||
FunctionRenderer concatFunction,
|
||||
FunctionRenderer substringFunction,
|
||||
BasicType<String> stringType,
|
||||
BasicType<Integer> integerType,
|
||||
Expression offsetExpression) {
|
||||
|
@ -593,8 +574,8 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
}
|
||||
|
||||
private Expression createSmallOffset(
|
||||
AbstractSqmSelfRenderingFunctionDescriptor concatFunction,
|
||||
AbstractSqmSelfRenderingFunctionDescriptor substringFunction,
|
||||
FunctionRenderer concatFunction,
|
||||
FunctionRenderer substringFunction,
|
||||
BasicType<String> stringType,
|
||||
BasicType<Integer> integerType,
|
||||
Expression offsetExpression) {
|
||||
|
@ -621,7 +602,7 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
}
|
||||
|
||||
private Expression concatAsLiteral(
|
||||
AbstractSqmSelfRenderingFunctionDescriptor concatFunction,
|
||||
FunctionRenderer concatFunction,
|
||||
BasicType<String> stringType,
|
||||
String delimiter,
|
||||
Expression expression,
|
||||
|
@ -645,23 +626,24 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
}
|
||||
|
||||
private Expression concat(
|
||||
AbstractSqmSelfRenderingFunctionDescriptor concatFunction,
|
||||
FunctionRenderer concatFunction,
|
||||
BasicType<String> stringType,
|
||||
Expression expression,
|
||||
Expression expression2) {
|
||||
if ( expression == null ) {
|
||||
return expression2;
|
||||
}
|
||||
else if ( expression instanceof SelfRenderingFunctionSqlAstExpression
|
||||
&& "concat".equals( ( (SelfRenderingFunctionSqlAstExpression) expression ).getFunctionName() ) ) {
|
||||
List<SqlAstNode> list = (List<SqlAstNode>) ( (SelfRenderingFunctionSqlAstExpression) expression ).getArguments();
|
||||
else if ( expression instanceof SelfRenderingFunctionSqlAstExpression selfRenderingFunction
|
||||
&& "concat".equals( selfRenderingFunction.getFunctionName() ) ) {
|
||||
final List<SqlAstNode> list = (List<SqlAstNode>) selfRenderingFunction.getArguments();
|
||||
final SqlAstNode lastOperand = list.get( list.size() - 1 );
|
||||
if ( expression2 instanceof QueryLiteral<?> && lastOperand instanceof QueryLiteral<?> ) {
|
||||
if ( expression2 instanceof QueryLiteral<?> literal2
|
||||
&& lastOperand instanceof QueryLiteral<?> literalOperand ) {
|
||||
list.set(
|
||||
list.size() - 1,
|
||||
new QueryLiteral<>(
|
||||
( (QueryLiteral<?>) lastOperand ).getLiteralValue().toString() +
|
||||
( (QueryLiteral<?>) expression2 ).getLiteralValue().toString(),
|
||||
literalOperand.getLiteralValue().toString()
|
||||
+ literal2.getLiteralValue().toString(),
|
||||
stringType
|
||||
)
|
||||
);
|
||||
|
@ -671,17 +653,17 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
}
|
||||
return expression;
|
||||
}
|
||||
else if ( expression2 instanceof SelfRenderingFunctionSqlAstExpression
|
||||
&& "concat".equals( ( (SelfRenderingFunctionSqlAstExpression) expression2 ).getFunctionName() ) ) {
|
||||
final List<SqlAstNode> list = (List<SqlAstNode>)
|
||||
( (SelfRenderingFunctionSqlAstExpression) expression2 ).getArguments();
|
||||
else if ( expression2 instanceof SelfRenderingFunctionSqlAstExpression selfRenderingFunction
|
||||
&& "concat".equals( selfRenderingFunction.getFunctionName() ) ) {
|
||||
final List<SqlAstNode> list = (List<SqlAstNode>) selfRenderingFunction.getArguments();
|
||||
final SqlAstNode firstOperand = list.get( 0 );
|
||||
if ( expression instanceof QueryLiteral<?> && firstOperand instanceof QueryLiteral<?> ) {
|
||||
if ( expression instanceof QueryLiteral<?> literal
|
||||
&& firstOperand instanceof QueryLiteral<?> literalOperand ) {
|
||||
list.set(
|
||||
list.size() - 1,
|
||||
new QueryLiteral<>(
|
||||
( (QueryLiteral<?>) expression ).getLiteralValue().toString() +
|
||||
( (QueryLiteral<?>) firstOperand ).getLiteralValue().toString(),
|
||||
literal.getLiteralValue().toString() +
|
||||
literalOperand.getLiteralValue().toString(),
|
||||
stringType
|
||||
)
|
||||
);
|
||||
|
@ -691,10 +673,11 @@ public class FormatFunction extends AbstractSqmFunctionDescriptor implements Fun
|
|||
}
|
||||
return expression2;
|
||||
}
|
||||
else if ( expression instanceof QueryLiteral<?> && expression2 instanceof QueryLiteral<?> ) {
|
||||
else if ( expression instanceof QueryLiteral<?> literal
|
||||
&& expression2 instanceof QueryLiteral<?> literal2 ) {
|
||||
return new QueryLiteral<>(
|
||||
( (QueryLiteral<?>) expression ).getLiteralValue().toString() +
|
||||
( (QueryLiteral<?>) expression2 ).getLiteralValue().toString(),
|
||||
literal.getLiteralValue().toString() +
|
||||
literal2.getLiteralValue().toString(),
|
||||
stringType
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ package org.hibernate.dialect.function;
|
|||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
|
|
|
@ -12,7 +12,6 @@ import java.util.function.Supplier;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.metamodel.mapping.MappingModelExpressible;
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.TemporalUnit;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
|
|
|
@ -70,12 +70,11 @@ public class OracleArrayAggEmulation extends AbstractSqmSelfRenderingFunctionDes
|
|||
List<SortSpecification> withinGroup,
|
||||
ReturnableType<?> returnType,
|
||||
SqlAstTranslator<?> translator) {
|
||||
if ( !( returnType instanceof BasicPluralType<?, ?> ) ) {
|
||||
if ( !( returnType instanceof BasicPluralType<?, ?> pluralType ) ) {
|
||||
throw new SemanticException(
|
||||
"Oracle array_agg emulation requires a basic plural return type, but resolved return type was: " + returnType
|
||||
);
|
||||
}
|
||||
final BasicPluralType<?, ?> pluralType = (BasicPluralType<?, ?>) returnType;
|
||||
final boolean returnJson = pluralType.getJdbcType().getDefaultSqlTypeCode() == SqlTypes.JSON;
|
||||
if ( returnJson ) {
|
||||
sqlAppender.append( "json_arrayagg(" );
|
||||
|
|
|
@ -9,19 +9,12 @@ package org.hibernate.dialect.function.array;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.query.ReturnableType;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.produce.function.ArgumentTypesValidator;
|
||||
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
|
||||
import org.hibernate.query.sqm.produce.function.StandardFunctionArgumentTypeResolvers;
|
||||
import org.hibernate.sql.ast.SqlAstTranslator;
|
||||
import org.hibernate.sql.ast.spi.SqlAppender;
|
||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||
import org.hibernate.sql.ast.tree.expression.Expression;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.ANY;
|
||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.INTEGER;
|
||||
|
||||
/**
|
||||
* Oracle array_to_string function.
|
||||
*/
|
||||
|
|
|
@ -831,8 +831,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
}
|
||||
|
||||
protected <R> HqlInterpretation<R> interpretHql(String hql, Class<R> resultType) {
|
||||
final QueryEngine queryEngine = getFactory().getQueryEngine();
|
||||
return queryEngine.interpretHql( hql, resultType );
|
||||
return getFactory().getQueryEngine().interpretHql( hql, resultType );
|
||||
}
|
||||
|
||||
protected static void checkSelectionQuery(String hql, HqlInterpretation<?> hqlInterpretation) {
|
||||
|
@ -944,8 +943,9 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
}
|
||||
|
||||
protected NamedResultSetMappingMemento getResultSetMappingMemento(String resultSetMappingName) {
|
||||
final NamedResultSetMappingMemento resultSetMappingMemento = getFactory().getQueryEngine()
|
||||
.getNamedObjectRepository().getResultSetMappingMemento( resultSetMappingName );
|
||||
final NamedResultSetMappingMemento resultSetMappingMemento =
|
||||
getFactory().getQueryEngine().getNamedObjectRepository()
|
||||
.getResultSetMappingMemento( resultSetMappingName );
|
||||
if ( resultSetMappingMemento == null ) {
|
||||
throw new HibernateException( "Could not resolve specified result-set mapping name: "
|
||||
+ resultSetMappingName );
|
||||
|
@ -1053,14 +1053,12 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
}
|
||||
|
||||
private NamedSqmQueryMemento getSqmQueryMemento(String queryName) {
|
||||
return getFactory().getQueryEngine()
|
||||
.getNamedObjectRepository()
|
||||
return getFactory().getQueryEngine().getNamedObjectRepository()
|
||||
.getSqmQueryMemento( queryName );
|
||||
}
|
||||
|
||||
private NamedNativeQueryMemento getNativeQueryMemento(String queryName) {
|
||||
return getFactory().getQueryEngine()
|
||||
.getNamedObjectRepository()
|
||||
return getFactory().getQueryEngine().getNamedObjectRepository()
|
||||
.getNativeQueryMemento( queryName );
|
||||
}
|
||||
|
||||
|
@ -1327,17 +1325,18 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
public ProcedureCall getNamedProcedureCall(String name) {
|
||||
checkOpen();
|
||||
|
||||
final NamedCallableQueryMemento memento = factory.getQueryEngine()
|
||||
.getNamedObjectRepository().getCallableQueryMemento( name );
|
||||
final NamedCallableQueryMemento memento =
|
||||
factory.getQueryEngine().getNamedObjectRepository()
|
||||
.getCallableQueryMemento( name );
|
||||
if ( memento == null ) {
|
||||
throw new IllegalArgumentException(
|
||||
"Could not find named stored procedure call with that registration name : " + name
|
||||
);
|
||||
}
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
final ProcedureCall procedureCall = memento.makeProcedureCall( this );
|
||||
// procedureCall.setComment( "Named stored procedure call [" + name + "]" );
|
||||
return procedureCall;
|
||||
|
|
|
@ -51,25 +51,22 @@ public interface OrderingExpression extends Node {
|
|||
sortExpression = expression;
|
||||
}
|
||||
else {
|
||||
final QueryEngine queryEngine = creationState.getCreationContext()
|
||||
.getSessionFactory()
|
||||
.getQueryEngine();
|
||||
final SqmToSqlAstConverter converter;
|
||||
if ( creationState instanceof SqmToSqlAstConverter ) {
|
||||
converter = (SqmToSqlAstConverter) creationState;
|
||||
}
|
||||
else {
|
||||
converter = new FakeSqmToSqlAstConverter( creationState );
|
||||
}
|
||||
sortExpression = queryEngine
|
||||
.getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( "collate" )
|
||||
.generateSqmExpression(
|
||||
new SqmSelfRenderingExpression<>( walker -> expression, null, null ),
|
||||
null,
|
||||
queryEngine
|
||||
)
|
||||
.convertToSqlAst( converter );
|
||||
final QueryEngine queryEngine =
|
||||
creationState.getCreationContext().getSessionFactory()
|
||||
.getQueryEngine();
|
||||
final SqmToSqlAstConverter converter =
|
||||
creationState instanceof SqmToSqlAstConverter sqmToSqlAstConverter
|
||||
? sqmToSqlAstConverter
|
||||
: new FakeSqmToSqlAstConverter(creationState);
|
||||
sortExpression =
|
||||
queryEngine.getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( "collate" )
|
||||
.generateSqmExpression(
|
||||
new SqmSelfRenderingExpression<>( walker -> expression, null, null ),
|
||||
null,
|
||||
queryEngine
|
||||
)
|
||||
.convertToSqlAst( converter );
|
||||
}
|
||||
return sortExpression;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ import java.util.Collection;
|
|||
|
||||
import jakarta.persistence.metamodel.EntityType;
|
||||
|
||||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
|
||||
/**
|
||||
* Extension to the JPA {@link EntityType} contract.
|
||||
*
|
||||
|
|
|
@ -25,12 +25,10 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.graph.GraphSemantic;
|
||||
import org.hibernate.graph.RootGraph;
|
||||
import org.hibernate.graph.spi.RootGraphImplementor;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
@ -96,6 +94,9 @@ import jakarta.persistence.PersistenceException;
|
|||
import jakarta.persistence.TemporalType;
|
||||
import jakarta.persistence.TransactionRequiredException;
|
||||
|
||||
import static java.lang.Boolean.parseBoolean;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.hibernate.internal.util.StringHelper.join;
|
||||
import static org.hibernate.jpa.HibernateHints.HINT_CALLABLE_FUNCTION;
|
||||
import static org.hibernate.procedure.internal.NamedCallableQueryMementoImpl.ParameterMementoImpl.fromRegistration;
|
||||
import static org.hibernate.query.results.ResultSetMapping.resolveResultSetMapping;
|
||||
|
@ -163,9 +164,9 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
this.synchronizedQuerySpaces = new HashSet<>();
|
||||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultClasses );
|
||||
final String mappingId = procedureName + ":" + join( ",", resultClasses );
|
||||
|
||||
this.resultSetMapping = ResultSetMapping.resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
this.resultSetMapping = resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
|
||||
Util.resolveResultSetMappingClasses(
|
||||
resultClasses,
|
||||
|
@ -197,8 +198,8 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
this.synchronizedQuerySpaces = new HashSet<>();
|
||||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultSetMappingNames );
|
||||
this.resultSetMapping = ResultSetMapping.resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
final String mappingId = procedureName + ":" + join( ",", resultSetMappingNames );
|
||||
this.resultSetMapping = resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
|
||||
Util.resolveResultSetMappingNames(
|
||||
resultSetMappingNames,
|
||||
|
@ -224,7 +225,7 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
this.synchronizedQuerySpaces = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
|
||||
this.resultSetMapping = ResultSetMapping.resolveResultSetMapping( memento.getRegistrationName(), session.getSessionFactory() );
|
||||
this.resultSetMapping = resolveResultSetMapping( memento.getRegistrationName(), session.getSessionFactory() );
|
||||
|
||||
Util.resolveResultSetMappings(
|
||||
memento.getResultSetMappingNames(),
|
||||
|
@ -256,15 +257,15 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
this.synchronizedQuerySpaces = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultTypes );
|
||||
this.resultSetMapping = ResultSetMapping.resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
final String mappingId = procedureName + ":" + join( ",", resultTypes );
|
||||
this.resultSetMapping = resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
|
||||
Util.resolveResultSetMappings(
|
||||
null,
|
||||
resultTypes,
|
||||
resultSetMapping,
|
||||
synchronizedQuerySpaces::add,
|
||||
() -> getSession().getFactory()
|
||||
getSession()::getFactory
|
||||
);
|
||||
|
||||
applyOptions( memento );
|
||||
|
@ -283,8 +284,8 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
this.synchronizedQuerySpaces = CollectionHelper.makeCopy( memento.getQuerySpaces() );
|
||||
|
||||
final String mappingId = procedureName + ":" + StringHelper.join( ",", resultSetMappingNames );
|
||||
this.resultSetMapping = ResultSetMapping.resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
final String mappingId = procedureName + ":" + join( ",", resultSetMappingNames );
|
||||
this.resultSetMapping = resolveResultSetMapping( mappingId, session.getSessionFactory() );
|
||||
|
||||
Util.resolveResultSetMappings(
|
||||
resultSetMappingNames,
|
||||
|
@ -302,7 +303,7 @@ public class ProcedureCallImpl<R>
|
|||
|
||||
if ( memento.getHints() != null ) {
|
||||
final Object callableFunction = memento.getHints().get( HINT_CALLABLE_FUNCTION );
|
||||
if ( callableFunction != null && Boolean.parseBoolean( callableFunction.toString() ) ) {
|
||||
if ( callableFunction != null && parseBoolean( callableFunction.toString() ) ) {
|
||||
applyCallableFunctionHint();
|
||||
}
|
||||
}
|
||||
|
@ -313,13 +314,19 @@ public class ProcedureCallImpl<R>
|
|||
resultSetMapping.visitResultBuilders(
|
||||
(index, resultBuilder) -> resultTypes.add( resultBuilder.getJavaType() )
|
||||
);
|
||||
final TypeConfiguration typeConfiguration = getSessionFactory().getTypeConfiguration();
|
||||
final BasicType<?> type;
|
||||
if ( resultTypes.size() != 1 || ( type = typeConfiguration.getBasicTypeForJavaType( resultTypes.get( 0 ) ) ) == null ) {
|
||||
markAsFunctionCall( Types.REF_CURSOR );
|
||||
if ( resultTypes.size() == 1 ) {
|
||||
final BasicType<?> type =
|
||||
getSessionFactory().getTypeConfiguration()
|
||||
.getBasicTypeForJavaType( resultTypes.get(0) );
|
||||
if ( type != null ) {
|
||||
markAsFunctionCall( type );
|
||||
}
|
||||
else {
|
||||
markAsFunctionCallRefRefCursor();
|
||||
}
|
||||
}
|
||||
else {
|
||||
markAsFunctionCall( type );
|
||||
markAsFunctionCallRefRefCursor();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,6 +370,10 @@ public class ProcedureCallImpl<R>
|
|||
return this;
|
||||
}
|
||||
|
||||
private void markAsFunctionCallRefRefCursor() {
|
||||
functionReturn = new FunctionReturnImpl<>( this, Types.REF_CURSOR );
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureCallImpl<R> markAsFunctionCall(Class<?> resultType) {
|
||||
final TypeConfiguration typeConfiguration = getSessionFactory().getTypeConfiguration();
|
||||
|
@ -370,7 +381,8 @@ public class ProcedureCallImpl<R>
|
|||
if ( basicType == null ) {
|
||||
throw new IllegalArgumentException( "Could not resolve a BasicType for the java type: " + resultType.getName() );
|
||||
}
|
||||
return markAsFunctionCall( basicType );
|
||||
markAsFunctionCall( basicType );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -381,10 +393,11 @@ public class ProcedureCallImpl<R>
|
|||
if ( basicType == null ) {
|
||||
throw new IllegalArgumentException( "Could not resolve a BasicType for the java type: " + typeReference.getName() );
|
||||
}
|
||||
return markAsFunctionCall( basicType );
|
||||
markAsFunctionCall( basicType );
|
||||
return this;
|
||||
}
|
||||
|
||||
private ProcedureCallImpl<R> markAsFunctionCall(BasicType<?> basicType) {
|
||||
private void markAsFunctionCall(BasicType<?> basicType) {
|
||||
if ( resultSetMapping.getNumberOfResultBuilders() == 0 ) {
|
||||
// Function returns might not be represented as callable parameters,
|
||||
// but we still want to convert the result to the requested java type if possible
|
||||
|
@ -394,7 +407,6 @@ public class ProcedureCallImpl<R>
|
|||
}
|
||||
//noinspection unchecked
|
||||
functionReturn = new FunctionReturnImpl<>( this, (OutputableType<R>) basicType );
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -402,10 +414,6 @@ public class ProcedureCallImpl<R>
|
|||
return paramBindings;
|
||||
}
|
||||
|
||||
public SessionFactoryImplementor getSessionFactory() {
|
||||
return getSession().getFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Query<R> setOrder(List<Order<? super R>> orderList) {
|
||||
throw new UnsupportedOperationException("Ordering not supported for stored procedure calls");
|
||||
|
@ -814,7 +822,7 @@ public class ProcedureCallImpl<R>
|
|||
ProcedureParameterMetadataImpl parameterMetadata) {
|
||||
if ( parameterMetadata.getParameterStrategy() == ParameterStrategy.UNKNOWN ) {
|
||||
// none...
|
||||
return Collections.emptyList();
|
||||
return emptyList();
|
||||
}
|
||||
|
||||
final List<NamedCallableQueryMemento.ParameterMemento> mementos = new ArrayList<>();
|
||||
|
@ -922,8 +930,8 @@ public class ProcedureCallImpl<R>
|
|||
if ( rtn == null ) {
|
||||
return -1;
|
||||
}
|
||||
else if ( rtn instanceof UpdateCountOutput ) {
|
||||
return ( (UpdateCountOutput) rtn ).getUpdateCount();
|
||||
else if ( rtn instanceof UpdateCountOutput updateCount ) {
|
||||
return updateCount.getUpdateCount();
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
|
@ -944,7 +952,7 @@ public class ProcedureCallImpl<R>
|
|||
@Override
|
||||
protected List<R> doList() {
|
||||
if ( getMaxResults() == 0 ) {
|
||||
return Collections.emptyList();
|
||||
return emptyList();
|
||||
}
|
||||
try {
|
||||
final Output rtn = outputs().getCurrent();
|
||||
|
@ -1127,7 +1135,7 @@ public class ProcedureCallImpl<R>
|
|||
@Override
|
||||
public ProcedureCallImplementor<R> setHint(String hintName, Object value) {
|
||||
if ( HINT_CALLABLE_FUNCTION.equals( hintName ) ) {
|
||||
if ( value != null && Boolean.parseBoolean( value.toString() ) ) {
|
||||
if ( value != null && parseBoolean( value.toString() ) ) {
|
||||
applyCallableFunctionHint();
|
||||
}
|
||||
}
|
||||
|
@ -1249,7 +1257,7 @@ public class ProcedureCallImpl<R>
|
|||
}
|
||||
|
||||
@Override
|
||||
public Stream stream() {
|
||||
public Stream<R> stream() {
|
||||
return getResultStream();
|
||||
}
|
||||
|
||||
|
|
|
@ -54,10 +54,11 @@ public class Util {
|
|||
ResultSetMapping resultSetMapping,
|
||||
Consumer<String> querySpaceConsumer,
|
||||
ResultSetMappingResolutionContext context) {
|
||||
final NamedObjectRepository namedObjectRepository = context.getSessionFactory().getQueryEngine().getNamedObjectRepository();
|
||||
|
||||
final NamedObjectRepository namedObjectRepository =
|
||||
context.getSessionFactory().getQueryEngine().getNamedObjectRepository();
|
||||
for ( String resultSetMappingName : resultSetMappingNames ) {
|
||||
final NamedResultSetMappingMemento memento = namedObjectRepository.getResultSetMappingMemento( resultSetMappingName );
|
||||
final NamedResultSetMappingMemento memento =
|
||||
namedObjectRepository.getResultSetMappingMemento( resultSetMappingName );
|
||||
if ( memento == null ) {
|
||||
throw new UnknownSqlResultSetMappingException( "Unknown SqlResultSetMapping [" + resultSetMappingName + "]" );
|
||||
}
|
||||
|
|
|
@ -98,9 +98,9 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
|||
}
|
||||
|
||||
private <T> Class<T> treatTarget(String typeName) {
|
||||
final ManagedDomainType<T> managedType = creationState.getCreationContext()
|
||||
.getJpaMetamodel()
|
||||
.managedType( typeName );
|
||||
final ManagedDomainType<T> managedType =
|
||||
creationState.getCreationContext().getJpaMetamodel()
|
||||
.managedType( typeName );
|
||||
return managedType.getJavaType();
|
||||
}
|
||||
|
||||
|
@ -132,35 +132,23 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
|||
if ( isBase ) {
|
||||
isBase = false;
|
||||
|
||||
final SqmPathRegistry sqmPathRegistry = creationState.getProcessingStateStack()
|
||||
.getCurrent()
|
||||
.getPathRegistry();
|
||||
final SqmPathRegistry sqmPathRegistry =
|
||||
creationState.getProcessingStateStack().getCurrent()
|
||||
.getPathRegistry();
|
||||
|
||||
final SqmFrom<?,?> pathRootByAlias = sqmPathRegistry.findFromByAlias( identifier, true );
|
||||
if ( pathRootByAlias != null ) {
|
||||
// identifier is an alias (identification variable)
|
||||
validateAsRoot( pathRootByAlias );
|
||||
|
||||
if ( isTerminal ) {
|
||||
return pathRootByAlias;
|
||||
}
|
||||
else {
|
||||
return new DomainPathPart( pathRootByAlias );
|
||||
}
|
||||
return isTerminal ? pathRootByAlias : new DomainPathPart( pathRootByAlias );
|
||||
}
|
||||
|
||||
final SqmFrom<?, ?> pathRootByExposedNavigable = sqmPathRegistry.findFromExposing( identifier );
|
||||
if ( pathRootByExposedNavigable != null ) {
|
||||
// identifier is an "unqualified attribute reference"
|
||||
validateAsRoot( pathRootByExposedNavigable );
|
||||
|
||||
final SqmPath<?> sqmPath = pathRootByExposedNavigable.get( identifier );
|
||||
if ( isTerminal ) {
|
||||
return sqmPath;
|
||||
}
|
||||
else {
|
||||
return new DomainPathPart( sqmPath );
|
||||
}
|
||||
return isTerminal ? sqmPath : new DomainPathPart( sqmPath );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,14 +164,14 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
|||
//
|
||||
// todo (6.0) : finish this logic. and see above note in `! isTerminal` block
|
||||
|
||||
final SqmCreationContext creationContext = creationState.getCreationContext();
|
||||
|
||||
if ( ! isTerminal ) {
|
||||
return this;
|
||||
}
|
||||
|
||||
final String path = pathSoFar.toString();
|
||||
final SqmCreationContext creationContext = creationState.getCreationContext();
|
||||
final JpaMetamodel jpaMetamodel = creationContext.getJpaMetamodel();
|
||||
final String path = pathSoFar.toString();
|
||||
final String importableName = jpaMetamodel.qualifyImportableName( path );
|
||||
final NodeBuilder nodeBuilder = creationContext.getNodeBuilder();
|
||||
if ( importableName != null ) {
|
||||
|
@ -197,14 +185,10 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
|||
}
|
||||
|
||||
final SqmFunctionDescriptor functionDescriptor =
|
||||
creationContext.getQueryEngine()
|
||||
.getSqmFunctionRegistry()
|
||||
creationContext.getQueryEngine().getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( path );
|
||||
if ( functionDescriptor != null ) {
|
||||
return functionDescriptor.generateSqmExpression(
|
||||
null,
|
||||
creationContext.getQueryEngine()
|
||||
);
|
||||
return functionDescriptor.generateSqmExpression( null, creationContext.getQueryEngine() );
|
||||
}
|
||||
|
||||
// see if it is a named field/enum reference
|
||||
|
@ -212,7 +196,6 @@ public class BasicDotIdentifierConsumer implements DotIdentifierConsumer {
|
|||
if ( splitPosition > 0 ) {
|
||||
final String prefix = path.substring( 0, splitPosition );
|
||||
final String terminal = path.substring( splitPosition + 1 );
|
||||
|
||||
try {
|
||||
final EnumJavaType<?> enumType = jpaMetamodel.getEnumType( prefix );
|
||||
if ( enumType != null ) {
|
||||
|
|
|
@ -19,7 +19,6 @@ import org.hibernate.query.sqm.SqmExpressible;
|
|||
import org.hibernate.query.sqm.SqmPathSource;
|
||||
import org.hibernate.query.sqm.TreatException;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
|
||||
import org.hibernate.query.sqm.produce.function.FunctionArgumentException;
|
||||
import org.hibernate.query.sqm.tree.SqmCopyContext;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmExpression;
|
||||
import org.hibernate.query.sqm.tree.expression.SqmFunction;
|
||||
|
|
|
@ -73,7 +73,7 @@ import org.hibernate.query.sqm.FrameKind;
|
|||
import org.hibernate.query.sqm.FrameMode;
|
||||
import org.hibernate.query.sqm.SetOperator;
|
||||
import org.hibernate.query.sqm.UnaryArithmeticOperator;
|
||||
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.FunctionRenderer;
|
||||
import org.hibernate.query.sqm.function.MultipatternSqmFunctionDescriptor;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression;
|
||||
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
|
||||
|
@ -325,7 +325,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
// This field holds the index of where the "recursive" keyword should appear in the sqlBuffer.
|
||||
// See #visitCteContainer for details about the usage.
|
||||
private int withClauseRecursiveIndex = -1;
|
||||
private transient AbstractSqmSelfRenderingFunctionDescriptor castFunction;
|
||||
private transient FunctionRenderer castFunction;
|
||||
private transient LazySessionWrapperOptions lazySessionWrapperOptions;
|
||||
private transient BasicType<Integer> integerType;
|
||||
private transient BasicType<String> stringType;
|
||||
|
@ -361,7 +361,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
return sessionFactory;
|
||||
}
|
||||
|
||||
protected AbstractSqmSelfRenderingFunctionDescriptor castFunction() {
|
||||
protected FunctionRenderer castFunction() {
|
||||
if ( castFunction == null ) {
|
||||
castFunction = findSelfRenderingFunction( "cast", 2 );
|
||||
}
|
||||
|
@ -685,11 +685,10 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
expression.accept( this );
|
||||
return;
|
||||
}
|
||||
else if ( expression instanceof JdbcParameter ) {
|
||||
else if ( expression instanceof JdbcParameter parameter ) {
|
||||
if ( jdbcParameterBindings == null ) {
|
||||
throw new IllegalArgumentException( "Can't interpret expression because no parameter bindings are available" );
|
||||
}
|
||||
final JdbcParameter parameter = (JdbcParameter) expression;
|
||||
renderAsLiteral( parameter, getParameterBindValue( parameter ) );
|
||||
return;
|
||||
}
|
||||
|
@ -732,13 +731,10 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
|
||||
private static Boolean matchOverOrWithinGroupClauses(final Clause clause) {
|
||||
switch ( clause ) {
|
||||
case OVER:
|
||||
case WITHIN_GROUP:
|
||||
return Boolean.TRUE;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return switch (clause) {
|
||||
case OVER, WITHIN_GROUP -> Boolean.TRUE;
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
protected Stack<Clause> getClauseStack() {
|
||||
|
@ -772,16 +768,14 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
|
||||
private static CteStatement matchCteStatement(final Statement stmt, final String cteName) {
|
||||
if ( stmt instanceof CteContainer ) {
|
||||
final CteContainer cteContainer = (CteContainer) stmt;
|
||||
if ( stmt instanceof CteContainer cteContainer ) {
|
||||
return cteContainer.getCteStatement( cteName );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static CteContainer matchCteContainerByStatement(final Statement stmt, final String cteName) {
|
||||
if ( stmt instanceof CteContainer ) {
|
||||
final CteContainer cteContainer = (CteContainer) stmt;
|
||||
if ( stmt instanceof CteContainer cteContainer ) {
|
||||
if ( cteContainer.getCteStatement( cteName ) != null ) {
|
||||
return cteContainer;
|
||||
}
|
||||
|
@ -2835,8 +2829,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
* The mappings are implemented in {@link #wrapRowComponentAsOrderPreservingConcatArgument(Expression)}.
|
||||
*/
|
||||
private void emulateSearchClauseOrderWithString(SelectClause selectClause) {
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor concat = findSelfRenderingFunction( "concat", 2 );
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor coalesce = findSelfRenderingFunction( "coalesce", 2 );
|
||||
final FunctionRenderer concat = findSelfRenderingFunction( "concat", 2 );
|
||||
final FunctionRenderer coalesce = findSelfRenderingFunction( "coalesce", 2 );
|
||||
final BasicType<String> stringType = getStringType();
|
||||
final BasicType<Integer> integerType = getIntegerType();
|
||||
// Shift by 1 bit instead of multiplying by 2
|
||||
|
@ -3148,7 +3142,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
|
||||
private Expression createNullSeparator() {
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor chr = findSelfRenderingFunction( "chr", 1 );
|
||||
final FunctionRenderer chr = findSelfRenderingFunction( "chr", 1 );
|
||||
final BasicType<String> stringType = getStringType();
|
||||
return new SelfRenderingFunctionSqlAstExpression(
|
||||
"chr",
|
||||
|
@ -3170,8 +3164,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
* The mappings are implemented in {@link #wrapRowComponentAsEqualityPreservingConcatArgument(Expression)}.
|
||||
*/
|
||||
private void emulateCycleClauseWithString(SelectClause selectClause) {
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor concat = findSelfRenderingFunction( "concat", 2 );
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor coalesce = findSelfRenderingFunction( "coalesce", 2 );
|
||||
final FunctionRenderer concat = findSelfRenderingFunction( "concat", 2 );
|
||||
final FunctionRenderer coalesce = findSelfRenderingFunction( "coalesce", 2 );
|
||||
final BasicType<String> stringType = getStringType();
|
||||
// Shift by 2 bit instead of multiplying by 4
|
||||
final List<SqlAstNode> arguments = new ArrayList<>( currentCteStatement.getCycleColumns().size() << 2 );
|
||||
|
@ -3284,7 +3278,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
|
||||
protected void renderStringContainsExactlyPredicate(Expression haystack, Expression needle) {
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor position = findSelfRenderingFunction( "position", 2 );
|
||||
final FunctionRenderer position = findSelfRenderingFunction( "position", 2 );
|
||||
new SelfRenderingFunctionSqlAstExpression(
|
||||
"position",
|
||||
position,
|
||||
|
@ -3348,8 +3342,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
final JdbcMapping jdbcMapping = expression.getExpressionType().getSingleJdbcMapping();
|
||||
switch ( jdbcMapping.getCastType() ) {
|
||||
case STRING:
|
||||
if ( expression.getExpressionType() instanceof SqlTypedMapping ) {
|
||||
final SqlTypedMapping sqlTypedMapping = (SqlTypedMapping) expression.getExpressionType();
|
||||
if ( expression.getExpressionType() instanceof SqlTypedMapping sqlTypedMapping ) {
|
||||
if ( sqlTypedMapping.getLength() != null ) {
|
||||
return sqlTypedMapping.getLength().intValue();
|
||||
}
|
||||
|
@ -3364,8 +3357,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
case LONG:
|
||||
return 20;
|
||||
case FIXED:
|
||||
if ( expression.getExpressionType() instanceof SqlTypedMapping ) {
|
||||
final SqlTypedMapping sqlTypedMapping = (SqlTypedMapping) expression.getExpressionType();
|
||||
if ( expression.getExpressionType() instanceof SqlTypedMapping sqlTypedMapping ) {
|
||||
if ( sqlTypedMapping.getPrecision() != null && sqlTypedMapping.getScale() != null ) {
|
||||
return sqlTypedMapping.getPrecision() + sqlTypedMapping.getScale() + 2;
|
||||
}
|
||||
|
@ -3409,7 +3401,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
// Should we maybe always cast instead? Not sure what is faster/better...
|
||||
final BasicType<String> stringType = getStringType();
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor concat = findSelfRenderingFunction( "concat", 2 );
|
||||
final FunctionRenderer concat = findSelfRenderingFunction( "concat", 2 );
|
||||
return new SelfRenderingFunctionSqlAstExpression(
|
||||
"concat",
|
||||
concat,
|
||||
|
@ -3434,8 +3426,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
final JdbcMapping jdbcMapping = expression.getExpressionType().getSingleJdbcMapping();
|
||||
switch ( jdbcMapping.getCastType() ) {
|
||||
case STRING:
|
||||
if ( expression.getExpressionType() instanceof SqlTypedMapping ) {
|
||||
final SqlTypedMapping sqlTypedMapping = (SqlTypedMapping) expression.getExpressionType();
|
||||
if ( expression.getExpressionType() instanceof SqlTypedMapping sqlTypedMapping ) {
|
||||
if ( sqlTypedMapping.getLength() != null ) {
|
||||
return sqlTypedMapping.getLength().intValue();
|
||||
}
|
||||
|
@ -3450,8 +3441,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
case LONG:
|
||||
return 20;
|
||||
case FIXED:
|
||||
if ( expression.getExpressionType() instanceof SqlTypedMapping ) {
|
||||
final SqlTypedMapping sqlTypedMapping = (SqlTypedMapping) expression.getExpressionType();
|
||||
if ( expression.getExpressionType() instanceof SqlTypedMapping sqlTypedMapping ) {
|
||||
if ( sqlTypedMapping.getPrecision() != null && sqlTypedMapping.getScale() != null ) {
|
||||
return sqlTypedMapping.getPrecision() + sqlTypedMapping.getScale() + 2;
|
||||
}
|
||||
|
@ -3470,10 +3460,9 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
|
||||
private Expression abs(Expression expression) {
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor abs = findSelfRenderingFunction( "abs", 2 );
|
||||
return new SelfRenderingFunctionSqlAstExpression(
|
||||
"abs",
|
||||
abs,
|
||||
findSelfRenderingFunction( "abs", 2 ),
|
||||
List.of( expression ),
|
||||
(ReturnableType<?>) expression.getExpressionType(),
|
||||
expression.getExpressionType()
|
||||
|
@ -3482,29 +3471,26 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
|
||||
private Expression lpad(Expression expression, int stringLength, String padString) {
|
||||
final BasicType<String> stringType = getStringType();
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor lpad = findSelfRenderingFunction( "lpad", 3 );
|
||||
final FunctionRenderer lpad = findSelfRenderingFunction( "lpad", 3 );
|
||||
return new SelfRenderingFunctionSqlAstExpression(
|
||||
"lpad",
|
||||
lpad,
|
||||
List.of(
|
||||
expression,
|
||||
List.of( expression,
|
||||
new QueryLiteral<>( stringLength, getIntegerType() ),
|
||||
new QueryLiteral<>( padString, stringType )
|
||||
),
|
||||
new QueryLiteral<>( padString, stringType ) ),
|
||||
stringType,
|
||||
stringType
|
||||
);
|
||||
}
|
||||
|
||||
private AbstractSqmSelfRenderingFunctionDescriptor findSelfRenderingFunction(String functionName, int argumentCount) {
|
||||
final SqmFunctionDescriptor functionDescriptor = sessionFactory.getQueryEngine()
|
||||
.getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( functionName );
|
||||
if ( functionDescriptor instanceof MultipatternSqmFunctionDescriptor ) {
|
||||
final MultipatternSqmFunctionDescriptor multiPatternFunction = (MultipatternSqmFunctionDescriptor) functionDescriptor;
|
||||
return (AbstractSqmSelfRenderingFunctionDescriptor) multiPatternFunction.getFunction( argumentCount );
|
||||
private FunctionRenderer findSelfRenderingFunction(String functionName, int argumentCount) {
|
||||
final SqmFunctionDescriptor functionDescriptor =
|
||||
sessionFactory.getQueryEngine().getSqmFunctionRegistry()
|
||||
.findFunctionDescriptor( functionName );
|
||||
if ( functionDescriptor instanceof MultipatternSqmFunctionDescriptor multiPatternFunction ) {
|
||||
return (FunctionRenderer) multiPatternFunction.getFunction( argumentCount );
|
||||
}
|
||||
return (AbstractSqmSelfRenderingFunctionDescriptor) functionDescriptor;
|
||||
return (FunctionRenderer) functionDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3512,7 +3498,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
*/
|
||||
protected Expression castNumberToString(Expression expression, int precision, int scale) {
|
||||
final BasicType<String> stringType = getStringType();
|
||||
final AbstractSqmSelfRenderingFunctionDescriptor concat = findSelfRenderingFunction( "concat", 2 );
|
||||
final FunctionRenderer concat = findSelfRenderingFunction( "concat", 2 );
|
||||
|
||||
final CaseSearchedExpression signExpression = new CaseSearchedExpression( stringType );
|
||||
signExpression.when(
|
||||
|
@ -3809,19 +3795,19 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
|
||||
protected Expression resolveAliasedExpression(List<SqlSelection> sqlSelections, Expression expression) {
|
||||
if ( expression instanceof Literal ) {
|
||||
Object literalValue = ( (Literal) expression ).getLiteralValue();
|
||||
if ( literalValue instanceof Integer ) {
|
||||
return sqlSelections.get( (Integer) literalValue ).getExpression();
|
||||
if ( expression instanceof Literal literal ) {
|
||||
final Object literalValue = literal.getLiteralValue();
|
||||
if ( literalValue instanceof Integer integer ) {
|
||||
return sqlSelections.get( integer ).getExpression();
|
||||
}
|
||||
}
|
||||
else if ( expression instanceof SqlSelectionExpression ) {
|
||||
return ( (SqlSelectionExpression) expression ).getSelection().getExpression();
|
||||
else if ( expression instanceof SqlSelectionExpression selectionExpression ) {
|
||||
return selectionExpression.getSelection().getExpression();
|
||||
}
|
||||
else if ( expression instanceof SqmPathInterpretation<?> ) {
|
||||
final Expression sqlExpression = ( (SqmPathInterpretation<?>) expression ).getSqlExpression();
|
||||
if ( sqlExpression instanceof SqlSelectionExpression ) {
|
||||
return ( (SqlSelectionExpression) sqlExpression ).getSelection().getExpression();
|
||||
else if ( expression instanceof SqmPathInterpretation<?> pathInterpretation ) {
|
||||
final Expression sqlExpression = pathInterpretation.getSqlExpression();
|
||||
if ( sqlExpression instanceof SqlSelectionExpression selectionExpression ) {
|
||||
return selectionExpression.getSelection().getExpression();
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
|
@ -3829,13 +3815,13 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
|
||||
protected Expression resolveExpressionToAlias(Expression expression) {
|
||||
int index = -1;
|
||||
if ( expression instanceof SqlSelectionExpression ) {
|
||||
index = ( (SqlSelectionExpression) expression ).getSelection().getValuesArrayPosition();
|
||||
if ( expression instanceof SqlSelectionExpression selectionExpression ) {
|
||||
index = selectionExpression.getSelection().getValuesArrayPosition();
|
||||
}
|
||||
else if ( expression instanceof SqmPathInterpretation<?> ) {
|
||||
final Expression sqlExpression = ( (SqmPathInterpretation<?>) expression ).getSqlExpression();
|
||||
if ( sqlExpression instanceof SqlSelectionExpression ) {
|
||||
index = ( (SqlSelectionExpression) sqlExpression ).getSelection().getValuesArrayPosition();
|
||||
else if ( expression instanceof SqmPathInterpretation<?> pathInterpretation ) {
|
||||
final Expression sqlExpression = pathInterpretation.getSqlExpression();
|
||||
if ( sqlExpression instanceof SqlSelectionExpression selectionExpression ) {
|
||||
index = selectionExpression.getSelection().getValuesArrayPosition();
|
||||
}
|
||||
}
|
||||
if ( index == -1 ) {
|
||||
|
@ -5496,8 +5482,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
final Expression overExpression = over.getExpression();
|
||||
overExpression.accept( this );
|
||||
final boolean orderedSetAggregate;
|
||||
if ( overExpression instanceof OrderedSetAggregateFunctionExpression ) {
|
||||
final OrderedSetAggregateFunctionExpression expression = (OrderedSetAggregateFunctionExpression) overExpression;
|
||||
if ( overExpression instanceof OrderedSetAggregateFunctionExpression expression ) {
|
||||
orderedSetAggregate = expression.getWithinGroup() != null && !expression.getWithinGroup().isEmpty();
|
||||
}
|
||||
else {
|
||||
|
@ -5766,8 +5751,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
|
||||
protected void renderSelectExpressionWithCastedOrInlinedPlainParameters(Expression expression) {
|
||||
// Null literals have to be casted in the select clause
|
||||
if ( expression instanceof Literal ) {
|
||||
final Literal literal = (Literal) expression;
|
||||
if ( expression instanceof Literal literal ) {
|
||||
if ( literal.getLiteralValue() == null ) {
|
||||
renderCasted( literal );
|
||||
}
|
||||
|
@ -5802,8 +5786,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
final List<SqlAstNode> arguments = new ArrayList<>( 2 );
|
||||
arguments.add( expression );
|
||||
final CastTarget castTarget;
|
||||
if ( expression instanceof SqlTypedMappingJdbcParameter ) {
|
||||
final SqlTypedMappingJdbcParameter parameter = (SqlTypedMappingJdbcParameter) expression;
|
||||
if ( expression instanceof SqlTypedMappingJdbcParameter parameter ) {
|
||||
final SqlTypedMapping sqlTypedMapping = parameter.getSqlTypedMapping();
|
||||
castTarget = new CastTarget(
|
||||
parameter.getJdbcMapping(),
|
||||
|
@ -6017,8 +6000,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
processTableGroupJoins( tableGroup );
|
||||
}
|
||||
ModelPartContainer modelPart = tableGroup.getModelPart();
|
||||
if ( modelPart instanceof EntityPersister ) {
|
||||
String[] querySpaces = (String[]) ( (EntityPersister) modelPart ).getQuerySpaces();
|
||||
if ( modelPart instanceof EntityPersister persister ) {
|
||||
String[] querySpaces = (String[]) persister.getQuerySpaces();
|
||||
for ( int i = 0; i < querySpaces.length; i++ ) {
|
||||
registerAffectedTable( querySpaces[i] );
|
||||
}
|
||||
|
@ -6151,8 +6134,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
|
||||
ModelPartContainer modelPart = tableGroup.getModelPart();
|
||||
if ( modelPart instanceof EntityPersister ) {
|
||||
String[] querySpaces = (String[]) ( (EntityPersister) modelPart ).getQuerySpaces();
|
||||
if ( modelPart instanceof EntityPersister persister ) {
|
||||
String[] querySpaces = (String[]) persister.getQuerySpaces();
|
||||
for ( int i = 0; i < querySpaces.length; i++ ) {
|
||||
registerAffectedTable( querySpaces[i] );
|
||||
}
|
||||
|
@ -6212,17 +6195,15 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
if ( dialect.supportsLateral() ) {
|
||||
appendSql( "lateral " );
|
||||
}
|
||||
else if ( tableReference instanceof QueryPartTableReference ) {
|
||||
final QueryPartTableReference queryPartTableReference = (QueryPartTableReference) tableReference;
|
||||
else if ( tableReference instanceof QueryPartTableReference queryPartTableReference ) {
|
||||
final SelectStatement emulationStatement = stripToSelectClause( queryPartTableReference.getStatement() );
|
||||
final QueryPart queryPart = queryPartTableReference.getStatement().getQueryPart();
|
||||
final QueryPart emulationQueryPart = emulationStatement.getQueryPart();
|
||||
final List<String> columnNames;
|
||||
if ( queryPart instanceof QuerySpec && needsLateralSortExpressionVirtualSelections( (QuerySpec) queryPart ) ) {
|
||||
if ( queryPart instanceof QuerySpec querySpec && needsLateralSortExpressionVirtualSelections( querySpec ) ) {
|
||||
// One of our lateral emulations requires that sort expressions are present in the select clause
|
||||
// when the query spec use limit/offset. So we add selections for these, if necessary
|
||||
columnNames = new ArrayList<>( queryPartTableReference.getColumnNames() );
|
||||
final QuerySpec querySpec = (QuerySpec) queryPart;
|
||||
final QuerySpec emulationQuerySpec = (QuerySpec) emulationQueryPart;
|
||||
final List<SqlSelection> sqlSelections = emulationQuerySpec.getSelectClause().getSqlSelections();
|
||||
final List<SortSpecification> sortSpecifications = queryPart.getSortSpecifications();
|
||||
|
@ -6519,8 +6500,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
|
||||
protected Predicate determineLateralEmulationPredicate(TableGroup tableGroup) {
|
||||
if ( tableGroup.getPrimaryTableReference() instanceof QueryPartTableReference ) {
|
||||
final QueryPartTableReference tableReference = (QueryPartTableReference) tableGroup.getPrimaryTableReference();
|
||||
if ( tableGroup.getPrimaryTableReference() instanceof QueryPartTableReference tableReference ) {
|
||||
final List<String> columnNames = tableReference.getColumnNames();
|
||||
final List<ColumnReference> columnReferences = new ArrayList<>( columnNames.size() );
|
||||
final SelectStatement statement = tableReference.getStatement();
|
||||
|
@ -6810,33 +6790,26 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
private boolean isNullsFirst(SortSpecification sortSpecification) {
|
||||
Nulls nullPrecedence = sortSpecification.getNullPrecedence();
|
||||
if ( nullPrecedence == null || nullPrecedence == Nulls.NONE ) {
|
||||
switch ( dialect.getNullOrdering() ) {
|
||||
case FIRST:
|
||||
nullPrecedence = Nulls.FIRST;
|
||||
break;
|
||||
case LAST:
|
||||
nullPrecedence = Nulls.LAST;
|
||||
break;
|
||||
case SMALLEST:
|
||||
nullPrecedence = sortSpecification.getSortOrder() == SortDirection.ASCENDING
|
||||
? Nulls.FIRST
|
||||
: Nulls.LAST;
|
||||
break;
|
||||
case GREATEST:
|
||||
nullPrecedence = sortSpecification.getSortOrder() == SortDirection.DESCENDING
|
||||
? Nulls.FIRST
|
||||
: Nulls.LAST;
|
||||
break;
|
||||
}
|
||||
nullPrecedence = switch ( dialect.getNullOrdering() ) {
|
||||
case FIRST -> Nulls.FIRST;
|
||||
case LAST -> Nulls.LAST;
|
||||
case SMALLEST ->
|
||||
sortSpecification.getSortOrder() == SortDirection.ASCENDING
|
||||
? Nulls.FIRST
|
||||
: Nulls.LAST;
|
||||
case GREATEST ->
|
||||
sortSpecification.getSortOrder() == SortDirection.DESCENDING
|
||||
? Nulls.FIRST
|
||||
: Nulls.LAST;
|
||||
};
|
||||
}
|
||||
return nullPrecedence == Nulls.FIRST;
|
||||
}
|
||||
|
||||
private int getSortSelectionIndex(QuerySpec querySpec, SortSpecification sortSpecification) {
|
||||
final Expression sortExpression = sortSpecification.getSortExpression();
|
||||
if ( sortExpression instanceof SqlSelectionExpression ) {
|
||||
final SqlSelection selection = ( (SqlSelectionExpression) sortExpression ).getSelection();
|
||||
return selection.getValuesArrayPosition();
|
||||
if ( sortExpression instanceof SqlSelectionExpression selectionExpression ) {
|
||||
return selectionExpression.getSelection().getValuesArrayPosition();
|
||||
}
|
||||
else {
|
||||
final List<SqlSelection> sqlSelections = querySpec.getSelectClause().getSqlSelections();
|
||||
|
@ -7149,8 +7122,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
|
||||
/**
|
||||
* Renders a parameter marker for the given position
|
||||
* @param jdbcParameter
|
||||
* @param position
|
||||
*/
|
||||
protected void renderParameterAsParameter(int position, JdbcParameter jdbcParameter) {
|
||||
final JdbcType jdbcType = jdbcParameter.getExpressionType().getJdbcMapping( 0 ).getJdbcType();
|
||||
|
@ -8089,8 +8060,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
|
||||
private void visitJunctionPredicate(Junction.Nature nature, Predicate p) {
|
||||
if ( p instanceof Junction ) {
|
||||
final Junction junction = (Junction) p;
|
||||
if ( p instanceof Junction junction ) {
|
||||
// If we have the same nature, or if this is a disjunction and the operand is a conjunction,
|
||||
// then we don't need parenthesis, because the AND operator binds stronger
|
||||
if ( nature == junction.getNature() || nature == Junction.Nature.DISJUNCTION ) {
|
||||
|
@ -8169,8 +8139,8 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
// Check if escapeCharacter was explicitly set and do nothing in that case
|
||||
// Note: this does not cover cases where it's set via parameter binding
|
||||
boolean isExplicitEscape = false;
|
||||
if ( escapeCharacter instanceof Literal ) {
|
||||
Object literalValue = ( (Literal) escapeCharacter ).getLiteralValue();
|
||||
if ( escapeCharacter instanceof Literal literal ) {
|
||||
Object literalValue = literal.getLiteralValue();
|
||||
isExplicitEscape = literalValue != null && !literalValue.toString().equals( "" );
|
||||
}
|
||||
if ( isExplicitEscape ) {
|
||||
|
@ -8467,17 +8437,13 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
if ( !supportsRowValueConstructorSyntax() ) {
|
||||
return true;
|
||||
}
|
||||
switch ( operator ) {
|
||||
case LESS_THAN:
|
||||
case LESS_THAN_OR_EQUAL:
|
||||
case GREATER_THAN:
|
||||
case GREATER_THAN_OR_EQUAL:
|
||||
return !supportsRowValueConstructorGtLtSyntax();
|
||||
case DISTINCT_FROM:
|
||||
case NOT_DISTINCT_FROM:
|
||||
return !supportsRowValueConstructorDistinctFromSyntax();
|
||||
}
|
||||
return false;
|
||||
return switch (operator) {
|
||||
case LESS_THAN, LESS_THAN_OR_EQUAL, GREATER_THAN, GREATER_THAN_OR_EQUAL ->
|
||||
!supportsRowValueConstructorGtLtSyntax();
|
||||
case DISTINCT_FROM, NOT_DISTINCT_FROM ->
|
||||
!supportsRowValueConstructorDistinctFromSyntax();
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8684,14 +8650,14 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
|
||||
private String[] determineKeyColumnNames(ModelPart modelPart) {
|
||||
if ( modelPart instanceof EntityPersister) {
|
||||
return ( (EntityPersister) modelPart ).getIdentifierColumnNames();
|
||||
if ( modelPart instanceof EntityPersister entityPersister ) {
|
||||
return entityPersister.getIdentifierColumnNames();
|
||||
}
|
||||
else if ( modelPart instanceof PluralAttributeMapping ) {
|
||||
return ((PluralAttributeMapping) modelPart).getCollectionDescriptor().getKeyColumnAliases( null );
|
||||
else if ( modelPart instanceof PluralAttributeMapping pluralAttributeMapping ) {
|
||||
return pluralAttributeMapping.getCollectionDescriptor().getKeyColumnAliases( null );
|
||||
}
|
||||
else if ( modelPart instanceof EntityAssociationMapping ) {
|
||||
return determineKeyColumnNames( ( (EntityAssociationMapping) modelPart ).getAssociatedEntityMappingType() );
|
||||
else if ( modelPart instanceof EntityAssociationMapping entityAssociationMapping ) {
|
||||
return determineKeyColumnNames( entityAssociationMapping.getAssociatedEntityMappingType() );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue