diff --git a/dbms/src/Functions/DateTimeTransforms.h b/dbms/src/Functions/DateTimeTransforms.h index f05ab048fcb..1ee552fa630 100644 --- a/dbms/src/Functions/DateTimeTransforms.h +++ b/dbms/src/Functions/DateTimeTransforms.h @@ -47,11 +47,12 @@ struct ToDateImpl { static constexpr auto name = "toDate"; - static inline UInt16 execute(DateTime64::NativeType t, const DateLUTImpl & time_zone) - { - std::cout << "converting DateTime64 t=" << t << " " << name << std::endl; - return UInt16(time_zone.toDayNum(decimalWholePart(DateTime64(t), 9))); - } +// static inline UInt16 execute(DateTime64::NativeType t, const DateLUTImpl & time_zone) +// { +// std::cout << "converting DateTime64 t=" << t << " " << name << std::endl; +// throw Exception("!!!! INVALID TO DATE FROM DATETIME64 implementation", ErrorCodes::NOT_IMPLEMENTED); +// return UInt16(time_zone.toDayNum(decimalWholePart(DateTime64(t), 9))); +// } static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone) { diff --git a/dbms/src/Functions/FunctionsConversion.h b/dbms/src/Functions/FunctionsConversion.h index e7f317adb96..ca83bde2997 100644 --- a/dbms/src/Functions/FunctionsConversion.h +++ b/dbms/src/Functions/FunctionsConversion.h @@ -159,15 +159,11 @@ struct ConvertImpl } }; - /** Conversion of DateTime to Date: throw off time component. */ template struct ConvertImpl : DateTimeTransformImpl {}; -template struct ConvertImpl - : DateTimeTransformImpl {}; - /** Conversion of Date to DateTime: adding 00:00:00 time component. */ @@ -180,18 +176,16 @@ struct ToDateTimeImpl return time_zone.fromDayNum(DayNum(d)); } - static inline UInt32 execute(DateTime64::NativeType d, const DateLUTImpl & time_zone) + // no-op conversion from DateTime to DateTime, used in DateTime64 to DateTime conversion. + static inline UInt32 execute(UInt32 d, const DateLUTImpl & /*time_zone*/) { - return time_zone.fromDayNum(DayNum(d)); + return d; } }; template struct ConvertImpl : DateTimeTransformImpl {}; -template struct ConvertImpl - : DateTimeTransformImpl {}; - /// Implementation of toDate function. template @@ -252,10 +246,34 @@ struct ToDateTime64Transform template struct ConvertImpl : DateTimeTransformImpl {}; - template struct ConvertImpl : DateTimeTransformImpl {}; +/** Conversion of DateTime64 to Date or DateTime: discards fractional part. + */ +template +struct FromDateTime64Transform +{ + static constexpr auto name = "toDateTime64"; + + const DateTime64::NativeType scale_multiplier = 1; + + FromDateTime64Transform(UInt32 scale) + : scale_multiplier(decimalScaleMultiplier(scale)) + {} + + inline auto execute(DateTime64::NativeType dt, const DateLUTImpl & time_zone) const + { + const auto c = decimalSplitWithScaleMultiplier(DateTime64(dt), scale_multiplier); + return Transform::execute(static_cast(c.whole), time_zone); + } +}; + +template struct ConvertImpl + : DateTimeTransformImpl> {}; +template struct ConvertImpl + : DateTimeTransformImpl> {}; + /** Transformation of numbers, dates, datetimes to strings: through formatting. */ @@ -1013,6 +1031,11 @@ private: ConvertImpl::execute(block, arguments, result, input_rows_count, scale); } + else if constexpr (IsDataTypeDateOrDateTime && std::is_same_v) + { + const auto * dt64 = assert_cast(block.getByPosition(arguments[0]).type.get()); + ConvertImpl::execute(block, arguments, result, input_rows_count, dt64->getScale()); + } else ConvertImpl::execute(block, arguments, result, input_rows_count);