Enable Date32 results for toStartOfYear, toStartOfISOYear, toStartOfQuarter, toStartOfMonth, toMonday, toLastDayOfMonth

This commit is contained in:
Roman Vasin 2022-09-09 13:25:52 +00:00
parent e1833d3cd6
commit b03a0a724f
3 changed files with 110 additions and 21 deletions

View File

@ -144,7 +144,7 @@ struct ToMondayImpl
{
static constexpr auto name = "toMonday";
static inline Int64 execute(Int64 t, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
{
return t < 0 ? 0 : time_zone.toFirstDayNumOfWeek(ExtendedDayNum(
std::min(Int32(time_zone.toDayNum(t)), Int32(DATE_LUT_MAX_DAY_NUM))));
@ -153,7 +153,7 @@ struct ToMondayImpl
{
return time_zone.toFirstDayNumOfWeek(t);
}
static inline Int32 execute(Int32 d, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
{
return d < 0 ? 0 : time_zone.toFirstDayNumOfWeek(ExtendedDayNum(std::min(d, Int32(DATE_LUT_MAX_DAY_NUM))));
}
@ -161,7 +161,15 @@ struct ToMondayImpl
{
return time_zone.toFirstDayNumOfWeek(DayNum(d));
}
static inline Int64 execute_compat(Int64 t, const DateLUTImpl & time_zone)
{
//return time_zone.toFirstDayNumOfWeek(time_zone.toDayNum(t));
return time_zone.toFirstDayNumOfWeek(t);
}
static inline Int32 execute_compat(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfWeek(ExtendedDayNum(d));
}
using FactorTransform = ZeroTransform;
};
@ -169,7 +177,7 @@ struct ToStartOfMonthImpl
{
static constexpr auto name = "toStartOfMonth";
static inline Int64 execute(Int64 t, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
{
return t < 0 ? 0 : time_zone.toFirstDayNumOfMonth(ExtendedDayNum(std::min(Int32(time_zone.toDayNum(t)), Int32(DATE_LUT_MAX_DAY_NUM))));
}
@ -177,7 +185,7 @@ struct ToStartOfMonthImpl
{
return time_zone.toFirstDayNumOfMonth(ExtendedDayNum(time_zone.toDayNum(t)));
}
static inline Int32 execute(Int32 d, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
{
return d < 0 ? 0 : time_zone.toFirstDayNumOfMonth(ExtendedDayNum(std::min(d, Int32(DATE_LUT_MAX_DAY_NUM))));
}
@ -185,6 +193,14 @@ struct ToStartOfMonthImpl
{
return time_zone.toFirstDayNumOfMonth(DayNum(d));
}
static inline Int64 execute_compat(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfMonth(time_zone.toDayNum(t));
}
static inline Int32 execute_compat(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfMonth(ExtendedDayNum(d));
}
using FactorTransform = ZeroTransform;
};
@ -193,7 +209,7 @@ struct ToLastDayOfMonthImpl
{
static constexpr auto name = "toLastDayOfMonth";
static inline Int64 execute(Int64 t, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
{
if (t < 0)
return 0;
@ -205,7 +221,7 @@ struct ToLastDayOfMonthImpl
{
return time_zone.toLastDayNumOfMonth(time_zone.toDayNum(t));
}
static inline Int32 execute(Int32 d, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
{
if (d < 0)
return 0;
@ -218,7 +234,14 @@ struct ToLastDayOfMonthImpl
/// 0xFFF9 is Int value for 2149-05-31 -- the last day where we can actually find LastDayOfMonth. This will also be the return value.
return time_zone.toLastDayNumOfMonth(DayNum(std::min(d, UInt16(0xFFF9))));
}
static inline Int64 execute_compat(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toLastDayNumOfMonth(time_zone.toDayNum(t));
}
static inline Int32 execute_compat(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toLastDayNumOfMonth(ExtendedDayNum(d));
}
using FactorTransform = ZeroTransform;
};
@ -226,7 +249,7 @@ struct ToStartOfQuarterImpl
{
static constexpr auto name = "toStartOfQuarter";
static inline Int64 execute(Int64 t, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
{
return t < 0 ? 0 : time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(std::min<Int64>(Int64(time_zone.toDayNum(t)), Int64(DATE_LUT_MAX_DAY_NUM))));
}
@ -234,7 +257,7 @@ struct ToStartOfQuarterImpl
{
return time_zone.toFirstDayNumOfQuarter(time_zone.toDayNum(t));
}
static inline Int32 execute(Int32 d, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
{
return d < 0 ? 0 : time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(std::min<Int32>(d, Int32(DATE_LUT_MAX_DAY_NUM))));
}
@ -242,7 +265,14 @@ struct ToStartOfQuarterImpl
{
return time_zone.toFirstDayNumOfQuarter(DayNum(d));
}
static inline Int64 execute_compat(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfQuarter(time_zone.toDayNum(t));
}
static inline Int32 execute_compat(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfQuarter(ExtendedDayNum(d));
}
using FactorTransform = ZeroTransform;
};
@ -250,7 +280,7 @@ struct ToStartOfYearImpl
{
static constexpr auto name = "toStartOfYear";
static inline Int64 execute(Int64 t, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
{
return t < 0 ? 0 : time_zone.toFirstDayNumOfYear(ExtendedDayNum(std::min(Int32(time_zone.toDayNum(t)), Int32(DATE_LUT_MAX_DAY_NUM))));
}
@ -258,7 +288,7 @@ struct ToStartOfYearImpl
{
return time_zone.toFirstDayNumOfYear(time_zone.toDayNum(t));
}
static inline Int32 execute(Int32 d, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
{
return d < 0 ? 0 : time_zone.toFirstDayNumOfYear(ExtendedDayNum(std::min(d, Int32(DATE_LUT_MAX_DAY_NUM))));
}
@ -266,6 +296,14 @@ struct ToStartOfYearImpl
{
return time_zone.toFirstDayNumOfYear(DayNum(d));
}
static inline Int64 execute_compat(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfYear(time_zone.toDayNum(t));
}
static inline Int32 execute_compat(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfYear(ExtendedDayNum(d));
}
using FactorTransform = ZeroTransform;
};
@ -891,7 +929,7 @@ struct ToStartOfISOYearImpl
{
static constexpr auto name = "toStartOfISOYear";
static inline Int64 execute(Int64 t, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfISOYear(time_zone.toDayNum(t));
}
@ -899,7 +937,7 @@ struct ToStartOfISOYearImpl
{
return time_zone.toFirstDayNumOfISOYear(time_zone.toDayNum(t));
}
static inline Int32 execute(Int32 d, const DateLUTImpl & time_zone)
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfISOYear(ExtendedDayNum(d));
}
@ -907,6 +945,14 @@ struct ToStartOfISOYearImpl
{
return time_zone.toFirstDayNumOfISOYear(DayNum(d));
}
static inline Int64 execute_compat(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfISOYear(time_zone.toDayNum(t));
}
static inline Int32 execute_compat(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toFirstDayNumOfISOYear(ExtendedDayNum(d));
}
using FactorTransform = ZeroTransform;
};
@ -1201,7 +1247,7 @@ struct ToYYYYMMDDhhmmssImpl
};
template <typename FromType, typename ToType, typename Transform>
template <typename FromType, typename ToType, typename Transform, bool is_compat = false>
struct Transformer
{
template <typename FromTypeVector, typename ToTypeVector>
@ -1211,18 +1257,21 @@ struct Transformer
vec_to.resize(size);
for (size_t i = 0; i < size; ++i)
vec_to[i] = transform.execute(vec_from[i], time_zone);
if constexpr (is_compat)
vec_to[i] = transform.execute_compat(vec_from[i], time_zone);
else
vec_to[i] = transform.execute(vec_from[i], time_zone);
}
};
template <typename FromDataType, typename ToDataType, typename Transform>
template <typename FromDataType, typename ToDataType, typename Transform, bool is_compat = false>
struct DateTimeTransformImpl
{
static ColumnPtr execute(
const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t /*input_rows_count*/, const Transform & transform = {})
{
using Op = Transformer<typename FromDataType::FieldType, typename ToDataType::FieldType, Transform>;
using Op = Transformer<typename FromDataType::FieldType, typename ToDataType::FieldType, Transform, is_compat>;
const ColumnPtr source_col = arguments[0].column;
if (const auto * sources = checkAndGetColumn<typename FromDataType::ColumnType>(source_col.get()))

View File

@ -56,7 +56,7 @@ public:
return DateTimeTransformImpl<DataTypeDate, DataTypeDate, Transform>::execute(arguments, result_type, input_rows_count);
else if (which.isDate32())
if (enable_date32_results)
return DateTimeTransformImpl<DataTypeDate32, DataTypeDate32, Transform>::execute(arguments, result_type, input_rows_count);
return DateTimeTransformImpl<DataTypeDate32, DataTypeDate32, Transform, true>::execute(arguments, result_type, input_rows_count);
else
return DateTimeTransformImpl<DataTypeDate32, DataTypeDate, Transform>::execute(arguments, result_type, input_rows_count);
else if (which.isDateTime())
@ -67,7 +67,7 @@ public:
const TransformDateTime64<Transform> transformer(scale);
if (enable_date32_results)
return DateTimeTransformImpl<DataTypeDateTime64, DataTypeDate32, decltype(transformer)>::execute(arguments, result_type, input_rows_count, transformer);
return DateTimeTransformImpl<DataTypeDateTime64, DataTypeDate32, decltype(transformer), true>::execute(arguments, result_type, input_rows_count, transformer);
else
return DateTimeTransformImpl<DataTypeDateTime64, DataTypeDate, decltype(transformer)>::execute(arguments, result_type, input_rows_count, transformer);
}

View File

@ -87,6 +87,46 @@ public:
return wrapped_transform.execute(t, std::forward<Args>(args)...);
}
template <typename ... Args>
inline auto NO_SANITIZE_UNDEFINED execute_compat(const DateTime64 & t, Args && ... args) const
{
/// Type conversion from float to integer may be required.
/// We are Ok with implementation specific result for out of range and denormals conversion.
if constexpr (TransformHasExecuteOverload_v<DateTime64, decltype(scale_multiplier), Args...>)
{
return wrapped_transform.execute_compat(t, scale_multiplier, std::forward<Args>(args)...);
}
else if constexpr (TransformHasExecuteOverload_v<DecimalUtils::DecimalComponents<DateTime64>, Args...>)
{
auto components = DecimalUtils::splitWithScaleMultiplier(t, scale_multiplier);
const auto result = wrapped_transform.execute_compat(components, std::forward<Args>(args)...);
using ResultType = std::decay_t<decltype(result)>;
if constexpr (std::is_same_v<DecimalUtils::DecimalComponents<DateTime64>, ResultType>)
{
return DecimalUtils::decimalFromComponentsWithMultiplier<DateTime64>(result, scale_multiplier);
}
else
{
return result;
}
}
else
{
const auto components = DecimalUtils::splitWithScaleMultiplier(t, scale_multiplier);
return wrapped_transform.execute_compat(static_cast<Int64>(components.whole), std::forward<Args>(args)...);
}
}
template <typename T, typename ... Args, typename = std::enable_if_t<!std::is_same_v<T, DateTime64>>>
inline auto execute_compat(const T & t, Args && ... args) const
{
return wrapped_transform.execute_compat(t, std::forward<Args>(args)...);
}
private:
DateTime64::NativeType scale_multiplier = 1;
Transform wrapped_transform = {};