1 | #include <Functions/FunctionFactory.h> |
2 | #include <Functions/FunctionHelpers.h> |
3 | #include <Functions/FunctionsRandom.h> |
4 | |
5 | namespace DB |
6 | { |
7 | |
8 | template <typename ToType, typename Name> |
9 | class ExecutableFunctionRandomConstant : public IExecutableFunctionImpl |
10 | { |
11 | public: |
12 | explicit ExecutableFunctionRandomConstant(ToType value_) : value(value_) {} |
13 | |
14 | String getName() const override { return Name::name; } |
15 | |
16 | bool useDefaultImplementationForNulls() const override { return false; } |
17 | |
18 | void execute(Block & block, const ColumnNumbers &, size_t result, size_t input_rows_count) override |
19 | { |
20 | block.getByPosition(result).column = DataTypeNumber<ToType>().createColumnConst(input_rows_count, value); |
21 | } |
22 | |
23 | private: |
24 | ToType value; |
25 | }; |
26 | |
27 | template <typename ToType, typename Name> |
28 | class FunctionBaseRandomConstant : public IFunctionBaseImpl |
29 | { |
30 | public: |
31 | explicit FunctionBaseRandomConstant(ToType value_, DataTypes argument_types_, DataTypePtr return_type_) |
32 | : value(value_) |
33 | , argument_types(std::move(argument_types_)) |
34 | , return_type(std::move(return_type_)) {} |
35 | |
36 | String getName() const override { return Name::name; } |
37 | |
38 | const DataTypes & getArgumentTypes() const override |
39 | { |
40 | return argument_types; |
41 | } |
42 | |
43 | const DataTypePtr & getReturnType() const override |
44 | { |
45 | return return_type; |
46 | } |
47 | |
48 | ExecutableFunctionImplPtr prepare(const Block &, const ColumnNumbers &, size_t) const override |
49 | { |
50 | return std::make_unique<ExecutableFunctionRandomConstant<ToType, Name>>(value); |
51 | } |
52 | |
53 | bool isDeterministic() const override { return false; } |
54 | bool isDeterministicInScopeOfQuery() const override { return true; } |
55 | |
56 | private: |
57 | ToType value; |
58 | DataTypes argument_types; |
59 | DataTypePtr return_type; |
60 | }; |
61 | |
62 | template <typename ToType, typename Name> |
63 | class RandomConstantOverloadResolver : public IFunctionOverloadResolverImpl |
64 | { |
65 | public: |
66 | static constexpr auto name = Name::name; |
67 | String getName() const override { return name; } |
68 | |
69 | bool isDeterministic() const override { return false; } |
70 | bool useDefaultImplementationForNulls() const override { return false; } |
71 | |
72 | bool isVariadic() const override { return true; } |
73 | size_t getNumberOfArguments() const override { return 0; } |
74 | |
75 | void checkNumberOfArgumentsIfVariadic(size_t number_of_arguments) const override |
76 | { |
77 | if (number_of_arguments > 1) |
78 | throw Exception("Number of arguments for function " + getName() + " doesn't match: passed " |
79 | + toString(number_of_arguments) + ", should be 0 or 1." , |
80 | ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); |
81 | } |
82 | |
83 | static FunctionOverloadResolverImplPtr create(const Context &) |
84 | { |
85 | return std::make_unique<RandomConstantOverloadResolver<ToType, Name>>(); |
86 | } |
87 | |
88 | DataTypePtr getReturnType(const DataTypes &) const override { return std::make_shared<DataTypeNumber<ToType>>(); } |
89 | |
90 | FunctionBaseImplPtr build(const ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type) const override |
91 | { |
92 | DataTypes argument_types; |
93 | |
94 | if (!arguments.empty()) |
95 | argument_types.emplace_back(arguments.back().type); |
96 | |
97 | typename ColumnVector<ToType>::Container vec_to(1); |
98 | RandImpl::execute(reinterpret_cast<char *>(vec_to.data()), sizeof(ToType)); |
99 | ToType value = vec_to[0]; |
100 | |
101 | return std::make_unique<FunctionBaseRandomConstant<ToType, Name>>(value, argument_types, return_type); |
102 | } |
103 | }; |
104 | |
105 | |
106 | struct NameRandConstant { static constexpr auto name = "randConstant" ; }; |
107 | using FunctionBuilderRandConstant = RandomConstantOverloadResolver<UInt32, NameRandConstant>; |
108 | |
109 | void registerFunctionRandConstant(FunctionFactory & factory) |
110 | { |
111 | factory.registerFunction<FunctionBuilderRandConstant>(); |
112 | } |
113 | |
114 | } |
115 | |
116 | |
117 | |