Remove toExtendedReplated; Add template argument is_extended_result

This commit is contained in:
Roman Vasin 2022-10-19 13:23:21 +00:00
parent 2b163e3bc0
commit c0f18f29bb
10 changed files with 113 additions and 243 deletions

View File

@ -1034,21 +1034,33 @@ struct ToISOWeekImpl
using FactorTransform = ToISOYearImpl;
};
/// Unsigned results (is_extended_result = false) potentially lead to overflows when returning values.
/// This mode is used by SQL functions "toRelative*Num()" which cannot easily be changed due to backward compatibility.
/// According to documentation, these functions merely need to compute the time difference to a deterministic, fixed point in the past.
/// As a future TODO, we should fix their behavior in a backwards-compatible way.
/// See https://github.com/ClickHouse/ClickHouse/issues/41977#issuecomment-1267536814.
template<bool is_extended_result>
struct ToRelativeYearNumImpl
{
static constexpr auto name = "toRelativeYearNum";
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
static inline auto execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toYear(t);
if constexpr (is_extended_result)
return static_cast<Int16>(time_zone.toYear(t));
else
return static_cast<UInt16>(time_zone.toYear(t));
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toYear(static_cast<time_t>(t));
}
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
static inline auto execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toYear(ExtendedDayNum(d));
if constexpr (is_extended_result)
return static_cast<Int16>(time_zone.toYear(ExtendedDayNum(d)));
else
return static_cast<UInt16>(time_zone.toYear(ExtendedDayNum(d)));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
@ -1058,21 +1070,28 @@ struct ToRelativeYearNumImpl
using FactorTransform = ZeroTransform;
};
template<bool is_extended_result>
struct ToRelativeQuarterNumImpl
{
static constexpr auto name = "toRelativeQuarterNum";
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
static inline auto execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeQuarterNum(t);
if constexpr (is_extended_result)
return static_cast<Int32>(time_zone.toRelativeQuarterNum(t));
else
return static_cast<UInt16>(time_zone.toRelativeQuarterNum(t));
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeQuarterNum(static_cast<time_t>(t));
}
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
static inline auto execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeQuarterNum(ExtendedDayNum(d));
if constexpr (is_extended_result)
return static_cast<Int32>(time_zone.toRelativeQuarterNum(ExtendedDayNum(d)));
else
return static_cast<UInt16>(time_zone.toRelativeQuarterNum(ExtendedDayNum(d)));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
@ -1082,21 +1101,28 @@ struct ToRelativeQuarterNumImpl
using FactorTransform = ZeroTransform;
};
template<bool is_extended_result>
struct ToRelativeMonthNumImpl
{
static constexpr auto name = "toRelativeMonthNum";
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
static inline auto execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMonthNum(t);
if constexpr (is_extended_result)
return static_cast<Int32>(time_zone.toRelativeMonthNum(t));
else
return static_cast<UInt16>(time_zone.toRelativeMonthNum(t));
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMonthNum(static_cast<time_t>(t));
}
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
static inline auto execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMonthNum(ExtendedDayNum(d));
if constexpr (is_extended_result)
return static_cast<Int32>(time_zone.toRelativeMonthNum(ExtendedDayNum(d)));
else
return static_cast<UInt16>(time_zone.toRelativeMonthNum(ExtendedDayNum(d)));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
@ -1106,21 +1132,28 @@ struct ToRelativeMonthNumImpl
using FactorTransform = ZeroTransform;
};
template<bool is_extended_result>
struct ToRelativeWeekNumImpl
{
static constexpr auto name = "toRelativeWeekNum";
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
static inline auto execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeWeekNum(t);
if constexpr (is_extended_result)
return static_cast<Int32>(time_zone.toRelativeWeekNum(t));
else
return static_cast<UInt16>(time_zone.toRelativeWeekNum(t));
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeWeekNum(static_cast<time_t>(t));
}
static inline UInt16 execute(Int32 d, const DateLUTImpl & time_zone)
static inline auto execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeWeekNum(ExtendedDayNum(d));
if constexpr (is_extended_result)
return static_cast<Int32>(time_zone.toRelativeWeekNum(ExtendedDayNum(d)));
else
return static_cast<UInt16>(time_zone.toRelativeWeekNum(ExtendedDayNum(d)));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
@ -1130,21 +1163,28 @@ struct ToRelativeWeekNumImpl
using FactorTransform = ZeroTransform;
};
template<bool is_extended_result>
struct ToRelativeDayNumImpl
{
static constexpr auto name = "toRelativeDayNum";
static inline UInt16 execute(Int64 t, const DateLUTImpl & time_zone)
static inline auto execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toDayNum(t);
if constexpr (is_extended_result)
return static_cast<Int64>(time_zone.toDayNum(t));
else
return static_cast<UInt16>(time_zone.toDayNum(t));
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toDayNum(static_cast<time_t>(t));
}
static inline UInt16 execute(Int32 d, const DateLUTImpl &)
static inline auto execute(Int32 d, const DateLUTImpl &)
{
return static_cast<ExtendedDayNum>(d);
if constexpr (is_extended_result)
return static_cast<Int32>(static_cast<ExtendedDayNum>(d));
else
return static_cast<UInt16>(static_cast<ExtendedDayNum>(d));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl &)
{
@ -1154,46 +1194,65 @@ struct ToRelativeDayNumImpl
using FactorTransform = ZeroTransform;
};
template<bool is_extended_result>
struct ToRelativeHourNumImpl
{
static constexpr auto name = "toRelativeHourNum";
static inline UInt32 execute(Int64 t, const DateLUTImpl & time_zone)
static inline auto execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeHourNum(t);
if constexpr (is_extended_result)
return static_cast<Int64>(time_zone.toStableRelativeHourNum(t));
else
return static_cast<UInt32>(time_zone.toRelativeHourNum(t));
}
static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeHourNum(static_cast<time_t>(t));
if constexpr (is_extended_result)
return time_zone.toStableRelativeHourNum(static_cast<time_t>(t));
else
return time_zone.toRelativeHourNum(static_cast<time_t>(t));
}
static inline UInt32 execute(Int32 d, const DateLUTImpl & time_zone)
static inline auto execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeHourNum(ExtendedDayNum(d));
if constexpr (is_extended_result)
return static_cast<Int64>(time_zone.toStableRelativeHourNum(ExtendedDayNum(d)));
else
return static_cast<UInt32>(time_zone.toRelativeHourNum(ExtendedDayNum(d)));
}
static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeHourNum(DayNum(d));
if constexpr (is_extended_result)
return time_zone.toStableRelativeHourNum(DayNum(d));
else
return time_zone.toRelativeHourNum(DayNum(d));
}
using FactorTransform = ZeroTransform;
};
template<bool is_extended_result>
struct ToRelativeMinuteNumImpl
{
static constexpr auto name = "toRelativeMinuteNum";
static inline UInt32 execute(Int64 t, const DateLUTImpl & time_zone)
static inline auto execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMinuteNum(t);
if constexpr (is_extended_result)
return static_cast<Int64>(time_zone.toRelativeMinuteNum(t));
else
return static_cast<UInt32>(time_zone.toRelativeMinuteNum(t));
}
static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMinuteNum(static_cast<time_t>(t));
}
static inline UInt32 execute(Int32 d, const DateLUTImpl & time_zone)
static inline auto execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMinuteNum(ExtendedDayNum(d));
if constexpr (is_extended_result)
return static_cast<Int64>(time_zone.toRelativeMinuteNum(ExtendedDayNum(d)));
else
return static_cast<UInt32>(time_zone.toRelativeMinuteNum(ExtendedDayNum(d)));
}
static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone)
{
@ -1203,6 +1262,7 @@ struct ToRelativeMinuteNumImpl
using FactorTransform = ZeroTransform;
};
template<bool is_extended_result>
struct ToRelativeSecondNumImpl
{
static constexpr auto name = "toRelativeSecondNum";
@ -1215,9 +1275,12 @@ struct ToRelativeSecondNumImpl
{
return t;
}
static inline UInt32 execute(Int32 d, const DateLUTImpl & time_zone)
static inline auto execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.fromDayNum(ExtendedDayNum(d));
if constexpr (is_extended_result)
return static_cast<Int64>(time_zone.fromDayNum(ExtendedDayNum(d)));
else
return static_cast<UInt32>(time_zone.fromDayNum(ExtendedDayNum(d)));
}
static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone)
{

View File

@ -33,199 +33,6 @@ namespace ErrorCodes
namespace
{
struct ToExtendedRelativeYearNumImpl
{
static constexpr auto name = "toExtendedRelativeYearNum";
static inline Int16 execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toYear(t);
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toYear(static_cast<time_t>(t));
}
static inline Int16 execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toYear(ExtendedDayNum(d));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toYear(DayNum(d));
}
using FactorTransform = ZeroTransform;
};
struct ToExtendedRelativeQuarterNumImpl
{
static constexpr auto name = "toExtendedRelativeQuarterNum";
static inline Int32 execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeQuarterNum(t);
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeQuarterNum(static_cast<time_t>(t));
}
static inline Int32 execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeQuarterNum(ExtendedDayNum(d));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeQuarterNum(DayNum(d));
}
using FactorTransform = ZeroTransform;
};
struct ToExtendedRelativeMonthNumImpl
{
static constexpr auto name = "toExtendedRelativeMonthNum";
static inline Int32 execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMonthNum(t);
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMonthNum(static_cast<time_t>(t));
}
static inline Int32 execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMonthNum(ExtendedDayNum(d));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMonthNum(DayNum(d));
}
using FactorTransform = ZeroTransform;
};
struct ToExtendedRelativeWeekNumImpl
{
static constexpr auto name = "toExtendedRelativeWeekNum";
static inline Int32 execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeWeekNum(t);
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeWeekNum(static_cast<time_t>(t));
}
static inline Int32 execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeWeekNum(ExtendedDayNum(d));
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeWeekNum(DayNum(d));
}
using FactorTransform = ZeroTransform;
};
struct ToExtendedRelativeDayNumImpl
{
static constexpr auto name = "toExtendedRelativeDayNum";
static inline Int64 execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toDayNum(t);
}
static inline UInt16 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toDayNum(static_cast<time_t>(t));
}
static inline Int32 execute(Int32 d, const DateLUTImpl &)
{
return static_cast<ExtendedDayNum>(d);
}
static inline UInt16 execute(UInt16 d, const DateLUTImpl &)
{
return static_cast<DayNum>(d);
}
using FactorTransform = ZeroTransform;
};
struct ToExtendedRelativeHourNumImpl
{
static constexpr auto name = "toExtendedRelativeHourNum";
static inline Int64 execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toStableRelativeHourNum(t);
}
static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toStableRelativeHourNum(static_cast<time_t>(t));
}
static inline Int64 execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toStableRelativeHourNum(ExtendedDayNum(d));
}
static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toStableRelativeHourNum(DayNum(d));
}
using FactorTransform = ZeroTransform;
};
struct ToExtendedRelativeMinuteNumImpl
{
static constexpr auto name = "toExtendedRelativeMinuteNum";
static inline Int64 execute(Int64 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMinuteNum(t);
}
static inline UInt32 execute(UInt32 t, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMinuteNum(static_cast<time_t>(t));
}
static inline Int64 execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMinuteNum(ExtendedDayNum(d));
}
static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.toRelativeMinuteNum(DayNum(d));
}
using FactorTransform = ZeroTransform;
};
struct ToExtendedRelativeSecondNumImpl
{
static constexpr auto name = "toExtendedRelativeSecondNum";
static inline Int64 execute(Int64 t, const DateLUTImpl &)
{
return t;
}
static inline UInt32 execute(UInt32 t, const DateLUTImpl &)
{
return t;
}
static inline Int64 execute(Int32 d, const DateLUTImpl & time_zone)
{
return time_zone.fromDayNum(ExtendedDayNum(d));
}
static inline UInt32 execute(UInt16 d, const DateLUTImpl & time_zone)
{
return time_zone.fromDayNum(DayNum(d));
}
using FactorTransform = ZeroTransform;
};
/** dateDiff('unit', t1, t2, [timezone])
* t1 and t2 can be Date or DateTime
*
@ -256,7 +63,7 @@ public:
if (arguments.size() != 3 && arguments.size() != 4)
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH,
"Number of arguments for function {} doesn't match: passed {}, should be 3 or 4",
getName(), toString(arguments.size()));
getName(), arguments.size());
if (!isString(arguments[0]))
throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
@ -305,21 +112,21 @@ public:
const auto & timezone_y = extractTimeZoneFromFunctionArguments(arguments, 3, 2);
if (unit == "year" || unit == "yy" || unit == "yyyy")
dispatchForColumns<ToExtendedRelativeYearNumImpl>(x, y, timezone_x, timezone_y, res->getData());
dispatchForColumns<ToRelativeYearNumImpl<true>>(x, y, timezone_x, timezone_y, res->getData());
else if (unit == "quarter" || unit == "qq" || unit == "q")
dispatchForColumns<ToExtendedRelativeQuarterNumImpl>(x, y, timezone_x, timezone_y, res->getData());
dispatchForColumns<ToRelativeQuarterNumImpl<true>>(x, y, timezone_x, timezone_y, res->getData());
else if (unit == "month" || unit == "mm" || unit == "m")
dispatchForColumns<ToExtendedRelativeMonthNumImpl>(x, y, timezone_x, timezone_y, res->getData());
dispatchForColumns<ToRelativeMonthNumImpl<true>>(x, y, timezone_x, timezone_y, res->getData());
else if (unit == "week" || unit == "wk" || unit == "ww")
dispatchForColumns<ToExtendedRelativeWeekNumImpl>(x, y, timezone_x, timezone_y, res->getData());
dispatchForColumns<ToRelativeWeekNumImpl<true>>(x, y, timezone_x, timezone_y, res->getData());
else if (unit == "day" || unit == "dd" || unit == "d")
dispatchForColumns<ToExtendedRelativeDayNumImpl>(x, y, timezone_x, timezone_y, res->getData());
dispatchForColumns<ToRelativeDayNumImpl<true>>(x, y, timezone_x, timezone_y, res->getData());
else if (unit == "hour" || unit == "hh" || unit == "h")
dispatchForColumns<ToExtendedRelativeHourNumImpl>(x, y, timezone_x, timezone_y, res->getData());
dispatchForColumns<ToRelativeHourNumImpl<true>>(x, y, timezone_x, timezone_y, res->getData());
else if (unit == "minute" || unit == "mi" || unit == "n")
dispatchForColumns<ToExtendedRelativeMinuteNumImpl>(x, y, timezone_x, timezone_y, res->getData());
dispatchForColumns<ToRelativeMinuteNumImpl<true>>(x, y, timezone_x, timezone_y, res->getData());
else if (unit == "second" || unit == "ss" || unit == "s")
dispatchForColumns<ToExtendedRelativeSecondNumImpl>(x, y, timezone_x, timezone_y, res->getData());
dispatchForColumns<ToRelativeSecondNumImpl<true>>(x, y, timezone_x, timezone_y, res->getData());
else
throw Exception(ErrorCodes::BAD_ARGUMENTS,
"Function {} does not support '{}' unit", getName(), unit);

View File

@ -7,7 +7,7 @@
namespace DB
{
using FunctionToRelativeDayNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeDayNumImpl>;
using FunctionToRelativeDayNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeDayNumImpl<false>>;
REGISTER_FUNCTION(ToRelativeDayNum)
{

View File

@ -7,7 +7,7 @@
namespace DB
{
using FunctionToRelativeHourNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeHourNumImpl>;
using FunctionToRelativeHourNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeHourNumImpl<false>>;
REGISTER_FUNCTION(ToRelativeHourNum)
{

View File

@ -7,7 +7,7 @@
namespace DB
{
using FunctionToRelativeMinuteNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeMinuteNumImpl>;
using FunctionToRelativeMinuteNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeMinuteNumImpl<false>>;
REGISTER_FUNCTION(ToRelativeMinuteNum)
{

View File

@ -7,7 +7,7 @@
namespace DB
{
using FunctionToRelativeMonthNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeMonthNumImpl>;
using FunctionToRelativeMonthNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeMonthNumImpl<false>>;
REGISTER_FUNCTION(ToRelativeMonthNum)
{

View File

@ -7,7 +7,7 @@
namespace DB
{
using FunctionToRelativeQuarterNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeQuarterNumImpl>;
using FunctionToRelativeQuarterNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeQuarterNumImpl<false>>;
REGISTER_FUNCTION(ToRelativeQuarterNum)
{

View File

@ -7,7 +7,7 @@
namespace DB
{
using FunctionToRelativeSecondNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeSecondNumImpl>;
using FunctionToRelativeSecondNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeSecondNumImpl<false>>;
REGISTER_FUNCTION(ToRelativeSecondNum)
{

View File

@ -7,7 +7,7 @@
namespace DB
{
using FunctionToRelativeWeekNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeWeekNumImpl>;
using FunctionToRelativeWeekNum = FunctionDateOrDateTimeToSomething<DataTypeUInt32, ToRelativeWeekNumImpl<false>>;
REGISTER_FUNCTION(ToRelativeWeekNum)
{

View File

@ -7,7 +7,7 @@
namespace DB
{
using FunctionToRelativeYearNum = FunctionDateOrDateTimeToSomething<DataTypeUInt16, ToRelativeYearNumImpl>;
using FunctionToRelativeYearNum = FunctionDateOrDateTimeToSomething<DataTypeUInt16, ToRelativeYearNumImpl<false>>;
REGISTER_FUNCTION(ToRelativeYearNum)
{