Skip to content

Commit

Permalink
[fix](Nereids) fix fe fold constant with date time out of range
Browse files Browse the repository at this point in the history
  • Loading branch information
LiBinfeng-01 committed Dec 26, 2024
1 parent b28adb5 commit 5ee0b13
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 417 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -828,10 +828,10 @@ private EvaluateRangeResult computeMonotonicFunctionRange(EvaluateRangeResult re
expressionRewriteContext) : null;
Expression upperValue = upper != null ? FoldConstantRuleOnFE.evaluate(func.withConstantArgs(upper),
expressionRewriteContext) : null;
if (lowerValue instanceof NullLiteral || upperValue instanceof NullLiteral) {
if (!checkFoldConstantValueIsValid(lowerValue, upperValue)) {
return result;
}
if (!func.isPositive()) {
if (!func.isPositive()) {
Expression temp = lowerValue;
lowerValue = upperValue;
upperValue = temp;
Expand All @@ -858,4 +858,16 @@ private EvaluateRangeResult computeMonotonicFunctionRange(EvaluateRangeResult re
return new EvaluateRangeResult((Expression) func, newRanges, result.childrenResult);
}
}

// only allow literal(except NullLiteral) and null
private boolean checkFoldConstantValueIsValid(Expression lowerValue, Expression upperValue) {
if (lowerValue instanceof NullLiteral || upperValue instanceof NullLiteral) {
return false;
}
if (lowerValue != null && !(lowerValue instanceof Literal)
|| upperValue != null && !(upperValue instanceof Literal)) {
return false;
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.apache.doris.analysis.LiteralExpr;
import org.apache.doris.catalog.Type;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.exceptions.NotSupportedException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DataType;
Expand Down Expand Up @@ -530,9 +531,10 @@ private long calculateDays(long year, long month, long day) {
}

public static Expression fromJavaDateType(LocalDateTime dateTime) {
return isDateOutOfRange(dateTime)
? new NullLiteral(DateType.INSTANCE)
: new DateLiteral(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
if (isDateOutOfRange(dateTime)) {
throw new AnalysisException("datetime out of range: " + dateTime.toString());
}
return new DateLiteral(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.apache.doris.analysis.LiteralExpr;
import org.apache.doris.catalog.Type;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.exceptions.NotSupportedException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DateTimeType;
Expand Down Expand Up @@ -394,9 +395,10 @@ public LocalDateTime toJavaDateType() {
}

public static Expression fromJavaDateType(LocalDateTime dateTime) {
return isDateOutOfRange(dateTime)
? new NullLiteral(DateTimeType.INSTANCE)
: new DateTimeLiteral(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(),
if (isDateOutOfRange(dateTime)) {
throw new AnalysisException("datetime out of range: " + dateTime.toString());
}
return new DateTimeLiteral(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(),
dateTime.getHour(), dateTime.getMinute(), dateTime.getSecond());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.apache.doris.analysis.LiteralExpr;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.exceptions.NotSupportedException;
import org.apache.doris.nereids.exceptions.UnboundException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
Expand Down Expand Up @@ -281,9 +282,10 @@ public static Expression fromJavaDateType(LocalDateTime dateTime) {
*/
public static Expression fromJavaDateType(LocalDateTime dateTime, int precision) {
long value = (long) Math.pow(10, DateTimeV2Type.MAX_SCALE - precision);
return isDateOutOfRange(dateTime)
? new NullLiteral(DateTimeV2Type.of(precision))
: new DateTimeV2Literal(DateTimeV2Type.of(precision), dateTime.getYear(),
if (isDateOutOfRange(dateTime)) {
throw new AnalysisException("datetime out of range" + dateTime.toString());
}
return new DateTimeV2Literal(DateTimeV2Type.of(precision), dateTime.getYear(),
dateTime.getMonthValue(), dateTime.getDayOfMonth(), dateTime.getHour(),
dateTime.getMinute(), dateTime.getSecond(),
(dateTime.getNano() / 1000) / value * value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import org.apache.doris.catalog.Type;
import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.exceptions.NotSupportedException;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DateTimeV2Type;
Expand Down Expand Up @@ -72,9 +73,10 @@ public Expression plusYears(long years) {
}

public static Expression fromJavaDateType(LocalDateTime dateTime) {
return isDateOutOfRange(dateTime)
? new NullLiteral(DateV2Type.INSTANCE)
: new DateV2Literal(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
if (isDateOutOfRange(dateTime)) {
throw new AnalysisException("datetime out of range: " + dateTime.toString());
}
return new DateV2Literal(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,11 @@ void testFoldDate() {
hoursAdd = new HoursAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(9999, 12, 31, 23, 1, 1)),
new IntegerLiteral(24));
rewritten = executor.rewrite(hoursAdd, context);
Assertions.assertEquals(new NullLiteral(hoursAdd.getDataType()), rewritten);
Assertions.assertEquals(hoursAdd, rewritten);
hoursAdd = new HoursAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(0, 1, 1, 1, 1, 1)),
new IntegerLiteral(-25));
rewritten = executor.rewrite(hoursAdd, context);
Assertions.assertEquals(new NullLiteral(hoursAdd.getDataType()), rewritten);
Assertions.assertEquals(hoursAdd, rewritten);

MinutesAdd minutesAdd = new MinutesAdd(DateLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
new IntegerLiteral(1));
Expand All @@ -237,11 +237,11 @@ void testFoldDate() {
minutesAdd = new MinutesAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(9999, 12, 31, 23, 59, 1)),
new IntegerLiteral(1440));
rewritten = executor.rewrite(minutesAdd, context);
Assertions.assertEquals(new NullLiteral(minutesAdd.getDataType()), rewritten);
Assertions.assertEquals(minutesAdd, rewritten);
minutesAdd = new MinutesAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(0, 1, 1, 0, 1, 1)),
new IntegerLiteral(-2));
rewritten = executor.rewrite(minutesAdd, context);
Assertions.assertEquals(new NullLiteral(minutesAdd.getDataType()), rewritten);
Assertions.assertEquals(minutesAdd, rewritten);

SecondsAdd secondsAdd = new SecondsAdd(DateLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)),
new IntegerLiteral(1));
Expand All @@ -254,11 +254,11 @@ void testFoldDate() {
secondsAdd = new SecondsAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(9999, 12, 31, 23, 59, 59)),
new IntegerLiteral(86400));
rewritten = executor.rewrite(secondsAdd, context);
Assertions.assertEquals(new NullLiteral(secondsAdd.getDataType()), rewritten);
Assertions.assertEquals(secondsAdd, rewritten);
secondsAdd = new SecondsAdd(DateV2Literal.fromJavaDateType(LocalDateTime.of(0, 1, 1, 0, 1, 1)),
new IntegerLiteral(-61));
rewritten = executor.rewrite(secondsAdd, context);
Assertions.assertEquals(new NullLiteral(secondsAdd.getDataType()), rewritten);
Assertions.assertEquals(secondsAdd, rewritten);

ToDays toDays = new ToDays(DateLiteral.fromJavaDateType(LocalDateTime.of(1, 1, 1, 1, 1, 1)));
rewritten = executor.rewrite(toDays, context);
Expand Down
Loading

0 comments on commit 5ee0b13

Please sign in to comment.