From 1a8458000583369ba0cf9260c6f056f5c257c5aa Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Tue, 8 Oct 2019 07:59:38 +0300 Subject: [PATCH] Scaffold for toDateTime64(scale, [timezone]) --- dbms/src/DataTypes/IDataType.h | 8 ++++++ dbms/src/Functions/FunctionsConversion.h | 31 +++++++++++++----------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/dbms/src/DataTypes/IDataType.h b/dbms/src/DataTypes/IDataType.h index 010597d68e7..15ce4cae83d 100644 --- a/dbms/src/DataTypes/IDataType.h +++ b/dbms/src/DataTypes/IDataType.h @@ -565,6 +565,14 @@ inline bool isFloat(const T & data_type) return which.isFloat(); } +template +inline bool isNativeInteger(const T & data_type) +{ + WhichDataType which(data_type); + return which.isNativeInt() || which.isNativeUInt(); +} + + template inline bool isNativeNumber(const T & data_type) { diff --git a/dbms/src/Functions/FunctionsConversion.h b/dbms/src/Functions/FunctionsConversion.h index d994f13240d..8f82aa340c7 100644 --- a/dbms/src/Functions/FunctionsConversion.h +++ b/dbms/src/Functions/FunctionsConversion.h @@ -828,20 +828,21 @@ public: else { UInt8 max_args = 2; -// UInt8 scale = 3; -// if constexpr (std::is_same_v) -// { -// max_args += 1; -// if (arguments.size() == max_args - 1) -// { + UInt32 scale = DataTypeDateTime64::default_scale; + // DateTime64 requires more arguments: scale and timezone. Since timezone is optional, scale should be first. + if constexpr (std::is_same_v) + { + max_args += 1; + if (isNativeInteger(*arguments[max_args - 1].type)) + { + scale = static_cast(arguments[max_args - 1].column->get64(0)); + } + } -// } -// } - /** Optional second argument with time zone is supported: + /** Optional (could be first or second) argument with time zone is supported: * - for functions toDateTime, toUnixTimestamp, toDate; * - for function toString of DateTime argument. */ - if (arguments.size() == max_args) { if (!checkAndGetDataType(arguments[max_args - 1].type.get())) @@ -856,15 +857,15 @@ public: || (std::is_same_v && (WhichDataType(arguments[0].type).isDateTime() || WhichDataType(arguments[0].type).isDateTime64())))) { throw Exception("Number of arguments for function " + getName() + " doesn't match: passed " - + toString(arguments.size()) + ", should be 1.", + + toString(arguments.size()) + ", should be " + std::to_string(max_args) + ".", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); } } if (std::is_same_v) - return std::make_shared(extractTimeZoneNameFromFunctionArguments(arguments, 1, 0)); -// else if (std::is_same_v) -// return std::make_shared(extractTimeZoneNameFromFunctionArguments(arguments, 1, 0)); + return std::make_shared(extractTimeZoneNameFromFunctionArguments(arguments, max_args - 1, 0)); + else if (std::is_same_v) + return std::make_shared(scale, extractTimeZoneNameFromFunctionArguments(arguments, max_args - 1, 0)); else return std::make_shared(); } @@ -1408,6 +1409,8 @@ using FunctionToFloat32 = FunctionConvert>; using FunctionToDate = FunctionConvert>; using FunctionToDateTime = FunctionConvert>; +// TODO (vnemkov): enable and test toDateTime64 function +//using FunctionToDateTime64 = FunctionConvert; using FunctionToUUID = FunctionConvert>; using FunctionToString = FunctionConvert; using FunctionToUnixTimestamp = FunctionConvert>;