1 | #include <AggregateFunctions/AggregateFunctionFactory.h> |
2 | #include <AggregateFunctions/AggregateFunctionGroupArrayMoving.h> |
3 | #include <AggregateFunctions/Helpers.h> |
4 | #include <AggregateFunctions/FactoryHelpers.h> |
5 | #include <DataTypes/DataTypeDate.h> |
6 | #include <DataTypes/DataTypeDateTime.h> |
7 | #include "registerAggregateFunctions.h" |
8 | |
9 | |
10 | namespace DB |
11 | { |
12 | |
13 | namespace ErrorCodes |
14 | { |
15 | extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; |
16 | extern const int BAD_ARGUMENTS; |
17 | } |
18 | |
19 | namespace |
20 | { |
21 | |
22 | template <typename T, typename Tlimit_num_elems> |
23 | struct MovingSum |
24 | { |
25 | using DataType = MovingSumData<T>; |
26 | using Function = MovingImpl<T, Tlimit_num_elems, DataType>; |
27 | }; |
28 | |
29 | template <typename T, typename Tlimit_num_elems> |
30 | struct MovingAvg |
31 | { |
32 | using DataType = MovingAvgData<T>; |
33 | using Function = MovingImpl<T, Tlimit_num_elems, DataType>; |
34 | }; |
35 | |
36 | template <typename T, typename Tlimit_num_elems> using MovingSumTemplate = typename MovingSum<T, Tlimit_num_elems>::Function; |
37 | template <typename T, typename Tlimit_num_elems> using MovingAvgTemplate = typename MovingAvg<T, Tlimit_num_elems>::Function; |
38 | |
39 | template <template <typename, typename> class Function, typename has_limit, typename ... TArgs> |
40 | inline AggregateFunctionPtr createAggregateFunctionMovingImpl(const std::string & name, const DataTypePtr & argument_type, TArgs ... args) |
41 | { |
42 | AggregateFunctionPtr res; |
43 | |
44 | if (isDecimal(argument_type)) |
45 | res.reset(createWithDecimalType<Function, has_limit>(*argument_type, argument_type, std::forward<TArgs>(args)...)); |
46 | else |
47 | res.reset(createWithNumericType<Function, has_limit>(*argument_type, argument_type, std::forward<TArgs>(args)...)); |
48 | |
49 | if (!res) |
50 | throw Exception("Illegal type " + argument_type->getName() + " of argument for aggregate function " + name, |
51 | ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); |
52 | |
53 | return res; |
54 | } |
55 | |
56 | template <template <typename, typename> class Function> |
57 | AggregateFunctionPtr createAggregateFunctionMoving(const std::string & name, const DataTypes & argument_types, const Array & parameters) |
58 | { |
59 | assertUnary(name, argument_types); |
60 | |
61 | bool limit_size = false; |
62 | |
63 | UInt64 max_elems = std::numeric_limits<UInt64>::max(); |
64 | |
65 | if (parameters.empty()) |
66 | { |
67 | // cumulative sum without parameter |
68 | } |
69 | else if (parameters.size() == 1) |
70 | { |
71 | auto type = parameters[0].getType(); |
72 | if (type != Field::Types::Int64 && type != Field::Types::UInt64) |
73 | throw Exception("Parameter for aggregate function " + name + " should be positive number" , ErrorCodes::BAD_ARGUMENTS); |
74 | |
75 | if ((type == Field::Types::Int64 && parameters[0].get<Int64>() < 0) || |
76 | (type == Field::Types::UInt64 && parameters[0].get<UInt64>() == 0)) |
77 | throw Exception("Parameter for aggregate function " + name + " should be positive number" , ErrorCodes::BAD_ARGUMENTS); |
78 | |
79 | limit_size = true; |
80 | max_elems = parameters[0].get<UInt64>(); |
81 | } |
82 | else |
83 | throw Exception("Incorrect number of parameters for aggregate function " + name + ", should be 0 or 1" , |
84 | ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); |
85 | |
86 | if (!limit_size) |
87 | return createAggregateFunctionMovingImpl<Function, std::false_type>(name, argument_types[0]); |
88 | else |
89 | return createAggregateFunctionMovingImpl<Function, std::true_type>(name, argument_types[0], max_elems); |
90 | } |
91 | |
92 | } |
93 | |
94 | |
95 | void registerAggregateFunctionMoving(AggregateFunctionFactory & factory) |
96 | { |
97 | factory.registerFunction("groupArrayMovingSum" , createAggregateFunctionMoving<MovingSumTemplate>); |
98 | factory.registerFunction("groupArrayMovingAvg" , createAggregateFunctionMoving<MovingAvgTemplate>); |
99 | } |
100 | |
101 | } |
102 | |