| 1 | #pragma once |
| 2 | |
| 3 | #include <DataTypes/IDataType.h> |
| 4 | #include <AggregateFunctions/IAggregateFunction.h> |
| 5 | |
| 6 | #define FOR_NUMERIC_TYPES(M) \ |
| 7 | M(UInt8) \ |
| 8 | M(UInt16) \ |
| 9 | M(UInt32) \ |
| 10 | M(UInt64) \ |
| 11 | M(Int8) \ |
| 12 | M(Int16) \ |
| 13 | M(Int32) \ |
| 14 | M(Int64) \ |
| 15 | M(Float32) \ |
| 16 | M(Float64) |
| 17 | |
| 18 | namespace DB |
| 19 | { |
| 20 | |
| 21 | /** Create an aggregate function with a numeric type in the template parameter, depending on the type of the argument. |
| 22 | */ |
| 23 | template <template <typename> class AggregateFunctionTemplate, typename... TArgs> |
| 24 | static IAggregateFunction * createWithNumericType(const IDataType & argument_type, TArgs && ... args) |
| 25 | { |
| 26 | WhichDataType which(argument_type); |
| 27 | #define DISPATCH(TYPE) \ |
| 28 | if (which.idx == TypeIndex::TYPE) return new AggregateFunctionTemplate<TYPE>(std::forward<TArgs>(args)...); |
| 29 | FOR_NUMERIC_TYPES(DISPATCH) |
| 30 | #undef DISPATCH |
| 31 | if (which.idx == TypeIndex::Enum8) return new AggregateFunctionTemplate<Int8>(std::forward<TArgs>(args)...); |
| 32 | if (which.idx == TypeIndex::Enum16) return new AggregateFunctionTemplate<Int16>(std::forward<TArgs>(args)...); |
| 33 | return nullptr; |
| 34 | } |
| 35 | |
| 36 | template <template <typename, bool> class AggregateFunctionTemplate, bool bool_param, typename... TArgs> |
| 37 | static IAggregateFunction * createWithNumericType(const IDataType & argument_type, TArgs && ... args) |
| 38 | { |
| 39 | WhichDataType which(argument_type); |
| 40 | #define DISPATCH(TYPE) \ |
| 41 | if (which.idx == TypeIndex::TYPE) return new AggregateFunctionTemplate<TYPE, bool_param>(std::forward<TArgs>(args)...); |
| 42 | FOR_NUMERIC_TYPES(DISPATCH) |
| 43 | #undef DISPATCH |
| 44 | if (which.idx == TypeIndex::Enum8) return new AggregateFunctionTemplate<Int8, bool_param>(std::forward<TArgs>(args)...); |
| 45 | if (which.idx == TypeIndex::Enum16) return new AggregateFunctionTemplate<Int16, bool_param>(std::forward<TArgs>(args)...); |
| 46 | return nullptr; |
| 47 | } |
| 48 | |
| 49 | template <template <typename, typename> class AggregateFunctionTemplate, typename Data, typename... TArgs> |
| 50 | static IAggregateFunction * createWithNumericType(const IDataType & argument_type, TArgs && ... args) |
| 51 | { |
| 52 | WhichDataType which(argument_type); |
| 53 | #define DISPATCH(TYPE) \ |
| 54 | if (which.idx == TypeIndex::TYPE) return new AggregateFunctionTemplate<TYPE, Data>(std::forward<TArgs>(args)...); |
| 55 | FOR_NUMERIC_TYPES(DISPATCH) |
| 56 | #undef DISPATCH |
| 57 | if (which.idx == TypeIndex::Enum8) return new AggregateFunctionTemplate<Int8, Data>(std::forward<TArgs>(args)...); |
| 58 | if (which.idx == TypeIndex::Enum16) return new AggregateFunctionTemplate<Int16, Data>(std::forward<TArgs>(args)...); |
| 59 | return nullptr; |
| 60 | } |
| 61 | |
| 62 | template <template <typename, typename> class AggregateFunctionTemplate, template <typename> class Data, typename... TArgs> |
| 63 | static IAggregateFunction * createWithNumericType(const IDataType & argument_type, TArgs && ... args) |
| 64 | { |
| 65 | WhichDataType which(argument_type); |
| 66 | #define DISPATCH(TYPE) \ |
| 67 | if (which.idx == TypeIndex::TYPE) return new AggregateFunctionTemplate<TYPE, Data<TYPE>>(std::forward<TArgs>(args)...); |
| 68 | FOR_NUMERIC_TYPES(DISPATCH) |
| 69 | #undef DISPATCH |
| 70 | if (which.idx == TypeIndex::Enum8) return new AggregateFunctionTemplate<Int8, Data<Int8>>(std::forward<TArgs>(args)...); |
| 71 | if (which.idx == TypeIndex::Enum16) return new AggregateFunctionTemplate<Int16, Data<Int16>>(std::forward<TArgs>(args)...); |
| 72 | return nullptr; |
| 73 | } |
| 74 | |
| 75 | template <template <typename, typename> class AggregateFunctionTemplate, template <typename> class Data, typename... TArgs> |
| 76 | static IAggregateFunction * createWithUnsignedIntegerType(const IDataType & argument_type, TArgs && ... args) |
| 77 | { |
| 78 | WhichDataType which(argument_type); |
| 79 | if (which.idx == TypeIndex::UInt8) return new AggregateFunctionTemplate<UInt8, Data<UInt8>>(std::forward<TArgs>(args)...); |
| 80 | if (which.idx == TypeIndex::UInt16) return new AggregateFunctionTemplate<UInt16, Data<UInt16>>(std::forward<TArgs>(args)...); |
| 81 | if (which.idx == TypeIndex::UInt32) return new AggregateFunctionTemplate<UInt32, Data<UInt32>>(std::forward<TArgs>(args)...); |
| 82 | if (which.idx == TypeIndex::UInt64) return new AggregateFunctionTemplate<UInt64, Data<UInt64>>(std::forward<TArgs>(args)...); |
| 83 | return nullptr; |
| 84 | } |
| 85 | |
| 86 | template <template <typename> class AggregateFunctionTemplate, typename... TArgs> |
| 87 | static IAggregateFunction * createWithNumericBasedType(const IDataType & argument_type, TArgs && ... args) |
| 88 | { |
| 89 | IAggregateFunction * f = createWithNumericType<AggregateFunctionTemplate>(argument_type, std::forward<TArgs>(args)...); |
| 90 | if (f) |
| 91 | return f; |
| 92 | |
| 93 | /// expects that DataTypeDate based on UInt16, DataTypeDateTime based on UInt32 and UUID based on UInt128 |
| 94 | WhichDataType which(argument_type); |
| 95 | if (which.idx == TypeIndex::Date) return new AggregateFunctionTemplate<UInt16>(std::forward<TArgs>(args)...); |
| 96 | if (which.idx == TypeIndex::DateTime) return new AggregateFunctionTemplate<UInt32>(std::forward<TArgs>(args)...); |
| 97 | if (which.idx == TypeIndex::UUID) return new AggregateFunctionTemplate<UInt128>(std::forward<TArgs>(args)...); |
| 98 | return nullptr; |
| 99 | } |
| 100 | |
| 101 | template <template <typename> class AggregateFunctionTemplate, typename... TArgs> |
| 102 | static IAggregateFunction * createWithDecimalType(const IDataType & argument_type, TArgs && ... args) |
| 103 | { |
| 104 | WhichDataType which(argument_type); |
| 105 | if (which.idx == TypeIndex::Decimal32) return new AggregateFunctionTemplate<Decimal32>(std::forward<TArgs>(args)...); |
| 106 | if (which.idx == TypeIndex::Decimal64) return new AggregateFunctionTemplate<Decimal64>(std::forward<TArgs>(args)...); |
| 107 | if (which.idx == TypeIndex::Decimal128) return new AggregateFunctionTemplate<Decimal128>(std::forward<TArgs>(args)...); |
| 108 | return nullptr; |
| 109 | } |
| 110 | |
| 111 | template <template <typename, typename> class AggregateFunctionTemplate, typename Data, typename... TArgs> |
| 112 | static IAggregateFunction * createWithDecimalType(const IDataType & argument_type, TArgs && ... args) |
| 113 | { |
| 114 | WhichDataType which(argument_type); |
| 115 | if (which.idx == TypeIndex::Decimal32) return new AggregateFunctionTemplate<Decimal32, Data>(std::forward<TArgs>(args)...); |
| 116 | if (which.idx == TypeIndex::Decimal64) return new AggregateFunctionTemplate<Decimal64, Data>(std::forward<TArgs>(args)...); |
| 117 | if (which.idx == TypeIndex::Decimal128) return new AggregateFunctionTemplate<Decimal128, Data>(std::forward<TArgs>(args)...); |
| 118 | return nullptr; |
| 119 | } |
| 120 | |
| 121 | /** For template with two arguments. |
| 122 | */ |
| 123 | template <typename FirstType, template <typename, typename> class AggregateFunctionTemplate, typename... TArgs> |
| 124 | static IAggregateFunction * createWithTwoNumericTypesSecond(const IDataType & second_type, TArgs && ... args) |
| 125 | { |
| 126 | WhichDataType which(second_type); |
| 127 | #define DISPATCH(TYPE) \ |
| 128 | if (which.idx == TypeIndex::TYPE) return new AggregateFunctionTemplate<FirstType, TYPE>(std::forward<TArgs>(args)...); |
| 129 | FOR_NUMERIC_TYPES(DISPATCH) |
| 130 | #undef DISPATCH |
| 131 | if (which.idx == TypeIndex::Enum8) return new AggregateFunctionTemplate<FirstType, Int8>(std::forward<TArgs>(args)...); |
| 132 | if (which.idx == TypeIndex::Enum16) return new AggregateFunctionTemplate<FirstType, Int16>(std::forward<TArgs>(args)...); |
| 133 | return nullptr; |
| 134 | } |
| 135 | |
| 136 | template <template <typename, typename> class AggregateFunctionTemplate, typename... TArgs> |
| 137 | static IAggregateFunction * createWithTwoNumericTypes(const IDataType & first_type, const IDataType & second_type, TArgs && ... args) |
| 138 | { |
| 139 | WhichDataType which(first_type); |
| 140 | #define DISPATCH(TYPE) \ |
| 141 | if (which.idx == TypeIndex::TYPE) \ |
| 142 | return createWithTwoNumericTypesSecond<TYPE, AggregateFunctionTemplate>(second_type, std::forward<TArgs>(args)...); |
| 143 | FOR_NUMERIC_TYPES(DISPATCH) |
| 144 | #undef DISPATCH |
| 145 | if (which.idx == TypeIndex::Enum8) |
| 146 | return createWithTwoNumericTypesSecond<Int8, AggregateFunctionTemplate>(second_type, std::forward<TArgs>(args)...); |
| 147 | if (which.idx == TypeIndex::Enum16) |
| 148 | return createWithTwoNumericTypesSecond<Int16, AggregateFunctionTemplate>(second_type, std::forward<TArgs>(args)...); |
| 149 | return nullptr; |
| 150 | } |
| 151 | |
| 152 | } |
| 153 | |