From a68b62b42100bfd12060db70ed5d00d4ca46e2b0 Mon Sep 17 00:00:00 2001 From: zclllyybb Date: Wed, 22 Nov 2023 22:08:13 +0800 Subject: [PATCH] [refactor](datatype) Introduce a toolkits for clarify datelike types usage (#26810) --- be/src/util/datetype_cast.hpp | 61 +++- be/src/vec/functions/function_convert_tz.cpp | 13 +- be/src/vec/functions/function_convert_tz.h | 242 +++++------- .../function_date_or_datetime_computation.h | 53 +-- be/src/vec/functions/function_timestamp.cpp | 343 +++++++----------- 5 files changed, 280 insertions(+), 432 deletions(-) diff --git a/be/src/util/datetype_cast.hpp b/be/src/util/datetype_cast.hpp index 316a0df208..495631ea7e 100644 --- a/be/src/util/datetype_cast.hpp +++ b/be/src/util/datetype_cast.hpp @@ -17,67 +17,94 @@ #pragma once +#include + #include "vec/columns/columns_number.h" +#include "vec/core/types.h" #include "vec/data_types/data_type_date.h" +#include "vec/data_types/data_type_date_time.h" #include "vec/data_types/data_type_time_v2.h" #include "vec/runtime/vdatetime_value.h" +/* + * We use these function family to clarify our types of datelike type. for example: + * DataTypeDate -------------------> ColumnDate -----------------------> Int64 + * | TypeToColumn ValueTypeOfColumn + * | TypeToValueType + * VecDateTimeValue + */ namespace doris::date_cast { -// DataTypeDate -> ColumnDate +// e.g. DataTypeDate -> ColumnDate template -struct DatatypeToColumn {}; +struct TypeToColumn {}; template <> -struct DatatypeToColumn { +struct TypeToColumn { using type = vectorized::ColumnDate; }; template <> -struct DatatypeToColumn { +struct TypeToColumn { using type = vectorized::ColumnDateTime; }; template <> -struct DatatypeToColumn { +struct TypeToColumn { using type = vectorized::ColumnDateV2; }; template <> -struct DatatypeToColumn { +struct TypeToColumn { using type = vectorized::ColumnDateTimeV2; }; template -using DateToColumnV = DatatypeToColumn::type; +using TypeToColumnV = TypeToColumn::type; -// DateTypeDate -> VecDateTimeValue +// e.g. DateTypeDate -> VecDateTimeValue template -struct DateToDateValueType {}; +struct TypeToValueType {}; template <> -struct DateToDateValueType { +struct TypeToValueType { using type = VecDateTimeValue; }; template <> -struct DateToDateValueType { +struct TypeToValueType { using type = VecDateTimeValue; }; template <> -struct DateToDateValueType { +struct TypeToValueType { using type = DateV2Value; }; template <> -struct DateToDateValueType { +struct TypeToValueType { using type = DateV2Value; }; template -using DateToDateValueTypeV = DateToDateValueType::type; +using TypeToValueTypeV = TypeToValueType::type; -// ColumnDate -> Int64 (see also columns_number.h) +// e.g. ColumnDate -> Int64 (see also columns_number.h) template requires requires { typename ColumnType::value_type; } -struct ValueTypeOfDateColumn { +struct ValueTypeOfColumn { using type = ColumnType::value_type; }; template -using ValueTypeOfDateColumnV = ValueTypeOfDateColumn::type; +using ValueTypeOfColumnV = ValueTypeOfColumn::type; + +// check V1 or V2 for both DateType/ColumnType/ValueType/ValueOfColumnType +template +constexpr bool IsV1() { + return static_cast(std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v); +} + +template +constexpr bool IsV2() { + return !IsV1(); +} } // namespace doris::date_cast diff --git a/be/src/vec/functions/function_convert_tz.cpp b/be/src/vec/functions/function_convert_tz.cpp index 6f83f1bf1a..f5e66f9b55 100644 --- a/be/src/vec/functions/function_convert_tz.cpp +++ b/be/src/vec/functions/function_convert_tz.cpp @@ -24,15 +24,10 @@ namespace doris::vectorized { void register_function_convert_tz(SimpleFunctionFactory& factory) { - factory.register_function< - FunctionConvertTZ, DataTypeDateTimeV2>, - DataTypeDateTimeV2>>(); - factory.register_function, - DataTypeDateTime>>(); - factory.register_function, DataTypeDateV2>, DataTypeDateV2>>(); - factory.register_function< - FunctionConvertTZ, DataTypeDate>>(); + factory.register_function>(); + factory.register_function>(); + factory.register_function>(); + factory.register_function>(); } } // namespace doris::vectorized diff --git a/be/src/vec/functions/function_convert_tz.h b/be/src/vec/functions/function_convert_tz.h index 6231879f97..c8957122ab 100644 --- a/be/src/vec/functions/function_convert_tz.h +++ b/be/src/vec/functions/function_convert_tz.h @@ -33,6 +33,7 @@ #include "runtime/runtime_state.h" #include "udf/udf.h" #include "util/binary_cast.hpp" +#include "util/datetype_cast.hpp" #include "util/timezone_utils.h" #include "vec/aggregate_functions/aggregate_function.h" #include "vec/columns/column.h" @@ -57,23 +58,92 @@ #include "vec/runtime/vdatetime_value.h" namespace doris::vectorized { -template -struct ConvertTZImpl { - using ColumnType = std::conditional_t< - std::is_same_v, DateValueType>, ColumnDateV2, - std::conditional_t, DateValueType>, - ColumnDateTimeV2, ColumnDateTime>>; - using NativeType = std::conditional_t< - std::is_same_v, DateValueType>, UInt32, - std::conditional_t, DateValueType>, - UInt64, Int64>>; - using ReturnDateType = std::conditional_t, - VecDateTimeValue, DateV2Value>; - using ReturnNativeType = - std::conditional_t, Int64, UInt64>; - using ReturnColumnType = std::conditional_t, - ColumnDateTime, ColumnDateTimeV2>; +template +class FunctionConvertTZ : public IFunction { + using DateValueType = date_cast::TypeToValueTypeV; + using ColumnType = date_cast::TypeToColumnV; + using NativeType = date_cast::ValueTypeOfColumnV; + constexpr static bool is_v1 = date_cast::IsV1(); + using ReturnDateType = std::conditional_t; + using ReturnDateValueType = date_cast::TypeToValueTypeV; + using ReturnColumnType = date_cast::TypeToColumnV; + using ReturnNativeType = date_cast::ValueTypeOfColumnV; +public: + static constexpr auto name = "convert_tz"; + + static FunctionPtr create() { return std::make_shared(); } + + String get_name() const override { return name; } + + size_t get_number_of_arguments() const override { return 3; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + if constexpr (is_v1) { + return make_nullable(std::make_shared()); + } else { + return make_nullable(std::make_shared()); + } + } + + bool is_variadic() const override { return true; } + + DataTypes get_variadic_argument_types_impl() const override { + return {std::make_shared(), std::make_shared(), + std::make_shared()}; + } + + bool use_default_implementation_for_nulls() const override { return false; } + + Status close(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { + return Status::OK(); + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) const override { + auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0); + + bool col_const[3]; + ColumnPtr argument_columns[3]; + for (int i = 0; i < 3; ++i) { + col_const[i] = is_column_const(*block.get_by_position(arguments[i]).column); + } + argument_columns[0] = col_const[0] ? static_cast( + *block.get_by_position(arguments[0]).column) + .convert_to_full_column() + : block.get_by_position(arguments[0]).column; + + default_preprocess_parameter_columns(argument_columns, col_const, {1, 2}, block, arguments); + + for (int i = 0; i < 3; i++) { + check_set_nullable(argument_columns[i], result_null_map_column, col_const[i]); + } + + if (col_const[1] && col_const[2]) { + auto result_column = ColumnType::create(); + execute_tz_const(context, assert_cast(argument_columns[0].get()), + assert_cast(argument_columns[1].get()), + assert_cast(argument_columns[2].get()), + assert_cast(result_column.get()), + assert_cast(result_null_map_column.get())->get_data(), + input_rows_count); + block.get_by_position(result).column = ColumnNullable::create( + std::move(result_column), std::move(result_null_map_column)); + } else { + auto result_column = ColumnType::create(); + execute(context, assert_cast(argument_columns[0].get()), + assert_cast(argument_columns[1].get()), + assert_cast(argument_columns[2].get()), + assert_cast(result_column.get()), + assert_cast(result_null_map_column.get())->get_data(), + input_rows_count); + block.get_by_position(result).column = ColumnNullable::create( + std::move(result_column), std::move(result_null_map_column)); + } //if const + return Status::OK(); + } + +private: static void execute(FunctionContext* context, const ColumnType* date_column, const ColumnString* from_tz_column, const ColumnString* to_tz_column, ReturnColumnType* result_column, NullMap& result_null_map, @@ -110,7 +180,7 @@ struct ConvertTZImpl { DateValueType ts_value = binary_cast(date_column->get_element(index_now)); cctz::time_zone from_tz {}, to_tz {}; - ReturnDateType ts_value2; + ReturnDateValueType ts_value2; if (!TimezoneUtils::find_cctz_time_zone(from_tz_name, from_tz)) { result_null_map[index_now] = true; @@ -124,7 +194,7 @@ struct ConvertTZImpl { return; } - if constexpr (std::is_same_v>) { + if constexpr (std::is_same_v) { std::pair timestamp; if (!ts_value.unix_timestamp(×tamp, from_tz)) { result_null_map[index_now] = true; @@ -152,141 +222,7 @@ struct ConvertTZImpl { } } - result_column->insert(binary_cast(ts_value2)); - } - - static DataTypes get_variadic_argument_types() { - return {std::make_shared(), std::make_shared(), - std::make_shared()}; - } -}; - -template -class FunctionConvertTZ : public IFunction { -public: - static constexpr auto name = "convert_tz"; - - static FunctionPtr create() { return std::make_shared(); } - - String get_name() const override { return name; } - - size_t get_number_of_arguments() const override { return 3; } - - DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { - if constexpr (std::is_same_v || - std::is_same_v) { - return make_nullable(std::make_shared()); - } else { - return make_nullable(std::make_shared()); - } - } - - bool is_variadic() const override { return true; } - - DataTypes get_variadic_argument_types_impl() const override { - return Transform::get_variadic_argument_types(); - } - - bool use_default_implementation_for_nulls() const override { return false; } - - Status close(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { - return Status::OK(); - } - - Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, - size_t result, size_t input_rows_count) const override { - auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0); - - bool col_const[3]; - ColumnPtr argument_columns[3]; - for (int i = 0; i < 3; ++i) { - col_const[i] = is_column_const(*block.get_by_position(arguments[i]).column); - } - argument_columns[0] = col_const[0] ? static_cast( - *block.get_by_position(arguments[0]).column) - .convert_to_full_column() - : block.get_by_position(arguments[0]).column; - - default_preprocess_parameter_columns(argument_columns, col_const, {1, 2}, block, arguments); - - for (int i = 0; i < 3; i++) { - check_set_nullable(argument_columns[i], result_null_map_column, col_const[i]); - } - - if (col_const[1] && col_const[2]) { - if constexpr (std::is_same_v || - std::is_same_v) { - auto result_column = ColumnDateTime::create(); - Transform::execute_tz_const( - context, assert_cast(argument_columns[0].get()), - assert_cast(argument_columns[1].get()), - assert_cast(argument_columns[2].get()), - assert_cast(result_column.get()), - assert_cast(result_null_map_column.get())->get_data(), - input_rows_count); - block.get_by_position(result).column = ColumnNullable::create( - std::move(result_column), std::move(result_null_map_column)); - } else if constexpr (std::is_same_v) { - auto result_column = ColumnDateTimeV2::create(); - Transform::execute_tz_const( - context, assert_cast(argument_columns[0].get()), - assert_cast(argument_columns[1].get()), - assert_cast(argument_columns[2].get()), - assert_cast(result_column.get()), - assert_cast(result_null_map_column.get())->get_data(), - input_rows_count); - block.get_by_position(result).column = ColumnNullable::create( - std::move(result_column), std::move(result_null_map_column)); - } else { - auto result_column = ColumnDateTimeV2::create(); - Transform::execute_tz_const( - context, assert_cast(argument_columns[0].get()), - assert_cast(argument_columns[1].get()), - assert_cast(argument_columns[2].get()), - assert_cast(result_column.get()), - assert_cast(result_null_map_column.get())->get_data(), - input_rows_count); - block.get_by_position(result).column = ColumnNullable::create( - std::move(result_column), std::move(result_null_map_column)); - } - } else { - if constexpr (std::is_same_v || - std::is_same_v) { - auto result_column = ColumnDateTime::create(); - Transform::execute( - context, assert_cast(argument_columns[0].get()), - assert_cast(argument_columns[1].get()), - assert_cast(argument_columns[2].get()), - assert_cast(result_column.get()), - assert_cast(result_null_map_column.get())->get_data(), - input_rows_count); - block.get_by_position(result).column = ColumnNullable::create( - std::move(result_column), std::move(result_null_map_column)); - } else if constexpr (std::is_same_v) { - auto result_column = ColumnDateTimeV2::create(); - Transform::execute( - context, assert_cast(argument_columns[0].get()), - assert_cast(argument_columns[1].get()), - assert_cast(argument_columns[2].get()), - assert_cast(result_column.get()), - assert_cast(result_null_map_column.get())->get_data(), - input_rows_count); - block.get_by_position(result).column = ColumnNullable::create( - std::move(result_column), std::move(result_null_map_column)); - } else { - auto result_column = ColumnDateTimeV2::create(); - Transform::execute( - context, assert_cast(argument_columns[0].get()), - assert_cast(argument_columns[1].get()), - assert_cast(argument_columns[2].get()), - assert_cast(result_column.get()), - assert_cast(result_null_map_column.get())->get_data(), - input_rows_count); - block.get_by_position(result).column = ColumnNullable::create( - std::move(result_column), std::move(result_null_map_column)); - } //if datatype - } //if const - return Status::OK(); + result_column->insert(binary_cast(ts_value2)); } }; diff --git a/be/src/vec/functions/function_date_or_datetime_computation.h b/be/src/vec/functions/function_date_or_datetime_computation.h index 3d0e0a8fd4..87d3fa8268 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation.h +++ b/be/src/vec/functions/function_date_or_datetime_computation.h @@ -35,6 +35,7 @@ #include "runtime/runtime_state.h" #include "udf/udf.h" #include "util/binary_cast.hpp" +#include "util/datetype_cast.hpp" #include "vec/aggregate_functions/aggregate_function.h" #include "vec/columns/column.h" #include "vec/columns/column_const.h" @@ -86,9 +87,7 @@ extern ResultType date_time_add(const Arg& t, Int64 delta, bool& is_null) { template \ struct CLASS { \ using ReturnType = std::conditional_t< \ - std::is_same_v || \ - std::is_same_v, \ - DataTypeDateTime, \ + date_cast::IsV1(), DataTypeDateTime, \ std::conditional_t< \ std::is_same_v, \ std::conditional_t, \ DataTypeDateTimeV2>>; \ - using ReturnNativeType = std::conditional_t< \ - std::is_same_v || \ - std::is_same_v, \ - Int64, \ - std::conditional_t< \ - std::is_same_v, \ - std::conditional_t, \ - UInt64>>; \ - using InputNativeType = std::conditional_t< \ - std::is_same_v || \ - std::is_same_v, \ - Int64, \ - std::conditional_t, UInt32, UInt64>>; \ + using ReturnNativeType = \ + date_cast::ValueTypeOfColumnV>; \ + using InputNativeType = date_cast::ValueTypeOfColumnV>; \ static constexpr auto name = #NAME; \ static constexpr auto is_nullable = true; \ static inline ReturnNativeType execute(const InputNativeType& t, Int64 delta, \ @@ -293,31 +278,19 @@ DECLARE_DATE_FUNCTIONS(DateDiffImpl, datediff, DataTypeInt32, (ts0.daynr() - ts1 // Expands to template struct TimeDiffImpl { - using ArgType1 = std ::conditional_t< - std ::is_same_v, UInt32, - std ::conditional_t, UInt64, Int64>>; - using ArgType2 = std ::conditional_t< - std ::is_same_v, UInt32, - std ::conditional_t, UInt64, Int64>>; - using DateValueType1 = std ::conditional_t< - std ::is_same_v, DateV2Value, - std ::conditional_t, - DateV2Value, VecDateTimeValue>>; - using DateValueType2 = std ::conditional_t< - std ::is_same_v, DateV2Value, - std ::conditional_t, - DateV2Value, VecDateTimeValue>>; - static constexpr bool UsingTimev2 = std::is_same_v || - std::is_same_v || - std::is_same_v || - std::is_same_v; + using DateValueType1 = date_cast::TypeToValueTypeV; + using DateValueType2 = date_cast::TypeToValueTypeV; + using ArgType1 = date_cast::ValueTypeOfColumnV>; + using ArgType2 = date_cast::ValueTypeOfColumnV>; + static constexpr bool UsingTimev2 = + date_cast::IsV2() || date_cast::IsV2(); using ReturnType = DataTypeTimeV2; static constexpr auto name = "timediff"; static constexpr auto is_nullable = false; - static inline ReturnType ::FieldType execute(const ArgType1& t0, const ArgType2& t1, - bool& is_null) { + static inline ReturnType::FieldType execute(const ArgType1& t0, const ArgType2& t1, + bool& is_null) { const auto& ts0 = reinterpret_cast(t0); const auto& ts1 = reinterpret_cast(t1); is_null = !ts0.is_valid_date() || !ts1.is_valid_date(); diff --git a/be/src/vec/functions/function_timestamp.cpp b/be/src/vec/functions/function_timestamp.cpp index ab26170217..c4c555cf9a 100644 --- a/be/src/vec/functions/function_timestamp.cpp +++ b/be/src/vec/functions/function_timestamp.cpp @@ -128,42 +128,42 @@ struct StrToDate { ColumnPtr res = nullptr; WhichDataType which(remove_nullable(block.get_by_position(result).type)); if (which.is_date_time_v2()) { - res = ColumnVector::create(); + res = ColumnDateTimeV2::create(); if (col_const[1]) { - execute_impl_const_right, UInt64>( + execute_impl_const_right( context, ldata, loffsets, specific_char_column->get_data_at(0), - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } else { - execute_impl, UInt64>( + execute_impl( context, ldata, loffsets, rdata, roffsets, - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } } else if (which.is_date_v2()) { - res = ColumnVector::create(); + res = ColumnDateV2::create(); if (col_const[1]) { - execute_impl_const_right, UInt32>( + execute_impl_const_right( context, ldata, loffsets, specific_char_column->get_data_at(0), - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } else { - execute_impl, UInt32>( + execute_impl( context, ldata, loffsets, rdata, roffsets, - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } } else { - res = ColumnVector::create(); + res = ColumnDateTime::create(); if (col_const[1]) { - execute_impl_const_right( + execute_impl_const_right( context, ldata, loffsets, specific_char_column->get_data_at(0), - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } else { - execute_impl( + execute_impl( context, ldata, loffsets, rdata, roffsets, - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } } @@ -173,7 +173,9 @@ struct StrToDate { } private: - template + template , + typename NativeType = date_cast::TypeToColumnV> static void execute_impl(FunctionContext* context, const ColumnString::Chars& ldata, const ColumnString::Offsets& loffsets, const ColumnString::Chars& rdata, @@ -193,7 +195,9 @@ private: i); } } - template + template , + typename NativeType = date_cast::TypeToColumnV> static void execute_impl_const_right(FunctionContext* context, const ColumnString::Chars& ldata, const ColumnString::Offsets& loffsets, const StringRef& rdata, PaddedPODArray& res, @@ -259,60 +263,60 @@ struct MakeDateImpl { ColumnPtr res = nullptr; WhichDataType which(remove_nullable(block.get_by_position(result).type)); if (which.is_date_v2()) { - res = ColumnVector::create(); + res = ColumnDateV2::create(); if (col_const[1]) { - execute_impl_right_const, UInt32>( + execute_impl_right_const( static_cast*>(argument_columns[0].get()) ->get_data(), static_cast*>(argument_columns[1].get()) ->get_element(0), - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } else { - execute_impl, UInt32>( + execute_impl( static_cast*>(argument_columns[0].get()) ->get_data(), static_cast*>(argument_columns[1].get()) ->get_data(), - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } } else if (which.is_date_time_v2()) { - res = ColumnVector::create(); + res = ColumnDateTimeV2::create(); if (col_const[1]) { - execute_impl_right_const, UInt64>( + execute_impl_right_const( static_cast*>(argument_columns[0].get()) ->get_data(), static_cast*>(argument_columns[1].get()) ->get_element(0), - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } else { - execute_impl, UInt64>( + execute_impl( static_cast*>(argument_columns[0].get()) ->get_data(), static_cast*>(argument_columns[1].get()) ->get_data(), - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } } else { - res = ColumnVector::create(); + res = ColumnDateTime::create(); if (col_const[1]) { - execute_impl_right_const( + execute_impl_right_const( static_cast*>(argument_columns[0].get()) ->get_data(), static_cast*>(argument_columns[1].get()) ->get_element(0), - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } else { - execute_impl( + execute_impl( static_cast*>(argument_columns[0].get()) ->get_data(), static_cast*>(argument_columns[1].get()) ->get_data(), - static_cast*>(res->assume_mutable().get())->get_data(), + static_cast(res->assume_mutable().get())->get_data(), null_map->get_data()); } } @@ -322,7 +326,8 @@ struct MakeDateImpl { } private: - template + template , + typename ReturnType = date_cast::TypeToColumnV> static void execute_impl(const PaddedPODArray& ldata, const PaddedPODArray& rdata, PaddedPODArray& res, NullMap& null_map) { auto len = ldata.size(); @@ -338,7 +343,8 @@ private: _execute_inner_loop(l, r, res, null_map, i); } } - template + template , + typename ReturnType = date_cast::TypeToColumnV> static void execute_impl_right_const(const PaddedPODArray& ldata, Int32 rdata, PaddedPODArray& res, NullMap& null_map) { auto len = ldata.size(); @@ -389,9 +395,9 @@ template struct DateTrunc { static constexpr auto name = "date_trunc"; - using ColumnType = date_cast::DateToColumnV; - using DateValueType = date_cast::DateToDateValueTypeV; - using ArgType = date_cast::ValueTypeOfDateColumnV; + using ColumnType = date_cast::TypeToColumnV; + using DateValueType = date_cast::TypeToValueTypeV; + using ArgType = date_cast::ValueTypeOfColumnV; static bool is_variadic() { return true; } @@ -501,14 +507,12 @@ public: res_column = ColumnInt64::create(input_rows_count); execute_straight( input_rows_count, null_map->get_data(), data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); + static_cast(res_column->assume_mutable().get())->get_data()); } else { - res_column = ColumnVector::create(input_rows_count); + res_column = ColumnDateV2::create(input_rows_count); execute_straight, UInt32>( input_rows_count, null_map->get_data(), data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); + static_cast(res_column->assume_mutable().get())->get_data()); } block.replace_by_position( @@ -824,7 +828,7 @@ public: continue; } StringRef source = column_data.get_data_at(i); - const DateV2Value& dt = + const auto& dt = reinterpret_cast&>(*source.data); int64_t timestamp {0}; if (!dt.unix_timestamp(×tamp, time_zone)) { @@ -865,8 +869,7 @@ public: is_nullable = is_nullable || it.type->is_nullable(); } - if constexpr (std::is_same_v || - std::is_same_v) { + if constexpr (date_cast::IsV1()) { return make_nullable(std::make_shared()); } else { return is_nullable ? make_nullable(std::make_shared()) @@ -875,15 +878,7 @@ public: } DataTypes get_variadic_argument_types_impl() const override { - if constexpr (std::is_same_v) { - return {std::make_shared()}; - } else if constexpr (std::is_same_v) { - return {std::make_shared()}; - } else if constexpr (std::is_same_v) { - return {std::make_shared()}; - } else { - return {std::make_shared()}; - } + return {std::make_shared()}; } Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, @@ -896,6 +891,14 @@ template struct LastDayImpl { static constexpr auto name = "last_day"; + using DateValueType = date_cast::TypeToValueTypeV; + using ColumnType = date_cast::TypeToColumnV; + using NativeType = date_cast::ValueTypeOfColumnV; + using ResultType = + std::conditional_t(), DataTypeDate, DataTypeDateV2>; + using ResultColumnType = date_cast::TypeToColumnV; + using ResultNativeType = date_cast::ValueTypeOfColumnV; + static Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result, size_t input_rows_count) { @@ -904,31 +907,11 @@ struct LastDayImpl { ColumnPtr argument_column = remove_nullable(block.get_by_position(arguments[0]).column); if (is_nullable) { auto null_map = ColumnUInt8::create(input_rows_count, 0); - if constexpr (std::is_same_v || - std::is_same_v) { - auto data_col = assert_cast*>(argument_column.get()); - res_column = ColumnInt64::create(input_rows_count); - execute_straight( - input_rows_count, null_map->get_data(), data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); - - } else if constexpr (std::is_same_v) { - auto data_col = assert_cast*>(argument_column.get()); - res_column = ColumnVector::create(input_rows_count); - execute_straight, UInt32, UInt32>( - input_rows_count, null_map->get_data(), data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); - - } else if constexpr (std::is_same_v) { - auto data_col = assert_cast*>(argument_column.get()); - res_column = ColumnVector::create(input_rows_count); - execute_straight, UInt32, UInt64>( - input_rows_count, null_map->get_data(), data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); - } + auto data_col = assert_cast(argument_column.get()); + res_column = ResultColumnType::create(input_rows_count); + execute_straight( + input_rows_count, null_map->get_data(), data_col->get_data(), + static_cast(res_column->assume_mutable().get())->get_data()); if (const auto* nullable_col = check_and_get_column( block.get_by_position(arguments[0]).column.get())) { @@ -941,63 +924,38 @@ struct LastDayImpl { block.replace_by_position(result, ColumnNullable::create(res_column, std::move(null_map))); } else { - if constexpr (std::is_same_v) { - auto data_col = assert_cast*>(argument_column.get()); - res_column = ColumnVector::create(input_rows_count); - execute_straight, UInt32, UInt32>( - input_rows_count, data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); - - } else if constexpr (std::is_same_v) { - auto data_col = assert_cast*>(argument_column.get()); - res_column = ColumnVector::create(input_rows_count); - execute_straight, UInt32, UInt64>( - input_rows_count, data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); + if constexpr (date_cast::IsV2()) { + auto data_col = assert_cast(argument_column.get()); + res_column = ResultColumnType::create(input_rows_count); + execute_straight(input_rows_count, data_col->get_data(), + static_cast(res_column->assume_mutable().get()) + ->get_data()); + block.replace_by_position(result, std::move(res_column)); } - block.replace_by_position(result, std::move(res_column)); } return Status::OK(); } - template static void execute_straight(size_t input_rows_count, NullMap& null_map, - const PaddedPODArray& data_col, - PaddedPODArray& res_data) { + const PaddedPODArray& data_col, + PaddedPODArray& res_data) { for (int i = 0; i < input_rows_count; i++) { - if constexpr (std::is_same_v) { - const auto& cur_data = data_col[i]; - auto ts_value = binary_cast(cur_data); - if (!ts_value.is_valid_date()) { - null_map[i] = 1; - continue; - } - int day = get_last_month_day(ts_value.year(), ts_value.month()); + const auto& cur_data = data_col[i]; + auto ts_value = binary_cast(cur_data); + if (!ts_value.is_valid_date()) { + null_map[i] = 1; + continue; + } + int day = get_last_month_day(ts_value.year(), ts_value.month()); + + if constexpr (date_cast::IsV1()) { ts_value.set_time(ts_value.year(), ts_value.month(), day, 0, 0, 0); ts_value.set_type(TIME_DATE); res_data[i] = binary_cast(ts_value); - - } else if constexpr (std::is_same_v>) { - const auto& cur_data = data_col[i]; - auto ts_value = binary_cast(cur_data); - if (!ts_value.is_valid_date()) { - null_map[i] = 1; - continue; - } - int day = get_last_month_day(ts_value.year(), ts_value.month()); + } else if constexpr (std::is_same_v) { ts_value.template set_time_unit(day); res_data[i] = binary_cast(ts_value); - } else { - const auto& cur_data = data_col[i]; - auto ts_value = binary_cast(cur_data); - if (!ts_value.is_valid_date()) { - null_map[i] = 1; - continue; - } - int day = get_last_month_day(ts_value.year(), ts_value.month()); ts_value.template set_time_unit(day); ts_value.set_time(ts_value.year(), ts_value.month(), day, 0, 0, 0, 0); UInt64 cast_value = binary_cast(ts_value); @@ -1006,24 +964,19 @@ struct LastDayImpl { } } - template static void execute_straight(size_t input_rows_count, - const PaddedPODArray& data_col, - PaddedPODArray& res_data) { + const PaddedPODArray& data_col, + PaddedPODArray& res_data) { for (int i = 0; i < input_rows_count; i++) { - if constexpr (std::is_same_v>) { - const auto& cur_data = data_col[i]; - auto ts_value = binary_cast(cur_data); - DCHECK(ts_value.is_valid_date()); - int day = get_last_month_day(ts_value.year(), ts_value.month()); - ts_value.template set_time_unit(day); + const auto& cur_data = data_col[i]; + auto ts_value = binary_cast(cur_data); + DCHECK(ts_value.is_valid_date()); + int day = get_last_month_day(ts_value.year(), ts_value.month()); + ts_value.template set_time_unit(day); + + if constexpr (std::is_same_v) { res_data[i] = binary_cast(ts_value); - } else { - const auto& cur_data = data_col[i]; - auto ts_value = binary_cast(cur_data); - DCHECK(ts_value.is_valid_date()); - int day = get_last_month_day(ts_value.year(), ts_value.month()); - ts_value.template set_time_unit(day); + } else if constexpr (std::is_same_v) { ts_value.set_time(ts_value.year(), ts_value.month(), day, 0, 0, 0, 0); UInt64 cast_value = binary_cast(ts_value); DataTypeDateTimeV2::cast_to_date_v2(cast_value, res_data[i]); @@ -1050,6 +1003,14 @@ template struct MondayImpl { static constexpr auto name = "to_monday"; + using DateValueType = date_cast::TypeToValueTypeV; + using ColumnType = date_cast::TypeToColumnV; + using NativeType = date_cast::ValueTypeOfColumnV; + using ResultType = + std::conditional_t(), DataTypeDate, DataTypeDateV2>; + using ResultColumnType = date_cast::TypeToColumnV; + using ResultNativeType = date_cast::ValueTypeOfColumnV; + static Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result, size_t input_rows_count) { @@ -1058,31 +1019,12 @@ struct MondayImpl { ColumnPtr res_column; if (is_nullable) { auto null_map = ColumnUInt8::create(input_rows_count, 0); - if constexpr (std::is_same_v || - std::is_same_v) { - auto data_col = assert_cast*>(argument_column.get()); - res_column = ColumnInt64::create(input_rows_count); - execute_straight( - input_rows_count, null_map->get_data(), data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); + auto data_col = assert_cast(argument_column.get()); + res_column = ResultColumnType::create(input_rows_count); + execute_straight( + input_rows_count, null_map->get_data(), data_col->get_data(), + static_cast(res_column->assume_mutable().get())->get_data()); - } else if constexpr (std::is_same_v) { - auto data_col = assert_cast*>(argument_column.get()); - res_column = ColumnVector::create(input_rows_count); - execute_straight, UInt32, UInt32>( - input_rows_count, null_map->get_data(), data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); - - } else if constexpr (std::is_same_v) { - auto data_col = assert_cast*>(argument_column.get()); - res_column = ColumnVector::create(input_rows_count); - execute_straight, UInt32, UInt64>( - input_rows_count, null_map->get_data(), data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); - } if (const auto* nullable_col = check_and_get_column( block.get_by_position(arguments[0]).column.get())) { NullMap& result_null_map = assert_cast(*null_map).get_data(); @@ -1094,39 +1036,30 @@ struct MondayImpl { block.replace_by_position(result, ColumnNullable::create(res_column, std::move(null_map))); } else { - if constexpr (std::is_same_v) { - auto data_col = assert_cast*>(argument_column.get()); - res_column = ColumnVector::create(input_rows_count); - execute_straight, UInt32, UInt32>( - input_rows_count, data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); - - } else if constexpr (std::is_same_v) { - auto data_col = assert_cast*>(argument_column.get()); - res_column = ColumnVector::create(input_rows_count); - execute_straight, UInt32, UInt64>( - input_rows_count, data_col->get_data(), - static_cast*>(res_column->assume_mutable().get()) - ->get_data()); + if constexpr (date_cast::IsV2()) { + auto data_col = assert_cast(argument_column.get()); + res_column = ResultColumnType::create(input_rows_count); + execute_straight(input_rows_count, data_col->get_data(), + static_cast(res_column->assume_mutable().get()) + ->get_data()); + block.replace_by_position(result, std::move(res_column)); } - block.replace_by_position(result, std::move(res_column)); } return Status::OK(); } - template + // v1, maybe makes null value static void execute_straight(size_t input_rows_count, NullMap& null_map, - const PaddedPODArray& data_col, - PaddedPODArray& res_data) { + const PaddedPODArray& data_col, + PaddedPODArray& res_data) { for (int i = 0; i < input_rows_count; i++) { - if constexpr (std::is_same_v) { - const auto& cur_data = data_col[i]; - auto ts_value = binary_cast(cur_data); - if (!ts_value.is_valid_date()) { - null_map[i] = 1; - continue; - } + const auto& cur_data = data_col[i]; + auto ts_value = binary_cast(cur_data); + if (!ts_value.is_valid_date()) [[unlikely]] { + null_map[i] = 1; + continue; + } + if constexpr (date_cast::IsV1()) { if (is_special_day(ts_value.year(), ts_value.month(), ts_value.day())) { ts_value.set_time(ts_value.year(), ts_value.month(), 1, 0, 0, 0); ts_value.set_type(TIME_DATE); @@ -1142,13 +1075,7 @@ struct MondayImpl { ts_value.set_type(TIME_DATE); res_data[i] = binary_cast(ts_value); - } else if constexpr (std::is_same_v>) { - const auto& cur_data = data_col[i]; - auto ts_value = binary_cast(cur_data); - if (!ts_value.is_valid_date()) { - null_map[i] = 1; - continue; - } + } else if constexpr (std::is_same_v) { if (is_special_day(ts_value.year(), ts_value.month(), ts_value.day())) { ts_value.template set_time_unit(1); res_data[i] = binary_cast(ts_value); @@ -1162,12 +1089,6 @@ struct MondayImpl { ts_value.template date_add_interval(interval); res_data[i] = binary_cast(ts_value); } else { - const auto& cur_data = data_col[i]; - auto ts_value = binary_cast(cur_data); - if (!ts_value.is_valid_date()) { - null_map[i] = 1; - continue; - } if (is_special_day(ts_value.year(), ts_value.month(), ts_value.day())) { ts_value.set_time(ts_value.year(), ts_value.month(), 1, 0, 0, 0, 0); UInt64 cast_value = binary_cast(ts_value); @@ -1186,31 +1107,27 @@ struct MondayImpl { } } - template + // v2, won't make null value static void execute_straight(size_t input_rows_count, - const PaddedPODArray& data_col, - PaddedPODArray& res_data) { + const PaddedPODArray& data_col, + PaddedPODArray& res_data) { for (int i = 0; i < input_rows_count; i++) { - if constexpr (std::is_same_v>) { - const auto& cur_data = data_col[i]; - auto ts_value = binary_cast(cur_data); - DCHECK(ts_value.is_valid_date()); + const auto& cur_data = data_col[i]; + auto ts_value = binary_cast(cur_data); + DCHECK(ts_value.is_valid_date()); + if constexpr (std::is_same_v) { if (is_special_day(ts_value.year(), ts_value.month(), ts_value.day())) { ts_value.template set_time_unit(1); res_data[i] = binary_cast(ts_value); continue; } - // day_of_week, from 1(Mon) to 7(Sun) int day_of_week = ts_value.weekday() + 1; int gap_of_monday = day_of_week - 1; TimeInterval interval(DAY, gap_of_monday, true); ts_value.template date_add_interval(interval); res_data[i] = binary_cast(ts_value); - } else { - const auto& cur_data = data_col[i]; - auto ts_value = binary_cast(cur_data); - DCHECK(ts_value.is_valid_date()); + } else if constexpr (std::is_same_v) { if (is_special_day(ts_value.year(), ts_value.month(), ts_value.day())) { ts_value.set_time(ts_value.year(), ts_value.month(), 1, 0, 0, 0, 0); UInt64 cast_value = binary_cast(ts_value);