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

toTimeZone function throw an error when no constant string is provided #48471

Merged
merged 5 commits into from
Apr 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/Functions/FunctionsCodingULID.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ class FunctionULIDStringToDateTime : public IFunction
String timezone;
if (arguments.size() == 2)
{
if (arguments[1].column)
timezone = extractTimeZoneNameFromColumn(*arguments[1].column);
timezone = extractTimeZoneNameFromColumn(arguments[1].column.get(), arguments[1].name);

if (timezone.empty())
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
Expand Down
3 changes: 2 additions & 1 deletion src/Functions/castOrDefault.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ class FunctionCastOrDefaultTyped final : public IFunction
{
if (additional_argument_index < arguments.size())
{
time_zone = extractTimeZoneNameFromColumn(*arguments[additional_argument_index].column);
time_zone = extractTimeZoneNameFromColumn(arguments[additional_argument_index].column.get(),
arguments[additional_argument_index].name);
++additional_argument_index;
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/Functions/extractTimeZoneFromFunctionArguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ namespace ErrorCodes
}


std::string extractTimeZoneNameFromColumn(const IColumn & column)
std::string extractTimeZoneNameFromColumn(const IColumn * column, const String & column_name)
{
const ColumnConst * time_zone_column = checkAndGetColumnConst<ColumnString>(&column);
const ColumnConst * time_zone_column = checkAndGetColumnConst<ColumnString>(column);

if (!time_zone_column)
throw Exception(ErrorCodes::ILLEGAL_COLUMN,
"Illegal column {} of time zone argument of function, must be constant string",
column.getName());
"Illegal column {} of time zone argument of function, must be a constant string",
column_name);

return time_zone_column->getValue<String>();
}
Expand All @@ -33,9 +33,9 @@ std::string extractTimeZoneNameFromColumn(const IColumn & column)
std::string extractTimeZoneNameFromFunctionArguments(const ColumnsWithTypeAndName & arguments, size_t time_zone_arg_num, size_t datetime_arg_num)
{
/// Explicit time zone may be passed in last argument.
if (arguments.size() == time_zone_arg_num + 1 && arguments[time_zone_arg_num].column)
if (arguments.size() == time_zone_arg_num + 1)
{
return extractTimeZoneNameFromColumn(*arguments[time_zone_arg_num].column);
return extractTimeZoneNameFromColumn(arguments[time_zone_arg_num].column.get(), arguments[time_zone_arg_num].name);
}
else
{
Expand All @@ -57,7 +57,7 @@ const DateLUTImpl & extractTimeZoneFromFunctionArguments(const ColumnsWithTypeAn
{
if (arguments.size() == time_zone_arg_num + 1)
{
std::string time_zone = extractTimeZoneNameFromColumn(*arguments[time_zone_arg_num].column);
std::string time_zone = extractTimeZoneNameFromColumn(arguments[time_zone_arg_num].column.get(), arguments[time_zone_arg_num].name);
if (time_zone.empty())
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Provided time zone must be non-empty and be a valid time zone");
return DateLUT::instance(time_zone);
Expand Down
2 changes: 1 addition & 1 deletion src/Functions/extractTimeZoneFromFunctionArguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace DB

class Block;

std::string extractTimeZoneNameFromColumn(const IColumn & column);
std::string extractTimeZoneNameFromColumn(const IColumn * column, const String & column_name);

/// Determine working timezone either from optional argument with time zone name or from time zone in DateTime type of argument.
/// Returns empty string if default time zone should be used.
Expand Down
2 changes: 1 addition & 1 deletion src/Functions/toTimezone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <IO/WriteHelpers.h>
#include <Common/assert_cast.h>


namespace DB
{
namespace ErrorCodes
Expand Down Expand Up @@ -100,6 +99,7 @@ class ToTimeZoneOverloadResolver : public IFunctionOverloadResolver
"Should be DateTime or DateTime64", arguments[0].type->getName(), getName());

String time_zone_name = extractTimeZoneNameFromFunctionArguments(arguments, 1, 0);

if (which_type.isDateTime())
return std::make_shared<DataTypeDateTime>(time_zone_name);

Expand Down
14 changes: 14 additions & 0 deletions tests/queries/0_stateless/00515_enhanced_time_zones.sql
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,17 @@ SELECT toTimeZone(toDateTime('2017-11-05 08:07:47', 'Asia/Istanbul'), 'Asia/Kolk
SELECT toString(toDateTime('2017-11-05 08:07:47', 'Asia/Istanbul'));
SELECT toString(toTimeZone(toDateTime('2017-11-05 08:07:47', 'Asia/Istanbul'), 'Asia/Kolkata'));
SELECT toString(toDateTime('2017-11-05 08:07:47', 'Asia/Istanbul'), 'Asia/Kolkata');

SELECT toTimeZone(dt, tz) FROM (
SELECT toDateTime('2017-11-05 08:07:47', 'Asia/Istanbul') AS dt, arrayJoin(['Asia/Kolkata', 'UTC']) AS tz
); -- { serverError ILLEGAL_COLUMN }
SELECT materialize('Asia/Kolkata') t, toTimeZone(toDateTime('2017-11-05 08:07:47', 'Asia/Istanbul'), t); -- { serverError ILLEGAL_COLUMN }

CREATE TEMPORARY TABLE tmp AS SELECT arrayJoin(['Europe/Istanbul', 'Asia/Istanbul']);
SELECT toTimeZone(now(), (*,).1) FROM tmp; -- { serverError ILLEGAL_COLUMN }
SELECT now((*,).1) FROM tmp; -- { serverError ILLEGAL_COLUMN }
SELECT now64(1, (*,).1) FROM tmp; -- { serverError ILLEGAL_COLUMN }
SELECT toStartOfInterval(now(), INTERVAL 3 HOUR, (*,).1) FROM tmp; -- { serverError ILLEGAL_COLUMN }
SELECT snowflakeToDateTime(toInt64(123), (*,).1) FROM tmp; -- { serverError ILLEGAL_COLUMN }
SELECT toUnixTimestamp(now(), (*,).1) FROM tmp; -- { serverError ILLEGAL_COLUMN }
SELECT toDateTimeOrDefault('2023-04-12 16:43:32', (*,).1, now()) FROM tmp; -- { serverError ILLEGAL_COLUMN }