Some fixups

This commit is contained in:
Robert Schulze 2024-03-13 12:12:12 +00:00 committed by Jordi Villar
parent 368d01872f
commit 2cc801e74c
7 changed files with 42 additions and 43 deletions

View File

@ -4386,7 +4386,7 @@ Default value: `ignore`.
## first_day_of_week ## first_day_of_week
The first day of the week (Monday or Sunday) used by `toStartOfInterval` and `date_diff` functions when using weeks as units. The first day of the week assumed by functions [`toStartOfInterval`](../../sql-reference/functions/date-time-functions.md#toStartOfInterval) and [`dateDiff`](../../sql-reference/functions/date-time-functions.md#dateDiff) functions when using weeks as unit.
Possible values: Possible values:

View File

@ -1413,7 +1413,7 @@ toStartOfFifteenMinutes(toDateTime('2023-04-21 10:20:00')): 2023-04-21 10:15:00
toStartOfFifteenMinutes(toDateTime('2023-04-21 10:23:00')): 2023-04-21 10:15:00 toStartOfFifteenMinutes(toDateTime('2023-04-21 10:23:00')): 2023-04-21 10:15:00
``` ```
## toStartOfInterval(date_or_date_with_time, INTERVAL x unit \[, time_zone\]) ## toStartOfInterval
This function generalizes other `toStartOf*()` functions. For example, This function generalizes other `toStartOf*()` functions. For example,
- `toStartOfInterval(t, INTERVAL 1 year)` returns the same as `toStartOfYear(t)`, - `toStartOfInterval(t, INTERVAL 1 year)` returns the same as `toStartOfYear(t)`,
@ -1440,7 +1440,7 @@ The calculation is performed relative to specific points in time:
(*) hour intervals are special: the calculation is always performed relative to 00:00:00 (midnight) of the current day. As a result, only (*) hour intervals are special: the calculation is always performed relative to 00:00:00 (midnight) of the current day. As a result, only
hour values between 1 and 23 are useful. hour values between 1 and 23 are useful.
If unit `week` was specified, `toStartOfInterval` assumes that weeks start on Monday by default. You can change this behavior with [`first_day_of_week`](/docs/en/operations/settings/settings.md/#first-day-of-week) If unit `week` was specified, `toStartOfInterval` assumes by default that weeks start on Monday. You can change this behavior with setting [`first_day_of_week`](../../operations/settings/settings.md/#first-day-of-week)
**See Also** **See Also**
@ -1675,7 +1675,7 @@ Like [fromDaysSinceYearZero](#fromDaysSinceYearZero) but returns a [Date32](../.
Returns the `unit` component of the difference between `startdate` and `enddate`. The difference is calculated using a precision of 1 nanosecond. Returns the `unit` component of the difference between `startdate` and `enddate`. The difference is calculated using a precision of 1 nanosecond.
E.g. the difference between `2021-12-29` and `2022-01-01` is 3 days for `day` unit, 0 months for `month` unit, 0 years for `year` unit. E.g. the difference between `2021-12-29` and `2022-01-01` is 3 days for `day` unit, 0 months for `month` unit, 0 years for `year` unit.
For an alternative to `age`, see function `date\_diff`. For an alternative to `age`, see function `date_diff`.
**Syntax** **Syntax**
@ -1749,9 +1749,9 @@ Result:
Returns the count of the specified `unit` boundaries crossed between the `startdate` and the `enddate`. Returns the count of the specified `unit` boundaries crossed between the `startdate` and the `enddate`.
The difference is calculated using relative units, e.g. the difference between `2021-12-29` and `2022-01-01` is 3 days for unit `day` (see [toRelativeDayNum](#torelativedaynum)), 1 month for unit `month` (see [toRelativeMonthNum](#torelativemonthnum)) and 1 year for unit `year` (see [toRelativeYearNum](#torelativeyearnum)). The difference is calculated using relative units, e.g. the difference between `2021-12-29` and `2022-01-01` is 3 days for unit `day` (see [toRelativeDayNum](#torelativedaynum)), 1 month for unit `month` (see [toRelativeMonthNum](#torelativemonthnum)) and 1 year for unit `year` (see [toRelativeYearNum](#torelativeyearnum)).
If unit `week` was specified, `date\_diff` assumes that weeks start on Monday by default. You can change this behavior with [`first_day_of_week`](/docs/en/operations/settings/settings.md/#first-day-of-week) If unit `week` was specified, `date_diff` assumes by default that weeks start on Monday. You can change this behavior with setting [`first_day_of_week`](../../operations/settings/settings.md/#first-day-of-week)
For an alternative to `date\_diff`, see function `age`. For an alternative to `date_diff`, see function `age`.
**Syntax** **Syntax**

View File

@ -549,6 +549,7 @@ class IColumn;
M(Bool, formatdatetime_parsedatetime_m_is_month_name, true, "Formatter '%M' in functions 'formatDateTime()' and 'parseDateTime()' print/parse the month name instead of minutes.", 0) \ M(Bool, formatdatetime_parsedatetime_m_is_month_name, true, "Formatter '%M' in functions 'formatDateTime()' and 'parseDateTime()' print/parse the month name instead of minutes.", 0) \
M(Bool, parsedatetime_parse_without_leading_zeros, true, "Formatters '%c', '%l' and '%k' in function 'parseDateTime()' parse months and hours without leading zeros.", 0) \ M(Bool, parsedatetime_parse_without_leading_zeros, true, "Formatters '%c', '%l' and '%k' in function 'parseDateTime()' parse months and hours without leading zeros.", 0) \
M(Bool, formatdatetime_format_without_leading_zeros, false, "Formatters '%c', '%l' and '%k' in function 'formatDateTime()' print months and hours without leading zeros.", 0) \ M(Bool, formatdatetime_format_without_leading_zeros, false, "Formatters '%c', '%l' and '%k' in function 'formatDateTime()' print months and hours without leading zeros.", 0) \
M(FirstDayOfWeek, first_day_of_week, FirstDayOfWeek::Monday, "The first day of the week (Monday or Sunday) used by date/time functions (default: Monday).", 0) \
\ \
M(UInt64, max_partitions_per_insert_block, 100, "Limit maximum number of partitions in single INSERTed block. Zero means unlimited. Throw exception if the block contains too many partitions. This setting is a safety threshold, because using large number of partitions is a common misconception.", 0) \ M(UInt64, max_partitions_per_insert_block, 100, "Limit maximum number of partitions in single INSERTed block. Zero means unlimited. Throw exception if the block contains too many partitions. This setting is a safety threshold, because using large number of partitions is a common misconception.", 0) \
M(Bool, throw_on_max_partitions_per_insert_block, true, "Used with max_partitions_per_insert_block. If true (default), an exception will be thrown when max_partitions_per_insert_block is reached. If false, details of the insert query reaching this limit with the number of partitions will be logged. This can be useful if you're trying to understand the impact on users when changing max_partitions_per_insert_block.", 0) \ M(Bool, throw_on_max_partitions_per_insert_block, true, "Used with max_partitions_per_insert_block. If true (default), an exception will be thrown when max_partitions_per_insert_block is reached. If false, details of the insert query reaching this limit with the number of partitions will be logged. This can be useful if you're trying to understand the impact on users when changing max_partitions_per_insert_block.", 0) \
@ -1202,7 +1203,6 @@ class IColumn;
M(Bool, precise_float_parsing, false, "Prefer more precise (but slower) float parsing algorithm", 0) \ M(Bool, precise_float_parsing, false, "Prefer more precise (but slower) float parsing algorithm", 0) \
M(DateTimeOverflowBehavior, date_time_overflow_behavior, "ignore", "Overflow mode for Date, Date32, DateTime, DateTime64 types. Possible values: 'ignore', 'throw', 'saturate'.", 0) \ M(DateTimeOverflowBehavior, date_time_overflow_behavior, "ignore", "Overflow mode for Date, Date32, DateTime, DateTime64 types. Possible values: 'ignore', 'throw', 'saturate'.", 0) \
M(Bool, validate_experimental_and_suspicious_types_inside_nested_types, true, "Validate usage of experimental and suspicious types inside nested types like Array/Map/Tuple", 0) \ M(Bool, validate_experimental_and_suspicious_types_inside_nested_types, true, "Validate usage of experimental and suspicious types inside nested types like Array/Map/Tuple", 0) \
M(FirstDayOfWeek, first_day_of_week, FirstDayOfWeek::Monday, "The first day of the week (Monday or Sunday) used by date/time functions (default: Monday).", 0) \
// End of FORMAT_FACTORY_SETTINGS // End of FORMAT_FACTORY_SETTINGS

View File

@ -46,7 +46,7 @@ struct ToStartOfTransform;
{ {
static auto execute(UInt32 t, UInt64 delta, const DateLUTImpl & time_zone) static auto execute(UInt32 t, UInt64 delta, const DateLUTImpl & time_zone)
{ {
return time_zone.toStartOfWeekInterval(time_zone.toDayNum(t), delta, /*week_mode*/1); return time_zone.toStartOfWeekInterval(time_zone.toDayNum(t), delta, /*week_mode*/ 1);
} }
}; };

View File

@ -1,23 +1,25 @@
#include <Columns/ColumnDecimal.h>
#include <DataTypes/DataTypeDateTime.h>
#include <DataTypes/DataTypeDateTime64.h>
#include <DataTypes/DataTypesNumber.h>
#include <Common/IntervalKind.h>
#include <Columns/ColumnString.h> #include <Columns/ColumnString.h>
#include <Columns/ColumnsDateTime.h> #include <Columns/ColumnsDateTime.h>
#include <Columns/ColumnsNumber.h> #include <Columns/ColumnsNumber.h>
#include <Columns/ColumnDecimal.h> #include <Common/IntervalKind.h>
#include <Core/SettingsEnums.h> #include <Core/SettingsEnums.h>
#include <DataTypes/DataTypeDateTime.h>
#include <DataTypes/DataTypeDateTime64.h>
#include <DataTypes/DataTypesNumber.h>
#include <Functions/DateTimeTransforms.h>
#include <Formats/FormatSettings.h> #include <Formats/FormatSettings.h>
#include <Functions/IFunction.h> #include <Functions/IFunction.h>
#include <Functions/FunctionHelpers.h> #include <Functions/FunctionHelpers.h>
#include <Functions/FunctionFactory.h> #include <Functions/FunctionFactory.h>
#include <Functions/extractTimeZoneFromFunctionArguments.h> #include <Functions/extractTimeZoneFromFunctionArguments.h>
#include <Functions/DateTimeTransforms.h> #include <Functions/FunctionFactory.h>
#include <Functions/FunctionHelpers.h>
#include <Functions/IFunction.h>
#include <Functions/TransformDateTime64.h> #include <Functions/TransformDateTime64.h>
#include <Functions/extractTimeZoneFromFunctionArguments.h>
#include <Interpreters/Context.h>
#include <IO/WriteHelpers.h> #include <IO/WriteHelpers.h>
#include <Interpreters/Context.h>
#include <base/find_symbols.h> #include <base/find_symbols.h>
@ -173,10 +175,10 @@ public:
template <typename TransformX, typename TransformY, typename T1, typename T2> template <typename TransformX, typename TransformY, typename T1, typename T2>
Int64 calculate(const TransformX & transform_x, const TransformY & transform_y, T1 x, T2 y, const DateLUTImpl & timezone_x, const DateLUTImpl & timezone_y) const Int64 calculate(const TransformX & transform_x, const TransformY & transform_y, T1 x, T2 y, const DateLUTImpl & timezone_x, const DateLUTImpl & timezone_y) const
{ {
UInt8 week_mode = first_day_of_week == FirstDayOfWeek::Monday ? 0 : 3;
if constexpr (is_diff) if constexpr (is_diff)
{ {
const UInt8 week_mode = (first_day_of_week == FirstDayOfWeek::Monday) ? 0 : 3;
return static_cast<Int64>(transform_y.execute(y, timezone_y, week_mode)) return static_cast<Int64>(transform_y.execute(y, timezone_y, week_mode))
- static_cast<Int64>(transform_x.execute(x, timezone_x, week_mode)); - static_cast<Int64>(transform_x.execute(x, timezone_x, week_mode));
} }
@ -322,7 +324,7 @@ public:
} }
private: private:
String name; String name;
FirstDayOfWeek first_day_of_week; const FirstDayOfWeek first_day_of_week;
}; };
@ -344,7 +346,7 @@ public:
static FunctionPtr create(ContextPtr context) { return std::make_shared<FunctionDateDiff>(context); } static FunctionPtr create(ContextPtr context) { return std::make_shared<FunctionDateDiff>(context); }
explicit FunctionDateDiff(ContextPtr context) explicit FunctionDateDiff(ContextPtr context)
: first_day_of_week(context->getSettingsRef().first_day_of_week) : impl(name, context->getSettingsRef().first_day_of_week)
{ {
} }
@ -439,8 +441,7 @@ public:
return res; return res;
} }
private: private:
FirstDayOfWeek first_day_of_week; DateDiffImpl<is_relative> impl;
DateDiffImpl<is_relative> impl{name, first_day_of_week};
}; };

