From 81ca591b2366fea17ebf2073bce9331e7cf27123 Mon Sep 17 00:00:00 2001 From: Martijn Bakker Date: Sat, 4 May 2019 13:13:59 +0100 Subject: [PATCH] various formatters are working, though there is still an issue with toDate for some reason, maybe the data is unaligned? --- dbms/src/Core/callOnTypeIndex.h | 4 +- dbms/src/DataTypes/DataTypeDateTime.h | 7 +++ dbms/src/Functions/DateTimeTransforms.h | 4 +- .../FunctionDateOrDateTimeToSomething.h | 17 ++++++- dbms/src/Functions/now.cpp | 44 ++++++++++++++++--- .../queries/0_stateless/00921_datetime64.sql | 21 +++++---- 6 files changed, 77 insertions(+), 20 deletions(-) diff --git a/dbms/src/Core/callOnTypeIndex.h b/dbms/src/Core/callOnTypeIndex.h index ac4e555212c..e33a3b76772 100644 --- a/dbms/src/Core/callOnTypeIndex.h +++ b/dbms/src/Core/callOnTypeIndex.h @@ -3,6 +3,7 @@ #include #include +#include namespace DB { @@ -71,6 +72,7 @@ bool callOnBasicType(TypeIndex number, F && f) { case TypeIndex::Date: return f(TypePair()); case TypeIndex::DateTime: return f(TypePair()); + case TypeIndex::DateTime64: return f(TypePair()); default: break; } @@ -145,8 +147,6 @@ inline bool callOnBasicTypes(TypeIndex type_num1, TypeIndex type_num2, F && f) class DataTypeDate; -class DataTypeDateTime; -class DataTypeDateTime64; class DataTypeString; class DataTypeFixedString; class DataTypeUUID; diff --git a/dbms/src/DataTypes/DataTypeDateTime.h b/dbms/src/DataTypes/DataTypeDateTime.h index d9d89af0cbe..980ab08f0d2 100644 --- a/dbms/src/DataTypes/DataTypeDateTime.h +++ b/dbms/src/DataTypes/DataTypeDateTime.h @@ -5,6 +5,13 @@ class DateLUTImpl; + +template class> +struct is_instance : public std::false_type {}; + +template class U> +struct is_instance, U> : public std::true_type {}; + namespace DB { diff --git a/dbms/src/Functions/DateTimeTransforms.h b/dbms/src/Functions/DateTimeTransforms.h index 6890b513602..f43cb76dbc0 100644 --- a/dbms/src/Functions/DateTimeTransforms.h +++ b/dbms/src/Functions/DateTimeTransforms.h @@ -5,7 +5,7 @@ #include #include #include - +#include namespace DB { @@ -47,10 +47,12 @@ struct ToDateImpl static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { + std::cout << "converting UInt32 t=" << t << " " << name << std::endl; return UInt16(time_zone.toDayNum(t)); } static inline UInt16 execute(UInt16 d, const DateLUTImpl &) { + std::cout << "converting UInt16 d=" << d << " " << name << std::endl; return d; } diff --git a/dbms/src/Functions/FunctionDateOrDateTimeToSomething.h b/dbms/src/Functions/FunctionDateOrDateTimeToSomething.h index bb32230a5b1..ad9aed612ee 100644 --- a/dbms/src/Functions/FunctionDateOrDateTimeToSomething.h +++ b/dbms/src/Functions/FunctionDateOrDateTimeToSomething.h @@ -15,6 +15,17 @@ namespace ErrorCodes extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; } +template +struct WithDateTime64Converter : public Transform { + static inline auto execute(DataTypeDateTime64::FieldType t, const DateLUTImpl & time_zone) + { + auto x = DateTime64(t); + auto res = Transform::execute(static_cast(x.split().datetime), time_zone); + std::cout << "calling through datetime64 wrapper v=" << x.get() << "tz= " << time_zone.getTimeZone() << " result=" << res << std::endl; + return res; + } +}; + /// See DateTimeTransforms.h template @@ -67,8 +78,8 @@ public: ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); /// For DateTime, if time zone is specified, attach it to type. - if (std::is_same_v) - return std::make_shared(extractTimeZoneNameFromFunctionArguments(arguments, 1, 0)); + if constexpr (is_instance{}) + return std::make_shared(extractTimeZoneNameFromFunctionArguments(arguments, 1, 0)); else return std::make_shared(); } @@ -85,6 +96,8 @@ public: DateTimeTransformImpl::execute(block, arguments, result, input_rows_count); else if (which.isDateTime()) DateTimeTransformImpl::execute(block, arguments, result, input_rows_count); + else if (which.isDateTime64()) + DateTimeTransformImpl>::execute(block, arguments, result, input_rows_count); else throw Exception("Illegal type " + block.getByPosition(arguments[0]).type->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); diff --git a/dbms/src/Functions/now.cpp b/dbms/src/Functions/now.cpp index 59501d96088..2706d8b849a 100644 --- a/dbms/src/Functions/now.cpp +++ b/dbms/src/Functions/now.cpp @@ -7,12 +7,43 @@ namespace DB { +template +struct TypeGetter; + +template<> +struct TypeGetter { + using Type = DataTypeDateTime64; + static constexpr auto name = "now64"; + + static DateTime64::Type now() { + long int ns; + time_t sec; + timespec spec; + clock_gettime(CLOCK_REALTIME, &spec); + sec = spec.tv_sec; + ns = spec.tv_nsec; + return 1000 * 1000 * 1000 * sec + ns; + } +}; + +template<> +struct TypeGetter { + using Type = DataTypeDateTime; + static constexpr auto name = "now"; + + static UInt64 now() { + return static_cast(time(nullptr)); + } +}; + + /// Get the current time. (It is a constant, it is evaluated once for the entire query.) +template class FunctionNow : public IFunction { public: - static constexpr auto name = "now"; - static FunctionPtr create(const Context &) { return std::make_shared(); } + static constexpr auto name = TypeGetter::name; + static FunctionPtr create(const Context &) { return std::make_shared>(); } String getName() const override { @@ -23,22 +54,21 @@ public: DataTypePtr getReturnTypeImpl(const DataTypes & /*arguments*/) const override { - return std::make_shared(); + return std::make_shared::Type>(); } bool isDeterministic() const override { return false; } void executeImpl(Block & block, const ColumnNumbers &, size_t result, size_t input_rows_count) override { - block.getByPosition(result).column = DataTypeDateTime().createColumnConst( - input_rows_count, - static_cast(time(nullptr))); + block.getByPosition(result).column = typename TypeGetter::Type().createColumnConst(input_rows_count, TypeGetter::now()); } }; void registerFunctionNow(FunctionFactory & factory) { - factory.registerFunction(FunctionFactory::CaseInsensitive); + factory.registerFunction>(FunctionFactory::CaseInsensitive); + factory.registerFunction>(FunctionFactory::CaseInsensitive); } } diff --git a/dbms/tests/queries/0_stateless/00921_datetime64.sql b/dbms/tests/queries/0_stateless/00921_datetime64.sql index 5c96c773171..bce8c6ad2a5 100644 --- a/dbms/tests/queries/0_stateless/00921_datetime64.sql +++ b/dbms/tests/queries/0_stateless/00921_datetime64.sql @@ -1,16 +1,21 @@ USE test; DROP TABLE IF EXISTS A; -DROP TABLE IF EXISTS B; +-- DROP TABLE IF EXISTS B; -CREATE TABLE A(k UInt32, t DateTime64, a Float64) ENGINE = MergeTree() ORDER BY (k, t); -INSERT INTO A(k,t,a) VALUES (2,1,1),(2,50000,3); -INSERT INTO A(k,t,a) VALUES (2,'2019-05-03 00:25:25.123456789',5); +CREATE TABLE A(t DateTime64, a Float64) ENGINE = MergeTree() ORDER BY t; +-- INSERT INTO A(t,a) VALUES (1,1),(50000,3); +INSERT INTO A(t,a) VALUES ('2019-05-03 11:25:25.123456789',5); +-- INSERT INTO A(t,a) VALUES (1556841600034000001,5); +-- INSERT INTO A(t,a) VALUES (now64(),5); -CREATE TABLE B(k UInt32, t DateTime64, b Float64) ENGINE = MergeTree() ORDER BY (k, t); -INSERT INTO B(k,t,b) VALUES (2,40000,3); +-- 1556841600034 -SELECT k, toString(A.t, 'Europe/Moscow'), a, b FROM A ASOF LEFT JOIN B USING(k,t) ORDER BY (k,t); -DROP TABLE B; +-- CREATE TABLE B(k UInt32, t DateTime64, b Float64) ENGINE = MergeTree() ORDER BY (k, t); +-- INSERT INTO B(k,t,b) VALUES (2,40000,3); + +SELECT toString(t, 'UTC'), toDate(t), toStartOfDay(t), toStartOfQuarter(t), toTime(t), toStartOfMinute(t), a FROM A ORDER BY t; + +-- DROP TABLE B; DROP TABLE A;