Fixed converting DateTime64 to DateTime and Date.

This commit is contained in:
Vasily Nemkov 2019-10-31 11:23:55 +03:00
parent be683588a5
commit a6ba05e5d9
2 changed files with 39 additions and 15 deletions

View File

@ -47,11 +47,12 @@ struct ToDateImpl
{ {
static constexpr auto name = "toDate"; static constexpr auto name = "toDate";
static inline UInt16 execute(DateTime64::NativeType t, const DateLUTImpl & time_zone) // static inline UInt16 execute(DateTime64::NativeType t, const DateLUTImpl & time_zone)
{ // {
std::cout << "converting DateTime64 t=" << t << " " << name << std::endl; // std::cout << "converting DateTime64 t=" << t << " " << name << std::endl;
return UInt16(time_zone.toDayNum(decimalWholePart(DateTime64(t), 9))); // 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) static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{ {

View File

@ -159,15 +159,11 @@ struct ConvertImpl
} }
}; };
/** Conversion of DateTime to Date: throw off time component. /** Conversion of DateTime to Date: throw off time component.
*/ */
template <typename Name> struct ConvertImpl<DataTypeDateTime, DataTypeDate, Name> template <typename Name> struct ConvertImpl<DataTypeDateTime, DataTypeDate, Name>
: DateTimeTransformImpl<DataTypeDateTime, DataTypeDate, ToDateImpl> {}; : DateTimeTransformImpl<DataTypeDateTime, DataTypeDate, ToDateImpl> {};
template <typename Name> struct ConvertImpl<DataTypeDateTime64, DataTypeDate, Name>
: DateTimeTransformImpl<DataTypeDateTime64, DataTypeDate, ToDateImpl> {};
/** Conversion of Date to DateTime: adding 00:00:00 time component. /** Conversion of Date to DateTime: adding 00:00:00 time component.
*/ */
@ -180,18 +176,16 @@ struct ToDateTimeImpl
return time_zone.fromDayNum(DayNum(d)); 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 <typename Name> struct ConvertImpl<DataTypeDate, DataTypeDateTime, Name> template <typename Name> struct ConvertImpl<DataTypeDate, DataTypeDateTime, Name>
: DateTimeTransformImpl<DataTypeDate, DataTypeDateTime, ToDateTimeImpl> {}; : DateTimeTransformImpl<DataTypeDate, DataTypeDateTime, ToDateTimeImpl> {};
template <typename Name> struct ConvertImpl<DataTypeDateTime64, DataTypeDateTime, Name>
: DateTimeTransformImpl<DataTypeDateTime64, DataTypeDateTime, ToDateTimeImpl> {};
/// Implementation of toDate function. /// Implementation of toDate function.
template <typename FromType, typename ToType> template <typename FromType, typename ToType>
@ -252,10 +246,34 @@ struct ToDateTime64Transform
template <typename Name> struct ConvertImpl<DataTypeDate, DataTypeDateTime64, Name> template <typename Name> struct ConvertImpl<DataTypeDate, DataTypeDateTime64, Name>
: DateTimeTransformImpl<DataTypeDate, DataTypeDateTime64, ToDateTime64Transform> {}; : DateTimeTransformImpl<DataTypeDate, DataTypeDateTime64, ToDateTime64Transform> {};
template <typename Name> struct ConvertImpl<DataTypeDateTime, DataTypeDateTime64, Name> template <typename Name> struct ConvertImpl<DataTypeDateTime, DataTypeDateTime64, Name>
: DateTimeTransformImpl<DataTypeDateTime, DataTypeDateTime64, ToDateTime64Transform> {}; : DateTimeTransformImpl<DataTypeDateTime, DataTypeDateTime64, ToDateTime64Transform> {};
/** Conversion of DateTime64 to Date or DateTime: discards fractional part.
*/
template <typename Transform>
struct FromDateTime64Transform
{
static constexpr auto name = "toDateTime64";
const DateTime64::NativeType scale_multiplier = 1;
FromDateTime64Transform(UInt32 scale)
: scale_multiplier(decimalScaleMultiplier<DateTime64::NativeType>(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<UInt32>(c.whole), time_zone);
}
};
template <typename Name> struct ConvertImpl<DataTypeDateTime64, DataTypeDate, Name>
: DateTimeTransformImpl<DataTypeDateTime64, DataTypeDate, FromDateTime64Transform<ToDateImpl>> {};
template <typename Name> struct ConvertImpl<DataTypeDateTime64, DataTypeDateTime, Name>
: DateTimeTransformImpl<DataTypeDateTime64, DataTypeDateTime, FromDateTime64Transform<ToDateTimeImpl>> {};
/** Transformation of numbers, dates, datetimes to strings: through formatting. /** Transformation of numbers, dates, datetimes to strings: through formatting.
*/ */
@ -1013,6 +1031,11 @@ private:
ConvertImpl<LeftDataType, RightDataType, Name>::execute(block, arguments, result, input_rows_count, scale); ConvertImpl<LeftDataType, RightDataType, Name>::execute(block, arguments, result, input_rows_count, scale);
} }
else if constexpr (IsDataTypeDateOrDateTime<RightDataType> && std::is_same_v<LeftDataType, DataTypeDateTime64>)
{
const auto * dt64 = assert_cast<const DataTypeDateTime64 *>(block.getByPosition(arguments[0]).type.get());
ConvertImpl<LeftDataType, RightDataType, Name>::execute(block, arguments, result, input_rows_count, dt64->getScale());
}
else else
ConvertImpl<LeftDataType, RightDataType, Name>::execute(block, arguments, result, input_rows_count); ConvertImpl<LeftDataType, RightDataType, Name>::execute(block, arguments, result, input_rows_count);