Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date time various timezone fixes #9574

Merged
13 changes: 13 additions & 0 deletions dbms/src/Functions/FunctionBinaryArithmetic.h
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,19 @@ class FunctionBinaryArithmetic : public IFunction
type_res = std::make_shared<LeftDataType>(left.getPrecision(), left.getScale());
else if constexpr (IsDataTypeDecimal<RightDataType>)
type_res = std::make_shared<RightDataType>(right.getPrecision(), right.getScale());
else if constexpr (std::is_same_v<ResultDataType, DataTypeDateTime>)
{
// Special case for DateTime: binary OPS should reuse timezone
// of DateTime argument as timezeone of result type.
// NOTE: binary plus/minus are not allowed on DateTime64, and we are not handling it here.

const TimezoneMixin * tz = nullptr;
if constexpr (std::is_same_v<RightDataType, DataTypeDateTime>)
tz = &right;
if constexpr (std::is_same_v<LeftDataType, DataTypeDateTime>)
tz = &left;
type_res = std::make_shared<ResultDataType>(*tz);
}
else
type_res = std::make_shared<ResultDataType>();
return true;
Expand Down
8 changes: 5 additions & 3 deletions dbms/src/Functions/extractTimeZoneFromFunctionArguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ std::string extractTimeZoneNameFromFunctionArguments(const ColumnsWithTypeAndNam
return {};

/// If time zone is attached to an argument of type DateTime.
if (const DataTypeDateTime * type = checkAndGetDataType<DataTypeDateTime>(arguments[datetime_arg_num].type.get()))
if (const auto * type = checkAndGetDataType<DataTypeDateTime>(arguments[datetime_arg_num].type.get()))
return type->getTimeZone().getTimeZone();
if (const DataTypeDateTime64 * type = checkAndGetDataType<DataTypeDateTime64>(arguments[datetime_arg_num].type.get()))
if (const auto * type = checkAndGetDataType<DataTypeDateTime64>(arguments[datetime_arg_num].type.get()))
return type->getTimeZone().getTimeZone();

return {};
Expand All @@ -61,7 +61,9 @@ const DateLUTImpl & extractTimeZoneFromFunctionArguments(Block & block, const Co
return DateLUT::instance();

/// If time zone is attached to an argument of type DateTime.
if (const DataTypeDateTime * type = checkAndGetDataType<DataTypeDateTime>(block.getByPosition(arguments[datetime_arg_num]).type.get()))
if (const auto * type = checkAndGetDataType<DataTypeDateTime>(block.getByPosition(arguments[datetime_arg_num]).type.get()))
return type->getTimeZone();
if (const auto * type = checkAndGetDataType<DataTypeDateTime64>(block.getByPosition(arguments[datetime_arg_num]).type.get()))
return type->getTimeZone();

return DateLUT::instance();
Expand Down
2 changes: 1 addition & 1 deletion dbms/src/Functions/formatDateTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ class FunctionFormatDateTime : public IFunction
size_t result_size = pattern_to_fill.size();

const DateLUTImpl * time_zone_tmp = nullptr;
if (arguments.size() == 3)
if (std::is_same_v<DataType, DataTypeDateTime64> || std::is_same_v<DataType, DataTypeDateTime>)
time_zone_tmp = &extractTimeZoneFromFunctionArguments(block, arguments, 2, 0);
else
time_zone_tmp = &DateLUT::instance();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
2019-09-16 19:20:11.000
2019-05-03 11:25:25.123 2019-05-03 2019-05-02 21:00:00 2019-04-01 1970-01-02 11:25:25 2019-05-03 11:25:00
2019-05-03 11:25:25.123 2019-05-03 2019-05-03 00:00:00 2019-04-01 1970-01-02 11:25:25 2019-05-03 11:25:00
2019-09-16 19:20:11.234
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ subtractHours(N, 1)
subtractMinutes(N, 1)
subtractSeconds(N, 1)
subtractQuarters(N, 1)
CAST(N as DateTime)
CAST(N as DateTime('Europe/Minsk'))
CAST(N as Date)
CAST(N as UInt64)
CAST(N as DateTime64(0))
CAST(N as DateTime64(3))
CAST(N as DateTime64(6))
CAST(N as DateTime64(9))
CAST(N as DateTime64(0, 'Europe/Minsk'))
CAST(N as DateTime64(3, 'Europe/Minsk'))
CAST(N as DateTime64(6, 'Europe/Minsk'))
CAST(N as DateTime64(9, 'Europe/Minsk'))
# Casting our test values to DateTime(12) will cause an overflow and hence will fail the test under UB sanitizer.
# CAST(N as DateTime64(12))
# DateTime64(18) will always fail due to zero precision, but it is Ok to test here:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,10 @@ SELECT subtractQuarters(N, 1)
"DateTime('Europe/Minsk')","2019-06-16 19:20:11"
"DateTime64(3, 'Europe/Minsk')","2019-06-16 19:20:11.234"
------------------------------------------
SELECT CAST(N as DateTime)
"DateTime","2019-09-16 00:00:00"
"DateTime","2019-09-16 19:20:11"
"DateTime","2019-09-16 19:20:11"
SELECT CAST(N as DateTime(\'Europe/Minsk\'))
"DateTime('Europe/Minsk')","2019-09-16 00:00:00"
"DateTime('Europe/Minsk')","2019-09-16 19:20:11"
"DateTime('Europe/Minsk')","2019-09-16 19:20:11"
------------------------------------------
SELECT CAST(N as Date)
"Date","2019-09-16"
Expand All @@ -325,25 +325,25 @@ SELECT CAST(N as UInt64)
"UInt64",1568650811
"UInt64",1568650811
------------------------------------------
SELECT CAST(N as DateTime64(0))
"DateTime64(0)","2019-09-16 00:00:00"
"DateTime64(0)","2019-09-16 19:20:11"
"DateTime64(0)","2019-09-16 19:20:11"
------------------------------------------
SELECT CAST(N as DateTime64(3))
"DateTime64(3)","2019-09-16 00:00:00.000"
"DateTime64(3)","2019-09-16 19:20:11.000"
"DateTime64(3)","2019-09-16 19:20:11.234"
------------------------------------------
SELECT CAST(N as DateTime64(6))
"DateTime64(6)","2019-09-16 00:00:00.000000"
"DateTime64(6)","2019-09-16 19:20:11.000000"
"DateTime64(6)","2019-09-16 19:20:11.234000"
------------------------------------------
SELECT CAST(N as DateTime64(9))
"DateTime64(9)","2019-09-16 00:00:00.000000000"
"DateTime64(9)","2019-09-16 19:20:11.000000000"
"DateTime64(9)","2019-09-16 19:20:11.234000000"
SELECT CAST(N as DateTime64(0, \'Europe/Minsk\'))
"DateTime64(0, 'Europe/Minsk')","2019-09-16 00:00:00"
"DateTime64(0, 'Europe/Minsk')","2019-09-16 19:20:11"
"DateTime64(0, 'Europe/Minsk')","2019-09-16 19:20:11"
------------------------------------------
SELECT CAST(N as DateTime64(3, \'Europe/Minsk\'))
"DateTime64(3, 'Europe/Minsk')","2019-09-16 00:00:00.000"
"DateTime64(3, 'Europe/Minsk')","2019-09-16 19:20:11.000"
"DateTime64(3, 'Europe/Minsk')","2019-09-16 19:20:11.234"
------------------------------------------
SELECT CAST(N as DateTime64(6, \'Europe/Minsk\'))
"DateTime64(6, 'Europe/Minsk')","2019-09-16 00:00:00.000000"
"DateTime64(6, 'Europe/Minsk')","2019-09-16 19:20:11.000000"
"DateTime64(6, 'Europe/Minsk')","2019-09-16 19:20:11.234000"
------------------------------------------
SELECT CAST(N as DateTime64(9, \'Europe/Minsk\'))
"DateTime64(9, 'Europe/Minsk')","2019-09-16 00:00:00.000000000"
"DateTime64(9, 'Europe/Minsk')","2019-09-16 19:20:11.000000000"
"DateTime64(9, 'Europe/Minsk')","2019-09-16 19:20:11.234000000"
------------------------------------------
SELECT formatDateTime(N, \'%C %d %D %e %F %H %I %j %m %M %p %R %S %T %u %V %w %y %Y %%\')
"String","20 16 09/16/19 16 2019-09-16 00 12 259 09 00 AM 00:00 00 00:00:00 1 38 1 19 2019 %"
Expand Down