This is an automated email from the ASF dual-hosted git repository.
morrySnow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 79226c65326 [fix](fe) Fix datediff folding for zero date (#64084)
79226c65326 is described below
commit 79226c65326491c7d4ae9b12de63095252c1b89c
Author: feiniaofeiafei <[email protected]>
AuthorDate: Mon Jun 8 16:59:17 2026 +0800
[fix](fe) Fix datediff folding for zero date (#64084)
### What problem does this PR solve?
Problem Summary: FE constant folding for DATEDIFF used Java proleptic
date arithmetic, while BE runtime evaluates DATEDIFF by subtracting
Doris day numbers. For zero-date inputs such as 0000-01-01, Java date
arithmetic disagrees with Doris day-number semantics, so folded DATEDIFF
could return a different result from runtime execution and from
TO_DAYS(a) - TO_DAYS(b). This change reuses the FE day-number
calculation used by TO_DAYS for DATEDIFF folding, keeping folded and
runtime semantics consistent for zero-date boundary cases.
---
.../functions/executable/DateTimeArithmetic.java | 16 ++++++++--------
.../executable/DateTimeExtractAndTransform.java | 2 +-
.../doris/nereids/rules/expression/FoldConstantTest.java | 6 ++++++
3 files changed, 15 insertions(+), 9 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeArithmetic.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeArithmetic.java
index c521c408f78..cd12c00df21 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeArithmetic.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeArithmetic.java
@@ -21,6 +21,7 @@ import org.apache.doris.nereids.exceptions.AnalysisException;
import org.apache.doris.nereids.trees.expressions.ExecFunction;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.DateLiteral;
import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
import org.apache.doris.nereids.trees.expressions.literal.DateV2Literal;
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
@@ -29,8 +30,6 @@ import
org.apache.doris.nereids.trees.expressions.literal.TimeV2Literal;
import org.apache.doris.nereids.trees.expressions.literal.TimestampTzLiteral;
import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
-import java.time.LocalDateTime;
-import java.time.temporal.ChronoUnit;
import java.util.Arrays;
/**
@@ -879,26 +878,27 @@ public class DateTimeArithmetic {
*/
@ExecFunction(name = "datediff")
public static Expression dateDiff(DateV2Literal date1, DateV2Literal
date2) {
- return new IntegerLiteral(dateDiff(date1.toJavaDateType(),
date2.toJavaDateType()));
+ return new IntegerLiteral(dateDiffByDayNumber(date1, date2));
}
@ExecFunction(name = "datediff")
public static Expression dateDiff(DateV2Literal date1, DateTimeV2Literal
date2) {
- return new IntegerLiteral(dateDiff(date1.toJavaDateType(),
date2.toJavaDateType()));
+ return new IntegerLiteral(dateDiffByDayNumber(date1, date2));
}
@ExecFunction(name = "datediff")
public static Expression dateDiff(DateTimeV2Literal date1, DateV2Literal
date2) {
- return new IntegerLiteral(dateDiff(date1.toJavaDateType(),
date2.toJavaDateType()));
+ return new IntegerLiteral(dateDiffByDayNumber(date1, date2));
}
@ExecFunction(name = "datediff")
public static Expression dateDiff(DateTimeV2Literal date1,
DateTimeV2Literal date2) {
- return new IntegerLiteral(dateDiff(date1.toJavaDateType(),
date2.toJavaDateType()));
+ return new IntegerLiteral(dateDiffByDayNumber(date1, date2));
}
- private static int dateDiff(LocalDateTime date1, LocalDateTime date2) {
- return ((int) ChronoUnit.DAYS.between(date2.toLocalDate(),
date1.toLocalDate()));
+ private static int dateDiffByDayNumber(DateLiteral date1, DateLiteral
date2) {
+ return (int)
(DateTimeExtractAndTransform.calcDayNumber(date1.getYear(), date1.getMonth(),
date1.getDay())
+ - DateTimeExtractAndTransform.calcDayNumber(date2.getYear(),
date2.getMonth(), date2.getDay()));
}
@ExecFunction(name = "to_days")
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
index f2324a396e7..3595010c96e 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/DateTimeExtractAndTransform.java
@@ -696,7 +696,7 @@ public class DateTimeExtractAndTransform {
// While BE/MySQL consider year 0 common, so:
// TO_DAYS('0000-02-28') == 59 and TO_DAYS('0000-02-29') == NULL. After
// 0000-03-01 the two implementations naturally align again.
- private static long calcDayNumber(long year, long month, long day) {
+ static long calcDayNumber(long year, long month, long day) {
if (year == 0 && month == 0) {
return 0;
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java
index 8806e2155bc..9f46a7970a2 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/expression/FoldConstantTest.java
@@ -1331,6 +1331,12 @@ class FoldConstantTest extends
ExpressionRewriteTestHelper {
Assertions.assertEquals(DateTimeArithmetic.dateDiff(dateV2Literal1,
dateTimeV2Literal).toSql(), "1826");
Assertions.assertEquals(DateTimeArithmetic.dateDiff(dateTimeV2Literal,
dateTimeV2Literal1).toSql(), "-1826");
Assertions.assertEquals(DateTimeArithmetic.dateDiff(dateTimeV2Literal1,
dateTimeV2Literal).toSql(), "1826");
+
+ DateV2Literal zeroDateV2Literal = new DateV2Literal("0000-01-01");
+ DateTimeV2Literal zeroDateTimeV2Literal = new
DateTimeV2Literal("0000-01-01 00:00:00");
+ DateTimeV2Literal dateTimeV2Literal2 = new
DateTimeV2Literal("2021-12-31 12:23:34");
+
Assertions.assertEquals(DateTimeArithmetic.dateDiff(dateTimeV2Literal2,
zeroDateV2Literal).toSql(), "738519");
+
Assertions.assertEquals(DateTimeArithmetic.dateDiff(dateTimeV2Literal2,
zeroDateTimeV2Literal).toSql(), "738519");
}
@Test
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]