1#include <Functions/IFunctionImpl.h>
2#include <Functions/FunctionFactory.h>
3#include <Functions/FunctionHelpers.h>
4#include <DataTypes/DataTypeAggregateFunction.h>
5#include <Columns/ColumnAggregateFunction.h>
6#include <Common/typeid_cast.h>
7
8
9namespace DB
10{
11
12namespace ErrorCodes
13{
14 extern const int ILLEGAL_COLUMN;
15 extern const int ILLEGAL_TYPE_OF_ARGUMENT;
16}
17
18
19/** finalizeAggregation(agg_state) - get the result from the aggregation state.
20 * Takes state of aggregate function. Returns result of aggregation (finalized state).
21 */
22class FunctionFinalizeAggregation : public IFunction
23{
24public:
25 static constexpr auto name = "finalizeAggregation";
26 static FunctionPtr create(const Context &)
27 {
28 return std::make_shared<FunctionFinalizeAggregation>();
29 }
30
31 String getName() const override
32 {
33 return name;
34 }
35
36 bool isStateful() const override
37 {
38 return true;
39 }
40
41 size_t getNumberOfArguments() const override
42 {
43 return 1;
44 }
45
46 bool useDefaultImplementationForConstants() const override { return true; }
47
48 DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
49 {
50 const DataTypeAggregateFunction * type = checkAndGetDataType<DataTypeAggregateFunction>(arguments[0].get());
51 if (!type)
52 throw Exception("Argument for function " + getName() + " must have type AggregateFunction - state of aggregate function.",
53 ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
54
55 return type->getReturnType();
56 }
57
58 void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) override
59 {
60 const ColumnAggregateFunction * column_with_states
61 = typeid_cast<const ColumnAggregateFunction *>(&*block.getByPosition(arguments.at(0)).column);
62 if (!column_with_states)
63 throw Exception("Illegal column " + block.getByPosition(arguments.at(0)).column->getName()
64 + " of first argument of function "
65 + getName(),
66 ErrorCodes::ILLEGAL_COLUMN);
67
68 block.getByPosition(result).column = column_with_states->convertToValues();
69 }
70};
71
72
73void registerFunctionFinalizeAggregation(FunctionFactory & factory)
74{
75 factory.registerFunction<FunctionFinalizeAggregation>();
76}
77
78}
79