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

Split large methods in Parser and IntervalOperation

上级 5ea97cd3
......@@ -3512,61 +3512,7 @@ public class Parser {
}
}
} else if (equalsToken("INTERVAL", name)) {
boolean negative = readIf(MINUS_SIGN);
if (!negative) {
readIf(PLUS_SIGN);
}
String s = readString();
IntervalQualifier qualifier;
if (readIf("YEAR")) {
if (readIf("TO")) {
read("MONTH");
qualifier = IntervalQualifier.YEAR_TO_MONTH;
} else {
qualifier = IntervalQualifier.YEAR;
}
} else if (readIf("MONTH")) {
qualifier = IntervalQualifier.MONTH;
} else if (readIf("DAY")) {
if (readIf("TO")) {
if (readIf("HOUR")) {
qualifier = IntervalQualifier.DAY_TO_HOUR;
} else if (readIf("MINUTE")) {
qualifier = IntervalQualifier.DAY_TO_MINUTE;
} else {
read("SECOND");
qualifier = IntervalQualifier.DAY_TO_SECOND;
}
} else {
qualifier = IntervalQualifier.DAY;
}
} else if (readIf("HOUR")) {
if (readIf("TO")) {
if (readIf("MINUTE")) {
qualifier = IntervalQualifier.HOUR_TO_MINUTE;
} else {
read("SECOND");
qualifier = IntervalQualifier.HOUR_TO_SECOND;
}
} else {
qualifier = IntervalQualifier.HOUR;
}
} else if (readIf("MINUTE")) {
if (readIf("TO")) {
read("SECOND");
qualifier = IntervalQualifier.MINUTE_TO_SECOND;
} else {
qualifier = IntervalQualifier.MINUTE;
}
} else {
read("SECOND");
qualifier = IntervalQualifier.SECOND;
}
try {
r = ValueExpression.get(DateTimeUtils.parseInterval(qualifier, negative, s));
} catch (Exception e) {
throw DbException.get(ErrorCode.INVALID_DATETIME_CONSTANT_2, e, "INTERVAL", s);
}
r = readInterval();
} else if (currentTokenType == VALUE &&
currentValue.getType() == Value.STRING) {
if (equalsToken("DATE", name) ||
......@@ -3718,6 +3664,64 @@ public class Parser {
return r;
}
private Expression readInterval() {
boolean negative = readIf(MINUS_SIGN);
if (!negative) {
readIf(PLUS_SIGN);
}
String s = readString();
IntervalQualifier qualifier;
if (readIf("YEAR")) {
if (readIf("TO")) {
read("MONTH");
qualifier = IntervalQualifier.YEAR_TO_MONTH;
} else {
qualifier = IntervalQualifier.YEAR;
}
} else if (readIf("MONTH")) {
qualifier = IntervalQualifier.MONTH;
} else if (readIf("DAY")) {
if (readIf("TO")) {
if (readIf("HOUR")) {
qualifier = IntervalQualifier.DAY_TO_HOUR;
} else if (readIf("MINUTE")) {
qualifier = IntervalQualifier.DAY_TO_MINUTE;
} else {
read("SECOND");
qualifier = IntervalQualifier.DAY_TO_SECOND;
}
} else {
qualifier = IntervalQualifier.DAY;
}
} else if (readIf("HOUR")) {
if (readIf("TO")) {
if (readIf("MINUTE")) {
qualifier = IntervalQualifier.HOUR_TO_MINUTE;
} else {
read("SECOND");
qualifier = IntervalQualifier.HOUR_TO_SECOND;
}
} else {
qualifier = IntervalQualifier.HOUR;
}
} else if (readIf("MINUTE")) {
if (readIf("TO")) {
read("SECOND");
qualifier = IntervalQualifier.MINUTE_TO_SECOND;
} else {
qualifier = IntervalQualifier.MINUTE;
}
} else {
read("SECOND");
qualifier = IntervalQualifier.SECOND;
}
try {
return ValueExpression.get(DateTimeUtils.parseInterval(qualifier, negative, s));
} catch (Exception e) {
throw DbException.get(ErrorCode.INVALID_DATETIME_CONSTANT_2, e, "INTERVAL", s);
}
}
private Expression parseDB2SpecialRegisters(String name) {
// Only "CURRENT" name is supported
if (readIf("TIMESTAMP")) {
......
......@@ -139,6 +139,53 @@ public class IntervalOperation extends Expression {
}
case DATETIME_PLUS_INTERVAL:
case DATETIME_MINUS_INTERVAL:
return getDateTimeWithInterval(l, r, lType, rType);
case INTERVAL_MULTIPLY_NUMERIC:
case INTERVAL_DIVIDE_NUMERIC: {
BigDecimal a1 = new BigDecimal(DateTimeUtils.intervalToAbsolute((ValueInterval) l));
BigDecimal a2 = r.getBigDecimal();
return DateTimeUtils.intervalFromAbsolute(IntervalQualifier.valueOf(lType - Value.INTERVAL_YEAR),
(opType == IntervalOpType.INTERVAL_MULTIPLY_NUMERIC ? a1.multiply(a2) : a1.divide(a2))
.toBigInteger());
}
case DATETIME_MINUS_DATETIME:
if (lType == Value.TIME && rType == Value.TIME) {
long diff = ((ValueTime) l).getNanos() - ((ValueTime) r).getNanos();
boolean negative = diff < 0;
if (negative) {
diff = -diff;
}
return ValueInterval.from(IntervalQualifier.HOUR_TO_SECOND, negative, diff / 3_600_000_000_000L,
diff % 3_600_000_000_000L);
} else if (lType == Value.DATE && rType == Value.DATE) {
long diff = DateTimeUtils.absoluteDayFromDateValue(((ValueDate) l).getDateValue())
- DateTimeUtils.absoluteDayFromDateValue(((ValueDate) r).getDateValue());
boolean negative = diff < 0;
if (negative) {
diff = -diff;
}
return ValueInterval.from(IntervalQualifier.DAY, negative, diff, 0L);
} else {
long[] a = DateTimeUtils.dateAndTimeFromValue(l);
long[] b = DateTimeUtils.dateAndTimeFromValue(r);
BigInteger bi1 = BigInteger.valueOf(a[0]).multiply(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY))
.add(BigInteger.valueOf(a[1]));
BigInteger bi2 = BigInteger.valueOf(b[0]).multiply(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY))
.add(BigInteger.valueOf(b[1]));
BigInteger diff = bi1.subtract(bi2);
if (lType == Value.TIMESTAMP_TZ || rType == Value.TIMESTAMP_TZ) {
l = l.convertTo(Value.TIMESTAMP_TZ);
r = r.convertTo(Value.TIMESTAMP_TZ);
diff = diff.add(BigInteger.valueOf((((ValueTimestampTimeZone) r).getTimeZoneOffsetMins()
- ((ValueTimestampTimeZone) l).getTimeZoneOffsetMins()) * 60_000_000_000L));
}
return DateTimeUtils.intervalFromAbsolute(IntervalQualifier.DAY_TO_SECOND, diff);
}
}
throw DbException.throwInternalError("type=" + opType);
}
private Value getDateTimeWithInterval(Value l, Value r, int lType, int rType) {
switch (lType) {
case Value.TIME: {
if (DataType.isYearMonthIntervalType(rType)) {
......@@ -193,49 +240,6 @@ public class IntervalOperation extends Expression {
}
}
}
break;
case INTERVAL_MULTIPLY_NUMERIC:
case INTERVAL_DIVIDE_NUMERIC: {
BigDecimal a1 = new BigDecimal(DateTimeUtils.intervalToAbsolute((ValueInterval) l));
BigDecimal a2 = r.getBigDecimal();
return DateTimeUtils.intervalFromAbsolute(IntervalQualifier.valueOf(lType - Value.INTERVAL_YEAR),
(opType == IntervalOpType.INTERVAL_MULTIPLY_NUMERIC ? a1.multiply(a2) : a1.divide(a2))
.toBigInteger());
}
case DATETIME_MINUS_DATETIME:
if (lType == Value.TIME && rType == Value.TIME) {
long diff = ((ValueTime) l).getNanos() - ((ValueTime) r).getNanos();
boolean negative = diff < 0;
if (negative) {
diff = -diff;
}
return ValueInterval.from(IntervalQualifier.HOUR_TO_SECOND, negative, diff / 3_600_000_000_000L,
diff % 3_600_000_000_000L);
} else if (lType == Value.DATE && rType == Value.DATE) {
long diff = DateTimeUtils.absoluteDayFromDateValue(((ValueDate) l).getDateValue())
- DateTimeUtils.absoluteDayFromDateValue(((ValueDate) r).getDateValue());
boolean negative = diff < 0;
if (negative) {
diff = -diff;
}
return ValueInterval.from(IntervalQualifier.DAY, negative, diff, 0L);
} else {
long[] a = DateTimeUtils.dateAndTimeFromValue(l);
long[] b = DateTimeUtils.dateAndTimeFromValue(r);
BigInteger bi1 = BigInteger.valueOf(a[0]).multiply(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY))
.add(BigInteger.valueOf(a[1]));
BigInteger bi2 = BigInteger.valueOf(b[0]).multiply(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY))
.add(BigInteger.valueOf(b[1]));
BigInteger diff = bi1.subtract(bi2);
if (lType == Value.TIMESTAMP_TZ || rType == Value.TIMESTAMP_TZ) {
l = l.convertTo(Value.TIMESTAMP_TZ);
r = r.convertTo(Value.TIMESTAMP_TZ);
diff = diff.add(BigInteger.valueOf((((ValueTimestampTimeZone) r).getTimeZoneOffsetMins()
- ((ValueTimestampTimeZone) l).getTimeZoneOffsetMins()) * 60_000_000_000L));
}
return DateTimeUtils.intervalFromAbsolute(IntervalQualifier.DAY_TO_SECOND, diff);
}
}
throw DbException.throwInternalError("type=" + opType);
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论