1 | #pragma once |
2 | |
3 | #include <IO/VarInt.h> |
4 | #include <IO/WriteHelpers.h> |
5 | |
6 | #include <array> |
7 | #include <DataTypes/DataTypesNumber.h> |
8 | #include <Columns/ColumnNullable.h> |
9 | #include <AggregateFunctions/IAggregateFunction.h> |
10 | #include <Common/assert_cast.h> |
11 | |
12 | |
13 | namespace DB |
14 | { |
15 | |
16 | struct AggregateFunctionCountData |
17 | { |
18 | UInt64 count = 0; |
19 | }; |
20 | |
21 | namespace ErrorCodes |
22 | { |
23 | extern const int LOGICAL_ERROR; |
24 | extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; |
25 | } |
26 | |
27 | |
28 | /// Simply count number of calls. |
29 | class AggregateFunctionCount final : public IAggregateFunctionDataHelper<AggregateFunctionCountData, AggregateFunctionCount> |
30 | { |
31 | public: |
32 | AggregateFunctionCount(const DataTypes & argument_types_) : IAggregateFunctionDataHelper(argument_types_, {}) {} |
33 | |
34 | String getName() const override { return "count" ; } |
35 | |
36 | DataTypePtr getReturnType() const override |
37 | { |
38 | return std::make_shared<DataTypeUInt64>(); |
39 | } |
40 | |
41 | void add(AggregateDataPtr place, const IColumn **, size_t, Arena *) const override |
42 | { |
43 | ++data(place).count; |
44 | } |
45 | |
46 | void merge(AggregateDataPtr place, ConstAggregateDataPtr rhs, Arena *) const override |
47 | { |
48 | data(place).count += data(rhs).count; |
49 | } |
50 | |
51 | void serialize(ConstAggregateDataPtr place, WriteBuffer & buf) const override |
52 | { |
53 | writeVarUInt(data(place).count, buf); |
54 | } |
55 | |
56 | void deserialize(AggregateDataPtr place, ReadBuffer & buf, Arena *) const override |
57 | { |
58 | readVarUInt(data(place).count, buf); |
59 | } |
60 | |
61 | void insertResultInto(ConstAggregateDataPtr place, IColumn & to) const override |
62 | { |
63 | assert_cast<ColumnUInt64 &>(to).getData().push_back(data(place).count); |
64 | } |
65 | |
66 | /// Reset the state to specified value. This function is not the part of common interface. |
67 | void set(AggregateDataPtr place, UInt64 new_count) |
68 | { |
69 | data(place).count = new_count; |
70 | } |
71 | }; |
72 | |
73 | |
74 | /// Simply count number of not-NULL values. |
75 | class AggregateFunctionCountNotNullUnary final : public IAggregateFunctionDataHelper<AggregateFunctionCountData, AggregateFunctionCountNotNullUnary> |
76 | { |
77 | public: |
78 | AggregateFunctionCountNotNullUnary(const DataTypePtr & argument, const Array & params) |
79 | : IAggregateFunctionDataHelper<AggregateFunctionCountData, AggregateFunctionCountNotNullUnary>({argument}, params) |
80 | { |
81 | if (!argument->isNullable()) |
82 | throw Exception("Logical error: not Nullable data type passed to AggregateFunctionCountNotNullUnary" , ErrorCodes::LOGICAL_ERROR); |
83 | } |
84 | |
85 | String getName() const override { return "count" ; } |
86 | |
87 | DataTypePtr getReturnType() const override |
88 | { |
89 | return std::make_shared<DataTypeUInt64>(); |
90 | } |
91 | |
92 | void add(AggregateDataPtr place, const IColumn ** columns, size_t row_num, Arena *) const override |
93 | { |
94 | data(place).count += !assert_cast<const ColumnNullable &>(*columns[0]).isNullAt(row_num); |
95 | } |
96 | |
97 | void merge(AggregateDataPtr place, ConstAggregateDataPtr rhs, Arena *) const override |
98 | { |
99 | data(place).count += data(rhs).count; |
100 | } |
101 | |
102 | void serialize(ConstAggregateDataPtr place, WriteBuffer & buf) const override |
103 | { |
104 | writeVarUInt(data(place).count, buf); |
105 | } |
106 | |
107 | void deserialize(AggregateDataPtr place, ReadBuffer & buf, Arena *) const override |
108 | { |
109 | readVarUInt(data(place).count, buf); |
110 | } |
111 | |
112 | void insertResultInto(ConstAggregateDataPtr place, IColumn & to) const override |
113 | { |
114 | assert_cast<ColumnUInt64 &>(to).getData().push_back(data(place).count); |
115 | } |
116 | }; |
117 | |
118 | } |
119 | |