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