1#pragma once
2#include <Functions/IFunctionImpl.h>
3
4namespace 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
10class ExecutableFunctionAdaptor final : public IExecutableFunction
11{
12public:
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
21private:
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
37class FunctionBaseAdaptor final : public IFunctionBase
38{
39public:
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
83private:
84 FunctionBaseImplPtr impl;
85};
86
87
88class FunctionOverloadResolverAdaptor final : public IFunctionOverloadResolver
89{
90public:
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
130private:
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
140class DefaultExecutable final : public IExecutableFunctionImpl
141{
142public:
143 explicit DefaultExecutable(std::shared_ptr<IFunction> function_) : function(std::move(function_)) {}
144
145 String getName() const override { return function->getName(); }
146
147protected:
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
162private:
163 std::shared_ptr<IFunction> function;
164};
165
166class DefaultFunction final : public IFunctionBaseImpl
167{
168public:
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 }
211private:
212 std::shared_ptr<IFunction> function;
213 DataTypes arguments;
214 DataTypePtr return_type;
215};
216
217class DefaultOverloadResolver : public IFunctionOverloadResolverImpl
218{
219public:
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
258private:
259 std::shared_ptr<IFunction> function;
260};
261
262
263}
264