Merge pull request #33505 from zvonand/issue_14648

Fix fromUnixTimestamp64 functions
This commit is contained in:
alexey-milovidov 2022-01-27 22:54:53 +03:00 committed by GitHub
commit 5a4ad04ae6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 66 additions and 8 deletions

View File

@ -18,6 +18,7 @@ namespace ErrorCodes
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
extern const int DECIMAL_OVERFLOW;
extern const int ILLEGAL_COLUMN;
}
/// Cast DateTime64 to Int64 representation narrowed down (or scaled up) to any scale value defined in Impl.
@ -108,8 +109,8 @@ public:
if (arguments.size() < 1 || arguments.size() > 2)
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, "Function {} takes one or two arguments", name);
if (!typeid_cast<const DataTypeInt64 *>(arguments[0].type.get()))
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "The first argument for function {} must be Int64", name);
if (!isInteger(arguments[0].type))
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "The first argument for function {} must be integer", name);
std::string timezone;
if (arguments.size() == 2)
@ -118,21 +119,48 @@ public:
return std::make_shared<DataTypeDateTime64>(target_scale, timezone);
}
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
template <typename T>
bool executeType(auto & result_column, const ColumnsWithTypeAndName & arguments, size_t input_rows_count) const
{
const auto & src = arguments[0];
const auto & col = *src.column;
auto res_column = ColumnDecimal<DateTime64>::create(input_rows_count, target_scale);
auto & result_data = res_column->getData();
if (!checkAndGetColumn<ColumnVector<T>>(col))
return 0;
const auto & source_data = typeid_cast<const ColumnInt64 &>(col).getData();
auto & result_data = result_column->getData();
const auto & source_data = typeid_cast<const ColumnVector<T> &>(col).getData();
for (size_t i = 0; i < input_rows_count; ++i)
result_data[i] = source_data[i];
return res_column;
return 1;
}
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
{
auto result_column = ColumnDecimal<DateTime64>::create(input_rows_count, target_scale);
if (!((executeType<UInt8>(result_column, arguments, input_rows_count))
|| (executeType<UInt16>(result_column, arguments, input_rows_count))
|| (executeType<UInt32>(result_column, arguments, input_rows_count))
|| (executeType<UInt32>(result_column, arguments, input_rows_count))
|| (executeType<UInt64>(result_column, arguments, input_rows_count))
|| (executeType<Int8>(result_column, arguments, input_rows_count))
|| (executeType<Int16>(result_column, arguments, input_rows_count))
|| (executeType<Int32>(result_column, arguments, input_rows_count))
|| (executeType<Int64>(result_column, arguments, input_rows_count))))
{
throw Exception(ErrorCodes::ILLEGAL_COLUMN,
"Illegal column {} of first argument of function {}",
arguments[0].column->getName(),
getName());
}
return result_column;
}
};
}

View File

@ -3,3 +3,7 @@ UTC 1234567891011 2009-02-13 23:31:31.011 1970-01-15 06:56:07.891011 1970-01-01
Asia/Makassar 1234567891011 2009-02-14 07:31:31.011 1970-01-15 14:56:07.891011 1970-01-01 08:20:34.567891011 DateTime64(9, \'Asia/Makassar\')
non-const column
1234567891011 2009-02-13 23:31:31.011 1970-01-15 06:56:07.891011 1970-01-01 00:20:34.567891011
upper range bound
9904447342 2283-11-10 19:22:22.123 2283-11-10 19:22:22.123456 1925-01-01 00:00:00.586094827
lower range bound
-1420066799 1925-01-01 01:00:01.123 1925-01-01 01:00:01.123456 1925-01-01 01:00:01.123456789

View File

@ -42,4 +42,30 @@ SELECT
i64,
fromUnixTimestamp64Milli(i64, tz),
fromUnixTimestamp64Micro(i64, tz),
fromUnixTimestamp64Nano(i64, tz) as dt64;
fromUnixTimestamp64Nano(i64, tz) as dt64;
SELECT 'upper range bound';
WITH
9904447342 AS timestamp,
CAST(9904447342123 AS Int64) AS milli,
CAST(9904447342123456 AS Int64) AS micro,
CAST(9904447342123456789 AS Int64) AS nano,
'UTC' AS tz
SELECT
timestamp,
fromUnixTimestamp64Milli(milli, tz),
fromUnixTimestamp64Micro(micro, tz),
fromUnixTimestamp64Nano(nano, tz);
SELECT 'lower range bound';
WITH
-1420066799 AS timestamp,
CAST(-1420066799123 AS Int64) AS milli,
CAST(-1420066799123456 AS Int64) AS micro,
CAST(-1420066799123456789 AS Int64) AS nano,
'UTC' AS tz
SELECT
timestamp,
fromUnixTimestamp64Milli(milli, tz),
fromUnixTimestamp64Micro(micro, tz),
fromUnixTimestamp64Nano(nano, tz);