From 5ffac7f39fa654e815f3daf6986afd2e702a5c80 Mon Sep 17 00:00:00 2001 From: kevinyhzou Date: Thu, 24 Oct 2024 20:02:54 +0800 Subject: [PATCH] improve performance --- src/Functions/UTCTimestampTransform.cpp | 30 ++++++++++--------- .../02812_from_to_utc_timestamp.sh | 3 ++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Functions/UTCTimestampTransform.cpp b/src/Functions/UTCTimestampTransform.cpp index 619951b8113..41f7f5fe749 100644 --- a/src/Functions/UTCTimestampTransform.cpp +++ b/src/Functions/UTCTimestampTransform.cpp @@ -27,7 +27,7 @@ namespace ErrorCodes namespace { - template + template class UTCTimestampTransform : public IFunction { public: @@ -77,7 +77,7 @@ namespace if (!time_zone_const_col) throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Illegal column {} of 2nd argument of function {}. Excepted const(String).", arg2.column->getName(), name); String time_zone_val = time_zone_const_col->getDataAt(0).toString(); - const DateLUTImpl & utc_time_zone = DateLUT::instance("UTC"); + const DateLUTImpl & time_zone = DateLUT::instance(time_zone_val); if (WhichDataType(arg1.type).isDateTime()) { const auto & date_time_col = checkAndGetColumn(*arg1.column); @@ -87,13 +87,15 @@ namespace for (size_t i = 0; i < input_rows_count; ++i) { UInt32 date_time_val = date_time_col.getElement(i); - LocalDateTime date_time(date_time_val, Name::to ? utc_time_zone : DateLUT::instance(time_zone_val)); - time_t time_val = date_time.to_time_t(Name::from ? utc_time_zone : DateLUT::instance(time_zone_val)); - result_data[i] = static_cast(time_val); + auto timezoneOffset = time_zone.timezoneOffset(date_time_val); + if constexpr (to) + result_data[i] = date_time_val - static_cast(timezoneOffset); + else + result_data[i] = date_time_val + static_cast(timezoneOffset); } return result_column; } - if (WhichDataType(arg1.type).isDateTime64()) + else if (WhichDataType(arg1.type).isDateTime64()) { const auto & date_time_col = checkAndGetColumn(*arg1.column); const DataTypeDateTime64 * date_time_type = static_cast(arg1.type.get()); @@ -107,8 +109,12 @@ namespace DateTime64 date_time_val = date_time_col.getElement(i); Int64 seconds = date_time_val.value / scale_multiplier; Int64 micros = date_time_val.value % scale_multiplier; - LocalDateTime date_time(seconds, Name::to ? utc_time_zone : DateLUT::instance(time_zone_val)); - time_t time_val = date_time.to_time_t(Name::from ? utc_time_zone : DateLUT::instance(time_zone_val)); + auto timezoneOffset = time_zone.timezoneOffset(seconds); + Int64 time_val = seconds; + if constexpr (to) + time_val -= timezoneOffset; + else + time_val += timezoneOffset; DateTime64 date_time_64(time_val * scale_multiplier + micros); result_data[i] = date_time_64; } @@ -122,19 +128,15 @@ namespace struct NameToUTCTimestamp { static constexpr auto name = "toUTCTimestamp"; - static constexpr auto from = false; - static constexpr auto to = true; }; struct NameFromUTCTimestamp { static constexpr auto name = "fromUTCTimestamp"; - static constexpr auto from = true; - static constexpr auto to = false; }; - using ToUTCTimestampFunction = UTCTimestampTransform; - using FromUTCTimestampFunction = UTCTimestampTransform; + using ToUTCTimestampFunction = UTCTimestampTransform; + using FromUTCTimestampFunction = UTCTimestampTransform; } REGISTER_FUNCTION(UTCTimestampTransform) diff --git a/tests/queries/0_stateless/02812_from_to_utc_timestamp.sh b/tests/queries/0_stateless/02812_from_to_utc_timestamp.sh index 59a6399ee2f..835dab8af57 100755 --- a/tests/queries/0_stateless/02812_from_to_utc_timestamp.sh +++ b/tests/queries/0_stateless/02812_from_to_utc_timestamp.sh @@ -12,4 +12,7 @@ ${CLICKHOUSE_CLIENT} -q "INSERT INTO test_tbl values(1, '2023-03-16', '2023-03-1 ${CLICKHOUSE_CLIENT} -q "INSERT INTO test_tbl values(2, '2023-03-16 11:22:33', '2023-03-16')" ${CLICKHOUSE_CLIENT} -q "INSERT INTO test_tbl values(3, '2023-03-16 11:22:33', '2023-03-16 11:22:33.123456')" $CLICKHOUSE_CLIENT -q "select x, to_utc_timestamp(toDateTime('2023-03-16 11:22:33'), 'Etc/GMT+1'), from_utc_timestamp(toDateTime64('2023-03-16 11:22:33', 3), 'Etc/GMT+1'), to_utc_timestamp(y, 'Asia/Shanghai'), from_utc_timestamp(z, 'Asia/Shanghai') from test_tbl order by x" +# timestamp convert between DST timezone and UTC +$CLICKHOUSE_CLIENT -q "select to_utc_timestamp(toDateTime('2024-02-24 11:22:33'), 'Europe/Madrid'), from_utc_timestamp(toDateTime('2024-02-24 11:22:33'), 'Europe/Madrid')" +$CLICKHOUSE_CLIENT -q "select to_utc_timestamp(toDateTime('2024-10-24 11:22:33'), 'Europe/Madrid'), from_utc_timestamp(toDateTime('2024-10-24 11:22:33'), 'Europe/Madrid')" $CLICKHOUSE_CLIENT -q "drop table test_tbl" \ No newline at end of file