1 | #include "duckdb/parser/query_node.hpp" |
2 | |
3 | #include "duckdb/parser/query_node/select_node.hpp" |
4 | #include "duckdb/parser/query_node/set_operation_node.hpp" |
5 | #include "duckdb/parser/query_node/recursive_cte_node.hpp" |
6 | #include "duckdb/common/limits.hpp" |
7 | #include "duckdb/common/field_writer.hpp" |
8 | #include "duckdb/common/serializer/format_serializer.hpp" |
9 | #include "duckdb/common/serializer/format_deserializer.hpp" |
10 | |
11 | namespace duckdb { |
12 | |
13 | CommonTableExpressionMap::CommonTableExpressionMap() { |
14 | } |
15 | |
16 | CommonTableExpressionMap CommonTableExpressionMap::Copy() const { |
17 | CommonTableExpressionMap res; |
18 | for (auto &kv : this->map) { |
19 | auto kv_info = make_uniq<CommonTableExpressionInfo>(); |
20 | for (auto &al : kv.second->aliases) { |
21 | kv_info->aliases.push_back(x: al); |
22 | } |
23 | kv_info->query = unique_ptr_cast<SQLStatement, SelectStatement>(src: kv.second->query->Copy()); |
24 | res.map[kv.first] = std::move(kv_info); |
25 | } |
26 | return res; |
27 | } |
28 | |
29 | string CommonTableExpressionMap::ToString() const { |
30 | if (map.empty()) { |
31 | return string(); |
32 | } |
33 | // check if there are any recursive CTEs |
34 | bool has_recursive = false; |
35 | for (auto &kv : map) { |
36 | if (kv.second->query->node->type == QueryNodeType::RECURSIVE_CTE_NODE) { |
37 | has_recursive = true; |
38 | break; |
39 | } |
40 | } |
41 | string result = "WITH " ; |
42 | if (has_recursive) { |
43 | result += "RECURSIVE " ; |
44 | } |
45 | bool first_cte = true; |
46 | for (auto &kv : map) { |
47 | if (!first_cte) { |
48 | result += ", " ; |
49 | } |
50 | auto &cte = *kv.second; |
51 | result += KeywordHelper::WriteOptionallyQuoted(text: kv.first); |
52 | if (!cte.aliases.empty()) { |
53 | result += " (" ; |
54 | for (idx_t k = 0; k < cte.aliases.size(); k++) { |
55 | if (k > 0) { |
56 | result += ", " ; |
57 | } |
58 | result += KeywordHelper::WriteOptionallyQuoted(text: cte.aliases[k]); |
59 | } |
60 | result += ")" ; |
61 | } |
62 | result += " AS (" ; |
63 | result += cte.query->ToString(); |
64 | result += ")" ; |
65 | first_cte = false; |
66 | } |
67 | return result; |
68 | } |
69 | |
70 | void CommonTableExpressionMap::FormatSerialize(FormatSerializer &serializer) const { |
71 | serializer.WriteProperty(tag: "map" , value: map); |
72 | } |
73 | |
74 | CommonTableExpressionMap CommonTableExpressionMap::FormatDeserialize(FormatDeserializer &deserializer) { |
75 | auto result = CommonTableExpressionMap(); |
76 | deserializer.ReadProperty(tag: "map" , ret&: result.map); |
77 | return result; |
78 | } |
79 | |
80 | string QueryNode::ResultModifiersToString() const { |
81 | string result; |
82 | for (idx_t modifier_idx = 0; modifier_idx < modifiers.size(); modifier_idx++) { |
83 | auto &modifier = *modifiers[modifier_idx]; |
84 | if (modifier.type == ResultModifierType::ORDER_MODIFIER) { |
85 | auto &order_modifier = modifier.Cast<OrderModifier>(); |
86 | result += " ORDER BY " ; |
87 | for (idx_t k = 0; k < order_modifier.orders.size(); k++) { |
88 | if (k > 0) { |
89 | result += ", " ; |
90 | } |
91 | result += order_modifier.orders[k].ToString(); |
92 | } |
93 | } else if (modifier.type == ResultModifierType::LIMIT_MODIFIER) { |
94 | auto &limit_modifier = modifier.Cast<LimitModifier>(); |
95 | if (limit_modifier.limit) { |
96 | result += " LIMIT " + limit_modifier.limit->ToString(); |
97 | } |
98 | if (limit_modifier.offset) { |
99 | result += " OFFSET " + limit_modifier.offset->ToString(); |
100 | } |
101 | } else if (modifier.type == ResultModifierType::LIMIT_PERCENT_MODIFIER) { |
102 | auto &limit_p_modifier = modifier.Cast<LimitPercentModifier>(); |
103 | if (limit_p_modifier.limit) { |
104 | result += " LIMIT (" + limit_p_modifier.limit->ToString() + ") %" ; |
105 | } |
106 | if (limit_p_modifier.offset) { |
107 | result += " OFFSET " + limit_p_modifier.offset->ToString(); |
108 | } |
109 | } |
110 | } |
111 | return result; |
112 | } |
113 | |
114 | bool QueryNode::Equals(const QueryNode *other) const { |
115 | if (!other) { |
116 | return false; |
117 | } |
118 | if (this == other) { |
119 | return true; |
120 | } |
121 | if (other->type != this->type) { |
122 | return false; |
123 | } |
124 | |
125 | if (modifiers.size() != other->modifiers.size()) { |
126 | return false; |
127 | } |
128 | for (idx_t i = 0; i < modifiers.size(); i++) { |
129 | if (!modifiers[i]->Equals(other: *other->modifiers[i])) { |
130 | return false; |
131 | } |
132 | } |
133 | // WITH clauses (CTEs) |
134 | if (cte_map.map.size() != other->cte_map.map.size()) { |
135 | return false; |
136 | } |
137 | for (auto &entry : cte_map.map) { |
138 | auto other_entry = other->cte_map.map.find(x: entry.first); |
139 | if (other_entry == other->cte_map.map.end()) { |
140 | return false; |
141 | } |
142 | if (entry.second->aliases != other_entry->second->aliases) { |
143 | return false; |
144 | } |
145 | if (!entry.second->query->Equals(other: *other_entry->second->query)) { |
146 | return false; |
147 | } |
148 | } |
149 | return other->type == type; |
150 | } |
151 | |
152 | void QueryNode::CopyProperties(QueryNode &other) const { |
153 | for (auto &modifier : modifiers) { |
154 | other.modifiers.push_back(x: modifier->Copy()); |
155 | } |
156 | for (auto &kv : cte_map.map) { |
157 | auto kv_info = make_uniq<CommonTableExpressionInfo>(); |
158 | for (auto &al : kv.second->aliases) { |
159 | kv_info->aliases.push_back(x: al); |
160 | } |
161 | kv_info->query = unique_ptr_cast<SQLStatement, SelectStatement>(src: kv.second->query->Copy()); |
162 | other.cte_map.map[kv.first] = std::move(kv_info); |
163 | } |
164 | } |
165 | |
166 | void QueryNode::Serialize(Serializer &main_serializer) const { |
167 | FieldWriter writer(main_serializer); |
168 | writer.WriteField<QueryNodeType>(element: type); |
169 | writer.WriteSerializableList(elements: modifiers); |
170 | // cte_map |
171 | |
172 | writer.WriteField<uint32_t>(element: (uint32_t)cte_map.map.size()); |
173 | auto &serializer = writer.GetSerializer(); |
174 | for (auto &cte : cte_map.map) { |
175 | serializer.WriteString(val: cte.first); |
176 | serializer.WriteStringVector(list: cte.second->aliases); |
177 | cte.second->query->Serialize(serializer); |
178 | } |
179 | Serialize(writer); |
180 | |
181 | writer.Finalize(); |
182 | } |
183 | |
184 | // Children should call the base method before their own. |
185 | void QueryNode::FormatSerialize(FormatSerializer &serializer) const { |
186 | serializer.WriteProperty(tag: "type" , value: type); |
187 | serializer.WriteProperty(tag: "modifiers" , value: modifiers); |
188 | serializer.WriteProperty(tag: "cte_map" , value: cte_map); |
189 | } |
190 | |
191 | unique_ptr<QueryNode> QueryNode::FormatDeserialize(FormatDeserializer &deserializer) { |
192 | |
193 | auto type = deserializer.ReadProperty<QueryNodeType>(tag: "type" ); |
194 | |
195 | auto modifiers = deserializer.ReadProperty<vector<unique_ptr<ResultModifier>>>(tag: "modifiers" ); |
196 | auto cte_map = deserializer.ReadProperty<CommonTableExpressionMap>(tag: "cte_map" ); |
197 | |
198 | unique_ptr<QueryNode> result; |
199 | |
200 | switch (type) { |
201 | case QueryNodeType::SELECT_NODE: |
202 | result = SelectNode::FormatDeserialize(deserializer); |
203 | break; |
204 | case QueryNodeType::SET_OPERATION_NODE: |
205 | result = SetOperationNode::FormatDeserialize(source&: deserializer); |
206 | break; |
207 | case QueryNodeType::RECURSIVE_CTE_NODE: |
208 | result = RecursiveCTENode::FormatDeserialize(source&: deserializer); |
209 | break; |
210 | default: |
211 | throw SerializationException("Could not deserialize Query Node: unknown type!" ); |
212 | } |
213 | |
214 | result->type = type; |
215 | result->modifiers = std::move(modifiers); |
216 | result->cte_map = std::move(cte_map); |
217 | return result; |
218 | } |
219 | |
220 | unique_ptr<QueryNode> QueryNode::Deserialize(Deserializer &main_source) { |
221 | FieldReader reader(main_source); |
222 | |
223 | auto type = reader.ReadRequired<QueryNodeType>(); |
224 | auto modifiers = reader.ReadRequiredSerializableList<ResultModifier>(); |
225 | // cte_map |
226 | auto cte_count = reader.ReadRequired<uint32_t>(); |
227 | auto &source = reader.GetSource(); |
228 | case_insensitive_map_t<unique_ptr<CommonTableExpressionInfo>> new_map; |
229 | for (idx_t i = 0; i < cte_count; i++) { |
230 | auto name = source.Read<string>(); |
231 | auto info = make_uniq<CommonTableExpressionInfo>(); |
232 | source.ReadStringVector(list&: info->aliases); |
233 | info->query = SelectStatement::Deserialize(source); |
234 | new_map[name] = std::move(info); |
235 | } |
236 | unique_ptr<QueryNode> result; |
237 | switch (type) { |
238 | case QueryNodeType::SELECT_NODE: |
239 | result = SelectNode::Deserialize(reader); |
240 | break; |
241 | case QueryNodeType::SET_OPERATION_NODE: |
242 | result = SetOperationNode::Deserialize(reader); |
243 | break; |
244 | case QueryNodeType::RECURSIVE_CTE_NODE: |
245 | result = RecursiveCTENode::Deserialize(reader); |
246 | break; |
247 | default: |
248 | throw SerializationException("Could not deserialize Query Node: unknown type!" ); |
249 | } |
250 | result->modifiers = std::move(modifiers); |
251 | result->cte_map.map = std::move(new_map); |
252 | reader.Finalize(); |
253 | return result; |
254 | } |
255 | |
256 | void QueryNode::AddDistinct() { |
257 | // check if we already have a DISTINCT modifier |
258 | for (idx_t modifier_idx = modifiers.size(); modifier_idx > 0; modifier_idx--) { |
259 | auto &modifier = *modifiers[modifier_idx - 1]; |
260 | if (modifier.type == ResultModifierType::DISTINCT_MODIFIER) { |
261 | auto &distinct_modifier = modifier.Cast<DistinctModifier>(); |
262 | if (distinct_modifier.distinct_on_targets.empty()) { |
263 | // we have a DISTINCT without an ON clause - this distinct does not need to be added |
264 | return; |
265 | } |
266 | } else if (modifier.type == ResultModifierType::LIMIT_MODIFIER || |
267 | modifier.type == ResultModifierType::LIMIT_PERCENT_MODIFIER) { |
268 | // we encountered a LIMIT or LIMIT PERCENT - these change the result of DISTINCT, so we do need to push a |
269 | // DISTINCT relation |
270 | break; |
271 | } |
272 | } |
273 | modifiers.push_back(x: make_uniq<DistinctModifier>()); |
274 | } |
275 | |
276 | } // namespace duckdb |
277 | |