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
18namespace DB
19{
20
21/** Create an aggregate function with a numeric type in the template parameter, depending on the type of the argument.
22 */
23template <template <typename> class AggregateFunctionTemplate, typename... TArgs>
24static 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
36template <template <typename, bool> class AggregateFunctionTemplate, bool bool_param, typename... TArgs>
37static 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
49template <template <typename, typename> class AggregateFunctionTemplate, typename Data, typename... TArgs>
50static 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
62template <template <typename, typename> class AggregateFunctionTemplate, template <typename> class Data, typename... TArgs>
63static 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
75template <template <typename, typename> class AggregateFunctionTemplate, template <typename> class Data, typename... TArgs>
76static 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
86template <template <typename> class AggregateFunctionTemplate, typename... TArgs>
87static 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
101template <template <typename> class AggregateFunctionTemplate, typename... TArgs>
102static 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
111template <template <typename, typename> class AggregateFunctionTemplate, typename Data, typename... TArgs>
112static 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 */
123template <typename FirstType, template <typename, typename> class AggregateFunctionTemplate, typename... TArgs>
124static 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
136template <template <typename, typename> class AggregateFunctionTemplate, typename... TArgs>
137static 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