1#include "duckdb/parser/query_node/select_node.hpp"
2#include "duckdb/parser/expression_util.hpp"
3#include "duckdb/common/field_writer.hpp"
4#include "duckdb/parser/keyword_helper.hpp"
5#include "duckdb/common/serializer/format_serializer.hpp"
6#include "duckdb/common/serializer/format_deserializer.hpp"
7
8namespace duckdb {
9
10SelectNode::SelectNode()
11 : QueryNode(QueryNodeType::SELECT_NODE), aggregate_handling(AggregateHandling::STANDARD_HANDLING) {
12}
13
14string SelectNode::ToString() const {
15 string result;
16 result = cte_map.ToString();
17 result += "SELECT ";
18
19 // search for a distinct modifier
20 for (idx_t modifier_idx = 0; modifier_idx < modifiers.size(); modifier_idx++) {
21 if (modifiers[modifier_idx]->type == ResultModifierType::DISTINCT_MODIFIER) {
22 auto &distinct_modifier = modifiers[modifier_idx]->Cast<DistinctModifier>();
23 result += "DISTINCT ";
24 if (!distinct_modifier.distinct_on_targets.empty()) {
25 result += "ON (";
26 for (idx_t k = 0; k < distinct_modifier.distinct_on_targets.size(); k++) {
27 if (k > 0) {
28 result += ", ";
29 }
30 result += distinct_modifier.distinct_on_targets[k]->ToString();
31 }
32 result += ") ";
33 }
34 }
35 }
36 for (idx_t i = 0; i < select_list.size(); i++) {
37 if (i > 0) {
38 result += ", ";
39 }
40 result += select_list[i]->ToString();
41 if (!select_list[i]->alias.empty()) {
42 result += StringUtil::Format(fmt_str: " AS %s", params: SQLIdentifier(select_list[i]->alias));
43 }
44 }
45 if (from_table && from_table->type != TableReferenceType::EMPTY) {
46 result += " FROM " + from_table->ToString();
47 }
48 if (where_clause) {
49 result += " WHERE " + where_clause->ToString();
50 }
51 if (!groups.grouping_sets.empty()) {
52 result += " GROUP BY ";
53 // if we are dealing with multiple grouping sets, we have to add a few additional brackets
54 bool grouping_sets = groups.grouping_sets.size() > 1;
55 if (grouping_sets) {
56 result += "GROUPING SETS (";
57 }
58 for (idx_t i = 0; i < groups.grouping_sets.size(); i++) {
59 auto &grouping_set = groups.grouping_sets[i];
60 if (i > 0) {
61 result += ",";
62 }
63 if (grouping_set.empty()) {
64 result += "()";
65 continue;
66 }
67 if (grouping_sets) {
68 result += "(";
69 }
70 bool first = true;
71 for (auto &grp : grouping_set) {
72 if (!first) {
73 result += ", ";
74 }
75 result += groups.group_expressions[grp]->ToString();
76 first = false;
77 }
78 if (grouping_sets) {
79 result += ")";
80 }
81 }
82 if (grouping_sets) {
83 result += ")";
84 }
85 } else if (aggregate_handling == AggregateHandling::FORCE_AGGREGATES) {
86 result += " GROUP BY ALL";
87 }
88 if (having) {
89 result += " HAVING " + having->ToString();
90 }
91 if (qualify) {
92 result += " QUALIFY " + qualify->ToString();
93 }
94 if (sample) {
95 result += " USING SAMPLE ";
96 result += sample->sample_size.ToString();
97 if (sample->is_percentage) {
98 result += "%";
99 }
100 result += " (" + EnumUtil::ToString(value: sample->method);
101 if (sample->seed >= 0) {
102 result += ", " + std::to_string(val: sample->seed);
103 }
104 result += ")";
105 }
106 return result + ResultModifiersToString();
107}
108
109bool SelectNode::Equals(const QueryNode *other_p) const {
110 if (!QueryNode::Equals(other: other_p)) {
111 return false;
112 }
113 if (this == other_p) {
114 return true;
115 }
116 auto &other = other_p->Cast<SelectNode>();
117
118 // SELECT
119 if (!ExpressionUtil::ListEquals(a: select_list, b: other.select_list)) {
120 return false;
121 }
122 // FROM
123 if (!TableRef::Equals(left: from_table, right: other.from_table)) {
124 return false;
125 }
126 // WHERE
127 if (!ParsedExpression::Equals(left: where_clause, right: other.where_clause)) {
128 return false;
129 }
130 // GROUP BY
131 if (!ParsedExpression::ListEquals(left: groups.group_expressions, right: other.groups.group_expressions)) {
132 return false;
133 }
134 if (groups.grouping_sets != other.groups.grouping_sets) {
135 return false;
136 }
137 if (!SampleOptions::Equals(a: sample.get(), b: other.sample.get())) {
138 return false;
139 }
140 // HAVING
141 if (!ParsedExpression::Equals(left: having, right: other.having)) {
142 return false;
143 }
144 // QUALIFY
145 if (!ParsedExpression::Equals(left: qualify, right: other.qualify)) {
146 return false;
147 }
148 return true;
149}
150
151unique_ptr<QueryNode> SelectNode::Copy() const {
152 auto result = make_uniq<SelectNode>();
153 for (auto &child : select_list) {
154 result->select_list.push_back(x: child->Copy());
155 }
156 result->from_table = from_table ? from_table->Copy() : nullptr;
157 result->where_clause = where_clause ? where_clause->Copy() : nullptr;
158 // groups
159 for (auto &group : groups.group_expressions) {
160 result->groups.group_expressions.push_back(x: group->Copy());
161 }
162 result->groups.grouping_sets = groups.grouping_sets;
163 result->aggregate_handling = aggregate_handling;
164 result->having = having ? having->Copy() : nullptr;
165 result->qualify = qualify ? qualify->Copy() : nullptr;
166 result->sample = sample ? sample->Copy() : nullptr;
167 this->CopyProperties(other&: *result);
168 return std::move(result);
169}
170
171void SelectNode::Serialize(FieldWriter &writer) const {
172 writer.WriteSerializableList(elements: select_list);
173 writer.WriteOptional(element: from_table);
174 writer.WriteOptional(element: where_clause);
175 writer.WriteSerializableList(elements: groups.group_expressions);
176 writer.WriteField<uint32_t>(element: groups.grouping_sets.size());
177 auto &serializer = writer.GetSerializer();
178 for (auto &grouping_set : groups.grouping_sets) {
179 serializer.Write<idx_t>(element: grouping_set.size());
180 for (auto &idx : grouping_set) {
181 serializer.Write<idx_t>(element: idx);
182 }
183 }
184 writer.WriteField<AggregateHandling>(element: aggregate_handling);
185 writer.WriteOptional(element: having);
186 writer.WriteOptional(element: sample);
187 writer.WriteOptional(element: qualify);
188}
189
190void SelectNode::FormatSerialize(FormatSerializer &serializer) const {
191 QueryNode::FormatSerialize(serializer);
192 serializer.WriteProperty(tag: "select_list", value: select_list);
193 serializer.WriteOptionalProperty(tag: "from_table", ptr: from_table);
194 serializer.WriteOptionalProperty(tag: "where_clause", ptr: where_clause);
195 serializer.WriteProperty(tag: "group_expressions", value: groups.group_expressions);
196 serializer.WriteProperty(tag: "group_sets", value: groups.grouping_sets);
197 serializer.WriteProperty(tag: "aggregate_handling", value: aggregate_handling);
198 serializer.WriteOptionalProperty(tag: "having", ptr: having);
199 serializer.WriteOptionalProperty(tag: "sample", ptr: sample);
200 serializer.WriteOptionalProperty(tag: "qualify", ptr: qualify);
201}
202
203unique_ptr<QueryNode> SelectNode::FormatDeserialize(FormatDeserializer &deserializer) {
204 auto result = make_uniq<SelectNode>();
205
206 deserializer.ReadProperty(tag: "select_list", ret&: result->select_list);
207 deserializer.ReadOptionalProperty(tag: "from_table", ret&: result->from_table);
208 deserializer.ReadOptionalProperty(tag: "where_clause", ret&: result->where_clause);
209 deserializer.ReadProperty(tag: "group_expressions", ret&: result->groups.group_expressions);
210 deserializer.ReadProperty(tag: "group_sets", ret&: result->groups.grouping_sets);
211 deserializer.ReadProperty(tag: "aggregate_handling", ret&: result->aggregate_handling);
212 deserializer.ReadOptionalProperty(tag: "having", ret&: result->having);
213 deserializer.ReadOptionalProperty(tag: "sample", ret&: result->sample);
214 deserializer.ReadOptionalProperty(tag: "qualify", ret&: result->qualify);
215
216 return std::move(result);
217}
218
219unique_ptr<QueryNode> SelectNode::Deserialize(FieldReader &reader) {
220 auto result = make_uniq<SelectNode>();
221 result->select_list = reader.ReadRequiredSerializableList<ParsedExpression>();
222 result->from_table = reader.ReadOptional<TableRef>(default_value: nullptr);
223 result->where_clause = reader.ReadOptional<ParsedExpression>(default_value: nullptr);
224 result->groups.group_expressions = reader.ReadRequiredSerializableList<ParsedExpression>();
225
226 auto grouping_set_count = reader.ReadRequired<uint32_t>();
227 auto &source = reader.GetSource();
228 for (idx_t set_idx = 0; set_idx < grouping_set_count; set_idx++) {
229 auto set_entries = source.Read<idx_t>();
230 GroupingSet grouping_set;
231 for (idx_t i = 0; i < set_entries; i++) {
232 grouping_set.insert(x: source.Read<idx_t>());
233 }
234 result->groups.grouping_sets.push_back(x: grouping_set);
235 }
236
237 result->aggregate_handling = reader.ReadRequired<AggregateHandling>();
238 result->having = reader.ReadOptional<ParsedExpression>(default_value: nullptr);
239 result->sample = reader.ReadOptional<SampleOptions>(default_value: nullptr);
240 result->qualify = reader.ReadOptional<ParsedExpression>(default_value: nullptr);
241 return std::move(result);
242}
243
244} // namespace duckdb
245