mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-23 08:02:02 +00:00
Merge pull request #45233 from ClickHouse/improve_week_day
Revert "Revert "Improve week day""
This commit is contained in:
commit
5b257ab806
@ -209,10 +209,25 @@ Aliases: `DAYOFMONTH`, `DAY`.
|
|||||||
|
|
||||||
## toDayOfWeek
|
## toDayOfWeek
|
||||||
|
|
||||||
Converts a date or date with time to a UInt8 number containing the number of the day of the week (Monday is 1, and Sunday is 7).
|
Converts a date or date with time to a UInt8 number containing the number of the day of the week.
|
||||||
|
|
||||||
|
The two-argument form of `toDayOfWeek()` enables you to specify whether the week starts on Monday or Sunday, and whether the return value should be in the range from 0 to 6 or 1 to 7. If the mode argument is ommited, the default mode is 0. The time zone of the date can be specified as the third argument.
|
||||||
|
|
||||||
|
| Mode | First day of week | Range |
|
||||||
|
|------|-------------------|------------------------------------------------|
|
||||||
|
| 0 | Monday | 1-7, Monday = 1, Tuesday = 2, ..., Sunday = 7 |
|
||||||
|
| 1 | Monday | 0-6, Monday = 0, Tuesday = 1, ..., Sunday = 6 |
|
||||||
|
| 2 | Sunday | 0-6, Sunday = 0, Monday = 1, ..., Saturday = 6 |
|
||||||
|
| 3 | Sunday | 1-7, Sunday = 1, Monday = 2, ..., Saturday = 7 |
|
||||||
|
|
||||||
Alias: `DAYOFWEEK`.
|
Alias: `DAYOFWEEK`.
|
||||||
|
|
||||||
|
**Syntax**
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
toDayOfWeek(t[, mode[, timezone]])
|
||||||
|
```
|
||||||
|
|
||||||
## toHour
|
## toHour
|
||||||
|
|
||||||
Converts a date with time to a UInt8 number containing the number of the hour in 24-hour time (0-23).
|
Converts a date with time to a UInt8 number containing the number of the hour in 24-hour time (0-23).
|
||||||
@ -316,11 +331,17 @@ If `toLastDayOfMonth` is called with an argument of type `Date` greater then 214
|
|||||||
Rounds down a date, or date with time, to the nearest Monday.
|
Rounds down a date, or date with time, to the nearest Monday.
|
||||||
Returns the date.
|
Returns the date.
|
||||||
|
|
||||||
## toStartOfWeek(t\[,mode\])
|
## toStartOfWeek
|
||||||
|
|
||||||
Rounds down a date, or date with time, to the nearest Sunday or Monday by mode.
|
Rounds a date or date with time down to the nearest Sunday or Monday.
|
||||||
Returns the date.
|
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.
|
The mode argument works exactly like the mode argument in function `toWeek()`. If no mode is specified, mode is assumed as 0.
|
||||||
|
|
||||||
|
**Syntax**
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
toStartOfWeek(t[, mode[, timezone]])
|
||||||
|
```
|
||||||
|
|
||||||
## toStartOfDay
|
## toStartOfDay
|
||||||
|
|
||||||
@ -455,10 +476,12 @@ Converts a date, or date with time, to a UInt16 number containing the ISO Year n
|
|||||||
|
|
||||||
Converts a date, or date with time, to a UInt8 number containing the ISO Week number.
|
Converts a date, or date with time, to a UInt8 number containing the ISO Week number.
|
||||||
|
|
||||||
## toWeek(date\[,mode\])
|
## toWeek
|
||||||
|
|
||||||
|
This function returns the week number for date or datetime. The two-argument form of `toWeek()` enables you to specify whether the week starts on Sunday or Monday and whether the return value should be in the range from 0 to 53 or from 1 to 53. If the mode argument is omitted, the default mode is 0.
|
||||||
|
|
||||||
|
`toISOWeek()` is a compatibility function that is equivalent to `toWeek(date,3)`.
|
||||||
|
|
||||||
This function returns the week number for date or datetime. The two-argument form of toWeek() enables you to specify whether the week starts on Sunday or Monday and whether the return value should be in the range from 0 to 53 or from 1 to 53. If the mode argument is omitted, the default mode is 0.
|
|
||||||
`toISOWeek()`is a compatibility function that is equivalent to `toWeek(date,3)`.
|
|
||||||
The following table describes how the mode argument works.
|
The following table describes how the mode argument works.
|
||||||
|
|
||||||
| Mode | First day of week | Range | Week 1 is the first week … |
|
| Mode | First day of week | Range | Week 1 is the first week … |
|
||||||
@ -482,13 +505,15 @@ For mode values with a meaning of “with 4 or more days this year,” weeks are
|
|||||||
|
|
||||||
For mode values with a meaning of “contains January 1”, the week contains January 1 is week 1. It does not matter how many days in the new year the week contained, even if it contained only one day.
|
For mode values with a meaning of “contains January 1”, the week contains January 1 is week 1. It does not matter how many days in the new year the week contained, even if it contained only one day.
|
||||||
|
|
||||||
|
**Syntax**
|
||||||
|
|
||||||
``` sql
|
``` sql
|
||||||
toWeek(date, [, mode][, Timezone])
|
toWeek(t[, mode[, time_zone]])
|
||||||
```
|
```
|
||||||
|
|
||||||
**Arguments**
|
**Arguments**
|
||||||
|
|
||||||
- `date` – Date or DateTime.
|
- `t` – Date or DateTime.
|
||||||
- `mode` – Optional parameter, Range of values is \[0,9\], default is 0.
|
- `mode` – Optional parameter, Range of values is \[0,9\], default is 0.
|
||||||
- `Timezone` – Optional parameter, it behaves like any other conversion function.
|
- `Timezone` – Optional parameter, it behaves like any other conversion function.
|
||||||
|
|
||||||
@ -504,13 +529,19 @@ SELECT toDate('2016-12-27') AS date, toWeek(date) AS week0, toWeek(date,1) AS we
|
|||||||
└────────────┴───────┴───────┴───────┘
|
└────────────┴───────┴───────┴───────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
## toYearWeek(date\[,mode\])
|
## toYearWeek
|
||||||
|
|
||||||
Returns year and week for a date. The year in the result may be different from the year in the date argument for the first and the last week of the year.
|
Returns year and week for a date. The year in the result may be different from the year in the date argument for the first and the last week of the year.
|
||||||
|
|
||||||
The mode argument works exactly like the mode argument to toWeek(). For the single-argument syntax, a mode value of 0 is used.
|
The mode argument works exactly like the mode argument to `toWeek()`. For the single-argument syntax, a mode value of 0 is used.
|
||||||
|
|
||||||
`toISOYear()`is a compatibility function that is equivalent to `intDiv(toYearWeek(date,3),100)`.
|
`toISOYear()` is a compatibility function that is equivalent to `intDiv(toYearWeek(date,3),100)`.
|
||||||
|
|
||||||
|
**Syntax**
|
||||||
|
|
||||||
|
``` sql
|
||||||
|
toYearWeek(t[, mode[, timezone]])
|
||||||
|
```
|
||||||
|
|
||||||
**Example**
|
**Example**
|
||||||
|
|
||||||
|
@ -39,6 +39,15 @@ enum class WeekModeFlag : UInt8
|
|||||||
};
|
};
|
||||||
using YearWeek = std::pair<UInt16, UInt8>;
|
using YearWeek = std::pair<UInt16, UInt8>;
|
||||||
|
|
||||||
|
/// Modes for toDayOfWeek() function.
|
||||||
|
enum class WeekDayMode
|
||||||
|
{
|
||||||
|
WeekStartsMonday1 = 0,
|
||||||
|
WeekStartsMonday0 = 1,
|
||||||
|
WeekStartsSunday0 = 2,
|
||||||
|
WeekStartsSunday1 = 3
|
||||||
|
};
|
||||||
|
|
||||||
/** Lookup table to conversion of time to date, and to month / year / day of week / day of month and so on.
|
/** Lookup table to conversion of time to date, and to month / year / day of week / day of month and so on.
|
||||||
* First time was implemented for OLAPServer, that needed to do billions of such transformations.
|
* First time was implemented for OLAPServer, that needed to do billions of such transformations.
|
||||||
*/
|
*/
|
||||||
@ -619,9 +628,28 @@ public:
|
|||||||
template <typename DateOrTime>
|
template <typename DateOrTime>
|
||||||
inline Int16 toYear(DateOrTime v) const { return lut[toLUTIndex(v)].year; }
|
inline Int16 toYear(DateOrTime v) const { return lut[toLUTIndex(v)].year; }
|
||||||
|
|
||||||
|
/// 1-based, starts on Monday
|
||||||
template <typename DateOrTime>
|
template <typename DateOrTime>
|
||||||
inline UInt8 toDayOfWeek(DateOrTime v) const { return lut[toLUTIndex(v)].day_of_week; }
|
inline UInt8 toDayOfWeek(DateOrTime v) const { return lut[toLUTIndex(v)].day_of_week; }
|
||||||
|
|
||||||
|
template <typename DateOrTime>
|
||||||
|
inline UInt8 toDayOfWeek(DateOrTime v, UInt8 week_day_mode) const
|
||||||
|
{
|
||||||
|
WeekDayMode mode = check_week_day_mode(week_day_mode);
|
||||||
|
|
||||||
|
UInt8 res = toDayOfWeek(v);
|
||||||
|
using enum WeekDayMode;
|
||||||
|
bool start_from_sunday = (mode == WeekStartsSunday0 || mode == WeekStartsSunday1);
|
||||||
|
bool zero_based = (mode == WeekStartsMonday0 || mode == WeekStartsSunday0);
|
||||||
|
|
||||||
|
if (start_from_sunday)
|
||||||
|
res = res % 7 + 1;
|
||||||
|
if (zero_based)
|
||||||
|
--res;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename DateOrTime>
|
template <typename DateOrTime>
|
||||||
inline UInt8 toDayOfMonth(DateOrTime v) const { return lut[toLUTIndex(v)].day_of_month; }
|
inline UInt8 toDayOfMonth(DateOrTime v) const { return lut[toLUTIndex(v)].day_of_month; }
|
||||||
|
|
||||||
@ -844,6 +872,12 @@ public:
|
|||||||
return week_format;
|
return week_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check and change mode to effective.
|
||||||
|
inline WeekDayMode check_week_day_mode(UInt8 mode) const /// NOLINT
|
||||||
|
{
|
||||||
|
return static_cast<WeekDayMode>(mode & 3);
|
||||||
|
}
|
||||||
|
|
||||||
/** Calculate weekday from d.
|
/** Calculate weekday from d.
|
||||||
* Returns 0 for monday, 1 for tuesday...
|
* Returns 0 for monday, 1 for tuesday...
|
||||||
*/
|
*/
|
||||||
|
@ -786,21 +786,21 @@ struct ToDayOfWeekImpl
|
|||||||
{
|
{
|
||||||
static constexpr auto name = "toDayOfWeek";
|
static constexpr auto name = "toDayOfWeek";
|
||||||
|
|
||||||
static inline UInt8 execute(Int64 t, const DateLUTImpl & time_zone)
|
static inline UInt8 execute(Int64 t, UInt8 mode, const DateLUTImpl & time_zone)
|
||||||
{
|
{
|
||||||
return time_zone.toDayOfWeek(t);
|
return time_zone.toDayOfWeek(t, mode);
|
||||||
}
|
}
|
||||||
static inline UInt8 execute(UInt32 t, const DateLUTImpl & time_zone)
|
static inline UInt8 execute(UInt32 t, UInt8 mode, const DateLUTImpl & time_zone)
|
||||||
{
|
{
|
||||||
return time_zone.toDayOfWeek(t);
|
return time_zone.toDayOfWeek(t, mode);
|
||||||
}
|
}
|
||||||
static inline UInt8 execute(Int32 d, const DateLUTImpl & time_zone)
|
static inline UInt8 execute(Int32 d, UInt8 mode, const DateLUTImpl & time_zone)
|
||||||
{
|
{
|
||||||
return time_zone.toDayOfWeek(ExtendedDayNum(d));
|
return time_zone.toDayOfWeek(ExtendedDayNum(d), mode);
|
||||||
}
|
}
|
||||||
static inline UInt8 execute(UInt16 d, const DateLUTImpl & time_zone)
|
static inline UInt8 execute(UInt16 d, UInt8 mode, const DateLUTImpl & time_zone)
|
||||||
{
|
{
|
||||||
return time_zone.toDayOfWeek(DayNum(d));
|
return time_zone.toDayOfWeek(DayNum(d), mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
using FactorTransform = ToMondayImpl;
|
using FactorTransform = ToMondayImpl;
|
||||||
|
@ -82,8 +82,8 @@ protected:
|
|||||||
arguments[0].type->getName(), getName());
|
arguments[0].type->getName(), getName());
|
||||||
if (!isUInt8(arguments[1].type))
|
if (!isUInt8(arguments[1].type))
|
||||||
throw Exception(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).",
|
"Illegal type {} of 2nd (optional) argument of function {}. Must be constant UInt8 (week mode).",
|
||||||
getName());
|
arguments[1].type->getName(), getName());
|
||||||
}
|
}
|
||||||
else if (arguments.size() == 3)
|
else if (arguments.size() == 3)
|
||||||
{
|
{
|
||||||
@ -93,12 +93,12 @@ protected:
|
|||||||
arguments[0].type->getName(), getName());
|
arguments[0].type->getName(), getName());
|
||||||
if (!isUInt8(arguments[1].type))
|
if (!isUInt8(arguments[1].type))
|
||||||
throw Exception(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).",
|
"Illegal type {} of 2nd (optional) argument of function {}. Must be constant UInt8 (week mode).",
|
||||||
getName());
|
arguments[1].type->getName(), getName());
|
||||||
if (!isString(arguments[2].type))
|
if (!isString(arguments[2].type))
|
||||||
throw Exception(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).",
|
"Illegal type {} of 3rd (optional) argument of function {}. Must be constant string (timezone name).",
|
||||||
getName());
|
arguments[2].type->getName(), getName());
|
||||||
if ((isDate(arguments[0].type) || isDate32(arguments[0].type)) && is_result_type_date_or_date32)
|
if ((isDate(arguments[0].type) || isDate32(arguments[0].type)) && is_result_type_date_or_date32)
|
||||||
throw Exception(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.",
|
"The timezone argument of function {} is allowed only when the 1st argument is DateTime or DateTime64.",
|
||||||
|
@ -225,8 +225,8 @@ public:
|
|||||||
}
|
}
|
||||||
else if constexpr (std::is_same_v<TransformX, TransformDateTime64<ToRelativeWeekNumImpl<ResultPrecision::Extended>>>)
|
else if constexpr (std::is_same_v<TransformX, TransformDateTime64<ToRelativeWeekNumImpl<ResultPrecision::Extended>>>)
|
||||||
{
|
{
|
||||||
auto x_day_of_week = TransformDateTime64<ToDayOfWeekImpl>(transform_x.getScaleMultiplier()).execute(x, timezone_x);
|
auto x_day_of_week = TransformDateTime64<ToDayOfWeekImpl>(transform_x.getScaleMultiplier()).execute(x, 0, timezone_x);
|
||||||
auto y_day_of_week = TransformDateTime64<ToDayOfWeekImpl>(transform_y.getScaleMultiplier()).execute(y, timezone_y);
|
auto y_day_of_week = TransformDateTime64<ToDayOfWeekImpl>(transform_y.getScaleMultiplier()).execute(y, 0, timezone_y);
|
||||||
if ((x_day_of_week > y_day_of_week)
|
if ((x_day_of_week > y_day_of_week)
|
||||||
|| ((x_day_of_week == y_day_of_week) && (a_comp.time.hour > b_comp.time.hour))
|
|| ((x_day_of_week == y_day_of_week) && (a_comp.time.hour > b_comp.time.hour))
|
||||||
|| ((a_comp.time.hour == b_comp.time.hour) && ((a_comp.time.minute > b_comp.time.minute)
|
|| ((a_comp.time.hour == b_comp.time.hour) && ((a_comp.time.minute > b_comp.time.minute)
|
||||||
|
@ -276,7 +276,7 @@ private:
|
|||||||
{
|
{
|
||||||
static inline void write(WriteBuffer & buffer, Time source, const DateLUTImpl & timezone)
|
static inline void write(WriteBuffer & buffer, Time source, const DateLUTImpl & timezone)
|
||||||
{
|
{
|
||||||
const auto day = ToDayOfWeekImpl::execute(source, timezone);
|
const auto day = ToDayOfWeekImpl::execute(source, 0, timezone);
|
||||||
static constexpr std::string_view day_names[] =
|
static constexpr std::string_view day_names[] =
|
||||||
{
|
{
|
||||||
"Monday",
|
"Monday",
|
||||||
|
@ -344,13 +344,13 @@ private:
|
|||||||
|
|
||||||
static size_t mysqlDayOfWeek(char * dest, Time source, UInt64, UInt32, const DateLUTImpl & timezone)
|
static size_t mysqlDayOfWeek(char * dest, Time source, UInt64, UInt32, const DateLUTImpl & timezone)
|
||||||
{
|
{
|
||||||
*dest = '0' + ToDayOfWeekImpl::execute(source, timezone);
|
*dest = '0' + ToDayOfWeekImpl::execute(source, 0, timezone);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t mysqlDayOfWeek0To6(char * dest, Time source, UInt64, UInt32, const DateLUTImpl & timezone)
|
static size_t mysqlDayOfWeek0To6(char * dest, Time source, UInt64, UInt32, const DateLUTImpl & timezone)
|
||||||
{
|
{
|
||||||
auto day = ToDayOfWeekImpl::execute(source, timezone);
|
auto day = ToDayOfWeekImpl::execute(source, 0, timezone);
|
||||||
*dest = '0' + (day == 7 ? 0 : day);
|
*dest = '0' + (day == 7 ? 0 : day);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -499,13 +499,13 @@ private:
|
|||||||
|
|
||||||
static size_t jodaDayOfWeek1Based(size_t min_represent_digits, char * dest, Time source, UInt64, UInt32, const DateLUTImpl & timezone)
|
static size_t jodaDayOfWeek1Based(size_t min_represent_digits, char * dest, Time source, UInt64, UInt32, const DateLUTImpl & timezone)
|
||||||
{
|
{
|
||||||
auto week_day = ToDayOfWeekImpl::execute(source, timezone);
|
auto week_day = ToDayOfWeekImpl::execute(source, 0, timezone);
|
||||||
return writeNumberWithPadding(dest, week_day, min_represent_digits);
|
return writeNumberWithPadding(dest, week_day, min_represent_digits);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t jodaDayOfWeekText(size_t min_represent_digits, char * dest, Time source, UInt64, UInt32, const DateLUTImpl & timezone)
|
static size_t jodaDayOfWeekText(size_t min_represent_digits, char * dest, Time source, UInt64, UInt32, const DateLUTImpl & timezone)
|
||||||
{
|
{
|
||||||
auto week_day = ToDayOfWeekImpl::execute(source, timezone);
|
auto week_day = ToDayOfWeekImpl::execute(source, 0, timezone);
|
||||||
if (week_day == 7)
|
if (week_day == 7)
|
||||||
week_day = 0;
|
week_day = 0;
|
||||||
|
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
#include <Functions/FunctionFactory.h>
|
#include <Functions/FunctionFactory.h>
|
||||||
#include <Functions/DateTimeTransforms.h>
|
#include <Functions/DateTimeTransforms.h>
|
||||||
#include <Functions/FunctionDateOrDateTimeToSomething.h>
|
|
||||||
#include <DataTypes/DataTypesNumber.h>
|
#include <DataTypes/DataTypesNumber.h>
|
||||||
|
#include <Functions/FunctionCustomWeekToSomething.h>
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
using FunctionToDayOfWeek = FunctionDateOrDateTimeToSomething<DataTypeUInt8, ToDayOfWeekImpl>;
|
using FunctionToDayOfWeek = FunctionCustomWeekToSomething<DataTypeUInt8, ToDayOfWeekImpl>;
|
||||||
|
|
||||||
REGISTER_FUNCTION(ToDayOfWeek)
|
REGISTER_FUNCTION(ToDayOfWeek)
|
||||||
{
|
{
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
<value>toSecond</value>
|
<value>toSecond</value>
|
||||||
<value>toMinute</value>
|
<value>toMinute</value>
|
||||||
<value>toHour</value>
|
<value>toHour</value>
|
||||||
<value>toDayOfWeek</value>
|
|
||||||
<value>toDayOfMonth</value>
|
<value>toDayOfMonth</value>
|
||||||
<value>toDayOfYear</value>
|
<value>toDayOfYear</value>
|
||||||
<value>toMonth</value>
|
<value>toMonth</value>
|
||||||
@ -47,21 +46,33 @@
|
|||||||
<value>toUnixTimestamp</value>
|
<value>toUnixTimestamp</value>
|
||||||
</values>
|
</values>
|
||||||
</substitution>
|
</substitution>
|
||||||
|
<substitution>
|
||||||
|
<name>datetime_transform_with_mode</name>
|
||||||
|
<values>
|
||||||
|
<value>toDayOfWeek</value>
|
||||||
|
<value>toStartOfWeek</value>
|
||||||
|
<value>toWeek</value>
|
||||||
|
<value>toYearWeek</value>
|
||||||
|
</values>
|
||||||
|
</substitution>
|
||||||
<substitution>
|
<substitution>
|
||||||
<name>date_transform</name>
|
<name>date_transform</name>
|
||||||
<values>
|
<values>
|
||||||
<value>toDayOfWeek</value>
|
|
||||||
<value>toDayOfMonth</value>
|
<value>toDayOfMonth</value>
|
||||||
|
<value>toDayOfWeek</value>
|
||||||
<value>toDayOfYear</value>
|
<value>toDayOfYear</value>
|
||||||
|
<value>toWeek</value>
|
||||||
<value>toMonth</value>
|
<value>toMonth</value>
|
||||||
<value>toQuarter</value>
|
<value>toQuarter</value>
|
||||||
<value>toYear</value>
|
<value>toYear</value>
|
||||||
|
<value>toYearWeek</value>
|
||||||
<value>toISOWeek</value>
|
<value>toISOWeek</value>
|
||||||
<value>toISOYear</value>
|
<value>toISOYear</value>
|
||||||
|
|
||||||
<value>toDate</value>
|
<value>toDate</value>
|
||||||
<value>toMonday</value>
|
<value>toMonday</value>
|
||||||
<value>toStartOfDay</value>
|
<value>toStartOfDay</value>
|
||||||
|
<value>toStartOfWeek</value>
|
||||||
<value>toStartOfMonth</value>
|
<value>toStartOfMonth</value>
|
||||||
<value>toStartOfQuarter</value>
|
<value>toStartOfQuarter</value>
|
||||||
<value>toStartOfYear</value>
|
<value>toStartOfYear</value>
|
||||||
@ -79,14 +90,6 @@
|
|||||||
<value>toRelativeQuarterNum</value>
|
<value>toRelativeQuarterNum</value>
|
||||||
</values>
|
</values>
|
||||||
</substitution>
|
</substitution>
|
||||||
<substitution>
|
|
||||||
<name>time_zone</name>
|
|
||||||
<values>
|
|
||||||
<value>UTC</value>
|
|
||||||
<value>Asia/Istanbul</value>
|
|
||||||
<value>Asia/Kolkata</value>
|
|
||||||
</values>
|
|
||||||
</substitution>
|
|
||||||
<substitution>
|
<substitution>
|
||||||
<name>binary_function</name>
|
<name>binary_function</name>
|
||||||
<values>
|
<values>
|
||||||
@ -116,11 +119,21 @@
|
|||||||
<value>subtractYears</value>
|
<value>subtractYears</value>
|
||||||
</values>
|
</values>
|
||||||
</substitution>
|
</substitution>
|
||||||
|
<substitution>
|
||||||
|
<name>time_zone</name>
|
||||||
|
<values>
|
||||||
|
<value>UTC</value>
|
||||||
|
<value>Asia/Istanbul</value>
|
||||||
|
<value>Asia/Kolkata</value>
|
||||||
|
</values>
|
||||||
|
</substitution>
|
||||||
</substitutions>
|
</substitutions>
|
||||||
|
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, {datetime_transform}(t, '{time_zone}'))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, {datetime_transform}(t, '{time_zone}'))</query>
|
||||||
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, {datetime_transform_with_mode}(t, 0, '{time_zone}'))</query>
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDate('2017-01-01') + number % 1000 + rand() % 10 AS t, {date_transform}(t))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDate('2017-01-01') + number % 1000 + rand() % 10 AS t, {date_transform}(t))</query>
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, {binary_function}(t, 1))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, {binary_function}(t, 1))</query>
|
||||||
|
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, toStartOfInterval(t, INTERVAL 1 month))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, toStartOfInterval(t, INTERVAL 1 month))</query>
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, date_trunc('month', t))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, date_trunc('month', t))</query>
|
||||||
</test>
|
</test>
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
|
<!--
|
||||||
|
This is a performance smoke test for DateTime and Date. Some other basic functions are tested by date_time_64.xml, and a more
|
||||||
|
exhaustive list of functions is in date_time_long.xml (it's about an hour so we can't afford to test it on each commit).
|
||||||
|
-->
|
||||||
<test>
|
<test>
|
||||||
<!--
|
|
||||||
This is a short screening test for DateTime and Date. Some
|
|
||||||
other basic functions are tested by date_time_64, and a more
|
|
||||||
exhaustive list of functions is in date_time_long.xml (it's
|
|
||||||
about an hour so we can't afford to test it on each commit).
|
|
||||||
-->
|
|
||||||
<substitutions>
|
<substitutions>
|
||||||
<substitution>
|
<substitution>
|
||||||
<name>date_transform</name>
|
<name>date_transform</name>
|
||||||
<values>
|
<values>
|
||||||
<value>toDayOfWeek</value>
|
|
||||||
<value>toMonday</value>
|
<value>toMonday</value>
|
||||||
<value>toRelativeDayNum</value>
|
<value>toRelativeDayNum</value>
|
||||||
<value>toYYYYMMDDhhmmss</value>
|
<value>toYYYYMMDDhhmmss</value>
|
||||||
@ -32,16 +29,24 @@
|
|||||||
</substitution>
|
</substitution>
|
||||||
</substitutions>
|
</substitutions>
|
||||||
|
|
||||||
<!-- date_transform -->
|
<!-- {date_transform} -->
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, {date_transform}(t, '{time_zone}'))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, {date_transform}(t, '{time_zone}'))</query>
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDate('2017-01-01') + number % 1000 + rand() % 10 AS t, {date_transform}(t))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDate('2017-01-01') + number % 1000 + rand() % 10 AS t, {date_transform}(t))</query>
|
||||||
|
|
||||||
<!-- toUnixTimestamp() -->
|
<!-- toUnixTimestamp() -->
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, toUnixTimestamp(t, '{time_zone}'))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, toUnixTimestamp(t, '{time_zone}'))</query>
|
||||||
<!-- toUnixTimestamp(Date()) is pro5bit, wrap Date() with toUInt16() to overcome -->
|
<!-- toUnixTimestamp(Date()) is prohibited, wrap Date() with toUInt16() to overcome -->
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDate('2017-01-01') + number % 1000 + rand() % 10 AS t, toUnixTimestamp(toUInt16(t)))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDate('2017-01-01') + number % 1000 + rand() % 10 AS t, toUnixTimestamp(toUInt16(t)))</query>
|
||||||
|
|
||||||
|
<!-- {binary_function} -->
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, {binary_function}(t, 1))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, {binary_function}(t, 1))</query>
|
||||||
|
|
||||||
|
<!-- misc -->
|
||||||
|
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, toStartOfInterval(t, INTERVAL 1 month))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, toStartOfInterval(t, INTERVAL 1 month))</query>
|
||||||
|
|
||||||
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, date_trunc('month', t))</query>
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, date_trunc('month', t))</query>
|
||||||
|
|
||||||
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDateTime('2017-01-01 00:00:00') + number % 100000000 + rand() % 100000 AS t, toDayOfWeek(t, 0, '{time_zone}'))</query>
|
||||||
|
<query>SELECT count() FROM numbers(50000000) WHERE NOT ignore(toDate('2017-01-01') + number % 1000 + rand() % 10 AS t, toDayOfWeek(t))</query>
|
||||||
</test>
|
</test>
|
||||||
|
@ -120,11 +120,11 @@ SELECT toDayOfMonth(toDateTime(1412106600), 'Pacific/Pitcairn');
|
|||||||
/* toDayOfWeek */
|
/* toDayOfWeek */
|
||||||
|
|
||||||
SELECT 'toDayOfWeek';
|
SELECT 'toDayOfWeek';
|
||||||
SELECT toDayOfWeek(toDateTime(1412106600), 'Asia/Istanbul');
|
SELECT toDayOfWeek(toDateTime(1412106600), 0, 'Asia/Istanbul');
|
||||||
SELECT toDayOfWeek(toDateTime(1412106600), 'Europe/Paris');
|
SELECT toDayOfWeek(toDateTime(1412106600), 0, 'Europe/Paris');
|
||||||
SELECT toDayOfWeek(toDateTime(1412106600), 'Europe/London');
|
SELECT toDayOfWeek(toDateTime(1412106600), 0, 'Europe/London');
|
||||||
SELECT toDayOfWeek(toDateTime(1412106600), 'Asia/Tokyo');
|
SELECT toDayOfWeek(toDateTime(1412106600), 0, 'Asia/Tokyo');
|
||||||
SELECT toDayOfWeek(toDateTime(1412106600), 'Pacific/Pitcairn');
|
SELECT toDayOfWeek(toDateTime(1412106600), 0, 'Pacific/Pitcairn');
|
||||||
|
|
||||||
/* toHour */
|
/* toHour */
|
||||||
|
|
||||||
|
@ -7,14 +7,14 @@ import sys
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
# Create SQL statement to verify dateTime64 is accepted as argument to functions taking DateTime.
|
# Create SQL statement to verify dateTime64 is accepted as argument to functions taking DateTime.
|
||||||
FUNCTIONS="""
|
FUNCTIONS = """
|
||||||
toTimeZone(N, 'UTC')
|
toTimeZone(N, 'UTC')
|
||||||
toYear(N, 'Asia/Istanbul')
|
toYear(N, 'Asia/Istanbul')
|
||||||
toQuarter(N, 'Asia/Istanbul')
|
toQuarter(N, 'Asia/Istanbul')
|
||||||
toMonth(N, 'Asia/Istanbul')
|
toMonth(N, 'Asia/Istanbul')
|
||||||
toDayOfYear(N, 'Asia/Istanbul')
|
toDayOfYear(N, 'Asia/Istanbul')
|
||||||
toDayOfMonth(N, 'Asia/Istanbul')
|
toDayOfMonth(N, 'Asia/Istanbul')
|
||||||
toDayOfWeek(N, 'Asia/Istanbul')
|
toDayOfWeek(N, 0, 'Asia/Istanbul')
|
||||||
toHour(N, 'Asia/Istanbul')
|
toHour(N, 'Asia/Istanbul')
|
||||||
toMinute(N, 'Asia/Istanbul')
|
toMinute(N, 'Asia/Istanbul')
|
||||||
toSecond(N, 'Asia/Istanbul')
|
toSecond(N, 'Asia/Istanbul')
|
||||||
@ -90,68 +90,51 @@ formatDateTime(N, '%C %d %D %e %F %H %I %j %m %M %p %R %S %T %u %V %w %y %Y %%',
|
|||||||
extra_ops = [
|
extra_ops = [
|
||||||
# With same type:
|
# With same type:
|
||||||
(
|
(
|
||||||
['N {op} N'],
|
["N {op} N"],
|
||||||
{
|
{
|
||||||
'op':
|
"op": [
|
||||||
[
|
"- ", # does not work, but should it?
|
||||||
'- ', # does not work, but should it?
|
"+ ", # does not work, but should it?
|
||||||
'+ ', # does not work, but should it?
|
"!=",
|
||||||
'!=', '==', # equality and inequality supposed to take sub-second part in account
|
"==", # equality and inequality supposed to take sub-second part in account
|
||||||
'< ',
|
"< ",
|
||||||
'<=',
|
"<=",
|
||||||
'> ',
|
"> ",
|
||||||
'>='
|
">=",
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
# With other DateTime types:
|
# With other DateTime types:
|
||||||
(
|
(
|
||||||
[
|
["N {op} {arg}", "{arg} {op} N"],
|
||||||
'N {op} {arg}',
|
|
||||||
'{arg} {op} N'
|
|
||||||
],
|
|
||||||
{
|
{
|
||||||
'op':
|
"op": [
|
||||||
[
|
"-", # does not work, but should it?
|
||||||
'-', # does not work, but should it?
|
"!=",
|
||||||
'!=', '==',
|
"==",
|
||||||
# these are naturally expected to work, but they don't:
|
# these are naturally expected to work, but they don't:
|
||||||
'< ',
|
"< ",
|
||||||
'<=',
|
"<=",
|
||||||
'> ',
|
"> ",
|
||||||
'>='
|
">=",
|
||||||
],
|
],
|
||||||
'arg': ['DT', 'D', 'DT64'],
|
"arg": ["DT", "D", "DT64"],
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
# With arithmetic types
|
# With arithmetic types
|
||||||
(
|
(
|
||||||
[
|
["N {op} {arg}", "{arg} {op} N"],
|
||||||
'N {op} {arg}',
|
|
||||||
'{arg} {op} N'
|
|
||||||
],
|
|
||||||
{
|
{
|
||||||
'op':
|
"op": ["+ ", "- ", "==", "!=", "< ", "<=", "> ", ">="],
|
||||||
[
|
"arg": [
|
||||||
'+ ',
|
"toUInt8(1)",
|
||||||
'- ',
|
"toInt8(-1)",
|
||||||
'==',
|
"toUInt16(1)",
|
||||||
'!=',
|
"toInt16(-1)",
|
||||||
'< ',
|
"toUInt32(1)",
|
||||||
'<=',
|
"toInt32(-1)",
|
||||||
'> ',
|
"toUInt64(1)",
|
||||||
'>='
|
"toInt64(-1)",
|
||||||
],
|
|
||||||
'arg':
|
|
||||||
[
|
|
||||||
'toUInt8(1)',
|
|
||||||
'toInt8(-1)',
|
|
||||||
'toUInt16(1)',
|
|
||||||
'toInt16(-1)',
|
|
||||||
'toUInt32(1)',
|
|
||||||
'toInt32(-1)',
|
|
||||||
'toUInt64(1)',
|
|
||||||
'toInt64(-1)'
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -167,14 +150,17 @@ for funcs, args in extra_ops:
|
|||||||
|
|
||||||
# filter out empty lines and commented out lines
|
# filter out empty lines and commented out lines
|
||||||
COMMENTED_OUT_LINE_RE = re.compile(r"^\s*#")
|
COMMENTED_OUT_LINE_RE = re.compile(r"^\s*#")
|
||||||
FUNCTIONS = list([f for f in FUNCTIONS if len(f) != 0 and COMMENTED_OUT_LINE_RE.match(f) == None])
|
FUNCTIONS = list(
|
||||||
TYPES = ['D', 'DT', 'DT64']
|
[f for f in FUNCTIONS if len(f) != 0 and COMMENTED_OUT_LINE_RE.match(f) == None]
|
||||||
|
)
|
||||||
|
TYPES = ["D", "DT", "DT64"]
|
||||||
|
|
||||||
|
|
||||||
def escape_string(s):
|
def escape_string(s):
|
||||||
if sys.version_info[0] > 2:
|
if sys.version_info[0] > 2:
|
||||||
return s.encode('unicode_escape').decode('utf-8').replace("'", "\\'")
|
return s.encode("unicode_escape").decode("utf-8").replace("'", "\\'")
|
||||||
else:
|
else:
|
||||||
return s.encode('string-escape').decode('utf-8')
|
return s.encode("string-escape").decode("utf-8")
|
||||||
|
|
||||||
|
|
||||||
def execute_functions_for_types(functions, types):
|
def execute_functions_for_types(functions, types):
|
||||||
@ -186,18 +172,39 @@ def execute_functions_for_types(functions, types):
|
|||||||
WITH \
|
WITH \
|
||||||
toDateTime64('2019-09-16 19:20:11.234', 3, 'Europe/Minsk') as DT64, \
|
toDateTime64('2019-09-16 19:20:11.234', 3, 'Europe/Minsk') as DT64, \
|
||||||
toDateTime('2019-09-16 19:20:11', 'Europe/Minsk') as DT, \
|
toDateTime('2019-09-16 19:20:11', 'Europe/Minsk') as DT, \
|
||||||
toDate('2019-09-16') as D, {X} as N".format(X=dt)
|
toDate('2019-09-16') as D, {X} as N".format(
|
||||||
print(("""{prologue} SELECT toTypeName(r), {func} as r FORMAT CSV;""".format(prologue=prologue, func=func)))
|
X=dt
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
(
|
||||||
|
"""{prologue} SELECT toTypeName(r), {func} as r FORMAT CSV;""".format(
|
||||||
|
prologue=prologue, func=func
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
print("""SELECT '------------------------------------------';""")
|
print("""SELECT '------------------------------------------';""")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
def parse_args():
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('--functions_re', type=re.compile, help="RE to enable functions", default=None)
|
parser.add_argument(
|
||||||
parser.add_argument('--types_re',
|
"--functions_re",
|
||||||
type=lambda s: re.compile('^(' + s + ')$'),
|
type=re.compile,
|
||||||
help="RE to enable types, supported types: " + ",".join(TYPES), default=None)
|
help="RE to enable functions",
|
||||||
parser.add_argument('--list_functions', action='store_true', help="List all functions to be tested and exit")
|
default=None,
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--types_re",
|
||||||
|
type=lambda s: re.compile("^(" + s + ")$"),
|
||||||
|
help="RE to enable types, supported types: " + ",".join(TYPES),
|
||||||
|
default=None,
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--list_functions",
|
||||||
|
action="store_true",
|
||||||
|
help="List all functions to be tested and exit",
|
||||||
|
)
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
@ -223,5 +230,6 @@ def main():
|
|||||||
|
|
||||||
execute_functions_for_types(functions, types)
|
execute_functions_for_types(functions, types)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
exit(main())
|
exit(main())
|
||||||
|
@ -28,7 +28,7 @@ SELECT toDayOfMonth(N, \'Asia/Istanbul\')
|
|||||||
"UInt8",16
|
"UInt8",16
|
||||||
"UInt8",16
|
"UInt8",16
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
SELECT toDayOfWeek(N, \'Asia/Istanbul\')
|
SELECT toDayOfWeek(N, 0, \'Asia/Istanbul\')
|
||||||
"UInt8",1
|
"UInt8",1
|
||||||
"UInt8",1
|
"UInt8",1
|
||||||
"UInt8",1
|
"UInt8",1
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
1 7
|
||||||
|
1 7
|
||||||
|
0 6
|
||||||
|
1 0
|
||||||
|
2 1
|
||||||
|
1 7
|
||||||
|
0 6
|
10
tests/queries/0_stateless/02521_to_custom_day_of_week.sql
Normal file
10
tests/queries/0_stateless/02521_to_custom_day_of_week.sql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
with toDate('2023-01-09') as date_mon, date_mon - 1 as date_sun select toDayOfWeek(date_mon), toDayOfWeek(date_sun);
|
||||||
|
with toDate('2023-01-09') as date_mon, date_mon - 1 as date_sun select toDayOfWeek(date_mon, 0), toDayOfWeek(date_sun, 0);
|
||||||
|
with toDate('2023-01-09') as date_mon, date_mon - 1 as date_sun select toDayOfWeek(date_mon, 1), toDayOfWeek(date_sun, 1);
|
||||||
|
with toDate('2023-01-09') as date_mon, date_mon - 1 as date_sun select toDayOfWeek(date_mon, 2), toDayOfWeek(date_sun, 2);
|
||||||
|
with toDate('2023-01-09') as date_mon, date_mon - 1 as date_sun select toDayOfWeek(date_mon, 3), toDayOfWeek(date_sun, 3);
|
||||||
|
with toDate('2023-01-09') as date_mon, date_mon - 1 as date_sun select toDayOfWeek(date_mon, 4), toDayOfWeek(date_sun, 4);
|
||||||
|
with toDate('2023-01-09') as date_mon, date_mon - 1 as date_sun select toDayOfWeek(date_mon, 5), toDayOfWeek(date_sun, 5);
|
||||||
|
|
||||||
|
select toDayOfWeek(today(), -1); -- { serverError 43 }
|
Loading…
Reference in New Issue
Block a user