提交 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,61 +139,7 @@ public class IntervalOperation extends Expression {
}
case DATETIME_PLUS_INTERVAL:
case DATETIME_MINUS_INTERVAL:
switch (lType) {
case Value.TIME: {
if (DataType.isYearMonthIntervalType(rType)) {
throw DbException.throwInternalError("type=" + rType);
}
BigInteger a1 = BigInteger.valueOf(((ValueTime) l).getNanos());
BigInteger a2 = DateTimeUtils.intervalToAbsolute((ValueInterval) r);
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) {
throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, n.toString());
}
return ValueTime.fromNanos(n.longValue());
}
case Value.DATE:
case Value.TIMESTAMP:
case Value.TIMESTAMP_TZ:
if (DataType.isYearMonthIntervalType(rType)) {
long m = DateTimeUtils.intervalToAbsolute((ValueInterval) r).longValue();
if (opType == IntervalOpType.DATETIME_MINUS_INTERVAL) {
m = -m;
}
return DateTimeFunctions.dateadd("MONTH", m, l);
} else {
BigInteger a2 = DateTimeUtils.intervalToAbsolute((ValueInterval) r);
if (lType == Value.DATE) {
BigInteger a1 = BigInteger
.valueOf(DateTimeUtils.absoluteDayFromDateValue(((ValueDate) l).getDateValue()));
a2 = a2.divide(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY));
BigInteger n = opType == IntervalOpType.DATETIME_PLUS_INTERVAL ? a1.add(a2) : a1.subtract(a2);
return ValueDate.fromDateValue(DateTimeUtils.dateValueFromAbsoluteDay(n.longValue()));
} else {
long[] a = DateTimeUtils.dateAndTimeFromValue(l);
long absoluteDay = DateTimeUtils.absoluteDayFromDateValue(a[0]);
long timeNanos = a[1];
BigInteger[] dr = a2.divideAndRemainder(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY));
if (opType == IntervalOpType.DATETIME_PLUS_INTERVAL) {
absoluteDay += dr[0].longValue();
timeNanos += dr[1].longValue();
} else {
absoluteDay -= dr[0].longValue();
timeNanos -= dr[1].longValue();
}
if (timeNanos >= DateTimeUtils.NANOS_PER_DAY) {
timeNanos -= DateTimeUtils.NANOS_PER_DAY;
absoluteDay++;
} else if (timeNanos < 0) {
timeNanos += DateTimeUtils.NANOS_PER_DAY;
absoluteDay--;
}
return DateTimeUtils.dateTimeToValue(l, DateTimeUtils.dateValueFromAbsoluteDay(absoluteDay),
timeNanos, false);
}
}
}
break;
return getDateTimeWithInterval(l, r, lType, rType);
case INTERVAL_MULTIPLY_NUMERIC:
case INTERVAL_DIVIDE_NUMERIC: {
BigDecimal a1 = new BigDecimal(DateTimeUtils.intervalToAbsolute((ValueInterval) l));
......@@ -239,6 +185,64 @@ public class IntervalOperation extends Expression {
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)) {
throw DbException.throwInternalError("type=" + rType);
}
BigInteger a1 = BigInteger.valueOf(((ValueTime) l).getNanos());
BigInteger a2 = DateTimeUtils.intervalToAbsolute((ValueInterval) r);
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) {
throw DbException.get(ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1, n.toString());
}
return ValueTime.fromNanos(n.longValue());
}
case Value.DATE:
case Value.TIMESTAMP:
case Value.TIMESTAMP_TZ:
if (DataType.isYearMonthIntervalType(rType)) {
long m = DateTimeUtils.intervalToAbsolute((ValueInterval) r).longValue();
if (opType == IntervalOpType.DATETIME_MINUS_INTERVAL) {
m = -m;
}
return DateTimeFunctions.dateadd("MONTH", m, l);
} else {
BigInteger a2 = DateTimeUtils.intervalToAbsolute((ValueInterval) r);
if (lType == Value.DATE) {
BigInteger a1 = BigInteger
.valueOf(DateTimeUtils.absoluteDayFromDateValue(((ValueDate) l).getDateValue()));
a2 = a2.divide(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY));
BigInteger n = opType == IntervalOpType.DATETIME_PLUS_INTERVAL ? a1.add(a2) : a1.subtract(a2);
return ValueDate.fromDateValue(DateTimeUtils.dateValueFromAbsoluteDay(n.longValue()));
} else {
long[] a = DateTimeUtils.dateAndTimeFromValue(l);
long absoluteDay = DateTimeUtils.absoluteDayFromDateValue(a[0]);
long timeNanos = a[1];
BigInteger[] dr = a2.divideAndRemainder(BigInteger.valueOf(DateTimeUtils.NANOS_PER_DAY));
if (opType == IntervalOpType.DATETIME_PLUS_INTERVAL) {
absoluteDay += dr[0].longValue();
timeNanos += dr[1].longValue();
} else {
absoluteDay -= dr[0].longValue();
timeNanos -= dr[1].longValue();
}
if (timeNanos >= DateTimeUtils.NANOS_PER_DAY) {
timeNanos -= DateTimeUtils.NANOS_PER_DAY;
absoluteDay++;
} else if (timeNanos < 0) {
timeNanos += DateTimeUtils.NANOS_PER_DAY;
absoluteDay--;
}
return DateTimeUtils.dateTimeToValue(l, DateTimeUtils.dateValueFromAbsoluteDay(absoluteDay),
timeNanos, false);
}
}
}
throw DbException.throwInternalError("type=" + opType);
}
@Override
public void mapColumns(ColumnResolver resolver, int level) {
left.mapColumns(resolver, level);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论