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