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_select.h"
15 : #include "sql_tokens.h"
16 : #include "sql_privileges.h"
17 : #include "sql_env.h"
18 : #include "sql_decimal.h"
19 : #include "sql_qc.h"
20 : #include "rel_rel.h"
21 : #include "rel_basetable.h"
22 : #include "rel_exp.h"
23 : #include "rel_xml.h"
24 : #include "rel_dump.h"
25 : #include "rel_prop.h"
26 : #include "rel_psm.h"
27 : #include "rel_schema.h"
28 : #include "rel_unnest.h"
29 : #include "rel_sequence.h"
30 : #include "rel_file_loader.h"
31 : #include "rel_optimizer_private.h"
32 :
33 : #define VALUE_FUNC(f) (f->func->type == F_FUNC || f->func->type == F_FILT)
34 : #define check_card(card,f) ((card == card_none && !f->res) || (CARD_VALUE(card) && f->res && VALUE_FUNC(f)) || card == card_loader || (card == card_relation && f->func->type == F_UNION))
35 :
36 : /* return all expressions, with table name == tname */
37 : static list *
38 57824 : rel_table_projections( mvc *sql, sql_rel *rel, char *tname, int level )
39 : {
40 58346 : list *exps;
41 :
42 58346 : if (mvc_highwater(sql))
43 1 : return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
44 :
45 58348 : if (!rel)
46 : return NULL;
47 :
48 58348 : if (!tname)
49 42616 : return _rel_projections(sql, rel, NULL, 1, 0, 1);
50 :
51 15732 : switch(rel->op) {
52 535 : case op_join:
53 : case op_left:
54 : case op_right:
55 : case op_full:
56 535 : exps = rel_table_projections( sql, rel->l, tname, level+1);
57 535 : if (exps)
58 : return exps;
59 20 : return rel_table_projections( sql, rel->r, tname, level+1);
60 502 : case op_semi:
61 : case op_anti:
62 : case op_select:
63 502 : return rel_table_projections( sql, rel->l, tname, level+1);
64 :
65 139 : case op_topn:
66 : case op_sample:
67 : case op_groupby:
68 : case op_union:
69 : case op_except:
70 : case op_inter:
71 : case op_project:
72 139 : if (!is_processed(rel) && level == 0)
73 0 : return rel_table_projections( sql, rel->l, tname, level+1);
74 : /* fall through */
75 : case op_munion:
76 148 : if (!is_processed(rel) && level == 0) {
77 0 : node *n = ((list*)rel->l)->h;
78 0 : if (n)
79 0 : return rel_table_projections(sql, n->data, tname, level+1);
80 : }
81 : /* fall through */
82 : case op_table:
83 : case op_basetable:
84 14695 : if (is_basetable(rel->op) && !rel->exps)
85 14045 : return rel_base_project_all(sql, rel, tname);
86 650 : if (rel->exps) {
87 650 : int rename = 0;
88 650 : node *en;
89 :
90 : /* first check alias */
91 650 : if (!is_base(rel->op) && !level) {
92 131 : list *exps = sa_list(sql->sa);
93 :
94 651 : for (en = rel->exps->h; en && !rename; en = en->next) {
95 520 : sql_exp *e = en->data;;
96 :
97 520 : if ((is_basecol(e) && exp_relname(e) && strcmp(exp_relname(e), tname) == 0) ||
98 285 : (is_basecol(e) && !exp_relname(e) && e->l && strcmp(e->l, tname) == 0)) {
99 235 : if (exp_name(e) && exps_bind_column2(exps, tname, exp_name(e), NULL))
100 : rename = 1;
101 : else
102 234 : append(exps, e);
103 : }
104 : }
105 : }
106 :
107 650 : exps = new_exp_list(sql->sa);
108 5220 : for (en = rel->exps->h; en; en = en->next) {
109 4570 : sql_exp *e = en->data;
110 4570 : if (is_basecol(e) && exp_relname(e) && strcmp(exp_relname(e), tname) == 0) {
111 4275 : if (rename)
112 2 : append(exps, exp_alias_ref(sql, e));
113 : else {
114 4273 : sql_exp *ne = exp_ref(sql, e);
115 4273 : exp_setname(sql, ne, tname, exp_name(e));
116 4273 : append(exps, ne);
117 : }
118 : }
119 4570 : if (is_basecol(e) && !exp_relname(e) && e->l && strcmp(e->l, tname) == 0) {
120 0 : if (rename)
121 0 : append(exps, exp_alias_ref(sql, e));
122 : else {
123 0 : sql_exp *ne = exp_ref(sql, e);
124 0 : exp_setname(sql, ne, tname, exp_name(e));
125 0 : append(exps, ne);
126 : }
127 : }
128 :
129 : }
130 650 : if (exps && list_length(exps))
131 : return exps;
132 : }
133 : /* fall through */
134 : default:
135 : return NULL;
136 : }
137 : }
138 :
139 : static sql_exp *
140 0 : rel_lastexp(mvc *sql, sql_rel *rel )
141 : {
142 0 : sql_exp *e;
143 :
144 0 : if (!is_processed(rel) || is_topn(rel->op) || is_sample(rel->op))
145 0 : rel = rel_parent(rel);
146 0 : assert(list_length(rel->exps));
147 0 : if (rel->op == op_project) {
148 0 : list_hash_clear(rel->exps);
149 0 : return exp_ref(sql, rel->exps->t->data);
150 : }
151 0 : assert(is_project(rel->op));
152 0 : e = rel->exps->t->data;
153 0 : return exp_ref(sql, e);
154 : }
155 :
156 : static sql_rel *
157 37063 : rel_orderby(mvc *sql, sql_rel *l)
158 : {
159 37063 : sql_rel *rel = rel_create(sql->sa);
160 37063 : if (!rel)
161 : return NULL;
162 :
163 37063 : assert(l->op == op_project && !l->r);
164 37063 : rel->l = l;
165 37063 : rel->r = NULL;
166 37063 : rel->op = op_project;
167 37063 : rel->exps = rel_projections(sql, l, NULL, 1, 0);
168 37063 : rel->card = l->card;
169 37063 : rel->nrcols = l->nrcols;
170 37063 : return rel;
171 : }
172 :
173 : /* forward refs */
174 : static sql_rel * rel_setquery(sql_query *query, symbol *sq);
175 : static sql_rel * rel_joinquery(sql_query *query, symbol *sq, list *refs);
176 :
177 : static sql_rel *
178 209379 : rel_table_optname(mvc *sql, sql_rel *sq, symbol *optname, list *refs)
179 : {
180 209379 : sql_rel *osq = sq;
181 209379 : node *ne;
182 :
183 209379 : if (optname && optname->token == SQL_NAME) {
184 17073 : dlist *columnrefs = NULL;
185 17073 : char *tname = optname->data.lval->h->data.sval;
186 17073 : list *l = sa_list(sql->sa);
187 :
188 17073 : columnrefs = optname->data.lval->h->next->data.lval;
189 17073 : if (is_topn(sq->op) || is_sample(sq->op) || ((is_simple_project(sq->op) || is_groupby(sq->op)) && sq->r) || is_base(sq->op)) {
190 138 : sq = rel_project(sql->sa, sq, rel_projections(sql, sq, NULL, 1, 0));
191 138 : osq = sq;
192 : }
193 17073 : if (columnrefs && dlist_length(columnrefs) != list_length(sq->exps))
194 6 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: The number of aliases don't match the number of columns (%d != %d)", dlist_length(columnrefs), sq->nrcols);
195 3860 : if (columnrefs && sq->exps) {
196 3860 : dnode *d = columnrefs->h;
197 :
198 3860 : ne = sq->exps->h;
199 3860 : list_hash_clear(sq->exps);
200 16131 : for (; d && ne; d = d->next, ne = ne->next) {
201 8412 : sql_exp *e = ne->data;
202 :
203 8412 : if (exps_bind_column2(l, tname, d->data.sval, NULL))
204 1 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: Duplicate column name '%s.%s'", tname, d->data.sval);
205 8411 : exp_setname(sql, e, tname, d->data.sval );
206 8411 : if (!is_intern(e))
207 8411 : set_basecol(e);
208 8411 : append(l, e);
209 : }
210 : }
211 17066 : if (!columnrefs && sq->exps) {
212 13207 : ne = sq->exps->h;
213 13207 : list_hash_clear(sq->exps);
214 125967 : for (; ne; ne = ne->next) {
215 99553 : sql_exp *e = ne->data;
216 99553 : char *name = NULL;
217 :
218 99553 : if (!is_intern(e)) {
219 99553 : if (!exp_name(e))
220 109 : name = make_label(sql->sa, ++sql->label);
221 99553 : noninternexp_setname(sql, e, tname, name);
222 99553 : set_basecol(e);
223 : }
224 : }
225 : }
226 17066 : if (refs) { /* if this relation is under a FROM clause, check for duplicate names */
227 17016 : if (list_find(refs, tname, (fcmp) &strcmp))
228 6 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: relation name \"%s\" specified more than once", tname);
229 17010 : assert(tname);
230 17010 : list_append(refs, tname);
231 : }
232 : } else {
233 192306 : if (!is_project(sq->op) || is_topn(sq->op) || is_sample(sq->op) || ((is_simple_project(sq->op) || is_groupby(sq->op)) && sq->r)) {
234 59251 : sq = rel_project(sql->sa, sq, rel_projections(sql, sq, NULL, 1, 1));
235 59251 : osq = sq;
236 : }
237 2404170 : for (ne = osq->exps->h; ne; ne = ne->next) {
238 2211864 : sql_exp *e = ne->data;
239 :
240 2211864 : if (!is_intern(e))
241 2081187 : set_basecol(e);
242 : }
243 : }
244 : return osq;
245 : }
246 :
247 : static sql_rel *
248 101908 : rel_subquery_optname(sql_query *query, symbol *ast, list *refs)
249 : {
250 101908 : mvc *sql = query->sql;
251 101908 : SelectNode *sn = (SelectNode *) ast;
252 101908 : exp_kind ek = {type_value, card_relation, TRUE};
253 101908 : sql_rel *sq = rel_subquery(query, ast, ek);
254 :
255 101908 : assert(ast->token == SQL_SELECT);
256 101908 : if (!sq)
257 : return NULL;
258 :
259 101886 : return rel_table_optname(sql, sq, sn->name, refs);
260 : }
261 :
262 : static void
263 10066 : rel_rename(mvc *sql, sql_rel *nrel, char *rname, sql_rel *brel)
264 : {
265 10066 : assert(is_project(nrel->op));
266 10066 : if (brel) {
267 156 : if (is_project(nrel->op) && nrel->exps) {
268 368 : for (node *ne = nrel->exps->h, *be = brel->exps->h; ne && be; ne = ne->next, be = be->next) {
269 212 : sql_exp *e = ne->data;
270 212 : sql_exp *b = be->data;
271 212 : char *name = NULL;
272 :
273 212 : if (!is_intern(e)) {
274 212 : if (!exp_name(e))
275 0 : name = make_label(sql->sa, ++sql->label);
276 212 : noninternexp_setname(sql, e, rname, name);
277 212 : set_basecol(e);
278 212 : e->alias.label = b->alias.label;
279 : }
280 : }
281 : }
282 156 : list_hash_clear(nrel->exps);
283 9910 : } else if (is_project(nrel->op) && nrel->exps) {
284 9910 : node *ne = nrel->exps->h;
285 :
286 40945 : for (; ne; ne = ne->next) {
287 31035 : sql_exp *e = ne->data;
288 31035 : char *name = NULL;
289 :
290 31035 : if (!is_intern(e)) {
291 31035 : if (!exp_name(e))
292 17 : name = make_label(sql->sa, ++sql->label);
293 31035 : noninternexp_setname(sql, e, rname, name);
294 31035 : set_basecol(e);
295 : }
296 : }
297 9910 : list_hash_clear(nrel->exps);
298 : }
299 10066 : }
300 :
301 : sql_rel *
302 5871 : rel_with_query(sql_query *query, symbol *q )
303 : {
304 5871 : mvc *sql = query->sql;
305 5871 : dnode *d = q->data.lval->h;
306 5871 : symbol *next = d->next->data.sym;
307 5871 : bool recursive = d->next->next->data.i_val;
308 5871 : sql_rel *rel;
309 :
310 5871 : if (!stack_push_frame(sql, NULL))
311 0 : return sql_error(sql, 02, SQLSTATE(HY013) MAL_MALLOC_FAIL);
312 : /* first handle all with's (ie inlined views) */
313 15859 : for (d = d->data.lval->h; d; d = d->next) {
314 10008 : symbol *sym = d->data.sym;
315 10008 : dnode *dn = sym->data.lval->h->next;
316 10008 : char *rname = qname_schema_object(dn->data.lval);
317 10008 : sql_rel *nrel, *base_rel = NULL;
318 10008 : symbol *recursive_part = NULL;
319 10008 : sql_rel_view *recursive_union = NULL;
320 10008 : int recursive_distinct = 0;
321 :
322 10008 : if (frame_find_rel_view(sql, rname)) {
323 3 : stack_pop_frame(sql);
324 3 : return sql_error(sql, 01, SQLSTATE(42000) "View '%s' already declared", rname);
325 : }
326 10005 : if (recursive) {
327 103 : symbol *union_stmt = dn->next->next->data.sym;
328 103 : if (union_stmt->token == SQL_UNION) { /* split in base and recursive part */
329 78 : dnode *n = union_stmt->data.lval->h;
330 78 : symbol *base = n->data.sym;
331 78 : recursive_distinct = n->next->data.i_val;
332 78 : dlist *corresponding = n->next->next->data.lval;
333 78 : recursive_part = n->next->next->next->data.sym;
334 78 : if (corresponding)
335 0 : return sql_error(sql, 01, SQLSTATE(42000) "Recursive with corresponding is not supported");
336 78 : dn->next->next->data.sym = base;
337 : }
338 : }
339 10005 : nrel = rel_semantic(query, sym);
340 10005 : if (!nrel) {
341 17 : stack_pop_frame(sql);
342 17 : return NULL;
343 : }
344 9988 : if (!(recursive_union = stack_push_rel_view(sql, rname, nrel))) {
345 0 : stack_pop_frame(sql);
346 0 : return sql_error(sql, 02, SQLSTATE(HY013) MAL_MALLOC_FAIL);
347 : }
348 9988 : if (recursive && recursive_part) {
349 78 : base_rel = nrel;
350 78 : rel_rename(sql, base_rel, rname, base_rel);
351 78 : dn->next->next->data.sym = recursive_part;
352 78 : set_processed(nrel);
353 78 : nrel = rel_semantic(query, sym);
354 78 : if (!nrel) {
355 0 : stack_pop_frame(sql);
356 0 : return NULL;
357 : }
358 78 : list *ls = rel_projections(sql, base_rel, NULL, 0, 1);
359 78 : list *rs = rel_projections(sql, nrel, NULL, 0, 1);
360 :
361 78 : if (!rel_is_ref(base_rel)) { /* not recursive */
362 3 : nrel = rel_setop_n_ary_check_types(sql, base_rel, nrel, ls, rs, op_munion);
363 : } else {
364 75 : base_rel->used |= statistics_gathered;
365 75 : prop *p = base_rel->p = prop_create(sql->sa, PROP_COUNT, base_rel->p);
366 75 : p->value.lval = 1000000; /* random ? */
367 :
368 : /* down cast the recursive side (on errors users should add casts on the base side) */
369 75 : list *nrs = new_exp_list(sql->sa);
370 75 : if(!nrs)
371 : return NULL;
372 :
373 174 : for (node *n = ls->h, *m = rs->h; n && m; n = n->next, m = m->next) {
374 99 : sql_subtype *t = exp_subtype(n->data);
375 99 : append(nrs, exp_check_type(sql, t, nrel, m->data, type_equal));
376 : }
377 75 : nrel = rel_project(sql->sa, nrel, nrs);
378 75 : nrel = rel_setop_n_ary(sql->sa, append(append(sa_list(sql->sa), base_rel), nrel), op_munion);
379 75 : set_recursive(nrel);
380 : }
381 78 : if (recursive_distinct)
382 34 : set_distinct(nrel);
383 78 : rel_setop_n_ary_set_exps(sql, nrel, rel_projections(sql, nrel, NULL, 0, 1), false);
384 78 : set_processed(nrel);
385 78 : recursive_union->rel_view = rel_dup(nrel); /* extra incref for independent flow */
386 : }
387 9988 : if (!is_project(nrel->op)) {
388 0 : if (is_topn(nrel->op) || is_sample(nrel->op)) {
389 0 : nrel = rel_project(sql->sa, nrel, rel_projections(sql, nrel, NULL, 1, 1));
390 : } else {
391 0 : stack_pop_frame(sql);
392 0 : return NULL;
393 : }
394 : }
395 9988 : rel_rename(sql, nrel, rname, base_rel);
396 : }
397 5851 : rel = rel_semantic(query, next);
398 5851 : stack_pop_frame(sql);
399 5851 : return rel;
400 : }
401 :
402 : static sql_rel *
403 60354 : query_exp_optname(sql_query *query, symbol *q, list *refs)
404 : {
405 60354 : mvc *sql = query->sql;
406 60354 : switch (q->token) {
407 983 : case SQL_WITH:
408 : {
409 983 : sql_rel *tq = rel_with_query(query, q);
410 :
411 983 : if (!tq)
412 : return NULL;
413 983 : if (q->data.lval->t->type == type_symbol)
414 983 : return rel_table_optname(sql, tq, q->data.lval->t->data.sym, refs);
415 : return tq;
416 : }
417 59371 : case SQL_JOIN:
418 : {
419 59371 : sql_rel *tq = rel_joinquery(query, q, refs);
420 :
421 59371 : if (!tq)
422 : return NULL;
423 59332 : return rel_table_optname(sql, tq, q->data.lval->t->data.sym, NULL);
424 : }
425 0 : default:
426 0 : (void) sql_error(sql, 02, SQLSTATE(42000) "case %d %s", (int) q->token, token2string(q->token));
427 : }
428 0 : return NULL;
429 : }
430 :
431 : static sql_subfunc *
432 549841 : bind_func_(mvc *sql, char *sname, char *fname, list *ops, sql_ftype type, bool private, bool *found, bool exact)
433 : {
434 549841 : sql_subfunc *sf = NULL;
435 :
436 550298 : if (sql->forward && strcmp(fname, sql->forward->base.name) == 0 &&
437 459 : list_cmp(sql->forward->ops, ops, (fcmp)&arg_subtype_cmp) == 0 &&
438 4 : execute_priv(sql, sql->forward) && type == sql->forward->type)
439 2 : return sql_dup_subfunc(sql->sa, sql->forward, NULL, NULL);
440 549839 : sf = sql_bind_func_(sql, sname, fname, ops, type, private, exact);
441 549839 : if (found)
442 549300 : *found |= sf != NULL;
443 549839 : if (sf && execute_priv(sql, sf->func))
444 : return sf;
445 : return NULL;
446 : }
447 :
448 : static sql_subfunc *
449 191684 : bind_func(mvc *sql, char *sname, char *fname, sql_subtype *t1, sql_subtype *t2, int nr, sql_ftype type, bool private, bool *found, bool exact)
450 : {
451 191684 : list *tl = sa_list(sql->sa);
452 191684 : assert(nr >= 1 && nr <= 2);
453 191684 : append(tl, t1);
454 191684 : if (nr == 2)
455 156510 : append(tl, t2);
456 191684 : sql_subfunc *sf = NULL;
457 :
458 191684 : if (sql->forward) {
459 22625 : if (execute_priv(sql, sql->forward) &&
460 22625 : strcmp(fname, sql->forward->base.name) == 0 &&
461 0 : ((!t1 && list_length(sql->forward->ops) == 0) ||
462 0 : (!t2 && list_length(sql->forward->ops) == 1 && arg_subtype_cmp(sql->forward->ops->h->data, t1) == 0) ||
463 0 : (list_length(sql->forward->ops) == 2 &&
464 0 : arg_subtype_cmp(sql->forward->ops->h->data, t1) == 0 &&
465 0 : arg_subtype_cmp(sql->forward->ops->h->next->data, t2) == 0)) && type == sql->forward->type) {
466 0 : return sql_dup_subfunc(sql->sa, sql->forward, NULL, NULL);
467 : }
468 : }
469 191684 : sf = sql_bind_func_(sql, sname, fname, tl, type, private, exact);
470 191684 : if (found)
471 191684 : *found |= sf != NULL;
472 191684 : if (sf && execute_priv(sql, sf->func))
473 : return sf;
474 : return NULL;
475 : }
476 :
477 : static sql_subfunc *
478 653830 : find_func(mvc *sql, char *sname, char *fname, int len, sql_ftype type, bool private, sql_subfunc *prev, bool *found)
479 : {
480 653830 : sql_subfunc *sf = NULL;
481 :
482 653830 : if (sql->forward && strcmp(fname, sql->forward->base.name) == 0 && list_length(sql->forward->ops) == len && execute_priv(sql, sql->forward) && type == sql->forward->type)
483 0 : return sql_dup_subfunc(sql->sa, sql->forward, NULL, NULL);
484 653830 : sf = sql_find_func(sql, sname, fname, len, type, private, prev);
485 653830 : if (found)
486 0 : *found |= sf != NULL;
487 653830 : if (sf && execute_priv(sql, sf->func))
488 : return sf;
489 : return NULL;
490 : }
491 :
492 : static sql_exp *
493 713075 : exp_fix_scale(mvc *sql, sql_subtype *ct, sql_exp *e)
494 : {
495 713075 : sql_subtype *et = exp_subtype(e);
496 :
497 713075 : if (ct->type->scale == SCALE_FIX && et->type->scale == SCALE_FIX) {
498 85152 : int scale_diff = ((int) ct->scale - (int) et->scale);
499 :
500 85152 : if (scale_diff) {
501 132 : if (scale_diff < 0)
502 : return e;
503 102 : sql_subtype st;
504 102 : int scale = ct->scale;
505 102 : int digits = ((et->type->eclass == EC_NUM)?bits2digits(et->digits):et->digits)-et->scale+scale;
506 102 : (void)sql_find_subtype(&st, ct->type->base.name, digits, scale);
507 102 : return exp_convert(sql, e, et, &st);
508 : }
509 : }
510 : return e;
511 : }
512 :
513 : static lng
514 9733 : rel_get_count(sql_rel *rel)
515 : {
516 31322 : if (!rel)
517 : return 0;
518 31318 : prop *p = NULL;
519 31318 : if (rel->p && (p = find_prop(rel->p, PROP_COUNT)) != NULL)
520 3073 : return p->value.lval;
521 28245 : else if(is_munion(rel->op)) {
522 174 : lng cnt = 0;
523 174 : list *l = rel->l;
524 522 : for (node *n = l->h; n; n = n->next) {
525 348 : lng lcnt = rel_get_count(n->data);
526 348 : if (lcnt == BUN_MAX)
527 : return BUN_MAX;
528 348 : cnt += lcnt;
529 : }
530 174 : return cnt;
531 28071 : } else if(rel->l) {
532 25387 : if (is_select(rel->op) || is_project(rel->op))
533 : return rel_get_count(rel->l);
534 : }
535 : return 0;
536 : }
537 :
538 : #define is_sum_aggr(f) (f->type == F_AGGR && strcmp(f->base.name, "sum") == 0)
539 :
540 : list *
541 753739 : check_arguments_and_find_largest_any_type(mvc *sql, sql_rel *rel, list *exps, sql_subfunc *sf, int maybe_zero_or_one, bool internal)
542 : {
543 753739 : list *nexps = new_exp_list(sql->sa);
544 753740 : sql_subtype *atp = NULL, super, *res = !list_empty(sf->res) ? sf->res->h->data: NULL;
545 753740 : unsigned int digits = 0, scale = 0;
546 :
547 : /* find largest any type argument */
548 2226192 : for (node *n = exps->h, *m = sf->func->ops->h; n && m; n = n->next, m = m->next) {
549 1472454 : sql_arg *a = m->data;
550 1472454 : sql_exp *e = n->data;
551 1472454 : sql_subtype *t = exp_subtype(e);
552 :
553 1472452 : if (a->type.type->eclass == EC_ANY) {
554 267679 : if (t && atp) {
555 117342 : supertype(&super, t, atp);
556 117342 : atp = &super;
557 150337 : } else if (t) {
558 : atp = t;
559 : }
560 : }
561 1472449 : if (t && sf->func->fix_scale == SCALE_FIX && t->type->eclass == EC_DEC) {
562 1260 : if (digits < t->digits)
563 : digits = t->digits;
564 1260 : if (scale < t->scale)
565 : scale = t->scale;
566 : }
567 : }
568 753738 : if (!atp && !list_empty(exps))
569 601552 : atp = exp_subtype(exps->h->data);
570 :
571 753740 : if ((atp && atp->type->localtype == TYPE_void) || !atp) /* NULL */
572 11917 : atp = sql_bind_localtype("str");
573 :
574 753740 : node *n, *m;
575 753740 : sql_arg *last = NULL;
576 3698738 : for (n = exps->h, m = sf->func->ops->h; n && ((sf->func->vararg && last) || m); n = n->next, m = m?m->next:NULL) {
577 1472499 : sql_arg *a = m?m->data:last;
578 1472499 : sql_exp *e = n->data;
579 1472499 : sql_subtype *ntp = &a->type, *t = exp_subtype(e);
580 :
581 1472499 : last = a;
582 1472499 : if (!t) {
583 38 : if (a->type.type->eclass == EC_ANY && atp)
584 3 : ntp = sql_create_subtype(sql->sa, atp->type, atp->digits, atp->scale);
585 61 : rel_set_type_param(sql, ntp, rel, e, sf->func->fix_scale != INOUT && !UDF_LANG(sf->func->lang));
586 1472461 : } else if (a->type.type->eclass == EC_ANY && atp) {
587 267723 : ntp = sql_create_subtype(sql->sa, atp->type, atp->digits, atp->scale);
588 1204738 : } else if (t && ntp->digits == 0 && EC_VARCHAR(a->type.type->eclass)) {
589 527384 : ntp = sql_create_subtype(sql->sa, a->type.type, type_digits_to_char_digits(t), 0);
590 677354 : } else if (t && ntp->digits > 0 && a->type.type->eclass == EC_NUM && t->type->eclass == EC_NUM) {
591 365182 : ntp = sql_create_subtype(sql->sa, a->type.type, t->digits, 0);
592 312172 : } else if (t && ntp->scale == 0 && ntp->type->eclass == EC_DEC && EC_VARCHAR(t->type->eclass)) {
593 0 : sql_subtype *res = SA_NEW(sql->sa, sql_subtype);
594 0 : int digits = t->digits?t->digits+3:ntp->digits;
595 0 : (void)sql_find_subtype(res, a->type.type->base.name, digits, 3);
596 0 : ntp = res;
597 312172 : } else if (t && ntp->scale == 0 && ntp->type->eclass == EC_DEC) {
598 4875 : ntp = sql_create_subtype(sql->sa, a->type.type, t->type->eclass == EC_NUM?bits2digits(t->digits):t->digits, t->scale);
599 307297 : } else if (t->type == ntp->type) {
600 305192 : ntp = t;
601 : }
602 1472499 : if (!(e = exp_check_type(sql, ntp, rel, e, type_equal)))
603 : return NULL;
604 1472499 : if (sf->func->fix_scale == SCALE_FIX) {
605 534037 : ntp = sql_create_subtype(sql->sa, a->type.type->localtype?a->type.type:t?t->type:atp->type, digits, scale);
606 534037 : e = exp_fix_scale(sql, ntp, e);
607 938462 : } else if (sf->func->fix_scale == SCALE_EQ) {
608 179038 : e = exp_fix_scale(sql, &a->type, e);
609 : }
610 1472499 : if (maybe_zero_or_one && e->card > CARD_ATOM) {
611 22 : sql_subfunc *zero_or_one = sql_bind_func(sql, "sys", "zero_or_one", exp_subtype(e), NULL, F_AGGR, true, false);
612 22 : e = exp_aggr1(sql->sa, e, zero_or_one, 0, 0, CARD_ATOM, has_nil(e));
613 : }
614 1472499 : append(nexps, e);
615 : }
616 : /* handle any extra arguments for rel_dump/analytic funcs */
617 753962 : for ( ; n; n = n->next)
618 223 : append(nexps, n->data);
619 753739 : if (sf->func->fix_scale == SCALE_FIX || IS_ANALYTIC(sf->func)) {
620 269501 : exps_scale_fix(sf, nexps, atp);
621 484238 : } else if (sf->func->fix_scale == MAX_BITS) {
622 113665 : exps_max_bits(sf, nexps);
623 370573 : } else if (sf->func->fix_scale == SCALE_MUL) {
624 25254 : exps_sum_scales(sf, nexps);
625 345319 : } else if (!internal && sf->func->fix_scale == SCALE_DIV) {
626 2613 : if (!exps_scale_algebra(sql, sf, rel, nexps))
627 : return NULL;
628 342706 : } else if (sf->func->fix_scale == DIGITS_ADD) {
629 186616 : exps_digits_add(sf, nexps);
630 156090 : } else if (sf->func->fix_scale == INOUT) {
631 19444 : exps_inout(sf, nexps);
632 136646 : } else if (is_sum_aggr(sf->func))
633 9385 : exps_largest_int(sf, nexps, rel_get_count(rel));
634 :
635 : /* dirty hack */
636 753737 : if (sf->func->type != F_PROC && sf->func->type != F_UNION && sf->func->type != F_LOADER && res) {
637 747850 : if (res->type->eclass == EC_ANY && atp)
638 73 : sf->res->h->data = sql_create_subtype(sql->sa, atp->type, atp->digits, atp->scale);
639 : }
640 : return nexps;
641 : }
642 :
643 : static char *
644 283 : nary_function_arg_types_2str(mvc *sql, list* types, int N)
645 : {
646 283 : char *arg_list = NULL;
647 283 : int i = 0;
648 :
649 764 : for (node *n = types->h; n && i < N; n = n->next) {
650 481 : sql_subtype *t = (sql_subtype *) n->data;
651 481 : char *tpe = t ? sql_subtype_string(sql->ta, t) : "?";
652 :
653 481 : if (arg_list) {
654 215 : arg_list = sa_message(sql->ta, "%s, %s", arg_list, tpe);
655 : } else {
656 : arg_list = tpe;
657 : }
658 481 : i++;
659 : }
660 283 : return arg_list;
661 : }
662 :
663 : static char *
664 35 : file_loader_add_table_column_types(mvc *sql, sql_subfunc *f, list *exps, list *res_exps, char *tname)
665 : {
666 35 : sql_exp *file = exps->h->data;
667 35 : if (!exp_is_atom(file))
668 : return "Filename missing";
669 :
670 35 : atom *a = file->l;
671 35 : if (a->data.vtype != TYPE_str || !a->data.val.sval)
672 : return "Filename missing";
673 :
674 35 : char *filename = a->data.val.sval;
675 35 : if (strcmp(filename, "") == 0)
676 : return "Filename missing";
677 :
678 33 : char *ext = strrchr(filename, '.'), *ep = ext;
679 :
680 33 : if (ext) {
681 30 : ext = ext + 1;
682 30 : ext = mkLower(sa_strdup(sql->sa, ext));
683 : }
684 30 : if (!ext)
685 3 : return "Filename extension missing";
686 :
687 30 : file_loader_t *fl = fl_find(ext);
688 30 : if (!fl) {
689 : /* maybe compressed */
690 10 : char *p = ep - 1;
691 66 : while (p > filename && *p != '.')
692 56 : p--;
693 10 : if (p != filename) {
694 8 : ext = p + 1;
695 8 : ext = sa_strdup(sql->sa, ext);
696 8 : char *d = strchr(ext, '.');
697 8 : assert(d);
698 8 : *d = 0;
699 8 : fl = fl_find(ext);
700 : }
701 10 : if (!fl) /* fallback */
702 2 : fl = fl_find("csv");
703 2 : if (!fl) /* not expected */
704 0 : return sa_message(sql->ta, "Filename extension '%s' missing", ext?ext:"");
705 : }
706 30 : str err = fl->add_types(sql, f, filename, res_exps, tname);
707 30 : if (err)
708 : return err;
709 16 : sql_subtype *st = sql_bind_localtype("str");
710 16 : sql_exp *ext_exp = exp_atom(sql->sa, atom_string(sql->sa, st, ext));
711 16 : if (!ext_exp)
712 : return MAL_MALLOC_FAIL;
713 16 : append(exps, ext_exp);
714 16 : return NULL;
715 : }
716 :
717 : static sql_rel *
718 35 : rel_file_loader(mvc *sql, list *exps, list *tl, char *tname)
719 : {
720 35 : sql_subfunc *f = NULL;
721 35 : bool found = false;
722 :
723 35 : if ((f = bind_func_(sql, NULL, "file_loader", tl, F_UNION, true, &found, false))) {
724 35 : list *nexps = exps;
725 35 : if (list_empty(tl) || (nexps = check_arguments_and_find_largest_any_type(sql, NULL, exps, f, 1, false))) {
726 35 : list *res_exps = sa_list(sql->sa);
727 35 : if (list_length(exps) == 1 && f && f->func->varres && strlen(f->func->mod) == 0 && strlen(f->func->imp) == 0) {
728 35 : char *err = file_loader_add_table_column_types(sql, f, nexps, res_exps, tname);
729 35 : if (err)
730 19 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: file_loader function failed '%s'", err);
731 : }
732 16 : sql_exp *e = exp_op(sql->sa, nexps, f);
733 16 : sql_rel *rel = rel_table_func(sql->sa, NULL, e, res_exps, TABLE_PROD_FUNC);
734 16 : if (rel)
735 16 : rel = rel_project(sql->sa, rel, exps_alias(sql, res_exps));
736 16 : return rel;
737 : }
738 : }
739 : return NULL;
740 : }
741 :
742 : sql_exp *
743 10805 : find_table_function(mvc *sql, char *sname, char *fname, list *exps, list *tl, sql_ftype type)
744 : {
745 10805 : bool found = false;
746 10805 : sql_subfunc *f = NULL;
747 :
748 10805 : assert(type == F_UNION || type == F_LOADER);
749 10805 : if ((f = bind_func_(sql, sname, fname, tl, type, false, &found, false))) {
750 10785 : list *nexps = exps;
751 10785 : if (list_empty(tl) || (nexps = check_arguments_and_find_largest_any_type(sql, NULL, exps, f, 1, false)))
752 10785 : return exp_op(sql->sa, nexps, f);
753 0 : found = false;
754 : }
755 20 : char *arg_list = list_length(tl) ? nary_function_arg_types_2str(sql, tl, list_length(tl)) : NULL;
756 55 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s %s function %s%s%s'%s'(%s)",
757 20 : found ? "insufficient privileges for" : "no such", type == F_UNION ? "table returning" : "loader", sname ? "'":"", sname ? sname : "",
758 : sname ? "'.":"", fname, arg_list ? arg_list : "");
759 : }
760 :
761 : static sql_rel *
762 10821 : rel_named_table_function(sql_query *query, sql_rel *rel, symbol *ast, int lateral, list *refs)
763 : {
764 10821 : mvc *sql = query->sql;
765 10821 : list *exps = NULL, *tl;
766 10821 : node *m;
767 10821 : exp_kind ek = {type_value, card_relation, TRUE};
768 10821 : sql_rel *sq = NULL, *outer = NULL;
769 10821 : sql_exp *e = NULL;
770 10821 : sql_subfunc *sf = NULL;
771 10821 : symbol *sym = ast->data.lval->h->data.sym, *subquery = NULL;
772 10821 : dnode *l = sym->data.lval->h, *n;
773 10821 : char *tname = NULL;
774 10821 : char *fname = qname_schema_object(l->data.lval);
775 10821 : char *sname = qname_schema(l->data.lval);
776 :
777 10821 : tl = sa_list(sql->sa);
778 10821 : exps = sa_list(sql->sa);
779 10821 : if (l->next)
780 10821 : l = l->next; /* skip distinct */
781 10821 : if (l->next) { /* table call with subquery */
782 10821 : int is_value = 1;
783 10821 : if (l->next->type == type_symbol || l->next->type == type_list) {
784 10821 : exp_kind iek = {type_value, card_set, TRUE};
785 10821 : int count = 0;
786 :
787 10821 : if (l->next->type == type_symbol)
788 : n = l->next;
789 : else
790 10821 : n = l->next->data.lval?l->next->data.lval->h:NULL;
791 :
792 13505 : for (dnode *m = n; m; m = m->next) {
793 2684 : if (m->type == type_symbol && m->data.sym->token == SQL_SELECT)
794 2684 : subquery = m->data.sym;
795 2684 : count++;
796 : }
797 10821 : if (subquery && count > 1)
798 17 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: The input for the table returning function %s%s%s'%s' must be either a single sub query, or a list of values",
799 : sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname);
800 :
801 10816 : if (subquery) {
802 40 : if (!(sq = rel_subquery(query, subquery, ek)))
803 : return NULL;
804 : is_value = 0;
805 : } else {
806 13399 : for ( ; n; n = n->next) {
807 2629 : sql_exp *e = rel_value_exp(query, &outer, n->data.sym, sql_sel | sql_from, iek);
808 :
809 2629 : if (!e)
810 : return NULL;
811 2623 : append(exps, e);
812 2623 : is_value &= exp_is_atom(e);
813 : }
814 10770 : if (!is_value || (lateral && outer))
815 14 : sq = rel_project(sql->sa, NULL, exps);
816 14 : if (lateral && outer) {
817 0 : sq = rel_crossproduct(sql->sa, sq, outer, op_join);
818 0 : set_dependent(sq);
819 0 : set_processed(sq);
820 : }
821 : }
822 : }
823 10809 : if (!is_value && (!sq || (!lateral && outer)))
824 0 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: no such table returning function %s%s%s'%s'", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname);
825 10809 : if (!is_value) {
826 53 : if (list_length(exps))
827 14 : exps = sa_list(sql->sa);
828 171 : for (node *en = sq->exps->h; en; en = en->next) {
829 118 : sql_exp *e = en->data;
830 :
831 118 : if (!e->alias.label)
832 28 : exp_label(sql->sa, e, ++sql->label);
833 118 : sql_exp *ne = exp_ref(sql, e);
834 : /* allow for table functions with table input */
835 118 : ne->card = CARD_ATOM;
836 118 : exp_setname(sql, ne, tname, exp_name(e));
837 118 : append(exps, ne);
838 118 : append(tl, exp_subtype(e));
839 : }
840 : } else {
841 13354 : for (node *en = exps->h; en; en = en->next)
842 2598 : append(tl, exp_subtype(en->data));
843 : }
844 : }
845 :
846 10809 : rel = NULL;
847 10809 : if (ast->data.lval->t->type == type_symbol && ast->data.lval->t->data.sym)
848 1219 : tname = ast->data.lval->t->data.sym->data.lval->h->data.sval;
849 : else
850 9590 : tname = make_label(sql->sa, ++sql->label);
851 :
852 10809 : if (!sname && strcmp(fname, "file_loader") == 0) {
853 35 : rel = rel_file_loader(sql, exps, tl, tname);
854 35 : if (!rel)
855 : return NULL;
856 20537 : } else if (!(e = find_table_function(sql, sname, fname, list_empty(exps) ? NULL : exps, tl, F_UNION)))
857 : return NULL;
858 :
859 10755 : if (!rel) {
860 10755 : rel = sq;
861 :
862 : /* column or table function */
863 10755 : sf = e->f;
864 10755 : if (e->type != e_func || sf->func->type != F_UNION)
865 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: '%s' does not return a table", exp_func_name(e));
866 :
867 10755 : if (sq) {
868 171 : for (node *n = sq->exps->h, *m = sf->func->ops->h ; n && m ; n = n->next, m = m->next) {
869 118 : sql_exp *e = (sql_exp*) n->data;
870 118 : sql_arg *a = (sql_arg*) m->data;
871 118 : if (!exp_subtype(e) && rel_set_type_param(sql, &(a->type), sq, e, 0) < 0)
872 : return NULL;
873 : }
874 : }
875 :
876 : /* for each column add table.column name */
877 10755 : exps = new_exp_list(sql->sa);
878 106173 : for (m = sf->func->res->h; m; m = m->next) {
879 95418 : sql_arg *a = m->data;
880 95418 : sql_exp *e = exp_column(sql->sa, tname, a->name, &a->type, CARD_MULTI, 1, 0, 0);
881 95418 : e->alias.label = -(sql->nid++);
882 :
883 95418 : set_basecol(e);
884 95418 : append(exps, e);
885 : }
886 21457 : rel = rel_table_func(sql->sa, rel, e, exps, (sq)?TABLE_FROM_RELATION:TABLE_PROD_FUNC);
887 : }
888 10771 : if (ast->data.lval->t->type == type_symbol && ast->data.lval->t->data.sym && ast->data.lval->t->data.sym->data.lval->h->next->data.lval) {
889 49 : rel = rel_table_optname(sql, rel, ast->data.lval->t->data.sym, refs);
890 10722 : } else if (refs) { /* if this relation is under a FROM clause, check for duplicate names */
891 10722 : if (list_find(refs, tname, (fcmp) &strcmp))
892 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: relation name \"%s\" specified more than once", tname);
893 10722 : list_append(refs, tname);
894 : }
895 : return rel;
896 : }
897 :
898 : static sql_exp*
899 4161 : exp_tuples_set_supertype(mvc *sql, list *tuple_values, sql_exp *tuples)
900 : {
901 4161 : assert(is_values(tuples));
902 4161 : list *vals = exp_get_values(tuples);
903 4161 : if (!vals || !vals->h)
904 : return NULL;
905 :
906 4161 : int tuple_width = list_length(tuple_values), i;
907 4161 : sql_subtype *types = SA_NEW_ARRAY(sql->sa, sql_subtype, tuple_width);
908 4161 : bool *has_type = SA_NEW_ARRAY(sql->sa, bool, tuple_width);
909 4161 : node *n;
910 :
911 4161 : memset(has_type, 0, sizeof(bool)*tuple_width);
912 13555 : for(n = tuple_values->h, i = 0; n; n = n->next, i++) {
913 9394 : sql_exp *e = n->data;
914 9394 : if (exp_subtype(e)) {
915 9392 : types[i] = *exp_subtype(e);
916 9392 : has_type[i] = 1;
917 : }
918 : }
919 :
920 8324 : for (node *m = vals->h; m; m = m->next) {
921 4163 : sql_exp *tuple = m->data;
922 4163 : if (is_values(tuple)) {
923 0 : list *exps = tuple->f;
924 0 : for(n = exps->h, i = 0; n; n = n->next, i++) {
925 0 : sql_subtype *tpe;
926 0 : sql_exp *e = n->data;
927 :
928 0 : if (has_type[i] && e->type == e_atom && !e->l && !e->r && !e->f && !e->tpe.type) {
929 0 : if (set_type_param(sql, types+i, e->flag) == 0)
930 0 : e->tpe = types[i];
931 : else
932 : return NULL;
933 : }
934 0 : tpe = exp_subtype(e);
935 0 : if (!tpe)
936 : return NULL;
937 0 : if (has_type[i] && tpe) {
938 0 : supertype(types+i, types+i, tpe);
939 : } else {
940 0 : has_type[i] = 1;
941 0 : types[i] = *tpe;
942 : }
943 : }
944 : } else {
945 4163 : sql_rel *tuple_relation = exp_rel_get_rel(sql->sa, tuple);
946 :
947 13561 : for(n = tuple_relation->exps->h, i = 0; n; n = n->next, i++) {
948 9398 : sql_subtype *tpe;
949 9398 : sql_exp *e = n->data;
950 :
951 9398 : if (has_type[i] && e->type == e_atom && !e->l && !e->r && !e->f && !e->tpe.type) {
952 5 : if (set_type_param(sql, types+i, e->flag) == 0)
953 5 : e->tpe = types[i];
954 : else
955 : return NULL;
956 : }
957 9398 : tpe = exp_subtype(e);
958 9398 : if (!tpe)
959 : return NULL;
960 9398 : if (has_type[i] && tpe) {
961 9396 : cmp_supertype(types+i, types+i, tpe);
962 : } else {
963 2 : has_type[i] = 1;
964 2 : types[i] = *tpe;
965 : }
966 : }
967 : }
968 : }
969 :
970 8324 : for (node *m = vals->h; m; m = m->next) {
971 4163 : sql_exp *tuple = m->data;
972 4163 : if (is_values(tuple)) {
973 0 : list *exps = tuple->f;
974 0 : list *nexps = sa_list(sql->sa);
975 0 : for(n = exps->h, i = 0; n; n = n->next, i++) {
976 0 : sql_exp *e = n->data;
977 :
978 0 : e = exp_check_type(sql, types+i, NULL, e, type_equal);
979 0 : if (!e)
980 : return NULL;
981 0 : exp_label(sql->sa, e, ++sql->label);
982 0 : append(nexps, e);
983 : }
984 0 : tuple->f = nexps;
985 : } else {
986 4163 : sql_rel *tuple_relation = exp_rel_get_rel(sql->sa, tuple);
987 :
988 4163 : list *nexps = sa_list(sql->sa);
989 13561 : for(n = tuple_relation->exps->h, i = 0; n; n = n->next, i++) {
990 9398 : sql_exp *e = n->data;
991 :
992 9398 : e = exp_check_type(sql, types+i, NULL, e, type_equal);
993 9398 : if (!e)
994 : return NULL;
995 9398 : append(nexps, e);
996 : }
997 4163 : tuple_relation->exps = nexps;
998 : }
999 : }
1000 : return tuples;
1001 : }
1002 :
1003 : static int
1004 9394 : rel_binop_check_types(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *rs, int upcast)
1005 : {
1006 9394 : sql_subtype *t1 = exp_subtype(ls), *t2 = exp_subtype(rs);
1007 :
1008 9394 : if (!t1 || !t2) {
1009 2 : if (t2 && !t1 && rel_set_type_param(sql, t2, rel, ls, upcast) < 0)
1010 : return -1;
1011 2 : if (t1 && !t2 && rel_set_type_param(sql, t1, rel, rs, upcast) < 0)
1012 : return -1;
1013 : }
1014 9394 : if (!exp_subtype(ls) && !exp_subtype(rs)) {
1015 0 : (void) sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) on both sides of an expression");
1016 0 : return -1;
1017 : }
1018 : return 0;
1019 : }
1020 :
1021 : static list *
1022 4161 : tuples_check_types(mvc *sql, list *tuple_values, sql_exp *tuples)
1023 : {
1024 4161 : list *tuples_list = exp_get_values(tuples);
1025 4161 : sql_exp *first_tuple = tuples_list->h->data;
1026 4161 : list *nvalues = sa_list(sql->sa);
1027 4161 : if (is_values(first_tuple)) {
1028 0 : list *vals = first_tuple->f;
1029 :
1030 0 : for (node *n = tuple_values->h, *m = vals->h; n && m; n = n->next, m = m->next) {
1031 0 : sql_exp *le = n->data, *re = m->data;
1032 :
1033 0 : if (rel_binop_check_types(sql, NULL, le, re, 0) < 0)
1034 : return NULL;
1035 0 : if ((le = exp_check_type(sql, exp_subtype(re), NULL, le, type_equal)) == NULL)
1036 : return NULL;
1037 0 : append(nvalues, le);
1038 : }
1039 : return nvalues;
1040 : } else {
1041 4161 : sql_rel *tuple_relation = exp_rel_get_rel(sql->sa, first_tuple);
1042 :
1043 4161 : assert(list_length(tuple_values) == list_length(tuple_relation->exps));
1044 13555 : for (node *n = tuple_values->h, *m = tuple_relation->exps->h; n && m; n = n->next, m = m->next) {
1045 9394 : sql_exp *le = n->data, *re = m->data;
1046 :
1047 9394 : if (rel_binop_check_types(sql, NULL, le, re, 0) < 0)
1048 : return NULL;
1049 9394 : if ((le = exp_check_type(sql, exp_subtype(re), NULL, le, type_equal)) == NULL)
1050 : return NULL;
1051 9394 : append(nvalues, le);
1052 : }
1053 : return nvalues;
1054 : }
1055 : return tuple_values;
1056 : }
1057 :
1058 : static sql_rel *
1059 3838 : rel_values(sql_query *query, symbol *tableref, list *refs)
1060 : {
1061 3838 : mvc *sql = query->sql;
1062 3838 : sql_rel *r = NULL;
1063 3838 : symbol *values = tableref;
1064 3838 : symbol *optname = NULL;
1065 3838 : if (tableref->token == SQL_TABLE) {
1066 1333 : values = tableref->data.lval->h->data.sym;
1067 1333 : optname = tableref->data.lval->t->type == type_symbol ? tableref->data.lval->t->data.sym : NULL;
1068 : }
1069 3838 : dlist *rowlist = values->data.lval;
1070 3838 : node *m;
1071 3838 : list *exps = sa_list(sql->sa);
1072 3838 : exp_kind ek = {type_value, card_value, TRUE};
1073 :
1074 15401 : for (dnode *o = rowlist->h; o; o = o->next) {
1075 11573 : dlist *values = o->data.lval;
1076 :
1077 11573 : if (!list_empty(exps) && list_length(exps) != dlist_length(values)) {
1078 3 : return sql_error(sql, 02, SQLSTATE(42000) "VALUES: number of columns doesn't match between rows");
1079 : } else {
1080 11570 : dnode *n;
1081 :
1082 11570 : if (list_empty(exps)) {
1083 10990 : for (n = values->h; n; n = n->next) {
1084 7152 : sql_exp *vals = exp_values(sql->sa, sa_list(sql->sa));
1085 :
1086 7152 : exp_label(sql->sa, vals, ++sql->label);
1087 7152 : list_append(exps, vals);
1088 : }
1089 : }
1090 35466 : for (n = values->h, m = exps->h; n && m; n = n->next, m = m->next) {
1091 23903 : sql_exp *vals = m->data;
1092 23903 : list *vals_list = vals->f;
1093 23903 : sql_exp *e = rel_value_exp(query, NULL, n->data.sym, sql_sel | sql_values, ek);
1094 23902 : if (!e)
1095 : return NULL;
1096 23895 : list_append(vals_list, e);
1097 : }
1098 : }
1099 : }
1100 :
1101 : /* loop to check types and cardinality */
1102 3828 : unsigned int card = exps->h && list_length(((sql_exp*)exps->h->data)->f) > 1 ? CARD_MULTI : CARD_ATOM;
1103 10963 : for (m = exps->h; m; m = m->next) {
1104 7138 : sql_exp *e = m->data;
1105 :
1106 7138 : if (!(e = exp_values_set_supertype(sql, e, NULL)))
1107 : return NULL;
1108 7135 : e->card = card;
1109 7135 : m->data = e;
1110 : }
1111 :
1112 3825 : r = rel_project(sql->sa, NULL, exps);
1113 3825 : r->nrcols = list_length(exps);
1114 3825 : r->card = card;
1115 3825 : return rel_table_optname(sql, r, optname, refs);
1116 : }
1117 :
1118 : static int
1119 509423 : check_is_lateral(symbol *tableref)
1120 : {
1121 509423 : if (tableref->token == SQL_NAME || tableref->token == SQL_TABLE ||
1122 : tableref->token == SQL_VALUES) {
1123 458966 : if (dlist_length(tableref->data.lval) == 3)
1124 458968 : return tableref->data.lval->h->next->data.i_val;
1125 : return 0;
1126 : } else if (tableref->token == SQL_WITH) {
1127 981 : if (dlist_length(tableref->data.lval) == 5)
1128 16 : return tableref->data.lval->h->next->next->next->data.i_val;
1129 : return 0;
1130 : } else if (tableref->token == SQL_SELECT) {
1131 2292 : SelectNode *sn = (SelectNode *) tableref;
1132 2292 : return sn->lateral;
1133 : } else if (tableref->token == SQL_EXCEPT || tableref->token == SQL_INTERSECT ||
1134 : tableref->token == SQL_UNION) {
1135 10990 : if (dlist_length(tableref->data.lval) == 6)
1136 9253 : return tableref->data.lval->h->next->next->next->next->data.i_val;
1137 : return 0;
1138 : } else {
1139 : return 0;
1140 : }
1141 : }
1142 :
1143 : static sql_rel *
1144 25 : rel_reduce_on_column_privileges(mvc *sql, sql_rel *rel, sql_table *t)
1145 : {
1146 25 : list *exps = sa_list(sql->sa);
1147 :
1148 99 : for (node *n = rel->exps->h, *m = ol_first_node(t->columns); n && m; n = n->next, m = m->next) {
1149 74 : sql_exp *e = n->data;
1150 74 : sql_column *c = m->data;
1151 :
1152 74 : if (column_privs(sql, c, PRIV_SELECT))
1153 12 : append(exps, e);
1154 : }
1155 25 : if (!list_empty(exps)) {
1156 9 : rel->exps = exps;
1157 9 : return rel;
1158 : }
1159 : return NULL;
1160 : }
1161 :
1162 : sql_rel *
1163 697997 : table_ref(sql_query *query, symbol *tableref, int lateral, list *refs)
1164 : {
1165 697997 : mvc *sql = query->sql;
1166 697997 : char *tname = NULL;
1167 697997 : sql_table *t = NULL;
1168 697997 : sql_rel *res = NULL;
1169 :
1170 697997 : if (tableref->token == SQL_NAME) {
1171 480255 : dlist *name = tableref->data.lval->h->data.lval;
1172 480255 : sql_rel *temp_table = NULL;
1173 480255 : char *sname = qname_schema(name);
1174 480271 : int allowed = 1;
1175 :
1176 480271 : tname = qname_schema_object(name);
1177 :
1178 480268 : if (dlist_length(name) > 2)
1179 4 : return sql_error(sql, 02, SQLSTATE(3F000) "SELECT: only a schema and table name expected");
1180 :
1181 480258 : if (!sname)
1182 109940 : temp_table = stack_find_rel_view(sql, tname);
1183 109940 : if (!temp_table)
1184 467423 : t = find_table_or_view_on_scope(sql, NULL, sname, tname, "SELECT", false);
1185 480258 : if (!t && !temp_table)
1186 : return NULL;
1187 480151 : if (!temp_table && !table_privs(sql, t, PRIV_SELECT))
1188 480147 : allowed = 0;
1189 :
1190 480147 : if (tableref->data.lval->t->type == type_symbol && tableref->data.lval->t->data.sym) /* AS */
1191 283679 : tname = tableref->data.lval->t->data.sym->data.lval->h->data.sval;
1192 480147 : if (temp_table && !t) {
1193 12833 : node *n;
1194 12833 : int needed = !is_simple_project(temp_table->op);
1195 :
1196 12833 : if (is_basetable(temp_table->op) && !temp_table->exps) {
1197 0 : if (strcmp(rel_base_name(temp_table), tname) != 0)
1198 0 : rel_base_rename(temp_table, tname);
1199 : } else {
1200 42024 : for (n = temp_table->exps->h; n && !needed; n = n->next) {
1201 29191 : sql_exp *e = n->data;
1202 :
1203 29191 : if (!exp_relname(e) || strcmp(exp_relname(e), tname) != 0)
1204 : needed = 1;
1205 : }
1206 :
1207 12833 : if (needed) {
1208 5767 : list *exps = rel_projections(sql, temp_table, NULL, 1, 1);
1209 :
1210 5767 : temp_table = rel_project(sql->sa, temp_table, exps);
1211 18548 : for (n = exps->h; n; n = n->next) {
1212 12781 : sql_exp *e = n->data;
1213 :
1214 12781 : noninternexp_setname(sql, e, tname, NULL);
1215 12781 : set_basecol(e);
1216 : }
1217 5767 : list_hash_clear(exps);
1218 : }
1219 : }
1220 12833 : if (temp_table && tableref->data.lval->t->type == type_symbol && tableref->data.lval->t->data.sym && tableref->data.lval->t->data.sym->data.lval->h->next->data.lval) /* AS with column aliases */
1221 10 : temp_table = rel_table_optname(sql, temp_table, tableref->data.lval->t->data.sym, refs);
1222 12833 : if (allowed)
1223 : return temp_table;
1224 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: access denied for %s to table '%s'", get_string_global_var(sql, "current_user"), tname);
1225 467314 : } else if (isView(t)) {
1226 : /* instantiate base view */
1227 71331 : node *n,*m;
1228 71331 : sql_rel *rel;
1229 :
1230 71331 : if (sql->emode == m_deps) {
1231 25016 : rel = rel_basetable(sql, t, tname);
1232 25016 : if (!allowed)
1233 0 : rel_base_disallow(rel);
1234 : } else {
1235 : /* when recreating a view, the view itself can't be found */
1236 46315 : if (sql->objid && sql->objid == t->base.id)
1237 1 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: attempting to recursively bind view '%s'.'%s'", t->s->base.name, tname);
1238 46314 : rel = rel_parse(sql, t->s, t->query, m_instantiate);
1239 46314 : if (rel && sql->emode == m_deps)
1240 0 : rel = rel_unnest(sql, rel);
1241 : }
1242 :
1243 71328 : if (!rel)
1244 2 : return NULL;
1245 : /* Rename columns of the rel_parse relation */
1246 71328 : if (sql->emode != m_deps) {
1247 46312 : assert(is_project(rel->op));
1248 46312 : set_processed(rel);
1249 46312 : if (is_mset(rel->op) || is_simple_project(rel->op) || (is_groupby(rel->op) && !list_empty(rel->r))) {
1250 : /* it's unsafe to set the projection names because of possible dependent sorting/grouping columns */
1251 46312 : rel = rel_project(sql->sa, rel, rel_projections(sql, rel, NULL, 0, 0));
1252 46312 : set_processed(rel);
1253 : }
1254 416698 : for (n = ol_first_node(t->columns), m = rel->exps->h; n && m; n = n->next, m = m->next) {
1255 370386 : sql_column *c = n->data;
1256 370386 : sql_exp *e = m->data;
1257 :
1258 370386 : exp_setname(sql, e, tname, c->base.name);
1259 370386 : set_basecol(e);
1260 : }
1261 46312 : list_hash_clear(rel->exps);
1262 : }
1263 71328 : if (rel && !allowed && t->query && (rel = rel_reduce_on_column_privileges(sql, rel, t)) == NULL)
1264 16 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: access denied for %s to view '%s.%s'", get_string_global_var(sql, "current_user"), t->s->base.name, tname);
1265 71312 : return rel;
1266 : }
1267 395983 : if ((isMergeTable(t) || isReplicaTable(t)) && list_length(t->members)==0)
1268 14 : return sql_error(sql, 02, SQLSTATE(42000) "%s '%s'.'%s' should have at least one table associated",
1269 14 : TABLE_TYPE_DESCRIPTION(t->type, t->properties), t->s->base.name, tname);
1270 395969 : res = rel_basetable(sql, t, tname);
1271 395982 : if (!allowed) {
1272 53 : rel_base_disallow(res);
1273 53 : if (rel_base_has_column_privileges(sql, res) == 0)
1274 62 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: access denied for %s to %s '%s.%s'", get_string_global_var(sql, "current_user"), isView(t) ? "view" : "table", t->s->base.name, tname);
1275 : }
1276 395951 : if (tableref->data.lval->t->type == type_symbol && tableref->data.lval->t->data.sym && tableref->data.lval->t->data.sym->data.lval->h->next->data.lval) { /* AS with column aliases */
1277 12 : res = rel_table_optname(sql, res, tableref->data.lval->t->data.sym, refs);
1278 395939 : } else if (refs) { /* if this relation is under a FROM clause, check for duplicate names */
1279 395934 : if (list_find(refs, tname, (fcmp) &strcmp))
1280 7 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: relation name \"%s\" specified more than once", tname);
1281 395927 : assert(tname);
1282 395927 : list_append(refs, tname);
1283 : }
1284 395944 : return res;
1285 217742 : } else if (tableref->token == SQL_VALUES || (tableref->token == SQL_TABLE && tableref->data.lval->h->data.sym->token == SQL_VALUES)) {
1286 1370 : return rel_values(query, tableref, refs);
1287 216372 : } else if (tableref->token == SQL_TABLE) {
1288 10821 : return rel_named_table_function(query, NULL, tableref, lateral, refs);
1289 : } else if (tableref->token == SQL_SELECT) {
1290 101908 : return rel_subquery_optname(query, tableref, refs);
1291 : } else if (tableref->token == SQL_UNION || tableref->token == SQL_EXCEPT || tableref->token == SQL_INTERSECT) {
1292 : /* subqueries will be called, ie no need to test for duplicate references */
1293 43289 : sql_rel *tq = rel_setquery(query, tableref);
1294 :
1295 43289 : if (!tq)
1296 : return NULL;
1297 : /* look for lateral joins */
1298 43282 : symbol *optname = tableref->data.lval->t->type == type_symbol ? tableref->data.lval->t->data.sym : NULL;
1299 43282 : return rel_table_optname(sql, tq, optname, refs);
1300 : } else {
1301 60354 : return query_exp_optname(query, tableref, refs);
1302 : }
1303 : }
1304 :
1305 : static sql_exp *
1306 122379 : rel_exp_variable_on_scope(mvc *sql, const char *sname, const char *vname)
1307 : {
1308 122379 : sql_subtype *tpe = NULL;
1309 122379 : sql_var *var = NULL;
1310 122379 : sql_arg *a = NULL;
1311 122379 : int level = 1;
1312 :
1313 122379 : if (find_variable_on_scope(sql, sname, vname, &var, &a, &tpe, &level, "SELECT")) {
1314 121432 : if (var) /* if variable is known from the stack or a global var */
1315 37504 : return exp_param_or_declared(sql->sa, var->sname ? sa_strdup(sql->sa, var->sname) : NULL, sa_strdup(sql->sa, var->name), &(var->var.tpe), level);
1316 88926 : if (a) /* if variable is a parameter */
1317 88926 : return exp_param_or_declared(sql->sa, NULL, sa_strdup(sql->sa, vname), &(a->type), level);
1318 : }
1319 : return NULL;
1320 : }
1321 :
1322 : static sql_exp *
1323 9257 : exps_get_exp(list *exps, int nth)
1324 : {
1325 9257 : node *n = NULL;
1326 9257 : int i = 0;
1327 :
1328 9257 : if (exps)
1329 27180 : for (n=exps->h, i=1; n && i<nth; n=n->next, i++)
1330 : ;
1331 9257 : if (n && i == nth)
1332 9254 : return n->data;
1333 : return NULL;
1334 : }
1335 :
1336 : static sql_rel *
1337 30955 : rel_find_groupby(sql_rel *groupby)
1338 : {
1339 30955 : if (groupby && !is_processed(groupby) && !is_base(groupby->op)) {
1340 40640 : while(!is_processed(groupby) && !is_base(groupby->op)) {
1341 32767 : if (is_groupby(groupby->op) || !groupby->l)
1342 : break;
1343 : if (groupby->l)
1344 : groupby = groupby->l;
1345 : }
1346 30830 : if (groupby && is_groupby(groupby->op))
1347 22957 : return groupby;
1348 : }
1349 : return NULL;
1350 : }
1351 :
1352 : static int
1353 307 : is_groupby_col(sql_rel *gb, sql_exp *e)
1354 : {
1355 307 : gb = rel_find_groupby(gb);
1356 :
1357 307 : if (gb) {
1358 174 : if (exp_relname(e)) {
1359 163 : if (exp_name(e) && exps_bind_column2(gb->r, exp_relname(e), exp_name(e), NULL))
1360 : return 1;
1361 : } else {
1362 11 : if (exp_name(e) && exps_bind_column(gb->r, exp_name(e), NULL, NULL, 1))
1363 : return 1;
1364 : }
1365 : }
1366 : return 0;
1367 : }
1368 :
1369 : static void
1370 4814 : set_dependent_( sql_rel *r)
1371 : {
1372 4814 : if (is_select(r->op))
1373 3642 : r = r->l;
1374 4814 : if (r && is_join(r->op))
1375 1226 : set_dependent(r);
1376 4814 : }
1377 :
1378 : static
1379 15 : sql_rel* find_union(visitor *v, sql_rel *rel) {
1380 15 : if (rel->op == op_union || rel->op == op_munion)
1381 1 : v->data = rel;
1382 15 : return rel;
1383 : }
1384 :
1385 : static inline
1386 54 : bool group_by_pk_project_uk_cond(mvc* sql, sql_rel* inner, sql_exp* exp,const char* sname, const char* tname) {
1387 54 : sql_table* t = find_table_or_view_on_scope(sql, NULL, sname, tname, "SELECT", false);
1388 54 : bool allow = false;
1389 54 : if (t) {
1390 17 : sql_idx* pki = NULL;
1391 17 : list *ukil = sa_list(sql->sa);
1392 :
1393 23 : for (node * n = ol_first_node(t->idxs); n; n = n->next) {
1394 6 : sql_idx *i = n->data;
1395 6 : if (!i->key)
1396 1 : continue;
1397 5 : switch (i->key->type) {
1398 3 : case pkey:
1399 3 : pki = i;
1400 3 : continue;
1401 2 : case ukey:
1402 : case unndkey:
1403 2 : list_append(ukil, i);
1404 2 : continue;
1405 0 : default:
1406 0 : continue;
1407 : }
1408 : }
1409 17 : if (pki && pki->columns->cnt == 1 && inner->r && ((list*) inner->r)->cnt == 1) {
1410 : /* for now only check simple case where primary key and group by expression is a single column*/
1411 3 : sql_exp* gbe = ((list*) inner->r)->h->data;
1412 3 : sql_column* pkc = ((sql_kc *)pki->columns->h->data)->c;
1413 3 : if (gbe->type == e_column && strcmp(gbe->alias.name, pkc->base.name) == 0) {
1414 2 : node *n;
1415 2 : for (n = ukil->h; n; n = n->next){
1416 2 : sql_idx* uki = n->data;
1417 2 : if (uki->columns->cnt == 1) {
1418 : /* for now only check simple case where unique key is a single column*/
1419 2 : sql_column* ukc = ((sql_kc *)uki->columns->h->data)->c;
1420 2 : if (strcmp(exp->alias.name, ukc->base.name) == 0) {
1421 : allow = true;
1422 : break;
1423 : }
1424 : }
1425 : }
1426 : }
1427 : }
1428 :
1429 2 : if (allow) {
1430 : /* sufficiency condition: abort if relation contains union subrelation
1431 : * because it may break functional dependency between pk and uk */
1432 2 : visitor v = {.sql=sql};
1433 2 : rel_visitor_topdown(&v, inner, &find_union);
1434 2 : if (v.data)
1435 1 : allow = false;
1436 : }
1437 : }
1438 :
1439 54 : return allow;
1440 :
1441 : }
1442 :
1443 : static sql_exp *
1444 2386517 : rel_column_ref(sql_query *query, sql_rel **rel, symbol *column_r, int f)
1445 : {
1446 2386517 : mvc *sql = query->sql;
1447 2386517 : sql_exp *exp = NULL;
1448 2386517 : dlist *l = NULL;
1449 2386517 : sql_rel *inner = rel?*rel:NULL, *outer = NULL;
1450 2386517 : int used_lower_after_processed = 0;
1451 :
1452 2386517 : assert((column_r->token == SQL_COLUMN || column_r->token == SQL_IDENT) && column_r->type == type_list);
1453 2386517 : l = column_r->data.lval;
1454 :
1455 2386517 : if (dlist_length(l) == 1) {
1456 1101018 : const char *name = l->h->data.sval;
1457 1101018 : if (!name)
1458 : return NULL;
1459 :
1460 1101018 : if (!exp && inner)
1461 1005271 : if (!(exp = rel_bind_column(sql, inner, name, f, 0)) && sql->session->status == -ERR_AMBIGUOUS)
1462 : return NULL;
1463 1101004 : if (!exp && inner && ((is_sql_aggr(f) && (is_groupby(inner->op) || is_select(inner->op))) ||
1464 24027 : (is_groupby(inner->op) && inner->flag))) {
1465 : /* if inner is selection, ie having clause, get the left relation to reach group by */
1466 : sql_rel *gp = inner;
1467 258 : while (gp && is_select(gp->op))
1468 27 : gp = gp->l;
1469 231 : if (gp && !is_basetable(gp->op) && gp->l && !(exp = rel_bind_column(sql, gp->l, name, f, 0)) && sql->session->status == -ERR_AMBIGUOUS)
1470 : return NULL;
1471 : }
1472 1101004 : if (!exp && query && query_has_outer(query)) {
1473 472 : int i;
1474 :
1475 525 : for (i=query_has_outer(query)-1; i>= 0 && !exp && (outer = query_fetch_outer(query,i)); i--) {
1476 496 : if (!(exp = rel_bind_column(sql, outer, name, f, 0)) && sql->session->status == -ERR_AMBIGUOUS)
1477 : return NULL;
1478 84 : if (!exp && is_groupby(outer->op)) {
1479 31 : if (!(exp = rel_bind_column(sql, outer->l, name, f, 0)) && sql->session->status == -ERR_AMBIGUOUS)
1480 : return NULL;
1481 : else
1482 31 : used_lower_after_processed = is_processed(outer);
1483 : }
1484 496 : if (exp && is_simple_project(outer->op) && !rel_find_exp(outer, exp))
1485 0 : exp = rel_project_add_exp(sql, outer, exp);
1486 443 : if (exp)
1487 : break;
1488 : }
1489 472 : if (exp && exp->card != CARD_AGGR && is_groupby(outer->op) && !is_sql_aggr(f) && rel_find_exp(outer->l, exp))
1490 5 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results without an aggregate function", name);
1491 467 : if (exp && outer && outer->card <= CARD_AGGR && exp->card > CARD_AGGR && !is_sql_aggr(f))
1492 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results without an aggregate function", name);
1493 467 : if (exp && outer && !is_sql_aggr(f) && !is_sql_aggr(query_fetch_outer_state(query, i))) {
1494 299 : if (used_lower_after_processed || query_outer_used_exp( query, i, exp, f)) {
1495 0 : sql_exp *lu = used_lower_after_processed?exp:query_outer_last_used(query, i);
1496 0 : if (exp_name(lu) && exp_relname(lu) && !has_label(lu))
1497 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\" from outer query", exp_relname(lu), exp_name(lu));
1498 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query");
1499 : }
1500 : }
1501 467 : if (exp) {
1502 438 : int of = query_fetch_outer_state(query, i);
1503 438 : if (is_groupby(outer->op) && !is_sql_aggr(f)) {
1504 37 : exp = rel_groupby_add_aggr(sql, outer, exp);
1505 37 : exp->card = CARD_ATOM;
1506 401 : } else if (is_groupby(outer->op) && is_sql_aggr(f) && exps_any_match(outer->exps, exp))
1507 57 : exp = exp_ref(sql, exp);
1508 : else
1509 344 : exp->card = CARD_ATOM;
1510 438 : set_freevar(exp, i);
1511 : /*
1512 : if (exp->alias.label == exp->nid)
1513 : exp->alias.label = -(sql->nid++);
1514 : */
1515 438 : if (!is_sql_where(of) && !is_sql_aggr(of) && !is_sql_aggr(f) && !outer->grouped)
1516 147 : set_outer(outer);
1517 : }
1518 467 : if (exp && outer && (is_select(outer->op) || is_join(outer->op)))
1519 43 : set_dependent_(outer);
1520 : }
1521 :
1522 : /* some views are just in the stack, like before and after updates views */
1523 1100999 : if (rel && sql->use_views) {
1524 13 : sql_rel *v = NULL;
1525 13 : int dup = stack_find_rel_view_projection_columns(sql, name, &v); /* trigger views are basetables relations, so those may conflict */
1526 :
1527 13 : if (dup < 0 || (v && exp && *rel && is_base(v->op) && v != *rel)) /* comparing pointers, ugh */
1528 2 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", name);
1529 11 : if (v && !exp) {
1530 4 : if (*rel)
1531 1 : *rel = rel_crossproduct(sql->sa, *rel, rel_dup(v), op_join);
1532 : else
1533 3 : *rel = rel_dup(v);
1534 4 : exp = rel_bind_column(sql, *rel, name, f, 0);
1535 : }
1536 : }
1537 1100997 : if (!exp) /* If no column was found, try a variable or parameter */
1538 119360 : exp = rel_exp_variable_on_scope(sql, NULL, name);
1539 :
1540 119360 : if (!exp) {
1541 947 : if (inner && !is_sql_aggr(f) && is_groupby(inner->op) && inner->l && (exp = rel_bind_column(sql, inner->l, name, f, 0)))
1542 47 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results without an aggregate function", name);
1543 : }
1544 :
1545 1100050 : if (!exp)
1546 900 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: identifier '%s' unknown", name);
1547 1100050 : if (exp && inner && inner->card <= CARD_AGGR && exp->card > CARD_AGGR && (is_sql_sel(f) || is_sql_having(f)) && (!is_sql_aggr(f) && !(inner->flag)))
1548 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results without an aggregate function", name);
1549 1100050 : if (exp && inner && is_groupby(inner->op) && !is_sql_aggr(f) && !is_freevar(exp) && !inner->flag)
1550 26122 : exp = rel_groupby_add_aggr(sql, inner, exp);
1551 1285499 : } else if (dlist_length(l) == 2 || dlist_length(l) == 3) {
1552 1285499 : const char *sname = NULL;
1553 1285499 : const char *tname = l->h->data.sval;
1554 1285499 : const char *cname = l->h->next->data.sval;
1555 1285499 : if (dlist_length(l) == 3) {
1556 1 : sname = l->h->data.sval;
1557 1 : tname = l->h->next->data.sval;
1558 1 : cname = l->h->next->next->data.sval;
1559 : }
1560 1285499 : if (!cname)
1561 : return NULL;
1562 :
1563 1270943 : if (!exp && rel && inner)
1564 1270816 : if (!(exp = rel_bind_column3(sql, inner, sname, tname, cname, f)) && sql->session->status == -ERR_AMBIGUOUS)
1565 : return NULL;
1566 1270942 : if (!exp && inner && is_sql_aggr(f) && (is_groupby(inner->op) || is_select(inner->op))) {
1567 : /* if inner is selection, ie having clause, get the left relation to reach group by */
1568 : sql_rel *gp = inner;
1569 59 : while (gp && is_select(gp->op))
1570 5 : gp = gp->l;
1571 54 : if (gp && !is_basetable(gp->op) && gp->l && !(exp = rel_bind_column3(sql, gp->l, sname, tname, cname, f)) && sql->session->status == -ERR_AMBIGUOUS)
1572 : return NULL;
1573 : }
1574 1270942 : if (!exp && query && query_has_outer(query)) {
1575 12008 : int i;
1576 :
1577 12218 : for (i=query_has_outer(query)-1; i>= 0 && !exp && (outer = query_fetch_outer(query,i)); i--) {
1578 12217 : if (!(exp = rel_bind_column3(sql, outer, sname, tname, cname, f | sql_outer)) && sql->session->status == -ERR_AMBIGUOUS)
1579 : return NULL;
1580 293 : if (!exp && is_groupby(outer->op)) {
1581 102 : if (!(exp = rel_bind_column3(sql, outer->l, sname, tname, cname, f)) && sql->session->status == -ERR_AMBIGUOUS)
1582 : return NULL;
1583 : else
1584 102 : used_lower_after_processed = is_processed(outer);
1585 : }
1586 12217 : if (exp && is_simple_project(outer->op) && !rel_find_exp(outer, exp))
1587 0 : exp = rel_project_add_exp(sql, outer, exp);
1588 12007 : if (exp)
1589 : break;
1590 : }
1591 12008 : if (exp && exp->card != CARD_AGGR && is_groupby(outer->op) && !is_sql_aggr(f) && rel_find_exp(outer->l, exp))
1592 6 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", tname, cname);
1593 12002 : if (exp && outer && outer->card <= CARD_AGGR && exp->card > CARD_AGGR && !is_sql_aggr(f))
1594 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", tname, cname);
1595 12002 : if (exp && outer && !is_sql_aggr(f)) {
1596 11725 : if (used_lower_after_processed || query_outer_used_exp( query, i, exp, f)) {
1597 0 : sql_exp *lu = used_lower_after_processed?exp:query_outer_last_used(query, i);
1598 0 : if (exp_name(lu) && exp_relname(lu) && !has_label(lu))
1599 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\" from outer query", exp_relname(lu), exp_name(lu));
1600 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query");
1601 : }
1602 : }
1603 12002 : if (exp) {
1604 12001 : int of = query_fetch_outer_state(query, i);
1605 12001 : if (is_groupby(outer->op) && !is_sql_aggr(f)) {
1606 64 : exp = rel_groupby_add_aggr(sql, outer, exp);
1607 64 : exp->card = CARD_ATOM;
1608 11937 : } else if (is_groupby(outer->op) && is_sql_aggr(f) && exps_any_match(outer->exps, exp))
1609 52 : exp = exp_ref(sql, exp);
1610 : else
1611 11885 : exp->card = CARD_ATOM;
1612 12001 : set_freevar(exp, i);
1613 : /*
1614 : if (exp->alias.label == exp->nid)
1615 : exp->alias.label = -(sql->nid++);
1616 : */
1617 12001 : if (!is_sql_where(of) && !is_sql_aggr(of) && !is_sql_aggr(f) && !outer->grouped)
1618 10289 : set_outer(outer);
1619 : }
1620 12002 : if (exp && outer && (is_select(outer->op) || is_join(outer->op)))
1621 4771 : set_dependent_(outer);
1622 : }
1623 :
1624 : /* some views are just in the stack, like before and after updates views */
1625 1270936 : if (rel && sql->use_views) {
1626 40 : sql_rel *v = stack_find_rel_view(sql, tname);
1627 :
1628 40 : if (v && exp && *rel && is_base(v->op) && v != *rel) /* trigger views are basetables relations, so those may conflict */
1629 0 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s.%s' ambiguous", tname, cname);
1630 40 : if (v && !exp) {
1631 20 : if (*rel)
1632 0 : *rel = rel_crossproduct(sql->sa, *rel, rel_dup(v), op_join);
1633 : else
1634 20 : *rel = rel_dup(v);
1635 20 : if (!(exp = rel_bind_column3(sql, *rel, sname, tname, cname, f)) && sql->session->status == -ERR_AMBIGUOUS)
1636 : return NULL;
1637 : }
1638 : }
1639 1270916 : if (!exp) { /* If no column was found, try a global variable */
1640 67016 : sql_var *var = NULL;
1641 67016 : sql_subtype *tpe = NULL;
1642 67016 : int level = 0;
1643 67016 : sql_arg *a = NULL;
1644 :
1645 67016 : if (find_variable_on_scope(sql, tname, cname, &var, &a, &tpe, &level, "SELECT")) { /* search schema with table name, ugh */
1646 10 : assert(level == 0);
1647 10 : exp = exp_param_or_declared(sql->sa, sa_strdup(sql->sa, var->sname), sa_strdup(sql->sa, var->name), &(var->var.tpe), 0);
1648 : }
1649 : }
1650 67016 : if (!exp) {
1651 67006 : if (inner && !is_sql_aggr(f) && is_groupby(inner->op) && inner->l && (exp = rel_bind_column3(sql, inner->l, sname, tname, cname, f))) {
1652 54 : if (group_by_pk_project_uk_cond(sql, inner, exp, sname, tname)) {
1653 : /* SQL23 feature: very special case where primary key is used in GROUP BY expression and
1654 : * unique key is in the project list or ORDER BY clause */
1655 1 : sql->session->status = 0;
1656 1 : sql->errstr[0] = 0;
1657 1 : exp->card = CARD_AGGR;
1658 1 : list_append(inner->exps, exp);
1659 : }
1660 : else
1661 53 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", tname, cname);
1662 : }
1663 : }
1664 :
1665 1 : if (!exp)
1666 66952 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42S22) "SELECT: no such column '%s.%s'", tname, cname);
1667 1203931 : if (exp && inner && inner->card <= CARD_AGGR && exp->card > CARD_AGGR && (is_sql_sel(f) || is_sql_having(f)) && !is_sql_aggr(f))
1668 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", tname, cname);
1669 1203931 : if (exp && inner && is_groupby(inner->op) && !is_sql_aggr(f) && !is_freevar(exp))
1670 17530 : exp = rel_groupby_add_aggr(sql, inner, exp);
1671 0 : } else if (dlist_length(l) > 3) {
1672 0 : return sql_error(sql, 02, SQLSTATE(42000) "cross-database references are not implemented");
1673 : }
1674 2303981 : if (exp && !exp_is_atom(exp) && rel && !outer) {
1675 2173125 : if (query->last_exp && query->last_rel == *rel && !is_sql_aggr(query->last_state) && is_sql_aggr(f)) {
1676 55 : if (!is_groupby(query->last_rel->op) || list_empty(query->last_rel->r) || !exps_find_exp(query->last_rel->r, query->last_exp)) {
1677 34 : if (exp_relname(query->last_exp) && exp_name(query->last_exp) && !has_label(query->last_exp))
1678 34 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", exp_relname(query->last_exp), exp_name(query->last_exp));
1679 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
1680 : }
1681 : }
1682 2173091 : query->prev = query->last_exp;
1683 2173091 : query->last_exp = exp;
1684 2173091 : query->last_state = f;
1685 2173091 : query->last_rel = *rel;
1686 : }
1687 : return exp;
1688 : }
1689 :
1690 : int
1691 1006204 : rel_convert_types(mvc *sql, sql_rel *ll, sql_rel *rr, sql_exp **L, sql_exp **R, int scale_fixing, check_type tpe)
1692 : {
1693 1006204 : sql_exp *ls = *L;
1694 1006204 : sql_exp *rs = *R;
1695 1006204 : sql_subtype *lt = exp_subtype(ls);
1696 1006204 : sql_subtype *rt = exp_subtype(rs);
1697 :
1698 1006204 : if (!rt && !lt) {
1699 2 : sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) on both sides of an expression");
1700 2 : return -1;
1701 : }
1702 1006202 : if (rt && (!lt || !lt->type))
1703 7 : return rel_set_type_param(sql, rt, ll, ls, 0);
1704 1006195 : if (lt && (!rt || !rt->type))
1705 648 : return rel_set_type_param(sql, lt, rr, rs, 0);
1706 :
1707 1005547 : if (rt && lt) {
1708 1005547 : sql_subtype *i = lt;
1709 1005547 : sql_subtype *r = rt;
1710 :
1711 1005547 : if (subtype_cmp(lt, rt) != 0 || (tpe == type_equal_no_any && (lt->type->localtype==0 || rt->type->localtype==0))) {
1712 277551 : sql_subtype super;
1713 :
1714 277551 : cmp_supertype(&super, r, i);
1715 277551 : if (scale_fixing) {
1716 : /* convert ls to super type */
1717 277551 : ls = exp_check_type(sql, &super, ll, ls, tpe);
1718 : /* convert rs to super type */
1719 277551 : rs = exp_check_type(sql, &super, rr, rs, tpe);
1720 : } else {
1721 : /* convert ls to super type */
1722 0 : super.scale = lt->scale;
1723 0 : ls = exp_check_type(sql, &super, ll, ls, tpe);
1724 : /* convert rs to super type */
1725 0 : super.scale = rt->scale;
1726 0 : rs = exp_check_type(sql, &super, rr, rs, tpe);
1727 : }
1728 : }
1729 1005547 : *L = ls;
1730 1005547 : *R = rs;
1731 1005547 : if (!ls || !rs)
1732 : return -1;
1733 : return 0;
1734 : }
1735 : return -1;
1736 : }
1737 :
1738 : static sql_rel *
1739 108038 : push_select_exp(mvc *sql, sql_rel *rel, sql_exp *e, sql_exp *ls, int f)
1740 : {
1741 108038 : if (is_outerjoin(rel->op)) {
1742 1182 : if ((is_left(rel->op) || is_full(rel->op)) && rel_find_exp(rel->l, ls)) {
1743 38 : rel_join_add_exp(sql->sa, rel, e);
1744 38 : return rel;
1745 1144 : } else if ((is_right(rel->op) || is_full(rel->op)) && rel_find_exp(rel->r, ls)) {
1746 5 : rel_join_add_exp(sql->sa, rel, e);
1747 5 : return rel;
1748 : }
1749 1139 : if (is_left(rel->op) && rel_find_exp(rel->r, ls)) {
1750 1113 : rel->r = rel_push_select(sql, rel->r, ls, e, f);
1751 1113 : return rel;
1752 26 : } else if (is_right(rel->op) && rel_find_exp(rel->l, ls)) {
1753 11 : rel->l = rel_push_select(sql, rel->l, ls, e, f);
1754 11 : return rel;
1755 : }
1756 : }
1757 : /* push select into the given relation */
1758 106871 : return rel_push_select(sql, rel, ls, e, f);
1759 : }
1760 :
1761 : static sql_rel *
1762 209671 : push_join_exp(mvc *sql, sql_rel *rel, sql_exp *e, sql_exp *L, sql_exp *R, sql_exp *R2, int f)
1763 : {
1764 209671 : sql_rel *r;
1765 209671 : if (/*is_semi(rel->op) ||*/ (is_outerjoin(rel->op) && !is_processed((rel)))) {
1766 21212 : rel_join_add_exp(sql->sa, rel, e);
1767 21212 : return rel;
1768 : }
1769 : /* push join into the given relation */
1770 188459 : if ((r = rel_push_join(sql, rel, L, R, R2, e, f)) != NULL)
1771 : return r;
1772 0 : rel_join_add_exp(sql->sa, rel, e);
1773 0 : return rel;
1774 : }
1775 :
1776 : static sql_rel *
1777 3734 : rel_select_push_filter_exp_down(mvc *sql, sql_rel *rel, sql_exp *e, list *l, list *r, int ff)
1778 : {
1779 3734 : sql_exp *ll;
1780 3734 : if (exps_card(r) <= CARD_ATOM && (exps_are_atoms(r) || exps_have_freevar(sql, r) || exps_have_freevar(sql, l))) {
1781 3637 : if (exps_card(l) == exps_card(r) || rel->processed) /* bin compare op */
1782 98 : return rel_select(sql->sa, rel, e);
1783 3539 : if ((ll = exps_find_one_multi_exp(l)))
1784 3539 : return push_select_exp(sql, rel, e, ll, ff);
1785 : }
1786 97 : if (is_outerjoin(rel->op))
1787 8 : return rel_select(sql->sa, rel, e);
1788 89 : return rel_select_add_exp(sql->sa, rel, e);
1789 : }
1790 :
1791 : static sql_rel *
1792 3617 : rel_filter(mvc *sql, sql_rel *rel, list *l, list *r, char *sname, char *filter_op, int anti, int ff)
1793 : {
1794 3617 : node *n;
1795 3617 : sql_exp *e = NULL;
1796 3617 : sql_subfunc *f = NULL;
1797 3617 : list *tl = sa_list(sql->sa);
1798 3617 : bool found = false;
1799 :
1800 7234 : for (n = l->h; n; n = n->next){
1801 3617 : sql_exp *e = n->data;
1802 :
1803 3617 : list_append(tl, exp_subtype(e));
1804 : }
1805 14391 : for (n = r->h; n; n = n->next){
1806 10774 : sql_exp *e = n->data;
1807 :
1808 10774 : list_append(tl, exp_subtype(e));
1809 : }
1810 : /* find filter function */
1811 3617 : f = bind_func_(sql, sname, filter_op, tl, F_FILT, false, &found, false);
1812 3617 : if (f) {
1813 3615 : node *n,*m = f->func->ops->h;
1814 3615 : list *nexps = sa_list(sql->sa);
1815 :
1816 7230 : for(n=l->h; m && n; m = m->next, n = n->next) {
1817 3615 : sql_arg *a = m->data;
1818 3615 : sql_exp *e = n->data;
1819 :
1820 3615 : e = exp_check_type(sql, &a->type, rel, e, type_equal);
1821 3615 : if (!e)
1822 : return NULL;
1823 3615 : list_append(nexps, e);
1824 : }
1825 3615 : l = nexps;
1826 3615 : nexps = sa_list(sql->sa);
1827 14381 : for(n=r->h; m && n; m = m->next, n = n->next) {
1828 10766 : sql_arg *a = m->data;
1829 10766 : sql_exp *e = n->data;
1830 :
1831 10766 : e = exp_check_type(sql, &a->type, rel, e, type_equal);
1832 10766 : if (!e)
1833 : return NULL;
1834 10766 : list_append(nexps, e);
1835 : }
1836 : r = nexps;
1837 : }
1838 3617 : if (!f)
1839 4 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s FILTER function %s%s%s'%s'",
1840 2 : found ? "insufficient privileges for" : "no such", sname ? "'":"", sname ? sname : "", sname ? "'.":"", filter_op);
1841 3615 : e = exp_filter(sql->sa, l, r, f, anti);
1842 :
1843 3615 : if (exps_one_is_rel(l) || exps_one_is_rel(r)) /* uncorrelated subquery case */
1844 9 : return rel_select(sql->sa, rel, e);
1845 : /* atom or row => select */
1846 7212 : for (node *n=l->h; n; n = n->next) {
1847 3606 : sql_exp *ls = n->data;
1848 :
1849 3606 : if (ls->card > rel->card) {
1850 0 : if (exp_name(ls) && !has_label(ls))
1851 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results without an aggregate function", exp_name(ls));
1852 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
1853 : }
1854 : }
1855 14345 : for (node *n=r->h; n; n = n->next) {
1856 10739 : sql_exp *rs = n->data;
1857 :
1858 10739 : if (rs->card > rel->card) {
1859 0 : if (exp_name(rs) && !has_label(rs))
1860 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results without an aggregate function", exp_name(rs));
1861 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
1862 : }
1863 : }
1864 3606 : return rel_select_push_filter_exp_down(sql, rel, e, l, r, ff);
1865 : }
1866 :
1867 : static sql_rel *
1868 3557 : rel_filter_exp_(mvc *sql, sql_rel *rel, sql_exp *ls, sql_exp *r1, sql_exp *r2, sql_exp *r3, char *filter_op, int anti, int f)
1869 : {
1870 3557 : list *l = sa_list(sql->sa);
1871 3557 : list *r = sa_list(sql->sa);
1872 :
1873 3557 : list_append(l, ls);
1874 3557 : list_append(r, r1);
1875 3557 : if (r2)
1876 3557 : list_append(r, r2);
1877 3557 : if (r3)
1878 3557 : list_append(r, r3);
1879 3557 : return rel_filter(sql, rel, l, r, "sys", filter_op, anti, f);
1880 : }
1881 :
1882 : static sql_rel *
1883 382356 : rel_select_push_compare_exp_down(mvc *sql, sql_rel *rel, sql_exp *e, sql_exp *ls, sql_exp *rs, sql_exp *rs2, int f)
1884 : {
1885 382356 : if (!is_join(rel->op) && !is_select(rel->op))
1886 85573 : return rel_select(sql->sa, rel, e);
1887 384445 : if ((rs->card <= CARD_ATOM || (rs2 && ls->card <= CARD_ATOM)) &&
1888 175324 : (exp_is_atom(rs) || (rs2 && exp_is_atom(ls)) || exp_has_freevar(sql, rs) || exp_has_freevar(sql, ls)) &&
1889 485 : (!rs2 || (rs2->card <= CARD_ATOM && (exp_is_atom(rs2) || exp_has_freevar(sql, rs2))))) {
1890 87112 : if (ls->card == rs->card || (rs2 && (ls->card == rs2->card || rs->card == rs2->card)) || rel->processed) /* bin compare op */
1891 1008 : return rel_select(sql->sa, rel, e);
1892 :
1893 86104 : return push_select_exp(sql, rel, e, ls, f);
1894 : } else { /* join */
1895 209671 : return push_join_exp(sql, rel, e, ls, rs, rs2, f);
1896 : }
1897 : return rel;
1898 : }
1899 :
1900 : static sql_rel *
1901 357976 : rel_compare_exp_(sql_query *query, sql_rel *rel, sql_exp *ls, sql_exp *rs, sql_exp *rs2, int type, int anti, int quantifier, int f, int symmetric, int is_semantics)
1902 : {
1903 357976 : mvc *sql = query->sql;
1904 357976 : sql_exp *e = NULL;
1905 :
1906 357976 : if (quantifier || exp_is_rel(ls) || exp_is_rel(rs) || (rs2 && exp_is_rel(rs2))) {
1907 3517 : if (rs2) {
1908 7 : e = exp_compare2(sql->sa, ls, rs, rs2, type, symmetric);
1909 7 : if (anti)
1910 0 : set_anti(e);
1911 : } else {
1912 3510 : assert(!symmetric);
1913 3510 : if (rel_convert_types(sql, rel, rel, &ls, &rs, 1, type_equal_no_any) < 0)
1914 : return NULL;
1915 3510 : e = exp_compare_func(sql, ls, rs, compare_func((comp_type)type, anti), quantifier);
1916 : }
1917 3517 : return rel_select(sql->sa, rel, e);
1918 354459 : } else if (!rs2) {
1919 351512 : assert(!symmetric);
1920 351512 : if (ls->card < rs->card) {
1921 12642 : sql_exp *swap = ls;
1922 12642 : ls = rs;
1923 12642 : rs = swap;
1924 12642 : type = (int)swap_compare((comp_type)type);
1925 : }
1926 351512 : if (rel_convert_types(sql, rel, rel, &ls, &rs, 1, type_equal_no_any) < 0)
1927 : return NULL;
1928 351509 : e = exp_compare(sql->sa, ls, rs, type);
1929 351509 : if (is_semantics) set_semantics(e);
1930 : } else {
1931 2947 : assert(rs2);
1932 2947 : if (rel_convert_types(sql, rel, rel, &ls, &rs, 1, type_equal_no_any) < 0)
1933 : return NULL;
1934 2947 : if (!(rs2 = exp_check_type(sql, exp_subtype(ls), rel, rs2, type_equal)))
1935 : return NULL;
1936 2947 : e = exp_compare2(sql->sa, ls, rs, rs2, type, symmetric);
1937 : }
1938 354456 : if (anti)
1939 847 : set_anti(e);
1940 :
1941 354456 : if (!rel)
1942 0 : return rel_select(sql->sa, rel_project_exp(sql, exp_atom_bool(sql->sa, 1)), e);
1943 :
1944 : /* atom or row => select */
1945 354456 : if (ls->card > rel->card || rs->card > rel->card || (rs2 && rs2->card > rel->card)) {
1946 0 : sql_exp *e = ls->card > rel->card ? ls : rs->card > rel->card ? rs : rs2;
1947 0 : if (exp_name(e) && !has_label(e))
1948 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results without an aggregate function", exp_name(e));
1949 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
1950 : }
1951 354456 : return rel_select_push_compare_exp_down(sql, rel, e, ls, rs, rs2, f);
1952 : }
1953 :
1954 : static sql_rel *
1955 355022 : rel_compare_exp(sql_query *query, sql_rel *rel, sql_exp *ls, sql_exp *rs, char *compare_op, int reduce, int quantifier, int need_not, int f, int is_semantics)
1956 : {
1957 355022 : mvc *sql = query->sql;
1958 355022 : comp_type type = cmp_equal;
1959 :
1960 355022 : if (!ls || !rs)
1961 : return NULL;
1962 :
1963 355022 : if (!quantifier && ((!rel && !query_has_outer(query)) || !reduce)) {
1964 : /* TODO to handle filters here */
1965 0 : sql_exp *e;
1966 :
1967 0 : if (rel_convert_types(sql, rel, rel, &ls, &rs, 1, type_equal_no_any) < 0)
1968 : return NULL;
1969 0 : e = rel_binop_(sql, rel, ls, rs, "sys", compare_op, card_value, true);
1970 :
1971 0 : if (!e)
1972 : return NULL;
1973 0 : if (!reduce) {
1974 0 : if (rel->op == op_project) {
1975 0 : append(rel->exps, e);
1976 : } else {
1977 0 : list *exps = new_exp_list(sql->sa);
1978 :
1979 0 : append(exps, e);
1980 0 : return rel_project(sql->sa, rel, exps);
1981 : }
1982 : } else {
1983 0 : return rel_select(sql->sa, rel, e);
1984 : }
1985 : }
1986 355022 : type = compare_str2type(compare_op);
1987 355022 : assert(type != cmp_filter);
1988 355022 : return rel_compare_exp_(query, rel, ls, rs, NULL, type, need_not, quantifier, f, 0, is_semantics);
1989 : }
1990 :
1991 : static sql_rel *
1992 354995 : rel_compare(sql_query *query, sql_rel *rel, symbol *sc, symbol *lo, symbol *ro, char *compare_op, int f, exp_kind k, int quantifier, int is_semantics)
1993 : {
1994 354995 : mvc *sql = query->sql;
1995 354995 : sql_exp *rs = NULL, *ls;
1996 354995 : comp_type cmp_type = compare_str2type(compare_op);
1997 354995 : exp_kind ek = {type_value, card_column, FALSE};
1998 354995 : int need_not = 0;
1999 :
2000 354995 : if ((quantifier == 1 && cmp_type == cmp_equal) ||
2001 354960 : (quantifier == 2 && cmp_type == cmp_notequal)) {
2002 63 : dnode *n = sc->data.lval->h;
2003 63 : dlist *dl = dlist_create(sql->sa);
2004 : /* map into IN/NOT IN */
2005 63 : sc->token = cmp_type==cmp_equal?SQL_IN:SQL_NOT_IN;
2006 63 : n->next->type = type_list;
2007 63 : n->next->data.lval = dl;
2008 63 : n->next->next->next = NULL; /* remove quantifier */
2009 63 : dl->h = n->next->next;
2010 63 : n->next->next = NULL; /* (remove comparison) moved righthand side */
2011 63 : return rel_logical_exp(query, rel, sc, f);
2012 : }
2013 : /* <> ANY -> NOT (= ALL) */
2014 354932 : if (quantifier == 1 && cmp_type == cmp_notequal) {
2015 5 : need_not = 1;
2016 5 : quantifier = 2;
2017 5 : cmp_type = cmp_equal;
2018 5 : compare_op = "=";
2019 : }
2020 :
2021 354932 : if ((lo->token == SQL_SELECT || lo->token == SQL_UNION || lo->token == SQL_EXCEPT || lo->token == SQL_INTERSECT || lo->token == SQL_VALUES) &&
2022 43 : (ro->token != SQL_SELECT && ro->token != SQL_UNION && ro->token != SQL_EXCEPT && ro->token != SQL_INTERSECT && ro->token != SQL_VALUES)) {
2023 30 : symbol *tmp = lo; /* swap subquery to the right hand side */
2024 :
2025 30 : lo = ro;
2026 30 : ro = tmp;
2027 :
2028 30 : if (compare_op[0] == '>')
2029 16 : compare_op[0] = '<';
2030 14 : else if (compare_op[0] == '<' && compare_op[1] != '>')
2031 1 : compare_op[0] = '>';
2032 30 : cmp_type = swap_compare(cmp_type);
2033 : }
2034 :
2035 354932 : ls = rel_value_exp(query, &rel, lo, f|sql_farg, ek);
2036 354932 : if (!ls)
2037 : return NULL;
2038 354884 : if (ls && rel && exp_has_freevar(sql, ls) && is_sql_sel(f))
2039 0 : ls = rel_project_add_exp(sql, rel, ls);
2040 354884 : if (quantifier)
2041 58 : ek.card = card_set;
2042 :
2043 354884 : rs = rel_value_exp(query, &rel, ro, f|sql_farg, ek);
2044 354884 : if (!rs)
2045 : return NULL;
2046 354854 : if (ls->card > rs->card && rs->card == CARD_AGGR && is_sql_having(f)) {
2047 0 : if (exp_name(ls) && exp_relname(ls) && !has_label(ls))
2048 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", exp_relname(ls), exp_name(ls));
2049 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
2050 : }
2051 354854 : if (rs->card > ls->card && ls->card == CARD_AGGR && is_sql_having(f)) {
2052 0 : if (exp_name(rs) && exp_relname(rs) && !has_label(rs))
2053 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", exp_relname(rs), exp_name(rs));
2054 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
2055 : }
2056 354854 : return rel_compare_exp(query, rel, ls, rs, compare_op, k.reduce, quantifier, need_not, f, is_semantics);
2057 : }
2058 :
2059 : static sql_exp*
2060 522194 : _rel_nop(mvc *sql, char *sname, char *fname, list *tl, sql_rel *rel, list *exps, exp_kind ek)
2061 : {
2062 522194 : bool found = false;
2063 522194 : int table_func = (ek.card == card_relation);
2064 522194 : sql_ftype type = (ek.card == card_loader)?F_LOADER:((ek.card == card_none)?F_PROC:
2065 : ((ek.card == card_relation)?F_UNION:F_FUNC));
2066 :
2067 522194 : sql_subfunc *f = bind_func_(sql, sname, fname, tl, type, false, &found, false);
2068 522194 : if (f && !(exps = check_arguments_and_find_largest_any_type(sql, rel, exps, f, table_func, false)))
2069 : f = NULL;
2070 :
2071 521927 : if (f)
2072 521927 : return exp_op(sql->sa, exps, f);
2073 267 : char *arg_list = nary_function_arg_types_2str(sql, tl, list_length(tl));
2074 551 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s operator %s%s%s'%s'(%s)",
2075 267 : found ? "insufficient privileges for" : "no such", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname, arg_list ? arg_list : "");
2076 : }
2077 :
2078 : static sql_exp *
2079 2096 : exp_exist(sql_query *query, sql_rel *rel, sql_exp *le, int exists)
2080 : {
2081 2096 : mvc *sql = query->sql;
2082 2096 : sql_subfunc *exists_func = NULL;
2083 2096 : sql_subtype *t;
2084 2096 : sql_exp *res;
2085 :
2086 2096 : if (!exp_name(le))
2087 753 : exp_label(sql->sa, le, ++sql->label);
2088 2096 : if (exp_is_rel(le)) { /* for the subquery case, propagate to the inner query */
2089 2096 : sql_rel *r = exp_rel_get_rel(sql->sa, le);
2090 2096 : if (is_project(r->op) && !list_empty(r->exps)) {
2091 6109 : for (node *n = r->exps->h; n; n = n->next)
2092 4013 : if (!exp_subtype(n->data) && rel_set_type_param(sql, sql_bind_localtype("bit"), r, n->data, 0) < 0) /* workaround */
2093 : return NULL;
2094 2096 : le->tpe = *exp_subtype(r->exps->h->data); /* just take the first expression type */
2095 : }
2096 0 : } else if (!exp_subtype(le) && rel_set_type_param(sql, sql_bind_localtype("bit"), rel, le, 0) < 0) /* workaround */
2097 : return NULL;
2098 2096 : t = exp_subtype(le);
2099 :
2100 2157 : if (!(exists_func = sql_bind_func(sql, "sys", exists ? "sql_exists" : "sql_not_exists", t, NULL, F_FUNC, true, true)))
2101 0 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "exist operator on type %s missing", t ? t->type->base.name : "unknown");
2102 2096 : res = exp_unop(sql->sa, le, exists_func);
2103 2096 : set_has_no_nil(res);
2104 2096 : return res;
2105 : }
2106 :
2107 : static sql_exp *
2108 1093 : rel_exists_value_exp(sql_query *query, sql_rel **rel, symbol *sc, int f)
2109 : {
2110 1093 : exp_kind ek = {type_value, card_exists, FALSE};
2111 1093 : sql_exp *le, *e;
2112 :
2113 1093 : le = rel_value_exp(query, rel, sc->data.sym, f|sql_farg, ek);
2114 1093 : if (!le)
2115 : return NULL;
2116 1092 : if (!(e = exp_exist(query, rel ? *rel : NULL, le, sc->token == SQL_EXISTS)))
2117 : return NULL;
2118 : /* only freevar should have CARD_AGGR */
2119 1092 : e->card = CARD_ATOM;
2120 1092 : return e;
2121 : }
2122 :
2123 : static sql_rel *
2124 1012 : rel_exists_exp(sql_query *query, sql_rel *rel, symbol *sc, int f)
2125 : {
2126 1012 : exp_kind ek = {type_value, card_exists, TRUE};
2127 1012 : mvc *sql = query->sql;
2128 1012 : sql_rel *sq = NULL;
2129 :
2130 1012 : if (is_psm_call(f) || is_sql_merge(f))
2131 3 : return sql_error(sql, 02, SQLSTATE(42000) "%s: subqueries not supported inside %s", is_psm_call(f) ? "CALL" : "MERGE", is_psm_call(f) ? "CALL statements" : "MERGE conditions");
2132 1011 : if (rel) {
2133 1011 : query_processed(query);
2134 1011 : query_push_outer(query, rel, f);
2135 : }
2136 1011 : sq = rel_subquery(query, sc->data.sym, ek);
2137 1011 : if (rel)
2138 1011 : rel = query_pop_outer(query);
2139 1011 : assert(!is_sql_sel(f));
2140 1011 : if (sq) {
2141 1004 : sql_exp *e = exp_rel(sql, sq);
2142 1004 : if (!(e = exp_exist(query, rel, e, sc->token == SQL_EXISTS)))
2143 : return NULL;
2144 : /* only freevar should have CARD_AGGR */
2145 1004 : e->card = CARD_ATOM;
2146 1004 : rel = rel_select_add_exp(sql->sa, rel, e);
2147 1004 : return rel;
2148 : }
2149 : return NULL;
2150 : }
2151 :
2152 : static int
2153 8597 : is_project_true(sql_rel *r)
2154 : {
2155 8597 : if (r && !r->l && list_length(r->exps) == 1) {
2156 82 : sql_exp *e = r->exps->h->data;
2157 82 : if (exp_is_atom(e) && exp_is_true(e))
2158 : return 1;
2159 : }
2160 : return 0;
2161 : }
2162 :
2163 : static sql_exp *
2164 64493 : rel_in_value_exp(sql_query *query, sql_rel **rel, symbol *sc, int f)
2165 : {
2166 64493 : mvc *sql = query->sql;
2167 64493 : exp_kind ek = {type_value, card_column, TRUE};
2168 64493 : dlist *dl = sc->data.lval;
2169 64493 : symbol *lo = NULL;
2170 64493 : dnode *n = dl->h->next, *dn = NULL;
2171 64493 : sql_exp *le = NULL, *re, *e = NULL;
2172 64493 : list *ll = sa_list(sql->sa);
2173 64493 : int is_tuple = 0, add_select = 0;
2174 :
2175 : /* complex case */
2176 : //if (dl->h->type == type_list) { /* (a,b..) in (.. ) */
2177 64493 : if (dl->h->type == type_symbol && dl->h->data.sym->token == SQL_VALUES) {
2178 4178 : lo = dl->h->data.sym;
2179 4178 : dn = lo->data.lval->h->data.lval->h;
2180 4178 : lo = dn->data.sym;
2181 4178 : dn = dn->next;
2182 : } else {
2183 60315 : lo = dl->h->data.sym;
2184 : }
2185 203967 : for( ; lo; lo = dn?dn->data.sym:NULL, dn = dn?dn->next:NULL ) {
2186 69741 : le = rel_value_exp(query, rel, lo, f|sql_farg, ek);
2187 69741 : if (!le)
2188 : return NULL;
2189 69737 : append(ll, le);
2190 : }
2191 64489 : if (list_length(ll) == 1) {
2192 60313 : le = ll->h->data;
2193 60313 : ek.card = card_set;
2194 : } else {
2195 4176 : le = exp_values(sql->sa, ll);
2196 4176 : exp_label(sql->sa, le, ++sql->label);
2197 4176 : ek.type = list_length(ll);
2198 4176 : is_tuple = list_length(ll);
2199 : }
2200 : /* list of values or subqueries */
2201 : /* 3 right hand side cases,
2202 : * 1 - value/tuple list of atoms
2203 : * 2 - list of scalar sub queries (needs check on 1 row/column per query)
2204 : * 3 - single tabular ie. multi column, multi row query
2205 : */
2206 64489 : if (n->type == type_list) {
2207 64489 : sql_exp *values;
2208 64489 : list *vals = sa_list(sql->sa);
2209 :
2210 64489 : n = dl->h->next;
2211 64489 : n = n->data.lval->h;
2212 :
2213 316392 : for (; n; n = n->next) {
2214 251942 : if (n->type == type_list) {
2215 0 : dnode *m = n->data.lval->h;
2216 0 : list *rl = sa_list(sql->sa);
2217 0 : for (; m; m = m->next) {
2218 0 : assert(m->type == type_symbol);
2219 0 : sql_exp *re = rel_value_exp(query, rel, m->data.sym, f|sql_farg, ek);
2220 0 : if (!re)
2221 : return NULL;
2222 0 : append(rl, re);
2223 : }
2224 0 : re = exp_values(sql->sa, rl);
2225 : } else {
2226 251942 : assert(n->type == type_symbol);
2227 251942 : re = rel_value_exp(query, rel, n->data.sym, f|sql_farg, ek);
2228 : }
2229 251942 : if (!re)
2230 : return NULL;
2231 251918 : if (is_tuple && (!exp_is_rel(re) && !is_values(re)))
2232 4 : return sql_error(sql, 02, SQLSTATE(42000) "Cannot match a tuple to a single value");
2233 4174 : if (is_tuple && exp_is_rel(re)) {
2234 4174 : sql_rel *r = exp_rel_get_rel(sql->sa, re);
2235 :
2236 4174 : if (!r)
2237 0 : return sql_error(sql, 02, SQLSTATE(42000) "Subquery missing");
2238 4174 : if (r->nrcols != ek.type)
2239 12 : return sql_error(sql, 02, SQLSTATE(42000) "Subquery has too %s columns", (r->nrcols < ek.type) ? "few" : "many");
2240 4165 : re = exp_rel_label(sql, re);
2241 4165 : if (r && r->l && n->next) /* not a value list */
2242 2 : return sql_error(sql, 02, SQLSTATE(42000) "subquery must return only one column");
2243 247740 : } else if (exp_is_rel(re)) {
2244 8598 : sql_rel *r = exp_rel_get_rel(sql->sa, re);
2245 8598 : add_select = 1;
2246 8598 : if (rel && *rel && is_join((*rel)->op))
2247 4469 : set_dependent((*rel));
2248 8598 : if (is_project(r->op) && is_project_true(r->l) && list_length(r->exps) == 1)
2249 80 : re = r->exps->h->data;
2250 239142 : } else if (is_values(re) && is_tuple != list_length(exp_get_values(re))) {
2251 0 : return sql_error(sql, 02, SQLSTATE(42000) "Tuple sizes do not match");
2252 : }
2253 251903 : append(vals, re);
2254 : }
2255 :
2256 64450 : if (list_empty(vals))
2257 0 : return sql_error(sql, 02, SQLSTATE(42000) "The list of values for IN operator cannot be empty");
2258 :
2259 64450 : values = exp_values(sql->sa, vals);
2260 64450 : exp_label(sql->sa, values, ++sql->label);
2261 64450 : if (is_tuple) {
2262 4161 : if (!(values = exp_tuples_set_supertype(sql, exp_get_values(le), values)))
2263 : return NULL;
2264 4161 : if (!(le->f = tuples_check_types(sql, exp_get_values(le), values)))
2265 : return NULL;
2266 : } else { /* if it's not a tuple, enforce coercion on the type for every element on the list */
2267 60289 : sql_subtype super, *le_tpe = exp_subtype(le), *values_tpe = NULL;
2268 :
2269 308028 : for (node *m = vals->h; m; m = m->next) { /* first get values supertype */
2270 247739 : sql_exp *e = m->data;
2271 247739 : sql_subtype *tpe = exp_subtype(e);
2272 :
2273 247739 : if (values_tpe && tpe) {
2274 187447 : cmp_supertype(&super, values_tpe, tpe);
2275 187447 : *values_tpe = super;
2276 60292 : } else if (!values_tpe && tpe) {
2277 60285 : super = *tpe;
2278 60285 : values_tpe = &super;
2279 : }
2280 : }
2281 60289 : if (!le_tpe)
2282 2 : le_tpe = values_tpe;
2283 60289 : if (!values_tpe)
2284 4 : values_tpe = le_tpe;
2285 60289 : if (!le_tpe || !values_tpe)
2286 1 : return sql_error(sql, 01, SQLSTATE(42000) "For the IN operator, both sides must have a type defined");
2287 60288 : cmp_supertype(&super, values_tpe, le_tpe); /* compute supertype */
2288 :
2289 : /* on selection/join cases we can generate cmp expressions instead of anyequal for trivial cases */
2290 60288 : if ((is_sql_where(f) || is_sql_having(f)) && !is_sql_farg(f) && !exp_has_rel(le) && exps_are_atoms(vals)) {
2291 23850 : if (list_length(vals) == 1) { /* use cmp_equal instead of cmp_in for 1 expression */
2292 117 : sql_exp *first = vals->h->data;
2293 117 : if (rel_convert_types(sql, rel ? *rel : NULL, rel ? *rel : NULL, &le, &first, 1, type_equal_no_any) < 0)
2294 0 : return NULL;
2295 142 : e = exp_compare(sql->sa, le, first, (sc->token == SQL_IN) ? cmp_equal : cmp_notequal);
2296 : } else { /* use cmp_in instead of anyequal for n simple expressions */
2297 120743 : for (node *n = vals->h ; n ; n = n->next)
2298 97010 : if ((n->data = exp_check_type(sql, &super, rel ? *rel : NULL, n->data, type_equal)) == NULL)
2299 : return NULL;
2300 23733 : if ((le = exp_check_type(sql, &super, rel ? *rel : NULL, le, type_equal)) == NULL)
2301 : return NULL;
2302 32413 : e = exp_in(sql->sa, le, vals, (sc->token == SQL_IN) ? cmp_in : cmp_notin);
2303 : }
2304 : }
2305 23850 : if (!e) { /* after computing supertype, check types for each IN value */
2306 187049 : for (node *n = vals->h ; n ; n = n->next)
2307 150611 : if ((n->data = exp_check_type(sql, &super, rel ? *rel : NULL, n->data, type_equal)) == NULL)
2308 : return NULL;
2309 36438 : values->tpe = *exp_subtype(vals->h->data);
2310 36438 : if (!(le = exp_check_type(sql, &super, rel ? *rel : NULL, le, type_equal)))
2311 : return NULL;
2312 : }
2313 : }
2314 60288 : if (!e) {
2315 40599 : if (add_select && rel && *rel && !is_project((*rel)->op) && !is_select((*rel)->op) && !is_base((*rel)->op))
2316 4468 : *rel = rel_select(sql->sa, *rel, NULL);
2317 40599 : if ((rel && *rel) || exp_has_rel(le) || exp_has_rel(values))
2318 35013 : e = exp_in_func(sql, le, values, (sc->token == SQL_IN), is_tuple);
2319 : else
2320 5586 : e = exp_in_aggr(sql, le, values, (sc->token == SQL_IN), is_tuple);
2321 : }
2322 : }
2323 : return e;
2324 : }
2325 :
2326 : static sql_rel *
2327 34048 : rel_in_exp(sql_query *query, sql_rel *rel, symbol *sc, int f)
2328 : {
2329 34048 : mvc *sql = query->sql;
2330 34048 : sql_exp *e = rel_in_value_exp(query, &rel, sc, f);
2331 :
2332 34048 : assert(!is_sql_sel(f));
2333 34048 : if (!e || !rel)
2334 : return NULL;
2335 :
2336 34021 : if (e->type == e_cmp) { /* it's a exp_in or cmp_equal of simple expressions, push down early on if possible */
2337 23848 : sql_exp *ls = e->l;
2338 23848 : bool rlist = (e->flag == cmp_in || e->flag == cmp_notin);
2339 23848 : unsigned int rcard = rlist ? exps_card(e->r) : exp_card(e->r);
2340 23848 : int r_is_atoms = rlist ? exps_are_atoms(e->r) : exp_is_atom(e->r);
2341 23848 : int r_has_freevar = rlist ? exps_have_freevar(sql, e->r) : exp_has_freevar(sql, e->r);
2342 :
2343 23848 : if (rcard <= CARD_ATOM && (r_is_atoms || r_has_freevar || exp_has_freevar(sql, ls))) {
2344 23848 : if ((exp_card(ls) == rcard) || rel->processed) /* bin compare op */
2345 5453 : return rel_select(sql->sa, rel, e);
2346 :
2347 18395 : return push_select_exp(sql, rel, e, ls, f);
2348 : } else { /* join */
2349 0 : sql_exp *rs = rlist ? exps_find_one_multi_exp(e->r) : e->r;
2350 0 : if (rs)
2351 0 : return push_join_exp(sql, rel, e, ls, rs, NULL, f);
2352 : }
2353 : }
2354 10173 : if (is_outerjoin(rel->op))
2355 13 : return rel_select(sql->sa, rel, e);
2356 10160 : return rel_select_add_exp(sql->sa, rel, e);
2357 : }
2358 :
2359 : static bool
2360 53565 : not_symbol_can_be_propagated(mvc *sql, symbol *sc)
2361 : {
2362 53565 : switch (sc->token) {
2363 : case SQL_IN:
2364 : case SQL_NOT_IN:
2365 : case SQL_EXISTS:
2366 : case SQL_NOT_EXISTS:
2367 : case SQL_LIKE:
2368 : case SQL_NOT_LIKE:
2369 : case SQL_BETWEEN:
2370 : case SQL_NOT_BETWEEN:
2371 : case SQL_IS_NULL:
2372 : case SQL_IS_NOT_NULL:
2373 : case SQL_NOT:
2374 : case SQL_COMPARE:
2375 : return true;
2376 6822 : case SQL_AND:
2377 : case SQL_OR: {
2378 6822 : symbol *lo = sc->data.lval->h->data.sym;
2379 6822 : symbol *ro = sc->data.lval->h->next->data.sym;
2380 6826 : return not_symbol_can_be_propagated(sql, lo) && not_symbol_can_be_propagated(sql, ro);
2381 : }
2382 37495 : default:
2383 37495 : return false;
2384 : }
2385 : }
2386 :
2387 : /* Warning, this function assumes the entire bison tree can be negated, so call it after 'not_symbol_can_be_propagated' */
2388 : static symbol *
2389 16065 : negate_symbol_tree(mvc *sql, symbol *sc)
2390 : {
2391 16065 : switch (sc->token) {
2392 1454 : case SQL_IN:
2393 1454 : sc->token = SQL_NOT_IN;
2394 1454 : break;
2395 22 : case SQL_NOT_IN:
2396 22 : sc->token = SQL_IN;
2397 22 : break;
2398 0 : case SQL_EXISTS:
2399 0 : sc->token = SQL_NOT_EXISTS;
2400 0 : break;
2401 0 : case SQL_NOT_EXISTS:
2402 0 : sc->token = SQL_EXISTS;
2403 0 : break;
2404 7 : case SQL_LIKE:
2405 7 : sc->token = SQL_NOT_LIKE;
2406 7 : break;
2407 0 : case SQL_NOT_LIKE:
2408 0 : sc->token = SQL_LIKE;
2409 0 : break;
2410 17 : case SQL_BETWEEN:
2411 17 : sc->token = SQL_NOT_BETWEEN;
2412 17 : break;
2413 11 : case SQL_NOT_BETWEEN:
2414 11 : sc->token = SQL_BETWEEN;
2415 11 : break;
2416 32 : case SQL_IS_NULL:
2417 32 : sc->token = SQL_IS_NOT_NULL;
2418 32 : break;
2419 15 : case SQL_IS_NOT_NULL:
2420 15 : sc->token = SQL_IS_NULL;
2421 15 : break;
2422 27 : case SQL_NOT: { /* nested NOTs eliminate each other */
2423 27 : if (sc->data.sym->token == SQL_ATOM) {
2424 5 : AtomNode *an = (AtomNode*) sc->data.sym;
2425 5 : sc = newAtomNode(sql->sa, an->a);
2426 22 : } else if (sc->data.sym->token == SQL_SELECT) {
2427 2 : SelectNode *sn = (SelectNode*) sc->data.sym;
2428 2 : sc = newSelectNode(sql->sa, sn->distinct, sn->selection, sn->into, sn->from, sn->where, sn->groupby, sn->having,
2429 : sn->orderby, sn->name, sn->limit, sn->offset, sn->sample, sn->seed, sn->window);
2430 : } else {
2431 20 : memmove(sc, sc->data.sym, sizeof(symbol));
2432 : }
2433 : } break;
2434 7662 : case SQL_COMPARE: {
2435 7662 : dnode *cmp_n = sc->data.lval->h;
2436 7662 : comp_type neg_cmp_type = negate_compare(compare_str2type(cmp_n->next->data.sval)); /* negate the comparator */
2437 7662 : if (cmp_n->next->next->next) {
2438 22 : switch(cmp_n->next->next->next->data.i_val)
2439 : {
2440 12 : case 0: /* negating ANY/ALL */
2441 12 : cmp_n->next->next->next->data.i_val = 1;
2442 12 : break;
2443 7 : case 1: /* negating ANY/ALL */
2444 7 : cmp_n->next->next->next->data.i_val = 0;
2445 7 : break;
2446 2 : case 2: /* negating IS [NOT] DINSTINCT FROM */
2447 2 : cmp_n->next->next->next->data.i_val = 3;
2448 2 : break;
2449 1 : case 3: /* negating IS [NOT] DINSTINCT FROM */
2450 1 : cmp_n->next->next->next->data.i_val = 2;
2451 1 : break;
2452 : }
2453 : }
2454 7662 : cmp_n->next->data.sval = sa_strdup(sql->sa, compare_func(neg_cmp_type, 0));
2455 7662 : } break;
2456 6818 : case SQL_AND:
2457 : case SQL_OR: {
2458 6818 : sc->data.lval->h->data.sym = negate_symbol_tree(sql, sc->data.lval->h->data.sym);
2459 6818 : sc->data.lval->h->next->data.sym= negate_symbol_tree(sql, sc->data.lval->h->next->data.sym);
2460 6818 : sc->token = sc->token == SQL_AND ? SQL_OR : SQL_AND;
2461 6818 : } break;
2462 : default:
2463 : break;
2464 : }
2465 16065 : return sc;
2466 : }
2467 :
2468 : static int
2469 3111 : exp_between_check_types(sql_subtype *res, sql_subtype *t1, sql_subtype *t2, sql_subtype *t3)
2470 : {
2471 3111 : bool type_found = false;
2472 3111 : sql_subtype super;
2473 :
2474 3111 : if (t1 && t2) {
2475 3105 : cmp_supertype(&super, t2, t1);
2476 3105 : type_found = true;
2477 6 : } else if (t1) {
2478 3 : super = *t1;
2479 3 : type_found = true;
2480 3 : } else if (t2) {
2481 1 : super = *t2;
2482 1 : type_found = true;
2483 : }
2484 3111 : if (t3) {
2485 3108 : if (type_found)
2486 3107 : cmp_supertype(&super, t3, &super);
2487 : else
2488 1 : super = *t3;
2489 : type_found = true;
2490 : }
2491 3 : if (!type_found)
2492 : return -1;
2493 3110 : *res = super;
2494 3110 : return 0;
2495 : }
2496 :
2497 : static bool
2498 119056 : exp_is_null_no_value_opt(sql_exp *e)
2499 : {
2500 119056 : if (!e)
2501 : return false;
2502 122982 : while (is_convert(e->type))
2503 3926 : e = e->l;
2504 238085 : return e->type == e_atom && e->l && atom_null(e->l);
2505 : }
2506 :
2507 : sql_exp *
2508 2670276 : rel_logical_value_exp(sql_query *query, sql_rel **rel, symbol *sc, int f, exp_kind ek)
2509 : {
2510 2670375 : mvc *sql = query->sql;
2511 :
2512 2670375 : if (!sc)
2513 : return NULL;
2514 :
2515 2670375 : if (mvc_highwater(sql))
2516 53 : return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2517 :
2518 2670928 : switch (sc->token) {
2519 52430 : case SQL_OR:
2520 : case SQL_AND:
2521 : {
2522 52430 : symbol *lo = sc->data.lval->h->data.sym;
2523 52430 : symbol *ro = sc->data.lval->h->next->data.sym;
2524 52430 : sql_exp *ls, *rs;
2525 :
2526 52430 : if (!(ls = rel_value_exp(query, rel, lo, f|sql_farg, ek)))
2527 : return NULL;
2528 52429 : if (!(rs = rel_value_exp(query, rel, ro, f|sql_farg, ek)))
2529 : return NULL;
2530 92640 : return rel_binop_(sql, rel ? *rel : NULL, ls, rs, "sys", sc->token == SQL_OR ? "or": "and", card_value, false);
2531 : }
2532 5 : case SQL_FILTER:
2533 : /* [ x,..] filter [ y,..] */
2534 : /* todo add anti, [ x,..] not filter [ y,...] */
2535 : /* no correlation */
2536 : {
2537 5 : dnode *ln = sc->data.lval->h->data.lval->h;
2538 5 : dnode *rn = sc->data.lval->h->next->next->data.lval->h;
2539 5 : dlist *filter_op = sc->data.lval->h->next->data.lval;
2540 5 : char *fname = qname_schema_object(filter_op);
2541 5 : char *sname = qname_schema(filter_op);
2542 5 : list *exps, *tl;
2543 5 : sql_subtype *obj_type = NULL;
2544 :
2545 5 : exps = sa_list(sql->sa);
2546 5 : tl = sa_list(sql->sa);
2547 15 : for (; ln; ln = ln->next) {
2548 5 : symbol *sym = ln->data.sym;
2549 :
2550 5 : sql_exp *e = rel_value_exp(query, rel, sym, f|sql_farg, ek);
2551 5 : if (!e)
2552 : return NULL;
2553 5 : if (!obj_type)
2554 5 : obj_type = exp_subtype(e);
2555 5 : list_append(exps, e);
2556 5 : append(tl, exp_subtype(e));
2557 : }
2558 13 : for (; rn; rn = rn->next) {
2559 10 : symbol *sym = rn->data.sym;
2560 :
2561 10 : sql_exp *e = rel_value_exp(query, rel, sym, f|sql_farg, ek);
2562 10 : if (!e)
2563 : return NULL;
2564 8 : list_append(exps, e);
2565 8 : append(tl, exp_subtype(e));
2566 : }
2567 : /* find the predicate filter function */
2568 3 : return _rel_nop(sql, sname, fname, tl, rel ? *rel : NULL, exps, ek);
2569 : }
2570 118773 : case SQL_COMPARE:
2571 : {
2572 118773 : dnode *n = sc->data.lval->h;
2573 118773 : symbol *lo = n->data.sym;
2574 118773 : symbol *ro = n->next->next->data.sym;
2575 118773 : char *compare_op = n->next->data.sval;
2576 118773 : int quantifier = 0, need_not = 0;
2577 118773 : sql_exp *rs = NULL, *ls;
2578 118773 : comp_type cmp_type = compare_str2type(compare_op);
2579 118773 : bool is_not_distinct_from = false;
2580 118773 : bool is_distinct_from = false;
2581 :
2582 : /*
2583 : * = ANY -> IN, <> ALL -> NOT( = ANY) -> NOT IN
2584 : * = ALL -> all(groupby(all, nil)), <> ANY -> NOT ( = ALL )
2585 : */
2586 118773 : if (n->next->next->next)
2587 258 : quantifier = n->next->next->next->data.i_val + 1;
2588 258 : assert(quantifier == 0 || quantifier == 1 || quantifier == 2 || quantifier == 3 || quantifier == 4);
2589 :
2590 : /* [NOT] DISTINCT FROM */
2591 118773 : if (quantifier == 3) {
2592 : is_not_distinct_from = true;
2593 : quantifier = 0;
2594 : }
2595 118759 : else if (quantifier == 4) {
2596 14 : is_distinct_from = true;
2597 14 : quantifier = 0;
2598 : }
2599 :
2600 118773 : if ((quantifier == 1 && cmp_type == cmp_equal) ||
2601 118707 : (quantifier == 2 && cmp_type == cmp_notequal)) {
2602 93 : dlist *dl = dlist_create(sql->sa);
2603 : /* map into IN/NOT IN */
2604 93 : sc->token = cmp_type==cmp_equal?SQL_IN:SQL_NOT_IN;
2605 93 : n->next->type = type_list;
2606 93 : n->next->data.lval = dl;
2607 93 : n->next->next->next = NULL; /* remove quantifier */
2608 93 : dl->h = n->next->next;
2609 93 : n->next->next = NULL; /* (remove comparison) moved righthand side */
2610 93 : return rel_logical_value_exp(query, rel, sc, f, ek);
2611 : }
2612 : /* <> ANY -> NOT (= ALL) */
2613 118680 : if (quantifier == 1 && cmp_type == cmp_notequal) {
2614 15 : need_not = 1;
2615 15 : quantifier = 2;
2616 15 : cmp_type = cmp_equal;
2617 15 : compare_op = "=";
2618 : }
2619 :
2620 118680 : ls = rel_value_exp(query, rel, lo, f|sql_farg, ek);
2621 118680 : if (!ls)
2622 : return NULL;
2623 118668 : if (quantifier)
2624 137 : ek.card = card_set;
2625 :
2626 118668 : rs = rel_value_exp(query, rel, ro, f|sql_farg, ek);
2627 118668 : if (!rs)
2628 : return NULL;
2629 :
2630 118658 : if (is_distinct_from || is_not_distinct_from) {
2631 28 : if (rel_convert_types(sql, rel ? *rel : NULL, rel ? *rel : NULL, &ls, &rs, 1, type_equal_no_any) < 0)
2632 : return NULL;
2633 42 : sql_exp* e = exp_compare(sql->sa, ls, rs, is_not_distinct_from?cmp_equal:cmp_notequal);
2634 28 : set_semantics(e);
2635 28 : return e;
2636 : }
2637 :
2638 118630 : if (rs->type == e_atom)
2639 107177 : quantifier = 0;
2640 :
2641 118630 : if (!exp_is_rel(ls) && !exp_is_rel(rs) && ls->card < rs->card) {
2642 13 : sql_exp *swap = ls; /* has to swap parameters like in the rel_logical_exp case */
2643 13 : ls = rs;
2644 13 : rs = swap;
2645 13 : cmp_type = swap_compare(cmp_type);
2646 : }
2647 :
2648 118630 : if (rel_convert_types(sql, rel ? *rel : NULL, rel ? *rel : NULL, &ls, &rs, 1, type_equal_no_any) < 0)
2649 : return NULL;
2650 118627 : if (exp_is_null_no_value_opt(ls) && exp_is_null_no_value_opt(rs))
2651 7 : return exp_atom(sql->sa, atom_general(sql->sa, sql_bind_localtype("bit"), NULL, 0));
2652 :
2653 118620 : return exp_compare_func(sql, ls, rs, compare_func(cmp_type, need_not), quantifier);
2654 : }
2655 : /* Set Member ship */
2656 30445 : case SQL_IN:
2657 : case SQL_NOT_IN:
2658 30445 : return rel_in_value_exp(query, rel, sc, f);
2659 1093 : case SQL_EXISTS:
2660 : case SQL_NOT_EXISTS:
2661 1093 : return rel_exists_value_exp(query, rel, sc, f);
2662 347 : case SQL_LIKE:
2663 : case SQL_NOT_LIKE:
2664 : {
2665 347 : symbol *lo = sc->data.lval->h->data.sym;
2666 347 : symbol *ro = sc->data.lval->h->next->data.sym;
2667 347 : int insensitive = sc->data.lval->h->next->next->data.i_val;
2668 347 : int anti = (sc->token == SQL_NOT_LIKE) != (sc->data.lval->h->next->next->next->data.i_val != 0);
2669 347 : sql_subtype *st = sql_bind_localtype("str");
2670 347 : sql_exp *le = rel_value_exp(query, rel, lo, f|sql_farg, ek), *re, *ee = NULL, *ie = exp_atom_bool(sql->sa, insensitive);
2671 :
2672 347 : if (!le)
2673 : return NULL;
2674 :
2675 347 : if (!exp_subtype(le))
2676 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: parameter not allowed on "
2677 : "left hand side of LIKE operator");
2678 :
2679 347 : lo = ro->data.lval->h->data.sym;
2680 : /* like uses a single string pattern */
2681 347 : ek.card = card_value;
2682 347 : re = rel_value_exp(query, rel, lo, f|sql_farg, ek);
2683 347 : if (!re)
2684 : return NULL;
2685 343 : if ((re = exp_check_type(sql, st, rel ? *rel : NULL, re, type_equal)) == NULL)
2686 0 : return sql_error(sql, 02, SQLSTATE(42000) "LIKE: wrong type, should be string");
2687 343 : if ((le = exp_check_type(sql, st, rel ? *rel : NULL, le, type_equal)) == NULL)
2688 0 : return sql_error(sql, 02, SQLSTATE(42000) "LIKE: wrong type, should be string");
2689 : /* Do we need to escape ? */
2690 343 : if (dlist_length(ro->data.lval) == 2) {
2691 63 : char *escape = ro->data.lval->h->next->data.sval;
2692 63 : ee = exp_atom(sql->sa, atom_string(sql->sa, st, sa_strdup(sql->sa, escape)));
2693 : } else {
2694 280 : ee = exp_atom(sql->sa, atom_string(sql->sa, st, sa_strdup(sql->sa, "")));
2695 : }
2696 573 : return rel_nop_(sql, rel ? *rel : NULL, le, re, ee, ie, "sys", anti ? "not_like" : "like", card_value);
2697 : }
2698 165 : case SQL_BETWEEN:
2699 : case SQL_NOT_BETWEEN:
2700 : {
2701 165 : symbol *lo = sc->data.lval->h->data.sym;
2702 165 : int symmetric = sc->data.lval->h->next->data.i_val;
2703 165 : symbol *ro1 = sc->data.lval->h->next->next->data.sym;
2704 165 : symbol *ro2 = sc->data.lval->h->next->next->next->data.sym;
2705 165 : sql_exp *le, *re1, *re2;
2706 165 : sql_subtype super;
2707 :
2708 165 : assert(sc->data.lval->h->next->type == type_int);
2709 :
2710 165 : if (!(le = rel_value_exp(query, rel, lo, f|sql_farg, ek)))
2711 : return NULL;
2712 164 : if (!(re1 = rel_value_exp(query, rel, ro1, f|sql_farg, ek)))
2713 : return NULL;
2714 161 : if (!(re2 = rel_value_exp(query, rel, ro2, f|sql_farg, ek)))
2715 : return NULL;
2716 :
2717 156 : if (exp_between_check_types(&super, exp_subtype(le), exp_subtype(re1), exp_subtype(re2)) < 0)
2718 0 : return sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) on both sides of an expression");
2719 :
2720 156 : if ((le = exp_check_type(sql, &super, rel ? *rel:NULL, le, type_equal)) == NULL ||
2721 156 : (re1 = exp_check_type(sql, &super, rel ? *rel:NULL, re1, type_equal)) == NULL ||
2722 156 : (re2 = exp_check_type(sql, &super, rel ? *rel:NULL, re2, type_equal)) == NULL)
2723 0 : return NULL;
2724 :
2725 156 : le = exp_compare2(sql->sa, le, re1, re2, 3, symmetric);
2726 156 : if (sc->token == SQL_NOT_BETWEEN)
2727 56 : set_anti(le);
2728 : return le;
2729 : }
2730 15227 : case SQL_IS_NULL:
2731 : case SQL_IS_NOT_NULL:
2732 : /* is (NOT) NULL */
2733 : {
2734 15227 : sql_exp *le = rel_value_exp(query, rel, sc->data.sym, f|sql_farg, ek);
2735 :
2736 15227 : if (!le)
2737 : return NULL;
2738 19527 : le = rel_unop_(sql, rel ? *rel : NULL, le, "sys", sc->token == SQL_IS_NULL ? "isnull" : "isnotnull", card_value);
2739 15224 : if (!le)
2740 : return NULL;
2741 15224 : set_has_no_nil(le);
2742 15224 : return le;
2743 : }
2744 19249 : case SQL_NOT: {
2745 19249 : if (not_symbol_can_be_propagated(sql, sc->data.sym)) {
2746 99 : sc->data.sym = negate_symbol_tree(sql, sc->data.sym);
2747 99 : return rel_logical_value_exp(query, rel, sc->data.sym, f, ek);
2748 : }
2749 19150 : sql_exp *le = rel_value_exp(query, rel, sc->data.sym, f|sql_farg, ek);
2750 :
2751 19150 : if (!le)
2752 : return NULL;
2753 19149 : return rel_unop_(sql, rel ? *rel : NULL, le, "sys", "not", card_value);
2754 : }
2755 : case SQL_ATOM: {
2756 2411917 : AtomNode *an = (AtomNode *) sc;
2757 2411917 : assert(an && an->a);
2758 2411917 : return exp_atom(sql->sa, an->a);
2759 : }
2760 20759 : case SQL_IDENT:
2761 : case SQL_COLUMN:
2762 20759 : return rel_column_ref(query, rel, sc, f);
2763 202 : case SQL_UNION:
2764 : case SQL_EXCEPT:
2765 : case SQL_INTERSECT: {
2766 202 : sql_rel *sq;
2767 :
2768 202 : if (is_psm_call(f) || is_sql_merge(f))
2769 4 : return sql_error(sql, 02, SQLSTATE(42000) "%s: subqueries not supported inside %s", is_psm_call(f) ? "CALL" : "MERGE", is_psm_call(f) ? "CALL statements" : "MERGE conditions");
2770 200 : if (rel && *rel)
2771 142 : query_push_outer(query, *rel, f);
2772 200 : sq = rel_setquery(query, sc);
2773 200 : if (rel && *rel) {
2774 142 : *rel = query_pop_outer(query);
2775 142 : if (is_sql_join(f) && is_groupby((*rel)->op)) {
2776 0 : return sql_error(sql, 05, SQLSTATE(42000) "SELECT: aggregate functions not allowed in JOIN conditions");
2777 142 : } else if (is_sql_where(f) && is_groupby((*rel)->op)) {
2778 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: aggregate functions not allowed in WHERE clause");
2779 142 : } else if ((is_sql_update_set(f) || is_sql_psm(f)) && is_groupby((*rel)->op)) {
2780 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: aggregate functions not allowed in SET, WHILE, IF, ELSE, CASE, WHEN, RETURN, ANALYZE clauses");
2781 : }
2782 : }
2783 200 : if (!sq)
2784 : return NULL;
2785 198 : if (ek.type == type_value && ek.card <= card_set && is_project(sq->op) && list_length(sq->exps) > 1)
2786 1 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: subquery must return only one column");
2787 197 : if (ek.type == type_relation && is_project(sq->op) && list_length(sq->exps) != ek.type)
2788 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: subquery has too %s columns", list_length(sq->exps) < ek.type ? "few" : "many");
2789 303 : if (ek.type == type_value && ek.card < card_set && sq->card >= CARD_AGGR && (is_sql_sel(f) | is_sql_having(f) | is_sql_farg(f) |
2790 106 : ( is_sql_where(f) && rel && (!*rel || is_basetable((*rel)->op) || is_simple_project((*rel)->op) || is_joinop((*rel)->op)))))
2791 106 : sq = rel_zero_or_one(sql, sq, ek);
2792 197 : return exp_rel(sql, sq);
2793 : }
2794 1 : case SQL_DEFAULT:
2795 1 : return sql_error(sql, 02, SQLSTATE(42000) "DEFAULT keyword not allowed outside insert and update statements");
2796 315 : default: {
2797 315 : sql_exp *le = rel_value_exp(query, rel, sc, f|sql_farg, ek);
2798 315 : sql_subtype bt;
2799 :
2800 315 : if (!le)
2801 : return NULL;
2802 313 : sql_find_subtype(&bt, "boolean", 0, 0);
2803 313 : if ((le = exp_check_type(sql, &bt, rel ? *rel : NULL, le, type_equal)) == NULL)
2804 : return NULL;
2805 313 : return rel_binop_(sql, rel ? *rel : NULL, le, exp_atom_bool(sql->sa, 1), "sys", "=", 0, true);
2806 : }
2807 : }
2808 : /* never reached, as all switch cases have a `return` */
2809 : }
2810 :
2811 : sql_rel *
2812 640820 : rel_logical_exp(sql_query *query, sql_rel *rel, symbol *sc, int f)
2813 : {
2814 640820 : mvc *sql = query->sql;
2815 640820 : exp_kind ek = {type_value, card_column, TRUE};
2816 :
2817 640820 : if (!sc)
2818 : return NULL;
2819 :
2820 640820 : if (mvc_highwater(sql))
2821 0 : return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2822 :
2823 640820 : switch (sc->token) {
2824 17675 : case SQL_OR:
2825 : {
2826 17675 : list *exps = NULL, *lexps = NULL, *rexps = NULL;
2827 17675 : symbol *lo = sc->data.lval->h->data.sym;
2828 17675 : symbol *ro = sc->data.lval->h->next->data.sym;
2829 17675 : sql_rel *lr, *rr;
2830 :
2831 17675 : if (!rel)
2832 : return NULL;
2833 :
2834 17675 : lr = rel;
2835 17675 : rr = rel_dup(lr);
2836 :
2837 17675 : if (is_outerjoin(rel->op) && !is_processed(rel)) {
2838 44 : exps = rel->exps;
2839 :
2840 44 : lr = rel_select_copy(sql->sa, lr, sa_list(sql->sa));
2841 44 : lr = rel_logical_exp(query, lr, lo, f | sql_or);
2842 44 : if (!lr)
2843 : return NULL;
2844 43 : query_processed(query);
2845 43 : rr = rel_select_copy(sql->sa, rr, sa_list(sql->sa));
2846 43 : rr = rel_logical_exp(query, rr, ro, f | sql_or);
2847 43 : if (!rr)
2848 : return NULL;
2849 42 : if (lr->l == rr->l) {
2850 42 : lexps = lr->exps;
2851 42 : lr = lr->l;
2852 42 : rexps = rr->exps;
2853 42 : rr = rr->l;
2854 : }
2855 42 : rel = NULL;
2856 : } else {
2857 17631 : lr = rel_logical_exp(query, lr, lo, f | sql_or);
2858 17631 : if (!lr)
2859 : return NULL;
2860 17629 : rr = rel_logical_exp(query, rr, ro, f | sql_or);
2861 : }
2862 :
2863 17671 : if (!lr || !rr)
2864 : return NULL;
2865 17671 : return rel_or(sql, rel, lr, rr, exps, lexps, rexps);
2866 : }
2867 196115 : case SQL_AND:
2868 : {
2869 196115 : symbol *lo = sc->data.lval->h->data.sym;
2870 196115 : symbol *ro = sc->data.lval->h->next->data.sym;
2871 196115 : rel = rel_logical_exp(query, rel, lo, f);
2872 196115 : if (!rel)
2873 : return NULL;
2874 196108 : return rel_logical_exp(query, rel, ro, f);
2875 : }
2876 60 : case SQL_FILTER:
2877 : /* [ x,..] filter [ y,..] */
2878 : /* todo add anti, [ x,..] NOT filter [ y,...] */
2879 : /* no correlation */
2880 : {
2881 60 : dnode *ln = sc->data.lval->h->data.lval->h;
2882 60 : dnode *rn = sc->data.lval->h->next->next->data.lval->h;
2883 60 : dlist *filter_op = sc->data.lval->h->next->data.lval;
2884 60 : char *fname = qname_schema_object(filter_op);
2885 60 : char *sname = qname_schema(filter_op);
2886 60 : list *l, *r;
2887 :
2888 60 : l = sa_list(sql->sa);
2889 60 : r = sa_list(sql->sa);
2890 180 : for (; ln; ln = ln->next) {
2891 60 : symbol *sym = ln->data.sym;
2892 :
2893 60 : sql_exp *e = rel_value_exp(query, &rel, sym, f|sql_farg, ek);
2894 60 : if (!e)
2895 : return NULL;
2896 60 : list_append(l, e);
2897 : }
2898 163 : for (; rn; rn = rn->next) {
2899 103 : symbol *sym = rn->data.sym;
2900 :
2901 103 : sql_exp *e = rel_value_exp(query, &rel, sym, f|sql_farg, ek);
2902 103 : if (!e)
2903 : return NULL;
2904 103 : list_append(r, e);
2905 : }
2906 60 : return rel_filter(sql, rel, l, r, sname, fname, 0, f);
2907 : }
2908 354995 : case SQL_COMPARE:
2909 : {
2910 354995 : dnode *n = sc->data.lval->h;
2911 354995 : symbol *lo = n->data.sym;
2912 354995 : symbol *ro = n->next->next->data.sym;
2913 354995 : char *compare_op = n->next->data.sval;
2914 354995 : int quantifier = 0;
2915 354995 : int is_semantics = 0;
2916 :
2917 354995 : if (n->next->next->next)
2918 131 : quantifier = n->next->next->next->data.i_val + 1;
2919 131 : assert(quantifier == 0 || quantifier == 1 || quantifier == 2 || quantifier == 3 || quantifier == 4);
2920 :
2921 354995 : if (quantifier >= 3) {
2922 10 : if (quantifier == 4)
2923 6 : compare_op = "<>";
2924 : quantifier = 0;
2925 : is_semantics = 1;
2926 : }
2927 354995 : return rel_compare(query, rel, sc, lo, ro, compare_op, f, ek, quantifier, is_semantics);
2928 : }
2929 : /* Set Member ship */
2930 34048 : case SQL_IN:
2931 : case SQL_NOT_IN:
2932 34048 : return rel_in_exp(query, rel, sc, f);
2933 1012 : case SQL_EXISTS:
2934 : case SQL_NOT_EXISTS:
2935 1012 : return rel_exists_exp(query, rel , sc, f);
2936 3560 : case SQL_LIKE:
2937 : case SQL_NOT_LIKE:
2938 : {
2939 3560 : symbol *lo = sc->data.lval->h->data.sym;
2940 3560 : symbol *ro = sc->data.lval->h->next->data.sym;
2941 3560 : int insensitive = sc->data.lval->h->next->next->data.i_val;
2942 3560 : int anti = (sc->token == SQL_NOT_LIKE) != (sc->data.lval->h->next->next->next->data.i_val != 0);
2943 3560 : sql_subtype *st = sql_bind_localtype("str");
2944 3560 : sql_exp *le = rel_value_exp(query, &rel, lo, f|sql_farg, ek), *re, *ee = NULL, *ie = exp_atom_bool(sql->sa, insensitive);
2945 :
2946 3560 : if (!le)
2947 : return NULL;
2948 :
2949 3558 : if (!exp_subtype(le))
2950 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: parameter not allowed on "
2951 : "left hand side of LIKE operator");
2952 :
2953 : /* Do we need to escape ? */
2954 3558 : if (dlist_length(ro->data.lval) == 2) {
2955 82 : char *escape = ro->data.lval->h->next->data.sval;
2956 82 : ee = exp_atom(sql->sa, atom_string(sql->sa, st, sa_strdup(sql->sa, escape)));
2957 : } else {
2958 3476 : ee = exp_atom(sql->sa, atom_string(sql->sa, st, sa_strdup(sql->sa, "")));
2959 : }
2960 3558 : ro = ro->data.lval->h->data.sym;
2961 3558 : re = rel_value_exp(query, &rel, ro, f|sql_farg, ek);
2962 3558 : if (!re)
2963 : return NULL;
2964 3557 : if ((re = exp_check_type(sql, st, rel, re, type_equal)) == NULL)
2965 0 : return sql_error(sql, 02, SQLSTATE(42000) "LIKE: wrong type, should be string");
2966 3557 : if ((le = exp_check_type(sql, st, rel, le, type_equal)) == NULL)
2967 0 : return sql_error(sql, 02, SQLSTATE(42000) "LIKE: wrong type, should be string");
2968 3557 : return rel_filter_exp_(sql, rel, le, re, ee, ie, "like", anti, f);
2969 : }
2970 2959 : case SQL_BETWEEN:
2971 : case SQL_NOT_BETWEEN:
2972 : {
2973 2959 : symbol *lo = sc->data.lval->h->data.sym;
2974 2959 : int symmetric = sc->data.lval->h->next->data.i_val;
2975 2959 : symbol *ro1 = sc->data.lval->h->next->next->data.sym;
2976 2959 : symbol *ro2 = sc->data.lval->h->next->next->next->data.sym;
2977 2959 : sql_exp *le, *re1, *re2;
2978 2959 : sql_subtype super;
2979 :
2980 2959 : assert(sc->data.lval->h->next->type == type_int);
2981 :
2982 2959 : if (!(le = rel_value_exp(query, &rel, lo, f|sql_farg, ek)))
2983 : return NULL;
2984 2957 : if (!(re1 = rel_value_exp(query, &rel, ro1, f|sql_farg, ek)))
2985 : return NULL;
2986 2955 : if (!(re2 = rel_value_exp(query, &rel, ro2, f|sql_farg, ek)))
2987 : return NULL;
2988 :
2989 2955 : if (exp_between_check_types(&super, exp_subtype(le), exp_subtype(re1), exp_subtype(re2)) < 0)
2990 1 : return sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) on both sides of an expression");
2991 :
2992 2954 : if ((le = exp_check_type(sql, &super, rel, le, type_equal)) == NULL ||
2993 2954 : (re1 = exp_check_type(sql, &super, rel, re1, type_equal)) == NULL ||
2994 2954 : (re2 = exp_check_type(sql, &super, rel, re2, type_equal)) == NULL)
2995 0 : return NULL;
2996 :
2997 2954 : return rel_compare_exp_(query, rel, le, re1, re2, 3, sc->token == SQL_NOT_BETWEEN ? 1 : 0, 0, f, symmetric, 0);
2998 : }
2999 7928 : case SQL_IS_NULL:
3000 : case SQL_IS_NOT_NULL:
3001 : /* is (NOT) NULL */
3002 : {
3003 7928 : sql_exp *le = rel_value_exp(query, &rel, sc->data.sym, f|sql_farg, ek);
3004 7928 : sql_subtype *t;
3005 :
3006 7928 : if (!le)
3007 : return NULL;
3008 7924 : if (!(t = exp_subtype(le)))
3009 1 : return sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) for IS%s NULL operator", sc->token == SQL_IS_NOT_NULL ? " NOT" : "");
3010 7923 : le = exp_compare(sql->sa, le, exp_atom(sql->sa, atom_general(sql->sa, t, NULL, 0)), cmp_equal);
3011 7923 : if (sc->token == SQL_IS_NOT_NULL)
3012 2603 : set_anti(le);
3013 7923 : set_has_no_nil(le);
3014 7923 : set_semantics(le);
3015 7923 : return rel_select_push_compare_exp_down(sql, rel, le, le->l, le->r, NULL, f);
3016 : }
3017 20675 : case SQL_NOT: {
3018 20675 : if (not_symbol_can_be_propagated(sql, sc->data.sym)) {
3019 2330 : sc->data.sym = negate_symbol_tree(sql, sc->data.sym);
3020 2330 : return rel_logical_exp(query, rel, sc->data.sym, f);
3021 : }
3022 18345 : sql_exp *le = rel_value_exp(query, &rel, sc->data.sym, f|sql_farg, ek);
3023 18345 : sql_subtype bt;
3024 :
3025 18345 : sql_find_subtype(&bt, "boolean", 0, 0);
3026 18345 : if (!le || !(le = exp_check_type(sql, &bt, rel, le, type_equal)))
3027 1 : return NULL;
3028 18344 : le = exp_compare(sql->sa, le, exp_atom_bool(sql->sa, 0), cmp_equal);
3029 18344 : return rel_select_push_compare_exp_down(sql, rel, le, le->l, le->r, NULL, f);
3030 : }
3031 629 : case SQL_ATOM: {
3032 : /* TRUE or FALSE */
3033 629 : sql_rel *or = rel;
3034 629 : AtomNode *an = (AtomNode *) sc;
3035 629 : sql_exp *e = exp_atom(sql->sa, an->a);
3036 :
3037 629 : if (e) {
3038 629 : sql_subtype bt;
3039 :
3040 629 : sql_find_subtype(&bt, "boolean", 0, 0);
3041 629 : e = exp_check_type(sql, &bt, rel, e, type_equal);
3042 : }
3043 629 : if (!e || or != rel)
3044 2 : return NULL;
3045 627 : e = exp_compare(sql->sa, e, exp_atom_bool(sql->sa, 1), cmp_equal);
3046 627 : return rel_select_push_compare_exp_down(sql, rel, e, e->l, e->r, NULL, f);
3047 : }
3048 710 : case SQL_IDENT:
3049 : case SQL_COLUMN: {
3050 710 : sql_rel *or = rel;
3051 710 : sql_exp *e = rel_column_ref(query, &rel, sc, f);
3052 :
3053 710 : if (e) {
3054 707 : sql_subtype bt;
3055 :
3056 707 : sql_find_subtype(&bt, "boolean", 0, 0);
3057 707 : e = exp_check_type(sql, &bt, rel, e, type_equal);
3058 : }
3059 707 : if (!e || or != rel)
3060 3 : return NULL;
3061 707 : e = exp_compare(sql->sa, e, exp_atom_bool(sql->sa, 1), cmp_equal);
3062 707 : return rel_select_push_compare_exp_down(sql, rel, e, e->l, e->r, NULL, f);
3063 : }
3064 12 : case SQL_UNION:
3065 : case SQL_EXCEPT:
3066 : case SQL_INTERSECT: {
3067 12 : sql_rel *sq;
3068 :
3069 12 : if (is_psm_call(f) || is_sql_merge(f))
3070 3 : return sql_error(sql, 02, SQLSTATE(42000) "%s: set operations not supported inside %s", is_psm_call(f) ? "CALL" : "MERGE", is_psm_call(f) ? "CALL statements" : "MERGE conditions");
3071 11 : if (rel)
3072 11 : query_push_outer(query, rel, f);
3073 11 : sq = rel_setquery(query, sc);
3074 11 : if (rel) {
3075 11 : rel = query_pop_outer(query);
3076 11 : if (is_sql_join(f) && is_groupby(rel->op)) {
3077 0 : return sql_error(sql, 05, SQLSTATE(42000) "SELECT: aggregate functions not allowed in JOIN conditions");
3078 11 : } else if (is_sql_where(f) && is_groupby(rel->op)) {
3079 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: aggregate functions not allowed in WHERE clause");
3080 11 : } else if ((is_sql_update_set(f) || is_sql_psm(f)) && is_groupby(rel->op)) {
3081 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: aggregate functions not allowed in SET, WHILE, IF, ELSE, CASE, WHEN, RETURN, ANALYZE clauses");
3082 : }
3083 : }
3084 11 : if (!sq)
3085 : return NULL;
3086 11 : assert(ek.type == type_value); /* I don't expect IN tuple matching calls to land here */
3087 11 : if (is_sql_where(f) && is_groupby(rel->op))
3088 0 : assert(0);
3089 11 : if (ek.card <= card_set && is_project(sq->op) && list_length(sq->exps) > 1)
3090 1 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: subquery must return only one column");
3091 10 : if (!rel)
3092 : return sq;
3093 10 : sq = rel_zero_or_one(sql, sq, ek);
3094 10 : if (is_sql_where(f) || is_sql_having(f)) {
3095 10 : sql_exp *le = exp_rel(sql, sq);
3096 10 : sql_subtype bt;
3097 :
3098 10 : sql_find_subtype(&bt, "boolean", 0, 0);
3099 10 : le = exp_check_type(sql, &bt, rel, le, type_equal);
3100 10 : if (!le)
3101 : return NULL;
3102 10 : le = exp_compare(sql->sa, le, exp_atom_bool(sql->sa, 1), cmp_equal);
3103 10 : return rel_select_push_compare_exp_down(sql, rel, le, le->l, le->r, NULL, f);
3104 : } else {
3105 0 : sq = rel_crossproduct(sql->sa, rel, sq, (f==sql_sel || is_single(sq))?op_left:op_join);
3106 0 : set_processed(sq);
3107 : }
3108 0 : return sq;
3109 : }
3110 0 : case SQL_DEFAULT:
3111 0 : return sql_error(sql, 02, SQLSTATE(42000) "DEFAULT keyword not allowed outside insert and update statements");
3112 442 : default: {
3113 442 : sql_exp *le = rel_value_exp(query, &rel, sc, f|sql_farg, ek);
3114 442 : sql_subtype bt;
3115 :
3116 442 : if (!le)
3117 : return NULL;
3118 417 : if (le && (!is_compare(le->type) || le->flag > cmp_filter)) {
3119 288 : sql_find_subtype(&bt, "boolean", 0, 0);
3120 288 : if (!(le = exp_check_type(sql, &bt, rel, le, type_equal)))
3121 : return NULL;
3122 288 : le = exp_compare(sql->sa, le, exp_atom_bool(sql->sa, 1), cmp_equal);
3123 : }
3124 417 : if (le->flag == cmp_filter)
3125 128 : return rel_select_push_filter_exp_down(sql, rel, le, le->l, le->r, f);
3126 : else
3127 289 : return rel_select_push_compare_exp_down(sql, rel, le, le->l, le->r, le->f, f);
3128 : }
3129 : }
3130 : /* never reached, as all switch cases have a `return` */
3131 : }
3132 :
3133 : static sql_exp * _rel_aggr(sql_query *query, sql_rel **rel, int distinct, char *sname, char *aname, dnode *arguments, int f);
3134 : static sql_exp *rel_aggr(sql_query *query, sql_rel **rel, symbol *se, int f);
3135 :
3136 : sql_exp *
3137 35174 : rel_unop_(mvc *sql, sql_rel *rel, sql_exp *e, char *sname, char *fname, int card)
3138 : {
3139 35174 : bool found = false;
3140 35174 : sql_subtype *t = exp_subtype(e);
3141 35174 : sql_ftype type = (card == card_loader)?F_LOADER:((card == card_none)?F_PROC:
3142 : ((card == card_relation)?F_UNION:F_FUNC));
3143 :
3144 35174 : sql_subfunc *f = bind_func(sql, sname, fname, t, NULL, 1, type, false, &found, false);
3145 35174 : if (f) {
3146 35173 : sql_arg *a = f->func->ops->h->data;
3147 35173 : t = &a->type;
3148 : }
3149 35174 : if (f && t && type_has_tz(t) && f->func->fix_scale == SCALE_FIX) {
3150 : /* set timezone (using msec (.3)) */
3151 0 : sql_subtype *intsec = sql_bind_subtype(sql->sa, "sec_interval", 10 /*hour to second */, 3);
3152 0 : atom *a = atom_int(sql->sa, intsec, sql->timezone);
3153 0 : sql_exp *tz = exp_atom(sql->sa, a);
3154 :
3155 0 : e = rel_binop_(sql, rel, e, tz, "sys", "sql_add", card, true);
3156 0 : if (!e)
3157 : return NULL;
3158 : }
3159 35174 : if (f) {
3160 35173 : if (check_card(card, f)) {
3161 35173 : list *args = list_append(sa_list(sql->sa), e);
3162 70346 : args = check_arguments_and_find_largest_any_type(sql, rel, args, f, card == card_relation && e->card > CARD_ATOM, false);
3163 35173 : if (args)
3164 35173 : return exp_op(sql->sa, args, f);
3165 : }
3166 0 : found = false; /* reset found */
3167 0 : f = NULL;
3168 : }
3169 : /* reset error */
3170 1 : sql->session->status = 0;
3171 1 : sql->errstr[0] = '\0';
3172 3 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s unary operator %s%s%s'%s'(%s)",
3173 2 : found ? "insufficient privileges for" : "no such", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname, t ? t->type->base.name : "?");
3174 : }
3175 :
3176 : sql_exp *
3177 156510 : rel_binop_(mvc *sql, sql_rel *rel, sql_exp *l, sql_exp *r, char *sname, char *fname, int card, bool exact)
3178 : {
3179 156510 : sql_subtype *t1 = exp_subtype(l), *t2 = exp_subtype(r);
3180 156510 : sql_ftype type = (card == card_loader)?F_LOADER:((card == card_none)?F_PROC:((card == card_relation)?F_UNION:F_FUNC));
3181 156510 : bool found = false;
3182 :
3183 156510 : if (card == card_loader)
3184 0 : card = card_none;
3185 :
3186 156510 : if (is_commutative(sname, fname) && l->card < r->card) { /* move constants to the right if possible */
3187 : sql_subtype *tmp = t1;
3188 156510 : t1 = t2;
3189 156510 : t2 = tmp;
3190 : sql_exp *res = l;
3191 156510 : l = r;
3192 156510 : r = res;
3193 : }
3194 : /* swap complex types (intervals) to left side of +, * */
3195 156510 : if (t1 && t2 && is_commutative(sname, fname)) {
3196 68 : if ((EC_INTERVAL(t1->type->eclass) && EC_TEMP(t2->type->eclass)) ||
3197 68 : ((!EC_TEMP(t1->type->eclass) && !EC_INTERVAL(t1->type->eclass)) && EC_INTERVAL(t2->type->eclass))) {
3198 : sql_subtype *tmp = t1;
3199 156510 : t1 = t2;
3200 156510 : t2 = tmp;
3201 : sql_exp *res = l;
3202 156510 : l = r;
3203 156510 : r = res;
3204 : }
3205 : }
3206 :
3207 156510 : sql_subfunc *f = bind_func(sql, sname, fname, t1, t2, 2, type, false, &found, exact);
3208 156510 : if (f && check_card(card,f)) {
3209 156510 : t1 = exp_subtype(l);
3210 156510 : t2 = exp_subtype(r);
3211 156510 : list *args = list_append(list_append(sa_list(sql->sa), l), r);
3212 :
3213 156510 : args = check_arguments_and_find_largest_any_type(sql, rel, args, f, 0, false);
3214 156510 : if (args)
3215 156510 : return exp_op(sql->sa, args, f);
3216 : return NULL;
3217 : }
3218 :
3219 0 : if (!exp_subtype(l) || !exp_subtype(r))
3220 0 : return sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) on both sides of an expression");
3221 0 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s binary operator %s%s%s'%s'(%s,%s)",
3222 0 : found ? "insufficient privileges for" : "no such", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname,
3223 0 : exp_subtype(l)->type->base.name, exp_subtype(r)->type->base.name);
3224 : }
3225 :
3226 : sql_exp *
3227 539 : rel_nop_(mvc *sql, sql_rel *rel, sql_exp *a1, sql_exp *a2, sql_exp *a3, sql_exp *a4, char *sname, char *fname, int card)
3228 : {
3229 539 : list *tl = sa_list(sql->sa);
3230 539 : sql_subfunc *f = NULL;
3231 539 : sql_ftype type = (card == card_none)?F_PROC:((card == card_relation)?F_UNION:F_FUNC);
3232 :
3233 : /* rel_nop_ should only be called for functions available to everyone, ie defined at sql_types! */
3234 539 : (void) rel;
3235 539 : append(tl, exp_subtype(a1));
3236 539 : append(tl, exp_subtype(a2));
3237 539 : append(tl, exp_subtype(a3));
3238 539 : if (a4)
3239 371 : append(tl, exp_subtype(a4));
3240 :
3241 539 : if (!(f = bind_func_(sql, sname, fname, tl, type, false, NULL, true)))
3242 : return NULL;
3243 539 : if (!a4)
3244 168 : return exp_op3(sql->sa, a1,a2,a3,f);
3245 371 : return exp_op4(sql->sa, a1,a2,a3,a4,f);
3246 : }
3247 :
3248 : static sql_func *
3249 3 : inplace_func(mvc *sql)
3250 : {
3251 3 : sql_func *f = SA_NEW(sql->sa, sql_func);
3252 :
3253 3 : *f = (sql_func) {
3254 : .mod = "",
3255 : .imp = "",
3256 : .type = F_PROC,
3257 : .lang = FUNC_LANG_INT,
3258 : .query = NULL,
3259 3 : .ops = sql->params,
3260 : .res = NULL,
3261 : };
3262 3 : base_init(sql->sa, &f->base, 0, true, NULL);
3263 3 : f->base.new = 1;
3264 3 : f->base.id = -1;
3265 3 : f->base.name = "-1";
3266 3 : f->instantiated = TRUE;
3267 3 : return f;
3268 : }
3269 :
3270 : static list *
3271 3 : reorder_args(mvc *sql, list *exps, list *names, list *params)
3272 : {
3273 3 : list *nexps = sa_list(sql->sa);
3274 8 : for(node *n = params->h; n; n = n->next) {
3275 5 : sql_arg *a = n->data;
3276 5 : int found =0;
3277 7 : for(node *m = names->h, *o = exps->h; m && o; m = m->next, o = o->next) {
3278 7 : if (strcmp(m->data, a->name) == 0) {
3279 5 : append(nexps, o->data);
3280 5 : found = 1;
3281 5 : break;
3282 : }
3283 : }
3284 5 : if (!found)
3285 : return NULL;
3286 : }
3287 : return nexps;
3288 : }
3289 :
3290 : static sql_exp *
3291 554470 : rel_nop(sql_query *query, sql_rel **rel, symbol *se, int fs, exp_kind ek)
3292 : {
3293 554470 : mvc *sql = query->sql;
3294 554470 : dnode *l = se->data.lval->h;
3295 554470 : dnode *ops = l->next->next->data.lval?l->next->next->data.lval->h:NULL;
3296 554470 : list *names = NULL;
3297 554470 : char *fname = NULL, *sname = NULL;;
3298 :
3299 554470 : if (l->type != type_int) {
3300 548561 : int nargs = 0;
3301 548561 : fname = qname_schema_object(l->data.lval);
3302 548561 : sname = qname_schema(l->data.lval);
3303 :
3304 1656483 : for (dnode *n = ops; n; n = n->next)
3305 1107922 : nargs++;
3306 :
3307 : /* first try aggregate */
3308 548561 : if (find_func(sql, sname, fname, nargs, F_AGGR, false, NULL, NULL))
3309 26284 : return _rel_aggr(query, rel, l->next->data.i_val, sname, fname, l->next->next->data.lval->h, fs);
3310 : }
3311 :
3312 528186 : int nr_args = 0;
3313 528186 : int split = (l->type == type_int && l->data.i_val == -1);
3314 528186 : list *exps = sa_list(sql->sa), *tl = sa_list(sql->sa);
3315 528186 : exp_kind iek = {type_value, card_column, FALSE};
3316 :
3317 528186 : if (split)
3318 3 : names = sa_list(sql->sa);
3319 1617109 : for (; ops; ops = ops->next, nr_args++) {
3320 1089009 : sql_exp *e = rel_value_exp(query, rel, ops->data.sym, fs|sql_farg, iek);
3321 1089009 : if (!e)
3322 : return NULL;
3323 1088923 : if (split) {
3324 5 : ops = ops->next;
3325 5 : append(names, ops->data.sval);
3326 : }
3327 1088923 : append(exps, e);
3328 1088923 : append(tl, exp_subtype(e));
3329 : }
3330 528100 : if (l->type == type_int) {
3331 : /* exec nr (ops)*/
3332 5908 : int nr = l->data.i_val;
3333 5908 : cq *q = NULL;
3334 :
3335 5908 : if (nr == -1 || (q = qc_find(sql->qc, nr))) {
3336 5906 : list *nexps = new_exp_list(sql->sa);
3337 5906 : sql_func *f = q?q->f:inplace_func(sql);
3338 5906 : list *ops = q?f->ops:sql->params;
3339 :
3340 5906 : tl = sa_list(sql->sa);
3341 5906 : if (list_length(ops) != list_length(exps))
3342 3 : return sql_error(sql, 02, SQLSTATE(42000) "EXEC called with wrong number of arguments: expected %d, got %d", list_length(ops), list_length(exps));
3343 5903 : if (split) {
3344 3 : exps = reorder_args(sql, exps, names, ops);
3345 3 : if (!exps)
3346 0 : return sql_error(sql, 02, SQLSTATE(42000) "EXEC called with wrong arguments");
3347 : }
3348 5903 : if (exps->h && ops) {
3349 21927 : for (node *n = exps->h, *m = ops->h; n && m; n = n->next, m = m->next) {
3350 16115 : sql_arg *a = m->data;
3351 16115 : sql_exp *e = n->data;
3352 16115 : sql_subtype *ntp = &a->type;
3353 :
3354 16115 : if (ntp && ntp->type)
3355 16115 : e = exp_check_type(sql, ntp, NULL, e, type_equal);
3356 : else
3357 0 : a->type = *exp_subtype(e);
3358 16115 : if (!e)
3359 : return NULL;
3360 16114 : append(nexps, e);
3361 16114 : append(tl, exp_subtype(e));
3362 : }
3363 : }
3364 :
3365 5902 : if (q)
3366 5899 : sql->type = q->type;
3367 5992 : return exp_op(sql->sa, list_empty(nexps) ? NULL : nexps, sql_dup_subfunc(sql->sa, f, tl, NULL));
3368 : } else {
3369 2 : return sql_error(sql, 02, SQLSTATE(42000) "EXEC: PREPARED Statement missing '%d'", nr);
3370 : }
3371 : }
3372 :
3373 522192 : if (nr_args == 2 && is_commutative(sname, fname)) {
3374 123227 : sql_subtype *t1 = tl->h->data;
3375 123227 : sql_subtype *t2 = tl->t->data;
3376 :
3377 123227 : if (t1 && t2 && ((EC_INTERVAL(t1->type->eclass) && EC_TEMP(t2->type->eclass)) ||
3378 123218 : ((!EC_TEMP(t1->type->eclass) && !EC_INTERVAL(t1->type->eclass)) && EC_INTERVAL(t2->type->eclass)))) {
3379 8 : list_revert(exps);
3380 8 : list_revert(tl);
3381 : }
3382 :
3383 : }
3384 :
3385 522192 : if (!sname && strcmp(fname, "field") == 0) { /* map into join */
3386 1 : if (list_length(exps) < 2)
3387 1 : return sql_error(sql, 02, SQLSTATE(42000) "Field function called with not enough arguments");
3388 0 : sql_exp *le = exps->h->data;
3389 0 : set_freevar(le, 1);
3390 0 : list_remove_data(exps, NULL, le);
3391 0 : sql_exp *re = exp_values(sql->sa, exps);
3392 0 : exp_label(sql->sa, re, ++sql->label);
3393 0 : sql_rel *r = rel_project(sql->sa, NULL, append(sa_list(sql->sa), re));
3394 0 : sql_exp *id = NULL;
3395 0 : rel_add_identity(sql, r, &id);
3396 0 : re = exp_ref(sql, re);
3397 0 : id = exp_ref(sql, id);
3398 0 : if (r) {
3399 0 : r->nrcols = list_length(exps);
3400 0 : sql_exp *e = exp_compare(sql->sa, le, re, cmp_equal);
3401 0 : r = rel_select(sql->sa, r, e);
3402 0 : r = rel_project(sql->sa, r, append(sa_list(sql->sa), exp_convert(sql, id, exp_subtype(id), sql_bind_localtype("int"))));
3403 0 : re = exp_rel(sql, r);
3404 0 : return re;
3405 : }
3406 : }
3407 522191 : return _rel_nop(sql, sname, fname, tl, rel ? *rel : NULL, exps, ek);
3408 : }
3409 :
3410 : typedef struct aggr_input {
3411 : sql_query *query;
3412 : int groupby;
3413 : char *err;
3414 : } aggr_input;
3415 :
3416 : static sql_exp *
3417 373 : exp_valid(visitor *v, sql_rel *rel, sql_exp *e, int depth)
3418 : {
3419 373 : aggr_input *ai = v->data;
3420 373 : (void)rel; (void)depth;
3421 :
3422 373 : int vf = is_freevar(e);
3423 373 : if (!v->changes && vf && vf < ai->groupby) { /* check need with outer query */
3424 14 : sql_rel *sq = query_fetch_outer(ai->query, vf-1);
3425 :
3426 : /* problem freevar have cardinality CARD_ATOM */
3427 14 : if (sq->card <= CARD_AGGR && exp_card(e) != CARD_AGGR && is_alias(e->type)) {
3428 4 : if (!exps_bind_column(sq->exps, e->l, e->r, NULL, 0)) {
3429 1 : v->changes = 1;
3430 1 : ai->err = SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query";
3431 : }
3432 : }
3433 359 : } else if (!v->changes && vf && vf == ai->groupby) { /* check if input is already aggregated */
3434 280 : sql_rel *sq = query_fetch_outer(ai->query, vf-1);
3435 280 : sql_exp *a = NULL;
3436 :
3437 280 : if (sq->card <= CARD_AGGR && is_alias(e->type)) {
3438 187 : if ((a = exps_bind_column(sq->exps, e->l, e->r, NULL, 0)) && is_aggr(a->type)) { /* aggregate */
3439 9 : v->changes = 1;
3440 9 : ai->err = SQLSTATE(42000) "SELECT: aggregate function calls cannot be nested";
3441 : }
3442 : }
3443 : }
3444 373 : return e;
3445 : }
3446 :
3447 : static char *
3448 273 : exps_valid(sql_query *query, list *exps, int groupby)
3449 : {
3450 273 : aggr_input ai = { .query = query, .groupby = groupby };
3451 273 : visitor v = { .sql = query->sql, .data = &ai };
3452 :
3453 273 : exps_exp_visitor_topdown(&v, NULL, exps, 0, &exp_valid, true);
3454 273 : if (v.changes)
3455 10 : return ai.err;
3456 : return NULL;
3457 : }
3458 :
3459 : static list * rel_order_by(sql_query *query, sql_rel **R, symbol *orderby, int needs_distinct, int f);
3460 :
3461 : static sql_exp *
3462 45740 : _rel_aggr(sql_query *query, sql_rel **rel, int distinct, char *sname, char *aname, dnode *args, int f)
3463 : {
3464 45740 : mvc *sql = query->sql;
3465 45740 : exp_kind ek = {type_value, card_column, FALSE};
3466 45740 : sql_subfunc *a = NULL;
3467 45740 : int no_nil = 0, group = 0, all_aggr = query_has_outer(query), i;
3468 45740 : unsigned int all_freevar = 0;
3469 45740 : sql_rel *groupby = rel ? *rel : NULL, *sel = NULL, *gr, *og = NULL, *res = groupby;
3470 45740 : sql_rel *subquery = NULL;
3471 45740 : list *exps = NULL, *ungrouped_cols = NULL;
3472 45740 : bool is_grouping = !strcmp(aname, "grouping"), has_args = false, found = false, used_rel = false;
3473 :
3474 45740 : if (!all_aggr) {
3475 30797 : if (!groupby) {
3476 4 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3477 4 : return sql_error(sql, 02, SQLSTATE(42000) "%s: missing group by", toUpperCopy(uaname, aname));
3478 30793 : } else if (is_sql_groupby(f)) {
3479 8 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3480 8 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate function '%s' not allowed in GROUP BY clause", toUpperCopy(uaname, aname), aname);
3481 30785 : } else if (is_sql_values(f)) {
3482 1 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3483 1 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed on an unique value", toUpperCopy(uaname, aname));
3484 30784 : } else if (is_sql_join(f)) { /* the is_sql_join test must come before is_sql_where, because the join conditions are handled with sql_where */
3485 3 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3486 3 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in JOIN conditions", toUpperCopy(uaname, aname));
3487 30781 : } else if (is_sql_where(f)) {
3488 4 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3489 4 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in WHERE clause", toUpperCopy(uaname, aname));
3490 30777 : } else if (is_sql_update_set(f) || is_sql_psm(f)) {
3491 1 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3492 1 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in SET, WHILE, IF, ELSE, CASE, WHEN, RETURN, ANALYZE clauses (use subquery)", toUpperCopy(uaname, aname));
3493 30776 : } else if (is_sql_aggr(f)) {
3494 4 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3495 4 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions cannot be nested", toUpperCopy(uaname, aname));
3496 30772 : } else if (is_psm_call(f)) {
3497 0 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3498 0 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed inside CALL", toUpperCopy(uaname, aname));
3499 30772 : } else if (is_sql_from(f)) {
3500 0 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3501 0 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in functions in FROM", toUpperCopy(uaname, aname));
3502 : }
3503 : }
3504 :
3505 45715 : exps = sa_list(sql->sa);
3506 45715 : if (args && args->data.sym) {
3507 26374 : bool arguments_correlated = true, all_const = true;
3508 :
3509 26374 : all_freevar = all_aggr?1:0;
3510 61464 : for (i = 0; args && args->data.sym && args->data.sym->token != SQL_ORDERBY; args = args->next, i++) {
3511 35150 : int base = (!groupby || !is_project(groupby->op) || is_base(groupby->op) || is_processed(groupby));
3512 27189 : sql_rel *gl = base?groupby:groupby->l, *ogl = gl; /* handle case of subqueries without correlation */
3513 35150 : sql_exp *e = rel_value_exp(query, &gl, args->data.sym, (f | sql_aggr)& ~sql_farg, ek);
3514 35150 : bool found_one_freevar = false;
3515 :
3516 35150 : if (!e)
3517 60 : return NULL;
3518 35096 : used_rel |= (rel_has_exp(gl, e, true) == 0);
3519 35096 : has_args = true;
3520 35096 : if (gl && gl != ogl) {
3521 5 : if (gl->grouped) {
3522 5 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3523 5 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions cannot be nested", toUpperCopy(uaname, aname));
3524 : }
3525 0 : if (!base)
3526 0 : groupby->l = subquery = gl;
3527 : else
3528 : groupby = subquery = gl;
3529 : }
3530 35091 : sql_subtype *t = exp_subtype(e);
3531 35091 : if (!t) { /* we also do not expect parameters here */
3532 1 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3533 1 : return sql_error(sql, 02, SQLSTATE(42000) "%s: parameters not allowed as arguments to aggregate functions", toUpperCopy(uaname, aname));
3534 : }
3535 35090 : if (!t->type->localtype) {
3536 47 : if (e->type == e_atom && !e->f) {
3537 44 : t = sql_bind_localtype("bte");
3538 44 : e->tpe = *t;
3539 44 : if (e->l)
3540 44 : e->l = atom_set_type(sql->sa, e->l, t);
3541 : }
3542 : }
3543 :
3544 35090 : all_aggr &= (exp_card(e) <= CARD_AGGR && !exp_is_atom(e) && is_aggr(e->type) && !is_func(e->type) && (!groupby || !is_groupby(groupby->op) || !groupby->r || !exps_find_exp(groupby->r, e)));
3545 35090 : exp_only_freevar(query, e, &arguments_correlated, &found_one_freevar, &ungrouped_cols);
3546 35090 : all_freevar &= (arguments_correlated && found_one_freevar) || (is_atom(e->type)?all_freevar:0); /* no uncorrelated variables must be found, plus at least one correlated variable to push this aggregate to an outer query */
3547 35090 : all_const &= is_atom(e->type);
3548 35090 : list_append(exps, e);
3549 : }
3550 26314 : if (all_const)
3551 206 : all_freevar = 0;
3552 : }
3553 45655 : if (!all_freevar) {
3554 45362 : if (is_sql_groupby(f)) {
3555 1 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3556 1 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate function '%s' not allowed in GROUP BY clause", toUpperCopy(uaname, aname), aname);
3557 45361 : } else if (is_sql_from(f)) {
3558 2 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3559 2 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in functions in FROM", toUpperCopy(uaname, aname));
3560 45359 : } else if (is_sql_aggr(f) && groupby->grouped) {
3561 2 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3562 2 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions cannot be nested", toUpperCopy(uaname, aname));
3563 45357 : } else if (is_sql_values(f)) {
3564 1 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3565 1 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed on an unique value", toUpperCopy(uaname, aname));
3566 45356 : } else if (is_sql_join(f)) { /* the is_sql_join test must come before is_sql_where, because the join conditions are handled with sql_where */
3567 1 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3568 1 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in JOIN conditions", toUpperCopy(uaname, aname));
3569 45355 : } else if (is_sql_where(f)) {
3570 5 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3571 5 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in WHERE clause", toUpperCopy(uaname, aname));
3572 45350 : } else if (!all_aggr && !list_empty(ungrouped_cols)) {
3573 123 : for (node *n = ungrouped_cols->h ; n ; n = n->next) {
3574 66 : sql_rel *outer;
3575 66 : sql_exp *e = (sql_exp*) n->data;
3576 :
3577 66 : if ((outer = query_fetch_outer(query, is_freevar(e)-1))) {
3578 66 : int of = query_fetch_outer_state(query, is_freevar(e)-1);
3579 66 : if (outer->grouped) {
3580 24 : bool err = false, was_processed = false;
3581 :
3582 24 : if (is_processed(outer)) {
3583 5 : was_processed = true;
3584 5 : reset_processed(outer);
3585 : }
3586 24 : if (!is_groupby_col(outer, e))
3587 3 : err = true;
3588 24 : if (was_processed)
3589 5 : set_processed(outer);
3590 24 : if (err) {
3591 3 : if (exp_name(e) && exp_relname(e) && !has_label(e))
3592 3 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\" from outer query", exp_relname(e), exp_name(e));
3593 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query");
3594 : }
3595 42 : } else if (!used_rel && is_sql_where(of)) {
3596 2 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3597 2 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions not allowed in WHERE clause", toUpperCopy(uaname, aname));
3598 40 : } else if (!is_sql_aggr(of)) {
3599 36 : set_outer(outer);
3600 : }
3601 : }
3602 : }
3603 : }
3604 : }
3605 :
3606 45638 : if (all_freevar) { /* case 2, ie use outer */
3607 293 : int card;
3608 293 : sql_exp *exp = NULL;
3609 : /* find proper groupby relation */
3610 593 : for (node *n = exps->h; n; n = n->next) {
3611 300 : sql_exp *e = n->data;
3612 :
3613 300 : int vf = exp_freevar_offset(sql, e);
3614 300 : if (vf > (int)all_freevar)
3615 23 : all_freevar = vf;
3616 300 : exp = e;
3617 : }
3618 293 : if (query_has_outer(query) >= all_freevar) {
3619 293 : int sql_state = query_fetch_outer_state(query,all_freevar-1);
3620 293 : res = groupby = query_fetch_outer(query, all_freevar-1);
3621 293 : card = query_outer_used_card(query, all_freevar-1);
3622 : /* given groupby validate all input expressions */
3623 293 : char *err;
3624 293 : if (groupby && !is_groupby(groupby->op)) {
3625 112 : sql_exp *p = query_outer_last_used(query, all_freevar-1);
3626 112 : if (p && !is_aggr(p->type) && !is_groupby_col(groupby, p)) {
3627 20 : if (p->type == e_column)
3628 20 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", (char*)p->l, (char*)p->r);
3629 0 : if (exp_name(p) && exp_relname(p) && !has_label(p))
3630 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", exp_relname(p), exp_name(p));
3631 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
3632 : }
3633 : }
3634 273 : if ((err = exps_valid(query, exps, all_freevar)) != NULL) {
3635 10 : strcpy(sql->errstr, err);
3636 10 : sql->session->status = -ERR_GROUPBY;
3637 10 : return NULL;
3638 : }
3639 263 : if (exp && !is_groupby_col(res, exp)) {
3640 192 : if (is_sql_groupby(sql_state))
3641 2 : return sql_error(sql, 05, SQLSTATE(42000) "SELECT: aggregate function '%s' not allowed in GROUP BY clause", aname);
3642 190 : if (is_sql_aggr(sql_state) && groupby->grouped) {
3643 3 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3644 3 : return sql_error(sql, 02, SQLSTATE(42000) "%s: aggregate functions cannot be nested", toUpperCopy(uaname, aname));
3645 : }
3646 187 : if (is_sql_values(sql_state))
3647 0 : return sql_error(sql, 05, SQLSTATE(42000) "SELECT: aggregate functions not allowed on an unique value");
3648 187 : if (is_sql_update_set(sql_state) || is_sql_psm(f))
3649 2 : return sql_error(sql, 05, SQLSTATE(42000) "SELECT: aggregate functions not allowed in SET, WHILE, IF, ELSE, CASE, WHEN, RETURN, ANALYZE clauses");
3650 185 : if (is_sql_join(sql_state))
3651 4 : return sql_error(sql, 05, SQLSTATE(42000) "SELECT: aggregate functions not allowed in JOIN conditions");
3652 181 : if (is_sql_where(sql_state))
3653 3 : return sql_error(sql, 05, SQLSTATE(42000) "SELECT: aggregate functions not allowed in WHERE clause");
3654 178 : if (is_psm_call(sql_state))
3655 0 : return sql_error(sql, 05, SQLSTATE(42000) "CALL: aggregate functions not allowed inside CALL");
3656 178 : if (is_sql_from(sql_state))
3657 0 : return sql_error(sql, 05, SQLSTATE(42000) "SELECT: aggregate functions not allowed in functions in FROM");
3658 178 : if (card > CARD_AGGR) { /* used an expression before on the non grouped relation */
3659 0 : sql_exp *lu = query_outer_last_used(query, all_freevar-1);
3660 0 : if (lu->type == e_column)
3661 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\" from outer query", (char*)lu->l, (char*)lu->r);
3662 0 : if (exp_name(lu) && exp_relname(lu) && !has_label(lu))
3663 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column \"%s.%s\" from outer query", exp_relname(lu), exp_name(lu));
3664 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query");
3665 : }
3666 178 : if (is_outer(groupby))
3667 2 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query");
3668 : }
3669 : } else {
3670 : all_freevar = 0;
3671 : }
3672 45345 : } else if (!subquery && groupby && is_outer(groupby) && !is_groupby(groupby->op))
3673 1 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: subquery uses ungrouped column from outer query");
3674 :
3675 : /* find having select */
3676 45591 : if (!subquery && groupby && !is_processed(groupby) && is_sql_having(f)) {
3677 108 : og = groupby;
3678 108 : while(!is_processed(groupby) && !is_base(groupby->op)) {
3679 63 : if (is_select(groupby->op) || !groupby->l)
3680 : break;
3681 : if (groupby->l)
3682 : groupby = groupby->l;
3683 : }
3684 67 : if (groupby && is_select(groupby->op) && !is_processed(groupby)) {
3685 22 : group = 1;
3686 22 : sel = groupby;
3687 : /* At the end we switch back to the old projection relation og.
3688 : * During the partitioning and ordering we add the expressions to the intermediate relations. */
3689 : }
3690 22 : if (!sel)
3691 : groupby = og;
3692 22 : if (sel && sel->l)
3693 22 : groupby = sel->l;
3694 : }
3695 :
3696 : /* find groupby */
3697 45591 : if (!subquery && groupby && !is_processed(groupby) && !is_base(groupby->op)) {
3698 30648 : og = groupby;
3699 30648 : groupby = rel_find_groupby(groupby);
3700 30648 : if (groupby)
3701 : group = 1;
3702 : else
3703 : groupby = og;
3704 : }
3705 :
3706 7865 : if (!groupby && exps_card(exps) > CARD_ATOM) {
3707 0 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3708 0 : return sql_error(sql, 02, SQLSTATE(42000) "%s: missing group by", toUpperCopy(uaname, aname));
3709 : }
3710 :
3711 45591 : if (!subquery && groupby && groupby->op != op_groupby) { /* implicit groupby */
3712 21069 : if (!all_freevar && query->last_exp && !is_sql_aggr(query->last_state)) {
3713 9 : if (exp_relname(query->last_exp) && exp_name(query->last_exp) && !has_label(query->last_exp))
3714 9 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s.%s' in query results without an aggregate function", exp_relname(query->last_exp), exp_name(query->last_exp));
3715 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
3716 : }
3717 21060 : res = groupby = rel_groupby(sql, groupby, NULL);
3718 : }
3719 45582 : if (subquery) {
3720 0 : assert(!all_freevar);
3721 0 : res = groupby;
3722 0 : if (is_sql_sel(f) && is_left(subquery->op) && !is_groupby(groupby->op)) {
3723 0 : res = groupby = rel_groupby(sql, groupby, NULL);
3724 0 : exps_set_freevar(sql, exps, groupby); /* mark free variables */
3725 0 : } else if (!is_groupby(groupby->op)) {
3726 0 : res = groupby = rel_groupby(sql, groupby, NULL);
3727 : }
3728 0 : assert(!is_base(groupby->op));
3729 : }
3730 45582 : if ((!exps || exps_card(exps) > CARD_ATOM) && (!res || !groupby))
3731 : return NULL;
3732 :
3733 45582 : list *obe = NULL;
3734 45582 : bool handled_order = true;
3735 45582 : if (args && args->data.sym && args->data.sym->token != SQL_ORDERBY)
3736 : return NULL;
3737 19337 : if (args && args->data.sym) { /* handle order by */
3738 0 : int base = (!groupby || !is_project(groupby->op) || is_base(groupby->op) || is_processed(groupby));
3739 0 : sql_rel *gl = base?groupby:groupby->l;//, *ogl = gl; /* handle case of subqueries without correlation */
3740 0 : obe = rel_order_by(query, &gl, args->data.sym, 0, f);
3741 0 : if (!obe)
3742 0 : return NULL;
3743 0 : handled_order = false;
3744 : }
3745 :
3746 45582 : if (all_freevar) {
3747 247 : query_update_outer(query, res, all_freevar-1);
3748 45335 : } else if (rel) {
3749 45335 : *rel = res;
3750 45335 : if (query->last_rel != res) {
3751 41397 : query->last_rel = res;
3752 41397 : query->last_state |= sql_aggr;
3753 : }
3754 : }
3755 :
3756 45582 : if (!has_args) { /* count(*) case */
3757 19337 : obe = NULL; /* no errors, although the order by is useless */
3758 19337 : sql_exp *e;
3759 :
3760 19337 : if (strcmp(aname, "count") != 0) {
3761 2 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3762 2 : return sql_error(sql, 02, SQLSTATE(42000) "%s: unable to perform '%s(*)'", toUpperCopy(uaname, aname), aname);
3763 : }
3764 19335 : a = sql_bind_func(sql, "sys", aname, sql_bind_localtype("void"), NULL, F_AGGR, true, true);
3765 19335 : e = exp_aggr(sql->sa, NULL, a, distinct, 0, groupby?groupby->card:CARD_ATOM, 0);
3766 :
3767 19335 : if (!groupby)
3768 : return e;
3769 19335 : if (all_freevar)
3770 0 : query_outer_used_exp(query, all_freevar-1, e, sql_aggr);
3771 19335 : e = rel_groupby_add_aggr(sql, groupby, e);
3772 19335 : if (!group && !all_freevar)
3773 : return e;
3774 3212 : if (all_freevar) {
3775 0 : assert(!is_simple_project(res->op));
3776 0 : e->card = CARD_ATOM;
3777 0 : set_freevar(e, all_freevar-1);
3778 0 : return e;
3779 : }
3780 : return e;
3781 : }
3782 :
3783 : /* use cnt as nils shouldn't be counted */
3784 26245 : no_nil = 1;
3785 :
3786 26245 : gr = groupby;
3787 26245 : if (gr && gr->op == op_project && gr->l)
3788 : gr = gr->l;
3789 :
3790 26245 : if (is_grouping) {
3791 109 : sql_subtype *tpe;
3792 109 : list *l = (list*) groupby->r;
3793 :
3794 109 : if (list_length(l) <= 7)
3795 107 : tpe = sql_bind_localtype("bte");
3796 2 : else if (list_length(l) <= 15)
3797 2 : tpe = sql_bind_localtype("sht");
3798 0 : else if (list_length(l) <= 31)
3799 0 : tpe = sql_bind_localtype("int");
3800 0 : else if (list_length(l) <= 63)
3801 0 : tpe = sql_bind_localtype("lng");
3802 : #ifdef HAVE_HGE
3803 0 : else if (list_length(l) <= 127)
3804 0 : tpe = sql_bind_localtype("hge");
3805 : #endif
3806 : else
3807 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: GROUPING the number of grouping columns is larger"
3808 : " than the maximum number of representable bits from this server (%d > %d)", list_length(l),
3809 : #ifdef HAVE_HGE
3810 : 127
3811 : #else
3812 : 63
3813 : #endif
3814 : );
3815 109 : a = sql_bind_func_result(sql, sname, aname, F_AGGR, true, tpe, 1, exp_subtype(exps->h->data));
3816 : } else {
3817 26136 : a = sql_bind_func_(sql, sname, aname, exp_types(sql->sa, exps), F_AGGR, false, false);
3818 26136 : if (!a && obe && list_length(obe) == 1) { /* try to find aggregation function with requires order by column */
3819 0 : list *nexps = append(sa_list(sql->sa), obe->h->data);
3820 0 : nexps = list_merge(nexps, exps, (fdup) NULL);
3821 0 : a = sql_bind_func_(sql, sname, aname, exp_types(sql->sa, nexps), F_AGGR, false, false);
3822 0 : if (a && a->func->order_required) {
3823 : /* reset error */
3824 0 : handled_order = true;
3825 0 : sql->session->status = 0;
3826 0 : sql->errstr[0] = '\0';
3827 0 : exps = nexps;
3828 0 : obe = NULL;
3829 : }
3830 : }
3831 : }
3832 :
3833 26245 : if (a) {
3834 26240 : found = true;
3835 26240 : if (!execute_priv(sql, a->func))
3836 0 : a = NULL;
3837 26240 : if (!is_grouping && a && !(exps = check_arguments_and_find_largest_any_type(sql, rel ? *rel : NULL, exps, a, 0, false)))
3838 0 : a = NULL;
3839 : }
3840 :
3841 26245 : if (a) {
3842 26240 : bool hasnil = have_nil(exps) || (strcmp(aname, "count") != 0 && (!groupby || list_empty(groupby->r))); /* for global case, the aggregate may return NULL */
3843 26240 : sql_exp *e = exp_aggr(sql->sa, exps, a, distinct, no_nil, groupby?groupby->card:CARD_ATOM, hasnil);
3844 :
3845 26240 : if (!obe && a->func->order_required && !handled_order) {
3846 : /* TODO preper error on missing order by */
3847 : return NULL;
3848 : }
3849 0 : if (obe && !a->func->order_required && !a->func->opt_order)
3850 : obe = NULL;
3851 0 : if (obe) /* add order by expressions */
3852 0 : e->r = append(sa_list(sql->sa), obe);
3853 26240 : if (!groupby)
3854 : return e;
3855 26240 : if (all_freevar)
3856 247 : query_outer_aggregated(query, all_freevar-1, e);
3857 26240 : e = rel_groupby_add_aggr(sql, groupby, e);
3858 26240 : if (!group && !all_freevar)
3859 : return e;
3860 19689 : if (all_freevar) {
3861 247 : rel_bind_vars(sql, groupby->l, exps);
3862 247 : assert(!is_simple_project(res->op));
3863 247 : e->card = CARD_ATOM;
3864 247 : set_freevar(e, all_freevar-1);
3865 247 : return e;
3866 : }
3867 : return e;
3868 : }
3869 5 : const char *type = "unknown";
3870 5 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
3871 :
3872 5 : if (!list_empty(exps)) {
3873 5 : sql_exp *e = exps->h->data;
3874 5 : type = exp_subtype(e)->type->base.name;
3875 : }
3876 15 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "%s: %s aggregate %s%s%s'%s'(%s)", toUpperCopy(uaname, aname), found ? "insufficient privileges for" : "no such",
3877 : sname ? "'":"", sname ? sname : "", sname ? "'.":"", aname, type);
3878 : }
3879 :
3880 : static sql_exp *
3881 19456 : rel_aggr(sql_query *query, sql_rel **rel, symbol *se, int f)
3882 : {
3883 19456 : dlist *l = se->data.lval;
3884 19456 : dnode *d = l->h->next->next;
3885 19456 : int distinct = l->h->next->data.i_val;
3886 19456 : char *aname = qname_schema_object(l->h->data.lval);
3887 19456 : char *sname = qname_schema(l->h->data.lval);
3888 :
3889 19456 : return _rel_aggr(query, rel, distinct, sname, aname, d, f);
3890 : }
3891 :
3892 : static sql_exp *
3893 101268 : rel_case(sql_query *query, sql_rel **rel, symbol *opt_cond, dlist *when_search_list, symbol *opt_else, int f)
3894 : {
3895 101268 : mvc *sql = query->sql;
3896 101268 : sql_subtype *tpe = NULL;
3897 101268 : list *conds = new_exp_list(sql->sa), *results = new_exp_list(sql->sa);
3898 101268 : sql_subtype *restype = NULL, *condtype = NULL, ctype, rtype, bt;
3899 101268 : sql_exp *res = NULL, *opt_cond_exp = NULL;
3900 101268 : exp_kind ek = {type_value, card_column, FALSE};
3901 :
3902 101268 : if (opt_cond) {
3903 9532 : if (!(opt_cond_exp = rel_value_exp(query, rel, opt_cond, f, ek)))
3904 : return NULL;
3905 9531 : condtype = exp_subtype(opt_cond_exp);
3906 : }
3907 :
3908 250105 : for (dnode *dn = when_search_list->h; dn; dn = dn->next) {
3909 148847 : sql_exp *cond = NULL, *result = NULL;
3910 148847 : dlist *when = dn->data.sym->data.lval;
3911 :
3912 148847 : if (opt_cond)
3913 45936 : cond = rel_value_exp(query, rel, when->h->data.sym, f, ek);
3914 : else
3915 102911 : cond = rel_logical_value_exp(query, rel, when->h->data.sym, f, ek);
3916 148847 : if (!cond)
3917 : return NULL;
3918 148841 : append(conds, cond);
3919 148841 : tpe = exp_subtype(cond);
3920 148841 : if (tpe && condtype) {
3921 57105 : result_datatype(&ctype, condtype, tpe);
3922 57105 : condtype = &ctype;
3923 91736 : } else if (tpe) {
3924 91734 : condtype = tpe;
3925 : }
3926 :
3927 148841 : if (!(result = rel_value_exp(query, rel, when->h->next->data.sym, f, ek)))
3928 : return NULL;
3929 148838 : append(results, result);
3930 148838 : tpe = exp_subtype(result);
3931 148838 : if (tpe && restype) {
3932 47577 : result_datatype(&rtype, restype, tpe);
3933 47577 : restype = &rtype;
3934 101261 : } else if (tpe) {
3935 101255 : restype = tpe;
3936 : }
3937 : }
3938 101258 : if (opt_else) {
3939 98664 : if (!(res = rel_value_exp(query, rel, opt_else, f, ek)))
3940 : return NULL;
3941 :
3942 98664 : tpe = exp_subtype(res);
3943 98664 : if (tpe && restype) {
3944 98659 : result_datatype(&rtype, restype, tpe);
3945 98659 : restype = &rtype;
3946 5 : } else if (tpe) {
3947 : restype = tpe;
3948 : }
3949 :
3950 98662 : if (!restype)
3951 2 : return sql_error(sql, 02, SQLSTATE(42000) "Result type missing");
3952 98662 : if (restype->type->localtype == TYPE_void) /* NULL */
3953 0 : restype = sql_bind_localtype("str");
3954 :
3955 98662 : if (!(res = exp_check_type(sql, restype, rel ? *rel : NULL, res, type_equal)))
3956 : return NULL;
3957 : } else {
3958 2594 : if (!restype)
3959 0 : return sql_error(sql, 02, SQLSTATE(42000) "Result type missing");
3960 2594 : if (restype->type->localtype == TYPE_void) /* NULL */
3961 7 : restype = sql_bind_localtype("str");
3962 2594 : res = exp_null(sql->sa, restype);
3963 : }
3964 :
3965 101256 : if (!condtype)
3966 0 : return sql_error(sql, 02, SQLSTATE(42000) "Condition type missing");
3967 101256 : if (condtype->type->localtype == TYPE_void) /* NULL */
3968 0 : condtype = sql_bind_localtype("str");
3969 101256 : if (opt_cond_exp && !(opt_cond_exp = exp_check_type(sql, condtype, rel ? *rel : NULL, opt_cond_exp, type_equal)))
3970 : return NULL;
3971 101256 : sql_find_subtype(&bt, "boolean", 0, 0);
3972 101256 : list *args = sa_list(sql->sa);
3973 101256 : if (opt_cond_exp)
3974 9525 : append(args, opt_cond_exp);
3975 250087 : for (node *n = conds->h, *m = results->h; n && m; n = n->next, m = m->next) {
3976 148832 : sql_exp *cond = n->data;
3977 148832 : sql_exp *result = m->data;
3978 :
3979 148832 : if (!(result = exp_check_type(sql, restype, rel ? *rel : NULL, result, type_equal)))
3980 : return NULL;
3981 :
3982 148832 : if (!(cond = exp_check_type(sql, condtype, rel ? *rel : NULL, cond, type_equal)))
3983 : return NULL;
3984 148831 : if (!opt_cond_exp && !(cond = exp_check_type(sql, &bt, rel ? *rel : NULL, cond, type_equal)))
3985 : return NULL;
3986 148831 : append(args, cond);
3987 148831 : append(args, result);
3988 : }
3989 101255 : assert(res);
3990 101255 : list_append(args, res);
3991 101255 : list *types = sa_list(sql->sa);
3992 101255 : types = append(append(types, restype), restype);
3993 192986 : sql_subfunc *case_func = find_func(sql, NULL, opt_cond_exp?"casewhen":"case", list_length(types), F_FUNC, true, NULL, NULL);
3994 101255 : res = exp_op(sql->sa, args, case_func);
3995 101255 : ((sql_subfunc*)res->f)->res->h->data = sql_create_subtype(sql->sa, restype->type, restype->digits, restype->scale);
3996 101255 : return res;
3997 : }
3998 :
3999 : static sql_exp *
4000 4027 : rel_complex_case(sql_query *query, sql_rel **rel, dlist *case_args, int f, str func)
4001 : {
4002 4027 : exp_kind ek = {type_value, card_column, FALSE};
4003 4027 : list *args = sa_list(query->sql->sa);
4004 4027 : sql_subtype *restype = NULL, rtype;
4005 4027 : sql_exp *res;
4006 :
4007 : /* generate nested func calls */
4008 12537 : for(dnode *dn = case_args->h; dn; dn = dn->next) {
4009 8523 : sql_exp *a = rel_value_exp(query, rel, dn->data.sym, f, ek);
4010 8523 : if (!a)
4011 : return NULL;
4012 8510 : append(args, a);
4013 : /* all arguments should have the same type */
4014 8510 : sql_subtype *tpe = exp_subtype(a);
4015 8510 : if (tpe && restype) {
4016 4485 : result_datatype(&rtype, restype, tpe);
4017 4485 : restype = &rtype;
4018 4025 : } else if (tpe) {
4019 4025 : restype = tpe;
4020 : }
4021 : }
4022 4014 : if (!restype)
4023 0 : return sql_error(query->sql, 02, SQLSTATE(42000) "Result type missing");
4024 4014 : if (restype->type->localtype == TYPE_void) /* NULL */
4025 0 : restype = sql_bind_localtype("str");
4026 4014 : list *nargs = sa_list(query->sql->sa);
4027 12509 : for (node *m = args->h; m; m = m->next) {
4028 8495 : sql_exp *result = m->data;
4029 :
4030 8495 : if (!(result = exp_check_type(query->sql, restype, rel ? *rel : NULL, result, type_equal)))
4031 : return NULL;
4032 8495 : append(nargs, result);
4033 : }
4034 4014 : list *types = append(append(sa_list(query->sql->sa), restype), restype);
4035 4014 : sql_subfunc *fnc = find_func(query->sql, NULL, func, list_length(types), F_FUNC, true, NULL, NULL);
4036 4014 : res = exp_op(query->sql->sa, nargs, fnc);
4037 4014 : ((sql_subfunc*)res->f)->res->h->data = sql_create_subtype(query->sql->sa, restype->type, restype->digits, restype->scale);
4038 4014 : return res;
4039 : }
4040 :
4041 : static sql_exp *
4042 105295 : rel_case_exp(sql_query *query, sql_rel **rel, symbol *se, int f)
4043 : {
4044 105295 : dlist *l = se->data.lval;
4045 :
4046 105295 : if (se->token == SQL_COALESCE) {
4047 3876 : return rel_complex_case(query, rel, l, f | sql_farg, "coalesce");
4048 101419 : } else if (se->token == SQL_NULLIF) {
4049 151 : return rel_complex_case(query, rel, l, f | sql_farg, "nullif");
4050 101268 : } else if (l->h->type == type_list) {
4051 91736 : dlist *when_search_list = l->h->data.lval;
4052 91736 : symbol *opt_else = l->h->next->data.sym;
4053 :
4054 91736 : return rel_case(query, rel, NULL, when_search_list, opt_else, f | sql_farg);
4055 : } else {
4056 9532 : symbol *scalar_exp = l->h->data.sym;
4057 9532 : dlist *when_value_list = l->h->next->data.lval;
4058 9532 : symbol *opt_else = l->h->next->next->data.sym;
4059 :
4060 9532 : return rel_case(query, rel, scalar_exp, when_value_list, opt_else, f | sql_farg);
4061 : }
4062 : }
4063 :
4064 : #define E_ATOM_STRING(e) ((atom*)(e)->l)->data.val.sval
4065 :
4066 : static sql_exp *
4067 172563 : rel_cast(sql_query *query, sql_rel **rel, symbol *se, int f)
4068 : {
4069 172563 : mvc *sql = query->sql;
4070 172563 : dlist *dl = se->data.lval;
4071 172563 : symbol *s = dl->h->data.sym;
4072 172563 : sql_subtype *tpe = &dl->h->next->data.typeval;
4073 172563 : exp_kind ek = {type_value, card_column, FALSE};
4074 172563 : sql_exp *e = rel_value_exp(query, rel, s, f|sql_farg, ek);
4075 :
4076 172563 : if (!e)
4077 : return NULL;
4078 :
4079 : /* strings may need to be truncated */
4080 172548 : if (EC_VARCHAR(tpe->type->eclass) && tpe->digits > 0) {
4081 84358 : sql_subtype *et = exp_subtype(e);
4082 : /* truncate only if the number of digits are smaller or from clob */
4083 84358 : if (et && EC_VARCHAR(et->type->eclass) && (tpe->digits < et->digits || et->digits == 0)) {
4084 2882 : sql_subfunc *c = sql_bind_func(sql, "sys", "truncate", et, sql_bind_localtype("int"), F_FUNC, true, true);
4085 2882 : if (c)
4086 2882 : e = exp_binop(sql->sa, e, exp_atom_int(sql->sa, tpe->digits), c);
4087 : }
4088 : }
4089 :
4090 172548 : if (tpe->type->eclass == EC_DEC) {
4091 447 : sql_subtype *et = exp_subtype(e);
4092 447 : if (e->type == e_atom && !tpe->digits) {
4093 9 : if (et->type->eclass == EC_NUM || et->type->eclass == EC_DEC) {
4094 6 : tpe->digits = atom_num_digits(e->l);
4095 6 : tpe = sql_bind_subtype(sql->sa, "decimal", tpe->digits, et->scale);
4096 3 : } else if (EC_VARCHAR(et->type->eclass)) {
4097 2 : char *s = E_ATOM_STRING(e);
4098 2 : unsigned int min_precision = 0, min_scale = 0;
4099 2 : bool dot_seen = false;
4100 16 : for (size_t i = 0; i < strlen(s); i++) {
4101 14 : if (isdigit(s[i])) {
4102 12 : min_precision++;
4103 12 : if (dot_seen)
4104 10 : min_scale++;
4105 2 : } else if (s[i] == '.') {
4106 2 : dot_seen = true;
4107 : }
4108 : }
4109 2 : tpe = sql_bind_subtype(sql->sa, "decimal", min_precision, min_scale);
4110 : } else { /* fallback */
4111 1 : tpe = sql_bind_subtype(sql->sa, "decimal", 18, 3);
4112 : }
4113 438 : } else if (!tpe->digits && !tpe->scale) {
4114 105 : if (et->type->eclass == EC_NUM)
4115 36 : tpe = sql_bind_subtype(sql->sa, "decimal", et->digits, 0);
4116 : else /* fallback */
4117 69 : tpe = sql_bind_subtype(sql->sa, "decimal", 18, 3);
4118 : }
4119 : }
4120 :
4121 172548 : if (e)
4122 172548 : e = exp_check_type(sql, tpe, rel ? *rel : NULL, e, type_cast);
4123 :
4124 172548 : if (e && e->type == e_convert)
4125 49059 : exp_label(sql->sa, e, ++sql->label);
4126 :
4127 : return e;
4128 : }
4129 :
4130 : static sql_exp *
4131 1584 : rel_next_value_for( mvc *sql, symbol *se )
4132 : {
4133 1584 : char *sname = qname_schema(se->data.lval);
4134 1584 : char *seqname = qname_schema_object(se->data.lval);
4135 1584 : sql_sequence *seq = NULL;
4136 1584 : sql_subtype t;
4137 1584 : sql_subfunc *f;
4138 :
4139 1584 : if (!sname)
4140 222 : sname = "sys";
4141 1584 : if (!stack_find_rel_view(sql, seqname)) {
4142 1388 : if (!(seq = find_sequence_on_scope(sql, sname, seqname, "NEXT VALUE FOR")))
4143 : return NULL;
4144 1386 : if (!mvc_schema_privs(sql, seq->s))
4145 0 : return sql_error(sql, 02, SQLSTATE(42000) "NEXT VALUE FOR: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), seq->s->base.name);
4146 : }
4147 1582 : sql_find_subtype(&t, "varchar", 0, 0);
4148 1582 : f = sql_bind_func(sql, "sys", "next_value_for", &t, &t, F_FUNC, true, true);
4149 1582 : assert(f);
4150 : /* sequence found in the stack, ie just created. use given schema? */
4151 1582 : return exp_binop(sql->sa, exp_atom_str(sql->sa, seq && seq->s ? seq->s->base.name : sname, &t), exp_atom_str(sql->sa, seqname, &t), f);
4152 : }
4153 :
4154 : /* some users like to use aliases already in the groupby */
4155 : static sql_exp *
4156 165 : rel_selection_ref(sql_query *query, sql_rel **rel, char *name, dlist *selection)
4157 : {
4158 165 : allocator *sa = query->sql->sa;
4159 165 : dlist *nl;
4160 165 : exp_kind ek = {type_value, card_column, FALSE};
4161 165 : sql_exp *res = NULL;
4162 165 : symbol *nsym;
4163 :
4164 165 : if (!selection)
4165 : return NULL;
4166 :
4167 679 : for (dnode *n = selection->h; n; n = n->next) {
4168 : /* we only look for columns */
4169 517 : tokens to = n->data.sym->token;
4170 517 : if (to == SQL_COLUMN || to == SQL_IDENT) {
4171 515 : dlist *l = n->data.sym->data.lval;
4172 : /* AS name */
4173 515 : if (l->h->next->data.sval && strcmp(l->h->next->data.sval, name) == 0) {
4174 146 : sql_exp *ve = rel_value_exp(query, rel, l->h->data.sym, sql_sel|sql_groupby, ek);
4175 146 : if (ve) {
4176 145 : if (res)
4177 1 : return sql_error(query->sql, ERR_AMBIGUOUS, SQLSTATE(42000) "SELECT: identifier '%s' ambiguous", name);
4178 144 : res = ve;
4179 :
4180 144 : nl = dlist_create(sa);
4181 144 : exp_setname(query->sql, ve, NULL, name);
4182 : /* now we should rewrite the selection such that it uses the new group by column */
4183 144 : dlist_append_string(sa, nl, sa_strdup(sa, name));
4184 144 : nsym = symbol_create_list(sa, to, nl);
4185 144 : nl = dlist_create(sa);
4186 144 : dlist_append_symbol(sa, nl, nsym);
4187 : /* no alias */
4188 144 : dlist_append_symbol(sa, nl, NULL);
4189 144 : n->data.sym = symbol_create_list(sa, to, nl);
4190 : }
4191 : }
4192 : }
4193 : }
4194 : return res;
4195 : }
4196 :
4197 : static char*
4198 197 : symbol_get_identifier(symbol *sym)
4199 : {
4200 197 : dlist *syml;
4201 :
4202 197 : if (sym->token != SQL_COLUMN && sym->token != SQL_IDENT)
4203 : return NULL;
4204 182 : syml = sym->data.lval;
4205 182 : if (dlist_length(syml) > 1)
4206 : return NULL;
4207 :
4208 165 : return syml->h->data.sval;
4209 : }
4210 :
4211 : static sql_exp*
4212 36415 : rel_group_column(sql_query *query, sql_rel **rel, symbol *grp, dlist *selection, list *exps, int f)
4213 : {
4214 36415 : sql_query *lquery = query_create(query->sql);
4215 36415 : mvc *sql = query->sql;
4216 36415 : exp_kind ek = {type_value, card_value, TRUE};
4217 36415 : sql_exp *e = rel_value_exp2(lquery, rel, grp, f, ek);
4218 :
4219 36415 : if (e && exp_is_atom(e)) {
4220 35 : sql_subtype *tpe = exp_subtype(e);
4221 35 : if (!is_atom(e->type) ||!tpe || tpe->type->eclass != EC_NUM) {
4222 3 : if (!tpe)
4223 2 : return sql_error(sql, 02, SQLSTATE(42000) "Cannot have a parameter (?) for group by column");
4224 4 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: non-integer constant in GROUP BY");
4225 : }
4226 : }
4227 :
4228 192 : if (!e) {
4229 192 : char buf[ERRSIZE], *name;
4230 192 : int status = sql->session->status;
4231 192 : strcpy(buf, sql->errstr);
4232 : /* reset error */
4233 192 : sql->session->status = 0;
4234 192 : sql->errstr[0] = '\0';
4235 :
4236 192 : if ((name = symbol_get_identifier(grp))) {
4237 163 : e = rel_selection_ref(query, rel, name, selection);
4238 163 : if (!e) { /* attempt to find in the existing list of group by expressions */
4239 29 : for (node *n = exps->h ; n && !e ; n = n->next) {
4240 9 : sql_exp *ge = (sql_exp *) n->data;
4241 9 : const char *gen = exp_name(ge);
4242 :
4243 9 : if (gen && strcmp(name, gen) == 0)
4244 5 : e = exp_ref(sql, ge);
4245 : }
4246 : }
4247 : }
4248 49 : if (!e && query_has_outer(query)) {
4249 : /* reset error */
4250 32 : sql->session->status = 0;
4251 32 : sql->errstr[0] = '\0';
4252 32 : e = rel_value_exp2(query, rel, grp, f, ek);
4253 : }
4254 44 : if (!e) {
4255 13 : if (sql->errstr[0] == 0) {
4256 10 : sql->session->status = status;
4257 10 : strcpy(sql->errstr, buf);
4258 : }
4259 13 : return NULL;
4260 : }
4261 : }
4262 36396 : if (!exp_subtype(e))
4263 0 : return sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) for group by column");
4264 : return e;
4265 : }
4266 :
4267 : static list*
4268 44 : list_power_set(allocator *sa, list* input) /* cube */
4269 : {
4270 44 : list *res = sa_list(sa);
4271 : /* N stores total number of subsets */
4272 44 : int N = (int) pow(2, input->cnt);
4273 :
4274 : /* generate each subset one by one */
4275 266 : for (int i = 0; i < N; i++) {
4276 222 : list *ll = sa_list(sa);
4277 222 : int j = 0; /* check every bit of i */
4278 844 : for (node *n = input->h ; n ; n = n->next) {
4279 : /* if j'th bit of i is set, then append */
4280 622 : if (i & (1 << j))
4281 311 : list_prepend(ll, n->data);
4282 622 : j++;
4283 : }
4284 222 : list_prepend(res, ll);
4285 : }
4286 44 : return res;
4287 : }
4288 :
4289 : static list*
4290 61 : list_rollup(allocator *sa, list* input)
4291 : {
4292 61 : list *res = sa_list(sa);
4293 :
4294 188 : for (int counter = input->cnt; counter > 0; counter--) {
4295 127 : list *ll = sa_list(sa);
4296 127 : int j = 0;
4297 376 : for (node *n = input->h; n && j < counter; j++, n = n->next)
4298 249 : list_append(ll, n->data);
4299 127 : list_append(res, ll);
4300 : }
4301 61 : list_append(res, sa_list(sa)); /* global aggregate case */
4302 61 : return res;
4303 : }
4304 :
4305 : static int
4306 320 : list_equal(list* list1, list* list2)
4307 : {
4308 375 : for (node *n = list1->h; n ; n = n->next) {
4309 328 : sql_exp *e = (sql_exp*) n->data;
4310 328 : if (!exps_find_exp(list2, e))
4311 : return 1;
4312 : }
4313 78 : for (node *n = list2->h; n ; n = n->next) {
4314 47 : sql_exp *e = (sql_exp*) n->data;
4315 47 : if (!exps_find_exp(list1, e))
4316 : return 1;
4317 : }
4318 : return 0;
4319 : }
4320 :
4321 : static list*
4322 26 : lists_cartesian_product_and_distinct(allocator *sa, list *l1, list *l2)
4323 : {
4324 26 : list *res = sa_list(sa);
4325 :
4326 : /* for each list of l2, merge into each list of l1 while removing duplicates */
4327 116 : for (node *n = l1->h ; n ; n = n->next) {
4328 90 : list *sub_list = (list*) n->data;
4329 :
4330 279 : for (node *m = l2->h ; m ; m = m->next) {
4331 189 : list *other = (list*) m->data;
4332 189 : list_append(res, list_distinct(list_merge(list_dup(sub_list, (fdup) NULL), other, (fdup) NULL), (fcmp) list_equal, (fdup) NULL));
4333 : }
4334 : }
4335 26 : return res;
4336 : }
4337 :
4338 : static list*
4339 13440 : rel_groupings(sql_query *query, sql_rel **rel, symbol *groupby, dlist *selection, int f, bool grouping_sets, list **sets)
4340 : {
4341 13440 : mvc *sql = query->sql;
4342 13440 : list *exps = new_exp_list(sql->sa);
4343 :
4344 13440 : if (mvc_highwater(sql))
4345 0 : return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
4346 :
4347 49762 : for (dnode *o = groupby->data.lval->h; o; o = o->next) {
4348 36342 : symbol *grouping = o->data.sym;
4349 36342 : list *next_set = NULL;
4350 :
4351 36342 : if (grouping->token == SQL_GROUPING_SETS) { /* call recursively, and merge the generated sets */
4352 39 : list *other = rel_groupings(query, rel, grouping, selection, f, true, &next_set);
4353 39 : if (!other)
4354 20 : return NULL;
4355 39 : exps = list_distinct(list_merge(exps, other, (fdup) NULL), (fcmp) exp_equal, (fdup) NULL);
4356 : } else {
4357 36303 : dlist *dl = grouping->data.lval;
4358 36303 : if (dl) {
4359 36277 : list *set_cols = new_exp_list(sql->sa); /* columns and combination of columns to be used for the next set */
4360 :
4361 72643 : for (dnode *oo = dl->h; oo; oo = oo->next) {
4362 36385 : symbol *grp = oo->data.sym;
4363 36385 : list *next_tuple = new_exp_list(sql->sa); /* next tuple of columns */
4364 :
4365 36385 : if (grp->token == SQL_COLUMN_GROUP) { /* set of columns */
4366 71 : assert(is_sql_group_totals(f));
4367 172 : for (dnode *ooo = grp->data.lval->h; ooo; ooo = ooo->next) {
4368 101 : symbol *elm = ooo->data.sym;
4369 101 : sql_exp *e = rel_group_column(query, rel, elm, selection, exps, f);
4370 101 : if (!e)
4371 : return NULL;
4372 101 : assert(e->type == e_column);
4373 101 : list_append(next_tuple, e);
4374 101 : list_append(exps, e);
4375 : }
4376 : } else { /* single column or expression */
4377 36314 : sql_exp *e = rel_group_column(query, rel, grp, selection, exps, f);
4378 36314 : if (!e)
4379 : return NULL;
4380 36295 : if (e->type != e_column && !exp_is_atom(e)) { /* store group by expressions in the stack */
4381 142 : if (is_sql_group_totals(f))
4382 0 : return sql_error(sql, 02, SQLSTATE(42000) "GROUP BY: grouping expressions not possible with ROLLUP, CUBE and GROUPING SETS");
4383 142 : if (!exp_has_rel(e) && !frame_push_groupby_expression(sql, grp, e))
4384 : return NULL;
4385 : }
4386 36295 : list_append(next_tuple, e);
4387 36295 : list_append(exps, e);
4388 : }
4389 36366 : list_append(set_cols, next_tuple);
4390 : }
4391 36258 : if (is_sql_group_totals(f)) {
4392 178 : if (grouping->token == SQL_ROLLUP)
4393 61 : next_set = list_rollup(sql->sa, set_cols);
4394 117 : else if (grouping->token == SQL_CUBE)
4395 44 : next_set = list_power_set(sql->sa, set_cols);
4396 : else /* the list of sets is not used in the "GROUP BY a, b, ..." case */
4397 73 : next_set = list_append(new_exp_list(sql->sa), set_cols);
4398 : }
4399 26 : } else if (is_sql_group_totals(f) && grouping_sets) /* The GROUP BY () case is the global aggregate which is always added by ROLLUP and CUBE */
4400 17 : next_set = list_append(new_exp_list(sql->sa), new_exp_list(sql->sa));
4401 : }
4402 36323 : if (is_sql_group_totals(f)) { /* if there are no sets, set the found one, otherwise calculate cartesian product and merge the distinct ones */
4403 235 : if (!next_set)
4404 1 : return sql_error(sql, 02, SQLSTATE(42000) "GROUP BY: GROUPING SETS is empty");
4405 234 : if (!*sets)
4406 157 : *sets = next_set;
4407 : else
4408 77 : *sets = grouping_sets ? list_merge(*sets, next_set, (fdup) NULL) : lists_cartesian_product_and_distinct(sql->sa, *sets, next_set);
4409 : }
4410 : }
4411 : return exps;
4412 : }
4413 :
4414 : static list*
4415 2321 : rel_partition_groupings(sql_query *query, sql_rel **rel, symbol *partitionby, dlist *selection, int f)
4416 : {
4417 2321 : mvc *sql = query->sql;
4418 2321 : dnode *o = partitionby->data.lval->h;
4419 2321 : list *exps = new_exp_list(sql->sa);
4420 :
4421 6994 : for (; o; o = o->next) {
4422 2360 : symbol *grp = o->data.sym;
4423 2360 : exp_kind ek = {type_value, card_value, TRUE};
4424 2360 : sql_exp *e = rel_value_exp2(query, rel, grp, f, ek);
4425 :
4426 2360 : if (!e) {
4427 5 : int status = sql->session->status;
4428 5 : char buf[ERRSIZE], *name;
4429 :
4430 : /* reset error */
4431 5 : sql->session->status = 0;
4432 5 : strcpy(buf, sql->errstr);
4433 5 : sql->errstr[0] = '\0';
4434 :
4435 5 : if ((name = symbol_get_identifier(grp))) {
4436 2 : e = rel_selection_ref(query, rel, name, selection);
4437 2 : if (!e) { /* attempt to find in the existing list of partition by expressions */
4438 3 : for (node *n = exps->h ; n ; n = n->next) {
4439 1 : sql_exp *ge = (sql_exp *) n->data;
4440 1 : const char *gen = exp_name(ge);
4441 :
4442 1 : if (gen && strcmp(name, gen) == 0) {
4443 0 : e = exp_ref(sql, ge);
4444 0 : break;
4445 : }
4446 : }
4447 : }
4448 : }
4449 5 : if (!e) {
4450 5 : if (sql->errstr[0] == 0) {
4451 5 : sql->session->status = status;
4452 5 : strcpy(sql->errstr, buf);
4453 : }
4454 5 : return NULL;
4455 : }
4456 : }
4457 :
4458 2355 : if (exp_has_rel(e))
4459 3 : return sql_error(sql, 02, SQLSTATE(42000) "PARTITION BY: subqueries not allowed in PARTITION BY clause");
4460 :
4461 2352 : if (e->type != e_column) { /* store group by expressions in the stack */
4462 42 : if (!frame_push_groupby_expression(sql, grp, e))
4463 : return NULL;
4464 : }
4465 :
4466 2352 : if (e->card > CARD_AGGR)
4467 2230 : e->card = CARD_AGGR;
4468 2352 : append(exps, e);
4469 : }
4470 : return exps;
4471 : }
4472 :
4473 : /* find selection expressions matching the order by column expression */
4474 : /* complex columns only */
4475 : static sql_exp *
4476 67743 : rel_order_by_column_exp(sql_query *query, sql_rel **R, symbol *column_r, int needs_distinct, int f)
4477 : {
4478 67743 : mvc *sql = query->sql;
4479 67743 : sql_rel *r = *R, *p = NULL;
4480 67743 : sql_exp *e = NULL, *found = NULL;
4481 67743 : exp_kind ek = {type_value, card_column, FALSE};
4482 :
4483 67743 : if (!r)
4484 : return e;
4485 :
4486 67743 : if (is_simple_project(r->op) && r->l && is_processed(r)) {
4487 67681 : p = r;
4488 67681 : r = r->l;
4489 : }
4490 :
4491 67743 : e = rel_value_exp(query, &r, column_r, f, ek);
4492 :
4493 67743 : if (r && !p)
4494 62 : *R = r;
4495 67681 : else if (r)
4496 67681 : p->l = r;
4497 67743 : if (e && p) {
4498 67654 : if (is_project(p->op) && (found = exps_any_match(p->exps, e))) { /* if one of the projections matches, return a reference to it */
4499 60010 : e = exp_ref(sql, found);
4500 : } else {
4501 7644 : if (needs_distinct)
4502 2 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: with DISTINCT ORDER BY expressions must appear in select list");
4503 7642 : e = rel_project_add_exp(sql, p, e);
4504 7642 : if (r) {
4505 125343 : for (node *n = p->exps->h ; n ; n = n->next) {
4506 117703 : sql_exp *ee = n->data;
4507 :
4508 117703 : if (ee->card > r->card) {
4509 2 : if (exp_name(ee) && !has_label(ee))
4510 2 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results without an aggregate function", exp_name(ee));
4511 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
4512 : }
4513 : }
4514 : }
4515 : }
4516 67650 : return e;
4517 : }
4518 89 : if (e && r && is_project(r->op)) {
4519 28 : sql_exp *found = exps_find_exp(r->exps, e);
4520 :
4521 28 : if (!found) {
4522 8 : if (needs_distinct)
4523 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: with DISTINCT ORDER BY expressions must appear in select list");
4524 8 : if (!is_simple_project(r->op) && !is_groupby(r->op))
4525 1 : *R = r = rel_project(sql->sa, r, rel_projections(sql, r, NULL, 1, 0));
4526 8 : append(r->exps, e);
4527 : } else {
4528 : e = found;
4529 : }
4530 28 : e = exp_ref(sql, e);
4531 : }
4532 : return e;
4533 : }
4534 :
4535 : static dlist *
4536 110037 : simple_selection(symbol *sq)
4537 : {
4538 110037 : if (sq->token == SQL_SELECT) {
4539 13 : SelectNode *sn;
4540 13 : sn = (SelectNode *) sq;
4541 :
4542 13 : if (!sn->from && !sn->where && !sn->distinct && !sn->window && dlist_length(sn->selection) == 1)
4543 7 : return sn->selection;
4544 : }
4545 : return NULL;
4546 : }
4547 :
4548 : static list *
4549 40092 : rel_order_by(sql_query *query, sql_rel **R, symbol *orderby, int needs_distinct, int f)
4550 : {
4551 40092 : mvc *sql = query->sql;
4552 40092 : sql_rel *rel = *R, *or = rel; /* the order by relation */
4553 40092 : list *exps = new_exp_list(sql->sa);
4554 :
4555 40092 : if (!orderby->data.lval) { /* by all */
4556 6 : if (is_sql_orderby(f)) {
4557 6 : assert(is_project(rel->op));
4558 22 : for(node *n = rel->exps->h; n; n = n->next) {
4559 16 : sql_exp *e = n->data;
4560 16 : append(exps, exp_ref(sql, e));
4561 : }
4562 : return exps;
4563 : }
4564 : return NULL;
4565 : }
4566 :
4567 40086 : dnode *o = orderby->data.lval->h;
4568 40086 : dlist *selection = NULL;
4569 :
4570 40086 : if (is_sql_orderby(f)) {
4571 37057 : assert(is_project(rel->op));
4572 37057 : rel = rel->l;
4573 : }
4574 :
4575 150075 : for (; o; o = o->next) {
4576 110037 : symbol *order = o->data.sym;
4577 :
4578 110037 : if (order->token == SQL_COLUMN || order->token == SQL_IDENT) {
4579 110037 : symbol *col = order->data.lval->h->data.sym;
4580 110037 : int direction = order->data.lval->h->next->data.i_val;
4581 110037 : sql_exp *e = NULL;
4582 :
4583 110037 : assert(order->data.lval->h->next->type == type_int);
4584 110037 : if ((selection = simple_selection(col)) != NULL) {
4585 7 : dnode *o = selection->h;
4586 7 : order = o->data.sym;
4587 7 : if (order->data.lval->h->type == type_symbol)
4588 6 : col = order->data.lval->h->data.sym;
4589 : /* remove optional name from selection */
4590 7 : order->data.lval->h->next = NULL;
4591 : }
4592 :
4593 110037 : if (col->token == SQL_COLUMN || col->token == SQL_IDENT || col->token == SQL_ATOM) {
4594 109815 : exp_kind ek = {type_value, card_column, FALSE};
4595 :
4596 109815 : e = rel_value_exp2(query, &rel, col, f, ek);
4597 :
4598 109815 : if (e && e->card <= CARD_ATOM) {
4599 9374 : sql_subtype *tpe = exp_subtype(e);
4600 : /* integer atom on the stack */
4601 9374 : if (!is_sql_window(f) && e->type == e_atom &&
4602 9266 : tpe->type->eclass == EC_NUM) {
4603 9257 : atom *a = e->l;
4604 9257 : int nr = (int)atom_get_int(a);
4605 :
4606 9257 : e = exps_get_exp(rel->exps, nr);
4607 9257 : if (!e)
4608 3 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: the order by column number (%d) is not in the number of projections range (%d)", nr, list_length(rel->exps));
4609 9254 : e = exp_ref(sql, e);
4610 : }
4611 32914 : } else if (e && exp_card(e) > rel->card) {
4612 0 : if (exp_name(e) && !has_label(e))
4613 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results without an aggregate function", exp_name(e));
4614 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
4615 : }
4616 109812 : if (e && !exp_name(e))
4617 23 : exp_label(sql->sa, e, ++sql->label);
4618 42285 : if (e && rel && is_project(rel->op)) {
4619 39757 : sql_exp *found = exps_find_exp(rel->exps, e);
4620 :
4621 39757 : if (!found) {
4622 33 : if (needs_distinct)
4623 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: with DISTINCT ORDER BY expressions must appear in select list");
4624 33 : if (!is_freevar(e))
4625 16 : append(rel->exps, e);
4626 : } else {
4627 : e = found;
4628 : }
4629 39757 : if (!is_freevar(e))
4630 39740 : e = exp_ref(sql, e);
4631 : }
4632 : }
4633 :
4634 110034 : if (rel && !e && sql->session->status != -ERR_AMBIGUOUS) {
4635 : /* reset error */
4636 67743 : sql->session->status = 0;
4637 67743 : sql->errstr[0] = '\0';
4638 :
4639 67743 : e = rel_order_by_column_exp(query, &rel, col, needs_distinct, sql_sel | sql_orderby | (f & sql_group_totals) | (f & sql_window));
4640 : }
4641 67749 : if (!e)
4642 : return NULL;
4643 109990 : if (!exp_subtype(e))
4644 1 : return sql_error(sql, 01, SQLSTATE(42000) "Cannot have a parameter (?) for order by column");
4645 109989 : set_direction(e, direction);
4646 109989 : list_append(exps, e);
4647 : } else {
4648 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: order not of type SQL_COLUMN");
4649 : }
4650 : }
4651 40038 : if (is_sql_orderby(f) && or != rel)
4652 37016 : or->l = rel;
4653 40038 : if (is_sql_window(f))
4654 3022 : *R = rel;
4655 : return exps;
4656 : }
4657 :
4658 : static int
4659 814 : generate_window_bound(tokens sql_token, bool first_half)
4660 : {
4661 814 : switch (sql_token) {
4662 408 : case SQL_PRECEDING:
4663 408 : return first_half ? BOUND_FIRST_HALF_PRECEDING : BOUND_SECOND_HALF_PRECEDING;
4664 284 : case SQL_FOLLOWING:
4665 284 : return first_half ? BOUND_FIRST_HALF_FOLLOWING : BOUND_SECOND_HALF_FOLLOWING;
4666 122 : case SQL_CURRENT_ROW:
4667 122 : return first_half ? CURRENT_ROW_PRECEDING : CURRENT_ROW_FOLLOWING;
4668 : default:
4669 0 : assert(0);
4670 : }
4671 : return 0;
4672 : }
4673 :
4674 : /* window functions */
4675 : static sql_exp*
4676 407 : generate_window_bound_call(mvc *sql, sql_exp **estart, sql_exp **eend, sql_exp *pe, sql_exp *e,
4677 : sql_exp *start, sql_exp *fend, int frame_type, int excl, tokens t1, tokens t2)
4678 : {
4679 407 : list *rargs1 = sa_list(sql->sa), *rargs2 = sa_list(sql->sa), *targs1 = sa_list(sql->sa), *targs2 = sa_list(sql->sa);
4680 407 : sql_subfunc *dc1, *dc2;
4681 407 : sql_subtype *it = sql_bind_localtype("int");
4682 :
4683 407 : if (pe) {
4684 186 : append(targs1, exp_subtype(pe));
4685 186 : append(targs2, exp_subtype(pe));
4686 186 : append(rargs1, exp_copy(sql, pe));
4687 186 : append(rargs2, exp_copy(sql, pe));
4688 : }
4689 407 : append(rargs1, exp_copy(sql, e));
4690 407 : append(rargs2, exp_copy(sql, e));
4691 407 : append(targs1, exp_subtype(e));
4692 407 : append(targs2, exp_subtype(e));
4693 407 : append(targs1, it);
4694 407 : append(targs2, it);
4695 407 : append(targs1, it);
4696 407 : append(targs2, it);
4697 407 : append(targs1, it);
4698 407 : append(targs2, it);
4699 407 : append(targs1, exp_subtype(start));
4700 407 : append(targs2, exp_subtype(fend));
4701 :
4702 407 : dc1 = sql_bind_func_(sql, "sys", "window_bound", targs1, F_ANALYTIC, true, false);
4703 407 : dc2 = sql_bind_func_(sql, "sys", "window_bound", targs2, F_ANALYTIC, true, false);
4704 407 : if (!dc1 || !dc2)
4705 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: function 'window_bound' not found");
4706 407 : append(rargs1, exp_atom_int(sql->sa, frame_type));
4707 407 : append(rargs2, exp_atom_int(sql->sa, frame_type));
4708 407 : append(rargs1, exp_atom_int(sql->sa, generate_window_bound(t1, true)));
4709 407 : append(rargs2, exp_atom_int(sql->sa, generate_window_bound(t2, false)));
4710 407 : append(rargs1, exp_atom_int(sql->sa, excl));
4711 407 : append(rargs2, exp_atom_int(sql->sa, excl));
4712 407 : append(rargs1, start);
4713 407 : append(rargs2, fend);
4714 :
4715 407 : *estart = exp_op(sql->sa, rargs1, dc1);
4716 407 : *eend = exp_op(sql->sa, rargs2, dc2);
4717 407 : return e; /* return something to say there were no errors */
4718 : }
4719 :
4720 : #define EC_NUMERIC(e) (e==EC_NUM||EC_INTERVAL(e)||e==EC_DEC||e==EC_FLT)
4721 :
4722 : static sql_exp*
4723 601 : calculate_window_bound(sql_query *query, sql_rel *p, tokens token, symbol *bound, sql_exp *ie, int frame_type, int f)
4724 : {
4725 601 : mvc *sql = query->sql;
4726 601 : sql_subtype *bt, *bound_tp = sql_bind_localtype("lng"), *iet = exp_subtype(ie);
4727 601 : sql_exp *res = NULL;
4728 :
4729 792 : if ((bound->token == SQL_PRECEDING || bound->token == SQL_FOLLOWING || bound->token == SQL_CURRENT_ROW) && bound->type == type_int) {
4730 191 : atom *a = NULL;
4731 191 : bt = (frame_type == FRAME_ROWS || frame_type == FRAME_GROUPS) ? bound_tp : iet;
4732 :
4733 191 : if ((bound->data.i_val == UNBOUNDED_PRECEDING_BOUND || bound->data.i_val == UNBOUNDED_FOLLOWING_BOUND)) {
4734 69 : a = atom_max_value(sql->sa, EC_NUMERIC(bt->type->eclass) ? bt : bound_tp);
4735 122 : } else if (bound->data.i_val == CURRENT_ROW_BOUND) {
4736 124 : a = atom_zero_value(sql->sa, EC_NUMERIC(bt->type->eclass) ? bt : bound_tp);
4737 : } else {
4738 0 : assert(0);
4739 : }
4740 191 : res = exp_atom(sql->sa, a);
4741 : } else { /* arbitrary expression case */
4742 410 : exp_kind ek = {type_value, card_column, FALSE};
4743 410 : const char *bound_desc = (token == SQL_PRECEDING) ? "PRECEDING" : "FOLLOWING";
4744 :
4745 410 : assert(token == SQL_PRECEDING || token == SQL_FOLLOWING);
4746 410 : if (!(res = rel_value_exp2(query, &p, bound, f, ek)))
4747 3 : return NULL;
4748 410 : if (!(bt = exp_subtype(res))) { /* frame bound is a parameter */
4749 3 : sql_subtype *t = (frame_type == FRAME_ROWS || frame_type == FRAME_GROUPS) ? bound_tp : iet;
4750 3 : if (rel_set_type_param(sql, t, p, res, 0) < 0) /* workaround */
4751 : return NULL;
4752 3 : bt = exp_subtype(res);
4753 : }
4754 410 : if (exp_is_null_no_value_opt(res))
4755 1 : return sql_error(sql, 02, SQLSTATE(42000) "%s offset must not be NULL", bound_desc);
4756 409 : if ((frame_type == FRAME_ROWS || frame_type == FRAME_GROUPS) && bt->type->eclass != EC_NUM && !(res = exp_check_type(sql, bound_tp, p, res, type_equal)))
4757 : return NULL;
4758 409 : if (frame_type == FRAME_RANGE) {
4759 70 : sql_class iet_class = iet->type->eclass;
4760 :
4761 70 : if (!EC_NUMERIC(iet_class) && !EC_TEMP(iet_class))
4762 1 : return sql_error(sql, 02, SQLSTATE(42000) "Ranges with arbitrary expressions are available to numeric, interval and temporal types only");
4763 12 : if (EC_NUMERIC(iet_class) && !(res = exp_check_type(sql, iet, p, res, type_equal)))
4764 : return NULL;
4765 69 : if ((iet_class == EC_TIME || iet_class == EC_TIME_TZ) && bt->type->eclass != EC_SEC) {
4766 1 : (void) sql_error(sql, 02, SQLSTATE(42000) "For %s input the %s boundary must be an interval type up to the day", subtype2string2(sql->ta, iet), bound_desc);
4767 1 : sa_reset(sql->ta);
4768 1 : return NULL;
4769 : }
4770 68 : if (EC_TEMP(iet->type->eclass) && !EC_INTERVAL(bt->type->eclass)) {
4771 0 : (void) sql_error(sql, 02, SQLSTATE(42000) "For %s input the %s boundary must be an interval type", subtype2string2(sql->ta, iet), bound_desc);
4772 0 : sa_reset(sql->ta);
4773 0 : return NULL;
4774 : }
4775 : }
4776 : }
4777 : return res;
4778 : }
4779 :
4780 : static dlist*
4781 16 : get_window_clauses(mvc *sql, char* ident, symbol **partition_by_clause, symbol **order_by_clause, symbol **frame_clause)
4782 : {
4783 16 : dlist *window_specification = NULL;
4784 16 : char *window_ident;
4785 16 : int pos;
4786 :
4787 16 : if (mvc_highwater(sql))
4788 0 : return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
4789 :
4790 16 : if ((window_specification = frame_get_window_def(sql, ident, &pos)) == NULL)
4791 1 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: window '%s' not found", ident);
4792 :
4793 : /* avoid infinite lookups */
4794 15 : if (frame_check_var_visited(sql, pos))
4795 1 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: cyclic references to window '%s' found", ident);
4796 14 : frame_set_var_visited(sql, pos);
4797 :
4798 14 : if (window_specification->h->next->data.sym) {
4799 2 : if (*partition_by_clause)
4800 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: redefinition of PARTITION BY clause from window '%s'", ident);
4801 2 : *partition_by_clause = window_specification->h->next->data.sym;
4802 : }
4803 14 : if (window_specification->h->next->next->data.sym) {
4804 4 : if (*order_by_clause)
4805 1 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: redefinition of ORDER BY clause from window '%s'", ident);
4806 3 : *order_by_clause = window_specification->h->next->next->data.sym;
4807 : }
4808 13 : if (window_specification->h->next->next->next->data.sym) {
4809 0 : if (*frame_clause)
4810 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: redefinition of frame clause from window '%s'", ident);
4811 0 : *frame_clause = window_specification->h->next->next->next->data.sym;
4812 : }
4813 :
4814 13 : window_ident = window_specification->h->data.sval;
4815 13 : if (window_ident && !get_window_clauses(sql, window_ident, partition_by_clause, order_by_clause, frame_clause))
4816 : return NULL; /* the error was already set */
4817 :
4818 : return window_specification; /* return something to say there were no errors */
4819 : }
4820 :
4821 : /*
4822 : * select x, y, rank_op() over (partition by x order by y) as, ...
4823 : aggr_op(z) over (partition by y order by x) as, ...
4824 : * from table [x,y,z,w,v]
4825 : *
4826 : * project and order by over x,y / y,x
4827 : * a = project( table ) [ x, y, z, w, v ], [ x, y]
4828 : * b = project( table ) [ x, y, z, w, v ], [ y, x]
4829 : *
4830 : * project with order dependent operators, ie combined prev/current value
4831 : * aa = project (a) [ x, y, r = rank_op(diff(x) (marks a new partition), rediff(diff(x), y) (marks diff value with in partition)), z, w, v ]
4832 : * project(aa) [ aa.x, aa.y, aa.r ] -- only keep current output list
4833 : * bb = project (b) [ x, y, a = aggr_op(z, diff(y), rediff(diff(y), x)), z, w, v ]
4834 : * project(bb) [ bb.x, bb.y, bb.a ] -- only keep current output list
4835 : */
4836 : static sql_exp *
4837 12707 : rel_rankop(sql_query *query, sql_rel **rel, symbol *se, int f)
4838 : {
4839 12707 : mvc *sql = query->sql;
4840 12707 : node *n;
4841 12707 : dlist *l = se->data.lval, *window_specification = NULL;
4842 12707 : symbol *window_function = l->h->data.sym, *partition_by_clause = NULL, *order_by_clause = NULL, *frame_clause = NULL;
4843 12707 : char *aname = NULL, *sname = NULL, *window_ident = NULL;
4844 12707 : sql_subfunc *wf = NULL;
4845 12707 : sql_exp *in = NULL, *pe = NULL, *oe = NULL, *call = NULL, *start = NULL, *eend = NULL, *fstart = NULL, *fend = NULL, *ie = NULL;
4846 12707 : sql_rel *p;
4847 12707 : list *gbe = NULL, *obe = NULL, *args = NULL, *types = NULL, *fargs = NULL;
4848 12707 : dnode *dn = window_function->data.lval->h, *dargs = NULL;
4849 12707 : int distinct = 0, frame_type, pos, nf = f, nfargs = 0;
4850 12707 : bool is_nth_value, supports_frames = false, found = false;
4851 :
4852 12707 : frame_clear_visited_flag(sql); /* clear visited flags before iterating */
4853 :
4854 12707 : if (l->h->next->type == type_list) {
4855 12691 : window_specification = l->h->next->data.lval;
4856 16 : } else if (l->h->next->type == type_string) {
4857 16 : const char* window_alias = l->h->next->data.sval;
4858 16 : if ((window_specification = frame_get_window_def(sql, window_alias, &pos)) == NULL)
4859 1 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: window '%s' not found", window_alias);
4860 15 : frame_set_var_visited(sql, pos);
4861 : } else {
4862 0 : assert(0);
4863 : }
4864 :
4865 12706 : window_ident = window_specification->h->data.sval;
4866 12706 : partition_by_clause = window_specification->h->next->data.sym;
4867 12706 : order_by_clause = window_specification->h->next->next->data.sym;
4868 12706 : frame_clause = window_specification->h->next->next->next->data.sym;
4869 :
4870 12706 : if (window_ident && !get_window_clauses(sql, window_ident, &partition_by_clause, &order_by_clause, &frame_clause))
4871 : return NULL;
4872 :
4873 12703 : frame_type = frame_clause ? frame_clause->data.lval->h->next->next->data.i_val : FRAME_RANGE;
4874 12703 : aname = qname_schema_object(dn->data.lval);
4875 12703 : sname = qname_schema(dn->data.lval);
4876 :
4877 12703 : is_nth_value = !strcmp(aname, "nth_value");
4878 12703 : bool is_value = is_nth_value || !strcmp(aname, "first_value") || !strcmp(aname, "last_value");
4879 12703 : bool rank = false;
4880 12703 : if (strcmp(aname, "row_number") == 0 || strcmp(aname, "rank") == 0 || strcmp(aname, "dense_rank") == 0 ||
4881 2917 : strcmp(aname, "percent_rank") == 0 || strcmp(aname, "cume_dist") == 0 || strcmp(aname, "ntile") == 0 ||
4882 2813 : strcmp(aname, "lag") == 0 || strcmp(aname, "lead") == 0 || strcmp(aname, "fetch") == 0)
4883 9962 : rank = true;
4884 12703 : supports_frames = (!rank || is_value);
4885 :
4886 12703 : if (is_sql_update_set(f) || is_sql_psm(f) || is_sql_values(f) || is_sql_join(f) || is_sql_where(f) || is_sql_groupby(f) || is_sql_having(f) || is_psm_call(f) || is_sql_from(f)) {
4887 13 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
4888 13 : const char *clause = is_sql_update_set(f)||is_sql_psm(f)?"in SET, WHILE, IF, ELSE, CASE, WHEN, RETURN, ANALYZE clauses (use subquery)":is_sql_values(f)?"on an unique value":
4889 8 : is_sql_join(f)?"in JOIN conditions":is_sql_where(f)?"in WHERE clause":is_sql_groupby(f)?"in GROUP BY clause":
4890 4 : is_psm_call(f)?"in CALL":is_sql_from(f)?"in functions in FROM":"in HAVING clause";
4891 13 : return sql_error(sql, 02, SQLSTATE(42000) "%s: window function '%s' not allowed %s", toUpperCopy(uaname, aname), aname, clause);
4892 12690 : } else if (is_sql_aggr(f)) {
4893 2 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
4894 2 : return sql_error(sql, 02, SQLSTATE(42000) "%s: window functions not allowed inside aggregation functions", toUpperCopy(uaname, aname));
4895 12688 : } else if (is_sql_window(f)) {
4896 6 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
4897 6 : return sql_error(sql, 02, SQLSTATE(42000) "%s: window functions cannot be nested", toUpperCopy(uaname, aname));
4898 : }
4899 12682 : if (window_function->token == SQL_AGGR) {
4900 106 : dn->next->next->type = type_list;
4901 106 : dn->next->next->data.lval = dlist_append_symbol(sql->sa, dlist_create( sql->sa ), dn->next->next->data.sym); /* make a list */
4902 : }
4903 12682 : if (window_function->token == SQL_NOP)
4904 12576 : window_function->token = SQL_AGGR;
4905 12682 : if (window_function->token != SQL_RANK && window_function->token != SQL_AGGR) {
4906 0 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
4907 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: window function '%s' unknown", toUpperCopy(uaname, aname));
4908 : }
4909 :
4910 : /* window operations are only allowed in the projection */
4911 12682 : if (!is_sql_sel(f))
4912 0 : return sql_error(sql, 02, SQLSTATE(42000) "OVER: only possible within the selection");
4913 :
4914 12682 : p = *rel;
4915 : /* Partition By */
4916 12682 : if (partition_by_clause) {
4917 2321 : gbe = rel_partition_groupings(query, &p, partition_by_clause, NULL /* cannot use (selection) column references, as this result is a selection column */, nf | sql_window);
4918 2321 : if (!gbe)
4919 : return NULL;
4920 4662 : for (n = gbe->h ; n ; n = n->next) {
4921 2349 : sql_exp *en = n->data;
4922 :
4923 2349 : set_ascending(en);
4924 2349 : set_nulls_first(en);
4925 : }
4926 : }
4927 :
4928 : /* Order By */
4929 12674 : if (order_by_clause) {
4930 3029 : obe = rel_order_by(query, &p, order_by_clause, 0, sql_window);
4931 3029 : if (!obe)
4932 : return NULL;
4933 : }
4934 :
4935 12667 : fargs = sa_list(sql->sa);
4936 12667 : if (rank) { /* rank function call */
4937 9948 : dlist *dl = dn->next->next->data.lval;
4938 9948 : bool is_lag = !strcmp(aname, "lag"), is_lead = !strcmp(aname, "lead"),
4939 9948 : extra_input = !strcmp(aname, "ntile") || !strcmp(aname, "rank") || !strcmp(aname, "dense_rank") || !strcmp(aname, "row_number") || !strcmp(aname, "percent_rank") || !strcmp(aname, "cume_dist");
4940 :
4941 9948 : distinct = dn->next->data.i_val;
4942 9948 : if (extra_input) { /* pass an input column for analytic functions that don't require it */
4943 9877 : sql_subfunc *star = sql_bind_func(sql, "sys", "star", NULL, NULL, F_FUNC, true, true);
4944 9877 : in = exp_op(sql->sa, NULL, star);
4945 9877 : append(fargs, in);
4946 : }
4947 9948 : if (dl)
4948 324 : for (dargs = dl->h ; dargs ; dargs = dargs->next) {
4949 182 : exp_kind ek = {type_value, card_column, FALSE};
4950 182 : sql_subtype *empty = sql_bind_localtype("void"), *bte = sql_bind_localtype("bte");
4951 :
4952 182 : in = rel_value_exp2(query, &p, dargs->data.sym, f | sql_window | sql_farg, ek);
4953 182 : if (!in)
4954 0 : return NULL;
4955 182 : if (!exp_subtype(in)) { /* we also do not expect parameters here */
4956 0 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
4957 0 : return sql_error(sql, 02, SQLSTATE(42000) "%s: parameters not allowed as arguments to window functions", toUpperCopy(uaname, aname));
4958 : }
4959 182 : if (!exp_name(in))
4960 99 : exp_label(sql->sa, in, ++sql->label);
4961 :
4962 : /* corner case, if the argument is null convert it into something countable such as bte */
4963 182 : if (subtype_cmp(exp_subtype(in), empty) == 0)
4964 13 : in = exp_convert(sql, in, empty, bte);
4965 182 : if ((is_lag || is_lead) && nfargs == 2) { /* lag and lead 3rd arg must have same type as 1st arg */
4966 10 : sql_exp *first = (sql_exp*) fargs->h->data;
4967 10 : if (!(in = exp_check_type(sql, exp_subtype(first), p, in, type_equal)))
4968 : return NULL;
4969 : }
4970 172 : if (!in)
4971 : return NULL;
4972 :
4973 182 : append(fargs, in);
4974 182 : in = exp_ref_save(sql, in);
4975 182 : nfargs++;
4976 : }
4977 : } else { /* aggregation function call */
4978 2719 : distinct = dn->next->data.i_val;
4979 2719 : assert(dn->next->next->type == type_list);
4980 2719 : dlist *dl = dn->next->next->data.lval;
4981 9152 : for (dargs = dl?dl->h:NULL; dargs && dargs->data.sym ; dargs = dargs->next) {
4982 3722 : exp_kind ek = {type_value, card_column, FALSE};
4983 3722 : sql_subtype *empty = sql_bind_localtype("void"), *bte = sql_bind_localtype("bte");
4984 :
4985 3722 : in = rel_value_exp2(query, &p, dargs->data.sym, f | sql_window | sql_farg, ek);
4986 3722 : if (!in)
4987 8 : return NULL;
4988 3715 : if (!exp_subtype(in)) { /* we also do not expect parameters here */
4989 1 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
4990 1 : return sql_error(sql, 02, SQLSTATE(42000) "%s: parameters not allowed as arguments to window functions", toUpperCopy(uaname, aname));
4991 : }
4992 3714 : if (!exp_name(in))
4993 1994 : exp_label(sql->sa, in, ++sql->label);
4994 :
4995 : /* corner case, if the argument is null convert it into something countable such as bte */
4996 3714 : if (subtype_cmp(exp_subtype(in), empty) == 0)
4997 53 : in = exp_convert(sql, in, empty, bte);
4998 3714 : if (!in)
4999 : return NULL;
5000 :
5001 3714 : append(fargs, in);
5002 3714 : in = exp_ref_save(sql, in);
5003 3714 : nfargs++;
5004 :
5005 3714 : if (!strcmp(aname, "count"))
5006 86 : append(fargs, exp_atom_bool(sql->sa, 1)); /* ignore nills */
5007 : }
5008 :
5009 2711 : if (!nfargs) { /* count(*) */
5010 110 : if (window_function->token == SQL_AGGR && strcmp(aname, "count") != 0) {
5011 3 : char *uaname = SA_NEW_ARRAY(sql->ta, char, strlen(aname) + 1);
5012 3 : return sql_error(sql, 02, SQLSTATE(42000) "%s: unable to perform '%s(*)'", toUpperCopy(uaname, aname), aname);
5013 : }
5014 107 : sql_subfunc *star = sql_bind_func(sql, "sys", "star", NULL, NULL, F_FUNC, true, true);
5015 107 : in = exp_op(sql->sa, NULL, star);
5016 107 : append(fargs, in);
5017 107 : append(fargs, exp_atom_bool(sql->sa, 0)); /* don't ignore nills */
5018 : }
5019 : }
5020 :
5021 12656 : if (distinct)
5022 4 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: DISTINCT clause is not implemented for window functions");
5023 :
5024 : /* diff for partitions */
5025 12652 : if (gbe) {
5026 2304 : sql_subtype *bt = sql_bind_localtype("bit");
5027 :
5028 4643 : for( n = gbe->h; n; n = n->next) {
5029 2340 : sql_subfunc *df;
5030 2340 : sql_exp *e = n->data;
5031 :
5032 2340 : if (!exp_subtype(e))
5033 1 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: parameters not allowed at PARTITION BY clause from window functions");
5034 :
5035 2339 : e = exp_copy(sql, e);
5036 2339 : args = sa_list(sql->sa);
5037 2339 : if (pe) {
5038 36 : df = sql_bind_func(sql, "sys", "diff", bt, exp_subtype(e), F_ANALYTIC, true, true);
5039 36 : append(args, pe);
5040 : } else {
5041 2303 : df = sql_bind_func(sql, "sys", "diff", exp_subtype(e), NULL, F_ANALYTIC, true, true);
5042 : }
5043 2339 : if (!df)
5044 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: function 'diff' not found");
5045 2339 : append(args, e);
5046 2339 : pe = exp_op(sql->sa, args, df);
5047 : }
5048 : } else {
5049 10348 : pe = exp_atom_bool(sql->sa, 0);
5050 : }
5051 :
5052 : /* diff for orderby */
5053 12651 : if (obe) {
5054 3020 : sql_subtype *bt = sql_bind_localtype("bit");
5055 :
5056 6196 : for( n = obe->h; n; n = n->next) {
5057 3176 : sql_subfunc *df;
5058 3176 : sql_exp *e = n->data;
5059 :
5060 3176 : if (!exp_subtype(e))
5061 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: parameters not allowed at ORDER BY clause from window functions");
5062 :
5063 3176 : e = exp_copy(sql, e);
5064 3176 : args = sa_list(sql->sa);
5065 3176 : if (oe) {
5066 156 : df = sql_bind_func(sql, "sys", "diff", bt, exp_subtype(e), F_ANALYTIC, true, true);
5067 156 : append(args, oe);
5068 : } else {
5069 3020 : df = sql_bind_func(sql, "sys", "diff", exp_subtype(e), NULL, F_ANALYTIC, true, true);
5070 : }
5071 3176 : if (!df)
5072 0 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: function 'diff' not found");
5073 3176 : append(args, e);
5074 3176 : oe = exp_op(sql->sa, args, df);
5075 : }
5076 : } else {
5077 9631 : oe = exp_atom_bool(sql->sa, 0);
5078 : }
5079 :
5080 12651 : if (frame_clause || supports_frames) {
5081 2708 : if (frame_type == FRAME_RANGE)
5082 2397 : ie = obe ? (sql_exp*) obe->t->data : in;
5083 : else
5084 311 : ie = obe ? oe : in;
5085 : }
5086 12651 : assert(oe && pe);
5087 :
5088 12651 : types = exp_types(sql->sa, fargs);
5089 12651 : wf = bind_func_(sql, sname, aname, types, F_ANALYTIC, false, &found, false);
5090 12651 : if (wf && !list_empty(fargs) && !(fargs = check_arguments_and_find_largest_any_type(sql, NULL, fargs, wf, 0, false)))
5091 : wf = NULL;
5092 12647 : if (!wf) {
5093 4 : char *arg_list = nfargs ? nary_function_arg_types_2str(sql, types, nfargs) : NULL;
5094 8 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: %s window function %s%s%s'%s'(%s)",
5095 4 : found ? "insufficient privileges for" : "no such", sname ? "'":"", sname ? sname : "", sname ? "'.":"", aname, arg_list ? arg_list : "");
5096 : }
5097 :
5098 : /* Frame */
5099 12647 : if (frame_clause) {
5100 410 : dnode *d = frame_clause->data.lval->h;
5101 410 : symbol *wstart = d->data.sym, *wend = d->next->data.sym, *rstart = wstart->data.lval->h->data.sym,
5102 410 : *rend = wend->data.lval->h->data.sym;
5103 410 : int excl = d->next->next->next->data.i_val;
5104 410 : bool shortcut = false;
5105 :
5106 410 : if (!supports_frames)
5107 4 : return sql_error(sql, 02, SQLSTATE(42000) "OVER: frame extend only possible with aggregation and first_value, last_value and nth_value functions");
5108 406 : if (excl != EXCLUDE_NONE)
5109 0 : return sql_error(sql, 02, SQLSTATE(42000) "Only EXCLUDE NO OTHERS exclusion is currently implemented");
5110 406 : if (list_empty(obe) && frame_type == FRAME_GROUPS)
5111 2 : return sql_error(sql, 02, SQLSTATE(42000) "GROUPS frame requires an order by expression");
5112 404 : if (wstart->token == SQL_FOLLOWING && wend->token == SQL_PRECEDING)
5113 1 : return sql_error(sql, 02, SQLSTATE(42000) "FOLLOWING offset must come after PRECEDING offset");
5114 403 : if (wstart->token == SQL_CURRENT_ROW && wend->token == SQL_PRECEDING)
5115 1 : return sql_error(sql, 02, SQLSTATE(42000) "CURRENT ROW offset must come after PRECEDING offset");
5116 402 : if (wstart->token == SQL_FOLLOWING && wend->token == SQL_CURRENT_ROW)
5117 1 : return sql_error(sql, 02, SQLSTATE(42000) "FOLLOWING offset must come after CURRENT ROW offset");
5118 401 : if (wstart->token != SQL_CURRENT_ROW && wend->token != SQL_CURRENT_ROW && wstart->token == wend->token && frame_type != FRAME_ROWS)
5119 4 : return sql_error(sql, 02, SQLSTATE(42000) "Non-centered windows are only supported in row frames");
5120 367 : if (frame_type == FRAME_RANGE) {
5121 97 : if (((wstart->token == SQL_PRECEDING || wstart->token == SQL_FOLLOWING) && rstart->token != SQL_PRECEDING && rstart->token != SQL_CURRENT_ROW && rstart->token != SQL_FOLLOWING) ||
5122 59 : ((wend->token == SQL_PRECEDING || wend->token == SQL_FOLLOWING) && rend->token != SQL_PRECEDING && rend->token != SQL_CURRENT_ROW && rend->token != SQL_FOLLOWING)) {
5123 40 : if (list_empty(obe))
5124 2 : return sql_error(sql, 02, SQLSTATE(42000) "RANGE frame with PRECEDING/FOLLOWING offset requires an order by expression");
5125 38 : if (list_length(obe) > 1)
5126 0 : return sql_error(sql, 02, SQLSTATE(42000) "RANGE with offset PRECEDING/FOLLOWING requires exactly one ORDER BY column");
5127 : }
5128 : }
5129 :
5130 395 : if (list_empty(obe) && frame_type == FRAME_RANGE) { /* window functions are weird */
5131 : frame_type = FRAME_ALL;
5132 : shortcut = true;
5133 383 : } else if (!is_value && (rstart->token == SQL_PRECEDING || rstart->token == SQL_CURRENT_ROW || rstart->token == SQL_FOLLOWING) && rstart->type == type_int &&
5134 150 : (rend->token == SQL_PRECEDING || rend->token == SQL_CURRENT_ROW || rend->token == SQL_FOLLOWING) && rend->type == type_int) {
5135 : /* special cases, don't calculate bounds */
5136 146 : if (frame_type != FRAME_ROWS && rstart->data.i_val == UNBOUNDED_PRECEDING_BOUND && rend->data.i_val == CURRENT_ROW_BOUND) {
5137 : frame_type = FRAME_UNBOUNDED_TILL_CURRENT_ROW;
5138 : shortcut = true;
5139 21 : } else if (frame_type != FRAME_ROWS && rstart->data.i_val == CURRENT_ROW_BOUND && rend->data.i_val == UNBOUNDED_FOLLOWING_BOUND) {
5140 : frame_type = FRAME_CURRENT_ROW_TILL_UNBOUNDED;
5141 : shortcut = true;
5142 86 : } else if (rstart->data.i_val == UNBOUNDED_PRECEDING_BOUND && rend->data.i_val == UNBOUNDED_FOLLOWING_BOUND) {
5143 : frame_type = FRAME_ALL;
5144 : shortcut = true;
5145 76 : } else if (rstart->data.i_val == CURRENT_ROW_BOUND && rend->data.i_val == CURRENT_ROW_BOUND) {
5146 395 : frame_type = FRAME_CURRENT_ROW;
5147 395 : shortcut = true;
5148 : }
5149 : }
5150 395 : if (!shortcut) {
5151 302 : if (!(fstart = calculate_window_bound(query, p, wstart->token, rstart, ie, frame_type, f | sql_window)))
5152 : return NULL;
5153 299 : if (!(fend = calculate_window_bound(query, p, wend->token, rend, ie, frame_type, f | sql_window)))
5154 : return NULL;
5155 471 : if (!generate_window_bound_call(sql, &start, &eend, gbe ? pe : NULL, ie, fstart, fend, frame_type, excl,
5156 : wstart->token, wend->token))
5157 : return NULL;
5158 : }
5159 12237 : } else if (supports_frames) { /* for analytic functions with no frame clause, we use the standard default values */
5160 2296 : if (is_value) {
5161 108 : sql_subtype *bound_tp = sql_bind_localtype("lng"), *bt = (frame_type == FRAME_ROWS || frame_type == FRAME_GROUPS) ? bound_tp : exp_subtype(ie);
5162 108 : unsigned char sclass = bt->type->eclass;
5163 :
5164 136 : fstart = exp_atom(sql->sa, atom_max_value(sql->sa, EC_NUMERIC(sclass) ? bt : bound_tp));
5165 108 : fend = order_by_clause ? exp_atom(sql->sa, atom_zero_value(sql->sa, EC_NUMERIC(sclass) ? bt : bound_tp)) :
5166 23 : exp_atom(sql->sa, atom_max_value(sql->sa, EC_NUMERIC(sclass) ? bt : bound_tp));
5167 :
5168 157 : if (generate_window_bound_call(sql, &start, &eend, gbe ? pe : NULL, ie, fstart, fend, frame_type, EXCLUDE_NONE, SQL_PRECEDING, SQL_FOLLOWING) == NULL)
5169 : return NULL;
5170 : } else {
5171 2188 : frame_type = list_empty(obe) ? FRAME_ALL : FRAME_UNBOUNDED_TILL_CURRENT_ROW;
5172 : }
5173 : }
5174 :
5175 12629 : args = sa_list(sql->sa);
5176 26652 : for (node *n = fargs->h ; n ; n = n->next)
5177 14023 : list_append(args, n->data);
5178 12629 : list_append(args, pe);
5179 12629 : list_append(args, oe);
5180 12629 : if (supports_frames) {
5181 2688 : list_append(args, exp_atom_int(sql->sa, frame_type));
5182 2688 : list_append(args, start ? start : exp_atom_oid(sql->sa, 1));
5183 2688 : list_append(args, eend ? eend : exp_atom_oid(sql->sa, 1));
5184 : }
5185 12629 : call = exp_rank_op(sql->sa, list_empty(args) ? NULL : args, gbe, obe, wf);
5186 12629 : *rel = p;
5187 12629 : return call;
5188 : }
5189 :
5190 : sql_exp *
5191 5948947 : rel_value_exp2(sql_query *query, sql_rel **rel, symbol *se, int f, exp_kind ek)
5192 : {
5193 5948947 : mvc *sql = query->sql;
5194 5948947 : if (!se)
5195 : return NULL;
5196 :
5197 5948947 : if (mvc_highwater(sql))
5198 30 : return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
5199 :
5200 5949168 : if (rel && *rel && (*rel)->card == CARD_AGGR) { /* group by expression case, handle it before */
5201 136260 : sql_exp *exp = NULL;
5202 136260 : if (!is_sql_aggr(f) && !is_sql_window(f))
5203 135801 : exp = frame_get_groupby_expression(sql, se);
5204 136260 : if (sql->errstr[0] != '\0')
5205 : return NULL;
5206 136260 : if (exp) {
5207 80 : sql_exp *res = exp_ref(sql, exp);
5208 80 : res->card = (*rel)->card;
5209 80 : if (se->token == SQL_AGGR) {
5210 0 : dlist *l = se->data.lval;
5211 0 : int distinct = l->h->next->data.i_val;
5212 0 : if (distinct)
5213 0 : set_distinct(res);
5214 : }
5215 80 : if (!query_has_outer(query) && is_groupby((*rel)->op))
5216 76 : res = rel_groupby_add_aggr(sql, *rel, res);
5217 80 : return res;
5218 : }
5219 : }
5220 :
5221 5949088 : switch (se->token) {
5222 554470 : case SQL_NOP:
5223 554470 : return rel_nop(query, rel, se, f, ek);
5224 19456 : case SQL_AGGR:
5225 19456 : return rel_aggr(query, rel, se, f);
5226 12707 : case SQL_WINDOW:
5227 12707 : return rel_rankop(query, rel, se, f);
5228 2365048 : case SQL_IDENT:
5229 : case SQL_COLUMN:
5230 2365048 : return rel_column_ref(query, rel, se, f );
5231 3019 : case SQL_NAME: {
5232 3019 : dlist *l = se->data.lval;
5233 3019 : const char *sname = qname_schema(l);
5234 3019 : const char *vname = qname_schema_object(l);
5235 3019 : return rel_exp_variable_on_scope(sql, sname, vname);
5236 : }
5237 50914 : case SQL_VALUES:
5238 : case SQL_WITH:
5239 : case SQL_SELECT: {
5240 50914 : sql_rel *r = NULL;
5241 :
5242 50914 : if (is_psm_call(f) || is_sql_merge(f))
5243 8 : return sql_error(sql, 02, SQLSTATE(42000) "%s: subqueries not supported inside %s", is_psm_call(f) ? "CALL" : "MERGE", is_psm_call(f) ? "CALL statements" : "MERGE conditions");
5244 50910 : if (rel && *rel)
5245 36797 : query_push_outer(query, *rel, f);
5246 50910 : if (se->token == SQL_WITH) {
5247 36 : r = rel_with_query(query, se);
5248 50874 : } else if (se->token == SQL_VALUES) {
5249 238 : r = rel_values(query, se, NULL);
5250 : } else {
5251 50636 : assert(se->token == SQL_SELECT);
5252 50636 : exp_kind nek = ek;
5253 50636 : nek.aggr = is_sql_aggr(f);
5254 50636 : if (is_sql_no_subquery(f))
5255 3 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: subquery not allowed");
5256 :
5257 50633 : r = rel_subquery(query, se, nek);
5258 50633 : if (r)
5259 50532 : exps_label(sql, r->exps);
5260 : }
5261 50907 : if (rel && *rel) {
5262 36794 : *rel = query_pop_outer(query);
5263 36794 : if (is_sql_join(f) && is_groupby((*rel)->op)) {
5264 0 : return sql_error(sql, 05, SQLSTATE(42000) "SELECT: aggregate functions not allowed in JOIN conditions");
5265 36794 : } else if (is_sql_where(f) && is_groupby((*rel)->op)) {
5266 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: aggregate functions not allowed in WHERE clause");
5267 36794 : } else if ((is_sql_update_set(f) || is_sql_psm(f)) && is_groupby((*rel)->op)) {
5268 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: aggregate functions not allowed in SET, WHILE, IF, ELSE, CASE, WHEN, RETURN, ANALYZE clauses");
5269 : }
5270 : }
5271 50907 : if (!r)
5272 : return NULL;
5273 50803 : if (ek.type == type_value && ek.card <= card_set && is_project(r->op) && list_length(r->exps) > 1)
5274 17 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: subquery must return only one column");
5275 50786 : if (ek.type == type_relation && is_project(r->op) && list_length(r->exps) != ek.type)
5276 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: subquery has too %s columns", list_length(r->exps) < ek.type ? "few" : "many");
5277 50786 : if (ek.type == type_value && list_length(r->exps) == 1 && !is_sql_psm(f)) /* for now don't rename multi attribute results */
5278 38527 : r = rel_zero_or_one(sql, r, ek);
5279 50786 : return exp_rel(sql, r);
5280 : }
5281 215 : case SQL_TABLE: {
5282 : /* turn a subquery into a tabular result */
5283 215 : *rel = rel_selects(query, se->data.sym);
5284 215 : if (*rel)
5285 213 : return lastexp(*rel);
5286 : return NULL;
5287 : }
5288 1612 : case SQL_PARAMETER: {
5289 1612 : assert(se->type == type_int);
5290 1612 : sql_arg *a = sql_bind_paramnr(sql, se->data.i_val);
5291 1612 : if (sql->emode != m_prepare) {
5292 1 : if (a && a->name && a->name[0])
5293 1 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: named placeholder ('%s') but named values list is missing", a->name);
5294 : else
5295 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: parameters ('?') not allowed in normal queries, use PREPARE");
5296 : }
5297 1611 : return exp_atom_ref(sql->sa, se->data.i_val, a?&a->type:NULL);
5298 : }
5299 107840 : case SQL_NULL:
5300 107840 : return exp_null(sql->sa, sql_bind_localtype("void"));
5301 1584 : case SQL_NEXT:
5302 1584 : return rel_next_value_for(sql, se);
5303 172563 : case SQL_CAST:
5304 172563 : return rel_cast(query, rel, se, f);
5305 105295 : case SQL_CASE:
5306 : case SQL_COALESCE:
5307 : case SQL_NULLIF:
5308 105295 : return rel_case_exp(query, rel, se, f);
5309 0 : case SQL_RANK:
5310 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: window function %s requires an OVER clause", qname_schema_object(se->data.lval->h->data.lval));
5311 25 : case SQL_XMLELEMENT:
5312 : case SQL_XMLFOREST:
5313 : case SQL_XMLCOMMENT:
5314 : case SQL_XMLATTRIBUTE:
5315 : case SQL_XMLCONCAT:
5316 : case SQL_XMLDOCUMENT:
5317 : case SQL_XMLPI:
5318 : case SQL_XMLTEXT:
5319 25 : return rel_xml(query, rel, se, f, ek);
5320 2554340 : default:
5321 2554340 : return rel_logical_value_exp(query, rel, se, f, ek);
5322 : }
5323 : }
5324 :
5325 : static int exps_has_rank(list *exps);
5326 :
5327 : static int
5328 : exp_has_rank(sql_exp *e)
5329 : {
5330 : switch(e->type) {
5331 : case e_convert:
5332 : return exp_has_rank(e->l);
5333 : case e_func:
5334 : if (e->r)
5335 : return 1;
5336 : /* fall through */
5337 : case e_aggr:
5338 : return exps_has_rank(e->l);
5339 : case e_cmp:
5340 : if (e->flag == cmp_or || e->flag == cmp_filter)
5341 : return exps_has_rank(e->l) || exps_has_rank(e->r);
5342 : if (e->flag == cmp_in || e->flag == cmp_notin)
5343 : return exp_has_rank(e->l) || exps_has_rank(e->r);
5344 : return exp_has_rank(e->l) || exp_has_rank(e->r) || (e->f && exp_has_rank(e->f));
5345 : default:
5346 : return 0;
5347 : }
5348 : }
5349 :
5350 : /* TODO create exps_has (list, fptr ) */
5351 : static int
5352 : exps_has_rank(list *exps)
5353 : {
5354 : if (!exps || list_empty(exps))
5355 : return 0;
5356 : for(node *n = exps->h; n; n=n->next){
5357 : sql_exp *e = n->data;
5358 :
5359 : if (exp_has_rank(e))
5360 : return 1;
5361 : }
5362 : return 0;
5363 : }
5364 :
5365 : sql_exp *
5366 4527525 : rel_value_exp(sql_query *query, sql_rel **rel, symbol *se, int f, exp_kind ek)
5367 : {
5368 4527525 : if (!se)
5369 : return NULL;
5370 :
5371 4527525 : if (mvc_highwater(query->sql))
5372 0 : return sql_error(query->sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
5373 :
5374 4527588 : sql_exp *e = rel_value_exp2(query, rel, se, f, ek);
5375 4527617 : if (e && (se->token == SQL_SELECT || se->token == SQL_TABLE) && !exp_is_rel(e)) {
5376 0 : assert(*rel);
5377 0 : return rel_lastexp(query->sql, *rel);
5378 : }
5379 : return e;
5380 : }
5381 :
5382 : static sql_exp *
5383 1339590 : column_exp(sql_query *query, sql_rel **rel, symbol *column_e, int f)
5384 : {
5385 1339590 : dlist *l = column_e->data.lval;
5386 1339590 : exp_kind ek = {type_value, card_column, FALSE};
5387 1339590 : sql_exp *ve;
5388 :
5389 1339590 : if (f == sql_sel && rel && *rel && (*rel)->card < CARD_AGGR)
5390 82660 : ek.card = card_value;
5391 1339590 : ve = rel_value_exp(query, rel, l->h->data.sym, f, ek);
5392 1339681 : if (!ve)
5393 : return NULL;
5394 : /* AS name */
5395 1324001 : if (ve && l->h->next->data.sval)
5396 507184 : exp_setname(query->sql, ve, NULL, l->h->next->data.sval);
5397 : return ve;
5398 : }
5399 :
5400 : static int
5401 843498 : exp_is_not_intern(sql_exp *e)
5402 : {
5403 843498 : return is_intern(e)?-1:0;
5404 : }
5405 :
5406 : static void
5407 129319 : rel_remove_internal_exp(sql_rel *rel)
5408 : {
5409 129319 : if (rel->exps) {
5410 129319 : list *n_exps = list_select(rel->exps, rel, (fcmp)&exp_is_not_intern, (fdup)NULL);
5411 :
5412 129319 : rel->exps = n_exps;
5413 : }
5414 129319 : }
5415 :
5416 : static inline int
5417 39 : exp_key(sql_exp *e)
5418 : {
5419 39 : if (e->alias.name)
5420 39 : return hash_key(e->alias.name);
5421 : return 0;
5422 : }
5423 :
5424 : static list *
5425 17 : group_merge_exps(mvc *sql, list *gexps, list *exps)
5426 : {
5427 17 : int nexps = list_length(gexps) + list_length(exps);
5428 :
5429 17 : sql_hash *ht = hash_new(sql->ta, nexps, (fkeyvalue)&exp_key);
5430 :
5431 27 : for (node *n = gexps->h; n ; n = n->next) { /* first add grouping expressions */
5432 10 : sql_exp *e = n->data;
5433 10 : int key = ht->key(e);
5434 :
5435 10 : hash_add(ht, key, e);
5436 : }
5437 :
5438 46 : for (node *n = exps->h; n ; n = n->next) { /* then test if the new grouping expressions are already there */
5439 29 : sql_exp *e = n->data;
5440 29 : int key = ht->key(e);
5441 29 : sql_hash_e *he = ht->buckets[key&(ht->size-1)];
5442 29 : bool duplicates = false;
5443 :
5444 37 : for (; he && !duplicates; he = he->chain) {
5445 8 : sql_exp *f = he->value;
5446 :
5447 8 : if (!exp_equal(e, f))
5448 4 : duplicates = true;
5449 : }
5450 29 : hash_add(ht, key, e);
5451 29 : if (!duplicates) {
5452 25 : list_append(gexps, e);
5453 25 : n->data = exp_ref(sql, e);
5454 : }
5455 : }
5456 17 : return gexps;
5457 : }
5458 :
5459 : static list *
5460 58776 : rel_table_exp(sql_query *query, sql_rel **rel, symbol *column_e, bool single_exp )
5461 : {
5462 58776 : mvc *sql = query->sql;
5463 58776 : if (column_e->token == SQL_TABLE && column_e->data.lval->h->type == type_symbol) {
5464 0 : sql_rel *r;
5465 :
5466 0 : if (!is_project((*rel)->op))
5467 : return NULL;
5468 0 : r = rel_named_table_function(query, (*rel)->l, column_e, 0, NULL);
5469 0 : if (!r)
5470 : return NULL;
5471 0 : *rel = r;
5472 0 : return sa_list(sql->sa);
5473 : }
5474 58776 : char *tname = NULL;
5475 58776 : if (column_e->token == SQL_TABLE) {
5476 43107 : tname = column_e->data.lval->h->data.sval;
5477 15669 : } else if (column_e->token == SQL_COLUMN && column_e->data.lval->h->type == type_symbol) {
5478 15669 : symbol *sym = column_e->data.lval->h->data.sym;
5479 15669 : if (sym->token == SQL_COLUMN)
5480 14675 : tname = sym->data.lval->h->data.sval;
5481 : else
5482 : return NULL;
5483 : } else {
5484 : return NULL;
5485 : }
5486 :
5487 :
5488 57782 : list *exps = NULL;
5489 57782 : sql_rel *project = *rel, *groupby = NULL;
5490 :
5491 : /* if there's a group by relation in the tree, skip it for the '*' case and use the underlying projection */
5492 57782 : if (project) {
5493 67124 : while (is_groupby(project->op) || is_select(project->op)) {
5494 9342 : if (is_groupby(project->op))
5495 37 : groupby = project;
5496 9342 : if (project->l)
5497 9342 : project = project->l;
5498 : }
5499 : assert(project);
5500 : }
5501 :
5502 57782 : if (project->op == op_project && project->l && project == *rel && !tname && !rel_is_ref(project) && !need_distinct(project) && single_exp) {
5503 498 : sql_rel *l = project->l;
5504 498 : if (!l || !is_project(l->op) || list_length(project->exps) == list_length(l->exps)) {
5505 491 : rel_remove_internal_exp(*rel);
5506 491 : exps = project->exps;
5507 491 : *rel = project->l;
5508 : }
5509 : }
5510 57782 : if ((exps || (exps = rel_table_projections(sql, project, tname, 0)) != NULL) && !list_empty(exps)) {
5511 57679 : if (!(exps = check_distinct_exp_names(sql, exps)))
5512 0 : return sql_error(sql, 02, SQLSTATE(42000) "Duplicate column names in table%s%s%s projection list", tname ? " '" : "", tname ? tname : "", tname ? "'" : "");
5513 57677 : if (groupby) {
5514 17 : groupby->exps = group_merge_exps(sql, groupby->exps, exps);
5515 40 : for (node *n = groupby->exps->h ; n ; n = n->next) {
5516 30 : sql_exp *e = n->data;
5517 :
5518 30 : if (e->card > groupby->card) {
5519 7 : if (exp_name(e) && !has_label(e))
5520 7 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results without an aggregate function", exp_name(e));
5521 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
5522 : }
5523 : }
5524 : }
5525 57670 : return exps;
5526 : }
5527 105 : if (!tname)
5528 2 : return sql_error(sql, 02, SQLSTATE(42000) "Table expression without table name");
5529 103 : return sql_error(sql, 02, SQLSTATE(42000) "Column expression Table '%s' unknown", tname);
5530 : //return NULL;
5531 : }
5532 :
5533 : sql_exp *
5534 1382698 : rel_column_exp(sql_query *query, sql_rel **rel, symbol *column_e, int f)
5535 : {
5536 1382698 : if (column_e->token == SQL_COLUMN || column_e->token == SQL_IDENT)
5537 1339594 : return column_exp(query, rel, column_e, f);
5538 : return NULL;
5539 : }
5540 :
5541 : static sql_rel*
5542 374883 : rel_where_groupby_nodes(sql_query *query, sql_rel *rel, SelectNode *sn, int *group_totals)
5543 : {
5544 374883 : mvc *sql = query->sql;
5545 :
5546 374883 : if (sn->where) {
5547 146695 : rel = rel_logical_exp(query, rel, sn->where, sql_where);
5548 146695 : if (!rel) {
5549 76 : if (sql->errstr[0] == 0)
5550 0 : return sql_error(sql, 02, SQLSTATE(42000) "Subquery result missing");
5551 : return NULL;
5552 : }
5553 : }
5554 374807 : query_processed(query);
5555 :
5556 374803 : if (rel && sn->groupby) {
5557 13409 : list *gbe = NULL, *sets = NULL;
5558 13409 : int all = 0;
5559 13409 : if (sn->groupby->data.lval == NULL) { /* ALL */
5560 : all = 1;
5561 : } else {
5562 49517 : for (dnode *o = sn->groupby->data.lval->h; o ; o = o->next) {
5563 36235 : symbol *grouping = o->data.sym;
5564 36235 : if (grouping->token == SQL_ROLLUP || grouping->token == SQL_CUBE || grouping->token == SQL_GROUPING_SETS) {
5565 119 : *group_totals |= sql_group_totals;
5566 119 : break;
5567 : }
5568 : }
5569 13401 : gbe = rel_groupings(query, &rel, sn->groupby, sn->selection, sql_sel | sql_groupby | *group_totals, false, &sets);
5570 13401 : if (!gbe)
5571 20 : return NULL;
5572 : }
5573 13389 : rel = rel_groupby(sql, rel, gbe);
5574 13389 : if (rel && all)
5575 8 : rel->flag = 2;
5576 13389 : if (sets && list_length(sets) > 1) { /* if there is only one combination, there is no reason to generate unions */
5577 114 : prop *p = prop_create(sql->sa, PROP_GROUPINGS, rel->p);
5578 114 : p->value.pval = sets;
5579 114 : rel->p = p;
5580 : }
5581 : }
5582 :
5583 374783 : if (rel && sn->having) {
5584 : /* having implies group by, ie if not supplied do a group by */
5585 1766 : if (rel->op != op_groupby)
5586 128 : rel = rel_groupby(sql, rel, NULL);
5587 : }
5588 374783 : query_processed(query);
5589 374814 : return rel;
5590 : }
5591 :
5592 : static sql_rel*
5593 373670 : rel_having_limits_nodes(sql_query *query, sql_rel *rel, SelectNode *sn, exp_kind ek, int group_totals)
5594 : {
5595 373670 : mvc *sql = query->sql;
5596 373670 : sql_rel *inner = NULL;
5597 373670 : int single_value = 1;
5598 :
5599 373670 : if (is_project(rel->op) && rel->l) {
5600 373670 : inner = rel->l;
5601 373670 : single_value = 0;
5602 : }
5603 :
5604 373670 : if (sn->having) {
5605 1759 : if (inner && is_groupby(inner->op))
5606 1759 : set_processed(inner);
5607 1759 : if (!(inner = rel_logical_exp(query, inner, sn->having, sql_having | group_totals)))
5608 : return NULL;
5609 1718 : if (inner->exps && exps_card(inner->exps) > CARD_AGGR)
5610 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: cannot compare sets with values, probably an aggregate function missing");
5611 1718 : if (!single_value)
5612 1718 : rel->l = inner;
5613 : }
5614 :
5615 373629 : if (rel && sn->distinct)
5616 1031 : rel = rel_distinct(rel);
5617 :
5618 373629 : if (rel && sn->orderby) {
5619 37063 : list *obe = NULL;
5620 37063 : sql_rel *sel = NULL, *l = rel->l;
5621 :
5622 : /* project( select ) */
5623 37063 : if (sn->having && is_select(l->op)) {
5624 52 : sel = l;
5625 52 : rel->l = l->l;
5626 : }
5627 37063 : rel = rel_orderby(sql, rel);
5628 37063 : set_processed(rel);
5629 37063 : obe = rel_order_by(query, &rel, sn->orderby, sn->distinct, sql_orderby | group_totals);
5630 37063 : if (!obe)
5631 : return NULL;
5632 37022 : rel->r = obe;
5633 37022 : if (sel) {
5634 51 : sql_rel *o = rel, *p = o->l;
5635 51 : p->l = sel;
5636 : }
5637 : }
5638 373588 : if (!rel)
5639 : return NULL;
5640 :
5641 373588 : if (sn->limit || sn->offset) {
5642 16719 : sql_subtype *lng = sql_bind_localtype("lng");
5643 16731 : list *exps = new_exp_list(sql->sa);
5644 :
5645 16729 : if (sn->limit) {
5646 16703 : sql_exp *l = rel_value_exp(query, NULL, sn->limit, 0, ek);
5647 :
5648 16702 : if (!l || !(l=exp_check_type(sql, lng, NULL, l, type_equal)))
5649 0 : return NULL;
5650 16705 : if ((ek.card != card_relation && sn->limit) &&
5651 : (ek.card == card_value && sn->limit)) {
5652 12 : sql_subfunc *zero_or_one = sql_bind_func(sql, "sys", "zero_or_one", exp_subtype(l), NULL, F_AGGR, true, true);
5653 12 : l = exp_aggr1(sql->sa, l, zero_or_one, 0, 0, CARD_ATOM, has_nil(l));
5654 : }
5655 16705 : list_append(exps, l);
5656 : } else
5657 26 : list_append(exps, exp_atom(sql->sa, atom_general(sql->sa, lng, NULL, 0)));
5658 16729 : if (sn->offset) {
5659 86 : sql_exp *o = rel_value_exp( query, NULL, sn->offset, 0, ek);
5660 86 : if (!o || !(o=exp_check_type(sql, lng, NULL, o, type_equal)))
5661 0 : return NULL;
5662 86 : list_append(exps, o);
5663 : }
5664 16729 : rel = rel_topn(sql->sa, rel, exps);
5665 : }
5666 :
5667 373596 : if (sn->sample || sn->seed) {
5668 40 : list *exps = new_exp_list(sql->sa);
5669 :
5670 23 : if (sn->sample) {
5671 23 : sql_exp *s = rel_value_exp(query, NULL, sn->sample, 0, ek);
5672 23 : if (!s)
5673 : return NULL;
5674 23 : if (!exp_subtype(s) && rel_set_type_param(sql, sql_bind_localtype("lng"), NULL, s, 0) < 0)
5675 : return NULL;
5676 23 : list_append(exps, s);
5677 : } else {
5678 0 : assert(sn->seed);
5679 0 : return sql_error(sql, 02, SQLSTATE(42000) "SEED: cannot have SEED without SAMPLE");
5680 : }
5681 23 : if (sn->seed) {
5682 12 : sql_exp *e = rel_value_exp(query, NULL, sn->seed, 0, ek);
5683 12 : if (!e || !(e=exp_check_type(sql, sql_bind_localtype("int"), NULL, e, type_equal)))
5684 0 : return NULL;
5685 12 : list_append(exps, e);
5686 : }
5687 23 : rel = rel_sample(sql->sa, rel, exps);
5688 : }
5689 :
5690 : /* after parsing the current query, set the group by relation as processed */
5691 373579 : if (!sn->having && inner && is_groupby(inner->op))
5692 32682 : set_processed(inner);
5693 373579 : if (rel)
5694 373579 : set_processed(rel);
5695 : return rel;
5696 : }
5697 :
5698 : static sql_rel *
5699 62 : join_on_column_name(sql_query *query, sql_rel *rel, sql_rel *t1, sql_rel *t2, int op, int l_nil, int r_nil)
5700 : {
5701 62 : mvc *sql = query->sql;
5702 62 : int found = 0, full = (op == op_full), right = (op == op_right);
5703 62 : list *exps = rel_projections(sql, t1, NULL, 1, 0);
5704 62 : list *r_exps = rel_projections(sql, t2, NULL, 1, 0);
5705 62 : list *outexps = new_exp_list(sql->sa);
5706 :
5707 62 : if (!exps || !r_exps)
5708 : return NULL;
5709 244 : for (node *n = exps->h; n; n = n->next) {
5710 185 : sql_exp *le = n->data;
5711 185 : int multi = 0;
5712 185 : const char *rname = exp_relname(le), *name = exp_name(le);
5713 185 : sql_exp *re = exps_bind_column(r_exps, name, NULL, &multi, 0);
5714 :
5715 185 : if (re) {
5716 140 : if (multi)
5717 3 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "NATURAL JOIN: common column name '%s' appears more than once in right table", rname);
5718 138 : multi = 0;
5719 138 : le = exps_bind_column(exps, name, NULL, &multi, 0);
5720 138 : if (multi)
5721 0 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "NATURAL JOIN: common column name '%s' appears more than once in left table", rname);
5722 :
5723 138 : found = 1;
5724 138 : if (!(rel = rel_compare_exp(query, rel, le, re, "=", TRUE, 0, 0, 0, 0)))
5725 : return NULL;
5726 137 : list_remove_data(r_exps, NULL, re);
5727 137 : if (full) {
5728 12 : sql_exp *cond = rel_unop_(sql, rel, le, "sys", "isnull", card_value);
5729 12 : if (!cond)
5730 : return NULL;
5731 12 : set_has_no_nil(cond);
5732 12 : if (rel_convert_types(sql, NULL, NULL, &le, &re, 1, type_equal_no_any) < 0)
5733 : return NULL;
5734 12 : if (!(le = rel_nop_(sql, rel, cond, re, le, NULL, "sys", "ifthenelse", card_value)))
5735 : return NULL;
5736 125 : } else if (right) {
5737 3 : le = re;
5738 : }
5739 137 : exp_setname(sql, le, rname, name);
5740 137 : set_not_unique(le);
5741 137 : append(outexps, le);
5742 : } else {
5743 45 : if (l_nil)
5744 5 : set_has_nil(le);
5745 45 : set_not_unique(le);
5746 45 : append(outexps, le);
5747 : }
5748 : }
5749 59 : if (!found)
5750 2 : return sql_error(sql, 02, SQLSTATE(42000) "JOIN: no columns of tables '%s' and '%s' match", rel_name(t1)?rel_name(t1):"", rel_name(t2)?rel_name(t2):"");
5751 90 : for (node *n = r_exps->h; n; n = n->next) {
5752 33 : sql_exp *re = n->data;
5753 33 : if (r_nil)
5754 3 : set_has_nil(re);
5755 33 : set_not_unique(re);
5756 33 : append(outexps, re);
5757 : }
5758 57 : rel = rel_project(sql->sa, rel, outexps);
5759 57 : return rel;
5760 : }
5761 :
5762 : static sql_rel *
5763 374907 : rel_select_exp(sql_query *query, sql_rel *rel, SelectNode *sn, exp_kind ek)
5764 : {
5765 374907 : mvc *sql = query->sql;
5766 374907 : sql_rel *inner = NULL;
5767 374907 : int group_totals = 0;
5768 374907 : list *pexps = NULL;
5769 :
5770 374907 : assert(sn->s.token == SQL_SELECT);
5771 374907 : if (!sn->selection)
5772 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: the selection or from part is missing");
5773 :
5774 374907 : if (!rel)
5775 72659 : rel = rel_project_exp(sql, exp_atom_bool(sql->sa, 1));
5776 374953 : rel = rel_where_groupby_nodes(query, rel, sn, &group_totals);
5777 374924 : if (sql->session->status) /* rel might be NULL as input, so we have to check for the session status for errors */
5778 : return NULL;
5779 :
5780 374825 : inner = rel;
5781 374825 : pexps = sa_list(sql->sa);
5782 1756480 : for (dnode *n = sn->selection->h; n; n = n->next) {
5783 : /* Here we could get real column expressions
5784 : * (including single atoms) but also table results.
5785 : * Therefore we try both rel_column_exp
5786 : * and rel_table_exp.
5787 : */
5788 1382766 : list *te = NULL;
5789 2765457 : sql_exp *ce = rel_column_exp(query, &inner, n->data.sym, sql_sel | group_totals | (ek.aggr?sql_aggr:0));
5790 :
5791 1382743 : if (ce) {
5792 1323966 : if (inner && inner->flag && is_groupby(inner->op)) {
5793 62 : int found = 0;
5794 62 : list *gbe = inner->r;
5795 : /* flag == 2 just add to group by/ aggrs and ref-to pexps*/
5796 : /* flag == 1 find group by exp referencing this column nr */
5797 62 : if (inner->flag == 2) {
5798 25 : if (ce->card > CARD_AGGR) {
5799 9 : if (!gbe)
5800 8 : inner->r = gbe = sa_list(sql->sa);
5801 9 : append(gbe, ce);
5802 9 : ce = exp_ref(sql, ce);
5803 9 : ce->card = CARD_AGGR;
5804 9 : list_append(inner->exps, ce);
5805 9 : ce = exp_ref(sql, ce);
5806 9 : found = 1;
5807 : }
5808 : } else {
5809 81 : for(node *n = gbe->h; n && !found; n = n->next) {
5810 44 : sql_exp *e = n->data;
5811 44 : if (is_atom(e->type) && !e->alias.name) {
5812 29 : atom *a = e->l;
5813 29 : int nr = (int)atom_get_int(a);
5814 29 : if (nr == (list_length(pexps) + 1)) {
5815 27 : n->data = ce;
5816 27 : ce = exp_ref(sql, ce);
5817 27 : ce->card = CARD_AGGR;
5818 27 : list_append(inner->exps, ce);
5819 27 : ce = exp_ref(sql, ce);
5820 27 : found = 1;
5821 : }
5822 : }
5823 : }
5824 : }
5825 : }
5826 1323966 : pexps = append(pexps, ce);
5827 1323971 : rel = inner;
5828 1323971 : continue;
5829 : } else {
5830 63338 : te = rel_table_exp(query, &rel, n->data.sym, !list_length(pexps) && !n->next);
5831 : }
5832 58776 : if (!ce && !te) {
5833 1106 : if (sql->errstr[0])
5834 : return NULL;
5835 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: subquery result missing");
5836 : }
5837 : /* here we should merge the column expressions we
5838 : * obtained so far with the table expression, ie
5839 : * t1.* or a subquery.
5840 : */
5841 57670 : pexps = list_merge(pexps, te, (fdup)NULL);
5842 : }
5843 373714 : if (rel && is_groupby(rel->op) && rel->flag) {
5844 34 : list *gbe = rel->r;
5845 34 : if (!list_empty(gbe)) {
5846 68 : for (node *n=gbe->h; n; n = n->next) {
5847 37 : sql_exp *e = n->data;
5848 37 : if (rel->flag == 1 && is_atom(e->type) && !e->alias.name) {
5849 1 : atom *a = e->l;
5850 1 : int nr = (int)atom_get_int(a);
5851 1 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: GROUP BY position %d is not in select list", nr);
5852 : }
5853 36 : if (exp_has_aggr(rel, e))
5854 2 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: aggregate functions are not allowed in GROUP BY");
5855 : }
5856 : }
5857 : }
5858 373711 : if (rel && is_groupby(rel->op) && (!sn->groupby || rel->flag) && !is_processed(rel)) {
5859 43235 : for (node *n=pexps->h; n; n = n->next) {
5860 22081 : sql_exp *ce = n->data;
5861 22081 : if (rel->card < ce->card && !exp_is_aggr(rel, ce)) {
5862 0 : if (exp_name(ce) && !has_label(ce))
5863 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column '%s' in query results without an aggregate function", exp_name(ce));
5864 0 : return sql_error(sql, ERR_GROUPBY, SQLSTATE(42000) "SELECT: cannot use non GROUP BY column in query results without an aggregate function");
5865 : }
5866 : }
5867 21154 : set_processed(rel);
5868 : }
5869 373711 : rel = rel_project(sql->sa, rel, pexps);
5870 :
5871 373721 : rel = rel_having_limits_nodes(query, rel, sn, ek, group_totals);
5872 373721 : return rel;
5873 : }
5874 :
5875 : static sql_rel*
5876 128780 : rel_unique_names(mvc *sql, sql_rel *rel)
5877 : {
5878 128780 : list *l;
5879 :
5880 128780 : if (!is_project(rel->op))
5881 : return rel;
5882 128780 : l = sa_list(sql->sa);
5883 969710 : for (node *n = rel->exps->h; n; n = n->next) {
5884 840930 : sql_exp *e = n->data;
5885 840930 : const char *name = exp_name(e);
5886 :
5887 : /* If there are two identical expression names, there will be ambiguity */
5888 840930 : if (!name || exps_bind_column(l, name, NULL, NULL, 0))
5889 58509 : exp_label(sql->sa, e, ++sql->label);
5890 840930 : append(l,e);
5891 : }
5892 128780 : rel->exps = l;
5893 128780 : return rel;
5894 : }
5895 :
5896 : static sql_rel *
5897 375228 : rel_query(sql_query *query, symbol *sq, exp_kind ek)
5898 : {
5899 375228 : mvc *sql = query->sql;
5900 375228 : sql_rel *res = NULL;
5901 375228 : SelectNode *sn = NULL;
5902 :
5903 375228 : if (sq->token != SQL_SELECT)
5904 22 : return table_ref(query, sq, 0, NULL);
5905 :
5906 : /* select ... into is currently not handled here ! */
5907 375206 : sn = (SelectNode *) sq;
5908 375206 : if (sn->into)
5909 : return NULL;
5910 :
5911 375206 : if (ek.card != card_relation && sn->orderby)
5912 2 : return sql_error(sql, 01, SQLSTATE(42000) "SELECT: ORDER BY only allowed on outermost SELECT");
5913 :
5914 375204 : if (sn->window) {
5915 20 : dlist *wl = sn->window->data.lval;
5916 51 : for (dnode *n = wl->h; n ; n = n->next) {
5917 32 : dlist *wd = n->data.sym->data.lval;
5918 32 : const char *name = wd->h->data.sval;
5919 32 : dlist *wdef = wd->h->next->data.lval;
5920 32 : if (frame_get_window_def(sql, name, NULL)) {
5921 1 : return sql_error(sql, 01, SQLSTATE(42000) "SELECT: Redefinition of window '%s'", name);
5922 31 : } else if (!frame_push_window_def(sql, name, wdef)) {
5923 0 : return sql_error(sql, 02, SQLSTATE(HY013) MAL_MALLOC_FAIL);
5924 : }
5925 : }
5926 : }
5927 :
5928 375203 : if (sn->from) {
5929 302516 : dlist *fl = sn->from->data.lval;
5930 302516 : sql_rel *fnd = NULL;
5931 302516 : list *refs = new_exp_list(sql->sa); /* Keep list of relation names in order to test for duplicates */
5932 :
5933 752561 : for (dnode *n = fl->h; n ; n = n->next) {
5934 450319 : int lateral = check_is_lateral(n->data.sym);
5935 :
5936 : /* just used current expression */
5937 450325 : if (lateral && res)
5938 22 : query_push_outer(query, res, sql_from);
5939 450325 : fnd = table_ref(query, n->data.sym, lateral, refs);
5940 450332 : if (lateral && res)
5941 22 : res = query_pop_outer(query);
5942 450332 : if (!fnd)
5943 : break;
5944 450051 : if (res) {
5945 147797 : res = rel_crossproduct(sql->sa, res, fnd, op_join);
5946 147797 : if (lateral)
5947 22 : set_dependent(res);
5948 : } else {
5949 : res = fnd;
5950 : }
5951 : }
5952 302523 : if (!fnd) {
5953 281 : if (res)
5954 12 : rel_destroy(res);
5955 281 : return NULL;
5956 : }
5957 72687 : } else if (!query_has_outer(query) || !res) {/* only on top level query */
5958 72667 : return rel_select_exp(query, NULL, sn, ek);
5959 : }
5960 :
5961 302242 : sql_rel *rel = NULL;
5962 302242 : if (res)
5963 302242 : rel = rel_select_exp(query, res, sn, ek);
5964 302236 : if (!rel && res)
5965 1041 : rel_destroy(res);
5966 : return rel;
5967 : }
5968 :
5969 : /* NOTE: does NOT "set" query but instead generate set ops (union, except, intersect) */
5970 : static sql_rel *
5971 23 : rel_setquery_corresponding(sql_query *query, sql_rel *l, sql_rel *r, dlist *cols, int op, int outer, bool n_ary_op)
5972 : {
5973 23 : mvc *sql = query->sql;
5974 23 : const char *opname = op==SQL_EXCEPT?"EXCEPT":op==SQL_INTERSECT?"INTERSECT":outer?"OUTER UNION":"UNION";
5975 23 : list *lexps = sa_list(query->sql->sa), *rexps = sa_list(query->sql->sa);
5976 23 : if (!lexps || !rexps)
5977 : return NULL;
5978 23 : assert(cols);
5979 23 : if (dlist_length(cols)) {
5980 22 : for (dnode *dn = cols->h; dn; dn = dn ->next) {
5981 13 : char *nm = dn->data.sym->data.lval->h->data.sval;
5982 13 : sql_exp *ls, *rs;
5983 :
5984 13 : if (!(ls = rel_bind_column(sql, l, nm, sql_where | sql_join, 0)) && sql->session->status == -ERR_AMBIGUOUS)
5985 : return NULL;
5986 13 : if (!(rs = rel_bind_column(sql, r, nm, sql_where | sql_join, 0)) && sql->session->status == -ERR_AMBIGUOUS)
5987 : return NULL;
5988 13 : if ((!outer && (!ls || !rs)) || (outer && !ls && !rs))
5989 2 : return sql_error(sql, 02, SQLSTATE(42000) "%s: tables '%s' and '%s' do not have a matching column '%s'", opname, rel_name(l)?rel_name(l):"", rel_name(r)?rel_name(r):"", nm);
5990 11 : if (outer && !ls)
5991 4 : ls = exp_null(sql->sa, exp_subtype(rs));
5992 11 : if (outer && !rs)
5993 4 : rs = exp_null(sql->sa, exp_subtype(ls));
5994 11 : append(lexps, ls);
5995 11 : append(rexps, rs);
5996 : }
5997 : } else {
5998 12 : int found = 0;
5999 12 : list *exps = rel_projections(sql, l, NULL, 1, 0), *r_exps = rel_projections(sql, r, NULL, 1, 0);
6000 12 : if (!exps || !r_exps)
6001 : return NULL;
6002 : /* find cols which exist on both sides */
6003 35 : for (node *n = exps->h; n; n = n->next) {
6004 23 : sql_exp *le = n->data;
6005 23 : int multi = 0;
6006 23 : const char *rname = exp_relname(le), *name = exp_name(le);
6007 23 : sql_exp *re = exps_bind_column(r_exps, name, NULL, &multi, 0);
6008 23 : if (re) {
6009 13 : if (multi)
6010 0 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "%s: common column name '%s' appears more than once in right table", opname, rname);
6011 13 : multi = 0;
6012 13 : le = exps_bind_column(exps, name, NULL, &multi, 0);
6013 13 : if (multi)
6014 0 : return sql_error(sql, ERR_AMBIGUOUS, SQLSTATE(42000) "%s: common column name '%s' appears more than once in left table", opname, rname);
6015 :
6016 13 : found = 1;
6017 13 : append(lexps, le);
6018 13 : append(rexps, re);
6019 13 : list_remove_data(r_exps, NULL, re);
6020 10 : } else if (outer) {
6021 3 : append(lexps, le);
6022 3 : re = exp_null(sql->sa, exp_subtype(le));
6023 3 : append(rexps, re); /* nils */
6024 : }
6025 : }
6026 12 : if (!found)
6027 0 : return sql_error(sql, 02, SQLSTATE(42000) "%s: no columns of tables '%s' and '%s' match", opname, rel_name(l)?rel_name(l):"", rel_name(r)?rel_name(r):"");
6028 12 : if (outer) {
6029 7 : for (node *n = r_exps->h; n; n = n->next) {
6030 4 : sql_exp *re = n->data, *le;
6031 4 : append(rexps, re);
6032 4 : le = exp_null(sql->sa, exp_subtype(re));
6033 4 : append(lexps, le); /* nils */
6034 : }
6035 : }
6036 : }
6037 21 : return n_ary_op ?
6038 21 : rel_setop_n_ary_check_types(sql, l, r, lexps, rexps, (operator_type)op) :
6039 2 : rel_setop_check_types(sql, l, r, lexps, rexps, (operator_type)op);
6040 : }
6041 :
6042 : static sql_rel *
6043 2484 : rel_setquery_(sql_query *query, sql_rel *l, sql_rel *r, dlist *cols, int op, int outer)
6044 : {
6045 2484 : mvc *sql = query->sql;
6046 2484 : sql_rel *rel;
6047 :
6048 2484 : if (outer && !cols)
6049 0 : return sql_error(sql, 02, SQLSTATE(42000) "UNION: OUTER needs to be combined with CORRESPONDING [ BY ( column list ) ]");
6050 2484 : if (!cols) {
6051 2482 : list *ls, *rs;
6052 :
6053 2482 : l = rel_unique_names(sql, l);
6054 2482 : r = rel_unique_names(sql, r);
6055 2482 : ls = rel_projections(sql, l, NULL, 0, 1);
6056 2482 : rs = rel_projections(sql, r, NULL, 0, 1);
6057 2482 : rel = rel_setop_check_types(sql, l, r, ls, rs, (operator_type)op);
6058 : } else {
6059 2 : rel = rel_setquery_corresponding(query, l, r, cols, op, outer, false);
6060 : }
6061 2484 : if (rel) {
6062 2481 : rel_setop_set_exps(sql, rel, rel_projections(sql, rel, NULL, 0, 1), false);
6063 2481 : set_processed(rel);
6064 : }
6065 : return rel;
6066 : }
6067 :
6068 : /* Generate n-ary set operator */
6069 : static sql_rel *
6070 61929 : rel_setquery_n_ary_(sql_query *query, sql_rel *l, sql_rel *r, dlist *cols, int op, int outer)
6071 : {
6072 : /* even though this is for a general n-ary operators in this phase of the query
6073 : * processing we gonna have only two operands (so technically it's binary). In
6074 : * general this op supports arbitrary number of operands.
6075 : */
6076 : // TODO: for now we support only multi-union
6077 61929 : assert(op == op_munion);
6078 :
6079 61929 : mvc *sql = query->sql;
6080 61929 : sql_rel *rel;
6081 :
6082 61929 : if (outer && !cols)
6083 0 : return sql_error(sql, 02, SQLSTATE(42000) "UNION: OUTER needs to be combined with CORRESPONDING [ BY ( column list ) ]");
6084 61929 : if (!cols) {
6085 : // TODO: make rel_setop_n_ary_check_types to accept a list of rels
6086 : // and a list of lists of exps
6087 61908 : list *ls, *rs;
6088 :
6089 61908 : l = rel_unique_names(sql, l);
6090 61908 : r = rel_unique_names(sql, r);
6091 61908 : ls = rel_projections(sql, l, NULL, 0, 1);
6092 61908 : rs = rel_projections(sql, r, NULL, 0, 1);
6093 61908 : rel = rel_setop_n_ary_check_types(sql, l, r, ls, rs, (operator_type)op);
6094 : } else {
6095 21 : rel = rel_setquery_corresponding(query, l, r, cols, op, outer, true);
6096 : }
6097 :
6098 61929 : if (rel) {
6099 61923 : rel_setop_n_ary_set_exps(sql, rel, rel_projections(sql, rel, NULL, 0, 1), false);
6100 61923 : set_processed(rel);
6101 : }
6102 :
6103 : return rel;
6104 :
6105 : }
6106 :
6107 : static sql_rel *
6108 64426 : rel_setquery(sql_query *query, symbol *q)
6109 : {
6110 64426 : mvc *sql = query->sql;
6111 64426 : sql_rel *res = NULL;
6112 64426 : dnode *n = q->data.lval->h;
6113 64426 : symbol *tab_ref1 = n->data.sym;
6114 64426 : int distinct = n->next->data.i_val;
6115 64426 : dlist *corresponding = n->next->next->data.lval;
6116 64426 : symbol *tab_ref2 = n->next->next->next->data.sym;
6117 64426 : sql_rel *t1, *t2;
6118 :
6119 64426 : assert(n->next->type == type_int);
6120 64426 : t1 = table_ref(query, tab_ref1, 0, NULL);
6121 64426 : if (!t1)
6122 : return NULL;
6123 64422 : t2 = table_ref(query, tab_ref2, 0, NULL);
6124 64422 : if (!t2)
6125 : return NULL;
6126 :
6127 64414 : rel_remove_internal_exp(t1);
6128 64414 : rel_remove_internal_exp(t2);
6129 64414 : if (!corresponding && list_length(t1->exps) != list_length(t2->exps)) {
6130 1 : int t1nrcols = list_length(t1->exps);
6131 1 : int t2nrcols = list_length(t2->exps);
6132 1 : const char *op = "UNION";
6133 1 : if (q->token == SQL_EXCEPT)
6134 : op = "EXCEPT";
6135 0 : else if (q->token == SQL_INTERSECT)
6136 0 : op = "INTERSECT";
6137 1 : rel_destroy(t1);
6138 1 : rel_destroy(t2);
6139 1 : return sql_error(sql, 02, SQLSTATE(42000) "%s: column counts (%d and %d) do not match", op, t1nrcols, t2nrcols);
6140 : }
6141 64413 : if ( q->token == SQL_UNION) {
6142 61929 : int outer = n->next->next->next->next->data.i_val;
6143 : /* For EXCEPT/INTERSECT the group by is always done within the implementation */
6144 : /* TODO add those later in an optimizer ! */
6145 61929 : if (t1 && distinct)
6146 3481 : t1 = rel_distinct(t1);
6147 61929 : if (t2 && distinct)
6148 3481 : t2 = rel_distinct(t2);
6149 : // TODO: this has to be fixed
6150 : /*res = rel_setquery_(query, t1, t2, corresponding, op_union, outer);*/
6151 61929 : res = rel_setquery_n_ary_(query, t1, t2, corresponding, op_munion, outer);
6152 2484 : } else if ( q->token == SQL_EXCEPT)
6153 2026 : res = rel_setquery_(query, t1, t2, corresponding, op_except, 0);
6154 458 : else if ( q->token == SQL_INTERSECT)
6155 458 : res = rel_setquery_(query, t1, t2, corresponding, op_inter, 0);
6156 64413 : if (res) {
6157 64404 : set_processed(res);
6158 64404 : if (distinct)
6159 5839 : res = rel_distinct(res);
6160 : }
6161 : return res;
6162 : }
6163 :
6164 : static sql_rel *
6165 59371 : rel_joinquery_(sql_query *query, symbol *tab1, int natural, jt jointype, symbol *tab2, symbol *js, list *refs)
6166 : {
6167 59371 : mvc *sql = query->sql;
6168 59371 : operator_type op = op_join;
6169 59371 : sql_rel *t1 = NULL, *t2 = NULL, *inner, *rel = NULL;
6170 59371 : int l_nil = 0, r_nil = 0, lateral = 0;
6171 :
6172 59371 : switch(jointype) {
6173 : case jt_inner:
6174 : case jt_cross: op = op_join;
6175 : break;
6176 : case jt_left: op = op_left;
6177 : r_nil = 1;
6178 : break;
6179 : case jt_right: op = op_right;
6180 : l_nil = 1;
6181 : break;
6182 : case jt_full: op = op_full;
6183 : l_nil = 1;
6184 : r_nil = 1;
6185 : break;
6186 : }
6187 :
6188 : /* a dependent join cannot depend on the right side, so disable lateral check for right and full joins */
6189 59371 : lateral = (op == op_join || op == op_left) && check_is_lateral(tab2);
6190 59371 : t1 = table_ref(query, tab1, 0, refs);
6191 59371 : if (t1) {
6192 59366 : if (!lateral) {
6193 59331 : t2 = table_ref(query, tab2, 0, refs);
6194 : } else {
6195 35 : query_processed(query);
6196 35 : query_push_outer(query, t1, sql_from);
6197 35 : t2 = table_ref(query, tab2, 0, refs);
6198 35 : t1 = query_pop_outer(query);
6199 : }
6200 : }
6201 59371 : if (!t1 || !t2)
6202 : return NULL;
6203 :
6204 59350 : query_processed(query);
6205 59350 : if (strcmp(rel_name(t1), rel_name(t2)) == 0) {
6206 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: ERROR: table name '%s' specified more than once", rel_name(t1));
6207 : }
6208 59350 : inner = rel = rel_crossproduct(sql->sa, t1, t2, op);
6209 59350 : if (!rel)
6210 : return NULL;
6211 59350 : if (lateral)
6212 34 : set_dependent(rel);
6213 :
6214 59350 : assert(jointype != jt_cross || (!natural && !js)); /* there are no natural cross joins, or cross joins with conditions */
6215 59350 : if (js && natural)
6216 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: cannot have a NATURAL JOIN with a join specification (ON or USING)");
6217 59350 : if (jointype != jt_cross && !js && !natural)
6218 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: must have NATURAL JOIN or a JOIN with a join specification (ON or USING)");
6219 :
6220 59350 : if (js && js->token != SQL_USING) { /* On sql_logical_exp */
6221 59173 : rel = rel_logical_exp(query, rel, js, sql_where | sql_join);
6222 177 : } else if (js) { /* using */
6223 24 : char rname[16], *rnme;
6224 24 : dnode *n = js->data.lval->h;
6225 24 : list *outexps = new_exp_list(sql->sa), *exps;
6226 24 : node *m;
6227 :
6228 24 : rnme = sa_strdup(sql->sa, number2name(rname, sizeof(rname), ++sql->label));
6229 54 : for (; n; n = n->next) {
6230 30 : char *nm = n->data.sval;
6231 30 : sql_exp *cond, *ls, *rs;
6232 :
6233 30 : if (!(ls = rel_bind_column(sql, t1, nm, sql_where | sql_join, 0)) && sql->session->status == -ERR_AMBIGUOUS)
6234 0 : return NULL;
6235 30 : if (!(rs = rel_bind_column(sql, t2, nm, sql_where | sql_join, 0)) && sql->session->status == -ERR_AMBIGUOUS)
6236 : return NULL;
6237 30 : if (!ls || !rs)
6238 0 : return sql_error(sql, 02, SQLSTATE(42000) "JOIN: tables '%s' and '%s' do not have a matching column '%s'", rel_name(t1)?rel_name(t1):"", rel_name(t2)?rel_name(t2):"", nm);
6239 30 : if (!(rel = rel_compare_exp(query, rel, ls, rs, "=", TRUE, 0, 0, 0, 0)))
6240 : return NULL;
6241 30 : if (op != op_join) {
6242 12 : if (!(cond = rel_unop_(sql, rel, ls, "sys", "isnull", card_value)))
6243 : return NULL;
6244 12 : set_has_no_nil(cond);
6245 12 : if (rel_convert_types(sql, t1, t2, &ls, &rs, 1, type_equal) < 0)
6246 : return NULL;
6247 12 : if (!(ls = rel_nop_(sql, rel, cond, rs, ls, NULL, "sys", "ifthenelse", card_value)))
6248 : return NULL;
6249 : }
6250 30 : exp_setname(sql, ls, rnme, nm);
6251 30 : append(outexps, ls);
6252 30 : if (!rel)
6253 : return NULL;
6254 : }
6255 24 : exps = rel_projections(sql, t1, NULL, 1, 1);
6256 207 : for (m = exps->h; m; m = m->next) {
6257 183 : const char *nm = exp_name(m->data);
6258 183 : int fnd = 0;
6259 :
6260 433 : for (n = js->data.lval->h; n; n = n->next) {
6261 280 : if (strcmp(nm, n->data.sval) == 0) {
6262 : fnd = 1;
6263 : break;
6264 : }
6265 : }
6266 183 : if (!fnd) {
6267 153 : sql_exp *ls = m->data;
6268 153 : if (l_nil)
6269 18 : set_has_nil(ls);
6270 153 : set_not_unique(ls);
6271 153 : append(outexps, ls);
6272 : }
6273 : }
6274 24 : exps = rel_projections(sql, t2, NULL, 1, 1);
6275 108 : for (m = exps->h; m; m = m->next) {
6276 84 : const char *nm = exp_name(m->data);
6277 84 : int fnd = 0;
6278 :
6279 234 : for (n = js->data.lval->h; n; n = n->next) {
6280 180 : if (strcmp(nm, n->data.sval) == 0) {
6281 : fnd = 1;
6282 : break;
6283 : }
6284 : }
6285 84 : if (!fnd) {
6286 54 : sql_exp *rs = m->data;
6287 54 : if (r_nil)
6288 14 : set_has_nil(rs);
6289 54 : set_not_unique(rs);
6290 54 : append(outexps, rs);
6291 : }
6292 : }
6293 24 : rel = rel_project(sql->sa, rel, outexps);
6294 153 : } else if (jointype != jt_cross) { /* ! js -> natural join */
6295 62 : rel = join_on_column_name(query, rel, t1, t2, op, l_nil, r_nil);
6296 : }
6297 59350 : if (!rel)
6298 : return NULL;
6299 59332 : if (inner && is_outerjoin(inner->op))
6300 20877 : set_processed(inner);
6301 59332 : set_processed(rel);
6302 59332 : query_processed(query);
6303 59332 : return rel;
6304 : }
6305 :
6306 : static sql_rel *
6307 59371 : rel_joinquery(sql_query *query, symbol *q, list *refs)
6308 : {
6309 59371 : dnode *n = q->data.lval->h;
6310 59371 : symbol *tab_ref1 = n->data.sym;
6311 59371 : int natural = n->next->data.i_val;
6312 59371 : jt jointype = (jt) n->next->next->data.i_val;
6313 59371 : symbol *tab_ref2 = n->next->next->next->data.sym;
6314 59371 : symbol *joinspec = n->next->next->next->next->data.sym;
6315 :
6316 59371 : assert(n->next->type == type_int);
6317 59371 : assert(n->next->next->type == type_int);
6318 59371 : return rel_joinquery_(query, tab_ref1, natural, jointype, tab_ref2, joinspec, refs);
6319 : }
6320 :
6321 : sql_rel *
6322 375193 : rel_subquery(sql_query *query, symbol *sq, exp_kind ek)
6323 : {
6324 375193 : mvc *sql = query->sql;
6325 :
6326 375193 : query_processed(query);
6327 375188 : if (!stack_push_frame(sql, NULL))
6328 0 : return sql_error(sql, 02, SQLSTATE(HY013) MAL_MALLOC_FAIL);
6329 375258 : sql_rel *rel = rel_query(query, sq, ek);
6330 375183 : stack_pop_frame(sql);
6331 375270 : if (!query_has_outer(query))
6332 336438 : query_processed(query);
6333 375250 : if (rel && ek.type == type_relation && ek.card < card_set && rel->card >= CARD_AGGR)
6334 15 : return rel_zero_or_one(sql, rel, ek);
6335 : return rel;
6336 : }
6337 :
6338 : sql_rel *
6339 237188 : rel_selects(sql_query *query, symbol *s)
6340 : {
6341 237188 : mvc *sql = query->sql;
6342 237188 : sql_rel *ret = NULL;
6343 :
6344 237188 : switch (s->token) {
6345 4469 : case SQL_WITH:
6346 4469 : ret = rel_with_query(query, s);
6347 4469 : sql->type = Q_TABLE;
6348 4469 : break;
6349 2230 : case SQL_VALUES:
6350 2230 : ret = rel_values(query, s, NULL);
6351 2230 : sql->type = Q_TABLE;
6352 2230 : break;
6353 209563 : case SQL_SELECT: {
6354 209563 : exp_kind ek = {type_value, card_relation, TRUE};
6355 209563 : SelectNode *sn = (SelectNode *) s;
6356 :
6357 209563 : if (sn->into) {
6358 1 : sql->type = Q_SCHEMA;
6359 1 : ret = rel_select_with_into(query, s);
6360 : } else {
6361 209562 : ret = rel_subquery(query, s, ek);
6362 209607 : sql->type = Q_TABLE;
6363 : }
6364 209609 : } break;
6365 0 : case SQL_JOIN:
6366 0 : ret = rel_joinquery(query, s, NULL);
6367 0 : sql->type = Q_TABLE;
6368 0 : break;
6369 20926 : case SQL_UNION:
6370 : case SQL_EXCEPT:
6371 : case SQL_INTERSECT:
6372 20926 : ret = rel_setquery(query, s);
6373 20926 : sql->type = Q_TABLE;
6374 20926 : break;
6375 : default:
6376 : return NULL;
6377 : }
6378 237234 : if (!ret && sql->errstr[0] == 0)
6379 0 : (void) sql_error(sql, 02, SQLSTATE(42000) "relational query without result");
6380 : return ret;
6381 : }
6382 :
6383 : sql_rel *
6384 77650 : schema_selects(sql_query *query, sql_schema *schema, symbol *s)
6385 : {
6386 77650 : mvc *sql = query->sql;
6387 77650 : sql_rel *res;
6388 77650 : sql_schema *os = cur_schema(sql);
6389 :
6390 77650 : sql->session->schema = schema;
6391 77650 : res = rel_selects(query, s);
6392 77650 : sql->session->schema = os;
6393 77650 : return res;
6394 : }
6395 :
6396 : sql_rel *
6397 26 : rel_loader_function(sql_query *query, symbol* fcall, list *fexps, sql_subfunc **loader_function)
6398 : {
6399 26 : mvc *sql = query->sql;
6400 26 : sql_rel *sq = NULL;
6401 26 : dnode *l = fcall->data.lval->h;
6402 26 : char *sname = qname_schema(l->data.lval);
6403 26 : char *fname = qname_schema_object(l->data.lval);
6404 :
6405 26 : list *tl = sa_list(sql->sa);
6406 26 : list *exps = sa_list(sql->sa);
6407 26 : if (l->next)
6408 26 : l = l->next; /* skip distinct */
6409 26 : if (l->next) { /* table call with subquery */
6410 26 : if (l->next->type == type_symbol || l->next->type == type_list) {
6411 26 : int count = 0;
6412 26 : symbol *subquery = NULL;
6413 26 : dnode *n = NULL;
6414 :
6415 26 : if (l->next->type == type_symbol)
6416 : n = l->next;
6417 : else
6418 26 : n = l->next->data.lval?l->next->data.lval->h:NULL;
6419 :
6420 70 : for (dnode *m = n; m; m = m->next) {
6421 44 : if (m->type == type_symbol && m->data.sym->token == SQL_SELECT)
6422 44 : subquery = m->data.sym;
6423 44 : count++;
6424 : }
6425 26 : if (subquery && count > 1)
6426 0 : return sql_error(sql, 02, SQLSTATE(42000) "SELECT: The input for the loader function '%s' must be either a single sub query, or a list of values", fname);
6427 :
6428 26 : if (subquery) {
6429 0 : exp_kind ek = { type_value, card_relation, TRUE };
6430 0 : if (!(sq = rel_subquery(query, subquery, ek)))
6431 0 : return NULL;
6432 : } else {
6433 26 : exp_kind ek = { type_value, card_column, TRUE };
6434 26 : list *exps = sa_list(sql->sa);
6435 96 : for ( ; n; n = n->next) {
6436 44 : sql_exp *e = rel_value_exp(query, NULL, n->data.sym, sql_sel | sql_from, ek);
6437 :
6438 44 : if (!e)
6439 0 : return NULL;
6440 44 : append(exps, e);
6441 : }
6442 26 : sq = rel_project(sql->sa, NULL, exps);
6443 : }
6444 : }
6445 26 : if (!sq)
6446 0 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(42000) "SELECT: no such loader function %s%s%s'%s'", sname ? "'":"", sname ? sname : "", sname ? "'.":"", fname);
6447 70 : for (node *en = sq->exps->h; en; en = en->next) {
6448 44 : sql_exp *e = en->data;
6449 :
6450 44 : append(exps, e = exp_ref(sql, e));
6451 44 : append(tl, exp_subtype(e));
6452 : }
6453 : }
6454 :
6455 26 : sql_exp *e = NULL;
6456 26 : if (!(e = find_table_function(sql, sname, fname, exps, tl, F_LOADER)))
6457 : return NULL;
6458 25 : sql_subfunc *sf = e->f;
6459 25 : if (sq) {
6460 69 : for (node *n = sq->exps->h, *m = sf->func->ops->h ; n && m ; n = n->next, m = m->next) {
6461 44 : sql_exp *e = (sql_exp*) n->data;
6462 44 : sql_arg *a = (sql_arg*) m->data;
6463 44 : if (!exp_subtype(e) && rel_set_type_param(sql, &(a->type), sq, e, 0) < 0)
6464 : return NULL;
6465 : }
6466 : }
6467 :
6468 25 : if (loader_function)
6469 25 : *loader_function = sf;
6470 :
6471 25 : return rel_table_func(sql->sa, sq, e, fexps, (sq)?TABLE_FROM_RELATION:TABLE_PROD_FUNC);
6472 : }
|