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