From b57fbb124546c7807a30a05e4545ef2d22493198 Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Fri, 4 Aug 2023 16:11:35 +0200 Subject: [PATCH] Fix Sybase duration arithmetic problem --- .../IntegralTimestampaddFunction.java | 2 +- .../org/hibernate/query/sqm/TemporalUnit.java | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/IntegralTimestampaddFunction.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/IntegralTimestampaddFunction.java index 154990cbf7..919f119eae 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/IntegralTimestampaddFunction.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/IntegralTimestampaddFunction.java @@ -103,7 +103,7 @@ public class IntegralTimestampaddFunction private Expression convertedArgument(DurationUnit field, TemporalUnit unit, Expression magnitude) { final BasicValuedMapping expressionType = (BasicValuedMapping) magnitude.getExpressionType(); - final String conversionFactor = field.getUnit().conversionFactor( unit, dialect ); + final String conversionFactor = field.getUnit().conversionFactorFull( unit, dialect ); return conversionFactor.isEmpty() ? magnitude : new BinaryArithmeticExpression( diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/TemporalUnit.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/TemporalUnit.java index d47c16d04c..b5aca3a272 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/TemporalUnit.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/TemporalUnit.java @@ -197,6 +197,33 @@ public enum TemporalUnit { } } + public String conversionFactorFull(TemporalUnit unit, Dialect dialect) { + + if ( unit == this ) { + //same unit, nothing to do + return ""; + } + + if ( unit.normalized() != normalized() ) { + throw new SemanticException("Illegal unit conversion " + this + " to " + unit); + } + + long from = normalizationFactor( dialect ); + long to = unit.normalizationFactor( dialect ); + if ( from == to ) { + // the units represent the same amount of time + return ""; + } + else { + // if from < to, then this unit represents a + // smaller amount of time than the given unit + // we are converting to (so we're going to + // need to use division) + return (from < to ? "/" : "*") + + (from < to ? to / from : from / to); + } + } + /** * The conversion factor required to convert this * unit to its {@link #normalized()} unit.