/root/doris/be/src/vec/functions/function.h
Line | Count | Source (jump to first uncovered line) |
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/status.h" |
33 | | #include "olap/rowset/segment_v2/inverted_index_reader.h" |
34 | | #include "udf/udf.h" |
35 | | #include "vec/core/block.h" |
36 | | #include "vec/core/column_numbers.h" |
37 | | #include "vec/core/column_with_type_and_name.h" |
38 | | #include "vec/core/columns_with_type_and_name.h" |
39 | | #include "vec/core/types.h" |
40 | | #include "vec/data_types/data_type.h" |
41 | | #include "vec/data_types/data_type_nullable.h" |
42 | | |
43 | | namespace doris::segment_v2 { |
44 | | struct FuncExprParams; |
45 | | } // namespace doris::segment_v2 |
46 | | |
47 | | namespace doris::vectorized { |
48 | | |
49 | | struct FunctionAttr { |
50 | | bool enable_decimal256 {false}; |
51 | | }; |
52 | | |
53 | | #define RETURN_REAL_TYPE_FOR_DATEV2_FUNCTION(TYPE) \ |
54 | 98 | bool is_nullable = false; \ |
55 | 98 | bool is_datev2 = false; \ |
56 | 149 | for (auto it : arguments) { \ |
57 | 149 | is_nullable = is_nullable || it.type->is_nullable(); \ |
58 | 149 | is_datev2 = is_datev2 || WhichDataType(remove_nullable(it.type)).is_date_v2() || \ |
59 | 149 | WhichDataType(remove_nullable(it.type)).is_date_time_v2(); \ |
60 | 149 | } \ |
61 | 102 | return is_nullable || !is_datev2 ? make_nullable(std::make_shared<TYPE>()) \ |
62 | 98 | : std::make_shared<TYPE>(); |
63 | | |
64 | | #define SET_NULLMAP_IF_FALSE(EXPR) \ |
65 | 0 | if (!EXPR) [[unlikely]] { \ |
66 | 0 | null_map[i] = true; \ |
67 | 0 | } |
68 | | |
69 | | class Field; |
70 | | class VExpr; |
71 | | |
72 | | // Only use dispose the variadic argument |
73 | | template <typename T> |
74 | | auto has_variadic_argument_types(T&& arg) -> decltype(T::get_variadic_argument_types()) {}; |
75 | | void has_variadic_argument_types(...); |
76 | | |
77 | | template <typename T> |
78 | | concept HasGetVariadicArgumentTypesImpl = requires(T t) { |
79 | | { t.get_variadic_argument_types_impl() } -> std::same_as<DataTypes>; |
80 | | }; |
81 | | |
82 | | bool have_null_column(const Block& block, const ColumnNumbers& args); |
83 | | bool have_null_column(const ColumnsWithTypeAndName& args); |
84 | | |
85 | | /// The simplest executable object. |
86 | | /// Motivation: |
87 | | /// * Prepare something heavy once before main execution loop instead of doing it for each block. |
88 | | /// * Provide const interface for IFunctionBase (later). |
89 | | class IPreparedFunction { |
90 | | public: |
91 | 29.2k | virtual ~IPreparedFunction() = default; |
92 | | |
93 | | /// Get the main function name. |
94 | | virtual String get_name() const = 0; |
95 | | |
96 | | virtual Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
97 | | uint32_t result, size_t input_rows_count, bool dry_run) const = 0; |
98 | | }; |
99 | | |
100 | | using PreparedFunctionPtr = std::shared_ptr<IPreparedFunction>; |
101 | | |
102 | | class PreparedFunctionImpl : public IPreparedFunction { |
103 | | public: |
104 | | Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
105 | | uint32_t result, size_t input_rows_count, bool dry_run = false) const final; |
106 | | |
107 | | /** If the function have non-zero number of arguments, |
108 | | * and if all arguments are constant, that we could automatically provide default implementation: |
109 | | * arguments are converted to ordinary columns with single value which is not const, then function is executed as usual, |
110 | | * and then the result is converted to constant column. |
111 | | */ |
112 | 20.7k | virtual bool use_default_implementation_for_constants() const { return true; } |
113 | | |
114 | | /** If use_default_implementation_for_nulls() is true, after execute the function, |
115 | | * whether need to replace the nested data of null data to the default value. |
116 | | * E.g. for binary arithmetic exprs, need return true to avoid false overflow. |
117 | | */ |
118 | 0 | virtual bool need_replace_null_data_to_default() const { return false; } |
119 | | |
120 | | protected: |
121 | | virtual Status execute_impl_dry_run(FunctionContext* context, Block& block, |
122 | | const ColumnNumbers& arguments, uint32_t result, |
123 | 0 | size_t input_rows_count) const { |
124 | 0 | return execute_impl(context, block, arguments, result, input_rows_count); |
125 | 0 | } |
126 | | |
127 | | virtual Status execute_impl(FunctionContext* context, Block& block, |
128 | | const ColumnNumbers& arguments, uint32_t result, |
129 | | size_t input_rows_count) const = 0; |
130 | | |
131 | | /** Default implementation in presence of Nullable arguments or NULL constants as arguments is the following: |
132 | | * if some of arguments are NULL constants then return NULL constant, |
133 | | * if some of arguments are Nullable, then execute function as usual for block, |
134 | | * where Nullable columns are substituted with nested columns (they have arbitrary values in rows corresponding to NULL value) |
135 | | * and wrap result in Nullable column where NULLs are in all rows where any of arguments are NULL. |
136 | | */ |
137 | 0 | virtual bool use_default_implementation_for_nulls() const { return true; } |
138 | | |
139 | | /** If function arguments has single low cardinality column and all other arguments are constants, call function on nested column. |
140 | | * Otherwise, convert all low cardinality columns to ordinary columns. |
141 | | * Returns ColumnLowCardinality if at least one argument is ColumnLowCardinality. |
142 | | */ |
143 | 0 | virtual bool use_default_implementation_for_low_cardinality_columns() const { return true; } |
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 | 29.1k | 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 | 260 | virtual Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) { |
186 | 260 | return Status::OK(); |
187 | 260 | } |
188 | | |
189 | | /// TODO: make const |
190 | | virtual Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
191 | 14.2k | uint32_t result, size_t input_rows_count, bool dry_run = false) const { |
192 | 14.2k | return prepare(context, block, arguments, result) |
193 | 14.2k | ->execute(context, block, arguments, result, input_rows_count, dry_run); |
194 | 14.2k | } |
195 | | |
196 | | virtual Status evaluate_inverted_index( |
197 | | const ColumnsWithTypeAndName& arguments, |
198 | | const std::vector<vectorized::IndexFieldNameAndTypePair>& data_type_with_names, |
199 | | std::vector<segment_v2::InvertedIndexIterator*> iterators, uint32_t num_rows, |
200 | 0 | segment_v2::InvertedIndexResultBitmap& bitmap_result) const { |
201 | 0 | return Status::OK(); |
202 | 0 | } |
203 | | |
204 | | /// Do cleaning work when function is finished, i.e., release state variables in the |
205 | | /// `FunctionContext` which are registered in `prepare` phase. |
206 | 21.8k | virtual Status close(FunctionContext* context, FunctionContext::FunctionStateScope scope) { |
207 | 21.8k | return Status::OK(); |
208 | 21.8k | } |
209 | | |
210 | | virtual bool is_use_default_implementation_for_constants() const = 0; |
211 | | |
212 | 0 | virtual bool is_udf_function() const { return false; } |
213 | | |
214 | 0 | virtual bool can_push_down_to_index() const { return false; } |
215 | | }; |
216 | | |
217 | | using FunctionBasePtr = std::shared_ptr<IFunctionBase>; |
218 | | |
219 | | /// Creates IFunctionBase from argument types list. |
220 | | class IFunctionBuilder { |
221 | | public: |
222 | 30.0k | virtual ~IFunctionBuilder() = default; |
223 | | |
224 | | /// Get the main function name. |
225 | | virtual String get_name() const = 0; |
226 | | |
227 | | /// Override and return true if function could take different number of arguments. |
228 | | virtual bool is_variadic() const = 0; |
229 | | |
230 | | /// For non-variadic functions, return number of arguments; otherwise return zero (that should be ignored). |
231 | | virtual size_t get_number_of_arguments() const = 0; |
232 | | |
233 | | /// Throw if number of arguments is incorrect. Default implementation will check only in non-variadic case. |
234 | | virtual void check_number_of_arguments(size_t number_of_arguments) const = 0; |
235 | | |
236 | | /// Check arguments and return IFunctionBase. |
237 | | virtual FunctionBasePtr build(const ColumnsWithTypeAndName& arguments, |
238 | | const DataTypePtr& return_type) const = 0; |
239 | | |
240 | | /// For higher-order functions (functions, that have lambda expression as at least one argument). |
241 | | /// You pass data types with empty DataTypeFunction for lambda arguments. |
242 | | /// This function will replace it with DataTypeFunction containing actual types. |
243 | | virtual DataTypes get_variadic_argument_types() const = 0; |
244 | | |
245 | | /// Returns indexes of arguments, that must be ColumnConst |
246 | | virtual ColumnNumbers get_arguments_that_are_always_constant() const = 0; |
247 | | }; |
248 | | |
249 | | using FunctionBuilderPtr = std::shared_ptr<IFunctionBuilder>; |
250 | | |
251 | 0 | inline std::string get_types_string(const ColumnsWithTypeAndName& arguments) { |
252 | 0 | std::string types; |
253 | 0 | for (const auto& argument : arguments) { |
254 | 0 | if (!types.empty()) { |
255 | 0 | types += ", "; |
256 | 0 | } |
257 | 0 | types += argument.type->get_name(); |
258 | 0 | } |
259 | 0 | return types; |
260 | 0 | } |
261 | | |
262 | | /// used in function_factory. when we register a function, save a builder. to get a function, to get a builder. |
263 | | /// will use DefaultFunctionBuilder as the default builder in function's registration if we didn't explicitly specify. |
264 | | class FunctionBuilderImpl : public IFunctionBuilder { |
265 | | public: |
266 | | FunctionBasePtr build(const ColumnsWithTypeAndName& arguments, |
267 | 14.2k | const DataTypePtr& return_type) const final { |
268 | 14.2k | const DataTypePtr& func_return_type = get_return_type(arguments); |
269 | | // check return types equal. |
270 | 14.2k | if (!(return_type->equals(*func_return_type) || |
271 | | // For null constant argument, `get_return_type` would return |
272 | | // Nullable<DataTypeNothing> when `use_default_implementation_for_nulls` is true. |
273 | 14.2k | (return_type->is_nullable() && func_return_type->is_nullable() && |
274 | 2 | is_nothing(((DataTypeNullable*)func_return_type.get())->get_nested_type())) || |
275 | 14.2k | is_date_or_datetime_or_decimal(return_type, func_return_type) || |
276 | 14.2k | is_array_nested_type_date_or_datetime_or_decimal(return_type, func_return_type))) { |
277 | 0 | LOG_WARNING( |
278 | 0 | "function return type check failed, function_name={}, " |
279 | 0 | "expect_return_type={}, real_return_type={}, input_arguments={}", |
280 | 0 | get_name(), return_type->get_name(), func_return_type->get_name(), |
281 | 0 | get_types_string(arguments)); |
282 | 0 | return nullptr; |
283 | 0 | } |
284 | 14.2k | return build_impl(arguments, return_type); |
285 | 14.2k | } |
286 | | |
287 | 9.77k | bool is_variadic() const override { return false; } |
288 | | |
289 | | // Default implementation. Will check only in non-variadic case. |
290 | | void check_number_of_arguments(size_t number_of_arguments) const override; |
291 | | // the return type should be same with what FE plans. |
292 | | // it returns: `get_return_type_impl` if `use_default_implementation_for_nulls` = false |
293 | | // `get_return_type_impl` warpped in NULL if `use_default_implementation_for_nulls` = true and input has NULL |
294 | | DataTypePtr get_return_type(const ColumnsWithTypeAndName& arguments) const; |
295 | | |
296 | 854 | DataTypes get_variadic_argument_types() const override { |
297 | 854 | return get_variadic_argument_types_impl(); |
298 | 854 | } |
299 | | |
300 | 0 | ColumnNumbers get_arguments_that_are_always_constant() const override { return {}; } |
301 | | |
302 | | protected: |
303 | | // Get the result type by argument type. If the function does not apply to these arguments, throw an exception. |
304 | | // the get_return_type_impl and its overrides should only return the nested type if `use_default_implementation_for_nulls` is true. |
305 | | // whether to wrap in nullable type will be automatically decided. |
306 | 13.9k | virtual DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const { |
307 | 13.9k | DataTypes data_types(arguments.size()); |
308 | 47.1k | for (size_t i = 0; i < arguments.size(); ++i) { |
309 | 33.1k | data_types[i] = arguments[i].type; |
310 | 33.1k | } |
311 | 13.9k | return get_return_type_impl(data_types); |
312 | 13.9k | } |
313 | | |
314 | 0 | virtual DataTypePtr get_return_type_impl(const DataTypes& /*arguments*/) const { |
315 | 0 | throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, |
316 | 0 | "get_return_type is not implemented for {}", get_name()); |
317 | 0 | return nullptr; |
318 | 0 | } |
319 | | |
320 | | /** If use_default_implementation_for_nulls() is true, than change arguments for get_return_type() and build_impl(): |
321 | | * if some of arguments are Nullable(Nothing) then don't call get_return_type(), call build_impl() with return_type = Nullable(Nothing), |
322 | | * if some of arguments are Nullable, then: |
323 | | * - Nullable types are substituted with nested types for get_return_type() function |
324 | | * - WRAP get_return_type() RESULT IN NULLABLE type and pass to build_impl |
325 | | * |
326 | | * Otherwise build returns build_impl(arguments, get_return_type(arguments)); |
327 | | */ |
328 | 0 | virtual bool use_default_implementation_for_nulls() const { return true; } |
329 | | |
330 | 0 | virtual bool need_replace_null_data_to_default() const { return false; } |
331 | | |
332 | | /** If use_default_implementation_for_nulls() is true, than change arguments for get_return_type() and build_impl(). |
333 | | * If function arguments has low cardinality types, convert them to ordinary types. |
334 | | * get_return_type returns ColumnLowCardinality if at least one argument type is ColumnLowCardinality. |
335 | | */ |
336 | 0 | virtual bool use_default_implementation_for_low_cardinality_columns() const { return true; } |
337 | | |
338 | | /// return a real function object to execute. called in build(...). |
339 | | virtual FunctionBasePtr build_impl(const ColumnsWithTypeAndName& arguments, |
340 | | const DataTypePtr& return_type) const = 0; |
341 | | |
342 | 304 | virtual DataTypes get_variadic_argument_types_impl() const { return {}; } |
343 | | |
344 | | private: |
345 | | DataTypePtr get_return_type_without_low_cardinality( |
346 | | const ColumnsWithTypeAndName& arguments) const; |
347 | | |
348 | | bool is_date_or_datetime_or_decimal(const DataTypePtr& return_type, |
349 | | const DataTypePtr& func_return_type) const; |
350 | | bool is_array_nested_type_date_or_datetime_or_decimal( |
351 | | const DataTypePtr& return_type, const DataTypePtr& func_return_type) const; |
352 | | }; |
353 | | |
354 | | /// Previous function interface. |
355 | | class IFunction : public std::enable_shared_from_this<IFunction>, |
356 | | public FunctionBuilderImpl, |
357 | | public IFunctionBase, |
358 | | public PreparedFunctionImpl { |
359 | | public: |
360 | | String get_name() const override = 0; |
361 | | |
362 | | /// Notice: We should not change the column in the block, because the column may be shared by multiple expressions or exec nodes. |
363 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
364 | | uint32_t result, size_t input_rows_count) const override = 0; |
365 | | |
366 | | /// Override this functions to change default implementation behavior. See details in IMyFunction. |
367 | 32.1k | bool use_default_implementation_for_nulls() const override { return true; } |
368 | | |
369 | 6.52k | bool need_replace_null_data_to_default() const override { return false; } |
370 | | |
371 | 14.0k | bool use_default_implementation_for_low_cardinality_columns() const override { return true; } |
372 | | |
373 | | /// all constancy check should use this function to do automatically |
374 | 20.4k | ColumnNumbers get_arguments_that_are_always_constant() const override { return {}; } |
375 | | |
376 | 2 | bool is_use_default_implementation_for_constants() const override { |
377 | 2 | return use_default_implementation_for_constants(); |
378 | 2 | } |
379 | | |
380 | | using PreparedFunctionImpl::execute; |
381 | | using PreparedFunctionImpl::execute_impl_dry_run; |
382 | | using FunctionBuilderImpl::get_return_type_impl; |
383 | | using FunctionBuilderImpl::get_variadic_argument_types_impl; |
384 | | using FunctionBuilderImpl::get_return_type; |
385 | | |
386 | | [[noreturn]] PreparedFunctionPtr prepare(FunctionContext* context, |
387 | | const Block& /*sample_block*/, |
388 | | const ColumnNumbers& /*arguments*/, |
389 | 0 | uint32_t /*result*/) const final { |
390 | 0 | throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, |
391 | 0 | "prepare is not implemented for IFunction {}", get_name()); |
392 | 0 | __builtin_unreachable(); |
393 | 0 | } |
394 | | |
395 | 21.0k | Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { |
396 | 21.0k | return Status::OK(); |
397 | 21.0k | } |
398 | | |
399 | 0 | [[noreturn]] const DataTypes& get_argument_types() const final { |
400 | 0 | throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, |
401 | 0 | "get_argument_types is not implemented for IFunction {}", |
402 | 0 | get_name()); |
403 | 0 | __builtin_unreachable(); |
404 | 0 | } |
405 | | |
406 | 0 | [[noreturn]] const DataTypePtr& get_return_type() const final { |
407 | 0 | throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, |
408 | 0 | "get_return_type is not implemented for IFunction {}", get_name()); |
409 | 0 | __builtin_unreachable(); |
410 | 0 | } |
411 | | |
412 | | protected: |
413 | | FunctionBasePtr build_impl(const ColumnsWithTypeAndName& /*arguments*/, |
414 | 0 | const DataTypePtr& /*return_type*/) const final { |
415 | 0 | throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, |
416 | 0 | "build_impl is not implemented for IFunction {}", get_name()); |
417 | 0 | __builtin_unreachable(); |
418 | 0 | return {}; |
419 | 0 | } |
420 | | }; |
421 | | |
422 | | /// Wrappers over IFunction. If we (default)use DefaultFunction as wrapper, all function execution will go through this. |
423 | | |
424 | | class DefaultExecutable final : public PreparedFunctionImpl { |
425 | | public: |
426 | | explicit DefaultExecutable(std::shared_ptr<IFunction> function_) |
427 | 14.1k | : function(std::move(function_)) {} |
428 | | |
429 | 0 | String get_name() const override { return function->get_name(); } |
430 | | |
431 | | protected: |
432 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
433 | 10.8k | uint32_t result, size_t input_rows_count) const final { |
434 | 10.8k | return function->execute_impl(context, block, arguments, result, input_rows_count); |
435 | 10.8k | } |
436 | | |
437 | | Status evaluate_inverted_index( |
438 | | const ColumnsWithTypeAndName& arguments, |
439 | | const std::vector<vectorized::IndexFieldNameAndTypePair>& data_type_with_names, |
440 | | std::vector<segment_v2::InvertedIndexIterator*> iterators, uint32_t num_rows, |
441 | 0 | segment_v2::InvertedIndexResultBitmap& bitmap_result) const { |
442 | 0 | return function->evaluate_inverted_index(arguments, data_type_with_names, iterators, |
443 | 0 | num_rows, bitmap_result); |
444 | 0 | } |
445 | | |
446 | | Status execute_impl_dry_run(FunctionContext* context, Block& block, |
447 | | const ColumnNumbers& arguments, uint32_t result, |
448 | 0 | size_t input_rows_count) const final { |
449 | 0 | return function->execute_impl_dry_run(context, block, arguments, result, input_rows_count); |
450 | 0 | } |
451 | 20.6k | bool use_default_implementation_for_nulls() const final { |
452 | 20.6k | return function->use_default_implementation_for_nulls(); |
453 | 20.6k | } |
454 | 6.55k | bool need_replace_null_data_to_default() const final { |
455 | 6.55k | return function->need_replace_null_data_to_default(); |
456 | 6.55k | } |
457 | 20.6k | bool use_default_implementation_for_constants() const final { |
458 | 20.6k | return function->use_default_implementation_for_constants(); |
459 | 20.6k | } |
460 | 0 | bool use_default_implementation_for_low_cardinality_columns() const final { |
461 | 0 | return function->use_default_implementation_for_low_cardinality_columns(); |
462 | 0 | } |
463 | 20.6k | ColumnNumbers get_arguments_that_are_always_constant() const final { |
464 | 20.6k | return function->get_arguments_that_are_always_constant(); |
465 | 20.6k | } |
466 | | |
467 | | private: |
468 | | std::shared_ptr<IFunction> function; |
469 | | }; |
470 | | |
471 | | /* |
472 | | * when we register a function which didn't specify its base(i.e. inherited from IFunction), actually we use this as a wrapper. |
473 | | * it saves real implementation as `function`. |
474 | | */ |
475 | | class DefaultFunction final : public IFunctionBase { |
476 | | public: |
477 | | DefaultFunction(std::shared_ptr<IFunction> function_, DataTypes arguments_, |
478 | | DataTypePtr return_type_) |
479 | | : function(std::move(function_)), |
480 | | arguments(std::move(arguments_)), |
481 | 14.0k | return_type(std::move(return_type_)) {} |
482 | | |
483 | 0 | String get_name() const override { return function->get_name(); } |
484 | | |
485 | 0 | const DataTypes& get_argument_types() const override { return arguments; } |
486 | 0 | const DataTypePtr& get_return_type() const override { return return_type; } |
487 | | |
488 | | // return a default wrapper for IFunction. |
489 | | PreparedFunctionPtr prepare(FunctionContext* context, const Block& /*sample_block*/, |
490 | | const ColumnNumbers& /*arguments*/, |
491 | 14.1k | uint32_t /*result*/) const override { |
492 | 14.1k | return std::make_shared<DefaultExecutable>(function); |
493 | 14.1k | } |
494 | | |
495 | 21.8k | Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { |
496 | 21.8k | return function->open(context, scope); |
497 | 21.8k | } |
498 | | |
499 | 21.7k | Status close(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { |
500 | 21.7k | return function->close(context, scope); |
501 | 21.7k | } |
502 | | |
503 | | Status evaluate_inverted_index( |
504 | | const ColumnsWithTypeAndName& args, |
505 | | const std::vector<vectorized::IndexFieldNameAndTypePair>& data_type_with_names, |
506 | | std::vector<segment_v2::InvertedIndexIterator*> iterators, uint32_t num_rows, |
507 | 0 | segment_v2::InvertedIndexResultBitmap& bitmap_result) const override { |
508 | 0 | return function->evaluate_inverted_index(args, data_type_with_names, iterators, num_rows, |
509 | 0 | bitmap_result); |
510 | 0 | } |
511 | | |
512 | 2 | bool is_use_default_implementation_for_constants() const override { |
513 | 2 | return function->is_use_default_implementation_for_constants(); |
514 | 2 | } |
515 | | |
516 | 0 | bool can_push_down_to_index() const override { return function->can_push_down_to_index(); } |
517 | | |
518 | | private: |
519 | | std::shared_ptr<IFunction> function; |
520 | | DataTypes arguments; |
521 | | DataTypePtr return_type; |
522 | | }; |
523 | | |
524 | | class DefaultFunctionBuilder : public FunctionBuilderImpl { |
525 | | public: |
526 | | explicit DefaultFunctionBuilder(std::shared_ptr<IFunction> function_) |
527 | 14.9k | : function(std::move(function_)) {} |
528 | | |
529 | 14.0k | void check_number_of_arguments(size_t number_of_arguments) const override { |
530 | 14.0k | return function->check_number_of_arguments(number_of_arguments); |
531 | 14.0k | } |
532 | | |
533 | 0 | String get_name() const override { return function->get_name(); } |
534 | 0 | bool is_variadic() const override { return function->is_variadic(); } |
535 | 0 | size_t get_number_of_arguments() const override { return function->get_number_of_arguments(); } |
536 | | |
537 | 0 | ColumnNumbers get_arguments_that_are_always_constant() const override { |
538 | 0 | return function->get_arguments_that_are_always_constant(); |
539 | 0 | } |
540 | | |
541 | | protected: |
542 | 0 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
543 | 0 | return function->get_return_type_impl(arguments); |
544 | 0 | } |
545 | 14.0k | DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const override { |
546 | 14.0k | return function->get_return_type_impl(arguments); |
547 | 14.0k | } |
548 | | |
549 | 14.0k | bool use_default_implementation_for_nulls() const override { |
550 | 14.0k | return function->use_default_implementation_for_nulls(); |
551 | 14.0k | } |
552 | | |
553 | 0 | bool need_replace_null_data_to_default() const override { |
554 | 0 | return function->need_replace_null_data_to_default(); |
555 | 0 | } |
556 | 14.0k | bool use_default_implementation_for_low_cardinality_columns() const override { |
557 | 14.0k | return function->use_default_implementation_for_low_cardinality_columns(); |
558 | 14.0k | } |
559 | | |
560 | | FunctionBasePtr build_impl(const ColumnsWithTypeAndName& arguments, |
561 | 14.0k | const DataTypePtr& return_type) const override { |
562 | 14.0k | DataTypes data_types(arguments.size()); |
563 | 47.4k | for (size_t i = 0; i < arguments.size(); ++i) { |
564 | 33.3k | data_types[i] = arguments[i].type; |
565 | 33.3k | } |
566 | 14.0k | return std::make_shared<DefaultFunction>(function, data_types, return_type); |
567 | 14.0k | } |
568 | | |
569 | 852 | DataTypes get_variadic_argument_types_impl() const override { |
570 | 852 | return function->get_variadic_argument_types_impl(); |
571 | 852 | } |
572 | | |
573 | | private: |
574 | | std::shared_ptr<IFunction> function; |
575 | | }; |
576 | | |
577 | | using FunctionPtr = std::shared_ptr<IFunction>; |
578 | | |
579 | | /** Return ColumnNullable of src, with null map as OR-ed null maps of args columns in blocks. |
580 | | * Or ColumnConst(ColumnNullable) if the result is always NULL or if the result is constant and always not NULL. |
581 | | */ |
582 | | ColumnPtr wrap_in_nullable(const ColumnPtr& src, const Block& block, const ColumnNumbers& args, |
583 | | uint32_t result, size_t input_rows_count); |
584 | | |
585 | | #define NUMERIC_TYPE_TO_COLUMN_TYPE(M) \ |
586 | 165 | M(UInt8, ColumnUInt8) \ |
587 | 165 | M(Int8, ColumnInt8) \ |
588 | 163 | M(Int16, ColumnInt16) \ |
589 | 159 | M(Int32, ColumnInt32) \ |
590 | 155 | M(Int64, ColumnInt64) \ |
591 | 86 | M(Int128, ColumnInt128) \ |
592 | 82 | M(Float32, ColumnFloat32) \ |
593 | 80 | M(Float64, ColumnFloat64) |
594 | | |
595 | | #define DECIMAL_TYPE_TO_COLUMN_TYPE(M) \ |
596 | 80 | M(Decimal32, ColumnDecimal<Decimal32>) \ |
597 | 80 | M(Decimal64, ColumnDecimal<Decimal64>) \ |
598 | 80 | M(Decimal128V2, ColumnDecimal<Decimal128V2>) \ |
599 | 78 | M(Decimal128V3, ColumnDecimal<Decimal128V3>) \ |
600 | 76 | M(Decimal256, ColumnDecimal<Decimal256>) |
601 | | |
602 | | #define STRING_TYPE_TO_COLUMN_TYPE(M) \ |
603 | 74 | M(String, ColumnString) \ |
604 | 74 | M(JSONB, ColumnString) |
605 | | |
606 | | #define TIME_TYPE_TO_COLUMN_TYPE(M) \ |
607 | 70 | M(Date, ColumnInt64) \ |
608 | 68 | M(DateTime, ColumnInt64) \ |
609 | 63 | M(DateV2, ColumnUInt32) \ |
610 | 50 | M(DateTimeV2, ColumnUInt64) |
611 | | |
612 | | #define IP_TYPE_TO_COLUMN_TYPE(M) \ |
613 | 44 | M(IPv4, ColumnIPv4) \ |
614 | 44 | M(IPv6, ColumnIPv6) |
615 | | |
616 | | #define COMPLEX_TYPE_TO_COLUMN_TYPE(M) \ |
617 | 44 | M(Array, ColumnArray) \ |
618 | 44 | M(Map, ColumnMap) \ |
619 | 8 | M(Struct, ColumnStruct) \ |
620 | 8 | M(VARIANT, ColumnObject) \ |
621 | 8 | M(BitMap, ColumnBitmap) \ |
622 | 8 | M(HLL, ColumnHLL) \ |
623 | 4 | M(QuantileState, ColumnQuantileState) |
624 | | |
625 | | #define TYPE_TO_BASIC_COLUMN_TYPE(M) \ |
626 | 105 | NUMERIC_TYPE_TO_COLUMN_TYPE(M) \ |
627 | 78 | DECIMAL_TYPE_TO_COLUMN_TYPE(M) \ |
628 | 74 | STRING_TYPE_TO_COLUMN_TYPE(M) \ |
629 | 68 | TIME_TYPE_TO_COLUMN_TYPE(M) \ |
630 | 105 | IP_TYPE_TO_COLUMN_TYPE(M) |
631 | | |
632 | | #define TYPE_TO_COLUMN_TYPE(M) \ |
633 | 105 | TYPE_TO_BASIC_COLUMN_TYPE(M) \ |
634 | 105 | COMPLEX_TYPE_TO_COLUMN_TYPE(M) |
635 | | |
636 | | } // namespace doris::vectorized |