diff --git a/be/src/olap/block_column_predicate.h b/be/src/olap/block_column_predicate.h index ef2a4ca038..6f679dbf25 100644 --- a/be/src/olap/block_column_predicate.h +++ b/be/src/olap/block_column_predicate.h @@ -29,7 +29,6 @@ namespace doris { // in the future // TODO: support do predicate on Bitmap and ZoneMap, So we can use index of column to do predicate on // page and segment - class BlockColumnPredicate { public: BlockColumnPredicate() = default; diff --git a/be/src/vec/data_types/data_type_date.h b/be/src/vec/data_types/data_type_date.h index b5d148b8bd..685363c396 100644 --- a/be/src/vec/data_types/data_type_date.h +++ b/be/src/vec/data_types/data_type_date.h @@ -27,7 +27,8 @@ namespace doris::vectorized { class DataTypeDate final : public DataTypeNumberBase { public: TypeIndex get_type_id() const override { return TypeIndex::Date; } - const char* get_family_name() const override { return "Date"; } + const char* get_family_name() const override { return "DateTime"; } + std::string do_get_name() const override {return "Date"; } bool can_be_used_as_version() const override { return true; } bool can_be_inside_nullable() const override { return true; } diff --git a/be/src/vec/data_types/data_type_date_time.cpp b/be/src/vec/data_types/data_type_date_time.cpp index ae6c94d19c..4b2619439a 100644 --- a/be/src/vec/data_types/data_type_date_time.cpp +++ b/be/src/vec/data_types/data_type_date_time.cpp @@ -28,10 +28,6 @@ namespace doris::vectorized { DataTypeDateTime::DataTypeDateTime() {} -std::string DataTypeDateTime::do_get_name() const { - return "DateTime"; -} - bool DataTypeDateTime::equals(const IDataType& rhs) const { return typeid(rhs) == typeid(*this); } diff --git a/be/src/vec/data_types/data_type_date_time.h b/be/src/vec/data_types/data_type_date_time.h index 6b6af04fb6..a0b21f18ef 100644 --- a/be/src/vec/data_types/data_type_date_time.h +++ b/be/src/vec/data_types/data_type_date_time.h @@ -52,7 +52,7 @@ public: DataTypeDateTime(); const char* get_family_name() const override { return "DateTime"; } - std::string do_get_name() const override; + std::string do_get_name() const override {return "DateTime"; } TypeIndex get_type_id() const override { return TypeIndex::DateTime; } bool can_be_used_as_version() const override { return true; } diff --git a/be/src/vec/functions/date_time_transforms.h b/be/src/vec/functions/date_time_transforms.h index eaab91806e..7640a2707d 100644 --- a/be/src/vec/functions/date_time_transforms.h +++ b/be/src/vec/functions/date_time_transforms.h @@ -27,8 +27,10 @@ #include "vec/columns/column_vector.h" #include "vec/common/exception.h" #include "vec/core/types.h" +#include "vec/data_types/data_type_date_time.h" #include "vec/functions/function_helpers.h" #include "vec/runtime/vdatetime_value.h" + namespace doris::vectorized { #define TIME_FUNCTION_IMPL(CLASS, UNIT, FUNCTION) \ @@ -46,7 +48,6 @@ namespace doris::vectorized { TO_TIME_FUNCTION(ToYearImpl, year); TO_TIME_FUNCTION(ToQuarterImpl, quarter); TO_TIME_FUNCTION(ToMonthImpl, month); -TO_TIME_FUNCTION(ToWeekImpl, week); TO_TIME_FUNCTION(ToDayImpl, day); TO_TIME_FUNCTION(ToHourImpl, hour); TO_TIME_FUNCTION(ToMinuteImpl, minute); @@ -58,7 +59,24 @@ TIME_FUNCTION_IMPL(DayOfMonthImpl, dayofmonth, day()); TIME_FUNCTION_IMPL(DayOfWeekImpl, dayofweek, day_of_week()); // TODO: the method should be always not nullable TIME_FUNCTION_IMPL(ToDaysImpl, to_days, daynr()); -TIME_FUNCTION_IMPL(ToYearWeekImpl, yearweek, year_week(mysql_week_mode(0))); + +#define TIME_FUNCTION_ONE_ARG_IMPL(CLASS, UNIT, FUNCTION) \ + struct CLASS { \ + static constexpr auto name = #UNIT; \ + static inline auto execute(const Int64& t, bool& is_null) { \ + const auto& date_time_value = (doris::vectorized::VecDateTimeValue&)(t); \ + is_null = !date_time_value.is_valid_date(); \ + return date_time_value.FUNCTION; \ + } \ + \ + static DataTypes get_variadic_argument_types() { \ + return {std::make_shared()}; \ + } \ + } + +TIME_FUNCTION_ONE_ARG_IMPL(ToWeekOneArgImpl, week, week(mysql_week_mode(0))); +TIME_FUNCTION_ONE_ARG_IMPL(ToYearWeekOneArgImpl, yearweek, year_week(mysql_week_mode(0))); + struct ToDateImpl { static constexpr auto name = "to_date"; diff --git a/be/src/vec/functions/function_date_or_datetime_computation.cpp b/be/src/vec/functions/function_date_or_datetime_computation.cpp index ecab986247..3de24abb84 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation.cpp +++ b/be/src/vec/functions/function_date_or_datetime_computation.cpp @@ -49,6 +49,9 @@ using FunctionHoursDiff = FunctionDateOrDateTimeComputation; using FunctionMinutesDiff = FunctionDateOrDateTimeComputation; using FunctionSecondsDiff = FunctionDateOrDateTimeComputation; +using FunctionToYearWeekTwoArgs = FunctionDateOrDateTimeComputation; +using FunctionToWeekTwoArgs = FunctionDateOrDateTimeComputation; + struct NowFunctionName { static constexpr auto name = "now"; }; @@ -103,6 +106,8 @@ void register_function_date_time_computation(SimpleFunctionFactory& factory) { factory.register_function(); factory.register_function(); factory.register_function(); + factory.register_alias("days_add", "add_dates"); + factory.register_alias("days_add", "date_add"); factory.register_function(); factory.register_function(); factory.register_function(); @@ -112,6 +117,8 @@ void register_function_date_time_computation(SimpleFunctionFactory& factory) { factory.register_function(); factory.register_function(); factory.register_function(); + factory.register_alias("days_sub", "subdate"); + factory.register_alias("days_sub", "date_sub"); factory.register_function(); factory.register_function(); factory.register_function(); @@ -126,6 +133,10 @@ void register_function_date_time_computation(SimpleFunctionFactory& factory) { factory.register_function(); factory.register_function(); factory.register_function(); + + factory.register_function(); + factory.register_function(); + factory.register_function(); factory.register_function(); factory.register_function(); 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 607039c6c7..7fdffef80a 100644 --- a/be/src/vec/functions/function_date_or_datetime_computation.h +++ b/be/src/vec/functions/function_date_or_datetime_computation.h @@ -145,6 +145,24 @@ TIME_DIFF_FUNCTION_IMPL(HoursDiffImpl, hours_diff, HOUR); TIME_DIFF_FUNCTION_IMPL(MintueSDiffImpl, minutes_diff, MINUTE); TIME_DIFF_FUNCTION_IMPL(SecondsDiffImpl, seconds_diff, SECOND); +#define TIME_FUNCTION_TWO_ARGS_IMPL(CLASS, NAME, FUNCTION) \ + struct CLASS { \ + using ReturnType = DataTypeInt32; \ + static constexpr auto name = #NAME; \ + static constexpr auto is_nullable = false; \ + static inline int64_t execute(const Int64& t0, const Int32 mode, bool& is_null) { \ + const auto& ts0 = reinterpret_cast(t0); \ + is_null = !ts0.is_valid_date(); \ + return ts0.FUNCTION; \ + } \ + static DataTypes get_variadic_argument_types() { \ + return {std::make_shared(), std::make_shared()}; \ + } \ + } + +TIME_FUNCTION_TWO_ARGS_IMPL(ToYearWeekTwoArgsImpl, yearweek, year_week(mysql_week_mode(mode))); +TIME_FUNCTION_TWO_ARGS_IMPL(ToWeekTwoArgsImpl, week, week(mysql_week_mode(mode))); + template struct DateTimeOp { // use for (DateTime, DateTime) -> other_type @@ -245,10 +263,14 @@ struct DateTimeAddIntervalImpl { Op::vector_constant(sources->get_data(), col_to->get_data(), null_map->get_data(), delta_const_column->get_field().get()); - } else { + } else if (delta_const_column->get_field().get_type() == Field::Types::Int64) { Op::vector_constant(sources->get_data(), col_to->get_data(), null_map->get_data(), delta_const_column->get_field().get()); + } else { + Op::vector_constant(sources->get_data(), col_to->get_data(), + null_map->get_data(), + delta_const_column->get_field().get()); } } else { if (const auto* delta_vec_column0 = @@ -296,6 +318,9 @@ template class FunctionDateOrDateTimeComputation : public IFunction { public: static constexpr auto name = Transform::name; + static constexpr bool has_variadic_argument = + !std::is_void_v()))>; + static FunctionPtr create() { return std::make_shared(); } String get_name() const override { return name; } @@ -303,6 +328,11 @@ public: bool is_variadic() const override { return true; } size_t get_number_of_arguments() const override { return 0; } + DataTypes get_variadic_argument_types_impl() const override { + if constexpr (has_variadic_argument) return Transform::get_variadic_argument_types(); + return {}; + } + DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const override { if (arguments.size() != 2 && arguments.size() != 3) { LOG(FATAL) << fmt::format( diff --git a/be/src/vec/functions/function_date_or_datetime_to_something.h b/be/src/vec/functions/function_date_or_datetime_to_something.h index 31e87b17c0..efef7c39d3 100644 --- a/be/src/vec/functions/function_date_or_datetime_to_something.h +++ b/be/src/vec/functions/function_date_or_datetime_to_something.h @@ -30,12 +30,19 @@ template class FunctionDateOrDateTimeToSomething : public IFunction { public: static constexpr auto name = Transform::name; + static constexpr bool has_variadic_argument = + !std::is_void_v()))>; + static FunctionPtr create() { return std::make_shared(); } String get_name() const override { return name; } bool is_variadic() const override { return true; } size_t get_number_of_arguments() const override { return 0; } + DataTypes get_variadic_argument_types_impl() const override { + if constexpr (has_variadic_argument) return Transform::get_variadic_argument_types(); + return {}; + } DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const override { if (arguments.size() == 1) { diff --git a/be/src/vec/functions/modulo.cpp b/be/src/vec/functions/modulo.cpp index 8fbfb8bb7f..3bd15c36eb 100644 --- a/be/src/vec/functions/modulo.cpp +++ b/be/src/vec/functions/modulo.cpp @@ -183,6 +183,7 @@ using FunctionPModulo = FunctionBinaryArithmeticToNullType(); factory.register_function(); + factory.register_alias("mod", "fmod"); } } // namespace doris::vectorized diff --git a/be/src/vec/functions/simple_function_factory.h b/be/src/vec/functions/simple_function_factory.h index 5b9f0fd213..ab3968c209 100644 --- a/be/src/vec/functions/simple_function_factory.h +++ b/be/src/vec/functions/simple_function_factory.h @@ -74,7 +74,7 @@ class SimpleFunctionFactory { using FunctionIsVariadic = phmap::flat_hash_set; public: - void register_function(const std::string& name, Creator ptr) { + void register_function(const std::string& name, const Creator& ptr) { DataTypes types = ptr()->get_variadic_argument_types(); // types.empty() means function is not variadic if (!types.empty()) { @@ -83,8 +83,8 @@ public: std::string key_str = name; if (!types.empty()) { - for (auto type : types) { - key_str.append(type->get_name()); + for (const auto& type : types) { + key_str.append(type->get_family_name()); } } function_creators[key_str] = ptr; @@ -116,8 +116,8 @@ public: key_str.append(arg.type->is_nullable() ? reinterpret_cast(arg.type.get()) ->get_nested_type() - ->get_name() - : arg.type->get_name()); + ->get_family_name() + : arg.type->get_family_name()); } } diff --git a/be/src/vec/functions/time_of_function.cpp b/be/src/vec/functions/time_of_function.cpp index f6d17aefe7..d3a677ac24 100644 --- a/be/src/vec/functions/time_of_function.cpp +++ b/be/src/vec/functions/time_of_function.cpp @@ -26,7 +26,8 @@ using FunctionWeekOfYear = FunctionDateOrDateTimeToSomething; using FunctionDayOfWeek = FunctionDateOrDateTimeToSomething; using FunctionDayOfMonth = FunctionDateOrDateTimeToSomething; -using FunctionYearWeek = FunctionDateOrDateTimeToSomething; +using FunctionYearWeek = FunctionDateOrDateTimeToSomething; + void register_function_time_of_fuction(SimpleFunctionFactory& factory) { factory.register_function(); factory.register_function(); diff --git a/be/src/vec/functions/to_time_function.cpp b/be/src/vec/functions/to_time_function.cpp index c6940cc1f7..e73ab3fce0 100644 --- a/be/src/vec/functions/to_time_function.cpp +++ b/be/src/vec/functions/to_time_function.cpp @@ -27,7 +27,7 @@ using FunctionYear = FunctionDateOrDateTimeToSomething; using FunctionMonth = FunctionDateOrDateTimeToSomething; using FunctionDay = FunctionDateOrDateTimeToSomething; -using FunctionWeek = FunctionDateOrDateTimeToSomething; +using FunctionWeek = FunctionDateOrDateTimeToSomething; using FunctionHour = FunctionDateOrDateTimeToSomething; using FunctionMinute = FunctionDateOrDateTimeToSomething; using FunctionSecond = FunctionDateOrDateTimeToSomething; diff --git a/be/test/vec/function/function_time_test.cpp b/be/test/vec/function/function_time_test.cpp index df6747aa95..31b2350178 100644 --- a/be/test/vec/function/function_time_test.cpp +++ b/be/test/vec/function/function_time_test.cpp @@ -478,6 +478,48 @@ TEST(TimestampFunctionsTest, date_test) { check_function(func_name, input_types, data_set); } +TEST(TimestampFunctionsTest, week_test) { + std::string func_name = "week"; + + InputTypeSet input_types = {TypeIndex::DateTime}; + + DataSet data_set = { + {{std::string("1989-03-21 06:00:00")}, 12}, + {{std::string("")}, Null()}, + {{std::string("9999-12-12 00:00:00")}, 50}}; + + check_function(func_name, input_types, data_set); + + InputTypeSet new_input_types = {TypeIndex::Date}; + DataSet new_data_set = { + {{std::string("1989-03-21")}, 12}, + {{std::string("")}, Null()}, + {{std::string("9999-12-12")}, 50}}; + + check_function(func_name, new_input_types, new_data_set); +} + +TEST(TimestampFunctionsTest, yearweek_test) { + std::string func_name = "yearweek"; + + InputTypeSet input_types = {TypeIndex::DateTime}; + + DataSet data_set = { + {{std::string("1989-03-21 06:00:00")}, 198912}, + {{std::string("")}, Null()}, + {{std::string("9999-12-12 00:00:00")}, 999950}}; + + check_function(func_name, input_types, data_set); + + InputTypeSet new_input_types = {TypeIndex::Date}; + DataSet new_data_set = { + {{std::string("1989-03-21")}, 198912}, + {{std::string("")}, Null()}, + {{std::string("9999-12-12")}, 999950}}; + + check_function(func_name, new_input_types, new_data_set); +} + TEST(TimestampFunctionsTest, makedate_test) { std::string func_name = "makedate"; diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index b82925fae1..5da020efe5 100755 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -206,13 +206,13 @@ visible_functions = [ '', '', 'vec', 'ALWAYS_NULLABLE'], [['yearweek'], 'INT', ['DATETIME', 'INT'], '_ZN5doris18TimestampFunctions9year_weekEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE', - '', '', '', ''], + '', '', 'vec', 'ALWAYS_NULLABLE'], [['week'], 'INT', ['DATETIME'], '_ZN5doris18TimestampFunctions4weekEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE', '', '', 'vec', 'ALWAYS_NULLABLE'], [['week'], 'INT', ['DATETIME', 'INT'], '_ZN5doris18TimestampFunctions4weekEPN9doris_udf15FunctionContextERKNS1_11DateTimeValERKNS1_6IntValE', - '', '', '', 'ALWAYS_NULLABLE'], + '', '', 'vec', 'ALWAYS_NULLABLE'], [['hour'], 'INT', ['DATETIME'], '_ZN5doris18TimestampFunctions4hourEPN9doris_udf15FunctionContextERKNS1_11DateTimeValE', '', '', 'vec', 'ALWAYS_NULLABLE'], @@ -643,28 +643,28 @@ visible_functions = [ '15FunctionContextERKNS1_9DoubleValES6_', '', '', 'vec', 'ALWAYS_NULLABLE'], [['mod'], 'TINYINT', ['TINYINT', 'TINYINT'], '_ZN5doris9Operators29mod_tiny_int_val_tiny_int_valEPN9doris_udf' - '15FunctionContextERKNS1_10TinyIntValES6_', '', '', '', 'ALWAYS_NULLABLE'], + '15FunctionContextERKNS1_10TinyIntValES6_', '', '', 'vec', 'ALWAYS_NULLABLE'], [['mod'], 'SMALLINT', ['SMALLINT', 'SMALLINT'], '_ZN5doris9Operators31mod_small_int_val_small_int_valEPN9doris_udf' - '15FunctionContextERKNS1_11SmallIntValES6_', '', '', '', 'ALWAYS_NULLABLE'], + '15FunctionContextERKNS1_11SmallIntValES6_', '', '', 'vec', 'ALWAYS_NULLABLE'], [['mod'], 'INT', ['INT', 'INT'], '_ZN5doris9Operators19mod_int_val_int_valEPN9doris_udf' - '15FunctionContextERKNS1_6IntValES6_', '', '', '', 'ALWAYS_NULLABLE'], + '15FunctionContextERKNS1_6IntValES6_', '', '', 'vec', 'ALWAYS_NULLABLE'], [['mod'], 'BIGINT', ['BIGINT', 'BIGINT'], '_ZN5doris9Operators27mod_big_int_val_big_int_valEPN9doris_udf' - '15FunctionContextERKNS1_9BigIntValES6_', '', '', '', 'ALWAYS_NULLABLE'], + '15FunctionContextERKNS1_9BigIntValES6_', '', '', 'vec', 'ALWAYS_NULLABLE'], [['mod'], 'LARGEINT', ['LARGEINT', 'LARGEINT'], '_ZN5doris9Operators31mod_large_int_val_large_int_valEPN9doris_udf' - '15FunctionContextERKNS1_11LargeIntValES6_', '', '', '', 'ALWAYS_NULLABLE'], + '15FunctionContextERKNS1_11LargeIntValES6_', '', '', 'vec', 'ALWAYS_NULLABLE'], [['mod'], 'DECIMALV2', ['DECIMALV2', 'DECIMALV2'], '_ZN5doris18DecimalV2Operators31mod_decimalv2_val_decimalv2_valEPN9doris_udf' - '15FunctionContextERKNS1_12DecimalV2ValES6_', '', '', '', 'ALWAYS_NULLABLE'], + '15FunctionContextERKNS1_12DecimalV2ValES6_', '', '', 'vec', 'ALWAYS_NULLABLE'], [['mod', 'fmod'], 'FLOAT', ['FLOAT', 'FLOAT'], '_ZN5doris13MathFunctions10fmod_floatEPN9doris_udf15FunctionContextERKNS1_8FloatValES6_', - '', '', '', 'ALWAYS_NULLABLE'], + '', '', 'vec', 'ALWAYS_NULLABLE'], [['mod', 'fmod'], 'DOUBLE', ['DOUBLE', 'DOUBLE'], '_ZN5doris13MathFunctions11fmod_doubleEPN9doris_udf15FunctionContextERKNS1_9DoubleValES6_', - '', '', '', 'ALWAYS_NULLABLE'], + '', '', 'vec', 'ALWAYS_NULLABLE'], [['positive'], 'BIGINT', ['BIGINT'], '_ZN5doris13MathFunctions15positive_bigintEPN9doris_udf'