mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Merge pull request #50315 from arenadata/ADQM-810
Add new function toLastDayOfWeek()
This commit is contained in:
commit
45b1fcdeda
@ -3818,8 +3818,8 @@ 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).
|
||||
- `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).
|
||||
- `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), [toLastDayOfMonth](../../sql-reference/functions/date-time-functions.md#tolastdayofmonth), [toStartOfWeek](../../sql-reference/functions/date-time-functions.md#tostartofweek), [toLastDayOfWeek](../../sql-reference/functions/date-time-functions.md#tolastdayofweek) and [toMonday](../../sql-reference/functions/date-time-functions.md#tomonday).
|
||||
- `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:
|
||||
|
||||
|
@ -403,12 +403,14 @@ from_date32: 1509840000
|
||||
```
|
||||
|
||||
:::note
|
||||
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.md#enable-extended-results-for-datetime-functions) which is `0` by default.
|
||||
The return type of `toStartOf*`, `toLastDayOf*`, `toMonday`, `timeSlot` functions described below is determined by the configuration parameter [enable_extended_results_for_datetime_functions](../../operations/settings/settings.md#enable-extended-results-for-datetime-functions) which is `0` by default.
|
||||
|
||||
Behavior for
|
||||
* `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.
|
||||
* `enable_extended_results_for_datetime_functions = 0`:
|
||||
* Functions `toStartOfYear`, `toStartOfISOYear`, `toStartOfQuarter`, `toStartOfMonth`, `toStartOfWeek`, `toLastDayOfWeek`, `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.
|
||||
* `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 `toStartOfYear`, `toStartOfISOYear`, `toStartOfQuarter`, `toStartOfMonth`, `toStartOfWeek`, `toLastDayOfWeek`, `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`.
|
||||
:::
|
||||
|
||||
@ -463,6 +465,18 @@ The mode argument works exactly like the mode argument in function `toWeek()`. I
|
||||
toStartOfWeek(t[, mode[, timezone]])
|
||||
```
|
||||
|
||||
## toLastDayOfWeek
|
||||
|
||||
Rounds a date or date with time up to the nearest Saturday or Sunday.
|
||||
Returns the date.
|
||||
The mode argument works exactly like the mode argument in function `toWeek()`. If no mode is specified, mode is assumed as 0.
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
toLastDayOfWeek(t[, mode[, timezone]])
|
||||
```
|
||||
|
||||
## toStartOfDay
|
||||
|
||||
Rounds down a date with time to the start of the day.
|
||||
|
@ -3790,7 +3790,7 @@ 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).
|
||||
- `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), [toLastDayOfMonth](../../sql-reference/functions/date-time-functions.md#tolastdayofmonth), [toStartOfWeek](../../sql-reference/functions/date-time-functions.md#tostartofweek), [toLastDayOfWeek](../../sql-reference/functions/date-time-functions.md#tolastdayofweek) и [toMonday](../../sql-reference/functions/date-time-functions.md#tomonday).
|
||||
- `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).
|
||||
|
||||
Возможные значения:
|
||||
|
@ -282,13 +282,15 @@ from_date32: 1509840000
|
||||
```
|
||||
|
||||
:::note
|
||||
Тип возвращаемого значения описанными далее функциями `toStartOf*`, `toLastDayOfMonth`, `toMonday`, `timeSlot` определяется конфигурационным параметром [enable_extended_results_for_datetime_functions](../../operations/settings/settings.md#enable-extended-results-for-datetime-functions) имеющим по умолчанию значение `0`.
|
||||
Тип возвращаемого значения описанными далее функциями `toStartOf*`, `toLastDayOf*`, `toMonday`, `timeSlot` определяется конфигурационным параметром [enable_extended_results_for_datetime_functions](../../operations/settings/settings.md#enable-extended-results-for-datetime-functions) имеющим по умолчанию значение `0`.
|
||||
|
||||
Поведение для
|
||||
* `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`) будет получен некорректный результат.
|
||||
* `enable_extended_results_for_datetime_functions = 0`:
|
||||
* Функции `toStartOfYear`, `toStartOfISOYear`, `toStartOfQuarter`, `toStartOfMonth`, `toStartOfWeek`, `toLastDayOfWeek`, `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`) будет получен некорректный результат.
|
||||
* `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`, `toStartOfISOYear`, `toStartOfQuarter`, `toStartOfMonth`, `toStartOfWeek`, `toLastDayOfWeek`, `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}
|
||||
@ -338,9 +340,15 @@ SELECT toStartOfISOYear(toDate('2017-01-01')) AS ISOYear20170101;
|
||||
Округляет дату или дату-с-временем вниз до ближайшего понедельника.
|
||||
Возвращается дата.
|
||||
|
||||
## toStartOfWeek(t[,mode]) {#tostartofweek}
|
||||
## toStartOfWeek(t[, mode[, timezone]])
|
||||
|
||||
Округляет дату или дату со временем до ближайшего воскресенья или понедельника в соответствии с mode.
|
||||
Округляет дату или дату-с-временем назад, до ближайшего воскресенья или понедельника, в соответствии с mode.
|
||||
Возвращается дата.
|
||||
Аргумент mode работает точно так же, как аргумент mode [toWeek()](#toweek). Если аргумент mode опущен, то используется режим 0.
|
||||
|
||||
## toLastDayOfWeek(t[, mode[, timezone]])
|
||||
|
||||
Округляет дату или дату-с-временем вперёд, до ближайшей субботы или воскресенья, в соответствии с mode.
|
||||
Возвращается дата.
|
||||
Аргумент mode работает точно так же, как аргумент mode [toWeek()](#toweek). Если аргумент mode опущен, то используется режим 0.
|
||||
|
||||
|
@ -313,11 +313,6 @@ public:
|
||||
|
||||
/// All functions below are thread-safe; arguments are not checked.
|
||||
|
||||
static ExtendedDayNum toDayNum(ExtendedDayNum d)
|
||||
{
|
||||
return d;
|
||||
}
|
||||
|
||||
static UInt32 saturateMinus(UInt32 x, UInt32 y)
|
||||
{
|
||||
UInt32 res = x - y;
|
||||
@ -325,6 +320,11 @@ public:
|
||||
return res;
|
||||
}
|
||||
|
||||
static ExtendedDayNum toDayNum(ExtendedDayNum d)
|
||||
{
|
||||
return d;
|
||||
}
|
||||
|
||||
static ExtendedDayNum toDayNum(LUTIndex d)
|
||||
{
|
||||
return ExtendedDayNum{static_cast<ExtendedDayNum::UnderlyingType>(d.toUnderType() - daynum_offset_epoch)};
|
||||
@ -365,6 +365,27 @@ public:
|
||||
return toDayNum(LUTIndex(i - (lut[i].day_of_week - 1)));
|
||||
}
|
||||
|
||||
/// Round up to the last day of week.
|
||||
template <typename DateOrTime>
|
||||
inline Time toLastDayOfWeek(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
return lut_saturated[i + (7 - lut[i].day_of_week)].date;
|
||||
else
|
||||
return lut[i + (7 - lut[i].day_of_week)].date;
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline auto toLastDayNumOfWeek(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
return toDayNum(LUTIndexWithSaturation(i + (7 - lut[i].day_of_week)));
|
||||
else
|
||||
return toDayNum(LUTIndex(i + (7 - lut[i].day_of_week)));
|
||||
}
|
||||
|
||||
/// Round down to start of month.
|
||||
template <typename DateOrTime>
|
||||
inline Time toFirstDayOfMonth(DateOrTime v) const
|
||||
@ -858,10 +879,31 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto day_of_week = toDayOfWeek(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
return (toDayOfWeek(v) != 7) ? DayNum(saturateMinus(v, toDayOfWeek(v))) : toDayNum(v);
|
||||
return (day_of_week != 7) ? DayNum(saturateMinus(v, day_of_week)) : toDayNum(v);
|
||||
else
|
||||
return (toDayOfWeek(v) != 7) ? ExtendedDayNum(v - toDayOfWeek(v)) : toDayNum(v);
|
||||
return (day_of_week != 7) ? ExtendedDayNum(v - day_of_week) : toDayNum(v);
|
||||
}
|
||||
}
|
||||
|
||||
/// Get last day of week with week_mode, return Saturday or Sunday
|
||||
template <typename DateOrTime>
|
||||
inline auto toLastDayNumOfWeek(DateOrTime v, UInt8 week_mode) const
|
||||
{
|
||||
bool monday_first_mode = week_mode & static_cast<UInt8>(WeekModeFlag::MONDAY_FIRST);
|
||||
if (monday_first_mode)
|
||||
{
|
||||
return toLastDayNumOfWeek(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto day_of_week = toDayOfWeek(v);
|
||||
v += 6;
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
return (day_of_week != 7) ? DayNum(saturateMinus(v, day_of_week)) : toDayNum(v);
|
||||
else
|
||||
return (day_of_week != 7) ? ExtendedDayNum(v - day_of_week) : toDayNum(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,6 +148,8 @@ TEST(DateLUTTest, TimeValuesInMiddleOfRange)
|
||||
EXPECT_EQ(lut.addYears(time, 10), 1884270011 /*time_t*/);
|
||||
EXPECT_EQ(lut.timeToString(time), "2019-09-16 19:20:11" /*std::string*/);
|
||||
EXPECT_EQ(lut.dateToString(time), "2019-09-16" /*std::string*/);
|
||||
EXPECT_EQ(lut.toLastDayOfWeek(time), 1569099600 /*time_t*/);
|
||||
EXPECT_EQ(lut.toLastDayNumOfWeek(time), DayNum(18161) /*DayNum*/);
|
||||
EXPECT_EQ(lut.toLastDayOfMonth(time), 1569790800 /*time_t*/);
|
||||
EXPECT_EQ(lut.toLastDayNumOfMonth(time), DayNum(18169) /*DayNum*/);
|
||||
}
|
||||
@ -211,6 +213,8 @@ TEST(DateLUTTest, TimeValuesAtLeftBoderOfRange)
|
||||
EXPECT_EQ(lut.addYears(time, 10), 315532800 /*time_t*/);
|
||||
EXPECT_EQ(lut.timeToString(time), "1970-01-01 00:00:00" /*std::string*/);
|
||||
EXPECT_EQ(lut.dateToString(time), "1970-01-01" /*std::string*/);
|
||||
EXPECT_EQ(lut.toLastDayOfWeek(time), 259200 /*time_t*/);
|
||||
EXPECT_EQ(lut.toLastDayNumOfWeek(time), DayNum(3) /*DayNum*/);
|
||||
EXPECT_EQ(lut.toLastDayOfMonth(time), 2592000 /*time_t*/);
|
||||
EXPECT_EQ(lut.toLastDayNumOfMonth(time), DayNum(30) /*DayNum*/);
|
||||
}
|
||||
@ -276,6 +280,8 @@ TEST(DateLUTTest, TimeValuesAtRightBoderOfRangeOfOldLUT)
|
||||
|
||||
EXPECT_EQ(lut.timeToString(time), "2106-01-31 01:17:53" /*std::string*/);
|
||||
EXPECT_EQ(lut.dateToString(time), "2106-01-31" /*std::string*/);
|
||||
EXPECT_EQ(lut.toLastDayOfWeek(time), 4294339200 /*time_t*/);
|
||||
EXPECT_EQ(lut.toLastDayNumOfWeek(time), DayNum(49703) /*DayNum*/);
|
||||
EXPECT_EQ(lut.toLastDayOfMonth(time), 4294339200 /*time_t*/); // 2106-01-01
|
||||
EXPECT_EQ(lut.toLastDayNumOfMonth(time), DayNum(49703));
|
||||
}
|
||||
|
@ -88,6 +88,38 @@ struct ToStartOfWeekImpl
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
|
||||
struct ToLastDayOfWeekImpl
|
||||
{
|
||||
static constexpr auto name = "toLastDayOfWeek";
|
||||
|
||||
static inline UInt16 execute(Int64 t, UInt8 week_mode, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfWeek(time_zone.toDayNum(t), week_mode);
|
||||
}
|
||||
static inline UInt16 execute(UInt32 t, UInt8 week_mode, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfWeek(time_zone.toDayNum(t), week_mode);
|
||||
}
|
||||
static inline UInt16 execute(Int32 d, UInt8 week_mode, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfWeek(ExtendedDayNum(d), week_mode);
|
||||
}
|
||||
static inline UInt16 execute(UInt16 d, UInt8 week_mode, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfWeek(DayNum(d), week_mode);
|
||||
}
|
||||
static inline Int64 executeExtendedResult(Int64 t, UInt8 week_mode, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfWeek(time_zone.toDayNum(t), week_mode);
|
||||
}
|
||||
static inline Int32 executeExtendedResult(Int32 d, UInt8 week_mode, const DateLUTImpl & time_zone)
|
||||
{
|
||||
return time_zone.toLastDayNumOfWeek(ExtendedDayNum(d), week_mode);
|
||||
}
|
||||
|
||||
using FactorTransform = ZeroTransform;
|
||||
};
|
||||
|
||||
struct ToWeekImpl
|
||||
{
|
||||
static constexpr auto name = "toWeek";
|
||||
|
@ -11,12 +11,14 @@ namespace DB
|
||||
using FunctionToWeek = FunctionCustomWeekToSomething<DataTypeUInt8, ToWeekImpl>;
|
||||
using FunctionToYearWeek = FunctionCustomWeekToSomething<DataTypeUInt32, ToYearWeekImpl>;
|
||||
using FunctionToStartOfWeek = FunctionCustomWeekToDateOrDate32<ToStartOfWeekImpl>;
|
||||
using FunctionToLastDayOfWeek = FunctionCustomWeekToDateOrDate32<ToLastDayOfWeekImpl>;
|
||||
|
||||
REGISTER_FUNCTION(ToCustomWeek)
|
||||
{
|
||||
factory.registerFunction<FunctionToWeek>();
|
||||
factory.registerFunction<FunctionToYearWeek>();
|
||||
factory.registerFunction<FunctionToStartOfWeek>();
|
||||
factory.registerFunction<FunctionToLastDayOfWeek>();
|
||||
|
||||
/// Compatibility aliases for mysql.
|
||||
factory.registerAlias("week", "toWeek", FunctionFactory::CaseInsensitive);
|
||||
|
@ -16,10 +16,34 @@ toMonday
|
||||
2014-12-29
|
||||
2014-12-22
|
||||
2014-12-29
|
||||
toStartOfWeek (Sunday)
|
||||
2014-12-28
|
||||
2014-12-28
|
||||
2014-12-28
|
||||
2014-12-28
|
||||
2014-12-28
|
||||
2014-12-28
|
||||
toStartOfWeek (Monday)
|
||||
2014-12-22
|
||||
2014-12-22
|
||||
2014-12-22
|
||||
2014-12-29
|
||||
2014-12-22
|
||||
2014-12-29
|
||||
2014-12-29
|
||||
2014-12-29
|
||||
toLastDayOfWeek (Sunday)
|
||||
2015-01-03
|
||||
2015-01-03
|
||||
2015-01-03
|
||||
2015-01-03
|
||||
2015-01-03
|
||||
2015-01-03
|
||||
toLastDayOfWeek (Monday)
|
||||
2014-12-28
|
||||
2014-12-28
|
||||
2014-12-28
|
||||
2015-01-04
|
||||
2014-12-28
|
||||
2015-01-04
|
||||
toStartOfMonth
|
||||
2014-12-01
|
||||
2014-12-01
|
||||
@ -27,10 +51,6 @@ toStartOfMonth
|
||||
2014-12-01
|
||||
2014-12-01
|
||||
2014-12-01
|
||||
2014-12-01
|
||||
2014-12-01
|
||||
2014-12-01
|
||||
2014-12-01
|
||||
toStartOfQuarter
|
||||
2014-07-01
|
||||
2014-07-01
|
||||
@ -38,10 +58,6 @@ toStartOfQuarter
|
||||
2014-10-01
|
||||
2014-07-01
|
||||
2014-07-01
|
||||
2014-07-01
|
||||
2014-07-01
|
||||
2014-07-01
|
||||
2014-07-01
|
||||
toStartOfYear
|
||||
2014-01-01
|
||||
2014-01-01
|
||||
@ -49,10 +65,6 @@ toStartOfYear
|
||||
2014-01-01
|
||||
2014-01-01
|
||||
2014-01-01
|
||||
2014-01-01
|
||||
2014-01-01
|
||||
2014-01-01
|
||||
2014-01-01
|
||||
toTime
|
||||
1970-01-02 11:00:00 1970-01-02 12:00:00
|
||||
1970-01-02 10:00:00 1970-01-02 11:00:00
|
||||
|
@ -33,11 +33,52 @@ SELECT toMonday(toDateTime(1419800400), 'Europe/Paris');
|
||||
SELECT toMonday(toDateTime(1419800400), 'Europe/London');
|
||||
SELECT toMonday(toDateTime(1419800400), 'Asia/Tokyo');
|
||||
SELECT toMonday(toDateTime(1419800400), 'Pacific/Pitcairn');
|
||||
SELECT toMonday(toDate(16433), 'Asia/Istanbul'); -- { serverError 43 }
|
||||
SELECT toMonday(toDate(16433));
|
||||
SELECT toMonday(toDate(16433));
|
||||
SELECT toMonday(toDate(16433));
|
||||
SELECT toMonday(toDate(16433));
|
||||
SELECT toMonday(toDate(16433));
|
||||
|
||||
/* toStartOfWeek (Sunday) */
|
||||
|
||||
SELECT 'toStartOfWeek (Sunday)';
|
||||
SELECT toStartOfWeek(toDateTime(1419800400), 0, 'Asia/Istanbul');
|
||||
SELECT toStartOfWeek(toDateTime(1419800400), 0, 'Europe/Paris');
|
||||
SELECT toStartOfWeek(toDateTime(1419800400), 0, 'Europe/London');
|
||||
SELECT toStartOfWeek(toDateTime(1419800400), 0, 'Asia/Tokyo');
|
||||
SELECT toStartOfWeek(toDateTime(1419800400), 0, 'Pacific/Pitcairn');
|
||||
SELECT toStartOfWeek(toDate(16433), 0, 'Asia/Istanbul'); -- { serverError 43 }
|
||||
SELECT toStartOfWeek(toDate(16433), 0);
|
||||
|
||||
/* toStartOfWeek (Monday) */
|
||||
|
||||
SELECT 'toStartOfWeek (Monday)';
|
||||
SELECT toStartOfWeek(toDateTime(1419800400), 1, 'Asia/Istanbul');
|
||||
SELECT toStartOfWeek(toDateTime(1419800400), 1, 'Europe/Paris');
|
||||
SELECT toStartOfWeek(toDateTime(1419800400), 1, 'Europe/London');
|
||||
SELECT toStartOfWeek(toDateTime(1419800400), 1, 'Asia/Tokyo');
|
||||
SELECT toStartOfWeek(toDateTime(1419800400), 1, 'Pacific/Pitcairn');
|
||||
SELECT toStartOfWeek(toDate(16433), 1, 'Asia/Istanbul'); -- { serverError 43 }
|
||||
SELECT toStartOfWeek(toDate(16433), 1);
|
||||
|
||||
/* toLastDayOfWeek (Sunday) */
|
||||
|
||||
SELECT 'toLastDayOfWeek (Sunday)';
|
||||
SELECT toLastDayOfWeek(toDateTime(1419800400), 0, 'Asia/Istanbul');
|
||||
SELECT toLastDayOfWeek(toDateTime(1419800400), 0, 'Europe/Paris');
|
||||
SELECT toLastDayOfWeek(toDateTime(1419800400), 0, 'Europe/London');
|
||||
SELECT toLastDayOfWeek(toDateTime(1419800400), 0, 'Asia/Tokyo');
|
||||
SELECT toLastDayOfWeek(toDateTime(1419800400), 0, 'Pacific/Pitcairn');
|
||||
SELECT toLastDayOfWeek(toDate(16433), 0, 'Asia/Istanbul'); -- { serverError 43 }
|
||||
SELECT toLastDayOfWeek(toDate(16433), 0);
|
||||
|
||||
/* toLastDayOfWeek (Monday) */
|
||||
|
||||
SELECT 'toLastDayOfWeek (Monday)';
|
||||
SELECT toLastDayOfWeek(toDateTime(1419800400), 1, 'Asia/Istanbul');
|
||||
SELECT toLastDayOfWeek(toDateTime(1419800400), 1, 'Europe/Paris');
|
||||
SELECT toLastDayOfWeek(toDateTime(1419800400), 1, 'Europe/London');
|
||||
SELECT toLastDayOfWeek(toDateTime(1419800400), 1, 'Asia/Tokyo');
|
||||
SELECT toLastDayOfWeek(toDateTime(1419800400), 1, 'Pacific/Pitcairn');
|
||||
SELECT toLastDayOfWeek(toDate(16433), 1, 'Asia/Istanbul'); -- { serverError 43 }
|
||||
SELECT toLastDayOfWeek(toDate(16433), 1);
|
||||
|
||||
/* toStartOfMonth */
|
||||
|
||||
@ -47,10 +88,7 @@ SELECT toStartOfMonth(toDateTime(1419800400), 'Europe/Paris');
|
||||
SELECT toStartOfMonth(toDateTime(1419800400), 'Europe/London');
|
||||
SELECT toStartOfMonth(toDateTime(1419800400), 'Asia/Tokyo');
|
||||
SELECT toStartOfMonth(toDateTime(1419800400), 'Pacific/Pitcairn');
|
||||
SELECT toStartOfMonth(toDate(16433));
|
||||
SELECT toStartOfMonth(toDate(16433));
|
||||
SELECT toStartOfMonth(toDate(16433));
|
||||
SELECT toStartOfMonth(toDate(16433));
|
||||
SELECT toStartOfMonth(toDate(16433), 'Asia/Istanbul'); -- { serverError 43 }
|
||||
SELECT toStartOfMonth(toDate(16433));
|
||||
|
||||
/* toStartOfQuarter */
|
||||
@ -61,10 +99,7 @@ SELECT toStartOfQuarter(toDateTime(1412106600), 'Europe/Paris');
|
||||
SELECT toStartOfQuarter(toDateTime(1412106600), 'Europe/London');
|
||||
SELECT toStartOfQuarter(toDateTime(1412106600), 'Asia/Tokyo');
|
||||
SELECT toStartOfQuarter(toDateTime(1412106600), 'Pacific/Pitcairn');
|
||||
SELECT toStartOfQuarter(toDate(16343));
|
||||
SELECT toStartOfQuarter(toDate(16343));
|
||||
SELECT toStartOfQuarter(toDate(16343));
|
||||
SELECT toStartOfQuarter(toDate(16343));
|
||||
SELECT toStartOfQuarter(toDate(16343), 'Asia/Istanbul'); -- { serverError 43 }
|
||||
SELECT toStartOfQuarter(toDate(16343));
|
||||
|
||||
/* toStartOfYear */
|
||||
@ -75,10 +110,7 @@ SELECT toStartOfYear(toDateTime(1419800400), 'Europe/Paris');
|
||||
SELECT toStartOfYear(toDateTime(1419800400), 'Europe/London');
|
||||
SELECT toStartOfYear(toDateTime(1419800400), 'Asia/Tokyo');
|
||||
SELECT toStartOfYear(toDateTime(1419800400), 'Pacific/Pitcairn');
|
||||
SELECT toStartOfYear(toDate(16433));
|
||||
SELECT toStartOfYear(toDate(16433));
|
||||
SELECT toStartOfYear(toDate(16433));
|
||||
SELECT toStartOfYear(toDate(16433));
|
||||
SELECT toStartOfYear(toDate(16433), 'Asia/Istanbul'); -- { serverError 43 }
|
||||
SELECT toStartOfYear(toDate(16433));
|
||||
|
||||
/* toTime */
|
||||
|
@ -61,13 +61,23 @@
|
||||
2017-01-09 00:00:00 2 3 201702 201703
|
||||
2017-01-10 00:00:00 2 3 201702 201703
|
||||
2017-01-11 00:00:00 2 3 201702 201703
|
||||
2018-12-25 2018-12-25 00:00:00 2018-12-23 2018-12-23 2018-12-24 2018-12-24
|
||||
2018-12-26 2018-12-26 00:00:00 2018-12-23 2018-12-23 2018-12-24 2018-12-24
|
||||
2018-12-27 2018-12-27 00:00:00 2018-12-23 2018-12-23 2018-12-24 2018-12-24
|
||||
2018-12-28 2018-12-28 00:00:00 2018-12-23 2018-12-23 2018-12-24 2018-12-24
|
||||
2018-12-29 2018-12-29 00:00:00 2018-12-23 2018-12-23 2018-12-24 2018-12-24
|
||||
2018-12-30 2018-12-30 00:00:00 2018-12-30 2018-12-30 2018-12-24 2018-12-24
|
||||
2018-12-31 2018-12-31 00:00:00 2018-12-30 2018-12-30 2018-12-31 2018-12-31
|
||||
2019-01-01 2019-01-01 00:00:00 2018-12-30 2018-12-30 2018-12-31 2018-12-31
|
||||
2019-01-02 2019-01-02 00:00:00 2018-12-30 2018-12-30 2018-12-31 2018-12-31
|
||||
2019-01-03 2019-01-03 00:00:00 2018-12-30 2018-12-30 2018-12-31 2018-12-31
|
||||
2018-12-25 00:00:00 2018-12-23 2018-12-23 2018-12-23 2018-12-23 2018-12-24 2018-12-24 2018-12-24 2018-12-24
|
||||
2018-12-26 00:00:00 2018-12-23 2018-12-23 2018-12-23 2018-12-23 2018-12-24 2018-12-24 2018-12-24 2018-12-24
|
||||
2018-12-27 00:00:00 2018-12-23 2018-12-23 2018-12-23 2018-12-23 2018-12-24 2018-12-24 2018-12-24 2018-12-24
|
||||
2018-12-28 00:00:00 2018-12-23 2018-12-23 2018-12-23 2018-12-23 2018-12-24 2018-12-24 2018-12-24 2018-12-24
|
||||
2018-12-29 00:00:00 2018-12-23 2018-12-23 2018-12-23 2018-12-23 2018-12-24 2018-12-24 2018-12-24 2018-12-24
|
||||
2018-12-30 00:00:00 2018-12-30 2018-12-30 2018-12-30 2018-12-30 2018-12-24 2018-12-24 2018-12-24 2018-12-24
|
||||
2018-12-31 00:00:00 2018-12-30 2018-12-30 2018-12-30 2018-12-30 2018-12-31 2018-12-31 2018-12-31 2018-12-31
|
||||
2019-01-01 00:00:00 2018-12-30 2018-12-30 2018-12-30 2018-12-30 2018-12-31 2018-12-31 2018-12-31 2018-12-31
|
||||
2019-01-02 00:00:00 2018-12-30 2018-12-30 2018-12-30 2018-12-30 2018-12-31 2018-12-31 2018-12-31 2018-12-31
|
||||
2019-01-03 00:00:00 2018-12-30 2018-12-30 2018-12-30 2018-12-30 2018-12-31 2018-12-31 2018-12-31 2018-12-31
|
||||
2018-12-25 00:00:00 2018-12-29 2018-12-29 2018-12-29 2018-12-29 2018-12-30 2018-12-30 2018-12-30 2018-12-30
|
||||
2018-12-26 00:00:00 2018-12-29 2018-12-29 2018-12-29 2018-12-29 2018-12-30 2018-12-30 2018-12-30 2018-12-30
|
||||
2018-12-27 00:00:00 2018-12-29 2018-12-29 2018-12-29 2018-12-29 2018-12-30 2018-12-30 2018-12-30 2018-12-30
|
||||
2018-12-28 00:00:00 2018-12-29 2018-12-29 2018-12-29 2018-12-29 2018-12-30 2018-12-30 2018-12-30 2018-12-30
|
||||
2018-12-29 00:00:00 2018-12-29 2018-12-29 2018-12-29 2018-12-29 2018-12-30 2018-12-30 2018-12-30 2018-12-30
|
||||
2018-12-30 00:00:00 2019-01-05 2019-01-05 2019-01-05 2019-01-05 2018-12-30 2018-12-30 2018-12-30 2018-12-30
|
||||
2018-12-31 00:00:00 2019-01-05 2019-01-05 2019-01-05 2019-01-05 2019-01-06 2019-01-06 2019-01-06 2019-01-06
|
||||
2019-01-01 00:00:00 2019-01-05 2019-01-05 2019-01-05 2019-01-05 2019-01-06 2019-01-06 2019-01-06 2019-01-06
|
||||
2019-01-02 00:00:00 2019-01-05 2019-01-05 2019-01-05 2019-01-05 2019-01-06 2019-01-06 2019-01-06 2019-01-06
|
||||
2019-01-03 00:00:00 2019-01-05 2019-01-05 2019-01-05 2019-01-05 2019-01-06 2019-01-06 2019-01-06 2019-01-06
|
||||
|
@ -41,12 +41,38 @@ SELECT toDateTime(toDate('2016-12-22') + number, 'Asia/Istanbul' ) AS d,
|
||||
FROM numbers(21);
|
||||
|
||||
-- toStartOfWeek
|
||||
WITH
|
||||
toDate('2018-12-25') + number AS d,
|
||||
toDate32(d) AS d32,
|
||||
toDateTime(d) AS dt,
|
||||
toDateTime64(d, 0) AS dt64
|
||||
SELECT
|
||||
toDate('2018-12-25') + number AS x,
|
||||
toDateTime(x) AS x_t,
|
||||
toStartOfWeek(x) AS w0,
|
||||
toStartOfWeek(x_t) AS wt0,
|
||||
toStartOfWeek(x, 3) AS w3,
|
||||
toStartOfWeek(x_t, 3) AS wt3
|
||||
dt64,
|
||||
toStartOfWeek(d) AS wd_sun,
|
||||
toStartOfWeek(d32) AS wd32_sun,
|
||||
toStartOfWeek(dt) AS wdt_sun,
|
||||
toStartOfWeek(dt64) AS wdt64_sun,
|
||||
toStartOfWeek(d, 1) AS wd_mon,
|
||||
toStartOfWeek(d32, 1) AS wd32_mon,
|
||||
toStartOfWeek(dt, 1) AS wdt_mon,
|
||||
toStartOfWeek(dt64, 1) AS wdt64_mon
|
||||
FROM numbers(10);
|
||||
|
||||
-- toLastDayOfWeek
|
||||
WITH
|
||||
toDate('2018-12-25') + number AS d,
|
||||
toDate32(d) AS d32,
|
||||
toDateTime(d) AS dt,
|
||||
toDateTime64(d, 0) AS dt64
|
||||
SELECT
|
||||
dt64,
|
||||
toLastDayOfWeek(d) AS wd_sun,
|
||||
toLastDayOfWeek(d32) AS wd32_sun,
|
||||
toLastDayOfWeek(dt) AS wdt_sun,
|
||||
toLastDayOfWeek(dt64) AS wdt64_sun,
|
||||
toLastDayOfWeek(d, 1) AS wd_mon,
|
||||
toLastDayOfWeek(d32, 1) AS wd32_mon,
|
||||
toLastDayOfWeek(dt, 1) AS wdt_mon,
|
||||
toLastDayOfWeek(dt64, 1) AS wdt64_mon
|
||||
FROM numbers(10);
|
||||
|
||||
|
@ -1,4 +1,9 @@
|
||||
2017-12-31 00:00:00
|
||||
2017-12-25
|
||||
2017-12-31
|
||||
2017-12-25
|
||||
2018-01-06
|
||||
2017-12-31
|
||||
2017-12-01
|
||||
2017-10-01
|
||||
2017-01-01
|
@ -1,6 +1,21 @@
|
||||
SELECT toStartOfDay(toDateTime('2017-12-31 00:00:00', 'UTC'), ''); -- {serverError 43}
|
||||
SELECT toStartOfDay(toDateTime('2017-12-31 03:45:00', 'UTC'), 'UTC'); -- success
|
||||
|
||||
SELECT toMonday(toDateTime('2017-12-31 00:00:00', 'UTC'), ''); -- {serverError 43}
|
||||
SELECT toMonday(toDateTime('2017-12-31 00:00:00', 'UTC'), 'UTC'); -- success
|
||||
|
||||
SELECT toStartOfWeek(toDateTime('2017-12-31 00:00:00', 'UTC'), 0, ''); -- {serverError 43}
|
||||
SELECT toStartOfWeek(toDateTime('2017-12-31 00:00:00', 'UTC'), 0, 'UTC'); -- success
|
||||
|
||||
SELECT toStartOfWeek(toDateTime('2017-12-31 00:00:00', 'UTC'), 1, ''); -- {serverError 43}
|
||||
SELECT toStartOfWeek(toDateTime('2017-12-31 00:00:00', 'UTC'), 1, 'UTC'); -- success
|
||||
|
||||
SELECT toLastDayOfWeek(toDateTime('2017-12-31 00:00:00', 'UTC'), 0, ''); -- {serverError 43}
|
||||
SELECT toLastDayOfWeek(toDateTime('2017-12-31 00:00:00', 'UTC'), 0, 'UTC'); -- success
|
||||
|
||||
SELECT toLastDayOfWeek(toDateTime('2017-12-31 00:00:00', 'UTC'), 1, ''); -- {serverError 43}
|
||||
SELECT toLastDayOfWeek(toDateTime('2017-12-31 00:00:00', 'UTC'), 1, 'UTC'); -- success
|
||||
|
||||
SELECT toStartOfMonth(toDateTime('2017-12-31 00:00:00', 'UTC'), ''); -- {serverError 43}
|
||||
SELECT toStartOfMonth(toDateTime('2017-12-31 00:00:00', 'UTC'), 'UTC'); -- success
|
||||
|
@ -84,6 +84,12 @@
|
||||
2120-07-05
|
||||
2120-07-26
|
||||
2021-06-20
|
||||
-------toLastDayOfWeek---------
|
||||
2079-06-12
|
||||
2079-06-12
|
||||
2120-07-11
|
||||
2120-08-01
|
||||
2021-06-26
|
||||
-------toStartOfMonth---------
|
||||
2079-06-07
|
||||
2079-06-07
|
||||
|
@ -36,6 +36,8 @@ select '-------toYearWeek---------';
|
||||
select toYearWeek(x1) from t1;
|
||||
select '-------toStartOfWeek---------';
|
||||
select toStartOfWeek(x1) from t1;
|
||||
select '-------toLastDayOfWeek---------';
|
||||
select toLastDayOfWeek(x1) from t1;
|
||||
select '-------toStartOfMonth---------';
|
||||
select toStartOfMonth(x1) from t1;
|
||||
select '-------toStartOfQuarter---------';
|
||||
|
@ -22,6 +22,10 @@ toMonday;toDate32;true 1920-02-02
|
||||
type;toMonday;toDate32;true Date32
|
||||
toMonday;toDateTime64;true 1920-02-02
|
||||
type;toMonday;toDateTime64;true Date32
|
||||
toLastDayOfWeek;toDate32;true 1920-02-07
|
||||
type;toLastDayOfWeek;toDate32;true Date32
|
||||
toLastDayOfWeek;toDateTime64;true 1920-02-07
|
||||
type;toLastDayOfWeek;toDateTime64;true Date32
|
||||
toLastDayOfMonth;toDate32;true 1920-02-29
|
||||
type;toLastDayOfMonth;toDate32;true Date32
|
||||
toLastDayOfMonth;toDateTime64;true 1920-02-29
|
||||
@ -66,6 +70,10 @@ toMonday;toDate32;false 2099-07-08
|
||||
type;toMonday;toDate32;false Date
|
||||
toMonday;toDateTime64;false 2099-07-08
|
||||
type;toMonday;toDateTime64;false Date
|
||||
toLastDayOfWeek;toDate32;false 2099-07-13
|
||||
type;toLastDayOfWeek;toDate32;false Date
|
||||
toLastDayOfWeek;toDateTime64;false 2099-07-13
|
||||
type;toLastDayOfWeek;toDateTime64;false Date
|
||||
toLastDayOfMonth;toDate32;false 2099-08-04
|
||||
type;toLastDayOfMonth;toDate32;false Date
|
||||
toLastDayOfMonth;toDateTime64;false 2099-08-04
|
||||
|
@ -1,5 +1,5 @@
|
||||
{% for option_value in ['true', 'false'] -%}
|
||||
{% for date_fun in ['toStartOfYear', 'toStartOfISOYear', 'toStartOfQuarter', 'toStartOfMonth', 'toStartOfWeek', 'toMonday', 'toLastDayOfMonth'] -%}
|
||||
{% for date_fun in ['toStartOfYear', 'toStartOfISOYear', 'toStartOfQuarter', 'toStartOfMonth', 'toStartOfWeek', 'toMonday', 'toLastDayOfWeek', 'toLastDayOfMonth'] -%}
|
||||
SELECT '{{ date_fun }};toDate32;{{ option_value }}', {{ date_fun }}(toDate32('1920-02-02')) SETTINGS enable_extended_results_for_datetime_functions = {{ option_value }};
|
||||
SELECT 'type;{{ date_fun }};toDate32;{{ option_value }}', toTypeName({{ date_fun }}(toDate32('1920-02-02'))) SETTINGS enable_extended_results_for_datetime_functions = {{ option_value }};
|
||||
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 }};
|
||||
|
@ -786,6 +786,7 @@ toIntervalWeek
|
||||
toIntervalYear
|
||||
toJSONString
|
||||
toLastDayOfMonth
|
||||
toLastDayOfWeek
|
||||
toLowCardinality
|
||||
toMinute
|
||||
toModifiedJulianDay
|
||||
|
Loading…
Reference in New Issue
Block a user