[Fix](function) Fix unix_timestamp core for string input (#32871)
This commit is contained in:
@ -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(×tamp, 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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; """
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user