1#include "duckdb/parser/expression/window_expression.hpp"
2
3#include "duckdb/common/serializer.hpp"
4#include "duckdb/common/string_util.hpp"
5
6using namespace duckdb;
7using namespace std;
8
9WindowExpression::WindowExpression(ExpressionType type, string schema, string function_name)
10 : ParsedExpression(type, ExpressionClass::WINDOW), schema(schema), function_name(StringUtil::Lower(function_name)) {
11 switch (type) {
12 case ExpressionType::WINDOW_AGGREGATE:
13 case ExpressionType::WINDOW_ROW_NUMBER:
14 case ExpressionType::WINDOW_FIRST_VALUE:
15 case ExpressionType::WINDOW_LAST_VALUE:
16 case ExpressionType::WINDOW_RANK:
17 case ExpressionType::WINDOW_RANK_DENSE:
18 case ExpressionType::WINDOW_PERCENT_RANK:
19 case ExpressionType::WINDOW_CUME_DIST:
20 case ExpressionType::WINDOW_LEAD:
21 case ExpressionType::WINDOW_LAG:
22 case ExpressionType::WINDOW_NTILE:
23 break;
24 default:
25 throw NotImplementedException("Window aggregate type %s not supported", ExpressionTypeToString(type).c_str());
26 }
27}
28
29string WindowExpression::ToString() const {
30 return "WINDOW";
31}
32
33bool WindowExpression::Equals(const WindowExpression *a, const WindowExpression *b) {
34 // check if the child expressions are equivalent
35 if (b->children.size() != a->children.size()) {
36 return false;
37 }
38 for (idx_t i = 0; i < a->children.size(); i++) {
39 if (!a->children[i]->Equals(b->children[i].get())) {
40 return false;
41 }
42 }
43 if (a->start != b->start || a->end != b->end) {
44 return false;
45 }
46 // check if the framing expressions are equivalent
47 if (!BaseExpression::Equals(a->start_expr.get(), b->start_expr.get()) ||
48 !BaseExpression::Equals(a->end_expr.get(), b->end_expr.get()) ||
49 !BaseExpression::Equals(a->offset_expr.get(), b->offset_expr.get()) ||
50 !BaseExpression::Equals(a->default_expr.get(), b->default_expr.get())) {
51 return false;
52 }
53
54 // check if the partitions are equivalent
55 if (a->partitions.size() != b->partitions.size()) {
56 return false;
57 }
58 for (idx_t i = 0; i < a->partitions.size(); i++) {
59 if (!a->partitions[i]->Equals(b->partitions[i].get())) {
60 return false;
61 }
62 }
63 // check if the orderings are equivalent
64 if (a->orders.size() != b->orders.size()) {
65 return false;
66 }
67 for (idx_t i = 0; i < a->orders.size(); i++) {
68 if (a->orders[i].type != b->orders[i].type) {
69 return false;
70 }
71 if (!a->orders[i].expression->Equals(b->orders[i].expression.get())) {
72 return false;
73 }
74 }
75 return true;
76}
77
78unique_ptr<ParsedExpression> WindowExpression::Copy() const {
79 auto new_window = make_unique<WindowExpression>(type, schema, function_name);
80 new_window->CopyProperties(*this);
81
82 for (auto &child : children) {
83 new_window->children.push_back(child->Copy());
84 }
85
86 for (auto &e : partitions) {
87 new_window->partitions.push_back(e->Copy());
88 }
89
90 for (auto &o : orders) {
91 OrderByNode node;
92 node.type = o.type;
93 node.expression = o.expression->Copy();
94 new_window->orders.push_back(move(node));
95 }
96
97 new_window->start = start;
98 new_window->end = end;
99 new_window->start_expr = start_expr ? start_expr->Copy() : nullptr;
100 new_window->end_expr = end_expr ? end_expr->Copy() : nullptr;
101 new_window->offset_expr = offset_expr ? offset_expr->Copy() : nullptr;
102 new_window->default_expr = default_expr ? default_expr->Copy() : nullptr;
103
104 return move(new_window);
105}
106
107void WindowExpression::Serialize(Serializer &serializer) {
108 ParsedExpression::Serialize(serializer);
109 serializer.WriteString(function_name);
110 serializer.WriteString(schema);
111 serializer.WriteList(children);
112 serializer.WriteList(partitions);
113 assert(orders.size() <= numeric_limits<uint32_t>::max());
114 serializer.Write<uint32_t>((uint32_t)orders.size());
115 for (auto &order : orders) {
116 serializer.Write<OrderType>(order.type);
117 order.expression->Serialize(serializer);
118 }
119 serializer.Write<WindowBoundary>(start);
120 serializer.Write<WindowBoundary>(end);
121
122 serializer.WriteOptional(start_expr);
123 serializer.WriteOptional(end_expr);
124 serializer.WriteOptional(offset_expr);
125 serializer.WriteOptional(default_expr);
126}
127
128unique_ptr<ParsedExpression> WindowExpression::Deserialize(ExpressionType type, Deserializer &source) {
129 auto function_name = source.Read<string>();
130 auto schema = source.Read<string>();
131 auto expr = make_unique<WindowExpression>(type, schema, function_name);
132 source.ReadList<ParsedExpression>(expr->children);
133 source.ReadList<ParsedExpression>(expr->partitions);
134
135 auto order_count = source.Read<uint32_t>();
136 for (idx_t i = 0; i < order_count; i++) {
137 auto order_type = source.Read<OrderType>();
138 auto expression = ParsedExpression::Deserialize(source);
139 expr->orders.push_back(OrderByNode(order_type, move(expression)));
140 }
141 expr->start = source.Read<WindowBoundary>();
142 expr->end = source.Read<WindowBoundary>();
143
144 expr->start_expr = source.ReadOptional<ParsedExpression>();
145 expr->end_expr = source.ReadOptional<ParsedExpression>();
146 expr->offset_expr = source.ReadOptional<ParsedExpression>();
147 expr->default_expr = source.ReadOptional<ParsedExpression>();
148 return move(expr);
149}
150