Coverage Report

Created: 2025-06-12 07:25

/src/duckdb/src/main/relation/aggregate_relation.cpp
Line
Count
Source (jump to first uncovered line)
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
6
namespace duckdb {
7
8
AggregateRelation::AggregateRelation(shared_ptr<Relation> child_p,
9
                                     vector<unique_ptr<ParsedExpression>> parsed_expressions)
10
0
    : Relation(child_p->context, RelationType::AGGREGATE_RELATION), expressions(std::move(parsed_expressions)),
11
0
      child(std::move(child_p)) {
12
  // bind the expressions
13
0
  TryBindRelation(columns);
14
0
}
15
16
AggregateRelation::AggregateRelation(shared_ptr<Relation> child_p,
17
                                     vector<unique_ptr<ParsedExpression>> parsed_expressions, GroupByNode groups_p)
18
0
    : Relation(child_p->context, RelationType::AGGREGATE_RELATION), expressions(std::move(parsed_expressions)),
19
0
      groups(std::move(groups_p)), child(std::move(child_p)) {
20
  // bind the expressions
21
0
  Relation::TryBindRelation(columns);
22
0
}
23
24
AggregateRelation::AggregateRelation(shared_ptr<Relation> child_p,
25
                                     vector<unique_ptr<ParsedExpression>> parsed_expressions,
26
                                     vector<unique_ptr<ParsedExpression>> groups_p)
27
0
    : Relation(child_p->context, RelationType::AGGREGATE_RELATION), expressions(std::move(parsed_expressions)),
28
0
      child(std::move(child_p)) {
29
0
  if (!groups_p.empty()) {
30
    // explicit groups provided: use standard handling
31
0
    GroupingSet grouping_set;
32
0
    for (idx_t i = 0; i < groups_p.size(); i++) {
33
0
      groups.group_expressions.push_back(std::move(groups_p[i]));
34
0
      grouping_set.insert(i);
35
0
    }
36
0
    groups.grouping_sets.push_back(std::move(grouping_set));
37
0
  }
38
  // bind the expressions
39
0
  TryBindRelation(columns);
40
0
}
41
42
0
unique_ptr<QueryNode> AggregateRelation::GetQueryNode() {
43
0
  auto child_ptr = child.get();
44
0
  while (child_ptr->InheritsColumnBindings()) {
45
0
    child_ptr = child_ptr->ChildRelation();
46
0
  }
47
0
  unique_ptr<QueryNode> result;
48
0
  if (child_ptr->type == RelationType::JOIN_RELATION) {
49
    // child node is a join: push projection into the child query node
50
0
    result = child->GetQueryNode();
51
0
  } else {
52
    // child node is not a join: create a new select node and push the child as a table reference
53
0
    auto select = make_uniq<SelectNode>();
54
0
    select->from_table = child->GetTableRef();
55
0
    result = std::move(select);
56
0
  }
57
0
  D_ASSERT(result->type == QueryNodeType::SELECT_NODE);
58
0
  auto &select_node = result->Cast<SelectNode>();
59
0
  if (!groups.group_expressions.empty()) {
60
0
    select_node.aggregate_handling = AggregateHandling::STANDARD_HANDLING;
61
0
    select_node.groups = groups.Copy();
62
0
  } else {
63
    // no groups provided: automatically figure out groups (if any)
64
0
    select_node.aggregate_handling = AggregateHandling::FORCE_AGGREGATES;
65
0
  }
66
0
  select_node.select_list.clear();
67
0
  for (auto &expr : expressions) {
68
0
    select_node.select_list.push_back(expr->Copy());
69
0
  }
70
0
  return result;
71
0
}
72
73
0
string AggregateRelation::GetAlias() {
74
0
  return child->GetAlias();
75
0
}
76
77
0
const vector<ColumnDefinition> &AggregateRelation::Columns() {
78
0
  return columns;
79
0
}
80
81
0
string AggregateRelation::ToString(idx_t depth) {
82
0
  string str = RenderWhitespace(depth) + "Aggregate [";
83
0
  for (idx_t i = 0; i < expressions.size(); i++) {
84
0
    if (i != 0) {
85
0
      str += ", ";
86
0
    }
87
0
    str += expressions[i]->ToString();
88
0
  }
89
0
  str += "]\n";
90
0
  return str + child->ToString(depth + 1);
91
0
}
92
93
} // namespace duckdb