diff --git a/be/src/exprs/function/function_date_or_datetime_computation.h b/be/src/exprs/function/function_date_or_datetime_computation.h index 9743ef79c55cc1..15643880c0a5b0 100644 --- a/be/src/exprs/function/function_date_or_datetime_computation.h +++ b/be/src/exprs/function/function_date_or_datetime_computation.h @@ -41,6 +41,7 @@ #include "core/block/columns_with_type_and_name.h" #include "core/column/column.h" #include "core/column/column_const.h" +#include "core/column/column_execute_util.h" #include "core/column/column_nullable.h" #include "core/column/column_vector.h" #include "core/data_type/data_type.h" @@ -1682,26 +1683,23 @@ class FunctionMonthsBetween : public IFunction { CHECK_EQ(arguments.size(), 3); auto res = ColumnFloat64::create(); - bool date_consts[2]; - date_consts[0] = is_column_const(*block.get_by_position(arguments[0]).column); - date_consts[1] = is_column_const(*block.get_by_position(arguments[1]).column); - ColumnPtr date_cols[2]; - // convert const columns to full columns if necessary - default_preprocess_parameter_columns(date_cols, date_consts, {0, 1}, block, arguments); - - const auto& [col3, col3_const] = - unpack_if_const(block.get_by_position(arguments[2]).column); - const auto& round_off_col = *assert_cast(col3.get()); - auto date_type = block.get_by_position(arguments[0]).type->get_primitive_type(); DORIS_CHECK_EQ(date_type, block.get_by_position(arguments[1]).type->get_primitive_type()); + auto round_off = + ColumnView::create(block.get_by_position(arguments[2]).column); if (date_type == TYPE_TIMESTAMP_NS) { - execute_typed(input_rows_count, date_cols, date_consts, col3_const, - round_off_col, *res); + auto date1 = ColumnView::create( + block.get_by_position(arguments[0]).column); + auto date2 = ColumnView::create( + block.get_by_position(arguments[1]).column); + execute_typed(input_rows_count, date1, date2, round_off, *res); } else { DORIS_CHECK_EQ(date_type, TYPE_DATEV2); - execute_typed(input_rows_count, date_cols, date_consts, col3_const, - round_off_col, *res); + auto date1 = + ColumnView::create(block.get_by_position(arguments[0]).column); + auto date2 = + ColumnView::create(block.get_by_position(arguments[1]).column); + execute_typed(input_rows_count, date1, date2, round_off, *res); } block.replace_by_position(result, std::move(res)); @@ -1709,50 +1707,15 @@ class FunctionMonthsBetween : public IFunction { } private: - template - static void execute_typed(size_t input_rows_count, const ColumnPtr (&date_cols)[2], - const bool (&date_consts)[2], bool round_off_const, - const ColumnBool& round_off_col, ColumnFloat64& res) { - const auto& date1_col = *assert_cast(date_cols[0].get()); - const auto& date2_col = *assert_cast(date_cols[1].get()); - if (date_consts[0] && date_consts[1]) { - execute_vector(input_rows_count, date1_col, date2_col, round_off_col, res); - } else if (round_off_const) { - execute_vector(input_rows_count, date1_col, date2_col, round_off_col, res); - } else { - execute_vector(input_rows_count, date1_col, date2_col, round_off_col, - res); - } - } - - template - static void execute_vector(const size_t input_rows_count, const DateColumn& date1_col, - const DateColumn& date2_col, const ColumnBool& round_off_col, - ColumnFloat64& res) { + template + static void execute_typed(size_t input_rows_count, const ColumnView& date1, + const ColumnView& date2, + const ColumnView& round_off, ColumnFloat64& res) { res.reserve(input_rows_count); - double months_between; - bool round_off; - - if constexpr (is_date_const) { - auto dtv1 = date_v2_from_date_like(date1_col.get_element(0)); - auto dtv2 = date_v2_from_date_like(date2_col.get_element(0)); - months_between = calc_months_between(dtv1, dtv2); - } - - if constexpr (is_round_off_const) { - round_off = round_off_col.get_element(0); - } - - for (int i = 0; i < input_rows_count; ++i) { - if constexpr (!is_date_const) { - auto dtv1 = date_v2_from_date_like(date1_col.get_element(i)); - auto dtv2 = date_v2_from_date_like(date2_col.get_element(i)); - months_between = calc_months_between(dtv1, dtv2); - } - if constexpr (!is_round_off_const) { - round_off = round_off_col.get_element(i); - } - if (round_off) { + for (size_t i = 0; i < input_rows_count; ++i) { + auto months_between = calc_months_between(date_v2_from_date_like(date1.value_at(i)), + date_v2_from_date_like(date2.value_at(i))); + if (round_off.value_at(i)) { months_between = round_months_between(months_between); } res.insert_value(months_between); diff --git a/regression-test/data/query_p0/sql_functions/string_functions/test_months_between.out b/regression-test/data/query_p0/sql_functions/string_functions/test_months_between.out index a2272c940b7e7b..55f6fe782c60fe 100644 --- a/regression-test/data/query_p0/sql_functions/string_functions/test_months_between.out +++ b/regression-test/data/query_p0/sql_functions/string_functions/test_months_between.out @@ -111,8 +111,8 @@ -1 -1 -1 -1 -1.90322581 -0.03225806 -1.90322581 -0.03225806 -1.90322581 0.90322581 \N \N --12.96774194 \N -12.96774193548387 \N --13.87096774 0.87096774 -13.87096774193548 \N +-12.96774194 \N -12.967741935483872 \N +-13.87096774 0.87096774 -13.870967741935484 \N -6 \N \N 4.93548387 -- !const_other_not_nullable -- @@ -122,8 +122,8 @@ -1.4516129 -0.5483871 -1.4516129 -0.5483871 -1.90322581 -0.03225806 -1.90322581 -0.03225806 -1.90322581 0.90322581 -1.903225806451613 0.9032258064516129 --12.96774194 10.96774194 -12.96774193548387 10.96774193548387 --13.87096774 0.87096774 -13.87096774193548 0.8709677419354839 +-12.96774194 10.96774194 -12.967741935483872 10.967741935483872 +-13.87096774 0.87096774 -13.870967741935484 0.8709677419354839 -6 4.93548387 -6 4.93548387 -971.96774194 -1441 -971.96774194 -1441 @@ -158,8 +158,8 @@ -1.4516129 -1.4516129 -1.90322581 -1.903225806451613 -1.90322581 -1.90322581 --12.96774194 -12.96774193548387 --13.87096774 -13.87096774193548 +-12.96774194 -12.967741935483872 +-13.87096774 -13.870967741935484 -6 -6 -971.96774194 -971.96774194 @@ -175,6 +175,18 @@ -1 -1 +-- !const_dates_round_off -- +1 true 2.03225806 +10 false 2.032258064516129 +2 false 2.032258064516129 +3 true 2.03225806 +4 false 2.032258064516129 +5 true 2.03225806 +6 false 2.032258064516129 +7 true 2.03225806 +8 false 2.032258064516129 +9 true 2.03225806 + -- !const23 -- -0.03225806 -0.5483871 diff --git a/regression-test/suites/query_p0/sql_functions/string_functions/test_months_between.groovy b/regression-test/suites/query_p0/sql_functions/string_functions/test_months_between.groovy index aa760d97838c04..937d01475e8289 100644 --- a/regression-test/suites/query_p0/sql_functions/string_functions/test_months_between.groovy +++ b/regression-test/suites/query_p0/sql_functions/string_functions/test_months_between.groovy @@ -82,6 +82,7 @@ suite("test_months_between") { order_qt_const_partial_nullable_no_null "select months_between('2020-01-01', nullable('2020-02-01')), months_between(nullable('2020-01-01'), '2020-02-01'), months_between('2020-01-01', nullable('2020-02-01 00:00:00'), nullable(true)) from months_between_args" order_qt_const1 "select months_between('2020-01-01', date2_not_null), months_between('2020-01-01', date2_not_null, round_off_not_null) from months_between_args" order_qt_const12 "select months_between('2020-01-01', '2020-02-01', round_off_not_null) from months_between_args" + order_qt_const_dates_round_off "select k0, round_off_not_null, months_between('2020-12-26', '2020-10-25', round_off_not_null) from months_between_args order by k0" order_qt_const23 "select months_between(date1_not_null, '2020-02-01', true) from months_between_args" order_qt_const3 "select months_between(date1_not_null, date2_not_null, true) from months_between_args"