/root/doris/be/src/vec/functions/function.h
| Line | Count | Source | 
| 1 |  | // Licensed to the Apache Software Foundation (ASF) under one | 
| 2 |  | // or more contributor license agreements.  See the NOTICE file | 
| 3 |  | // distributed with this work for additional information | 
| 4 |  | // regarding copyright ownership.  The ASF licenses this file | 
| 5 |  | // to you under the Apache License, Version 2.0 (the | 
| 6 |  | // "License"); you may not use this file except in compliance | 
| 7 |  | // with the License.  You may obtain a copy of the License at | 
| 8 |  | // | 
| 9 |  | //   http://www.apache.org/licenses/LICENSE-2.0 | 
| 10 |  | // | 
| 11 |  | // Unless required by applicable law or agreed to in writing, | 
| 12 |  | // software distributed under the License is distributed on an | 
| 13 |  | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
| 14 |  | // KIND, either express or implied.  See the License for the | 
| 15 |  | // specific language governing permissions and limitations | 
| 16 |  | // under the License. | 
| 17 |  | // This file is copied from | 
| 18 |  | // https://github.com/ClickHouse/ClickHouse/blob/master/src/Functions/IFunction.h | 
| 19 |  | // and modified by Doris | 
| 20 |  |  | 
| 21 |  | #pragma once | 
| 22 |  |  | 
| 23 |  | #include <fmt/format.h> | 
| 24 |  | #include <glog/logging.h> | 
| 25 |  |  | 
| 26 |  | #include <cstddef> | 
| 27 |  | #include <memory> | 
| 28 |  | #include <string> | 
| 29 |  | #include <utility> | 
| 30 |  |  | 
| 31 |  | #include "common/exception.h" | 
| 32 |  | #include "common/logging.h" | 
| 33 |  | #include "common/status.h" | 
| 34 |  | #include "olap/rowset/segment_v2/inverted_index_iterator.h" // IWYU pragma: keep | 
| 35 |  | #include "runtime/define_primitive_type.h" | 
| 36 |  | #include "udf/udf.h" | 
| 37 |  | #include "vec/core/block.h" | 
| 38 |  | #include "vec/core/column_numbers.h" | 
| 39 |  | #include "vec/core/column_with_type_and_name.h" | 
| 40 |  | #include "vec/core/columns_with_type_and_name.h" | 
| 41 |  | #include "vec/core/types.h" | 
| 42 |  | #include "vec/data_types/data_type.h" | 
| 43 |  | #include "vec/data_types/data_type_array.h" | 
| 44 |  | #include "vec/data_types/data_type_map.h" | 
| 45 |  | #include "vec/data_types/data_type_nullable.h" | 
| 46 |  | #include "vec/data_types/data_type_struct.h" | 
| 47 |  |  | 
| 48 |  | namespace doris::vectorized { | 
| 49 |  |  | 
| 50 |  | struct FunctionAttr { | 
| 51 |  |     bool enable_decimal256 {false}; | 
| 52 |  |     bool new_version_unix_timestamp {false}; | 
| 53 |  | }; | 
| 54 |  |  | 
| 55 |  | #define RETURN_REAL_TYPE_FOR_DATEV2_FUNCTION(TYPE)                                             \ | 
| 56 | 31 |     bool is_nullable = false;                                                                  \ | 
| 57 | 31 |     bool is_datev2 = false;                                                                    \ | 
| 58 | 53 |     for (auto it : arguments) {                                                                \ | 
| 59 | 53 |         is_nullable = is_nullable || it.type->is_nullable();                                   \ | 
| 60 | 53 |         is_datev2 = is_datev2 || it.type->get_primitive_type() == TYPE_DATEV2 ||               \ | 
| 61 | 53 |                     it.type->get_primitive_type() == TYPE_DATETIMEV2;                          \ | 
| 62 | 53 |     }                                                                                          \ | 
| 63 | 31 |     return is_nullable || !is_datev2                                                           \ | 
| 64 | 31 |                    ? make_nullable(                                                            \ | 
| 65 | 26 |                              std::make_shared<typename PrimitiveTypeTraits<TYPE>::DataType>()) \ | 
| 66 | 31 |                    : std::make_shared<typename PrimitiveTypeTraits<TYPE>::DataType>(); | 
| 67 |  |  | 
| 68 |  | #define SET_NULLMAP_IF_FALSE(EXPR) \ | 
| 69 |  |     if (!EXPR) [[unlikely]] {      \ | 
| 70 |  |         null_map[i] = true;        \ | 
| 71 |  |     } | 
| 72 |  |  | 
| 73 |  | class Field; | 
| 74 |  | class VExpr; | 
| 75 |  |  | 
| 76 |  | // Only use dispose the variadic argument | 
| 77 |  | template <typename T> | 
| 78 |  | auto has_variadic_argument_types(T&& arg) -> decltype(T::get_variadic_argument_types()) {}; | 
| 79 |  | void has_variadic_argument_types(...); | 
| 80 |  |  | 
| 81 |  | template <typename T> | 
| 82 |  | concept HasGetVariadicArgumentTypesImpl = requires(T t) { | 
| 83 |  |     { t.get_variadic_argument_types_impl() } -> std::same_as<DataTypes>; | 
| 84 |  | }; | 
| 85 |  |  | 
| 86 |  | bool have_null_column(const Block& block, const ColumnNumbers& args); | 
| 87 |  | bool have_null_column(const ColumnsWithTypeAndName& args); | 
| 88 |  |  | 
| 89 |  | /// The simplest executable object. | 
| 90 |  | /// Motivation: | 
| 91 |  | ///  * Prepare something heavy once before main execution loop instead of doing it for each block. | 
| 92 |  | ///  * Provide const interface for IFunctionBase (later). | 
| 93 |  | class IPreparedFunction { | 
| 94 |  | public: | 
| 95 | 102k |     virtual ~IPreparedFunction() = default; | 
| 96 |  |  | 
| 97 |  |     /// Get the main function name. | 
| 98 |  |     virtual String get_name() const = 0; | 
| 99 |  |  | 
| 100 |  |     virtual Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, | 
| 101 |  |                            uint32_t result, size_t input_rows_count, bool dry_run) const = 0; | 
| 102 |  | }; | 
| 103 |  |  | 
| 104 |  | using PreparedFunctionPtr = std::shared_ptr<IPreparedFunction>; | 
| 105 |  |  | 
| 106 |  | class PreparedFunctionImpl : public IPreparedFunction { | 
| 107 |  | public: | 
| 108 |  |     Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, | 
| 109 |  |                    uint32_t result, size_t input_rows_count, bool dry_run = false) const final; | 
| 110 |  |  | 
| 111 |  |     /** If the function have non-zero number of arguments, | 
| 112 |  |       *  and if all arguments are constant, that we could automatically provide default implementation: | 
| 113 |  |       *  arguments are converted to ordinary columns with single value which is not const, then function is executed as usual, | 
| 114 |  |       *  and then the result is converted to constant column. | 
| 115 |  |       */ | 
| 116 | 108k |     virtual bool use_default_implementation_for_constants() const { return true; } | 
| 117 |  |  | 
| 118 |  |     /** If use_default_implementation_for_nulls() is true, after execute the function, | 
| 119 |  |       * whether need to replace the nested data of null data to the default value. | 
| 120 |  |       * E.g. for binary arithmetic exprs, need return true to avoid false overflow. | 
| 121 |  |       */ | 
| 122 | 0 |     virtual bool need_replace_null_data_to_default() const { return false; } | 
| 123 |  |  | 
| 124 |  | protected: | 
| 125 |  |     virtual Status execute_impl_dry_run(FunctionContext* context, Block& block, | 
| 126 |  |                                         const ColumnNumbers& arguments, uint32_t result, | 
| 127 | 0 |                                         size_t input_rows_count) const { | 
| 128 | 0 |         return execute_impl(context, block, arguments, result, input_rows_count); | 
| 129 | 0 |     } | 
| 130 |  |  | 
| 131 |  |     virtual Status execute_impl(FunctionContext* context, Block& block, | 
| 132 |  |                                 const ColumnNumbers& arguments, uint32_t result, | 
| 133 |  |                                 size_t input_rows_count) const = 0; | 
| 134 |  |  | 
| 135 |  |     /** Default implementation in presence of Nullable arguments or NULL constants as arguments is the following: | 
| 136 |  |       *  if some of arguments are NULL constants then return NULL constant, | 
| 137 |  |       *  if some of arguments are Nullable, then execute function as usual for block, | 
| 138 |  |       *   where Nullable columns are substituted with nested columns (they have arbitrary values in rows corresponding to NULL value) | 
| 139 |  |       *   and wrap result in Nullable column where NULLs are in all rows where any of arguments are NULL. | 
| 140 |  |       */ | 
| 141 | 0 |     virtual bool use_default_implementation_for_nulls() const { return true; } | 
| 142 |  |  | 
| 143 | 0 |     virtual bool skip_return_type_check() const { return false; } | 
| 144 |  |  | 
| 145 |  |     /** Some arguments could remain constant during this implementation. | 
| 146 |  |       * Every argument required const must write here and no checks elsewhere. | 
| 147 |  |       */ | 
| 148 | 0 |     virtual ColumnNumbers get_arguments_that_are_always_constant() const { return {}; } | 
| 149 |  |  | 
| 150 |  | private: | 
| 151 |  |     Status default_implementation_for_nulls(FunctionContext* context, Block& block, | 
| 152 |  |                                             const ColumnNumbers& args, uint32_t result, | 
| 153 |  |                                             size_t input_rows_count, bool dry_run, | 
| 154 |  |                                             bool* executed) const; | 
| 155 |  |     Status default_implementation_for_constant_arguments(FunctionContext* context, Block& block, | 
| 156 |  |                                                          const ColumnNumbers& args, uint32_t result, | 
| 157 |  |                                                          size_t input_rows_count, bool dry_run, | 
| 158 |  |                                                          bool* executed) const; | 
| 159 |  |     Status execute_without_low_cardinality_columns(FunctionContext* context, Block& block, | 
| 160 |  |                                                    const ColumnNumbers& arguments, uint32_t result, | 
| 161 |  |                                                    size_t input_rows_count, bool dry_run) const; | 
| 162 |  |     Status _execute_skipped_constant_deal(FunctionContext* context, Block& block, | 
| 163 |  |                                           const ColumnNumbers& args, uint32_t result, | 
| 164 |  |                                           size_t input_rows_count, bool dry_run) const; | 
| 165 |  | }; | 
| 166 |  |  | 
| 167 |  | /// Function with known arguments and return type. | 
| 168 |  | class IFunctionBase { | 
| 169 |  | public: | 
| 170 | 117k |     virtual ~IFunctionBase() = default; | 
| 171 |  |  | 
| 172 |  |     /// Get the main function name. | 
| 173 |  |     virtual String get_name() const = 0; | 
| 174 |  |  | 
| 175 |  |     virtual const DataTypes& get_argument_types() const = 0; | 
| 176 |  |     virtual const DataTypePtr& get_return_type() const = 0; | 
| 177 |  |  | 
| 178 |  |     /// Do preparations and return executable. | 
| 179 |  |     /// sample_block should contain data types of arguments and values of constants, if relevant. | 
| 180 |  |     virtual PreparedFunctionPtr prepare(FunctionContext* context, const Block& sample_block, | 
| 181 |  |                                         const ColumnNumbers& arguments, uint32_t result) const = 0; | 
| 182 |  |  | 
| 183 |  |     /// Override this when function need to store state in the `FunctionContext`, or do some | 
| 184 |  |     /// preparation work according to information from `FunctionContext`. | 
| 185 | 74.4k |     virtual Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) { | 
| 186 | 74.4k |         return Status::OK(); | 
| 187 | 74.4k |     } | 
| 188 |  |  | 
| 189 |  |     Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, | 
| 190 | 99.9k |                    uint32_t result, size_t input_rows_count, bool dry_run = false) const { | 
| 191 | 99.9k |         try { | 
| 192 | 99.9k |             return prepare(context, block, arguments, result) | 
| 193 | 99.9k |                     ->execute(context, block, arguments, result, input_rows_count, dry_run); | 
| 194 | 99.9k |         } catch (const Exception& e) { | 
| 195 | 1 |             return e.to_status(); | 
| 196 | 1 |         } | 
| 197 | 99.9k |     } | 
| 198 |  |  | 
| 199 |  |     virtual Status evaluate_inverted_index( | 
| 200 |  |             const ColumnsWithTypeAndName& arguments, | 
| 201 |  |             const std::vector<vectorized::IndexFieldNameAndTypePair>& data_type_with_names, | 
| 202 |  |             std::vector<segment_v2::IndexIterator*> iterators, uint32_t num_rows, | 
| 203 | 0 |             segment_v2::InvertedIndexResultBitmap& bitmap_result) const { | 
| 204 | 0 |         return Status::OK(); | 
| 205 | 0 |     } | 
| 206 |  |  | 
| 207 |  |     /// Do cleaning work when function is finished, i.e., release state variables in the | 
| 208 |  |     /// `FunctionContext` which are registered in `prepare` phase. | 
| 209 | 51.1k |     virtual Status close(FunctionContext* context, FunctionContext::FunctionStateScope scope) { | 
| 210 | 51.1k |         return Status::OK(); | 
| 211 | 51.1k |     } | 
| 212 |  |  | 
| 213 |  |     virtual bool is_use_default_implementation_for_constants() const = 0; | 
| 214 |  |  | 
| 215 | 0 |     virtual bool is_udf_function() const { return false; } | 
| 216 |  |  | 
| 217 | 0 |     virtual bool can_push_down_to_index() const { return false; } | 
| 218 |  |  | 
| 219 | 0 |     virtual bool is_blockable() const { return false; } | 
| 220 |  | }; | 
| 221 |  |  | 
| 222 |  | using FunctionBasePtr = std::shared_ptr<IFunctionBase>; | 
| 223 |  |  | 
| 224 |  | /// Creates IFunctionBase from argument types list. | 
| 225 |  | class IFunctionBuilder { | 
| 226 |  | public: | 
| 227 | 119k |     virtual ~IFunctionBuilder() = default; | 
| 228 |  |  | 
| 229 |  |     /// Get the main function name. | 
| 230 |  |     virtual String get_name() const = 0; | 
| 231 |  |  | 
| 232 |  |     /// Override and return true if function could take different number of arguments. | 
| 233 |  |     ///TODO: this function is not actually used now. but in check_number_of_arguments we still need it because for many | 
| 234 |  |     /// functions we didn't set the correct number of arguments. | 
| 235 |  |     virtual bool is_variadic() const = 0; | 
| 236 |  |  | 
| 237 |  |     /// For non-variadic functions, return number of arguments; otherwise return zero (that should be ignored). | 
| 238 |  |     virtual size_t get_number_of_arguments() const = 0; | 
| 239 |  |  | 
| 240 |  |     /// Throw if number of arguments is incorrect. Default implementation will check only in non-variadic case. | 
| 241 |  |     virtual void check_number_of_arguments(size_t number_of_arguments) const = 0; | 
| 242 |  |  | 
| 243 |  |     /// Check arguments and return IFunctionBase. | 
| 244 |  |     virtual FunctionBasePtr build(const ColumnsWithTypeAndName& arguments, | 
| 245 |  |                                   const DataTypePtr& return_type) const = 0; | 
| 246 |  |  | 
| 247 |  |     /// For higher-order functions (functions, that have lambda expression as at least one argument). | 
| 248 |  |     /// You pass data types with empty DataTypeFunction for lambda arguments. | 
| 249 |  |     /// This function will replace it with DataTypeFunction containing actual types. | 
| 250 |  |     virtual DataTypes get_variadic_argument_types() const = 0; | 
| 251 |  |  | 
| 252 |  |     /// Returns indexes of arguments, that must be ColumnConst | 
| 253 |  |     virtual ColumnNumbers get_arguments_that_are_always_constant() const = 0; | 
| 254 |  | }; | 
| 255 |  |  | 
| 256 |  | using FunctionBuilderPtr = std::shared_ptr<IFunctionBuilder>; | 
| 257 |  |  | 
| 258 | 3 | inline std::string get_types_string(const ColumnsWithTypeAndName& arguments) { | 
| 259 | 3 |     std::string types; | 
| 260 | 3 |     for (const auto& argument : arguments) { | 
| 261 | 2 |         if (!types.empty()) { | 
| 262 | 1 |             types += ", "; | 
| 263 | 1 |         } | 
| 264 | 2 |         types += argument.type->get_name(); | 
| 265 | 2 |     } | 
| 266 | 3 |     return types; | 
| 267 | 3 | } | 
| 268 |  |  | 
| 269 |  | /// used in function_factory. when we register a function, save a builder. to get a function, to get a builder. | 
| 270 |  | /// will use DefaultFunctionBuilder as the default builder in function's registration if we didn't explicitly specify. | 
| 271 |  | class FunctionBuilderImpl : public IFunctionBuilder { | 
| 272 |  | public: | 
| 273 |  |     FunctionBasePtr build(const ColumnsWithTypeAndName& arguments, | 
| 274 | 100k |                           const DataTypePtr& return_type) const final { | 
| 275 | 100k |         if (skip_return_type_check()) { | 
| 276 | 85.9k |             return build_impl(arguments, return_type); | 
| 277 | 85.9k |         } | 
| 278 | 14.4k |         const DataTypePtr& func_return_type = get_return_type(arguments); | 
| 279 | 14.4k |         if (func_return_type == nullptr) { | 
| 280 | 1 |             throw doris::Exception( | 
| 281 | 1 |                     ErrorCode::INTERNAL_ERROR, | 
| 282 | 1 |                     "function return type check failed, function_name={}, " | 
| 283 | 1 |                     "expect_return_type={}, real_return_type is nullptr, input_arguments={}", | 
| 284 | 1 |                     get_name(), return_type->get_name(), get_types_string(arguments)); | 
| 285 | 1 |         } | 
| 286 |  |  | 
| 287 |  |         // check return types equal. | 
| 288 | 14.4k |         if (!(return_type->equals(*func_return_type) || | 
| 289 |  |               // For null constant argument, `get_return_type` would return | 
| 290 |  |               // Nullable<DataTypeNothing> when `use_default_implementation_for_nulls` is true. | 
| 291 | 14.4k |               (return_type->is_nullable() && func_return_type->is_nullable() && | 
| 292 | 9 |                ((DataTypeNullable*)func_return_type.get()) | 
| 293 | 4 |                                ->get_nested_type() | 
| 294 | 4 |                                ->get_primitive_type() == INVALID_TYPE) || | 
| 295 | 14.4k |               is_date_or_datetime_or_decimal(return_type, func_return_type) || | 
| 296 | 14.4k |               is_nested_type_date_or_datetime_or_decimal(return_type, func_return_type))) { | 
| 297 | 2 |             throw doris::Exception( | 
| 298 | 2 |                     ErrorCode::INTERNAL_ERROR, | 
| 299 | 2 |                     "function return type check failed, function_name={}, " | 
| 300 | 2 |                     "fe plan return type={},  be real return type={}, input_arguments={}", | 
| 301 | 2 |                     get_name(), return_type->get_name(), func_return_type->get_name(), | 
| 302 | 2 |                     get_types_string(arguments)); | 
| 303 | 2 |         } | 
| 304 | 14.4k |         return build_impl(arguments, return_type); | 
| 305 | 14.4k |     } | 
| 306 |  |  | 
| 307 | 10.7k |     bool is_variadic() const override { return false; } | 
| 308 |  |  | 
| 309 |  |     // Default implementation. Will check only in non-variadic case. | 
| 310 |  |     void check_number_of_arguments(size_t number_of_arguments) const override; | 
| 311 |  |     // the return type should be same with what FE plans. | 
| 312 |  |     // it returns: `get_return_type_impl` if `use_default_implementation_for_nulls` = false | 
| 313 |  |     //  `get_return_type_impl` warpped in NULL if `use_default_implementation_for_nulls` = true and input has NULL | 
| 314 |  |     DataTypePtr get_return_type(const ColumnsWithTypeAndName& arguments) const; | 
| 315 |  |  | 
| 316 | 1.08k |     DataTypes get_variadic_argument_types() const override { | 
| 317 | 1.08k |         return get_variadic_argument_types_impl(); | 
| 318 | 1.08k |     } | 
| 319 |  |  | 
| 320 | 0 |     ColumnNumbers get_arguments_that_are_always_constant() const override { return {}; } | 
| 321 |  |  | 
| 322 |  | protected: | 
| 323 |  |     // Get the result type by argument type. If the function does not apply to these arguments, throw an exception. | 
| 324 |  |     // the get_return_type_impl and its overrides should only return the nested type if `use_default_implementation_for_nulls` is true. | 
| 325 |  |     // whether to wrap in nullable type will be automatically decided. | 
| 326 | 14.2k |     virtual DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const { | 
| 327 | 14.2k |         DataTypes data_types(arguments.size()); | 
| 328 | 53.0k |         for (size_t i = 0; i < arguments.size(); ++i) { | 
| 329 | 38.7k |             data_types[i] = arguments[i].type; | 
| 330 | 38.7k |         } | 
| 331 | 14.2k |         return get_return_type_impl(data_types); | 
| 332 | 14.2k |     } | 
| 333 |  |  | 
| 334 | 0 |     virtual DataTypePtr get_return_type_impl(const DataTypes& /*arguments*/) const { | 
| 335 | 0 |         throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, | 
| 336 | 0 |                                "get_return_type is not implemented for {}", get_name()); | 
| 337 | 0 |         return nullptr; | 
| 338 | 0 |     } | 
| 339 |  |  | 
| 340 |  |     /** If use_default_implementation_for_nulls() is true, than change arguments for get_return_type() and build_impl(): | 
| 341 |  |       *  if some of arguments are Nullable(Nothing) then don't call get_return_type(), call build_impl() with return_type = Nullable(Nothing), | 
| 342 |  |       *  if some of arguments are Nullable, then: | 
| 343 |  |       *   - Nullable types are substituted with nested types for get_return_type() function | 
| 344 |  |       *   - WRAP get_return_type() RESULT IN NULLABLE type and pass to build_impl | 
| 345 |  |       * | 
| 346 |  |       * Otherwise build returns build_impl(arguments, get_return_type(arguments)); | 
| 347 |  |       */ | 
| 348 | 0 |     virtual bool use_default_implementation_for_nulls() const { return true; } | 
| 349 |  |  | 
| 350 | 0 |     virtual bool skip_return_type_check() const { return false; } | 
| 351 |  |  | 
| 352 | 0 |     virtual bool need_replace_null_data_to_default() const { return false; } | 
| 353 |  |  | 
| 354 |  |     /// return a real function object to execute. called in build(...). | 
| 355 |  |     virtual FunctionBasePtr build_impl(const ColumnsWithTypeAndName& arguments, | 
| 356 |  |                                        const DataTypePtr& return_type) const = 0; | 
| 357 |  |  | 
| 358 | 364 |     virtual DataTypes get_variadic_argument_types_impl() const { return {}; } | 
| 359 |  |  | 
| 360 |  | private: | 
| 361 |  |     bool is_date_or_datetime_or_decimal(const DataTypePtr& return_type, | 
| 362 |  |                                         const DataTypePtr& func_return_type) const; | 
| 363 |  |     bool is_nested_type_date_or_datetime_or_decimal(const DataTypePtr& return_type, | 
| 364 |  |                                                     const DataTypePtr& func_return_type) const; | 
| 365 |  | }; | 
| 366 |  |  | 
| 367 |  | /// Previous function interface. | 
| 368 |  | class IFunction : public std::enable_shared_from_this<IFunction>, | 
| 369 |  |                   public FunctionBuilderImpl, | 
| 370 |  |                   public IFunctionBase, | 
| 371 |  |                   public PreparedFunctionImpl { | 
| 372 |  | public: | 
| 373 |  |     String get_name() const override = 0; | 
| 374 |  |  | 
| 375 |  |     /// Notice: We should not change the column in the block, because the column may be shared by multiple expressions or exec nodes. | 
| 376 |  |     Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, | 
| 377 |  |                         uint32_t result, size_t input_rows_count) const override = 0; | 
| 378 |  |  | 
| 379 |  |     /// Override this functions to change default implementation behavior. See details in IMyFunction. | 
| 380 | 35.6k |     bool use_default_implementation_for_nulls() const override { return true; } | 
| 381 |  |  | 
| 382 | 14.4k |     bool skip_return_type_check() const override { return false; } | 
| 383 |  |  | 
| 384 | 8.75k |     bool need_replace_null_data_to_default() const override { return false; } | 
| 385 |  |  | 
| 386 |  |     /// all constancy check should use this function to do automatically | 
| 387 | 23.3k |     ColumnNumbers get_arguments_that_are_always_constant() const override { return {}; } | 
| 388 |  |  | 
| 389 | 43 |     bool is_use_default_implementation_for_constants() const override { | 
| 390 | 43 |         return use_default_implementation_for_constants(); | 
| 391 | 43 |     } | 
| 392 |  |  | 
| 393 |  |     using PreparedFunctionImpl::execute; | 
| 394 |  |     using PreparedFunctionImpl::execute_impl_dry_run; | 
| 395 |  |     using FunctionBuilderImpl::get_return_type_impl; | 
| 396 |  |     using FunctionBuilderImpl::get_variadic_argument_types_impl; | 
| 397 |  |     using FunctionBuilderImpl::get_return_type; | 
| 398 |  |  | 
| 399 |  |     [[noreturn]] PreparedFunctionPtr prepare(FunctionContext* context, | 
| 400 |  |                                              const Block& /*sample_block*/, | 
| 401 |  |                                              const ColumnNumbers& /*arguments*/, | 
| 402 | 0 |                                              uint32_t /*result*/) const final { | 
| 403 | 0 |         throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, | 
| 404 | 0 |                                "prepare is not implemented for IFunction {}", get_name()); | 
| 405 | 0 |         __builtin_unreachable(); | 
| 406 | 0 |     } | 
| 407 |  |  | 
| 408 | 26.6k |     Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { | 
| 409 | 26.6k |         return Status::OK(); | 
| 410 | 26.6k |     } | 
| 411 |  |  | 
| 412 | 0 |     [[noreturn]] const DataTypes& get_argument_types() const final { | 
| 413 | 0 |         throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, | 
| 414 | 0 |                                "get_argument_types is not implemented for IFunction {}", | 
| 415 | 0 |                                get_name()); | 
| 416 | 0 |         __builtin_unreachable(); | 
| 417 | 0 |     } | 
| 418 |  |  | 
| 419 | 0 |     [[noreturn]] const DataTypePtr& get_return_type() const final { | 
| 420 | 0 |         throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, | 
| 421 | 0 |                                "get_return_type is not implemented for IFunction {}", get_name()); | 
| 422 | 0 |         __builtin_unreachable(); | 
| 423 | 0 |     } | 
| 424 |  |  | 
| 425 |  | protected: | 
| 426 |  |     FunctionBasePtr build_impl(const ColumnsWithTypeAndName& /*arguments*/, | 
| 427 | 0 |                                const DataTypePtr& /*return_type*/) const final { | 
| 428 | 0 |         throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, | 
| 429 | 0 |                                "build_impl is not implemented for IFunction {}", get_name()); | 
| 430 | 0 |         __builtin_unreachable(); | 
| 431 | 0 |         return {}; | 
| 432 | 0 |     } | 
| 433 |  | }; | 
| 434 |  |  | 
| 435 |  | /* | 
| 436 |  |  * when we register a function which didn't specify its base(i.e. inherited from IFunction), actually we use this as a wrapper. | 
| 437 |  |  * it saves real implementation as `function`.  | 
| 438 |  | */ | 
| 439 |  | class DefaultFunction final : public IFunctionBase { | 
| 440 |  | public: | 
| 441 |  |     DefaultFunction(std::shared_ptr<IFunction> function_, DataTypes arguments_, | 
| 442 |  |                     DataTypePtr return_type_) | 
| 443 | 14.5k |             : function(std::move(function_)), | 
| 444 | 14.5k |               arguments(std::move(arguments_)), | 
| 445 | 14.5k |               return_type(std::move(return_type_)) {} | 
| 446 |  |  | 
| 447 | 0 |     String get_name() const override { return function->get_name(); } | 
| 448 |  |  | 
| 449 | 0 |     const DataTypes& get_argument_types() const override { return arguments; } | 
| 450 | 1 |     const DataTypePtr& get_return_type() const override { return return_type; } | 
| 451 |  |  | 
| 452 |  |     // return a default wrapper for IFunction. | 
| 453 |  |     PreparedFunctionPtr prepare(FunctionContext* context, const Block& /*sample_block*/, | 
| 454 |  |                                 const ColumnNumbers& /*arguments*/, | 
| 455 | 14.5k |                                 uint32_t /*result*/) const override { | 
| 456 | 14.5k |         return function; | 
| 457 | 14.5k |     } | 
| 458 |  |  | 
| 459 | 28.3k |     Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { | 
| 460 | 28.3k |         return function->open(context, scope); | 
| 461 | 28.3k |     } | 
| 462 |  |  | 
| 463 | 28.3k |     Status close(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { | 
| 464 | 28.3k |         return function->close(context, scope); | 
| 465 | 28.3k |     } | 
| 466 |  |  | 
| 467 |  |     Status evaluate_inverted_index( | 
| 468 |  |             const ColumnsWithTypeAndName& args, | 
| 469 |  |             const std::vector<vectorized::IndexFieldNameAndTypePair>& data_type_with_names, | 
| 470 |  |             std::vector<segment_v2::IndexIterator*> iterators, uint32_t num_rows, | 
| 471 | 0 |             segment_v2::InvertedIndexResultBitmap& bitmap_result) const override { | 
| 472 | 0 |         return function->evaluate_inverted_index(args, data_type_with_names, iterators, num_rows, | 
| 473 | 0 |                                                  bitmap_result); | 
| 474 | 0 |     } | 
| 475 |  |  | 
| 476 | 43 |     bool is_use_default_implementation_for_constants() const override { | 
| 477 | 43 |         return function->is_use_default_implementation_for_constants(); | 
| 478 | 43 |     } | 
| 479 |  |  | 
| 480 | 0 |     bool can_push_down_to_index() const override { return function->can_push_down_to_index(); } | 
| 481 |  |  | 
| 482 | 0 |     bool is_blockable() const override { return function->is_blockable(); } | 
| 483 |  |  | 
| 484 |  | private: | 
| 485 |  |     std::shared_ptr<IFunction> function; | 
| 486 |  |     DataTypes arguments; | 
| 487 |  |     DataTypePtr return_type; | 
| 488 |  | }; | 
| 489 |  |  | 
| 490 |  | class DefaultFunctionBuilder : public FunctionBuilderImpl { | 
| 491 |  | public: | 
| 492 |  |     explicit DefaultFunctionBuilder(std::shared_ptr<IFunction> function_) | 
| 493 | 16.6k |             : function(std::move(function_)) {} | 
| 494 |  |  | 
| 495 | 14.4k |     void check_number_of_arguments(size_t number_of_arguments) const override { | 
| 496 | 14.4k |         function->check_number_of_arguments(number_of_arguments); | 
| 497 | 14.4k |     } | 
| 498 |  |  | 
| 499 | 499 |     String get_name() const override { return function->get_name(); } | 
| 500 | 1.05k |     bool is_variadic() const override { return function->is_variadic(); } | 
| 501 | 0 |     size_t get_number_of_arguments() const override { return function->get_number_of_arguments(); } | 
| 502 |  |  | 
| 503 | 0 |     ColumnNumbers get_arguments_that_are_always_constant() const override { | 
| 504 | 0 |         return function->get_arguments_that_are_always_constant(); | 
| 505 | 0 |     } | 
| 506 |  |  | 
| 507 |  | protected: | 
| 508 | 0 |     DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { | 
| 509 | 0 |         return function->get_return_type_impl(arguments); | 
| 510 | 0 |     } | 
| 511 | 14.4k |     DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const override { | 
| 512 | 14.4k |         return function->get_return_type_impl(arguments); | 
| 513 | 14.4k |     } | 
| 514 |  |  | 
| 515 | 14.4k |     bool use_default_implementation_for_nulls() const override { | 
| 516 | 14.4k |         return function->use_default_implementation_for_nulls(); | 
| 517 | 14.4k |     } | 
| 518 |  |  | 
| 519 | 14.4k |     bool skip_return_type_check() const override { return function->skip_return_type_check(); } | 
| 520 |  |  | 
| 521 | 0 |     bool need_replace_null_data_to_default() const override { | 
| 522 | 0 |         return function->need_replace_null_data_to_default(); | 
| 523 | 0 |     } | 
| 524 |  |  | 
| 525 |  |     FunctionBasePtr build_impl(const ColumnsWithTypeAndName& arguments, | 
| 526 | 14.4k |                                const DataTypePtr& return_type) const override { | 
| 527 | 14.4k |         DataTypes data_types(arguments.size()); | 
| 528 | 53.6k |         for (size_t i = 0; i < arguments.size(); ++i) { | 
| 529 | 39.1k |             data_types[i] = arguments[i].type; | 
| 530 | 39.1k |         } | 
| 531 | 14.4k |         return std::make_shared<DefaultFunction>(function, data_types, return_type); | 
| 532 | 14.4k |     } | 
| 533 |  |  | 
| 534 | 1.08k |     DataTypes get_variadic_argument_types_impl() const override { | 
| 535 | 1.08k |         return function->get_variadic_argument_types_impl(); | 
| 536 | 1.08k |     } | 
| 537 |  |  | 
| 538 |  | private: | 
| 539 |  |     std::shared_ptr<IFunction> function; | 
| 540 |  | }; | 
| 541 |  |  | 
| 542 |  | using FunctionPtr = std::shared_ptr<IFunction>; | 
| 543 |  |  | 
| 544 |  | /** Return ColumnNullable of src, with null map as OR-ed null maps of args columns in blocks. | 
| 545 |  |   * Or ColumnConst(ColumnNullable) if the result is always NULL or if the result is constant and always not NULL. | 
| 546 |  |   */ | 
| 547 |  | ColumnPtr wrap_in_nullable(const ColumnPtr& src, const Block& block, const ColumnNumbers& args, | 
| 548 |  |                            uint32_t result, size_t input_rows_count); | 
| 549 |  |  | 
| 550 |  | } // namespace doris::vectorized |