1#include <DataTypes/DataTypeNullable.h>
2#include <AggregateFunctions/AggregateFunctionNull.h>
3#include <AggregateFunctions/AggregateFunctionNothing.h>
4#include <AggregateFunctions/AggregateFunctionCount.h>
5#include <AggregateFunctions/AggregateFunctionCombinatorFactory.h>
6#include "registerAggregateFunctions.h"
7
8
9namespace DB
10{
11
12namespace ErrorCodes
13{
14 extern const int ILLEGAL_TYPE_OF_ARGUMENT;
15}
16
17class AggregateFunctionCombinatorNull final : public IAggregateFunctionCombinator
18{
19public:
20 String getName() const override { return "Null"; }
21
22 bool isForInternalUsageOnly() const override { return true; }
23
24 DataTypes transformArguments(const DataTypes & arguments) const override
25 {
26 size_t size = arguments.size();
27 DataTypes res(size);
28 for (size_t i = 0; i < size; ++i)
29 res[i] = removeNullable(arguments[i]);
30 return res;
31 }
32
33 AggregateFunctionPtr transformAggregateFunction(
34 const AggregateFunctionPtr & nested_function, const DataTypes & arguments, const Array & params) const override
35 {
36 bool has_nullable_types = false;
37 bool has_null_types = false;
38 for (const auto & arg_type : arguments)
39 {
40 if (arg_type->isNullable())
41 {
42 has_nullable_types = true;
43 if (arg_type->onlyNull())
44 {
45 has_null_types = true;
46 break;
47 }
48 }
49 }
50
51 if (!has_nullable_types)
52 throw Exception("Aggregate function combinator 'Null' requires at least one argument to be Nullable", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
53
54 /// Special case for 'count' function. It could be called with Nullable arguments
55 /// - that means - count number of calls, when all arguments are not NULL.
56 if (nested_function && nested_function->getName() == "count")
57 return std::make_shared<AggregateFunctionCountNotNullUnary>(arguments[0], params);
58
59 if (has_null_types)
60 return std::make_shared<AggregateFunctionNothing>(arguments, params);
61
62 bool return_type_is_nullable = nested_function->getReturnType()->canBeInsideNullable();
63
64 if (arguments.size() == 1)
65 {
66 if (return_type_is_nullable)
67 return std::make_shared<AggregateFunctionNullUnary<true>>(nested_function, arguments, params);
68 else
69 return std::make_shared<AggregateFunctionNullUnary<false>>(nested_function, arguments, params);
70 }
71 else
72 {
73 if (return_type_is_nullable)
74 return std::make_shared<AggregateFunctionNullVariadic<true>>(nested_function, arguments, params);
75 else
76 return std::make_shared<AggregateFunctionNullVariadic<false>>(nested_function, arguments, params);
77 }
78 }
79};
80
81void registerAggregateFunctionCombinatorNull(AggregateFunctionCombinatorFactory & factory)
82{
83 factory.registerCombinator(std::make_shared<AggregateFunctionCombinatorNull>());
84}
85
86}
87