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 "sql_parser.h"
15 : #include "sql_symbol.h"
16 : #include "sql_semantic.h"
17 : #include "sql_env.h"
18 : #include "sql_privileges.h"
19 : #include "sql_string.h"
20 : #include "sql_atom.h"
21 :
22 : #include <unistd.h>
23 : #include <string.h>
24 : #include <ctype.h>
25 :
26 : #include "rel_semantic.h"
27 :
28 : /*
29 : * For debugging purposes we need to be able to convert sql-tokens to
30 : * a string representation.
31 : *
32 : * !SQL ERROR <sqlerrno> : <details>
33 : * !SQL DEBUG <details>
34 : * !SQL WARNING <details>
35 : * !SQL <informative message, reserved for ...rows affected>
36 : */
37 :
38 : void
39 384850 : sql_add_param(mvc *sql, const char *name, sql_subtype *st)
40 : {
41 384850 : sql_arg *a = SA_ZNEW(sql->sa, sql_arg);
42 :
43 384850 : if (name)
44 383234 : a->name = sa_strdup(sql->sa, name);
45 384850 : if (st && st->type)
46 383223 : a->type = *st;
47 384850 : a->inout = ARG_IN;
48 384850 : if (name && strcmp(name, "*") == 0)
49 4 : a->type = *sql_bind_localtype("int");
50 384850 : if (!sql->params)
51 226844 : sql->params = sa_list(sql->sa);
52 384850 : list_append(sql->params, a);
53 384850 : }
54 :
55 : int
56 97095 : sql_bind_param(mvc *sql, const char *name)
57 : {
58 97095 : node *n;
59 97095 : int nr = 0;
60 :
61 97095 : if (sql->params) {
62 209614 : for (n = sql->params->h; n; n = n->next, nr++) {
63 205231 : sql_arg *a = n->data;
64 :
65 205231 : if (a->name && strcmp(a->name, name) == 0)
66 89013 : return nr;
67 : }
68 : }
69 : return -1;
70 : }
71 :
72 : sql_arg *
73 92190 : sql_bind_paramnr(mvc *sql, int nr)
74 : {
75 92190 : int i=0;
76 92190 : node *n;
77 :
78 92190 : if (sql->params && nr < list_length(sql->params)) {
79 681616 : for (n = sql->params->h, i=0; n && i<nr; n = n->next, i++)
80 : ;
81 :
82 92190 : if (n)
83 92190 : return n->data;
84 : }
85 : return NULL;
86 : }
87 :
88 : sql_arg *
89 6 : sql_find_param(mvc *sql, char *name)
90 : {
91 9 : for (node *n = sql->params->h; n; n = n->next) {
92 8 : sql_arg *a = n->data;
93 8 : if (strcmp(a->name, name) == 0)
94 5 : return a;
95 : }
96 : return NULL;
97 : }
98 :
99 : void
100 747501 : sql_destroy_params(mvc *sql)
101 : {
102 747501 : sql->params = NULL;
103 747501 : }
104 :
105 : sql_schema *
106 1706033 : cur_schema(mvc *sql)
107 : {
108 1706033 : return sql->session->schema;
109 : }
110 :
111 : sql_schema *
112 560866 : tmp_schema(mvc *sql)
113 : {
114 560866 : return mvc_bind_schema(sql, "tmp");
115 : }
116 :
117 : #define DO_NOTHING(x) ;
118 :
119 : /* as we don't have OOP in C, I prefer a single macro with the search path algorithm to passing function pointers */
120 : #define search_object_on_path(CALL, EXTRA_CONDITION, EXTRA, ERROR_CODE, show_error) \
121 : do { \
122 : sql_schema *next = NULL; \
123 : \
124 : if (sname) { /* user has explicitly typed the schema, so either the object is there or we return error */ \
125 : if (!(next = mvc_bind_schema(sql, sname))) \
126 : return sql_error(sql, ERR_NOTFOUND, SQLSTATE(3F000) "%s: no such schema '%s'", error, sname); \
127 : EXTRA_CONDITION(EXTRA); /* for functions without schema, 'sys' is a valid schema to bind them */ \
128 : if (!res) { \
129 : CALL; \
130 : } \
131 : } else { \
132 : sql_schema *cur = cur_schema(sql); \
133 : char *session_schema = cur->base.name; \
134 : \
135 : EXTRA; \
136 : if (!res && !sql->schema_path_has_tmp && strcmp(session_schema, "tmp") != 0) { /* if 'tmp' is not in the search path, search it before all others */ \
137 : next = tmp_schema(sql); \
138 : CALL; \
139 : } \
140 : if (!res) { /* then current session's schema */ \
141 : next = cur; \
142 : CALL; \
143 : } \
144 : if (!res) { \
145 : /* object not found yet, look inside search path */ \
146 : for (node *n = sql->schema_path->h ; n && !res ; n = n->next) { \
147 : str p = (str) n->data; \
148 : if (strcmp(session_schema, p) != 0 && (next = mvc_bind_schema(sql, p))) \
149 : CALL; \
150 : } \
151 : } \
152 : if (!res && !sql->schema_path_has_sys && strcmp(session_schema, "sys") != 0) { /* if 'sys' is not in the current path search it next */ \
153 : next = mvc_bind_schema(sql, "sys"); \
154 : CALL; \
155 : } \
156 : } \
157 : if (!res && show_error) \
158 : return sql_error(sql, ERR_NOTFOUND, ERROR_CODE "%s: no such %s %s%s%s'%s'", error, objstr, sname ? "'":"", sname ? sname : "", sname ? "'.":"", name); \
159 : } while (0)
160 :
161 : #define table_extra \
162 : do { \
163 : if (s) { \
164 : next = s; /* there's a default schema to search before all others, e.g. bind a child table from a merge table */ \
165 : res = mvc_bind_table(sql, next, name); \
166 : } \
167 : if (!res && strcmp(objstr, "table") == 0 && (res = stack_find_table(sql, name))) /* for tables, first try a declared table from the stack */ \
168 : return res; \
169 : } while (0)
170 :
171 : sql_table *
172 684804 : find_table_or_view_on_scope(mvc *sql, sql_schema *s, const char *sname, const char *name, const char *error, bool isView)
173 : {
174 684804 : const char *objstr = isView ? "view" : "table";
175 684804 : sql_table *res = NULL;
176 :
177 685369 : search_object_on_path(res = mvc_bind_table(sql, next, name), DO_NOTHING, table_extra, SQLSTATE(42S02), true);
178 : return res;
179 : }
180 :
181 : sql_sequence *
182 1480 : find_sequence_on_scope(mvc *sql, const char *sname, const char *name, const char *error)
183 : {
184 1480 : const char objstr[] = "sequence";
185 1480 : sql_sequence *res = NULL;
186 :
187 1482 : search_object_on_path(res = find_sql_sequence(sql->session->tr, next, name), DO_NOTHING, ;, SQLSTATE(42000), true);
188 : return res;
189 : }
190 :
191 : sql_idx *
192 218 : find_idx_on_scope(mvc *sql, const char *sname, const char *name, const char *error)
193 : {
194 218 : const char objstr[] = "index";
195 218 : sql_idx *res = NULL;
196 :
197 292 : search_object_on_path(res = mvc_bind_idx(sql, next, name), DO_NOTHING, ;, SQLSTATE(42S12), true);
198 : return res;
199 : }
200 :
201 : sql_type *
202 5 : find_type_on_scope(mvc *sql, const char *sname, const char *name, const char *error)
203 : {
204 5 : const char objstr[] = "type";
205 5 : sql_type *res = NULL;
206 :
207 7 : search_object_on_path(res = schema_bind_type(sql, next, name), DO_NOTHING, ;, SQLSTATE(42S01), true);
208 : return res;
209 : }
210 :
211 : sql_trigger *
212 96 : find_trigger_on_scope(mvc *sql, const char *sname, const char *name, const char *error)
213 : {
214 96 : const char objstr[] = "trigger";
215 96 : sql_trigger *res = NULL;
216 :
217 118 : search_object_on_path(res = mvc_bind_trigger(sql, next, name), DO_NOTHING, ;, SQLSTATE(3F000), true);
218 : return res;
219 : }
220 :
221 : /* A variable can be any of the following, from the innermost to the outermost:
222 : - 'parameter of the function' (ie in the param list)
223 : - local variable, declared earlier
224 : - global variable, also declared earlier
225 : */
226 : #define variable_extra \
227 : do { \
228 : if (!res) { \
229 : if ((*var = stack_find_var_frame(sql, name, level))) { /* check if variable is known from the stack */ \
230 : *tpe = &((*var)->var.tpe); \
231 : res = true; \
232 : } else if ((nr = sql_bind_param(sql, name)) >= 0) { /* then if it is a parameter */ \
233 : *a = sql_bind_paramnr(sql, nr); \
234 : *tpe = &((*a)->type); \
235 : *level = 1; \
236 : res = true; \
237 : } \
238 : } \
239 : } while (0)
240 :
241 : #define var_find_on_global \
242 : do { \
243 : if ((*var = find_global_var(sql, next, name))) { /* then if it is a global var */ \
244 : *tpe = &((*var)->var.tpe); \
245 : *level = 0; \
246 : res = true; \
247 : } \
248 : } while (0)
249 :
250 : bool
251 205693 : find_variable_on_scope(mvc *sql, const char *sname, const char *name, sql_var **var, sql_arg **a, sql_subtype **tpe, int *level, const char *error)
252 : {
253 205693 : const char objstr[] = "variable";
254 205693 : bool res = false;
255 205693 : int nr = 0;
256 :
257 205693 : (void)nr;
258 210740 : search_object_on_path(var_find_on_global, DO_NOTHING, variable_extra, SQLSTATE(42000), true);
259 : return res;
260 : }
261 :
262 : static sql_subfunc *
263 949490 : _dup_subaggr(allocator *sa, sql_func *a, sql_subtype *member)
264 : {
265 949490 : node *tn;
266 949490 : unsigned int scale = 0, digits = 0;
267 949490 : sql_subfunc *ares = SA_ZNEW(sa, sql_subfunc);
268 :
269 :
270 949651 : ares->func = a;
271 949651 : if (IS_FILT(a)) {
272 4779 : ares->res = sa_list(sa);
273 4779 : list_append(ares->res, sql_bind_localtype("bit"));
274 944872 : } else if (IS_FUNC(a) || IS_UNION(a) || IS_ANALYTIC(a) || IS_AGGR(a)) { /* not needed for PROC */
275 940013 : if (a->res) {
276 940013 : ares->res = sa_list(sa);
277 1964569 : for(tn = a->res->h; tn; tn = tn->next) {
278 1024524 : sql_arg *rarg = tn->data;
279 1024524 : sql_subtype *res, *r = &rarg->type;
280 :
281 1024524 : if (a->fix_scale == SCALE_EQ && !IS_AGGR(a)) {
282 : res = r;
283 : } else {
284 849043 : digits = r->digits;
285 849043 : scale = r->scale;
286 : /* same scale as the input */
287 849043 : if (member && (member->scale != scale ||
288 177909 : (digits != member->digits && !EC_NUMBER(member->type->eclass)))) {
289 91690 : if (member->digits > digits)
290 : digits = member->digits;
291 : scale = member->scale;
292 : }
293 : /* same type as the input */
294 849043 : if (r->type->eclass == EC_ANY && member) {
295 13155 : r = member;
296 13155 : digits = member->digits;
297 : }
298 849043 : if (!EC_SCALE(r->type->eclass))
299 849043 : scale = 0;
300 849043 : res = sql_create_subtype(sa, r->type, digits, scale);
301 : }
302 1024596 : list_append(ares->res, res);
303 : }
304 : }
305 : }
306 949683 : return ares;
307 : }
308 :
309 :
310 :
311 : static sql_subfunc *
312 133592 : func_cmp(allocator *sa, sql_func *f, const char *name, int nrargs)
313 : {
314 133592 : if (strcmp(f->base.name, name) == 0) {
315 133592 : if (f->vararg)
316 : //return (f->type == F_AGGR) ? _dup_subaggr(sa, f, NULL) : sql_dup_subfunc(sa, f, NULL, NULL);
317 2 : return _dup_subaggr(sa, f, NULL);
318 133590 : if (nrargs < 0 || list_length(f->ops) == nrargs)
319 : //return (f->type == F_AGGR) ? _dup_subaggr(sa, f, NULL) : sql_dup_subfunc(sa, f, NULL, NULL);
320 132809 : return _dup_subaggr(sa, f, NULL);
321 : }
322 : return NULL;
323 : }
324 :
325 : static sql_subfunc *
326 654389 : sql_find_func_internal(mvc *sql, list *ff, const char *fname, int nrargs, sql_ftype type, bool private, sql_subfunc *prev)
327 : {
328 654389 : int key = hash_key(fname);
329 654389 : sql_subfunc *res = NULL;
330 654389 : int found = 0;
331 654389 : sql_ftype filt = (type == F_FUNC)?F_FILT:type;
332 :
333 654389 : if (ff) {
334 654389 : if (ff->ht) {
335 654389 : sql_hash_e *he = ff->ht->buckets[key&(ff->ht->size-1)];
336 654389 : if (prev) {
337 0 : for (; he && !found; he = he->chain)
338 0 : if (he->value == prev->func)
339 0 : found = 1;
340 : }
341 7803351 : for (; he; he = he->chain) {
342 7272164 : sql_func *f = he->value;
343 :
344 7272164 : if ((f->type != type && f->type != filt) || (f->private && !private))
345 7148947 : continue;
346 123217 : if ((res = func_cmp(sql->sa, f, fname, nrargs)) != NULL)
347 123202 : return res;
348 : }
349 : } else {
350 0 : node *n = ff->h;
351 0 : if (prev) {
352 0 : for (; n && !found; n = n->next)
353 0 : if (n->data == prev->func)
354 0 : found = 1;
355 : }
356 0 : for (; n; n = n->next) {
357 0 : sql_func *f = n->data;
358 :
359 0 : if ((f->type != type && f->type != filt) || (f->private && !private))
360 0 : continue;
361 0 : if ((res = func_cmp(sql->sa, f, fname, nrargs)) != NULL)
362 0 : return res;
363 : }
364 : }
365 : }
366 : return res;
367 : }
368 :
369 : static sql_subfunc *
370 779363 : os_find_func_internal(mvc *sql, struct objectset *ff, const char *fname, int nrargs, sql_ftype type, bool private, sql_subfunc *prev)
371 : {
372 779363 : sql_subfunc *res = NULL;
373 779363 : sql_ftype filt = (type == F_FUNC)?F_FILT:type;
374 :
375 779363 : if (ff) {
376 779363 : struct os_iter oi;
377 779363 : os_iterator(&oi, ff, sql->session->tr, fname);
378 876417 : for (sql_base *b = oi_next(&oi); b; b = oi_next(&oi)) {
379 106663 : sql_func *f = (sql_func*)b;
380 106663 : if (prev && prev->func != f) {
381 0 : continue;
382 106663 : } else if (prev) {
383 0 : prev = NULL;
384 0 : continue;
385 : }
386 :
387 106663 : if ((f->type != type && f->type != filt) || (f->private && !private))
388 96288 : continue;
389 10375 : if ((res = func_cmp(sql->sa, f, fname, nrargs)) != NULL)
390 9609 : return res;
391 : }
392 : }
393 : return res;
394 : }
395 :
396 : #define functions_without_schema(X) if (strcmp(sname, "sys") == 0) X
397 :
398 : #define find_func_extra \
399 : do { \
400 : if (!res && (res = sql_find_func_internal(sql, funcs, name, nrargs, type, private, prev))) /* search system wide functions first */ \
401 : return res; \
402 : } while (0)
403 :
404 : sql_subfunc *
405 655088 : sql_find_func(mvc *sql, const char *sname, const char *name, int nrargs, sql_ftype type, bool private, sql_subfunc *prev)
406 : {
407 655088 : char *F = NULL, *objstr = NULL;
408 655088 : const char error[] = "CATALOG";
409 655088 : sql_subfunc *res = NULL;
410 :
411 655088 : FUNC_TYPE_STR(type, F, objstr);
412 655088 : (void) F; /* not used */
413 :
414 655088 : assert(nrargs >= -1);
415 :
416 886483 : search_object_on_path(res = os_find_func_internal(sql, next->funcs, name, nrargs, type, private, prev), functions_without_schema, find_func_extra, "", false); //SQLSTATE(42000), true);
417 : return res;
418 : }
419 :
420 : sql_subfunc *
421 375141 : sql_bind_func(mvc *sql, const char *sname, const char *fname, sql_subtype *tp1, sql_subtype *tp2, sql_ftype type, bool private, bool exact)
422 : {
423 375141 : list *l = sa_list(sql->sa);
424 :
425 375286 : if (tp1)
426 365088 : list_append(l, tp1);
427 375324 : if (tp2)
428 216982 : list_append(l, tp2);
429 375324 : return sql_bind_func_(sql, sname, fname, l, type, private, exact);
430 : }
431 :
432 : sql_subfunc *
433 175 : sql_bind_func3(mvc *sql, const char *sname, const char *fname, sql_subtype *tp1, sql_subtype *tp2, sql_subtype *tp3, sql_ftype type, bool private)
434 : {
435 175 : list *l = sa_list(sql->sa);
436 :
437 175 : if (tp1)
438 175 : list_append(l, tp1);
439 175 : if (tp2)
440 175 : list_append(l, tp2);
441 175 : if (tp3)
442 175 : list_append(l, tp3);
443 175 : return sql_bind_func_(sql, sname, fname, l, type, private, false);
444 : }
445 :
446 : static int /* bind the function version with more identical type matches */
447 747433 : next_cand_points(list *args, list *ops)
448 : {
449 747433 : int res = 0;
450 :
451 747433 : if (!list_empty(args) && !list_empty(ops))
452 1975932 : for (node *n = args->h, *m = ops->h; n && m ; n = n->next, m = m->next) {
453 1249229 : sql_arg *a = n->data;
454 1249229 : sql_subtype *t = m->data;
455 :
456 1249229 : if (a->type.type->eclass == EC_ANY)
457 636164 : res += 100;
458 613065 : else if (t)
459 613065 : res += a->type.type->base.id == t->type->base.id;
460 : }
461 747866 : res += (list_empty(args) && list_empty(ops));
462 747873 : return res;
463 : }
464 :
465 : static int
466 8078693 : score_func( sql_func *f, list *tl, bool exact, bool *downcast)
467 : {
468 8078693 : int score = 0;
469 8078693 : node *n, *m;
470 :
471 8078693 : if (exact)
472 706856 : return next_cand_points(f->ops, tl);
473 7371837 : if (!tl)
474 : return 1;
475 7371837 : if (f->vararg)
476 : return 1;
477 7371455 : unsigned int digits = 0, scale = 0;
478 7371455 : if (f->fix_scale == SCALE_FIX) {
479 3121906 : for (n = f->ops->h, m = tl->h; n && m; n = n->next, m = m->next) {
480 2079667 : sql_subtype *t = m->data;
481 :
482 2079667 : if (!t)
483 51 : continue;
484 2079616 : if (t->type->eclass == EC_DEC) {
485 8142 : if (digits < t->digits)
486 : digits = t->digits;
487 8142 : if (scale < t->scale)
488 : scale = t->scale;
489 : }
490 : }
491 3121906 : for (n = f->ops->h, m = tl->h; n && m; n = n->next, m = m->next) {
492 2079667 : sql_arg *a = n->data;
493 2079667 : sql_subtype *t = m->data;
494 :
495 2079667 : if (!t)
496 51 : continue;
497 2079616 : if (a->type.type->eclass == EC_DEC && t->type->eclass == EC_NUM) {
498 1149405 : if (digits < scale + bits2digits(t->digits))
499 809940 : digits = scale + bits2digits(t->digits);
500 : }
501 : }
502 : }
503 7371455 : int nr_strconverts = 0;
504 16283046 : for (n = f->ops->h, m = tl->h; n && m; n = n->next, m = m->next) {
505 11701396 : sql_arg *a = n->data;
506 11701396 : sql_subtype *t = m->data;
507 :
508 11701396 : if (!t) { /* parameters */
509 502 : int ec = a->type.type->eclass;
510 502 : score++;
511 502 : if (ec == EC_DEC)
512 : return 0;
513 326 : if (a && EC_NUMBER(ec) && !EC_INTERVAL(ec))
514 218 : score += a->type.type->localtype * 10; /* premium on larger types */
515 108 : else if (a) /* all other types */
516 108 : score += 99;
517 326 : continue;
518 : }
519 :
520 11700894 : int nscore = sql_type_convert_preference(t->type->eclass, a->type.type->eclass);
521 : /* EX_EXTERNAL can only convert between equal implementation types */
522 11700894 : if (nscore == 0 &&
523 2588178 : t->type->eclass == a->type.type->eclass &&
524 571 : t->type->eclass == EC_EXTERNAL &&
525 571 : t->type->localtype == a->type.type->localtype)
526 : nscore = 10;
527 9113278 : if (nscore &&
528 9113278 : t->type->eclass == EC_NUM && a->type.type->eclass == EC_DEC &&
529 3420640 : t->type->localtype > a->type.type->localtype)
530 708628 : *downcast = true;
531 9113278 : if (nscore == 0)
532 : return 0;
533 9113278 : nscore *= 100; /* first based on preferred conversions */
534 9113278 : if (nscore < 0) {
535 292511 : *downcast = true;
536 292511 : nscore = -nscore;
537 : }
538 9113278 : score += nscore;
539 9113278 : if (EC_VARCHAR(t->type->eclass) && EC_NUMBER(a->type.type->eclass))
540 1227 : nr_strconverts++;
541 9113278 : if (nr_strconverts > 1)
542 : return 0;
543 :
544 9113242 : if (f->fix_scale == SCALE_FIX && a->type.type->eclass == EC_DEC && digits > a->type.type->digits) /* doesn't fit */
545 : return 0;
546 : /* sql types equal but implementation differences */
547 8911265 : else if (t->type->eclass == EC_BIT && a->type.type->eclass == EC_NUM && t->type->localtype <= a->type.type->localtype) /* convert bits into smallest number */
548 146 : score += (11 + t->type->localtype - a->type.type->localtype) * 8;
549 : /* sql types close but digits/scale diffs */
550 8911119 : else if (t->type->eclass == EC_NUM && a->type.type->eclass == EC_DEC && /*t->type->localtype <= a->type.type->localtype*/ bits2digits(t->digits) < a->type.type->digits)
551 : //score += (10 + t->type->localtype - a->type.type->localtype) * 8;
552 2507282 : score += (38 + bits2digits(t->digits) - a->type.type->digits);
553 : /* same class over converting to other class */
554 6403837 : else if (t->type->eclass == a->type.type->eclass && t->type->localtype <= a->type.type->localtype) {
555 3406227 : score += (11 + t->type->localtype - a->type.type->localtype) * 4;
556 : /* handle intervals (day, hour, minutes, second) mapped
557 : * within same eclass and implementation type. */
558 3406227 : if (t->type->eclass == a->type.type->eclass && t->type->eclass == EC_SEC)
559 3088 : score += ((t->type->digits > 4 && a->type.type->digits > 4) ||
560 3467 : (t->type->digits <= 4 && a->type.type->digits <= 4)) * 4;
561 : }
562 : /* conversion matrix needs check if conversion is possible */
563 2997610 : else if (t->type->eclass == a->type.type->eclass) {
564 1103267 : if (t->type->localtype <= a->type.type->localtype) {
565 0 : int nscore = sql_type_convert_preference(t->type->eclass, a->type.type->eclass);
566 0 : score += (10 + t->type->localtype - a->type.type->localtype) * nscore;
567 1103267 : } else if (t->type->eclass == EC_NUM || t->type->eclass == EC_FLT) { /* down casting */
568 1088365 : *downcast = true;
569 1088365 : score += 10 * (10 - t->type->localtype - a->type.type->localtype);
570 : }
571 : }
572 : }
573 4581650 : score += (list_empty(tl) && list_empty(f->ops));
574 4581651 : return score;
575 : }
576 :
577 :
578 : static sql_subfunc *
579 1557107 : sql_bind_func__(mvc *sql, list *ff, const char *fname, list *ops, sql_ftype type, bool private, bool exact)
580 : {
581 1557107 : sql_ftype filt = (type == F_FUNC)?F_FILT:type;
582 1557107 : sql_subtype *input_type = NULL;
583 1557107 : sql_func *cand = NULL, *dcand = NULL;
584 1557107 : int points = 0, dpoints = 0;
585 :
586 1557107 : if (ops && ops->h)
587 1517865 : input_type = ops->h->data;
588 :
589 1557107 : assert(ff==funcs);
590 1557107 : if (ff) {
591 1557324 : if (ff->ht) {
592 1557324 : int key = hash_key(fname);
593 1557324 : sql_hash_e *he = ff->ht->buckets[key&(ff->ht->size-1)];
594 9767994 : for (; he; he = he->chain) {
595 8210651 : sql_func *f = he->value;
596 8210651 : bool downcast = false;
597 :
598 8210651 : if ((f->type != type && f->type != filt) || (f->private && !private))
599 338483 : continue;
600 7872168 : if (strcmp(f->base.name, fname) == 0 && ((!exact && (list_length(f->ops) == list_length(ops) || (list_length(f->ops) <= list_length(ops) && f->vararg))) || (exact && list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 0))) {
601 7744315 : int npoints = score_func(f, ops, exact, &downcast);
602 7744033 : if (downcast) {
603 1849685 : if ((!dcand && (npoints || exact)) || (dcand && npoints > dpoints)) {
604 7872187 : dcand = f;
605 7872187 : dpoints = npoints;
606 : }
607 : } else {
608 5894348 : if ((!cand && (npoints || exact)) || (cand && npoints > points)) {
609 7872187 : cand = f;
610 7872187 : points = npoints;
611 : }
612 : }
613 : }
614 : }
615 : } else {
616 0 : node *n;
617 0 : sql_base_loop(ff, n) {
618 0 : sql_func *f = n->data;
619 0 : bool downcast = false;
620 :
621 0 : if ((f->type != type && f->type != filt) || (f->private && !private))
622 0 : continue;
623 0 : if (strcmp(f->base.name, fname) == 0 && ((!exact && (list_length(f->ops) == list_length(ops) || (list_length(f->ops) <= list_length(ops) && f->vararg))) || (exact && list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 0))) {
624 0 : int npoints = score_func(f, ops, exact, &downcast);
625 0 : if (downcast) {
626 0 : if ((!dcand && (npoints || exact)) || (dcand && npoints > dpoints)) {
627 0 : dcand = f;
628 0 : dpoints = npoints;
629 : }
630 : } else {
631 0 : if ((!cand && (npoints || exact)) || (cand && npoints > points)) {
632 0 : cand = f;
633 0 : points = npoints;
634 : }
635 : }
636 : }
637 : }
638 : }
639 : }
640 1557126 : if (!cand && dcand)
641 20050 : cand = dcand;
642 1557126 : if (cand && exact && type != F_AGGR)
643 386730 : return sql_dup_subfunc(sql->sa, cand, ops, NULL);
644 1170396 : if (cand)
645 : //return (type == F_AGGR) ? _dup_subaggr(sql->sa, cand, input_type) : sql_dup_subfunc(sql->sa, cand, ops, NULL);
646 1199435 : return _dup_subaggr(sql->sa, cand, (type == F_AGGR) ?input_type: NULL);
647 : return NULL;
648 : }
649 :
650 : static sql_subfunc *
651 639364 : os_bind_func__(mvc *sql, struct objectset *ff, const char *fname, list *ops, sql_ftype type, bool private, bool exact)
652 : {
653 639364 : sql_ftype filt = (type == F_FUNC)?F_FILT:type;
654 639364 : sql_subtype *input_type = NULL;
655 639364 : sql_func *cand = NULL, *dcand = NULL;
656 639364 : int points = 0, dpoints = 0;
657 :
658 639364 : if (ops && ops->h)
659 606707 : input_type = ops->h->data;
660 :
661 639364 : if (ff) {
662 639364 : struct os_iter oi;
663 639364 : os_iterator(&oi, ff, sql->session->tr, fname);
664 2141985 : for (sql_base *b = oi_next(&oi); b; b=oi_next(&oi)) {
665 1502621 : sql_func *f = (sql_func*)b;
666 1502621 : bool downcast = false;
667 :
668 1502621 : if ((f->type != type && f->type != filt) || (f->private && !private))
669 475399 : continue;
670 1027222 : if (strcmp(f->base.name, fname) == 0 && ((!exact && (list_length(f->ops) == list_length(ops) || (list_length(f->ops) <= list_length(ops) && f->vararg))) || (exact && list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 0))) {
671 334699 : int npoints = score_func(f, ops, exact, &downcast);
672 334699 : if (downcast) {
673 2563 : if ((!dcand && (npoints || exact)) || (dcand && npoints > dpoints)) {
674 1027222 : dcand = f;
675 1027222 : dpoints = npoints;
676 : }
677 : } else {
678 332136 : if ((!cand && (npoints || exact)) || (cand && npoints > points)) {
679 1027222 : cand = f;
680 1027222 : points = npoints;
681 : }
682 : }
683 : }
684 : }
685 : }
686 639364 : if (!cand && dcand)
687 302 : cand = dcand;
688 639364 : if (cand && exact && type != F_AGGR)
689 167696 : return sql_dup_subfunc(sql->sa, cand, ops, NULL);
690 471668 : if (cand)
691 : //return (type == F_AGGR) ? _dup_subaggr(sql->sa, cand, input_type) : sql_dup_subfunc(sql->sa, cand, ops, NULL);
692 255345 : return _dup_subaggr(sql->sa, cand, (type == F_AGGR) ?input_type: NULL);
693 : return NULL;
694 : }
695 :
696 : #define sql_bind_func__extra \
697 : do { \
698 : if (!res && (res = sql_bind_func__(sql, funcs, name, ops, type, private, exact))) /* search system wide functions first */ \
699 : return res; \
700 : } while (0)
701 :
702 : sql_subfunc *
703 1582497 : sql_bind_func_(mvc *sql, const char *sname, const char *name, list *ops, sql_ftype type, bool private, bool exact)
704 : {
705 1582497 : char *F = NULL, *objstr = NULL;
706 1582497 : const char error[] = "CATALOG";
707 1582497 : sql_subfunc *res = NULL;
708 :
709 1582497 : FUNC_TYPE_STR(type, F, objstr);
710 1582497 : (void) F; /* not used */
711 :
712 1584037 : search_object_on_path(res = os_bind_func__(sql, next->funcs, name, ops, type, private, exact), functions_without_schema, sql_bind_func__extra, SQLSTATE(42000), true);
713 : return res;
714 : }
715 :
716 : static sql_subfunc *
717 40572 : sql_bind_func_result_internal(mvc *sql, list *ff, const char *fname, sql_ftype type, bool private, list *ops, sql_subtype *res)
718 : {
719 40572 : sql_subtype *tp = sql_bind_localtype("bit");
720 40561 : sql_func *cand = NULL;
721 40561 : int points = 0, npoints = 0;
722 :
723 40561 : if (ff) {
724 40561 : if (ff->ht) {
725 40561 : int key = hash_key(fname);
726 40561 : sql_hash_e *he = ff->ht->buckets[key&(ff->ht->size-1)];
727 143589 : for (; he; he = he->chain) {
728 102991 : sql_func *f = he->value;
729 102991 : sql_arg *firstres = NULL;
730 :
731 102991 : if ((!f->res && !IS_FILT(f)) || (f->private && !private))
732 0 : continue;
733 102991 : firstres = IS_FILT(f)?tp->type:f->res->h->data;
734 102991 : if (strcmp(f->base.name, fname) == 0 && f->type == type && (is_subtype(&firstres->type, res) || firstres->type.type->eclass == EC_ANY) && list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 0) {
735 40595 : npoints = next_cand_points(f->ops, ops);
736 :
737 40594 : if (!cand || npoints > points) {
738 103028 : cand = f;
739 103028 : points = npoints;
740 : }
741 : }
742 : }
743 : } else {
744 0 : node *n;
745 0 : sql_base_loop( ff, n) {
746 0 : sql_func *f = n->data;
747 0 : sql_arg *firstres = NULL;
748 :
749 0 : if ((!f->res && !IS_FILT(f)) || (f->private && !private))
750 0 : continue;
751 0 : firstres = IS_FILT(f)?tp->type:f->res->h->data;
752 0 : if (strcmp(f->base.name, fname) == 0 && f->type == type && (is_subtype(&firstres->type, res) || firstres->type.type->eclass == EC_ANY) && list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 0) {
753 0 : npoints = next_cand_points(f->ops, ops);
754 :
755 0 : if (!cand || npoints > points) {
756 0 : cand = f;
757 0 : points = npoints;
758 : }
759 : }
760 : }
761 : }
762 : }
763 40598 : if (cand)
764 40597 : return (type == F_AGGR) ? _dup_subaggr(sql->sa, cand, NULL) : sql_dup_subfunc(sql->sa, cand, ops, NULL);
765 : return NULL;
766 : }
767 :
768 : static sql_subfunc *
769 1 : os_bind_func_result_internal(mvc *sql, struct objectset *ff, const char *fname, sql_ftype type, bool private, list *ops, sql_subtype *res)
770 : {
771 1 : sql_subtype *tp = sql_bind_localtype("bit");
772 1 : sql_func *cand = NULL;
773 1 : int points = 0, npoints = 0;
774 :
775 1 : if (ff) {
776 1 : struct os_iter oi;
777 1 : os_iterator(&oi, ff, sql->session->tr, fname);
778 2 : for (sql_base *b = oi_next(&oi); b; b=oi_next(&oi)) {
779 1 : sql_func *f = (sql_func*)b;
780 1 : sql_arg *firstres = NULL;
781 :
782 1 : if ((!f->res && !IS_FILT(f)) || (f->private && !private))
783 0 : continue;
784 1 : firstres = IS_FILT(f)?tp->type:f->res->h->data;
785 1 : if (strcmp(f->base.name, fname) == 0 && f->type == type && (is_subtype(&firstres->type, res) || firstres->type.type->eclass == EC_ANY) && list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 0) {
786 1 : npoints = next_cand_points(f->ops, ops);
787 :
788 1 : if (!cand || npoints > points) {
789 1 : cand = f;
790 1 : points = npoints;
791 : }
792 : }
793 : }
794 : }
795 1 : if (cand)
796 1 : return (type == F_AGGR) ? _dup_subaggr(sql->sa, cand, NULL) : sql_dup_subfunc(sql->sa, cand, ops, NULL);
797 : return NULL;
798 : }
799 :
800 : #define sql_bind_func_result_extra \
801 : do { \
802 : if (!res) \
803 : res = sql_bind_func_result_internal(sql, funcs, name, type, private, ops, r_res); /* search system wide functions first */ \
804 : } while (0)
805 :
806 :
807 : sql_subfunc *
808 40565 : sql_bind_func_result(mvc *sql, const char *sname, const char *name, sql_ftype type, bool private, sql_subtype *r_res, int nargs, ...)
809 : {
810 40565 : char *F = NULL, *objstr = NULL;
811 40565 : const char error[] = "CATALOG";
812 40565 : sql_subfunc *res = NULL;
813 40565 : list *ops = sa_list(sql->sa);
814 40585 : va_list valist;
815 :
816 40585 : FUNC_TYPE_STR(type, F, objstr);
817 40585 : (void) F; /* not used */
818 :
819 40585 : va_start(valist, nargs);
820 123239 : for (int i = 0; i < nargs; i++) {
821 82642 : sql_type *tpe = va_arg(valist, sql_type*);
822 82651 : list_append(ops, tpe);
823 : }
824 40597 : va_end(valist);
825 :
826 40597 : search_object_on_path(res = os_bind_func_result_internal(sql, next->funcs, name, type, private, ops, r_res), functions_without_schema, sql_bind_func_result_extra, SQLSTATE(42000), true);
827 40599 : if (res) /* make sure we have the correct result type */
828 40599 : res->res->h->data = r_res;
829 40599 : return res;
830 : }
831 :
832 : static list *
833 5273 : sql_find_funcs_by_name_internal(mvc *sql, list *ff, const char *fname, sql_ftype type, bool private)
834 : {
835 5273 : int key = hash_key(fname);
836 5273 : list *res = NULL;
837 :
838 5273 : if (ff) {
839 5273 : if (ff->ht) {
840 5273 : for (sql_hash_e *he = ff->ht->buckets[key&(ff->ht->size-1)]; he; he = he->chain) {
841 0 : sql_func *f = he->value;
842 :
843 0 : if (f->type != type || (f->private && !private))
844 0 : continue;
845 0 : if (strcmp(f->base.name, fname) == 0) {
846 0 : if (!res)
847 0 : res = sa_list(sql->sa);
848 0 : list_append(res, f);
849 : }
850 : }
851 : } else {
852 0 : node *n;
853 0 : sql_base_loop( ff, n) {
854 0 : sql_func *f = n->data;
855 :
856 0 : if (f->type != type || (f->private && !private))
857 0 : continue;
858 0 : if (strcmp(f->base.name, fname) == 0) {
859 0 : if (!res)
860 0 : res = sa_list(sql->sa);
861 0 : list_append(res, f);
862 : }
863 : }
864 : }
865 : }
866 5273 : return res;
867 : }
868 :
869 : static list *
870 9107 : os_find_funcs_by_name_internal(mvc *sql, struct objectset *ff, const char *fname, sql_ftype type, bool private)
871 : {
872 9107 : list *res = NULL;
873 :
874 9107 : if (ff) {
875 9107 : struct os_iter oi;
876 9107 : os_iterator(&oi, ff, sql->session->tr, fname);
877 14881 : for (sql_base *b = oi_next(&oi); b; b=oi_next(&oi)) {
878 5774 : sql_func *f = (sql_func*)b;
879 :
880 5774 : if (f->type != type || (f->private && !private))
881 1333 : continue;
882 4441 : if (strcmp(f->base.name, fname) == 0) {
883 4441 : if (!res)
884 4413 : res = sa_list(sql->sa);
885 4441 : list_append(res, f);
886 : }
887 : }
888 : }
889 9107 : return res;
890 : }
891 :
892 : #define sql_find_funcs_by_name_extra \
893 : do { \
894 : if (!res && (res = sql_find_funcs_by_name_internal(sql, funcs, name, type, private))) /* search system wide functions first */ \
895 : return res; \
896 : } while (0)
897 :
898 : list *
899 5748 : sql_find_funcs_by_name(mvc *sql, const char *sname, const char *name, sql_ftype type, bool private)
900 : {
901 5748 : char *F = NULL, *objstr = NULL;
902 5748 : const char error[] = "CATALOG";
903 5748 : list *res = NULL;
904 :
905 5748 : FUNC_TYPE_STR(type, F, objstr);
906 5748 : (void) F; /* not used */
907 :
908 6096 : search_object_on_path(res = os_find_funcs_by_name_internal(sql, next->funcs, name, type, private), functions_without_schema, sql_find_funcs_by_name_extra, "", false);
909 : return res;
910 : }
911 :
912 : char *
913 1974857 : qname_schema(dlist *qname)
914 : {
915 1974857 : assert(qname && qname->h);
916 :
917 1974857 : if (dlist_length(qname) == 2) {
918 1161314 : return qname->h->data.sval;
919 813634 : } else if (dlist_length(qname) == 3) {
920 4 : return qname->h->next->data.sval;
921 : }
922 : return NULL;
923 : }
924 :
925 : char *
926 1985452 : qname_schema_object(dlist *qname)
927 : {
928 1985452 : assert(qname && qname->h);
929 :
930 1985452 : if (dlist_length(qname) == 1) {
931 823766 : return qname->h->data.sval;
932 1161616 : } else if (dlist_length(qname) == 2) {
933 1161612 : return qname->h->next->data.sval;
934 4 : } else if (dlist_length(qname) == 3) {
935 4 : return qname->h->next->next->data.sval;
936 : }
937 : return "unknown";
938 : }
939 :
940 : char *
941 0 : qname_catalog(dlist *qname)
942 : {
943 0 : assert(qname && qname->h);
944 :
945 0 : if (dlist_length(qname) == 3) {
946 0 : return qname->h->data.sval;
947 : }
948 : return NULL;
949 : }
950 :
951 : int
952 1559 : set_type_param(mvc *sql, sql_subtype *type, int nr)
953 : {
954 1559 : sql_arg *a = sql_bind_paramnr(sql, nr);
955 :
956 1559 : if (!a)
957 : return -1;
958 1559 : a->type = *type;
959 1559 : return 0;
960 : }
961 :
962 : /*
963 : * Find the result_datatype for certain combinations of values
964 : * (like case expressions or columns in a result of a query expression).
965 : * See standaard pages 505-507 Result of data type combinations */
966 : sql_subtype *
967 207826 : result_datatype(sql_subtype *super, sql_subtype *l, sql_subtype *r)
968 : {
969 207826 : int lclass = l->type->eclass, rclass = r->type->eclass;
970 :
971 : /* case a strings */
972 290064 : if (EC_VARCHAR(lclass) || EC_VARCHAR(rclass)) {
973 82238 : const char *tpe = "varchar";
974 82238 : unsigned int digits = 0;
975 82238 : if (!EC_VARCHAR(lclass)) {
976 492 : tpe = r->type->base.name;
977 492 : digits = (!l->digits)?0:r->digits;
978 81746 : } else if (!EC_VARCHAR(rclass)) {
979 5184 : tpe = l->type->base.name;
980 5184 : digits = (!r->digits)?0:l->digits;
981 : } else { /* both */
982 76562 : tpe = !strcmp(l->type->base.name, "varchar")?l->type->base.name:!strcmp(r->type->base.name, "varchar")?r->type->base.name:
983 7 : (l->type->base.id > r->type->base.id)?l->type->base.name:r->type->base.name;
984 76562 : digits = (!l->digits||!r->digits)?0:sql_max(l->digits, r->digits);
985 : }
986 82238 : sql_find_subtype(super, tpe, digits, 0);
987 : /* case b blob */
988 125588 : } else if (lclass == EC_BLOB || rclass == EC_BLOB) {
989 14 : *super = (lclass == EC_BLOB) ? *l : *r;
990 : /* case c all exact numeric */
991 223679 : } else if (EC_EXACTNUM(lclass) && EC_EXACTNUM(rclass)) {
992 98105 : char *tpe = (l->type->base.id > r->type->base.id)?l->type->base.name:r->type->base.name;
993 98105 : unsigned int digits = sql_max(l->digits, r->digits);
994 98105 : unsigned int scale = sql_max(l->scale, r->scale);
995 :
996 98105 : if (l->type->radix == 10 && r->type->radix == 10) {
997 90 : digits = scale + (sql_max(l->digits - l->scale, r->digits - r->scale));
998 : #ifdef HAVE_HGE
999 90 : if (digits > 38) {
1000 0 : digits = 38;
1001 : #else
1002 : if (digits > 18) {
1003 : digits = 18;
1004 : #endif
1005 0 : scale = MIN(scale, digits - 1);
1006 : }
1007 98015 : } else if (l->type->radix == 2 && r->type->radix == 10) { /* change to radix 10 */
1008 47 : digits = bits2digits(l->type->digits);
1009 47 : digits = sql_max(r->digits, digits);
1010 47 : scale = r->scale;
1011 97968 : } else if (l->type->radix == 10 && r->type->radix == 2) { /* change to radix 10 */
1012 121 : digits = bits2digits(r->type->digits);
1013 121 : digits = sql_max(l->digits, digits);
1014 121 : scale = l->scale;
1015 : }
1016 98105 : sql_find_subtype(super, tpe, digits, scale);
1017 : /* case d approximate numeric */
1018 27469 : } else if (EC_APPNUM(lclass) || EC_APPNUM(rclass)) {
1019 157 : if (!EC_APPNUM(lclass)) {
1020 45 : *super = *r;
1021 112 : } else if (!EC_APPNUM(rclass)) {
1022 91 : *super = *l;
1023 : } else { /* both */
1024 21 : char *tpe = (l->type->base.id > r->type->base.id)?l->type->base.name:r->type->base.name;
1025 21 : unsigned int digits = sql_max(l->digits, r->digits); /* bits precision */
1026 21 : sql_find_subtype(super, tpe, digits, 0);
1027 : }
1028 : /* now its getting serious, ie e any 'case e' datetime data type */
1029 : /* 'case f' interval types */
1030 : /* 'case g' boolean */
1031 : /* 'case h-l' compounds like row (tuple), etc */
1032 : } else {
1033 27312 : return supertype(super, l, r);
1034 : }
1035 : return super;
1036 : }
1037 :
1038 : char *
1039 80 : toUpperCopy(char *dest, const char *src)
1040 : {
1041 80 : size_t i, len;
1042 :
1043 80 : if (src == NULL) {
1044 0 : *dest = '\0';
1045 0 : return(dest);
1046 : }
1047 :
1048 80 : len = _strlen(src);
1049 433 : for (i = 0; i < len; i++)
1050 353 : dest[i] = (char)toupper((int)src[i]);
1051 :
1052 80 : dest[i] = '\0';
1053 80 : return(dest);
1054 : }
1055 :
1056 : static char * _symbol2string(mvc *sql, symbol *se, int expression, char **err);
1057 :
1058 : static char *
1059 1 : dlist2string(mvc *sql, dlist *l, int expression, char **err)
1060 : {
1061 1 : char *b = NULL;
1062 1 : dnode *n;
1063 :
1064 3 : for (n=l->h; n; n = n->next) {
1065 2 : char *s = NULL;
1066 :
1067 2 : if (n->type == type_string && n->data.sval)
1068 2 : s = sa_strdup(sql->ta, n->data.sval);
1069 0 : else if (n->type == type_symbol)
1070 0 : s = _symbol2string(sql, n->data.sym, expression, err);
1071 :
1072 2 : if (!s)
1073 0 : return NULL;
1074 2 : if (b) {
1075 1 : char *o = SA_NEW_ARRAY(sql->ta, char, strlen(b) + strlen(s) + 2);
1076 1 : if (o)
1077 1 : stpcpy(stpcpy(stpcpy(o, b), "."), s);
1078 0 : b = o;
1079 1 : if (b == NULL)
1080 : return NULL;
1081 : } else {
1082 : b = s;
1083 : }
1084 : }
1085 : return b;
1086 : }
1087 :
1088 : static const char *
1089 876 : symbol_escape_ident(allocator *sa, const char *s)
1090 : {
1091 876 : char *res = NULL;
1092 876 : if (s) {
1093 824 : size_t l = strlen(s);
1094 824 : char *r = SA_NEW_ARRAY(sa, char, (l * 2) + 1);
1095 :
1096 824 : res = r;
1097 6094 : while (*s) {
1098 5270 : if (*s == '"')
1099 1 : *r++ = '"';
1100 5270 : *r++ = *s++;
1101 : }
1102 824 : *r = '\0';
1103 : }
1104 876 : return res;
1105 : }
1106 :
1107 : char *
1108 1584 : _symbol2string(mvc *sql, symbol *se, int expression, char **err)
1109 : {
1110 : /* inner symbol2string uses the temporary allocator */
1111 1584 : switch (se->token) {
1112 153 : case SQL_NOP: {
1113 153 : dnode *lst = se->data.lval->h, *ops = NULL, *aux;
1114 153 : const char *op = symbol_escape_ident(sql->ta, qname_schema_object(lst->data.lval)),
1115 153 : *sname = symbol_escape_ident(sql->ta, qname_schema(lst->data.lval));
1116 153 : int i = 0, nargs = 0;
1117 153 : char** inputs = NULL, *res;
1118 153 : size_t inputs_length = 0, extra = sname ? strlen(sname) + 3 : 0;
1119 :
1120 153 : if (lst->next->next->data.lval)
1121 113 : ops = lst->next->next->data.lval->h;
1122 :
1123 294 : for (aux = ops; aux; aux = aux->next)
1124 141 : nargs++;
1125 153 : if (!(inputs = SA_ZNEW_ARRAY(sql->ta, char*, nargs)))
1126 : return NULL;
1127 :
1128 289 : for (aux = ops; aux; aux = aux->next) {
1129 139 : if (!(inputs[i] = _symbol2string(sql, aux->data.sym, expression, err))) {
1130 : return NULL;
1131 : }
1132 136 : inputs_length += strlen(inputs[i]);
1133 136 : i++;
1134 : }
1135 :
1136 300 : if ((res = SA_NEW_ARRAY(sql->ta, char, extra + strlen(op) + inputs_length + 3 + (nargs - 1 /* commas */) + 2))) {
1137 150 : char *concat = res;
1138 150 : if (sname)
1139 100 : concat = stpcpy(stpcpy(stpcpy(res, "\""), sname), "\".");
1140 150 : concat = stpcpy(stpcpy(stpcpy(concat, "\""), op), "\"(");
1141 150 : i = 0;
1142 286 : for (aux = ops; aux; aux = aux->next) {
1143 136 : concat = stpcpy(concat, inputs[i]);
1144 136 : if (aux->next)
1145 26 : concat = stpcpy(concat, ",");
1146 136 : i++;
1147 : }
1148 150 : concat = stpcpy(concat, ")");
1149 : }
1150 : return res;
1151 : }
1152 0 : case SQL_PARAMETER:
1153 0 : return sa_strdup(sql->ta, "?");
1154 193 : case SQL_NULL:
1155 193 : return sa_strdup(sql->ta, "NULL");
1156 : case SQL_ATOM:{
1157 929 : AtomNode *an = (AtomNode *) se;
1158 929 : if (an && an->a)
1159 929 : return atom2sql(sql->ta, an->a, sql->timezone);
1160 : else
1161 0 : return sa_strdup(sql->ta, "NULL");
1162 : }
1163 269 : case SQL_NEXT: {
1164 269 : const char *seq = symbol_escape_ident(sql->ta, qname_schema_object(se->data.lval)),
1165 269 : *sname = qname_schema(se->data.lval);
1166 269 : char *res;
1167 :
1168 269 : if (!sname)
1169 200 : sname = sql->session->schema->base.name;
1170 269 : sname = symbol_escape_ident(sql->ta, sname);
1171 :
1172 538 : if ((res = SA_NEW_ARRAY(sql->ta, char, strlen("next value for \"") + strlen(sname) + strlen(seq) + 5)))
1173 269 : stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "next value for \""), sname), "\".\""), seq), "\"");
1174 : return res;
1175 33 : } break;
1176 33 : case SQL_IDENT:
1177 : case SQL_COLUMN: {
1178 : /* can only be variables */
1179 33 : dlist *l = se->data.lval;
1180 33 : assert(l->h->type != type_lng);
1181 33 : if (expression && dlist_length(l) == 1 && l->h->type == type_string) {
1182 : /* when compiling an expression, a column of a table might be present in the symbol, so we need this case */
1183 32 : const char *op = symbol_escape_ident(sql->ta, l->h->data.sval);
1184 32 : char *res;
1185 :
1186 64 : if ((res = SA_NEW_ARRAY(sql->ta, char, strlen(op) + 3)))
1187 32 : stpcpy(stpcpy(stpcpy(res, "\""), op), "\"");
1188 32 : return res;
1189 0 : } else if (expression && dlist_length(l) == 2 && l->h->type == type_string && l->h->next->type == type_string) {
1190 0 : const char *first = symbol_escape_ident(sql->ta, l->h->data.sval),
1191 0 : *second = symbol_escape_ident(sql->ta, l->h->next->data.sval);
1192 0 : char *res;
1193 :
1194 0 : if (!first || !second)
1195 : return NULL;
1196 0 : if ((res = SA_NEW_ARRAY(sql->ta, char, strlen(first) + strlen(second) + 6)))
1197 0 : stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "\""), first), "\".\""), second), "\"");
1198 0 : return res;
1199 : } else {
1200 1 : char *e = dlist2string(sql, l, expression, err);
1201 1 : if (e)
1202 1 : *err = e;
1203 1 : return NULL;
1204 : }
1205 : }
1206 6 : case SQL_CAST: {
1207 6 : dlist *dl = se->data.lval;
1208 6 : char *val = NULL, *tpe = NULL, *res;
1209 :
1210 6 : if (!(val = _symbol2string(sql, dl->h->data.sym, expression, err)) || !(tpe = subtype2string2(sql->ta, &dl->h->next->data.typeval)))
1211 0 : return NULL;
1212 12 : if ((res = SA_NEW_ARRAY(sql->ta, char, strlen(val) + strlen(tpe) + 11)))
1213 6 : stpcpy(stpcpy(stpcpy(stpcpy(stpcpy(res, "cast("), val), " as "), tpe), ")");
1214 : return res;
1215 : }
1216 1 : default: {
1217 1 : const char msg[] = "SQL feature not yet available for expressions and default values: ";
1218 1 : char *tok_str = token2string(se->token);
1219 2 : if ((*err = SA_NEW_ARRAY(sql->ta, char, strlen(msg) + strlen(tok_str) + 1)))
1220 1 : stpcpy(stpcpy(*err, msg), tok_str);
1221 : }
1222 : }
1223 1 : return NULL;
1224 : }
1225 :
1226 : char *
1227 1439 : symbol2string(mvc *sql, symbol *se, int expression, char **err)
1228 : {
1229 1439 : char *res = _symbol2string(sql, se, expression, err);
1230 :
1231 1439 : if (res)
1232 1437 : res = sa_strdup(sql->sa, res);
1233 1439 : if (*err)
1234 2 : *err = sa_strdup(sql->sa, *err);
1235 1439 : sa_reset(sql->ta);
1236 1439 : return res;
1237 : }
|