Introduce FunctionExpression in SQL AST and remove shallowness handling in sqm to sql converter
This commit is contained in:
parent
7934625688
commit
682678fbe5
|
@ -90,6 +90,7 @@ public class TimestampaddFunction
|
||||||
SqlAstNode... sqlAstArguments) {
|
SqlAstNode... sqlAstArguments) {
|
||||||
Expression to = (Expression) sqlAstArguments[2];
|
Expression to = (Expression) sqlAstArguments[2];
|
||||||
return new SelfRenderingFunctionSqlAstExpression(
|
return new SelfRenderingFunctionSqlAstExpression(
|
||||||
|
getName(),
|
||||||
this::render,
|
this::render,
|
||||||
asList( sqlAstArguments ),
|
asList( sqlAstArguments ),
|
||||||
impliedResultType,
|
impliedResultType,
|
||||||
|
|
|
@ -95,6 +95,7 @@ public class TimestampdiffFunction
|
||||||
SqlAstNode... sqlAstArguments) {
|
SqlAstNode... sqlAstArguments) {
|
||||||
DurationUnit field = (DurationUnit) sqlAstArguments[0];
|
DurationUnit field = (DurationUnit) sqlAstArguments[0];
|
||||||
return new SelfRenderingFunctionSqlAstExpression(
|
return new SelfRenderingFunctionSqlAstExpression(
|
||||||
|
getName(),
|
||||||
this::render,
|
this::render,
|
||||||
asList( sqlAstArguments ),
|
asList( sqlAstArguments ),
|
||||||
impliedResultType,
|
impliedResultType,
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||||
import org.hibernate.sql.ast.tree.SqlAstNode;
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
import org.hibernate.sql.ast.tree.expression.FunctionExpression;
|
||||||
import org.hibernate.sql.ast.tree.expression.SelfRenderingExpression;
|
import org.hibernate.sql.ast.tree.expression.SelfRenderingExpression;
|
||||||
import org.hibernate.sql.results.graph.DomainResult;
|
import org.hibernate.sql.results.graph.DomainResult;
|
||||||
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
import org.hibernate.sql.results.graph.DomainResultCreationState;
|
||||||
|
@ -40,17 +41,20 @@ import java.util.List;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public class SelfRenderingFunctionSqlAstExpression
|
public class SelfRenderingFunctionSqlAstExpression
|
||||||
implements SelfRenderingExpression, Selectable, SqlExpressable, DomainResultProducer {
|
implements SelfRenderingExpression, Selectable, SqlExpressable, DomainResultProducer, FunctionExpression {
|
||||||
|
private final String functionName;
|
||||||
private final FunctionRenderingSupport renderer;
|
private final FunctionRenderingSupport renderer;
|
||||||
private final List<SqlAstNode> sqlAstArguments;
|
private final List<SqlAstNode> sqlAstArguments;
|
||||||
private final AllowableFunctionReturnType<?> type;
|
private final AllowableFunctionReturnType<?> type;
|
||||||
private final MappingModelExpressable<?> expressable;
|
private final MappingModelExpressable<?> expressable;
|
||||||
|
|
||||||
public SelfRenderingFunctionSqlAstExpression(
|
public SelfRenderingFunctionSqlAstExpression(
|
||||||
|
String functionName,
|
||||||
FunctionRenderingSupport renderer,
|
FunctionRenderingSupport renderer,
|
||||||
List<SqlAstNode> sqlAstArguments,
|
List<SqlAstNode> sqlAstArguments,
|
||||||
AllowableFunctionReturnType<?> type,
|
AllowableFunctionReturnType<?> type,
|
||||||
MappingModelExpressable<?> expressable) {
|
MappingModelExpressable<?> expressable) {
|
||||||
|
this.functionName = functionName;
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
this.sqlAstArguments = sqlAstArguments;
|
this.sqlAstArguments = sqlAstArguments;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
@ -58,6 +62,16 @@ public class SelfRenderingFunctionSqlAstExpression
|
||||||
this.expressable = expressable;
|
this.expressable = expressable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFunctionName() {
|
||||||
|
return functionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SqlAstNode> getArguments() {
|
||||||
|
return sqlAstArguments;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MappingModelExpressable getExpressionType() {
|
public MappingModelExpressable getExpressionType() {
|
||||||
return expressable;
|
return expressable;
|
||||||
|
|
|
@ -31,9 +31,7 @@ import static java.util.Collections.emptyList;
|
||||||
public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
|
public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
|
||||||
private final AllowableFunctionReturnType<T> impliedResultType;
|
private final AllowableFunctionReturnType<T> impliedResultType;
|
||||||
private final FunctionReturnTypeResolver returnTypeResolver;
|
private final FunctionReturnTypeResolver returnTypeResolver;
|
||||||
private final String name;
|
|
||||||
private final FunctionRenderingSupport renderingSupport;
|
private final FunctionRenderingSupport renderingSupport;
|
||||||
private final List<SqmTypedNode<?>> arguments;
|
|
||||||
private AllowableFunctionReturnType<?> resultType;
|
private AllowableFunctionReturnType<?> resultType;
|
||||||
|
|
||||||
public SelfRenderingSqmFunction(
|
public SelfRenderingSqmFunction(
|
||||||
|
@ -44,41 +42,38 @@ public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
|
||||||
FunctionReturnTypeResolver returnTypeResolver,
|
FunctionReturnTypeResolver returnTypeResolver,
|
||||||
NodeBuilder nodeBuilder,
|
NodeBuilder nodeBuilder,
|
||||||
String name) {
|
String name) {
|
||||||
super( name, descriptor, impliedResultType, nodeBuilder );
|
super( name, descriptor, impliedResultType, arguments, nodeBuilder );
|
||||||
this.renderingSupport = renderingSupport;
|
this.renderingSupport = renderingSupport;
|
||||||
this.arguments = arguments;
|
|
||||||
this.impliedResultType = impliedResultType;
|
this.impliedResultType = impliedResultType;
|
||||||
this.returnTypeResolver = returnTypeResolver;
|
this.returnTypeResolver = returnTypeResolver;
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<SqmTypedNode<?>> getArguments() {
|
|
||||||
return arguments;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public FunctionRenderingSupport getRenderingSupport() {
|
public FunctionRenderingSupport getRenderingSupport() {
|
||||||
return renderingSupport;
|
return renderingSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<SqlAstNode> resolveSqlAstArguments(List<SqmTypedNode<?>> sqmArguments, SqmToSqlAstConverter walker) {
|
protected static List<SqlAstNode> resolveSqlAstArguments(List<SqmTypedNode<?>> sqmArguments, SqmToSqlAstConverter walker) {
|
||||||
if ( sqmArguments == null || sqmArguments.isEmpty() ) {
|
if ( sqmArguments == null || sqmArguments.isEmpty() ) {
|
||||||
return emptyList();
|
return emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
final ArrayList<SqlAstNode> sqlAstArguments = new ArrayList<>();
|
final ArrayList<SqlAstNode> sqlAstArguments = new ArrayList<>( sqmArguments.size() );
|
||||||
for ( SqmTypedNode<?> sqmArgument : sqmArguments ) {
|
for ( SqmTypedNode<?> sqmArgument : sqmArguments ) {
|
||||||
sqlAstArguments.add((SqlAstNode) ((SqmVisitableNode) sqmArgument).accept(walker));
|
sqlAstArguments.add( (SqlAstNode) ( (SqmVisitableNode) sqmArgument ).accept( walker ) );
|
||||||
}
|
}
|
||||||
return sqlAstArguments;
|
return sqlAstArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SelfRenderingFunctionSqlAstExpression convertToSqlAst(SqmToSqlAstConverter walker) {
|
public SelfRenderingFunctionSqlAstExpression convertToSqlAst(SqmToSqlAstConverter walker) {
|
||||||
resolveResultType( walker.getCreationContext().getDomainModel().getTypeConfiguration() );
|
final AllowableFunctionReturnType<?> resultType = resolveResultType(
|
||||||
|
walker.getCreationContext().getDomainModel().getTypeConfiguration()
|
||||||
|
);
|
||||||
|
|
||||||
return new SelfRenderingFunctionSqlAstExpression(
|
return new SelfRenderingFunctionSqlAstExpression(
|
||||||
|
getFunctionName(),
|
||||||
getRenderingSupport(),
|
getRenderingSupport(),
|
||||||
resolveSqlAstArguments( getArguments(), walker),
|
resolveSqlAstArguments( getArguments(), walker ),
|
||||||
resultType,
|
resultType,
|
||||||
getMappingModelExpressable( walker, resultType )
|
getMappingModelExpressable( walker, resultType )
|
||||||
);
|
);
|
||||||
|
@ -93,7 +88,7 @@ public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
|
||||||
return nodeType;
|
return nodeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveResultType(TypeConfiguration typeConfiguration) {
|
protected AllowableFunctionReturnType<?> resolveResultType(TypeConfiguration typeConfiguration) {
|
||||||
if ( resultType == null ) {
|
if ( resultType == null ) {
|
||||||
resultType = returnTypeResolver.resolveFunctionReturnType(
|
resultType = returnTypeResolver.resolveFunctionReturnType(
|
||||||
impliedResultType,
|
impliedResultType,
|
||||||
|
@ -102,9 +97,10 @@ public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
|
||||||
);
|
);
|
||||||
setExpressableType( resultType );
|
setExpressableType( resultType );
|
||||||
}
|
}
|
||||||
|
return resultType;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MappingModelExpressable<?> getMappingModelExpressable(
|
protected MappingModelExpressable<?> getMappingModelExpressable(
|
||||||
SqmToSqlAstConverter walker,
|
SqmToSqlAstConverter walker,
|
||||||
AllowableFunctionReturnType<?> resultType) {
|
AllowableFunctionReturnType<?> resultType) {
|
||||||
MappingModelExpressable<?> mapping;
|
MappingModelExpressable<?> mapping;
|
||||||
|
@ -131,17 +127,12 @@ public class SelfRenderingSqmFunction<T> extends SqmFunction<T> {
|
||||||
return null; // this works at least approximately
|
return null; // this works at least approximately
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
resolveSqlAstArguments( arguments, walker )
|
resolveSqlAstArguments( getArguments(), walker )
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFunctionName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applySqlSelections(DomainResultCreationState creationState) {
|
public void applySqlSelections(DomainResultCreationState creationState) {
|
||||||
//implemented on SelfRenderingFunctionSqlAstExpression
|
//implemented on SelfRenderingFunctionSqlAstExpression
|
||||||
|
|
|
@ -293,13 +293,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
|
|
||||||
private static final Logger log = Logger.getLogger( BaseSqmToSqlAstConverter.class );
|
private static final Logger log = Logger.getLogger( BaseSqmToSqlAstConverter.class );
|
||||||
|
|
||||||
protected enum Shallowness {
|
|
||||||
NONE,
|
|
||||||
CTOR,
|
|
||||||
FUNCTION,
|
|
||||||
SUBQUERY
|
|
||||||
}
|
|
||||||
|
|
||||||
private final SqlAstCreationContext creationContext;
|
private final SqlAstCreationContext creationContext;
|
||||||
private final SqmStatement<?> statement;
|
private final SqmStatement<?> statement;
|
||||||
|
|
||||||
|
@ -326,7 +319,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
private FromClauseIndex lastPoppedFromClauseIndex;
|
private FromClauseIndex lastPoppedFromClauseIndex;
|
||||||
|
|
||||||
private final Stack<Clause> currentClauseStack = new StandardStack<>();
|
private final Stack<Clause> currentClauseStack = new StandardStack<>();
|
||||||
private final Stack<Shallowness> shallownessStack = new StandardStack<>( Shallowness.NONE );
|
|
||||||
|
|
||||||
private SqmByUnit appliedByUnit;
|
private SqmByUnit appliedByUnit;
|
||||||
private Expression adjustedTimestamp;
|
private Expression adjustedTimestamp;
|
||||||
|
@ -1331,7 +1323,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
@Override
|
@Override
|
||||||
public SelectClause visitSelectClause(SqmSelectClause selectClause) {
|
public SelectClause visitSelectClause(SqmSelectClause selectClause) {
|
||||||
currentClauseStack.push( Clause.SELECT );
|
currentClauseStack.push( Clause.SELECT );
|
||||||
shallownessStack.push( Shallowness.SUBQUERY );
|
|
||||||
try {
|
try {
|
||||||
super.visitSelectClause( selectClause );
|
super.visitSelectClause( selectClause );
|
||||||
|
|
||||||
|
@ -1340,7 +1331,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
return sqlSelectClause;
|
return sqlSelectClause;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
shallownessStack.pop();
|
|
||||||
currentClauseStack.pop();
|
currentClauseStack.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2297,12 +2287,10 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
@Override
|
@Override
|
||||||
public Expression visitFunction(SqmFunction sqmFunction) {
|
public Expression visitFunction(SqmFunction sqmFunction) {
|
||||||
inferableTypeAccessStack.push( () -> null );
|
inferableTypeAccessStack.push( () -> null );
|
||||||
shallownessStack.push( Shallowness.FUNCTION );
|
|
||||||
try {
|
try {
|
||||||
return sqmFunction.convertToSqlAst( this );
|
return sqmFunction.convertToSqlAst( this );
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
shallownessStack.pop();
|
|
||||||
inferableTypeAccessStack.pop();
|
inferableTypeAccessStack.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2319,61 +2307,37 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitTrimSpecification(SqmTrimSpecification specification) {
|
public Object visitTrimSpecification(SqmTrimSpecification specification) {
|
||||||
shallownessStack.push( Shallowness.FUNCTION );
|
return new TrimSpecification( specification.getSpecification() );
|
||||||
try {
|
|
||||||
return new TrimSpecification( specification.getSpecification() );
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
shallownessStack.pop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitCastTarget(SqmCastTarget target) {
|
public Object visitCastTarget(SqmCastTarget target) {
|
||||||
shallownessStack.push( Shallowness.FUNCTION );
|
BasicValuedMapping targetType = (BasicValuedMapping) target.getType();
|
||||||
try {
|
if ( targetType instanceof BasicType<?> ) {
|
||||||
BasicValuedMapping targetType = (BasicValuedMapping) target.getType();
|
targetType = InferredBasicValueResolver.resolveSqlTypeIndicators( this, (BasicType<?>) targetType );
|
||||||
if ( targetType instanceof BasicType<?> ) {
|
|
||||||
targetType = InferredBasicValueResolver.resolveSqlTypeIndicators( this, (BasicType<?>) targetType );
|
|
||||||
}
|
|
||||||
return new CastTarget(
|
|
||||||
targetType,
|
|
||||||
target.getLength(),
|
|
||||||
target.getPrecision(),
|
|
||||||
target.getScale()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
shallownessStack.pop();
|
|
||||||
}
|
}
|
||||||
|
return new CastTarget(
|
||||||
|
targetType,
|
||||||
|
target.getLength(),
|
||||||
|
target.getPrecision(),
|
||||||
|
target.getScale()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitExtractUnit(SqmExtractUnit unit) {
|
public Object visitExtractUnit(SqmExtractUnit unit) {
|
||||||
shallownessStack.push( Shallowness.FUNCTION );
|
return new ExtractUnit(
|
||||||
try {
|
unit.getUnit(),
|
||||||
return new ExtractUnit(
|
(BasicValuedMapping) unit.getType()
|
||||||
unit.getUnit(),
|
);
|
||||||
(BasicValuedMapping) unit.getType()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
shallownessStack.pop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitDurationUnit(SqmDurationUnit unit) {
|
public Object visitDurationUnit(SqmDurationUnit unit) {
|
||||||
shallownessStack.push( Shallowness.FUNCTION );
|
return new DurationUnit(
|
||||||
try {
|
unit.getUnit(),
|
||||||
return new DurationUnit(
|
(BasicValuedMapping) unit.getType()
|
||||||
unit.getUnit(),
|
);
|
||||||
(BasicValuedMapping) unit.getType()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
shallownessStack.pop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2764,18 +2728,11 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitUnaryOperationExpression(SqmUnaryOperation expression) {
|
public Object visitUnaryOperationExpression(SqmUnaryOperation expression) {
|
||||||
shallownessStack.push( Shallowness.NONE );
|
return new UnaryOperation(
|
||||||
|
interpret( expression.getOperation() ),
|
||||||
try {
|
toSqlExpression( expression.getOperand().accept( this ) ),
|
||||||
return new UnaryOperation(
|
(BasicValuedMapping) determineValueMapping( expression.getOperand() )
|
||||||
interpret( expression.getOperation() ),
|
);
|
||||||
toSqlExpression( expression.getOperand().accept( this ) ),
|
|
||||||
(BasicValuedMapping) determineValueMapping( expression.getOperand() )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
shallownessStack.pop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private UnaryArithmeticOperator interpret(UnaryArithmeticOperator operator) {
|
private UnaryArithmeticOperator interpret(UnaryArithmeticOperator operator) {
|
||||||
|
@ -2784,52 +2741,45 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object visitBinaryArithmeticExpression(SqmBinaryArithmetic expression) {
|
public Object visitBinaryArithmeticExpression(SqmBinaryArithmetic expression) {
|
||||||
shallownessStack.push( Shallowness.NONE );
|
SqmExpression leftOperand = expression.getLeftHandOperand();
|
||||||
|
SqmExpression rightOperand = expression.getRightHandOperand();
|
||||||
|
|
||||||
try {
|
boolean durationToRight = TypeConfiguration.isDuration( rightOperand.getNodeType() );
|
||||||
SqmExpression leftOperand = expression.getLeftHandOperand();
|
TypeConfiguration typeConfiguration = getCreationContext().getDomainModel().getTypeConfiguration();
|
||||||
SqmExpression rightOperand = expression.getRightHandOperand();
|
TemporalType temporalTypeToLeft = typeConfiguration.getSqlTemporalType( leftOperand.getNodeType() );
|
||||||
|
TemporalType temporalTypeToRight = typeConfiguration.getSqlTemporalType( rightOperand.getNodeType() );
|
||||||
|
boolean temporalTypeSomewhereToLeft = adjustedTimestamp != null || temporalTypeToLeft != null;
|
||||||
|
|
||||||
boolean durationToRight = TypeConfiguration.isDuration( rightOperand.getNodeType() );
|
if ( temporalTypeToLeft != null && durationToRight ) {
|
||||||
TypeConfiguration typeConfiguration = getCreationContext().getDomainModel().getTypeConfiguration();
|
if ( adjustmentScale != null || negativeAdjustment ) {
|
||||||
TemporalType temporalTypeToLeft = typeConfiguration.getSqlTemporalType( leftOperand.getNodeType() );
|
//we can't distribute a scale over a date/timestamp
|
||||||
TemporalType temporalTypeToRight = typeConfiguration.getSqlTemporalType( rightOperand.getNodeType() );
|
throw new SemanticException( "scalar multiplication of temporal value" );
|
||||||
boolean temporalTypeSomewhereToLeft = adjustedTimestamp != null || temporalTypeToLeft != null;
|
|
||||||
|
|
||||||
if ( temporalTypeToLeft != null && durationToRight ) {
|
|
||||||
if ( adjustmentScale != null || negativeAdjustment ) {
|
|
||||||
//we can't distribute a scale over a date/timestamp
|
|
||||||
throw new SemanticException( "scalar multiplication of temporal value" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( durationToRight && temporalTypeSomewhereToLeft ) {
|
|
||||||
return transformDurationArithmetic( expression );
|
|
||||||
}
|
|
||||||
else if ( temporalTypeToLeft != null && temporalTypeToRight != null ) {
|
|
||||||
return transformDatetimeArithmetic( expression );
|
|
||||||
}
|
|
||||||
else if ( durationToRight && appliedByUnit != null ) {
|
|
||||||
return new BinaryArithmeticExpression(
|
|
||||||
toSqlExpression( leftOperand.accept( this ) ),
|
|
||||||
expression.getOperator(),
|
|
||||||
toSqlExpression( rightOperand.accept( this ) ),
|
|
||||||
//after distributing the 'by unit' operator
|
|
||||||
//we always get a Long value back
|
|
||||||
(BasicValuedMapping) appliedByUnit.getNodeType()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return new BinaryArithmeticExpression(
|
|
||||||
toSqlExpression( leftOperand.accept( this ) ),
|
|
||||||
expression.getOperator(),
|
|
||||||
toSqlExpression( rightOperand.accept( this ) ),
|
|
||||||
getExpressionType( expression )
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
shallownessStack.pop();
|
if ( durationToRight && temporalTypeSomewhereToLeft ) {
|
||||||
|
return transformDurationArithmetic( expression );
|
||||||
|
}
|
||||||
|
else if ( temporalTypeToLeft != null && temporalTypeToRight != null ) {
|
||||||
|
return transformDatetimeArithmetic( expression );
|
||||||
|
}
|
||||||
|
else if ( durationToRight && appliedByUnit != null ) {
|
||||||
|
return new BinaryArithmeticExpression(
|
||||||
|
toSqlExpression( leftOperand.accept( this ) ),
|
||||||
|
expression.getOperator(),
|
||||||
|
toSqlExpression( rightOperand.accept( this ) ),
|
||||||
|
//after distributing the 'by unit' operator
|
||||||
|
//we always get a Long value back
|
||||||
|
(BasicValuedMapping) appliedByUnit.getNodeType()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new BinaryArithmeticExpression(
|
||||||
|
toSqlExpression( leftOperand.accept( this ) ),
|
||||||
|
expression.getOperator(),
|
||||||
|
toSqlExpression( rightOperand.accept( this ) ),
|
||||||
|
getExpressionType( expression )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* 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.sql.ast.tree.expression;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.sql.ast.tree.SqlAstNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Models a function expression at the SQL AST level.
|
||||||
|
*
|
||||||
|
* @author Christian Beikov
|
||||||
|
*/
|
||||||
|
public interface FunctionExpression extends Expression {
|
||||||
|
|
||||||
|
String getFunctionName();
|
||||||
|
|
||||||
|
List<SqlAstNode> getArguments();
|
||||||
|
}
|
Loading…
Reference in New Issue