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