use of org.hibernate.query.sqm.BinaryArithmeticOperator in project hibernate-orm by hibernate.
the class SemanticQueryBuilder method visitMultiplicationExpression.
@Override
public Object visitMultiplicationExpression(HqlParser.MultiplicationExpressionContext ctx) {
if (ctx.getChildCount() != 3) {
throw new ParsingException("Expecting 2 operands to the multiplicative operator");
}
final SqmExpression<?> left = (SqmExpression<?>) ctx.getChild(0).accept(this);
final SqmExpression<?> right = (SqmExpression<?>) ctx.getChild(2).accept(this);
final BinaryArithmeticOperator operator = (BinaryArithmeticOperator) ctx.getChild(1).accept(this);
if (operator == BinaryArithmeticOperator.MODULO) {
return getFunctionDescriptor("mod").generateSqmExpression(asList(left, right), null, creationContext.getQueryEngine(), creationContext.getJpaMetamodel().getTypeConfiguration());
} else {
return new SqmBinaryArithmetic<>(operator, left, right, creationContext.getJpaMetamodel(), creationContext.getNodeBuilder());
}
}
use of org.hibernate.query.sqm.BinaryArithmeticOperator in project hibernate-orm by hibernate.
the class BaseSqmToSqlAstConverter method transformDatetimeArithmetic.
private Object transformDatetimeArithmetic(SqmBinaryArithmetic<?> expression) {
BinaryArithmeticOperator operator = expression.getOperator();
// timestamps are ill-formed
if (operator != SUBTRACT) {
throw new SemanticException("illegal operator for temporal type: " + operator);
}
// a difference between two dates or two
// timestamps is a leaf duration, so we
// must apply the scale, and the 'by unit'
// ts1 - ts2
Expression left = cleanly(() -> toSqlExpression(expression.getLeftHandOperand().accept(this)));
Expression right = cleanly(() -> toSqlExpression(expression.getRightHandOperand().accept(this)));
TypeConfiguration typeConfiguration = getCreationContext().getMappingMetamodel().getTypeConfiguration();
TemporalType leftTimestamp = typeConfiguration.getSqlTemporalType(expression.getLeftHandOperand().getNodeType());
TemporalType rightTimestamp = typeConfiguration.getSqlTemporalType(expression.getRightHandOperand().getNodeType());
// when we're dealing with Dates, we use
// DAY as the smallest unit, otherwise we
// use a platform-specific granularity
TemporalUnit baseUnit = (rightTimestamp == TemporalType.TIMESTAMP || leftTimestamp == TemporalType.TIMESTAMP) ? NATIVE : DAY;
if (adjustedTimestamp != null) {
if (appliedByUnit != null) {
throw new IllegalStateException();
}
// we're using the resulting duration to
// adjust a date or timestamp on the left
// baseUnit is the finest resolution for the
// temporal type, so we must use it for both
// the diff, and then the subsequent add
DurationUnit unit = new DurationUnit(baseUnit, basicType(Integer.class));
Expression magnitude = applyScale(timestampdiff().expression(null, unit, right, left));
return timestampadd().expression(// TODO should be adjustedTimestamp.getType()
(ReturnableType<?>) adjustedTimestampType, unit, magnitude, adjustedTimestamp);
} else if (appliedByUnit != null) {
// we're immediately converting the resulting
// duration to a scalar in the given unit
DurationUnit unit = (DurationUnit) appliedByUnit.getUnit().accept(this);
return applyScale(timestampdiff().expression(null, unit, right, left));
} else {
// a plain "bare" Duration
DurationUnit unit = new DurationUnit(baseUnit, basicType(Integer.class));
BasicValuedMapping durationType = (BasicValuedMapping) expression.getNodeType();
Expression scaledMagnitude = applyScale(timestampdiff().expression((ReturnableType<?>) expression.getNodeType(), unit, right, left));
return new Duration(scaledMagnitude, baseUnit, durationType);
}
}
Aggregations