View File

@ -27,17 +27,14 @@ namespace ErrorCodes
class FunctionToStartOfInterval : public IFunction class FunctionToStartOfInterval : public IFunction
{ {
FirstDayOfWeek first_day_of_week;
public: public:
static FunctionPtr create(ContextPtr context) { return std::make_shared<FunctionToStartOfInterval>(context); } static constexpr auto name = "toStartOfInterval";
static FunctionPtr create(ContextPtr context) { return std::make_shared<FunctionToStartOfInterval>(context); }
explicit FunctionToStartOfInterval(ContextPtr context) explicit FunctionToStartOfInterval(ContextPtr context)
: first_day_of_week(context->getSettingsRef().first_day_of_week) : first_day_of_week(context->getSettingsRef().first_day_of_week)
{ {
} }
static constexpr auto name = "toStartOfInterval";
String getName() const override { return name; } String getName() const override { return name; }
bool isVariadic() const override { return true; } bool isVariadic() const override { return true; }
size_t getNumberOfArguments() const override { return 0; } size_t getNumberOfArguments() const override { return 0; }
@ -256,16 +253,16 @@ private:
auto & result_data = col_to->getData(); auto & result_data = col_to->getData();
result_data.resize(size); result_data.resize(size);
Int64 scale_multiplier = DecimalUtils::scaleMultiplier<DateTime64>(scale); const Int64 scale_multiplier = DecimalUtils::scaleMultiplier<DateTime64>(scale);
UInt8 week_mode = first_day_of_week == FirstDayOfWeek::Monday ? 1 : 0; const UInt8 week_mode = (first_day_of_week == FirstDayOfWeek::Monday) ? 1 : 0;
for (size_t i = 0; i != size; ++i) for (size_t i = 0; i != size; ++i)
{
result_data[i] = static_cast<ResultFieldType>(ToStartOfInterval<unit>::execute(time_data[i], num_units, scale_multiplier, week_mode, time_zone)); result_data[i] = static_cast<ResultFieldType>(ToStartOfInterval<unit>::execute(time_data[i], num_units, scale_multiplier, week_mode, time_zone));
}
return result_col; return result_col;
} }
const FirstDayOfWeek first_day_of_week;
}; };
REGISTER_FUNCTION(ToStartOfInterval) REGISTER_FUNCTION(ToStartOfInterval)

