1/// @file
2/// @brief grammar: Value expression productions
3
4#ifndef EXPR_HH
5#define EXPR_HH
6
7#include "prod.hh"
8#include <string>
9
10using std::shared_ptr;
11using std::string;
12using std::vector;
13
14struct value_expr : prod {
15 sqltype *type;
16 virtual void out(std::ostream &out) = 0;
17 virtual ~value_expr() {
18 }
19 value_expr(prod *p) : prod(p) {
20 }
21 static shared_ptr<value_expr> factory(prod *p, sqltype *type_constraint = 0);
22};
23
24struct case_expr : value_expr {
25 shared_ptr<value_expr> condition;
26 shared_ptr<value_expr> true_expr;
27 shared_ptr<value_expr> false_expr;
28 case_expr(prod *p, sqltype *type_constraint = 0);
29 virtual void out(std::ostream &out);
30 virtual void accept(prod_visitor *v);
31};
32
33struct funcall : value_expr {
34 routine *proc;
35 bool is_aggregate;
36 vector<shared_ptr<value_expr>> parms;
37 virtual void out(std::ostream &out);
38 virtual ~funcall() {
39 }
40 funcall(prod *p, sqltype *type_constraint = 0, bool agg = 0);
41 virtual void accept(prod_visitor *v) {
42 v->visit(this);
43 for (auto p : parms)
44 p->accept(v);
45 }
46};
47
48struct atomic_subselect : value_expr {
49 table *tab;
50 column *col;
51 int offset;
52 routine *agg;
53 atomic_subselect(prod *p, sqltype *type_constraint = 0);
54 virtual void out(std::ostream &out);
55};
56
57struct const_expr : value_expr {
58 std::string expr;
59 const_expr(prod *p, sqltype *type_constraint = 0);
60 virtual void out(std::ostream &out) {
61 out << expr;
62 }
63 virtual ~const_expr() {
64 }
65};
66
67struct column_reference : value_expr {
68 column_reference(prod *p, sqltype *type_constraint = 0);
69 virtual void out(std::ostream &out) {
70 out << reference;
71 }
72 std::string reference;
73 virtual ~column_reference() {
74 }
75};
76
77struct coalesce : value_expr {
78 const char *abbrev_;
79 vector<shared_ptr<value_expr>> value_exprs;
80 virtual ~coalesce(){};
81 coalesce(prod *p, sqltype *type_constraint = 0, const char *abbrev = "coalesce");
82 virtual void out(std::ostream &out);
83 virtual void accept(prod_visitor *v) {
84 v->visit(this);
85 for (auto p : value_exprs)
86 p->accept(v);
87 }
88};
89
90struct nullif : coalesce {
91 virtual ~nullif(){};
92 nullif(prod *p, sqltype *type_constraint = 0) : coalesce(p, type_constraint, "nullif"){};
93};
94
95struct bool_expr : value_expr {
96 virtual ~bool_expr() {
97 }
98 bool_expr(prod *p) : value_expr(p) {
99 type = scope->schema->booltype;
100 }
101 static shared_ptr<bool_expr> factory(prod *p);
102};
103
104struct truth_value : bool_expr {
105 virtual ~truth_value() {
106 }
107 const char *op;
108 virtual void out(std::ostream &out) {
109 out << op;
110 }
111 truth_value(prod *p) : bool_expr(p) {
112 op = ((d6() < 4) ? scope->schema->true_literal : scope->schema->false_literal);
113 }
114};
115
116struct null_predicate : bool_expr {
117 virtual ~null_predicate() {
118 }
119 const char *negate;
120 shared_ptr<value_expr> expr;
121 null_predicate(prod *p) : bool_expr(p) {
122 negate = ((d6() < 4) ? "not " : "");
123 expr = value_expr::factory(this);
124 }
125 virtual void out(std::ostream &out) {
126 out << *expr << " is " << negate << "NULL";
127 }
128 virtual void accept(prod_visitor *v) {
129 v->visit(this);
130 expr->accept(v);
131 }
132};
133
134struct exists_predicate : bool_expr {
135 shared_ptr<struct query_spec> subquery;
136 virtual ~exists_predicate() {
137 }
138 exists_predicate(prod *p);
139 virtual void out(std::ostream &out);
140 virtual void accept(prod_visitor *v);
141};
142
143struct bool_binop : bool_expr {
144 shared_ptr<value_expr> lhs, rhs;
145 bool_binop(prod *p) : bool_expr(p) {
146 }
147 virtual void out(std::ostream &out) = 0;
148 virtual void accept(prod_visitor *v) {
149 v->visit(this);
150 lhs->accept(v);
151 rhs->accept(v);
152 }
153};
154
155struct bool_term : bool_binop {
156 virtual ~bool_term() {
157 }
158 const char *op;
159 virtual void out(std::ostream &out) {
160 out << "(" << *lhs << ") ";
161 indent(out);
162 out << op << " (" << *rhs << ")";
163 }
164 bool_term(prod *p) : bool_binop(p) {
165 op = ((d6() < 4) ? "or" : "and");
166 lhs = bool_expr::factory(this);
167 rhs = bool_expr::factory(this);
168 }
169};
170
171struct distinct_pred : bool_binop {
172 distinct_pred(prod *p);
173 virtual ~distinct_pred(){};
174 virtual void out(std::ostream &o) {
175 o << *lhs << " is distinct from " << *rhs;
176 }
177};
178
179struct comparison_op : bool_binop {
180 op *oper;
181 comparison_op(prod *p);
182 virtual ~comparison_op(){};
183 virtual void out(std::ostream &o) {
184 o << *lhs << " " << oper->name << " " << *rhs;
185 }
186};
187
188struct window_function : value_expr {
189 virtual void out(std::ostream &out);
190 virtual ~window_function() {
191 }
192 window_function(prod *p, sqltype *type_constraint);
193 vector<shared_ptr<column_reference>> partition_by;
194 vector<shared_ptr<column_reference>> order_by;
195 shared_ptr<funcall> aggregate;
196 static bool allowed(prod *pprod);
197 virtual void accept(prod_visitor *v) {
198 v->visit(this);
199 aggregate->accept(v);
200 for (auto p : partition_by)
201 p->accept(v);
202 for (auto p : order_by)
203 p->accept(v);
204 }
205};
206
207#endif
208