1#include "duckdb/main/relation/aggregate_relation.hpp"
2#include "duckdb/main/client_context.hpp"
3#include "duckdb/parser/query_node/select_node.hpp"
4#include "duckdb/parser/tableref/subqueryref.hpp"
5
6namespace duckdb {
7
8AggregateRelation::AggregateRelation(shared_ptr<Relation> child_p,
9 vector<unique_ptr<ParsedExpression>> parsed_expressions)
10 : Relation(child_p->context, RelationType::AGGREGATE_RELATION), expressions(move(parsed_expressions)), child(move(child_p)) {
11 // bind the expressions
12 context.TryBindRelation(*this, this->columns);
13}
14
15AggregateRelation::AggregateRelation(shared_ptr<Relation> child_p,
16 vector<unique_ptr<ParsedExpression>> parsed_expressions,
17 vector<unique_ptr<ParsedExpression>> groups_p)
18 : Relation(child_p->context, RelationType::AGGREGATE_RELATION), expressions(move(parsed_expressions)),
19 groups(move(groups_p)), child(move(child_p)) {
20 // bind the expressions
21 context.TryBindRelation(*this, this->columns);
22}
23
24unique_ptr<QueryNode> AggregateRelation::GetQueryNode() {
25 auto child_ptr = child.get();
26 while (child_ptr->InheritsColumnBindings()) {
27 child_ptr = child_ptr->ChildRelation();
28 }
29 unique_ptr<QueryNode> result;
30 if (child_ptr->type == RelationType::JOIN_RELATION) {
31 // child node is a join: push projection into the child query node
32 result = child->GetQueryNode();
33 } else {
34 // child node is not a join: create a new select node and push the child as a table reference
35 auto select = make_unique<SelectNode>();
36 select->from_table = child->GetTableRef();
37 result = move(select);
38 }
39 assert(result->type == QueryNodeType::SELECT_NODE);
40 auto &select_node = (SelectNode &)*result;
41 if (groups.size() > 0) {
42 // explicit groups provided: use standard handling
43 select_node.aggregate_handling = AggregateHandling::STANDARD_HANDLING;
44 select_node.groups.clear();
45 for (auto &group : groups) {
46 select_node.groups.push_back(group->Copy());
47 }
48 } else {
49 // no groups provided: automatically figure out groups (if any)
50 select_node.aggregate_handling = AggregateHandling::FORCE_AGGREGATES;
51 }
52 select_node.select_list.clear();
53 for (auto &expr : expressions) {
54 select_node.select_list.push_back(expr->Copy());
55 }
56 return result;
57}
58
59string AggregateRelation::GetAlias() {
60 return child->GetAlias();
61}
62
63const vector<ColumnDefinition> &AggregateRelation::Columns() {
64 return columns;
65}
66
67string AggregateRelation::ToString(idx_t depth) {
68 string str = RenderWhitespace(depth) + "Aggregate [";
69 for (idx_t i = 0; i < expressions.size(); i++) {
70 if (i != 0) {
71 str += ", ";
72 }
73 str += expressions[i]->ToString();
74 }
75 str += "]\n";
76 return str + child->ToString(depth + 1);
77}
78
79} // namespace duckdb
80