mutable
A Database System for Research and Fast Prototyping
Loading...
Searching...
No Matches
ASTPrinter.cpp
Go to the documentation of this file.
2
4
5
6using namespace m;
7using namespace m::ast;
8
9
10/*===== Expr =========================================================================================================*/
11
12void ASTPrinter::operator()(Const<ErrorExpr>&)
13{
14 out << "[error-expression]";
15}
16
17void ASTPrinter::operator()(Const<Designator> &e)
18{
19 if (e.has_explicit_table_name())
20 out << e.get_table_name() << '.';
21 out << e.attr_name.text;
22}
23
24void ASTPrinter::operator()(Const<Constant> &e)
25{
26 out << e.tok.text;
27}
28
29void ASTPrinter::operator()(Const<FnApplicationExpr> &e)
30{
31 (*this)(*e.fn);
32 out << '(';
33 for (auto it = e.args.cbegin(), end = e.args.cend(); it != end; ++it) {
34 if (it != e.args.cbegin()) out << ", ";
35 (*this)(**it);
36 }
37 out << ')';
38}
39
40void ASTPrinter::operator()(Const<UnaryExpr> &e)
41{
42 out << '(' << e.op().text;
43 if (e.op() == TK_Not) out << ' ';
44 (*this)(*e.expr);
45 out << ')';
46}
47
48void ASTPrinter::operator()(Const<BinaryExpr> &e)
49{
50 out << '(';
51 (*this)(*e.lhs);
52 out << ' ' << e.op().text << ' ';
53 (*this)(*e.rhs);
54 out << ')';
55}
56
57void ASTPrinter::operator()(Const<QueryExpr> &e)
58{
60 out << '(';
61 (*this)(*e.query);
62 out << ')';
63 } else {
64 out << e.alias() << '.' << e.alias(); // name of artificial source followed by name of single result
65 }
66}
67
68/*===== Clause =======================================================================================================*/
69
70void ASTPrinter::operator()(Const<ErrorClause>&)
71{
72 out << "[error-clause]";
73}
74
75void ASTPrinter::operator()(Const<SelectClause> &c)
76{
77 out << "SELECT ";
78 if (c.select_all) out << '*';
79 for (auto it = c.select.cbegin(), end = c.select.cend(); it != end; ++it) {
80 if (c.select_all or it != c.select.cbegin()) out << ", ";
81 (*this)(*it->first);
82 if (it->second) out << " AS " << it->second.text;
83 }
84}
85
86void ASTPrinter::operator()(Const<FromClause> &c)
87{
88 out << "FROM ";
89 for (auto it = c.from.cbegin(), end = c.from.cend(); it != end; ++it) {
90 if (it != c.from.cbegin()) out << ", ";
91 if (auto tok = std::get_if<Token>(&it->source)) {
92 out << tok->text;
93 } else if (auto stmt = std::get_if<Stmt*>(&it->source)) {
94 out << '(';
95 (*this)(**stmt);
96 out << ')';
97 } else {
98 M_unreachable("illegal variant");
99 }
100 if (it->alias) out << " AS " << it->alias.text;
101 }
102}
103
104void ASTPrinter::operator()(Const<WhereClause> &c)
105{
106 out << "WHERE " << *c.where;
107}
108
109void ASTPrinter::operator()(Const<GroupByClause> &c)
110{
111 out << "GROUP BY ";
112 for (auto it = c.group_by.cbegin(), end = c.group_by.cend(); it != end; ++it) {
113 if (it != c.group_by.cbegin()) out << ", ";
114 auto &[grp, alias] = *it;
115 (*this)(*grp);
116 if (it->second)
117 out << " AS " << alias.text;
118 }
119}
120
121void ASTPrinter::operator()(Const<HavingClause> &c)
122{
123 out << "HAVING " << *c.having;
124}
125
126void ASTPrinter::operator()(Const<OrderByClause> &c)
127{
128 out << "ORDER BY ";
129 for (auto it = c.order_by.cbegin(), end = c.order_by.cend(); it != end; ++it) {
130 if (it != c.order_by.cbegin()) out << ", ";
131 (*this)(*it->first);
132 if (it->second) out << " ASC";
133 else out << " DESC";
134 }
135}
136
137void ASTPrinter::operator()(Const<LimitClause> &c)
138{
139 out << "LIMIT " << c.limit.text;
140 if (c.offset)
141 out << " OFFSET " << c.offset.text;
142}
143
144/*===== Constraint ===================================================================================================*/
145
146void ASTPrinter::operator()(Const<PrimaryKeyConstraint>&)
147{
148 out << "PRIMARY KEY";
149}
150
151void ASTPrinter::operator()(Const<UniqueConstraint>&)
152{
153 out << "UNIQUE";
154}
155
156void ASTPrinter::operator()(Const<NotNullConstraint>&)
157{
158 out << "NOT NULL";
159}
160
161void ASTPrinter::operator()(Const<CheckConditionConstraint> &c)
162{
163 out << "CHECK (" << *c.cond << ')';
164}
165
166void ASTPrinter::operator()(Const<ReferenceConstraint> &c)
167{
168 out << "REFERENCES " << c.table_name.text << '(' << c.attr_name.text << ')';
169}
170
171
172/*===== Instruction ==================================================================================================*/
173
174void ASTPrinter::operator()(Const<Instruction> &inst)
175{
176 out << inst.tok.text;
177}
178
179
180/*===== Stmt =========================================================================================================*/
181
182void ASTPrinter::operator()(Const<ErrorStmt>&)
183{
184 out << "[error-statement];";
185}
186
187void ASTPrinter::operator()(Const<EmptyStmt>&)
188{
189 out << ';';
190}
191
192void ASTPrinter::operator()(Const<CreateDatabaseStmt> &s)
193{
194 out << "CREATE DATABASE " << s.database_name.text << ';';
195}
196
197void ASTPrinter::operator()(Const<DropDatabaseStmt> &s)
198{
199 out << "DROP DATABASE ";
200 if (s.has_if_exists)
201 out << "IF EXISTS ";
202 out << s.database_name.text << ';';
203}
204
205void ASTPrinter::operator()(Const<UseDatabaseStmt> &s)
206{
207 out << "USE " << s.database_name.text << ';';
208}
209
210void ASTPrinter::operator()(Const<CreateTableStmt> &s)
211{
212 out << "CREATE TABLE " << s.table_name.text << "\n(";
213 for (auto it = s.attributes.cbegin(), end = s.attributes.cend(); it != end; ++it) {
214 auto &attr = *it;
215 if (it != s.attributes.cbegin()) out << ',';
216 out << "\n " << attr->name.text << ' ' << *attr->type;
217 for (auto &c : attr->constraints) {
218 out << ' ';
219 (*this)(*c);
220 }
221 }
222 out << "\n);";
223}
224
225void ASTPrinter::operator()(Const<DropTableStmt> &s)
226{
227 out << "DROP TABLE ";
228 if (s.has_if_exists)
229 out << "IF EXISTS ";
230 for (auto it = s.table_names.cbegin(), end = s.table_names.cend(); it != end; ++it) {
231 auto &table_name = *it;
232 if (it != s.table_names.cbegin()) out << ", ";
233 out << table_name->text;
234 }
235 out << ';';
236}
237
238void ASTPrinter::operator()(Const<CreateIndexStmt> &s)
239{
240 out << "CREATE ";
241 if (s.has_unique)
242 out << "UNIQUE ";
243 out << "INDEX ";
244 if (s.has_if_not_exists)
245 out << "IF NOT EXISTS ";
246 if (s.index_name)
247 out << s.index_name.text << ' ';
248 out << "ON " << s.table_name.text;
249 if (s.method)
250 out << " USING " << s.method.text;
251 out << "\n(";
252 for (auto it = s.key_fields.cbegin(), end = s.key_fields.cend(); it != end; ++it) {
253 auto &field = *it;
254 if (it != s.key_fields.cbegin()) out << ',';
255 out << "\n ";
256 (*this)(*field);
257 }
258 out << "\n);";
259}
260
261void ASTPrinter::operator()(Const<DropIndexStmt> &s)
262{
263 out << "DROP INDEX ";
264 if (s.has_if_exists)
265 out << "IF EXISTS ";
266 for (auto it = s.index_names.cbegin(), end = s.index_names.cend(); it != end; ++it) {
267 auto &idx = *it;
268 if (it != s.index_names.cbegin()) out << ", ";
269 out << idx->text;
270 }
271 out << ';';
272}
273
274void ASTPrinter::operator()(Const<SelectStmt> &s)
275{
276 bool was_nested = is_nested_;
277 is_nested_ = true;
278
279 (*this)(*s.select);
280
281 if (s.from) {
282 out << '\n';
283 (*this)(*s.from);
284 }
285
286 if (s.where) {
287 out << '\n';
288 (*this)(*s.where);
289 }
290 if (s.group_by) {
291 out << '\n';
292 (*this)(*s.group_by);
293 }
294 if (s.having) {
295 out << '\n';
296 (*this)(*s.having);
297 }
298 if (s.order_by) {
299 out << '\n';
300 (*this)(*s.order_by);
301 }
302 if (s.limit) {
303 out << '\n';
304 (*this)(*s.limit);
305 }
306
307 is_nested_ = was_nested;
308 if (not is_nested_)
309 out << ';';
310}
311
312void ASTPrinter::operator()(Const<InsertStmt> &s)
313{
314 out << "INSERT INTO " << s.table_name.text << "\nVALUES\n ";
315 for (auto value_it = s.tuples.cbegin(), end = s.tuples.cend(); value_it != end; ++value_it) {
316 if (value_it != s.tuples.cbegin()) out << ",\n ";
317 out << '(';
318 for (auto elem_it = value_it->cbegin(), elem_end = value_it->cend(); elem_it != elem_end; ++elem_it) {
319 if (elem_it != value_it->cbegin()) out << ", ";
320 switch (elem_it->first) {
321 case InsertStmt::I_Default: out << "DEFAULT"; break;
322 case InsertStmt::I_Null: out << "NULL"; break;
323 case InsertStmt::I_Expr: out << *elem_it->second; break;
324 }
325 }
326 out << ')';
327 }
328 out << ';';
329}
330
331void ASTPrinter::operator()(Const<UpdateStmt> &s)
332{
333 out << "UPDATE " << s.table_name.text << "\nSET\n";
334 for (auto it = s.set.cbegin(), end = s.set.cend(); it != end; ++it) {
335 if (it != s.set.cbegin()) out << ",\n";
336 out << " " << it->first.text << " = " << *it->second;
337 }
338 if (s.where) out << '\n' << *s.where;
339 out << ';';
340}
341
342void ASTPrinter::operator()(Const<DeleteStmt> &s)
343{
344 out << "DELETE FROM " << s.table_name.text;
345 if (s.where) out << '\n' << *s.where;
346 out << ';';
347}
348
349void ASTPrinter::operator()(Const<DSVImportStmt> &s)
350{
351 out << "IMPORT INTO " << s.table_name.text << " DSV " << s.path.text;
352 if (s.rows)
353 out << " ROWS " << s.rows.text;
354 if (s.delimiter)
355 out << " DELIMITER " << s.delimiter.text;
356 if (s.has_header)
357 out << " HAS HEADER";
358 if (s.skip_header)
359 out << " SKIP HEADER";
360 out << ';';
361}
#define M_unreachable(MSG)
Definition: macro.hpp:146
‍mutable namespace
Definition: Backend.hpp:10
bool is_nested_
whether the statement is nested; determines whether a final ';' must be printed
Definition: ASTPrinter.hpp:15
std::ostream & out
the output stream to write to
Definition: ASTPrinter.hpp:12
bool expand_nested_queries_
determines whether nested queries are printed
Definition: ASTPrinter.hpp:16