Merge pull request #46073 from zk-kiger/improve_format_datetime_joda

Add new functionality to the function FormatDataTime
This commit is contained in:
Kruglov Pavel 2023-02-13 13:33:09 +01:00 committed by GitHub
commit 8d15a019a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 180 additions and 9 deletions

View File

@ -710,6 +710,56 @@ struct ToYearImpl
using FactorTransform = ZeroTransform;
};
struct ToWeekYearImpl
{
static constexpr auto name = "toWeekYear";
static constexpr Int8 week_mode = 3;
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toYearWeek(t, week_mode).first;
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toYearWeek(t, week_mode).first;
}
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toYearWeek(ExtendedDayNum(d), week_mode).first;
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toYearWeek(DayNum(d), week_mode).first;
}
using FactorTransform = ZeroTransform;
};
struct ToWeekOfWeekYearImpl
{
static constexpr auto name = "toWeekOfWeekYear";
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toISOWeek(t);
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toISOWeek(t);
}
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toISOWeek(ExtendedDayNum(d));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toISOWeek(DayNum(d));
}
using FactorTransform = ZeroTransform;
};
struct ToQuarterImpl
{
static constexpr auto name = "toQuarter";

View File

@ -527,6 +527,18 @@ private:
return writeNumberWithPadding(dest, year, min_represent_digits);
}
static size_t jodaWeekYear(size_t min_represent_digits, char * dest, Time source, UInt64, UInt32, const DateLUTImpl & timezone)
{
auto week_year = ToWeekYearImpl::execute(source, timezone);
return writeNumberWithPadding(dest, week_year, min_represent_digits);
}
static size_t jodaWeekOfWeekYear(size_t min_represent_digits, char * dest, Time source, UInt64, UInt32, const DateLUTImpl & timezone)
{
auto week_of_weekyear = ToWeekOfWeekYearImpl::execute(source, timezone);
return writeNumberWithPadding(dest, week_of_weekyear, min_represent_digits);
}
static size_t jodaDayOfYear(size_t min_represent_digits, char * dest, Time source, UInt64, UInt32, const DateLUTImpl & timezone)
{
auto day_of_year = ToDayOfYearImpl::execute(source, timezone);
@ -597,6 +609,30 @@ private:
return writeNumberWithPadding(dest, second_of_minute, min_represent_digits);
}
static size_t jodaFractionOfSecond(size_t min_represent_digits, char * dest, Time /*source*/, UInt64 fractional_second, UInt32 scale, const DateLUTImpl & /*timezone*/)
{
if (min_represent_digits > 9)
min_represent_digits = 9;
if (fractional_second == 0)
{
for (UInt64 i = 0; i < min_represent_digits; ++i)
dest[i] = '0';
return min_represent_digits;
}
auto str = toString(fractional_second);
if (min_represent_digits > scale)
{
for (UInt64 i = 0; i < min_represent_digits - scale; ++i)
str += '0';
}
else if (min_represent_digits < scale)
{
str = str.substr(0, min_represent_digits);
}
memcpy(dest, str.data(), str.size());
return min_represent_digits;
}
static size_t jodaTimezone(size_t min_represent_digits, char * dest, Time /*source*/, UInt64, UInt32, const DateLUTImpl & timezone)
{
if (min_represent_digits <= 3)
@ -1147,9 +1183,15 @@ public:
reserve_size += repetitions == 2 ? 2 : std::max(repetitions, 4);
break;
case 'x':
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "format is not supported for WEEK_YEAR");
instructions.emplace_back(std::bind_front(&Action<T>::jodaWeekYear, repetitions));
/// weekyear range [1900, 2299]
reserve_size += std::max(repetitions, 4);
break;
case 'w':
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "format is not supported for WEEK_OF_WEEK_YEAR");
instructions.emplace_back(std::bind_front(&Action<T>::jodaWeekOfWeekYear, repetitions));
/// Week of weekyear range [1, 52]
reserve_size += std::max(repetitions, 2);
break;
case 'e':
instructions.emplace_back(std::bind_front(&Action<T>::jodaDayOfWeek1Based, repetitions));
/// Day of week range [1, 7]
@ -1234,7 +1276,11 @@ public:
reserve_size += std::max(repetitions, 2);
break;
case 'S':
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "format is not supported for FRACTION_OF_SECOND");
/// Default fraction of second is 0
instructions.emplace_back(std::bind_front(&Action<T>::jodaFractionOfSecond, repetitions));
/// 'S' repetitions range [0, 9]
reserve_size += repetitions <= 9 ? repetitions : 9;
break;
case 'z':
if (repetitions <= 3)
throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Short name time zone is not yet supported");

