zclllyybb commented on code in PR #49122:
URL: https://github.com/apache/doris/pull/49122#discussion_r2020676024
##########
be/src/vec/functions/function_date_or_datetime_computation.h:
##########
@@ -998,4 +998,83 @@ class CurrentDateFunctionBuilder : public
FunctionBuilderImpl {
}
};
+class FunctionMonthsBetween : public IFunction {
+public:
+ static constexpr auto name = "months_between";
+ static FunctionPtr create() { return
std::make_shared<FunctionMonthsBetween>(); }
+ 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 {
+ return std::make_shared<DataTypeFloat64>();
+ }
+
+ Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
+ uint32_t result, size_t input_rows_count) const
override {
+ CHECK_EQ(arguments.size(), 3);
+ auto res = ColumnFloat64::create();
+ res->reserve(input_rows_count);
+
+ bool col_const[3];
+ ColumnPtr argument_columns[3];
+ for (size_t i = 0; i < 3; ++i) {
+ col_const[i] =
is_column_const(*block.get_by_position(arguments[i]).column);
+ }
+ default_preprocess_parameter_columns(argument_columns, col_const, {0,
1, 2}, block,
+ arguments);
+
+ const auto& date1_col = *assert_cast<const
ColumnDateV2*>(argument_columns[0].get());
+ const auto& date2_col = *assert_cast<const
ColumnDateV2*>(argument_columns[1].get());
+ const auto& round_off_col = *assert_cast<const
ColumnBool*>(argument_columns[2].get());
+
+ auto calc_months_between = [](const auto& date1, const auto& date2,
bool round_off) {
+ auto dtv1 = binary_cast<UInt32,
DateV2Value<DateV2ValueType>>(date1);
+ auto dtv2 = binary_cast<UInt32,
DateV2Value<DateV2ValueType>>(date2);
+ auto year_between = dtv1.year() - dtv2.year();
+ auto months_between = dtv1.month() - dtv2.month();
+ auto days_in_month1 = S_DAYS_IN_MONTH[dtv1.month()];
+ if (UNLIKELY(is_leap(dtv1.year()) && dtv1.month() == 2)) {
+ days_in_month1 = 29;
+ }
+ auto days_in_month2 = S_DAYS_IN_MONTH[dtv2.month()];
+ if (UNLIKELY(is_leap(dtv2.year()) && dtv2.month() == 2)) {
+ days_in_month2 = 29;
+ }
+ double days_between = 0;
+ // if date1 and date2 are all the last day of the month,
days_between is 0
+ if (UNLIKELY(dtv1.day() == days_in_month1 && dtv2.day() ==
days_in_month2)) {
+ days_between = 0;
+ } else {
+ days_between = (dtv1.day() - dtv2.day()) / (double)31.0;
+ }
+
+ // calculate months between
+ double result = year_between * 12 + months_between + days_between;
+ // rounded to 8 digits unless roundOff=false.
+ if (round_off) {
+ result = round(result * 100000000) / 100000000;
+ }
+ return result;
+ };
+
+ // only handle all const case
+ if (col_const[0] && col_const[1] && col_const[2]) {
Review Comment:
这个情况框架提前处理了,不可能出现
##########
be/src/vec/functions/function_date_or_datetime_computation.h:
##########
@@ -998,4 +998,83 @@ class CurrentDateFunctionBuilder : public
FunctionBuilderImpl {
}
};
+class FunctionMonthsBetween : public IFunction {
+public:
+ static constexpr auto name = "months_between";
+ static FunctionPtr create() { return
std::make_shared<FunctionMonthsBetween>(); }
+ 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 {
+ return std::make_shared<DataTypeFloat64>();
+ }
+
+ Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
+ uint32_t result, size_t input_rows_count) const
override {
+ CHECK_EQ(arguments.size(), 3);
+ auto res = ColumnFloat64::create();
+ res->reserve(input_rows_count);
+
+ bool col_const[3];
+ ColumnPtr argument_columns[3];
+ for (size_t i = 0; i < 3; ++i) {
+ col_const[i] =
is_column_const(*block.get_by_position(arguments[i]).column);
+ }
+ default_preprocess_parameter_columns(argument_columns, col_const, {0,
1, 2}, block,
Review Comment:
这个用法不对,应该只有idx=2的列属于“参数列”。我们可以只考虑以下情况:
if (const0 && const1) {
//做一个特殊处理的逻辑
} else if (const2) {
//这时候把0和1列遇到的const直接展开,最多只有一个
} else {
//非const的情况
}
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]