1#pragma once
2
3#include <AggregateFunctions/AggregateFunctionMinMaxAny.h>
4#include <AggregateFunctions/AggregateFunctionArgMinMax.h>
5#include <AggregateFunctions/FactoryHelpers.h>
6#include <AggregateFunctions/Helpers.h>
7
8#include <DataTypes/DataTypeDate.h>
9#include <DataTypes/DataTypeDateTime.h>
10#include <DataTypes/DataTypeString.h>
11
12
13namespace DB
14{
15
16/// min, max, any, anyLast, anyHeavy, etc...
17template <template <typename> class AggregateFunctionTemplate, template <typename> class Data>
18static IAggregateFunction * createAggregateFunctionSingleValue(const String & name, const DataTypes & argument_types, const Array & parameters)
19{
20 assertNoParameters(name, parameters);
21 assertUnary(name, argument_types);
22
23 const DataTypePtr & argument_type = argument_types[0];
24
25 WhichDataType which(argument_type);
26#define DISPATCH(TYPE) \
27 if (which.idx == TypeIndex::TYPE) return new AggregateFunctionTemplate<Data<SingleValueDataFixed<TYPE>>>(argument_type);
28 FOR_NUMERIC_TYPES(DISPATCH)
29#undef DISPATCH
30
31 if (which.idx == TypeIndex::Date)
32 return new AggregateFunctionTemplate<Data<SingleValueDataFixed<DataTypeDate::FieldType>>>(argument_type);
33 if (which.idx == TypeIndex::DateTime)
34 return new AggregateFunctionTemplate<Data<SingleValueDataFixed<DataTypeDateTime::FieldType>>>(argument_type);
35 if (which.idx == TypeIndex::DateTime64)
36 return new AggregateFunctionTemplate<Data<SingleValueDataFixed<DateTime64>>>(argument_type);
37 if (which.idx == TypeIndex::Decimal32)
38 return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal32>>>(argument_type);
39 if (which.idx == TypeIndex::Decimal64)
40 return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal64>>>(argument_type);
41 if (which.idx == TypeIndex::Decimal128)
42 return new AggregateFunctionTemplate<Data<SingleValueDataFixed<Decimal128>>>(argument_type);
43 if (which.idx == TypeIndex::String)
44 return new AggregateFunctionTemplate<Data<SingleValueDataString>>(argument_type);
45
46 return new AggregateFunctionTemplate<Data<SingleValueDataGeneric>>(argument_type);
47}
48
49
50/// argMin, argMax
51template <template <typename> class MinMaxData, typename ResData>
52static IAggregateFunction * createAggregateFunctionArgMinMaxSecond(const DataTypePtr & res_type, const DataTypePtr & val_type)
53{
54 WhichDataType which(val_type);
55
56#define DISPATCH(TYPE) \
57 if (which.idx == TypeIndex::TYPE) \
58 return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<TYPE>>>>(res_type, val_type);
59 FOR_NUMERIC_TYPES(DISPATCH)
60#undef DISPATCH
61
62 if (which.idx == TypeIndex::Date)
63 return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DataTypeDate::FieldType>>>>(res_type, val_type);
64 if (which.idx == TypeIndex::DateTime)
65 return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DataTypeDateTime::FieldType>>>>(res_type, val_type);
66 if (which.idx == TypeIndex::DateTime64)
67 return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<DateTime64>>>>(res_type, val_type);
68 if (which.idx == TypeIndex::Decimal32)
69 return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal32>>>>(res_type, val_type);
70 if (which.idx == TypeIndex::Decimal64)
71 return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal64>>>>(res_type, val_type);
72 if (which.idx == TypeIndex::Decimal128)
73 return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataFixed<Decimal128>>>>(res_type, val_type);
74 if (which.idx == TypeIndex::String)
75 return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataString>>>(res_type, val_type);
76
77 return new AggregateFunctionArgMinMax<AggregateFunctionArgMinMaxData<ResData, MinMaxData<SingleValueDataGeneric>>>(res_type, val_type);
78}
79
80template <template <typename> class MinMaxData>
81static IAggregateFunction * createAggregateFunctionArgMinMax(const String & name, const DataTypes & argument_types, const Array & parameters)
82{
83 assertNoParameters(name, parameters);
84 assertBinary(name, argument_types);
85
86 const DataTypePtr & res_type = argument_types[0];
87 const DataTypePtr & val_type = argument_types[1];
88
89 WhichDataType which(res_type);
90#define DISPATCH(TYPE) \
91 if (which.idx == TypeIndex::TYPE) \
92 return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<TYPE>>(res_type, val_type);
93 FOR_NUMERIC_TYPES(DISPATCH)
94#undef DISPATCH
95
96 if (which.idx == TypeIndex::Date)
97 return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<DataTypeDate::FieldType>>(res_type, val_type);
98 if (which.idx == TypeIndex::DateTime)
99 return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<DataTypeDateTime::FieldType>>(res_type, val_type);
100 if (which.idx == TypeIndex::DateTime64)
101 return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<DateTime64>>(res_type, val_type);
102 if (which.idx == TypeIndex::Decimal32)
103 return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<Decimal32>>(res_type, val_type);
104 if (which.idx == TypeIndex::Decimal64)
105 return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<Decimal64>>(res_type, val_type);
106 if (which.idx == TypeIndex::Decimal128)
107 return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataFixed<Decimal128>>(res_type, val_type);
108 if (which.idx == TypeIndex::String)
109 return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataString>(res_type, val_type);
110
111 return createAggregateFunctionArgMinMaxSecond<MinMaxData, SingleValueDataGeneric>(res_type, val_type);
112}
113
114}
115