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

yiguolei 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 49411092ef6 [Enhancement](date) Enhance the sec_to_time function to 
support return microseconds (#55964)
49411092ef6 is described below

commit 49411092ef61c97255c93dd22d4ba711eb79f676
Author: linrrarity <[email protected]>
AuthorDate: Sun Sep 14 08:37:42 2025 +0800

    [Enhancement](date) Enhance the sec_to_time function to support return 
microseconds (#55964)
---
 .../function_date_or_datetime_computation.h        |  12 ++++++---
 be/src/vec/runtime/time_value.h                    |   6 ++++-
 .../executable/DateTimeExtractAndTransform.java    |  17 +++++++++++++
 .../expressions/functions/scalar/SecToTime.java    |   5 +++-
 .../trees/expressions/literal/TimeV2Literal.java   |  24 ++++++++++++++++--
 .../data/correctness/test_time_function.out        | Bin 502 -> 860 bytes
 .../suites/correctness/test_time_function.groovy   |  28 +++++++++++++++++++++
 7 files changed, 85 insertions(+), 7 deletions(-)

diff --git a/be/src/vec/functions/function_date_or_datetime_computation.h 
b/be/src/vec/functions/function_date_or_datetime_computation.h
index 3081b5c4381..b41b151378c 100644
--- a/be/src/vec/functions/function_date_or_datetime_computation.h
+++ b/be/src/vec/functions/function_date_or_datetime_computation.h
@@ -910,12 +910,18 @@ struct SecToTimeImpl {
     static Status execute(FunctionContext* context, Block& block, const 
ColumnNumbers& arguments,
                           uint32_t result, size_t input_rows_count) {
         const auto& arg_col = block.get_by_position(arguments[0]).column;
-        const auto& column_data = assert_cast<const ColumnInt32&>(*arg_col);
 
         auto res_col = ColumnTimeV2::create(input_rows_count);
         auto& res_data = res_col->get_data();
-        for (int i = 0; i < input_rows_count; ++i) {
-            res_data[i] = 
TimeValue::from_seconds_with_limit(column_data.get_element(i));
+        if (const auto* int_column_ptr = 
check_and_get_column<ColumnInt32>(arg_col.get())) {
+            for (int i = 0; i < input_rows_count; ++i) {
+                res_data[i] = 
TimeValue::from_seconds_with_limit(int_column_ptr->get_element(i));
+            }
+        } else {
+            const auto* double_column_ptr = assert_cast<const 
ColumnFloat64*>(arg_col.get());
+            for (int i = 0; i < input_rows_count; ++i) {
+                res_data[i] = 
TimeValue::from_double_with_limit(double_column_ptr->get_element(i));
+            }
         }
 
         block.replace_by_position(result, std::move(res_col));
diff --git a/be/src/vec/runtime/time_value.h b/be/src/vec/runtime/time_value.h
index 17614429947..ff22b2b74e4 100644
--- a/be/src/vec/runtime/time_value.h
+++ b/be/src/vec/runtime/time_value.h
@@ -43,7 +43,7 @@ public:
     constexpr static int64_t ONE_HOUR_SECONDS = 60 * ONE_MINUTE_SECONDS;
     constexpr static uint32_t MICROS_SCALE = 6;
     constexpr static int64_t MAX_TIME = 838 * ONE_HOUR_MICROSECONDS + 59 * 
ONE_MINUTE_MICROSECONDS +
-                                        59 * ONE_SECOND_MICROSECONDS + 999999; 
// 838:59:59.999999
+                                        59 * ONE_SECOND_MICROSECONDS; // 
838:59:59.000000
 
     /// TODO: Why is the time type stored as double? Can we directly use int64 
and remove the time limit?
     using TimeType = typename PrimitiveTypeTraits<TYPE_TIMEV2>::CppType; // 
double
@@ -126,6 +126,10 @@ public:
         return limit_with_bound((TimeType)sec * ONE_SECOND_MICROSECONDS);
     }
 
+    static TimeType from_double_with_limit(double sec) {
+        return limit_with_bound((TimeType)(sec * ONE_SECOND_MICROSECONDS));
+    }
+
     // refer to https://dev.mysql.com/doc/refman/5.7/en/time.html
     // the time value between '-838:59:59' and '838:59:59'
     static TimeType limit_with_bound(TimeType time) {
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 12b64e69090..9cb6a9443df 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
@@ -37,6 +37,7 @@ import 
org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.StringLikeLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.TimeV2Literal;
 import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
 import org.apache.doris.nereids.trees.expressions.literal.VarcharLiteral;
 import org.apache.doris.nereids.types.DataType;
@@ -1307,4 +1308,20 @@ public class DateTimeExtractAndTransform {
         daysToAdd = daysToAdd == 0 ? 7 : daysToAdd;
         return date.plusDays(daysToAdd);
     }
+
+    /**
+     * date transform function sec_to_time
+     */
+    @ExecFunction(name = "sec_to_time")
+    public static Expression secToTime(IntegerLiteral sec) {
+        return new TimeV2Literal((double) sec.getValue() * 1000000, 0);
+    }
+
+    /**
+     * date transform function sec_to_time
+     */
+    @ExecFunction(name = "sec_to_time")
+    public static Expression secToTime(DoubleLiteral sec) {
+        return new TimeV2Literal(sec.getValue() * 1000000);
+    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecToTime.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecToTime.java
index 5043770d958..fd1eaab126a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecToTime.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SecToTime.java
@@ -23,6 +23,7 @@ import 
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSi
 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.DoubleType;
 import org.apache.doris.nereids.types.IntegerType;
 import org.apache.doris.nereids.types.TimeV2Type;
 
@@ -38,7 +39,9 @@ public class SecToTime extends ScalarFunction
         implements UnaryExpression, ExplicitlyCastableSignature, 
PropagateNullable {
 
     public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
-            
FunctionSignature.ret(TimeV2Type.INSTANCE).args(IntegerType.INSTANCE));
+            
FunctionSignature.ret(TimeV2Type.INSTANCE).args(IntegerType.INSTANCE),
+            FunctionSignature.ret(TimeV2Type.MAX).args(DoubleType.INSTANCE)
+    );
 
     /**
      * constructor with 1 argument.
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/TimeV2Literal.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/TimeV2Literal.java
index becbb415b04..538052d9ad7 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/TimeV2Literal.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/TimeV2Literal.java
@@ -33,8 +33,8 @@ import java.time.LocalDateTime;
 public class TimeV2Literal extends Literal {
     private static final LocalDateTime START_OF_A_DAY = LocalDateTime.of(0, 1, 
1, 0, 0, 0);
     private static final LocalDateTime END_OF_A_DAY = LocalDateTime.of(9999, 
12, 31, 23, 59, 59, 999999000);
-    private static final TimeV2Literal MIN_VALUE = new TimeV2Literal(838, 59, 
59, 999999, 6, true);
-    private static final TimeV2Literal MAX_VALUE = new TimeV2Literal(838, 59, 
59, 999999, 6, false);
+    private static final TimeV2Literal MIN_VALUE = new TimeV2Literal(838, 59, 
59, 0, 6, true);
+    private static final TimeV2Literal MAX_VALUE = new TimeV2Literal(838, 59, 
59, 0, 6, false);
 
     protected int hour;
     protected int minute;
@@ -72,6 +72,26 @@ public class TimeV2Literal extends Literal {
         this.hour = (int) v;
     }
 
+    /**
+     * C'tor time literal with confirmed scale.
+     */
+    public TimeV2Literal(double value, int scale) throws AnalysisException {
+        super(TimeV2Type.of(scale));
+        if (value > (double) MAX_VALUE.getValue() || value < (double) 
MIN_VALUE.getValue()) {
+            throw new AnalysisException("The value " + value + " is out of 
range, expect value range is ["
+                + (double) MIN_VALUE.getValue() + ", " + (double) 
MAX_VALUE.getValue() + "]");
+        }
+        this.negative = value < 0;
+        long v = (long) Math.abs(value);
+        this.microsecond = (int) (v % 1000000);
+        v /= 1000000;
+        this.second = (int) (v % 60);
+        v /= 60;
+        this.minute = (int) (v % 60);
+        v /= 60;
+        this.hour = (int) v;
+    }
+
     /**
      * C'tor for time type.
      */
diff --git a/regression-test/data/correctness/test_time_function.out 
b/regression-test/data/correctness/test_time_function.out
index 5c15a86c1ab..96a4f818f33 100644
Binary files a/regression-test/data/correctness/test_time_function.out and 
b/regression-test/data/correctness/test_time_function.out differ
diff --git a/regression-test/suites/correctness/test_time_function.groovy 
b/regression-test/suites/correctness/test_time_function.groovy
index 6cb3f1cc49a..513a1e69de1 100644
--- a/regression-test/suites/correctness/test_time_function.groovy
+++ b/regression-test/suites/correctness/test_time_function.groovy
@@ -80,4 +80,32 @@ suite("test_time_function") {
     qt_maxtime2 """
         select SEC_TO_TIME(-762021855) ;
     """
+
+    qt_select """SELECT sec_to_time(35211.7895)"""
+    qt_select """SELECT sec_to_time(35211.00)"""
+    qt_select """SELECT sec_to_time(-35211.7895)"""
+
+    qt_select """SELECT sec_to_time(3020399);"""
+    qt_select """SELECT sec_to_time(3020398.999999);"""
+    qt_select """SELECT sec_to_time(3020400);"""
+    qt_select """SELECT sec_to_time(3020399.0);"""
+    qt_select """SELECT sec_to_time(3020499.000001);"""
+    qt_select """SELECT sec_to_time(-3020398);"""
+    qt_select """SELECT sec_to_time(-3020398.999999);"""
+    qt_select """SELECT sec_to_time(-3020400);"""
+    qt_select """SELECT sec_to_time(-3020399.000001);"""
+
+    testFoldConst("SELECT sec_to_time(35211)")
+    testFoldConst("SELECT sec_to_time(-35211)")
+    testFoldConst("SELECT sec_to_time(35211.7895)")
+    testFoldConst("SELECT sec_to_time(-35211.7895)")
+    testFoldConst("SELECT sec_to_time(35211.00)")
+    testFoldConst("SELECT sec_to_time(3020399)")
+    testFoldConst("SELECT sec_to_time(3020398.999999)")
+    testFoldConst("SELECT sec_to_time(3020400)")
+    testFoldConst("SELECT sec_to_time(3020399.000001)")
+    testFoldConst("SELECT sec_to_time(-3020398)")
+    testFoldConst("SELECT sec_to_time(-3020398.999999)")
+    testFoldConst("SELECT sec_to_time(-3020400)")
+    testFoldConst("SELECT sec_to_time(3020399.0)")
 }


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

Reply via email to