1#include "duckdb/planner/expression/bound_window_expression.hpp"
2#include "duckdb/function/aggregate_function.hpp"
3
4using namespace duckdb;
5using namespace std;
6
7BoundWindowExpression::BoundWindowExpression(ExpressionType type, TypeId return_type,
8 unique_ptr<AggregateFunction> aggregate)
9 : Expression(type, ExpressionClass::BOUND_WINDOW, return_type), aggregate(move(aggregate)) {
10}
11
12string BoundWindowExpression::ToString() const {
13 return "WINDOW";
14}
15
16bool BoundWindowExpression::Equals(const BaseExpression *other_) const {
17 if (!BaseExpression::Equals(other_)) {
18 return false;
19 }
20 auto other = (BoundWindowExpression *)other_;
21
22 if (start != other->start || end != other->end) {
23 return false;
24 }
25 // check if the child expressions are equivalent
26 if (other->children.size() != children.size()) {
27 return false;
28 }
29 for (idx_t i = 0; i < children.size(); i++) {
30 if (!Expression::Equals(children[i].get(), other->children[i].get())) {
31 return false;
32 }
33 }
34 // check if the framing expressions are equivalent
35 if (!Expression::Equals(start_expr.get(), other->start_expr.get()) ||
36 !Expression::Equals(end_expr.get(), other->end_expr.get()) ||
37 !Expression::Equals(offset_expr.get(), other->offset_expr.get()) ||
38 !Expression::Equals(default_expr.get(), other->default_expr.get())) {
39 return false;
40 }
41
42 // check if the partitions are equivalent
43 if (partitions.size() != other->partitions.size()) {
44 return false;
45 }
46 for (idx_t i = 0; i < partitions.size(); i++) {
47 if (!Expression::Equals(partitions[i].get(), other->partitions[i].get())) {
48 return false;
49 }
50 }
51 // check if the orderings are equivalent
52 if (orders.size() != other->orders.size()) {
53 return false;
54 }
55 for (idx_t i = 0; i < orders.size(); i++) {
56 if (orders[i].type != other->orders[i].type) {
57 return false;
58 }
59 if (!BaseExpression::Equals((BaseExpression *)orders[i].expression.get(),
60 (BaseExpression *)other->orders[i].expression.get())) {
61 return false;
62 }
63 }
64 return true;
65}
66
67unique_ptr<Expression> BoundWindowExpression::Copy() {
68 auto new_window = make_unique<BoundWindowExpression>(type, return_type, nullptr);
69 new_window->CopyProperties(*this);
70
71 if (aggregate) {
72 new_window->aggregate = make_unique<AggregateFunction>(*aggregate);
73 }
74 for (auto &child : children) {
75 new_window->children.push_back(child->Copy());
76 }
77 for (auto &e : partitions) {
78 new_window->partitions.push_back(e->Copy());
79 }
80
81 for (auto &o : orders) {
82 BoundOrderByNode node;
83 node.type = o.type;
84 node.expression = o.expression->Copy();
85 new_window->orders.push_back(move(node));
86 }
87
88 new_window->start = start;
89 new_window->end = end;
90 new_window->start_expr = start_expr ? start_expr->Copy() : nullptr;
91 new_window->end_expr = end_expr ? end_expr->Copy() : nullptr;
92 new_window->offset_expr = offset_expr ? offset_expr->Copy() : nullptr;
93 new_window->default_expr = default_expr ? default_expr->Copy() : nullptr;
94
95 return move(new_window);
96}
97