[Fix](function) Fix unix_timestamp core for string input (#32871)

This commit is contained in:
zclllyybb
2024-03-27 11:19:03 +08:00
committed by yiguolei
parent b5b0181a79
commit 2a0644f442
4 changed files with 64 additions and 6 deletions

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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; """
}