View File

@ -1,26 +1,28 @@
-- Testing setting behavior first_day_of_week. -- Testing behavior of date/time functions under setting 'first_day_of_week'.
-- It allows us to change `toStartOfInterval` and `date_diff` first day of week to Monday or Sunday
SELECT '-- toStartOfInterval'; SELECT '-- toStartOfInterval';
-- default behavior
SELECT SELECT
toDateTime('2024-01-02 00:00:00', 'UTC') dt, toDateTime('2024-01-02 00:00:00', 'UTC') dt,
toStartOfInterval(dt, INTERVAL 1 WEEK) w_1, -- Monday, Jan 01 toStartOfInterval(dt, INTERVAL 1 WEEK), -- Monday, Jan 01
toStartOfInterval(dt, INTERVAL 2 WEEK) w_2 -- Monday, Dec 25 toStartOfInterval(dt, INTERVAL 2 WEEK); -- Monday, Dec 25
;
SELECT SELECT
toDateTime('2024-01-02 00:00:00', 'UTC') dt, toDateTime('2024-01-02 00:00:00', 'UTC') dt,
toStartOfInterval(dt, INTERVAL 1 WEEK) w_1, -- Monday, Jan 01 toStartOfInterval(dt, INTERVAL 1 WEEK), -- Monday, Jan 01
toStartOfInterval(dt, INTERVAL 2 WEEK) w_2 -- Monday, Dec 25 toStartOfInterval(dt, INTERVAL 2 WEEK) -- Monday, Dec 25
SETTINGS first_day_of_week = 'Monday'; SETTINGS first_day_of_week = 'Monday';
SELECT SELECT
toDateTime('2024-01-02 00:00:00', 'UTC') dt, toDateTime('2024-01-02 00:00:00', 'UTC') dt,
toStartOfInterval(dt, INTERVAL 1 WEEK) w_1, -- Sunday, Dec 31 toStartOfInterval(dt, INTERVAL 1 WEEK), -- Sunday, Dec 31
toStartOfInterval(dt, INTERVAL 2 WEEK) w_2 -- Sunday, Dec 24 toStartOfInterval(dt, INTERVAL 2 WEEK) -- Sunday, Dec 24
SETTINGS first_day_of_week = 'Sunday'; SETTINGS first_day_of_week = 'Sunday';
SELECT '-- date_diff'; SELECT '-- date_diff';
-- default behavior
SELECT SELECT
toDateTime('2023-01-22 00:00:00', 'UTC') sunday, toDateTime('2023-01-22 00:00:00', 'UTC') sunday,
toDateTime('2023-01-23 00:00:00', 'UTC') monday, toDateTime('2023-01-23 00:00:00', 'UTC') monday,
@ -29,8 +31,7 @@ SELECT
dateDiff('week', sunday, monday), dateDiff('week', sunday, monday),
age('week', monday, tuesday), age('week', monday, tuesday),
age('week', sunday, monday), age('week', sunday, monday),
age('week', sunday, monday + toIntervalDay(10)) age('week', sunday, monday + toIntervalDay(10));
;
SELECT SELECT
toDateTime('2023-01-22 00:00:00', 'UTC') sunday, toDateTime('2023-01-22 00:00:00', 'UTC') sunday,