1#include "duckdb/planner/expression/bound_aggregate_expression.hpp"
2#include "duckdb/parser/expression/function_expression.hpp"
3
4#include "duckdb/catalog/catalog_entry/aggregate_function_catalog_entry.hpp"
5#include "duckdb/common/types/hash.hpp"
6#include "duckdb/common/field_writer.hpp"
7#include "duckdb/planner/expression/bound_cast_expression.hpp"
8#include "duckdb/function/function_serialization.hpp"
9
10namespace duckdb {
11
12BoundAggregateExpression::BoundAggregateExpression(AggregateFunction function, vector<unique_ptr<Expression>> children,
13 unique_ptr<Expression> filter, unique_ptr<FunctionData> bind_info,
14 AggregateType aggr_type)
15 : Expression(ExpressionType::BOUND_AGGREGATE, ExpressionClass::BOUND_AGGREGATE, function.return_type),
16 function(std::move(function)), children(std::move(children)), bind_info(std::move(bind_info)),
17 aggr_type(aggr_type), filter(std::move(filter)) {
18 D_ASSERT(!function.name.empty());
19}
20
21string BoundAggregateExpression::ToString() const {
22 return FunctionExpression::ToString<BoundAggregateExpression, Expression, BoundOrderModifier>(
23 entry: *this, schema: string(), function_name: function.name, is_operator: false, distinct: IsDistinct(), filter: filter.get(), order_bys: order_bys.get());
24}
25
26hash_t BoundAggregateExpression::Hash() const {
27 hash_t result = Expression::Hash();
28 result = CombineHash(left: result, right: function.Hash());
29 result = CombineHash(left: result, right: duckdb::Hash(value: IsDistinct()));
30 return result;
31}
32
33bool BoundAggregateExpression::Equals(const BaseExpression &other_p) const {
34 if (!Expression::Equals(other: other_p)) {
35 return false;
36 }
37 auto &other = other_p.Cast<BoundAggregateExpression>();
38 if (other.aggr_type != aggr_type) {
39 return false;
40 }
41 if (other.function != function) {
42 return false;
43 }
44 if (children.size() != other.children.size()) {
45 return false;
46 }
47 if (!Expression::Equals(left: other.filter, right: filter)) {
48 return false;
49 }
50 for (idx_t i = 0; i < children.size(); i++) {
51 if (!Expression::Equals(left: *children[i], right: *other.children[i])) {
52 return false;
53 }
54 }
55 if (!FunctionData::Equals(left: bind_info.get(), right: other.bind_info.get())) {
56 return false;
57 }
58 if (!BoundOrderModifier::Equals(left: order_bys, right: other.order_bys)) {
59 return false;
60 }
61 return true;
62}
63
64bool BoundAggregateExpression::PropagatesNullValues() const {
65 return function.null_handling == FunctionNullHandling::SPECIAL_HANDLING ? false
66 : Expression::PropagatesNullValues();
67}
68
69unique_ptr<Expression> BoundAggregateExpression::Copy() {
70 vector<unique_ptr<Expression>> new_children;
71 new_children.reserve(n: children.size());
72 for (auto &child : children) {
73 new_children.push_back(x: child->Copy());
74 }
75 auto new_bind_info = bind_info ? bind_info->Copy() : nullptr;
76 auto new_filter = filter ? filter->Copy() : nullptr;
77 auto copy = make_uniq<BoundAggregateExpression>(args&: function, args: std::move(new_children), args: std::move(new_filter),
78 args: std::move(new_bind_info), args&: aggr_type);
79 copy->CopyProperties(other&: *this);
80 copy->order_bys = order_bys ? order_bys->Copy() : nullptr;
81 return std::move(copy);
82}
83
84void BoundAggregateExpression::Serialize(FieldWriter &writer) const {
85 writer.WriteField(element: IsDistinct());
86 writer.WriteOptional(element: filter);
87 writer.WriteOptional(element: order_bys);
88 FunctionSerializer::Serialize<AggregateFunction>(writer, function, return_type, children, bind_info: bind_info.get());
89}
90
91unique_ptr<Expression> BoundAggregateExpression::Deserialize(ExpressionDeserializationState &state,
92 FieldReader &reader) {
93 auto distinct = reader.ReadRequired<bool>();
94 auto filter = reader.ReadOptional<Expression>(default_value: nullptr, args&: state.gstate);
95 auto order_bys = reader.ReadOptional<BoundOrderModifier>(default_value: nullptr, args&: state.gstate);
96 vector<unique_ptr<Expression>> children;
97 unique_ptr<FunctionData> bind_info;
98 auto function = FunctionSerializer::Deserialize<AggregateFunction, AggregateFunctionCatalogEntry>(
99 reader, state, type: CatalogType::AGGREGATE_FUNCTION_ENTRY, children, bind_info);
100
101 auto x = make_uniq<BoundAggregateExpression>(args&: function, args: std::move(children), args: std::move(filter), args: std::move(bind_info),
102 args: distinct ? AggregateType::DISTINCT : AggregateType::NON_DISTINCT);
103 x->order_bys = std::move(order_bys);
104 return std::move(x);
105}
106
107} // namespace duckdb
108