be/src/exprs/function/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 "core/block/block.h" |
35 | | #include "core/block/column_numbers.h" |
36 | | #include "core/block/column_with_type_and_name.h" |
37 | | #include "core/block/columns_with_type_and_name.h" |
38 | | #include "core/data_type/data_type.h" |
39 | | #include "core/data_type/data_type_array.h" |
40 | | #include "core/data_type/data_type_nullable.h" |
41 | | #include "core/data_type/data_type_struct.h" |
42 | | #include "core/data_type/define_primitive_type.h" |
43 | | #include "core/types.h" |
44 | | #include "exprs/function_context.h" |
45 | | #include "exprs/vexpr_fwd.h" |
46 | | #include "storage/index/zone_map/zonemap_filter_result.h" |
47 | | |
48 | | namespace doris { |
49 | | struct InvertedIndexAnalyzerCtx; |
50 | | namespace expr_zonemap { |
51 | | struct DictionaryEvalContext; |
52 | | struct BloomFilterEvalContext; |
53 | | } // namespace expr_zonemap |
54 | | using DictionaryEvalContext = expr_zonemap::DictionaryEvalContext; |
55 | | using BloomFilterEvalContext = expr_zonemap::BloomFilterEvalContext; |
56 | | namespace segment_v2 { |
57 | | class IndexIterator; |
58 | | class InvertedIndexResultBitmap; |
59 | | } // namespace segment_v2 |
60 | | } // namespace doris |
61 | | |
62 | | namespace doris { |
63 | | |
64 | | struct FunctionAttr { |
65 | | bool new_version_unix_timestamp {false}; |
66 | | bool new_version_bitmap_op_count {false}; |
67 | | }; |
68 | | |
69 | | #define RETURN_REAL_TYPE_FOR_DATEV2_FUNCTION(TYPE) \ |
70 | 3.74k | bool is_nullable = false; \ |
71 | 3.74k | bool is_datev2 = false; \ |
72 | 6.92k | for (auto it : arguments) { \ |
73 | 6.92k | is_nullable = is_nullable || it.type->is_nullable(); \ |
74 | 6.92k | is_datev2 = is_datev2 || it.type->get_primitive_type() == TYPE_DATEV2 || \ |
75 | 6.92k | it.type->get_primitive_type() == TYPE_DATETIMEV2 || \ |
76 | 6.92k | it.type->get_primitive_type() == TYPE_TIMESTAMP_NS; \ |
77 | 6.92k | } \ |
78 | 3.74k | return is_nullable || !is_datev2 \ |
79 | 3.74k | ? make_nullable( \ |
80 | 3.25k | std::make_shared<typename PrimitiveTypeTraits<TYPE>::DataType>()) \ |
81 | 3.74k | : std::make_shared<typename PrimitiveTypeTraits<TYPE>::DataType>(); |
82 | | |
83 | | #define SET_NULLMAP_IF_FALSE(EXPR) \ |
84 | | if (!EXPR) [[unlikely]] { \ |
85 | | null_map[i] = true; \ |
86 | | } |
87 | | |
88 | | class Field; |
89 | | class VExpr; |
90 | | class ZoneMapEvalContext; |
91 | | |
92 | | // Only use dispose the variadic argument |
93 | | template <typename T> |
94 | | auto has_variadic_argument_types(T&& arg) -> decltype(T::get_variadic_argument_types()) {}; |
95 | | void has_variadic_argument_types(...); |
96 | | |
97 | | template <typename T> |
98 | | concept HasGetVariadicArgumentTypesImpl = requires(T t) { |
99 | | { t.get_variadic_argument_types_impl() } -> std::same_as<DataTypes>; |
100 | | }; |
101 | | |
102 | | bool have_null_column(const Block& block, const ColumnNumbers& args); |
103 | | bool have_null_column(const ColumnsWithTypeAndName& args); |
104 | | |
105 | | /// The simplest executable object. |
106 | | /// Motivation: |
107 | | /// * Prepare something heavy once before main execution loop instead of doing it for each block. |
108 | | /// * Provide const interface for IFunctionBase (later). |
109 | | class IPreparedFunction { |
110 | | public: |
111 | 952k | virtual ~IPreparedFunction() = default; |
112 | | |
113 | | /// Get the main function name. |
114 | | virtual String get_name() const = 0; |
115 | | |
116 | | virtual Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
117 | | uint32_t result, size_t input_rows_count) const = 0; |
118 | | }; |
119 | | |
120 | | using PreparedFunctionPtr = std::shared_ptr<IPreparedFunction>; |
121 | | |
122 | | class PreparedFunctionImpl : public IPreparedFunction { |
123 | | public: |
124 | | Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
125 | | uint32_t result, size_t input_rows_count) const final; |
126 | | |
127 | | /** If the function have non-zero number of arguments, |
128 | | * and if all arguments are constant, that we could automatically provide default implementation: |
129 | | * arguments are converted to ordinary columns with single value which is not const, then function is executed as usual, |
130 | | * and then the result is converted to constant column. |
131 | | */ |
132 | 2.26M | virtual bool use_default_implementation_for_constants() const { return true; } |
133 | | |
134 | | /** If use_default_implementation_for_nulls() is true, after execute the function, |
135 | | * whether need to replace the nested data of null data to the default value. |
136 | | * E.g. for binary arithmetic exprs, need return true to avoid false overflow. |
137 | | */ |
138 | 0 | virtual bool need_replace_null_data_to_default() const { return false; } |
139 | | |
140 | | protected: |
141 | | virtual Status execute_impl(FunctionContext* context, Block& block, |
142 | | const ColumnNumbers& arguments, uint32_t result, |
143 | | size_t input_rows_count) const = 0; |
144 | | |
145 | | /** Default implementation in presence of Nullable arguments or NULL constants as arguments is the following: |
146 | | * if some of arguments are NULL constants then return NULL constant, |
147 | | * if some of arguments are Nullable, then execute function as usual for block, |
148 | | * where Nullable columns are substituted with nested columns (they have arbitrary values in rows corresponding to NULL value) |
149 | | * and wrap result in Nullable column where NULLs are in all rows where any of arguments are NULL. |
150 | | */ |
151 | 0 | virtual bool use_default_implementation_for_nulls() const { return true; } |
152 | | |
153 | 0 | virtual bool skip_return_type_check() const { return false; } |
154 | | |
155 | | /** Some arguments could remain constant during this implementation. |
156 | | * Every argument required const must write here and no checks elsewhere. |
157 | | */ |
158 | 2.75k | virtual ColumnNumbers get_arguments_that_are_always_constant() const { return {}; } |
159 | | |
160 | | private: |
161 | | Status default_implementation_for_nulls(FunctionContext* context, Block& block, |
162 | | const ColumnNumbers& args, uint32_t result, |
163 | | size_t input_rows_count, bool* executed) const; |
164 | | Status default_implementation_for_constant_arguments(FunctionContext* context, Block& block, |
165 | | const ColumnNumbers& args, uint32_t result, |
166 | | size_t input_rows_count, |
167 | | bool* executed) const; |
168 | | Status default_execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
169 | | uint32_t result, size_t input_rows_count) const; |
170 | | Status _execute_skipped_constant_deal(FunctionContext* context, Block& block, |
171 | | const ColumnNumbers& args, uint32_t result, |
172 | | size_t input_rows_count) const; |
173 | | }; |
174 | | |
175 | | /// Function with known arguments and return type. |
176 | | class IFunctionBase { |
177 | | public: |
178 | 1.41M | virtual ~IFunctionBase() = default; |
179 | | |
180 | | /// Get the main function name. |
181 | | virtual String get_name() const = 0; |
182 | | |
183 | | virtual const DataTypes& get_argument_types() const = 0; |
184 | | virtual const DataTypePtr& get_return_type() const = 0; |
185 | | |
186 | 2.27k | virtual double execute_cost() const { return 1.0; } |
187 | | |
188 | | /// Do preparations and return executable. |
189 | | /// sample_block should contain data types of arguments and values of constants, if relevant. |
190 | | virtual PreparedFunctionPtr prepare(FunctionContext* context, const Block& sample_block, |
191 | | const ColumnNumbers& arguments, uint32_t result) const = 0; |
192 | | |
193 | | /// Override this when function need to store state in the `FunctionContext`, or do some |
194 | | /// preparation work according to information from `FunctionContext`. |
195 | 546k | virtual Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) { |
196 | 546k | return Status::OK(); |
197 | 546k | } |
198 | | |
199 | | Status execute(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
200 | 846k | uint32_t result, size_t input_rows_count) const { |
201 | | // Some function implementations may not handle the case where input_rows_count is 0 |
202 | | // (e.g., some functions access the 0th row of input columns during execution). |
203 | | // Additionally, some UDF functions may hang if they write 0 rows and then try to read. |
204 | | // Therefore, before executing the function, we first check if input_rows_count is 0. |
205 | | // If it is 0, we directly return an empty result column to avoid executing the function body. |
206 | 846k | if (input_rows_count == 0) { |
207 | 145 | block.get_by_position(result).column = |
208 | 145 | block.get_by_position(result).type->create_column(); |
209 | 145 | return Status::OK(); |
210 | 145 | } |
211 | 845k | try { |
212 | 845k | return prepare(context, block, arguments, result) |
213 | 845k | ->execute(context, block, arguments, result, input_rows_count); |
214 | 845k | } catch (const Exception& e) { |
215 | 369 | return e.to_status(); |
216 | 369 | } |
217 | 845k | } |
218 | | |
219 | | // True when this function's index push-down can only ever answer with an approximate |
220 | | // (superset) candidate set instead of the exact row set. Such a result is usable in one |
221 | | // place only -- narrowing the candidate rows of a conjunct that stays pushed down for |
222 | | // row-level re-verification -- so VExpr skips the push-down entirely wherever it would be |
223 | | // computed and then dropped, rather than paying for the index reads first. |
224 | 18.5k | virtual bool index_result_is_approximate() const { return false; } |
225 | | |
226 | | // VExpr calls this after binding the indexed fields to storage-compatible types and |
227 | | // iterators; the arguments carry the call's literals, in child order. |
228 | | virtual Status evaluate_inverted_index( |
229 | | const ColumnsWithTypeAndName& arguments, |
230 | | const std::vector<IndexFieldNameAndTypePair>& data_type_with_names, |
231 | | std::vector<segment_v2::IndexIterator*> iterators, uint32_t num_rows, |
232 | | const InvertedIndexAnalyzerCtx* analyzer_ctx, |
233 | 39 | segment_v2::InvertedIndexResultBitmap& bitmap_result) const { |
234 | 39 | return Status::OK(); |
235 | 39 | } |
236 | | |
237 | | /// Do cleaning work when function is finished, i.e., release state variables in the |
238 | | /// `FunctionContext` which are registered in `prepare` phase. |
239 | 2.65M | virtual Status close(FunctionContext* context, FunctionContext::FunctionStateScope scope) { |
240 | 2.65M | return Status::OK(); |
241 | 2.65M | } |
242 | | |
243 | | virtual bool is_use_default_implementation_for_constants() const = 0; |
244 | | |
245 | 0 | virtual bool is_udf_function() const { return false; } |
246 | | |
247 | 2.65k | virtual bool can_push_down_to_index() const { return false; } |
248 | | |
249 | 589k | virtual bool is_blockable() const { return false; } |
250 | | |
251 | | virtual ZoneMapFilterResult evaluate_zonemap_filter(const ZoneMapEvalContext& ctx, |
252 | | const VExprSPtrs& function_arguments) const; |
253 | | |
254 | 10.5k | virtual bool can_evaluate_zonemap_filter(const VExprSPtrs& /*function_arguments*/) const { |
255 | 10.5k | return false; |
256 | 10.5k | } |
257 | | |
258 | | virtual ZoneMapFilterResult evaluate_dictionary_filter( |
259 | | const DictionaryEvalContext& ctx, const VExprSPtrs& function_arguments) const; |
260 | | |
261 | 54 | virtual bool can_evaluate_dictionary_filter(const VExprSPtrs& /*function_arguments*/) const { |
262 | 54 | return false; |
263 | 54 | } |
264 | | |
265 | | virtual ZoneMapFilterResult evaluate_bloom_filter(const BloomFilterEvalContext& ctx, |
266 | | const VExprSPtrs& function_arguments) const; |
267 | | |
268 | 27 | virtual bool can_evaluate_bloom_filter(const VExprSPtrs& /*function_arguments*/) const { |
269 | 27 | return false; |
270 | 27 | } |
271 | | }; |
272 | | |
273 | | using FunctionBasePtr = std::shared_ptr<IFunctionBase>; |
274 | | |
275 | | /// Creates IFunctionBase from argument types list. |
276 | | class IFunctionBuilder { |
277 | | public: |
278 | 1.42M | virtual ~IFunctionBuilder() = default; |
279 | | |
280 | | /// Get the main function name. |
281 | | virtual String get_name() const = 0; |
282 | | |
283 | | /// Override and return true if function could take different number of arguments. |
284 | | ///TODO: this function is not actually used now. but in check_number_of_arguments we still need it because for many |
285 | | /// functions we didn't set the correct number of arguments. |
286 | | virtual bool is_variadic() const = 0; |
287 | | |
288 | | /// For non-variadic functions, return number of arguments; otherwise return zero (that should be ignored). |
289 | | virtual size_t get_number_of_arguments() const = 0; |
290 | | |
291 | | /// Throw if number of arguments is incorrect. Default implementation will check only in non-variadic case. |
292 | | virtual void check_number_of_arguments(size_t number_of_arguments) const = 0; |
293 | | |
294 | | /// Check arguments and return IFunctionBase. |
295 | | virtual FunctionBasePtr build(const ColumnsWithTypeAndName& arguments, |
296 | | const DataTypePtr& return_type) const = 0; |
297 | | |
298 | | /// For higher-order functions (functions, that have lambda expression as at least one argument). |
299 | | /// You pass data types with empty DataTypeFunction for lambda arguments. |
300 | | /// This function will replace it with DataTypeFunction containing actual types. |
301 | | virtual DataTypes get_variadic_argument_types() const = 0; |
302 | | |
303 | | /// Returns indexes of arguments, that must be ColumnConst |
304 | | virtual ColumnNumbers get_arguments_that_are_always_constant() const = 0; |
305 | | }; |
306 | | |
307 | | using FunctionBuilderPtr = std::shared_ptr<IFunctionBuilder>; |
308 | | |
309 | 5 | inline std::string get_types_string(const ColumnsWithTypeAndName& arguments) { |
310 | 5 | std::string types; |
311 | 5 | for (const auto& argument : arguments) { |
312 | 2 | if (!types.empty()) { |
313 | 1 | types += ", "; |
314 | 1 | } |
315 | 2 | types += argument.type->get_name(); |
316 | 2 | } |
317 | 5 | return types; |
318 | 5 | } |
319 | | |
320 | | /// used in function_factory. when we register a function, save a builder. to get a function, to get a builder. |
321 | | /// will use DefaultFunctionBuilder as the default builder in function's registration if we didn't explicitly specify. |
322 | | class FunctionBuilderImpl : public IFunctionBuilder { |
323 | | public: |
324 | | FunctionBasePtr build(const ColumnsWithTypeAndName& arguments, |
325 | 837k | const DataTypePtr& return_type) const final { |
326 | 837k | if (skip_return_type_check()) { |
327 | 283k | return build_impl(arguments, return_type); |
328 | 283k | } |
329 | 553k | const DataTypePtr& func_return_type = get_return_type(arguments); |
330 | 553k | if (func_return_type == nullptr) { |
331 | 1 | throw doris::Exception( |
332 | 1 | ErrorCode::INTERNAL_ERROR, |
333 | 1 | "function return type check failed, function_name={}, " |
334 | 1 | "expect_return_type={}, real_return_type is nullptr, input_arguments={}", |
335 | 1 | get_name(), return_type->get_name(), get_types_string(arguments)); |
336 | 1 | } |
337 | | |
338 | | // check return types equal. |
339 | 553k | if (!(return_type->equals(*func_return_type) || |
340 | | // For null constant argument, `get_return_type` would return |
341 | | // Nullable<DataTypeNothing> when `use_default_implementation_for_nulls` is true. |
342 | 553k | (return_type->is_nullable() && func_return_type->is_nullable() && |
343 | 2.49k | ((DataTypeNullable*)func_return_type.get()) |
344 | 1.43k | ->get_nested_type() |
345 | 1.43k | ->get_primitive_type() == INVALID_TYPE) || |
346 | 553k | is_date_or_datetime_or_decimal(return_type, func_return_type) || |
347 | 553k | is_nested_type_date_or_datetime_or_decimal(return_type, func_return_type))) { |
348 | 4 | throw doris::Exception( |
349 | 4 | ErrorCode::INTERNAL_ERROR, |
350 | 4 | "function return type check failed, function_name={}, " |
351 | 4 | "fe plan return type={}, be real return type={}, input_arguments={}", |
352 | 4 | get_name(), return_type->get_name(), func_return_type->get_name(), |
353 | 4 | get_types_string(arguments)); |
354 | 4 | } |
355 | 553k | return build_impl(arguments, return_type); |
356 | 553k | } |
357 | | |
358 | 464k | bool is_variadic() const override { return false; } |
359 | | |
360 | | // Default implementation. Will check only in non-variadic case. |
361 | | void check_number_of_arguments(size_t number_of_arguments) const override; |
362 | | // the return type should be same with what FE plans. |
363 | | // it returns: `get_return_type_impl` if `use_default_implementation_for_nulls` = false |
364 | | // `get_return_type_impl` warpped in NULL if `use_default_implementation_for_nulls` = true and input has NULL |
365 | | DataTypePtr get_return_type(const ColumnsWithTypeAndName& arguments) const; |
366 | | |
367 | 11.0k | DataTypes get_variadic_argument_types() const override { |
368 | 11.0k | return get_variadic_argument_types_impl(); |
369 | 11.0k | } |
370 | | |
371 | 0 | ColumnNumbers get_arguments_that_are_always_constant() const override { return {}; } |
372 | | |
373 | | protected: |
374 | | // Get the result type by argument type. If the function does not apply to these arguments, throw an exception. |
375 | | // the get_return_type_impl and its overrides should only return the nested type if `use_default_implementation_for_nulls` is true. |
376 | | // whether to wrap in nullable type will be automatically decided. |
377 | 542k | virtual DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const { |
378 | 542k | DataTypes data_types(arguments.size()); |
379 | 1.62M | for (size_t i = 0; i < arguments.size(); ++i) { |
380 | 1.07M | data_types[i] = arguments[i].type; |
381 | 1.07M | } |
382 | 542k | return get_return_type_impl(data_types); |
383 | 542k | } |
384 | | |
385 | 0 | virtual DataTypePtr get_return_type_impl(const DataTypes& /*arguments*/) const { |
386 | 0 | throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, |
387 | 0 | "get_return_type is not implemented for {}", get_name()); |
388 | 0 | return nullptr; |
389 | 0 | } |
390 | | |
391 | | /** If use_default_implementation_for_nulls() is true, than change arguments for get_return_type() and build_impl(): |
392 | | * if some of arguments are Nullable(Nothing) then don't call get_return_type(), call build_impl() with return_type = Nullable(Nothing), |
393 | | * if some of arguments are Nullable, then: |
394 | | * - Nullable types are substituted with nested types for get_return_type() function |
395 | | * - WRAP get_return_type() RESULT IN NULLABLE type and pass to build_impl |
396 | | * |
397 | | * Otherwise build returns build_impl(arguments, get_return_type(arguments)); |
398 | | */ |
399 | 0 | virtual bool use_default_implementation_for_nulls() const { return true; } |
400 | | |
401 | 16 | virtual bool skip_return_type_check() const { return false; } |
402 | | |
403 | 0 | virtual bool need_replace_null_data_to_default() const { return false; } |
404 | | |
405 | | /// return a real function object to execute. called in build(...). |
406 | | virtual FunctionBasePtr build_impl(const ColumnsWithTypeAndName& arguments, |
407 | | const DataTypePtr& return_type) const = 0; |
408 | | |
409 | 2.93k | virtual DataTypes get_variadic_argument_types_impl() const { return {}; } |
410 | | |
411 | | private: |
412 | | bool is_date_or_datetime_or_decimal(const DataTypePtr& return_type, |
413 | | const DataTypePtr& func_return_type) const; |
414 | | bool is_nested_type_date_or_datetime_or_decimal(const DataTypePtr& return_type, |
415 | | const DataTypePtr& func_return_type) const; |
416 | | }; |
417 | | |
418 | | /// Previous function interface. |
419 | | class IFunction : public std::enable_shared_from_this<IFunction>, |
420 | | public FunctionBuilderImpl, |
421 | | public IFunctionBase, |
422 | | public PreparedFunctionImpl { |
423 | | public: |
424 | | String get_name() const override = 0; |
425 | | |
426 | | /// Notice: We should not change the column in the block, because the column may be shared by multiple expressions or exec nodes. |
427 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
428 | | uint32_t result, size_t input_rows_count) const override = 0; |
429 | | |
430 | | /// Override this functions to change default implementation behavior. See details in IMyFunction. |
431 | 1.01M | bool use_default_implementation_for_nulls() const override { return true; } |
432 | | |
433 | 553k | bool skip_return_type_check() const override { return false; } |
434 | | |
435 | 177k | bool need_replace_null_data_to_default() const override { return false; } |
436 | | |
437 | | /// all constancy check should use this function to do automatically |
438 | 661k | ColumnNumbers get_arguments_that_are_always_constant() const override { return {}; } |
439 | | |
440 | 1.54M | bool is_use_default_implementation_for_constants() const override { |
441 | 1.54M | return use_default_implementation_for_constants(); |
442 | 1.54M | } |
443 | | |
444 | | using PreparedFunctionImpl::execute; |
445 | | using FunctionBuilderImpl::get_return_type_impl; |
446 | | using FunctionBuilderImpl::get_variadic_argument_types_impl; |
447 | | using FunctionBuilderImpl::get_return_type; |
448 | | |
449 | | [[noreturn]] PreparedFunctionPtr prepare(FunctionContext* context, |
450 | | const Block& /*sample_block*/, |
451 | | const ColumnNumbers& /*arguments*/, |
452 | 0 | uint32_t /*result*/) const final { |
453 | 0 | throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, |
454 | 0 | "prepare is not implemented for IFunction {}", get_name()); |
455 | 0 | __builtin_unreachable(); |
456 | 0 | } |
457 | | |
458 | 2.05M | Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { |
459 | 2.05M | return Status::OK(); |
460 | 2.05M | } |
461 | | |
462 | 0 | [[noreturn]] const DataTypes& get_argument_types() const final { |
463 | 0 | throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, |
464 | 0 | "get_argument_types is not implemented for IFunction {}", |
465 | 0 | get_name()); |
466 | 0 | __builtin_unreachable(); |
467 | 0 | } |
468 | | |
469 | 0 | [[noreturn]] const DataTypePtr& get_return_type() const final { |
470 | 0 | throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, |
471 | 0 | "get_return_type is not implemented for IFunction {}", get_name()); |
472 | 0 | __builtin_unreachable(); |
473 | 0 | } |
474 | | |
475 | | protected: |
476 | | FunctionBasePtr build_impl(const ColumnsWithTypeAndName& /*arguments*/, |
477 | 0 | const DataTypePtr& /*return_type*/) const final { |
478 | 0 | throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, |
479 | 0 | "build_impl is not implemented for IFunction {}", get_name()); |
480 | 0 | __builtin_unreachable(); |
481 | 0 | return {}; |
482 | 0 | } |
483 | | }; |
484 | | |
485 | | /* |
486 | | * when we register a function which didn't specify its base(i.e. inherited from IFunction), actually we use this as a wrapper. |
487 | | * it saves real implementation as `function`. |
488 | | */ |
489 | | class DefaultFunction final : public IFunctionBase { |
490 | | public: |
491 | | DefaultFunction(std::shared_ptr<IFunction> function_, DataTypes arguments_, |
492 | | DataTypePtr return_type_) |
493 | 555k | : function(std::move(function_)), |
494 | 555k | arguments(std::move(arguments_)), |
495 | 555k | return_type(std::move(return_type_)) {} |
496 | | |
497 | 392 | String get_name() const override { return function->get_name(); } |
498 | | |
499 | 0 | const DataTypes& get_argument_types() const override { return arguments; } |
500 | 36 | const DataTypePtr& get_return_type() const override { return return_type; } |
501 | | |
502 | | // return a default wrapper for IFunction. |
503 | | PreparedFunctionPtr prepare(FunctionContext* context, const Block& /*sample_block*/, |
504 | | const ColumnNumbers& /*arguments*/, |
505 | 465k | uint32_t /*result*/) const override { |
506 | 465k | return function; |
507 | 465k | } |
508 | | |
509 | 679k | double execute_cost() const override { return function->execute_cost(); } |
510 | | |
511 | 2.15M | Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { |
512 | 2.15M | return function->open(context, scope); |
513 | 2.15M | } |
514 | | |
515 | 2.15M | Status close(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { |
516 | 2.15M | return function->close(context, scope); |
517 | 2.15M | } |
518 | | |
519 | 20.9k | bool index_result_is_approximate() const override { |
520 | 20.9k | return function->index_result_is_approximate(); |
521 | 20.9k | } |
522 | | |
523 | | Status evaluate_inverted_index( |
524 | | const ColumnsWithTypeAndName& args, |
525 | | const std::vector<IndexFieldNameAndTypePair>& data_type_with_names, |
526 | | std::vector<segment_v2::IndexIterator*> iterators, uint32_t num_rows, |
527 | | const InvertedIndexAnalyzerCtx* analyzer_ctx, |
528 | 10.8k | segment_v2::InvertedIndexResultBitmap& bitmap_result) const override { |
529 | 10.8k | return function->evaluate_inverted_index(args, data_type_with_names, iterators, num_rows, |
530 | 10.8k | analyzer_ctx, bitmap_result); |
531 | 10.8k | } |
532 | | |
533 | 1.54M | bool is_use_default_implementation_for_constants() const override { |
534 | 1.54M | return function->is_use_default_implementation_for_constants(); |
535 | 1.54M | } |
536 | | |
537 | 2.64k | bool can_push_down_to_index() const override { return function->can_push_down_to_index(); } |
538 | | |
539 | 588k | bool is_blockable() const override { return function->is_blockable(); } |
540 | | |
541 | | ZoneMapFilterResult evaluate_zonemap_filter( |
542 | 8.27k | const ZoneMapEvalContext& ctx, const VExprSPtrs& function_arguments) const override { |
543 | 8.27k | return function->evaluate_zonemap_filter(ctx, function_arguments); |
544 | 8.27k | } |
545 | | |
546 | 53.4k | bool can_evaluate_zonemap_filter(const VExprSPtrs& function_arguments) const override { |
547 | 53.4k | return function->can_evaluate_zonemap_filter(function_arguments); |
548 | 53.4k | } |
549 | | |
550 | | ZoneMapFilterResult evaluate_dictionary_filter( |
551 | 6 | const DictionaryEvalContext& ctx, const VExprSPtrs& function_arguments) const override { |
552 | 6 | return function->evaluate_dictionary_filter(ctx, function_arguments); |
553 | 6 | } |
554 | | |
555 | 192 | bool can_evaluate_dictionary_filter(const VExprSPtrs& function_arguments) const override { |
556 | 192 | return function->can_evaluate_dictionary_filter(function_arguments); |
557 | 192 | } |
558 | | |
559 | | ZoneMapFilterResult evaluate_bloom_filter(const BloomFilterEvalContext& ctx, |
560 | 8 | const VExprSPtrs& function_arguments) const override { |
561 | 8 | return function->evaluate_bloom_filter(ctx, function_arguments); |
562 | 8 | } |
563 | | |
564 | 83 | bool can_evaluate_bloom_filter(const VExprSPtrs& function_arguments) const override { |
565 | 83 | return function->can_evaluate_bloom_filter(function_arguments); |
566 | 83 | } |
567 | | |
568 | | private: |
569 | | std::shared_ptr<IFunction> function; |
570 | | DataTypes arguments; |
571 | | DataTypePtr return_type; |
572 | | }; |
573 | | |
574 | | struct simple_function_creator_without_type0 { |
575 | | template <typename AggregateFunctionTemplate, typename... TArgs> |
576 | 170 | static std::shared_ptr<IFunction> create(const DataTypePtr& result_type, TArgs&&... args) { |
577 | 170 | std::unique_ptr<IFunction> result(std::make_unique<AggregateFunctionTemplate>( |
578 | 170 | result_type, std::forward<TArgs>(args)...)); |
579 | 170 | return std::shared_ptr<IFunction>(result.release()); |
580 | 170 | } _ZN5doris37simple_function_creator_without_type06createINS_19FunctionArrayCumSumILNS_13PrimitiveTypeE30EEEJEEESt10shared_ptrINS_9IFunctionEERKS5_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 576 | 14 | static std::shared_ptr<IFunction> create(const DataTypePtr& result_type, TArgs&&... args) { | 577 | 14 | std::unique_ptr<IFunction> result(std::make_unique<AggregateFunctionTemplate>( | 578 | 14 | result_type, std::forward<TArgs>(args)...)); | 579 | 14 | return std::shared_ptr<IFunction>(result.release()); | 580 | 14 | } |
_ZN5doris37simple_function_creator_without_type06createINS_19FunctionArrayCumSumILNS_13PrimitiveTypeE35EEEJEEESt10shared_ptrINS_9IFunctionEERKS5_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 576 | 31 | static std::shared_ptr<IFunction> create(const DataTypePtr& result_type, TArgs&&... args) { | 577 | 31 | std::unique_ptr<IFunction> result(std::make_unique<AggregateFunctionTemplate>( | 578 | 31 | result_type, std::forward<TArgs>(args)...)); | 579 | 31 | return std::shared_ptr<IFunction>(result.release()); | 580 | 31 | } |
_ZN5doris37simple_function_creator_without_type06createINS_25FunctionArrayAggDecimalV3INS_27ArrayAggregateImplDecimalV3ILNS_18AggregateOperationE2ELNS_13PrimitiveTypeE30EEENS_12NameArraySumEEEJEEESt10shared_ptrINS_9IFunctionEERKS9_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 576 | 12 | static std::shared_ptr<IFunction> create(const DataTypePtr& result_type, TArgs&&... args) { | 577 | 12 | std::unique_ptr<IFunction> result(std::make_unique<AggregateFunctionTemplate>( | 578 | 12 | result_type, std::forward<TArgs>(args)...)); | 579 | 12 | return std::shared_ptr<IFunction>(result.release()); | 580 | 12 | } |
_ZN5doris37simple_function_creator_without_type06createINS_25FunctionArrayAggDecimalV3INS_27ArrayAggregateImplDecimalV3ILNS_18AggregateOperationE2ELNS_13PrimitiveTypeE35EEENS_12NameArraySumEEEJEEESt10shared_ptrINS_9IFunctionEERKS9_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 576 | 29 | static std::shared_ptr<IFunction> create(const DataTypePtr& result_type, TArgs&&... args) { | 577 | 29 | std::unique_ptr<IFunction> result(std::make_unique<AggregateFunctionTemplate>( | 578 | 29 | result_type, std::forward<TArgs>(args)...)); | 579 | 29 | return std::shared_ptr<IFunction>(result.release()); | 580 | 29 | } |
_ZN5doris37simple_function_creator_without_type06createINS_25FunctionArrayAggDecimalV3INS_27ArrayAggregateImplDecimalV3ILNS_18AggregateOperationE3ELNS_13PrimitiveTypeE30EEENS_16NameArrayAverageEEEJEEESt10shared_ptrINS_9IFunctionEERKS9_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 576 | 11 | static std::shared_ptr<IFunction> create(const DataTypePtr& result_type, TArgs&&... args) { | 577 | 11 | std::unique_ptr<IFunction> result(std::make_unique<AggregateFunctionTemplate>( | 578 | 11 | result_type, std::forward<TArgs>(args)...)); | 579 | 11 | return std::shared_ptr<IFunction>(result.release()); | 580 | 11 | } |
_ZN5doris37simple_function_creator_without_type06createINS_25FunctionArrayAggDecimalV3INS_27ArrayAggregateImplDecimalV3ILNS_18AggregateOperationE3ELNS_13PrimitiveTypeE35EEENS_16NameArrayAverageEEEJEEESt10shared_ptrINS_9IFunctionEERKS9_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 576 | 30 | static std::shared_ptr<IFunction> create(const DataTypePtr& result_type, TArgs&&... args) { | 577 | 30 | std::unique_ptr<IFunction> result(std::make_unique<AggregateFunctionTemplate>( | 578 | 30 | result_type, std::forward<TArgs>(args)...)); | 579 | 30 | return std::shared_ptr<IFunction>(result.release()); | 580 | 30 | } |
_ZN5doris37simple_function_creator_without_type06createINS_25FunctionArrayAggDecimalV3INS_27ArrayAggregateImplDecimalV3ILNS_18AggregateOperationE4ELNS_13PrimitiveTypeE30EEENS_16NameArrayProductEEEJEEESt10shared_ptrINS_9IFunctionEERKS9_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 576 | 12 | static std::shared_ptr<IFunction> create(const DataTypePtr& result_type, TArgs&&... args) { | 577 | 12 | std::unique_ptr<IFunction> result(std::make_unique<AggregateFunctionTemplate>( | 578 | 12 | result_type, std::forward<TArgs>(args)...)); | 579 | 12 | return std::shared_ptr<IFunction>(result.release()); | 580 | 12 | } |
_ZN5doris37simple_function_creator_without_type06createINS_25FunctionArrayAggDecimalV3INS_27ArrayAggregateImplDecimalV3ILNS_18AggregateOperationE4ELNS_13PrimitiveTypeE35EEENS_16NameArrayProductEEEJEEESt10shared_ptrINS_9IFunctionEERKS9_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 576 | 31 | static std::shared_ptr<IFunction> create(const DataTypePtr& result_type, TArgs&&... args) { | 577 | 31 | std::unique_ptr<IFunction> result(std::make_unique<AggregateFunctionTemplate>( | 578 | 31 | result_type, std::forward<TArgs>(args)...)); | 579 | 31 | return std::shared_ptr<IFunction>(result.release()); | 580 | 31 | } |
|
581 | | }; |
582 | | template <template <PrimitiveType> class FunctionTemplate> |
583 | | struct SimpleFunctionCurryDirectWithResultType0 { |
584 | | template <PrimitiveType ResultType> |
585 | | using T = FunctionTemplate<ResultType>; |
586 | | }; |
587 | | template <PrimitiveType... AllowedTypes> |
588 | | struct simple_function_creator_with_result_type0 { |
589 | | template <typename Class, typename... TArgs> |
590 | | static std::shared_ptr<IFunction> create_base_with_result_type(const DataTypePtr& result_type, |
591 | 170 | TArgs&&... args) { |
592 | 170 | auto create = [&]<PrimitiveType ResultType>() { |
593 | 170 | return simple_function_creator_without_type0::create< |
594 | 170 | typename Class::template T<ResultType>>(result_type, |
595 | 170 | std::forward<TArgs>(args)...); |
596 | 170 | }; _ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_19FunctionArrayCumSumEEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlTnS1_vE_clILS1_30EEEDav Line | Count | Source | 592 | 14 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 14 | return simple_function_creator_without_type0::create< | 594 | 14 | typename Class::template T<ResultType>>(result_type, | 595 | 14 | std::forward<TArgs>(args)...); | 596 | 14 | }; |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_19FunctionArrayCumSumEEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlTnS1_vE_clILS1_35EEEDav Line | Count | Source | 592 | 31 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 31 | return simple_function_creator_without_type0::create< | 594 | 31 | typename Class::template T<ResultType>>(result_type, | 595 | 31 | std::forward<TArgs>(args)...); | 596 | 31 | }; |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_17ArraySumDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlTnS1_vE_clILS1_30EEEDav Line | Count | Source | 592 | 12 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 12 | return simple_function_creator_without_type0::create< | 594 | 12 | typename Class::template T<ResultType>>(result_type, | 595 | 12 | std::forward<TArgs>(args)...); | 596 | 12 | }; |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_17ArraySumDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlTnS1_vE_clILS1_35EEEDav Line | Count | Source | 592 | 29 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 29 | return simple_function_creator_without_type0::create< | 594 | 29 | typename Class::template T<ResultType>>(result_type, | 595 | 29 | std::forward<TArgs>(args)...); | 596 | 29 | }; |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_17ArrayAvgDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlTnS1_vE_clILS1_30EEEDav Line | Count | Source | 592 | 11 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 11 | return simple_function_creator_without_type0::create< | 594 | 11 | typename Class::template T<ResultType>>(result_type, | 595 | 11 | std::forward<TArgs>(args)...); | 596 | 11 | }; |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_17ArrayAvgDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlTnS1_vE_clILS1_35EEEDav Line | Count | Source | 592 | 30 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 30 | return simple_function_creator_without_type0::create< | 594 | 30 | typename Class::template T<ResultType>>(result_type, | 595 | 30 | std::forward<TArgs>(args)...); | 596 | 30 | }; |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_21ArrayProductDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlTnS1_vE_clILS1_30EEEDav Line | Count | Source | 592 | 12 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 12 | return simple_function_creator_without_type0::create< | 594 | 12 | typename Class::template T<ResultType>>(result_type, | 595 | 12 | std::forward<TArgs>(args)...); | 596 | 12 | }; |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_21ArrayProductDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlTnS1_vE_clILS1_35EEEDav Line | Count | Source | 592 | 31 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 31 | return simple_function_creator_without_type0::create< | 594 | 31 | typename Class::template T<ResultType>>(result_type, | 595 | 31 | std::forward<TArgs>(args)...); | 596 | 31 | }; |
|
597 | 170 | std::shared_ptr<IFunction> result = nullptr; |
598 | 170 | auto type = result_type->get_primitive_type(); |
599 | | |
600 | 170 | ( |
601 | 340 | [&] { |
602 | 340 | if (type == AllowedTypes) { |
603 | 170 | static_assert(AllowedTypes == TYPE_DECIMAL128I || |
604 | 170 | AllowedTypes == TYPE_DECIMAL256); |
605 | 170 | result = create.template operator()<AllowedTypes>(); |
606 | 170 | } |
607 | 340 | }(), _ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_19FunctionArrayCumSumEEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlvE0_clEv Line | Count | Source | 601 | 45 | [&] { | 602 | 45 | if (type == AllowedTypes) { | 603 | 14 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 14 | AllowedTypes == TYPE_DECIMAL256); | 605 | 14 | result = create.template operator()<AllowedTypes>(); | 606 | 14 | } | 607 | 45 | }(), |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_19FunctionArrayCumSumEEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlvE_clEv Line | Count | Source | 601 | 45 | [&] { | 602 | 45 | if (type == AllowedTypes) { | 603 | 31 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 31 | AllowedTypes == TYPE_DECIMAL256); | 605 | 31 | result = create.template operator()<AllowedTypes>(); | 606 | 31 | } | 607 | 45 | }(), |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_17ArraySumDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlvE0_clEv Line | Count | Source | 601 | 41 | [&] { | 602 | 41 | if (type == AllowedTypes) { | 603 | 12 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 12 | AllowedTypes == TYPE_DECIMAL256); | 605 | 12 | result = create.template operator()<AllowedTypes>(); | 606 | 12 | } | 607 | 41 | }(), |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_17ArraySumDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlvE_clEv Line | Count | Source | 601 | 41 | [&] { | 602 | 41 | if (type == AllowedTypes) { | 603 | 29 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 29 | AllowedTypes == TYPE_DECIMAL256); | 605 | 29 | result = create.template operator()<AllowedTypes>(); | 606 | 29 | } | 607 | 41 | }(), |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_17ArrayAvgDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlvE0_clEv Line | Count | Source | 601 | 41 | [&] { | 602 | 41 | if (type == AllowedTypes) { | 603 | 11 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 11 | AllowedTypes == TYPE_DECIMAL256); | 605 | 11 | result = create.template operator()<AllowedTypes>(); | 606 | 11 | } | 607 | 41 | }(), |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_17ArrayAvgDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlvE_clEv Line | Count | Source | 601 | 41 | [&] { | 602 | 41 | if (type == AllowedTypes) { | 603 | 30 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 30 | AllowedTypes == TYPE_DECIMAL256); | 605 | 30 | result = create.template operator()<AllowedTypes>(); | 606 | 30 | } | 607 | 41 | }(), |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_21ArrayProductDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlvE0_clEv Line | Count | Source | 601 | 43 | [&] { | 602 | 43 | if (type == AllowedTypes) { | 603 | 12 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 12 | AllowedTypes == TYPE_DECIMAL256); | 605 | 12 | result = create.template operator()<AllowedTypes>(); | 606 | 12 | } | 607 | 43 | }(), |
_ZZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_21ArrayProductDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ENKUlvE_clEv Line | Count | Source | 601 | 43 | [&] { | 602 | 43 | if (type == AllowedTypes) { | 603 | 31 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 31 | AllowedTypes == TYPE_DECIMAL256); | 605 | 31 | result = create.template operator()<AllowedTypes>(); | 606 | 31 | } | 607 | 43 | }(), |
|
608 | 170 | ...); |
609 | | |
610 | 170 | return result; |
611 | 170 | } _ZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_19FunctionArrayCumSumEEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 591 | 45 | TArgs&&... args) { | 592 | 45 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 45 | return simple_function_creator_without_type0::create< | 594 | 45 | typename Class::template T<ResultType>>(result_type, | 595 | 45 | std::forward<TArgs>(args)...); | 596 | 45 | }; | 597 | 45 | std::shared_ptr<IFunction> result = nullptr; | 598 | 45 | auto type = result_type->get_primitive_type(); | 599 | | | 600 | 45 | ( | 601 | 45 | [&] { | 602 | 45 | if (type == AllowedTypes) { | 603 | 45 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 45 | AllowedTypes == TYPE_DECIMAL256); | 605 | 45 | result = create.template operator()<AllowedTypes>(); | 606 | 45 | } | 607 | 45 | }(), | 608 | 45 | ...); | 609 | | | 610 | 45 | return result; | 611 | 45 | } |
_ZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_17ArraySumDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 591 | 41 | TArgs&&... args) { | 592 | 41 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 41 | return simple_function_creator_without_type0::create< | 594 | 41 | typename Class::template T<ResultType>>(result_type, | 595 | 41 | std::forward<TArgs>(args)...); | 596 | 41 | }; | 597 | 41 | std::shared_ptr<IFunction> result = nullptr; | 598 | 41 | auto type = result_type->get_primitive_type(); | 599 | | | 600 | 41 | ( | 601 | 41 | [&] { | 602 | 41 | if (type == AllowedTypes) { | 603 | 41 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 41 | AllowedTypes == TYPE_DECIMAL256); | 605 | 41 | result = create.template operator()<AllowedTypes>(); | 606 | 41 | } | 607 | 41 | }(), | 608 | 41 | ...); | 609 | | | 610 | 41 | return result; | 611 | 41 | } |
_ZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_17ArrayAvgDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 591 | 41 | TArgs&&... args) { | 592 | 41 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 41 | return simple_function_creator_without_type0::create< | 594 | 41 | typename Class::template T<ResultType>>(result_type, | 595 | 41 | std::forward<TArgs>(args)...); | 596 | 41 | }; | 597 | 41 | std::shared_ptr<IFunction> result = nullptr; | 598 | 41 | auto type = result_type->get_primitive_type(); | 599 | | | 600 | 41 | ( | 601 | 41 | [&] { | 602 | 41 | if (type == AllowedTypes) { | 603 | 41 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 41 | AllowedTypes == TYPE_DECIMAL256); | 605 | 41 | result = create.template operator()<AllowedTypes>(); | 606 | 41 | } | 607 | 41 | }(), | 608 | 41 | ...); | 609 | | | 610 | 41 | return result; | 611 | 41 | } |
_ZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE28create_base_with_result_typeINS_40SimpleFunctionCurryDirectWithResultType0INS_21ArrayProductDecimalV3EEEJEEESt10shared_ptrINS_9IFunctionEERKS7_IKNS_9IDataTypeEEDpOT0_ Line | Count | Source | 591 | 43 | TArgs&&... args) { | 592 | 43 | auto create = [&]<PrimitiveType ResultType>() { | 593 | 43 | return simple_function_creator_without_type0::create< | 594 | 43 | typename Class::template T<ResultType>>(result_type, | 595 | 43 | std::forward<TArgs>(args)...); | 596 | 43 | }; | 597 | 43 | std::shared_ptr<IFunction> result = nullptr; | 598 | 43 | auto type = result_type->get_primitive_type(); | 599 | | | 600 | 43 | ( | 601 | 43 | [&] { | 602 | 43 | if (type == AllowedTypes) { | 603 | 43 | static_assert(AllowedTypes == TYPE_DECIMAL128I || | 604 | 43 | AllowedTypes == TYPE_DECIMAL256); | 605 | 43 | result = create.template operator()<AllowedTypes>(); | 606 | 43 | } | 607 | 43 | }(), | 608 | 43 | ...); | 609 | | | 610 | 43 | return result; | 611 | 43 | } |
|
612 | | |
613 | | // Create agg function with result type from FE. |
614 | | // Currently only used for decimalv3 sum and avg. |
615 | | template <template <PrimitiveType> class FunctionTemplate> |
616 | 170 | static std::shared_ptr<IFunction> creator_with_result_type(const DataTypePtr& result_type) { |
617 | 170 | return create_base_with_result_type< |
618 | 170 | SimpleFunctionCurryDirectWithResultType0<FunctionTemplate>>(result_type); |
619 | 170 | } _ZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE24creator_with_result_typeINS_19FunctionArrayCumSumEEESt10shared_ptrINS_9IFunctionEERKS5_IKNS_9IDataTypeEE Line | Count | Source | 616 | 45 | static std::shared_ptr<IFunction> creator_with_result_type(const DataTypePtr& result_type) { | 617 | 45 | return create_base_with_result_type< | 618 | 45 | SimpleFunctionCurryDirectWithResultType0<FunctionTemplate>>(result_type); | 619 | 45 | } |
_ZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE24creator_with_result_typeINS_17ArraySumDecimalV3EEESt10shared_ptrINS_9IFunctionEERKS5_IKNS_9IDataTypeEE Line | Count | Source | 616 | 41 | static std::shared_ptr<IFunction> creator_with_result_type(const DataTypePtr& result_type) { | 617 | 41 | return create_base_with_result_type< | 618 | 41 | SimpleFunctionCurryDirectWithResultType0<FunctionTemplate>>(result_type); | 619 | 41 | } |
_ZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE24creator_with_result_typeINS_17ArrayAvgDecimalV3EEESt10shared_ptrINS_9IFunctionEERKS5_IKNS_9IDataTypeEE Line | Count | Source | 616 | 41 | static std::shared_ptr<IFunction> creator_with_result_type(const DataTypePtr& result_type) { | 617 | 41 | return create_base_with_result_type< | 618 | 41 | SimpleFunctionCurryDirectWithResultType0<FunctionTemplate>>(result_type); | 619 | 41 | } |
_ZN5doris41simple_function_creator_with_result_type0IJLNS_13PrimitiveTypeE30ELS1_35EEE24creator_with_result_typeINS_21ArrayProductDecimalV3EEESt10shared_ptrINS_9IFunctionEERKS5_IKNS_9IDataTypeEE Line | Count | Source | 616 | 43 | static std::shared_ptr<IFunction> creator_with_result_type(const DataTypePtr& result_type) { | 617 | 43 | return create_base_with_result_type< | 618 | 43 | SimpleFunctionCurryDirectWithResultType0<FunctionTemplate>>(result_type); | 619 | 43 | } |
|
620 | | }; |
621 | | |
622 | | class DefaultFunctionBuilder : public FunctionBuilderImpl { |
623 | | public: |
624 | | explicit DefaultFunctionBuilder(std::shared_ptr<IFunction> function_) |
625 | 566k | : function(std::move(function_)) {} |
626 | | |
627 | | // template <template <PrimitiveType> class FunctionTemplate> |
628 | | explicit DefaultFunctionBuilder(DataTypePtr return_type) |
629 | 170 | : _return_type(std::move(return_type)) {} |
630 | | |
631 | | template <template <PrimitiveType> class FunctionTemplate> |
632 | 170 | static FunctionBuilderPtr create_array_agg_function_decimalv3(DataTypePtr return_type) { |
633 | 170 | auto builder = std::make_shared<DefaultFunctionBuilder>(return_type); |
634 | 170 | DataTypePtr real_return_type; |
635 | | // for array_cum_sum, the return type is array, |
636 | | // so here should check nested type |
637 | 170 | if (PrimitiveType::TYPE_ARRAY == return_type->get_primitive_type()) { |
638 | 45 | const DataTypeArray* data_type_array = |
639 | 45 | static_cast<const DataTypeArray*>(remove_nullable(return_type).get()); |
640 | 45 | real_return_type = data_type_array->get_nested_type(); |
641 | 125 | } else { |
642 | 125 | real_return_type = return_type; |
643 | 125 | } |
644 | 170 | builder->function = |
645 | 170 | simple_function_creator_with_result_type0<TYPE_DECIMAL128I, TYPE_DECIMAL256>:: |
646 | 170 | creator_with_result_type<FunctionTemplate>(real_return_type); |
647 | 170 | return builder; |
648 | 170 | } _ZN5doris22DefaultFunctionBuilder35create_array_agg_function_decimalv3INS_19FunctionArrayCumSumEEESt10shared_ptrINS_16IFunctionBuilderEES3_IKNS_9IDataTypeEE Line | Count | Source | 632 | 45 | static FunctionBuilderPtr create_array_agg_function_decimalv3(DataTypePtr return_type) { | 633 | 45 | auto builder = std::make_shared<DefaultFunctionBuilder>(return_type); | 634 | 45 | DataTypePtr real_return_type; | 635 | | // for array_cum_sum, the return type is array, | 636 | | // so here should check nested type | 637 | 45 | if (PrimitiveType::TYPE_ARRAY == return_type->get_primitive_type()) { | 638 | 45 | const DataTypeArray* data_type_array = | 639 | 45 | static_cast<const DataTypeArray*>(remove_nullable(return_type).get()); | 640 | 45 | real_return_type = data_type_array->get_nested_type(); | 641 | 45 | } else { | 642 | 0 | real_return_type = return_type; | 643 | 0 | } | 644 | 45 | builder->function = | 645 | 45 | simple_function_creator_with_result_type0<TYPE_DECIMAL128I, TYPE_DECIMAL256>:: | 646 | 45 | creator_with_result_type<FunctionTemplate>(real_return_type); | 647 | 45 | return builder; | 648 | 45 | } |
_ZN5doris22DefaultFunctionBuilder35create_array_agg_function_decimalv3INS_17ArraySumDecimalV3EEESt10shared_ptrINS_16IFunctionBuilderEES3_IKNS_9IDataTypeEE Line | Count | Source | 632 | 41 | static FunctionBuilderPtr create_array_agg_function_decimalv3(DataTypePtr return_type) { | 633 | 41 | auto builder = std::make_shared<DefaultFunctionBuilder>(return_type); | 634 | 41 | DataTypePtr real_return_type; | 635 | | // for array_cum_sum, the return type is array, | 636 | | // so here should check nested type | 637 | 41 | if (PrimitiveType::TYPE_ARRAY == return_type->get_primitive_type()) { | 638 | 0 | const DataTypeArray* data_type_array = | 639 | 0 | static_cast<const DataTypeArray*>(remove_nullable(return_type).get()); | 640 | 0 | real_return_type = data_type_array->get_nested_type(); | 641 | 41 | } else { | 642 | 41 | real_return_type = return_type; | 643 | 41 | } | 644 | 41 | builder->function = | 645 | 41 | simple_function_creator_with_result_type0<TYPE_DECIMAL128I, TYPE_DECIMAL256>:: | 646 | 41 | creator_with_result_type<FunctionTemplate>(real_return_type); | 647 | 41 | return builder; | 648 | 41 | } |
_ZN5doris22DefaultFunctionBuilder35create_array_agg_function_decimalv3INS_17ArrayAvgDecimalV3EEESt10shared_ptrINS_16IFunctionBuilderEES3_IKNS_9IDataTypeEE Line | Count | Source | 632 | 41 | static FunctionBuilderPtr create_array_agg_function_decimalv3(DataTypePtr return_type) { | 633 | 41 | auto builder = std::make_shared<DefaultFunctionBuilder>(return_type); | 634 | 41 | DataTypePtr real_return_type; | 635 | | // for array_cum_sum, the return type is array, | 636 | | // so here should check nested type | 637 | 41 | if (PrimitiveType::TYPE_ARRAY == return_type->get_primitive_type()) { | 638 | 0 | const DataTypeArray* data_type_array = | 639 | 0 | static_cast<const DataTypeArray*>(remove_nullable(return_type).get()); | 640 | 0 | real_return_type = data_type_array->get_nested_type(); | 641 | 41 | } else { | 642 | 41 | real_return_type = return_type; | 643 | 41 | } | 644 | 41 | builder->function = | 645 | 41 | simple_function_creator_with_result_type0<TYPE_DECIMAL128I, TYPE_DECIMAL256>:: | 646 | 41 | creator_with_result_type<FunctionTemplate>(real_return_type); | 647 | 41 | return builder; | 648 | 41 | } |
_ZN5doris22DefaultFunctionBuilder35create_array_agg_function_decimalv3INS_21ArrayProductDecimalV3EEESt10shared_ptrINS_16IFunctionBuilderEES3_IKNS_9IDataTypeEE Line | Count | Source | 632 | 43 | static FunctionBuilderPtr create_array_agg_function_decimalv3(DataTypePtr return_type) { | 633 | 43 | auto builder = std::make_shared<DefaultFunctionBuilder>(return_type); | 634 | 43 | DataTypePtr real_return_type; | 635 | | // for array_cum_sum, the return type is array, | 636 | | // so here should check nested type | 637 | 43 | if (PrimitiveType::TYPE_ARRAY == return_type->get_primitive_type()) { | 638 | 0 | const DataTypeArray* data_type_array = | 639 | 0 | static_cast<const DataTypeArray*>(remove_nullable(return_type).get()); | 640 | 0 | real_return_type = data_type_array->get_nested_type(); | 641 | 43 | } else { | 642 | 43 | real_return_type = return_type; | 643 | 43 | } | 644 | 43 | builder->function = | 645 | 43 | simple_function_creator_with_result_type0<TYPE_DECIMAL128I, TYPE_DECIMAL256>:: | 646 | 43 | creator_with_result_type<FunctionTemplate>(real_return_type); | 647 | 43 | return builder; | 648 | 43 | } |
|
649 | | |
650 | 553k | void check_number_of_arguments(size_t number_of_arguments) const override { |
651 | 553k | function->check_number_of_arguments(number_of_arguments); |
652 | 553k | } |
653 | | |
654 | 520 | String get_name() const override { return function->get_name(); } |
655 | 1.38k | bool is_variadic() const override { return function->is_variadic(); } |
656 | 0 | size_t get_number_of_arguments() const override { return function->get_number_of_arguments(); } |
657 | | |
658 | 0 | ColumnNumbers get_arguments_that_are_always_constant() const override { |
659 | 0 | return function->get_arguments_that_are_always_constant(); |
660 | 0 | } |
661 | | |
662 | | protected: |
663 | 0 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
664 | 0 | return function->get_return_type_impl(arguments); |
665 | 0 | } |
666 | 553k | DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const override { |
667 | 553k | return function->get_return_type_impl(arguments); |
668 | 553k | } |
669 | | |
670 | 552k | bool use_default_implementation_for_nulls() const override { |
671 | 552k | return function->use_default_implementation_for_nulls(); |
672 | 552k | } |
673 | | |
674 | 554k | bool skip_return_type_check() const override { return function->skip_return_type_check(); } |
675 | | |
676 | 0 | bool need_replace_null_data_to_default() const override { |
677 | 0 | return function->need_replace_null_data_to_default(); |
678 | 0 | } |
679 | | |
680 | | FunctionBasePtr build_impl(const ColumnsWithTypeAndName& arguments, |
681 | 553k | const DataTypePtr& return_type) const override { |
682 | 553k | DataTypes data_types(arguments.size()); |
683 | 1.65M | for (size_t i = 0; i < arguments.size(); ++i) { |
684 | 1.09M | data_types[i] = arguments[i].type; |
685 | 1.09M | } |
686 | 553k | return std::make_shared<DefaultFunction>(function, data_types, return_type); |
687 | 553k | } |
688 | | |
689 | 11.0k | DataTypes get_variadic_argument_types_impl() const override { |
690 | 11.0k | return function->get_variadic_argument_types_impl(); |
691 | 11.0k | } |
692 | | |
693 | | private: |
694 | | std::shared_ptr<IFunction> function; |
695 | | DataTypePtr _return_type; |
696 | | }; |
697 | | |
698 | | using FunctionPtr = std::shared_ptr<IFunction>; |
699 | | /** Return ColumnNullable of src, with null map as OR-ed null maps of args columns in blocks. |
700 | | * Or ColumnConst(ColumnNullable) if the result is always NULL or if the result is constant and always not NULL. |
701 | | */ |
702 | | ColumnPtr wrap_in_nullable(const ColumnPtr& src, const Block& block, const ColumnNumbers& args, |
703 | | size_t input_rows_count); |
704 | | ColumnPtr wrap_in_nullable(const ColumnPtr& src, const Block& block, const ColumnNumbers& args, |
705 | | const NullableColumnInfos& nullable_column_infos, |
706 | | size_t input_rows_count); |
707 | | |
708 | | } // namespace doris |