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
15using std::shared_ptr;
16
17struct 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
26struct 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
34struct 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
42struct 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
49private:
50 string method;
51 double percent;
52};
53
54struct 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
63struct lateral_subquery : table_subquery {
64 lateral_subquery(prod *p) : table_subquery(p, true) {
65 }
66};
67
68struct 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
78struct 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
86struct 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
99struct 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
120struct 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
133struct 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
148struct 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
167struct 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
175struct 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
193struct 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
204struct 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
220struct 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
234struct 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
247struct 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
261struct 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
280struct 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
293struct 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
305struct 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
315struct 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
324struct 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
336struct 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
353shared_ptr<prod> statement_factory(struct scope *s);
354
355struct 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