View File

@ -121,3 +121,29 @@ with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) a
ADaaa012 ADaaa012 ADaaa012 ADaaa012
with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) as datetime64, toDate(s) as date, toDate32(s) as date32 SELECT formatDateTimeInJodaSyntax(datetime, 'G\'a\'\'aa\'DDD'), formatDateTimeInJodaSyntax(datetime64, 'G\'a\'\'aa\'DDD'), formatDateTimeInJodaSyntax(date, 'G\'a\'\'aa\'DDD'), formatDateTimeInJodaSyntax(date32, 'G\'a\'\'aa\'DDD');
ADa\'aa012 ADa\'aa012 ADa\'aa012 ADa\'aa012
with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) as datetime64, toDate(s) as date, toDate32(s) as date32 SELECT formatDateTimeInJodaSyntax(datetime, 'x'), formatDateTimeInJodaSyntax(datetime64, 'x'), formatDateTimeInJodaSyntax(date, 'x'), formatDateTimeInJodaSyntax(date32, 'x');
2018 2018 2018 2018
with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) as datetime64, toDate(s) as date, toDate32(s) as date32 SELECT formatDateTimeInJodaSyntax(datetime, 'w'), formatDateTimeInJodaSyntax(datetime64, 'w'), formatDateTimeInJodaSyntax(date, 'w'), formatDateTimeInJodaSyntax(date32, 'w');
2 2 2 2
with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) as datetime64, toDate(s) as date, toDate32(s) as date32 SELECT formatDateTimeInJodaSyntax(datetime, 'S'), formatDateTimeInJodaSyntax(datetime64, 'S'), formatDateTimeInJodaSyntax(date, 'S'), formatDateTimeInJodaSyntax(date32, 'S');
0 0 0 0
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'S');
5
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SS');
55
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSS');
550
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSS');
5500
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSS');
55000
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSSS');
550000
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSSSS');
5500000
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSSSSS');
55000000
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSSSSSS');
550000000
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSSSSSSS');
550000000

View File

