| 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 | |