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
|
||||
|
||||
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`.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
toDayOfWeek(t[, mode[, timezone]])
|
||||
```
|
||||
|
||||
## toHour
|
||||
|
||||
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.
|
||||
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.
|
||||
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
|
||||
|
||||
@ -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.
|
||||
|
||||
## 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.
|
||||
|
||||
| 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.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
toWeek(date, [, mode][, Timezone])
|
||||
toWeek(t[, mode[, time_zone]])
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `date` – Date or DateTime.
|
||||
- `t` – Date or DateTime.
|
||||
- `mode` – Optional parameter, Range of values is \[0,9\], default is 0.
|
||||
- `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.
|
||||
|
||||
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**
|
||||
|
||||
|
@ -39,6 +39,15 @@ enum class WeekModeFlag : 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.
|
||||
* First time was implemented for OLAPServer, that needed to do billions of such transformations.
|
||||
*/
|
||||
@ -619,9 +628,28 @@ public:
|
||||
template <typename DateOrTime>
|
||||
inline Int16 toYear(DateOrTime v) const { return lut[toLUTIndex(v)].year; }
|
||||
|
||||
/// 1-based, starts on Monday
|
||||
template <typename DateOrTime>
|
||||
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>
|
||||
inline UInt8 toDayOfMonth(DateOrTime v) const { return lut[toLUTIndex(v)].day_of_month; }
|
||||
|
||||
@ -844,6 +872,12 @@ public:
|
||||
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.
|
||||
* Returns 0 for monday, 1 for tuesday...
|
||||
*/
|
||||
|
@ -786,21 +786,21 @@ struct ToDayOfWeekImpl
|
||||
{
|
||||
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;
|
||||
|
@ -82,8 +82,8 @@ protected:
|
||||
arguments[0].type->getName(), getName());
|
||||
if (!isUInt8(arguments[1].type))
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type of 2nd (optional) argument of function {}. Must be constant UInt8 (week mode).",
|
||||
getName());
|
||||
"Illegal type {} of 2nd (optional) argument of function {}. Must be constant UInt8 (week mode).",
|
||||
arguments[1].type->getName(), getName());
|
||||
}
|
||||
else if (arguments.size() == 3)
|
||||
{
|
||||
@ -93,12 +93,12 @@ protected:
|
||||
arguments[0].type->getName(), getName());
|
||||
if (!isUInt8(arguments[1].type))
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type of 2nd (optional) argument of function {}. Must be constant UInt8 (week mode).",
|
||||
getName());
|
||||
"Illegal type {} of 2nd (optional) argument of function {}. Must be constant UInt8 (week mode).",
|
||||
arguments[1].type->getName(), getName());
|
||||
if (!isString(arguments[2].type))
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Illegal type of 3rd (optional) argument of function {}. Must be constant string (timezone name).",
|
||||
getName());
|
||||
"Illegal type {} of 3rd (optional) argument of function {}. Must be constant string (timezone name).",
|
||||
arguments[2].type->getName(), getName());
|
||||
if ((isDate(arguments[0].type) || isDate32(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 is DateTime or DateTime64.",
|
||||
|
@ -225,8 +225,8 @@ public:
|
||||
}
|
||||
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 y_day_of_week = TransformDateTime64<ToDayOfWeekImpl>(transform_y.getScaleMultiplier()).execute(y, timezone_y);
|
||||
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, 0, timezone_y);
|
||||
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))
|
||||
|| ((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)
|
||||
{
|
||||
const auto day = ToDayOfWeekImpl::execute(source, timezone);
|
||||
const auto day = ToDayOfWeekImpl::execute(source, 0, timezone);
|
||||
static constexpr std::string_view day_names[] =
|
||||
{
|
||||
"Monday",
|
||||
|
@ -344,13 +344,13 @@ private:
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
{
|
||||
auto week_day = ToDayOfWeekImpl::execute(source, timezone);
|
||||
auto week_day = ToDayOfWeekImpl::execute(source, 0, timezone);
|
||||
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)
|
||||
{
|
||||
auto week_day = ToDayOfWeekImpl::execute(source, timezone);
|
||||
auto week_day = ToDayOfWeekImpl::execute(source, 0, timezone);
|
||||
if (week_day == 7)
|
||||
week_day = 0;
|
||||
|
||||
|
@ -1,13 +1,12 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/DateTimeTransforms.h>
|
||||
#include <Functions/FunctionDateOrDateTimeToSomething.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
|
||||
#include <Functions/FunctionCustomWeekToSomething.h>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
using FunctionToDayOfWeek = FunctionDateOrDateTimeToSomething<DataTypeUInt8, ToDayOfWeekImpl>;
|
||||
using FunctionToDayOfWeek = FunctionCustomWeekToSomething<DataTypeUInt8, ToDayOfWeekImpl>;
|
||||
|
||||
REGISTER_FUNCTION(ToDayOfWeek)
|
||||
{
|
||||
|
@ -6,7 +6,6 @@
|
||||
<value>toSecond</value>
|
||||
<value>toMinute</value>
|
||||
<value>toHour</value>
|
||||
<value>toDayOfWeek</value>
|
||||
<value>toDayOfMonth</value>
|
||||
<value>toDayOfYear</value>
|
||||
<value>toMonth</value>
|
||||
@ -47,21 +46,33 @@
|
||||
<value>toUnixTimestamp</value>
|
||||
</values>
|
||||
</substitution>
|
||||
<substitution>
|
||||
<name>datetime_transform_with_mode</name>
|
||||
<values>
|
||||
<value>toDayOfWeek</value>
|
||||
<value>toStartOfWeek</value>
|
||||
<value>toWeek</value>
|
||||
<value>toYearWeek</value>
|
||||
</values>
|
||||
</substitution>
|
||||
<substitution>
|
||||
<name>date_transform</name>
|
||||
<values>
|
||||
<value>toDayOfWeek</value>
|
||||
<value>toDayOfMonth</value>
|
||||
<value>toDayOfWeek</value>
|
||||
<value>toDayOfYear</value>
|
||||
<value>toWeek</value>
|
||||
<value>toMonth</value>
|
||||
<value>toQuarter</value>
|
||||
<value>toYear</value>
|
||||
<value>toYearWeek</value>
|
||||
<value>toISOWeek</value>
|
||||
<value>toISOYear</value>
|
||||
|
||||
<value>toDate</value>
|
||||
<value>toMonday</value>
|
||||
<value>toStartOfDay</value>
|
||||
<value>toStartOfWeek</value>
|
||||
<value>toStartOfMonth</value>
|
||||
<value>toStartOfQuarter</value>
|
||||
<value>toStartOfYear</value>
|
||||
@ -79,14 +90,6 @@
|
||||
<value>toRelativeQuarterNum</value>
|
||||
</values>
|
||||
</substitution>
|
||||
<substitution>
|
||||
<name>time_zone</name>
|
||||
<values>
|
||||
<value>UTC</value>
|
||||
<value>Asia/Istanbul</value>
|
||||
<value>Asia/Kolkata</value>
|
||||
</values>
|
||||
</substitution>
|
||||
<substitution>
|
||||
<name>binary_function</name>
|
||||
<values>
|
||||
@ -116,11 +119,21 @@
|
||||
<value>subtractYears</value>
|
||||
</values>
|
||||
</substitution>
|
||||
<substitution>
|
||||
<name>time_zone</name>
|
||||
<values>
|
||||
<value>UTC</value>
|
||||
<value>Asia/Istanbul</value>
|
||||
<value>Asia/Kolkata</value>
|
||||
</values>
|
||||
</substitution>
|
||||
</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_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(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, date_trunc('month', t))</query>
|
||||
</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>
|
||||
<!--
|
||||
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>
|
||||
<substitution>
|
||||
<name>date_transform</name>
|
||||
<values>
|
||||
<value>toDayOfWeek</value>
|
||||
<value>toMonday</value>
|
||||
<value>toRelativeDayNum</value>
|
||||
<value>toYYYYMMDDhhmmss</value>
|
||||
@ -32,16 +29,24 @@
|
||||
</substitution>
|
||||
</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(toDate('2017-01-01') + number % 1000 + rand() % 10 AS t, {date_transform}(t))</query>
|
||||
|
||||
<!-- 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>
|
||||
<!-- 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>
|
||||
|
||||
<!-- {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>
|
||||
|
||||
<!-- 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, 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>
|
||||
|
@ -120,11 +120,11 @@ SELECT toDayOfMonth(toDateTime(1412106600), 'Pacific/Pitcairn');
|
||||
/* toDayOfWeek */
|
||||
|
||||
SELECT 'toDayOfWeek';
|
||||
SELECT toDayOfWeek(toDateTime(1412106600), 'Asia/Istanbul');
|
||||
SELECT toDayOfWeek(toDateTime(1412106600), 'Europe/Paris');
|
||||
SELECT toDayOfWeek(toDateTime(1412106600), 'Europe/London');
|
||||
SELECT toDayOfWeek(toDateTime(1412106600), 'Asia/Tokyo');
|
||||
SELECT toDayOfWeek(toDateTime(1412106600), 'Pacific/Pitcairn');
|
||||
SELECT toDayOfWeek(toDateTime(1412106600), 0, 'Asia/Istanbul');
|
||||
SELECT toDayOfWeek(toDateTime(1412106600), 0, 'Europe/Paris');
|
||||
SELECT toDayOfWeek(toDateTime(1412106600), 0, 'Europe/London');
|
||||
SELECT toDayOfWeek(toDateTime(1412106600), 0, 'Asia/Tokyo');
|
||||
SELECT toDayOfWeek(toDateTime(1412106600), 0, 'Pacific/Pitcairn');
|
||||
|
||||
/* toHour */
|
||||
|
||||
|
@ -7,14 +7,14 @@ import sys
|
||||
import argparse
|
||||
|
||||
# Create SQL statement to verify dateTime64 is accepted as argument to functions taking DateTime.
|
||||
FUNCTIONS="""
|
||||
FUNCTIONS = """
|
||||
toTimeZone(N, 'UTC')
|
||||
toYear(N, 'Asia/Istanbul')
|
||||
toQuarter(N, 'Asia/Istanbul')
|
||||
toMonth(N, 'Asia/Istanbul')
|
||||
toDayOfYear(N, 'Asia/Istanbul')
|
||||
toDayOfMonth(N, 'Asia/Istanbul')
|
||||
toDayOfWeek(N, 'Asia/Istanbul')
|
||||
toDayOfWeek(N, 0, 'Asia/Istanbul')
|
||||
toHour(N, 'Asia/Istanbul')
|
||||
toMinute(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 = [
|
||||
# With same type:
|
||||
(
|
||||
['N {op} N'],
|
||||
["N {op} N"],
|
||||
{
|
||||
'op':
|
||||
[
|
||||
'- ', # does not work, but should it?
|
||||
'+ ', # does not work, but should it?
|
||||
'!=', '==', # equality and inequality supposed to take sub-second part in account
|
||||
'< ',
|
||||
'<=',
|
||||
'> ',
|
||||
'>='
|
||||
"op": [
|
||||
"- ", # does not work, but should it?
|
||||
"+ ", # does not work, but should it?
|
||||
"!=",
|
||||
"==", # equality and inequality supposed to take sub-second part in account
|
||||
"< ",
|
||||
"<=",
|
||||
"> ",
|
||||
">=",
|
||||
]
|
||||
}
|
||||
},
|
||||
),
|
||||
# With other DateTime types:
|
||||
(
|
||||
[
|
||||
'N {op} {arg}',
|
||||
'{arg} {op} N'
|
||||
],
|
||||
["N {op} {arg}", "{arg} {op} N"],
|
||||
{
|
||||
'op':
|
||||
[
|
||||
'-', # does not work, but should it?
|
||||
'!=', '==',
|
||||
"op": [
|
||||
"-", # does not work, but should it?
|
||||
"!=",
|
||||
"==",
|
||||
# these are naturally expected to work, but they don't:
|
||||
'< ',
|
||||
'<=',
|
||||
'> ',
|
||||
'>='
|
||||
"< ",
|
||||
"<=",
|
||||
"> ",
|
||||
">=",
|
||||
],
|
||||
'arg': ['DT', 'D', 'DT64'],
|
||||
}
|
||||
"arg": ["DT", "D", "DT64"],
|
||||
},
|
||||
),
|
||||
# With arithmetic types
|
||||
(
|
||||
[
|
||||
'N {op} {arg}',
|
||||
'{arg} {op} N'
|
||||
],
|
||||
["N {op} {arg}", "{arg} {op} N"],
|
||||
{
|
||||
'op':
|
||||
[
|
||||
'+ ',
|
||||
'- ',
|
||||
'==',
|
||||
'!=',
|
||||
'< ',
|
||||
'<=',
|
||||
'> ',
|
||||
'>='
|
||||
],
|
||||
'arg':
|
||||
[
|
||||
'toUInt8(1)',
|
||||
'toInt8(-1)',
|
||||
'toUInt16(1)',
|
||||
'toInt16(-1)',
|
||||
'toUInt32(1)',
|
||||
'toInt32(-1)',
|
||||
'toUInt64(1)',
|
||||
'toInt64(-1)'
|
||||
"op": ["+ ", "- ", "==", "!=", "< ", "<=", "> ", ">="],
|
||||
"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
|
||||
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])
|
||||
TYPES = ['D', 'DT', 'DT64']
|
||||
FUNCTIONS = list(
|
||||
[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):
|
||||
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:
|
||||
return s.encode('string-escape').decode('utf-8')
|
||||
return s.encode("string-escape").decode("utf-8")
|
||||
|
||||
|
||||
def execute_functions_for_types(functions, types):
|
||||
@ -186,18 +172,39 @@ def execute_functions_for_types(functions, types):
|
||||
WITH \
|
||||
toDateTime64('2019-09-16 19:20:11.234', 3, 'Europe/Minsk') as DT64, \
|
||||
toDateTime('2019-09-16 19:20:11', 'Europe/Minsk') as DT, \
|
||||
toDate('2019-09-16') as D, {X} as N".format(X=dt)
|
||||
print(("""{prologue} SELECT toTypeName(r), {func} as r FORMAT CSV;""".format(prologue=prologue, func=func)))
|
||||
toDate('2019-09-16') as D, {X} as N".format(
|
||||
X=dt
|
||||
)
|
||||
print(
|
||||
(
|
||||
"""{prologue} SELECT toTypeName(r), {func} as r FORMAT CSV;""".format(
|
||||
prologue=prologue, func=func
|
||||
)
|
||||
)
|
||||
)
|
||||
print("""SELECT '------------------------------------------';""")
|
||||
|
||||
|
||||
def main():
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--functions_re', type=re.compile, help="RE to enable functions", 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")
|
||||
parser.add_argument(
|
||||
"--functions_re",
|
||||
type=re.compile,
|
||||
help="RE to enable functions",
|
||||
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()
|
||||
|
||||
args = parse_args()
|
||||
@ -223,5 +230,6 @@ def main():
|
||||
|
||||
execute_functions_for_types(functions, types)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
||||
|
@ -28,7 +28,7 @@ SELECT toDayOfMonth(N, \'Asia/Istanbul\')
|
||||
"UInt8",16
|
||||
"UInt8",16
|
||||
------------------------------------------
|
||||
SELECT toDayOfWeek(N, \'Asia/Istanbul\')
|
||||
SELECT toDayOfWeek(N, 0, \'Asia/Istanbul\')
|
||||
"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