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

yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.0 by this push:
     new 12bd9ae9b9f branch-4.0: [Feature](function) Support function 
TO_SECONDS #58635 (#58868)
12bd9ae9b9f is described below

commit 12bd9ae9b9fee703930f1a9d08d92f4e25a28faf
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Dec 10 11:02:26 2025 +0800

    branch-4.0: [Feature](function) Support function TO_SECONDS #58635 (#58868)
    
    Cherry-picked from #58635
    
    Co-authored-by: linrrarity <[email protected]>
---
 be/src/vec/functions/date_time_transforms.h        |  2 +
 be/src/vec/functions/to_time_function.cpp          |  3 +
 .../doris/catalog/BuiltinScalarFunctions.java      |  2 +
 .../executable/DateTimeExtractAndTransform.java    | 46 ++++++++++++--
 .../expressions/functions/scalar/ToSeconds.java    | 74 ++++++++++++++++++++++
 .../expressions/visitor/ScalarFunctionVisitor.java |  5 ++
 .../sql-functions/doc_date_functions_test.out      | 48 ++++++++++++++
 .../sql-functions/doc_date_functions_test.groovy   | 35 ++++++++++
 8 files changed, 211 insertions(+), 4 deletions(-)

diff --git a/be/src/vec/functions/date_time_transforms.h 
b/be/src/vec/functions/date_time_transforms.h
index ddce29e2446..f494750cf24 100644
--- a/be/src/vec/functions/date_time_transforms.h
+++ b/be/src/vec/functions/date_time_transforms.h
@@ -106,6 +106,8 @@ TIME_FUNCTION_IMPL(DayOfWeekImpl, dayofweek, day_of_week());
 TIME_FUNCTION_IMPL(WeekDayImpl, weekday, weekday());
 // TODO: the method should be always not nullable
 TIME_FUNCTION_IMPL(ToDaysImpl, to_days, daynr());
+TIME_FUNCTION_IMPL(ToSecondsImpl, to_seconds,
+                   daynr() * 86400L + date_time_value.time_part_to_seconds());
 
 #define TIME_FUNCTION_ONE_ARG_IMPL(CLASS, UNIT, FUNCTION)                      
               \
     template <PrimitiveType PType>                                             
               \
diff --git a/be/src/vec/functions/to_time_function.cpp 
b/be/src/vec/functions/to_time_function.cpp
index e930a42eb4b..a382ddedfed 100644
--- a/be/src/vec/functions/to_time_function.cpp
+++ b/be/src/vec/functions/to_time_function.cpp
@@ -41,6 +41,8 @@ using FunctionSecondV2 = 
FunctionDateOrDateTimeToSomething<DataTypeInt8, ToSecon
 using FunctionToDaysV2 = FunctionDateOrDateTimeToSomething<DataTypeInt32, 
ToDaysImpl<TYPE_DATEV2>>;
 using FunctionToDateV2 = FunctionDateOrDateTimeToSomething<DataTypeDateV2, 
ToDateImpl<TYPE_DATEV2>>;
 using FunctionDateV2 = FunctionDateOrDateTimeToSomething<DataTypeDateV2, 
DateImpl<TYPE_DATEV2>>;
+using FunctionToSeconds =
+        FunctionDateOrDateTimeToSomething<DataTypeInt64, 
ToSecondsImpl<TYPE_DATETIMEV2>>;
 
 using FunctionDateTimeV2Year =
         FunctionDateOrDateTimeToSomething<DataTypeInt16, 
