Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "rel_rel.h"
15 : #include "rel_basetable.h"
16 : #include "rel_exp.h"
17 : #include "rel_prop.h"
18 : #include "rel_unnest.h"
19 : #include "sql_semantic.h"
20 : #include "sql_mvc.h"
21 : #include "rel_rewriter.h"
22 :
23 : void
24 193 : rel_set_exps(sql_rel *rel, list *exps)
25 : {
26 193 : rel->exps = exps;
27 193 : rel->nrcols = list_length(exps);
28 193 : }
29 :
30 : /* some projections results are order dependend (row_number etc) */
31 : int
32 796321 : project_unsafe(sql_rel *rel, int allow_identity)
33 : {
34 796321 : sql_rel *sub = rel->l;
35 :
36 796321 : if (need_distinct(rel) || rel->r /* order by */)
37 : return 1;
38 723494 : if (list_empty(rel->exps))
39 : return 0;
40 : /* projects without sub and projects around ddl's cannot be changed */
41 723495 : if (!sub || sub->op == op_ddl)
42 : return 1;
43 4895732 : for(node *n = rel->exps->h; n; n = n->next) {
44 4533236 : sql_exp *e = n->data, *ne;
45 :
46 : /* aggr func in project ! */
47 4533236 : if (exp_unsafe(e, allow_identity))
48 : return 1;
49 4429383 : if ((ne = rel_find_exp(rel, e)) && ne != e)
50 : return 1; /* no self referencing */
51 : }
52 : return 0;
53 : }
54 :
55 : /* we don't name relations directly, but sometimes we need the relation
56 : name. So we look it up in the first expression
57 :
58 : we should clean up (remove) this function.
59 : */
60 : const char *
61 132437 : rel_name( sql_rel *r )
62 : {
63 136430 : if (is_basetable(r->op))
64 132310 : return rel_base_name(r);
65 8113 : if (!is_project(r->op) && !is_base(r->op) && r->l)
66 : return rel_name(r->l);
67 127 : if (r->exps && list_length(r->exps)) {
68 127 : sql_exp *e = r->exps->h->data;
69 127 : if (exp_relname(e))
70 127 : return exp_relname(e);
71 0 : if (e->type == e_column)
72 0 : return e->l;
73 : }
74 : return NULL;
75 : }
76 :
77 : sql_rel *
78 9294 : rel_distinct(sql_rel *l)
79 : {
80 9294 : set_distinct(l);
81 9294 : return l;
82 : }
83 :
84 : sql_rel *
85 434602 : rel_dup(sql_rel *r)
86 : {
87 434602 : sql_ref_inc(&r->ref);
88 434602 : return r;
89 : }
90 :
91 : static void
92 535186 : rel_destroy_(sql_rel *rel)
93 : {
94 535186 : if (!rel)
95 : return;
96 535186 : switch(rel->op){
97 : case op_basetable:
98 : break;
99 4938 : case op_table:
100 4938 : if ((IS_TABLE_PROD_FUNC(rel->flag) || rel->flag == TABLE_FROM_RELATION) && rel->l)
101 11 : rel_destroy(rel->l);
102 : break;
103 255009 : case op_join:
104 : case op_left:
105 : case op_right:
106 : case op_full:
107 : case op_semi:
108 : case op_anti:
109 : case op_union:
110 : case op_inter:
111 : case op_except:
112 : case op_insert:
113 : case op_update:
114 : case op_delete:
115 : case op_merge:
116 255009 : if (rel->l)
117 12289 : rel_destroy(rel->l);
118 255009 : if (rel->r)
119 12253 : rel_destroy(rel->r);
120 : break;
121 4258 : case op_munion:
122 : /* the rel->l might be in purpose NULL see rel_merge_table_rewrite_() */
123 4258 : if (rel->l)
124 12774 : for (node *n = ((list*)rel->l)->h; n; n = n->next)
125 8516 : rel_destroy(n->data);
126 : break;
127 260342 : case op_project:
128 : case op_groupby:
129 : case op_select:
130 : case op_topn:
131 : case op_sample:
132 : case op_truncate:
133 260342 : if (rel->l)
134 58691 : rel_destroy(rel->l);
135 : break;
136 0 : case op_ddl:
137 0 : if (rel->flag == ddl_output || rel->flag == ddl_create_seq || rel->flag == ddl_alter_seq || rel->flag == ddl_alter_table || rel->flag == ddl_create_table || rel->flag == ddl_create_view) {
138 0 : if (rel->l)
139 0 : rel_destroy(rel->l);
140 : } else if (rel->flag == ddl_list || rel->flag == ddl_exception) {
141 0 : if (rel->l)
142 0 : rel_destroy(rel->l);
143 0 : if (rel->r)
144 0 : rel_destroy(rel->r);
145 : }
146 : break;
147 : }
148 : }
149 :
150 : void
151 951613 : rel_destroy(sql_rel *rel)
152 : {
153 951613 : if (!rel)
154 : return;
155 951178 : if (sql_ref_dec(&rel->ref) > 0)
156 : return;
157 527745 : rel_destroy_(rel);
158 : }
159 :
160 : sql_rel*
161 3116584 : rel_create(allocator *sa)
162 : {
163 3116584 : sql_rel *r = SA_NEW(sa, sql_rel);
164 3116810 : if(!r)
165 : return NULL;
166 :
167 3116810 : *r = (sql_rel) {
168 : .card = CARD_ATOM,
169 : };
170 3116810 : sql_ref_init(&r->ref);
171 3116810 : return r;
172 : }
173 :
174 : sql_rel *
175 173 : rel_copy(mvc *sql, sql_rel *i, int deep)
176 : {
177 173 : sql_rel *rel;
178 :
179 173 : if (mvc_highwater(sql))
180 0 : return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
181 :
182 173 : rel = rel_create(sql->sa);
183 173 : if (!rel)
184 : return NULL;
185 :
186 173 : rel->op = i->op;
187 173 : switch(i->op) {
188 57 : case op_basetable:
189 57 : rel_base_copy(sql, i, rel);
190 57 : break;
191 0 : case op_table:
192 0 : if ((IS_TABLE_PROD_FUNC(i->flag) || i->flag == TABLE_FROM_RELATION) && i->l)
193 0 : rel->l = rel_copy(sql, i->l, deep);
194 0 : rel->r = i->r;
195 0 : break;
196 73 : case op_project:
197 : case op_groupby:
198 73 : if (i->l)
199 63 : rel->l = rel_copy(sql, i->l, deep);
200 73 : if (i->r) {
201 8 : if (!deep) {
202 0 : rel->r = list_dup(i->r, (fdup) NULL);
203 : } else {
204 8 : rel->r = exps_copy(sql, i->r);
205 : }
206 : }
207 : break;
208 0 : case op_munion:
209 0 : if (i->l)
210 0 : rel->l = list_dup(i->l, (fdup) rel_dup);
211 : break;
212 0 : case op_ddl:
213 0 : if (i->flag == ddl_output || i->flag == ddl_create_seq || i->flag == ddl_alter_seq || i->flag == ddl_alter_table || i->flag == ddl_create_table || i->flag == ddl_create_view) {
214 0 : if (i->l)
215 0 : rel->l = rel_copy(sql, i->l, deep);
216 0 : } else if (rel->flag == ddl_list || rel->flag == ddl_exception) {
217 0 : if (i->l)
218 0 : rel->l = rel_copy(sql, i->l, deep);
219 0 : if (i->r)
220 0 : rel->r = rel_copy(sql, i->r, deep);
221 : }
222 : break;
223 22 : case op_select:
224 : case op_topn:
225 : case op_sample:
226 : case op_truncate:
227 22 : if (i->l)
228 22 : rel->l = rel_copy(sql, i->l, deep);
229 : break;
230 21 : case op_join:
231 : case op_left:
232 : case op_right:
233 : case op_full:
234 : case op_semi:
235 : case op_anti:
236 :
237 : case op_union:
238 : case op_inter:
239 : case op_except:
240 :
241 : case op_insert:
242 : case op_update:
243 : case op_delete:
244 : case op_merge:
245 21 : if (i->l)
246 21 : rel->l = rel_copy(sql, i->l, deep);
247 21 : if (i->r)
248 21 : rel->r = rel_copy(sql, i->r, deep);
249 : break;
250 : }
251 :
252 173 : rel->card = i->card;
253 173 : rel->flag = i->flag;
254 173 : rel->nrcols = i->nrcols;
255 173 : rel->grouped = i->grouped;
256 173 : rel->used = i->used;
257 :
258 173 : if (is_processed(i))
259 110 : set_processed(rel);
260 173 : if (is_dependent(i))
261 0 : set_dependent(rel);
262 173 : if (is_outer(i))
263 10 : set_outer(rel);
264 173 : if (is_single(i))
265 4 : set_single(rel);
266 173 : if (need_distinct(i))
267 2 : set_distinct(rel);
268 :
269 173 : rel->p = prop_copy(sql->sa, i->p);
270 173 : rel->exps = (!i->exps)?NULL:deep?exps_copy(sql, i->exps):list_dup(i->exps, (fdup)NULL);
271 173 : rel->attr = (!i->attr)?NULL:deep?exps_copy(sql, i->attr):list_dup(i->attr, (fdup)NULL);
272 173 : return rel;
273 : }
274 :
275 : sql_rel *
276 4700 : rel_select_copy(allocator *sa, sql_rel *l, list *exps)
277 : {
278 4700 : sql_rel *rel = rel_create(sa);
279 4700 : if(!rel)
280 : return NULL;
281 :
282 4700 : rel->l = l;
283 4700 : rel->r = NULL;
284 4700 : rel->op = op_select;
285 4700 : rel->exps = exps?list_dup(exps, (fdup)NULL):NULL;
286 4700 : rel->card = CARD_ATOM; /* no relation */
287 4700 : if (l) {
288 4700 : rel->card = l->card;
289 4700 : rel->nrcols = l->nrcols;
290 : }
291 : return rel;
292 : }
293 :
294 : sql_exp *
295 7935982 : rel_bind_column( mvc *sql, sql_rel *rel, const char *cname, int f, int no_tname)
296 : {
297 7935982 : int ambiguous = 0, multi = 0;
298 :
299 7935982 : if (!rel)
300 : return NULL;
301 7935982 : if (mvc_highwater(sql))
302 0 : return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
303 :
304 7935982 : if ((is_project(rel->op) || is_base(rel->op))) {
305 4208018 : sql_exp *e = NULL;
306 :
307 4208018 : if (is_base(rel->op) && !rel->exps)
308 4030557 : return rel_base_bind_column(sql, rel, cname, no_tname);
309 177461 : if (!list_empty(rel->exps)) {
310 177427 : e = exps_bind_column(rel->exps, cname, &ambiguous, &multi, no_tname);
311 177427 : if (ambiguous || multi)
312 10 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname);
313 177417 : if (!e && is_groupby(rel->op) && rel->r) {
314 197 : e = exps_bind_alias(rel->r, NULL, cname);
315 197 : if (e) {
316 0 : e = exps_bind_column(rel->r, cname, &ambiguous, &multi, no_tname);
317 0 : if (ambiguous || multi)
318 0 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname);
319 : return e;
320 : }
321 : }
322 : }
323 19080 : if (!e && (is_sql_sel(f) || is_sql_having(f) || !f) && is_groupby(rel->op) && rel->r) {
324 197 : e = exps_bind_column(rel->r, cname, &ambiguous, &multi, no_tname);
325 197 : if (ambiguous || multi)
326 0 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname);
327 197 : if (e) {
328 1 : e = exp_ref(sql, e);
329 1 : e->card = rel->card;
330 1 : return e;
331 : }
332 : }
333 158371 : if (e)
334 158371 : return exp_alias_or_copy(sql, exp_relname(e), cname, rel, e);
335 : }
336 3747043 : if (is_simple_project(rel->op) && rel->l) {
337 6996 : if (!is_processed(rel))
338 0 : return rel_bind_column(sql, rel->l, cname, f, no_tname);
339 3740047 : } else if (is_set(rel->op)) {
340 22 : assert(is_processed(rel));
341 : return NULL;
342 : } else if (is_join(rel->op)) {
343 3224988 : sql_exp *e1 = rel_bind_column(sql, rel->l, cname, f, no_tname), *e2 = NULL, *res;
344 :
345 3224988 : if (e1 && (is_right(rel->op) || is_full(rel->op)))
346 6 : set_has_nil(e1);
347 1610902 : if (!e1 || !is_freevar(e1)) {
348 3224988 : e2 = rel_bind_column(sql, rel->r, cname, f, no_tname);
349 3224988 : if (e2 && (is_left(rel->op) || is_full(rel->op)))
350 56 : set_has_nil(e2);
351 3224988 : if (e1 && e2 && !is_dependent(rel))
352 23 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname);
353 : }
354 3224965 : if (!e1 && !e2 && !list_empty(rel->attr)) {
355 0 : e1 = exps_bind_column(rel->attr, cname, &ambiguous, &multi, no_tname);
356 0 : if (ambiguous || multi)
357 0 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", cname);
358 : }
359 3224965 : res = e1 ? e1 : e2;
360 1614086 : if (res)
361 1699326 : set_not_unique(res);
362 3224965 : return res;
363 : } else if (is_semi(rel->op) ||
364 : is_select(rel->op) ||
365 : is_topn(rel->op) ||
366 : is_sample(rel->op)) {
367 502976 : if (rel->l)
368 502976 : return rel_bind_column(sql, rel->l, cname, f, no_tname);
369 : }
370 : return NULL;
371 : }
372 :
373 : sql_exp *
374 4624626 : rel_bind_column2( mvc *sql, sql_rel *rel, const char *tname, const char *cname, int f)
375 : {
376 4624626 : int ambiguous = 0, multi = 0;
377 :
378 4624626 : if (!rel)
379 : return NULL;
380 4624159 : if (mvc_highwater(sql))
381 0 : return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
382 :
383 4624159 : if ((is_project(rel->op) || is_base(rel->op))) {
384 2182961 : sql_exp *e = NULL;
385 :
386 2182961 : if (is_basetable(rel->op) && !rel->exps)
387 1308114 : return rel_base_bind_column2(sql, rel, tname, cname);
388 : /* in case of orderby we should also lookup the column in group by list (and use existing references) */
389 874847 : if (!list_empty(rel->exps)) {
390 874768 : e = exps_bind_column2(rel->exps, tname, cname, &multi);
391 874768 : if (multi)
392 2 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s.%s' ambiguous",
393 : tname, cname);
394 874766 : if (!e && is_groupby(rel->op) && rel->r) {
395 135 : e = exps_bind_alias(rel->r, tname, cname);
396 135 : if (e) {
397 4 : const char *rname = exp_relname(e), *nname = exp_name(e);
398 4 : if (rname)
399 0 : e = exps_bind_column2(rel->exps, rname, nname, &multi);
400 : else
401 4 : e = exps_bind_column(rel->exps, nname, &ambiguous, &multi, 0);
402 4 : if (ambiguous || multi)
403 0 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s%s%s' ambiguous",
404 : rname ? rname : "", rname ? "." : "", nname);
405 4 : if (e)
406 : return e;
407 : }
408 : }
409 : }
410 314669 : if (!e && (is_sql_sel(f) || is_sql_having(f) || !f) && is_groupby(rel->op) && rel->r) {
411 150 : e = exps_bind_column2(rel->r, tname, cname, &multi);
412 150 : if (multi)
413 0 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s.%s' ambiguous",
414 : tname, cname);
415 150 : if (e) {
416 10 : e = exp_ref(sql, e);
417 10 : e->card = rel->card;
418 10 : return e;
419 : }
420 : }
421 560173 : if (e)
422 560173 : return exp_alias_or_copy(sql, tname, cname, rel, e);
423 : }
424 2755857 : if (is_simple_project(rel->op) && rel->l) {
425 278285 : if (!is_processed(rel))
426 0 : return rel_bind_column2(sql, rel->l, tname, cname, f);
427 2477572 : } else if (is_set(rel->op)) {
428 228 : assert(is_processed(rel));
429 : return NULL;
430 : } else if (is_join(rel->op)) {
431 1971386 : sql_exp *e = rel_bind_column2(sql, rel->l, tname, cname, f);
432 :
433 1971386 : if (e && (is_right(rel->op) || is_full(rel->op)))
434 243 : set_has_nil(e);
435 243 : if (!e) {
436 866086 : e = rel_bind_column2(sql, rel->r, tname, cname, f);
437 866086 : if (e && (is_left(rel->op) || is_full(rel->op)))
438 23597 : set_has_nil(e);
439 : }
440 415427 : if (!e && !list_empty(rel->attr)) {
441 14 : e = exps_bind_column2(rel->attr, tname, cname, &multi);
442 14 : if (multi)
443 0 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s.%s' ambiguous",
444 : tname, cname);
445 : }
446 391830 : if (e)
447 1579560 : set_not_unique(e);
448 1971386 : return e;
449 : } else if (is_semi(rel->op) ||
450 : is_select(rel->op) ||
451 : is_topn(rel->op) ||
452 : is_sample(rel->op)) {
453 469813 : if (rel->l)
454 469813 : return rel_bind_column2(sql, rel->l, tname, cname, f);
455 : }
456 : return NULL;
457 : }
458 :
459 : sql_exp *
460 1210041 : rel_bind_column3( mvc *sql, sql_rel *rel, const char *sname, const char *tname, const char *cname, int f)
461 : {
462 1210041 : if (!sname)
463 1210040 : return rel_bind_column2(sql, rel, tname, cname, f);
464 1 : if (is_basetable(rel->op) && !rel->exps) {
465 0 : return rel_base_bind_column3(sql, rel, sname, tname, cname);
466 1 : } else if (is_set(rel->op)) {
467 : return NULL;
468 1 : } else if (is_project(rel->op) && rel->l) {
469 1 : if (!is_processed(rel))
470 : return rel_bind_column3(sql, rel->l, sname, tname, cname, f);
471 : else
472 1 : return rel_bind_column2(sql, rel->l, tname, cname, f);
473 0 : } else if (is_join(rel->op)) {
474 0 : sql_exp *e = rel_bind_column3(sql, rel->l, sname, tname, cname, f);
475 :
476 0 : if (e && (is_right(rel->op) || is_full(rel->op)))
477 0 : set_has_nil(e);
478 0 : if (!e) {
479 0 : e = rel_bind_column3(sql, rel->r, sname, tname, cname, f);
480 0 : if (e && (is_left(rel->op) || is_full(rel->op)))
481 0 : set_has_nil(e);
482 : }
483 0 : if (!e)
484 0 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s.%s.%s' ambiguous", sname, tname, cname);
485 0 : if (e)
486 0 : set_not_unique(e);
487 0 : return e;
488 0 : } else if (is_semi(rel->op) ||
489 0 : is_select(rel->op) ||
490 0 : is_topn(rel->op) ||
491 : is_sample(rel->op)) {
492 0 : if (rel->l)
493 : return rel_bind_column3(sql, rel->l, sname, tname, cname, f);
494 : }
495 : return NULL;
496 : }
497 :
498 : sql_exp *
499 0 : rel_first_column(mvc *sql, sql_rel *r)
500 : {
501 0 : if (is_simple_project(r->op))
502 0 : return r->exps->h->data;
503 :
504 0 : list *exps = rel_projections(sql, r, NULL, 1, 1);
505 :
506 0 : if (!list_empty(exps))
507 0 : return exps->h->data;
508 :
509 : return NULL;
510 : }
511 :
512 : /* rel_inplace_* used to convert a rel node into another flavor */
513 : static void
514 46372 : rel_inplace_reset_props(sql_rel *rel)
515 : {
516 46372 : rel->flag = 0;
517 46372 : rel->attr = NULL;
518 46372 : reset_dependent(rel);
519 46372 : set_processed(rel);
520 : }
521 :
522 : sql_rel *
523 103 : rel_inplace_basetable(sql_rel *rel, sql_rel *bt)
524 : {
525 103 : assert(is_basetable(bt->op));
526 :
527 103 : rel_destroy_(rel);
528 103 : rel_inplace_reset_props(rel);
529 103 : rel->l = bt->l;
530 103 : rel->r = bt->r;
531 103 : rel->op = op_basetable;
532 103 : rel->exps = bt->exps;
533 103 : rel->card = CARD_MULTI;
534 103 : rel->nrcols = bt->nrcols;
535 103 : return rel;
536 : }
537 :
538 : sql_rel *
539 2344 : rel_inplace_setop(mvc *sql, sql_rel *rel, sql_rel *l, sql_rel *r, operator_type setop, list *exps)
540 : {
541 2344 : rel_destroy_(rel);
542 2344 : rel_inplace_reset_props(rel);
543 2344 : rel->l = l;
544 2344 : rel->r = r;
545 2344 : rel->op = setop;
546 2344 : rel->card = CARD_MULTI;
547 2344 : rel_setop_set_exps(sql, rel, exps, false);
548 2344 : return rel;
549 : }
550 :
551 : sql_rel *
552 3938 : rel_inplace_setop_n_ary(mvc *sql, sql_rel *rel, list *rl, operator_type setop, list *exps)
553 : {
554 : // TODO: for now we only deal with munion
555 3938 : assert(setop == op_munion);
556 3938 : rel_destroy_(rel);
557 3938 : rel_inplace_reset_props(rel);
558 : /* rl should be a list of relations */
559 3938 : rel->l = rl;
560 3938 : rel->op = setop;
561 3938 : rel->card = CARD_MULTI;
562 3938 : rel_setop_n_ary_set_exps(sql, rel, exps, false);
563 3938 : return rel;
564 : }
565 :
566 : sql_rel *
567 38973 : rel_inplace_project(allocator *sa, sql_rel *rel, sql_rel *l, list *e)
568 : {
569 38973 : if (!l) {
570 38930 : l = rel_create(sa);
571 38930 : if(!l)
572 : return NULL;
573 :
574 38930 : *l = *rel;
575 38930 : l->ref.refcnt = 1;
576 : } else {
577 43 : rel_destroy_(rel);
578 : }
579 38973 : rel_inplace_reset_props(rel);
580 38973 : rel->l = l;
581 38973 : rel->r = NULL;
582 38973 : rel->op = op_project;
583 38973 : rel->exps = e;
584 38973 : rel->card = CARD_MULTI;
585 38973 : if (l) {
586 38973 : rel->nrcols = l->nrcols;
587 38973 : assert (exps_card(rel->exps) <= rel->card);
588 : }
589 : return rel;
590 : }
591 :
592 : sql_rel *
593 724 : rel_inplace_select(sql_rel *rel, sql_rel *l, list *exps)
594 : {
595 724 : rel_destroy_(rel);
596 724 : rel_inplace_reset_props(rel);
597 724 : rel->l = l;
598 724 : rel->r = NULL;
599 724 : rel->op = op_select;
600 724 : rel->exps = exps;
601 724 : rel->card = CARD_ATOM; /* no relation */
602 724 : if (l) {
603 724 : rel->card = l->card;
604 724 : rel->nrcols = l->nrcols;
605 724 : if (is_single(l))
606 0 : set_single(rel);
607 : }
608 724 : return rel;
609 : }
610 :
611 : sql_rel *
612 290 : rel_inplace_groupby(sql_rel *rel, sql_rel *l, list *groupbyexps, list *exps )
613 : {
614 290 : rel_destroy_(rel);
615 290 : rel_inplace_reset_props(rel);
616 290 : rel->card = CARD_ATOM;
617 290 : if (groupbyexps)
618 217 : rel->card = CARD_AGGR;
619 290 : rel->l = l;
620 290 : rel->r = groupbyexps;
621 290 : rel->exps = exps;
622 290 : rel->nrcols = l->nrcols;
623 290 : rel->op = op_groupby;
624 290 : return rel;
625 : }
626 :
627 : sql_rel *
628 0 : rel_inplace_munion(sql_rel *rel, list *rels)
629 : {
630 0 : rel_destroy_(rel);
631 0 : rel_inplace_reset_props(rel);
632 : // TODO: what is the semantics of cardinality? is that right?
633 0 : rel->card = CARD_MULTI;
634 0 : rel->nrcols = 0;
635 0 : if (rels)
636 0 : rel->l = rels;
637 0 : if (rels) {
638 0 : for (node* n = rels->h; n; n = n->next) {
639 0 : sql_rel *r = n->data;
640 : // TODO: could we overflow the nrcols this way?
641 0 : rel->nrcols += r->nrcols;
642 : }
643 : }
644 0 : rel->r = NULL;
645 0 : rel->exps = NULL;
646 0 : rel->op = op_munion;
647 0 : return rel;
648 : }
649 :
650 : /* this function is to be used with the above rel_inplace_* functions */
651 : sql_rel *
652 694 : rel_dup_copy(allocator *sa, sql_rel *rel)
653 : {
654 694 : sql_rel *nrel = rel_create(sa);
655 :
656 694 : if (!nrel)
657 : return NULL;
658 694 : *nrel = *rel;
659 694 : nrel->ref.refcnt = 1;
660 694 : switch(nrel->op){
661 : case op_basetable:
662 : case op_ddl:
663 : break;
664 0 : case op_table:
665 0 : if ((IS_TABLE_PROD_FUNC(nrel->flag) || nrel->flag == TABLE_FROM_RELATION) && nrel->l)
666 0 : rel_dup(nrel->l);
667 : break;
668 689 : case op_join:
669 : case op_left:
670 : case op_right:
671 : case op_full:
672 : case op_semi:
673 : case op_anti:
674 : case op_union:
675 : case op_inter:
676 : case op_except:
677 : case op_insert:
678 : case op_update:
679 : case op_delete:
680 : case op_merge:
681 689 : if (nrel->l)
682 689 : rel_dup(nrel->l);
683 689 : if (nrel->r)
684 689 : rel_dup(nrel->r);
685 : break;
686 5 : case op_project:
687 : case op_groupby:
688 : case op_select:
689 : case op_topn:
690 : case op_sample:
691 : case op_truncate:
692 5 : if (nrel->l)
693 5 : rel_dup(nrel->l);
694 : break;
695 0 : case op_munion:
696 : // TODO: is that even right?
697 0 : if (nrel->l)
698 0 : nrel->l = list_dup(nrel->l, (fdup) rel_dup);
699 : break;
700 : }
701 : return nrel;
702 : }
703 :
704 : sql_rel *
705 6523 : rel_setop(allocator *sa, sql_rel *l, sql_rel *r, operator_type setop)
706 : {
707 6523 : sql_rel *rel = rel_create(sa);
708 6523 : if(!rel)
709 : return NULL;
710 6523 : rel->l = l;
711 6523 : rel->r = r;
712 6523 : rel->op = setop;
713 6523 : rel->exps = NULL;
714 6523 : rel->card = CARD_MULTI;
715 6523 : assert(l->nrcols == r->nrcols);
716 6523 : rel->nrcols = l->nrcols;
717 6523 : return rel;
718 : }
719 :
720 : sql_rel *
721 2419 : rel_setop_check_types(mvc *sql, sql_rel *l, sql_rel *r, list *ls, list *rs, operator_type op)
722 : {
723 2419 : list *nls = new_exp_list(sql->sa);
724 2419 : list *nrs = new_exp_list(sql->sa);
725 2419 : node *n, *m;
726 :
727 2419 : if(!nls || !nrs)
728 : return NULL;
729 :
730 4952 : for (n = ls->h, m = rs->h; n && m; n = n->next, m = m->next) {
731 2536 : sql_exp *le = n->data;
732 2536 : sql_exp *re = m->data;
733 :
734 2536 : if (rel_convert_types(sql, l, r, &le, &re, 1, type_set) < 0)
735 3 : return NULL;
736 2533 : append(nls, le);
737 2533 : append(nrs, re);
738 : }
739 2416 : l = rel_project(sql->sa, l, nls);
740 2416 : r = rel_project(sql->sa, r, nrs);
741 2416 : set_processed(l);
742 2416 : set_processed(r);
743 2416 : return rel_setop(sql->sa, l, r, op);
744 : }
745 :
746 : void
747 7321 : rel_setop_set_exps(mvc *sql, sql_rel *rel, list *exps, bool keep_props)
748 : {
749 7321 : sql_rel *l = rel->l, *r = rel->r;
750 7321 : list *lexps = l->exps, *rexps = r->exps;
751 :
752 7321 : if (!is_project(l->op))
753 1885 : lexps = rel_projections(sql, l, NULL, 0, 1);
754 7321 : if (!is_project(r->op))
755 1941 : rexps = rel_projections(sql, r, NULL, 0, 1);
756 :
757 7321 : assert(is_set(rel->op) /*&& list_length(lexps) == list_length(rexps) && list_length(exps) == list_length(lexps)*/);
758 :
759 29349 : for (node *n = exps->h, *m = lexps->h, *o = rexps->h ; m && n && o ; n = n->next, m = m->next,o = o->next) {
760 22028 : sql_exp *e = n->data, *f = m->data, *g = o->data;
761 :
762 22028 : if (is_union(rel->op)) { /* propagate set_has_no_nil only if it's applicable to both sides of the union*/
763 19290 : if (has_nil(f) || has_nil(g))
764 16448 : set_has_nil(e);
765 : else
766 2842 : set_has_no_nil(e);
767 19290 : if (!keep_props) {
768 18993 : e->p = NULL; /* remove all the properties on unions on the general case */
769 18993 : set_not_unique(e);
770 : }
771 : }
772 22028 : e->card = CARD_MULTI; /* multi cardinality */
773 : }
774 7321 : rel->nrcols = l->nrcols;
775 7321 : rel->exps = exps;
776 7321 : }
777 :
778 : sql_rel *
779 56013 : rel_setop_n_ary(allocator *sa, list *rels, operator_type setop)
780 : {
781 : // TODO: for now we support only n-ary union
782 56013 : assert(setop == op_munion);
783 :
784 56013 : if (!rels)
785 : return NULL;
786 :
787 56013 : assert(list_length(rels) >= 2);
788 56013 : sql_rel *rel = rel_create(sa);
789 56013 : if(!rel)
790 : return NULL;
791 :
792 56013 : rel->l = rels;
793 56013 : rel->r = NULL;
794 56013 : rel->op = setop;
795 56013 : rel->exps = NULL;
796 56013 : rel->card = CARD_MULTI;
797 : // TODO: properly introduce the assertion over rels elements
798 : /*assert(l->nrcols == r->nrcols);*/
799 56013 : rel->nrcols = ((sql_rel*)rels->h->data)->nrcols;
800 56013 : return rel;
801 : }
802 :
803 : sql_rel *
804 55770 : rel_setop_n_ary_check_types(mvc *sql, sql_rel *l, sql_rel *r, list *ls, list *rs, operator_type op)
805 : {
806 : // TODO: for now we support only 2 relation in the list at ->l of
807 : // the n-ary operator. In the future this function should be variadic (?)
808 : // TODO: for now we support only n-ary union
809 55770 : assert(op == op_munion);
810 :
811 : /* NOTE: this is copied logic from rel_setop_check_types. A DRY-er approach
812 : * would be to call rel_setop_check_types which will return a binary
813 : * setop from which we could extract ->l and ->r and add them in a list
814 : * for the op_munion. This is kind of ugly though...
815 : */
816 55770 : list *nls = new_exp_list(sql->sa);
817 55770 : list *nrs = new_exp_list(sql->sa);
818 55770 : node *n, *m;
819 55770 : list* rels;
820 :
821 55770 : if(!nls || !nrs)
822 : return NULL;
823 :
824 440513 : for (n = ls->h, m = rs->h; n && m; n = n->next, m = m->next) {
825 384747 : sql_exp *le = n->data;
826 384747 : sql_exp *re = m->data;
827 :
828 384747 : if (rel_convert_types(sql, l, r, &le, &re, 1, type_set) < 0)
829 4 : return NULL;
830 384743 : append(nls, le);
831 384743 : append(nrs, re);
832 : }
833 55766 : l = rel_project(sql->sa, l, nls);
834 55766 : r = rel_project(sql->sa, r, nrs);
835 55766 : set_processed(l);
836 55766 : set_processed(r);
837 :
838 : /* create a list with only 2 sql_rel entries for the n-ary set op */
839 55766 : rels = sa_list(sql->sa);
840 55766 : append(rels, l);
841 55766 : append(rels, r);
842 :
843 55766 : return rel_setop_n_ary(sql->sa, rels, op);
844 : }
845 :
846 : void
847 59920 : rel_setop_n_ary_set_exps(mvc *sql, sql_rel *rel, list *exps, bool keep_props)
848 : {
849 59920 : list *rexps;
850 59920 : sql_rel *r;
851 :
852 : /* set the exps properties first */
853 479380 : for (node *m = exps->h; m; m = m->next) {
854 : /* the nil/no_nil property will be set in the next loop where
855 : * we go through the exps of every rel of the rels. For now no_nil
856 : */
857 419460 : sql_exp *e = (sql_exp*)m->data;
858 419460 : set_has_no_nil(e);
859 : /* remove all the properties on unions on the general case */
860 419460 : if (!keep_props) {
861 419460 : e->p = NULL;
862 419460 : set_not_unique(e);
863 : }
864 : }
865 :
866 : /* for every relation in the list of relations */
867 179760 : for (node *n = ((list*)rel->l)->h; n; n = n->next) {
868 119840 : r = n->data;
869 119840 : rexps = r->exps;
870 :
871 119840 : if (!is_project(r->op))
872 7816 : rexps = rel_projections(sql, r, NULL, 0, 1);
873 :
874 : /* go through the relation's exps */
875 958760 : for (node *m = exps->h, *o = rexps->h; m && o; m = m->next, o = o->next) {
876 838920 : sql_exp *e = m->data, *f = o->data;
877 : /* for multi-union if any operand has nil then set the nil prop for the op exp */
878 838920 : if (is_munion(rel->op) && has_nil(f))
879 479909 : set_has_nil(e);
880 838920 : e->card = CARD_MULTI;
881 : }
882 : }
883 :
884 59920 : rel->exps = exps;
885 : // TODO: probably setting nrcols is redundant as we have allready done
886 : // that when we create the setop_n_ary. check rel_setop_n_ary()
887 59920 : rel->nrcols = ((sql_rel*)((list*)rel->l)->h->data)->nrcols;
888 59920 : }
889 :
890 : sql_rel *
891 473994 : rel_crossproduct(allocator *sa, sql_rel *l, sql_rel *r, operator_type join)
892 : {
893 473994 : sql_rel *rel = rel_create(sa);
894 473994 : if(!rel)
895 : return NULL;
896 :
897 473994 : rel->l = l;
898 473994 : rel->r = r;
899 473994 : rel->op = join;
900 473994 : rel->exps = NULL;
901 473994 : rel->card = CARD_MULTI;
902 473994 : rel->nrcols = l->nrcols + r->nrcols;
903 473994 : return rel;
904 : }
905 :
906 : sql_exp *
907 0 : rel_is_constant(sql_rel **R, sql_exp *e)
908 : {
909 0 : sql_rel *rel = *R;
910 :
911 0 : if (rel && rel->op == op_project && list_length(rel->exps) == 1 &&
912 0 : !rel->l && !rel->r && !rel_is_ref(rel) && e->type == e_column) {
913 0 : sql_exp *ne = rel_find_exp(rel, e);
914 0 : if (ne) {
915 0 : rel_destroy(rel);
916 0 : *R = NULL;
917 0 : return ne;
918 : }
919 : }
920 : return e;
921 : }
922 :
923 : sql_rel *
924 16907 : rel_topn(allocator *sa, sql_rel *l, list *exps )
925 : {
926 16907 : sql_rel *rel = rel_create(sa);
927 16912 : if(!rel)
928 : return NULL;
929 :
930 16912 : rel->l = l;
931 16912 : rel->r = NULL;
932 16912 : rel->op = op_topn;
933 16912 : rel->exps = exps;
934 16912 : rel->card = l->card;
935 16912 : rel->nrcols = l->nrcols;
936 16912 : return rel;
937 : }
938 :
939 : sql_rel *
940 23 : rel_sample(allocator *sa, sql_rel *l, list *exps )
941 : {
942 23 : sql_rel *rel = rel_create(sa);
943 23 : if(!rel)
944 : return NULL;
945 :
946 23 : rel->l = l;
947 23 : rel->r = NULL;
948 23 : rel->op = op_sample;
949 23 : rel->exps = exps;
950 23 : rel->card = l->card;
951 23 : rel->nrcols = l->nrcols;
952 23 : return rel;
953 : }
954 :
955 : sql_rel *
956 14057 : rel_label( mvc *sql, sql_rel *r, int all)
957 : {
958 14057 : int nr = ++sql->label;
959 14057 : char tname[16], *tnme;
960 14057 : char cname[16], *cnme = NULL;
961 :
962 14057 : tnme = sa_strdup(sql->sa, number2name(tname, sizeof(tname), nr));
963 14061 : if (!is_simple_project(r->op))
964 597 : r = rel_project(sql->sa, r, rel_projections(sql, r, NULL, 1, 1));
965 14061 : if (!list_empty(r->exps)) {
966 14060 : list_hash_clear(r->exps);
967 55506 : for (node *ne = r->exps->h; ne; ne = ne->next) {
968 41445 : sql_exp *e = ne->data;
969 :
970 41445 : if (!is_freevar(e)) {
971 41437 : if (all) {
972 41437 : nr = ++sql->label;
973 41437 : cnme = sa_strdup(sql->sa, number2name(cname, sizeof(cname), nr));
974 : }
975 41444 : exp_setname(sql->sa, e, tnme, cnme );
976 : }
977 : }
978 : }
979 : /* op_projects can have a order by list */
980 14062 : if (!list_empty(r->r)) {
981 0 : for (node *ne = ((list*)r->r)->h; ne; ne = ne->next) {
982 0 : if (all) {
983 0 : nr = ++sql->label;
984 0 : cnme = sa_strdup(sql->sa, number2name(cname, sizeof(cname), nr));
985 : }
986 0 : exp_setname(sql->sa, ne->data, tnme, cnme );
987 : }
988 : }
989 14061 : return r;
990 : }
991 :
992 : sql_exp *
993 30087 : rel_project_add_exp( mvc *sql, sql_rel *rel, sql_exp *e)
994 : {
995 30087 : assert(is_project(rel->op));
996 :
997 30087 : if (!exp_name(e))
998 90 : exp_label(sql->sa, e, ++sql->label);
999 30087 : if (is_simple_project(rel->op)) {
1000 30087 : sql_rel *l = rel->l;
1001 30087 : if (!rel->exps)
1002 19 : rel->exps = new_exp_list(sql->sa);
1003 30087 : if (l && is_groupby(l->op) && exp_card(e) <= CARD_ATOM && list_empty(l->exps))
1004 0 : e = rel_project_add_exp(sql, l, e);
1005 30087 : if (e->card > rel->card)
1006 0 : rel->card = e->card;
1007 30087 : append(rel->exps, e);
1008 30087 : rel->nrcols++;
1009 0 : } else if (is_groupby(rel->op)) {
1010 0 : return rel_groupby_add_aggr(sql, rel, e);
1011 : }
1012 30087 : e = exp_ref(sql, e);
1013 30087 : return e;
1014 : }
1015 :
1016 : sql_rel *
1017 278003 : rel_select_add_exp(allocator *sa, sql_rel *l, sql_exp *e)
1018 : {
1019 278003 : if ((l->op != op_select && !is_outerjoin(l->op)) || rel_is_ref(l))
1020 6851 : return rel_select(sa, l, e);
1021 :
1022 : /* allow during AST->relational for bool expresssions as well
1023 : if (e->type != e_cmp && e->card > CARD_ATOM) {
1024 : sql_exp *t = exp_atom_bool(sa, 1);
1025 : e = exp_compare(sa, e, t, cmp_equal);
1026 : }
1027 : */
1028 271152 : if (!l->exps)
1029 4581 : l->exps = new_exp_list(sa);
1030 271152 : append(l->exps, e);
1031 271152 : return l;
1032 : }
1033 :
1034 : void
1035 448779 : rel_join_add_exp( allocator *sa, sql_rel *rel, sql_exp *e)
1036 : {
1037 448779 : assert(is_join(rel->op) || is_semi(rel->op) || is_select(rel->op));
1038 :
1039 448779 : if (!rel->exps)
1040 404480 : rel->exps = new_exp_list(sa);
1041 448779 : append(rel->exps, e);
1042 448779 : if (e->card > rel->card)
1043 0 : rel->card = e->card;
1044 448779 : }
1045 :
1046 : sql_exp *
1047 76444 : rel_groupby_add_aggr(mvc *sql, sql_rel *rel, sql_exp *e)
1048 : {
1049 76444 : sql_exp *m = NULL, *ne;
1050 :
1051 76444 : if (list_empty(rel->r))
1052 26492 : rel->card = e->card = CARD_ATOM;
1053 :
1054 76444 : if ((m=exps_any_match(rel->exps, e)) == NULL) {
1055 44704 : if (!exp_name(e))
1056 44666 : exp_label(sql->sa, e, ++sql->label);
1057 44704 : append(rel->exps, e);
1058 44704 : rel->nrcols++;
1059 44704 : m = e;
1060 : }
1061 76444 : ne = exp_ref(sql, m);
1062 76444 : return ne;
1063 : }
1064 :
1065 : sql_rel *
1066 256697 : rel_select(allocator *sa, sql_rel *l, sql_exp *e)
1067 : {
1068 256697 : sql_rel *rel;
1069 :
1070 256697 : if (l && is_outerjoin(l->op) && !is_processed(l)) {
1071 188 : if (e) {
1072 172 : if (!l->exps)
1073 157 : l->exps = new_exp_list(sa);
1074 172 : append(l->exps, e);
1075 : }
1076 188 : return l;
1077 : }
1078 :
1079 256509 : if (l && is_select(l->op) && !rel_is_ref(l)) { /* refine old select */
1080 17576 : if (e)
1081 9706 : rel_select_add_exp(sa, l, e);
1082 17576 : return l;
1083 : }
1084 238933 : rel = rel_create(sa);
1085 238933 : if(!rel)
1086 : return NULL;
1087 :
1088 238933 : rel->l = l;
1089 238933 : rel->r = NULL;
1090 238933 : rel->op = op_select;
1091 238933 : rel->exps = new_exp_list(sa);
1092 238933 : if (e)
1093 186213 : rel_select_add_exp(sa, rel, e);
1094 238933 : rel->card = CARD_ATOM; /* no relation */
1095 238933 : if (l) {
1096 238933 : rel->card = l->card;
1097 238933 : rel->nrcols = l->nrcols;
1098 238933 : if (is_single(l))
1099 1487 : set_single(rel);
1100 : }
1101 : return rel;
1102 : }
1103 :
1104 : sql_rel *
1105 36379 : rel_groupby(mvc *sql, sql_rel *l, list *groupbyexps )
1106 : {
1107 36379 : sql_rel *rel = rel_create(sql->sa);
1108 36379 : list *aggrs = new_exp_list(sql->sa);
1109 36379 : node *en;
1110 36379 : if(!rel || !aggrs) {
1111 0 : rel_destroy(rel);
1112 0 : return NULL;
1113 : }
1114 :
1115 36379 : rel->card = CARD_ATOM;
1116 : /* reduce duplicates in groupbyexps */
1117 36379 : if (groupbyexps && list_length(groupbyexps) > 1) {
1118 4969 : list *gexps = sa_list(sql->sa);
1119 :
1120 24204 : for (en = groupbyexps->h; en; en = en->next) {
1121 19235 : sql_exp *e = en->data, *ne = exps_find_exp(gexps, e);
1122 :
1123 19235 : if (!ne) {
1124 19132 : list_append(gexps, e);
1125 : } else {
1126 103 : const char *ername = exp_relname(e), *nername = exp_relname(ne), *ename = exp_name(e), *nename = exp_name(ne);
1127 103 : if ((ername && !nername) || (!ername && nername) ||
1128 97 : (ername && nername && strcmp(ername,nername) != 0) || strcmp(ename,nename) != 0)
1129 10 : list_append(gexps, e);
1130 : }
1131 : }
1132 : groupbyexps = gexps;
1133 : }
1134 :
1135 9994 : if (groupbyexps) {
1136 9994 : rel->card = CARD_AGGR;
1137 34024 : for (en = groupbyexps->h; en; en = en->next) {
1138 24030 : sql_exp *e = en->data, *ne;
1139 :
1140 : /* after the group by the cardinality reduces */
1141 24030 : e->card = MIN(e->card, rel->card); /* if the column is an atom, the cardinality should not change */
1142 24030 : ne = exp_ref(sql, e);
1143 24030 : ne = exp_propagate(sql->sa, ne, e);
1144 24030 : append(aggrs, ne);
1145 : }
1146 : }
1147 36379 : rel->l = l;
1148 36379 : rel->r = groupbyexps;
1149 36379 : rel->exps = aggrs;
1150 36379 : rel->nrcols = aggrs?list_length(aggrs):0;
1151 36379 : rel->op = op_groupby;
1152 36379 : rel->grouped = 1;
1153 36379 : return rel;
1154 : }
1155 :
1156 : sql_rel *
1157 901301 : rel_project(allocator *sa, sql_rel *l, list *e)
1158 : {
1159 901301 : sql_rel *rel = rel_create(sa);
1160 901203 : if(!rel)
1161 : return NULL;
1162 :
1163 901203 : rel->l = l;
1164 901203 : rel->r = NULL;
1165 901203 : rel->op = op_project;
1166 901203 : rel->exps = e;
1167 901203 : rel->card = exps_card(e);
1168 901620 : if (l) {
1169 710301 : rel->card = l->card;
1170 710301 : if (e)
1171 706037 : rel->nrcols = list_length(e);
1172 : else
1173 4264 : rel->nrcols = l->nrcols;
1174 710308 : rel->single = is_single(l);
1175 : }
1176 901627 : if (e && !list_empty(e)) {
1177 896635 : set_processed(rel);
1178 896635 : rel->nrcols = list_length(e);
1179 : }
1180 : return rel;
1181 : }
1182 :
1183 : sql_rel *
1184 72254 : rel_project_exp(mvc *sql, sql_exp *e)
1185 : {
1186 72254 : if (!exp_name(e))
1187 72308 : exp_label(sql->sa, e, ++sql->label);
1188 72251 : return rel_project(sql->sa, NULL, list_append(sa_list(sql->sa), e));
1189 : }
1190 :
1191 : sql_rel *
1192 111563 : rel_list(allocator *sa, sql_rel *l, sql_rel *r)
1193 : {
1194 111563 : sql_rel *rel = rel_create(sa);
1195 111563 : if (!rel)
1196 : return NULL;
1197 111563 : if (!l)
1198 : return r;
1199 556 : rel->l = l;
1200 556 : rel->r = r;
1201 556 : rel->op = op_ddl;
1202 556 : rel->flag = ddl_list;
1203 556 : return rel;
1204 : }
1205 :
1206 : sql_rel *
1207 157 : rel_exception(allocator *sa, sql_rel *l, sql_rel *r, list *exps)
1208 : {
1209 157 : sql_rel *rel = rel_create(sa);
1210 157 : if(!rel)
1211 : return NULL;
1212 157 : rel->r = r;
1213 157 : rel->exps = exps;
1214 157 : rel->op = op_ddl;
1215 157 : rel->flag = ddl_exception;
1216 157 : if (l)
1217 157 : return rel_list(sa, rel, l); /* keep base relation on the right ! */
1218 : return rel;
1219 : }
1220 :
1221 : sql_rel *
1222 300 : rel_relational_func(allocator *sa, sql_rel *l, list *exps)
1223 : {
1224 300 : sql_rel *rel = rel_create(sa);
1225 300 : if(!rel)
1226 : return NULL;
1227 :
1228 300 : rel->flag = TABLE_PROD_FUNC;
1229 300 : rel->l = l;
1230 300 : rel->op = op_table;
1231 300 : rel->exps = exps;
1232 300 : rel->card = CARD_MULTI;
1233 300 : rel->nrcols = list_length(exps);
1234 300 : return rel;
1235 : }
1236 :
1237 : sql_rel *
1238 16351 : rel_table_func(allocator *sa, sql_rel *l, sql_exp *f, list *exps, int kind)
1239 : {
1240 16351 : sql_rel *rel = rel_create(sa);
1241 16351 : if(!rel)
1242 : return NULL;
1243 :
1244 16351 : assert(kind > 0);
1245 16351 : rel->flag = kind;
1246 16351 : rel->l = l; /* relation before call */
1247 16351 : rel->r = f; /* expression (table func call) */
1248 16351 : rel->op = op_table;
1249 16351 : rel->exps = exps;
1250 16351 : rel->card = CARD_MULTI;
1251 16351 : rel->nrcols = list_length(exps);
1252 16351 : return rel;
1253 : }
1254 :
1255 : static void
1256 260932 : exps_reset_props(list *exps, bool setnil)
1257 : {
1258 260932 : if (!list_empty(exps)) {
1259 2686767 : for (node *m = exps->h; m; m = m->next) {
1260 2428724 : sql_exp *e = m->data;
1261 :
1262 2428724 : if (setnil)
1263 194153 : set_has_nil(e);
1264 2428724 : set_not_unique(e);
1265 : }
1266 : }
1267 260932 : }
1268 :
1269 : /* Return a list with all the projection expressions, that optionaly
1270 : * refer to the tname relation, anywhere in the relational tree
1271 : */
1272 : list *
1273 953263 : _rel_projections(mvc *sql, sql_rel *rel, const char *tname, int settname, int intern, int basecol /* basecol only */ )
1274 : {
1275 1021622 : list *lexps, *rexps = NULL, *exps = NULL, *rels;
1276 1021622 : sql_rel *r = NULL;
1277 :
1278 1021622 : if (mvc_highwater(sql))
1279 4 : return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
1280 :
1281 1021621 : if (!rel)
1282 0 : return new_exp_list(sql->sa);
1283 :
1284 1021621 : if (!tname && is_basetable(rel->op) && !is_processed(rel))
1285 258886 : rel_base_use_all( sql, rel);
1286 :
1287 1021619 : switch(rel->op) {
1288 130466 : case op_join:
1289 : case op_left:
1290 : case op_right:
1291 : case op_full:
1292 130466 : lexps = _rel_projections(sql, rel->l, tname, settname, intern, basecol);
1293 130466 : exps_reset_props(lexps, is_right(rel->op) || is_full(rel->op));
1294 130466 : if (!rel->attr)
1295 127594 : rexps = _rel_projections(sql, rel->r, tname, settname, intern, basecol);
1296 130466 : exps_reset_props(rexps, is_left(rel->op) || is_full(rel->op));
1297 130466 : if (rexps)
1298 127594 : lexps = list_merge(lexps, rexps, (fdup)NULL);
1299 130466 : if (rel->attr)
1300 2872 : append(lexps, exp_ref(sql, rel->attr->h->data));
1301 : return lexps;
1302 6579 : case op_groupby:
1303 6579 : if (list_empty(rel->exps) && rel->r) {
1304 1 : list *r = rel->r;
1305 1 : int label = 0;
1306 :
1307 1 : if (!settname)
1308 0 : label = ++sql->label;
1309 1 : exps = new_exp_list(sql->sa);
1310 2 : for (node *en = r->h; en; en = en->next) {
1311 1 : sql_exp *e = en->data;
1312 :
1313 1 : if (basecol && !is_basecol(e))
1314 0 : continue;
1315 1 : if (intern || !is_intern(e)) {
1316 1 : e = exp_alias_or_copy(sql, tname, exp_name(e), rel, e);
1317 1 : if (!settname) /* noname use alias */
1318 0 : exp_setrelname(sql->sa, e, label);
1319 1 : append(exps, e);
1320 : }
1321 : }
1322 : return exps;
1323 : }
1324 : /* fall through */
1325 : case op_project:
1326 : case op_basetable:
1327 : case op_table:
1328 :
1329 : case op_union:
1330 : case op_except:
1331 : case op_inter:
1332 : case op_munion:
1333 822793 : if (is_basetable(rel->op) && !rel->exps)
1334 98147 : return rel_base_projection(sql, rel, intern);
1335 724646 : if (rel->exps) {
1336 666464 : int label = 0;
1337 :
1338 666464 : if (!settname)
1339 186169 : label = ++sql->label;
1340 666464 : exps = new_exp_list(sql->sa);
1341 5401931 : for (node *en = rel->exps->h; en; en = en->next) {
1342 4735463 : sql_exp *e = en->data;
1343 :
1344 4735463 : if (basecol && !is_basecol(e))
1345 40 : continue;
1346 4735423 : if (intern || !is_intern(e)) {
1347 4722225 : e = exp_alias_or_copy(sql, tname, exp_name(e), rel, e);
1348 4722225 : if (!settname) /* noname use alias */
1349 1236214 : exp_setrelname(sql->sa, e, label);
1350 4722225 : append(exps, e);
1351 : }
1352 : }
1353 : return exps;
1354 : }
1355 : /* differentiate for the munion set op (for now) */
1356 58182 : if (is_munion(rel->op)) {
1357 55766 : assert(rel->l);
1358 : /* get the exps from the first relation */
1359 55766 : rels = rel->l;
1360 55766 : if (rels->h)
1361 55766 : r = rels->h->data;
1362 55766 : if (r)
1363 55766 : exps = _rel_projections(sql, r, tname, settname, intern, basecol);
1364 : /* for every other relation in the list */
1365 : // TODO: do we need the assertion here? for no-assert the loop is no-op
1366 : /*
1367 : for (node *n = rels->h->next; n; n = n->next) {
1368 : rexps = _rel_projections(sql, n->data, tname, settname, intern, basecol);
1369 : assert(list_length(exps) == list_length(rexps));
1370 : }
1371 : */
1372 : /* it's a multi-union (expressions have to be the same in all the operands)
1373 : * so we are ok only with the expressions of the first operand
1374 : */
1375 55766 : if (exps) {
1376 55766 : int label = 0;
1377 55766 : if (!settname)
1378 55766 : label = ++sql->label;
1379 440509 : for (node *en = exps->h; en; en = en->next) {
1380 384743 : sql_exp *e = en->data;
1381 :
1382 384743 : e->card = rel->card;
1383 384743 : if (!settname) /* noname use alias */
1384 384743 : exp_setrelname(sql->sa, e, label);
1385 : }
1386 55766 : if (!settname)
1387 55766 : list_hash_clear(rel->l);
1388 : }
1389 55766 : return exps;
1390 : }
1391 : /* I only expect set relations to hit here */
1392 2416 : assert(is_set(rel->op));
1393 2416 : lexps = _rel_projections(sql, rel->l, tname, settname, intern, basecol);
1394 : //rexps = _rel_projections(sql, rel->r, tname, settname, intern, basecol);
1395 2416 : if (lexps/* && rexps*/) {
1396 2416 : int label = 0;
1397 :
1398 2416 : if (!settname)
1399 2416 : label = ++sql->label;
1400 : //assert(list_length(lexps) == list_length(rexps));
1401 4949 : for (node *en = lexps->h; en; en = en->next) {
1402 2533 : sql_exp *e = en->data;
1403 :
1404 2533 : e->card = rel->card;
1405 2533 : if (!settname) /* noname use alias */
1406 2533 : exp_setrelname(sql->sa, e, label);
1407 : }
1408 2416 : if (!settname)
1409 2416 : list_hash_clear(lexps);
1410 : }
1411 : return lexps;
1412 :
1413 68359 : case op_ddl:
1414 : case op_semi:
1415 : case op_anti:
1416 :
1417 : case op_select:
1418 : case op_topn:
1419 : case op_sample:
1420 68359 : return _rel_projections(sql, rel->l, tname, settname, intern, basecol);
1421 : default:
1422 : return NULL;
1423 : }
1424 : }
1425 :
1426 : list *
1427 597457 : rel_projections(mvc *sql, sql_rel *rel, const char *tname, int settname, int intern)
1428 : {
1429 597457 : assert(tname == NULL);
1430 597457 : return _rel_projections(sql, rel, tname, settname, intern, 0);
1431 : }
1432 :
1433 : /* find the path to the relation containing the base of the expression
1434 : (e_column), in most cases this means go down the join tree and
1435 : find the base column.
1436 : */
1437 : static int
1438 3999169 : rel_bind_path_(mvc *sql, sql_rel *rel, sql_exp *e, list *path )
1439 : {
1440 3999169 : int found = 0;
1441 3999169 : list *rels;
1442 :
1443 3999169 : if (mvc_highwater(sql)) {
1444 0 : sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
1445 0 : return 0;
1446 : }
1447 :
1448 3999169 : switch (rel->op) {
1449 1856472 : case op_join:
1450 : case op_left:
1451 : case op_right:
1452 : case op_full:
1453 : /* first right (possible subquery) */
1454 1856472 : found = rel_bind_path_(sql, rel->r, e, path);
1455 1856472 : if (!found)
1456 1563538 : found = rel_bind_path_(sql, rel->l, e, path);
1457 1563538 : if (!found && !list_empty(rel->attr)) {
1458 0 : if (e->l && exps_bind_column2(rel->attr, e->l, e->r, NULL))
1459 : found = 1;
1460 0 : if (!found && !e->l && exps_bind_column(rel->attr, e->r, NULL, NULL, 1))
1461 : found = 1;
1462 : }
1463 : break;
1464 115084 : case op_semi:
1465 : case op_anti:
1466 : case op_select:
1467 : case op_topn:
1468 : case op_sample:
1469 115084 : found = rel_bind_path_(sql, rel->l, e, path);
1470 115084 : break;
1471 2024346 : case op_basetable:
1472 : case op_union:
1473 : case op_inter:
1474 : case op_except:
1475 : case op_groupby:
1476 : case op_project:
1477 : case op_table:
1478 2024346 : if (is_basetable(rel->op) && !rel->exps) {
1479 1836980 : if (e->l) {
1480 1836980 : if (rel_base_bind_column2_(rel, e->l, e->r))
1481 : found = 1;
1482 0 : } else if (rel_base_bind_column_(rel, e->r))
1483 : found = 1;
1484 187366 : } else if (rel->exps) {
1485 187366 : if (!found && e->l && exps_bind_column2(rel->exps, e->l, e->r, NULL))
1486 : found = 1;
1487 96578 : if (!found && !e->l && exps_bind_column(rel->exps, e->r, NULL, NULL, 1))
1488 : found = 1;
1489 : }
1490 : break;
1491 3267 : case op_munion:
1492 3267 : assert(rel->l);
1493 3267 : rels = rel->l;
1494 7036 : for (node *n = rels->h; n && !found; n = n->next) {
1495 3769 : if (!found && e->l && exps_bind_column2(rel->exps, e->l, e->r, NULL))
1496 : found = 1;
1497 1004 : if (!found && !e->l && exps_bind_column(rel->exps, e->r, NULL, NULL, 1))
1498 2765 : found = 1;
1499 : }
1500 : break;
1501 : case op_insert:
1502 : case op_update:
1503 : case op_delete:
1504 : case op_truncate:
1505 : case op_merge:
1506 : case op_ddl:
1507 : break;
1508 : }
1509 214936 : if (found)
1510 2391091 : list_prepend(path, rel);
1511 : return found;
1512 : }
1513 :
1514 : static list *
1515 490677 : rel_bind_path(mvc *sql, sql_rel *rel, sql_exp *e, list *path)
1516 : {
1517 490677 : if (!path)
1518 : return NULL;
1519 :
1520 490677 : if (e->type == e_convert) {
1521 21033 : if (!(path = rel_bind_path(sql, rel, e->l, path)))
1522 : return NULL;
1523 469644 : } else if (e->type == e_column) {
1524 464075 : if (rel) {
1525 464075 : if (!rel_bind_path_(sql, rel, e, path)) {
1526 : /* something is wrong */
1527 : return NULL;
1528 : }
1529 : }
1530 464075 : return path;
1531 : }
1532 : /* default the top relation */
1533 26602 : append(path, rel);
1534 26602 : return path;
1535 : }
1536 :
1537 : static sql_rel *
1538 21989 : rel_select_push_exp_down(mvc *sql, sql_rel *rel, sql_exp *e)
1539 : {
1540 21989 : sql_rel *r = rel->l, *jl = r->l, *jr = r->r;
1541 21989 : int left = r->op == op_join || r->op == op_left;
1542 21989 : int right = r->op == op_join || r->op == op_right;
1543 21989 : int done = 0;
1544 :
1545 21989 : assert(is_select(rel->op));
1546 21989 : if (!is_full(r->op) && !is_single(r)) {
1547 21989 : if (left && rel_rebind_exp(sql, jl, e)) {
1548 9 : done = 1;
1549 9 : r->l = jl = rel_select_add_exp(sql->sa, jl, e);
1550 21980 : } else if (right && rel_rebind_exp(sql, jr, e)) {
1551 6 : done = 1;
1552 6 : r->r = jr = rel_select_add_exp(sql->sa, jr, e);
1553 : }
1554 : }
1555 15 : if (!done)
1556 21974 : rel_select_add_exp(sql->sa, rel, e);
1557 21989 : return rel;
1558 : }
1559 :
1560 : /* ls is the left expression of the select, e is the select expression. */
1561 : sql_rel *
1562 110641 : rel_push_select(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *e, int f)
1563 : {
1564 110641 : list *l = rel_bind_path(sql, rel, ls, sa_list(sql->sa));
1565 110641 : node *n;
1566 110641 : sql_rel *lrel = NULL, *p = NULL;
1567 :
1568 110641 : if (!l)
1569 : return NULL;
1570 110641 : if (is_sql_or(f)) /* expression has no clear parent relation, so filter current with it */
1571 21517 : return rel_select(sql->sa, rel, e);
1572 :
1573 254206 : for (n = l->h; n; n = n->next ) {
1574 253499 : lrel = n->data;
1575 :
1576 253499 : if (rel_is_ref(lrel))
1577 : break;
1578 :
1579 : /* push down as long as the operators allow this */
1580 253491 : if (!is_select(lrel->op) &&
1581 231930 : !(is_semi(lrel->op) && !rel_is_ref(lrel->l)) &&
1582 88409 : lrel->op != op_join &&
1583 : lrel->op != op_left)
1584 : break;
1585 : /* pushing through left head of a left join is allowed */
1586 165086 : if (lrel->op == op_left && (!n->next || lrel->l != n->next->data))
1587 : break;
1588 165082 : p = lrel;
1589 : }
1590 89124 : if (!lrel)
1591 : return NULL;
1592 89124 : if (p && is_select(p->op) && !rel_is_ref(p)) { /* refine old select */
1593 19190 : p = rel_select_push_exp_down(sql, p, e);
1594 : } else {
1595 69934 : sql_rel *n = rel_select(sql->sa, lrel, e);
1596 :
1597 69934 : if (p && p != lrel) {
1598 64665 : assert(p->op == op_join || p->op == op_left || is_semi(p->op));
1599 64665 : if (p->l == lrel) {
1600 23355 : p->l = n;
1601 : } else {
1602 41310 : p->r = n;
1603 : }
1604 : } else {
1605 5269 : if (rel != lrel)
1606 0 : assert(0);
1607 : rel = n;
1608 : }
1609 : }
1610 : return rel;
1611 : }
1612 :
1613 : /* ls and rs are the left and right expression of the join, e is the
1614 : join expression.
1615 : */
1616 : sql_rel *
1617 179243 : rel_push_join(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *rs, sql_exp *rs2, sql_exp *e, int f)
1618 : {
1619 179243 : list *l = NULL, *r = NULL, *r2 = NULL;
1620 179243 : node *ln, *rn;
1621 179243 : sql_rel *lrel = NULL, *rrel = NULL, *rrel2 = NULL, *p = NULL;
1622 :
1623 179243 : if (!(l = rel_bind_path(sql, rel, ls, sa_list(sql->sa))) ||
1624 179243 : !(r = rel_bind_path(sql, rel, rs, sa_list(sql->sa))) ||
1625 517 : (rs2 && !(r2 = rel_bind_path(sql, rel, rs2, sa_list(sql->sa)))))
1626 0 : return NULL;
1627 :
1628 179243 : if (is_sql_or(f))
1629 2989 : return rel_push_select(sql, rel, ls, e, f);
1630 :
1631 176254 : p = rel;
1632 176254 : if (r2) {
1633 509 : node *rn2;
1634 :
1635 1025 : for (ln = l->h, rn = r->h, rn2 = r2->h; ln && rn && rn2; ln = ln->next, rn = rn->next, rn2 = rn2->next ) {
1636 533 : lrel = ln->data;
1637 533 : rrel = rn->data;
1638 533 : rrel2 = rn2->data;
1639 :
1640 533 : if (rel_is_ref(lrel) || rel_is_ref(rrel) || rel_is_ref(rrel2) || is_processed(lrel) || is_processed(rrel))
1641 : break;
1642 :
1643 : /* push down as long as the operators allow this
1644 : and the relation is equal.
1645 : */
1646 528 : if (lrel != rrel || lrel != rrel2 ||
1647 516 : (!is_select(lrel->op) &&
1648 61 : !(is_semi(lrel->op) && !rel_is_ref(lrel->l)) &&
1649 0 : lrel->op != op_join &&
1650 : lrel->op != op_left))
1651 : break;
1652 : /* pushing through left head of a left join is allowed */
1653 516 : if (lrel->op == op_left && (!ln->next || lrel->l != ln->next->data))
1654 : break;
1655 516 : p = lrel;
1656 : }
1657 : } else {
1658 792997 : for (ln = l->h, rn = r->h; ln && rn; ln = ln->next, rn = rn->next ) {
1659 790248 : lrel = ln->data;
1660 790248 : rrel = rn->data;
1661 :
1662 790248 : if (rel_is_ref(lrel) || rel_is_ref(rrel) || is_processed(lrel) || is_processed(rrel))
1663 : break;
1664 :
1665 : /* push down as long as the operators allow this
1666 : and the relation is equal.
1667 : */
1668 750832 : if (lrel != rrel ||
1669 618909 : (!is_select(lrel->op) &&
1670 615522 : !(is_semi(lrel->op) && !rel_is_ref(lrel->l)) &&
1671 1657 : lrel->op != op_join &&
1672 : lrel->op != op_left))
1673 : break;
1674 : /* pushing through left head of a left join is allowed */
1675 617252 : if (lrel->op == op_left && (!ln->next || lrel->l != ln->next->data))
1676 : break;
1677 617252 : p = lrel;
1678 : }
1679 : }
1680 176254 : if (!lrel || !rrel || (r2 && !rrel2))
1681 : return NULL;
1682 :
1683 : /* filter on columns of this relation */
1684 176254 : if ((lrel == rrel && (!r2 || lrel == rrel2) && lrel->op != op_join) || rel_is_ref(p)) {
1685 2813 : if (is_select(lrel->op) && !rel_is_ref(lrel)) {
1686 1145 : lrel = rel_select_push_exp_down(sql, lrel, e);
1687 1668 : } else if (p && is_select(p->op) && !rel_is_ref(p)) {
1688 1654 : p = rel_select_push_exp_down(sql, p, e);
1689 : } else {
1690 14 : sql_rel *n = rel_select(sql->sa, lrel, e);
1691 :
1692 14 : if (p && p != lrel) {
1693 12 : if (p->l == lrel)
1694 1 : p->l = n;
1695 : else
1696 11 : p->r = n;
1697 : } else {
1698 : rel = n;
1699 : }
1700 : }
1701 2813 : return rel;
1702 : }
1703 :
1704 173441 : rel_join_add_exp( sql->sa, p, e);
1705 173441 : return rel;
1706 : }
1707 :
1708 : sql_rel *
1709 18666 : rel_or(mvc *sql, sql_rel *rel, sql_rel *l, sql_rel *r, list *oexps, list *lexps, list *rexps)
1710 : {
1711 18666 : sql_rel *ll = l->l, *rl = r->l;
1712 18666 : list *ls, *rs;
1713 :
1714 18666 : assert(!lexps || l == r);
1715 18666 : if (l == r && lexps) { /* merge both lists */
1716 36 : sql_exp *e = exp_or(sql->sa, lexps, rexps, 0);
1717 36 : list *nl = oexps?oexps:new_exp_list(sql->sa);
1718 :
1719 36 : rel_destroy(r);
1720 36 : append(nl, e);
1721 36 : if (is_outerjoin(l->op) && is_processed(l))
1722 0 : l = rel_select(sql->sa, l, NULL);
1723 36 : l->exps = nl;
1724 36 : return l;
1725 : }
1726 :
1727 : /* favor or expressions over union */
1728 18630 : if (l->op == r->op && is_select(l->op) &&
1729 18630 : ll == rl && ll == rel && !rel_is_ref(l) && !rel_is_ref(r)) {
1730 18630 : sql_exp *e = exp_or(sql->sa, l->exps, r->exps, 0);
1731 18630 : list *nl = new_exp_list(sql->sa);
1732 :
1733 18630 : rel_destroy(r);
1734 18630 : append(nl, e);
1735 18630 : l->exps = nl;
1736 :
1737 : /* merge and expressions */
1738 18630 : ll = l->l;
1739 20968 : while (ll && is_select(ll->op) && !rel_is_ref(ll)) {
1740 2338 : list_merge(l->exps, ll->exps, (fdup)NULL);
1741 2338 : l->l = ll->l;
1742 2338 : ll->l = NULL;
1743 2338 : rel_destroy(ll);
1744 2338 : ll = l->l;
1745 : }
1746 : return l;
1747 : }
1748 :
1749 0 : if (rel) {
1750 0 : ls = rel_projections(sql, rel, NULL, 1, 1);
1751 0 : rs = rel_projections(sql, rel, NULL, 1, 1);
1752 : } else {
1753 0 : ls = rel_projections(sql, l, NULL, 1, 1);
1754 0 : rs = rel_projections(sql, r, NULL, 1, 1);
1755 : }
1756 0 : set_processed(l);
1757 0 : set_processed(r);
1758 0 : rel = rel_setop_check_types(sql, l, r, ls, rs, op_union);
1759 0 : if (!rel)
1760 : return NULL;
1761 0 : rel_setop_set_exps(sql, rel, rel_projections(sql, rel, NULL, 1, 1), false);
1762 0 : set_processed(rel);
1763 0 : rel->nrcols = list_length(rel->exps);
1764 0 : rel = rel_distinct(rel);
1765 0 : if (!rel)
1766 : return NULL;
1767 0 : if (exps_card(l->exps) <= CARD_AGGR &&
1768 0 : exps_card(r->exps) <= CARD_AGGR)
1769 : {
1770 0 : rel->card = exps_card(l->exps);
1771 0 : exps_fix_card( rel->exps, rel->card);
1772 : }
1773 : return rel;
1774 : }
1775 :
1776 : sql_table *
1777 4002 : rel_ddl_table_get(sql_rel *r)
1778 : {
1779 4002 : if (r->flag == ddl_alter_table || r->flag == ddl_create_table || r->flag == ddl_create_view) {
1780 4002 : sql_exp *e = r->exps->t->data;
1781 4002 : atom *a = e->l;
1782 :
1783 4002 : return a->data.val.pval;
1784 : }
1785 : return NULL;
1786 : }
1787 :
1788 : sql_rel *
1789 2285 : rel_ddl_basetable_get(sql_rel *r)
1790 : {
1791 2285 : if (r->flag == ddl_alter_table || r->flag == ddl_create_table || r->flag == ddl_create_view) {
1792 2285 : return r->l;
1793 : }
1794 : return NULL;
1795 : }
1796 :
1797 : static sql_exp *
1798 26 : exps_find_identity(list *exps, sql_rel *p)
1799 : {
1800 26 : node *n;
1801 :
1802 102 : for (n=exps->h; n; n = n->next) {
1803 77 : sql_exp *e = n->data;
1804 :
1805 77 : if (is_identity(e, p))
1806 1 : return e;
1807 : }
1808 : return NULL;
1809 : }
1810 :
1811 : static sql_rel *
1812 76 : _rel_add_identity(mvc *sql, sql_rel *rel, sql_exp **exp)
1813 : {
1814 76 : list *exps = rel_projections(sql, rel, NULL, 1, 1);
1815 76 : sql_exp *e = NULL;
1816 :
1817 76 : if (list_empty(exps)) {
1818 0 : *exp = NULL;
1819 0 : return rel;
1820 : }
1821 76 : if (!is_simple_project(rel->op) || need_distinct(rel) || !list_empty(rel->r) || rel_is_ref(rel))
1822 52 : rel = rel_project(sql->sa, rel, exps);
1823 : /* filter parameters out */
1824 152 : for (node *n = rel->exps->h ; n && !e ; n = n->next) {
1825 76 : sql_exp *re = n->data;
1826 :
1827 76 : if (exp_subtype(re))
1828 76 : e = re;
1829 : }
1830 76 : if (!e)
1831 0 : return sql_error(sql, 10, SQLSTATE(42000) "Query projection must have at least one parameter with known SQL type");
1832 :
1833 76 : e = exp_column(sql->sa, exp_relname(e), exp_name(e), exp_subtype(e), rel->card, has_nil(e), is_unique(e), is_intern(e));
1834 76 : e = exp_unop(sql->sa, e, sql_bind_func(sql, "sys", "identity", exp_subtype(e), NULL, F_FUNC, true, true));
1835 76 : set_intern(e);
1836 76 : set_has_no_nil(e);
1837 76 : set_unique(e);
1838 76 : e->p = prop_create(sql->sa, PROP_HASHCOL, e->p);
1839 76 : *exp = exp_label(sql->sa, e, ++sql->label);
1840 76 : (void) rel_project_add_exp(sql, rel, e);
1841 76 : return rel;
1842 : }
1843 :
1844 : sql_rel *
1845 92 : rel_add_identity(mvc *sql, sql_rel *rel, sql_exp **exp)
1846 : {
1847 92 : if (rel && is_basetable(rel->op)) { /* for base table relations just use TID column as identity */
1848 15 : *exp = basetable_get_tid_or_add_it(sql, rel);
1849 15 : return rel;
1850 : }
1851 77 : if (rel && is_simple_project(rel->op) && !need_distinct(rel) && (*exp = exps_find_identity(rel->exps, rel->l)) != NULL)
1852 : return rel;
1853 76 : return _rel_add_identity(sql, rel, exp);
1854 : }
1855 :
1856 : sql_rel *
1857 0 : rel_add_identity2(mvc *sql, sql_rel *rel, sql_exp **exp)
1858 : {
1859 0 : sql_rel *l = rel, *p = rel;
1860 :
1861 0 : if (rel && is_basetable(rel->op)) { /* for base table relations just use TID column as identity */
1862 0 : *exp = basetable_get_tid_or_add_it(sql, rel);
1863 0 : return rel;
1864 : }
1865 0 : if (rel && is_simple_project(rel->op) && !need_distinct(rel) && (*exp = exps_find_identity(rel->exps, rel->l)) != NULL)
1866 : return rel;
1867 0 : while(l && !is_set(l->op) && rel_has_freevar(sql, l) && l->l) {
1868 : p = l;
1869 : l = l->l;
1870 : }
1871 0 : if (l != p) {
1872 0 : sql_rel *o = rel;
1873 0 : sql_exp *id;
1874 :
1875 0 : if (!(p->l = _rel_add_identity(sql, l, exp)))
1876 : return NULL;
1877 0 : l = p->l;
1878 0 : id = exp_ref(sql, *exp);
1879 0 : while (o && o != l) {
1880 0 : *exp = id;
1881 0 : if (is_project(o->op))
1882 0 : rel_project_add_exp(sql, o, id);
1883 0 : o = o->l;
1884 : }
1885 : return rel;
1886 : }
1887 0 : return _rel_add_identity(sql, rel, exp);
1888 : }
1889 :
1890 : static sql_exp *
1891 1474 : rel_find_column_(allocator *sa, list *exps, const char *tname, const char *cname)
1892 : {
1893 1474 : int ambiguous = 0, multi = 0;
1894 1474 : sql_exp *e = exps_bind_column2(exps, tname, cname, &multi);
1895 1474 : if (!e && cname[0] == '%' && !tname)
1896 0 : e = exps_bind_column(exps, cname, &ambiguous, &multi, 0);
1897 1474 : if (e && !ambiguous && !multi)
1898 1473 : return exp_alias(sa, exp_relname(e), exp_name(e), exp_relname(e), cname, exp_subtype(e), e->card, has_nil(e), is_unique(e), is_intern(e));
1899 : return NULL;
1900 : }
1901 :
1902 : sql_exp *
1903 1474 : rel_find_column(allocator *sa, sql_rel *rel, const char *tname, const char *cname )
1904 : {
1905 1761 : sql_exp *e = NULL;
1906 :
1907 1761 : if (!rel)
1908 : return NULL;
1909 1761 : if (rel->exps && (is_project(rel->op) || is_base(rel->op)) && (e = rel_find_column_(sa, rel->exps, tname, cname)))
1910 : return e;
1911 288 : if ((is_simple_project(rel->op) || is_groupby(rel->op)) && rel->l) {
1912 1 : if (!is_processed(rel))
1913 : return rel_find_column(sa, rel->l, tname, cname);
1914 287 : } else if (is_set(rel->op)) {
1915 0 : assert(is_processed(rel));
1916 : return NULL;
1917 : } else if (is_join(rel->op)) {
1918 0 : e = rel_find_column(sa, rel->l, tname, cname);
1919 :
1920 0 : if (e && (is_right(rel->op) || is_full(rel->op)))
1921 0 : set_has_nil(e);
1922 0 : if (!e) {
1923 0 : e = rel_find_column(sa, rel->r, tname, cname);
1924 0 : if (e && (is_left(rel->op) || is_full(rel->op)))
1925 0 : set_has_nil(e);
1926 : }
1927 0 : if (!e && !list_empty(rel->attr))
1928 0 : e = rel_find_column_(sa, rel->attr, tname, cname);
1929 0 : if (e)
1930 0 : set_not_unique(e);
1931 0 : return e;
1932 : } else if (is_semi(rel->op) ||
1933 : is_select(rel->op) ||
1934 : is_topn(rel->op) ||
1935 : is_sample(rel->op)) {
1936 287 : if (rel->l)
1937 : return rel_find_column(sa, rel->l, tname, cname);
1938 : }
1939 : return NULL;
1940 : }
1941 :
1942 : int
1943 0 : rel_in_rel(sql_rel *super, sql_rel *sub)
1944 : {
1945 0 : if (!super)
1946 : return 0;
1947 0 : if (super == sub)
1948 : return 1;
1949 0 : if (is_join(super->op) || is_semi(super->op) || is_set(super->op) || is_modify(super->op) || is_ddl(super->op))
1950 0 : return rel_in_rel(super->l, sub) || rel_in_rel(super->r, sub);
1951 : if (is_select(super->op) || is_simple_project(super->op) || is_groupby(super->op) || is_topn(super->op) || is_sample(super->op))
1952 0 : return rel_in_rel(super->l, sub);
1953 : return 0;
1954 : }
1955 :
1956 : sql_rel*
1957 6 : rel_parent(sql_rel *rel)
1958 : {
1959 6 : if (rel->l && (is_project(rel->op) || is_topn(rel->op) || is_sample(rel->op))) {
1960 6 : sql_rel *l = rel->l;
1961 6 : if (is_project(l->op))
1962 6 : return l;
1963 : }
1964 : return rel;
1965 : }
1966 :
1967 : sql_exp *
1968 26632 : lastexp(sql_rel *rel)
1969 : {
1970 26632 : if (!is_processed(rel) || is_topn(rel->op) || is_sample(rel->op))
1971 6 : rel = rel_parent(rel);
1972 26632 : assert(list_length(rel->exps));
1973 26632 : assert(is_project(rel->op) || rel->op == op_table);
1974 26632 : return rel->exps->t->data;
1975 : }
1976 :
1977 : sql_rel *
1978 5676 : rel_return_zero_or_one(mvc *sql, sql_rel *rel, exp_kind ek)
1979 : {
1980 5676 : if (ek.card < card_set && rel->card > CARD_ATOM) {
1981 4333 : list *exps = rel->exps;
1982 :
1983 4333 : assert (is_simple_project(rel->op) || is_mset(rel->op));
1984 4333 : rel = rel_groupby(sql, rel, NULL);
1985 8676 : for(node *n = exps->h; n; n=n->next) {
1986 4343 : sql_exp *e = n->data;
1987 4343 : if (!has_label(e))
1988 49 : exp_label(sql->sa, e, ++sql->label);
1989 4343 : sql_subtype *t = exp_subtype(e); /* parameters don't have a type defined, for those use 'void' one */
1990 4343 : sql_subfunc *zero_or_one = sql_bind_func(sql, "sys", "zero_or_one", t ? t : sql_bind_localtype("void"), NULL, F_AGGR, true, true);
1991 :
1992 4343 : e = exp_ref(sql, e);
1993 4343 : e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, has_nil(e));
1994 4343 : (void)rel_groupby_add_aggr(sql, rel, e);
1995 : }
1996 4333 : set_processed(rel);
1997 : }
1998 5676 : return rel;
1999 : }
2000 :
2001 : sql_rel *
2002 35870 : rel_zero_or_one(mvc *sql, sql_rel *rel, exp_kind ek)
2003 : {
2004 35870 : if (is_topn(rel->op) || is_sample(rel->op))
2005 17 : rel = rel_project(sql->sa, rel, rel_projections(sql, rel, NULL, 1, 0));
2006 35870 : if (ek.card < card_set && rel->card > CARD_ATOM) {
2007 9433 : assert (is_simple_project(rel->op) || is_mset(rel->op));
2008 :
2009 9433 : list *exps = rel->exps;
2010 18887 : for(node *n = exps->h; n; n=n->next) {
2011 9454 : sql_exp *e = n->data;
2012 9454 : if (!has_label(e))
2013 9417 : exp_label(sql->sa, e, ++sql->label);
2014 : }
2015 9433 : set_single(rel);
2016 : } else {
2017 26437 : sql_exp *e = lastexp(rel);
2018 26437 : if (!has_label(e))
2019 12135 : exp_label(sql->sa, e, ++sql->label);
2020 : }
2021 35870 : return rel;
2022 : }
2023 :
2024 : static sql_rel *
2025 6528 : refs_find_rel(list *refs, sql_rel *rel)
2026 : {
2027 6528 : node *n;
2028 :
2029 16952 : for(n=refs->h; n; n = n->next->next) {
2030 13796 : sql_rel *ref = n->data;
2031 13796 : sql_rel *s = n->next->data;
2032 :
2033 13796 : if (rel == ref)
2034 : return s;
2035 : }
2036 : return NULL;
2037 : }
2038 :
2039 : static int exp_deps(mvc *sql, sql_exp *e, list *refs, list *l);
2040 :
2041 : static int
2042 667045 : exps_deps(mvc *sql, list *exps, list *refs, list *l)
2043 : {
2044 :
2045 2757069 : for(node *n = exps->h; n; n = n->next)
2046 2090024 : if (exp_deps(sql, n->data, refs, l) != 0)
2047 : return -1;
2048 : return 0;
2049 : }
2050 :
2051 : static int
2052 6863266 : id_cmp(sql_base *id1, sql_base *id2)
2053 : {
2054 6863266 : if (id1->id == id2->id)
2055 87374 : return 0;
2056 : return -1;
2057 : }
2058 :
2059 : static list *
2060 718086 : cond_append(list *l, sql_base *b)
2061 : {
2062 718086 : if (b->id >= FUNC_OIDS && !list_find(l, b, (fcmp) &id_cmp))
2063 352794 : list_append(l, b);
2064 718086 : return l;
2065 : }
2066 :
2067 : static int rel_deps(mvc *sql, sql_rel *r, list *refs, list *l);
2068 :
2069 : static int
2070 2271169 : exp_deps(mvc *sql, sql_exp *e, list *refs, list *l)
2071 : {
2072 2367707 : if (mvc_highwater(sql)) {
2073 0 : (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2074 0 : return -1;
2075 : }
2076 :
2077 2367707 : switch(e->type) {
2078 43702 : case e_psm:
2079 43702 : if (e->flag & PSM_SET || e->flag & PSM_RETURN || e->flag & PSM_EXCEPTION) {
2080 18706 : return exp_deps(sql, e->l, refs, l);
2081 24996 : } else if (e->flag & PSM_VAR) {
2082 : return 0;
2083 20388 : } else if (e->flag & PSM_WHILE || e->flag & PSM_IF) {
2084 6113 : if (exp_deps(sql, e->l, refs, l) != 0 || exps_deps(sql, e->r, refs, l) != 0)
2085 0 : return -1;
2086 6113 : if (e->flag & PSM_IF && e->f)
2087 732 : return exps_deps(sql, e->f, refs, l);
2088 14275 : } else if (e->flag & PSM_REL) {
2089 14275 : sql_rel *rel = e->l;
2090 14275 : return rel_deps(sql, rel, refs, l);
2091 : }
2092 : break;
2093 832958 : case e_atom:
2094 832958 : if (e->f && exps_deps(sql, e->f, refs, l) != 0)
2095 : return -1;
2096 : break;
2097 : case e_column:
2098 : break;
2099 77808 : case e_convert:
2100 77808 : return exp_deps(sql, e->l, refs, l);
2101 286195 : case e_func: {
2102 286195 : sql_subfunc *f = e->f;
2103 :
2104 286195 : if (e->l && exps_deps(sql, e->l, refs, l) != 0)
2105 : return -1;
2106 286195 : cond_append(l, &f->func->base);
2107 286195 : if (e->l && list_length(e->l) == 2 && strcmp(f->func->base.name, "next_value_for") == 0) {
2108 : /* add dependency on seq nr */
2109 81 : list *nl = e->l;
2110 81 : sql_exp *schname = nl->h->data, *seqname = nl->t->data;
2111 81 : char *sch_name = is_atom(schname->type) && schname->l ? ((atom*)schname->l)->data.val.sval : NULL;
2112 81 : char *seq_name = is_atom(seqname->type) && seqname->l ? ((atom*)seqname->l)->data.val.sval : NULL;
2113 :
2114 81 : if (sch_name && seq_name) {
2115 81 : sql_schema *sche = mvc_bind_schema(sql, sch_name);
2116 81 : if (sche) {
2117 81 : sql_sequence *seq = find_sql_sequence(sql->session->tr, sche, seq_name);
2118 81 : if (seq)
2119 81 : cond_append(l, &seq->base);
2120 : }
2121 : }
2122 : }
2123 : } break;
2124 19690 : case e_aggr: {
2125 19690 : sql_subfunc *a = e->f;
2126 :
2127 19690 : if (e->l && exps_deps(sql, e->l, refs, l) != 0)
2128 : return -1;
2129 19690 : cond_append(l, &a->func->base);
2130 19690 : } break;
2131 90468 : case e_cmp: {
2132 90468 : if (e->flag == cmp_or || e->flag == cmp_filter) {
2133 718 : if (e->flag == cmp_filter) {
2134 488 : sql_subfunc *f = e->f;
2135 488 : cond_append(l, &f->func->base);
2136 : }
2137 1436 : if (exps_deps(sql, e->l, refs, l) != 0 ||
2138 718 : exps_deps(sql, e->r, refs, l) != 0)
2139 0 : return -1;
2140 89750 : } else if (e->flag == cmp_in || e->flag == cmp_notin) {
2141 8936 : if (exp_deps(sql, e->l, refs, l) != 0 ||
2142 4468 : exps_deps(sql, e->r, refs, l) != 0)
2143 0 : return -1;
2144 : } else {
2145 170564 : if (exp_deps(sql, e->l, refs, l) != 0 ||
2146 85282 : exp_deps(sql, e->r, refs, l) != 0)
2147 0 : return -1;
2148 85282 : if (e->f)
2149 : return exp_deps(sql, e->f, refs, l);
2150 : }
2151 : } break;
2152 : }
2153 : return 0;
2154 : }
2155 :
2156 : static int
2157 464568 : rel_deps(mvc *sql, sql_rel *r, list *refs, list *l)
2158 : {
2159 464568 : if (mvc_highwater(sql)) {
2160 0 : (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2161 0 : return -1;
2162 : }
2163 :
2164 464568 : if (!r)
2165 : return 0;
2166 :
2167 462375 : if (rel_is_ref(r) && refs_find_rel(refs, r)) /* already handled */
2168 : return 0;
2169 452475 : switch (r->op) {
2170 98505 : case op_basetable: {
2171 98505 : sql_table *t = r->l;
2172 :
2173 98505 : cond_append(l, &t->base);
2174 : /* find all used columns */
2175 440384 : for (node *en = r->exps->h; en; en = en->next) {
2176 341879 : sql_exp *exp = en->data;
2177 341879 : const char *oname = exp->r;
2178 :
2179 341879 : assert(!is_func(exp->type));
2180 341879 : if (oname[0] == '%' && strcmp(oname, TID) == 0) {
2181 32783 : continue;
2182 309096 : } else if (oname[0] == '%') {
2183 216 : sql_idx *i = find_sql_idx(t, oname+1);
2184 216 : if (i) {
2185 215 : cond_append(l, &i->base);
2186 215 : continue;
2187 : }
2188 : }
2189 308881 : sql_column *c = find_sql_column(t, oname);
2190 308881 : if (!c)
2191 : return -1;
2192 308881 : cond_append(l, &c->base);
2193 : }
2194 : } break;
2195 4031 : case op_table: {
2196 4031 : if ((IS_TABLE_PROD_FUNC(r->flag) || r->flag == TABLE_FROM_RELATION) && r->r) { /* table producing function, excluding rel_relational_func cases */
2197 4031 : sql_exp *op = r->r;
2198 4031 : sql_subfunc *f = op->f;
2199 4031 : cond_append(l, &f->func->base);
2200 : }
2201 : } break;
2202 68170 : case op_join:
2203 : case op_left:
2204 : case op_right:
2205 : case op_full:
2206 : case op_semi:
2207 : case op_anti:
2208 : case op_union:
2209 : case op_except:
2210 : case op_inter:
2211 :
2212 : case op_insert:
2213 : case op_update:
2214 : case op_delete:
2215 : case op_merge:
2216 136340 : if (rel_deps(sql, r->l, refs, l) != 0 ||
2217 68170 : rel_deps(sql, r->r, refs, l) != 0)
2218 0 : return -1;
2219 : break;
2220 8468 : case op_munion:
2221 25404 : for (node *n = ((list*)r->l)->h; n; n = n->next) {
2222 16936 : if (rel_deps(sql, n->data, refs, l) != 0)
2223 : return -1;
2224 : }
2225 : break;
2226 155624 : case op_project:
2227 : case op_select:
2228 : case op_groupby:
2229 : case op_topn:
2230 : case op_sample:
2231 : case op_truncate:
2232 155624 : if (rel_deps(sql, r->l, refs, l) != 0)
2233 : return -1;
2234 : break;
2235 117677 : case op_ddl:
2236 117677 : if (r->flag == ddl_output || r->flag == ddl_create_seq || r->flag == ddl_alter_seq || r->flag == ddl_alter_table || r->flag == ddl_create_table || r->flag == ddl_create_view) {
2237 21 : if (rel_deps(sql, r->l, refs, l) != 0)
2238 : return -1;
2239 : } else if (r->flag == ddl_list || r->flag == ddl_exception) {
2240 0 : if (rel_deps(sql, r->l, refs, l) != 0 ||
2241 0 : rel_deps(sql, r->r, refs, l) != 0)
2242 0 : return -1;
2243 : }
2244 : break;
2245 : }
2246 452475 : if (!is_base(r->op) && r->exps) {
2247 337571 : if (exps_deps(sql, r->exps, refs, l) != 0)
2248 : return -1;
2249 : }
2250 452475 : if ((is_simple_project(r->op) || is_groupby(r->op)) && r->r) {
2251 18170 : if (exps_deps(sql, r->r, refs, l) != 0)
2252 : return -1;
2253 : }
2254 452475 : if (rel_is_ref(r)) {
2255 3156 : list_append(refs, r);
2256 3156 : list_append(refs, l);
2257 : }
2258 : return 0;
2259 : }
2260 :
2261 : list *
2262 141372 : rel_dependencies(mvc *sql, sql_rel *r)
2263 : {
2264 141372 : list *refs = sa_list(sql->sa);
2265 141372 : list *l = sa_list(sql->sa);
2266 :
2267 141372 : if (rel_deps(sql, r, refs, l) != 0)
2268 0 : return NULL;
2269 : return l;
2270 : }
2271 :
2272 : static list *exps_exp_visitor(visitor *v, sql_rel *rel, list *exps, int depth, exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown);
2273 :
2274 : static inline list *
2275 41273 : exps_exps_exp_visitor(visitor *v, sql_rel *rel, list *lists, int depth, exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown)
2276 : {
2277 41273 : node *n;
2278 :
2279 41273 : if (list_empty(lists))
2280 : return lists;
2281 90559 : for (n = lists->h; n; n = n->next) {
2282 49286 : if (n->data && (n->data = exps_exp_visitor(v, rel, n->data, depth, exp_rewriter, topdown, relations_topdown)) == NULL)
2283 : return NULL;
2284 : }
2285 : return lists;
2286 : }
2287 :
2288 : static sql_rel *rel_exp_visitor(visitor *v, sql_rel *rel, exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown);
2289 :
2290 : static sql_exp *
2291 78983111 : exp_visitor(visitor *v, sql_rel *rel, sql_exp *e, int depth, exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown, bool *changed)
2292 : {
2293 78983111 : if (mvc_highwater(v->sql))
2294 0 : return sql_error(v->sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2295 :
2296 79043411 : assert(e);
2297 79043411 : if (topdown) {
2298 6395729 : int changes = v->changes;
2299 6395729 : if (!(e = exp_rewriter(v, rel, e, depth)))
2300 : return NULL;
2301 6397133 : *changed |= v->changes > changes;
2302 : }
2303 :
2304 79044815 : switch(e->type) {
2305 : case e_column:
2306 : break;
2307 1062790 : case e_convert:
2308 1062790 : if ((e->l = exp_visitor(v, rel, e->l, depth+1, exp_rewriter, topdown, relations_topdown, changed)) == NULL)
2309 : return NULL;
2310 : break;
2311 3982277 : case e_aggr:
2312 : case e_func:
2313 3982277 : if (e->r) /* rewrite rank -r is list of lists */
2314 41273 : if ((e->r = exps_exps_exp_visitor(v, rel, e->r, depth+1, exp_rewriter, topdown, relations_topdown)) == NULL)
2315 : return NULL;
2316 3982277 : if (e->l)
2317 3813872 : if ((e->l = exps_exp_visitor(v, rel, e->l, depth+1, exp_rewriter, topdown, relations_topdown)) == NULL)
2318 : return NULL;
2319 : break;
2320 3338071 : case e_cmp:
2321 3338071 : if (e->flag == cmp_or || e->flag == cmp_filter) {
2322 191261 : if ((e->l = exps_exp_visitor(v, rel, e->l, depth+1, exp_rewriter, topdown, relations_topdown)) == NULL)
2323 : return NULL;
2324 191261 : if ((e->r = exps_exp_visitor(v, rel, e->r, depth+1, exp_rewriter, topdown, relations_topdown)) == NULL)
2325 : return NULL;
2326 3146810 : } else if (e->flag == cmp_in || e->flag == cmp_notin) {
2327 209437 : if ((e->l = exp_visitor(v, rel, e->l, depth+1, exp_rewriter, topdown, relations_topdown, changed)) == NULL)
2328 : return NULL;
2329 209437 : if ((e->r = exps_exp_visitor(v, rel, e->r, depth+1, exp_rewriter, topdown, relations_topdown)) == NULL)
2330 : return NULL;
2331 : } else {
2332 2937373 : if ((e->l = exp_visitor(v, rel, e->l, depth+1, exp_rewriter, topdown, relations_topdown, changed)) == NULL)
2333 : return NULL;
2334 2937373 : if ((e->r = exp_visitor(v, rel, e->r, depth+1, exp_rewriter, topdown, relations_topdown, changed)) == NULL)
2335 : return NULL;
2336 2937373 : if (e->f && (e->f = exp_visitor(v, rel, e->f, depth+1, exp_rewriter, topdown, relations_topdown, changed)) == NULL)
2337 : return NULL;
2338 : }
2339 : break;
2340 371877 : case e_psm:
2341 371877 : if (e->flag & PSM_SET || e->flag & PSM_RETURN || e->flag & PSM_EXCEPTION) {
2342 114194 : if ((e->l = exp_visitor(v, rel, e->l, depth+1, exp_rewriter, topdown, relations_topdown, changed)) == NULL)
2343 : return NULL;
2344 257683 : } else if (e->flag & PSM_VAR) {
2345 : return e;
2346 227885 : } else if (e->flag & PSM_WHILE || e->flag & PSM_IF) {
2347 35117 : if ((e->l = exp_visitor(v, rel, e->l, depth+1, exp_rewriter, topdown, relations_topdown, changed)) == NULL)
2348 : return NULL;
2349 35117 : if ((e->r = exps_exp_visitor(v, rel, e->r, depth+1, exp_rewriter, topdown, relations_topdown)) == NULL)
2350 : return NULL;
2351 35117 : if (e->flag == PSM_IF && e->f && (e->f = exps_exp_visitor(v, rel, e->f, depth+1, exp_rewriter, topdown, relations_topdown)) == NULL)
2352 : return NULL;
2353 192768 : } else if (e->flag & PSM_REL) {
2354 192768 : if ((e->l = rel_exp_visitor(v, e->l, exp_rewriter, topdown, relations_topdown)) == NULL)
2355 : return NULL;
2356 : }
2357 : break;
2358 25627920 : case e_atom:
2359 25627920 : if (e->f)
2360 902212 : if ((e->f = exps_exp_visitor(v, rel, e->f, depth+1, exp_rewriter, topdown, relations_topdown)) == NULL)
2361 : return NULL;
2362 : break;
2363 : }
2364 79015991 : if (!topdown) {
2365 72595308 : int changes = v->changes;
2366 72595308 : if (!(e = exp_rewriter(v, rel, e, depth)))
2367 : return NULL;
2368 72601325 : *changed |= v->changes > changes;
2369 : }
2370 : return e;
2371 : }
2372 :
2373 : static list *
2374 20736235 : exps_exp_visitor(visitor *v, sql_rel *rel, list *exps, int depth, exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown)
2375 : {
2376 20736235 : bool changed = false;
2377 20736235 : if (list_empty(exps))
2378 : return exps;
2379 92233697 : for (node *n = exps->h; n; n = n->next)
2380 71525679 : if (n->data && (n->data = exp_visitor(v, rel, n->data, depth, exp_rewriter, topdown, relations_topdown, &changed)) == NULL)
2381 : return NULL;
2382 20708018 : if (changed && depth == 0) /* only level 0 exps use hash, so remove only on those */
2383 19161 : list_hash_clear(exps);
2384 : return exps;
2385 : }
2386 :
2387 : static inline sql_rel *
2388 15930542 : rel_exp_visitor(visitor *v, sql_rel *rel, exp_rewrite_fptr exp_rewriter, bool topdown, bool relations_topdown)
2389 : {
2390 15930542 : if (mvc_highwater(v->sql))
2391 0 : return sql_error(v->sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2392 :
2393 15934623 : if (!rel)
2394 : return rel;
2395 :
2396 15934602 : if (relations_topdown) {
2397 5795562 : if (rel->exps && (rel->exps = exps_exp_visitor(v, rel, rel->exps, 0, exp_rewriter, topdown, relations_topdown)) == NULL)
2398 : return NULL;
2399 5795983 : if ((is_groupby(rel->op) || is_simple_project(rel->op)) && rel->r && (rel->r = exps_exp_visitor(v, rel, rel->r, 0, exp_rewriter, topdown, relations_topdown)) == NULL)
2400 : return NULL;
2401 : }
2402 :
2403 15935023 : switch(rel->op){
2404 : case op_basetable:
2405 : break;
2406 44128 : case op_table:
2407 44128 : if (IS_TABLE_PROD_FUNC(rel->flag) || rel->flag == TABLE_FROM_RELATION) {
2408 44067 : bool changed = false;
2409 44067 : if (rel->l)
2410 921 : if ((rel->l = rel_exp_visitor(v, rel->l, exp_rewriter, topdown, relations_topdown)) == NULL)
2411 0 : return NULL;
2412 44067 : if (rel->r)
2413 43772 : if ((rel->r = exp_visitor(v, rel, rel->r, 0, exp_rewriter, topdown, relations_topdown, &changed)) == NULL)
2414 : return NULL;
2415 : }
2416 : break;
2417 2357859 : case op_ddl:
2418 2357859 : if (rel->flag == ddl_output || rel->flag == ddl_create_seq || rel->flag == ddl_alter_seq || rel->flag == ddl_alter_table || rel->flag == ddl_create_table || rel->flag == ddl_create_view) {
2419 220253 : if (rel->l)
2420 218120 : if ((rel->l = rel_exp_visitor(v, rel->l, exp_rewriter, topdown, relations_topdown)) == NULL)
2421 : return NULL;
2422 : } else if (rel->flag == ddl_list || rel->flag == ddl_exception) {
2423 2589 : if (rel->l)
2424 2275 : if ((rel->l = rel_exp_visitor(v, rel->l, exp_rewriter, topdown, relations_topdown)) == NULL)
2425 : return NULL;
2426 2589 : if (rel->r)
2427 2345 : if ((rel->r = rel_exp_visitor(v, rel->r, exp_rewriter, topdown, relations_topdown)) == NULL)
2428 : return NULL;
2429 : }
2430 : break;
2431 2184906 : case op_insert:
2432 : case op_update:
2433 : case op_delete:
2434 : case op_merge:
2435 :
2436 : case op_join:
2437 : case op_left:
2438 : case op_right:
2439 : case op_full:
2440 : case op_semi:
2441 : case op_anti:
2442 :
2443 : case op_union:
2444 : case op_inter:
2445 : case op_except:
2446 2184906 : if (rel->l)
2447 2184867 : if ((rel->l = rel_exp_visitor(v, rel->l, exp_rewriter, topdown, relations_topdown)) == NULL)
2448 : return NULL;
2449 2185518 : if (rel->r)
2450 2183221 : if ((rel->r = rel_exp_visitor(v, rel->r, exp_rewriter, topdown, relations_topdown)) == NULL)
2451 : return NULL;
2452 : break;
2453 490751 : case op_munion:
2454 1472253 : for (node *n = ((list*)rel->l)->h; n; n = n->next) {
2455 981502 : if ((n->data = rel_exp_visitor(v, n->data, exp_rewriter, topdown, relations_topdown)) == NULL)
2456 : return NULL;
2457 : }
2458 : break;
2459 7066354 : case op_select:
2460 : case op_topn:
2461 : case op_sample:
2462 : case op_project:
2463 : case op_groupby:
2464 : case op_truncate:
2465 7066354 : if (rel->l)
2466 5964304 : if ((rel->l = rel_exp_visitor(v, rel->l, exp_rewriter, topdown, relations_topdown)) == NULL)
2467 : return NULL;
2468 : break;
2469 : }
2470 :
2471 15935947 : if (!relations_topdown) {
2472 10139731 : if (rel->exps && (rel->exps = exps_exp_visitor(v, rel, rel->exps, 0, exp_rewriter, topdown, relations_topdown)) == NULL)
2473 : return NULL;
2474 10140472 : if ((is_groupby(rel->op) || is_simple_project(rel->op)) && rel->r && (rel->r = exps_exp_visitor(v, rel, rel->r, 0, exp_rewriter, topdown, relations_topdown)) == NULL)
2475 : return NULL;
2476 : }
2477 :
2478 : return rel;
2479 : }
2480 :
2481 : sql_rel *
2482 553618 : rel_exp_visitor_topdown(visitor *v, sql_rel *rel, exp_rewrite_fptr exp_rewriter, bool relations_topdown)
2483 : {
2484 553618 : return rel_exp_visitor(v, rel, exp_rewriter, true, relations_topdown);
2485 : }
2486 :
2487 : sql_rel *
2488 3650689 : rel_exp_visitor_bottomup(visitor *v, sql_rel *rel, exp_rewrite_fptr exp_rewriter, bool relations_topdown)
2489 : {
2490 3650689 : return rel_exp_visitor(v, rel, exp_rewriter, false, relations_topdown);
2491 : }
2492 :
2493 : static list *exps_rel_visitor(visitor *v, list *exps, rel_rewrite_fptr rel_rewriter, bool topdown);
2494 : static list *exps_exps_rel_visitor(visitor *v, list *lists, rel_rewrite_fptr rel_rewriter, bool topdown);
2495 :
2496 : static sql_exp *
2497 325312808 : exp_rel_visitor(visitor *v, sql_exp *e, rel_rewrite_fptr rel_rewriter, bool topdown)
2498 : {
2499 325312808 : if (mvc_highwater(v->sql))
2500 0 : return sql_error(v->sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2501 :
2502 325413968 : assert(e);
2503 325413968 : switch(e->type) {
2504 : case e_column:
2505 : break;
2506 4884699 : case e_convert:
2507 4884699 : if ((e->l = exp_rel_visitor(v, e->l, rel_rewriter, topdown)) == NULL)
2508 : return NULL;
2509 : break;
2510 19635311 : case e_aggr:
2511 : case e_func:
2512 19635311 : if (e->r) /* rewrite rank */
2513 65150 : if ((e->r = exps_exps_rel_visitor(v, e->r, rel_rewriter, topdown)) == NULL)
2514 : return NULL;
2515 19635311 : if (e->l)
2516 18823444 : if ((e->l = exps_rel_visitor(v, e->l, rel_rewriter, topdown)) == NULL)
2517 : return NULL;
2518 : break;
2519 20173774 : case e_cmp:
2520 20173774 : if (e->flag == cmp_or || e->flag == cmp_filter) {
2521 744448 : if ((e->l = exps_rel_visitor(v, e->l, rel_rewriter, topdown)) == NULL)
2522 : return NULL;
2523 744448 : if ((e->r = exps_rel_visitor(v, e->r, rel_rewriter, topdown)) == NULL)
2524 : return NULL;
2525 19429326 : } else if (e->flag == cmp_in || e->flag == cmp_notin) {
2526 1380927 : if ((e->l = exp_rel_visitor(v, e->l, rel_rewriter, topdown)) == NULL)
2527 : return NULL;
2528 1380927 : if ((e->r = exps_rel_visitor(v, e->r, rel_rewriter, topdown)) == NULL)
2529 : return NULL;
2530 : } else {
2531 18048399 : if ((e->l = exp_rel_visitor(v, e->l, rel_rewriter, topdown)) == NULL)
2532 : return NULL;
2533 18048399 : if ((e->r = exp_rel_visitor(v, e->r, rel_rewriter, topdown)) == NULL)
2534 : return NULL;
2535 18048399 : if (e->f && (e->f = exp_rel_visitor(v, e->f, rel_rewriter, topdown)) == NULL)
2536 : return NULL;
2537 : }
2538 : break;
2539 1885190 : case e_psm:
2540 1885190 : if (e->flag & PSM_SET || e->flag & PSM_RETURN || e->flag & PSM_EXCEPTION) {
2541 619578 : if ((e->l = exp_rel_visitor(v, e->l, rel_rewriter, topdown)) == NULL)
2542 : return NULL;
2543 1265612 : } else if (e->flag & PSM_VAR) {
2544 : return e;
2545 1075812 : } else if (e->flag & PSM_WHILE || e->flag & PSM_IF) {
2546 168672 : if ((e->l = exp_rel_visitor(v, e->l, rel_rewriter, topdown)) == NULL)
2547 : return NULL;
2548 168672 : if ((e->r = exps_rel_visitor(v, e->r, rel_rewriter, topdown)) == NULL)
2549 : return NULL;
2550 168672 : if (e->flag == PSM_IF && e->f && (e->f = exps_rel_visitor(v, e->f, rel_rewriter, topdown)) == NULL)
2551 : return NULL;
2552 907140 : } else if (e->flag & PSM_REL) {
2553 907140 : sql_rel *(*func)(visitor *, sql_rel *, rel_rewrite_fptr) = topdown ? rel_visitor_topdown : rel_visitor_bottomup;
2554 907140 : if ((e->l = func(v, e->l, rel_rewriter)) == NULL)
2555 : return NULL;
2556 : }
2557 : break;
2558 64427264 : case e_atom:
2559 64427264 : if (e->f)
2560 1480294 : if ((e->f = exps_rel_visitor(v, e->f, rel_rewriter, topdown)) == NULL)
2561 : return NULL;
2562 : break;
2563 : }
2564 : return e;
2565 : }
2566 :
2567 : static list *
2568 91963226 : exps_rel_visitor(visitor *v, list *exps, rel_rewrite_fptr rel_rewriter, bool topdown)
2569 : {
2570 91963226 : if (list_empty(exps))
2571 : return exps;
2572 373762595 : for (node *n = exps->h; n; n = n->next)
2573 282132043 : if (n->data && (n->data = exp_rel_visitor(v, n->data, rel_rewriter, topdown)) == NULL)
2574 : return NULL;
2575 : return exps;
2576 : }
2577 :
2578 : static list *
2579 65150 : exps_exps_rel_visitor(visitor *v, list *lists, rel_rewrite_fptr rel_rewriter, bool topdown)
2580 : {
2581 65150 : if (list_empty(lists))
2582 : return lists;
2583 130300 : for (node *n = lists->h; n; n = n->next)
2584 65150 : if (n->data && (n->data = exps_rel_visitor(v, n->data, rel_rewriter, topdown)) == NULL)
2585 : return NULL;
2586 : return lists;
2587 : }
2588 :
2589 : static inline sql_rel *
2590 69376628 : do_rel_visitor(visitor *v, sql_rel *rel, rel_rewrite_fptr rel_rewriter, bool topdown)
2591 : {
2592 69376628 : if (rel->exps && (rel->exps = exps_rel_visitor(v, rel->exps, rel_rewriter, topdown)) == NULL)
2593 : return NULL;
2594 69379318 : if ((is_groupby(rel->op) || is_simple_project(rel->op)) && rel->r && (rel->r = exps_rel_visitor(v, rel->r, rel_rewriter, topdown)) == NULL)
2595 : return NULL;
2596 69379317 : int changes = v->changes;
2597 69379317 : rel = rel_rewriter(v, rel);
2598 69377249 : if (rel && rel->exps && v->changes > changes) {
2599 273253 : list_hash_clear(rel->exps);
2600 273246 : if ((is_groupby(rel->op) || is_simple_project(rel->op)) && rel->r)
2601 12326 : list_hash_clear(rel->r);
2602 : }
2603 : return rel;
2604 : }
2605 :
2606 : static inline sql_rel *
2607 69373003 : rel_visitor(visitor *v, sql_rel *rel, rel_rewrite_fptr rel_rewriter, bool topdown)
2608 : {
2609 69373003 : sql_rel *parent = v->parent;
2610 :
2611 69373003 : if (mvc_highwater(v->sql))
2612 0 : return sql_error(v->sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2613 :
2614 69382784 : if (!rel)
2615 : return NULL;
2616 :
2617 69382733 : if (topdown && !(rel = do_rel_visitor(v, rel, rel_rewriter, true)))
2618 : return NULL;
2619 :
2620 69383441 : sql_rel *(*func)(visitor *, sql_rel *, rel_rewrite_fptr) = topdown ? rel_visitor_topdown : rel_visitor_bottomup;
2621 :
2622 69383441 : v->parent = rel;
2623 69383441 : switch(rel->op){
2624 : case op_basetable:
2625 : break;
2626 131565 : case op_table:
2627 131565 : if (IS_TABLE_PROD_FUNC(rel->flag) || rel->flag == TABLE_FROM_RELATION) {
2628 131289 : if (rel->l)
2629 2891 : if ((rel->l = func(v, rel->l, rel_rewriter)) == NULL)
2630 : return NULL;
2631 : }
2632 : break;
2633 4005592 : case op_ddl:
2634 4005592 : if (rel->flag == ddl_output || rel->flag == ddl_create_seq || rel->flag == ddl_alter_seq || rel->flag == ddl_alter_table || rel->flag == ddl_create_table || rel->flag == ddl_create_view) {
2635 407492 : if (rel->l)
2636 403897 : if ((rel->l = func(v, rel->l, rel_rewriter)) == NULL)
2637 : return NULL;
2638 : } else if (rel->flag == ddl_list || rel->flag == ddl_exception) {
2639 14206 : if (rel->l)
2640 10339 : if ((rel->l = func(v, rel->l, rel_rewriter)) == NULL)
2641 : return NULL;
2642 14206 : if (rel->r)
2643 13290 : if ((rel->r = func(v, rel->r, rel_rewriter)) == NULL)
2644 : return NULL;
2645 : } else if (rel->flag == ddl_psm) {
2646 272684 : if ((rel->exps = exps_rel_visitor(v, rel->exps, rel_rewriter, topdown)) == NULL)
2647 : return NULL;
2648 : }
2649 : break;
2650 12696306 : case op_insert:
2651 : case op_update:
2652 : case op_delete:
2653 : case op_merge:
2654 :
2655 : case op_join:
2656 : case op_left:
2657 : case op_right:
2658 : case op_full:
2659 : case op_semi:
2660 : case op_anti:
2661 :
2662 : case op_union:
2663 : case op_inter:
2664 : case op_except:
2665 12696306 : if (rel->l)
2666 12696306 : if ((rel->l = func(v, rel->l, rel_rewriter)) == NULL)
2667 : return NULL;
2668 12696665 : if (rel->r)
2669 12682441 : if ((rel->r = func(v, rel->r, rel_rewriter)) == NULL)
2670 : return NULL;
2671 : break;
2672 2262107 : case op_munion:
2673 6786321 : for (node *n = ((list*)rel->l)->h; n; n = n->next) {
2674 4524214 : if ((n->data = func(v, n->data, rel_rewriter)) == NULL)
2675 : return NULL;
2676 : }
2677 : break;
2678 32706104 : case op_select:
2679 : case op_topn:
2680 : case op_sample:
2681 : case op_project:
2682 : case op_groupby:
2683 : case op_truncate:
2684 32706104 : if (rel->l)
2685 30330227 : if ((rel->l = func(v, rel->l, rel_rewriter)) == NULL)
2686 : return NULL;
2687 : break;
2688 : }
2689 69385154 : v->parent = parent;
2690 :
2691 69385154 : if (!topdown)
2692 43576402 : rel = do_rel_visitor(v, rel, rel_rewriter, false);
2693 : return rel;
2694 : }
2695 :
2696 : sql_rel *
2697 25802100 : rel_visitor_topdown(visitor *v, sql_rel *rel, rel_rewrite_fptr rel_rewriter)
2698 : {
2699 25802100 : v->depth++;
2700 25802100 : rel = rel_visitor(v, rel, rel_rewriter, true);
2701 25803657 : v->depth--;
2702 25803657 : return rel;
2703 : }
2704 :
2705 : sql_rel *
2706 43576491 : rel_visitor_bottomup(visitor *v, sql_rel *rel, rel_rewrite_fptr rel_rewriter)
2707 : {
2708 43576491 : v->depth++;
2709 43576491 : rel = rel_visitor(v, rel, rel_rewriter, false);
2710 43579325 : v->depth--;
2711 43579325 : return rel;
2712 : }
2713 :
2714 : list *
2715 276 : exps_exp_visitor_topdown(visitor *v, sql_rel *rel, list *exps, int depth, exp_rewrite_fptr exp_rewriter, bool relations_topdown)
2716 : {
2717 276 : return exps_exp_visitor(v, rel, exps, depth, exp_rewriter, true, relations_topdown);
2718 : }
2719 :
2720 : list *
2721 531358 : exps_exp_visitor_bottomup(visitor *v, sql_rel *rel, list *exps, int depth, exp_rewrite_fptr exp_rewriter, bool relations_topdown)
2722 : {
2723 531358 : return exps_exp_visitor(v, rel, exps, depth, exp_rewriter, false, relations_topdown);
2724 : }
2725 :
2726 : static bool
2727 74128 : exps_rebind_exp(mvc *sql, sql_rel *rel, list *exps)
2728 : {
2729 74128 : bool ok = true;
2730 :
2731 74128 : if (mvc_highwater(sql)) {
2732 0 : (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2733 0 : return false;
2734 : }
2735 :
2736 74128 : if (list_empty(exps))
2737 : return true;
2738 84639 : for (node *n = exps->h; n && ok; n = n->next)
2739 52128 : ok &= rel_rebind_exp(sql, rel, n->data);
2740 : return ok;
2741 : }
2742 :
2743 : bool
2744 2825077 : rel_rebind_exp(mvc *sql, sql_rel *rel, sql_exp *e)
2745 : {
2746 2848546 : if (mvc_highwater(sql)) {
2747 0 : (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2748 0 : return false;
2749 : }
2750 :
2751 2848546 : switch (e->type) {
2752 23469 : case e_convert:
2753 23469 : return rel_rebind_exp(sql, rel, e->l);
2754 13205 : case e_aggr:
2755 : case e_func:
2756 13205 : return exps_rebind_exp(sql, rel, e->l);
2757 1147050 : case e_cmp:
2758 1147050 : if (e->flag == cmp_in || e->flag == cmp_notin)
2759 8261 : return rel_rebind_exp(sql, rel, e->l) && exps_rebind_exp(sql, rel, e->r);
2760 1140822 : if (e->flag == cmp_or || e->flag == cmp_filter)
2761 19388 : return exps_rebind_exp(sql, rel, e->l) && exps_rebind_exp(sql, rel, e->r);
2762 2259586 : return rel_rebind_exp(sql, rel, e->l) && rel_rebind_exp(sql, rel, e->r) && (!e->f || rel_rebind_exp(sql, rel, e->f));
2763 1623191 : case e_column:
2764 1623191 : if (e->freevar)
2765 : return true;
2766 1623177 : return rel_find_exp(rel, e) != NULL;
2767 41626 : case e_atom:
2768 41626 : return exps_rebind_exp(sql, rel, e->f);
2769 : case e_psm:
2770 : return true;
2771 : }
2772 : return true;
2773 : }
2774 :
2775 : static sql_exp *
2776 409 : _exp_freevar_offset(visitor *v, sql_rel *rel, sql_exp *e, int depth)
2777 : {
2778 409 : (void)rel; (void)depth;
2779 : /* visitor will handle recursion, ie only need to check columns here */
2780 409 : int vf = is_freevar(e);
2781 409 : if (v->changes < vf)
2782 316 : v->changes=vf;
2783 409 : return e;
2784 : }
2785 :
2786 : int
2787 306 : exp_freevar_offset(mvc *sql, sql_exp *e)
2788 : {
2789 306 : bool changed = false;
2790 306 : visitor v = { .sql = sql };
2791 :
2792 306 : (void) changed;
2793 306 : exp_visitor(&v, NULL, e, 0, &_exp_freevar_offset, true, true, &changed);
2794 : /* freevar offset is passed via changes */
2795 306 : return (v.changes);
2796 : }
2797 :
2798 : static sql_exp *
2799 296161 : _exp_has_selfref(visitor *v, sql_rel *rel, sql_exp *e, int depth)
2800 : {
2801 296161 : (void)rel; (void)depth;
2802 296161 : int vf = is_selfref(e);
2803 296161 : if (v->changes < vf)
2804 871 : v->changes=vf;
2805 296161 : return e;
2806 : }
2807 :
2808 : int
2809 184614 : exp_has_selfref(mvc *sql, sql_exp *e)
2810 : {
2811 184614 : bool changed = false;
2812 184614 : visitor v = { .sql = sql };
2813 :
2814 184614 : (void) changed;
2815 184614 : exp_visitor(&v, NULL, e, 0, &_exp_has_selfref, true, true, &changed);
2816 : /* freevar offset is passed via changes */
2817 184614 : return (v.changes);
2818 : }
|