1#include <Functions/FunctionFactory.h>
2#include <Functions/FunctionHelpers.h>
3#include <Functions/FunctionsRandom.h>
4
5namespace DB
6{
7
8template <typename ToType, typename Name>
9class ExecutableFunctionRandomConstant : public IExecutableFunctionImpl
10{
11public:
12 explicit ExecutableFunctionRandomConstant(ToType value_) : value(value_) {}
13
14 String getName() const override { return Name::name; }
15
16bool 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
23private:
24 ToType value;
25};
26
27template <typename ToType, typename Name>
28class FunctionBaseRandomConstant : public IFunctionBaseImpl
29{
30public:
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
56private:
57 ToType value;
58 DataTypes argument_types;
59 DataTypePtr return_type;
60};
61
62template <typename ToType, typename Name>
63class RandomConstantOverloadResolver : public IFunctionOverloadResolverImpl
64{
65public:
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
106struct NameRandConstant { static constexpr auto name = "randConstant"; };
107using FunctionBuilderRandConstant = RandomConstantOverloadResolver<UInt32, NameRandConstant>;
108
109void registerFunctionRandConstant(FunctionFactory & factory)
110{
111 factory.registerFunction<FunctionBuilderRandConstant>();
112}
113
114}
115
116
117