From 7082eb00058a144be6ba865767ed2e3191802a4e Mon Sep 17 00:00:00 2001 From: zclllyybb Date: Wed, 20 Aug 2025 17:02:08 +0800 Subject: [PATCH] [Fix](function) Fix wrong decimal of unix_timestamp (#55013) when the input datetime has decimal part start with zero, the result was wrong before. now fixed. before: ```sql mysql> select UNIX_TIMESTAMP('2015-11-13 10:20:19.012'); +-------------------------------------------+ | UNIX_TIMESTAMP('2015-11-13 10:20:19.012') | +-------------------------------------------+ | 1447381219.120 | +-------------------------------------------+ ``` now: ```sql mysql> select UNIX_TIMESTAMP('2015-11-13 10:20:19.012'); +-------------------------------------------+ | UNIX_TIMESTAMP('2015-11-13 10:20:19.012') | +-------------------------------------------+ | 1447381219.012 | +-------------------------------------------+ ``` --- be/src/vec/functions/function_timestamp.cpp | 10 +++++----- .../executable/DateTimeExtractAndTransform.java | 2 +- .../datetime_functions/test_date_function.out | 6 ++++++ .../datetime_functions/test_date_function.groovy | 9 +++++++-- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/be/src/vec/functions/function_timestamp.cpp b/be/src/vec/functions/function_timestamp.cpp index 4dd3c77ebf0dca..1510a200d0596f 100644 --- a/be/src/vec/functions/function_timestamp.cpp +++ b/be/src/vec/functions/function_timestamp.cpp @@ -49,6 +49,7 @@ #include "vec/columns/column_vector.h" #include "vec/columns/columns_number.h" #include "vec/common/assert_cast.h" +#include "vec/common/int_exp.h" #include "vec/common/pod_array_fwd.h" #include "vec/common/string_ref.h" #include "vec/core/block.h" @@ -674,11 +675,10 @@ struct UnixTimeStampDateImpl { DCHECK(valid); auto [sec, ms] = UnixTimeStampImpl::trim_timestamp(timestamp); - auto ms_str = std::to_string(ms).substr(0, scale); - if (ms_str.empty()) { - ms_str = "0"; - } - col_result_data[i] = Decimal64::from_int_frac(sec, std::stoll(ms_str), scale).value; + col_result_data[i] = + Decimal64::from_int_frac( + sec, ms / static_cast(std::pow(10, 6 - scale)), scale) + .value; } block.replace_by_position(result, std::move(col_result)); } 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 aa45df5d1c83c8..d1e8a88a0a937d 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 @@ -620,7 +620,7 @@ private static String getTimestamp(LocalDateTime dateTime) { if (duration.getNano() == 0) { return String.valueOf(duration.getSeconds()); } else { - return duration.getSeconds() + "." + (duration.getNano() / 1000); + return duration.getSeconds() + "." + String.format("%06d", duration.getNano() / 1000); } } diff --git a/regression-test/data/nereids_p0/sql_functions/datetime_functions/test_date_function.out b/regression-test/data/nereids_p0/sql_functions/datetime_functions/test_date_function.out index 30fe2980862d3c..cbfc68fc27df5e 100644 --- a/regression-test/data/nereids_p0/sql_functions/datetime_functions/test_date_function.out +++ b/regression-test/data/nereids_p0/sql_functions/datetime_functions/test_date_function.out @@ -375,6 +375,12 @@ February -- !sql_ustamp9 -- 0 +-- !sql_ustamp10 -- +1447381219.00001 + +-- !sql_ustamp11 -- +1447381219.012000 + -- !sql -- 0 diff --git a/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy b/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy index 7edf5e6cb11ba4..5cf16d07eeef17 100644 --- a/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy +++ b/regression-test/suites/nereids_p0/sql_functions/datetime_functions/test_date_function.groovy @@ -387,8 +387,13 @@ suite("test_date_function") { qt_sql_ustamp7 """ select unix_timestamp(cast('2007-11-30 10:30:19.123456' as datetimev2(4))) """ qt_sql_ustamp8 """ SELECT UNIX_TIMESTAMP('9999-12-30 23:59:59.999'); """ qt_sql_ustamp9 """ SELECT UNIX_TIMESTAMP('9999-12-30 23:59:59'); """ - testFoldConst("SELECT UNIX_TIMESTAMP('9999-12-30 23:59:59.999');") - testFoldConst("SELECT UNIX_TIMESTAMP('9999-12-30 23:59:59');") + qt_sql_ustamp10 """ select UNIX_TIMESTAMP('2015-11-13 10:20:19.000010'); """ + qt_sql_ustamp11 """ select UNIX_TIMESTAMP(cast('2015-11-13 10:20:19.012' as datetime(6))); """ + check_fold_consistency(" UNIX_TIMESTAMP('9999-12-30 23:59:59.999')") + check_fold_consistency(" UNIX_TIMESTAMP('9999-12-30 23:59:59')") + check_fold_consistency(" UNIX_TIMESTAMP('2015-11-13 10:20:19.000010')") + // check_fold_consistency(" UNIX_TIMESTAMP(cast('2015-11-13 10:20:19.000' as datetime(6)))") + check_fold_consistency(" UNIX_TIMESTAMP(cast('2015-11-13 10:20:19.012' as datetime(6)))") // UTC_TIMESTAMP def utc_timestamp_str = sql """ select utc_timestamp(),utc_timestamp() + 1 """