From 537fb8c4eeb50276ee5c8f6a232a1864378f1c42 Mon Sep 17 00:00:00 2001 From: zvonand Date: Mon, 15 Aug 2022 01:16:35 +0300 Subject: [PATCH 01/24] fix 1 --- src/Functions/DateTimeTransforms.h | 103 +++++++++++++++++++++++----- src/Functions/FunctionsConversion.h | 29 +++++--- 2 files changed, 108 insertions(+), 24 deletions(-) diff --git a/src/Functions/DateTimeTransforms.h b/src/Functions/DateTimeTransforms.h index 065f08296d0..42733a82165 100644 --- a/src/Functions/DateTimeTransforms.h +++ b/src/Functions/DateTimeTransforms.h @@ -61,15 +61,24 @@ struct ToDateImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - return UInt16(time_zone.toDayNum(t)); + auto day_num = time_zone.toDayNum(t); + if (day_num < 0) + return 0; + else if (day_num > DATE_LUT_MAX_DAY_NUM) + return UInt16(DATE_LUT_MAX_DAY_NUM); + else + return UInt16(day_num); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { return UInt16(time_zone.toDayNum(t)); } - static inline UInt16 execute(Int32, const DateLUTImpl &) + static inline UInt16 execute(Int32 t, const DateLUTImpl &) { - return dateIsNotSupported(name); + if (t < 0) + return 0; + + return UInt16(t < DATE_LUT_MAX_DAY_NUM ? t : DATE_LUT_MAX_DAY_NUM); } static inline UInt16 execute(UInt16 d, const DateLUTImpl &) { @@ -111,7 +120,10 @@ struct ToStartOfDayImpl //TODO: right now it is hardcoded to produce DateTime only, needs fixing later. See date_and_time_type_details::ResultDataTypeMap for deduction of result type example. static inline UInt32 execute(const DecimalUtils::DecimalComponents & t, const DateLUTImpl & time_zone) { - return time_zone.toDate(static_cast(t.whole)); + if (t.whole < 0) + return 0; + + return time_zone.toDate(t.whole < DATE_LUT_MAX_DAY_NUM ? t.whole : DATE_LUT_MAX_DAY_NUM); } static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -119,7 +131,10 @@ struct ToStartOfDayImpl } static inline UInt32 execute(Int32 d, const DateLUTImpl & time_zone) { - return time_zone.toDate(ExtendedDayNum(d)); + if (d < 0) + return 0; + + return time_zone.toDate(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); } static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -135,8 +150,14 @@ struct ToMondayImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { + if (t < 0) + return 0; + + auto day_num = time_zone.toDayNum(t); + + return time_zone.toFirstDayNumOfWeek(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM); //return time_zone.toFirstDayNumOfWeek(time_zone.toDayNum(t)); - return time_zone.toFirstDayNumOfWeek(t); +// return time_zone.toFirstDayNumOfWeek(t); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -145,7 +166,11 @@ struct ToMondayImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(d)); + if (d < 0) + return 0; + + return time_zone.toFirstDayNumOfWeek(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); +// return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(d)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -161,7 +186,13 @@ struct ToStartOfMonthImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - return time_zone.toFirstDayNumOfMonth(time_zone.toDayNum(t)); + if (t < 0) + return 0; + + auto day_num = time_zone.toDayNum(t); + + return time_zone.toFirstDayNumOfMonth(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM); +// return time_zone.toFirstDayNumOfMonth(time_zone.toDayNum(t)); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -169,7 +200,11 @@ struct ToStartOfMonthImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - return time_zone.toFirstDayNumOfMonth(ExtendedDayNum(d)); + if (d < 0) + return 0; + + return time_zone.toFirstDayNumOfMonth(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); +// return time_zone.toFirstDayNumOfMonth(ExtendedDayNum(d)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -185,7 +220,13 @@ struct ToLastDayOfMonthImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - return time_zone.toLastDayNumOfMonth(time_zone.toDayNum(t)); + if (t < 0) + return 0; + + auto day_num = time_zone.toDayNum(t); + + return time_zone.toLastDayNumOfMonth(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM); +// return time_zone.toLastDayNumOfMonth(time_zone.toDayNum(t)); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -193,7 +234,11 @@ struct ToLastDayOfMonthImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - return time_zone.toLastDayNumOfMonth(ExtendedDayNum(d)); + if (d < 0) + return 0; + + return time_zone.toLastDayNumOfMonth(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); +// return time_zone.toLastDayNumOfMonth(ExtendedDayNum(d)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -209,7 +254,13 @@ struct ToStartOfQuarterImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - return time_zone.toFirstDayNumOfQuarter(time_zone.toDayNum(t)); + if (t < 0) + return 0; + + auto day_num = time_zone.toDayNum(t); + + return time_zone.toFirstDayNumOfQuarter(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM); +// return time_zone.toFirstDayNumOfQuarter(time_zone.toDayNum(t)); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -217,7 +268,11 @@ struct ToStartOfQuarterImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - return time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(d)); + if (d < 0) + return 0; + + return time_zone.toFirstDayNumOfQuarter(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); +// return time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(d)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -233,7 +288,13 @@ struct ToStartOfYearImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - return time_zone.toFirstDayNumOfYear(time_zone.toDayNum(t)); + if (t < 0) + return 0; + + auto day_num = time_zone.toDayNum(t); + + return time_zone.toFirstDayNumOfYear(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM); +// return time_zone.toFirstDayNumOfYear(time_zone.toDayNum(t)); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -241,7 +302,11 @@ struct ToStartOfYearImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - return time_zone.toFirstDayNumOfYear(ExtendedDayNum(d)); + if (d < 0) + return 0; + + return time_zone.toFirstDayNumOfYear(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); +// return time_zone.toFirstDayNumOfYear(ExtendedDayNum(d)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -283,7 +348,13 @@ struct ToStartOfMinuteImpl static inline UInt32 execute(const DecimalUtils::DecimalComponents & t, const DateLUTImpl & time_zone) { - return time_zone.toStartOfMinute(t.whole); + if (t.whole < 0) + return 0; + + auto day_num = time_zone.toDayNum(t.whole); + + return time_zone.toStartOfMinute(day_num < DATE_LUT_MAX_DAY_NUM ? t.whole : INT16_MAX); +// return time_zone.toStartOfMinute(t.whole); } static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone) { diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index 2788e2cc390..c4599fa2de3 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -322,9 +322,12 @@ struct ToDateTimeImpl return time_zone.fromDayNum(DayNum(d)); } - static inline Int64 execute(Int32 d, const DateLUTImpl & time_zone) + static inline UInt32 execute(Int32 d, const DateLUTImpl & time_zone) { - return time_zone.fromDayNum(ExtendedDayNum(d)); + if (d < 0) + return 0; + + return time_zone.fromDayNum(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)); } static inline UInt32 execute(UInt32 dt, const DateLUTImpl & /*time_zone*/) @@ -332,10 +335,15 @@ struct ToDateTimeImpl return dt; } - // TODO: return UInt32 ??? - static inline Int64 execute(Int64 dt64, const DateLUTImpl & /*time_zone*/) + static inline UInt32 execute(Int64 dt64, const DateLUTImpl & time_zone) { - return dt64; + if (dt64 < 0) + return 0; + + auto day_num = time_zone.toDayNum(dt64); + return (day_num < DATE_LUT_MAX_DAY_NUM) + ? dt64 + : time_zone.toDayNum(std::min(time_t(dt64), time_t(0xFFFFFFFF))); } }; @@ -355,6 +363,8 @@ struct ToDateTransform32Or64 static inline NO_SANITIZE_UNDEFINED ToType execute(const FromType & from, const DateLUTImpl & time_zone) { // since converting to Date, no need in values outside of default LUT range. + if (from < 0) + return time_t(0); return (from < DATE_LUT_MAX_DAY_NUM) ? from : time_zone.toDayNum(std::min(time_t(from), time_t(0xFFFFFFFF))); @@ -509,11 +519,14 @@ struct ToDateTimeTransform64Signed { static constexpr auto name = "toDateTime"; - static inline NO_SANITIZE_UNDEFINED ToType execute(const FromType & from, const DateLUTImpl &) + static inline NO_SANITIZE_UNDEFINED ToType execute(const FromType & from, const DateLUTImpl & time_zone) { if (from < 0) return 0; - return std::min(time_t(from), time_t(0xFFFFFFFF)); + else if (time_zone.toDayNum(from) > DATE_LUT_MAX_DAY_NUM) + return DATE_LUT_MAX_DAY_NUM; + else + return time_t(from); } }; @@ -1786,7 +1799,7 @@ private: { /// Account for optional timezone argument. if (arguments.size() != 2 && arguments.size() != 3) - throw Exception{"Function " + getName() + " expects 2 or 3 arguments for DataTypeDateTime64.", + throw Exception{"Function " + getName() + " expects 2 or 3 arguments for DateTime64.", ErrorCodes::TOO_FEW_ARGUMENTS_FOR_FUNCTION}; } else if (arguments.size() != 2) From a7a1269e60cdc82316dd1ca7e77951a0b5da3441 Mon Sep 17 00:00:00 2001 From: zvonand Date: Wed, 17 Aug 2022 18:33:36 +0300 Subject: [PATCH 02/24] updated tests + improve logic --- docs/ru/sql-reference/data-types/date.md | 2 +- src/Functions/DateTimeTransforms.h | 68 +++++++++---------- src/Functions/FunctionsConversion.h | 51 +++++++++----- .../02403_date_time_narrowing.reference | 17 +++++ .../0_stateless/02403_date_time_narrowing.sql | 51 ++++++++++++++ 5 files changed, 136 insertions(+), 53 deletions(-) create mode 100644 tests/queries/0_stateless/02403_date_time_narrowing.reference create mode 100644 tests/queries/0_stateless/02403_date_time_narrowing.sql diff --git a/docs/ru/sql-reference/data-types/date.md b/docs/ru/sql-reference/data-types/date.md index 46f73bc8cb7..c4088102ac3 100644 --- a/docs/ru/sql-reference/data-types/date.md +++ b/docs/ru/sql-reference/data-types/date.md @@ -5,7 +5,7 @@ sidebar_label: Date # Date {#data-type-date} -Дата. Хранится в двух байтах в виде (беззнакового) числа дней, прошедших от 1970-01-01. Позволяет хранить значения от чуть больше, чем начала unix-эпохи до верхнего порога, определяющегося константой на этапе компиляции (сейчас - до 2106 года, последний полностью поддерживаемый год - 2105). +Дата. Хранится в двух байтах в виде (беззнакового) числа дней, прошедших от 1970-01-01. Позволяет хранить значения от чуть больше, чем начала unix-эпохи до верхнего порога, определяющегося константой на этапе компиляции (сейчас - до 2149 года, последний полностью поддерживаемый год - 2148). Диапазон значений: \[1970-01-01, 2149-06-06\]. diff --git a/src/Functions/DateTimeTransforms.h b/src/Functions/DateTimeTransforms.h index 42733a82165..30c262e988b 100644 --- a/src/Functions/DateTimeTransforms.h +++ b/src/Functions/DateTimeTransforms.h @@ -61,24 +61,22 @@ struct ToDateImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - auto day_num = time_zone.toDayNum(t); - if (day_num < 0) + if (t < 0) return 0; - else if (day_num > DATE_LUT_MAX_DAY_NUM) - return UInt16(DATE_LUT_MAX_DAY_NUM); - else - return UInt16(day_num); + + auto day_num = time_zone.toDayNum(t); + return day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM; } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { - return UInt16(time_zone.toDayNum(t)); + return time_zone.toDayNum(t); } static inline UInt16 execute(Int32 t, const DateLUTImpl &) { if (t < 0) return 0; - return UInt16(t < DATE_LUT_MAX_DAY_NUM ? t : DATE_LUT_MAX_DAY_NUM); + return t < DATE_LUT_MAX_DAY_NUM ? t : DATE_LUT_MAX_DAY_NUM; } static inline UInt16 execute(UInt16 d, const DateLUTImpl &) { @@ -123,7 +121,11 @@ struct ToStartOfDayImpl if (t.whole < 0) return 0; - return time_zone.toDate(t.whole < DATE_LUT_MAX_DAY_NUM ? t.whole : DATE_LUT_MAX_DAY_NUM); + Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(t.whole)); + if (date_time <= 0xffffffff) + return date_time; + else + return time_zone.toDate(0xffffffff); } static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -134,11 +136,19 @@ struct ToStartOfDayImpl if (d < 0) return 0; - return time_zone.toDate(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); + Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(d)); + if (date_time <= 0xffffffff) + return date_time; + else + return time_zone.toDate(0xffffffff); } static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone) { - return time_zone.toDate(DayNum(d)); + Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(d)); + if (date_time <= 0xffffffff) + return date_time; + else + return time_zone.toDate(0xffffffff); } using FactorTransform = ZeroTransform; @@ -155,13 +165,10 @@ struct ToMondayImpl auto day_num = time_zone.toDayNum(t); - return time_zone.toFirstDayNumOfWeek(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM); - //return time_zone.toFirstDayNumOfWeek(time_zone.toDayNum(t)); -// return time_zone.toFirstDayNumOfWeek(t); + return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { - //return time_zone.toFirstDayNumOfWeek(time_zone.toDayNum(t)); return time_zone.toFirstDayNumOfWeek(t); } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) @@ -169,8 +176,8 @@ struct ToMondayImpl if (d < 0) return 0; - return time_zone.toFirstDayNumOfWeek(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); -// return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(d)); + return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)) + ; } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -191,20 +198,18 @@ struct ToStartOfMonthImpl auto day_num = time_zone.toDayNum(t); - return time_zone.toFirstDayNumOfMonth(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM); -// return time_zone.toFirstDayNumOfMonth(time_zone.toDayNum(t)); + return time_zone.toFirstDayNumOfMonth(ExtendedDayNum(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { - return time_zone.toFirstDayNumOfMonth(time_zone.toDayNum(t)); + return time_zone.toFirstDayNumOfMonth(ExtendedDayNum(time_zone.toDayNum(t))); } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { if (d < 0) return 0; - return time_zone.toFirstDayNumOfMonth(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); -// return time_zone.toFirstDayNumOfMonth(ExtendedDayNum(d)); + return time_zone.toFirstDayNumOfMonth(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -224,9 +229,7 @@ struct ToLastDayOfMonthImpl return 0; auto day_num = time_zone.toDayNum(t); - - return time_zone.toLastDayNumOfMonth(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM); -// return time_zone.toLastDayNumOfMonth(time_zone.toDayNum(t)); + return time_zone.toLastDayNumOfMonth(ExtendedDayNum(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -237,8 +240,7 @@ struct ToLastDayOfMonthImpl if (d < 0) return 0; - return time_zone.toLastDayNumOfMonth(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); -// return time_zone.toLastDayNumOfMonth(ExtendedDayNum(d)); + return time_zone.toLastDayNumOfMonth(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -259,8 +261,7 @@ struct ToStartOfQuarterImpl auto day_num = time_zone.toDayNum(t); - return time_zone.toFirstDayNumOfQuarter(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM); -// return time_zone.toFirstDayNumOfQuarter(time_zone.toDayNum(t)); + return time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -271,8 +272,7 @@ struct ToStartOfQuarterImpl if (d < 0) return 0; - return time_zone.toFirstDayNumOfQuarter(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); -// return time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(d)); + return time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -293,8 +293,7 @@ struct ToStartOfYearImpl auto day_num = time_zone.toDayNum(t); - return time_zone.toFirstDayNumOfYear(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM); -// return time_zone.toFirstDayNumOfYear(time_zone.toDayNum(t)); + return time_zone.toFirstDayNumOfYear(ExtendedDayNum(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -305,8 +304,7 @@ struct ToStartOfYearImpl if (d < 0) return 0; - return time_zone.toFirstDayNumOfYear(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM); -// return time_zone.toFirstDayNumOfYear(ExtendedDayNum(d)); + return time_zone.toFirstDayNumOfYear(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index c4599fa2de3..9062f3a5846 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -301,6 +301,11 @@ struct ConvertImpl } }; +/** Conversion of Date32 to Date: check bounds. + */ +template struct ConvertImpl + : DateTimeTransformImpl {}; + /** Conversion of DateTime to Date: throw off time component. */ template struct ConvertImpl @@ -319,7 +324,8 @@ struct ToDateTimeImpl static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone) { - return time_zone.fromDayNum(DayNum(d)); + Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(d)); + return date_time <= 0xffffffff ? UInt32(date_time) : UInt32(0xffffffff); } static inline UInt32 execute(Int32 d, const DateLUTImpl & time_zone) @@ -327,7 +333,8 @@ struct ToDateTimeImpl if (d < 0) return 0; - return time_zone.fromDayNum(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)); + Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(d)); + return date_time <= 0xffffffff ? UInt32(date_time) : UInt32(0xffffffff); } static inline UInt32 execute(UInt32 dt, const DateLUTImpl & /*time_zone*/) @@ -335,15 +342,13 @@ struct ToDateTimeImpl return dt; } - static inline UInt32 execute(Int64 dt64, const DateLUTImpl & time_zone) + static inline UInt32 execute(const DecimalUtils::DecimalComponents & t, const DateLUTImpl & time_zone) { - if (dt64 < 0) + if (t.whole < 0) return 0; - auto day_num = time_zone.toDayNum(dt64); - return (day_num < DATE_LUT_MAX_DAY_NUM) - ? dt64 - : time_zone.toDayNum(std::min(time_t(dt64), time_t(0xFFFFFFFF))); + auto day_num = time_zone.toDayNum(t.whole); + return (day_num < DATE_LUT_MAX_DAY_NUM) ? t.whole : time_t(0xFFFFFFFF); } }; @@ -364,10 +369,10 @@ struct ToDateTransform32Or64 { // since converting to Date, no need in values outside of default LUT range. if (from < 0) - return time_t(0); - return (from < DATE_LUT_MAX_DAY_NUM) - ? from - : time_zone.toDayNum(std::min(time_t(from), time_t(0xFFFFFFFF))); + return 0; + + auto day_num = time_zone.toDayNum(from); + return day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM; } }; @@ -382,9 +387,9 @@ struct ToDateTransform32Or64Signed /// The function should be monotonic (better for query optimizations), so we saturate instead of overflow. if (from < 0) return 0; - return (from < DATE_LUT_MAX_DAY_NUM) - ? from - : time_zone.toDayNum(std::min(time_t(from), time_t(0xFFFFFFFF))); + + auto day_num = time_zone.toDayNum(from); + return day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM; } }; @@ -457,35 +462,49 @@ struct ToDate32Transform8Or16Signed */ template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; + template struct ConvertImpl : DateTimeTransformImpl> {}; @@ -647,8 +666,6 @@ struct FromDateTime64Transform } }; -/** Conversion of DateTime64 to Date or DateTime: discards fractional part. - */ template struct ConvertImpl : DateTimeTransformImpl> {}; template struct ConvertImpl diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.reference b/tests/queries/0_stateless/02403_date_time_narrowing.reference new file mode 100644 index 00000000000..9aaee671f42 --- /dev/null +++ b/tests/queries/0_stateless/02403_date_time_narrowing.reference @@ -0,0 +1,17 @@ +1970-01-01 2149-06-06 +1970-01-01 2149-06-06 +1970-01-01 00:00:00 2106-02-07 06:28:15 +1970-01-01 00:00:00 2106-02-07 06:28:15 +2106-02-07 06:28:15 +toStartOfDay +2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 1970-01-01 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 +toMonday +2149-06-02 1970-01-01 1970-01-01 2149-06-02 +toStartOfMonth +2149-06-01 1970-01-01 1970-01-01 2149-06-01 +toLastDayOfMonth +1970-01-24 1970-01-01 1970-01-01 1970-01-24 +toStartOfQuarter +2149-04-01 1970-01-01 1970-01-01 2149-04-01 +toStartOfYear +2149-01-01 1970-01-01 1970-01-01 2149-01-01 diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.sql b/tests/queries/0_stateless/02403_date_time_narrowing.sql new file mode 100644 index 00000000000..19b68188ead --- /dev/null +++ b/tests/queries/0_stateless/02403_date_time_narrowing.sql @@ -0,0 +1,51 @@ +SELECT toDate(toDate32('1930-01-01', 'UTC'), 'UTC'), + toDate(toDate32('2150-01-01', 'UTC'), 'UTC'); + +SELECT toDate(toDateTime64('1930-01-01 12:12:12.12', 3, 'UTC'), 'UTC'), + toDate(toDateTime64('2150-01-01 12:12:12.12', 3, 'UTC'), 'UTC'); + +SELECT toDateTime(toDateTime64('1930-01-01 12:12:12.12', 3, 'UTC'), 'UTC'), + toDateTime(toDateTime64('2150-01-01 12:12:12.12', 3, 'UTC'), 'UTC'); + +SELECT toDateTime(toDate32('1930-01-01', 'UTC'), 'UTC'), + toDateTime(toDate32('2150-01-01', 'UTC'), 'UTC'); + +SELECT toDateTime(toDate('2140-01-01', 'UTC'), 'UTC'); + +SELECT 'toStartOfDay'; +SELECT toStartOfDay(toDate('2141-01-01', 'UTC'), 'UTC'), + toStartOfDay(toDate('1941-01-01', 'UTC'), 'UTC'), + toStartOfDay(toDate32('2141-01-01', 'UTC'), 'UTC'), + toStartOfDay(toDate32('1941-01-01', 'UTC'), 'UTC'), + toStartOfDay(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), + toStartOfDay(toDateTime64('2141-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); + +SELECT 'toMonday'; +SELECT toMonday(toDate32('2151-01-01', 'UTC')), + toMonday(toDate32('1941-01-01', 'UTC')), + toMonday(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), + toMonday(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); + +SELECT 'toStartOfMonth'; +SELECT toStartOfMonth(toDate32('2151-01-01', 'UTC')), + toStartOfMonth(toDate32('1941-01-01', 'UTC')), + toStartOfMonth(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), + toStartOfMonth(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); + +SELECT 'toLastDayOfMonth'; +SELECT toLastDayOfMonth(toDate32('2151-01-01', 'UTC')), + toLastDayOfMonth(toDate32('1941-01-01', 'UTC')), + toLastDayOfMonth(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), + toLastDayOfMonth(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); + +SELECT 'toStartOfQuarter'; +SELECT toStartOfQuarter(toDate32('2151-01-01', 'UTC')), + toStartOfQuarter(toDate32('1941-01-01', 'UTC')), + toStartOfQuarter(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), + toStartOfQuarter(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); + +SELECT 'toStartOfYear'; +SELECT toStartOfYear(toDate32('2151-01-01', 'UTC')), + toStartOfYear(toDate32('1941-01-01', 'UTC')), + toStartOfYear(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), + toStartOfYear(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); \ No newline at end of file From eba4bd2a875ac45413d82b8a71b3d77bdb1db143 Mon Sep 17 00:00:00 2001 From: zvonand Date: Sun, 21 Aug 2022 18:59:09 +0300 Subject: [PATCH 03/24] update test and chinese docs --- docs/zh/sql-reference/data-types/date.md | 2 +- .../02403_date_time_narrowing.reference | 12 ++--- .../0_stateless/02403_date_time_narrowing.sql | 48 +++++++++---------- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/zh/sql-reference/data-types/date.md b/docs/zh/sql-reference/data-types/date.md index ab5d3acae1b..35d0299bb37 100644 --- a/docs/zh/sql-reference/data-types/date.md +++ b/docs/zh/sql-reference/data-types/date.md @@ -1,6 +1,6 @@ # 日期 {#date} -日期类型,用两个字节存储,表示从 1970-01-01 (无符号) 到当前的日期值。允许存储从 Unix 纪元开始到编译阶段定义的上限阈值常量(目前上限是2106年,但最终完全支持的年份为2105)。最小值输出为1970-01-01。 +日期类型,用两个字节存储,表示从 1970-01-01 (无符号) 到当前的日期值。允许存储从 Unix 纪元开始到编译阶段定义的上限阈值常量(目前上限是2149年,但最终完全支持的年份为2148)。最小值输出为1970-01-01。 值的范围: \[1970-01-01, 2149-06-06\]。 diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.reference b/tests/queries/0_stateless/02403_date_time_narrowing.reference index 9aaee671f42..5f1f37c11ae 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.reference +++ b/tests/queries/0_stateless/02403_date_time_narrowing.reference @@ -4,14 +4,14 @@ 1970-01-01 00:00:00 2106-02-07 06:28:15 2106-02-07 06:28:15 toStartOfDay -2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 1970-01-01 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 +1970-01-01 00:00:00 2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 toMonday -2149-06-02 1970-01-01 1970-01-01 2149-06-02 +1970-01-01 2149-06-02 1970-01-01 2149-06-02 toStartOfMonth -2149-06-01 1970-01-01 1970-01-01 2149-06-01 +1970-01-01 2149-06-01 1970-01-01 2149-06-01 toLastDayOfMonth -1970-01-24 1970-01-01 1970-01-01 1970-01-24 +1970-01-01 1970-01-24 1970-01-01 1970-01-24 toStartOfQuarter -2149-04-01 1970-01-01 1970-01-01 2149-04-01 +1970-01-01 2149-04-01 1970-01-01 2149-04-01 toStartOfYear -2149-01-01 1970-01-01 1970-01-01 2149-01-01 +1970-01-01 2149-01-01 1970-01-01 2149-01-01 diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.sql b/tests/queries/0_stateless/02403_date_time_narrowing.sql index 19b68188ead..ff7f0b1f020 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.sql +++ b/tests/queries/0_stateless/02403_date_time_narrowing.sql @@ -1,51 +1,51 @@ SELECT toDate(toDate32('1930-01-01', 'UTC'), 'UTC'), - toDate(toDate32('2150-01-01', 'UTC'), 'UTC'); + toDate(toDate32('2151-01-01', 'UTC'), 'UTC'); SELECT toDate(toDateTime64('1930-01-01 12:12:12.12', 3, 'UTC'), 'UTC'), - toDate(toDateTime64('2150-01-01 12:12:12.12', 3, 'UTC'), 'UTC'); + toDate(toDateTime64('2151-01-01 12:12:12.12', 3, 'UTC'), 'UTC'); SELECT toDateTime(toDateTime64('1930-01-01 12:12:12.12', 3, 'UTC'), 'UTC'), - toDateTime(toDateTime64('2150-01-01 12:12:12.12', 3, 'UTC'), 'UTC'); + toDateTime(toDateTime64('2151-01-01 12:12:12.12', 3, 'UTC'), 'UTC'); SELECT toDateTime(toDate32('1930-01-01', 'UTC'), 'UTC'), - toDateTime(toDate32('2150-01-01', 'UTC'), 'UTC'); + toDateTime(toDate32('2151-01-01', 'UTC'), 'UTC'); -SELECT toDateTime(toDate('2140-01-01', 'UTC'), 'UTC'); +SELECT toDateTime(toDate('2141-01-01', 'UTC'), 'UTC'); SELECT 'toStartOfDay'; -SELECT toStartOfDay(toDate('2141-01-01', 'UTC'), 'UTC'), - toStartOfDay(toDate('1941-01-01', 'UTC'), 'UTC'), +SELECT toStartOfDay(toDate('1930-01-01', 'UTC'), 'UTC'), + toStartOfDay(toDate('2141-01-01', 'UTC'), 'UTC'), + toStartOfDay(toDate32('1930-01-01', 'UTC'), 'UTC'), toStartOfDay(toDate32('2141-01-01', 'UTC'), 'UTC'), - toStartOfDay(toDate32('1941-01-01', 'UTC'), 'UTC'), - toStartOfDay(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), + toStartOfDay(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), toStartOfDay(toDateTime64('2141-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); SELECT 'toMonday'; -SELECT toMonday(toDate32('2151-01-01', 'UTC')), - toMonday(toDate32('1941-01-01', 'UTC')), - toMonday(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), +SELECT toMonday(toDate32('1930-01-01', 'UTC')), + toMonday(toDate32('2151-01-01', 'UTC')), + toMonday(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), toMonday(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); SELECT 'toStartOfMonth'; -SELECT toStartOfMonth(toDate32('2151-01-01', 'UTC')), - toStartOfMonth(toDate32('1941-01-01', 'UTC')), - toStartOfMonth(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), +SELECT toStartOfMonth(toDate32('1930-01-01', 'UTC')), + toStartOfMonth(toDate32('2151-01-01', 'UTC')), + toStartOfMonth(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), toStartOfMonth(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); SELECT 'toLastDayOfMonth'; -SELECT toLastDayOfMonth(toDate32('2151-01-01', 'UTC')), - toLastDayOfMonth(toDate32('1941-01-01', 'UTC')), - toLastDayOfMonth(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), +SELECT toLastDayOfMonth(toDate32('1930-01-01', 'UTC')), + toLastDayOfMonth(toDate32('2151-01-01', 'UTC')), + toLastDayOfMonth(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), toLastDayOfMonth(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); SELECT 'toStartOfQuarter'; -SELECT toStartOfQuarter(toDate32('2151-01-01', 'UTC')), - toStartOfQuarter(toDate32('1941-01-01', 'UTC')), - toStartOfQuarter(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), +SELECT toStartOfQuarter(toDate32('1930-01-01', 'UTC')), + toStartOfQuarter(toDate32('2151-01-01', 'UTC')), + toStartOfQuarter(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), toStartOfQuarter(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); SELECT 'toStartOfYear'; -SELECT toStartOfYear(toDate32('2151-01-01', 'UTC')), - toStartOfYear(toDate32('1941-01-01', 'UTC')), - toStartOfYear(toDateTime64('1941-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), +SELECT toStartOfYear(toDate32('1930-01-01', 'UTC')), + toStartOfYear(toDate32('2151-01-01', 'UTC')), + toStartOfYear(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), toStartOfYear(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); \ No newline at end of file From e5b4fb4191dbc665c7f64c9629d031bb4a5e3fc7 Mon Sep 17 00:00:00 2001 From: zvonand Date: Mon, 22 Aug 2022 00:02:27 +0300 Subject: [PATCH 04/24] fix some issues --- src/Functions/DateTimeTransforms.h | 91 +++++++----------------------- 1 file changed, 21 insertions(+), 70 deletions(-) diff --git a/src/Functions/DateTimeTransforms.h b/src/Functions/DateTimeTransforms.h index 30c262e988b..c7b8d178802 100644 --- a/src/Functions/DateTimeTransforms.h +++ b/src/Functions/DateTimeTransforms.h @@ -61,11 +61,7 @@ struct ToDateImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - if (t < 0) - return 0; - - auto day_num = time_zone.toDayNum(t); - return day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM; + return t < 0 ? 0 : std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -73,10 +69,7 @@ struct ToDateImpl } static inline UInt16 execute(Int32 t, const DateLUTImpl &) { - if (t < 0) - return 0; - - return t < DATE_LUT_MAX_DAY_NUM ? t : DATE_LUT_MAX_DAY_NUM; + return t < 0 ? 0 : std::min(time_t(t), time_t(DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl &) { @@ -118,7 +111,7 @@ struct ToStartOfDayImpl //TODO: right now it is hardcoded to produce DateTime only, needs fixing later. See date_and_time_type_details::ResultDataTypeMap for deduction of result type example. static inline UInt32 execute(const DecimalUtils::DecimalComponents & t, const DateLUTImpl & time_zone) { - if (t.whole < 0) + if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0)) return 0; Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(t.whole)); @@ -145,10 +138,7 @@ struct ToStartOfDayImpl static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone) { Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(d)); - if (date_time <= 0xffffffff) - return date_time; - else - return time_zone.toDate(0xffffffff); + return date_time < 0xffffffff ? date_time : time_zone.toDate(0xffffffff); } using FactorTransform = ZeroTransform; @@ -160,12 +150,8 @@ struct ToMondayImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - if (t < 0) - return 0; - - auto day_num = time_zone.toDayNum(t); - - return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM)); + return t < 0 ? 0 : time_zone.toFirstDayNumOfWeek(ExtendedDayNum( + std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -173,11 +159,7 @@ struct ToMondayImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - if (d < 0) - return 0; - - return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)) - ; + return d < 0 ? 0 : time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM))); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -193,12 +175,7 @@ struct ToStartOfMonthImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - if (t < 0) - return 0; - - auto day_num = time_zone.toDayNum(t); - - return time_zone.toFirstDayNumOfMonth(ExtendedDayNum(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM)); + return t < 0 ? 0 : time_zone.toFirstDayNumOfMonth(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -206,10 +183,7 @@ struct ToStartOfMonthImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - if (d < 0) - return 0; - - return time_zone.toFirstDayNumOfMonth(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)); + return d < 0 ? 0 : time_zone.toFirstDayNumOfMonth(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM))); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -225,11 +199,7 @@ struct ToLastDayOfMonthImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - if (t < 0) - return 0; - - auto day_num = time_zone.toDayNum(t); - return time_zone.toLastDayNumOfMonth(ExtendedDayNum(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM)); + return t < 0 ? 0 : time_zone.toLastDayNumOfMonth(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -237,10 +207,7 @@ struct ToLastDayOfMonthImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - if (d < 0) - return 0; - - return time_zone.toLastDayNumOfMonth(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)); + return d < 0 ? 0 : time_zone.toLastDayNumOfMonth(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM))); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -256,12 +223,7 @@ struct ToStartOfQuarterImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - if (t < 0) - return 0; - - auto day_num = time_zone.toDayNum(t); - - return time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM)); + return t < 0 ? 0 : time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -269,10 +231,7 @@ struct ToStartOfQuarterImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - if (d < 0) - return 0; - - return time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)); + return d < 0 ? 0 : time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM))); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -288,12 +247,7 @@ struct ToStartOfYearImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - if (t < 0) - return 0; - - auto day_num = time_zone.toDayNum(t); - - return time_zone.toFirstDayNumOfYear(ExtendedDayNum(day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM)); + return t < 0 ? 0 : time_zone.toFirstDayNumOfYear(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -301,10 +255,7 @@ struct ToStartOfYearImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - if (d < 0) - return 0; - - return time_zone.toFirstDayNumOfYear(ExtendedDayNum(d < DATE_LUT_MAX_DAY_NUM ? d : DATE_LUT_MAX_DAY_NUM)); + return d < 0 ? 0 : time_zone.toFirstDayNumOfYear(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM))); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -346,13 +297,10 @@ struct ToStartOfMinuteImpl static inline UInt32 execute(const DecimalUtils::DecimalComponents & t, const DateLUTImpl & time_zone) { - if (t.whole < 0) + if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0)) return 0; - auto day_num = time_zone.toDayNum(t.whole); - - return time_zone.toStartOfMinute(day_num < DATE_LUT_MAX_DAY_NUM ? t.whole : INT16_MAX); -// return time_zone.toStartOfMinute(t.whole); + return time_zone.toStartOfMinute(std::min(t.whole, time_t(0xffffffff))); } static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -643,7 +591,10 @@ struct ToStartOfHourImpl static inline UInt32 execute(const DecimalUtils::DecimalComponents & t, const DateLUTImpl & time_zone) { - return time_zone.toStartOfHour(t.whole); + if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0)) + return 0; + + return time_zone.toStartOfHour(std::min(t.whole, time_t(0xffffffff))); } static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone) From 963d838647b87383feec43ea9054e3bd335d9338 Mon Sep 17 00:00:00 2001 From: zvonand Date: Mon, 22 Aug 2022 13:59:03 +0300 Subject: [PATCH 05/24] updated docs --- .../functions/date-time-functions.md | 16 +++++++++++----- .../functions/date-time-functions.md | 18 +++++++++++++++--- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/docs/en/sql-reference/functions/date-time-functions.md b/docs/en/sql-reference/functions/date-time-functions.md index d54028582c5..47134d0cb3e 100644 --- a/docs/en/sql-reference/functions/date-time-functions.md +++ b/docs/en/sql-reference/functions/date-time-functions.md @@ -266,8 +266,13 @@ Result: └────────────────┘ ``` -:::note -The return type `toStartOf*` functions described below is `Date` or `DateTime`. Though these functions can take `DateTime64` as an argument, passing them a `DateTime64` that is out of the normal range (years 1900 - 2299) will give an incorrect result. +:::Attention +The return type of `toStartOf*`, `toLastDayOfMonth`, `toMonday` functions described below is `Date` or `DateTime`. +Though these functions can take `Date32` and `DateTime64` values as an argument, passing them a time point that is out of the normal range (years 1970 - 2148) will give wrong result. +In case argument is out of normal range: + * `1970-01-01 (00:00:00)` will be returned for values prior to 1970, + * `2106-02-07 08:28:15` will be taken as argument when actual argument is above this timestamp and return type is `DateTime`, + * `2149-06-06` will be taken as argument when actual argument is above this timestamp and return type is `Date`. ::: ## toStartOfYear @@ -291,9 +296,10 @@ Returns the date. Rounds down a date or date with time to the first day of the month. Returns the date. -:::note -The behavior of parsing incorrect dates is implementation specific. ClickHouse may return zero date, throw an exception or do “natural” overflow. -::: +## toLastDayOfMonth + +Rounds up a date or date with time to the last day of the month. +Returns the date. ## toMonday diff --git a/docs/ru/sql-reference/functions/date-time-functions.md b/docs/ru/sql-reference/functions/date-time-functions.md index 9c873b0fcfc..311f5138f69 100644 --- a/docs/ru/sql-reference/functions/date-time-functions.md +++ b/docs/ru/sql-reference/functions/date-time-functions.md @@ -269,6 +269,16 @@ SELECT toUnixTimestamp('2017-11-05 08:07:47', 'Asia/Tokyo') AS unix_timestamp; :::note "Attention" `Date` или `DateTime` это возвращаемый тип функций `toStartOf*`, который описан ниже. Несмотря на то, что эти функции могут принимать `DateTime64` в качестве аргумента, если переданное значение типа `DateTime64` выходит за пределы нормального диапазона (с 1900 по 2299 год), то это даст неверный результат. ::: + +:::Attention +Тип возвращаемого описанными далее функциями `toStartOf*`, `toLastDayOfMonth`, `toMonday` значения - `Date` или `DateTime`. +Хотя эти функции могут принимать значения типа `Date32` или `DateTime64` в качестве аргумента, при обработке аргумента вне нормального диапазона значений (`1970` - `2148` для `Date` и `1970-01-01 00:00:00`-`2106-02-07 08:28:15` для `DateTime`) будет получен некорректный результат. +Возвращаемые значения для значений вне нормального диапазона: +* `1970-01-01 (00:00:00)` будет возвращён для моментов времени до 1970 года, +* `2106-02-07 08:28:15` будет взят в качестве аргумента, если полученный аргумент превосходит данное значение и возвращаемый тип - `DateTime`, +* `2149-06-06` будет взят в качестве аргумента, если полученный аргумент превосходит данное значение и возвращаемый тип - `Date`. + ::: +* ## toStartOfYear {#tostartofyear} Округляет дату или дату-с-временем вниз до первого дня года. @@ -302,9 +312,11 @@ SELECT toStartOfISOYear(toDate('2017-01-01')) AS ISOYear20170101; Округляет дату или дату-с-временем вниз до первого дня месяца. Возвращается дата. - :::note "Attention" - Возвращаемое значение для некорректных дат зависит от реализации. ClickHouse может вернуть нулевую дату, выбросить исключение, или выполнить «естественное» перетекание дат между месяцами. - ::: +## toLastDayOfMonth + +Округляет дату или дату-с-временем до последнего числа месяца. +Возвращается дата. + ## toMonday {#tomonday} Округляет дату или дату-с-временем вниз до ближайшего понедельника. From d789dabc9d94d4010c8fd04d9d3477d7f3cd2dca Mon Sep 17 00:00:00 2001 From: zvonand Date: Mon, 22 Aug 2022 17:36:10 +0300 Subject: [PATCH 06/24] Fixed , updated docs --- .../functions/date-time-functions.md | 3 ++- .../functions/date-time-functions.md | 5 +++-- src/Functions/DateTimeTransforms.h | 21 ++++++++++++------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/docs/en/sql-reference/functions/date-time-functions.md b/docs/en/sql-reference/functions/date-time-functions.md index 47134d0cb3e..3a474f27a11 100644 --- a/docs/en/sql-reference/functions/date-time-functions.md +++ b/docs/en/sql-reference/functions/date-time-functions.md @@ -272,7 +272,8 @@ Though these functions can take `Date32` and `DateTime64` values as an argument, In case argument is out of normal range: * `1970-01-01 (00:00:00)` will be returned for values prior to 1970, * `2106-02-07 08:28:15` will be taken as argument when actual argument is above this timestamp and return type is `DateTime`, - * `2149-06-06` will be taken as argument when actual argument is above this timestamp and return type is `Date`. + * `2149-06-06` will be taken as argument when actual argument is above this timestamp and return type is `Date`, + * `2149-05-31` will be the result of execution of `toLastDayOfMonth` when argument is greater then `2149-05-31`. ::: ## toStartOfYear diff --git a/docs/ru/sql-reference/functions/date-time-functions.md b/docs/ru/sql-reference/functions/date-time-functions.md index 311f5138f69..6a17efce35e 100644 --- a/docs/ru/sql-reference/functions/date-time-functions.md +++ b/docs/ru/sql-reference/functions/date-time-functions.md @@ -271,12 +271,13 @@ SELECT toUnixTimestamp('2017-11-05 08:07:47', 'Asia/Tokyo') AS unix_timestamp; ::: :::Attention -Тип возвращаемого описанными далее функциями `toStartOf*`, `toLastDayOfMonth`, `toMonday` значения - `Date` или `DateTime`. +Тип возвращаемого описанными далее функциями `toStartOf*`, `toMonday` значения - `Date` или `DateTime`. Хотя эти функции могут принимать значения типа `Date32` или `DateTime64` в качестве аргумента, при обработке аргумента вне нормального диапазона значений (`1970` - `2148` для `Date` и `1970-01-01 00:00:00`-`2106-02-07 08:28:15` для `DateTime`) будет получен некорректный результат. Возвращаемые значения для значений вне нормального диапазона: * `1970-01-01 (00:00:00)` будет возвращён для моментов времени до 1970 года, * `2106-02-07 08:28:15` будет взят в качестве аргумента, если полученный аргумент превосходит данное значение и возвращаемый тип - `DateTime`, -* `2149-06-06` будет взят в качестве аргумента, если полученный аргумент превосходит данное значение и возвращаемый тип - `Date`. +* `2149-06-06` будет взят в качестве аргумента, если полученный аргумент превосходит данное значение и возвращаемый тип - `Date`, +* `2149-05-31` будет результатом функции `toLastDayOfMonth` при обработке аргумента больше `2149-05-31`. ::: * ## toStartOfYear {#tostartofyear} diff --git a/src/Functions/DateTimeTransforms.h b/src/Functions/DateTimeTransforms.h index c7b8d178802..3b31eafd774 100644 --- a/src/Functions/DateTimeTransforms.h +++ b/src/Functions/DateTimeTransforms.h @@ -114,11 +114,7 @@ struct ToStartOfDayImpl if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0)) return 0; - Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(t.whole)); - if (date_time <= 0xffffffff) - return date_time; - else - return time_zone.toDate(0xffffffff); + return time_zone.toDate(std::min(t.whole, time_t(0xffffffff))); } static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -199,7 +195,11 @@ struct ToLastDayOfMonthImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - return t < 0 ? 0 : time_zone.toLastDayNumOfMonth(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)))); + if (t < 0) + return 0; + + /// 0xFFF9 is Int value for 2149-05-31 -- the last day where we can actually find LastDayOfMonth. This will also be the return value. + return time_zone.toLastDayNumOfMonth(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(0xFFF9)))); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -207,11 +207,16 @@ struct ToLastDayOfMonthImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - return d < 0 ? 0 : time_zone.toLastDayNumOfMonth(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM))); + if (d < 0) + return 0; + + /// 0xFFF9 is Int value for 2149-05-31 -- the last day where we can actually find LastDayOfMonth. This will also be the return value. + return time_zone.toLastDayNumOfMonth(ExtendedDayNum(std::min(d, 0xFFF9))); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { - return time_zone.toLastDayNumOfMonth(DayNum(d)); + /// 0xFFF9 is Int value for 2149-05-31 -- the last day where we can actually find LastDayOfMonth. This will also be the return value. + return time_zone.toLastDayNumOfMonth(DayNum(std::min(d, UInt16(0xFFF9)))); } using FactorTransform = ZeroTransform; From 1df3d607c28b9c48e76bd37e0084c6cb6d472cf3 Mon Sep 17 00:00:00 2001 From: zvonand Date: Mon, 22 Aug 2022 21:45:34 +0300 Subject: [PATCH 07/24] fix tests --- tests/queries/0_stateless/02403_date_time_narrowing.reference | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.reference b/tests/queries/0_stateless/02403_date_time_narrowing.reference index 5f1f37c11ae..d9672fd629a 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.reference +++ b/tests/queries/0_stateless/02403_date_time_narrowing.reference @@ -10,7 +10,7 @@ toMonday toStartOfMonth 1970-01-01 2149-06-01 1970-01-01 2149-06-01 toLastDayOfMonth -1970-01-01 1970-01-24 1970-01-01 1970-01-24 +1970-01-01 2149-05-31 1970-01-01 2149-05-31 toStartOfQuarter 1970-01-01 2149-04-01 1970-01-01 2149-04-01 toStartOfYear From 6abe09a725aa6597a6ec4501f51ed5547c9632ed Mon Sep 17 00:00:00 2001 From: zvonand Date: Tue, 23 Aug 2022 17:13:39 +0300 Subject: [PATCH 08/24] updated tests + teStartOfWeek --- src/Functions/CustomWeekTransforms.h | 22 ++++++++++-- src/Functions/FunctionCustomWeekToSomething.h | 36 ++++++++----------- src/Functions/FunctionsConversion.h | 2 +- .../02403_date_time_narrowing.reference | 9 +++-- .../0_stateless/02403_date_time_narrowing.sql | 36 ++++++++++++++++--- 5 files changed, 73 insertions(+), 32 deletions(-) diff --git a/src/Functions/CustomWeekTransforms.h b/src/Functions/CustomWeekTransforms.h index c296c8228b1..617beea72bf 100644 --- a/src/Functions/CustomWeekTransforms.h +++ b/src/Functions/CustomWeekTransforms.h @@ -62,7 +62,15 @@ struct ToStartOfWeekImpl static inline UInt16 execute(Int64 t, UInt8 week_mode, const DateLUTImpl & time_zone) { - return time_zone.toFirstDayNumOfWeek(time_zone.toDayNum(t), week_mode); + if (t < 0) + return 0; + + auto res = time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM))), week_mode); + + if (res < 0) + return 0; + else + return res; } static inline UInt16 execute(UInt32 t, UInt8 week_mode, const DateLUTImpl & time_zone) { @@ -70,11 +78,19 @@ struct ToStartOfWeekImpl } static inline UInt16 execute(Int32 d, UInt8 week_mode, const DateLUTImpl & time_zone) { - return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(d), week_mode); + if (d < 0) + return 0; + + return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM)), week_mode); } static inline UInt16 execute(UInt16 d, UInt8 week_mode, const DateLUTImpl & time_zone) { - return time_zone.toFirstDayNumOfWeek(DayNum(d), week_mode); + auto res = time_zone.toFirstDayNumOfWeek(DayNum(d), week_mode); + + if (res > d) + return 0; + else + return res; } using FactorTransform = ZeroTransform; diff --git a/src/Functions/FunctionCustomWeekToSomething.h b/src/Functions/FunctionCustomWeekToSomething.h index 6ed751fd889..8a0f474a7e8 100644 --- a/src/Functions/FunctionCustomWeekToSomething.h +++ b/src/Functions/FunctionCustomWeekToSomething.h @@ -41,23 +41,20 @@ public: if (!isDate(arguments[0].type) && !isDate32(arguments[0].type) && !isDateTime(arguments[0].type) && !isDateTime64(arguments[0].type)) throw Exception( "Illegal type " + arguments[0].type->getName() + " of argument of function " + getName() - + ". Should be a date or a date with time", + + ". Must be Date, Date32, DateTime or DateTime64.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); } else if (arguments.size() == 2) { if (!isDate(arguments[0].type) && !isDate32(arguments[0].type) && !isDateTime(arguments[0].type) && !isDateTime64(arguments[0].type)) throw Exception( - "Illegal type " + arguments[0].type->getName() + " of argument of function " + getName() - + ". Should be a date or a date with time", + "Illegal type " + arguments[0].type->getName() + " of 1st argument of function " + getName() + + ". Must be Date, Date32, DateTime or DateTime64.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); if (!isUInt8(arguments[1].type)) throw Exception( - "Function " + getName() - + " supports 1 or 2 or 3 arguments. The 1st argument " - "must be of type Date or DateTime. The 2nd argument (optional) must be " - "a constant UInt8 with week mode. The 3rd argument (optional) must be " - "a constant string with timezone name", + "Illegal type of 2nd (optional) argument of function " + getName() + + ". Must be constant UInt8 (week mode).", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); } else if (arguments.size() == 3) @@ -65,33 +62,28 @@ public: if (!isDate(arguments[0].type) && !isDate32(arguments[0].type) && !isDateTime(arguments[0].type) && !isDateTime64(arguments[0].type)) throw Exception( "Illegal type " + arguments[0].type->getName() + " of argument of function " + getName() - + ". Should be a date or a date with time", + + ". Must be Date, Date32, DateTime or DateTime64", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); if (!isUInt8(arguments[1].type)) throw Exception( - "Function " + getName() - + " supports 1 or 2 or 3 arguments. The 1st argument " - "must be of type Date or DateTime. The 2nd argument (optional) must be " - "a constant UInt8 with week mode. The 3rd argument (optional) must be " - "a constant string with timezone name", + "Illegal type of 2nd (optional) argument of function " + getName() + + ". Must be constant UInt8 (week mode).", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); if (!isString(arguments[2].type)) throw Exception( - "Function " + getName() - + " supports 1 or 2 or 3 arguments. The 1st argument " - "must be of type Date or DateTime. The 2nd argument (optional) must be " - "a constant UInt8 with week mode. The 3rd argument (optional) must be " - "a constant string with timezone name", + "Illegal type of 3rd (optional) argument of function " + getName() + + ". Must be constant string (timezone name).", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - if (isDate(arguments[0].type) && std::is_same_v) + if ((isDate(arguments[0].type) || isDate32(arguments[0].type)) + && (std::is_same_v || std::is_same_v)) throw Exception( - "The timezone argument of function " + getName() + " is allowed only when the 1st argument has the type DateTime", + "The timezone argument of function " + getName() + " is allowed only when the 1st argument is DateTime or DateTime64.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); } else throw Exception( "Number of arguments for function " + getName() + " doesn't match: passed " + toString(arguments.size()) - + ", should be 1 or 2 or 3", + + ", expected 1, 2 or 3.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); return std::make_shared(); diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index 9062f3a5846..94b81a51711 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -388,7 +388,7 @@ struct ToDateTransform32Or64Signed if (from < 0) return 0; - auto day_num = time_zone.toDayNum(from); + auto day_num = time_zone.toDayNum(ExtendedDayNum(from)); return day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM; } }; diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.reference b/tests/queries/0_stateless/02403_date_time_narrowing.reference index d9672fd629a..af762d70d7a 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.reference +++ b/tests/queries/0_stateless/02403_date_time_narrowing.reference @@ -1,3 +1,4 @@ +1970-01-01 2149-06-06 1970-01-01 2149-06-06 1900-01-01 1970-01-02 1970-01-01 2149-06-06 1970-01-01 2149-06-06 1970-01-01 00:00:00 2106-02-07 06:28:15 @@ -5,12 +6,16 @@ 2106-02-07 06:28:15 toStartOfDay 1970-01-01 00:00:00 2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 +toStartOfWeek +1970-01-01 2149-06-03 1970-01-01 1970-01-01 1970-01-01 2149-06-01 1970-01-01 2149-06-01 toMonday -1970-01-01 2149-06-02 1970-01-01 2149-06-02 +1970-01-01 1970-01-01 2149-06-02 1970-01-01 2149-06-02 +toStartOfMonth +1970-01-01 2149-06-01 1970-01-01 2149-06-01 toStartOfMonth 1970-01-01 2149-06-01 1970-01-01 2149-06-01 toLastDayOfMonth -1970-01-01 2149-05-31 1970-01-01 2149-05-31 +2149-05-31 1970-01-01 2149-05-31 1970-01-01 2149-05-31 toStartOfQuarter 1970-01-01 2149-04-01 1970-01-01 2149-04-01 toStartOfYear diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.sql b/tests/queries/0_stateless/02403_date_time_narrowing.sql index ff7f0b1f020..7fd47a664fe 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.sql +++ b/tests/queries/0_stateless/02403_date_time_narrowing.sql @@ -1,5 +1,14 @@ -SELECT toDate(toDate32('1930-01-01', 'UTC'), 'UTC'), - toDate(toDate32('2151-01-01', 'UTC'), 'UTC'); +-- check conversion of overflown numbers to date/time -- +SELECT toDate(toInt32(toDate32('1930-01-01'))), + toDate(toInt32(toDate32('2151-01-01'))), + toDate(toInt64(toDateTime64('1930-01-01 12:12:12.123', 3))), + toDate(toInt64(toDateTime64('2151-01-01 12:12:12.123', 3))), + toDate32(toInt32(toDate32('1900-01-01')) - 1), + toDate32(toInt32(toDate32('2299-12-31')) + 1); + +-- check conversion of extended range type to normal range type -- +SELECT toDate(toDate32('1930-01-01')), + toDate(toDate32('2151-01-01')); SELECT toDate(toDateTime64('1930-01-01 12:12:12.12', 3, 'UTC'), 'UTC'), toDate(toDateTime64('2151-01-01 12:12:12.12', 3, 'UTC'), 'UTC'); @@ -12,6 +21,7 @@ SELECT toDateTime(toDate32('1930-01-01', 'UTC'), 'UTC'), SELECT toDateTime(toDate('2141-01-01', 'UTC'), 'UTC'); +-- test DateTimeTransforms -- SELECT 'toStartOfDay'; SELECT toStartOfDay(toDate('1930-01-01', 'UTC'), 'UTC'), toStartOfDay(toDate('2141-01-01', 'UTC'), 'UTC'), @@ -20,8 +30,19 @@ SELECT toStartOfDay(toDate('1930-01-01', 'UTC'), 'UTC'), toStartOfDay(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), toStartOfDay(toDateTime64('2141-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); +SELECT 'toStartOfWeek'; +SELECT toStartOfWeek(toDate('1970-01-01')), + toStartOfWeek(toDate32('1970-01-01')), + toStartOfWeek(toDateTime('1970-01-01 10:10:10')), + toStartOfWeek(toDateTime64('1970-01-01 10:10:10.123', 3)), + toStartOfWeek(toDate32('1930-01-01')), + toStartOfWeek(toDate32('2151-01-01')), + toStartOfWeek(toDateTime64('1930-01-01 12:12:12.123', 3)), + toStartOfWeek(toDateTime64('2151-01-01 12:12:12.123', 3)); + SELECT 'toMonday'; -SELECT toMonday(toDate32('1930-01-01', 'UTC')), +SELECT toMonday(toDate('1970-01-02')), + toMonday(toDate32('1930-01-01', 'UTC')), toMonday(toDate32('2151-01-01', 'UTC')), toMonday(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), toMonday(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); @@ -32,8 +53,15 @@ SELECT toStartOfMonth(toDate32('1930-01-01', 'UTC')), toStartOfMonth(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), toStartOfMonth(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); +SELECT 'toStartOfMonth'; +SELECT toStartOfMonth(toDate32('1930-01-01', 'UTC')), + toStartOfMonth(toDate32('2151-01-01', 'UTC')), + toStartOfMonth(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), + toStartOfMonth(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); + SELECT 'toLastDayOfMonth'; -SELECT toLastDayOfMonth(toDate32('1930-01-01', 'UTC')), +SELECT toLastDayOfMonth(toDate('2149-06-03')), + toLastDayOfMonth(toDate32('1930-01-01', 'UTC')), toLastDayOfMonth(toDate32('2151-01-01', 'UTC')), toLastDayOfMonth(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), toLastDayOfMonth(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); From 6dd9f7fd23822ad5866de0ce5c723e2667d0aa63 Mon Sep 17 00:00:00 2001 From: zvonand Date: Tue, 23 Aug 2022 17:15:20 +0300 Subject: [PATCH 09/24] fix identation --- tests/queries/0_stateless/02403_date_time_narrowing.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.sql b/tests/queries/0_stateless/02403_date_time_narrowing.sql index 7fd47a664fe..511c222bda0 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.sql +++ b/tests/queries/0_stateless/02403_date_time_narrowing.sql @@ -76,4 +76,4 @@ SELECT 'toStartOfYear'; SELECT toStartOfYear(toDate32('1930-01-01', 'UTC')), toStartOfYear(toDate32('2151-01-01', 'UTC')), toStartOfYear(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), - toStartOfYear(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); \ No newline at end of file + toStartOfYear(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); From 42f86442abb116a8bb7aee41b22502dc1b6a8604 Mon Sep 17 00:00:00 2001 From: zvonand Date: Tue, 23 Aug 2022 18:32:55 +0300 Subject: [PATCH 10/24] updated tests + toStartOfWeek --- src/Functions/CustomWeekTransforms.h | 7 ++++++- src/Functions/FunctionsConversion.h | 5 +++-- .../0_stateless/02403_date_time_narrowing.reference | 6 +++--- tests/queries/0_stateless/02403_date_time_narrowing.sql | 5 ++--- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Functions/CustomWeekTransforms.h b/src/Functions/CustomWeekTransforms.h index 617beea72bf..2e783eb953d 100644 --- a/src/Functions/CustomWeekTransforms.h +++ b/src/Functions/CustomWeekTransforms.h @@ -81,7 +81,12 @@ struct ToStartOfWeekImpl if (d < 0) return 0; - return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM)), week_mode); + auto res = time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM)), week_mode); + + if (res < 0) + return 0; + else + return res; } static inline UInt16 execute(UInt16 d, UInt8 week_mode, const DateLUTImpl & time_zone) { diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index 94b81a51711..63e4633ccb5 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -434,9 +434,10 @@ struct ToDate32Transform32Or64Signed static const Int32 daynum_min_offset = -static_cast(DateLUT::instance().getDayNumOffsetEpoch()); if (from < daynum_min_offset) return daynum_min_offset; - return (from < DATE_LUT_MAX_EXTEND_DAY_NUM) + + return (time_zone.toDayNum(from) < DATE_LUT_MAX_EXTEND_DAY_NUM) ? from - : time_zone.toDayNum(std::min(time_t(from), time_t(0xFFFFFFFF))); + : time_zone.toDayNum(std::min(time_t(from), time_t(DATE_LUT_MAX_EXTEND_DAY_NUM))); } }; diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.reference b/tests/queries/0_stateless/02403_date_time_narrowing.reference index af762d70d7a..cbdac452cfa 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.reference +++ b/tests/queries/0_stateless/02403_date_time_narrowing.reference @@ -1,13 +1,13 @@ -1970-01-01 2149-06-06 1970-01-01 2149-06-06 1900-01-01 1970-01-02 +1970-01-01 2149-06-06 1970-01-01 2149-06-06 1900-01-01 2299-12-31 1970-01-01 2149-06-06 1970-01-01 2149-06-06 1970-01-01 00:00:00 2106-02-07 06:28:15 1970-01-01 00:00:00 2106-02-07 06:28:15 2106-02-07 06:28:15 toStartOfDay -1970-01-01 00:00:00 2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 +2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 toStartOfWeek -1970-01-01 2149-06-03 1970-01-01 1970-01-01 1970-01-01 2149-06-01 1970-01-01 2149-06-01 +1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 2149-06-01 1970-01-01 2149-06-01 toMonday 1970-01-01 1970-01-01 2149-06-02 1970-01-01 2149-06-02 toStartOfMonth diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.sql b/tests/queries/0_stateless/02403_date_time_narrowing.sql index 511c222bda0..d32bac1a47b 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.sql +++ b/tests/queries/0_stateless/02403_date_time_narrowing.sql @@ -1,4 +1,4 @@ --- check conversion of overflown numbers to date/time -- +-- check conversion of numbers to date/time -- SELECT toDate(toInt32(toDate32('1930-01-01'))), toDate(toInt32(toDate32('2151-01-01'))), toDate(toInt64(toDateTime64('1930-01-01 12:12:12.123', 3))), @@ -23,8 +23,7 @@ SELECT toDateTime(toDate('2141-01-01', 'UTC'), 'UTC'); -- test DateTimeTransforms -- SELECT 'toStartOfDay'; -SELECT toStartOfDay(toDate('1930-01-01', 'UTC'), 'UTC'), - toStartOfDay(toDate('2141-01-01', 'UTC'), 'UTC'), +SELECT toStartOfDay(toDate('2141-01-01', 'UTC'), 'UTC'), toStartOfDay(toDate32('1930-01-01', 'UTC'), 'UTC'), toStartOfDay(toDate32('2141-01-01', 'UTC'), 'UTC'), toStartOfDay(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), From e4f00e2f150d0cdb39594e995bc63dafa697b9c8 Mon Sep 17 00:00:00 2001 From: Andrey Zvonov <32552679+zvonand@users.noreply.github.com> Date: Tue, 23 Aug 2022 23:40:34 +0300 Subject: [PATCH 11/24] Update docs 1 Co-authored-by: Robert Schulze --- docs/en/sql-reference/functions/date-time-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/sql-reference/functions/date-time-functions.md b/docs/en/sql-reference/functions/date-time-functions.md index 3a474f27a11..2795ca0b9e4 100644 --- a/docs/en/sql-reference/functions/date-time-functions.md +++ b/docs/en/sql-reference/functions/date-time-functions.md @@ -272,7 +272,7 @@ Though these functions can take `Date32` and `DateTime64` values as an argument, In case argument is out of normal range: * `1970-01-01 (00:00:00)` will be returned for values prior to 1970, * `2106-02-07 08:28:15` will be taken as argument when actual argument is above this timestamp and return type is `DateTime`, - * `2149-06-06` will be taken as argument when actual argument is above this timestamp and return type is `Date`, + * If the return type is `Date` and the argument is larger than `2149-06-06`, the result will be calculated from the argument `2149-06-06` instead. * `2149-05-31` will be the result of execution of `toLastDayOfMonth` when argument is greater then `2149-05-31`. ::: From 946223df20772f92dbcfedfd812d74264768b6e3 Mon Sep 17 00:00:00 2001 From: Andrey Zvonov <32552679+zvonand@users.noreply.github.com> Date: Tue, 23 Aug 2022 23:41:01 +0300 Subject: [PATCH 12/24] Update docs/en/sql-reference/functions/date-time-functions.md Co-authored-by: Robert Schulze --- docs/en/sql-reference/functions/date-time-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/sql-reference/functions/date-time-functions.md b/docs/en/sql-reference/functions/date-time-functions.md index 2795ca0b9e4..d1e75fbf1b0 100644 --- a/docs/en/sql-reference/functions/date-time-functions.md +++ b/docs/en/sql-reference/functions/date-time-functions.md @@ -268,7 +268,7 @@ Result: :::Attention The return type of `toStartOf*`, `toLastDayOfMonth`, `toMonday` functions described below is `Date` or `DateTime`. -Though these functions can take `Date32` and `DateTime64` values as an argument, passing them a time point that is out of the normal range (years 1970 - 2148) will give wrong result. +Though these functions can take values of the extended types `Date32` and `DateTime64` as an argument, passing them a time outside the normal range (year 1970 to 2149 for `Date` / 2106 for `DateTime`) will produce wrong results. In case argument is out of normal range: * `1970-01-01 (00:00:00)` will be returned for values prior to 1970, * `2106-02-07 08:28:15` will be taken as argument when actual argument is above this timestamp and return type is `DateTime`, From 6c1fa6844fcef8f0ff786f09e79d2e61a6eb61fa Mon Sep 17 00:00:00 2001 From: Andrey Zvonov <32552679+zvonand@users.noreply.github.com> Date: Tue, 23 Aug 2022 23:41:19 +0300 Subject: [PATCH 13/24] Update docs/en/sql-reference/functions/date-time-functions.md Co-authored-by: Robert Schulze --- docs/en/sql-reference/functions/date-time-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/sql-reference/functions/date-time-functions.md b/docs/en/sql-reference/functions/date-time-functions.md index d1e75fbf1b0..e5b6443596f 100644 --- a/docs/en/sql-reference/functions/date-time-functions.md +++ b/docs/en/sql-reference/functions/date-time-functions.md @@ -270,7 +270,7 @@ Result: The return type of `toStartOf*`, `toLastDayOfMonth`, `toMonday` functions described below is `Date` or `DateTime`. Though these functions can take values of the extended types `Date32` and `DateTime64` as an argument, passing them a time outside the normal range (year 1970 to 2149 for `Date` / 2106 for `DateTime`) will produce wrong results. In case argument is out of normal range: - * `1970-01-01 (00:00:00)` will be returned for values prior to 1970, + * If the argument is smaller than 1970, the result will be calculated from the argument `1970-01-01 (00:00:00)` instead. * `2106-02-07 08:28:15` will be taken as argument when actual argument is above this timestamp and return type is `DateTime`, * If the return type is `Date` and the argument is larger than `2149-06-06`, the result will be calculated from the argument `2149-06-06` instead. * `2149-05-31` will be the result of execution of `toLastDayOfMonth` when argument is greater then `2149-05-31`. From b54a04d48fa8a8cfebd3d937c562566b78703ca8 Mon Sep 17 00:00:00 2001 From: Andrey Zvonov <32552679+zvonand@users.noreply.github.com> Date: Tue, 23 Aug 2022 23:42:01 +0300 Subject: [PATCH 14/24] Update docs/en/sql-reference/functions/date-time-functions.md Co-authored-by: Robert Schulze --- docs/en/sql-reference/functions/date-time-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/sql-reference/functions/date-time-functions.md b/docs/en/sql-reference/functions/date-time-functions.md index e5b6443596f..70dacd40ad1 100644 --- a/docs/en/sql-reference/functions/date-time-functions.md +++ b/docs/en/sql-reference/functions/date-time-functions.md @@ -271,7 +271,7 @@ The return type of `toStartOf*`, `toLastDayOfMonth`, `toMonday` functions descri Though these functions can take values of the extended types `Date32` and `DateTime64` as an argument, passing them a time outside the normal range (year 1970 to 2149 for `Date` / 2106 for `DateTime`) will produce wrong results. In case argument is out of normal range: * If the argument is smaller than 1970, the result will be calculated from the argument `1970-01-01 (00:00:00)` instead. - * `2106-02-07 08:28:15` will be taken as argument when actual argument is above this timestamp and return type is `DateTime`, + * If the return type is `DateTime` and the argument is larger than `2106-02-07 08:28:15`, the result will be calculated from the argument `2106-02-07 08:28:15` instead. * If the return type is `Date` and the argument is larger than `2149-06-06`, the result will be calculated from the argument `2149-06-06` instead. * `2149-05-31` will be the result of execution of `toLastDayOfMonth` when argument is greater then `2149-05-31`. ::: From f40bd2194f9d3c841b0aaf557707ef11f8e26178 Mon Sep 17 00:00:00 2001 From: Andrey Zvonov <32552679+zvonand@users.noreply.github.com> Date: Tue, 23 Aug 2022 23:42:19 +0300 Subject: [PATCH 15/24] Update docs/en/sql-reference/functions/date-time-functions.md Co-authored-by: Robert Schulze --- docs/en/sql-reference/functions/date-time-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/sql-reference/functions/date-time-functions.md b/docs/en/sql-reference/functions/date-time-functions.md index 70dacd40ad1..a9eca5541dc 100644 --- a/docs/en/sql-reference/functions/date-time-functions.md +++ b/docs/en/sql-reference/functions/date-time-functions.md @@ -273,7 +273,7 @@ In case argument is out of normal range: * If the argument is smaller than 1970, the result will be calculated from the argument `1970-01-01 (00:00:00)` instead. * If the return type is `DateTime` and the argument is larger than `2106-02-07 08:28:15`, the result will be calculated from the argument `2106-02-07 08:28:15` instead. * If the return type is `Date` and the argument is larger than `2149-06-06`, the result will be calculated from the argument `2149-06-06` instead. - * `2149-05-31` will be the result of execution of `toLastDayOfMonth` when argument is greater then `2149-05-31`. + * If `toLastDayOfMonth` is called with an argument greater then `2149-05-31`, the result will be calculated from the argument `2149-05-31` instead. ::: ## toStartOfYear From a9fd73387119ca8f91732f7e31a39c588ac10074 Mon Sep 17 00:00:00 2001 From: zvonand Date: Mon, 22 Aug 2022 13:59:03 +0300 Subject: [PATCH 16/24] updated docs --- .../en/sql-reference/functions/date-time-functions.md | 4 ++-- .../ru/sql-reference/functions/date-time-functions.md | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/en/sql-reference/functions/date-time-functions.md b/docs/en/sql-reference/functions/date-time-functions.md index a9eca5541dc..6f137da78f9 100644 --- a/docs/en/sql-reference/functions/date-time-functions.md +++ b/docs/en/sql-reference/functions/date-time-functions.md @@ -267,7 +267,7 @@ Result: ``` :::Attention -The return type of `toStartOf*`, `toLastDayOfMonth`, `toMonday` functions described below is `Date` or `DateTime`. +The return type of `toStartOf*`, `toLastDayOfMonth`, `toMonday` functions described below is `Date` or `DateTime`. Though these functions can take values of the extended types `Date32` and `DateTime64` as an argument, passing them a time outside the normal range (year 1970 to 2149 for `Date` / 2106 for `DateTime`) will produce wrong results. In case argument is out of normal range: * If the argument is smaller than 1970, the result will be calculated from the argument `1970-01-01 (00:00:00)` instead. @@ -1046,7 +1046,7 @@ Example: SELECT timeSlots(toDateTime('2012-01-01 12:20:00'), toUInt32(600)); SELECT timeSlots(toDateTime('1980-12-12 21:01:02', 'UTC'), toUInt32(600), 299); SELECT timeSlots(toDateTime64('1980-12-12 21:01:02.1234', 4, 'UTC'), toDecimal64(600.1, 1), toDecimal64(299, 0)); -``` +``` ``` text ┌─timeSlots(toDateTime('2012-01-01 12:20:00'), toUInt32(600))─┐ │ ['2012-01-01 12:00:00','2012-01-01 12:30:00'] │ diff --git a/docs/ru/sql-reference/functions/date-time-functions.md b/docs/ru/sql-reference/functions/date-time-functions.md index 2a74db69ad6..56f3b3d7ddf 100644 --- a/docs/ru/sql-reference/functions/date-time-functions.md +++ b/docs/ru/sql-reference/functions/date-time-functions.md @@ -276,6 +276,15 @@ SELECT toUnixTimestamp('2017-11-05 08:07:47', 'Asia/Tokyo') AS unix_timestamp; * `2149-05-31` будет результатом функции `toLastDayOfMonth` при обработке аргумента больше `2149-05-31`. ::: +:::Attention +Тип возвращаемого описанными далее функциями `toStartOf*`, `toLastDayOfMonth`, `toMonday` значения - `Date` или `DateTime`. +Хотя эти функции могут принимать значения типа `Date32` или `DateTime64` в качестве аргумента, при обработке аргумента вне нормального диапазона значений (`1970` - `2148` для `Date` и `1970-01-01 00:00:00`-`2106-02-07 08:28:15` для `DateTime`) будет получен некорректный результат. +Возвращаемые значения для значений вне нормального диапазона: +* `1970-01-01 (00:00:00)` будет возвращён для моментов времени до 1970 года, +* `2106-02-07 08:28:15` будет взят в качестве аргумента, если полученный аргумент превосходит данное значение и возвращаемый тип - `DateTime`, +* `2149-06-06` будет взят в качестве аргумента, если полученный аргумент превосходит данное значение и возвращаемый тип - `Date`. + ::: +* ## toStartOfYear {#tostartofyear} Округляет дату или дату-с-временем вниз до первого дня года. @@ -964,7 +973,7 @@ SELECT now('Europe/Moscow'); ## timeSlots(StartTime, Duration,\[, Size\]) {#timeslotsstarttime-duration-size} Для интервала, начинающегося в `StartTime` и длящегося `Duration` секунд, возвращает массив моментов времени, кратных `Size`. Параметр `Size` указывать необязательно, по умолчанию он равен 1800 секундам (30 минутам) - необязательный параметр. -Данная функция может использоваться, например, для анализа количества просмотров страницы за соответствующую сессию. +Данная функция может использоваться, например, для анализа количества просмотров страницы за соответствующую сессию. Аргумент `StartTime` может иметь тип `DateTime` или `DateTime64`. В случае, если используется `DateTime`, аргументы `Duration` и `Size` должны иметь тип `UInt32`; Для DateTime64 они должны быть типа `Decimal64`. Возвращает массив DateTime/DateTime64 (тип будет совпадать с типом параметра ’StartTime’). Для DateTime64 масштаб(scale) возвращаемой величины может отличаться от масштаба фргумента ’StartTime’ --- результат будет иметь наибольший масштаб среди всех данных аргументов. From e257f9d0cda4690fdfb1d911026a52f06094d6fd Mon Sep 17 00:00:00 2001 From: zvonand Date: Wed, 24 Aug 2022 00:44:08 +0300 Subject: [PATCH 17/24] update docs, tests + small fixes --- .../functions/date-time-functions.md | 4 +++- .../functions/date-time-functions.md | 4 +++- src/Functions/CustomWeekTransforms.h | 24 +++++++++---------- src/Functions/DateTimeTransforms.h | 4 ++-- src/Functions/FunctionsConversion.h | 9 ++++--- .../02403_date_time_narrowing.reference | 2 +- .../0_stateless/02403_date_time_narrowing.sql | 4 +++- 7 files changed, 28 insertions(+), 23 deletions(-) diff --git a/docs/en/sql-reference/functions/date-time-functions.md b/docs/en/sql-reference/functions/date-time-functions.md index 6f137da78f9..2c1fcd05bf7 100644 --- a/docs/en/sql-reference/functions/date-time-functions.md +++ b/docs/en/sql-reference/functions/date-time-functions.md @@ -305,13 +305,15 @@ Returns the date. ## toMonday Rounds down a date or date with time to the nearest Monday. +As a special case, date arguments `1970-01-01`, `1970-01-02`, `1970-01-03` and `1970-01-04` return date `1970-01-01`. Returns the date. ## toStartOfWeek(t\[,mode\]) Rounds down a date or date with time to the nearest Sunday or Monday by mode. Returns the date. -The mode argument works exactly like the mode argument to toWeek(). For the single-argument syntax, a mode value of 0 is used. +As a special case, date arguments `1970-01-01`, `1970-01-02`, `1970-01-03` and `1970-01-04` (and `1970-01-05` if `mode` is `1`) return date `1970-01-01`. +The `mode` argument works exactly like the mode argument to toWeek(). For the single-argument syntax, a mode value of 0 is used. ## toStartOfDay diff --git a/docs/ru/sql-reference/functions/date-time-functions.md b/docs/ru/sql-reference/functions/date-time-functions.md index 56f3b3d7ddf..dbd4151f31e 100644 --- a/docs/ru/sql-reference/functions/date-time-functions.md +++ b/docs/ru/sql-reference/functions/date-time-functions.md @@ -326,13 +326,15 @@ SELECT toStartOfISOYear(toDate('2017-01-01')) AS ISOYear20170101; ## toMonday {#tomonday} Округляет дату или дату-с-временем вниз до ближайшего понедельника. +Частный случай: для дат `1970-01-01`, `1970-01-02`, `1970-01-03` и `1970-01-04` результатом будет `1970-01-01`. Возвращается дата. ## toStartOfWeek(t[,mode]) {#tostartofweek} Округляет дату или дату со временем до ближайшего воскресенья или понедельника в соответствии с mode. Возвращается дата. -Аргумент mode работает точно так же, как аргумент mode [toWeek()](#toweek). Если аргумент mode опущен, то используется режим 0. +Частный случай: для дат `1970-01-01`, `1970-01-02`, `1970-01-03` и `1970-01-04` (и `1970-01-05`, если `mode` равен `1`) результатом будет `1970-01-01`. +Аргумент `mode` работает точно так же, как аргумент mode [toWeek()](#toweek). Если аргумент mode опущен, то используется режим 0. ## toStartOfDay {#tostartofday} diff --git a/src/Functions/CustomWeekTransforms.h b/src/Functions/CustomWeekTransforms.h index 2e783eb953d..1b6eb590f74 100644 --- a/src/Functions/CustomWeekTransforms.h +++ b/src/Functions/CustomWeekTransforms.h @@ -65,12 +65,12 @@ struct ToStartOfWeekImpl if (t < 0) return 0; - auto res = time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM))), week_mode); - - if (res < 0) - return 0; - else - return res; + return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM))), week_mode); +// +// if (res < 0) +// return 0; +// else +// return res; } static inline UInt16 execute(UInt32 t, UInt8 week_mode, const DateLUTImpl & time_zone) { @@ -81,12 +81,12 @@ struct ToStartOfWeekImpl if (d < 0) return 0; - auto res = time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM)), week_mode); - - if (res < 0) - return 0; - else - return res; + return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM)), week_mode); +// +// if (res < 0) +// return 0; +// else +// return res; } static inline UInt16 execute(UInt16 d, UInt8 week_mode, const DateLUTImpl & time_zone) { diff --git a/src/Functions/DateTimeTransforms.h b/src/Functions/DateTimeTransforms.h index 3b31eafd774..8af908abdae 100644 --- a/src/Functions/DateTimeTransforms.h +++ b/src/Functions/DateTimeTransforms.h @@ -125,7 +125,7 @@ struct ToStartOfDayImpl if (d < 0) return 0; - Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(d)); + auto date_time = time_zone.fromDayNum(ExtendedDayNum(d)); if (date_time <= 0xffffffff) return date_time; else @@ -133,7 +133,7 @@ struct ToStartOfDayImpl } static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone) { - Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(d)); + auto date_time = time_zone.fromDayNum(ExtendedDayNum(d)); return date_time < 0xffffffff ? date_time : time_zone.toDate(0xffffffff); } diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index 63e4633ccb5..40d5b754c9f 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -324,7 +324,7 @@ struct ToDateTimeImpl static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone) { - Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(d)); + auto date_time = time_zone.fromDayNum(ExtendedDayNum(d)); return date_time <= 0xffffffff ? UInt32(date_time) : UInt32(0xffffffff); } @@ -333,7 +333,7 @@ struct ToDateTimeImpl if (d < 0) return 0; - Int64 date_time = time_zone.fromDayNum(ExtendedDayNum(d)); + auto date_time = time_zone.fromDayNum(ExtendedDayNum(d)); return date_time <= 0xffffffff ? UInt32(date_time) : UInt32(0xffffffff); } @@ -344,11 +344,10 @@ struct ToDateTimeImpl static inline UInt32 execute(const DecimalUtils::DecimalComponents & t, const DateLUTImpl & time_zone) { - if (t.whole < 0) + if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0)) return 0; - auto day_num = time_zone.toDayNum(t.whole); - return (day_num < DATE_LUT_MAX_DAY_NUM) ? t.whole : time_t(0xFFFFFFFF); + return time_zone.toDayNum(std::min(t.whole, time_t(0xFFFFFFFF))); } }; diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.reference b/tests/queries/0_stateless/02403_date_time_narrowing.reference index cbdac452cfa..3196be6332e 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.reference +++ b/tests/queries/0_stateless/02403_date_time_narrowing.reference @@ -1,4 +1,4 @@ -1970-01-01 2149-06-06 1970-01-01 2149-06-06 1900-01-01 2299-12-31 +1970-01-01 2149-06-06 1970-01-01 2149-06-06 1900-01-01 2299-12-31 1970-01-01 03:00:00 1970-01-01 21:12:15 1970-01-01 2149-06-06 1970-01-01 2149-06-06 1970-01-01 00:00:00 2106-02-07 06:28:15 diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.sql b/tests/queries/0_stateless/02403_date_time_narrowing.sql index d32bac1a47b..ddadf507055 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.sql +++ b/tests/queries/0_stateless/02403_date_time_narrowing.sql @@ -4,7 +4,9 @@ SELECT toDate(toInt32(toDate32('1930-01-01'))), toDate(toInt64(toDateTime64('1930-01-01 12:12:12.123', 3))), toDate(toInt64(toDateTime64('2151-01-01 12:12:12.123', 3))), toDate32(toInt32(toDate32('1900-01-01')) - 1), - toDate32(toInt32(toDate32('2299-12-31')) + 1); + toDate32(toInt32(toDate32('2299-12-31')) + 1), + toDateTime(toInt64(toDateTime64('1930-01-01 12:12:12.123', 3))), + toDateTime(toInt64(toDateTime64('2151-01-01 12:12:12.123', 3))); -- check conversion of extended range type to normal range type -- SELECT toDate(toDate32('1930-01-01')), From b4564099f9c5aef48a4644acb759666a43aeaa9e Mon Sep 17 00:00:00 2001 From: zvonand Date: Wed, 24 Aug 2022 17:07:30 +0300 Subject: [PATCH 18/24] fix inherited parts --- src/Functions/CustomWeekTransforms.h | 26 +++++++++++++------------- src/Functions/FunctionsConversion.h | 15 ++++++--------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/Functions/CustomWeekTransforms.h b/src/Functions/CustomWeekTransforms.h index 1b6eb590f74..3f520d12420 100644 --- a/src/Functions/CustomWeekTransforms.h +++ b/src/Functions/CustomWeekTransforms.h @@ -65,12 +65,12 @@ struct ToStartOfWeekImpl if (t < 0) return 0; - return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM))), week_mode); -// -// if (res < 0) -// return 0; -// else -// return res; + auto res = time_zone.toFirstDayNumOfWeek(DayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM))), week_mode); + + if (res > time_zone.toDayNum(t)) + return 0; + else + return res; } static inline UInt16 execute(UInt32 t, UInt8 week_mode, const DateLUTImpl & time_zone) { @@ -81,16 +81,16 @@ struct ToStartOfWeekImpl if (d < 0) return 0; - return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM)), week_mode); -// -// if (res < 0) -// return 0; -// else -// return res; + auto res = time_zone.toFirstDayNumOfWeek(DayNum(std::min(d, DATE_LUT_MAX_DAY_NUM)), week_mode); + + if (res > d) + return 0; + else + return res; } static inline UInt16 execute(UInt16 d, UInt8 week_mode, const DateLUTImpl & time_zone) { - auto res = time_zone.toFirstDayNumOfWeek(DayNum(d), week_mode); + auto res = time_zone.toFirstDayNumOfWeek(d, week_mode); if (res > d) return 0; diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index 40d5b754c9f..6bd6f480eed 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -342,12 +342,12 @@ struct ToDateTimeImpl return dt; } - static inline UInt32 execute(const DecimalUtils::DecimalComponents & t, const DateLUTImpl & time_zone) + static inline UInt32 execute(const DecimalUtils::DecimalComponents & t, const DateLUTImpl & /*time_zone*/) { if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0)) return 0; - return time_zone.toDayNum(std::min(t.whole, time_t(0xFFFFFFFF))); + return std::min(t.whole, time_t(0xFFFFFFFF)); } }; @@ -417,9 +417,7 @@ struct ToDate32Transform32Or64 static inline NO_SANITIZE_UNDEFINED ToType execute(const FromType & from, const DateLUTImpl & time_zone) { - return (from < DATE_LUT_MAX_EXTEND_DAY_NUM) - ? from - : time_zone.toDayNum(std::min(time_t(from), time_t(0xFFFFFFFF))); + return std::min(time_t(time_zone.toDayNum(from)), time_t(DATE_LUT_MAX_EXTEND_DAY_NUM)); } }; @@ -434,9 +432,7 @@ struct ToDate32Transform32Or64Signed if (from < daynum_min_offset) return daynum_min_offset; - return (time_zone.toDayNum(from) < DATE_LUT_MAX_EXTEND_DAY_NUM) - ? from - : time_zone.toDayNum(std::min(time_t(from), time_t(DATE_LUT_MAX_EXTEND_DAY_NUM))); + return std::min(time_t(time_zone.toDayNum(from)), time_t(DATE_LUT_MAX_EXTEND_DAY_NUM)); } }; @@ -689,7 +685,8 @@ struct ToDateTime64Transform inline DateTime64::NativeType execute(Int32 d, const DateLUTImpl & time_zone) const { - const auto dt = ToDateTimeImpl::execute(d, time_zone); +// const auto dt = ToDateTimeImpl::execute(d, time_zone); + const auto dt = time_zone.fromDayNum(ExtendedDayNum(d)); return DecimalUtils::decimalFromComponentsWithMultiplier(dt, 0, scale_multiplier); } From 5c004289403b3123ed61f93c624eb1eae3ef8eb4 Mon Sep 17 00:00:00 2001 From: zvonand Date: Wed, 24 Aug 2022 19:46:17 +0300 Subject: [PATCH 19/24] updated as was before --- src/Functions/FunctionsConversion.h | 17 +++++++++++++---- .../02403_date_time_narrowing.reference | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index 6bd6f480eed..b60f9f739f5 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -334,7 +334,7 @@ struct ToDateTimeImpl return 0; auto date_time = time_zone.fromDayNum(ExtendedDayNum(d)); - return date_time <= 0xffffffff ? UInt32(date_time) : UInt32(0xffffffff); + return date_time <= 0xffffffff ? date_time : 0xffffffff; } static inline UInt32 execute(UInt32 dt, const DateLUTImpl & /*time_zone*/) @@ -342,6 +342,15 @@ struct ToDateTimeImpl return dt; } + static inline UInt32 execute(Int64 d, const DateLUTImpl & time_zone) + { + if (d < 0) + return 0; + + auto date_time = time_zone.toDate(d); + return date_time <= 0xffffffff ? date_time : 0xffffffff; + } + static inline UInt32 execute(const DecimalUtils::DecimalComponents & t, const DateLUTImpl & /*time_zone*/) { if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0)) @@ -431,8 +440,9 @@ struct ToDate32Transform32Or64Signed static const Int32 daynum_min_offset = -static_cast(DateLUT::instance().getDayNumOffsetEpoch()); if (from < daynum_min_offset) return daynum_min_offset; - - return std::min(time_t(time_zone.toDayNum(from)), time_t(DATE_LUT_MAX_EXTEND_DAY_NUM)); + return (from < DATE_LUT_MAX_EXTEND_DAY_NUM) + ? from + : time_zone.toDayNum(std::min(time_t(from), time_t(0xFFFFFFFF))); } }; @@ -685,7 +695,6 @@ struct ToDateTime64Transform inline DateTime64::NativeType execute(Int32 d, const DateLUTImpl & time_zone) const { -// const auto dt = ToDateTimeImpl::execute(d, time_zone); const auto dt = time_zone.fromDayNum(ExtendedDayNum(d)); return DecimalUtils::decimalFromComponentsWithMultiplier(dt, 0, scale_multiplier); } diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.reference b/tests/queries/0_stateless/02403_date_time_narrowing.reference index 3196be6332e..3d8e09ac5e1 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.reference +++ b/tests/queries/0_stateless/02403_date_time_narrowing.reference @@ -1,4 +1,4 @@ -1970-01-01 2149-06-06 1970-01-01 2149-06-06 1900-01-01 2299-12-31 1970-01-01 03:00:00 1970-01-01 21:12:15 +1970-01-01 2149-06-06 1970-01-01 2149-06-06 1900-01-01 1970-01-02 1970-01-01 03:00:00 1970-01-01 21:12:15 1970-01-01 2149-06-06 1970-01-01 2149-06-06 1970-01-01 00:00:00 2106-02-07 06:28:15 From a61fd73c882ab7b2c852fde8e8eddf2bb5181ada Mon Sep 17 00:00:00 2001 From: zvonand Date: Thu, 25 Aug 2022 00:26:44 +0300 Subject: [PATCH 20/24] fix test fails --- src/Functions/CustomWeekTransforms.h | 21 ++------ src/Functions/FunctionsConversion.h | 24 ++++++---- .../0_stateless/00941_to_custom_week.sql | 1 - .../01440_to_date_monotonicity.reference | 2 +- .../01921_datatype_date32.reference | 48 +++++++++---------- .../02403_date_time_narrowing.reference | 2 +- .../0_stateless/02403_date_time_narrowing.sql | 12 ++--- 7 files changed, 50 insertions(+), 60 deletions(-) diff --git a/src/Functions/CustomWeekTransforms.h b/src/Functions/CustomWeekTransforms.h index 3f520d12420..3fd5cd07824 100644 --- a/src/Functions/CustomWeekTransforms.h +++ b/src/Functions/CustomWeekTransforms.h @@ -65,12 +65,7 @@ struct ToStartOfWeekImpl if (t < 0) return 0; - auto res = time_zone.toFirstDayNumOfWeek(DayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM))), week_mode); - - if (res > time_zone.toDayNum(t)) - return 0; - else - return res; + return time_zone.toFirstDayNumOfWeek(DayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM))), week_mode); } static inline UInt16 execute(UInt32 t, UInt8 week_mode, const DateLUTImpl & time_zone) { @@ -81,21 +76,11 @@ struct ToStartOfWeekImpl if (d < 0) return 0; - auto res = time_zone.toFirstDayNumOfWeek(DayNum(std::min(d, DATE_LUT_MAX_DAY_NUM)), week_mode); - - if (res > d) - return 0; - else - return res; + return time_zone.toFirstDayNumOfWeek(DayNum(std::min(d, DATE_LUT_MAX_DAY_NUM)), week_mode); } static inline UInt16 execute(UInt16 d, UInt8 week_mode, const DateLUTImpl & time_zone) { - auto res = time_zone.toFirstDayNumOfWeek(d, week_mode); - - if (res > d) - return 0; - else - return res; + return time_zone.toFirstDayNumOfWeek(DayNum(d), week_mode); } using FactorTransform = ZeroTransform; diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index b60f9f739f5..7a94e42d330 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -379,8 +379,9 @@ struct ToDateTransform32Or64 if (from < 0) return 0; - auto day_num = time_zone.toDayNum(from); - return day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM; + return (from < DATE_LUT_MAX_DAY_NUM) + ? from + : std::min(UInt64(time_zone.toDayNum(from)), UInt64(DATE_LUT_MAX_DAY_NUM)); } }; @@ -398,6 +399,11 @@ struct ToDateTransform32Or64Signed auto day_num = time_zone.toDayNum(ExtendedDayNum(from)); return day_num < DATE_LUT_MAX_DAY_NUM ? day_num : DATE_LUT_MAX_DAY_NUM; + + return (from < DATE_LUT_MAX_DAY_NUM) + ? from + : std::min(UInt64(time_zone.toDayNum(from)), UInt64(0xFFFFFFFF)); + } }; @@ -426,7 +432,9 @@ struct ToDate32Transform32Or64 static inline NO_SANITIZE_UNDEFINED ToType execute(const FromType & from, const DateLUTImpl & time_zone) { - return std::min(time_t(time_zone.toDayNum(from)), time_t(DATE_LUT_MAX_EXTEND_DAY_NUM)); + return (from < DATE_LUT_MAX_EXTEND_DAY_NUM) + ? from + : std::min(UInt64(time_zone.toDayNum(from)), UInt64(DATE_LUT_MAX_EXTEND_DAY_NUM)); } }; @@ -442,7 +450,7 @@ struct ToDate32Transform32Or64Signed return daynum_min_offset; return (from < DATE_LUT_MAX_EXTEND_DAY_NUM) ? from - : time_zone.toDayNum(std::min(time_t(from), time_t(0xFFFFFFFF))); + : time_zone.toDayNum(std::min(Int64(from), Int64(0xFFFFFFFF))); } }; @@ -544,14 +552,12 @@ struct ToDateTimeTransform64Signed { static constexpr auto name = "toDateTime"; - static inline NO_SANITIZE_UNDEFINED ToType execute(const FromType & from, const DateLUTImpl & time_zone) + static inline NO_SANITIZE_UNDEFINED ToType execute(const FromType & from, const DateLUTImpl & /* time_zone */) { if (from < 0) return 0; - else if (time_zone.toDayNum(from) > DATE_LUT_MAX_DAY_NUM) - return DATE_LUT_MAX_DAY_NUM; - else - return time_t(from); + + return std::min(Int64(from), Int64(0xFFFFFFFF)); } }; diff --git a/tests/queries/0_stateless/00941_to_custom_week.sql b/tests/queries/0_stateless/00941_to_custom_week.sql index 4dd5d209306..04ff08d4117 100644 --- a/tests/queries/0_stateless/00941_to_custom_week.sql +++ b/tests/queries/0_stateless/00941_to_custom_week.sql @@ -49,4 +49,3 @@ SELECT toStartOfWeek(x, 3) AS w3, toStartOfWeek(x_t, 3) AS wt3 FROM numbers(10); - diff --git a/tests/queries/0_stateless/01440_to_date_monotonicity.reference b/tests/queries/0_stateless/01440_to_date_monotonicity.reference index 2dbec540fbb..dd8545b721d 100644 --- a/tests/queries/0_stateless/01440_to_date_monotonicity.reference +++ b/tests/queries/0_stateless/01440_to_date_monotonicity.reference @@ -1,4 +1,4 @@ 0 -1970-01-01 2106-02-07 1970-04-11 1970-01-01 2149-06-06 +1970-01-01 2120-07-26 1970-04-11 1970-01-01 2149-06-06 1970-01-01 02:00:00 2106-02-07 09:28:15 1970-01-01 02:16:40 2000-01-01 13:12:12 diff --git a/tests/queries/0_stateless/01921_datatype_date32.reference b/tests/queries/0_stateless/01921_datatype_date32.reference index acb0cc4ca59..a33a96ffffb 100644 --- a/tests/queries/0_stateless/01921_datatype_date32.reference +++ b/tests/queries/0_stateless/01921_datatype_date32.reference @@ -43,16 +43,16 @@ -------toMinute--------- -------toSecond--------- -------toStartOfDay--------- -2036-02-07 07:31:20 -2036-02-07 07:31:20 -2027-10-01 11:03:28 -2027-10-17 11:03:28 +1970-01-01 02:00:00 +1970-01-01 02:00:00 +2106-02-07 00:00:00 +2106-02-07 00:00:00 2021-06-22 00:00:00 -------toMonday--------- -2079-06-07 -2079-06-07 -2120-07-06 -2120-07-20 +1970-01-01 +1970-01-01 +2149-06-02 +2149-06-02 2021-06-21 -------toISOWeek--------- 1 @@ -79,28 +79,28 @@ 229953 202125 -------toStartOfWeek--------- -2079-06-06 -2079-06-06 -2120-07-05 -2120-07-26 +1970-01-01 +1970-01-01 +2149-06-01 +2149-06-01 2021-06-20 -------toStartOfMonth--------- -2079-06-07 -2079-06-07 -2120-06-26 -2120-06-26 +1970-01-01 +1970-01-01 +2149-06-01 +2149-06-01 2021-06-01 -------toStartOfQuarter--------- -2079-06-07 -2079-06-07 -2120-04-26 -2120-04-26 +1970-01-01 +1970-01-01 +2149-04-01 +2149-04-01 2021-04-01 -------toStartOfYear--------- -2079-06-07 -2079-06-07 -2119-07-28 -2119-07-28 +1970-01-01 +1970-01-01 +2149-01-01 +2149-01-01 2021-01-01 -------toStartOfSecond--------- -------toStartOfMinute--------- diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.reference b/tests/queries/0_stateless/02403_date_time_narrowing.reference index 3d8e09ac5e1..1d97c361773 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.reference +++ b/tests/queries/0_stateless/02403_date_time_narrowing.reference @@ -1,4 +1,4 @@ -1970-01-01 2149-06-06 1970-01-01 2149-06-06 1900-01-01 1970-01-02 1970-01-01 03:00:00 1970-01-01 21:12:15 +1970-01-01 2149-06-06 1970-01-01 2149-06-06 1900-01-01 1970-01-02 1970-01-01 00:00:00 2106-02-07 06:28:15 1970-01-01 2149-06-06 1970-01-01 2149-06-06 1970-01-01 00:00:00 2106-02-07 06:28:15 diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.sql b/tests/queries/0_stateless/02403_date_time_narrowing.sql index ddadf507055..bcc35df5934 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.sql +++ b/tests/queries/0_stateless/02403_date_time_narrowing.sql @@ -1,12 +1,12 @@ -- check conversion of numbers to date/time -- SELECT toDate(toInt32(toDate32('1930-01-01'))), toDate(toInt32(toDate32('2151-01-01'))), - toDate(toInt64(toDateTime64('1930-01-01 12:12:12.123', 3))), - toDate(toInt64(toDateTime64('2151-01-01 12:12:12.123', 3))), + toDate(toInt64(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'))), + toDate(toInt64(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'))), toDate32(toInt32(toDate32('1900-01-01')) - 1), toDate32(toInt32(toDate32('2299-12-31')) + 1), - toDateTime(toInt64(toDateTime64('1930-01-01 12:12:12.123', 3))), - toDateTime(toInt64(toDateTime64('2151-01-01 12:12:12.123', 3))); + toDateTime(toInt64(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC')), 'UTC'), + toDateTime(toInt64(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC')), 'UTC'); -- check conversion of extended range type to normal range type -- SELECT toDate(toDate32('1930-01-01')), @@ -34,8 +34,8 @@ SELECT toStartOfDay(toDate('2141-01-01', 'UTC'), 'UTC'), SELECT 'toStartOfWeek'; SELECT toStartOfWeek(toDate('1970-01-01')), toStartOfWeek(toDate32('1970-01-01')), - toStartOfWeek(toDateTime('1970-01-01 10:10:10')), - toStartOfWeek(toDateTime64('1970-01-01 10:10:10.123', 3)), + toStartOfWeek(toDateTime('1970-01-01 10:10:10', 'UTC')), + toStartOfWeek(toDateTime64('1970-01-01 10:10:10.123', 3, 'UTC')), toStartOfWeek(toDate32('1930-01-01')), toStartOfWeek(toDate32('2151-01-01')), toStartOfWeek(toDateTime64('1930-01-01 12:12:12.123', 3)), From d319e8274dc6524292c9b95672cb93b00056cf89 Mon Sep 17 00:00:00 2001 From: zvonand Date: Thu, 25 Aug 2022 02:34:16 +0300 Subject: [PATCH 21/24] fix parquet test --- tests/queries/0_stateless/00900_long_parquet.reference | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/queries/0_stateless/00900_long_parquet.reference b/tests/queries/0_stateless/00900_long_parquet.reference index bbdad7243bd..4dfc726145e 100644 --- a/tests/queries/0_stateless/00900_long_parquet.reference +++ b/tests/queries/0_stateless/00900_long_parquet.reference @@ -44,12 +44,12 @@ converted: diff: dest: 79 81 82 83 84 85 86 87 88 89 str01\0\0\0\0\0\0\0\0\0\0 fstr1\0\0\0\0\0\0\0\0\0\0 2003-03-04 2004-05-06 00:00:00 2004-05-06 07:08:09.012000000 -80 81 82 83 84 85 86 87 88 89 str02 fstr2\0\0\0\0\0\0\0\0\0\0 2005-03-04 2006-08-09 10:11:12 2006-08-09 10:11:12.345000000 +80 81 82 83 84 85 86 87 88 89 str02 fstr2\0\0\0\0\0\0\0\0\0\0 2149-06-06 2006-08-09 10:11:12 2006-08-09 10:11:12.345000000 min: --128 0 0 0 0 0 0 0 -1 -1 string-1\0\0\0\0\0\0\0 fixedstring-1\0\0 2003-04-05 2003-02-03 2003-02-03 04:05:06.789000000 --108 108 8 92 -8 108 -40 -116 -1 -1 string-0\0\0\0\0\0\0\0 fixedstring\0\0\0\0 2001-02-03 2002-02-03 2002-02-03 04:05:06.789000000 +-128 0 0 0 0 0 0 0 -1 -1 string-1\0\0\0\0\0\0\0 fixedstring-1\0\0 2003-04-05 2149-06-06 2003-02-03 04:05:06.789000000 +-108 108 8 92 -8 108 -40 -116 -1 -1 string-0\0\0\0\0\0\0\0 fixedstring\0\0\0\0 2001-02-03 2149-06-06 2002-02-03 04:05:06.789000000 79 81 82 83 84 85 86 87 88 89 str01\0\0\0\0\0\0\0\0\0\0 fstr1\0\0\0\0\0\0\0\0\0\0 2003-03-04 2004-05-06 2004-05-06 07:08:09.012000000 -127 -1 -1 -1 -1 -1 -1 -1 -1 -1 string-2\0\0\0\0\0\0\0 fixedstring-2\0\0 2004-06-07 2004-02-03 2004-02-03 04:05:06.789000000 +127 -1 -1 -1 -1 -1 -1 -1 -1 -1 string-2\0\0\0\0\0\0\0 fixedstring-2\0\0 2004-06-07 2149-06-06 2004-02-03 04:05:06.789000000 max: -128 0 -32768 0 -2147483648 0 -9223372036854775808 0 -1 -1 string-1 fixedstring-1\0\0 2003-04-05 00:00:00 2003-02-03 04:05:06 2003-02-03 04:05:06.789000000 -108 108 -1016 1116 -1032 1132 -1064 1164 -1 -1 string-0 fixedstring\0\0\0\0 2001-02-03 00:00:00 2002-02-03 04:05:06 2002-02-03 04:05:06.789000000 From bd3383cd27cb6915847d8534c6c5db8cad0a7eac Mon Sep 17 00:00:00 2001 From: zvonand Date: Thu, 25 Aug 2022 11:10:01 +0300 Subject: [PATCH 22/24] update test --- .../queries/0_stateless/02403_date_time_narrowing.reference | 2 -- tests/queries/0_stateless/02403_date_time_narrowing.sql | 6 ------ 2 files changed, 8 deletions(-) diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.reference b/tests/queries/0_stateless/02403_date_time_narrowing.reference index 1d97c361773..ff5641c3d92 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.reference +++ b/tests/queries/0_stateless/02403_date_time_narrowing.reference @@ -12,8 +12,6 @@ toMonday 1970-01-01 1970-01-01 2149-06-02 1970-01-01 2149-06-02 toStartOfMonth 1970-01-01 2149-06-01 1970-01-01 2149-06-01 -toStartOfMonth -1970-01-01 2149-06-01 1970-01-01 2149-06-01 toLastDayOfMonth 2149-05-31 1970-01-01 2149-05-31 1970-01-01 2149-05-31 toStartOfQuarter diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.sql b/tests/queries/0_stateless/02403_date_time_narrowing.sql index bcc35df5934..59918e170bc 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.sql +++ b/tests/queries/0_stateless/02403_date_time_narrowing.sql @@ -54,12 +54,6 @@ SELECT toStartOfMonth(toDate32('1930-01-01', 'UTC')), toStartOfMonth(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), toStartOfMonth(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); -SELECT 'toStartOfMonth'; -SELECT toStartOfMonth(toDate32('1930-01-01', 'UTC')), - toStartOfMonth(toDate32('2151-01-01', 'UTC')), - toStartOfMonth(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), - toStartOfMonth(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); - SELECT 'toLastDayOfMonth'; SELECT toLastDayOfMonth(toDate('2149-06-03')), toLastDayOfMonth(toDate32('1930-01-01', 'UTC')), From 24dfa0c64afe5963aaeef6f1fe57bccd4fbf4096 Mon Sep 17 00:00:00 2001 From: zvonand Date: Thu, 25 Aug 2022 12:28:15 +0300 Subject: [PATCH 23/24] tryfix darwin --- src/Functions/CustomWeekTransforms.h | 4 ++-- src/Functions/DateTimeTransforms.h | 30 ++++++++++++++-------------- src/Functions/FunctionsConversion.h | 14 ++++++------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/Functions/CustomWeekTransforms.h b/src/Functions/CustomWeekTransforms.h index 3fd5cd07824..3378aec02d5 100644 --- a/src/Functions/CustomWeekTransforms.h +++ b/src/Functions/CustomWeekTransforms.h @@ -65,7 +65,7 @@ struct ToStartOfWeekImpl if (t < 0) return 0; - return time_zone.toFirstDayNumOfWeek(DayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM))), week_mode); + return time_zone.toFirstDayNumOfWeek(DayNum(std::min(Int32(time_zone.toDayNum(t)), Int32(DATE_LUT_MAX_DAY_NUM))), week_mode); } static inline UInt16 execute(UInt32 t, UInt8 week_mode, const DateLUTImpl & time_zone) { @@ -76,7 +76,7 @@ struct ToStartOfWeekImpl if (d < 0) return 0; - return time_zone.toFirstDayNumOfWeek(DayNum(std::min(d, DATE_LUT_MAX_DAY_NUM)), week_mode); + return time_zone.toFirstDayNumOfWeek(DayNum(std::min(d, Int32(DATE_LUT_MAX_DAY_NUM))), week_mode); } static inline UInt16 execute(UInt16 d, UInt8 week_mode, const DateLUTImpl & time_zone) { diff --git a/src/Functions/DateTimeTransforms.h b/src/Functions/DateTimeTransforms.h index 8af908abdae..66d57f2463f 100644 --- a/src/Functions/DateTimeTransforms.h +++ b/src/Functions/DateTimeTransforms.h @@ -61,7 +61,7 @@ struct ToDateImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - return t < 0 ? 0 : std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)); + return t < 0 ? 0 : std::min(Int32(time_zone.toDayNum(t)), Int32(DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -69,7 +69,7 @@ struct ToDateImpl } static inline UInt16 execute(Int32 t, const DateLUTImpl &) { - return t < 0 ? 0 : std::min(time_t(t), time_t(DATE_LUT_MAX_DAY_NUM)); + return t < 0 ? 0 : std::min(t, Int32(DATE_LUT_MAX_DAY_NUM)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl &) { @@ -114,7 +114,7 @@ struct ToStartOfDayImpl if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0)) return 0; - return time_zone.toDate(std::min(t.whole, time_t(0xffffffff))); + return time_zone.toDate(std::min(t.whole, Int64(0xffffffff))); } static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -147,7 +147,7 @@ struct ToMondayImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { return t < 0 ? 0 : time_zone.toFirstDayNumOfWeek(ExtendedDayNum( - std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)))); + std::min(Int32(time_zone.toDayNum(t)), Int32(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -155,7 +155,7 @@ struct ToMondayImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - return d < 0 ? 0 : time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM))); + return d < 0 ? 0 : time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(d, Int32(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -171,7 +171,7 @@ struct ToStartOfMonthImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - return t < 0 ? 0 : time_zone.toFirstDayNumOfMonth(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)))); + return t < 0 ? 0 : time_zone.toFirstDayNumOfMonth(ExtendedDayNum(std::min(Int32(time_zone.toDayNum(t)), Int32(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -179,7 +179,7 @@ struct ToStartOfMonthImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - return d < 0 ? 0 : time_zone.toFirstDayNumOfMonth(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM))); + return d < 0 ? 0 : time_zone.toFirstDayNumOfMonth(ExtendedDayNum(std::min(d, Int32(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -199,7 +199,7 @@ struct ToLastDayOfMonthImpl return 0; /// 0xFFF9 is Int value for 2149-05-31 -- the last day where we can actually find LastDayOfMonth. This will also be the return value. - return time_zone.toLastDayNumOfMonth(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(0xFFF9)))); + return time_zone.toLastDayNumOfMonth(ExtendedDayNum(std::min(Int32(time_zone.toDayNum(t)), Int32(0xFFF9)))); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -211,7 +211,7 @@ struct ToLastDayOfMonthImpl return 0; /// 0xFFF9 is Int value for 2149-05-31 -- the last day where we can actually find LastDayOfMonth. This will also be the return value. - return time_zone.toLastDayNumOfMonth(ExtendedDayNum(std::min(d, 0xFFF9))); + return time_zone.toLastDayNumOfMonth(ExtendedDayNum(std::min(d, Int32(0xFFF9)))); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -228,7 +228,7 @@ struct ToStartOfQuarterImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - return t < 0 ? 0 : time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)))); + return t < 0 ? 0 : time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(std::min(Int64(time_zone.toDayNum(t)), Int64(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -236,7 +236,7 @@ struct ToStartOfQuarterImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - return d < 0 ? 0 : time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM))); + return d < 0 ? 0 : time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(std::min(d, Int32(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -252,7 +252,7 @@ struct ToStartOfYearImpl static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone) { - return t < 0 ? 0 : time_zone.toFirstDayNumOfYear(ExtendedDayNum(std::min(time_t(time_zone.toDayNum(t)), time_t(DATE_LUT_MAX_DAY_NUM)))); + return t < 0 ? 0 : time_zone.toFirstDayNumOfYear(ExtendedDayNum(std::min(Int32(time_zone.toDayNum(t)), Int32(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -260,7 +260,7 @@ struct ToStartOfYearImpl } static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone) { - return d < 0 ? 0 : time_zone.toFirstDayNumOfYear(ExtendedDayNum(std::min(d, DATE_LUT_MAX_DAY_NUM))); + return d < 0 ? 0 : time_zone.toFirstDayNumOfYear(ExtendedDayNum(std::min(d, Int32(DATE_LUT_MAX_DAY_NUM)))); } static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone) { @@ -305,7 +305,7 @@ struct ToStartOfMinuteImpl if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0)) return 0; - return time_zone.toStartOfMinute(std::min(t.whole, time_t(0xffffffff))); + return time_zone.toStartOfMinute(std::min(t.whole, Int64(0xffffffff))); } static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone) { @@ -599,7 +599,7 @@ struct ToStartOfHourImpl if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0)) return 0; - return time_zone.toStartOfHour(std::min(t.whole, time_t(0xffffffff))); + return time_zone.toStartOfHour(std::min(t.whole, Int64(0xffffffff))); } static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone) diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index 12a70f01d57..96c28b21ef0 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -356,7 +356,7 @@ struct ToDateTimeImpl if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0)) return 0; - return std::min(t.whole, time_t(0xFFFFFFFF)); + return std::min(t.whole, Int64(0xFFFFFFFF)); } }; @@ -381,7 +381,7 @@ struct ToDateTransform32Or64 return (from < DATE_LUT_MAX_DAY_NUM) ? from - : std::min(UInt64(time_zone.toDayNum(from)), UInt64(DATE_LUT_MAX_DAY_NUM)); + : std::min(Int32(time_zone.toDayNum(from)), Int32(DATE_LUT_MAX_DAY_NUM)); } }; @@ -402,7 +402,7 @@ struct ToDateTransform32Or64Signed return (from < DATE_LUT_MAX_DAY_NUM) ? from - : std::min(UInt64(time_zone.toDayNum(from)), UInt64(0xFFFFFFFF)); + : std::min(Int32(time_zone.toDayNum(from)), Int32(0xFFFFFFFF)); } }; @@ -434,7 +434,7 @@ struct ToDate32Transform32Or64 { return (from < DATE_LUT_MAX_EXTEND_DAY_NUM) ? from - : std::min(UInt64(time_zone.toDayNum(from)), UInt64(DATE_LUT_MAX_EXTEND_DAY_NUM)); + : std::min(Int32(time_zone.toDayNum(from)), Int32(DATE_LUT_MAX_EXTEND_DAY_NUM)); } }; @@ -450,7 +450,7 @@ struct ToDate32Transform32Or64Signed return daynum_min_offset; return (from < DATE_LUT_MAX_EXTEND_DAY_NUM) ? from - : time_zone.toDayNum(std::min(Int64(from), Int64(0xFFFFFFFF))); + : time_zone.toDayNum(std::min(Int64(from), Int64(0xFFFFFFFF))); } }; @@ -530,7 +530,7 @@ struct ToDateTimeTransform64 static inline NO_SANITIZE_UNDEFINED ToType execute(const FromType & from, const DateLUTImpl &) { - return std::min(time_t(from), time_t(0xFFFFFFFF)); + return std::min(Int64(from), Int64(0xFFFFFFFF)); } }; @@ -557,7 +557,7 @@ struct ToDateTimeTransform64Signed if (from < 0) return 0; - return std::min(Int64(from), Int64(0xFFFFFFFF)); + return std::min(Int64(from), Int64(0xFFFFFFFF)); } }; From b9b8f7a05d29104af1dbeb8216c3d99da2cb140c Mon Sep 17 00:00:00 2001 From: zvonand Date: Fri, 26 Aug 2022 18:43:31 +0300 Subject: [PATCH 24/24] explicit timezone in test --- .../02403_date_time_narrowing.reference | 2 +- .../0_stateless/02403_date_time_narrowing.sql | 36 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.reference b/tests/queries/0_stateless/02403_date_time_narrowing.reference index ff5641c3d92..7d6e91c61b8 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.reference +++ b/tests/queries/0_stateless/02403_date_time_narrowing.reference @@ -7,7 +7,7 @@ toStartOfDay 2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 1970-01-01 00:00:00 2106-02-07 00:00:00 toStartOfWeek -1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 2149-06-01 1970-01-01 2149-06-01 +1970-01-01 1970-01-01 1970-01-01 1970-01-01 1970-01-01 2149-06-01 1970-01-01 2149-06-02 toMonday 1970-01-01 1970-01-01 2149-06-02 1970-01-01 2149-06-02 toStartOfMonth diff --git a/tests/queries/0_stateless/02403_date_time_narrowing.sql b/tests/queries/0_stateless/02403_date_time_narrowing.sql index 59918e170bc..07cbba6f31c 100644 --- a/tests/queries/0_stateless/02403_date_time_narrowing.sql +++ b/tests/queries/0_stateless/02403_date_time_narrowing.sql @@ -1,16 +1,16 @@ -- check conversion of numbers to date/time -- -SELECT toDate(toInt32(toDate32('1930-01-01'))), - toDate(toInt32(toDate32('2151-01-01'))), - toDate(toInt64(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'))), - toDate(toInt64(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'))), - toDate32(toInt32(toDate32('1900-01-01')) - 1), - toDate32(toInt32(toDate32('2299-12-31')) + 1), +SELECT toDate(toInt32(toDate32('1930-01-01', 'UTC')), 'UTC'), + toDate(toInt32(toDate32('2151-01-01', 'UTC')), 'UTC'), + toDate(toInt64(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC')), 'UTC'), + toDate(toInt64(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC')), 'UTC'), + toDate32(toInt32(toDate32('1900-01-01', 'UTC')) - 1, 'UTC'), + toDate32(toInt32(toDate32('2299-12-31', 'UTC')) + 1, 'UTC'), toDateTime(toInt64(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC')), 'UTC'), toDateTime(toInt64(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC')), 'UTC'); -- check conversion of extended range type to normal range type -- -SELECT toDate(toDate32('1930-01-01')), - toDate(toDate32('2151-01-01')); +SELECT toDate(toDate32('1930-01-01', 'UTC'), 'UTC'), + toDate(toDate32('2151-01-01', 'UTC'), 'UTC'); SELECT toDate(toDateTime64('1930-01-01 12:12:12.12', 3, 'UTC'), 'UTC'), toDate(toDateTime64('2151-01-01 12:12:12.12', 3, 'UTC'), 'UTC'); @@ -32,17 +32,17 @@ SELECT toStartOfDay(toDate('2141-01-01', 'UTC'), 'UTC'), toStartOfDay(toDateTime64('2141-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); SELECT 'toStartOfWeek'; -SELECT toStartOfWeek(toDate('1970-01-01')), - toStartOfWeek(toDate32('1970-01-01')), - toStartOfWeek(toDateTime('1970-01-01 10:10:10', 'UTC')), - toStartOfWeek(toDateTime64('1970-01-01 10:10:10.123', 3, 'UTC')), - toStartOfWeek(toDate32('1930-01-01')), - toStartOfWeek(toDate32('2151-01-01')), - toStartOfWeek(toDateTime64('1930-01-01 12:12:12.123', 3)), - toStartOfWeek(toDateTime64('2151-01-01 12:12:12.123', 3)); +SELECT toStartOfWeek(toDate('1970-01-01', 'UTC')), + toStartOfWeek(toDate32('1970-01-01', 'UTC')), + toStartOfWeek(toDateTime('1970-01-01 10:10:10', 'UTC'), 0, 'UTC'), + toStartOfWeek(toDateTime64('1970-01-01 10:10:10.123', 3, 'UTC'), 1, 'UTC'), + toStartOfWeek(toDate32('1930-01-01', 'UTC')), + toStartOfWeek(toDate32('2151-01-01', 'UTC')), + toStartOfWeek(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 2, 'UTC'), + toStartOfWeek(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 3, 'UTC'); SELECT 'toMonday'; -SELECT toMonday(toDate('1970-01-02')), +SELECT toMonday(toDate('1970-01-02', 'UTC')), toMonday(toDate32('1930-01-01', 'UTC')), toMonday(toDate32('2151-01-01', 'UTC')), toMonday(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'), @@ -55,7 +55,7 @@ SELECT toStartOfMonth(toDate32('1930-01-01', 'UTC')), toStartOfMonth(toDateTime64('2151-01-01 12:12:12.123', 3, 'UTC'), 'UTC'); SELECT 'toLastDayOfMonth'; -SELECT toLastDayOfMonth(toDate('2149-06-03')), +SELECT toLastDayOfMonth(toDate('2149-06-03', 'UTC')), toLastDayOfMonth(toDate32('1930-01-01', 'UTC')), toLastDayOfMonth(toDate32('2151-01-01', 'UTC')), toLastDayOfMonth(toDateTime64('1930-01-01 12:12:12.123', 3, 'UTC'), 'UTC'),