1 | #include <AggregateFunctions/AggregateFunctionQuantile.h> |
2 | |
3 | #include <AggregateFunctions/AggregateFunctionFactory.h> |
4 | #include <AggregateFunctions/Helpers.h> |
5 | |
6 | #include <Core/Field.h> |
7 | #include "registerAggregateFunctions.h" |
8 | |
9 | namespace DB |
10 | { |
11 | |
12 | namespace ErrorCodes |
13 | { |
14 | extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; |
15 | } |
16 | |
17 | namespace |
18 | { |
19 | |
20 | template <typename Value, bool float_return> using FuncQuantile = AggregateFunctionQuantile<Value, QuantileReservoirSampler<Value>, NameQuantile, false, std::conditional_t<float_return, Float64, void>, false>; |
21 | template <typename Value, bool float_return> using FuncQuantiles = AggregateFunctionQuantile<Value, QuantileReservoirSampler<Value>, NameQuantiles, false, std::conditional_t<float_return, Float64, void>, true>; |
22 | |
23 | template <typename Value, bool float_return> using FuncQuantileDeterministic = AggregateFunctionQuantile<Value, QuantileReservoirSamplerDeterministic<Value>, NameQuantileDeterministic, true, std::conditional_t<float_return, Float64, void>, false>; |
24 | template <typename Value, bool float_return> using FuncQuantilesDeterministic = AggregateFunctionQuantile<Value, QuantileReservoirSamplerDeterministic<Value>, NameQuantilesDeterministic, true, std::conditional_t<float_return, Float64, void>, true>; |
25 | |
26 | template <typename Value, bool _> using FuncQuantileExact = AggregateFunctionQuantile<Value, QuantileExact<Value>, NameQuantileExact, false, void, false>; |
27 | template <typename Value, bool _> using FuncQuantilesExact = AggregateFunctionQuantile<Value, QuantileExact<Value>, NameQuantilesExact, false, void, true>; |
28 | |
29 | template <typename Value, bool _> using FuncQuantileExactExclusive = AggregateFunctionQuantile<Value, QuantileExactExclusive<Value>, NameQuantileExactExclusive, false, Float64, false>; |
30 | template <typename Value, bool _> using FuncQuantilesExactExclusive = AggregateFunctionQuantile<Value, QuantileExactExclusive<Value>, NameQuantilesExactExclusive, false, Float64, true>; |
31 | |
32 | template <typename Value, bool _> using FuncQuantileExactInclusive = AggregateFunctionQuantile<Value, QuantileExactInclusive<Value>, NameQuantileExactInclusive, false, Float64, false>; |
33 | template <typename Value, bool _> using FuncQuantilesExactInclusive = AggregateFunctionQuantile<Value, QuantileExactInclusive<Value>, NameQuantilesExactInclusive, false, Float64, true>; |
34 | |
35 | template <typename Value, bool _> using FuncQuantileExactWeighted = AggregateFunctionQuantile<Value, QuantileExactWeighted<Value>, NameQuantileExactWeighted, true, void, false>; |
36 | template <typename Value, bool _> using FuncQuantilesExactWeighted = AggregateFunctionQuantile<Value, QuantileExactWeighted<Value>, NameQuantilesExactWeighted, true, void, true>; |
37 | |
38 | template <typename Value, bool _> using FuncQuantileTiming = AggregateFunctionQuantile<Value, QuantileTiming<Value>, NameQuantileTiming, false, Float32, false>; |
39 | template <typename Value, bool _> using FuncQuantilesTiming = AggregateFunctionQuantile<Value, QuantileTiming<Value>, NameQuantilesTiming, false, Float32, true>; |
40 | |
41 | template <typename Value, bool _> using FuncQuantileTimingWeighted = AggregateFunctionQuantile<Value, QuantileTiming<Value>, NameQuantileTimingWeighted, true, Float32, false>; |
42 | template <typename Value, bool _> using FuncQuantilesTimingWeighted = AggregateFunctionQuantile<Value, QuantileTiming<Value>, NameQuantilesTimingWeighted, true, Float32, true>; |
43 | |
44 | template <typename Value, bool float_return> using FuncQuantileTDigest = AggregateFunctionQuantile<Value, QuantileTDigest<Value>, NameQuantileTDigest, false, std::conditional_t<float_return, Float32, void>, false>; |
45 | template <typename Value, bool float_return> using FuncQuantilesTDigest = AggregateFunctionQuantile<Value, QuantileTDigest<Value>, NameQuantilesTDigest, false, std::conditional_t<float_return, Float32, void>, true>; |
46 | |
47 | template <typename Value, bool float_return> using FuncQuantileTDigestWeighted = AggregateFunctionQuantile<Value, QuantileTDigest<Value>, NameQuantileTDigestWeighted, true, std::conditional_t<float_return, Float32, void>, false>; |
48 | template <typename Value, bool float_return> using FuncQuantilesTDigestWeighted = AggregateFunctionQuantile<Value, QuantileTDigest<Value>, NameQuantilesTDigestWeighted, true, std::conditional_t<float_return, Float32, void>, true>; |
49 | |
50 | |
51 | template <template <typename, bool> class Function> |
52 | static constexpr bool supportDecimal() |
53 | { |
54 | return std::is_same_v<Function<Float32, false>, FuncQuantile<Float32, false>> || |
55 | std::is_same_v<Function<Float32, false>, FuncQuantiles<Float32, false>> || |
56 | std::is_same_v<Function<Float32, false>, FuncQuantileExact<Float32, false>> || |
57 | std::is_same_v<Function<Float32, false>, FuncQuantilesExact<Float32, false>> || |
58 | std::is_same_v<Function<Float32, false>, FuncQuantileExactWeighted<Float32, false>> || |
59 | std::is_same_v<Function<Float32, false>, FuncQuantilesExactWeighted<Float32, false>>; |
60 | } |
61 | |
62 | |
63 | template <template <typename, bool> class Function> |
64 | AggregateFunctionPtr createAggregateFunctionQuantile(const std::string & name, const DataTypes & argument_types, const Array & params) |
65 | { |
66 | /// Second argument type check doesn't depend on the type of the first one. |
67 | Function<void, true>::assertSecondArg(argument_types); |
68 | |
69 | const DataTypePtr & argument_type = argument_types[0]; |
70 | WhichDataType which(argument_type); |
71 | |
72 | #define DISPATCH(TYPE) \ |
73 | if (which.idx == TypeIndex::TYPE) return std::make_shared<Function<TYPE, true>>(argument_type, params); |
74 | FOR_NUMERIC_TYPES(DISPATCH) |
75 | #undef DISPATCH |
76 | if (which.idx == TypeIndex::Date) return std::make_shared<Function<DataTypeDate::FieldType, false>>(argument_type, params); |
77 | if (which.idx == TypeIndex::DateTime) return std::make_shared<Function<DataTypeDateTime::FieldType, false>>(argument_type, params); |
78 | |
79 | if constexpr (supportDecimal<Function>()) |
80 | { |
81 | if (which.idx == TypeIndex::Decimal32) return std::make_shared<Function<Decimal32, false>>(argument_type, params); |
82 | if (which.idx == TypeIndex::Decimal64) return std::make_shared<Function<Decimal64, false>>(argument_type, params); |
83 | if (which.idx == TypeIndex::Decimal128) return std::make_shared<Function<Decimal128, false>>(argument_type, params); |
84 | } |
85 | |
86 | throw Exception("Illegal type " + argument_type->getName() + " of argument for aggregate function " + name, |
87 | ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); |
88 | } |
89 | |
90 | } |
91 | |
92 | void registerAggregateFunctionsQuantile(AggregateFunctionFactory & factory) |
93 | { |
94 | factory.registerFunction(NameQuantile::name, createAggregateFunctionQuantile<FuncQuantile>); |
95 | factory.registerFunction(NameQuantiles::name, createAggregateFunctionQuantile<FuncQuantiles>); |
96 | |
97 | factory.registerFunction(NameQuantileDeterministic::name, createAggregateFunctionQuantile<FuncQuantileDeterministic>); |
98 | factory.registerFunction(NameQuantilesDeterministic::name, createAggregateFunctionQuantile<FuncQuantilesDeterministic>); |
99 | |
100 | factory.registerFunction(NameQuantileExact::name, createAggregateFunctionQuantile<FuncQuantileExact>); |
101 | factory.registerFunction(NameQuantilesExact::name, createAggregateFunctionQuantile<FuncQuantilesExact>); |
102 | |
103 | factory.registerFunction(NameQuantileExactExclusive::name, createAggregateFunctionQuantile<FuncQuantileExactExclusive>); |
104 | factory.registerFunction(NameQuantilesExactExclusive::name, createAggregateFunctionQuantile<FuncQuantilesExactExclusive>); |
105 | |
106 | factory.registerFunction(NameQuantileExactInclusive::name, createAggregateFunctionQuantile<FuncQuantileExactInclusive>); |
107 | factory.registerFunction(NameQuantilesExactInclusive::name, createAggregateFunctionQuantile<FuncQuantilesExactInclusive>); |
108 | |
109 | factory.registerFunction(NameQuantileExactWeighted::name, createAggregateFunctionQuantile<FuncQuantileExactWeighted>); |
110 | factory.registerFunction(NameQuantilesExactWeighted::name, createAggregateFunctionQuantile<FuncQuantilesExactWeighted>); |
111 | |
112 | factory.registerFunction(NameQuantileTiming::name, createAggregateFunctionQuantile<FuncQuantileTiming>); |
113 | factory.registerFunction(NameQuantilesTiming::name, createAggregateFunctionQuantile<FuncQuantilesTiming>); |
114 | |
115 | factory.registerFunction(NameQuantileTimingWeighted::name, createAggregateFunctionQuantile<FuncQuantileTimingWeighted>); |
116 | factory.registerFunction(NameQuantilesTimingWeighted::name, createAggregateFunctionQuantile<FuncQuantilesTimingWeighted>); |
117 | |
118 | factory.registerFunction(NameQuantileTDigest::name, createAggregateFunctionQuantile<FuncQuantileTDigest>); |
119 | factory.registerFunction(NameQuantilesTDigest::name, createAggregateFunctionQuantile<FuncQuantilesTDigest>); |
120 | |
121 | factory.registerFunction(NameQuantileTDigestWeighted::name, createAggregateFunctionQuantile<FuncQuantileTDigestWeighted>); |
122 | factory.registerFunction(NameQuantilesTDigestWeighted::name, createAggregateFunctionQuantile<FuncQuantilesTDigestWeighted>); |
123 | |
124 | /// 'median' is an alias for 'quantile' |
125 | factory.registerAlias("median" , NameQuantile::name); |
126 | factory.registerAlias("medianDeterministic" , NameQuantileDeterministic::name); |
127 | factory.registerAlias("medianExact" , NameQuantileExact::name); |
128 | factory.registerAlias("medianExactWeighted" , NameQuantileExactWeighted::name); |
129 | factory.registerAlias("medianTiming" , NameQuantileTiming::name); |
130 | factory.registerAlias("medianTimingWeighted" , NameQuantileTimingWeighted::name); |
131 | factory.registerAlias("medianTDigest" , NameQuantileTDigest::name); |
132 | factory.registerAlias("medianTDigestWeighted" , NameQuantileTDigestWeighted::name); |
133 | } |
134 | |
135 | } |
136 | |