1 | /// @file |
2 | /// @brief grammar: Top-level and unsorted grammar productions |
3 | |
4 | #ifndef GRAMMAR_HH |
5 | #define GRAMMAR_HH |
6 | |
7 | #include "relmodel.hh" |
8 | #include "schema.hh" |
9 | #include <memory> |
10 | #include <ostream> |
11 | |
12 | #include "expr.hh" |
13 | #include "prod.hh" |
14 | |
15 | using std::shared_ptr; |
16 | |
17 | struct table_ref : prod { |
18 | vector<shared_ptr<named_relation>> refs; |
19 | static shared_ptr<table_ref> factory(prod *p); |
20 | table_ref(prod *p) : prod(p) { |
21 | } |
22 | virtual ~table_ref() { |
23 | } |
24 | }; |
25 | |
26 | struct table_or_query_name : table_ref { |
27 | virtual void out(std::ostream &out); |
28 | table_or_query_name(prod *p); |
29 | virtual ~table_or_query_name() { |
30 | } |
31 | named_relation *t; |
32 | }; |
33 | |
34 | struct target_table : table_ref { |
35 | virtual void out(std::ostream &out); |
36 | target_table(prod *p, table *victim = 0); |
37 | virtual ~target_table() { |
38 | } |
39 | table *victim_; |
40 | }; |
41 | |
42 | struct table_sample : table_ref { |
43 | virtual void out(std::ostream &out); |
44 | table_sample(prod *p); |
45 | virtual ~table_sample() { |
46 | } |
47 | struct table *t; |
48 | |
49 | private: |
50 | string method; |
51 | double percent; |
52 | }; |
53 | |
54 | struct table_subquery : table_ref { |
55 | bool is_lateral; |
56 | virtual void out(std::ostream &out); |
57 | shared_ptr<struct query_spec> query; |
58 | table_subquery(prod *p, bool lateral = false); |
59 | virtual ~table_subquery(); |
60 | virtual void accept(prod_visitor *v); |
61 | }; |
62 | |
63 | struct lateral_subquery : table_subquery { |
64 | lateral_subquery(prod *p) : table_subquery(p, true) { |
65 | } |
66 | }; |
67 | |
68 | struct join_cond : prod { |
69 | static shared_ptr<join_cond> factory(prod *p, table_ref &lhs, table_ref &rhs); |
70 | join_cond(prod *p, table_ref &lhs, table_ref &rhs) : prod(p) { |
71 | (void)lhs; |
72 | (void)rhs; |
73 | } |
74 | virtual ~join_cond() { |
75 | } |
76 | }; |
77 | |
78 | struct simple_join_cond : join_cond { |
79 | std::string condition; |
80 | simple_join_cond(prod *p, table_ref &lhs, table_ref &rhs); |
81 | virtual ~simple_join_cond() { |
82 | } |
83 | virtual void out(std::ostream &out); |
84 | }; |
85 | |
86 | struct expr_join_cond : join_cond { |
87 | struct scope joinscope; |
88 | shared_ptr<bool_expr> search; |
89 | expr_join_cond(prod *p, table_ref &lhs, table_ref &rhs); |
90 | virtual ~expr_join_cond() { |
91 | } |
92 | virtual void out(std::ostream &out); |
93 | virtual void accept(prod_visitor *v) { |
94 | search->accept(v); |
95 | v->visit(this); |
96 | } |
97 | }; |
98 | |
99 | struct joined_table : table_ref { |
100 | virtual void out(std::ostream &out); |
101 | joined_table(prod *p); |
102 | std::string type; |
103 | std::string alias; |
104 | virtual std::string ident() { |
105 | return alias; |
106 | } |
107 | shared_ptr<table_ref> lhs; |
108 | shared_ptr<table_ref> rhs; |
109 | shared_ptr<join_cond> condition; |
110 | virtual ~joined_table() { |
111 | } |
112 | virtual void accept(prod_visitor *v) { |
113 | lhs->accept(v); |
114 | rhs->accept(v); |
115 | condition->accept(v); |
116 | v->visit(this); |
117 | } |
118 | }; |
119 | |
120 | struct from_clause : prod { |
121 | std::vector<shared_ptr<table_ref>> reflist; |
122 | virtual void out(std::ostream &out); |
123 | from_clause(prod *p); |
124 | virtual ~from_clause() { |
125 | } |
126 | virtual void accept(prod_visitor *v) { |
127 | v->visit(this); |
128 | for (auto p : reflist) |
129 | p->accept(v); |
130 | } |
131 | }; |
132 | |
133 | struct select_list : prod { |
134 | std::vector<shared_ptr<value_expr>> value_exprs; |
135 | relation derived_table; |
136 | int columns = 0; |
137 | select_list(prod *p); |
138 | virtual void out(std::ostream &out); |
139 | virtual ~select_list() { |
140 | } |
141 | virtual void accept(prod_visitor *v) { |
142 | v->visit(this); |
143 | for (auto p : value_exprs) |
144 | p->accept(v); |
145 | } |
146 | }; |
147 | |
148 | struct query_spec : prod { |
149 | std::string set_quantifier; |
150 | shared_ptr<struct from_clause> from_clause; |
151 | shared_ptr<struct select_list> select_list; |
152 | shared_ptr<bool_expr> search; |
153 | std::string limit_clause; |
154 | struct scope myscope; |
155 | virtual void out(std::ostream &out); |
156 | query_spec(prod *p, struct scope *s, bool lateral = 0); |
157 | virtual ~query_spec() { |
158 | } |
159 | virtual void accept(prod_visitor *v) { |
160 | v->visit(this); |
161 | select_list->accept(v); |
162 | from_clause->accept(v); |
163 | search->accept(v); |
164 | } |
165 | }; |
166 | |
167 | struct select_for_update : query_spec { |
168 | const char *lockmode; |
169 | virtual void out(std::ostream &out); |
170 | select_for_update(prod *p, struct scope *s, bool lateral = 0); |
171 | virtual ~select_for_update() { |
172 | } |
173 | }; |
174 | |
175 | struct prepare_stmt : prod { |
176 | query_spec q; |
177 | static long seq; |
178 | long id; |
179 | virtual void out(std::ostream &out) { |
180 | out << "prepare prep" << id << " as " << q; |
181 | } |
182 | prepare_stmt(prod *p) : prod(p), q(p, scope) { |
183 | id = seq++; |
184 | } |
185 | virtual ~prepare_stmt() { |
186 | } |
187 | virtual void accept(prod_visitor *v) { |
188 | v->visit(this); |
189 | q.accept(v); |
190 | } |
191 | }; |
192 | |
193 | struct modifying_stmt : prod { |
194 | table *victim; |
195 | struct scope myscope; |
196 | modifying_stmt(prod *p, struct scope *s, struct table *victim = 0); |
197 | virtual ~modifying_stmt() { |
198 | } |
199 | // shared_ptr<modifying_stmt> modifying_stmt::factory(prod *p, struct |
200 | // scope *s); |
201 | virtual void pick_victim(); |
202 | }; |
203 | |
204 | struct delete_stmt : modifying_stmt { |
205 | shared_ptr<bool_expr> search; |
206 | delete_stmt(prod *p, struct scope *s, table *v); |
207 | virtual ~delete_stmt() { |
208 | } |
209 | virtual void out(std::ostream &out) { |
210 | out << "delete from " << victim->ident(); |
211 | indent(out); |
212 | out << "where " << std::endl << *search; |
213 | } |
214 | virtual void accept(prod_visitor *v) { |
215 | v->visit(this); |
216 | search->accept(v); |
217 | } |
218 | }; |
219 | |
220 | struct delete_returning : delete_stmt { |
221 | shared_ptr<struct select_list> select_list; |
222 | delete_returning(prod *p, struct scope *s, table *victim = 0); |
223 | virtual void out(std::ostream &out) { |
224 | delete_stmt::out(out); |
225 | out << std::endl << "returning " << *select_list; |
226 | } |
227 | virtual void accept(prod_visitor *v) { |
228 | v->visit(this); |
229 | search->accept(v); |
230 | select_list->accept(v); |
231 | } |
232 | }; |
233 | |
234 | struct insert_stmt : modifying_stmt { |
235 | vector<shared_ptr<value_expr>> value_exprs; |
236 | insert_stmt(prod *p, struct scope *s, table *victim = 0); |
237 | virtual ~insert_stmt() { |
238 | } |
239 | virtual void out(std::ostream &out); |
240 | virtual void accept(prod_visitor *v) { |
241 | v->visit(this); |
242 | for (auto p : value_exprs) |
243 | p->accept(v); |
244 | } |
245 | }; |
246 | |
247 | struct set_list : prod { |
248 | vector<shared_ptr<value_expr>> value_exprs; |
249 | vector<string> names; |
250 | set_list(prod *p, table *target); |
251 | virtual ~set_list() { |
252 | } |
253 | virtual void out(std::ostream &out); |
254 | virtual void accept(prod_visitor *v) { |
255 | v->visit(this); |
256 | for (auto p : value_exprs) |
257 | p->accept(v); |
258 | } |
259 | }; |
260 | |
261 | struct upsert_stmt : insert_stmt { |
262 | shared_ptr<struct set_list> set_list; |
263 | string constraint; |
264 | shared_ptr<bool_expr> search; |
265 | upsert_stmt(prod *p, struct scope *s, table *v = 0); |
266 | virtual void out(std::ostream &out) { |
267 | insert_stmt::out(out); |
268 | out << " on conflict on constraint " << constraint << " do update " ; |
269 | out << *set_list << " where " << *search; |
270 | } |
271 | virtual void accept(prod_visitor *v) { |
272 | insert_stmt::accept(v); |
273 | set_list->accept(v); |
274 | search->accept(v); |
275 | } |
276 | virtual ~upsert_stmt() { |
277 | } |
278 | }; |
279 | |
280 | struct update_stmt : modifying_stmt { |
281 | shared_ptr<bool_expr> search; |
282 | shared_ptr<struct set_list> set_list; |
283 | update_stmt(prod *p, struct scope *s, table *victim = 0); |
284 | virtual ~update_stmt() { |
285 | } |
286 | virtual void out(std::ostream &out); |
287 | virtual void accept(prod_visitor *v) { |
288 | v->visit(this); |
289 | search->accept(v); |
290 | } |
291 | }; |
292 | |
293 | struct when_clause : prod { |
294 | bool matched; |
295 | shared_ptr<bool_expr> condition; |
296 | // shared_ptr<prod> merge_action; |
297 | when_clause(struct merge_stmt *p); |
298 | virtual ~when_clause() { |
299 | } |
300 | static shared_ptr<when_clause> factory(struct merge_stmt *p); |
301 | virtual void out(std::ostream &out); |
302 | virtual void accept(prod_visitor *v); |
303 | }; |
304 | |
305 | struct when_clause_update : when_clause { |
306 | shared_ptr<struct set_list> set_list; |
307 | struct scope myscope; |
308 | when_clause_update(struct merge_stmt *p); |
309 | virtual ~when_clause_update() { |
310 | } |
311 | virtual void out(std::ostream &out); |
312 | virtual void accept(prod_visitor *v); |
313 | }; |
314 | |
315 | struct when_clause_insert : when_clause { |
316 | vector<shared_ptr<value_expr>> exprs; |
317 | when_clause_insert(struct merge_stmt *p); |
318 | virtual ~when_clause_insert() { |
319 | } |
320 | virtual void out(std::ostream &out); |
321 | virtual void accept(prod_visitor *v); |
322 | }; |
323 | |
324 | struct merge_stmt : modifying_stmt { |
325 | merge_stmt(prod *p, struct scope *s, table *victim = 0); |
326 | shared_ptr<table_ref> target_table_; |
327 | shared_ptr<table_ref> data_source; |
328 | shared_ptr<join_cond> join_condition; |
329 | vector<shared_ptr<when_clause>> clauselist; |
330 | virtual ~merge_stmt() { |
331 | } |
332 | virtual void out(std::ostream &out); |
333 | virtual void accept(prod_visitor *v); |
334 | }; |
335 | |
336 | struct update_returning : update_stmt { |
337 | shared_ptr<struct select_list> select_list; |
338 | update_returning(prod *p, struct scope *s, table *victim = 0); |
339 | virtual ~update_returning() { |
340 | } |
341 | virtual void out(std::ostream &out) { |
342 | update_stmt::out(out); |
343 | out << std::endl << "returning " << *select_list; |
344 | } |
345 | virtual void accept(prod_visitor *v) { |
346 | v->visit(this); |
347 | search->accept(v); |
348 | set_list->accept(v); |
349 | select_list->accept(v); |
350 | } |
351 | }; |
352 | |
353 | shared_ptr<prod> statement_factory(struct scope *s); |
354 | |
355 | struct common_table_expression : prod { |
356 | vector<shared_ptr<prod>> with_queries; |
357 | shared_ptr<prod> query; |
358 | vector<shared_ptr<named_relation>> refs; |
359 | struct scope myscope; |
360 | virtual void out(std::ostream &out); |
361 | virtual void accept(prod_visitor *v); |
362 | common_table_expression(prod *parent, struct scope *s); |
363 | virtual ~common_table_expression() { |
364 | } |
365 | }; |
366 | |
367 | #endif |
368 | |