1 | /* |
2 | * This Source Code Form is subject to the terms of the Mozilla Public |
3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
5 | * |
6 | * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V. |
7 | */ |
8 | |
9 | #ifndef SQL_RELATION_H |
10 | #define SQL_RELATION_H |
11 | |
12 | #include "sql_catalog.h" |
13 | |
14 | typedef enum expression_type { |
15 | e_atom, |
16 | e_column, |
17 | e_cmp, |
18 | e_func, |
19 | e_aggr, |
20 | e_convert, |
21 | e_psm |
22 | } expression_type; |
23 | |
24 | #define CARD_ATOM 1 |
25 | #define CARD_AGGR 2 |
26 | #define CARD_MULTI 3 |
27 | |
28 | typedef struct sql_exp_name { |
29 | unsigned int label; |
30 | const char *name; |
31 | const char *rname; |
32 | } sql_exp_name; |
33 | |
34 | typedef struct expression { |
35 | expression_type type; /* atom, cmp, func/aggr */ |
36 | sql_exp_name alias; |
37 | void *l; |
38 | void *r; |
39 | void *f; /* func's and aggr's, also e_cmp may have have 2 arguments */ |
40 | unsigned int |
41 | flag:18, /* EXP_DISTINCT, NO_NIL, ASCENDING, NULLS_LAST, cmp types */ |
42 | card:2, /* card (0 truth value!) (1 atoms) (2 aggr) (3 multi value) */ |
43 | freevar:4, /* free variable, ie binds to the upper dependent join */ |
44 | intern:1, |
45 | anti:1, |
46 | base:1, |
47 | used:1; /* used for quick dead code removal */ |
48 | sql_subtype tpe; |
49 | void *p; /* properties for the optimizer */ |
50 | } sql_exp; |
51 | |
52 | #define EXP_DISTINCT 1 |
53 | #define NO_NIL 2 |
54 | #define TOPN_INCLUDING 4 |
55 | #define ZERO_IF_EMPTY 8 |
56 | |
57 | #define LEFT_JOIN 4 |
58 | |
59 | /* ASCENDING > 15 else we have problems with cmp types */ |
60 | #define ASCENDING 16 |
61 | #define CMPMASK (ASCENDING-1) |
62 | #define get_cmp(e) (e->flag&CMPMASK) |
63 | #define HAS_NO_NIL 32 |
64 | #define NULLS_LAST 64 |
65 | |
66 | #define UPD_COMP 1 |
67 | #define UPD_LOCKED 2 |
68 | #define UPD_NO_CONSTRAINT 4 |
69 | |
70 | #define REL_PARTITION 8 |
71 | |
72 | /* We need bit wise exclusive numbers as we merge the level also in the flag */ |
73 | #define PSM_SET 1 |
74 | #define PSM_VAR 2 |
75 | #define PSM_RETURN 4 |
76 | #define PSM_WHILE 8 |
77 | #define PSM_IF 16 |
78 | #define PSM_REL 32 |
79 | #define PSM_EXCEPTION 64 |
80 | |
81 | #define SET_PSM_LEVEL(level) (level<<8) |
82 | #define GET_PSM_LEVEL(level) (level>>8) |
83 | |
84 | typedef enum ddl_statement { |
85 | ddl_output, |
86 | ddl_list, |
87 | ddl_psm, |
88 | ddl_exception, |
89 | ddl_create_seq, |
90 | ddl_alter_seq, |
91 | ddl_drop_seq, |
92 | ddl_alter_table_add_range_partition, |
93 | ddl_alter_table_add_list_partition, |
94 | ddl_release, |
95 | ddl_commit, |
96 | ddl_rollback, |
97 | ddl_trans, |
98 | ddl_create_schema, |
99 | ddl_drop_schema, |
100 | ddl_create_table, |
101 | ddl_drop_table, |
102 | ddl_create_view, |
103 | ddl_drop_view, |
104 | ddl_drop_constraint, |
105 | ddl_alter_table, |
106 | ddl_create_type, |
107 | ddl_drop_type, |
108 | ddl_drop_index, |
109 | ddl_create_function, |
110 | ddl_drop_function, |
111 | ddl_create_trigger, |
112 | ddl_drop_trigger, |
113 | ddl_grant_roles, |
114 | ddl_revoke_roles, |
115 | ddl_grant, |
116 | ddl_revoke, |
117 | ddl_grant_func, |
118 | ddl_revoke_func, |
119 | ddl_create_user, |
120 | ddl_drop_user, |
121 | ddl_alter_user, |
122 | ddl_rename_user, |
123 | ddl_create_role, |
124 | ddl_drop_role, |
125 | ddl_alter_table_add_table, |
126 | ddl_alter_table_del_table, |
127 | ddl_alter_table_set_access, |
128 | , |
129 | ddl_rename_schema, |
130 | ddl_rename_table, |
131 | ddl_rename_column, |
132 | ddl_maxops /* evaluated to the max value, should be always kept at the bottom */ |
133 | } ddl_statement; |
134 | |
135 | typedef enum operator_type { |
136 | op_basetable = 0, |
137 | op_table, |
138 | op_ddl, |
139 | op_project, /* includes order by */ |
140 | op_select, |
141 | op_join, |
142 | op_left, |
143 | op_right, |
144 | op_full, |
145 | op_semi, |
146 | op_anti, |
147 | op_union, |
148 | op_inter, |
149 | op_except, |
150 | op_groupby, |
151 | op_topn, |
152 | op_sample, |
153 | op_insert, /* insert(l=table, r insert expressions) */ |
154 | op_update, /* update(l=table, r update expressions) */ |
155 | op_delete, /* delete(l=table, r delete expression) */ |
156 | op_truncate /* truncate(l=table) */ |
157 | } operator_type; |
158 | |
159 | #define is_atom(et) \ |
160 | (et == e_atom) |
161 | /* a simple atom is a literal or on the query stack */ |
162 | #define is_simple_atom(e) \ |
163 | (is_atom(e->type) && !e->r && !e->f) |
164 | #define is_values(e) \ |
165 | ((e)->type == e_atom && (e)->f) |
166 | #define is_func(et) \ |
167 | (et == e_func) |
168 | #define is_aggr(et) \ |
169 | (et == e_aggr) |
170 | #define is_convert(et) \ |
171 | (et == e_convert) |
172 | #define is_map_op(et) \ |
173 | (et == e_func || et == e_convert) |
174 | #define is_compare(et) \ |
175 | (et == e_cmp) |
176 | #define is_column(et) \ |
177 | (et != e_cmp) |
178 | #define is_alias(et) \ |
179 | (et == e_column) |
180 | #define is_analytic(e) \ |
181 | (e->type == e_func && ((sql_subfunc*)e->f)->func->type == F_ANALYTIC) |
182 | #define is_base(op) \ |
183 | (op == op_basetable || op == op_table) |
184 | #define is_basetable(op) \ |
185 | (op == op_basetable) |
186 | #define is_ddl(op) \ |
187 | (op == op_ddl) |
188 | #define is_outerjoin(op) \ |
189 | (op == op_left || op == op_right || op == op_full) |
190 | #define is_left(op) \ |
191 | (op == op_left) |
192 | #define is_right(op) \ |
193 | (op == op_right) |
194 | #define is_full(op) \ |
195 | (op == op_full) |
196 | #define is_join(op) \ |
197 | (op == op_join || is_outerjoin(op)) |
198 | #define is_semi(op) \ |
199 | (op == op_semi || op == op_anti) |
200 | #define is_joinop(op) \ |
201 | (is_join(op) || is_semi(op)) |
202 | #define is_select(op) \ |
203 | (op == op_select) |
204 | #define is_set(op) \ |
205 | (op == op_union || op == op_inter || op == op_except) |
206 | #define is_union(op) \ |
207 | (op == op_union) |
208 | #define is_inter(rel) \ |
209 | (op == op_inter) |
210 | #define is_except(rel) \ |
211 | (op == op_except) |
212 | #define is_simple_project(op) \ |
213 | (op == op_project) |
214 | #define is_project(op) \ |
215 | (op == op_project || op == op_groupby || is_set(op)) |
216 | #define is_groupby(op) \ |
217 | (op == op_groupby) |
218 | #define is_sort(rel) \ |
219 | ((rel->op == op_project && rel->r) || rel->op == op_topn) |
220 | #define is_topn(op) \ |
221 | (op == op_topn) |
222 | #define is_modify(op) \ |
223 | (op == op_insert || op == op_update || op == op_delete || op == op_truncate) |
224 | #define is_sample(op) \ |
225 | (op == op_sample) |
226 | #define is_insert(op) \ |
227 | (op == op_insert) |
228 | #define is_update(op) \ |
229 | (op == op_update) |
230 | #define is_delete(op) \ |
231 | (op == op_delete) |
232 | #define is_truncate(op) \ |
233 | (op == op_truncate) |
234 | |
235 | /* NO NIL semantics of aggr operations */ |
236 | #define need_no_nil(e) \ |
237 | ((e->flag&NO_NIL)==NO_NIL) |
238 | #define set_no_nil(e) \ |
239 | e->flag |= NO_NIL |
240 | |
241 | /* ZERO on empty sets, needed for sum (of counts)). */ |
242 | #define zero_if_empty(e) \ |
243 | ((e->flag&ZERO_IF_EMPTY)==ZERO_IF_EMPTY) |
244 | #define set_zero_if_empty(e) \ |
245 | e->flag |= ZERO_IF_EMPTY |
246 | |
247 | /* does the expression (possibly) have nils */ |
248 | #define has_nil(e) \ |
249 | (((e)->flag&HAS_NO_NIL) == 0) |
250 | #define set_has_no_nil(e) \ |
251 | (e)->flag |= HAS_NO_NIL |
252 | #define set_has_nil(e) \ |
253 | (e)->flag &= (~HAS_NO_NIL) |
254 | |
255 | #define is_ascending(e) \ |
256 | (((e)->flag&ASCENDING)==ASCENDING) |
257 | #define nulls_last(e) \ |
258 | (((e)->flag&NULLS_LAST)==NULLS_LAST) |
259 | #define set_direction(e, dir) \ |
260 | (e)->flag |= ((dir&1)?ASCENDING:0) | ((dir&2)?NULLS_LAST:0) |
261 | |
262 | #define is_anti(e) \ |
263 | ((e)->anti) |
264 | #define set_anti(e) \ |
265 | (e)->anti = 1 |
266 | #define is_intern(e) \ |
267 | ((e)->intern) |
268 | #define set_intern(e) \ |
269 | (e)->intern = 1 |
270 | #define is_basecol(e) \ |
271 | ((e)->base) |
272 | #define set_basecol(e) \ |
273 | (e)->base = 1 |
274 | |
275 | #define has_label(e) \ |
276 | ((e)->alias.label > 0) |
277 | |
278 | /* used for expressions and relations */ |
279 | #define need_distinct(e) \ |
280 | ((e->flag&EXP_DISTINCT)==EXP_DISTINCT) |
281 | #define set_distinct(e) \ |
282 | e->flag |= EXP_DISTINCT |
283 | #define set_nodistinct(e) \ |
284 | e->flag &= (~EXP_DISTINCT) |
285 | |
286 | #define is_processed(rel) \ |
287 | ((rel)->processed) |
288 | #define set_processed(rel) \ |
289 | (rel)->processed = 1 |
290 | #define reset_processed(rel) \ |
291 | (rel)->processed = 0 |
292 | #define is_subquery(rel) \ |
293 | ((rel)->subquery) |
294 | #define set_subquery(rel) \ |
295 | (rel)->subquery = 1 |
296 | #define reset_subquery(rel) \ |
297 | (rel)->subquery = 0 |
298 | #define is_dependent(rel) \ |
299 | ((rel)->dependent) |
300 | #define set_dependent(rel) \ |
301 | (rel)->dependent = 1 |
302 | #define reset_dependent(rel) \ |
303 | (rel)->dependent = 0 |
304 | |
305 | #define is_freevar(e) \ |
306 | ((e)->freevar) |
307 | #define set_freevar(e,level) \ |
308 | (e)->freevar = level+1 |
309 | #define reset_freevar(e) \ |
310 | (e)->freevar = 0 |
311 | |
312 | #define rel_is_ref(rel) (((sql_rel*)rel)->ref.refcnt > 1) |
313 | |
314 | typedef struct relation { |
315 | sql_ref ref; |
316 | |
317 | operator_type op; |
318 | void *l; |
319 | void *r; |
320 | list *exps; |
321 | int nrcols; /* nr of cols */ |
322 | unsigned int |
323 | flag:8, /* EXP_DISTINCT */ |
324 | card:4, /* 0, 1 (row), 2 aggr, 3 */ |
325 | dependent:1, /* dependent join */ |
326 | single:1, /* single join operator */ |
327 | processed:1, /* fully processed or still in the process of building */ |
328 | subquery:1; /* is this part a subquery, this is needed for proper name binding */ |
329 | void *p; /* properties for the optimizer, distribution */ |
330 | } sql_rel; |
331 | |
332 | #endif /* SQL_RELATION_H */ |
333 | |