This is an automated email from the ASF dual-hosted git repository.

Mryange 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 4ab7cc02461 [fix](function) support TIMESTAMPDIFF MICROSECOND in 
nereids (#63365)
4ab7cc02461 is described below

commit 4ab7cc024611e53d9317c2a1e64f265af46e2913
Author: Mryange <[email protected]>
AuthorDate: Thu May 21 12:07:33 2026 +0800

    [fix](function) support TIMESTAMPDIFF MICROSECOND in nereids (#63365)
    
    ### What problem does this PR solve?
    
    Nereids rejects `TIMESTAMPDIFF(MICROSECOND, ...)` during analysis.
    
    The executable path already exists through `MicroSecondsDiff`, but the
    FE binder cannot reach it because:
    
    - `Interval.TimeUnit` does not define a standalone `MICROSECOND`
    - `DatetimeFunctionBinder` only routes `TIMESTAMPDIFF` up to `SECOND`
    
    As a result, queries such as `TIMESTAMPDIFF(MICROSECOND, MIN(t),
    MAX(t))` fail even for valid `DATETIMEV2(6)` inputs.
---
 .../rules/analysis/DatetimeFunctionBinder.java     |  5 +++-
 .../trees/expressions/literal/Interval.java        |  1 +
 .../rules/analysis/DatetimeFunctionBinderTest.java | 10 ++++++++
 .../data/nereids_syntax_p0/test_timestampdiff.out  |  6 +++++
 .../nereids_syntax_p0/test_timestampdiff.groovy    | 28 ++++++++++++++++++++++
 5 files changed, 49 insertions(+), 1 deletion(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/DatetimeFunctionBinder.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/DatetimeFunctionBinder.java
index c93f151cf0c..4e1a768bd97 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/DatetimeFunctionBinder.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/analysis/DatetimeFunctionBinder.java
@@ -55,6 +55,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.HourSecondSub
 import org.apache.doris.nereids.trees.expressions.functions.scalar.HoursAdd;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.HoursDiff;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.HoursSub;
+import 
org.apache.doris.nereids.trees.expressions.functions.scalar.MicroSecondsDiff;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.MinuteCeil;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.MinuteFloor;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.MinuteMicrosecondAdd;
@@ -301,9 +302,11 @@ public class DatetimeFunctionBinder {
                 return new MinutesDiff(end, start);
             case SECOND:
                 return new SecondsDiff(end, start);
+            case MICROSECOND:
+                return new MicroSecondsDiff(end, start);
             default:
                 throw new AnalysisException("Unsupported time stamp diff time 
unit: " + unit
-                        + ", supported time unit: 
YEAR/QUARTER/MONTH/WEEK/DAY/HOUR/MINUTE/SECOND");
+                        + ", supported time unit: 
YEAR/QUARTER/MONTH/WEEK/DAY/HOUR/MINUTE/SECOND/MICROSECOND");
         }
     }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Interval.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Interval.java
index 275e0f74fe1..f490c225c44 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Interval.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/Interval.java
@@ -106,6 +106,7 @@ public class Interval extends Expression implements 
UnaryExpression, AlwaysNotNu
         MINUTE_SECOND("MINUTE_SECOND", false, 200),
         MINUTE_MICROSECOND("MINUTE_MICROSECOND", false, 200),
         SECOND("SECOND", true, 100),
+        MICROSECOND("MICROSECOND", true, 0),
         SECOND_MICROSECOND("SECOND_MICROSECOND", true, 100);
 
         private final String description;
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/DatetimeFunctionBinderTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/DatetimeFunctionBinderTest.java
index 81f24ed878b..a63e4a3e628 100644
--- 
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/DatetimeFunctionBinderTest.java
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/DatetimeFunctionBinderTest.java
@@ -42,6 +42,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.HourFloor;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.HoursAdd;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.HoursDiff;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.HoursSub;
+import 
org.apache.doris.nereids.trees.expressions.functions.scalar.MicroSecondsDiff;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.MinuteCeil;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.MinuteFloor;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.MinutesAdd;
@@ -110,6 +111,8 @@ public class DatetimeFunctionBinderTest {
             TinyIntType.INSTANCE, false, ImmutableList.of());
     private final SlotReference secondUnit = new SlotReference(new ExprId(-1), 
"SECOND",
             TinyIntType.INSTANCE, false, ImmutableList.of());
+    private final SlotReference microsecondUnit = new SlotReference(new 
ExprId(-1), "MICROSECOND",
+            TinyIntType.INSTANCE, false, ImmutableList.of());
     private final SlotReference invalidUnit = new SlotReference(new 
ExprId(-1), "INVALID",
             TinyIntType.INSTANCE, false, ImmutableList.of());
 
@@ -172,6 +175,13 @@ public class DatetimeFunctionBinderTest {
             Assertions.assertEquals(dateTimeV2Literal2, result.child(0));
             Assertions.assertEquals(dateTimeV2Literal1, result.child(1));
 
+            timeDiff = new UnboundFunction(functionName, ImmutableList.of(
+                    microsecondUnit, dateTimeV2Literal1, dateTimeV2Literal2));
+            result = DatetimeFunctionBinder.INSTANCE.bind(timeDiff);
+            Assertions.assertInstanceOf(MicroSecondsDiff.class, result);
+            Assertions.assertEquals(dateTimeV2Literal2, result.child(0));
+            Assertions.assertEquals(dateTimeV2Literal1, result.child(1));
+
             Assertions.assertThrowsExactly(AnalysisException.class,
                     () -> DatetimeFunctionBinder.INSTANCE.bind(
                             new UnboundFunction(functionName, 
ImmutableList.of(invalidUnit,
diff --git a/regression-test/data/nereids_syntax_p0/test_timestampdiff.out 
b/regression-test/data/nereids_syntax_p0/test_timestampdiff.out
index 0e2dd6a5375..15623515ed4 100644
--- a/regression-test/data/nereids_syntax_p0/test_timestampdiff.out
+++ b/regression-test/data/nereids_syntax_p0/test_timestampdiff.out
@@ -17,3 +17,9 @@
 -- !select --
 40
 
+-- !select --
+876543
+
+-- !select --
+2024-01-01T10:00:00.999999     2024-01-01T10:00:00.123456      876543
+
diff --git a/regression-test/suites/nereids_syntax_p0/test_timestampdiff.groovy 
b/regression-test/suites/nereids_syntax_p0/test_timestampdiff.groovy
index 34500732e22..0a3e563bd7f 100644
--- a/regression-test/suites/nereids_syntax_p0/test_timestampdiff.groovy
+++ b/regression-test/suites/nereids_syntax_p0/test_timestampdiff.groovy
@@ -37,4 +37,32 @@ suite("test_timestampdiff") {
     qt_select """
         SELECT TIMESTAMPDIFF(second,'2003-02-03 11:00:00','2003-02-03 
11:00:40');
     """
+
+    qt_select """
+        SELECT TIMESTAMPDIFF(microsecond,
+                CAST('2024-01-01 10:00:00.123456' AS DATETIMEV2(6)),
+                CAST('2024-01-01 10:00:00.999999' AS DATETIMEV2(6)));
+    """
+
+    sql """drop table if exists test_timestampdiff_microsecond"""
+    sql """
+        create table test_timestampdiff_microsecond (
+            id int,
+            t datetimev2(6)
+        )
+        duplicate key(id)
+        distributed by hash(id) buckets 1
+        properties("replication_num" = "1");
+    """
+
+    sql """
+        insert into test_timestampdiff_microsecond values
+            (1, '2024-01-01 10:00:00.123456'),
+            (2, '2024-01-01 10:00:00.999999');
+    """
+
+    qt_select """
+        SELECT MAX(t), MIN(t), TIMESTAMPDIFF(MICROSECOND, MIN(t), MAX(t))
+        FROM test_timestampdiff_microsecond;
+    """
 }
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to