mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 09:32:01 +00:00
Merge pull request #41910 from arenadata/ADQM-583
Improve enable_extended_results_for_datetime_functions option to return results of type DateTime64
This commit is contained in:
commit
8e727d4fbc
@ -3147,12 +3147,14 @@ Result:
|
||||
|
||||
## enable_extended_results_for_datetime_functions {#enable-extended-results-for-datetime-functions}
|
||||
|
||||
Enables or disables returning results of type `Date32` with extended range (compared to type `Date`) for functions [toStartOfYear](../../sql-reference/functions/date-time-functions.md#tostartofyear), [toStartOfISOYear](../../sql-reference/functions/date-time-functions.md#tostartofisoyear), [toStartOfQuarter](../../sql-reference/functions/date-time-functions.md#tostartofquarter), [toStartOfMonth](../../sql-reference/functions/date-time-functions.md#tostartofmonth), [toStartOfWeek](../../sql-reference/functions/date-time-functions.md#tostartofweek), [toMonday](../../sql-reference/functions/date-time-functions.md#tomonday) and [toLastDayOfMonth](../../sql-reference/functions/date-time-functions.md#tolastdayofmonth).
|
||||
Enables or disables returning results of type:
|
||||
- `Date32` with extended range (compared to type `Date`) for functions [toStartOfYear](../../sql-reference/functions/date-time-functions.md#tostartofyear), [toStartOfISOYear](../../sql-reference/functions/date-time-functions.md#tostartofisoyear), [toStartOfQuarter](../../sql-reference/functions/date-time-functions.md#tostartofquarter), [toStartOfMonth](../../sql-reference/functions/date-time-functions.md#tostartofmonth), [toStartOfWeek](../../sql-reference/functions/date-time-functions.md#tostartofweek), [toMonday](../../sql-reference/functions/date-time-functions.md#tomonday) and [toLastDayOfMonth](../../sql-reference/functions/date-time-functions.md#tolastdayofmonth).
|
||||
- `DateTime64` with extended range (compared to type `DateTime`) for functions [toStartOfDay](../../sql-reference/functions/date-time-functions.md#tostartofday), [toStartOfHour](../../sql-reference/functions/date-time-functions.md#tostartofhour), [toStartOfMinute](../../sql-reference/functions/date-time-functions.md#tostartofminute), [toStartOfFiveMinutes](../../sql-reference/functions/date-time-functions.md#tostartoffiveminutes), [toStartOfTenMinutes](../../sql-reference/functions/date-time-functions.md#tostartoftenminutes), [toStartOfFifteenMinutes](../../sql-reference/functions/date-time-functions.md#tostartoffifteenminutes) and [timeSlot](../../sql-reference/functions/date-time-functions.md#timeslot).
|
||||
|
||||
Possible values:
|
||||
|
||||
- 0 — Functions return `Date` for all types of arguments.
|
||||
- 1 — Functions return `Date32` for `Date32` or `DateTime64` arguments and `Date` otherwise.
|
||||
- 0 — Functions return `Date` or `DateTime` for all types of arguments.
|
||||
- 1 — Functions return `Date32` or `DateTime64` for `Date32` or `DateTime64` arguments and `Date` or `DateTime` otherwise.
|
||||
|
||||
Default value: `0`.
|
||||
|
||||
|
@ -268,15 +268,17 @@ Result:
|
||||
```
|
||||
|
||||
:::note
|
||||
The return type of `toStartOf*`, `toLastDayOfMonth`, `toMonday` functions described below is determined by the configuration parameter [enable_extended_results_for_datetime_functions](../../operations/settings/settings#enable-extended-results-for-datetime-functions) which is `0` by default.
|
||||
The return type of `toStartOf*`, `toLastDayOfMonth`, `toMonday`, `timeSlot` functions described below is determined by the configuration parameter [enable_extended_results_for_datetime_functions](../../operations/settings/settings#enable-extended-results-for-datetime-functions) which is `0` by default.
|
||||
|
||||
Behavior for
|
||||
* `enable_extended_results_for_datetime_functions = 0`: Functions `toStartOf*`, `toLastDayOfMonth`, `toMonday` return `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:
|
||||
* `enable_extended_results_for_datetime_functions = 0`: Functions `toStartOfYear`, `toStartOfISOYear`, `toStartOfQuarter`, `toStartOfMonth`, `toStartOfWeek`, `toLastDayOfMonth`, `toMonday` return `Date` or `DateTime`. Functions `toStartOfDay`, `toStartOfHour`, `toStartOfFifteenMinutes`, `toStartOfTenMinutes`, `toStartOfFiveMinutes`, `toStartOfMinute`, `timeSlot` return `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.
|
||||
* 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.
|
||||
* If `toLastDayOfMonth` is called with an argument greater then `2149-05-31`, the result will be calculated from the argument `2149-05-31` instead.
|
||||
* `enable_extended_results_for_datetime_functions = 1`: Functions `toStartOfYear`, `toStartOfISOYear`, `toStartOfQuarter`, `toStartOfMonth`, `toStartOfWeek`, `toLastDayOfMonth`, `toMonday` return `Date` or `DateTime` if their argument is a `Date` or `DateTime`, and they return `Date32` or `DateTime64` if their argument is a `Date32` or `DateTime64`.
|
||||
* `enable_extended_results_for_datetime_functions = 1`:
|
||||
* Functions `toStartOfYear`, `toStartOfISOYear`, `toStartOfQuarter`, `toStartOfMonth`, `toStartOfWeek`, `toLastDayOfMonth`, `toMonday` return `Date` or `DateTime` if their argument is a `Date` or `DateTime`, and they return `Date32` or `DateTime64` if their argument is a `Date32` or `DateTime64`.
|
||||
* Functions `toStartOfDay`, `toStartOfHour`, `toStartOfFifteenMinutes`, `toStartOfTenMinutes`, `toStartOfFiveMinutes`, `toStartOfMinute`, `timeSlot` return `DateTime` if their argument is a `Date` or `DateTime`, and they return `DateTime64` if their argument is a `Date32` or `DateTime64`.
|
||||
:::
|
||||
|
||||
## toStartOfYear
|
||||
|
@ -3799,17 +3799,6 @@ Exception: Total regexp lengths too large.
|
||||
|
||||
Значение по умолчанию: `1`.
|
||||
|
||||
## enable_extended_results_for_datetime_functions {#enable-extended-results-for-datetime-functions}
|
||||
|
||||
Включает или отключает возвращение результатов типа `Date32` с расширенным диапазоном (по сравнению с типом `Date`) для функций [toStartOfYear](../../sql-reference/functions/date-time-functions.md#tostartofyear), [toStartOfISOYear](../../sql-reference/functions/date-time-functions.md#tostartofisoyear), [toStartOfQuarter](../../sql-reference/functions/date-time-functions.md#tostartofquarter), [toStartOfMonth](../../sql-reference/functions/date-time-functions.md#tostartofmonth), [toStartOfWeek](../../sql-reference/functions/date-time-functions.md#tostartofweek), [toMonday](../../sql-reference/functions/date-time-functions.md#tomonday) и [toLastDayOfMonth](../../sql-reference/functions/date-time-functions.md#tolastdayofmonth).
|
||||
|
||||
Возможные значения:
|
||||
|
||||
- 0 — Функции возвращают результаты типа `Date` для всех типов аргументов.
|
||||
- 1 — Функции возвращают результаты типа `Date32` для аргументов типа `Date32` или `DateTime64` и возвращают `Date` в других случаях.
|
||||
|
||||
Значение по умолчанию: `0`.
|
||||
|
||||
**Пример**
|
||||
|
||||
Запрос:
|
||||
@ -3832,6 +3821,19 @@ SELECT * FROM positional_arguments ORDER BY 2,3;
|
||||
└─────┴─────┴───────┘
|
||||
```
|
||||
|
||||
## enable_extended_results_for_datetime_functions {#enable-extended-results-for-datetime-functions}
|
||||
|
||||
Включает или отключает возвращение результатов типа:
|
||||
- `Date32` с расширенным диапазоном (по сравнению с типом `Date`) для функций [toStartOfYear](../../sql-reference/functions/date-time-functions.md#tostartofyear), [toStartOfISOYear](../../sql-reference/functions/date-time-functions.md#tostartofisoyear), [toStartOfQuarter](../../sql-reference/functions/date-time-functions.md#tostartofquarter), [toStartOfMonth](../../sql-reference/functions/date-time-functions.md#tostartofmonth), [toStartOfWeek](../../sql-reference/functions/date-time-functions.md#tostartofweek), [toMonday](../../sql-reference/functions/date-time-functions.md#tomonday) и [toLastDayOfMonth](../../sql-reference/functions/date-time-functions.md#tolastdayofmonth).
|
||||
- `DateTime64` с расширенным диапазоном (по сравнению с типом `DateTime`) для функций [toStartOfDay](../../sql-reference/functions/date-time-functions.md#tostartofday), [toStartOfHour](../../sql-reference/functions/date-time-functions.md#tostartofhour), [toStartOfMinute](../../sql-reference/functions/date-time-functions.md#tostartofminute), [toStartOfFiveMinutes](../../sql-reference/functions/date-time-functions.md#tostartoffiveminutes), [toStartOfTenMinutes](../../sql-reference/functions/date-time-functions.md#tostartoftenminutes), [toStartOfFifteenMinutes](../../sql-reference/functions/date-time-functions.md#tostartoffifteenminutes) и [timeSlot](../../sql-reference/functions/date-time-functions.md#timeslot).
|
||||
|
||||
Возможные значения:
|
||||
|
||||
- 0 — Функции возвращают результаты типа `Date` или `DateTime` для всех типов аргументов.
|
||||
- 1 — Функции возвращают результаты типа `Date32` или `DateTime64` для аргументов типа `Date32` или `DateTime64` и возвращают `Date` или `DateTime` в других случаях.
|
||||
|
||||
Значение по умолчанию: `0`.
|
||||
|
||||
## optimize_move_to_prewhere {#optimize_move_to_prewhere}
|
||||
|
||||
Включает или отключает автоматическую оптимизацию [PREWHERE](../../sql-reference/statements/select/prewhere.md) в запросах [SELECT](../../sql-reference/statements/select/index.md).
|
||||
|
@ -268,16 +268,19 @@ SELECT toUnixTimestamp('2017-11-05 08:07:47', 'Asia/Tokyo') AS unix_timestamp;
|
||||
```
|
||||
|
||||
:::note
|
||||
Тип возвращаемого значения описанными далее функциями `toStartOf*`, `toLastDayOfMonth`, `toMonday` определяется конфигурационным параметром [enable_extended_results_for_datetime_functions](../../operations/settings/settings#enable-extended-results-for-datetime-functions) имеющим по умолчанию значение `0`.
|
||||
Тип возвращаемого значения описанными далее функциями `toStartOf*`, `toLastDayOfMonth`, `toMonday`, `timeSlot` определяется конфигурационным параметром [enable_extended_results_for_datetime_functions](../../operations/settings/settings#enable-extended-results-for-datetime-functions) имеющим по умолчанию значение `0`.
|
||||
|
||||
Поведение для
|
||||
* `enable_extended_results_for_datetime_functions = 0`: Функции `toStartOf*`, `toLastDayOfMonth`, `toMonday` возвращают `Date` или `DateTime`. Хотя эти функции могут принимать значения типа `Date32` или `DateTime64` в качестве аргумента, при обработке аргумента вне нормального диапазона значений (`1970` - `2148` для `Date` и `1970-01-01 00:00:00`-`2106-02-07 08:28:15` для `DateTime`) будет получен некорректный результат.
|
||||
* `enable_extended_results_for_datetime_functions = 0`: Функции `toStartOf*`, `toLastDayOfMonth`, `toMonday` возвращают `Date` или `DateTime`. Функции `toStartOfDay`, `toStartOfHour`, `toStartOfFifteenMinutes`, `toStartOfTenMinutes`, `toStartOfFiveMinutes`, `toStartOfMinute`, `timeSlot` возвращают `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-05-31` будет результатом функции `toLastDayOfMonth` при обработке аргумента больше `2149-05-31`.
|
||||
* `enable_extended_results_for_datetime_functions = 1`: Функции `toStartOfYear`, `toStartOfISOYear`, `toStartOfQuarter`, `toStartOfMonth`, `toStartOfWeek`, `toLastDayOfMonth`, `toMonday` возвращают `Date` или `DateTime` если их аргумент `Date` или `DateTime` и они возвращают `Date32` или `DateTime64` если их аргумент `Date32` или `DateTime64`.
|
||||
* `enable_extended_results_for_datetime_functions = 1`:
|
||||
* Функции `toStartOfYear`, `toStartOfISOYear`, `toStartOfQuarter`, `toStartOfMonth`, `toStartOfWeek`, `toLastDayOfMonth`, `toMonday` возвращают `Date` или `DateTime` если их аргумент `Date` или `DateTime` и они возвращают `Date32` или `DateTime64` если их аргумент `Date32` или `DateTime64`.
|
||||
* Функции `toStartOfDay`, `toStartOfHour`, `toStartOfFifteenMinutes`, `toStartOfTenMinutes`, `toStartOfFiveMinutes`, `toStartOfMinute`, `timeSlot` возвращают `DateTime` если их аргумент `Date` или `DateTime` и они возвращают `DateTime64` если их аргумент `Date32` или `DateTime64`.
|
||||
|
||||
:::
|
||||
|
||||
## toStartOfYear {#tostartofyear}
|
||||
|
@ -1030,7 +1030,7 @@ public:
|
||||
template <typename DateOrTime>
|
||||
DateOrTime toStartOfMinuteInterval(DateOrTime t, UInt64 minutes) const
|
||||
{
|
||||
UInt64 divisor = 60 * minutes;
|
||||
Int64 divisor = 60 * minutes;
|
||||
if (likely(offset_is_whole_number_of_minutes_during_epoch))
|
||||
{
|
||||
if (likely(t >= 0))
|
||||
|
@ -82,11 +82,11 @@ struct ToStartOfWeekImpl
|
||||
{
|
||||
return time_zone.toFirstDayNumOfWeek(DayNum(d), week_mode);
|
||||
}
|
||||
static inline Int64 execute_extended_result(Int64 t, UInt8 week_mode, const DateLUTImpl & time_zone)
|
||||
static inline Int64 executeExtendedResult(Int64 t, UInt8 week_mode, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfWeek(time_zone.toDayNum(t), week_mode);
|
||||
}
|
||||
static inline Int32 execute_extended_result(Int32 d, UInt8 week_mode, const DateLUTImpl & time_zone)
|
||||
static inline Int32 executeExtendedResult(Int32 d, UInt8 week_mode, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(d), week_mode);
|
||||
}
|
||||
@ -139,7 +139,7 @@ struct WeekTransformer
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
if constexpr (is_extended_result)
|
||||
vec_to[i] = transform.execute_extended_result(vec_from[i], week_mode, time_zone);
|
||||
vec_to[i] = transform.executeExtendedResult(vec_from[i], week_mode, time_zone);
|
||||
else
|
||||
vec_to[i] = transform.execute(vec_from[i], week_mode, time_zone);
|
||||
}
|
||||
@ -174,10 +174,9 @@ struct CustomWeekTransformImpl
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception(
|
||||
"Illegal column " + arguments[0].column->getName() + " of first argument of function "
|
||||
+ Transform::name,
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
throw Exception(ErrorCodes::ILLEGAL_COLUMN,
|
||||
"Illegal column {} of first argument of function {}",
|
||||
arguments[0].column->getName(), Transform::name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -38,12 +38,17 @@ namespace ErrorCodes
|
||||
|
||||
static inline UInt32 dateIsNotSupported(const char * name)
|
||||
{
|
||||
throw Exception("Illegal type Date of argument for function " + std::string(name), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type Date of argument for function {}", name);
|
||||
}
|
||||
|
||||
static inline UInt32 dateTimeIsNotSupported(const char * name)
|
||||
{
|
||||
throw Exception("Illegal type DateTime of argument for function " + std::string(name), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type DateTime of argument for function {}", name);
|
||||
}
|
||||
|
||||
static inline Int64 date32IsNotSupported(const char * name)
|
||||
{
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type Date32 of argument for function {}", name);
|
||||
}
|
||||
|
||||
/// This factor transformation will say that the function is monotone everywhere.
|
||||
@ -108,7 +113,6 @@ struct ToStartOfDayImpl
|
||||
{
|
||||
static constexpr auto name = "toStartOfDay";
|
||||
|
||||
//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<DateTime64> & t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
if (t.whole < 0 || (t.whole >= 0 && t.fractional < 0))
|
||||
@ -136,6 +140,14 @@ struct ToStartOfDayImpl
|
||||
auto date_time = time_zone.fromDayNum(ExtendedDayNum(d));
|
||||
return date_time < 0xffffffff ? date_time : time_zone.toDate(0xffffffff);
|
||||
}
|
||||
static inline DecimalUtils::DecimalComponents<DateTime64> executeExtendedResult(const DecimalUtils::DecimalComponents<DateTime64> & t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return {time_zone.toDate(t.whole), 0};
|
||||
}
|
||||
static inline Int64 executeExtendedResult(Int32 d, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.fromDayNum(ExtendedDayNum(d)) * DecimalUtils::scaleMultiplier<DateTime64>(DataTypeDateTime64::default_scale);
|
||||
}
|
||||
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
@ -161,11 +173,11 @@ struct ToMondayImpl
|
||||
{
|
||||
return time_zone.toFirstDayNumOfWeek(DayNum(d));
|
||||
}
|
||||
static inline Int64 execute_extended_result(Int64 t, const DateLUTImpl & time_zone)
|
||||
static inline Int64 executeExtendedResult(Int64 t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfWeek(time_zone.toDayNum(t));
|
||||
}
|
||||
static inline Int32 execute_extended_result(Int32 d, const DateLUTImpl & time_zone)
|
||||
static inline Int32 executeExtendedResult(Int32 d, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(d));
|
||||
}
|
||||
@ -192,11 +204,11 @@ struct ToStartOfMonthImpl
|
||||
{
|
||||
return time_zone.toFirstDayNumOfMonth(DayNum(d));
|
||||
}
|
||||
static inline Int64 execute_extended_result(Int64 t, const DateLUTImpl & time_zone)
|
||||
static inline Int64 executeExtendedResult(Int64 t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfMonth(time_zone.toDayNum(t));
|
||||
}
|
||||
static inline Int32 execute_extended_result(Int32 d, const DateLUTImpl & time_zone)
|
||||
static inline Int32 executeExtendedResult(Int32 d, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfMonth(ExtendedDayNum(d));
|
||||
}
|
||||
@ -233,11 +245,11 @@ struct ToLastDayOfMonthImpl
|
||||
/// 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))));
|
||||
}
|
||||
static inline Int64 execute_extended_result(Int64 t, const DateLUTImpl & time_zone)
|
||||
static inline Int64 executeExtendedResult(Int64 t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfMonth(time_zone.toDayNum(t));
|
||||
}
|
||||
static inline Int32 execute_extended_result(Int32 d, const DateLUTImpl & time_zone)
|
||||
static inline Int32 executeExtendedResult(Int32 d, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfMonth(ExtendedDayNum(d));
|
||||
}
|
||||
@ -264,11 +276,11 @@ struct ToStartOfQuarterImpl
|
||||
{
|
||||
return time_zone.toFirstDayNumOfQuarter(DayNum(d));
|
||||
}
|
||||
static inline Int64 execute_extended_result(Int64 t, const DateLUTImpl & time_zone)
|
||||
static inline Int64 executeExtendedResult(Int64 t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfQuarter(time_zone.toDayNum(t));
|
||||
}
|
||||
static inline Int32 execute_extended_result(Int32 d, const DateLUTImpl & time_zone)
|
||||
static inline Int32 executeExtendedResult(Int32 d, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(d));
|
||||
}
|
||||
@ -295,11 +307,11 @@ struct ToStartOfYearImpl
|
||||
{
|
||||
return time_zone.toFirstDayNumOfYear(DayNum(d));
|
||||
}
|
||||
static inline Int64 execute_extended_result(Int64 t, const DateLUTImpl & time_zone)
|
||||
static inline Int64 executeExtendedResult(Int64 t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfYear(time_zone.toDayNum(t));
|
||||
}
|
||||
static inline Int32 execute_extended_result(Int32 d, const DateLUTImpl & time_zone)
|
||||
static inline Int32 executeExtendedResult(Int32 d, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfYear(ExtendedDayNum(d));
|
||||
}
|
||||
@ -356,6 +368,14 @@ struct ToStartOfMinuteImpl
|
||||
{
|
||||
return dateIsNotSupported(name);
|
||||
}
|
||||
static inline DecimalUtils::DecimalComponents<DateTime64> executeExtendedResult(const DecimalUtils::DecimalComponents<DateTime64> & t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return {time_zone.toStartOfMinute(t.whole), 0};
|
||||
}
|
||||
static inline Int64 executeExtendedResult(Int32, const DateLUTImpl &)
|
||||
{
|
||||
return date32IsNotSupported(name);
|
||||
}
|
||||
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
@ -385,7 +405,7 @@ struct ToStartOfSecondImpl
|
||||
|
||||
static inline UInt32 execute(UInt32, const DateLUTImpl &)
|
||||
{
|
||||
throw Exception("Illegal type DateTime of argument for function " + std::string(name), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type DateTime of argument for function {}", name);
|
||||
}
|
||||
static inline UInt32 execute(Int32, const DateLUTImpl &)
|
||||
{
|
||||
@ -432,7 +452,7 @@ struct ToStartOfMillisecondImpl
|
||||
|
||||
static inline UInt32 execute(UInt32, const DateLUTImpl &)
|
||||
{
|
||||
throw Exception("Illegal type DateTime of argument for function " + std::string(name), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type DateTime of argument for function {}", name);
|
||||
}
|
||||
static inline UInt32 execute(Int32, const DateLUTImpl &)
|
||||
{
|
||||
@ -475,7 +495,7 @@ struct ToStartOfMicrosecondImpl
|
||||
|
||||
static inline UInt32 execute(UInt32, const DateLUTImpl &)
|
||||
{
|
||||
throw Exception("Illegal type DateTime of argument for function " + std::string(name), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type DateTime of argument for function {}", name);
|
||||
}
|
||||
static inline UInt32 execute(Int32, const DateLUTImpl &)
|
||||
{
|
||||
@ -506,13 +526,13 @@ struct ToStartOfNanosecondImpl
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception("Illegal type of argument for function " + std::string(name) + ", DateTime64 expected", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type of argument for function {}, DateTime64 expected", name);
|
||||
}
|
||||
}
|
||||
|
||||
static inline UInt32 execute(UInt32, const DateLUTImpl &)
|
||||
{
|
||||
throw Exception("Illegal type DateTime of argument for function " + std::string(name), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Illegal type DateTime of argument for function {}", name);
|
||||
}
|
||||
static inline UInt32 execute(Int32, const DateLUTImpl &)
|
||||
{
|
||||
@ -546,6 +566,14 @@ struct ToStartOfFiveMinutesImpl
|
||||
{
|
||||
return dateIsNotSupported(name);
|
||||
}
|
||||
static inline DecimalUtils::DecimalComponents<DateTime64> executeExtendedResult(const DecimalUtils::DecimalComponents<DateTime64> & t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return {time_zone.toStartOfFiveMinutes(t.whole), 0};
|
||||
}
|
||||
static inline Int64 executeExtendedResult(Int32, const DateLUTImpl &)
|
||||
{
|
||||
return date32IsNotSupported(name);
|
||||
}
|
||||
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
@ -570,6 +598,14 @@ struct ToStartOfTenMinutesImpl
|
||||
{
|
||||
return dateIsNotSupported(name);
|
||||
}
|
||||
static inline DecimalUtils::DecimalComponents<DateTime64> executeExtendedResult(const DecimalUtils::DecimalComponents<DateTime64> & t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return {time_zone.toStartOfTenMinutes(t.whole), 0};
|
||||
}
|
||||
static inline Int64 executeExtendedResult(Int32, const DateLUTImpl &)
|
||||
{
|
||||
return date32IsNotSupported(name);
|
||||
}
|
||||
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
@ -594,6 +630,14 @@ struct ToStartOfFifteenMinutesImpl
|
||||
{
|
||||
return dateIsNotSupported(name);
|
||||
}
|
||||
static inline DecimalUtils::DecimalComponents<DateTime64> executeExtendedResult(const DecimalUtils::DecimalComponents<DateTime64> & t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return {time_zone.toStartOfFifteenMinutes(t.whole), 0};
|
||||
}
|
||||
static inline Int64 executeExtendedResult(Int32, const DateLUTImpl &)
|
||||
{
|
||||
return date32IsNotSupported(name);
|
||||
}
|
||||
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
@ -603,7 +647,6 @@ struct TimeSlotImpl
|
||||
{
|
||||
static constexpr auto name = "timeSlot";
|
||||
|
||||
//static inline DecimalUtils::DecimalComponents<DateTime64> execute(const DecimalUtils::DecimalComponents<DateTime64> & t, const DateLUTImpl &)
|
||||
static inline UInt32 execute(const DecimalUtils::DecimalComponents<DateTime64> & t, const DateLUTImpl &)
|
||||
{
|
||||
return t.whole / 1800 * 1800;
|
||||
@ -624,6 +667,18 @@ struct TimeSlotImpl
|
||||
return dateIsNotSupported(name);
|
||||
}
|
||||
|
||||
static inline DecimalUtils::DecimalComponents<DateTime64> executeExtendedResult(const DecimalUtils::DecimalComponents<DateTime64> & t, const DateLUTImpl &)
|
||||
{
|
||||
if (likely(t.whole >= 0))
|
||||
return {t.whole / 1800 * 1800, 0};
|
||||
return {(t.whole + 1 - 1800) / 1800 * 1800, 0};
|
||||
}
|
||||
|
||||
static inline Int64 executeExtendedResult(Int32, const DateLUTImpl &)
|
||||
{
|
||||
return date32IsNotSupported(name);
|
||||
}
|
||||
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
|
||||
@ -654,6 +709,16 @@ struct ToStartOfHourImpl
|
||||
return dateIsNotSupported(name);
|
||||
}
|
||||
|
||||
static inline DecimalUtils::DecimalComponents<DateTime64> executeExtendedResult(const DecimalUtils::DecimalComponents<DateTime64> & t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return {time_zone.toStartOfHour(t.whole), 0};
|
||||
}
|
||||
|
||||
static inline Int64 executeExtendedResult(Int32, const DateLUTImpl &)
|
||||
{
|
||||
return date32IsNotSupported(name);
|
||||
}
|
||||
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
|
||||
@ -944,11 +1009,11 @@ struct ToStartOfISOYearImpl
|
||||
{
|
||||
return time_zone.toFirstDayNumOfISOYear(DayNum(d));
|
||||
}
|
||||
static inline Int64 execute_extended_result(Int64 t, const DateLUTImpl & time_zone)
|
||||
static inline Int64 executeExtendedResult(Int64 t, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfISOYear(time_zone.toDayNum(t));
|
||||
}
|
||||
static inline Int32 execute_extended_result(Int32 d, const DateLUTImpl & time_zone)
|
||||
static inline Int32 executeExtendedResult(Int32 d, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toFirstDayNumOfISOYear(ExtendedDayNum(d));
|
||||
}
|
||||
@ -1257,7 +1322,7 @@ struct Transformer
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
if constexpr (is_extended_result)
|
||||
vec_to[i] = transform.execute_extended_result(vec_from[i], time_zone);
|
||||
vec_to[i] = transform.executeExtendedResult(vec_from[i], time_zone);
|
||||
else
|
||||
vec_to[i] = transform.execute(vec_from[i], time_zone);
|
||||
}
|
||||
@ -1298,9 +1363,9 @@ struct DateTimeTransformImpl
|
||||
}
|
||||
else
|
||||
{
|
||||
throw Exception("Illegal column " + arguments[0].column->getName()
|
||||
+ " of first argument of function " + Transform::name,
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
throw Exception(ErrorCodes::ILLEGAL_COLUMN,
|
||||
"Illegal column {} of first argument of function {}",
|
||||
arguments[0].column->getName(), Transform::name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -10,19 +10,19 @@ namespace ErrorCodes
|
||||
}
|
||||
|
||||
template <typename Transform>
|
||||
class FunctionCustomWeekToDateOrDate32 : public IFunctionCustomWeek<Transform>, WithContext
|
||||
class FunctionCustomWeekToDateOrDate32 : public IFunctionCustomWeek<Transform>
|
||||
{
|
||||
public:
|
||||
private:
|
||||
const bool enable_extended_results_for_datetime_functions = false;
|
||||
|
||||
public:
|
||||
static FunctionPtr create(ContextPtr context_)
|
||||
{
|
||||
return std::make_shared<FunctionCustomWeekToDateOrDate32>(context_);
|
||||
}
|
||||
|
||||
explicit FunctionCustomWeekToDateOrDate32(ContextPtr context_)
|
||||
: WithContext(context_)
|
||||
, enable_extended_results_for_datetime_functions(context_->getSettingsRef().enable_extended_results_for_datetime_functions)
|
||||
: enable_extended_results_for_datetime_functions(context_->getSettingsRef().enable_extended_results_for_datetime_functions)
|
||||
{
|
||||
}
|
||||
|
||||
@ -47,12 +47,14 @@ public:
|
||||
return CustomWeekTransformImpl<DataTypeDate, DataTypeDate>::execute(
|
||||
arguments, result_type, input_rows_count, Transform{});
|
||||
else if (which.isDate32())
|
||||
{
|
||||
if (enable_extended_results_for_datetime_functions)
|
||||
return CustomWeekTransformImpl<DataTypeDate32, DataTypeDate32, /*is_extended_result*/ true>::execute(
|
||||
arguments, result_type, input_rows_count, Transform{});
|
||||
else
|
||||
return CustomWeekTransformImpl<DataTypeDate32, DataTypeDate>::execute(
|
||||
arguments, result_type, input_rows_count, Transform{});
|
||||
}
|
||||
else if (which.isDateTime())
|
||||
return CustomWeekTransformImpl<DataTypeDateTime, DataTypeDate>::execute(
|
||||
arguments, result_type, input_rows_count, Transform{});
|
||||
@ -68,9 +70,9 @@ public:
|
||||
TransformDateTime64<Transform>{assert_cast<const DataTypeDateTime64 *>(from_type)->getScale()});
|
||||
}
|
||||
else
|
||||
throw Exception(
|
||||
"Illegal type " + arguments[0].type->getName() + " of argument of function " + this->getName(),
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}",
|
||||
arguments[0].type->getName(), this->getName());
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -45,9 +45,9 @@ public:
|
||||
TransformDateTime64<Transform>{assert_cast<const DataTypeDateTime64 *>(from_type)->getScale()});
|
||||
}
|
||||
else
|
||||
throw Exception(
|
||||
"Illegal type " + arguments[0].type->getName() + " of argument of function " + this->getName(),
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}",
|
||||
arguments[0].type->getName(), this->getName());
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -10,19 +10,19 @@ namespace ErrorCodes
|
||||
}
|
||||
|
||||
template <typename Transform>
|
||||
class FunctionDateOrDateTimeToDateOrDate32 : public IFunctionDateOrDateTime<Transform>, WithContext
|
||||
class FunctionDateOrDateTimeToDateOrDate32 : public IFunctionDateOrDateTime<Transform>
|
||||
{
|
||||
public:
|
||||
private:
|
||||
const bool enable_extended_results_for_datetime_functions = false;
|
||||
|
||||
public:
|
||||
static FunctionPtr create(ContextPtr context_)
|
||||
{
|
||||
return std::make_shared<FunctionDateOrDateTimeToDateOrDate32>(context_);
|
||||
}
|
||||
|
||||
explicit FunctionDateOrDateTimeToDateOrDate32(ContextPtr context_)
|
||||
: WithContext(context_)
|
||||
, enable_extended_results_for_datetime_functions(context_->getSettingsRef().enable_extended_results_for_datetime_functions)
|
||||
: enable_extended_results_for_datetime_functions(context_->getSettingsRef().enable_extended_results_for_datetime_functions)
|
||||
{
|
||||
}
|
||||
|
||||
@ -37,9 +37,9 @@ public:
|
||||
/// only validate the time_zone part if the number of arguments is 2.
|
||||
if ((which.isDateTime() || which.isDateTime64()) && arguments.size() == 2
|
||||
&& extractTimeZoneNameFromFunctionArguments(arguments, 1, 0).empty())
|
||||
throw Exception(
|
||||
"Function " + this->getName() + " supports a 2nd argument (optional) that must be non-empty and be a valid time zone",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Function {} supports a 2nd argument (optional) that must be a valid time zone",
|
||||
this->getName());
|
||||
|
||||
if ((which.isDate32() || which.isDateTime64()) && enable_extended_results_for_datetime_functions)
|
||||
return std::make_shared<DataTypeDate32>();
|
||||
@ -55,10 +55,12 @@ public:
|
||||
if (which.isDate())
|
||||
return DateTimeTransformImpl<DataTypeDate, DataTypeDate, Transform>::execute(arguments, result_type, input_rows_count);
|
||||
else if (which.isDate32())
|
||||
{
|
||||
if (enable_extended_results_for_datetime_functions)
|
||||
return DateTimeTransformImpl<DataTypeDate32, DataTypeDate32, Transform, /*is_extended_result*/ true>::execute(arguments, result_type, input_rows_count);
|
||||
else
|
||||
return DateTimeTransformImpl<DataTypeDate32, DataTypeDate, Transform>::execute(arguments, result_type, input_rows_count);
|
||||
}
|
||||
else if (which.isDateTime())
|
||||
return DateTimeTransformImpl<DataTypeDateTime, DataTypeDate, Transform>::execute(arguments, result_type, input_rows_count);
|
||||
else if (which.isDateTime64())
|
||||
@ -72,8 +74,9 @@ public:
|
||||
return DateTimeTransformImpl<DataTypeDateTime64, DataTypeDate, decltype(transformer)>::execute(arguments, result_type, input_rows_count, transformer);
|
||||
}
|
||||
else
|
||||
throw Exception("Illegal type " + arguments[0].type->getName() + " of argument of function " + this->getName(),
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}",
|
||||
arguments[0].type->getName(), this->getName());
|
||||
}
|
||||
|
||||
};
|
||||
|
93
src/Functions/FunctionDateOrDateTimeToDateTimeOrDateTime64.h
Normal file
93
src/Functions/FunctionDateOrDateTimeToDateTimeOrDateTime64.h
Normal file
@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
#include <Functions/IFunctionDateOrDateTime.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
}
|
||||
|
||||
template <typename Transform>
|
||||
class FunctionDateOrDateTimeToDateTimeOrDateTime64 : public IFunctionDateOrDateTime<Transform>
|
||||
{
|
||||
private:
|
||||
const bool enable_extended_results_for_datetime_functions = false;
|
||||
|
||||
public:
|
||||
static FunctionPtr create(ContextPtr context_)
|
||||
{
|
||||
return std::make_shared<FunctionDateOrDateTimeToDateTimeOrDateTime64>(context_);
|
||||
}
|
||||
|
||||
explicit FunctionDateOrDateTimeToDateTimeOrDateTime64(ContextPtr context_)
|
||||
: enable_extended_results_for_datetime_functions(context_->getSettingsRef().enable_extended_results_for_datetime_functions)
|
||||
{
|
||||
}
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
this->checkArguments(arguments, /*is_result_type_date_or_date32*/ false);
|
||||
|
||||
const IDataType * from_type = arguments[0].type.get();
|
||||
|
||||
WhichDataType which(from_type);
|
||||
|
||||
std::string time_zone = extractTimeZoneNameFromFunctionArguments(arguments, 1, 0);
|
||||
|
||||
/// If the time zone is specified but empty, throw an exception.
|
||||
/// only validate the time_zone part if the number of arguments is 2.
|
||||
if (arguments.size() == 2 && time_zone.empty())
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Function {} supports a 2nd argument (optional) that must be a valid time zone",
|
||||
this->getName());
|
||||
|
||||
if ((which.isDate32() || which.isDateTime64()) && enable_extended_results_for_datetime_functions)
|
||||
{
|
||||
Int64 scale = DataTypeDateTime64::default_scale;
|
||||
if (which.isDateTime64())
|
||||
{
|
||||
if (const auto * dt64 = checkAndGetDataType<DataTypeDateTime64>(arguments[0].type.get()))
|
||||
scale = dt64->getScale();
|
||||
}
|
||||
return std::make_shared<DataTypeDateTime64>(scale, time_zone);
|
||||
}
|
||||
else
|
||||
return std::make_shared<DataTypeDateTime>(time_zone);
|
||||
}
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override
|
||||
{
|
||||
const IDataType * from_type = arguments[0].type.get();
|
||||
WhichDataType which(from_type);
|
||||
if (which.isDate())
|
||||
return DateTimeTransformImpl<DataTypeDate, DataTypeDateTime, Transform>::execute(arguments, result_type, input_rows_count);
|
||||
else if (which.isDate32())
|
||||
{
|
||||
if (enable_extended_results_for_datetime_functions)
|
||||
return DateTimeTransformImpl<DataTypeDate32, DataTypeDateTime64, Transform, /*is_extended_result*/ true>::execute(arguments, result_type, input_rows_count);
|
||||
else
|
||||
return DateTimeTransformImpl<DataTypeDate32, DataTypeDateTime, Transform>::execute(arguments, result_type, input_rows_count);
|
||||
}
|
||||
else if (which.isDateTime())
|
||||
return DateTimeTransformImpl<DataTypeDateTime, DataTypeDateTime, Transform>::execute(arguments, result_type, input_rows_count);
|
||||
else if (which.isDateTime64())
|
||||
{
|
||||
const auto scale = static_cast<const DataTypeDateTime64 *>(from_type)->getScale();
|
||||
|
||||
const TransformDateTime64<Transform> transformer(scale);
|
||||
if (enable_extended_results_for_datetime_functions)
|
||||
return DateTimeTransformImpl<DataTypeDateTime64, DataTypeDateTime64, decltype(transformer), /*is_extended_result*/ true>::execute(arguments, result_type, input_rows_count, transformer);
|
||||
else
|
||||
return DateTimeTransformImpl<DataTypeDateTime64, DataTypeDateTime, decltype(transformer)>::execute(arguments, result_type, input_rows_count, transformer);
|
||||
}
|
||||
else
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}",
|
||||
arguments[0].type->getName(), this->getName());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
@ -28,9 +28,9 @@ public:
|
||||
/// only validate the time_zone part if the number of arguments is 2. This is mainly
|
||||
/// to accommodate functions like toStartOfDay(today()), toStartOfDay(yesterday()) etc.
|
||||
if (arguments.size() == 2 && time_zone.empty())
|
||||
throw Exception(
|
||||
"Function " + this->getName() + " supports a 2nd argument (optional) that must be non-empty and be a valid time zone",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Function {} supports a 2nd argument (optional) that must be a valid time zone",
|
||||
this->getName());
|
||||
return std::make_shared<ToDataType>(time_zone);
|
||||
}
|
||||
if constexpr (std::is_same_v<ToDataType, DataTypeDateTime64>)
|
||||
@ -78,8 +78,9 @@ public:
|
||||
return DateTimeTransformImpl<DataTypeDateTime64, ToDataType, decltype(transformer)>::execute(arguments, result_type, input_rows_count, transformer);
|
||||
}
|
||||
else
|
||||
throw Exception("Illegal type " + arguments[0].type->getName() + " of argument of function " + this->getName(),
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}",
|
||||
arguments[0].type->getName(), this->getName());
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -70,51 +70,44 @@ protected:
|
||||
if (arguments.size() == 1)
|
||||
{
|
||||
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()
|
||||
+ ". Must be Date, Date32, DateTime or DateTime64.",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}. Must be Date, Date32, DateTime or DateTime64.",
|
||||
arguments[0].type->getName(), getName());
|
||||
}
|
||||
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 1st argument of function " + getName()
|
||||
+ ". Must be Date, Date32, DateTime or DateTime64.",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of 1st argument of function {}. Must be Date, Date32, DateTime or DateTime64.",
|
||||
arguments[0].type->getName(), getName());
|
||||
if (!isUInt8(arguments[1].type))
|
||||
throw Exception(
|
||||
"Illegal type of 2nd (optional) argument of function " + getName()
|
||||
+ ". Must be constant UInt8 (week mode).",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type of 2nd (optional) argument of function {}. Must be constant UInt8 (week mode).",
|
||||
getName());
|
||||
}
|
||||
else if (arguments.size() == 3)
|
||||
{
|
||||
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()
|
||||
+ ". Must be Date, Date32, DateTime or DateTime64",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}. Must be Date, Date32, DateTime or DateTime64",
|
||||
arguments[0].type->getName(), getName());
|
||||
if (!isUInt8(arguments[1].type))
|
||||
throw Exception(
|
||||
"Illegal type of 2nd (optional) argument of function " + getName()
|
||||
+ ". Must be constant UInt8 (week mode).",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type of 2nd (optional) argument of function {}. Must be constant UInt8 (week mode).",
|
||||
getName());
|
||||
if (!isString(arguments[2].type))
|
||||
throw Exception(
|
||||
"Illegal type of 3rd (optional) argument of function " + getName()
|
||||
+ ". Must be constant string (timezone name).",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type of 3rd (optional) argument of function {}. Must be constant string (timezone name).",
|
||||
getName());
|
||||
if ((isDate(arguments[0].type) || isDate32(arguments[0].type)) && is_result_type_date_or_date32)
|
||||
throw Exception(
|
||||
"The timezone argument of function " + getName() + " is allowed only when the 1st argument is DateTime or DateTime64.",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"The timezone argument of function {} is allowed only when the 1st argument is DateTime or DateTime64.",
|
||||
getName());
|
||||
}
|
||||
else
|
||||
throw Exception(
|
||||
"Number of arguments for function " + getName() + " doesn't match: passed " + toString(arguments.size())
|
||||
+ ", expected 1, 2 or 3.",
|
||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
|
||||
"Number of arguments for function {} doesn't match: passed {}, expected 1, 2 or 3.",
|
||||
getName(), arguments.size());
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -85,33 +85,30 @@ protected:
|
||||
if (arguments.size() == 1)
|
||||
{
|
||||
if (!isDateOrDate32(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 Date, Date32, DateTime or DateTime64",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}. Should be Date, Date32, DateTime or DateTime64",
|
||||
arguments[0].type->getName(), getName());
|
||||
}
|
||||
else if (arguments.size() == 2)
|
||||
{
|
||||
if (!isDateOrDate32(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 Date, Date32, DateTime or DateTime64",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type {} of argument of function {}. Should be Date, Date32, DateTime or DateTime64",
|
||||
arguments[0].type->getName(), getName());
|
||||
if (!isString(arguments[1].type))
|
||||
throw Exception(
|
||||
"Function " + getName() + " supports 1 or 2 arguments. The optional 2nd argument must be "
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Function {} supports 1 or 2 arguments. The optional 2nd argument must be "
|
||||
"a constant string with a timezone name",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
if ((isDate(arguments[0].type) || isDate32(arguments[0].type)) && is_result_type_date_or_date32)
|
||||
throw Exception(
|
||||
"The timezone argument of function " + getName() + " is allowed only when the 1st argument has the type DateTime or DateTime64",
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||
getName());
|
||||
if (isDateOrDate32(arguments[0].type) && is_result_type_date_or_date32)
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"The timezone argument of function {} is allowed only when the 1st argument has the type DateTime or DateTime64",
|
||||
getName());
|
||||
}
|
||||
else
|
||||
throw Exception(
|
||||
"Number of arguments for function " + getName() + " doesn't match: passed " + toString(arguments.size())
|
||||
+ ", should be 1 or 2",
|
||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
|
||||
"Number of arguments for function {} doesn't match: passed {}, should be 1 or 2",
|
||||
getName(), arguments.size());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -89,20 +89,20 @@ public:
|
||||
|
||||
|
||||
template <typename ... Args>
|
||||
inline auto NO_SANITIZE_UNDEFINED execute_extended_result(const DateTime64 & t, Args && ... args) const
|
||||
inline auto NO_SANITIZE_UNDEFINED executeExtendedResult(const DateTime64 & t, Args && ... args) const
|
||||
{
|
||||
/// Type conversion from float to integer may be required.
|
||||
/// We are Ok with implementation specific result for out of range and denormals conversion.
|
||||
|
||||
if constexpr (TransformHasExecuteOverload_v<DateTime64, decltype(scale_multiplier), Args...>)
|
||||
{
|
||||
return wrapped_transform.execute_extended_result(t, scale_multiplier, std::forward<Args>(args)...);
|
||||
return wrapped_transform.executeExtendedResult(t, scale_multiplier, std::forward<Args>(args)...);
|
||||
}
|
||||
else if constexpr (TransformHasExecuteOverload_v<DecimalUtils::DecimalComponents<DateTime64>, Args...>)
|
||||
{
|
||||
auto components = DecimalUtils::splitWithScaleMultiplier(t, scale_multiplier);
|
||||
|
||||
const auto result = wrapped_transform.execute_extended_result(components, std::forward<Args>(args)...);
|
||||
const auto result = wrapped_transform.executeExtendedResult(components, std::forward<Args>(args)...);
|
||||
using ResultType = std::decay_t<decltype(result)>;
|
||||
|
||||
if constexpr (std::is_same_v<DecimalUtils::DecimalComponents<DateTime64>, ResultType>)
|
||||
@ -117,14 +117,14 @@ public:
|
||||
else
|
||||
{
|
||||
const auto components = DecimalUtils::splitWithScaleMultiplier(t, scale_multiplier);
|
||||
return wrapped_transform.execute_extended_result(static_cast<Int64>(components.whole), std::forward<Args>(args)...);
|
||||
return wrapped_transform.executeExtendedResult(static_cast<Int64>(components.whole), std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename ... Args, typename = std::enable_if_t<!std::is_same_v<T, DateTime64>>>
|
||||
inline auto execute_extended_result(const T & t, Args && ... args) const
|
||||
inline auto executeExtendedResult(const T & t, Args && ... args) const
|
||||
{
|
||||
return wrapped_transform.execute_extended_result(t, std::forward<Args>(args)...);
|
||||
return wrapped_transform.executeExtendedResult(t, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -1,14 +1,14 @@
|
||||
#include <Functions/IFunction.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/DateTimeTransforms.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToSomething.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToDateTimeOrDateTime64.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using FunctionTimeSlot = FunctionDateOrDateTimeToSomething<DataTypeDateTime, TimeSlotImpl>;
|
||||
using FunctionTimeSlot = FunctionDateOrDateTimeToDateTimeOrDateTime64<TimeSlotImpl>;
|
||||
|
||||
REGISTER_FUNCTION(TimeSlot)
|
||||
{
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/DateTimeTransforms.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToSomething.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToDateTimeOrDateTime64.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using FunctionToStartOfDay = FunctionDateOrDateTimeToSomething<DataTypeDateTime, ToStartOfDayImpl>;
|
||||
using FunctionToStartOfDay = FunctionDateOrDateTimeToDateTimeOrDateTime64<ToStartOfDayImpl>;
|
||||
|
||||
REGISTER_FUNCTION(ToStartOfDay)
|
||||
{
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/DateTimeTransforms.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToSomething.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToDateTimeOrDateTime64.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using FunctionToStartOfFifteenMinutes = FunctionDateOrDateTimeToSomething<DataTypeDateTime, ToStartOfFifteenMinutesImpl>;
|
||||
using FunctionToStartOfFifteenMinutes = FunctionDateOrDateTimeToDateTimeOrDateTime64<ToStartOfFifteenMinutesImpl>;
|
||||
|
||||
REGISTER_FUNCTION(ToStartOfFifteenMinutes)
|
||||
{
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/DateTimeTransforms.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToSomething.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToDateTimeOrDateTime64.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using FunctionToStartOfFiveMinutes = FunctionDateOrDateTimeToSomething<DataTypeDateTime, ToStartOfFiveMinutesImpl>;
|
||||
using FunctionToStartOfFiveMinutes = FunctionDateOrDateTimeToDateTimeOrDateTime64<ToStartOfFiveMinutesImpl>;
|
||||
|
||||
REGISTER_FUNCTION(ToStartOfFiveMinutes)
|
||||
{
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/DateTimeTransforms.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToSomething.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToDateTimeOrDateTime64.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using FunctionToStartOfHour = FunctionDateOrDateTimeToSomething<DataTypeDateTime, ToStartOfHourImpl>;
|
||||
using FunctionToStartOfHour = FunctionDateOrDateTimeToDateTimeOrDateTime64<ToStartOfHourImpl>;
|
||||
|
||||
REGISTER_FUNCTION(ToStartOfHour)
|
||||
{
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/DateTimeTransforms.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToSomething.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToDateTimeOrDateTime64.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using FunctionToStartOfMinute = FunctionDateOrDateTimeToSomething<DataTypeDateTime, ToStartOfMinuteImpl>;
|
||||
using FunctionToStartOfMinute = FunctionDateOrDateTimeToDateTimeOrDateTime64<ToStartOfMinuteImpl>;
|
||||
|
||||
REGISTER_FUNCTION(ToStartOfMinute)
|
||||
{
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/DateTimeTransforms.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToSomething.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToDateTimeOrDateTime64.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using FunctionToStartOfTenMinutes = FunctionDateOrDateTimeToSomething<DataTypeDateTime, ToStartOfTenMinutesImpl>;
|
||||
using FunctionToStartOfTenMinutes = FunctionDateOrDateTimeToDateTimeOrDateTime64<ToStartOfTenMinutesImpl>;
|
||||
|
||||
REGISTER_FUNCTION(ToStartOfTenMinutes)
|
||||
{
|
||||
|
@ -26,6 +26,22 @@ toLastDayOfMonth;toDate32;true 1920-02-29
|
||||
type;toLastDayOfMonth;toDate32;true Date32
|
||||
toLastDayOfMonth;toDateTime64;true 1920-02-29
|
||||
type;toLastDayOfMonth;toDateTime64;true Date32
|
||||
toStartOfDay;toDateTime64;true 1920-02-02 00:00:00.000
|
||||
type;toStartOfDay;toDateTime64;true DateTime64(3, \'UTC\')
|
||||
toStartOfHour;toDateTime64;true 1920-02-02 10:00:00.000
|
||||
type;toStartOfHour;toDateTime64;true DateTime64(3, \'UTC\')
|
||||
toStartOfMinute;toDateTime64;true 1920-02-02 10:23:00.000
|
||||
type;toStartOfMinute;toDateTime64;true DateTime64(3, \'UTC\')
|
||||
toStartOfFiveMinutes;toDateTime64;true 1920-02-02 10:20:00.000
|
||||
type;toStartOfFiveMinutes;toDateTime64;true DateTime64(3, \'UTC\')
|
||||
toStartOfTenMinutes;toDateTime64;true 1920-02-02 10:20:00.000
|
||||
type;toStartOfTenMinutes;toDateTime64;true DateTime64(3, \'UTC\')
|
||||
toStartOfFifteenMinutes;toDateTime64;true 1920-02-02 10:15:00.000
|
||||
type;toStartOfFifteenMinutes;toDateTime64;true DateTime64(3, \'UTC\')
|
||||
timeSlot;toDateTime64;true 1920-02-02 10:00:00.000
|
||||
type;timeSlot;toDateTime64;true DateTime64(3, \'UTC\')
|
||||
toStartOfDay;toDate32;true 1920-02-02 00:00:00.000
|
||||
type;toStartOfDay;toDate32;true DateTime64(3, \'UTC\')
|
||||
toStartOfYear;toDate32;false 1970-01-01
|
||||
type;toStartOfYear;toDate32;false Date
|
||||
toStartOfYear;toDateTime64;false 1970-01-01
|
||||
@ -54,3 +70,19 @@ toLastDayOfMonth;toDate32;false 1970-01-01
|
||||
type;toLastDayOfMonth;toDate32;false Date
|
||||
toLastDayOfMonth;toDateTime64;false 1970-01-01
|
||||
type;toLastDayOfMonth;toDateTime64;false Date
|
||||
toStartOfDay;toDateTime64;false 1970-01-01 00:00:00
|
||||
type;toStartOfDay;toDateTime64;false DateTime(\'UTC\')
|
||||
toStartOfHour;toDateTime64;false 1970-01-01 00:00:00
|
||||
type;toStartOfHour;toDateTime64;false DateTime(\'UTC\')
|
||||
toStartOfMinute;toDateTime64;false 1970-01-01 00:00:00
|
||||
type;toStartOfMinute;toDateTime64;false DateTime(\'UTC\')
|
||||
toStartOfFiveMinutes;toDateTime64;false 2056-03-09 16:48:16
|
||||
type;toStartOfFiveMinutes;toDateTime64;false DateTime(\'UTC\')
|
||||
toStartOfTenMinutes;toDateTime64;false 2056-03-09 16:48:16
|
||||
type;toStartOfTenMinutes;toDateTime64;false DateTime(\'UTC\')
|
||||
toStartOfFifteenMinutes;toDateTime64;false 2056-03-09 16:43:16
|
||||
type;toStartOfFifteenMinutes;toDateTime64;false DateTime(\'UTC\')
|
||||
timeSlot;toDateTime64;false 2056-03-09 16:58:16
|
||||
type;timeSlot;toDateTime64;false DateTime(\'UTC\')
|
||||
toStartOfDay;toDate32;false 1970-01-01 00:00:00
|
||||
type;toStartOfDay;toDate32;false DateTime(\'UTC\')
|
||||
|
@ -5,5 +5,10 @@ SELECT 'type;{{ date_fun }};toDate32;{{ option_value }}', toTypeName({{ date_fun
|
||||
SELECT '{{ date_fun }};toDateTime64;{{ option_value }}', {{ date_fun }}(toDateTime64('1920-02-02 10:20:30', 3)) SETTINGS enable_extended_results_for_datetime_functions = {{ option_value }};
|
||||
SELECT 'type;{{ date_fun }};toDateTime64;{{ option_value }}', toTypeName({{ date_fun }}(toDateTime64('1920-02-02 10:20:30', 3))) SETTINGS enable_extended_results_for_datetime_functions = {{ option_value }};
|
||||
{% endfor -%}
|
||||
{% for date_fun in ['toStartOfDay', 'toStartOfHour', 'toStartOfMinute', 'toStartOfFiveMinutes', 'toStartOfTenMinutes', 'toStartOfFifteenMinutes', 'timeSlot'] -%}
|
||||
SELECT '{{ date_fun }};toDateTime64;{{ option_value }}', {{ date_fun }}(toDateTime64('1920-02-02 10:23:33.789', 3, 'UTC'), 'UTC') SETTINGS enable_extended_results_for_datetime_functions = {{ option_value }};
|
||||
SELECT 'type;{{ date_fun }};toDateTime64;{{ option_value }}', toTypeName({{ date_fun }}(toDateTime64('1920-02-02 10:20:30', 3, 'UTC'), 'UTC')) SETTINGS enable_extended_results_for_datetime_functions = {{ option_value }};
|
||||
{% endfor -%}
|
||||
SELECT 'toStartOfDay;toDate32;{{ option_value }}', toStartOfDay(toDate32('1920-02-02', 'UTC'), 'UTC') SETTINGS enable_extended_results_for_datetime_functions = {{ option_value }};
|
||||
SELECT 'type;toStartOfDay;toDate32;{{ option_value }}', toTypeName(toStartOfDay(toDate32('1920-02-02', 'UTC'), 'UTC')) SETTINGS enable_extended_results_for_datetime_functions = {{ option_value }};
|
||||
{% endfor -%}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user