Simplify the whole SqmFunctionDescriptor hierarchy

And make the various function implementations work in more common ways.

- remove some unnecessary flexibility
- simplify some function descriptors to do their work during render()
- fix generics of QueryLiteral
- fix DerbyConcatEmulation
This commit is contained in:
gavinking 2020-01-28 02:06:02 +01:00 committed by Steve Ebersole
parent effec02964
commit 5a3838dfa6
34 changed files with 326 additions and 380 deletions

View File

@ -7,27 +7,24 @@
package org.hibernate.dialect.function;
import org.hibernate.dialect.Dialect;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.metamodel.mapping.BasicValuedMapping;
import org.hibernate.query.CastType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.query.sqm.tree.expression.SqmCastTarget;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.CastTarget;
import org.hibernate.sql.ast.tree.expression.Expression;
import java.util.List;
import static org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers.useArgType;
/**
* @author Gavin King
*/
public class CastFunction
extends AbstractSqmFunctionDescriptor {
public class CastFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
private Dialect dialect;
@ -41,30 +38,44 @@ public class CastFunction
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
SqmCastTarget<?> targetType = (SqmCastTarget<?>) arguments.get(1);
SqmExpression<?> arg = (SqmExpression<?>) arguments.get(0);
public void render(SqlAppender sqlAppender, List<SqlAstNode> arguments, SqlAstWalker walker) {
CastTarget targetType = (CastTarget) arguments.get(1);
Expression arg = (Expression) arguments.get(0);
CastType to = CastType.from( targetType.getType() );
CastType from = CastType.from( arg.getNodeType() );
CastType to = CastType.from( targetType.getExpressionType().getBasicType() );
//TODO: generalize this to things which aren't BasicValuedMappings
CastType from = CastType.from( ( (BasicValuedMapping) arg.getExpressionType() ).getBasicType() );
return queryEngine.getSqmFunctionRegistry()
.patternDescriptorBuilder( "cast", dialect.castPattern( from, to ) )
.setExactArgumentCount( 2 )
.setReturnTypeResolver( useArgType( 2 ) )
.descriptor()
.generateSqmExpression(
arguments,
impliedResultType,
queryEngine,
typeConfiguration
);
String cast = dialect.castPattern( from, to );
new PatternRenderer( cast ).render( sqlAppender, arguments, walker );
}
// @Override
// protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
// List<SqmTypedNode<?>> arguments,
// AllowableFunctionReturnType<T> impliedResultType,
// QueryEngine queryEngine,
// TypeConfiguration typeConfiguration) {
// SqmCastTarget<?> targetType = (SqmCastTarget<?>) arguments.get(1);
// SqmExpression<?> arg = (SqmExpression<?>) arguments.get(0);
//
// CastType to = CastType.from( targetType.getType() );
// CastType from = CastType.from( arg.getNodeType() );
//
// return queryEngine.getSqmFunctionRegistry()
// .patternDescriptorBuilder( "cast", dialect.castPattern( from, to ) )
// .setExactArgumentCount( 2 )
// .setReturnTypeResolver( useArgType( 2 ) )
// .descriptor()
// .generateSqmExpression(
// arguments,
// impliedResultType,
// queryEngine,
// typeConfiguration
// );
// }
@Override
public String getArgumentListSignature() {
return "(arg as Type)";

View File

@ -9,7 +9,7 @@ package org.hibernate.dialect.function;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.query.sqm.tree.SqmTypedNode;
@ -36,7 +36,7 @@ public class CastStrEmulation
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,

View File

@ -9,7 +9,7 @@ package org.hibernate.dialect.function;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.type.spi.TypeConfiguration;
@ -30,7 +30,7 @@ public class CoalesceIfnullEmulation
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,

View File

@ -6,19 +6,13 @@
*/
package org.hibernate.dialect.function;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.type.BasicType;
import org.hibernate.type.spi.TypeConfiguration;
import java.util.List;
@ -26,9 +20,8 @@ import java.util.List;
* @author Gavin King
*/
public class CurrentFunction
extends AbstractSqmFunctionDescriptor implements FunctionRenderingSupport {
extends AbstractSqmSelfRenderingFunctionDescriptor {
private final String name;
private final String sql;
public CurrentFunction(String name, String sql, BasicType type) {
@ -37,7 +30,6 @@ public class CurrentFunction
StandardArgumentsValidators.NO_ARGS,
StandardFunctionReturnTypeResolvers.invariant( type )
);
this.name = name;
this.sql = sql;
}
@ -49,22 +41,6 @@ public class CurrentFunction
sqlAppender.appendSql(sql);
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
return new SelfRenderingSqlFunctionExpression<T>(
this, this,
arguments,
impliedResultType,
getReturnTypeResolver(),
queryEngine.getCriteriaBuilder(),
name
);
}
@Override
public String getArgumentListSignature() {
return "";

View File

@ -7,21 +7,15 @@
package org.hibernate.dialect.function;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.Format;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
import java.util.List;
@ -34,7 +28,7 @@ import java.util.List;
* @author Gavin King
*/
public class DB2FormatEmulation
extends AbstractSqmFunctionDescriptor implements FunctionRenderingSupport {
extends AbstractSqmSelfRenderingFunctionDescriptor {
public DB2FormatEmulation() {
super(
@ -84,22 +78,6 @@ public class DB2FormatEmulation
sqlAppender.appendSql(")");
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
return new SelfRenderingSqlFunctionExpression<T>(
this, this,
arguments,
impliedResultType,
getReturnTypeResolver(),
queryEngine.getCriteriaBuilder(),
"format"
);
}
@Override
public String getArgumentListSignature() {
return "(datetime as pattern)";

View File

@ -7,12 +7,12 @@
package org.hibernate.dialect.function;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.function.FunctionRenderingSupport;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.type.StandardBasicTypes;
import java.util.List;
@ -25,8 +25,7 @@ import java.util.List;
* @author Christian Beikov
*/
public class DerbyConcatEmulation
extends AbstractSqmSelfRenderingFunctionDescriptor
implements FunctionRenderingSupport {
extends AbstractSqmSelfRenderingFunctionDescriptor {
public DerbyConcatEmulation() {
super(
@ -36,11 +35,6 @@ public class DerbyConcatEmulation
);
}
@Override
public FunctionRenderingSupport getRenderingSupport() {
return this;
}
@Override
public void render(
SqlAppender sqlAppender,
@ -55,7 +49,7 @@ public class DerbyConcatEmulation
if ( i > 0 ) {
sqlAppender.appendSql("||");
}
boolean param = false; //TODO: argument instanceof GenericParameter;
boolean param = argument instanceof JdbcParameter;
if ( param ) {
sqlAppender.appendSql("cast(");
}

View File

@ -13,7 +13,7 @@ import org.hibernate.query.TemporalUnit;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.query.sqm.tree.SqmTypedNode;
@ -47,7 +47,7 @@ public class ExtractFunction
}
@Override
protected <T> SelfRenderingSqlFunctionExpression generateSqmFunctionExpression(
protected <T> SelfRenderingSqmFunction generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
@ -96,7 +96,7 @@ public class ExtractFunction
}
}
private SelfRenderingSqlFunctionExpression<Integer> extractWeek(
private SelfRenderingSqmFunction<Integer> extractWeek(
SqmExpression<?> expressionToExtract,
SqmExtractUnit<?> field,
TemporalUnit dayOf,
@ -160,7 +160,7 @@ public class ExtractFunction
);
}
private SelfRenderingSqlFunctionExpression<Long> toLong(
private SelfRenderingSqmFunction<Long> toLong(
SqmExpression<?> arg,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
@ -183,7 +183,7 @@ public class ExtractFunction
);
}
private SelfRenderingSqlFunctionExpression<Long> extractNanoseconds(
private SelfRenderingSqmFunction<Long> extractNanoseconds(
SqmExpression<?> expressionToExtract,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
@ -211,7 +211,7 @@ public class ExtractFunction
);
}
private SelfRenderingSqlFunctionExpression<ZoneOffset> extractOffsetUsingFormat(
private SelfRenderingSqmFunction<ZoneOffset> extractOffsetUsingFormat(
SqmExpression<?> expressionToExtract,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
@ -235,7 +235,7 @@ public class ExtractFunction
);
}
private SelfRenderingSqlFunctionExpression<?> extractDateOrTimeUsingCast(
private SelfRenderingSqmFunction<?> extractDateOrTimeUsingCast(
SqmExpression<?> expressionToExtract,
AllowableFunctionReturnType<?> type,
QueryEngine queryEngine,

View File

@ -10,7 +10,7 @@ import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.BinaryArithmeticOperator;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
@ -41,7 +41,7 @@ public class InsertSubstringOverlayEmulation
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,

View File

@ -9,7 +9,7 @@ package org.hibernate.dialect.function;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.query.sqm.tree.SqmTypedNode;
@ -33,7 +33,7 @@ public class LocatePositionEmulation
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,

View File

@ -10,7 +10,7 @@ import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.TrimSpec;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.query.sqm.tree.SqmTypedNode;
@ -37,7 +37,7 @@ public class LpadRpadPadEmulation
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,

View File

@ -9,7 +9,7 @@ package org.hibernate.dialect.function;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.SelfRenderingSqmFunction;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
@ -40,17 +40,22 @@ public class NvlCoalesceEmulation
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
SqmFunctionDescriptor nvl = queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder("nvl").setExactArgumentCount(2).template();
SqmFunctionDescriptor nvl =
queryEngine.getSqmFunctionRegistry()
.namedDescriptorBuilder("nvl")
.setExactArgumentCount(2)
.descriptor();
int pos = arguments.size();
SqmExpression<?> result = (SqmExpression<?>) arguments.get( --pos );
AllowableFunctionReturnType<?> type = (AllowableFunctionReturnType<?>) result.getNodeType();
AllowableFunctionReturnType<?> type =
(AllowableFunctionReturnType<?>) result.getNodeType();
while (pos>0) {
SqmExpression<?> next = (SqmExpression<?>) arguments.get( --pos );
@ -63,7 +68,7 @@ public class NvlCoalesceEmulation
}
//noinspection unchecked
return (SelfRenderingSqlFunctionExpression<T>) result;
return (SelfRenderingSqmFunction<T>) result;
}
}

View File

@ -8,16 +8,13 @@ package org.hibernate.dialect.function;
import org.hibernate.dialect.Dialect;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
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;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmExtractUnit;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.DurationUnit;
import org.hibernate.sql.ast.tree.expression.Expression;
@ -26,14 +23,12 @@ import org.hibernate.type.spi.TypeConfiguration;
import java.util.List;
import static java.util.Arrays.asList;
import static org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers.useArgType;
import static org.hibernate.type.spi.TypeConfiguration.isSqlTimestampType;
/**
* @author Gavin King
*/
public class TimestampaddFunction
extends AbstractSqmFunctionDescriptor {
extends AbstractSqmSelfRenderingFunctionDescriptor {
private Dialect dialect;
@ -47,44 +42,56 @@ public class TimestampaddFunction
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
SqmExtractUnit<?> field = (SqmExtractUnit<?>) arguments.get(0);
SqmExpression<?> to = (SqmExpression<?>) arguments.get(2);
return queryEngine.getSqmFunctionRegistry()
.patternDescriptorBuilder(
"timestampadd",
dialect.timestampaddPattern(
public void render(
SqlAppender sqlAppender,
List<SqlAstNode> arguments,
SqlAstWalker walker) {
DurationUnit field = (DurationUnit) arguments.get(0);
Expression to = (Expression) arguments.get(2);
String pattern = dialect.timestampaddPattern(
field.getUnit(),
typeConfiguration.isTimestampType( to.getNodeType() )
)
)
.setExactArgumentCount( 3 )
.setReturnTypeResolver( useArgType( 3 ) )
.descriptor()
.generateSqmExpression(
arguments,
impliedResultType,
queryEngine,
typeConfiguration
TypeConfiguration.isSqlTimestampType( to.getExpressionType() )
);
new PatternRenderer( pattern ).render( sqlAppender, arguments, walker );
}
// @Override
// protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
// List<SqmTypedNode<?>> arguments,
// AllowableFunctionReturnType<T> impliedResultType,
// QueryEngine queryEngine,
// TypeConfiguration typeConfiguration) {
// SqmExtractUnit<?> field = (SqmExtractUnit<?>) arguments.get(0);
// SqmExpression<?> to = (SqmExpression<?>) arguments.get(2);
// return queryEngine.getSqmFunctionRegistry()
// .patternDescriptorBuilder(
// "timestampadd",
// dialect.timestampaddPattern(
// field.getUnit(),
// typeConfiguration.isSqlTimestampType( to.getNodeType() )
// )
// )
// .setExactArgumentCount( 3 )
// .setReturnTypeResolver( useArgType( 3 ) )
// .descriptor()
// .generateSqmExpression(
// arguments,
// impliedResultType,
// queryEngine,
// typeConfiguration
// );
// }
public SelfRenderingFunctionSqlAstExpression expression(
AllowableFunctionReturnType<?> impliedResultType,
SqlAstNode... sqlAstArguments) {
DurationUnit field = (DurationUnit) sqlAstArguments[0];
Expression to = (Expression) sqlAstArguments[2];
return new SelfRenderingFunctionSqlAstExpression(
new PatternRenderer(
dialect.timestampaddPattern(
field.getUnit(),
isSqlTimestampType( to.getExpressionType() )
)
)::render,
(sqlAppender, sqlAstArguments1, walker)
-> render(sqlAppender, sqlAstArguments1, walker),
asList( sqlAstArguments ),
impliedResultType,
to.getExpressionType()

View File

@ -8,16 +8,13 @@ package org.hibernate.dialect.function;
import org.hibernate.dialect.Dialect;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
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;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmExtractUnit;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.DurationUnit;
import org.hibernate.sql.ast.tree.expression.Expression;
@ -27,13 +24,12 @@ import org.hibernate.type.spi.TypeConfiguration;
import java.util.List;
import static java.util.Arrays.asList;
import static org.hibernate.type.spi.TypeConfiguration.isSqlTimestampType;
/**
* @author Gavin King
*/
public class TimestampdiffFunction
extends AbstractSqmFunctionDescriptor {
extends AbstractSqmSelfRenderingFunctionDescriptor {
private Dialect dialect;
@ -47,48 +43,60 @@ public class TimestampdiffFunction
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
SqmExtractUnit<?> field = (SqmExtractUnit<?>) arguments.get(0);
SqmExpression<?> from = (SqmExpression<?>) arguments.get(1);
SqmExpression<?> to = (SqmExpression<?>) arguments.get(2);
return queryEngine.getSqmFunctionRegistry()
.patternDescriptorBuilder(
"timestampdiff",
dialect.timestampdiffPattern(
public void render(
SqlAppender sqlAppender,
List<SqlAstNode> arguments,
SqlAstWalker walker) {
DurationUnit field = (DurationUnit) arguments.get(0);
Expression from = (Expression) arguments.get(1);
Expression to = (Expression) arguments.get(2);
String pattern = dialect.timestampdiffPattern(
field.getUnit(),
typeConfiguration.isTimestampType( from.getNodeType() ),
typeConfiguration.isTimestampType( to.getNodeType() )
)
)
.setInvariantType( StandardBasicTypes.LONG )
.setExactArgumentCount( 3 )
.descriptor()
.generateSqmExpression(
arguments,
impliedResultType,
queryEngine,
typeConfiguration
TypeConfiguration.isSqlTimestampType( from.getExpressionType() ),
TypeConfiguration.isSqlTimestampType( to.getExpressionType() )
);
new PatternRenderer( pattern ).render( sqlAppender, arguments, walker );
}
// @Override
// protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
// List<SqmTypedNode<?>> arguments,
// AllowableFunctionReturnType<T> impliedResultType,
// QueryEngine queryEngine,
// TypeConfiguration typeConfiguration) {
// SqmExtractUnit<?> field = (SqmExtractUnit<?>) arguments.get(0);
// SqmExpression<?> from = (SqmExpression<?>) arguments.get(1);
// SqmExpression<?> to = (SqmExpression<?>) arguments.get(2);
// return queryEngine.getSqmFunctionRegistry()
// .patternDescriptorBuilder(
// "timestampdiff",
// dialect.timestampdiffPattern(
// field.getUnit(),
// typeConfiguration.isSqlTimestampType( from.getNodeType() ),
// typeConfiguration.isSqlTimestampType( to.getNodeType() )
// )
// )
// .setInvariantType( StandardBasicTypes.LONG )
// .setExactArgumentCount( 3 )
// .descriptor()
// .generateSqmExpression(
// arguments,
// impliedResultType,
// queryEngine,
// typeConfiguration
// );
// }
public SelfRenderingFunctionSqlAstExpression expression(
AllowableFunctionReturnType<?> impliedResultType,
SqlAstNode... sqlAstArguments) {
DurationUnit field = (DurationUnit) sqlAstArguments[0];
Expression from = (Expression) sqlAstArguments[1];
Expression to = (Expression) sqlAstArguments[2];
return new SelfRenderingFunctionSqlAstExpression(
new PatternRenderer(
dialect.timestampdiffPattern(
field.getUnit(),
isSqlTimestampType( from.getExpressionType() ),
isSqlTimestampType( to.getExpressionType() )
)
)::render,
(sqlAppender, sqlAstArguments1, walker)
-> render(sqlAppender, sqlAstArguments1, walker),
asList( sqlAstArguments ),
impliedResultType,
field.getExpressionType()

View File

@ -7,19 +7,18 @@
package org.hibernate.dialect.function;
import org.hibernate.dialect.Dialect;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.TrimSpec;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor;
import org.hibernate.query.sqm.produce.function.StandardArgumentsValidators;
import org.hibernate.query.sqm.produce.function.StandardFunctionReturnTypeResolvers;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmLiteral;
import org.hibernate.query.sqm.tree.expression.SqmTrimSpecification;
import org.hibernate.query.sqm.produce.function.internal.PatternRenderer;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.expression.Expression;
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
import org.hibernate.sql.ast.tree.expression.TrimSpecification;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
import java.util.Collections;
import java.util.List;
@ -27,7 +26,7 @@ import java.util.List;
/**
* @author Gavin King
*/
public class TrimFunction extends AbstractSqmFunctionDescriptor {
public class TrimFunction extends AbstractSqmSelfRenderingFunctionDescriptor {
private Dialect dialect;
@ -41,30 +40,41 @@ public class TrimFunction extends AbstractSqmFunctionDescriptor {
}
@Override
@SuppressWarnings("unchecked")
public <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
final TrimSpec specification = ( (SqmTrimSpecification) arguments.get( 0 ) ).getSpecification();
final char trimCharacter = ( (SqmLiteral<Character>) arguments.get( 1 ) ).getLiteralValue();
final SqmExpression sourceExpr = (SqmExpression) arguments.get( 2 );
public void render(SqlAppender sqlAppender, List<SqlAstNode> sqlAstArguments, SqlAstWalker walker) {
final TrimSpec specification = ( (TrimSpecification) sqlAstArguments.get( 0 ) ).getSpecification();
final Character trimCharacter = ( (QueryLiteral<Character>) sqlAstArguments.get( 1 ) ).getLiteralValue();
final Expression sourceExpr = (Expression) sqlAstArguments.get( 2 );
String trim = dialect.trimPattern( specification, trimCharacter );
return queryEngine.getSqmFunctionRegistry()
.patternDescriptorBuilder( "trim", trim )
.setInvariantType( StandardBasicTypes.STRING )
.setExactArgumentCount( 1 )
.descriptor() //TODO: we could cache the 6 variations here
.generateSqmExpression(
Collections.singletonList( sourceExpr ),
impliedResultType,
queryEngine,
typeConfiguration
);
new PatternRenderer( trim ).render( sqlAppender, Collections.singletonList( sourceExpr ), walker );
}
// @Override
// @SuppressWarnings("unchecked")
// public <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
// List<SqmTypedNode<?>> arguments,
// AllowableFunctionReturnType<T> impliedResultType,
// QueryEngine queryEngine,
// TypeConfiguration typeConfiguration) {
// final TrimSpec specification = ( (SqmTrimSpecification) arguments.get( 0 ) ).getSpecification();
// final char trimCharacter = ( (SqmLiteral<Character>) arguments.get( 1 ) ).getLiteralValue();
// final SqmExpression sourceExpr = (SqmExpression) arguments.get( 2 );
//
// String trim = dialect.trimPattern( specification, trimCharacter );
// return queryEngine.getSqmFunctionRegistry()
// .patternDescriptorBuilder( "trim", trim )
// .setInvariantType( StandardBasicTypes.STRING )
// .setExactArgumentCount( 1 )
// .descriptor() //TODO: we could cache the 6 variations here
// .generateSqmExpression(
// Collections.singletonList( sourceExpr ),
// impliedResultType,
// queryEngine,
// typeConfiguration
// );
// }
@Override
public String getArgumentListSignature() {
return "([[{leading|trailing|both} ][arg0 ]from] arg1)";

View File

@ -927,7 +927,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
ComparisonOperator.EQUAL,
new QueryLiteral<>(
getDiscriminatorValue(),
( (BasicType) getDiscriminatorType() )
( (BasicType<?>) getDiscriminatorType() )
)
);
}

View File

@ -2243,7 +2243,7 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
final List<SqmTypedNode<?>> arguments = new ArrayList<>();
if ( ctx.datetimeField() != null ) {
arguments.add( (SqmTypedNode<?>) ctx.datetimeField().accept( this ) );
arguments.add( toDurationUnit( (SqmExtractUnit<?>) ctx.datetimeField().accept( this ) ) );
}
for ( int i=0, size=ctx.expression().size(); i<size; i++ ) {

View File

@ -75,9 +75,6 @@ public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescri
}
private static SqlAstNode toSqlAstNode(Object arg, SqmToSqlAstConverter walker) {
// if (arg instanceof SqmExpressionInterpretation) {
// return ( (SqmExpressionInterpretation) arg ).toSqlExpression( walker );
// }
return (SqlAstNode) arg;
}
@ -95,7 +92,7 @@ public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescri
}
@Override
public final <T> SelfRenderingSqlFunctionExpression<T> generateSqmExpression(
public final <T> SelfRenderingSqmFunction<T> generateSqmExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
@ -110,11 +107,18 @@ public abstract class AbstractSqmFunctionDescriptor implements SqmFunctionDescri
);
}
protected abstract <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
/**
* Return an SQM node or subtree representing an invocation of this function
* with the given arguments. This method may be overridden in the case of
* function descriptors that wish to customize creation of the node.
*
* @param arguments the arguments of the function invocation
* @param impliedResultType the function return type as inferred from its usage
*/
protected abstract <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine, TypeConfiguration typeConfiguration);
QueryEngine queryEngine,
TypeConfiguration typeConfiguration);
}

View File

@ -5,6 +5,9 @@ import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.produce.function.ArgumentsValidator;
import org.hibernate.query.sqm.produce.function.FunctionReturnTypeResolver;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.spi.SqlAppender;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.type.spi.TypeConfiguration;
import java.util.List;
@ -13,22 +16,22 @@ import java.util.List;
* @author Gavin King
*/
public abstract class AbstractSqmSelfRenderingFunctionDescriptor
extends AbstractSqmFunctionDescriptor
implements SqmSelfRenderingFunctionDescriptor {
extends AbstractSqmFunctionDescriptor {
public AbstractSqmSelfRenderingFunctionDescriptor(String name, ArgumentsValidator argumentsValidator, FunctionReturnTypeResolver returnTypeResolver) {
super( name, argumentsValidator, returnTypeResolver );
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
return new SelfRenderingSqlFunctionExpression<T>(
return new SelfRenderingSqmFunction<T>(
this,
getRenderingSupport(),
(sqlAppender, sqlAstArguments, walker)
-> render(sqlAppender, sqlAstArguments, walker),
arguments,
impliedResultType,
getReturnTypeResolver(),
@ -37,4 +40,12 @@ public abstract class AbstractSqmSelfRenderingFunctionDescriptor
);
}
/**
* Must be overridden by subclasses
*/
public abstract void render(
SqlAppender sqlAppender,
List<SqlAstNode> sqlAstArguments,
SqlAstWalker walker);
}

View File

@ -13,8 +13,12 @@ import org.hibernate.sql.ast.tree.SqlAstNode;
import java.util.List;
/**
* Support for SqmFunctionTemplates that ultimately want to
* perform SQL rendering themselves
* Support for {@link SqmFunctionDescriptor}s that ultimately want
* to perform SQL rendering themselves. This is a protocol passed
* from the {@link AbstractSqmSelfRenderingFunctionDescriptor}
* along to its {@link SelfRenderingSqmFunction} and ultimately to
* the {@link SelfRenderingFunctionSqlAstExpression} which calls it
* to finally render SQL.
*
* @author Steve Ebersole
*/

View File

@ -9,16 +9,17 @@ package org.hibernate.query.sqm.function;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.spi.QueryEngine;
import org.hibernate.query.sqm.tree.SqmTypedNode;
import org.hibernate.query.sqm.tree.expression.SqmJdbcFunctionEscapeWrapper;
import org.hibernate.type.spi.TypeConfiguration;
import java.util.List;
/**
* Acts as a wrapper to another SqmFunctionTemplate - upon rendering uses the
* standard JDBC escape sequence (i.e. `{fn blah}`) when rendering the SQL.
* Acts as a wrapper to another {@link SqmFunctionDescriptor}, rendering the
* standard JDBC escape sequence {@code {fn f(x, y)}} around the invocation
* syntax generated by its delegate.
*
* @author Steve Ebersole
* @author Gavin King
*/
public class JdbcEscapeFunctionDescriptor
extends AbstractSqmFunctionDescriptor {
@ -30,20 +31,32 @@ public class JdbcEscapeFunctionDescriptor
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {
return new SqmJdbcFunctionEscapeWrapper<>(
this,
final SelfRenderingSqmFunction<T> delegate =
wrapped.generateSqmExpression(
arguments,
impliedResultType,
queryEngine,
typeConfiguration
),
queryEngine.getCriteriaBuilder()
);
return new SelfRenderingSqmFunction<T>(
JdbcEscapeFunctionDescriptor.this,
(sqlAppender, sqlAstArguments, walker) -> {
sqlAppender.appendSql("{fn ");
delegate.getRenderingSupport()
.render(sqlAppender, sqlAstArguments, walker);
sqlAppender.appendSql("}");
},
arguments,
impliedResultType,
getReturnTypeResolver(),
queryEngine.getCriteriaBuilder(),
getName());
}
}

View File

@ -56,7 +56,8 @@ public class MultipatternSqmFunctionDescriptor extends AbstractSqmFunctionDescri
public MultipatternSqmFunctionDescriptor(
String name, SqmFunctionDescriptor[] functions,
FunctionReturnTypeResolver type) {
super("",
super(
name,
StandardArgumentsValidators.between(
first(functions),
last(functions)
@ -67,7 +68,7 @@ public class MultipatternSqmFunctionDescriptor extends AbstractSqmFunctionDescri
}
@Override
protected <T> SelfRenderingSqlFunctionExpression<T> generateSqmFunctionExpression(
protected <T> SelfRenderingSqmFunction<T> generateSqmFunctionExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,

View File

@ -25,8 +25,7 @@ import java.util.Locale;
* @author Steve Ebersole
*/
public class NamedSqmFunctionDescriptor
extends AbstractSqmSelfRenderingFunctionDescriptor
implements FunctionRenderingSupport {
extends AbstractSqmSelfRenderingFunctionDescriptor {
private final String functionName;
private final boolean useParenthesesWhenNoArgs;
private final String argumentListSignature;
@ -72,11 +71,6 @@ public class NamedSqmFunctionDescriptor
return useParenthesesWhenNoArgs;
}
@Override
public FunctionRenderingSupport getRenderingSupport() {
return this;
}
@Override
public void render(
SqlAppender sqlAppender,

View File

@ -35,8 +35,7 @@ import java.util.List;
* @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
*/
public class PatternBasedSqmFunctionDescriptor
extends AbstractSqmSelfRenderingFunctionDescriptor
implements FunctionRenderingSupport {
extends AbstractSqmSelfRenderingFunctionDescriptor {
private final PatternRenderer renderer;
private final String argumentListSignature;
@ -66,11 +65,6 @@ public class PatternBasedSqmFunctionDescriptor
this.argumentListSignature = argumentListSignature;
}
@Override
public FunctionRenderingSupport getRenderingSupport() {
return this;
}
@Override
public void render(
SqlAppender sqlAppender,

View File

@ -121,7 +121,7 @@ public class SelfRenderingFunctionSqlAstExpression
SqlAppender sqlAppender,
SqlAstWalker walker,
SessionFactoryImplementor sessionFactory) {
renderer.render( sqlAppender, sqlAstArguments, walker);
renderer.render( sqlAppender, sqlAstArguments, walker );
}
@Override

View File

@ -26,14 +26,14 @@ import static java.util.Collections.emptyList;
/**
* @author Steve Ebersole
*/
public class SelfRenderingSqlFunctionExpression<T> extends SqmFunction<T> {
public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
private final AllowableFunctionReturnType<T> impliedResultType;
private final FunctionReturnTypeResolver returnTypeResolver;
private final String name;
private final FunctionRenderingSupport renderingSupport;
private final List<SqmTypedNode<?>> arguments;
public SelfRenderingSqlFunctionExpression(
public SelfRenderingSqmFunction(
SqmFunctionDescriptor descriptor,
FunctionRenderingSupport renderingSupport,
List<SqmTypedNode<?>> arguments,

View File

@ -39,7 +39,7 @@ public interface SqmFunctionDescriptor {
* simplifying the task of writing HQL functions which are
* portable between databases.
*/
<T> SelfRenderingSqlFunctionExpression<T> generateSqmExpression(
<T> SelfRenderingSqmFunction<T> generateSqmExpression(
List<SqmTypedNode<?>> arguments,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
@ -48,7 +48,7 @@ public interface SqmFunctionDescriptor {
/**
* Convenience for single argument
*/
default <T> SelfRenderingSqlFunctionExpression<T> generateSqmExpression(
default <T> SelfRenderingSqmFunction<T> generateSqmExpression(
SqmTypedNode<?> argument,
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
@ -64,7 +64,7 @@ public interface SqmFunctionDescriptor {
/**
* Convenience for no arguments
*/
default <T> SelfRenderingSqlFunctionExpression<T> generateSqmExpression(
default <T> SelfRenderingSqmFunction<T> generateSqmExpression(
AllowableFunctionReturnType<T> impliedResultType,
QueryEngine queryEngine,
TypeConfiguration typeConfiguration) {

View File

@ -1,14 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.sqm.function;
/**
* @author Steve Ebersole
*/
public interface SqmSelfRenderingFunctionDescriptor extends SqmFunctionDescriptor {
FunctionRenderingSupport getRenderingSupport();
}

View File

@ -116,7 +116,7 @@ public final class ExecuteWithIdTableHelper {
new SqlSelectionImpl(
jdbcPosition,
jdbcPosition + 1,
new QueryLiteral(
new QueryLiteral<>(
sessionUidAccess.apply( executionContext.getSession() ),
StandardBasicTypes.STRING
)
@ -215,7 +215,7 @@ public final class ExecuteWithIdTableHelper {
executionContext.getSession().getFactory()
),
ComparisonOperator.EQUAL,
new QueryLiteral(
new QueryLiteral<>(
sessionUidAccess.apply( executionContext.getSession() ),
UUIDCharType.INSTANCE
)

View File

@ -10,7 +10,6 @@ import org.hibernate.query.sqm.function.NamedSqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.type.BasicType;
import org.hibernate.type.StandardBasicTypes;
/**
* @author Steve Ebersole
@ -72,10 +71,10 @@ public class NamedFunctionDescriptorBuilder {
}
public SqmFunctionDescriptor register() {
return registry.register( registrationKey, template() );
return registry.register( registrationKey, descriptor() );
}
public SqmFunctionDescriptor template() {
public SqmFunctionDescriptor descriptor() {
return new NamedSqmFunctionDescriptor(
functionName,
useParenthesesWhenNoArgs,

View File

@ -859,10 +859,10 @@ public abstract class BaseSqmToSqlAstConverter
@Override
public Expression visitLiteral(SqmLiteral literal) {
if ( literal instanceof SqmLiteralNull ) {
return new QueryLiteral( null, (BasicValuedMapping) inferableTypeAccessStack.getCurrent().get() );
return new QueryLiteral<>( null, (BasicValuedMapping) inferableTypeAccessStack.getCurrent().get() );
}
return new QueryLiteral(
return new QueryLiteral<>(
literal.getLiteralValue(),
(BasicValuedMapping) SqmMappingModelHelper.resolveMappingModelExpressable(
literal,
@ -1527,8 +1527,8 @@ public abstract class BaseSqmToSqlAstConverter
boolean durationToRight = TypeConfiguration.isDuration( rightOperand.getNodeType() );
TypeConfiguration typeConfiguration = getCreationContext().getDomainModel().getTypeConfiguration();
boolean temporalTypeToLeft = typeConfiguration.isTemporalType( leftOperand.getNodeType() );
boolean temporalTypeToRight = typeConfiguration.isTemporalType( rightOperand.getNodeType() );
boolean temporalTypeToLeft = typeConfiguration.isSqlTemporalType( leftOperand.getNodeType() );
boolean temporalTypeToRight = typeConfiguration.isSqlTemporalType( rightOperand.getNodeType() );
boolean temporalTypeSomewhereToLeft = adjustedTimestamp != null || temporalTypeToLeft;
if (temporalTypeToLeft && durationToRight) {
@ -1684,8 +1684,8 @@ public abstract class BaseSqmToSqlAstConverter
Expression right = cleanly(() -> toSqlExpression( expression.getRightHandOperand().accept(this) ));
TypeConfiguration typeConfiguration = getCreationContext().getDomainModel().getTypeConfiguration();
boolean leftTimestamp = typeConfiguration.isTimestampType( expression.getLeftHandOperand().getNodeType() ) ;
boolean rightTimestamp = typeConfiguration.isTimestampType( expression.getRightHandOperand().getNodeType() );
boolean leftTimestamp = typeConfiguration.isSqlTimestampType( expression.getLeftHandOperand().getNodeType() ) ;
boolean rightTimestamp = typeConfiguration.isSqlTimestampType( expression.getRightHandOperand().getNodeType() );
// when we're dealing with Dates, we use
// DAY as the smallest unit, otherwise we
@ -1819,9 +1819,10 @@ public abstract class BaseSqmToSqlAstConverter
return magnitude;
}
@SuppressWarnings("unchecked")
static boolean isOne(Expression scale) {
return scale instanceof QueryLiteral
&& ((QueryLiteral) scale).getLiteralValue().toString().equals("1");
&& ((QueryLiteral<Number>) scale).getLiteralValue().longValue() == 1L;
}
@Override
@ -1954,7 +1955,7 @@ public abstract class BaseSqmToSqlAstConverter
@Override
public Object visitEnumLiteral(SqmEnumLiteral sqmEnumLiteral) {
return new QueryLiteral(
return new QueryLiteral<>(
sqmEnumLiteral.getEnumValue(),
(BasicValuedMapping) determineValueMapping( sqmEnumLiteral )
);
@ -1962,7 +1963,7 @@ public abstract class BaseSqmToSqlAstConverter
@Override
public Object visitFieldLiteral(SqmFieldLiteral sqmFieldLiteral) {
return new QueryLiteral(
return new QueryLiteral<>(
sqmFieldLiteral.getValue(),
(BasicValuedMapping) determineValueMapping( sqmFieldLiteral )
);

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.query.sqm.tree.expression;
import org.hibernate.NotYetImplementedFor6Exception;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.TemporalUnit;
import org.hibernate.query.sqm.NodeBuilder;

View File

@ -1,53 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.sqm.tree.expression;
import org.hibernate.metamodel.model.domain.AllowableFunctionReturnType;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.function.SelfRenderingSqlFunctionExpression;
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
/**
* Adds a JDBC function escape (i.e. `{fn <wrapped-function-call>}) around the wrapped function
*
* @author Steve Ebersole
* @author Gavin King
*/
public class SqmJdbcFunctionEscapeWrapper<T>
extends SelfRenderingSqlFunctionExpression<T> {
private final SelfRenderingSqlFunctionExpression<?> wrappedSqmFunction;
public SqmJdbcFunctionEscapeWrapper(
SqmFunctionDescriptor fun,
SelfRenderingSqlFunctionExpression<T> wrappedSqmFunction,
NodeBuilder nodeBuilder) {
super(
fun,
(sqlAppender, sqlAstArguments, walker) -> {
sqlAppender.appendSql( "{fn " );
wrappedSqmFunction.getRenderingSupport().render(
sqlAppender,
sqlAstArguments,
walker
);
sqlAppender.appendSql( "}" );
},
wrappedSqmFunction.getArguments(),
(AllowableFunctionReturnType<T>) wrappedSqmFunction.getNodeType(),
null, //TODO!!!!!!
nodeBuilder,
wrappedSqmFunction.getFunctionName()
);
this.wrappedSqmFunction = wrappedSqmFunction;
}
@Override
public String asLoggableText() {
return "wrapped-function[ " + wrappedSqmFunction.asLoggableText() + " ]";
}
}

View File

@ -34,16 +34,16 @@ import org.hibernate.type.spi.TypeConfiguration;
* @author Steve Ebersole
*/
public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
private final Object value;
private final T value;
private final BasicValuedMapping type;
public QueryLiteral(Object value, BasicValuedMapping type) {
public QueryLiteral(T value, BasicValuedMapping type) {
this.value = value;
this.type = type;
}
@Override
public Object getLiteralValue() {
public T getLiteralValue() {
return value;
}
@ -98,7 +98,7 @@ public class QueryLiteral<T> implements Literal, DomainResultProducer<T> {
JdbcParameterBindings jdbcParameterBindings,
ExecutionContext executionContext) throws SQLException {
//noinspection unchecked
( (BasicType) getExpressionType() ).getJdbcValueBinder().bind(
( (BasicType<?>) getExpressionType() ).getJdbcValueBinder().bind(
statement,
getLiteralValue(),
startPosition,

View File

@ -46,6 +46,7 @@ import org.hibernate.query.sqm.SqmExpressable;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.BasicType;
import org.hibernate.type.BasicTypeRegistry;
import org.hibernate.type.SingleColumnType;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
@ -473,8 +474,8 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
SqmExpressable<?> secondType,
boolean isDivision) {
if ( isTemporalType( firstType ) ) {
if ( secondType==null || isTemporalType( secondType ) ) {
if ( isSqlTemporalType( firstType ) ) {
if ( secondType==null || isSqlTemporalType( secondType ) ) {
// special case for subtraction of two dates
// or timestamps resulting in a duration
return getBasicTypeRegistry().getRegisteredType( Duration.class );
@ -490,7 +491,7 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
// or prefix scalar multiplication of a duration
return secondType;
}
else if ( firstType==null && isTemporalType( secondType ) ) {
else if ( firstType==null && isSqlTemporalType( secondType ) ) {
// subtraction of a date or timestamp from a
// parameter (which doesn't have a type yet)
return getBasicTypeRegistry().getRegisteredType( Duration.class );
@ -613,33 +614,40 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
);
}
public boolean isTimestampType(SqmExpressable type) {
public boolean isSqlTimestampType(SqmExpressable type) {
return type != null
&& isTimestampType( type.getExpressableJavaTypeDescriptor().getJdbcRecommendedSqlType( getCurrentBaseSqlTypeIndicators() ) );
}
public static boolean isTimestampType(SqlTypeDescriptor descriptor) {
int jdbcTypeCode = descriptor.getJdbcTypeCode();
return jdbcTypeCode == Types.TIMESTAMP
|| jdbcTypeCode == Types.TIMESTAMP_WITH_TIMEZONE;
&& isSqlTimestampType( type.getExpressableJavaTypeDescriptor().getJdbcRecommendedSqlType( getCurrentBaseSqlTypeIndicators() ) );
}
public static boolean isSqlTimestampType(MappingModelExpressable type) {
if ( type instanceof BasicValuedMapping ) {
return isSqlTimestampType( ( (BasicValuedMapping) type ).getJdbcMapping().getSqlTypeDescriptor() );
}
else if (type instanceof SingleColumnType) {
return isSqlTimestampType( ((SingleColumnType) type).sqlType() );
}
return false;
}
public static boolean isSqlTimestampType(SqlTypeDescriptor descriptor) {
int jdbcTypeCode = descriptor.getJdbcTypeCode();
return isSqlTimestampType( descriptor.getJdbcTypeCode() );
}
protected static boolean isSqlTimestampType(int jdbcTypeCode) {
return jdbcTypeCode == Types.TIMESTAMP
|| jdbcTypeCode == Types.TIMESTAMP_WITH_TIMEZONE;
}
public static boolean isTemporalType(SqlTypeDescriptor descriptor) {
int jdbcTypeCode = descriptor.getJdbcTypeCode();
public static boolean isSqlTemporalType(SqlTypeDescriptor descriptor) {
return isSqlTemporalType( descriptor.getJdbcTypeCode() );
}
public boolean isSqlTemporalType(SqmExpressable<?> type) {
return type != null
&& isSqlTemporalType( type.getExpressableJavaTypeDescriptor().getJdbcRecommendedSqlType( getCurrentBaseSqlTypeIndicators() ) );
}
private static boolean isSqlTemporalType(int jdbcTypeCode) {
return jdbcTypeCode == Types.TIMESTAMP
|| jdbcTypeCode == Types.TIMESTAMP_WITH_TIMEZONE
|| jdbcTypeCode == Types.TIME
@ -647,10 +655,6 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|| jdbcTypeCode == Types.DATE;
}
public boolean isTemporalType(SqmExpressable<?> type) {
return type != null
&& isTemporalType( type.getExpressableJavaTypeDescriptor().getJdbcRecommendedSqlType( getCurrentBaseSqlTypeIndicators() ) );
}
public static boolean isJdbcTemporalType(SqmExpressable<?> type) {
return matchesJavaType( type, Date.class );