ToYearImpl<TYPE_DATETIMEV2>>;
@@ -97,6 +99,7 @@ void 
register_function_to_time_function(SimpleFunctionFactory& factory) {
     factory.register_function<FunctionDateTimeV2Date>();
     factory.register_function<FunctionCenturyV2>();
     factory.register_function<FunctionDateTimeV2Century>();
+    factory.register_function<FunctionToSeconds>();
     factory.register_alias("date", "datev2");
     factory.register_alias("to_date", "to_datev2");
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
index 2d391a02c51..3542f983c7a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
@@ -504,6 +504,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.ToIso8601;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.ToJson;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.ToMonday;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.ToQuantileState;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.ToSeconds;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Tokenize;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.TopLevelDomain;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Translate;
@@ -1056,6 +1057,7 @@ public class BuiltinScalarFunctions implements 
FunctionHelper {
             scalar(ToMonday.class, "to_monday"),
             scalar(TopLevelDomain.class, "top_level_domain"),
             scalar(ToQuantileState.class, "to_quantile_state"),
+            scalar(ToSeconds.class, "to_seconds"),
             scalar(Translate.class, "translate"),
             scalar(Trim.class, "trim"),
             scalar(TrimIn.class, "trim_in"),
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 a6fcab95c32..ea6551687ba 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
@@ -572,14 +572,52 @@ public class DateTimeExtractAndTransform {
      */
     @ExecFunction(name = "to_days")
     public static Expression toDays(DateV2Literal date) {
-        return new IntegerLiteral(((int) Duration.between(
-                LocalDateTime.of(0, 1, 1, 0, 0, 0), 
date.toJavaDateType()).toDays()));
+        return new IntegerLiteral((int) calcDayNumber(date.getYear(), 
date.getMonth(), date.getDay()));
     }
 
     @ExecFunction(name = "to_days")
     public static Expression toDays(DateTimeV2Literal date) {
-        return new IntegerLiteral(((int) Duration.between(
-                LocalDateTime.of(0, 1, 1, 0, 0, 0), 
date.toJavaDateType()).toDays()));
+        return new IntegerLiteral((int) calcDayNumber(date.getYear(), 
date.getMonth(), date.getDay()));
+    }
+
+    /**
+     * date transformation function: to_seconds
+     */
+    @ExecFunction(name = "to_seconds")
+    public static Expression toSeconds(DateV2Literal date) {
+        return new BigIntLiteral(calcDayNumber(date.getYear(), 
date.getMonth(), date.getDay()) * 86400L);
+    }
+
+    @ExecFunction(name = "to_seconds")
+    public static Expression toSeconds(DateTimeV2Literal date) {
+        return new BigIntLiteral(calcDayNumber(date.getYear(), 
date.getMonth(), date.getDay()) * 86400L
+                                    + date.getHour() * 3600L + 
date.getMinute() * 60L + date.getSecond());
+    }
+
+    // Java Duration cannot represent days before 0000-01-01, so using it 
would turn
+    // TO_DAYS('0000-01-01') into the diff between that date and itself (0).
+    // We use BE's arithmetic instead so 0000-01-01 returns 1 as expected.
+    // Previous FE logic often matched BE only because Java treats year 0 as 
leap
+    // making TO_DAYS('0000-02-29') fold to 59.
+    // 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) {
+        if (year == 0 && month == 0) {
+            return 0;
+        }
+        if (year == 0 && month == 1 && day == 1) {
+            return 1;
+        }
+
+        long y = year;
+        long delsum = 365L * y + 31L * (month - 1) + day;
+        if (month <= 2) {
+            y -= 1;
+        } else {
+            delsum -= (month * 4 + 23) / 10;
+        }
+        return delsum + y / 4 - y / 100 + y / 400;
     }
 
     /**
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToSeconds.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToSeconds.java
new file mode 100644
index 00000000000..02a601ca5c4
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ToSeconds.java
@@ -0,0 +1,74 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
+import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
+import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.BigIntType;
+import org.apache.doris.nereids.types.DateTimeV2Type;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * ScalarFunction 'to_seoncds'.
+ */
+public class ToSeconds extends ScalarFunction
+        implements UnaryExpression, ExplicitlyCastableSignature, 
PropagateNullable {
+
+    private static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+            
FunctionSignature.ret(BigIntType.INSTANCE).args(DateTimeV2Type.WILDCARD)
+    );
+
+    /**
+     * constructor with 1 argument.
+     */
+    public ToSeconds(Expression arg) {
+        super("to_seconds", arg);
+    }
+
+    /** constructor for withChildren and reuse signature */
+    private ToSeconds(ScalarFunctionParams functionParams) {
+        super(functionParams);
+    }
+
+    /**
+     * withChildren.
+     */
+    @Override
+    public ToSeconds withChildren(List<Expression> children) {
+        Preconditions.checkArgument(children.size() == 1);
+        return new ToSeconds(getFunctionParams(children));
+    }
+
+    @Override
+    public List<FunctionSignature> getSignatures() {
+        return SIGNATURES;
+    }
+
+    @Override
+    public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+        return visitor.visitToSeconds(this, context);
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
index de862909961..0c1a0bcb254 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
@@ -504,6 +504,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.scalar.ToIso8601;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.ToJson;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.ToMonday;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.ToQuantileState;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.ToSeconds;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Tokenize;
 import 
org.apache.doris.nereids.trees.expressions.functions.scalar.TopLevelDomain;
 import org.apache.doris.nereids.trees.expressions.functions.scalar.Translate;
@@ -2378,6 +2379,10 @@ public interface ScalarFunctionVisitor<R, C> {
         return visitScalarFunction(toQuantileState, context);
     }
 
+    default R visitToSeconds(ToSeconds toSeconds, C context) {
+        return visitScalarFunction(toSeconds, context);
+    }
+
     default R visitTranslate(Translate translate, C context) {
         return visitScalarFunction(translate, context);
     }
diff --git 
a/regression-test/data/doc/sql-manual/sql-functions/doc_date_functions_test.out 
b/regression-test/data/doc/sql-manual/sql-functions/doc_date_functions_test.out
index 99924258d49..25c5b1672ab 100644
--- 
a/regression-test/data/doc/sql-manual/sql-functions/doc_date_functions_test.out
+++ 
b/regression-test/data/doc/sql-manual/sql-functions/doc_date_functions_test.out
@@ -1622,6 +1622,18 @@ da fanadur
 -- !to_days_2 --
 733321
 
+-- !to_days_3 --
+1
+
+-- !to_days_4 --
+59
+
+-- !to_days_5 --
+\N
+
+-- !to_days_6 --
+60
+
 -- !to_iso8601_1 --
 2023-10-05
 
@@ -2017,6 +2029,42 @@ da fanadur
 \N
 07:23:25
 
+-- !to_seconds_1 --
+63358934400
+
+-- !to_seconds_2 --
+63358970589
+
+-- !to_seconds_3 --
+86400
+
+-- !to_seconds_4 --
+315569519999
+
+-- !to_seconds_5 --
+\N
+
+-- !to_seconds_6 --
+\N
+
+-- !to_seconds_7 --
+\N
+
+-- !to_seconds_8 --
+63863901296
+
+-- !to_seconds_9 --
+\N
+
+-- !to_seconds_10 --
+\N
+
+-- !to_seconds_11 --
+63902908800
+
+-- !to_seconds_12 --
+63902953845
+
 -- !dateceil --
 2025-10-10T12:34:56    2026-01-01T00:00        2025-11-01T00:00        
2025-10-11T00:00        2025-10-10T13:00        2025-10-10T12:35        
2025-10-10T12:34:56
 2025-01-01T00:00       2025-01-01T00:00        2025-01-01T00:00        
2025-01-01T00:00        2025-01-01T00:00        2025-01-01T00:00        
2025-01-01T00:00
diff --git 
a/regression-test/suites/doc/sql-manual/sql-functions/doc_date_functions_test.groovy
 
b/regression-test/suites/doc/sql-manual/sql-functions/doc_date_functions_test.groovy
index 583394da8a4..41930efff3b 100644
--- 
a/regression-test/suites/doc/sql-manual/sql-functions/doc_date_functions_test.groovy
+++ 
b/regression-test/suites/doc/sql-manual/sql-functions/doc_date_functions_test.groovy
@@ -1202,6 +1202,11 @@ suite("doc_date_functions_test") {
     // 79. TO_DAYS function tests
     qt_to_days_1 """select to_days('2007-10-07')"""
     qt_to_days_2 """select to_days('2007-10-07 10:03:09')"""
+    qt_to_days_3 """select to_days('0000-01-01')"""
+    qt_to_days_4 """select to_days('0000-02-28')"""
+    qt_to_days_5 """select to_days('0000-02-29')"""
+    qt_to_days_6 """select to_days('0000-03-01')"""
+
 
     // 80. TO_ISO8601 function tests
     qt_to_iso8601_1 """SELECT TO_ISO8601(CAST('2023-10-05' AS DATE)) AS 
date_result"""
@@ -1400,6 +1405,32 @@ suite("doc_date_functions_test") {
     testFoldConst("SELECT YEARWEEK('2023-01-02', 5) AS yearweek_mode5")
     testFoldConst("SELECT YEARWEEK('2023-12-25', 1) AS date_type_mode1")
 
+    // TO_SECONDS function tests
+    qt_to_seconds_1 """select to_seconds('2007-10-07')"""
+    qt_to_seconds_2 """select to_seconds('2007-10-07 10:03:09')"""
+    qt_to_seconds_3 """select to_seconds('0000-01-01 00:00:00')"""
+    qt_to_seconds_4 """select to_seconds('9999-12-31 23:59:59')"""
+    qt_to_seconds_5 """select to_seconds('101-01-01 08:30:15.123456')"""
+    qt_to_seconds_6 """select to_seconds('2023-02-30 12:00:00')"""
+    qt_to_seconds_7 """select to_seconds(NULL)"""
+    qt_to_seconds_8 """select to_seconds('2023-10-07 12:34:56.654321')"""
+    qt_to_seconds_9 """select to_seconds('12:34:56')"""
+    qt_to_seconds_10 """select to_seconds('-12:34:56.123456')"""
+    qt_to_seconds_11 """select to_seconds(20250101)"""
+    qt_to_seconds_12 """select to_seconds(20250101123045)"""
+    testFoldConst("SELECT to_seconds('2007-10-07')")
+    testFoldConst("SELECT to_seconds('2007-10-07 10:03:09')")
+    testFoldConst("SELECT to_seconds('0000-01-01 00:00:00')")
+    testFoldConst("SELECT to_seconds('9999-12-31 23:59:59')")
+    testFoldConst("SELECT to_seconds('101-01-01 08:30:15.123456')")
+    testFoldConst("SELECT to_seconds('2023-02-30 12:00:00')")
+    testFoldConst("SELECT to_seconds(NULL)")
+    testFoldConst("SELECT to_seconds('2023-10-07 12:34:56.654321')")
+    testFoldConst("SELECT to_seconds('12:34:56')")
+    testFoldConst("SELECT to_seconds('-12:34:56.123456')")
+    testFoldConst("SELECT to_seconds(20250101)")
+    testFoldConst("SELECT to_seconds(20250101123045)")
+
     // Test constant folding for Group 1 functions (基础日期函数)
     
     // 1. CONVERT_TZ function constant folding tests
@@ -1889,6 +1920,10 @@ suite("doc_date_functions_test") {
     // 79. TO_DAYS function constant folding tests
     testFoldConst("SELECT TO_DAYS('2007-10-07')")
     testFoldConst("SELECT TO_DAYS('2007-10-07 10:03:09')")
+    testFoldConst("SELECT TO_DAYS('0000-01-01 00:00:00')")
+    testFoldConst("SELECT TO_DAYS('0000-02-28')")
+    testFoldConst("SELECT TO_DAYS('0000-02-29')")
+    testFoldConst("SELECT TO_DAYS('0000-03-01')")
 
     // 80. TO_ISO8601 function constant folding tests
     testFoldConst("SELECT TO_ISO8601(CAST('2023-10-05' AS DATE)) AS 
date_result")


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

Reply via email to