From e257f9d0cda4690fdfb1d911026a52f06094d6fd Mon Sep 17 00:00:00 2001 From: zvonand Date: Wed, 24 Aug 2022 00:44:08 +0300 Subject: [PATCH] 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')),