1 | #pragma once |
2 | #include <Functions/IFunctionImpl.h> |
3 | |
4 | namespace DB |
5 | { |
6 | |
7 | /// Adaptors are implement user interfaces from IFunction.h via developer interfaces from IFunctionImpl.h |
8 | /// Typically, you don't need to change this classes. |
9 | |
10 | class ExecutableFunctionAdaptor final : public IExecutableFunction |
11 | { |
12 | public: |
13 | explicit ExecutableFunctionAdaptor(ExecutableFunctionImplPtr impl_) : impl(std::move(impl_)) {} |
14 | |
15 | String getName() const final { return impl->getName(); } |
16 | |
17 | void execute(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count, bool dry_run) final; |
18 | |
19 | void createLowCardinalityResultCache(size_t cache_size) override; |
20 | |
21 | private: |
22 | ExecutableFunctionImplPtr impl; |
23 | |
24 | /// Cache is created by function createLowCardinalityResultCache() |
25 | ExecutableFunctionLowCardinalityResultCachePtr low_cardinality_result_cache; |
26 | |
27 | bool defaultImplementationForConstantArguments( |
28 | Block & block, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run); |
29 | |
30 | bool defaultImplementationForNulls( |
31 | Block & block, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run); |
32 | |
33 | void executeWithoutLowCardinalityColumns( |
34 | Block & block, const ColumnNumbers & args, size_t result, size_t input_rows_count, bool dry_run); |
35 | }; |
36 | |
37 | class FunctionBaseAdaptor final : public IFunctionBase |
38 | { |
39 | public: |
40 | explicit FunctionBaseAdaptor(FunctionBaseImplPtr impl_) : impl(std::move(impl_)) {} |
41 | |
42 | String getName() const final { return impl->getName(); } |
43 | |
44 | const DataTypes & getArgumentTypes() const final { return impl->getArgumentTypes(); } |
45 | const DataTypePtr & getReturnType() const final { return impl->getReturnType(); } |
46 | |
47 | ExecutableFunctionPtr prepare(const Block & sample_block, const ColumnNumbers & arguments, size_t result) const final |
48 | { |
49 | return std::make_shared<ExecutableFunctionAdaptor>(impl->prepare(sample_block, arguments, result)); |
50 | } |
51 | |
52 | #if USE_EMBEDDED_COMPILER |
53 | |
54 | bool isCompilable() const final { return impl->isCompilable(); } |
55 | |
56 | llvm::Value * compile(llvm::IRBuilderBase & builder, ValuePlaceholders values) const override |
57 | { |
58 | return impl->compile(builder, std::move(values)); |
59 | } |
60 | |
61 | #endif |
62 | |
63 | bool isStateful() const final { return impl->isStateful(); } |
64 | bool isSuitableForConstantFolding() const final { return impl->isSuitableForConstantFolding(); } |
65 | |
66 | ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const Block & block, const ColumnNumbers & arguments) const final |
67 | { |
68 | return impl->getResultIfAlwaysReturnsConstantAndHasArguments(block, arguments); |
69 | } |
70 | |
71 | bool isInjective(const Block & sample_block) final { return impl->isInjective(sample_block); } |
72 | bool isDeterministic() const final { return impl->isDeterministic(); } |
73 | bool isDeterministicInScopeOfQuery() const final { return impl->isDeterministicInScopeOfQuery(); } |
74 | bool hasInformationAboutMonotonicity() const final { return impl->hasInformationAboutMonotonicity(); } |
75 | |
76 | Monotonicity getMonotonicityForRange(const IDataType & type, const Field & left, const Field & right) const final |
77 | { |
78 | return impl->getMonotonicityForRange(type, left, right); |
79 | } |
80 | |
81 | const IFunctionBaseImpl * getImpl() const { return impl.get(); } |
82 | |
83 | private: |
84 | FunctionBaseImplPtr impl; |
85 | }; |
86 | |
87 | |
88 | class FunctionOverloadResolverAdaptor final : public IFunctionOverloadResolver |
89 | { |
90 | public: |
91 | explicit FunctionOverloadResolverAdaptor(FunctionOverloadResolverImplPtr impl_) : impl(std::move(impl_)) {} |
92 | |
93 | String getName() const final { return impl->getName(); } |
94 | |
95 | bool isDeterministic() const final { return impl->isDeterministic(); } |
96 | |
97 | bool isDeterministicInScopeOfQuery() const final { return impl->isDeterministicInScopeOfQuery(); } |
98 | |
99 | bool isStateful() const final { return impl->isStateful(); } |
100 | |
101 | bool isVariadic() const final { return impl->isVariadic(); } |
102 | |
103 | size_t getNumberOfArguments() const final { return impl->getNumberOfArguments(); } |
104 | |
105 | void checkNumberOfArguments(size_t number_of_arguments) const final; |
106 | |
107 | FunctionBaseImplPtr buildImpl(const ColumnsWithTypeAndName & arguments) const |
108 | { |
109 | return impl->build(arguments, getReturnType(arguments)); |
110 | } |
111 | |
112 | FunctionBasePtr build(const ColumnsWithTypeAndName & arguments) const final |
113 | { |
114 | return std::make_shared<FunctionBaseAdaptor>(buildImpl(arguments)); |
115 | } |
116 | |
117 | void getLambdaArgumentTypes(DataTypes & arguments) const final |
118 | { |
119 | checkNumberOfArguments(arguments.size()); |
120 | impl->getLambdaArgumentTypes(arguments); |
121 | } |
122 | |
123 | ColumnNumbers getArgumentsThatAreAlwaysConstant() const final { return impl->getArgumentsThatAreAlwaysConstant(); } |
124 | |
125 | ColumnNumbers getArgumentsThatDontImplyNullableReturnType(size_t number_of_arguments) const final |
126 | { |
127 | return impl->getArgumentsThatDontImplyNullableReturnType(number_of_arguments); |
128 | } |
129 | |
130 | private: |
131 | FunctionOverloadResolverImplPtr impl; |
132 | |
133 | DataTypePtr getReturnTypeWithoutLowCardinality(const ColumnsWithTypeAndName & arguments) const; |
134 | DataTypePtr getReturnType(const ColumnsWithTypeAndName & arguments) const; |
135 | }; |
136 | |
137 | |
138 | /// Following classes are implement IExecutableFunctionImpl, IFunctionBaseImpl and IFunctionOverloadResolverImpl via IFunction. |
139 | |
140 | class DefaultExecutable final : public IExecutableFunctionImpl |
141 | { |
142 | public: |
143 | explicit DefaultExecutable(std::shared_ptr<IFunction> function_) : function(std::move(function_)) {} |
144 | |
145 | String getName() const override { return function->getName(); } |
146 | |
147 | protected: |
148 | void execute(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) final |
149 | { |
150 | return function->executeImpl(block, arguments, result, input_rows_count); |
151 | } |
152 | void executeDryRun(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) final |
153 | { |
154 | return function->executeImplDryRun(block, arguments, result, input_rows_count); |
155 | } |
156 | bool useDefaultImplementationForNulls() const final { return function->useDefaultImplementationForNulls(); } |
157 | bool useDefaultImplementationForConstants() const final { return function->useDefaultImplementationForConstants(); } |
158 | bool useDefaultImplementationForLowCardinalityColumns() const final { return function->useDefaultImplementationForLowCardinalityColumns(); } |
159 | ColumnNumbers getArgumentsThatAreAlwaysConstant() const final { return function->getArgumentsThatAreAlwaysConstant(); } |
160 | bool canBeExecutedOnDefaultArguments() const override { return function->canBeExecutedOnDefaultArguments(); } |
161 | |
162 | private: |
163 | std::shared_ptr<IFunction> function; |
164 | }; |
165 | |
166 | class DefaultFunction final : public IFunctionBaseImpl |
167 | { |
168 | public: |
169 | DefaultFunction(std::shared_ptr<IFunction> function_, DataTypes arguments_, DataTypePtr return_type_) |
170 | : function(std::move(function_)), arguments(std::move(arguments_)), return_type(std::move(return_type_)) {} |
171 | |
172 | String getName() const override { return function->getName(); } |
173 | |
174 | const DataTypes & getArgumentTypes() const override { return arguments; } |
175 | const DataTypePtr & getReturnType() const override { return return_type; } |
176 | |
177 | #if USE_EMBEDDED_COMPILER |
178 | |
179 | bool isCompilable() const override { return function->isCompilable(arguments); } |
180 | |
181 | llvm::Value * compile(llvm::IRBuilderBase & builder, ValuePlaceholders values) const override { return function->compile(builder, arguments, std::move(values)); } |
182 | |
183 | #endif |
184 | |
185 | ExecutableFunctionImplPtr prepare(const Block & /*sample_block*/, const ColumnNumbers & /*arguments*/, size_t /*result*/) const override |
186 | { |
187 | return std::make_unique<DefaultExecutable>(function); |
188 | } |
189 | |
190 | bool isSuitableForConstantFolding() const override { return function->isSuitableForConstantFolding(); } |
191 | ColumnPtr getResultIfAlwaysReturnsConstantAndHasArguments(const Block & block, const ColumnNumbers & arguments_) const override |
192 | { |
193 | return function->getResultIfAlwaysReturnsConstantAndHasArguments(block, arguments_); |
194 | } |
195 | |
196 | bool isStateful() const override { return function->isStateful(); } |
197 | |
198 | bool isInjective(const Block & sample_block) override { return function->isInjective(sample_block); } |
199 | |
200 | bool isDeterministic() const override { return function->isDeterministic(); } |
201 | |
202 | bool isDeterministicInScopeOfQuery() const override { return function->isDeterministicInScopeOfQuery(); } |
203 | |
204 | bool hasInformationAboutMonotonicity() const override { return function->hasInformationAboutMonotonicity(); } |
205 | |
206 | using Monotonicity = IFunctionBase::Monotonicity; |
207 | Monotonicity getMonotonicityForRange(const IDataType & type, const Field & left, const Field & right) const override |
208 | { |
209 | return function->getMonotonicityForRange(type, left, right); |
210 | } |
211 | private: |
212 | std::shared_ptr<IFunction> function; |
213 | DataTypes arguments; |
214 | DataTypePtr return_type; |
215 | }; |
216 | |
217 | class DefaultOverloadResolver : public IFunctionOverloadResolverImpl |
218 | { |
219 | public: |
220 | explicit DefaultOverloadResolver(std::shared_ptr<IFunction> function_) : function(std::move(function_)) {} |
221 | |
222 | void checkNumberOfArgumentsIfVariadic(size_t number_of_arguments) const override |
223 | { |
224 | return function->checkNumberOfArgumentsIfVariadic(number_of_arguments); |
225 | } |
226 | |
227 | bool isDeterministic() const override { return function->isDeterministic(); } |
228 | bool isDeterministicInScopeOfQuery() const override { return function->isDeterministicInScopeOfQuery(); } |
229 | |
230 | String getName() const override { return function->getName(); } |
231 | bool isStateful() const override { return function->isStateful(); } |
232 | bool isVariadic() const override { return function->isVariadic(); } |
233 | size_t getNumberOfArguments() const override { return function->getNumberOfArguments(); } |
234 | |
235 | ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return function->getArgumentsThatAreAlwaysConstant(); } |
236 | ColumnNumbers getArgumentsThatDontImplyNullableReturnType(size_t number_of_arguments) const override |
237 | { |
238 | return function->getArgumentsThatDontImplyNullableReturnType(number_of_arguments); |
239 | } |
240 | |
241 | DataTypePtr getReturnType(const DataTypes & arguments) const override { return function->getReturnTypeImpl(arguments); } |
242 | DataTypePtr getReturnType(const ColumnsWithTypeAndName & arguments) const override { return function->getReturnTypeImpl(arguments); } |
243 | |
244 | bool useDefaultImplementationForNulls() const override { return function->useDefaultImplementationForNulls(); } |
245 | bool useDefaultImplementationForLowCardinalityColumns() const override { return function->useDefaultImplementationForLowCardinalityColumns(); } |
246 | bool canBeExecutedOnLowCardinalityDictionary() const override { return function->canBeExecutedOnLowCardinalityDictionary(); } |
247 | |
248 | FunctionBaseImplPtr build(const ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type) const override |
249 | { |
250 | DataTypes data_types(arguments.size()); |
251 | for (size_t i = 0; i < arguments.size(); ++i) |
252 | data_types[i] = arguments[i].type; |
253 | return std::make_unique<DefaultFunction>(function, data_types, return_type); |
254 | } |
255 | |
256 | void getLambdaArgumentTypes(DataTypes & arguments) const override { function->getLambdaArgumentTypes(arguments); } |
257 | |
258 | private: |
259 | std::shared_ptr<IFunction> function; |
260 | }; |
261 | |
262 | |
263 | } |
264 | |