1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9#include "monetdb_config.h"
10#include "sql_relation.h"
11#include "sql_semantic.h"
12#include "rel_exp.h"
13#include "rel_rel.h"
14#include "rel_prop.h" /* for prop_copy() */
15#include "rel_unnest.h"
16#include "rel_optimizer.h"
17#include "rel_distribute.h"
18#ifdef HAVE_HGE
19#include "mal.h" /* for have_hge */
20#endif
21#include "mtime.h"
22#include "blob.h"
23
24comp_type
25compare_str2type( char *compare_op)
26{
27 comp_type type = cmp_filter;
28
29 if (compare_op[0] == '=') {
30 type = cmp_equal;
31 } else if (compare_op[0] == '<') {
32 type = cmp_lt;
33 if (compare_op[1] != '\0') {
34 if (compare_op[1] == '>')
35 type = cmp_notequal;
36 else if (compare_op[1] == '=')
37 type = cmp_lte;
38 }
39 } else if (compare_op[0] == '>') {
40 type = cmp_gt;
41 if (compare_op[1] != '\0')
42 if (compare_op[1] == '=')
43 type = cmp_gte;
44 }
45 return type;
46}
47
48comp_type
49swap_compare( comp_type t )
50{
51 switch(t) {
52 case cmp_equal:
53 return cmp_equal;
54 case cmp_lt:
55 return cmp_gt;
56 case cmp_lte:
57 return cmp_gte;
58 case cmp_gte:
59 return cmp_lte;
60 case cmp_gt:
61 return cmp_lt;
62 case cmp_notequal:
63 return cmp_notequal;
64 default:
65 return cmp_equal;
66 }
67}
68
69comp_type
70range2lcompare( int r )
71{
72 if (r&1) {
73 return cmp_gte;
74 } else {
75 return cmp_gt;
76 }
77}
78
79comp_type
80range2rcompare( int r )
81{
82 if (r&2) {
83 return cmp_lte;
84 } else {
85 return cmp_lt;
86 }
87}
88
89int
90compare2range( int l, int r )
91{
92 if (l == cmp_gt) {
93 if (r == cmp_lt)
94 return 0;
95 else if (r == cmp_lte)
96 return 2;
97 } else if (l == cmp_gte) {
98 if (r == cmp_lt)
99 return 1;
100 else if (r == cmp_lte)
101 return 3;
102 }
103 return -1;
104}
105
106static sql_exp *
107exp_create(sql_allocator *sa, int type )
108{
109 sql_exp *e = SA_NEW(sa, sql_exp);
110
111 if (e == NULL)
112 return NULL;
113 e->type = (expression_type)type;
114 e->alias.label = 0;
115 e->alias.name = NULL;
116 e->alias.rname = NULL;
117 e->f = e->l = e->r = NULL;
118 e->flag = 0;
119 e->card = 0;
120 e->freevar = 0;
121 e->intern = 0;
122 e->anti = 0;
123 e->base = 0;
124 e->used = 0;
125 e->tpe.type = NULL;
126 e->tpe.digits = e->tpe.scale = 0;
127 e->p = NULL;
128 return e;
129}
130
131sql_exp *
132exp_compare(sql_allocator *sa, sql_exp *l, sql_exp *r, int cmptype)
133{
134 sql_exp *e = exp_create(sa, e_cmp);
135 if (e == NULL)
136 return NULL;
137 e->card = MAX(l->card,r->card);
138 if (e->card == CARD_ATOM && !exp_is_atom(l))
139 e->card = CARD_AGGR;
140 e->l = l;
141 e->r = r;
142 e->flag = cmptype;
143 return e;
144}
145
146sql_exp *
147exp_compare2(sql_allocator *sa, sql_exp *l, sql_exp *r, sql_exp *h, int cmptype)
148{
149 sql_exp *e = exp_create(sa, e_cmp);
150 if (e == NULL)
151 return NULL;
152 e->card = l->card;
153 if (e->card == CARD_ATOM && !exp_is_atom(l))
154 e->card = CARD_AGGR;
155 e->l = l;
156 e->r = r;
157 if (h)
158 e->f = h;
159 e->flag = cmptype;
160 return e;
161}
162
163sql_exp *
164exp_filter(sql_allocator *sa, list *l, list *r, sql_subfunc *f, int anti)
165{
166 sql_exp *e = exp_create(sa, e_cmp);
167
168 if (e == NULL)
169 return NULL;
170 e->card = exps_card(l);
171 e->l = l;
172 e->r = r;
173 e->f = f;
174 e->flag = cmp_filter;
175 if (anti)
176 set_anti(e);
177 return e;
178}
179
180sql_exp *
181exp_or(sql_allocator *sa, list *l, list *r, int anti)
182{
183 sql_exp *f = NULL;
184 sql_exp *e = exp_create(sa, e_cmp);
185
186 if (e == NULL)
187 return NULL;
188 f = l->h?l->h->data:r->h?r->h->data:NULL;
189 e->card = l->h?exps_card(l):exps_card(r);
190 e->l = l;
191 e->r = r;
192 assert(f);
193 e->f = f;
194 e->flag = cmp_or;
195 if (anti)
196 set_anti(e);
197 return e;
198}
199
200sql_exp *
201exp_in(sql_allocator *sa, sql_exp *l, list *r, int cmptype)
202{
203 sql_exp *e = exp_create(sa, e_cmp);
204
205 if (e == NULL)
206 return NULL;
207 e->card = l->card;
208 e->l = l;
209 e->r = r;
210 assert( cmptype == cmp_in || cmptype == cmp_notin);
211 e->flag = cmptype;
212 return e;
213}
214
215sql_exp *
216exp_in_func(mvc *sql, sql_exp *le, sql_exp *vals, int anyequal, int is_tuple)
217{
218 sql_subfunc *a_func = NULL;
219 sql_exp *e = le;
220
221 if (is_tuple) {
222 list *l = exp_get_values(e);
223 e = l->h->data;
224 }
225 if (anyequal)
226 a_func = sql_bind_func(sql->sa, sql->session->schema, "sql_anyequal", exp_subtype(e), exp_subtype(e), F_FUNC);
227 else
228 a_func = sql_bind_func(sql->sa, sql->session->schema, "sql_not_anyequal", exp_subtype(e), exp_subtype(e), F_FUNC);
229
230 if (!a_func)
231 return sql_error(sql, 02, SQLSTATE(42000) "(NOT) IN operator on type %s missing", exp_subtype(le)->type->sqlname);
232 e = exp_binop(sql->sa, le, vals, a_func);
233 if (e)
234 e->card = le->card;
235 return e;
236}
237
238sql_exp *
239exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, sql_exp *oe, char *compareop, int quantifier)
240{
241 sql_subfunc *cmp_func = NULL;
242 sql_exp *e;
243
244 if (!oe) {
245 cmp_func = sql_bind_func(sql->sa, NULL, compareop, exp_subtype(le), exp_subtype(le), F_FUNC);
246 assert(cmp_func);
247 e = exp_binop(sql->sa, le, re, cmp_func);
248 } else {
249 list *types = sa_list(sql->sa), *args = sa_list(sql->sa);
250 append(types, exp_subtype(le));
251 append(types, exp_subtype(le));
252 append(types, exp_subtype(le));
253 append(args, le);
254 append(args, re);
255 append(args, oe);
256 cmp_func = sql_bind_func_(sql->sa, NULL, compareop, types, F_FUNC);
257 assert(cmp_func);
258 e = exp_op(sql->sa, args, cmp_func);
259 }
260 if (e) {
261 e->flag = quantifier;
262 e->card = le->card;
263 }
264 return e;
265}
266
267static sql_subtype*
268dup_subtype(sql_allocator *sa, sql_subtype *st)
269{
270 sql_subtype *res = SA_NEW(sa, sql_subtype);
271
272 if (res == NULL)
273 return NULL;
274 *res = *st;
275 return res;
276}
277
278sql_exp *
279exp_convert(sql_allocator *sa, sql_exp *exp, sql_subtype *fromtype, sql_subtype *totype )
280{
281 sql_exp *e = exp_create(sa, e_convert);
282 if (e == NULL)
283 return NULL;
284 e->card = exp->card;
285 e->l = exp;
286 totype = dup_subtype(sa, totype);
287 e->r = append(append(sa_list(sa), dup_subtype(sa, fromtype)),totype);
288 e->tpe = *totype;
289 e->alias = exp->alias;
290 return e;
291}
292
293sql_exp *
294exp_op( sql_allocator *sa, list *l, sql_subfunc *f )
295{
296 sql_exp *e = exp_create(sa, e_func);
297 if (e == NULL)
298 return NULL;
299 e->card = exps_card(l);
300 if (!l || list_length(l) == 0)
301 e->card = CARD_ATOM; /* unop returns a single atom */
302 e->l = l;
303 e->f = f;
304 return e;
305}
306
307sql_exp *
308exp_rank_op( sql_allocator *sa, list *l, list *gbe, list *obe, sql_subfunc *f )
309{
310 sql_exp *e = exp_create(sa, e_func);
311 if (e == NULL)
312 return NULL;
313 e->card = exps_card(l);
314 if (!l || list_length(l) == 0)
315 e->card = CARD_ATOM; /* unop returns a single atom */
316 e->l = l;
317 e->r = append(append(sa_list(sa), gbe), obe);
318 e->f = f;
319 return e;
320}
321
322sql_exp *
323exp_aggr( sql_allocator *sa, list *l, sql_subaggr *a, int distinct, int no_nils, unsigned int card, int has_nils )
324{
325 sql_exp *e = exp_create(sa, e_aggr);
326 if (e == NULL)
327 return NULL;
328 e->card = card;
329 e->l = l;
330 e->f = a;
331 if (distinct)
332 set_distinct(e);
333 if (no_nils)
334 set_no_nil(e);
335 if (!has_nils)
336 set_has_no_nil(e);
337 return e;
338}
339
340sql_exp *
341exp_atom(sql_allocator *sa, atom *a)
342{
343 sql_exp *e = exp_create(sa, e_atom);
344 if (e == NULL)
345 return NULL;
346 e->card = CARD_ATOM;
347 e->tpe = a->tpe;
348 e->l = a;
349 return e;
350}
351
352sql_exp *
353exp_atom_max(sql_allocator *sa, sql_subtype *tpe)
354{
355
356 if (tpe->type->localtype == TYPE_bte) {
357 return exp_atom_bte(sa, GDK_bte_max);
358 } else if (tpe->type->localtype == TYPE_sht) {
359 return exp_atom_sht(sa, GDK_sht_max);
360 } else if (tpe->type->localtype == TYPE_int) {
361 return exp_atom_int(sa, GDK_int_max);
362 } else if (tpe->type->localtype == TYPE_lng) {
363 return exp_atom_lng(sa, GDK_lng_max);
364#ifdef HAVE_HGE
365 } else if (tpe->type->localtype == TYPE_hge) {
366 return exp_atom_hge(sa, GDK_hge_max);
367#endif
368 }
369 return NULL;
370}
371
372sql_exp *
373exp_atom_bool(sql_allocator *sa, int b)
374{
375 sql_subtype bt;
376
377 sql_find_subtype(&bt, "boolean", 0, 0);
378 if (b)
379 return exp_atom(sa, atom_bool(sa, &bt, TRUE ));
380 else
381 return exp_atom(sa, atom_bool(sa, &bt, FALSE ));
382}
383
384sql_exp *
385exp_atom_bte(sql_allocator *sa, bte i)
386{
387 sql_subtype it;
388
389 sql_find_subtype(&it, "tinyint", 3, 0);
390 return exp_atom(sa, atom_int(sa, &it, i ));
391}
392
393sql_exp *
394exp_atom_sht(sql_allocator *sa, sht i)
395{
396 sql_subtype it;
397
398 sql_find_subtype(&it, "smallint", 5, 0);
399 return exp_atom(sa, atom_int(sa, &it, i ));
400}
401
402sql_exp *
403exp_atom_int(sql_allocator *sa, int i)
404{
405 sql_subtype it;
406
407 sql_find_subtype(&it, "int", 9, 0);
408 return exp_atom(sa, atom_int(sa, &it, i ));
409}
410
411sql_exp *
412exp_atom_lng(sql_allocator *sa, lng i)
413{
414 sql_subtype it;
415
416#ifdef HAVE_HGE
417 sql_find_subtype(&it, "bigint", have_hge ? 18 : 19, 0);
418#else
419 sql_find_subtype(&it, "bigint", 19, 0);
420#endif
421 return exp_atom(sa, atom_int(sa, &it, i ));
422}
423
424#ifdef HAVE_HGE
425sql_exp *
426exp_atom_hge(sql_allocator *sa, hge i)
427{
428 sql_subtype it;
429
430 sql_find_subtype(&it, "hugeint", 39, 0);
431 return exp_atom(sa, atom_int(sa, &it, i ));
432}
433#endif
434
435sql_exp *
436exp_atom_flt(sql_allocator *sa, flt f)
437{
438 sql_subtype it;
439
440 sql_find_subtype(&it, "real", 24, 0);
441 return exp_atom(sa, atom_float(sa, &it, (dbl)f ));
442}
443
444sql_exp *
445exp_atom_dbl(sql_allocator *sa, dbl f)
446{
447 sql_subtype it;
448
449 sql_find_subtype(&it, "double", 53, 0);
450 return exp_atom(sa, atom_float(sa, &it, (dbl)f ));
451}
452
453sql_exp *
454exp_atom_str(sql_allocator *sa, const char *s, sql_subtype *st)
455{
456 return exp_atom(sa, atom_string(sa, st, s?sa_strdup(sa, s):NULL));
457}
458
459sql_exp *
460exp_atom_clob(sql_allocator *sa, const char *s)
461{
462 sql_subtype clob;
463
464 sql_find_subtype(&clob, "clob", 0, 0);
465 return exp_atom(sa, atom_string(sa, &clob, s?sa_strdup(sa, s):NULL));
466}
467
468sql_exp *
469exp_atom_ptr(sql_allocator *sa, void *s)
470{
471 sql_subtype *t = sql_bind_localtype("ptr");
472 return exp_atom(sa, atom_ptr(sa, t, s));
473}
474
475sql_exp *
476exp_atom_ref(sql_allocator *sa, int i, sql_subtype *tpe)
477{
478 sql_exp *e = exp_create(sa, e_atom);
479 if (e == NULL)
480 return NULL;
481 e->card = CARD_ATOM;
482 e->flag = i;
483 if (tpe)
484 e->tpe = *tpe;
485 return e;
486}
487
488sql_exp *
489exp_null(sql_allocator *sa, sql_subtype *tpe)
490{
491 atom *a = atom_general(sa, tpe, NULL);
492 return exp_atom(sa, a);
493}
494
495atom *
496exp_value(mvc *sql, sql_exp *e, atom **args, int maxarg)
497{
498 if (!e || e->type != e_atom)
499 return NULL;
500 if (e->l) { /* literal */
501 return e->l;
502 } else if (e->r) { /* param (ie not set) */
503 if (e->flag <= 1) /* global variable */
504 return stack_get_var(sql, e->r);
505 return NULL;
506 } else if (sql->emode == m_normal && e->flag < (unsigned) maxarg) { /* do not get the value in the prepared case */
507 return args[e->flag];
508 }
509 return NULL;
510}
511
512sql_exp *
513exp_param(sql_allocator *sa, const char *name, sql_subtype *tpe, int frame)
514{
515 sql_exp *e = exp_create(sa, e_atom);
516 if (e == NULL)
517 return NULL;
518 e->r = (char*)name;
519 e->card = CARD_ATOM;
520 e->flag = frame;
521 if (tpe)
522 e->tpe = *tpe;
523 return e;
524}
525
526sql_exp *
527exp_values(sql_allocator *sa, list *exps)
528{
529 sql_exp *e = exp_create(sa, e_atom);
530 if (e == NULL)
531 return NULL;
532 e->card = exps_card(exps);
533 e->f = exps;
534 return e;
535}
536
537list *
538exp_get_values(sql_exp *e)
539{
540 if (is_atom(e->type) && e->f)
541 return e->f;
542 return NULL;
543}
544
545list *
546exp_types(sql_allocator *sa, list *exps)
547{
548 list *l = sa_list(sa);
549 node *n;
550
551 for ( n = exps->h; n; n = n->next)
552 append(l, exp_subtype(n->data));
553 return l;
554}
555
556int
557have_nil(list *exps)
558{
559 int has_nil = 0;
560 node *n;
561
562 for ( n = exps->h; n && !has_nil; n = n->next) {
563 sql_exp *e = n->data;
564 has_nil |= has_nil(e);
565 }
566 return has_nil;
567}
568
569sql_exp *
570exp_column(sql_allocator *sa, const char *rname, const char *cname, sql_subtype *t, unsigned int card, int has_nils, int intern)
571{
572 sql_exp *e = exp_create(sa, e_column);
573
574 if (e == NULL)
575 return NULL;
576 assert(cname);
577 e->card = card;
578 e->alias.name = cname;
579 e->alias.rname = rname;
580 e->r = (char*)e->alias.name;
581 e->l = (char*)e->alias.rname;
582 if (t)
583 e->tpe = *t;
584 if (!has_nils)
585 set_has_no_nil(e);
586 if (intern)
587 set_intern(e);
588 return e;
589}
590
591sql_exp *
592exp_propagate(sql_allocator *sa, sql_exp *ne, sql_exp *oe)
593{
594 if (has_label(oe) &&
595 (oe->alias.rname == ne->alias.rname || (oe->alias.rname && ne->alias.rname && strcmp(oe->alias.rname, ne->alias.rname) == 0)) &&
596 (oe->alias.name == ne->alias.name || (oe->alias.name && ne->alias.name && strcmp(oe->alias.name, ne->alias.name) == 0)))
597 ne->alias.label = oe->alias.label;
598 if (is_intern(oe))
599 set_intern(ne);
600 if (is_anti(oe))
601 set_anti(ne);
602 if (is_basecol(oe))
603 set_basecol(ne);
604 ne->p = prop_copy(sa, oe->p);
605 return ne;
606}
607
608sql_exp *
609exp_alias(sql_allocator *sa, const char *arname, const char *acname, const char *org_rname, const char *org_cname, sql_subtype *t, unsigned int card, int has_nils, int intern)
610{
611 sql_exp *e = exp_column(sa, org_rname, org_cname, t, card, has_nils, intern);
612
613 if (e == NULL)
614 return NULL;
615 assert(acname && org_cname);
616 exp_setname(sa, e, (arname)?arname:org_rname, acname);
617 return e;
618}
619
620sql_exp *
621exp_alias_or_copy( mvc *sql, const char *tname, const char *cname, sql_rel *orel, sql_exp *old)
622{
623 sql_exp *ne = NULL;
624
625 if (!tname)
626 tname = old->alias.rname;
627
628 if (!cname && exp_name(old) && has_label(old)) {
629 ne = exp_column(sql->sa, exp_relname(old), exp_name(old), exp_subtype(old), orel?orel->card:CARD_ATOM, has_nil(old), is_intern(old));
630 return exp_propagate(sql->sa, ne, old);
631 } else if (!cname) {
632 exp_label(sql->sa, old, ++sql->label);
633 ne = exp_column(sql->sa, exp_relname(old), exp_name(old), exp_subtype(old), orel?orel->card:CARD_ATOM, has_nil(old), is_intern(old));
634 return exp_propagate(sql->sa, ne, old);
635 } else if (cname && !old->alias.name) {
636 exp_setname(sql->sa, old, tname, cname);
637 }
638 ne = exp_column(sql->sa, tname, cname, exp_subtype(old), orel?orel->card:CARD_ATOM, has_nil(old), is_intern(old));
639 return exp_propagate(sql->sa, ne, old);
640}
641
642sql_exp *
643exp_alias_ref(mvc *sql, sql_exp *e)
644{
645 sql_exp *ne = NULL;
646 const char *tname = exp_relname(e);
647 const char *cname = exp_name(e);
648
649 if (!has_label(e))
650 exp_label(sql->sa, e, ++sql->label);
651 ne = exp_ref(sql->sa, e);
652 exp_setname(sql->sa, ne, tname, cname);
653 return exp_propagate(sql->sa, ne, e);
654}
655
656sql_exp *
657exp_set(sql_allocator *sa, const char *name, sql_exp *val, int level)
658{
659 sql_exp *e = exp_create(sa, e_psm);
660
661 if (e == NULL)
662 return NULL;
663 e->alias.name = name;
664 e->l = val;
665 e->flag = PSM_SET + SET_PSM_LEVEL(level);
666 return e;
667}
668
669sql_exp *
670exp_var(sql_allocator *sa, const char *name, sql_subtype *type, int level)
671{
672 sql_exp *e = exp_create(sa, e_psm);
673
674 if (e == NULL)
675 return NULL;
676 e->alias.name = name;
677 e->tpe = *type;
678 e->flag = PSM_VAR + SET_PSM_LEVEL(level);
679 return e;
680}
681
682sql_exp *
683exp_table(sql_allocator *sa, const char *name, sql_table *t, int level)
684{
685 sql_exp *e = exp_create(sa, e_psm);
686
687 if (e == NULL)
688 return NULL;
689 e->alias.name = name;
690 e->f = t;
691 e->flag = PSM_VAR + SET_PSM_LEVEL(level);
692 return e;
693}
694
695sql_exp *
696exp_return(sql_allocator *sa, sql_exp *val, int level)
697{
698 sql_exp *e = exp_create(sa, e_psm);
699
700 if (e == NULL)
701 return NULL;
702 e->l = val;
703 e->flag = PSM_RETURN + SET_PSM_LEVEL(level);
704 return e;
705}
706
707sql_exp *
708exp_while(sql_allocator *sa, sql_exp *cond, list *stmts)
709{
710 sql_exp *e = exp_create(sa, e_psm);
711
712 if (e == NULL)
713 return NULL;
714 e->l = cond;
715 e->r = stmts;
716 e->flag = PSM_WHILE;
717 return e;
718}
719
720sql_exp *
721exp_if(sql_allocator *sa, sql_exp *cond, list *if_stmts, list *else_stmts)
722{
723 sql_exp *e = exp_create(sa, e_psm);
724
725 if (e == NULL)
726 return NULL;
727 e->l = cond;
728 e->r = if_stmts;
729 e->f = else_stmts;
730 e->flag = PSM_IF;
731 return e;
732}
733
734sql_exp *
735exp_rel(mvc *sql, sql_rel *rel)
736{
737 sql_exp *e = exp_create(sql->sa, e_psm);
738
739 if (e == NULL)
740 return NULL;
741 /*
742 rel = rel_optimizer(sql, rel, 0);
743 rel = rel_distribute(sql, rel);
744 */
745 e->l = rel;
746 e->flag = PSM_REL;
747 e->card = rel->card;
748 assert(rel);
749 if (is_project(rel->op)) {
750 sql_exp *last = rel->exps->t->data;
751 e->tpe = *exp_subtype(last);
752 }
753 return e;
754}
755
756sql_exp *
757exp_exception(sql_allocator *sa, sql_exp *cond, char* error_message)
758{
759 sql_exp *e = exp_create(sa, e_psm);
760
761 if (e == NULL)
762 return NULL;
763 e->l = cond;
764 e->r = sa_strdup(sa, error_message);
765 e->flag = PSM_EXCEPTION;
766 return e;
767}
768
769/* Set a name (alias) for the expression, such that we can refer
770 to this expression by this simple name.
771 */
772void
773exp_setname(sql_allocator *sa, sql_exp *e, const char *rname, const char *name )
774{
775 e->alias.label = 0;
776 if (name)
777 e->alias.name = sa_strdup(sa, name);
778 e->alias.rname = (rname)?sa_strdup(sa, rname):NULL;
779}
780
781void
782noninternexp_setname(sql_allocator *sa, sql_exp *e, const char *rname, const char *name )
783{
784 if (!is_intern(e))
785 exp_setname(sa, e, rname, name);
786}
787
788void
789exp_setalias(sql_exp *e, const char *rname, const char *name )
790{
791 e->alias.label = 0;
792 e->alias.name = name;
793 e->alias.rname = rname;
794}
795
796void
797exp_prop_alias(sql_allocator *sa, sql_exp *e, sql_exp *oe )
798{
799 if (oe->alias.name == NULL && exp_has_rel(oe)) {
800 sql_rel *r = exp_rel_get_rel(sa, oe);
801 if (!is_project(r->op))
802 return ;
803 oe = r->exps->t->data;
804 }
805 e->alias = oe->alias;
806}
807
808str
809number2name(str s, int len, int i)
810{
811 s[--len] = 0;
812 while(i>0) {
813 s[--len] = '0' + (i & 7);
814 i >>= 3;
815 }
816 s[--len] = '%';
817 return s + len;
818}
819
820void
821exp_setrelname(sql_allocator *sa, sql_exp *e, int nr)
822{
823 char name[16], *nme;
824
825 nme = number2name(name, sizeof(name), nr);
826 e->alias.label = 0;
827 e->alias.rname = sa_strdup(sa, nme);
828}
829
830char *
831make_label(sql_allocator *sa, int nr)
832{
833 char name[16], *nme;
834
835 nme = number2name(name, sizeof(name), nr);
836 return sa_strdup(sa, nme);
837}
838
839sql_exp*
840exp_label(sql_allocator *sa, sql_exp *e, int nr)
841{
842 assert(nr > 0);
843 e->alias.label = nr;
844 e->alias.rname = e->alias.name = make_label(sa, nr);
845 return e;
846}
847
848sql_exp*
849exp_label_table(sql_allocator *sa, sql_exp *e, int nr)
850{
851 e->alias.rname = make_label(sa, nr);
852 return e;
853}
854
855list*
856exps_label(sql_allocator *sa, list *exps, int nr)
857{
858 node *n;
859
860 if (!exps)
861 return NULL;
862 for (n = exps->h; n; n = n->next)
863 n->data = exp_label(sa, n->data, nr++);
864 return exps;
865}
866
867void
868exp_swap( sql_exp *e )
869{
870 sql_exp *s = e->l;
871
872 e->l = e->r;
873 e->r = s;
874 e->flag = swap_compare((comp_type)e->flag);
875}
876
877sql_subtype *
878exp_subtype( sql_exp *e )
879{
880 switch(e->type) {
881 case e_atom: {
882 if (e->l) {
883 atom *a = e->l;
884 return atom_type(a);
885 } else if (e->tpe.type) { /* atom reference */
886 return &e->tpe;
887 }
888 break;
889 }
890 case e_convert:
891 case e_column:
892 if (e->tpe.type)
893 return &e->tpe;
894 break;
895 case e_aggr: {
896 sql_subaggr *a = e->f;
897 if (a->res && list_length(a->res) == 1)
898 return a->res->h->data;
899 return NULL;
900 }
901 case e_func: {
902 if (e->f) {
903 sql_subfunc *f = e->f;
904 if (f->res && list_length(f->res) == 1)
905 return f->res->h->data;
906 }
907 return NULL;
908 }
909 case e_cmp:
910 /* return bit */
911 case e_psm:
912 if (e->tpe.type)
913 return &e->tpe;
914 /* fall through */
915 default:
916 return NULL;
917 }
918 return NULL;
919}
920
921const char *
922exp_name( sql_exp *e )
923{
924 if (e->alias.name)
925 return e->alias.name;
926 if (e->type == e_convert && e->l)
927 return exp_name(e->l);
928 if (e->type == e_psm && e->l) { /* subquery return name of last expression */
929 sql_rel *r = e->l;
930 if (is_project(r->op))
931 return exp_name(r->exps->t->data);
932 }
933 return NULL;
934}
935
936const char *
937exp_relname( sql_exp *e )
938{
939 if (e->alias.rname)
940 return e->alias.rname;
941 return NULL;
942}
943
944const char *
945exp_find_rel_name(sql_exp *e)
946{
947 if (e->alias.rname)
948 return e->alias.rname;
949 switch(e->type) {
950 case e_column:
951 break;
952 case e_convert:
953 return exp_find_rel_name(e->l);
954 default:
955 return NULL;
956 }
957 return NULL;
958}
959
960unsigned int
961exp_card( sql_exp *e )
962{
963 return e->card;
964}
965
966const char *
967exp_func_name( sql_exp *e )
968{
969 if (e->type == e_func && e->f) {
970 sql_subfunc *f = e->f;
971 return f->func->base.name;
972 }
973 if (e->alias.name)
974 return e->alias.name;
975 if (e->type == e_convert && e->l)
976 return exp_name(e->l);
977 return NULL;
978}
979
980int
981exp_cmp( sql_exp *e1, sql_exp *e2)
982{
983 return (e1 == e2)?0:-1;
984}
985
986int
987exp_equal( sql_exp *e1, sql_exp *e2)
988{
989 if (e1 == e2)
990 return 0;
991 if (e1->alias.rname && e2->alias.rname && strcmp(e1->alias.rname, e2->alias.rname) == 0)
992 return strcmp(e1->alias.name, e2->alias.name);
993 if (!e1->alias.rname && !e2->alias.rname && e1->alias.label == e2->alias.label && e1->alias.name && e2->alias.name)
994 return strcmp(e1->alias.name, e2->alias.name);
995 return -1;
996}
997
998int
999exp_match( sql_exp *e1, sql_exp *e2)
1000{
1001 if (exp_cmp(e1, e2) == 0)
1002 return 1;
1003 if (e1->type == e2->type && e1->type == e_column) {
1004 if (e1->l != e2->l && (!e1->l || !e2->l || strcmp(e1->l, e2->l) != 0))
1005 return 0;
1006 if (!e1->r || !e2->r || strcmp(e1->r, e2->r) != 0)
1007 return 0;
1008 return 1;
1009 }
1010 if (e1->type == e2->type && e1->type == e_func) {
1011 if (is_identity(e1, NULL) && is_identity(e2, NULL)) {
1012 list *args1 = e1->l;
1013 list *args2 = e2->l;
1014
1015 if (list_length(args1) == list_length(args2) && list_length(args1) == 1) {
1016 sql_exp *ne1 = args1->h->data;
1017 sql_exp *ne2 = args2->h->data;
1018
1019 if (exp_match(ne1,ne2))
1020 return 1;
1021 }
1022 }
1023 }
1024 return 0;
1025}
1026
1027/* list already contains matching expression */
1028sql_exp*
1029exps_find_exp( list *l, sql_exp *e)
1030{
1031 node *n;
1032
1033 if (!l || !l->h)
1034 return NULL;
1035
1036 for(n=l->h; n; n = n->next) {
1037 if (exp_match(n->data, e) || exp_refers(n->data, e))
1038 return n->data;
1039 }
1040 return NULL;
1041}
1042
1043
1044/* c refers to the parent p */
1045int
1046exp_refers( sql_exp *p, sql_exp *c)
1047{
1048 if (c->type == e_column) {
1049 if (!p->alias.name || !c->r || strcmp(p->alias.name, c->r) != 0)
1050 return 0;
1051 if (c->l && ((p->alias.rname && strcmp(p->alias.rname, c->l) != 0) || (!p->alias.rname && strcmp(p->l, c->l) != 0)))
1052 return 0;
1053 return 1;
1054 }
1055 return 0;
1056}
1057
1058int
1059exp_match_col_exps( sql_exp *e, list *l)
1060{
1061 node *n;
1062
1063 for(n=l->h; n; n = n->next) {
1064 sql_exp *re = n->data;
1065 sql_exp *re_r = re->r;
1066
1067 if (re->type == e_cmp && re->flag == cmp_or)
1068 return exp_match_col_exps(e, re->l) &&
1069 exp_match_col_exps(e, re->r);
1070
1071 if (re->type != e_cmp || /*re->flag != cmp_equal ||*/ !re_r || re_r->card != 1 || !exp_match_exp(e, re->l))
1072 return 0;
1073 }
1074 return 1;
1075}
1076
1077int
1078exps_match_col_exps( sql_exp *e1, sql_exp *e2)
1079{
1080 sql_exp *e1_r = e1->r;
1081 sql_exp *e2_r = e2->r;
1082
1083 if (e1->type != e_cmp || e2->type != e_cmp)
1084 return 0;
1085
1086 if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
1087 !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
1088 return exp_match_exp(e1->l, e2->l);
1089
1090 if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
1091 (e2->flag == cmp_in || e2->flag == cmp_notin))
1092 return exp_match_exp(e1->l, e2->l);
1093 if ((e1->flag == cmp_in || e1->flag == cmp_notin) &&
1094 !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
1095 return exp_match_exp(e1->l, e2->l);
1096
1097 if ((e1->flag == cmp_in || e1->flag == cmp_notin) &&
1098 (e2->flag == cmp_in || e2->flag == cmp_notin))
1099 return exp_match_exp(e1->l, e2->l);
1100
1101 if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
1102 e2->flag == cmp_or)
1103 return exp_match_col_exps(e1->l, e2->l) &&
1104 exp_match_col_exps(e1->l, e2->r);
1105
1106 if (e1->flag == cmp_or &&
1107 !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
1108 return exp_match_col_exps(e2->l, e1->l) &&
1109 exp_match_col_exps(e2->l, e1->r);
1110
1111 if (e1->flag == cmp_or && e2->flag == cmp_or) {
1112 list *l = e1->l, *r = e1->r;
1113 sql_exp *el = l->h->data;
1114 sql_exp *er = r->h->data;
1115
1116 return list_length(l) == 1 && list_length(r) == 1 &&
1117 exps_match_col_exps(el, e2) &&
1118 exps_match_col_exps(er, e2);
1119 }
1120 return 0;
1121}
1122
1123int
1124exp_match_list( list *l, list *r)
1125{
1126 node *n, *m;
1127 char *lu, *ru;
1128 int lc = 0, rc = 0, match = 0;
1129
1130 if (!l || !r)
1131 return l == r;
1132 if (list_length(l) != list_length(r))
1133 return 0;
1134 lu = calloc(list_length(l), sizeof(char));
1135 ru = calloc(list_length(r), sizeof(char));
1136 for (n = l->h, lc = 0; n; n = n->next, lc++) {
1137 sql_exp *le = n->data;
1138
1139 for ( m = r->h, rc = 0; m; m = m->next, rc++) {
1140 sql_exp *re = m->data;
1141
1142 if (!ru[rc] && exp_match_exp(le,re)) {
1143 lu[lc] = 1;
1144 ru[rc] = 1;
1145 match = 1;
1146 }
1147 }
1148 }
1149 for (n = l->h, lc = 0; n && match; n = n->next, lc++)
1150 if (!lu[lc])
1151 match = 0;
1152 for (n = r->h, rc = 0; n && match; n = n->next, rc++)
1153 if (!ru[rc])
1154 match = 0;
1155 free(lu);
1156 free(ru);
1157 return match;
1158}
1159
1160static int
1161exps_equal( list *l, list *r)
1162{
1163 node *n, *m;
1164
1165 if (!l || !r)
1166 return l == r;
1167 if (list_length(l) != list_length(r))
1168 return 0;
1169 for (n = l->h, m = r->h; n && m; n = n->next, m = m->next) {
1170 sql_exp *le = n->data, *re = m->data;
1171
1172 if (!exp_match_exp(le,re))
1173 return 0;
1174 }
1175 return 1;
1176}
1177
1178int
1179exp_match_exp( sql_exp *e1, sql_exp *e2)
1180{
1181 if (exp_match(e1, e2))
1182 return 1;
1183 if (e1->type == e2->type) {
1184 switch(e1->type) {
1185 case e_cmp:
1186 if (e1->flag == e2->flag && !is_complex_exp(e1->flag) &&
1187 exp_match_exp(e1->l, e2->l) &&
1188 exp_match_exp(e1->r, e2->r) &&
1189 ((!e1->f && !e2->f) || exp_match_exp(e1->f, e2->f)))
1190 return 1;
1191 else if (e1->flag == e2->flag && get_cmp(e1) == cmp_or &&
1192 exp_match_list(e1->l, e2->l) &&
1193 exp_match_list(e1->r, e2->r))
1194 return 1;
1195 else if (e1->flag == e2->flag && is_anti(e1) == is_anti(e2) &&
1196 (e1->flag == cmp_in || e1->flag == cmp_notin) &&
1197 exp_match_exp(e1->l, e2->l) &&
1198 exp_match_list(e1->r, e2->r))
1199 return 1;
1200 else if (e1->flag == e2->flag && (e1->flag == cmp_equal || e1->flag == cmp_notequal) &&
1201 exp_match_exp(e1->l, e2->r) && exp_match_exp(e1->r, e2->l))
1202 return 1; /* = and <> operations are reflective, so exp_match_exp can be called crossed */
1203 break;
1204 case e_convert:
1205 if (!subtype_cmp(exp_totype(e1), exp_totype(e2)) &&
1206 !subtype_cmp(exp_fromtype(e1), exp_fromtype(e2)) &&
1207 exp_match_exp(e1->l, e2->l))
1208 return 1;
1209 break;
1210 case e_aggr:
1211 if (!subaggr_cmp(e1->f, e2->f) && /* equal aggregation*/
1212 exps_equal(e1->l, e2->l) &&
1213 e1->flag == e2->flag)
1214 return 1;
1215 break;
1216 case e_func:
1217 if (!subfunc_cmp(e1->f, e2->f) && /* equal functions */
1218 exps_equal(e1->l, e2->l) &&
1219 /* optional order by expressions */
1220 exps_equal(e1->r, e2->r)) {
1221 sql_subfunc *f = e1->f;
1222 if (!f->func->side_effect)
1223 return 1;
1224 }
1225 break;
1226 case e_atom:
1227 if (e1->l && e2->l && !atom_cmp(e1->l, e2->l))
1228 return 1;
1229 break;
1230 default:
1231 break;
1232 }
1233 }
1234 return 0;
1235}
1236
1237static int
1238exps_are_joins( list *l )
1239{
1240 node *n;
1241
1242 for (n = l->h; n; n = n->next) {
1243 sql_exp *e = n->data;
1244
1245 if (exp_is_join_exp(e))
1246 return -1;
1247 }
1248 return 0;
1249}
1250
1251int
1252exp_is_join_exp(sql_exp *e)
1253{
1254 if (exp_is_join(e, NULL) == 0)
1255 return 0;
1256 if (e->type == e_cmp && e->flag == cmp_or && e->card >= CARD_AGGR)
1257 if (exps_are_joins(e->l) == 0 && exps_are_joins(e->r) == 0)
1258 return 0;
1259 return -1;
1260}
1261
1262static int
1263exp_is_complex_select( sql_exp *e )
1264{
1265 switch (e->type) {
1266 case e_atom:
1267 return 0;
1268 case e_convert:
1269 return exp_is_complex_select(e->l);
1270 case e_func:
1271 case e_aggr:
1272 {
1273 int r = (e->card == CARD_ATOM);
1274 node *n;
1275 list *l = e->l;
1276
1277 if (r && l)
1278 for (n = l->h; n && !r; n = n->next)
1279 r |= exp_is_complex_select(n->data);
1280 return r;
1281 }
1282 case e_column:
1283 case e_cmp:
1284 default:
1285 return 0;
1286 case e_psm:
1287 return 1;
1288 }
1289}
1290
1291static int
1292complex_select(sql_exp *e)
1293{
1294 sql_exp *l = e->l, *r = e->r;
1295
1296 if (exp_is_complex_select(l) || exp_is_complex_select(r))
1297 return 1;
1298 return 0;
1299}
1300
1301static int
1302distinct_rel(sql_exp *e, const char **rname)
1303{
1304 const char *e_rname = NULL;
1305
1306 switch(e->type) {
1307 case e_column:
1308 e_rname = exp_relname(e);
1309
1310 if (*rname && e_rname && strcmp(*rname, e_rname) == 0)
1311 return 1;
1312 if (!*rname) {
1313 *rname = e_rname;
1314 return 1;
1315 }
1316 break;
1317 case e_aggr:
1318 case e_func:
1319 if (e->l) {
1320 int m = 1;
1321 list *l = e->l;
1322 node *n;
1323
1324 for(n=l->h; n && m; n = n->next) {
1325 sql_exp *ae = n->data;
1326
1327 m = distinct_rel(ae, rname);
1328 }
1329 return m;
1330 }
1331 return 0;
1332 case e_atom:
1333 return 1;
1334 case e_convert:
1335 return distinct_rel(e->l, rname);
1336 default:
1337 return 0;
1338 }
1339 return 0;
1340}
1341
1342int
1343rel_has_exp(sql_rel *rel, sql_exp *e)
1344{
1345 if (rel_find_exp(rel, e) != NULL)
1346 return 0;
1347 return -1;
1348}
1349
1350int
1351rel_has_exps(sql_rel *rel, list *exps)
1352{
1353 node *n;
1354
1355 if (!exps)
1356 return -1;
1357 for (n = exps->h; n; n = n->next)
1358 if (rel_has_exp(rel, n->data) >= 0)
1359 return 0;
1360 return -1;
1361}
1362
1363int
1364rel_has_all_exps(sql_rel *rel, list *exps)
1365{
1366 node *n;
1367
1368 if (!exps)
1369 return -1;
1370 for (n = exps->h; n; n = n->next)
1371 if (rel_has_exp(rel, n->data) < 0)
1372 return 0;
1373 return 1;
1374}
1375
1376
1377sql_rel *
1378find_rel(list *rels, sql_exp *e)
1379{
1380 node *n = list_find(rels, e, (fcmp)&rel_has_exp);
1381 if (n)
1382 return n->data;
1383 return NULL;
1384}
1385
1386sql_rel *
1387find_one_rel(list *rels, sql_exp *e)
1388{
1389 node *n;
1390 sql_rel *fnd = NULL;
1391
1392 for(n = rels->h; n; n = n->next) {
1393 if (rel_has_exp(n->data, e) == 0) {
1394 if (fnd)
1395 return NULL;
1396 fnd = n->data;
1397 }
1398 }
1399 return fnd;
1400}
1401
1402static int
1403exp_is_rangejoin(sql_exp *e, list *rels)
1404{
1405 /* assume e is a e_cmp with 3 args
1406 * Need to check e->r and e->f only touch one table.
1407 */
1408 const char *rname = 0;
1409
1410 if (distinct_rel(e->r, &rname) && distinct_rel(e->f, &rname))
1411 return 0;
1412 if (rels) {
1413 sql_rel *r = find_rel(rels, e->r);
1414 sql_rel *f = find_rel(rels, e->f);
1415 if (r && f && r == f)
1416 return 0;
1417 }
1418 return -1;
1419}
1420
1421int
1422exp_is_join(sql_exp *e, list *rels)
1423{
1424 /* only simple compare expressions, ie not or lists
1425 or range expressions (e->f)
1426 */
1427 if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r && !e->f && e->card >= CARD_AGGR && !complex_select(e))
1428 return 0;
1429 if (e->type == e_cmp && get_cmp(e) == cmp_filter && e->l && e->r && e->card >= CARD_AGGR)
1430 return 0;
1431 /* range expression */
1432 if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r && e->f && e->card >= CARD_AGGR && !complex_select(e))
1433 return exp_is_rangejoin(e, rels);
1434 return -1;
1435}
1436
1437int
1438exp_is_eqjoin(sql_exp *e)
1439{
1440 if (e->flag == cmp_equal) {
1441 sql_exp *l = e->l;
1442 sql_exp *r = e->r;
1443
1444 if (!is_func(l->type) && !is_func(r->type))
1445 return 0;
1446 }
1447 return -1;
1448}
1449
1450static sql_exp *
1451rel_find_exp_( sql_rel *rel, sql_exp *e)
1452{
1453 sql_exp *ne = NULL;
1454
1455 if (!rel)
1456 return NULL;
1457 switch(e->type) {
1458 case e_column:
1459 if (rel->exps && (is_project(rel->op) || is_base(rel->op))) {
1460 if (e->l) {
1461 ne = exps_bind_column2(rel->exps, e->l, e->r);
1462 } else {
1463 ne = exps_bind_column(rel->exps, e->r, NULL);
1464 }
1465 }
1466 return ne;
1467 case e_convert:
1468 return rel_find_exp_(rel, e->l);
1469 case e_aggr:
1470 case e_func:
1471 if (e->l) {
1472 list *l = e->l;
1473 node *n = l->h;
1474
1475 ne = n->data;
1476 while (ne != NULL && n != NULL) {
1477 ne = rel_find_exp_(rel, n->data);
1478 n = n->next;
1479 }
1480 return ne;
1481 }
1482 break;
1483 /* fall through */
1484 case e_cmp:
1485 case e_psm:
1486 return NULL;
1487 case e_atom:
1488 if (e->f) { /* values */
1489 list *l = e->f;
1490 node *n = l->h;
1491
1492 ne = n->data;
1493 while (ne != NULL && n != NULL) {
1494 ne = rel_find_exp_(rel, n->data);
1495 n = n->next;
1496 }
1497 return ne;
1498 }
1499 return e;
1500 }
1501 return ne;
1502}
1503
1504sql_exp *
1505rel_find_exp( sql_rel *rel, sql_exp *e)
1506{
1507 sql_exp *ne = rel_find_exp_(rel, e);
1508
1509 if (rel && !ne) {
1510 switch(rel->op) {
1511 case op_left:
1512 case op_right:
1513 case op_full:
1514 case op_join:
1515 ne = rel_find_exp(rel->l, e);
1516 if (!ne)
1517 ne = rel_find_exp(rel->r, e);
1518 break;
1519 case op_table:
1520 if (rel->exps && e->type == e_column && e->l && exps_bind_column2(rel->exps, e->l, e->r))
1521 ne = e;
1522 break;
1523 case op_union:
1524 case op_except:
1525 case op_inter:
1526 {
1527 if (rel->l)
1528 ne = rel_find_exp(rel->l, e);
1529 else if (rel->exps && e->l)
1530 ne = exps_bind_column2(rel->exps, e->l, e->r);
1531 else if (rel->exps)
1532 ne = exps_bind_column(rel->exps, e->r, NULL);
1533 }
1534 break;
1535 case op_basetable:
1536 if (rel->exps && e->type == e_column && e->l)
1537 ne = exps_bind_column2(rel->exps, e->l, e->r);
1538 break;
1539 default:
1540 if (!is_project(rel->op) && rel->l)
1541 ne = rel_find_exp(rel->l, e);
1542 }
1543 }
1544 return ne;
1545}
1546
1547int
1548exp_is_true(mvc *sql, sql_exp *e)
1549{
1550 if (e->type == e_atom) {
1551 if (e->l) {
1552 return atom_is_true(e->l);
1553 } else if(sql->emode == m_normal && (unsigned) sql->argc > e->flag && EC_BOOLEAN(exp_subtype(e)->type->eclass)) {
1554 return atom_is_true(sql->args[e->flag]);
1555 }
1556 }
1557 return 0;
1558}
1559
1560int
1561exp_is_zero(mvc *sql, sql_exp *e)
1562{
1563 if (e->type == e_atom) {
1564 if (e->l) {
1565 return atom_is_zero(e->l);
1566 } else if(sql->emode == m_normal && (unsigned) sql->argc > e->flag && EC_COMPUTE(exp_subtype(e)->type->eclass)) {
1567 return atom_is_zero(sql->args[e->flag]);
1568 }
1569 }
1570 return 0;
1571}
1572
1573int
1574exp_is_not_null(mvc *sql, sql_exp *e)
1575{
1576 if (e->type == e_atom) {
1577 if (e->l) {
1578 return !(atom_null(e->l));
1579 } else if(sql->emode == m_normal && (unsigned) sql->argc > e->flag && EC_COMPUTE(exp_subtype(e)->type->eclass)) {
1580 return !atom_null(sql->args[e->flag]);
1581 }
1582 }
1583 return 0;
1584}
1585
1586int
1587exp_is_null(mvc *sql, sql_exp *e )
1588{
1589 switch (e->type) {
1590 case e_atom:
1591 if (e->f) /* values list */
1592 return 0;
1593 if (e->l) {
1594 return (atom_null(e->l));
1595 } else if (sql->emode == m_normal && (unsigned) sql->argc > e->flag) {
1596 return atom_null(sql->args[e->flag]);
1597 }
1598 return 0;
1599 case e_convert:
1600 return exp_is_null(sql, e->l);
1601 case e_func:
1602 case e_aggr:
1603 {
1604 int r = 0;
1605 node *n;
1606 list *l = e->l;
1607
1608 if (!r && l && list_length(l) == 2) {
1609 for (n = l->h; n && !r; n = n->next)
1610 r |= exp_is_null(sql, n->data);
1611 }
1612 return r;
1613 }
1614 case e_column:
1615 case e_cmp:
1616 case e_psm:
1617 return 0;
1618 }
1619 return 0;
1620}
1621
1622int
1623exp_is_atom( sql_exp *e )
1624{
1625 switch (e->type) {
1626 case e_atom:
1627 if (e->f) /* values list */
1628 return 0;
1629 return 1;
1630 case e_convert:
1631 return exp_is_atom(e->l);
1632 case e_func:
1633 case e_aggr:
1634 {
1635 int r = (e->card == CARD_ATOM);
1636 node *n;
1637 list *l = e->l;
1638
1639 if (r && l)
1640 for (n = l->h; n && r; n = n->next)
1641 r &= exp_is_atom(n->data);
1642 return r;
1643 }
1644 case e_column:
1645 case e_cmp:
1646 case e_psm:
1647 return 0;
1648 }
1649 return 0;
1650}
1651
1652int
1653exp_is_rel( sql_exp *e )
1654{
1655 return (e->type == e_psm && e->flag == PSM_REL && e->l);
1656}
1657
1658int
1659exp_has_rel( sql_exp *e )
1660{
1661 if (!e)
1662 return 0;
1663 switch(e->type){
1664 case e_func:
1665 case e_aggr:
1666 return exps_have_rel_exp(e->l);
1667 case e_cmp:
1668 if (get_cmp(e) == cmp_or || get_cmp(e) == cmp_filter) {
1669 return (exps_have_rel_exp(e->l) || exps_have_rel_exp(e->r));
1670 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
1671 return (exp_has_rel(e->l) || exps_have_rel_exp(e->r));
1672 } else {
1673 return (exp_has_rel(e->l) || exp_has_rel(e->r) || (e->f && exp_has_rel(e->f)));
1674 }
1675 case e_convert:
1676 return exp_has_rel(e->l);
1677 case e_psm:
1678 return exp_is_rel(e);
1679 case e_atom:
1680 return (e->f && exps_have_rel_exp(e->f));
1681 case e_column:
1682 return 0;
1683 }
1684 return 0;
1685}
1686
1687int
1688exps_have_rel_exp( list *exps)
1689{
1690 if (list_empty(exps))
1691 return 0;
1692 for(node *n=exps->h; n; n=n->next) {
1693 sql_exp *e = n->data;
1694
1695 if (exp_has_rel(e))
1696 return 1;
1697 }
1698 return 0;
1699}
1700
1701static sql_rel *
1702exps_rel_get_rel(sql_allocator *sa, list *exps )
1703{
1704 sql_rel *xp = NULL;
1705
1706 if (list_empty(exps))
1707 return NULL;
1708 for (node *n = exps->h; n; n=n->next){
1709 sql_exp *e = n->data;
1710
1711 if (exp_has_rel(e)) {
1712 sql_rel *r = exp_rel_get_rel(sa, e);
1713
1714 if (!r)
1715 return NULL;
1716 if (xp)
1717 xp = rel_crossproduct(sa, xp, r, op_join);
1718 else
1719 xp = r;
1720 }
1721 }
1722 return xp;
1723}
1724
1725sql_rel *
1726exp_rel_get_rel(sql_allocator *sa, sql_exp *e)
1727{
1728 if (!e)
1729 return NULL;
1730
1731 switch(e->type){
1732 case e_func:
1733 case e_aggr:
1734 return exps_rel_get_rel(sa, e->l);
1735 case e_cmp:
1736 if (get_cmp(e) == cmp_or || get_cmp(e) == cmp_filter) {
1737 if (exps_have_rel_exp(e->l))
1738 return exps_rel_get_rel(sa, e->l);
1739 if (exps_have_rel_exp(e->r))
1740 return exps_rel_get_rel(sa, e->r);
1741 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
1742 if (exp_has_rel(e->l))
1743 return exp_rel_get_rel(sa, e->l);
1744 if (exps_have_rel_exp(e->r))
1745 return exps_rel_get_rel(sa, e->r);
1746 } else {
1747 if (exp_has_rel(e->l))
1748 return exp_rel_get_rel(sa, e->l);
1749 if (exp_has_rel(e->r))
1750 return exp_rel_get_rel(sa, e->r);
1751 if (e->f && exp_has_rel(e->f))
1752 return exp_rel_get_rel(sa, e->f);
1753 }
1754 return NULL;
1755 case e_convert:
1756 return exp_rel_get_rel(sa, e->l);
1757 case e_psm:
1758 if (exp_is_rel(e))
1759 return e->l;
1760 return NULL;
1761 case e_atom:
1762 if (e->f && exps_have_rel_exp(e->f))
1763 return exps_rel_get_rel(sa, e->f);
1764 return NULL;
1765 case e_column:
1766 return NULL;
1767 }
1768 return NULL;
1769}
1770
1771static list *
1772exp_rel_update_exps(sql_allocator *sa, list *exps )
1773{
1774 if (list_empty(exps))
1775 return exps;
1776 for (node *n = exps->h; n; n=n->next){
1777 sql_exp *e = n->data;
1778
1779 if (exp_has_rel(e))
1780 n->data = exp_rel_update_exp(sa, e);
1781 }
1782 list_hash_clear(exps);
1783 return exps;
1784}
1785
1786sql_exp *
1787exp_rel_update_exp(sql_allocator *sa, sql_exp *e)
1788{
1789 if (!e)
1790 return NULL;
1791
1792 switch(e->type){
1793 case e_func:
1794 case e_aggr:
1795 e->l = exp_rel_update_exps(sa, e->l);
1796 return e;
1797 case e_cmp:
1798 if (get_cmp(e) == cmp_or || get_cmp(e) == cmp_filter) {
1799 if (exps_have_rel_exp(e->l))
1800 e->l = exp_rel_update_exps(sa, e->l);
1801 if (exps_have_rel_exp(e->r))
1802 e->r = exp_rel_update_exps(sa, e->r);
1803 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
1804 if (exp_has_rel(e->l))
1805 e->l = exp_rel_update_exp(sa, e->l);
1806 if (exps_have_rel_exp(e->r))
1807 e->r = exp_rel_update_exps(sa, e->r);
1808 } else {
1809 if (exp_has_rel(e->l))
1810 e->l = exp_rel_update_exp(sa, e->l);
1811 if (exp_has_rel(e->r))
1812 e->r = exp_rel_update_exp(sa, e->r);
1813 if (e->f && exp_has_rel(e->f))
1814 e->f = exp_rel_update_exp(sa, e->f);
1815 }
1816 return e;
1817 case e_convert:
1818 e->l = exp_rel_update_exp(sa, e->l);
1819 return e;
1820 case e_psm:
1821 if (exp_is_rel(e)) {
1822 sql_rel *r = exp_rel_get_rel(sa, e);
1823 e = r->exps->t->data;
1824 return exp_ref(sa, e);
1825 }
1826 return e;
1827 case e_atom:
1828 if (e->f && exps_have_rel_exp(e->f))
1829 e->f = exp_rel_update_exps(sa, e->f);
1830 return e;
1831 case e_column:
1832 return e;
1833 }
1834 return e;
1835}
1836
1837sql_exp *
1838exp_rel_label(mvc *sql, sql_exp *e)
1839{
1840 if (exp_is_rel(e)) {
1841 sql_rel *r = e->l;
1842
1843 e->l = r = rel_label(sql, r, 1);
1844 }
1845 return e;
1846}
1847
1848int
1849exps_are_atoms( list *exps)
1850{
1851 node *n;
1852 int atoms = 1;
1853
1854 for(n=exps->h; n && atoms; n=n->next)
1855 atoms &= exp_is_atom(n->data);
1856 return atoms;
1857}
1858
1859static int
1860exps_has_func( list *exps)
1861{
1862 node *n;
1863 int has_func = 0;
1864
1865 for(n=exps->h; n && !has_func; n=n->next)
1866 has_func |= exp_has_func(n->data);
1867 return has_func;
1868}
1869
1870int
1871exp_has_func( sql_exp *e )
1872{
1873 if (!e)
1874 return 0;
1875 switch (e->type) {
1876 case e_atom:
1877 return 0;
1878 case e_convert:
1879 return exp_has_func(e->l);
1880 case e_func:
1881 return 1;
1882 case e_aggr:
1883 if (e->l)
1884 return exps_has_func(e->l);
1885 return 0;
1886 case e_cmp:
1887 if (get_cmp(e) == cmp_or) {
1888 return (exps_has_func(e->l) || exps_has_func(e->r));
1889 } else if (e->flag == cmp_in || e->flag == cmp_notin || get_cmp(e) == cmp_filter) {
1890 return (exp_has_func(e->l) || exps_has_func(e->r));
1891 } else {
1892 return (exp_has_func(e->l) || exp_has_func(e->r) ||
1893 (e->f && exp_has_func(e->f)));
1894 }
1895 case e_column:
1896 case e_psm:
1897 return 0;
1898 }
1899 return 0;
1900}
1901
1902static int
1903exps_has_sideeffect( list *exps)
1904{
1905 node *n;
1906 int has_sideeffect = 0;
1907
1908 for(n=exps->h; n && !has_sideeffect; n=n->next)
1909 has_sideeffect |= exp_has_sideeffect(n->data);
1910 return has_sideeffect;
1911}
1912
1913int
1914exp_has_sideeffect( sql_exp *e )
1915{
1916 switch (e->type) {
1917 case e_convert:
1918 return exp_has_sideeffect(e->l);
1919 case e_func:
1920 {
1921 sql_subfunc *f = e->f;
1922
1923 if (f->func->side_effect)
1924 return 1;
1925 if (e->l)
1926 return exps_has_sideeffect(e->l);
1927 return 0;
1928 }
1929 case e_atom:
1930 case e_aggr:
1931 case e_cmp:
1932 case e_column:
1933 case e_psm:
1934 return 0;
1935 }
1936 return 0;
1937}
1938
1939int
1940exp_unsafe( sql_exp *e, int allow_identity)
1941{
1942 if (!e)
1943 return 0;
1944
1945 if (e->type != e_func && e->type != e_convert)
1946 return 0;
1947
1948 if (e->type == e_convert && e->l)
1949 return exp_unsafe(e->l, allow_identity);
1950 if (e->type == e_func && e->l) {
1951 sql_subfunc *f = e->f;
1952 list *args = e->l;
1953 node *n;
1954
1955 if (IS_ANALYTIC(f->func) || (!allow_identity && is_identity(e, NULL)))
1956 return 1;
1957 for(n = args->h; n; n = n->next) {
1958 sql_exp *e = n->data;
1959
1960 if (exp_unsafe(e, allow_identity))
1961 return 1;
1962 }
1963 }
1964 return 0;
1965}
1966
1967static int
1968exp_key( sql_exp *e )
1969{
1970 if (e->alias.name)
1971 return hash_key(e->alias.name);
1972 return 0;
1973}
1974
1975sql_exp *
1976exps_bind_column( list *exps, const char *cname, int *ambiguous )
1977{
1978 sql_exp *e = NULL;
1979
1980 if (exps && cname) {
1981 node *en;
1982
1983 if (exps) {
1984 MT_lock_set(&exps->ht_lock);
1985 if (!exps->ht && list_length(exps) > HASH_MIN_SIZE) {
1986 exps->ht = hash_new(exps->sa, list_length(exps), (fkeyvalue)&exp_key);
1987 if (exps->ht == NULL) {
1988 MT_lock_unset(&exps->ht_lock);
1989 return NULL;
1990 }
1991 for (en = exps->h; en; en = en->next ) {
1992 sql_exp *e = en->data;
1993 if (e->alias.name) {
1994 int key = exp_key(e);
1995
1996 if (hash_add(exps->ht, key, e) == NULL) {
1997 MT_lock_unset(&exps->ht_lock);
1998 return NULL;
1999 }
2000 }
2001 }
2002 }
2003 if (exps->ht) {
2004 int key = hash_key(cname);
2005 sql_hash_e *he = exps->ht->buckets[key&(exps->ht->size-1)];
2006
2007 for (; he; he = he->chain) {
2008 sql_exp *ce = he->value;
2009
2010 if (ce->alias.name && strcmp(ce->alias.name, cname) == 0) {
2011 if (e && e != ce && ce->alias.rname && e->alias.rname && strcmp(ce->alias.rname, e->alias.rname) != 0 ) {
2012 if (ambiguous)
2013 *ambiguous = 1;
2014 MT_lock_unset(&exps->ht_lock);
2015 return NULL;
2016 }
2017 e = ce;
2018 }
2019 }
2020 MT_lock_unset(&exps->ht_lock);
2021 return e;
2022 }
2023 MT_lock_unset(&exps->ht_lock);
2024 }
2025 for (en = exps->h; en; en = en->next ) {
2026 sql_exp *ce = en->data;
2027 if (ce->alias.name && strcmp(ce->alias.name, cname) == 0) {
2028 if (e && e != ce && ce->alias.rname && e->alias.rname && strcmp(ce->alias.rname, e->alias.rname) != 0 ) {
2029 if (ambiguous)
2030 *ambiguous = 1;
2031 return NULL;
2032 }
2033 e = ce;
2034 }
2035 }
2036 }
2037 return e;
2038}
2039
2040sql_exp *
2041exps_bind_column2( list *exps, const char *rname, const char *cname )
2042{
2043 if (exps) {
2044 node *en;
2045
2046 if (exps) {
2047 MT_lock_set(&exps->ht_lock);
2048 if (!exps->ht && list_length(exps) > HASH_MIN_SIZE) {
2049 exps->ht = hash_new(exps->sa, list_length(exps), (fkeyvalue)&exp_key);
2050 if (exps->ht == NULL) {
2051 MT_lock_unset(&exps->ht_lock);
2052 return NULL;
2053 }
2054
2055 for (en = exps->h; en; en = en->next ) {
2056 sql_exp *e = en->data;
2057 if (e->alias.name) {
2058 int key = exp_key(e);
2059
2060 if (hash_add(exps->ht, key, e) == NULL) {
2061 MT_lock_unset(&exps->ht_lock);
2062 return NULL;
2063 }
2064 }
2065 }
2066 }
2067 if (exps->ht) {
2068 int key = hash_key(cname);
2069 sql_hash_e *he = exps->ht->buckets[key&(exps->ht->size-1)];
2070
2071 for (; he; he = he->chain) {
2072 sql_exp *e = he->value;
2073
2074 if ((e && is_column(e->type) && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) ||
2075 (e && e->type == e_column && e->alias.name && !e->alias.rname && e->l && strcmp(e->alias.name, cname) == 0 && strcmp(e->l, rname) == 0)) {
2076 MT_lock_unset(&exps->ht_lock);
2077 return e;
2078 }
2079 }
2080 MT_lock_unset(&exps->ht_lock);
2081 return NULL;
2082 }
2083 MT_lock_unset(&exps->ht_lock);
2084 }
2085 for (en = exps->h; en; en = en->next ) {
2086 sql_exp *e = en->data;
2087
2088 if (e && is_column(e->type) && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0)
2089 return e;
2090 if (e && e->type == e_column && e->alias.name && !e->alias.rname && e->l && strcmp(e->alias.name, cname) == 0 && strcmp(e->l, rname) == 0)
2091 return e;
2092 }
2093 }
2094 return NULL;
2095}
2096
2097/* find an column based on the original name, not the alias it got */
2098sql_exp *
2099exps_bind_alias( list *exps, const char *rname, const char *cname )
2100{
2101 if (exps) {
2102 node *en;
2103
2104 for (en = exps->h; en; en = en->next ) {
2105 sql_exp *e = en->data;
2106
2107 if (e && is_column(e->type) && !rname && e->r && strcmp(e->r, cname) == 0)
2108 return e;
2109 if (e && e->type == e_column && rname && e->l && e->r && strcmp(e->r, cname) == 0 && strcmp(e->l, rname) == 0) {
2110 return e;
2111 }
2112 }
2113 }
2114 return NULL;
2115}
2116
2117unsigned int
2118exps_card( list *l )
2119{
2120 node *n;
2121 unsigned int card = CARD_ATOM;
2122
2123 if (l) for(n = l->h; n; n = n->next) {
2124 sql_exp *e = n->data;
2125
2126 if (card < e->card)
2127 card = e->card;
2128 }
2129 return card;
2130}
2131
2132void
2133exps_fix_card( list *exps, unsigned int card)
2134{
2135 node *n;
2136
2137 for (n = exps->h; n; n = n->next) {
2138 sql_exp *e = n->data;
2139
2140 if (e->card > card)
2141 e->card = card;
2142 }
2143}
2144
2145void
2146exps_setcard( list *exps, unsigned int card)
2147{
2148 node *n;
2149
2150 for (n = exps->h; n; n = n->next) {
2151 sql_exp *e = n->data;
2152
2153 if (e->card != CARD_ATOM)
2154 e->card = card;
2155 }
2156}
2157
2158int
2159exps_intern(list *exps)
2160{
2161 node *n;
2162
2163 for (n=exps->h; n; n = n->next) {
2164 sql_exp *e = n->data;
2165
2166 if (is_intern(e))
2167 return 1;
2168 }
2169 return 0;
2170}
2171
2172char *
2173compare_func( comp_type t, int anti )
2174{
2175 switch(t) {
2176 case mark_in:
2177 case cmp_equal:
2178 return anti?"<>":"=";
2179 case cmp_lt:
2180 return anti?">":"<";
2181 case cmp_lte:
2182 return anti?">=":"<=";
2183 case cmp_gte:
2184 return anti?"<=":">=";
2185 case cmp_gt:
2186 return anti?"<":">";
2187 case mark_notin:
2188 case cmp_notequal:
2189 return anti?"=":"<>";
2190 default:
2191 return NULL;
2192 }
2193}
2194
2195int
2196is_identity( sql_exp *e, sql_rel *r)
2197{
2198 switch(e->type) {
2199 case e_column:
2200 if (r && is_project(r->op)) {
2201 sql_exp *re = NULL;
2202 if (e->l)
2203 re = exps_bind_column2(r->exps, e->l, e->r);
2204 if (!re && has_label(e))
2205 re = exps_bind_column(r->exps, e->r, NULL);
2206 if (re)
2207 return is_identity(re, r->l);
2208 }
2209 return 0;
2210 case e_func: {
2211 sql_subfunc *f = e->f;
2212 return (strcmp(f->func->base.name, "identity") == 0);
2213 }
2214 default:
2215 return 0;
2216 }
2217}
2218
2219list *
2220exps_alias( sql_allocator *sa, list *exps)
2221{
2222 node *n;
2223 list *nl = new_exp_list(sa);
2224
2225 for (n = exps->h; n; n = n->next) {
2226 sql_exp *e = n->data, *ne;
2227
2228 assert(exp_name(e));
2229 ne = exp_ref(sa, e);
2230 append(nl, ne);
2231 }
2232 return nl;
2233}
2234
2235list *
2236exps_copy( mvc *sql, list *exps)
2237{
2238 node *n;
2239 list *nl;
2240
2241 if (!exps)
2242 return exps;
2243
2244 nl = new_exp_list(sql->sa);
2245 for(n = exps->h; n; n = n->next) {
2246 sql_exp *arg = n->data;
2247
2248 arg = exp_copy(sql, arg);
2249 if (!arg)
2250 return NULL;
2251 append(nl, arg);
2252 }
2253 return nl;
2254}
2255
2256sql_exp *
2257exp_copy( mvc *sql, sql_exp * e)
2258{
2259 sql_exp *l, *r, *r2, *ne = NULL;
2260
2261 switch(e->type){
2262 case e_column:
2263 ne = exp_column(sql->sa, e->l, e->r, exp_subtype(e), e->card, has_nil(e), is_intern(e));
2264 ne->flag = e->flag;
2265 break;
2266 case e_cmp:
2267 if (get_cmp(e) == cmp_or || get_cmp(e) == cmp_filter) {
2268 list *l = exps_copy(sql, e->l);
2269 list *r = exps_copy(sql, e->r);
2270 if (l && r) {
2271 if (get_cmp(e) == cmp_filter)
2272 ne = exp_filter(sql->sa, l, r, e->f, is_anti(e));
2273 else
2274 ne = exp_or(sql->sa, l, r, is_anti(e));
2275 }
2276 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
2277 sql_exp *l = exp_copy(sql, e->l);
2278 list *r = exps_copy(sql, e->r);
2279
2280 if (l && r)
2281 ne = exp_in(sql->sa, l, r, e->flag);
2282 } else {
2283 l = exp_copy(sql, e->l);
2284 r = exp_copy(sql, e->r);
2285
2286 if (e->f) {
2287 r2 = exp_copy(sql, e->f);
2288 if (l && r && r2)
2289 ne = exp_compare2(sql->sa, l, r, r2, e->flag);
2290 } else if (l && r) {
2291 ne = exp_compare(sql->sa, l, r, e->flag);
2292 }
2293 }
2294 break;
2295 case e_convert:
2296 l = exp_copy(sql, e->l);
2297 if (l)
2298 ne = exp_convert(sql->sa, l, exp_fromtype(e), exp_totype(e));
2299 break;
2300 case e_aggr:
2301 case e_func: {
2302 list *l = e->l, *nl = NULL;
2303
2304 if (!l) {
2305 return e;
2306 } else {
2307 nl = exps_copy(sql, l);
2308 if (!nl)
2309 return NULL;
2310 }
2311 if (e->type == e_func)
2312 ne = exp_op(sql->sa, nl, e->f);
2313 else
2314 ne = exp_aggr(sql->sa, nl, e->f, need_distinct(e), need_no_nil(e), e->card, has_nil(e));
2315 break;
2316 }
2317 case e_atom:
2318 if (e->l)
2319 ne = exp_atom(sql->sa, e->l);
2320 else if (!e->r)
2321 ne = exp_atom_ref(sql->sa, e->flag, &e->tpe);
2322 else
2323 ne = exp_param(sql->sa, e->r, &e->tpe, e->flag);
2324 break;
2325 case e_psm:
2326 if (e->flag == PSM_SET)
2327 ne = exp_set(sql->sa, e->alias.name, exp_copy(sql, e->l), GET_PSM_LEVEL(e->flag));
2328 if (e->flag == PSM_REL) {
2329 if (!exp_name(e))
2330 exp_label(sql->sa, e, ++sql->label);
2331 return exp_ref(sql->sa, e);
2332 }
2333 break;
2334 }
2335 if (!ne)
2336 return ne;
2337 if (e->alias.name)
2338 exp_prop_alias(sql->sa, ne, e);
2339 ne = exp_propagate(sql->sa, ne, e);
2340 if (is_freevar(e))
2341 set_freevar(ne, is_freevar(e)-1);
2342 return ne;
2343}
2344
2345atom *
2346exp_flatten(mvc *sql, sql_exp *e)
2347{
2348 if (e->type == e_atom) {
2349 atom *v = exp_value(sql, e, sql->args, sql->argc);
2350
2351 if (v)
2352 return atom_dup(sql->sa, v);
2353 } else if (e->type == e_convert) {
2354 atom *v = exp_flatten(sql, e->l);
2355
2356 if (v && atom_cast(sql->sa, v, &e->tpe))
2357 return v;
2358 return NULL;
2359 } else if (e->type == e_func) {
2360 sql_subfunc *f = e->f;
2361 list *l = e->l;
2362 sql_arg *res = (f->func->res)?(f->func->res->h->data):NULL;
2363
2364 /* TODO handle date + x months */
2365 if (strcmp(f->func->base.name, "sql_add") == 0 && list_length(l) == 2 && res && EC_NUMBER(res->type.type->eclass)) {
2366 atom *l1 = exp_flatten(sql, l->h->data);
2367 atom *l2 = exp_flatten(sql, l->h->next->data);
2368 if (l1 && l2)
2369 return atom_add(l1,l2);
2370 } else if (strcmp(f->func->base.name, "sql_sub") == 0 && list_length(l) == 2 && res && EC_NUMBER(res->type.type->eclass)) {
2371 atom *l1 = exp_flatten(sql, l->h->data);
2372 atom *l2 = exp_flatten(sql, l->h->next->data);
2373 if (l1 && l2)
2374 return atom_sub(l1,l2);
2375 }
2376 }
2377 return NULL;
2378}
2379
2380void
2381exp_sum_scales(sql_subfunc *f, sql_exp *l, sql_exp *r)
2382{
2383 sql_arg *ares = f->func->res->h->data;
2384
2385 if (strcmp(f->func->imp, "*") == 0 && ares->type.type->scale == SCALE_FIX) {
2386 sql_subtype t;
2387 sql_subtype *lt = exp_subtype(l);
2388 sql_subtype *rt = exp_subtype(r);
2389 sql_subtype *res = f->res->h->data;
2390
2391 res->scale = lt->scale + rt->scale;
2392 res->digits = lt->digits + rt->digits;
2393
2394 /* HACK alert: digits should be less than max */
2395#ifdef HAVE_HGE
2396 if (have_hge) {
2397 if (ares->type.type->radix == 10 && res->digits > 39)
2398 res->digits = 39;
2399 if (ares->type.type->radix == 2 && res->digits > 128)
2400 res->digits = 128;
2401 } else
2402#endif
2403 {
2404
2405 if (ares->type.type->radix == 10 && res->digits > 19)
2406 res->digits = 19;
2407 if (ares->type.type->radix == 2 && res->digits > 64)
2408 res->digits = 64;
2409 }
2410
2411 /* numeric types are fixed length */
2412 if (ares->type.type->eclass == EC_NUM) {
2413#ifdef HAVE_HGE
2414 if (have_hge && ares->type.type->localtype == TYPE_hge && res->digits == 128)
2415 t = *sql_bind_localtype("hge");
2416 else
2417#endif
2418 if (ares->type.type->localtype == TYPE_lng && res->digits == 64)
2419 t = *sql_bind_localtype("lng");
2420 else
2421 sql_find_numeric(&t, ares->type.type->localtype, res->digits);
2422 } else {
2423 sql_find_subtype(&t, ares->type.type->sqlname, res->digits, res->scale);
2424 }
2425 *res = t;
2426 }
2427}
2428
2429sql_exp *
2430create_table_part_atom_exp(mvc *sql, sql_subtype tpe, ptr value)
2431{
2432 str buf = NULL;
2433 size_t len = 0;
2434 sql_exp *res = NULL;
2435
2436 switch (tpe.type->eclass) {
2437 case EC_BIT: {
2438 bit bval = *((bit*) value);
2439 return exp_atom_bool(sql->sa, bval ? 1 : 0);
2440 }
2441 case EC_POS:
2442 case EC_NUM:
2443 case EC_DEC:
2444 case EC_SEC:
2445 case EC_MONTH:
2446 switch (tpe.type->localtype) {
2447#ifdef HAVE_HGE
2448 case TYPE_hge: {
2449 hge hval = *((hge*) value);
2450 return exp_atom_hge(sql->sa, hval);
2451 }
2452#endif
2453 case TYPE_lng: {
2454 lng lval = *((lng*) value);
2455 return exp_atom_lng(sql->sa, lval);
2456 }
2457 case TYPE_int: {
2458 int ival = *((int*) value);
2459 return exp_atom_int(sql->sa, ival);
2460 }
2461 case TYPE_sht: {
2462 sht sval = *((sht*) value);
2463 return exp_atom_sht(sql->sa, sval);
2464 }
2465 case TYPE_bte: {
2466 bte bbval = *((bte *) value);
2467 return exp_atom_bte(sql->sa, bbval);
2468 }
2469 default:
2470 return NULL;
2471 }
2472 case EC_FLT:
2473 switch (tpe.type->localtype) {
2474 case TYPE_flt: {
2475 flt fval = *((flt*) value);
2476 return exp_atom_flt(sql->sa, fval);
2477 }
2478 case TYPE_dbl: {
2479 dbl dval = *((dbl*) value);
2480 return exp_atom_dbl(sql->sa, dval);
2481 }
2482 default:
2483 return NULL;
2484 }
2485 case EC_DATE: {
2486 if(date_tostr(&buf, &len, (const date *)value, false) < 0)
2487 return NULL;
2488 res = exp_atom(sql->sa, atom_general(sql->sa, &tpe, buf));
2489 break;
2490 }
2491 case EC_TIME: {
2492 if(daytime_tostr(&buf, &len, (const daytime *)value, false) < 0)
2493 return NULL;
2494 res = exp_atom(sql->sa, atom_general(sql->sa, &tpe, buf));
2495 break;
2496 }
2497 case EC_TIMESTAMP: {
2498 if(timestamp_tostr(&buf, &len, (const timestamp *)value, false) < 0)
2499 return NULL;
2500 res = exp_atom(sql->sa, atom_general(sql->sa, &tpe, buf));
2501 break;
2502 }
2503 case EC_BLOB: {
2504 if(BLOBtostr(&buf, &len, (const blob *)value, false) < 0)
2505 return NULL;
2506 res = exp_atom(sql->sa, atom_general(sql->sa, &tpe, buf));
2507 break;
2508 }
2509 case EC_CHAR:
2510 case EC_STRING:
2511 return exp_atom_clob(sql->sa, sa_strdup(sql->sa, value));
2512 default:
2513 assert(0);
2514 }
2515 if(buf)
2516 GDKfree(buf);
2517 return res;
2518}
2519
2520int
2521exp_aggr_is_count(sql_exp *e)
2522{
2523 if (e->type == e_aggr && strcmp(((sql_subaggr *)e->f)->aggr->base.name, "count") == 0)
2524 return 1;
2525 return 0;
2526}
2527
2528void
2529exps_reset_freevar(list *exps)
2530{
2531 node *n;
2532
2533 for(n=exps->h; n; n=n->next) {
2534 sql_exp *e = n->data;
2535
2536 /*later use case per type */
2537 reset_freevar(e);
2538 }
2539}
2540
2541static int
2542exp_set_list_recurse(mvc *sql, sql_subtype *type, sql_exp *e, const char **relname, const char** expname)
2543{
2544 if (THRhighwater()) {
2545 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2546 return -1;
2547 }
2548 assert(*relname && *expname);
2549 if (!e)
2550 return 0;
2551
2552 if (e->f) {
2553 const char *next_rel = exp_relname(e), *next_exp = exp_name(e);
2554 if (next_rel && next_exp && !strcmp(next_rel, *relname) && !strcmp(next_exp, *expname))
2555 for (node *n = ((list *) e->f)->h; n; n = n->next)
2556 exp_set_list_recurse(sql, type, (sql_exp *) n->data, relname, expname);
2557 }
2558 if ((e->f || (!e->l && !e->r && !e->f)) && !e->tpe.type) {
2559 if (set_type_param(sql, type, e->flag) == 0)
2560 e->tpe = *type;
2561 else
2562 return -1;
2563 }
2564 return 0;
2565}
2566
2567static int
2568exp_set_type_recurse(mvc *sql, sql_subtype *type, sql_exp *e, const char **relname, const char** expname)
2569{
2570 if (THRhighwater()) {
2571 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2572 return -1;
2573 }
2574 assert(*relname && *expname);
2575 if (!e)
2576 return 0;
2577
2578 switch (e->type) {
2579 case e_atom: {
2580 return exp_set_list_recurse(sql, type, e, relname, expname);
2581 } break;
2582 case e_convert:
2583 case e_column: {
2584 /* if the column pretended is found, set its type */
2585 const char *next_rel = exp_relname(e), *next_exp = exp_name(e);
2586 if (next_rel && !strcmp(next_rel, *relname)) {
2587 *relname = (e->type == e_column && e->l) ? (const char*) e->l : next_rel;
2588 if (next_exp && !strcmp(next_exp, *expname)) {
2589 *expname = (e->type == e_column && e->r) ? (const char*) e->r : next_exp;
2590 if (e->type == e_column && !e->tpe.type) {
2591 if (set_type_param(sql, type, e->flag) == 0)
2592 e->tpe = *type;
2593 else
2594 return -1;
2595 }
2596 }
2597 }
2598 if (e->type == e_convert)
2599 exp_set_type_recurse(sql, type, e->l, relname, expname);
2600 } break;
2601 case e_psm: {
2602 if (e->flag & PSM_RETURN) {
2603 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
2604 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
2605 } else if (e->flag & PSM_WHILE) {
2606 exp_set_type_recurse(sql, type, e->l, relname, expname);
2607 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
2608 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
2609 } else if (e->flag & PSM_IF) {
2610 exp_set_type_recurse(sql, type, e->l, relname, expname);
2611 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
2612 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
2613 if (e->f)
2614 for(node *n = ((list*)e->f)->h ; n ; n = n->next)
2615 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
2616 } else if (e->flag & PSM_REL) {
2617 rel_set_type_recurse(sql, type, e->l, relname, expname);
2618 } else if (e->flag & PSM_EXCEPTION) {
2619 exp_set_type_recurse(sql, type, e->l, relname, expname);
2620 }
2621 } break;
2622 case e_func: {
2623 for(node *n = ((list*)e->l)->h ; n ; n = n->next)
2624 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
2625 if (e->r)
2626 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
2627 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
2628 } break;
2629 case e_aggr: {
2630 if (e->l)
2631 for(node *n = ((list*)e->l)->h ; n ; n = n->next)
2632 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
2633 } break;
2634 case e_cmp: {
2635 if (e->flag == cmp_in || e->flag == cmp_notin) {
2636 exp_set_type_recurse(sql, type, e->l, relname, expname);
2637 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
2638 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
2639 } else if (get_cmp(e) == cmp_or || get_cmp(e) == cmp_filter) {
2640 for(node *n = ((list*)e->l)->h ; n ; n = n->next)
2641 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
2642 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
2643 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
2644 } else {
2645 if(e->l)
2646 exp_set_type_recurse(sql, type, e->l, relname, expname);
2647 if(e->r)
2648 exp_set_type_recurse(sql, type, e->r, relname, expname);
2649 if(e->f)
2650 exp_set_type_recurse(sql, type, e->f, relname, expname);
2651 }
2652 } break;
2653 }
2654 return 0;
2655}
2656
2657int
2658rel_set_type_recurse(mvc *sql, sql_subtype *type, sql_rel *rel, const char **relname, const char **expname)
2659{
2660 if (THRhighwater()) {
2661 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
2662 return -1;
2663 }
2664 assert(*relname && *expname);
2665 if (!rel)
2666 return 0;
2667
2668 if (rel->exps)
2669 for(node *n = rel->exps->h; n; n = n->next)
2670 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
2671
2672 switch (rel->op) {
2673 case op_basetable:
2674 case op_table:
2675 case op_ddl:
2676 break;
2677 case op_join:
2678 case op_left:
2679 case op_right:
2680 case op_full:
2681 case op_semi:
2682 case op_anti:
2683 case op_union:
2684 case op_inter:
2685 case op_except:
2686 if (rel->l)
2687 rel_set_type_recurse(sql, type, rel->l, relname, expname);
2688 if (rel->r)
2689 rel_set_type_recurse(sql, type, rel->r, relname, expname);
2690 break;
2691 case op_groupby:
2692 case op_project:
2693 case op_select:
2694 case op_topn:
2695 case op_sample:
2696 if (rel->l)
2697 rel_set_type_recurse(sql, type, rel->l, relname, expname);
2698 break;
2699 case op_insert:
2700 case op_update:
2701 case op_delete:
2702 case op_truncate:
2703 if (rel->r)
2704 rel_set_type_recurse(sql, type, rel->r, relname, expname);
2705 break;
2706 }
2707 return 0;
2708}
2709