@ -62,20 +62,30 @@ with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) a
with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) as datetime64, toDate(s) as date, toDate32(s) as date32 SELECT formatDateTimeInJodaSyntax(datetime, 'G\'\'DDD'), formatDateTimeInJodaSyntax(datetime64, 'G\'\'DDD'), formatDateTimeInJodaSyntax(date, 'G\'\'DDD'), formatDateTimeInJodaSyntax(date32, 'G\'\'DDD');
with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) as datetime64, toDate(s) as date, toDate32(s) as date32 SELECT formatDateTimeInJodaSyntax(datetime, 'G\'aaa\'DDD'), formatDateTimeInJodaSyntax(datetime64, 'G\'aaa\'DDD'), formatDateTimeInJodaSyntax(date, 'G\'aaa\'DDD'), formatDateTimeInJodaSyntax(date32, 'G\'aaa\'DDD');
with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) as datetime64, toDate(s) as date, toDate32(s) as date32 SELECT formatDateTimeInJodaSyntax(datetime, 'G\'a\'\'aa\'DDD'), formatDateTimeInJodaSyntax(datetime64, 'G\'a\'\'aa\'DDD'), formatDateTimeInJodaSyntax(date, 'G\'a\'\'aa\'DDD'), formatDateTimeInJodaSyntax(date32, 'G\'a\'\'aa\'DDD');
with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) as datetime64, toDate(s) as date, toDate32(s) as date32 SELECT formatDateTimeInJodaSyntax(datetime, 'x'), formatDateTimeInJodaSyntax(datetime64, 'x'), formatDateTimeInJodaSyntax(date, 'x'), formatDateTimeInJodaSyntax(date32, 'x');
with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) as datetime64, toDate(s) as date, toDate32(s) as date32 SELECT formatDateTimeInJodaSyntax(datetime, 'w'), formatDateTimeInJodaSyntax(datetime64, 'w'), formatDateTimeInJodaSyntax(date, 'w'), formatDateTimeInJodaSyntax(date32, 'w');
with '2018-01-12 22:33:44' as s, toDateTime(s) as datetime, toDateTime64(s, 6) as datetime64, toDate(s) as date, toDate32(s) as date32 SELECT formatDateTimeInJodaSyntax(datetime, 'S'), formatDateTimeInJodaSyntax(datetime64, 'S'), formatDateTimeInJodaSyntax(date, 'S'), formatDateTimeInJodaSyntax(date32, 'S');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'S');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SS');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSS');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSS');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSS');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSSS');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSSSS');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSSSSS');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSSSSSS');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT formatDateTimeInJodaSyntax(datetime64, 'SSSSSSSSSS');
-- { echoOff }
SELECT formatDateTimeInJodaSyntax(toDateTime('2018-01-12 22:33:44'), 'x'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDateTime('2018-01-12 22:33:44'), 'w'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDateTime('2018-01-12 22:33:44'), 'S'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDateTime('2018-01-12 22:33:44'), 'z'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDateTime('2018-01-12 22:33:44'), 'zz'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDateTime('2018-01-12 22:33:44'), 'zzz'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDateTime('2018-01-12 22:33:44'), 'Z'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDateTime('2018-01-12 22:33:44'), 'b'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDate32('2018-01-12 22:33:44'), 'x'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDate32('2018-01-12 22:33:44'), 'w'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDate32('2018-01-12 22:33:44'), 'S'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDate32('2018-01-12 22:33:44'), 'z'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDate32('2018-01-12 22:33:44'), 'zz'); -- { serverError 48 }
SELECT formatDateTimeInJodaSyntax(toDate32('2018-01-12 22:33:44'), 'zzz'); -- { serverError 48 }

View File

@ -113,3 +113,29 @@ SELECT fromUnixTimestampInJodaSyntax(1669804872, 'sss', 'UTC');
012
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'zzzz', 'UTC');
UTC
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'x', 'UTC');
2022
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'w', 'UTC');
48
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'S', 'UTC');
0
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'SS', 'UTC');
00
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'S', 'UTC');
5
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SS', 'UTC');
55
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSS', 'UTC');
550
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSS', 'UTC');
5500
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSSS', 'UTC');
55000
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSSSS', 'UTC');
550000
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSSSSS', 'UTC');
5500000
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSSSSSS', 'UTC');
55000000
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSSSSSSS', 'UTC');
550000000

View File

@ -56,4 +56,17 @@ SELECT fromUnixTimestampInJodaSyntax(1669804872, 's', 'UTC');
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'ss', 'UTC');
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'sss', 'UTC');
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'zzzz', 'UTC');
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'x', 'UTC');
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'w', 'UTC');
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'S', 'UTC');
SELECT fromUnixTimestampInJodaSyntax(1669804872, 'SS', 'UTC');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'S', 'UTC');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SS', 'UTC');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSS', 'UTC');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSS', 'UTC');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSSS', 'UTC');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSSSS', 'UTC');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSSSSS', 'UTC');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSSSSSS', 'UTC');
with '2018-01-12 22:33:44.55' as s, toDateTime64(s, 6) as datetime64 SELECT fromUnixTimestampInJodaSyntax(datetime64, 'SSSSSSSSS', 'UTC');
-- { echoOff }