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