mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 01:25:21 +00:00
Merge branch 'ClickHouse:master' into zvonand-globs-small-fix
This commit is contained in:
commit
9e89055990
@ -1425,6 +1425,8 @@ Rounds the time to the half hour.
|
||||
|
||||
Converts a date or date with time to a UInt32 number containing the year and month number (YYYY \* 100 + MM). Accepts a second optional timezone argument. If provided, the timezone must be a string constant.
|
||||
|
||||
This functions is the opposite of function `YYYYMMDDToDate()`.
|
||||
|
||||
**Example**
|
||||
|
||||
``` sql
|
||||
@ -1447,8 +1449,7 @@ Converts a date or date with time to a UInt32 number containing the year and mon
|
||||
**Example**
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
toYYYYMMDD(now(), 'US/Eastern')
|
||||
SELECT toYYYYMMDD(now(), 'US/Eastern')
|
||||
```
|
||||
|
||||
Result:
|
||||
@ -1466,8 +1467,7 @@ Converts a date or date with time to a UInt64 number containing the year and mon
|
||||
**Example**
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
toYYYYMMDDhhmmss(now(), 'US/Eastern')
|
||||
SELECT toYYYYMMDDhhmmss(now(), 'US/Eastern')
|
||||
```
|
||||
|
||||
Result:
|
||||
@ -1478,6 +1478,93 @@ Result:
|
||||
└───────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## YYYYMMDDToDate
|
||||
|
||||
Converts a number containing the year, month and day number to a [Date](../../sql-reference/data-types/date.md).
|
||||
|
||||
This functions is the opposite of function `toYYYYMMDD()`.
|
||||
|
||||
The output is undefined if the input does not encode a valid Date value.
|
||||
|
||||
**Syntax**
|
||||
|
||||
```sql
|
||||
YYYYMMDDToDate(yyyymmdd);
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `yyyymmdd` - A number representing the year, month and day. [Integer](../../sql-reference/data-types/int-uint.md), [Float](../../sql-reference/data-types/float.md) or [Decimal](../../sql-reference/data-types/decimal.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
- a date created from the arguments.
|
||||
|
||||
Type: [Date](../../sql-reference/data-types/date.md).
|
||||
|
||||
**Example**
|
||||
|
||||
```sql
|
||||
SELECT YYYYMMDDToDate(20230911);
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```response
|
||||
┌─toYYYYMMDD(20230911)─┐
|
||||
│ 2023-09-11 │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
## YYYYMMDDToDate32
|
||||
|
||||
Like function `YYYYMMDDToDate()` but produces a [Date32](../../sql-reference/data-types/date32.md).
|
||||
|
||||
## YYYYMMDDhhmmssToDateTime
|
||||
|
||||
Converts a number containing the year, month, day, hours, minute and second number to a [DateTime](../../sql-reference/data-types/datetime.md).
|
||||
|
||||
The output is undefined if the input does not encode a valid DateTime value.
|
||||
|
||||
This functions is the opposite of function `toYYYYMMDDhhmmss()`.
|
||||
|
||||
**Syntax**
|
||||
|
||||
```sql
|
||||
YYYYMMDDhhmmssToDateTime(yyyymmddhhmmss[, timezone]);
|
||||
```
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `yyyymmddhhmmss` - A number representing the year, month and day. [Integer](../../sql-reference/data-types/int-uint.md), [Float](../../sql-reference/data-types/float.md) or [Decimal](../../sql-reference/data-types/decimal.md).
|
||||
- `timezone` - [Timezone](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional).
|
||||
|
||||
**Returned value**
|
||||
|
||||
- a date with time created from the arguments.
|
||||
|
||||
Type: [DateTime](../../sql-reference/data-types/datetime.md).
|
||||
|
||||
**Example**
|
||||
|
||||
```sql
|
||||
SELECT YYYYMMDDToDateTime(20230911131415);
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```response
|
||||
┌──────YYYYMMDDhhmmssToDateTime(20230911131415)─┐
|
||||
│ 2023-09-11 13:14:15 │
|
||||
└───────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## YYYYMMDDhhmmssToDateTime64
|
||||
|
||||
Like function `YYYYMMDDhhmmssToDate()` but produces a [DateTime64](../../sql-reference/data-types/datetime64.md).
|
||||
|
||||
Accepts an additional, optional `precision` parameter after the `timezone` parameter.
|
||||
|
||||
## addYears, addMonths, addWeeks, addDays, addHours, addMinutes, addSeconds, addQuarters
|
||||
|
||||
Function adds a Date/DateTime interval to a Date/DateTime and then return the Date/DateTime. For example:
|
||||
|
@ -71,14 +71,14 @@ private:
|
||||
// Same as above but select different function overloads for zero saturation.
|
||||
STRONG_TYPEDEF(UInt32, LUTIndexWithSaturation)
|
||||
|
||||
static inline LUTIndex normalizeLUTIndex(UInt32 index)
|
||||
static LUTIndex normalizeLUTIndex(UInt32 index)
|
||||
{
|
||||
if (index >= DATE_LUT_SIZE)
|
||||
return LUTIndex(DATE_LUT_SIZE - 1);
|
||||
return LUTIndex{index};
|
||||
}
|
||||
|
||||
static inline LUTIndex normalizeLUTIndex(Int64 index)
|
||||
static LUTIndex normalizeLUTIndex(Int64 index)
|
||||
{
|
||||
if (unlikely(index < 0))
|
||||
return LUTIndex(0);
|
||||
@ -88,59 +88,59 @@ private:
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
friend inline LUTIndex operator+(const LUTIndex & index, const T v)
|
||||
friend LUTIndex operator+(const LUTIndex & index, const T v)
|
||||
{
|
||||
return normalizeLUTIndex(index.toUnderType() + UInt32(v));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
friend inline LUTIndex operator+(const T v, const LUTIndex & index)
|
||||
friend LUTIndex operator+(const T v, const LUTIndex & index)
|
||||
{
|
||||
return normalizeLUTIndex(static_cast<Int64>(v + index.toUnderType()));
|
||||
}
|
||||
|
||||
friend inline LUTIndex operator+(const LUTIndex & index, const LUTIndex & v)
|
||||
friend LUTIndex operator+(const LUTIndex & index, const LUTIndex & v)
|
||||
{
|
||||
return normalizeLUTIndex(static_cast<UInt32>(index.toUnderType() + v.toUnderType()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
friend inline LUTIndex operator-(const LUTIndex & index, const T v)
|
||||
friend LUTIndex operator-(const LUTIndex & index, const T v)
|
||||
{
|
||||
return normalizeLUTIndex(static_cast<Int64>(index.toUnderType() - UInt32(v)));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
friend inline LUTIndex operator-(const T v, const LUTIndex & index)
|
||||
friend LUTIndex operator-(const T v, const LUTIndex & index)
|
||||
{
|
||||
return normalizeLUTIndex(static_cast<Int64>(v - index.toUnderType()));
|
||||
}
|
||||
|
||||
friend inline LUTIndex operator-(const LUTIndex & index, const LUTIndex & v)
|
||||
friend LUTIndex operator-(const LUTIndex & index, const LUTIndex & v)
|
||||
{
|
||||
return normalizeLUTIndex(static_cast<Int64>(index.toUnderType() - v.toUnderType()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
friend inline LUTIndex operator*(const LUTIndex & index, const T v)
|
||||
friend LUTIndex operator*(const LUTIndex & index, const T v)
|
||||
{
|
||||
return normalizeLUTIndex(index.toUnderType() * UInt32(v));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
friend inline LUTIndex operator*(const T v, const LUTIndex & index)
|
||||
friend LUTIndex operator*(const T v, const LUTIndex & index)
|
||||
{
|
||||
return normalizeLUTIndex(v * index.toUnderType());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
friend inline LUTIndex operator/(const LUTIndex & index, const T v)
|
||||
friend LUTIndex operator/(const LUTIndex & index, const T v)
|
||||
{
|
||||
return normalizeLUTIndex(index.toUnderType() / UInt32(v));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
friend inline LUTIndex operator/(const T v, const LUTIndex & index)
|
||||
friend LUTIndex operator/(const T v, const LUTIndex & index)
|
||||
{
|
||||
return normalizeLUTIndex(UInt32(v) / index.toUnderType());
|
||||
}
|
||||
@ -172,12 +172,12 @@ public:
|
||||
Int8 amount_of_offset_change_value; /// Usually -4 or 4, but look at Lord Howe Island. Multiply by OffsetChangeFactor
|
||||
UInt8 time_at_offset_change_value; /// In seconds from beginning of the day. Multiply by OffsetChangeFactor
|
||||
|
||||
inline Int32 amount_of_offset_change() const /// NOLINT
|
||||
Int32 amount_of_offset_change() const /// NOLINT
|
||||
{
|
||||
return static_cast<Int32>(amount_of_offset_change_value) * OffsetChangeFactor;
|
||||
}
|
||||
|
||||
inline UInt32 time_at_offset_change() const /// NOLINT
|
||||
UInt32 time_at_offset_change() const /// NOLINT
|
||||
{
|
||||
return static_cast<UInt32>(time_at_offset_change_value) * OffsetChangeFactor;
|
||||
}
|
||||
@ -221,7 +221,7 @@ private:
|
||||
/// Time zone name.
|
||||
std::string time_zone;
|
||||
|
||||
inline LUTIndex findIndex(Time t) const
|
||||
LUTIndex findIndex(Time t) const
|
||||
{
|
||||
/// First guess.
|
||||
Time guess = (t / 86400) + daynum_offset_epoch;
|
||||
@ -248,34 +248,34 @@ private:
|
||||
return LUTIndex(guess ? static_cast<unsigned>(guess) - 1 : 0);
|
||||
}
|
||||
|
||||
static inline LUTIndex toLUTIndex(DayNum d)
|
||||
static LUTIndex toLUTIndex(DayNum d)
|
||||
{
|
||||
return normalizeLUTIndex(d + daynum_offset_epoch);
|
||||
}
|
||||
|
||||
static inline LUTIndex toLUTIndex(ExtendedDayNum d)
|
||||
static LUTIndex toLUTIndex(ExtendedDayNum d)
|
||||
{
|
||||
return normalizeLUTIndex(static_cast<Int64>(d + daynum_offset_epoch));
|
||||
}
|
||||
|
||||
inline LUTIndex toLUTIndex(Time t) const
|
||||
LUTIndex toLUTIndex(Time t) const
|
||||
{
|
||||
return findIndex(t);
|
||||
}
|
||||
|
||||
static inline LUTIndex toLUTIndex(LUTIndex i)
|
||||
static LUTIndex toLUTIndex(LUTIndex i)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline const Values & find(DateOrTime v) const
|
||||
const Values & find(DateOrTime v) const
|
||||
{
|
||||
return lut[toLUTIndex(v)];
|
||||
}
|
||||
|
||||
template <typename DateOrTime, typename Divisor>
|
||||
inline DateOrTime roundDown(DateOrTime x, Divisor divisor) const
|
||||
DateOrTime roundDown(DateOrTime x, Divisor divisor) const
|
||||
{
|
||||
static_assert(std::is_integral_v<DateOrTime> && std::is_integral_v<Divisor>);
|
||||
assert(divisor > 0);
|
||||
@ -336,7 +336,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline auto toDayNum(DateOrTime v) const
|
||||
auto toDayNum(DateOrTime v) const
|
||||
{
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
return DayNum{static_cast<DayNum::UnderlyingType>(saturateMinus(toLUTIndex(v).toUnderType(), daynum_offset_epoch))};
|
||||
@ -346,7 +346,7 @@ public:
|
||||
|
||||
/// Round down to start of monday.
|
||||
template <typename DateOrTime>
|
||||
inline Time toFirstDayOfWeek(DateOrTime v) const
|
||||
Time toFirstDayOfWeek(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
@ -356,7 +356,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline auto toFirstDayNumOfWeek(DateOrTime v) const
|
||||
auto toFirstDayNumOfWeek(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
@ -367,7 +367,7 @@ public:
|
||||
|
||||
/// Round up to the last day of week.
|
||||
template <typename DateOrTime>
|
||||
inline Time toLastDayOfWeek(DateOrTime v) const
|
||||
Time toLastDayOfWeek(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
@ -377,7 +377,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline auto toLastDayNumOfWeek(DateOrTime v) const
|
||||
auto toLastDayNumOfWeek(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
@ -388,7 +388,7 @@ public:
|
||||
|
||||
/// Round down to start of month.
|
||||
template <typename DateOrTime>
|
||||
inline Time toFirstDayOfMonth(DateOrTime v) const
|
||||
Time toFirstDayOfMonth(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
@ -398,7 +398,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline auto toFirstDayNumOfMonth(DateOrTime v) const
|
||||
auto toFirstDayNumOfMonth(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
@ -409,7 +409,7 @@ public:
|
||||
|
||||
/// Round up to last day of month.
|
||||
template <typename DateOrTime>
|
||||
inline Time toLastDayOfMonth(DateOrTime v) const
|
||||
Time toLastDayOfMonth(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
@ -419,7 +419,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline auto toLastDayNumOfMonth(DateOrTime v) const
|
||||
auto toLastDayNumOfMonth(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
@ -430,7 +430,7 @@ public:
|
||||
|
||||
/// Round down to start of quarter.
|
||||
template <typename DateOrTime>
|
||||
inline auto toFirstDayNumOfQuarter(DateOrTime v) const
|
||||
auto toFirstDayNumOfQuarter(DateOrTime v) const
|
||||
{
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
return toDayNum(LUTIndexWithSaturation(toFirstDayOfQuarterIndex(v)));
|
||||
@ -439,7 +439,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline LUTIndex toFirstDayOfQuarterIndex(DateOrTime v) const
|
||||
LUTIndex toFirstDayOfQuarterIndex(DateOrTime v) const
|
||||
{
|
||||
LUTIndex index = toLUTIndex(v);
|
||||
size_t month_inside_quarter = (lut[index].month - 1) % 3;
|
||||
@ -455,25 +455,25 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline Time toFirstDayOfQuarter(DateOrTime v) const
|
||||
Time toFirstDayOfQuarter(DateOrTime v) const
|
||||
{
|
||||
return toDate(toFirstDayOfQuarterIndex(v));
|
||||
}
|
||||
|
||||
/// Round down to start of year.
|
||||
inline Time toFirstDayOfYear(Time t) const
|
||||
Time toFirstDayOfYear(Time t) const
|
||||
{
|
||||
return lut[years_lut[lut[findIndex(t)].year - DATE_LUT_MIN_YEAR]].date;
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline LUTIndex toFirstDayNumOfYearIndex(DateOrTime v) const
|
||||
LUTIndex toFirstDayNumOfYearIndex(DateOrTime v) const
|
||||
{
|
||||
return years_lut[lut[toLUTIndex(v)].year - DATE_LUT_MIN_YEAR];
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline auto toFirstDayNumOfYear(DateOrTime v) const
|
||||
auto toFirstDayNumOfYear(DateOrTime v) const
|
||||
{
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
return toDayNum(LUTIndexWithSaturation(toFirstDayNumOfYearIndex(v)));
|
||||
@ -481,14 +481,14 @@ public:
|
||||
return toDayNum(LUTIndex(toFirstDayNumOfYearIndex(v)));
|
||||
}
|
||||
|
||||
inline Time toFirstDayOfNextMonth(Time t) const
|
||||
Time toFirstDayOfNextMonth(Time t) const
|
||||
{
|
||||
LUTIndex index = findIndex(t);
|
||||
index += 32 - lut[index].day_of_month;
|
||||
return lut[index - (lut[index].day_of_month - 1)].date;
|
||||
}
|
||||
|
||||
inline Time toFirstDayOfPrevMonth(Time t) const
|
||||
Time toFirstDayOfPrevMonth(Time t) const
|
||||
{
|
||||
LUTIndex index = findIndex(t);
|
||||
index -= lut[index].day_of_month;
|
||||
@ -496,13 +496,13 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline UInt8 daysInMonth(DateOrTime value) const
|
||||
UInt8 daysInMonth(DateOrTime value) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(value);
|
||||
return lut[i].days_in_month;
|
||||
}
|
||||
|
||||
inline UInt8 daysInMonth(Int16 year, UInt8 month) const
|
||||
UInt8 daysInMonth(Int16 year, UInt8 month) const
|
||||
{
|
||||
UInt16 idx = year - DATE_LUT_MIN_YEAR;
|
||||
if (unlikely(idx >= DATE_LUT_YEARS))
|
||||
@ -515,12 +515,12 @@ public:
|
||||
|
||||
/** Round to start of day, then shift for specified amount of days.
|
||||
*/
|
||||
inline Time toDateAndShift(Time t, Int32 days) const
|
||||
Time toDateAndShift(Time t, Int32 days) const
|
||||
{
|
||||
return lut[findIndex(t) + days].date;
|
||||
}
|
||||
|
||||
inline Time toTime(Time t) const
|
||||
Time toTime(Time t) const
|
||||
{
|
||||
const LUTIndex index = findIndex(t);
|
||||
|
||||
@ -532,7 +532,7 @@ public:
|
||||
return res - offset_at_start_of_epoch; /// Starting at 1970-01-01 00:00:00 local time.
|
||||
}
|
||||
|
||||
inline unsigned toHour(Time t) const
|
||||
unsigned toHour(Time t) const
|
||||
{
|
||||
const LUTIndex index = findIndex(t);
|
||||
|
||||
@ -552,7 +552,7 @@ public:
|
||||
* then subtract the former from the latter to get the offset result.
|
||||
* The boundaries when meets DST(daylight saving time) change should be handled very carefully.
|
||||
*/
|
||||
inline Time timezoneOffset(Time t) const
|
||||
Time timezoneOffset(Time t) const
|
||||
{
|
||||
const LUTIndex index = findIndex(t);
|
||||
|
||||
@ -574,7 +574,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
inline unsigned toSecond(Time t) const
|
||||
unsigned toSecond(Time t) const
|
||||
{
|
||||
if (likely(offset_is_whole_number_of_minutes_during_epoch))
|
||||
{
|
||||
@ -593,7 +593,7 @@ public:
|
||||
return time % 60;
|
||||
}
|
||||
|
||||
inline unsigned toMinute(Time t) const
|
||||
unsigned toMinute(Time t) const
|
||||
{
|
||||
if (t >= 0 && offset_is_whole_number_of_hours_during_epoch)
|
||||
return (t / 60) % 60;
|
||||
@ -630,11 +630,11 @@ public:
|
||||
* because the same calendar day starts/ends at different timestamps in different time zones)
|
||||
*/
|
||||
|
||||
inline Time fromDayNum(DayNum d) const { return lut_saturated[toLUTIndex(d)].date; }
|
||||
inline Time fromDayNum(ExtendedDayNum d) const { return lut[toLUTIndex(d)].date; }
|
||||
Time fromDayNum(DayNum d) const { return lut_saturated[toLUTIndex(d)].date; }
|
||||
Time fromDayNum(ExtendedDayNum d) const { return lut[toLUTIndex(d)].date; }
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline Time toDate(DateOrTime v) const
|
||||
Time toDate(DateOrTime v) const
|
||||
{
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
return lut_saturated[toLUTIndex(v)].date;
|
||||
@ -643,20 +643,20 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline UInt8 toMonth(DateOrTime v) const { return lut[toLUTIndex(v)].month; }
|
||||
UInt8 toMonth(DateOrTime v) const { return lut[toLUTIndex(v)].month; }
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline UInt8 toQuarter(DateOrTime v) const { return (lut[toLUTIndex(v)].month - 1) / 3 + 1; }
|
||||
UInt8 toQuarter(DateOrTime v) const { return (lut[toLUTIndex(v)].month - 1) / 3 + 1; }
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline Int16 toYear(DateOrTime v) const { return lut[toLUTIndex(v)].year; }
|
||||
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; }
|
||||
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
|
||||
UInt8 toDayOfWeek(DateOrTime v, UInt8 week_day_mode) const
|
||||
{
|
||||
WeekDayMode mode = check_week_day_mode(week_day_mode);
|
||||
|
||||
@ -674,10 +674,10 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline UInt8 toDayOfMonth(DateOrTime v) const { return lut[toLUTIndex(v)].day_of_month; }
|
||||
UInt8 toDayOfMonth(DateOrTime v) const { return lut[toLUTIndex(v)].day_of_month; }
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline UInt16 toDayOfYear(DateOrTime v) const
|
||||
UInt16 toDayOfYear(DateOrTime v) const
|
||||
{
|
||||
// TODO: different overload for ExtendedDayNum
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
@ -688,7 +688,7 @@ public:
|
||||
/// (round down to monday and divide DayNum by 7; we made an assumption,
|
||||
/// that in domain of the function there was no weeks with any other number of days than 7)
|
||||
template <typename DateOrTime>
|
||||
inline Int32 toRelativeWeekNum(DateOrTime v) const
|
||||
Int32 toRelativeWeekNum(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
/// We add 8 to avoid underflow at beginning of unix epoch.
|
||||
@ -697,7 +697,7 @@ public:
|
||||
|
||||
/// Get year that contains most of the current week. Week begins at monday.
|
||||
template <typename DateOrTime>
|
||||
inline Int16 toISOYear(DateOrTime v) const
|
||||
Int16 toISOYear(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
/// That's effectively the year of thursday of current week.
|
||||
@ -708,7 +708,7 @@ public:
|
||||
/// Example: ISO year 2019 begins at 2018-12-31. And ISO year 2017 begins at 2017-01-02.
|
||||
/// https://en.wikipedia.org/wiki/ISO_week_date
|
||||
template <typename DateOrTime>
|
||||
inline LUTIndex toFirstDayNumOfISOYearIndex(DateOrTime v) const
|
||||
LUTIndex toFirstDayNumOfISOYearIndex(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
auto iso_year = toISOYear(i);
|
||||
@ -722,7 +722,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline auto toFirstDayNumOfISOYear(DateOrTime v) const
|
||||
auto toFirstDayNumOfISOYear(DateOrTime v) const
|
||||
{
|
||||
if constexpr (std::is_unsigned_v<DateOrTime> || std::is_same_v<DateOrTime, DayNum>)
|
||||
return toDayNum(LUTIndexWithSaturation(toFirstDayNumOfISOYearIndex(v)));
|
||||
@ -730,7 +730,7 @@ public:
|
||||
return toDayNum(LUTIndex(toFirstDayNumOfISOYearIndex(v)));
|
||||
}
|
||||
|
||||
inline Time toFirstDayOfISOYear(Time t) const
|
||||
Time toFirstDayOfISOYear(Time t) const
|
||||
{
|
||||
return lut[toFirstDayNumOfISOYearIndex(t)].date;
|
||||
}
|
||||
@ -738,7 +738,7 @@ public:
|
||||
/// ISO 8601 week number. Week begins at monday.
|
||||
/// The week number 1 is the first week in year that contains 4 or more days (that's more than half).
|
||||
template <typename DateOrTime>
|
||||
inline UInt8 toISOWeek(DateOrTime v) const
|
||||
UInt8 toISOWeek(DateOrTime v) const
|
||||
{
|
||||
return 1 + (toFirstDayNumOfWeek(v) - toDayNum(toFirstDayNumOfISOYearIndex(v))) / 7;
|
||||
}
|
||||
@ -777,7 +777,7 @@ public:
|
||||
next week is week 1.
|
||||
*/
|
||||
template <typename DateOrTime>
|
||||
inline YearWeek toYearWeek(DateOrTime v, UInt8 week_mode) const
|
||||
YearWeek toYearWeek(DateOrTime v, UInt8 week_mode) const
|
||||
{
|
||||
const bool newyear_day_mode = week_mode & static_cast<UInt8>(WeekModeFlag::NEWYEAR_DAY);
|
||||
week_mode = check_week_mode(week_mode);
|
||||
@ -836,7 +836,7 @@ public:
|
||||
/// Calculate week number of WeekModeFlag::NEWYEAR_DAY mode
|
||||
/// The week number 1 is the first week in year that contains January 1,
|
||||
template <typename DateOrTime>
|
||||
inline YearWeek toYearWeekOfNewyearMode(DateOrTime v, bool monday_first_mode) const
|
||||
YearWeek toYearWeekOfNewyearMode(DateOrTime v, bool monday_first_mode) const
|
||||
{
|
||||
YearWeek yw(0, 0);
|
||||
UInt16 offset_day = monday_first_mode ? 0U : 1U;
|
||||
@ -870,7 +870,7 @@ public:
|
||||
|
||||
/// Get first day of week with week_mode, return Sunday or Monday
|
||||
template <typename DateOrTime>
|
||||
inline auto toFirstDayNumOfWeek(DateOrTime v, UInt8 week_mode) const
|
||||
auto toFirstDayNumOfWeek(DateOrTime v, UInt8 week_mode) const
|
||||
{
|
||||
bool monday_first_mode = week_mode & static_cast<UInt8>(WeekModeFlag::MONDAY_FIRST);
|
||||
if (monday_first_mode)
|
||||
@ -889,7 +889,7 @@ public:
|
||||
|
||||
/// Get last day of week with week_mode, return Saturday or Sunday
|
||||
template <typename DateOrTime>
|
||||
inline auto toLastDayNumOfWeek(DateOrTime v, UInt8 week_mode) const
|
||||
auto toLastDayNumOfWeek(DateOrTime v, UInt8 week_mode) const
|
||||
{
|
||||
bool monday_first_mode = week_mode & static_cast<UInt8>(WeekModeFlag::MONDAY_FIRST);
|
||||
if (monday_first_mode)
|
||||
@ -908,7 +908,7 @@ public:
|
||||
}
|
||||
|
||||
/// Check and change mode to effective.
|
||||
inline UInt8 check_week_mode(UInt8 mode) const /// NOLINT
|
||||
UInt8 check_week_mode(UInt8 mode) const /// NOLINT
|
||||
{
|
||||
UInt8 week_format = (mode & 7);
|
||||
if (!(week_format & static_cast<UInt8>(WeekModeFlag::MONDAY_FIRST)))
|
||||
@ -917,7 +917,7 @@ public:
|
||||
}
|
||||
|
||||
/// Check and change mode to effective.
|
||||
inline WeekDayMode check_week_day_mode(UInt8 mode) const /// NOLINT
|
||||
WeekDayMode check_week_day_mode(UInt8 mode) const /// NOLINT
|
||||
{
|
||||
return static_cast<WeekDayMode>(mode & 3);
|
||||
}
|
||||
@ -926,7 +926,7 @@ public:
|
||||
* Returns 0 for monday, 1 for tuesday...
|
||||
*/
|
||||
template <typename DateOrTime>
|
||||
inline UInt8 calc_weekday(DateOrTime v, bool sunday_first_day_of_week) const /// NOLINT
|
||||
UInt8 calc_weekday(DateOrTime v, bool sunday_first_day_of_week) const /// NOLINT
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
if (!sunday_first_day_of_week)
|
||||
@ -936,28 +936,28 @@ public:
|
||||
}
|
||||
|
||||
/// Calculate days in one year.
|
||||
inline UInt16 calc_days_in_year(Int32 year) const /// NOLINT
|
||||
UInt16 calc_days_in_year(Int32 year) const /// NOLINT
|
||||
{
|
||||
return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)) ? 366 : 365);
|
||||
}
|
||||
|
||||
/// Number of month from some fixed moment in the past (year * 12 + month)
|
||||
template <typename DateOrTime>
|
||||
inline Int32 toRelativeMonthNum(DateOrTime v) const
|
||||
Int32 toRelativeMonthNum(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
return lut[i].year * 12 + lut[i].month;
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline Int32 toRelativeQuarterNum(DateOrTime v) const
|
||||
Int32 toRelativeQuarterNum(DateOrTime v) const
|
||||
{
|
||||
const LUTIndex i = toLUTIndex(v);
|
||||
return lut[i].year * 4 + (lut[i].month - 1) / 3;
|
||||
}
|
||||
|
||||
/// We count all hour-length intervals, unrelated to offset changes.
|
||||
inline Time toRelativeHourNum(Time t) const
|
||||
Time toRelativeHourNum(Time t) const
|
||||
{
|
||||
if (t >= 0 && offset_is_whole_number_of_hours_during_epoch)
|
||||
return t / 3600;
|
||||
@ -968,37 +968,37 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline Time toRelativeHourNum(DateOrTime v) const
|
||||
Time toRelativeHourNum(DateOrTime v) const
|
||||
{
|
||||
return toRelativeHourNum(lut[toLUTIndex(v)].date);
|
||||
}
|
||||
|
||||
/// The same formula is used for positive time (after Unix epoch) and negative time (before Unix epoch).
|
||||
/// It’s needed for correct work of dateDiff function.
|
||||
inline Time toStableRelativeHourNum(Time t) const
|
||||
Time toStableRelativeHourNum(Time t) const
|
||||
{
|
||||
return (t + DATE_LUT_ADD + 86400 - offset_at_start_of_epoch) / 3600 - (DATE_LUT_ADD / 3600);
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline Time toStableRelativeHourNum(DateOrTime v) const
|
||||
Time toStableRelativeHourNum(DateOrTime v) const
|
||||
{
|
||||
return toStableRelativeHourNum(lut[toLUTIndex(v)].date);
|
||||
}
|
||||
|
||||
inline Time toRelativeMinuteNum(Time t) const /// NOLINT
|
||||
Time toRelativeMinuteNum(Time t) const /// NOLINT
|
||||
{
|
||||
return (t + DATE_LUT_ADD) / 60 - (DATE_LUT_ADD / 60);
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline Time toRelativeMinuteNum(DateOrTime v) const
|
||||
Time toRelativeMinuteNum(DateOrTime v) const
|
||||
{
|
||||
return toRelativeMinuteNum(lut[toLUTIndex(v)].date);
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline auto toStartOfYearInterval(DateOrTime v, UInt64 years) const
|
||||
auto toStartOfYearInterval(DateOrTime v, UInt64 years) const
|
||||
{
|
||||
if (years == 1)
|
||||
return toFirstDayNumOfYear(v);
|
||||
@ -1019,7 +1019,7 @@ public:
|
||||
|
||||
template <typename Date>
|
||||
requires std::is_same_v<Date, DayNum> || std::is_same_v<Date, ExtendedDayNum>
|
||||
inline auto toStartOfQuarterInterval(Date d, UInt64 quarters) const
|
||||
auto toStartOfQuarterInterval(Date d, UInt64 quarters) const
|
||||
{
|
||||
if (quarters == 1)
|
||||
return toFirstDayNumOfQuarter(d);
|
||||
@ -1028,7 +1028,7 @@ public:
|
||||
|
||||
template <typename Date>
|
||||
requires std::is_same_v<Date, DayNum> || std::is_same_v<Date, ExtendedDayNum>
|
||||
inline auto toStartOfMonthInterval(Date d, UInt64 months) const
|
||||
auto toStartOfMonthInterval(Date d, UInt64 months) const
|
||||
{
|
||||
if (months == 1)
|
||||
return toFirstDayNumOfMonth(d);
|
||||
@ -1042,7 +1042,7 @@ public:
|
||||
|
||||
template <typename Date>
|
||||
requires std::is_same_v<Date, DayNum> || std::is_same_v<Date, ExtendedDayNum>
|
||||
inline auto toStartOfWeekInterval(Date d, UInt64 weeks) const
|
||||
auto toStartOfWeekInterval(Date d, UInt64 weeks) const
|
||||
{
|
||||
if (weeks == 1)
|
||||
return toFirstDayNumOfWeek(d);
|
||||
@ -1056,7 +1056,7 @@ public:
|
||||
|
||||
template <typename Date>
|
||||
requires std::is_same_v<Date, DayNum> || std::is_same_v<Date, ExtendedDayNum>
|
||||
inline Time toStartOfDayInterval(Date d, UInt64 days) const
|
||||
Time toStartOfDayInterval(Date d, UInt64 days) const
|
||||
{
|
||||
if (days == 1)
|
||||
return toDate(d);
|
||||
@ -1152,7 +1152,7 @@ public:
|
||||
return static_cast<DateOrTime>(roundDown(t, seconds));
|
||||
}
|
||||
|
||||
inline LUTIndex makeLUTIndex(Int16 year, UInt8 month, UInt8 day_of_month) const
|
||||
LUTIndex makeLUTIndex(Int16 year, UInt8 month, UInt8 day_of_month) const
|
||||
{
|
||||
if (unlikely(year < DATE_LUT_MIN_YEAR || month < 1 || month > 12 || day_of_month < 1 || day_of_month > 31))
|
||||
return LUTIndex(0);
|
||||
@ -1167,7 +1167,7 @@ public:
|
||||
}
|
||||
|
||||
/// Create DayNum from year, month, day of month.
|
||||
inline ExtendedDayNum makeDayNum(Int16 year, UInt8 month, UInt8 day_of_month, Int32 default_error_day_num = 0) const
|
||||
ExtendedDayNum makeDayNum(Int16 year, UInt8 month, UInt8 day_of_month, Int32 default_error_day_num = 0) const
|
||||
{
|
||||
if (unlikely(year < DATE_LUT_MIN_YEAR || month < 1 || month > 12 || day_of_month < 1 || day_of_month > 31))
|
||||
return ExtendedDayNum(default_error_day_num);
|
||||
@ -1175,14 +1175,14 @@ public:
|
||||
return toDayNum(makeLUTIndex(year, month, day_of_month));
|
||||
}
|
||||
|
||||
inline Time makeDate(Int16 year, UInt8 month, UInt8 day_of_month) const
|
||||
Time makeDate(Int16 year, UInt8 month, UInt8 day_of_month) const
|
||||
{
|
||||
return lut[makeLUTIndex(year, month, day_of_month)].date;
|
||||
}
|
||||
|
||||
/** Does not accept daylight saving time as argument: in case of ambiguity, it choose greater timestamp.
|
||||
*/
|
||||
inline Time makeDateTime(Int16 year, UInt8 month, UInt8 day_of_month, UInt8 hour, UInt8 minute, UInt8 second) const
|
||||
Time makeDateTime(Int16 year, UInt8 month, UInt8 day_of_month, UInt8 hour, UInt8 minute, UInt8 second) const
|
||||
{
|
||||
size_t index = makeLUTIndex(year, month, day_of_month);
|
||||
Time time_offset = hour * 3600 + minute * 60 + second;
|
||||
@ -1194,28 +1194,28 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline const Values & getValues(DateOrTime v) const { return lut[toLUTIndex(v)]; }
|
||||
const Values & getValues(DateOrTime v) const { return lut[toLUTIndex(v)]; }
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline UInt32 toNumYYYYMM(DateOrTime v) const
|
||||
UInt32 toNumYYYYMM(DateOrTime v) const
|
||||
{
|
||||
const Values & values = getValues(v);
|
||||
return values.year * 100 + values.month;
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline UInt32 toNumYYYYMMDD(DateOrTime v) const
|
||||
UInt32 toNumYYYYMMDD(DateOrTime v) const
|
||||
{
|
||||
const Values & values = getValues(v);
|
||||
return values.year * 10000 + values.month * 100 + values.day_of_month;
|
||||
}
|
||||
|
||||
inline Time YYYYMMDDToDate(UInt32 num) const /// NOLINT
|
||||
Time YYYYMMDDToDate(UInt32 num) const /// NOLINT
|
||||
{
|
||||
return makeDate(num / 10000, num / 100 % 100, num % 100);
|
||||
}
|
||||
|
||||
inline ExtendedDayNum YYYYMMDDToDayNum(UInt32 num) const /// NOLINT
|
||||
ExtendedDayNum YYYYMMDDToDayNum(UInt32 num) const /// NOLINT
|
||||
{
|
||||
return makeDayNum(num / 10000, num / 100 % 100, num % 100);
|
||||
}
|
||||
@ -1241,13 +1241,13 @@ public:
|
||||
TimeComponents time;
|
||||
};
|
||||
|
||||
inline DateComponents toDateComponents(Time t) const
|
||||
DateComponents toDateComponents(Time t) const
|
||||
{
|
||||
const Values & values = getValues(t);
|
||||
return { values.year, values.month, values.day_of_month };
|
||||
}
|
||||
|
||||
inline DateTimeComponents toDateTimeComponents(Time t) const
|
||||
DateTimeComponents toDateTimeComponents(Time t) const
|
||||
{
|
||||
const LUTIndex index = findIndex(t);
|
||||
const Values & values = lut[index];
|
||||
@ -1283,12 +1283,12 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline DateTimeComponents toDateTimeComponents(DateOrTime v) const
|
||||
DateTimeComponents toDateTimeComponents(DateOrTime v) const
|
||||
{
|
||||
return toDateTimeComponents(lut[toLUTIndex(v)].date);
|
||||
}
|
||||
|
||||
inline UInt64 toNumYYYYMMDDhhmmss(Time t) const
|
||||
UInt64 toNumYYYYMMDDhhmmss(Time t) const
|
||||
{
|
||||
DateTimeComponents components = toDateTimeComponents(t);
|
||||
|
||||
@ -1301,7 +1301,7 @@ public:
|
||||
+ UInt64(components.date.year) * 10000000000;
|
||||
}
|
||||
|
||||
inline Time YYYYMMDDhhmmssToTime(UInt64 num) const /// NOLINT
|
||||
Time YYYYMMDDhhmmssToTime(UInt64 num) const /// NOLINT
|
||||
{
|
||||
return makeDateTime(
|
||||
num / 10000000000,
|
||||
@ -1315,7 +1315,7 @@ public:
|
||||
/// Adding calendar intervals.
|
||||
/// Implementation specific behaviour when delta is too big.
|
||||
|
||||
inline NO_SANITIZE_UNDEFINED Time addDays(Time t, Int64 delta) const
|
||||
NO_SANITIZE_UNDEFINED Time addDays(Time t, Int64 delta) const
|
||||
{
|
||||
const LUTIndex index = findIndex(t);
|
||||
const Values & values = lut[index];
|
||||
@ -1332,12 +1332,12 @@ public:
|
||||
return lut[new_index].date + time;
|
||||
}
|
||||
|
||||
inline NO_SANITIZE_UNDEFINED Time addWeeks(Time t, Int64 delta) const
|
||||
NO_SANITIZE_UNDEFINED Time addWeeks(Time t, Int64 delta) const
|
||||
{
|
||||
return addDays(t, delta * 7);
|
||||
}
|
||||
|
||||
inline UInt8 saturateDayOfMonth(Int16 year, UInt8 month, UInt8 day_of_month) const
|
||||
UInt8 saturateDayOfMonth(Int16 year, UInt8 month, UInt8 day_of_month) const
|
||||
{
|
||||
if (likely(day_of_month <= 28))
|
||||
return day_of_month;
|
||||
@ -1351,7 +1351,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline LUTIndex NO_SANITIZE_UNDEFINED addMonthsIndex(DateOrTime v, Int64 delta) const
|
||||
LUTIndex NO_SANITIZE_UNDEFINED addMonthsIndex(DateOrTime v, Int64 delta) const
|
||||
{
|
||||
const Values & values = lut[toLUTIndex(v)];
|
||||
|
||||
@ -1375,11 +1375,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/// If resulting month has less deys than source month, then saturation can happen.
|
||||
/// If resulting month has less days than source month, then saturation can happen.
|
||||
/// Example: 31 Aug + 1 month = 30 Sep.
|
||||
template <typename DateTime>
|
||||
requires std::is_same_v<DateTime, UInt32> || std::is_same_v<DateTime, Int64> || std::is_same_v<DateTime, time_t>
|
||||
inline Time NO_SANITIZE_UNDEFINED addMonths(DateTime t, Int64 delta) const
|
||||
Time NO_SANITIZE_UNDEFINED addMonths(DateTime t, Int64 delta) const
|
||||
{
|
||||
const auto result_day = addMonthsIndex(t, delta);
|
||||
|
||||
@ -1405,7 +1405,7 @@ public:
|
||||
|
||||
template <typename Date>
|
||||
requires std::is_same_v<Date, DayNum> || std::is_same_v<Date, ExtendedDayNum>
|
||||
inline auto NO_SANITIZE_UNDEFINED addMonths(Date d, Int64 delta) const
|
||||
auto NO_SANITIZE_UNDEFINED addMonths(Date d, Int64 delta) const
|
||||
{
|
||||
if constexpr (std::is_same_v<Date, DayNum>)
|
||||
return toDayNum(LUTIndexWithSaturation(addMonthsIndex(d, delta)));
|
||||
@ -1414,13 +1414,13 @@ public:
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline auto NO_SANITIZE_UNDEFINED addQuarters(DateOrTime d, Int64 delta) const
|
||||
auto NO_SANITIZE_UNDEFINED addQuarters(DateOrTime d, Int64 delta) const
|
||||
{
|
||||
return addMonths(d, delta * 3);
|
||||
}
|
||||
|
||||
template <typename DateOrTime>
|
||||
inline LUTIndex NO_SANITIZE_UNDEFINED addYearsIndex(DateOrTime v, Int64 delta) const
|
||||
LUTIndex NO_SANITIZE_UNDEFINED addYearsIndex(DateOrTime v, Int64 delta) const
|
||||
{
|
||||
const Values & values = lut[toLUTIndex(v)];
|
||||
|
||||
@ -1438,7 +1438,7 @@ public:
|
||||
/// Saturation can occur if 29 Feb is mapped to non-leap year.
|
||||
template <typename DateTime>
|
||||
requires std::is_same_v<DateTime, UInt32> || std::is_same_v<DateTime, Int64> || std::is_same_v<DateTime, time_t>
|
||||
inline Time addYears(DateTime t, Int64 delta) const
|
||||
Time addYears(DateTime t, Int64 delta) const
|
||||
{
|
||||
auto result_day = addYearsIndex(t, delta);
|
||||
|
||||
@ -1464,7 +1464,7 @@ public:
|
||||
|
||||
template <typename Date>
|
||||
requires std::is_same_v<Date, DayNum> || std::is_same_v<Date, ExtendedDayNum>
|
||||
inline auto addYears(Date d, Int64 delta) const
|
||||
auto addYears(Date d, Int64 delta) const
|
||||
{
|
||||
if constexpr (std::is_same_v<Date, DayNum>)
|
||||
return toDayNum(LUTIndexWithSaturation(addYearsIndex(d, delta)));
|
||||
@ -1473,7 +1473,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
inline std::string timeToString(Time t) const
|
||||
std::string timeToString(Time t) const
|
||||
{
|
||||
DateTimeComponents components = toDateTimeComponents(t);
|
||||
|
||||
@ -1498,7 +1498,7 @@ public:
|
||||
return s;
|
||||
}
|
||||
|
||||
inline std::string dateToString(Time t) const
|
||||
std::string dateToString(Time t) const
|
||||
{
|
||||
const Values & values = getValues(t);
|
||||
|
||||
@ -1516,7 +1516,7 @@ public:
|
||||
return s;
|
||||
}
|
||||
|
||||
inline std::string dateToString(ExtendedDayNum d) const
|
||||
std::string dateToString(ExtendedDayNum d) const
|
||||
{
|
||||
const Values & values = getValues(d);
|
||||
|
||||
|
@ -16,19 +16,23 @@
|
||||
#include <Common/typeid_cast.h>
|
||||
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int BAD_ARGUMENTS;
|
||||
extern const int ARGUMENT_OUT_OF_BOUND;
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/// Functions common to makeDate, makeDate32, makeDateTime, makeDateTime64
|
||||
/// Functionality common to
|
||||
/// - makeDate, makeDate32, makeDateTime, makeDateTime64,
|
||||
/// - YYYYMMDDToDate, YYYYMMDDToDate32, YYYYMMDDhhmmssToDateTime, YYYYMMDDhhmmssToDateTime64
|
||||
class FunctionWithNumericParamsBase : public IFunction
|
||||
{
|
||||
public:
|
||||
@ -48,11 +52,11 @@ public:
|
||||
size_t getNumberOfArguments() const override { return 0; }
|
||||
|
||||
protected:
|
||||
template <class ArgumentNames>
|
||||
template <class DataType = DataTypeFloat32, class ArgumentNames>
|
||||
Columns convertMandatoryArguments(const ColumnsWithTypeAndName & arguments, const ArgumentNames & argument_names) const
|
||||
{
|
||||
Columns converted_arguments;
|
||||
const DataTypePtr converted_argument_type = std::make_shared<DataTypeFloat32>();
|
||||
const DataTypePtr converted_argument_type = std::make_shared<DataType>();
|
||||
for (size_t i = 0; i < argument_names.size(); ++i)
|
||||
{
|
||||
ColumnPtr argument_column = castColumn(arguments[i], converted_argument_type);
|
||||
@ -63,7 +67,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
/// Common implementation for makeDate, makeDate32
|
||||
/// Implementation of makeDate, makeDate32
|
||||
template <typename Traits>
|
||||
class FunctionMakeDate : public FunctionWithNumericParamsBase
|
||||
{
|
||||
@ -72,7 +76,7 @@ private:
|
||||
static constexpr std::array mandatory_argument_names_year_dayofyear = {"year", "dayofyear"};
|
||||
|
||||
public:
|
||||
static constexpr auto name = Traits::name;
|
||||
static constexpr auto name = Traits::makeDateName;
|
||||
|
||||
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionMakeDate>(); }
|
||||
|
||||
@ -80,9 +84,9 @@ public:
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
const bool isYearMonthDayVariant = (arguments.size() == 3);
|
||||
const bool is_year_month_variant = (arguments.size() == 3);
|
||||
|
||||
if (isYearMonthDayVariant)
|
||||
if (is_year_month_variant)
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{mandatory_argument_names_year_month_day[0], &isNumber<IDataType>, nullptr, "Number"},
|
||||
@ -105,10 +109,10 @@ public:
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
const bool isYearMonthDayVariant = (arguments.size() == 3);
|
||||
const bool is_year_month_day_variant = (arguments.size() == 3);
|
||||
|
||||
Columns converted_arguments;
|
||||
if (isYearMonthDayVariant)
|
||||
if (is_year_month_day_variant)
|
||||
converted_arguments = convertMandatoryArguments(arguments, mandatory_argument_names_year_month_day);
|
||||
else
|
||||
converted_arguments = convertMandatoryArguments(arguments, mandatory_argument_names_year_dayofyear);
|
||||
@ -119,7 +123,7 @@ public:
|
||||
const auto & date_lut = DateLUT::instance();
|
||||
const Int32 max_days_since_epoch = date_lut.makeDayNum(Traits::MAX_DATE[0], Traits::MAX_DATE[1], Traits::MAX_DATE[2]);
|
||||
|
||||
if (isYearMonthDayVariant)
|
||||
if (is_year_month_day_variant)
|
||||
{
|
||||
const auto & year_data = typeid_cast<const ColumnFloat32 &>(*converted_arguments[0]).getData();
|
||||
const auto & month_data = typeid_cast<const ColumnFloat32 &>(*converted_arguments[1]).getData();
|
||||
@ -133,8 +137,7 @@ public:
|
||||
|
||||
Int32 day_num = 0;
|
||||
|
||||
if (year >= Traits::MIN_YEAR &&
|
||||
year <= Traits::MAX_YEAR &&
|
||||
if (year >= Traits::MIN_YEAR && year <= Traits::MAX_YEAR &&
|
||||
month >= 1 && month <= 12 &&
|
||||
day >= 1 && day <= 31)
|
||||
{
|
||||
@ -158,8 +161,7 @@ public:
|
||||
|
||||
Int32 day_num = 0;
|
||||
|
||||
if (year >= Traits::MIN_YEAR &&
|
||||
year <= Traits::MAX_YEAR &&
|
||||
if (year >= Traits::MIN_YEAR && year <= Traits::MAX_YEAR &&
|
||||
dayofyear >= 1 && dayofyear <= 365)
|
||||
{
|
||||
Int32 days_since_epoch = date_lut.makeDayNum(static_cast<Int16>(year), 1, 1) + static_cast<Int32>(dayofyear) - 1;
|
||||
@ -175,20 +177,90 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct MakeDateTraits
|
||||
/// Implementation of YYYYMMDDToDate, YYYYMMDDToDate32
|
||||
template<typename Traits>
|
||||
class FunctionYYYYYMMDDToDate : public FunctionWithNumericParamsBase
|
||||
{
|
||||
static constexpr auto name = "makeDate";
|
||||
private:
|
||||
static constexpr std::array mandatory_argument_names = { "YYYYMMDD" };
|
||||
|
||||
public:
|
||||
static constexpr auto name = Traits::YYYYMMDDName;
|
||||
|
||||
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionYYYYYMMDDToDate>(); }
|
||||
|
||||
String getName() const override { return name; }
|
||||
|
||||
bool isVariadic() const override { return false; }
|
||||
size_t getNumberOfArguments() const override { return mandatory_argument_names.size(); }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors args{
|
||||
{mandatory_argument_names[0], &isNumber<IDataType>, nullptr, "Number"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, args);
|
||||
|
||||
return std::make_shared<typename Traits::ReturnDataType>();
|
||||
}
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
Columns converted_arguments = convertMandatoryArguments<DataTypeFloat64>(arguments, mandatory_argument_names);
|
||||
|
||||
auto res_column = Traits::ReturnDataType::ColumnType::create(input_rows_count);
|
||||
auto & result_data = res_column->getData();
|
||||
|
||||
const auto & yyyymmdd_data = typeid_cast<const ColumnFloat64 &>(*converted_arguments[0]).getData();
|
||||
|
||||
const auto & date_lut = DateLUT::instance();
|
||||
const Int32 max_days_since_epoch = date_lut.makeDayNum(Traits::MAX_DATE[0], Traits::MAX_DATE[1], Traits::MAX_DATE[2]);
|
||||
|
||||
for (size_t i = 0; i < input_rows_count; ++i)
|
||||
{
|
||||
if (std::isinf(yyyymmdd_data[i]) || std::isnan(yyyymmdd_data[i])) [[unlikely]]
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Argument for function {} must be finite", getName());
|
||||
|
||||
const auto yyyymmdd = std::llround(yyyymmdd_data[i]);
|
||||
|
||||
const auto year = yyyymmdd / 10'000;
|
||||
const auto month = yyyymmdd / 100 % 100;
|
||||
const auto day = yyyymmdd % 100;
|
||||
|
||||
Int32 day_num = 0;
|
||||
|
||||
if (year >= Traits::MIN_YEAR && year <= Traits::MAX_YEAR &&
|
||||
month >= 1 && month <= 12 &&
|
||||
day >= 1 && day <= 31)
|
||||
{
|
||||
Int32 days_since_epoch = date_lut.makeDayNum(static_cast<Int16>(year), static_cast<UInt8>(month), static_cast<UInt8>(day));
|
||||
if (days_since_epoch <= max_days_since_epoch)
|
||||
day_num = days_since_epoch;
|
||||
}
|
||||
|
||||
result_data[i] = day_num;
|
||||
}
|
||||
|
||||
return res_column;
|
||||
}
|
||||
};
|
||||
|
||||
struct DateTraits
|
||||
{
|
||||
static constexpr auto makeDateName = "makeDate";
|
||||
static constexpr auto YYYYMMDDName = "YYYYMMDDToDate";
|
||||
using ReturnDataType = DataTypeDate;
|
||||
|
||||
static constexpr auto MIN_YEAR = 1970;
|
||||
static constexpr auto MAX_YEAR = 2149;
|
||||
/// This date has the maximum day number that fits in 16-bit uint
|
||||
static constexpr std::array MAX_DATE = {MAX_YEAR, 6, 6};
|
||||
};
|
||||
|
||||
struct MakeDate32Traits
|
||||
struct Date32Traits
|
||||
{
|
||||
static constexpr auto name = "makeDate32";
|
||||
static constexpr auto makeDateName = "makeDate32";
|
||||
static constexpr auto YYYYMMDDName = "YYYYMMDDToDate32";
|
||||
using ReturnDataType = DataTypeDate32;
|
||||
|
||||
static constexpr auto MIN_YEAR = 1900;
|
||||
@ -196,11 +268,11 @@ struct MakeDate32Traits
|
||||
static constexpr std::array MAX_DATE = {MAX_YEAR, 12, 31};
|
||||
};
|
||||
|
||||
/// Common implementation for makeDateTime, makeDateTime64
|
||||
class FunctionMakeDateTimeBase : public FunctionWithNumericParamsBase
|
||||
/// Functionality common to makeDateTime, makeDateTime64, YYYYMMDDhhmmssToDateTime, YYYYMMDDhhmmssToDateTime64
|
||||
class FunctionDateTimeBase : public FunctionWithNumericParamsBase
|
||||
{
|
||||
protected:
|
||||
static constexpr std::array mandatory_argument_names = {"year", "month", "day", "hour", "minute", "second"};
|
||||
static constexpr UInt32 DEFAULT_PRECISION = 3;
|
||||
|
||||
template <typename T>
|
||||
static Int64 dateTime(T year, T month, T day_of_month, T hour, T minute, T second, const DateLUTImpl & lut)
|
||||
@ -233,14 +305,35 @@ protected:
|
||||
|
||||
std::string extractTimezone(const ColumnWithTypeAndName & timezone_argument) const
|
||||
{
|
||||
std::string timezone;
|
||||
if (!isStringOrFixedString(timezone_argument.type) || !timezone_argument.column || (timezone_argument.column->size() != 1 && !typeid_cast<const ColumnConst*>(timezone_argument.column.get())))
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Argument 'timezone' for function {} must be const string", getName());
|
||||
timezone = timezone_argument.column->getDataAt(0).toString();
|
||||
|
||||
String timezone = timezone_argument.column->getDataAt(0).toString();
|
||||
|
||||
return timezone;
|
||||
}
|
||||
|
||||
UInt32 extractPrecision(const ColumnWithTypeAndName & precision_argument) const
|
||||
{
|
||||
if (!isNumber(precision_argument.type) || !precision_argument.column || (precision_argument.column->size() != 1 && !typeid_cast<const ColumnConst*>(precision_argument.column.get())))
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Argument 'precision' for function {} must be constant number", getName());
|
||||
|
||||
Int64 precision = precision_argument.column->getInt(0);
|
||||
|
||||
if (precision < 0 || precision > 9)
|
||||
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND,
|
||||
"Argument 'precision' for function {} must be in range [0, 9]", getName());
|
||||
|
||||
return static_cast<UInt32>(precision);
|
||||
}
|
||||
};
|
||||
|
||||
class FunctionMakeDateTimeBase : public FunctionDateTimeBase
|
||||
{
|
||||
protected:
|
||||
static constexpr std::array mandatory_argument_names = {"year", "month", "day", "hour", "minute", "second"};
|
||||
};
|
||||
|
||||
/// makeDateTime(year, month, day, hour, minute, second, [timezone])
|
||||
@ -268,7 +361,7 @@ public:
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{optional_argument_names[0], &isString<IDataType>, nullptr, "String"}
|
||||
{optional_argument_names[0], &isString<IDataType>, isColumnConst, "const String"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
@ -329,7 +422,6 @@ class FunctionMakeDateTime64 : public FunctionMakeDateTimeBase
|
||||
{
|
||||
private:
|
||||
static constexpr std::array optional_argument_names = {"fraction", "precision", "timezone"};
|
||||
static constexpr UInt8 DEFAULT_PRECISION = 3;
|
||||
|
||||
public:
|
||||
static constexpr auto name = "makeDateTime64";
|
||||
@ -350,9 +442,9 @@ public:
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{optional_argument_names[0], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{optional_argument_names[1], &isNumber<IDataType>, nullptr, "Number"},
|
||||
{optional_argument_names[2], &isString<IDataType>, nullptr, "String"}
|
||||
{optional_argument_names[0], &isNumber<IDataType>, isColumnConst, "const Number"},
|
||||
{optional_argument_names[1], &isNumber<IDataType>, isColumnConst, "const Number"},
|
||||
{optional_argument_names[2], &isString<IDataType>, isColumnConst, "const String"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
@ -456,20 +548,182 @@ public:
|
||||
|
||||
return res_column;
|
||||
}
|
||||
};
|
||||
|
||||
class FunctionYYYYMMDDhhmmssToDateTimeBase : public FunctionDateTimeBase
|
||||
{
|
||||
protected:
|
||||
static constexpr std::array mandatory_argument_names = { "YYYYMMDDhhmmss" };
|
||||
};
|
||||
|
||||
/// YYYYMMDDhhmmssToDateTime
|
||||
class FunctionYYYYMMDDhhmmssToDateTime : public FunctionYYYYMMDDhhmmssToDateTimeBase
|
||||
{
|
||||
private:
|
||||
UInt8 extractPrecision(const ColumnWithTypeAndName & precision_argument) const
|
||||
{
|
||||
Int64 precision = DEFAULT_PRECISION;
|
||||
if (!isNumber(precision_argument.type) || !precision_argument.column || (precision_argument.column->size() != 1 && !typeid_cast<const ColumnConst*>(precision_argument.column.get())))
|
||||
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
"Argument 'precision' for function {} must be constant number", getName());
|
||||
precision = precision_argument.column->getInt(0);
|
||||
if (precision < 0 || precision > 9)
|
||||
throw Exception(ErrorCodes::ARGUMENT_OUT_OF_BOUND,
|
||||
"Argument 'precision' for function {} must be in range [0, 9]", getName());
|
||||
static constexpr std::array optional_argument_names = { "timezone" };
|
||||
|
||||
return precision;
|
||||
public:
|
||||
static constexpr auto name = "YYYYMMDDhhmmssToDateTime";
|
||||
|
||||
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionYYYYMMDDhhmmssToDateTime>(); }
|
||||
|
||||
String getName() const override { return name; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{mandatory_argument_names[0], &isNumber<IDataType>, nullptr, "Number"}
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{optional_argument_names[0], &isString<IDataType>, isColumnConst, "const String"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
|
||||
/// Optional timezone argument
|
||||
std::string timezone;
|
||||
if (arguments.size() == mandatory_argument_names.size() + 1)
|
||||
timezone = extractTimezone(arguments.back());
|
||||
|
||||
return std::make_shared<DataTypeDateTime>(timezone);
|
||||
}
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
std::string timezone;
|
||||
if (arguments.size() == mandatory_argument_names.size() + 1)
|
||||
timezone = extractTimezone(arguments.back());
|
||||
|
||||
Columns converted_arguments = convertMandatoryArguments<DataTypeFloat64>(arguments, mandatory_argument_names);
|
||||
|
||||
auto res_column = ColumnDateTime::create(input_rows_count);
|
||||
auto & result_data = res_column->getData();
|
||||
|
||||
const auto & yyyymmddhhmmss_data = typeid_cast<const ColumnFloat64 &>(*converted_arguments[0]).getData();
|
||||
|
||||
const auto & date_lut = DateLUT::instance(timezone);
|
||||
|
||||
for (size_t i = 0; i < input_rows_count; i++)
|
||||
{
|
||||
if (std::isinf(yyyymmddhhmmss_data[i]) || std::isnan(yyyymmddhhmmss_data[i])) [[unlikely]]
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Argument for function {} must be finite", getName());
|
||||
|
||||
const auto yyyymmddhhmmss = std::llround(yyyymmddhhmmss_data[i]);
|
||||
|
||||
const auto yyyymmdd = yyyymmddhhmmss / 1'000'000;
|
||||
const auto hhmmss = yyyymmddhhmmss % 1'000'000;
|
||||
|
||||
const auto year = yyyymmdd / 10'000;
|
||||
const auto month = yyyymmdd / 100 % 100;
|
||||
const auto day = yyyymmdd % 100;
|
||||
const auto hour = hhmmss / 10'000;
|
||||
const auto minute = hhmmss / 100 % 100;
|
||||
const auto second = hhmmss % 100;
|
||||
|
||||
auto date_time = dateTime(year, month, day, hour, minute, second, date_lut);
|
||||
|
||||
if (date_time < 0) [[unlikely]]
|
||||
date_time = 0;
|
||||
else if (date_time > 0x0ffffffffll) [[unlikely]]
|
||||
date_time = 0x0ffffffffll;
|
||||
|
||||
result_data[i] = static_cast<UInt32>(date_time);
|
||||
}
|
||||
|
||||
return res_column;
|
||||
}
|
||||
};
|
||||
|
||||
/// YYYYMMDDhhmmssToDateTime64
|
||||
class FunctionYYYYMMDDhhmmssToDateTime64 : public FunctionYYYYMMDDhhmmssToDateTimeBase
|
||||
{
|
||||
private:
|
||||
static constexpr std::array optional_argument_names = { "precision", "timezone" };
|
||||
|
||||
public:
|
||||
static constexpr auto name = "YYYYMMDDhhmmssToDateTime64";
|
||||
|
||||
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionYYYYMMDDhhmmssToDateTime64>(); }
|
||||
|
||||
String getName() const override { return name; }
|
||||
|
||||
DataTypePtr getReturnTypeImpl(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
FunctionArgumentDescriptors mandatory_args{
|
||||
{mandatory_argument_names[0], &isNumber<IDataType>, nullptr, "Number"}
|
||||
};
|
||||
|
||||
FunctionArgumentDescriptors optional_args{
|
||||
{optional_argument_names[0], &isNumber<IDataType>, isColumnConst, "const Number"},
|
||||
{optional_argument_names[0], &isString<IDataType>, isColumnConst, "const String"}
|
||||
};
|
||||
|
||||
validateFunctionArgumentTypes(*this, arguments, mandatory_args, optional_args);
|
||||
|
||||
/// Optional precision argument
|
||||
auto precision = DEFAULT_PRECISION;
|
||||
if (arguments.size() >= mandatory_argument_names.size() + 1)
|
||||
precision = extractPrecision(arguments[mandatory_argument_names.size()]);
|
||||
|
||||
/// Optional timezone argument
|
||||
std::string timezone;
|
||||
if (arguments.size() == mandatory_argument_names.size() + 2)
|
||||
timezone = extractTimezone(arguments.back());
|
||||
|
||||
return std::make_shared<DataTypeDateTime64>(precision, timezone);
|
||||
}
|
||||
|
||||
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||
{
|
||||
UInt32 precision = DEFAULT_PRECISION;
|
||||
if (arguments.size() >= mandatory_argument_names.size() + 1)
|
||||
precision = extractPrecision(arguments[mandatory_argument_names.size()]);
|
||||
|
||||
std::string timezone;
|
||||
if (arguments.size() == mandatory_argument_names.size() + 2)
|
||||
timezone = extractTimezone(arguments.back());
|
||||
|
||||
Columns converted_arguments = convertMandatoryArguments<DataTypeFloat64>(arguments, mandatory_argument_names);
|
||||
|
||||
auto res_column = ColumnDateTime64::create(input_rows_count, static_cast<UInt32>(precision));
|
||||
auto & result_data = res_column->getData();
|
||||
|
||||
const auto & yyyymmddhhmmss_data = typeid_cast<const ColumnFloat64 &>(*converted_arguments[0]).getData();
|
||||
|
||||
const auto & date_lut = DateLUT::instance(timezone);
|
||||
|
||||
const auto fraction_pow = common::exp10_i32(precision);
|
||||
|
||||
for (size_t i = 0; i < input_rows_count; i++)
|
||||
{
|
||||
const auto float_date = yyyymmddhhmmss_data[i];
|
||||
|
||||
if (std::isinf(float_date) || std::isnan(float_date)) [[unlikely]]
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Argument for function {} must be finite", getName());
|
||||
|
||||
const auto yyyymmddhhmmss = std::llround(float_date);
|
||||
|
||||
const auto yyyymmdd = yyyymmddhhmmss / 1'000'000;
|
||||
const auto hhmmss = yyyymmddhhmmss % 1'000'000;
|
||||
|
||||
const auto decimal = float_date - yyyymmddhhmmss;
|
||||
|
||||
const auto year = yyyymmdd / 10'000;
|
||||
const auto month = yyyymmdd / 100 % 100;
|
||||
const auto day = yyyymmdd % 100;
|
||||
const auto hour = hhmmss / 10'000;
|
||||
const auto minute = hhmmss / 100 % 100;
|
||||
const auto second = hhmmss % 100;
|
||||
|
||||
auto date_time = dateTime(year, month, day, hour, minute, second, date_lut);
|
||||
|
||||
auto fraction = std::llround(decimal * fraction_pow);
|
||||
|
||||
result_data[i] = DecimalUtils::decimalFromComponents<DateTime64>(date_time, fraction, precision);
|
||||
}
|
||||
|
||||
return res_column;
|
||||
}
|
||||
};
|
||||
|
||||
@ -477,10 +731,48 @@ private:
|
||||
|
||||
REGISTER_FUNCTION(MakeDate)
|
||||
{
|
||||
factory.registerFunction<FunctionMakeDate<MakeDateTraits>>({}, FunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction<FunctionMakeDate<MakeDate32Traits>>();
|
||||
factory.registerFunction<FunctionMakeDate<DateTraits>>({}, FunctionFactory::CaseInsensitive);
|
||||
factory.registerFunction<FunctionMakeDate<Date32Traits>>();
|
||||
factory.registerFunction<FunctionMakeDateTime>();
|
||||
factory.registerFunction<FunctionMakeDateTime64>();
|
||||
|
||||
factory.registerFunction<FunctionYYYYYMMDDToDate<DateTraits>>(
|
||||
FunctionDocumentation{
|
||||
.description = R"(
|
||||
Converts a number containing the year, month and day number to a Date.
|
||||
This functions is the opposite of function `toYYYYMMDD()`.
|
||||
The output is undefined if the input does not encode a valid Date value.
|
||||
)",
|
||||
.categories{"Dates and Times"}
|
||||
}
|
||||
);
|
||||
factory.registerFunction<FunctionYYYYYMMDDToDate<Date32Traits>>(
|
||||
FunctionDocumentation{
|
||||
.description = R"(
|
||||
Like function `YYYYMMDDToDate()` but produces a Date32.
|
||||
)",
|
||||
.categories{"Dates and Times"}
|
||||
}
|
||||
);
|
||||
factory.registerFunction<FunctionYYYYMMDDhhmmssToDateTime>(
|
||||
FunctionDocumentation{
|
||||
.description = R"(
|
||||
Converts a number containing the year, month, day, hour, minute and second number to a DateTime.
|
||||
The output is undefined if the input does not encode a valid DateTime value.
|
||||
This functions is the opposite of function `toYYYYMMDD()`.
|
||||
)",
|
||||
.categories{"Dates and Times"}
|
||||
}
|
||||
);
|
||||
factory.registerFunction<FunctionYYYYMMDDhhmmssToDateTime64>(
|
||||
FunctionDocumentation{
|
||||
.description = R"(
|
||||
Like function `YYYYMMDDhhmmssToDate()` but produces a DateTime64.
|
||||
Accepts an additional, optional `precision` parameter after the `timezone` parameter.
|
||||
)",
|
||||
.categories{"Dates and Times"}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -353,6 +353,7 @@ QueryPipeline::QueryPipeline(Pipe pipe)
|
||||
totals = pipe.getTotalsPort();
|
||||
extremes = pipe.getExtremesPort();
|
||||
partial_result = pipe.getPartialResultPort(0);
|
||||
num_threads = pipe.max_parallel_streams;
|
||||
|
||||
processors = std::move(pipe.processors);
|
||||
checkPulling(*processors, output, totals, extremes, partial_result);
|
||||
|
@ -86,4 +86,4 @@ select makeDateTime64(year, 1, 1, 1, 0, 0, 0, precision, timezone) from (
|
||||
select 1984 as year, 5 as precision, 'UTC' as timezone
|
||||
union all
|
||||
select 1985 as year, 5 as precision, 'UTC' as timezone
|
||||
); -- { serverError 43 }
|
||||
); -- { serverError 44 }
|
||||
|
@ -0,0 +1,86 @@
|
||||
--- YYYYMMDDToDateTime
|
||||
Invalid input types are rejected
|
||||
Result type is DateTime
|
||||
DateTime
|
||||
Nullable(DateTime)
|
||||
Check correctness, integer arguments
|
||||
1970-01-02 11:59:59
|
||||
1970-01-01 00:00:00
|
||||
2020-02-29 11:11:11
|
||||
2023-09-11 15:05:05
|
||||
2106-02-07 06:28:15
|
||||
2106-02-07 06:28:15
|
||||
1970-01-01 00:00:00
|
||||
Check correctness, float arguments
|
||||
1970-01-02 11:59:59
|
||||
1970-01-01 00:00:00
|
||||
2020-02-29 11:11:11
|
||||
2023-09-11 15:05:05
|
||||
2106-02-07 06:28:15
|
||||
2106-02-07 06:28:15
|
||||
Check correctness, decimal arguments
|
||||
1970-01-02 11:59:59
|
||||
1970-01-01 00:00:00
|
||||
2020-02-29 11:11:11
|
||||
2023-09-11 15:05:05
|
||||
2106-02-07 06:28:15
|
||||
2106-02-07 06:28:15
|
||||
Special cases
|
||||
1970-01-01 00:00:00
|
||||
1970-01-01 00:00:00
|
||||
1970-01-01 00:00:00
|
||||
1970-01-01 00:00:00
|
||||
2106-02-07 06:28:15
|
||||
1970-01-01 00:00:00
|
||||
1970-01-01 00:00:00
|
||||
1970-01-01 00:00:00
|
||||
1970-01-01 00:00:00
|
||||
2023-02-28 11:11:11
|
||||
1970-01-01 00:00:00
|
||||
1970-01-01 00:00:00
|
||||
\N
|
||||
1970-01-01 00:00:00
|
||||
1970-01-01 00:00:00
|
||||
--- YYYYMMDDToDateTime64
|
||||
Invalid input types are rejected
|
||||
Result type is DateTime
|
||||
DateTime64(3)
|
||||
DateTime64(5)
|
||||
Nullable(DateTime64(3))
|
||||
Check correctness, integer arguments
|
||||
1900-01-01 00:00:00.000
|
||||
1900-01-01 00:00:00.000
|
||||
2020-02-29 11:11:11.000
|
||||
2023-09-11 15:05:05.000
|
||||
2299-12-31 23:59:59.000
|
||||
2299-12-31 23:59:59.000
|
||||
Check correctness, float arguments
|
||||
1900-01-01 00:00:00.900
|
||||
1900-01-01 00:00:00.898
|
||||
2020-02-29 11:11:11.102
|
||||
2023-09-11 15:05:05.102
|
||||
2299-12-31 23:59:59.102
|
||||
2299-12-31 23:59:59.102
|
||||
Check correctness, decimal arguments
|
||||
1900-01-01 00:00:00.900
|
||||
1900-01-01 00:00:00.898
|
||||
2020-02-29 11:11:11.102
|
||||
2023-09-11 15:05:05.102
|
||||
2299-12-31 23:59:59.102
|
||||
2299-12-31 23:59:59.102
|
||||
Special cases
|
||||
1900-01-01 00:00:00.000
|
||||
1900-01-01 00:00:00.000
|
||||
1900-01-01 00:00:00.000
|
||||
1900-01-01 00:00:00.000
|
||||
2299-12-31 23:59:59.000
|
||||
1900-01-01 00:00:00.000
|
||||
1900-01-01 00:00:00.000
|
||||
1900-01-01 00:00:00.000
|
||||
1900-01-01 00:00:00.000
|
||||
2023-02-28 11:11:11.000
|
||||
1900-01-01 00:00:00.000
|
||||
1900-01-01 00:00:00.000
|
||||
\N
|
||||
1900-01-01 00:00:00.000
|
||||
1900-01-01 00:00:00.000
|
127
tests/queries/0_stateless/02876_yyyymmddhhmmsstodatetime.sql
Normal file
127
tests/queries/0_stateless/02876_yyyymmddhhmmsstodatetime.sql
Normal file
@ -0,0 +1,127 @@
|
||||
SET session_timezone = 'UTC'; -- no time zone randomization, please
|
||||
|
||||
-----------------------------------------------------------
|
||||
SELECT '--- YYYYMMDDToDateTime';
|
||||
|
||||
SELECT 'Invalid input types are rejected';
|
||||
SELECT YYYYMMDDhhmmssToDateTime(); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
|
||||
SELECT YYYYMMDDhhmmssToDateTime(toDate('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime(toDate32('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime(toDateTime('2023-09-11 12:18:00')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime(toDateTime64('2023-09-11 12:18:00', 3)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime('2023-09-11'); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20230911134254, 3); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20230911134254, 'invalid tz'); -- { serverError BAD_ARGUMENTS }
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20230911134254, 'Europe/Berlin', 'bad'); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
|
||||
|
||||
SELECT 'Result type is DateTime';
|
||||
SELECT toTypeName(YYYYMMDDhhmmssToDateTime(19910824));
|
||||
SELECT toTypeName(YYYYMMDDhhmmssToDateTime(cast(19910824 AS Nullable(UInt64))));
|
||||
--
|
||||
SELECT 'Check correctness, integer arguments';
|
||||
SELECT YYYYMMDDhhmmssToDateTime(19691231595959);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(19700101000000);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20200229111111); -- leap day
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20230911150505);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(21060207062815);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(21060207062816);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(9223372036854775807); -- huge value
|
||||
|
||||
SELECT 'Check correctness, float arguments';
|
||||
SELECT YYYYMMDDhhmmssToDateTime(19691231595959.1);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(19700101000000.1);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20200229111111.1); -- leap day
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20230911150505.1);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(21060207062815.1);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(21060207062816.1);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(NaN); -- { serverError BAD_ARGUMENTS }
|
||||
SELECT YYYYMMDDhhmmssToDateTime(Inf); -- { serverError BAD_ARGUMENTS }
|
||||
SELECT YYYYMMDDhhmmssToDateTime(-Inf); -- { serverError BAD_ARGUMENTS }
|
||||
|
||||
SELECT 'Check correctness, decimal arguments';
|
||||
SELECT YYYYMMDDhhmmssToDateTime(toDecimal64(19691231595959.1, 5));
|
||||
SELECT YYYYMMDDhhmmssToDateTime(toDecimal64(19700101000000.1, 5));
|
||||
SELECT YYYYMMDDhhmmssToDateTime(toDecimal64(20200229111111.1, 5)); -- leap day
|
||||
SELECT YYYYMMDDhhmmssToDateTime(toDecimal64(20230911150505.1, 5));
|
||||
SELECT YYYYMMDDhhmmssToDateTime(toDecimal64(21060207062815.1, 5));
|
||||
SELECT YYYYMMDDhhmmssToDateTime(toDecimal64(21060207062816.1, 5));
|
||||
|
||||
SELECT 'Special cases';
|
||||
SELECT YYYYMMDDhhmmssToDateTime(-20230911111111); -- negative
|
||||
SELECT YYYYMMDDhhmmssToDateTime(110); -- invalid everything
|
||||
SELECT YYYYMMDDhhmmssToDateTime(999999999999999999); -- huge value
|
||||
SELECT YYYYMMDDhhmmssToDateTime(15001113111111); -- year out of range
|
||||
SELECT YYYYMMDDhhmmssToDateTime(35001113111111); -- year out of range
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20231620111111); -- invalid month
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20230020111111); -- invalid month
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20230940111111); -- invalid day
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20230900111111); -- invalid day
|
||||
SELECT YYYYMMDDhhmmssToDateTime(20230228111111); -- leap day when there is none
|
||||
SELECT YYYYMMDDhhmmssToDateTime(True);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(False);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(NULL);
|
||||
SELECT YYYYMMDDhhmmssToDateTime(yyyymmdd) FROM (SELECT 19840121 AS yyyymmdd UNION ALL SELECT 20230911 AS yyyymmdd) ORDER BY yyyymmdd; -- non-const
|
||||
|
||||
-----------------------------------------------------------
|
||||
SELECT '--- YYYYMMDDToDateTime64';
|
||||
|
||||
SELECT 'Invalid input types are rejected';
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(toDate('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(toDate32('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(toDateTime('2023-09-11 12:18:00')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(toDateTime64('2023-09-11 12:18:00', 3)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime64('2023-09-11'); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime64('2023-09-11', 'invalid precision'); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20230911134254, 3, 3); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20230911134254, 3, 'invalid tz'); -- { serverError BAD_ARGUMENTS }
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20230911134254, 3, 'Europe/Berlin', 'no more args'); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
|
||||
|
||||
SELECT 'Result type is DateTime';
|
||||
SELECT toTypeName(YYYYMMDDhhmmssToDateTime64(19910824));
|
||||
SELECT toTypeName(YYYYMMDDhhmmssToDateTime64(19910824, 5));
|
||||
SELECT toTypeName(YYYYMMDDhhmmssToDateTime64(cast(19910824 AS Nullable(UInt64))));
|
||||
|
||||
SELECT 'Check correctness, integer arguments';
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(189912315959);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(19000101000000);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20200229111111); -- leap day
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20230911150505);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(22991231235959);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(23000101000000);
|
||||
-- SELECT YYYYMMDDhhmmssToDateTime64(9223372036854775807); -- huge value, commented out because on ARM, the rounding is slightly different
|
||||
|
||||
SELECT 'Check correctness, float arguments';
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(189912315959.1);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(19000101000000.1);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20200229111111.1); -- leap day
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20230911150505.1);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(22991231235959.1);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(23000101000000.1);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(NaN); -- { serverError BAD_ARGUMENTS }
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(Inf); -- { serverError BAD_ARGUMENTS }
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(-Inf); -- { serverError BAD_ARGUMENTS }
|
||||
|
||||
SELECT 'Check correctness, decimal arguments';
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(toDecimal64(189912315959.1, 5));
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(toDecimal64(19000101000000.1, 5));
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(toDecimal64(20200229111111.1, 5)); -- leap day
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(toDecimal64(20230911150505.1, 5));
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(toDecimal64(22991231235959.1, 5));
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(toDecimal64(23000101000000.1, 5));
|
||||
|
||||
SELECT 'Special cases';
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(-20230911111111); -- negative
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(110); -- invalid everything
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(999999999999999999); -- huge value
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(15001113111111); -- year out of range
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(35001113111111); -- year out of range
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20231620111111); -- invalid month
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20230020111111); -- invalid month
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20230940111111); -- invalid day
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20230900111111); -- invalid day
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(20230228111111); -- leap day when there is none
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(True);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(False);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(NULL);
|
||||
SELECT YYYYMMDDhhmmssToDateTime64(yyyymmdd) FROM (SELECT 19840121 AS yyyymmdd UNION ALL SELECT 20230911 AS yyyymmdd) ORDER BY yyyymmdd; -- non-const
|
86
tests/queries/0_stateless/02876_yyyymmddtodate.reference
Normal file
86
tests/queries/0_stateless/02876_yyyymmddtodate.reference
Normal file
@ -0,0 +1,86 @@
|
||||
--- YYYYMMDDToDate
|
||||
Invalid input types are rejected
|
||||
Result type is Date
|
||||
Date
|
||||
Nullable(Date)
|
||||
Check correctness, integer arguments
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
2020-02-29
|
||||
2023-09-11
|
||||
2149-06-06
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
Check correctness, float arguments
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
2020-02-29
|
||||
2023-09-11
|
||||
2149-06-06
|
||||
1970-01-01
|
||||
Check correctness, decimal arguments
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
2020-02-29
|
||||
2023-09-11
|
||||
2149-06-06
|
||||
1970-01-01
|
||||
Special cases
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
2023-02-28
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
\N
|
||||
1984-01-21
|
||||
2023-09-11
|
||||
--- YYYYMMDDToDate32
|
||||
Invalid input types are rejected
|
||||
Result type is Date32
|
||||
Date32
|
||||
Nullable(Date32)
|
||||
Check correctness, integer arguments
|
||||
1970-01-01
|
||||
1900-01-01
|
||||
2020-02-29
|
||||
2023-09-11
|
||||
2299-12-31
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
Check correctness, float arguments
|
||||
1970-01-01
|
||||
1900-01-01
|
||||
2020-02-29
|
||||
2023-09-11
|
||||
2299-12-31
|
||||
1970-01-01
|
||||
Check correctness, decimal arguments
|
||||
1970-01-01
|
||||
1900-01-01
|
||||
2020-02-29
|
||||
2023-09-11
|
||||
2299-12-31
|
||||
1970-01-01
|
||||
Special cases
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
2023-02-28
|
||||
1970-01-01
|
||||
1970-01-01
|
||||
\N
|
||||
1984-01-21
|
||||
2023-09-11
|
120
tests/queries/0_stateless/02876_yyyymmddtodate.sql
Normal file
120
tests/queries/0_stateless/02876_yyyymmddtodate.sql
Normal file
@ -0,0 +1,120 @@
|
||||
-----------------------------------------------------------
|
||||
SELECT '--- YYYYMMDDToDate';
|
||||
|
||||
SELECT 'Invalid input types are rejected';
|
||||
SELECT YYYYMMDDToDate(); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
|
||||
SELECT YYYYMMDDToDate(toDate('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDToDate(toDate32('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDToDate(toDateTime('2023-09-11 12:18:00')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDToDate(toDateTime64('2023-09-11 12:18:00', 3)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDToDate('2023-09-11'); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDToDate(2023, 09, 11); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
|
||||
SELECT YYYYMMDDToDate(2023, 110); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
|
||||
|
||||
SELECT 'Result type is Date';
|
||||
SELECT toTypeName(YYYYMMDDToDate(19910824));
|
||||
SELECT toTypeName(YYYYMMDDToDate(cast(19910824 AS Nullable(UInt64))));
|
||||
|
||||
SELECT 'Check correctness, integer arguments';
|
||||
SELECT YYYYMMDDToDate(19691231);
|
||||
SELECT YYYYMMDDToDate(19700101);
|
||||
SELECT YYYYMMDDToDate(20200229); -- leap day
|
||||
SELECT YYYYMMDDToDate(20230911);
|
||||
SELECT YYYYMMDDToDate(21490606);
|
||||
SELECT YYYYMMDDToDate(21490607);
|
||||
SELECT YYYYMMDDToDate(9223372036854775807); -- huge value
|
||||
|
||||
SELECT 'Check correctness, float arguments';
|
||||
SELECT YYYYMMDDToDate(19691231.1);
|
||||
SELECT YYYYMMDDToDate(19700101.1);
|
||||
SELECT YYYYMMDDToDate(20200229.1); -- leap day
|
||||
SELECT YYYYMMDDToDate(20230911.1);
|
||||
SELECT YYYYMMDDToDate(21490606.1);
|
||||
SELECT YYYYMMDDToDate(21490607.1);
|
||||
SELECT YYYYMMDDToDate(NaN); -- { serverError BAD_ARGUMENTS }
|
||||
SELECT YYYYMMDDToDate(Inf); -- { serverError BAD_ARGUMENTS }
|
||||
SELECT YYYYMMDDToDate(-Inf); -- { serverError BAD_ARGUMENTS }
|
||||
|
||||
SELECT 'Check correctness, decimal arguments';
|
||||
SELECT YYYYMMDDToDate(toDecimal64(19691231.1, 5));
|
||||
SELECT YYYYMMDDToDate(toDecimal64(19700101.1, 5));
|
||||
SELECT YYYYMMDDToDate(toDecimal64(20200229.1, 5)); -- leap day
|
||||
SELECT YYYYMMDDToDate(toDecimal64(20230911.1, 5));
|
||||
SELECT YYYYMMDDToDate(toDecimal64(21490606.1, 5));
|
||||
SELECT YYYYMMDDToDate(toDecimal64(21490607.1, 5));
|
||||
|
||||
SELECT 'Special cases';
|
||||
SELECT YYYYMMDDToDate(-20230911); -- negative
|
||||
SELECT YYYYMMDDToDate(110); -- invalid everything
|
||||
SELECT YYYYMMDDToDate(9999999999999); -- huge value
|
||||
SELECT YYYYMMDDToDate(15001113); -- year out of range
|
||||
SELECT YYYYMMDDToDate(35001113); -- year out of range
|
||||
SELECT YYYYMMDDToDate(20231620); -- invalid month
|
||||
SELECT YYYYMMDDToDate(20230020); -- invalid month
|
||||
SELECT YYYYMMDDToDate(20230940); -- invalid day
|
||||
SELECT YYYYMMDDToDate(20230900); -- invalid day
|
||||
SELECT YYYYMMDDToDate(20230228); -- leap day when there is none
|
||||
SELECT YYYYMMDDToDate(True);
|
||||
SELECT YYYYMMDDToDate(False);
|
||||
SELECT YYYYMMDDToDate(NULL);
|
||||
SELECT YYYYMMDDToDate(yyyymmdd) FROM (SELECT 19840121 AS yyyymmdd UNION ALL SELECT 20230911 AS yyyymmdd) ORDER BY yyyymmdd; -- non-const
|
||||
|
||||
-----------------------------------------------------------
|
||||
SELECT '--- YYYYMMDDToDate32';
|
||||
|
||||
SELECT 'Invalid input types are rejected';
|
||||
SELECT YYYYMMDDToDate32(toDate('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDToDate32(toDate32('2023-09-11')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDToDate32(toDateTime('2023-09-11 12:18:00')); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDToDate32(toDateTime64('2023-09-11 12:18:00', 3)); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDToDate32('2023-09-11'); -- { serverError ILLEGAL_TYPE_OF_ARGUMENT }
|
||||
SELECT YYYYMMDDToDate32(2023, 09, 11); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
|
||||
SELECT YYYYMMDDToDate32(2023, 110); -- { serverError NUMBER_OF_ARGUMENTS_DOESNT_MATCH }
|
||||
|
||||
SELECT 'Result type is Date32';
|
||||
SELECT toTypeName(YYYYMMDDToDate32(19910824));
|
||||
SELECT toTypeName(YYYYMMDDToDate32(cast(19910824 AS Nullable(UInt64))));
|
||||
|
||||
SELECT 'Check correctness, integer arguments';
|
||||
SELECT YYYYMMDDToDate32(18991231);
|
||||
SELECT YYYYMMDDToDate32(19000101);
|
||||
SELECT YYYYMMDDToDate32(20200229); -- leap day
|
||||
SELECT YYYYMMDDToDate32(20230911);
|
||||
SELECT YYYYMMDDToDate32(22991231);
|
||||
SELECT YYYYMMDDToDate32(23000101);
|
||||
SELECT YYYYMMDDToDate32(9223372036854775807); -- huge value
|
||||
|
||||
SELECT 'Check correctness, float arguments';
|
||||
SELECT YYYYMMDDToDate32(18991231.1);
|
||||
SELECT YYYYMMDDToDate32(19000101.1);
|
||||
SELECT YYYYMMDDToDate32(20200229.1); -- leap day
|
||||
SELECT YYYYMMDDToDate32(20230911.1);
|
||||
SELECT YYYYMMDDToDate32(22991231.1);
|
||||
SELECT YYYYMMDDToDate32(23000101.1);
|
||||
SELECT YYYYMMDDToDate32(NaN); -- { serverError BAD_ARGUMENTS }
|
||||
SELECT YYYYMMDDToDate32(Inf); -- { serverError BAD_ARGUMENTS }
|
||||
SELECT YYYYMMDDToDate32(-Inf); -- { serverError BAD_ARGUMENTS }
|
||||
|
||||
SELECT 'Check correctness, decimal arguments';
|
||||
SELECT YYYYMMDDToDate32(toDecimal64(18991231.1, 5));
|
||||
SELECT YYYYMMDDToDate32(toDecimal64(19000101.1, 5));
|
||||
SELECT YYYYMMDDToDate32(toDecimal64(20200229.1, 5)); -- leap day
|
||||
SELECT YYYYMMDDToDate32(toDecimal64(20230911.1, 5));
|
||||
SELECT YYYYMMDDToDate32(toDecimal64(22991231.1, 5));
|
||||
SELECT YYYYMMDDToDate32(toDecimal64(23000101.1, 5));
|
||||
|
||||
SELECT 'Special cases';
|
||||
SELECT YYYYMMDDToDate32(-20230911); -- negative
|
||||
SELECT YYYYMMDDToDate32(110); -- invalid everything
|
||||
SELECT YYYYMMDDToDate32(9999999999999); -- huge value
|
||||
SELECT YYYYMMDDToDate32(15001113); -- year out of range
|
||||
SELECT YYYYMMDDToDate32(35001113); -- year out of range
|
||||
SELECT YYYYMMDDToDate32(20231620); -- invalid month
|
||||
SELECT YYYYMMDDToDate32(20230020); -- invalid month
|
||||
SELECT YYYYMMDDToDate32(20230940); -- invalid day
|
||||
SELECT YYYYMMDDToDate32(20230900); -- invalid day
|
||||
SELECT YYYYMMDDToDate32(20230228); -- leap day when there is none
|
||||
SELECT YYYYMMDDToDate32(True);
|
||||
SELECT YYYYMMDDToDate32(False);
|
||||
SELECT YYYYMMDDToDate32(NULL);
|
||||
SELECT YYYYMMDDToDate32(yyyymmdd) FROM (SELECT 19840121 AS yyyymmdd UNION ALL SELECT 20230911 AS yyyymmdd) ORDER BY yyyymmdd; -- non-const
|
@ -969,6 +969,8 @@ Xeon
|
||||
YAML
|
||||
YAMLRegExpTree
|
||||
YYYY
|
||||
YYYYMMDDToDate
|
||||
YYYYMMDDhhmmssToDateTime
|
||||
Yandex
|
||||
Yasm
|
||||
Zabbix
|
||||
|
Loading…
Reference in New Issue
Block a user