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 6c24a0a6bf0 [Fix](function) Fix unix_timestamp core for string input 
(#32871)
6c24a0a6bf0 is described below

commit 6c24a0a6bf0de2792a78f87daa89a1d9f25b4c16
Author: zclllyybb <zhaochan...@selectdb.com>
AuthorDate: Wed Mar 27 11:19:03 2024 +0800

    [Fix](function) Fix unix_timestamp core for string input (#32871)
---
 be/src/vec/functions/function_timestamp.cpp        | 18 ++++++++----
 be/src/vec/runtime/vdatetime_value.cpp             |  2 +-
 .../datetime_functions/test_date_function.out      | 33 ++++++++++++++++++++++
 .../datetime_functions/test_date_function.groovy   | 17 +++++++++++
 4 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/be/src/vec/functions/function_timestamp.cpp 
b/be/src/vec/functions/function_timestamp.cpp
index 764c6a72f44..c2285795c71 100644
--- a/be/src/vec/functions/function_timestamp.cpp
+++ b/be/src/vec/functions/function_timestamp.cpp
@@ -559,6 +559,13 @@ struct UnixTimeStampImpl {
         return (Int32)timestamp;
     }
 
+    static std::pair<Int32, Int32> trim_timestamp(std::pair<Int64, Int64> 
timestamp) {
+        if (timestamp.first < 0 || timestamp.first > INT_MAX) {
+            return {0, 0};
+        }
+        return std::make_pair((Int32)timestamp.first, (Int32)timestamp.second);
+    }
+
     static DataTypes get_variadic_argument_types() { return {}; }
 
     static DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& 
arguments) {
@@ -835,8 +842,8 @@ struct UnixTimeStampStrImpl {
         const auto* col_source = assert_cast<const 
ColumnString*>(col_left.get());
         const auto* col_format = assert_cast<const 
ColumnString*>(col_right.get());
         for (int i = 0; i < input_rows_count; i++) {
-            StringRef source = col_source->get_data_at(i);
-            StringRef fmt = col_format->get_data_at(i);
+            StringRef source = col_source->get_data_at(index_check_const(i, 
source_const));
+            StringRef fmt = col_format->get_data_at(index_check_const(i, 
format_const));
 
             DateV2Value<DateTimeV2ValueType> ts_value;
             if (!ts_value.from_date_format_str(fmt.data, fmt.size, 
source.data, source.size)) {
@@ -846,16 +853,17 @@ struct UnixTimeStampStrImpl {
 
             std::pair<int64_t, int64_t> timestamp {};
             if (!ts_value.unix_timestamp(&timestamp, 
context->state()->timezone_obj())) {
-                null_map_data[i] = true;
+                null_map_data[i] = true; // impossible now
             } else {
                 null_map_data[i] = false;
 
-                auto& [sec, ms] = timestamp;
-                sec = UnixTimeStampImpl::trim_timestamp(sec);
+                auto [sec, ms] = UnixTimeStampImpl::trim_timestamp(timestamp);
+                // trailing ms
                 auto ms_str = std::to_string(ms).substr(0, 6);
                 if (ms_str.empty()) {
                     ms_str = "0";
                 }
+
                 col_result_data[i] = Decimal64::from_int_frac(sec, 
std::stoll(ms_str), 6).value;
             }
         }
diff --git a/be/src/vec/runtime/vdatetime_value.cpp 
b/be/src/vec/runtime/vdatetime_value.cpp
index 7d3f7f8be7e..ee384286455 100644
--- a/be/src/vec/runtime/vdatetime_value.cpp
+++ b/be/src/vec/runtime/vdatetime_value.cpp
@@ -3265,7 +3265,7 @@ bool DateV2Value<T>::unix_timestamp(std::pair<int64_t, 
int64_t>* timestamp,
                               ctz);
         timestamp->first = tp.time_since_epoch().count();
         timestamp->second = date_v2_value_.microsecond_;
-    } else {
+    } else { // just make compiler happy
     }
     return true;
 }
diff --git 
a/regression-test/data/query_p0/sql_functions/datetime_functions/test_date_function.out
 
b/regression-test/data/query_p0/sql_functions/datetime_functions/test_date_function.out
index ffd8d5b8cd2..6a59c3c9947 100644
--- 
a/regression-test/data/query_p0/sql_functions/datetime_functions/test_date_function.out
+++ 
b/regression-test/data/query_p0/sql_functions/datetime_functions/test_date_function.out
@@ -686,3 +686,36 @@ true
 -- !sql --
 1694966400.000000      1694966400.000000
 
+-- !sql_varchar1 --
+0000-00-00     %Y-%m-%d        \N
+9999-12-31 23:59:59.999999     %Y-%m-%d %H:%i:%s.%f    0.000000
+9999-12-31 23:59:59.9999999    %Y-%m-%d %H:%i:%s.%f    0.000000
+0000-01-01     %Y-%m-%d        0.000000
+9999-12-31 23:59:59    %Y-%m-%d %H:%i:%s       0.000000
+1999-12-31 23:59:59.9999999    %Y-%m-%d %H:%i:%s.%f    946655999.999999
+20201111       %Y%m%d  1605024000.000000
+2020-12-12     %Y-%m-%d        1607702400.000000
+202012-13      %Y%m-%d 1607788800.000000
+
+-- !sql_varchar1 --
+20201111       \N
+0000-00-00     \N
+202012-13      \N
+0000-01-01     0.000000
+9999-12-31 23:59:59.9999999    0.000000
+9999-12-31 23:59:59.999999     0.000000
+9999-12-31 23:59:59    0.000000
+1999-12-31 23:59:59.9999999    946569600.000000
+2020-12-12     1607702400.000000
+
+-- !sql_varchar1 --
+%Y%m-%d        \N
+%Y%m%d \N
+%Y-%m-%d       660931200.000000
+%Y-%m-%d %H:%i:%s.%f   660931200.000000
+%Y-%m-%d %H:%i:%s.%f   660931200.000000
+%Y-%m-%d       660931200.000000
+%Y-%m-%d       660931200.000000
+%Y-%m-%d %H:%i:%s.%f   660931200.000000
+%Y-%m-%d %H:%i:%s      660931200.000000
+
diff --git 
a/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy
 
b/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy
index ba48c34f409..f174819979d 100644
--- 
a/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy
+++ 
b/regression-test/suites/query_p0/sql_functions/datetime_functions/test_date_function.groovy
@@ -734,4 +734,21 @@ suite("test_date_function") {
            (
             SELECT FROM_UNIXTIME(UNIX_TIMESTAMP('20230918', '%Y%m%d'), 
'yyyy-MM-dd HH:mm:ss') AS `a`
            )t """
+
+    sql """ drop table if exists date_varchar """
+    sql """
+        create table date_varchar(
+            dt varchar null,
+            fmt varchar null
+        )
+        DISTRIBUTED BY HASH(`dt`) BUCKETS 1
+        properties("replication_num" = "1");
+    """
+    sql """ insert into date_varchar values ("2020-12-12", "%Y-%m-%d"), 
("20201111", "%Y%m%d"), ("202012-13", "%Y%m-%d"),
+    ("0000-00-00", "%Y-%m-%d"),("0000-01-01", "%Y-%m-%d"),("9999-12-31 
23:59:59", "%Y-%m-%d %H:%i:%s"),
+    ("9999-12-31 23:59:59.999999", "%Y-%m-%d %H:%i:%s.%f"), ("9999-12-31 
23:59:59.9999999", "%Y-%m-%d %H:%i:%s.%f"),
+    ("1999-12-31 23:59:59.9999999", "%Y-%m-%d %H:%i:%s.%f"); """
+    qt_sql_varchar1 """ select dt, fmt, unix_timestamp(dt, fmt) as k1 from 
date_varchar order by k1; """
+    qt_sql_varchar1 """ select dt, unix_timestamp(dt, "%Y-%m-%d") as k1 from 
date_varchar order by k1; """
+    qt_sql_varchar1 """ select fmt, unix_timestamp("1990-12-12", fmt) as k1 
from date_varchar order by k1; """
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to