diff --git a/be/src/vec/functions/function.h b/be/src/vec/functions/function.h index a768fa1ed1..63cf78c417 100644 --- a/be/src/vec/functions/function.h +++ b/be/src/vec/functions/function.h @@ -238,13 +238,6 @@ public: virtual bool is_deterministic_in_scope_of_query() const = 0; - /** Lets you know if the function is monotonic in a range of values. - * This is used to work with the index in a sorted chunk of data. - * And allows to use the index not only when it is written, for example `date >= const`, but also, for example, `toMonth(date) >= 11`. - * All this is considered only for functions of one argument. - */ - virtual bool has_information_about_monotonicity() const { return false; } - virtual bool is_use_default_implementation_for_constants() const = 0; /// The property of monotonicity for a certain range. @@ -583,10 +576,6 @@ public: return function->is_deterministic_in_scope_of_query(); } - bool has_information_about_monotonicity() const override { - return function->has_information_about_monotonicity(); - } - IFunctionBase::Monotonicity get_monotonicity_for_range(const IDataType& type, const Field& left, const Field& right) const override { return function->get_monotonicity_for_range(type, left, right); diff --git a/be/src/vec/functions/function_agg_state.h b/be/src/vec/functions/function_agg_state.h index 8d28e0da1e..b17e8916d0 100644 --- a/be/src/vec/functions/function_agg_state.h +++ b/be/src/vec/functions/function_agg_state.h @@ -52,7 +52,6 @@ public: size_t get_number_of_arguments() const override { return _argument_types.size(); } - bool use_default_implementation_for_constants() const override { return true; } bool use_default_implementation_for_nulls() const override { return false; } String get_name() const override { return fmt::format("{}_state", _agg_function->get_name()); } diff --git a/be/src/vec/functions/function_cast.h b/be/src/vec/functions/function_cast.h index 1a24595b2d..562fd7a1f6 100644 --- a/be/src/vec/functions/function_cast.h +++ b/be/src/vec/functions/function_cast.h @@ -1291,8 +1291,6 @@ public: } } - bool has_information_about_monotonicity() const override { return Monotonic::has(); } - Monotonicity get_monotonicity_for_range(const IDataType& type, const Field& left, const Field& right) const override { return Monotonic::get(type, left, right); @@ -1699,10 +1697,6 @@ public: bool is_deterministic() const override { return true; } bool is_deterministic_in_scope_of_query() const override { return true; } - bool has_information_about_monotonicity() const override { - return static_cast(monotonicity_for_range); - } - Monotonicity get_monotonicity_for_range(const IDataType& type, const Field& left, const Field& right) const override { return monotonicity_for_range(type, left, right); 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 200cd606c2..e711ad7b00 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 @@ -97,8 +97,6 @@ public: Transform>::execute(block, arguments, result, input_rows_count); } - - bool has_information_about_monotonicity() const override { return true; } }; } // namespace doris::vectorized diff --git a/be/src/vec/functions/function_fake.h b/be/src/vec/functions/function_fake.h index 2f32fd146b..0dabdfb3c8 100644 --- a/be/src/vec/functions/function_fake.h +++ b/be/src/vec/functions/function_fake.h @@ -54,6 +54,7 @@ public: } bool use_default_implementation_for_nulls() const override { return true; } + bool use_default_implementation_for_constants() const override { return false; } Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, diff --git a/be/src/vec/functions/function_json.cpp b/be/src/vec/functions/function_json.cpp index 9eb50ec775..03bd03c52e 100644 --- a/be/src/vec/functions/function_json.cpp +++ b/be/src/vec/functions/function_json.cpp @@ -892,7 +892,6 @@ public: String get_name() const override { return name; } size_t get_number_of_arguments() const override { return 0; } bool is_variadic() const override { return true; } - bool use_default_implementation_for_constants() const override { return true; } DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { return make_nullable(std::make_shared()); } diff --git a/be/src/vec/functions/function_multi_same_args.h b/be/src/vec/functions/function_multi_same_args.h index a0cd4e01ed..0c45c7cd44 100644 --- a/be/src/vec/functions/function_multi_same_args.h +++ b/be/src/vec/functions/function_multi_same_args.h @@ -36,8 +36,6 @@ public: bool use_default_implementation_for_nulls() const override { return true; } - bool use_default_implementation_for_constants() const override { return false; } - bool is_variadic() const override { return true; } size_t get_number_of_arguments() const override { return 0; } diff --git a/be/src/vec/functions/function_string.h b/be/src/vec/functions/function_string.h index b2508decf7..0c67d83561 100644 --- a/be/src/vec/functions/function_string.h +++ b/be/src/vec/functions/function_string.h @@ -1562,8 +1562,6 @@ public: bool use_default_implementation_for_nulls() const override { return true; } - bool use_default_implementation_for_constants() const override { return false; } - Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, size_t result, size_t input_rows_count) const override { DCHECK_EQ(arguments.size(), 3); @@ -1576,9 +1574,10 @@ public: auto& res_offsets = res->get_offsets(); auto& res_chars = res->get_chars(); res_offsets.resize(input_rows_count); - - ColumnPtr content_column = - block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); + ColumnPtr content_column; + bool content_const = false; + std::tie(content_column, content_const) = + unpack_if_const(block.get_by_position(arguments[0]).column); if (auto* nullable = check_and_get_column(*content_column)) { // Danger: Here must dispose the null map data first! Because @@ -1588,25 +1587,16 @@ public: content_column = nullable->get_nested_column_ptr(); } - for (size_t i = 1; i <= 2; i++) { - ColumnPtr columnPtr = remove_nullable(block.get_by_position(arguments[i]).column); - - if (!is_column_const(*columnPtr)) { - return Status::RuntimeError("Argument at index {} for function {} must be constant", - i + 1, get_name()); - } - } - auto str_col = assert_cast(content_column.get()); - const IColumn& delimiter_col = *block.get_by_position(arguments[1]).column; - const auto* delimiter_const = typeid_cast(&delimiter_col); - auto delimiter = delimiter_const->get_field().get(); - int32_t delimiter_size = delimiter.size(); + [[maybe_unused]] const auto& [delimiter_col, delimiter_const] = + unpack_if_const(block.get_by_position(arguments[1]).column); + auto delimiter = delimiter_col->get_data_at(0); + int32_t delimiter_size = delimiter.size; - const IColumn& part_num_col = *block.get_by_position(arguments[2]).column; - const auto* part_num_col_const = typeid_cast(&part_num_col); - auto part_number = part_num_col_const->get_field().get(); + [[maybe_unused]] const auto& [part_num_col, part_const] = + unpack_if_const(block.get_by_position(arguments[2]).column); + auto part_number = *((int*)part_num_col->get_data_at(0).data); if (part_number == 0 || delimiter_size == 0) { for (size_t i = 0; i < input_rows_count; ++i) { @@ -1622,7 +1612,7 @@ public: while (num < part_number) { size_t n = str.size - offset - 1; const char* pos = reinterpret_cast( - memchr(str.data + offset + 1, delimiter[0], n)); + memchr(str.data + offset + 1, delimiter.data[0], n)); if (pos != nullptr) { offset = pos - str.data; num++; diff --git a/be/src/vec/functions/function_struct_element.cpp b/be/src/vec/functions/function_struct_element.cpp index 0a9e71a348..8c66386cd9 100644 --- a/be/src/vec/functions/function_struct_element.cpp +++ b/be/src/vec/functions/function_struct_element.cpp @@ -49,8 +49,6 @@ public: bool use_default_implementation_for_nulls() const override { return true; } - bool use_default_implementation_for_constants() const override { return true; } - size_t get_number_of_arguments() const override { return 2; } ColumnNumbers get_arguments_that_are_always_constant() const override { return {1}; } diff --git a/be/src/vec/functions/function_unary_arithmetic.h b/be/src/vec/functions/function_unary_arithmetic.h index 51aabb9a80..8d18129a04 100644 --- a/be/src/vec/functions/function_unary_arithmetic.h +++ b/be/src/vec/functions/function_unary_arithmetic.h @@ -146,8 +146,6 @@ public: } return Status::OK(); } - - bool has_information_about_monotonicity() const override { return false; } }; struct PositiveMonotonicity { diff --git a/be/src/vec/functions/least_greast.cpp b/be/src/vec/functions/least_greast.cpp index be35504d83..4c008da67f 100644 --- a/be/src/vec/functions/least_greast.cpp +++ b/be/src/vec/functions/least_greast.cpp @@ -186,13 +186,14 @@ struct FunctionFieldImpl { WhichDataType which(data_type); //TODO: maybe could use hashmap to save column data, not use for loop ervey time to test equals. if (which.is_string_or_fixed_string()) { - const auto& column_string = reinterpret_cast(*argument_columns[0]); + const auto& column_string = assert_cast(*argument_columns[0]); for (int row = 0; row < input_rows_count; ++row) { const auto& str_data = column_string.get_data_at(index_check_const(row, arg_const)); for (int col = 1; col < column_size; ++col) { - const auto& temp_data = - reinterpret_cast(*argument_columns[col]) - .get_data_at(0); + auto [column, is_const] = + unpack_if_const(block.safe_get_by_position(col).column); + const auto& temp_data = assert_cast(*column).get_data_at( + index_check_const(row, is_const)); if (EqualsOp::apply(temp_data, str_data)) { res_data[row] = col; break; @@ -229,12 +230,13 @@ private: static void insert_result_data(PaddedPODArray& __restrict res_data, ColumnPtr first_column, ColumnPtr argument_column, const size_t input_rows_count, const int col) { + auto [first_column_raw, first_column_is_const] = unpack_if_const(first_column); auto* __restrict first_raw_data = - reinterpret_cast(first_column.get())->get_data().data(); - const auto& column_raw_data = - reinterpret_cast(*argument_column).get_data_column(); + assert_cast(first_column_raw.get())->get_data().data(); + + auto [argument_column_raw, argument_column_is_const] = unpack_if_const(argument_column); const auto& arg_data = - reinterpret_cast(column_raw_data).get_data().data()[0]; + assert_cast(*argument_column_raw).get_data().data()[0]; if constexpr (std::is_same_v) { for (size_t i = 0; i < input_rows_count; ++i) { res_data[i] |= (!res_data[i] * diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SubstringIndex.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SubstringIndex.java index 22f59905f3..5374950135 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SubstringIndex.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/SubstringIndex.java @@ -18,6 +18,7 @@ package org.apache.doris.nereids.trees.expressions.functions.scalar; import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.exceptions.AnalysisException; import org.apache.doris.nereids.trees.expressions.Expression; import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable; import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; @@ -52,6 +53,16 @@ public class SubstringIndex extends ScalarFunction super("substring_index", arg0, arg1, arg2); } + @Override + public void checkLegalityBeforeTypeCoercion() { + for (int i = 1; i < children.size(); ++i) { + if (!getArgument(i).isConstant()) { + throw new AnalysisException(getName() + + " function except for the first argument, other parameter must be a constant."); + } + } + } + /** * withChildren. */