From c91bc0a1fe7459eae56ecac031435328fc10dd09 Mon Sep 17 00:00:00 2001 From: robot-clickhouse Date: Mon, 18 Nov 2024 16:07:06 +0000 Subject: [PATCH] Backport #71849 to 24.8: Fix: add monotonic estimation for DateTime64 in toDayOfWeek --- src/Functions/DateTimeTransforms.h | 1 + src/Functions/IFunctionCustomWeek.h | 19 ++++++++++++++++--- ...71_decimal_monotonic_day_of_week.reference | 1 + .../03271_decimal_monotonic_day_of_week.sql | 7 +++++++ 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 tests/queries/0_stateless/03271_decimal_monotonic_day_of_week.reference create mode 100644 tests/queries/0_stateless/03271_decimal_monotonic_day_of_week.sql diff --git a/src/Functions/DateTimeTransforms.h b/src/Functions/DateTimeTransforms.h index dfb4b76e5e2..f52c83fa8ab 100644 --- a/src/Functions/DateTimeTransforms.h +++ b/src/Functions/DateTimeTransforms.h @@ -63,6 +63,7 @@ constexpr time_t MAX_DATETIME_DAY_NUM = 49710; // 2106-02-07 /// This factor transformation will say that the function is monotone everywhere. struct ZeroTransform { + static constexpr auto name = "Zero"; static UInt16 execute(Int64, const DateLUTImpl &) { return 0; } static UInt16 execute(UInt32, const DateLUTImpl &) { return 0; } static UInt16 execute(Int32, const DateLUTImpl &) { return 0; } diff --git a/src/Functions/IFunctionCustomWeek.h b/src/Functions/IFunctionCustomWeek.h index ba0baa35819..c6f1aebea88 100644 --- a/src/Functions/IFunctionCustomWeek.h +++ b/src/Functions/IFunctionCustomWeek.h @@ -55,13 +55,26 @@ public: ? is_monotonic : is_not_monotonic; } - else + + if (checkAndGetDataType(&type)) { - return Transform::FactorTransform::execute(UInt32(left.safeGet()), date_lut) - == Transform::FactorTransform::execute(UInt32(right.safeGet()), date_lut) + + const auto & left_date_time = left.safeGet(); + TransformDateTime64 transformer_left(left_date_time.getScale()); + + const auto & right_date_time = right.safeGet(); + TransformDateTime64 transformer_right(right_date_time.getScale()); + + return transformer_left.execute(left_date_time.getValue(), date_lut) + == transformer_right.execute(right_date_time.getValue(), date_lut) ? is_monotonic : is_not_monotonic; } + + return Transform::FactorTransform::execute(UInt32(left.safeGet()), date_lut) + == Transform::FactorTransform::execute(UInt32(right.safeGet()), date_lut) + ? is_monotonic + : is_not_monotonic; } protected: diff --git a/tests/queries/0_stateless/03271_decimal_monotonic_day_of_week.reference b/tests/queries/0_stateless/03271_decimal_monotonic_day_of_week.reference new file mode 100644 index 00000000000..b8626c4cff2 --- /dev/null +++ b/tests/queries/0_stateless/03271_decimal_monotonic_day_of_week.reference @@ -0,0 +1 @@ +4 diff --git a/tests/queries/0_stateless/03271_decimal_monotonic_day_of_week.sql b/tests/queries/0_stateless/03271_decimal_monotonic_day_of_week.sql new file mode 100644 index 00000000000..66e085c502d --- /dev/null +++ b/tests/queries/0_stateless/03271_decimal_monotonic_day_of_week.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS decimal_dt; + +CREATE TABLE decimal_dt (timestamp DateTime64(9)) ENGINE=MergeTree() ORDER BY timestamp; +INSERT INTO decimal_dt VALUES (toDate('2024-11-11')),(toDate('2024-11-12')),(toDate('2024-11-13')),(toDate('2024-11-14')),(toDate('2024-11-15')),(toDate('2024-11-16')),(toDate('2024-11-17')); +SELECT count() FROM decimal_dt WHERE toDayOfWeek(timestamp) > 3; + +DROP TABLE IF EXISTS decimal_dt;