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