提交 93685170 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Extract BigInteger constants in IntervalUtils

上级 f0169c88
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
*/ */
package org.h2.expression; package org.h2.expression;
import static org.h2.util.IntervalUtils.NANOS_PER_DAY_BI;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
...@@ -169,9 +171,9 @@ public class IntervalOperation extends Expression { ...@@ -169,9 +171,9 @@ public class IntervalOperation extends Expression {
} else { } else {
long[] a = DateTimeUtils.dateAndTimeFromValue(l); long[] a = DateTimeUtils.dateAndTimeFromValue(l);
long[] b = DateTimeUtils.dateAndTimeFromValue(r); long[] b = DateTimeUtils.dateAndTimeFromValue(r);
BigInteger bi1 = BigInteger.valueOf(a[0]).multiply(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY)) BigInteger bi1 = BigInteger.valueOf(a[0]).multiply(NANOS_PER_DAY_BI)
.add(BigInteger.valueOf(a[1])); .add(BigInteger.valueOf(a[1]));
BigInteger bi2 = BigInteger.valueOf(b[0]).multiply(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY)) BigInteger bi2 = BigInteger.valueOf(b[0]).multiply(NANOS_PER_DAY_BI)
.add(BigInteger.valueOf(b[1])); .add(BigInteger.valueOf(b[1]));
BigInteger diff = bi1.subtract(bi2); BigInteger diff = bi1.subtract(bi2);
if (lType == Value.TIMESTAMP_TZ || rType == Value.TIMESTAMP_TZ) { if (lType == Value.TIMESTAMP_TZ || rType == Value.TIMESTAMP_TZ) {
...@@ -195,7 +197,7 @@ public class IntervalOperation extends Expression { ...@@ -195,7 +197,7 @@ public class IntervalOperation extends Expression {
BigInteger a1 = BigInteger.valueOf(((ValueTime) l).getNanos()); BigInteger a1 = BigInteger.valueOf(((ValueTime) l).getNanos());
BigInteger a2 = IntervalUtils.intervalToAbsolute((ValueInterval) r); BigInteger a2 = IntervalUtils.intervalToAbsolute((ValueInterval) r);
BigInteger n = opType == IntervalOpType.DATETIME_PLUS_INTERVAL ? a1.add(a2) : a1.subtract(a2); BigInteger n = opType == IntervalOpType.DATETIME_PLUS_INTERVAL ? a1.add(a2) : a1.subtract(a2);
if (n.signum() < 0 || n.compareTo(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY)) >= 0) { if (n.signum() < 0 || n.compareTo(NANOS_PER_DAY_BI) >= 0) {
throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, n.toString()); throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, n.toString());
} }
return ValueTime.fromNanos(n.longValue()); return ValueTime.fromNanos(n.longValue());
...@@ -214,14 +216,14 @@ public class IntervalOperation extends Expression { ...@@ -214,14 +216,14 @@ public class IntervalOperation extends Expression {
if (lType == Value.DATE) { if (lType == Value.DATE) {
BigInteger a1 = BigInteger BigInteger a1 = BigInteger
.valueOf(DateTimeUtils.absoluteDayFromDateValue(((ValueDate) l).getDateValue())); .valueOf(DateTimeUtils.absoluteDayFromDateValue(((ValueDate) l).getDateValue()));
a2 = a2.divide(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY)); a2 = a2.divide(NANOS_PER_DAY_BI);
BigInteger n = opType == IntervalOpType.DATETIME_PLUS_INTERVAL ? a1.add(a2) : a1.subtract(a2); BigInteger n = opType == IntervalOpType.DATETIME_PLUS_INTERVAL ? a1.add(a2) : a1.subtract(a2);
return ValueDate.fromDateValue(DateTimeUtils.dateValueFromAbsoluteDay(n.longValue())); return ValueDate.fromDateValue(DateTimeUtils.dateValueFromAbsoluteDay(n.longValue()));
} else { } else {
long[] a = DateTimeUtils.dateAndTimeFromValue(l); long[] a = DateTimeUtils.dateAndTimeFromValue(l);
long absoluteDay = DateTimeUtils.absoluteDayFromDateValue(a[0]); long absoluteDay = DateTimeUtils.absoluteDayFromDateValue(a[0]);
long timeNanos = a[1]; long timeNanos = a[1];
BigInteger[] dr = a2.divideAndRemainder(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY)); BigInteger[] dr = a2.divideAndRemainder(NANOS_PER_DAY_BI);
if (opType == IntervalOpType.DATETIME_PLUS_INTERVAL) { if (opType == IntervalOpType.DATETIME_PLUS_INTERVAL) {
absoluteDay += dr[0].longValue(); absoluteDay += dr[0].longValue();
timeNanos += dr[1].longValue(); timeNanos += dr[1].longValue();
......
...@@ -22,6 +22,29 @@ import org.h2.value.ValueInterval; ...@@ -22,6 +22,29 @@ import org.h2.value.ValueInterval;
*/ */
public class IntervalUtils { public class IntervalUtils {
private static final BigInteger NANOS_PER_SECOND_BI = BigInteger.valueOf(NANOS_PER_SECOND);
private static final BigInteger NANOS_PER_MINUTE_BI = BigInteger.valueOf(NANOS_PER_MINUTE);
private static final BigInteger NANOS_PER_HOUR_BI = BigInteger.valueOf(NANOS_PER_HOUR);
/**
* The number of nanoseconds per day as BigInteger.
*/
public static final BigInteger NANOS_PER_DAY_BI = BigInteger.valueOf(NANOS_PER_DAY);
private static final BigInteger MONTHS_PER_YEAR_BI = BigInteger.valueOf(12);
private static final BigInteger HOURS_PER_DAY_BI = BigInteger.valueOf(24);
private static final BigInteger MINUTES_PER_DAY_BI = BigInteger.valueOf(24 * 60);
private static final BigInteger MINUTES_PER_HOUR_BI = BigInteger.valueOf(60);
private static final BigInteger LEADING_MIN = BigInteger.valueOf(-999_999_999_999_999_999L);
private static final BigInteger LEADING_MAX = BigInteger.valueOf(999_999_999_999_999_999L);
private IntervalUtils() { private IntervalUtils() {
// utility class // utility class
} }
...@@ -458,43 +481,43 @@ public class IntervalUtils { ...@@ -458,43 +481,43 @@ public class IntervalUtils {
BigInteger r; BigInteger r;
switch (interval.getQualifier()) { switch (interval.getQualifier()) {
case YEAR: case YEAR:
r = BigInteger.valueOf(interval.getLeading()).multiply(BigInteger.valueOf(12)); r = BigInteger.valueOf(interval.getLeading()).multiply(MONTHS_PER_YEAR_BI);
break; break;
case MONTH: case MONTH:
r = BigInteger.valueOf(interval.getLeading()); r = BigInteger.valueOf(interval.getLeading());
break; break;
case DAY: case DAY:
r = BigInteger.valueOf(interval.getLeading()).multiply(BigInteger.valueOf(NANOS_PER_DAY)); r = BigInteger.valueOf(interval.getLeading()).multiply(NANOS_PER_DAY_BI);
break; break;
case HOUR: case HOUR:
r = BigInteger.valueOf(interval.getLeading()).multiply(BigInteger.valueOf(NANOS_PER_HOUR)); r = BigInteger.valueOf(interval.getLeading()).multiply(NANOS_PER_HOUR_BI);
break; break;
case MINUTE: case MINUTE:
r = BigInteger.valueOf(interval.getLeading()).multiply(BigInteger.valueOf(NANOS_PER_MINUTE)); r = BigInteger.valueOf(interval.getLeading()).multiply(NANOS_PER_MINUTE_BI);
break; break;
case SECOND: case SECOND:
r = intervalToAbsolute(interval, NANOS_PER_SECOND); r = intervalToAbsolute(interval, NANOS_PER_SECOND_BI);
break; break;
case YEAR_TO_MONTH: case YEAR_TO_MONTH:
r = intervalToAbsolute(interval, 12); r = intervalToAbsolute(interval, MONTHS_PER_YEAR_BI);
break; break;
case DAY_TO_HOUR: case DAY_TO_HOUR:
r = intervalToAbsolute(interval, 24, NANOS_PER_HOUR); r = intervalToAbsolute(interval, HOURS_PER_DAY_BI, NANOS_PER_HOUR_BI);
break; break;
case DAY_TO_MINUTE: case DAY_TO_MINUTE:
r = intervalToAbsolute(interval, 24 * 60, NANOS_PER_MINUTE); r = intervalToAbsolute(interval, MINUTES_PER_DAY_BI, NANOS_PER_MINUTE_BI);
break; break;
case DAY_TO_SECOND: case DAY_TO_SECOND:
r = intervalToAbsolute(interval, NANOS_PER_DAY); r = intervalToAbsolute(interval, NANOS_PER_DAY_BI);
break; break;
case HOUR_TO_MINUTE: case HOUR_TO_MINUTE:
r = intervalToAbsolute(interval, 60, NANOS_PER_MINUTE); r = intervalToAbsolute(interval, MINUTES_PER_HOUR_BI, NANOS_PER_MINUTE_BI);
break; break;
case HOUR_TO_SECOND: case HOUR_TO_SECOND:
r = intervalToAbsolute(interval, NANOS_PER_HOUR); r = intervalToAbsolute(interval, NANOS_PER_HOUR_BI);
break; break;
case MINUTE_TO_SECOND: case MINUTE_TO_SECOND:
r = intervalToAbsolute(interval, NANOS_PER_MINUTE); r = intervalToAbsolute(interval, NANOS_PER_MINUTE_BI);
break; break;
default: default:
throw new IllegalArgumentException(); throw new IllegalArgumentException();
...@@ -502,12 +525,13 @@ public class IntervalUtils { ...@@ -502,12 +525,13 @@ public class IntervalUtils {
return interval.isNegative() ? r.negate() : r; return interval.isNegative() ? r.negate() : r;
} }
private static BigInteger intervalToAbsolute(ValueInterval interval, long multiplier, long totalMultiplier) { private static BigInteger intervalToAbsolute(ValueInterval interval, BigInteger multiplier,
return intervalToAbsolute(interval, multiplier).multiply(BigInteger.valueOf(totalMultiplier)); BigInteger totalMultiplier) {
return intervalToAbsolute(interval, multiplier).multiply(totalMultiplier);
} }
private static BigInteger intervalToAbsolute(ValueInterval interval, long multiplier) { private static BigInteger intervalToAbsolute(ValueInterval interval, BigInteger multiplier) {
return BigInteger.valueOf(interval.getLeading()).multiply(BigInteger.valueOf(multiplier)) return BigInteger.valueOf(interval.getLeading()).multiply(multiplier)
.add(BigInteger.valueOf(interval.getRemaining())); .add(BigInteger.valueOf(interval.getRemaining()));
} }
...@@ -525,47 +549,47 @@ public class IntervalUtils { ...@@ -525,47 +549,47 @@ public class IntervalUtils {
switch (qualifier) { switch (qualifier) {
case YEAR: case YEAR:
return ValueInterval.from(qualifier, absolute.signum() < 0, return ValueInterval.from(qualifier, absolute.signum() < 0,
leadingExact(absolute.divide(BigInteger.valueOf(12))), 0); leadingExact(absolute.divide(MONTHS_PER_YEAR_BI)), 0);
case MONTH: case MONTH:
return ValueInterval.from(qualifier, absolute.signum() < 0, leadingExact(absolute), 0); return ValueInterval.from(qualifier, absolute.signum() < 0, leadingExact(absolute), 0);
case DAY: case DAY:
return ValueInterval.from(qualifier, absolute.signum() < 0, return ValueInterval.from(qualifier, absolute.signum() < 0, leadingExact(absolute.divide(NANOS_PER_DAY_BI)),
leadingExact(absolute.divide(BigInteger.valueOf(NANOS_PER_DAY))), 0); 0);
case HOUR: case HOUR:
return ValueInterval.from(qualifier, absolute.signum() < 0, return ValueInterval.from(qualifier, absolute.signum() < 0,
leadingExact(absolute.divide(BigInteger.valueOf(NANOS_PER_HOUR))), 0); leadingExact(absolute.divide(NANOS_PER_HOUR_BI)), 0);
case MINUTE: case MINUTE:
return ValueInterval.from(qualifier, absolute.signum() < 0, return ValueInterval.from(qualifier, absolute.signum() < 0,
leadingExact(absolute.divide(BigInteger.valueOf(NANOS_PER_MINUTE))), 0); leadingExact(absolute.divide(NANOS_PER_MINUTE_BI)), 0);
case SECOND: case SECOND:
return intervalFromAbsolute(qualifier, absolute, NANOS_PER_SECOND); return intervalFromAbsolute(qualifier, absolute, NANOS_PER_SECOND_BI);
case YEAR_TO_MONTH: case YEAR_TO_MONTH:
return intervalFromAbsolute(qualifier, absolute, 12); return intervalFromAbsolute(qualifier, absolute, MONTHS_PER_YEAR_BI);
case DAY_TO_HOUR: case DAY_TO_HOUR:
return intervalFromAbsolute(qualifier, absolute.divide(BigInteger.valueOf(NANOS_PER_HOUR)), 24); return intervalFromAbsolute(qualifier, absolute.divide(NANOS_PER_HOUR_BI), HOURS_PER_DAY_BI);
case DAY_TO_MINUTE: case DAY_TO_MINUTE:
return intervalFromAbsolute(qualifier, absolute.divide(BigInteger.valueOf(NANOS_PER_MINUTE)), 24 * 60); return intervalFromAbsolute(qualifier, absolute.divide(NANOS_PER_MINUTE_BI), MINUTES_PER_DAY_BI);
case DAY_TO_SECOND: case DAY_TO_SECOND:
return intervalFromAbsolute(qualifier, absolute, NANOS_PER_DAY); return intervalFromAbsolute(qualifier, absolute, NANOS_PER_DAY_BI);
case HOUR_TO_MINUTE: case HOUR_TO_MINUTE:
return intervalFromAbsolute(qualifier, absolute.divide(BigInteger.valueOf(NANOS_PER_MINUTE)), 60); return intervalFromAbsolute(qualifier, absolute.divide(NANOS_PER_MINUTE_BI), MINUTES_PER_HOUR_BI);
case HOUR_TO_SECOND: case HOUR_TO_SECOND:
return intervalFromAbsolute(qualifier, absolute, NANOS_PER_HOUR); return intervalFromAbsolute(qualifier, absolute, NANOS_PER_HOUR_BI);
case MINUTE_TO_SECOND: case MINUTE_TO_SECOND:
return intervalFromAbsolute(qualifier, absolute, NANOS_PER_MINUTE); return intervalFromAbsolute(qualifier, absolute, NANOS_PER_MINUTE_BI);
default: default:
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
} }
private static ValueInterval intervalFromAbsolute(IntervalQualifier qualifier, BigInteger absolute, long divisor) { private static ValueInterval intervalFromAbsolute(IntervalQualifier qualifier, BigInteger absolute,
BigInteger[] dr = absolute.divideAndRemainder(BigInteger.valueOf(divisor)); BigInteger divisor) {
BigInteger[] dr = absolute.divideAndRemainder(divisor);
return ValueInterval.from(qualifier, absolute.signum() < 0, leadingExact(dr[0]), Math.abs(dr[1].longValue())); return ValueInterval.from(qualifier, absolute.signum() < 0, leadingExact(dr[0]), Math.abs(dr[1].longValue()));
} }
private static long leadingExact(BigInteger absolute) { private static long leadingExact(BigInteger absolute) {
if (absolute.compareTo(BigInteger.valueOf(999_999_999_999_999_999L)) > 0 if (absolute.compareTo(LEADING_MAX) > 0 || absolute.compareTo(LEADING_MIN) < 0) {
|| absolute.compareTo(BigInteger.valueOf(-999_999_999_999_999_999L)) < 0) {
throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, absolute.toString()); throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, absolute.toString());
} }
return Math.abs(absolute.longValue()); return Math.abs(absolute.longValue());
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论