LCOV - code coverage report
Current view: top level - sql/server - rel_exp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1793 2047 87.6 %
Date: 2024-11-14 20:04:02 Functions: 168 183 91.8 %

          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_relation.h"
      15             : #include "sql_semantic.h"
      16             : #include "sql_decimal.h"
      17             : #include "rel_exp.h"
      18             : #include "rel_rel.h"
      19             : #include "rel_basetable.h"
      20             : #include "rel_prop.h"
      21             : 
      22             : comp_type
      23      825371 : compare_str2type(const char *compare_op)
      24             : {
      25      825371 :         comp_type type = cmp_filter;
      26             : 
      27      825371 :         if (compare_op[0] == '=') {
      28             :                 type = cmp_equal;
      29      162067 :         } else if (compare_op[0] == '<') {
      30      103547 :                 type = cmp_lt;
      31      103547 :                 if (compare_op[1] == '>')
      32             :                         type = cmp_notequal;
      33       23226 :                 else if (compare_op[1] == '=')
      34        4164 :                         type = cmp_lte;
      35       58520 :         } else if (compare_op[0] == '>') {
      36       58520 :                 type = cmp_gt;
      37       58520 :                 if (compare_op[1] == '=')
      38        3337 :                         type = cmp_gte;
      39             :         }
      40      825371 :         return type;
      41             : }
      42             : 
      43             : comp_type
      44       52249 : swap_compare( comp_type t )
      45             : {
      46       52249 :         switch(t) {
      47             :         case cmp_equal:
      48             :                 return cmp_equal;
      49             :         case cmp_lt:
      50             :                 return cmp_gt;
      51             :         case cmp_lte:
      52             :                 return cmp_gte;
      53             :         case cmp_gte:
      54             :                 return cmp_lte;
      55             :         case cmp_gt:
      56             :                 return cmp_lt;
      57             :         case cmp_notequal:
      58             :                 return cmp_notequal;
      59             :         default:
      60             :                 return cmp_equal;
      61             :         }
      62             : }
      63             : 
      64             : comp_type
      65        7662 : negate_compare( comp_type t )
      66             : {
      67        7662 :         switch(t) {
      68             :         case cmp_equal:
      69             :                 return cmp_notequal;
      70          29 :         case cmp_notequal:
      71          29 :                 return cmp_equal;
      72           2 :         case cmp_lt:
      73           2 :                 return cmp_gte;
      74           5 :         case cmp_lte:
      75           5 :                 return cmp_gt;
      76           3 :         case cmp_gte:
      77           3 :                 return cmp_lt;
      78           3 :         case cmp_gt:
      79           3 :                 return cmp_lte;
      80             : 
      81           0 :         case cmp_in:
      82           0 :                 return cmp_notin;
      83           0 :         case cmp_notin:
      84           0 :                 return cmp_in;
      85             : 
      86           0 :         default:
      87           0 :                 return t;
      88             :         }
      89             : }
      90             : 
      91             : comp_type
      92        3203 : range2lcompare( int r )
      93             : {
      94        3203 :         if (r&1) {
      95             :                 return cmp_gte;
      96             :         } else {
      97        1215 :                 return cmp_gt;
      98             :         }
      99             : }
     100             : 
     101             : comp_type
     102        3260 : range2rcompare( int r )
     103             : {
     104        3260 :         if (r&2) {
     105             :                 return cmp_lte;
     106             :         } else {
     107        1252 :                 return cmp_lt;
     108             :         }
     109             : }
     110             : 
     111             : int
     112        1910 : compare2range( int l, int r )
     113             : {
     114        1910 :         if (l == cmp_gt) {
     115        1787 :                 if (r == cmp_lt)
     116             :                         return 0;
     117          23 :                 else if (r == cmp_lte)
     118          23 :                         return 2;
     119         123 :         } else if (l == cmp_gte) {
     120         123 :                 if (r == cmp_lt)
     121             :                         return 1;
     122          85 :                 else if (r == cmp_lte)
     123          85 :                         return 3;
     124             :         }
     125             :         return -1;
     126             : }
     127             : 
     128             : int
     129          95 : compare_funcs2range(const char *l_op, const char *r_op)
     130             : {
     131          95 :         assert(l_op[0] == '>' && r_op[0] == '<');
     132          95 :         if (!l_op[1] && !r_op[1])
     133             :                 return 0;
     134          93 :         if (!l_op[1] && r_op[1] == '=')
     135             :                 return 2;
     136          93 :         if (l_op[1] == '=' && !r_op[1])
     137             :                 return 1;
     138           1 :         if (l_op[1] == '=' && r_op[1] == '=')
     139             :                 return 3;
     140           0 :         assert(0);
     141             :         return 0;
     142             : }
     143             : 
     144             : static sql_exp *
     145    20945054 : exp_create(allocator *sa, int type)
     146             : {
     147    20945054 :         sql_exp *e = SA_NEW(sa, sql_exp);
     148             : 
     149    20944876 :         if (!e)
     150             :                 return NULL;
     151    20944876 :         *e = (sql_exp) {
     152    20944876 :                 .type = (expression_type) type,
     153             :         };
     154    20944876 :         return e;
     155             : }
     156             : 
     157             : sql_exp *
     158      474269 : exp_compare(allocator *sa, sql_exp *l, sql_exp *r, int cmptype)
     159             : {
     160      474269 :         sql_exp *e = exp_create(sa, e_cmp);
     161      474269 :         if (e == NULL)
     162             :                 return NULL;
     163      474269 :         e->card = MAX(l->card,r->card);
     164      474269 :         e->l = l;
     165      474269 :         e->r = r;
     166      474269 :         e->flag = cmptype;
     167      474269 :         if (!has_nil(l) && !has_nil(r))
     168      340560 :                 set_has_no_nil(e);
     169             :         return e;
     170             : }
     171             : 
     172             : sql_exp *
     173        6662 : exp_compare2(allocator *sa, sql_exp *l, sql_exp *r, sql_exp *f, int cmptype, int symmetric)
     174             : {
     175        6662 :         sql_exp *e = exp_create(sa, e_cmp);
     176        6662 :         if (e == NULL)
     177             :                 return NULL;
     178        6662 :         assert(f);
     179        6662 :         e->card = MAX(MAX(l->card,r->card),f->card);
     180        6662 :         e->l = l;
     181        6662 :         e->r = r;
     182        6662 :         e->f = f;
     183        6662 :         e->flag = cmptype;
     184        6662 :         if (symmetric)
     185          77 :                 set_symmetric(e);
     186        6662 :         if (!has_nil(l) && !has_nil(r) && !has_nil(f))
     187        1590 :                 set_has_no_nil(e);
     188             :         return e;
     189             : }
     190             : 
     191             : sql_exp *
     192        6321 : exp_filter(allocator *sa, list *l, list *r, sql_subfunc *f, int anti)
     193             : {
     194        6321 :         sql_exp *e = exp_create(sa, e_cmp);
     195             : 
     196        6321 :         if (e == NULL)
     197             :                 return NULL;
     198        6321 :         e->card = MAX(exps_card(l),exps_card(r));
     199        6321 :         if (!r) { /* split l */
     200        1384 :                 list *nl = sa_list(sa), *nr = sa_list(sa);
     201        1384 :                 node *n = l->h;
     202        1384 :                 append(nl, n->data); /* sofar only first is left */
     203        3583 :                 for(n = n->next; n; n = n->next)
     204        2199 :                         append(nr, n->data);
     205             :                 l = nl;
     206             :                 r = nr;
     207             :         }
     208        6321 :         e->l = l;
     209        6321 :         e->r = r;
     210        6321 :         e->f = f;
     211        6321 :         e->flag = cmp_filter;
     212        6321 :         if (anti)
     213         704 :                 set_anti(e);
     214        6321 :         if (!have_nil(l) && !have_nil(r))
     215        4563 :                 set_has_no_nil(e);
     216             :         return e;
     217             : }
     218             : 
     219             : sql_exp *
     220       66069 : exp_or(allocator *sa, list *l, list *r, int anti)
     221             : {
     222       66069 :         sql_exp *e = exp_create(sa, e_cmp);
     223             : 
     224       66069 :         if (e == NULL)
     225             :                 return NULL;
     226       66069 :         e->card = MAX(exps_card(l),exps_card(r));
     227       66069 :         e->l = l;
     228       66069 :         e->r = r;
     229       66069 :         e->flag = cmp_or;
     230       66069 :         if (anti)
     231           2 :                 set_anti(e);
     232       66069 :         if (!have_nil(l) && !have_nil(r))
     233       45352 :                 set_has_no_nil(e);
     234             :         return e;
     235             : }
     236             : 
     237             : sql_exp *
     238       29552 : exp_in(allocator *sa, sql_exp *l, list *r, int cmptype)
     239             : {
     240       29552 :         sql_exp *e = exp_create(sa, e_cmp);
     241       29552 :         unsigned int exps_card = CARD_ATOM;
     242             : 
     243       29552 :         if (e == NULL)
     244             :                 return NULL;
     245             : 
     246             :         /* ignore the cardinalites of sub-relations */
     247      146118 :         for (node *n = r->h; n ; n = n->next) {
     248      116566 :                 sql_exp *next = n->data;
     249             : 
     250      116566 :                 if (!exp_is_rel(next) && exps_card < next->card)
     251      116566 :                         exps_card = next->card;
     252             :         }
     253       29552 :         e->card = MAX(l->card, exps_card);
     254       29552 :         e->l = l;
     255       29552 :         e->r = r;
     256       29552 :         assert( cmptype == cmp_in || cmptype == cmp_notin);
     257       29552 :         e->flag = cmptype;
     258       29552 :         if (!has_nil(l) && !have_nil(r))
     259       23208 :                 set_has_no_nil(e);
     260             :         return e;
     261             : }
     262             : 
     263             : sql_exp *
     264       32690 : exp_in_func(mvc *sql, sql_exp *le, sql_exp *vals, int anyequal, int is_tuple)
     265             : {
     266       32690 :         sql_subfunc *a_func = NULL;
     267       32690 :         sql_exp *e = le;
     268             : 
     269       32690 :         if (is_tuple) {
     270        4100 :                 list *l = exp_get_values(e);
     271        4100 :                 e = l->h->data;
     272             :         }
     273       37045 :         if (!(a_func = sql_bind_func(sql, "sys", anyequal ? "sql_anyequal" : "sql_not_anyequal", exp_subtype(e), exp_subtype(e), F_FUNC, true, true)))
     274           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "(NOT) IN operator on type %s missing", exp_subtype(e) ? exp_subtype(e)->type->base.name : "unknown");
     275       32690 :         e = exp_binop(sql->sa, le, vals, a_func);
     276       32690 :         if (e) {
     277       32690 :                 unsigned int exps_card = CARD_ATOM;
     278             : 
     279             :                 /* ignore the cardinalites of sub-relations */
     280       32690 :                 if (vals->type == e_atom && vals->f) {
     281      156506 :                         for (node *n = ((list*)vals->f)->h ; n ; n = n->next) {
     282      123816 :                                 sql_exp *next = n->data;
     283             : 
     284      123816 :                                 if (!exp_is_rel(next) && exps_card < next->card)
     285      123816 :                                         exps_card = next->card;
     286             :                         }
     287           0 :                 } else if (!exp_is_rel(vals))
     288           0 :                         exps_card = vals->card;
     289             : 
     290       32690 :                 e->card = MAX(le->card, exps_card);
     291       32690 :                 if (!has_nil(le) && !has_nil(vals))
     292           0 :                         set_has_no_nil(e);
     293             :         }
     294             :         return e;
     295             : }
     296             : 
     297             : sql_exp *
     298        5562 : exp_in_aggr(mvc *sql, sql_exp *le, sql_exp *vals, int anyequal, int is_tuple)
     299             : {
     300        5562 :         sql_subfunc *a_func = NULL;
     301        5562 :         sql_exp *e = le;
     302             : 
     303        5562 :         if (is_tuple) {
     304           0 :                 list *l = exp_get_values(e);
     305           0 :                 e = l->h->data;
     306             :         }
     307        5571 :         if (!(a_func = sql_bind_func(sql, "sys", anyequal ? "anyequal" : "allnotequal", exp_subtype(e), exp_subtype(e), F_AGGR, true, true)))
     308           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "(NOT) IN operator on type %s missing", exp_subtype(e) ? exp_subtype(e)->type->base.name : "unknown");
     309        5562 :         e = exp_aggr2(sql->sa, le, vals, a_func, need_distinct(e), need_no_nil(e), e->card, has_nil(e));
     310        5562 :         if (e) {
     311        5562 :                 unsigned int exps_card = CARD_ATOM;
     312             : 
     313             :                 /* ignore the cardinalites of sub-relations */
     314        5562 :                 if (vals->type == e_atom && vals->f) {
     315       31472 :                         for (node *n = ((list*)vals->f)->h ; n ; n = n->next) {
     316       25910 :                                 sql_exp *next = n->data;
     317             : 
     318       25910 :                                 if (!exp_is_rel(next) && exps_card < next->card)
     319       25910 :                                         exps_card = next->card;
     320             :                         }
     321           0 :                 } else if (!exp_is_rel(vals))
     322           0 :                         exps_card = vals->card;
     323             : 
     324        5562 :                 e->card = MAX(le->card, exps_card);
     325        5562 :                 if (!has_nil(le) && !has_nil(vals))
     326           0 :                         set_has_no_nil(e);
     327             :         }
     328             :         return e;
     329             : }
     330             : 
     331             : sql_exp *
     332      120764 : exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, const char *compareop, int quantifier)
     333             : {
     334      120764 :         sql_subfunc *cmp_func = sql_bind_func(sql, "sys", compareop, exp_subtype(le), exp_subtype(le), F_FUNC, true, true);
     335      120764 :         sql_exp *e = NULL;
     336             : 
     337      120764 :         if (cmp_func == NULL)
     338             :                 return NULL;
     339             : 
     340      120764 :         e = exp_binop(sql->sa, le, re, cmp_func);
     341      120764 :         if (e) {
     342      120764 :                 e->flag = quantifier;
     343             :                 /* At ANY and ALL operators, the cardinality on the right side is ignored if it is a sub-relation */
     344      120764 :                 e->card = quantifier && exp_is_rel(re) ? le->card : MAX(le->card, re->card);
     345      120764 :                 if (!has_nil(le) && !has_nil(re))
     346       77260 :                         set_has_no_nil(e);
     347             :         }
     348             :         return e;
     349             : }
     350             : 
     351             : static sql_subtype*
     352      852312 : dup_subtype(allocator *sa, sql_subtype *st)
     353             : {
     354      852312 :         sql_subtype *res = SA_NEW(sa, sql_subtype);
     355             : 
     356      852312 :         if (res == NULL)
     357             :                 return NULL;
     358      852312 :         *res = *st;
     359      852312 :         return res;
     360             : }
     361             : 
     362             : sql_exp *
     363      426156 : exp_convert(mvc *sql, sql_exp *exp, sql_subtype *fromtype, sql_subtype *totype )
     364             : {
     365      426156 :         sql_exp *e = exp_create(sql->sa, e_convert);
     366      426156 :         if (e == NULL)
     367             :                 return NULL;
     368      426156 :         e->card = exp->card;
     369      426156 :         e->l = exp;
     370      426156 :         totype = dup_subtype(sql->sa, totype);
     371      426156 :         e->r = append(append(sa_list(sql->sa), dup_subtype(sql->sa, fromtype)),totype);
     372      426156 :         e->tpe = *totype;
     373      426156 :         e->alias = exp->alias;
     374      426156 :         if (e->alias.label)
     375      278324 :                 e->alias.label = -(sql->nid++);
     376      426156 :         if (!has_nil(exp))
     377      166709 :                 set_has_no_nil(e);
     378             :         return e;
     379             : }
     380             : 
     381             : sql_exp *
     382     1079724 : exp_op( allocator *sa, list *l, sql_subfunc *f )
     383             : {
     384     1079724 :         if (f->func->type == F_FILT)
     385        1384 :                 return exp_filter(sa, l, NULL, f, false);
     386     1078340 :         sql_exp *e = exp_create(sa, e_func);
     387     1078340 :         if (e == NULL)
     388             :                 return NULL;
     389     1078340 :         e->card = exps_card(l);
     390     1078340 :         e->l = l;
     391     1078340 :         e->f = f;
     392     1078340 :         e->semantics = f->func->semantics;
     393     1078340 :         if (!is_semantics(e) && !is_any(e) && l && !have_nil(l))
     394      253544 :                 set_has_no_nil(e);
     395             :         return e;
     396             : }
     397             : 
     398             : sql_exp *
     399       17869 : exp_rank_op( allocator *sa, list *l, list *gbe, list *obe, sql_subfunc *f )
     400             : {
     401       17869 :         sql_exp *e = exp_create(sa, e_func);
     402       17869 :         if (e == NULL)
     403             :                 return NULL;
     404       17869 :         e->card = list_empty(l)?CARD_MULTI:exps_card(l);
     405       17869 :         e->l = l;
     406       17869 :         e->r = append(append(sa_list(sa), gbe), obe);
     407       17869 :         e->f = f;
     408       17869 :         if (!f->func->s && strcmp(f->func->base.name, "count") == 0)
     409         180 :                 set_has_no_nil(e);
     410       17869 :         e->semantics = f->func->semantics;
     411       17869 :         return e;
     412             : }
     413             : 
     414             : sql_exp *
     415       60882 : exp_aggr( allocator *sa, list *l, sql_subfunc *a, int distinct, int no_nils, unsigned int card, int has_nils )
     416             : {
     417       60882 :         sql_exp *e = exp_create(sa, e_aggr);
     418       60882 :         if (e == NULL)
     419             :                 return NULL;
     420       60882 :         e->card = card;
     421       60882 :         e->l = l;
     422       60882 :         e->f = a;
     423       60882 :         e->semantics = a->func->semantics;
     424       60882 :         if (distinct)
     425         373 :                 set_distinct(e);
     426       60882 :         if (no_nils)
     427       25165 :                 set_no_nil(e);
     428       60882 :         if ((!a->func->semantics && !has_nils) || (!a->func->s && strcmp(a->func->base.name, "count") == 0))
     429       25764 :                 set_has_no_nil(e);
     430             :         return e;
     431             : }
     432             : 
     433             : sql_exp *
     434     4904302 : exp_atom(allocator *sa, atom *a)
     435             : {
     436     4904302 :         sql_exp *e = exp_create(sa, e_atom);
     437     4904172 :         if (e == NULL)
     438             :                 return NULL;
     439     4904172 :         e->card = CARD_ATOM;
     440     4904172 :         e->tpe = a->tpe;
     441     4904172 :         e->l = a;
     442     4904172 :         if (!a->isnull)
     443     4628900 :                 set_has_no_nil(e);
     444             :         return e;
     445             : }
     446             : 
     447             : sql_exp *
     448           0 : exp_atom_max(allocator *sa, sql_subtype *tpe)
     449             : {
     450           0 :         if (tpe->type->localtype == TYPE_bte) {
     451           0 :                 return exp_atom_bte(sa, GDK_bte_max);
     452             :         } else if (tpe->type->localtype == TYPE_sht) {
     453           0 :                 return exp_atom_sht(sa, GDK_sht_max);
     454             :         } else if (tpe->type->localtype == TYPE_int) {
     455           0 :                 return exp_atom_int(sa, GDK_int_max);
     456             :         } else if (tpe->type->localtype == TYPE_lng) {
     457           0 :                 return exp_atom_lng(sa, GDK_lng_max);
     458             : #ifdef HAVE_HGE
     459             :         } else if (tpe->type->localtype == TYPE_hge) {
     460           0 :                 return exp_atom_hge(sa, GDK_hge_max);
     461             : #endif
     462             :         }
     463             :         return NULL;
     464             : }
     465             : 
     466             : sql_exp *
     467      146539 : exp_atom_bool(allocator *sa, int b)
     468             : {
     469      146539 :         sql_subtype bt;
     470             : 
     471      146539 :         sql_find_subtype(&bt, "boolean", 0, 0);
     472      146539 :         if (b)
     473       98500 :                 return exp_atom(sa, atom_bool(sa, &bt, TRUE ));
     474             :         else
     475       48039 :                 return exp_atom(sa, atom_bool(sa, &bt, FALSE ));
     476             : }
     477             : 
     478             : sql_exp *
     479           0 : exp_atom_bte(allocator *sa, bte i)
     480             : {
     481           0 :         sql_subtype it;
     482             : 
     483           0 :         sql_find_subtype(&it, "tinyint", 3, 0);
     484           0 :         return exp_atom(sa, atom_int(sa, &it, i ));
     485             : }
     486             : 
     487             : sql_exp *
     488           0 : exp_atom_sht(allocator *sa, sht i)
     489             : {
     490           0 :         sql_subtype it;
     491             : 
     492           0 :         sql_find_subtype(&it, "smallint", 5, 0);
     493           0 :         return exp_atom(sa, atom_int(sa, &it, i ));
     494             : }
     495             : 
     496             : sql_exp *
     497      866118 : exp_atom_int(allocator *sa, int i)
     498             : {
     499      866118 :         sql_subtype it;
     500             : 
     501      866118 :         sql_find_subtype(&it, "int", 9, 0);
     502      866117 :         return exp_atom(sa, atom_int(sa, &it, i ));
     503             : }
     504             : 
     505             : sql_exp *
     506       16436 : exp_atom_lng(allocator *sa, lng i)
     507             : {
     508       16436 :         sql_subtype it;
     509             : 
     510             : #ifdef HAVE_HGE
     511       16436 :         sql_find_subtype(&it, "bigint", 18, 0);
     512             : #else
     513             :         sql_find_subtype(&it, "bigint", 19, 0);
     514             : #endif
     515       16436 :         return exp_atom(sa, atom_int(sa, &it, i ));
     516             : }
     517             : 
     518             : sql_exp *
     519       16336 : exp_atom_oid(allocator *sa, oid i)
     520             : {
     521       16336 :         sql_subtype it;
     522             : 
     523             : #if SIZEOF_OID == SIZEOF_INT
     524             :         sql_find_subtype(&it, "oid", 31, 0);
     525             : #else
     526       16336 :         sql_find_subtype(&it, "oid", 63, 0);
     527             : #endif
     528       16336 :         return exp_atom(sa, atom_int(sa, &it, i ));
     529             : }
     530             : 
     531             : #ifdef HAVE_HGE
     532             : sql_exp *
     533           1 : exp_atom_hge(allocator *sa, hge i)
     534             : {
     535           1 :         sql_subtype it;
     536             : 
     537           1 :         sql_find_subtype(&it, "hugeint", 39, 0);
     538           1 :         return exp_atom(sa, atom_int(sa, &it, i ));
     539             : }
     540             : #endif
     541             : 
     542             : sql_exp *
     543           0 : exp_atom_flt(allocator *sa, flt f)
     544             : {
     545           0 :         sql_subtype it;
     546             : 
     547           0 :         sql_find_subtype(&it, "real", 24, 0);
     548           0 :         return exp_atom(sa, atom_float(sa, &it, (dbl)f ));
     549             : }
     550             : 
     551             : sql_exp *
     552           0 : exp_atom_dbl(allocator *sa, dbl f)
     553             : {
     554           0 :         sql_subtype it;
     555             : 
     556           0 :         sql_find_subtype(&it, "double", 53, 0);
     557           0 :         return exp_atom(sa, atom_float(sa, &it, (dbl)f ));
     558             : }
     559             : 
     560             : sql_exp *
     561       85447 : exp_atom_str(allocator *sa, const char *s, sql_subtype *st)
     562             : {
     563      166309 :         return exp_atom(sa, atom_string(sa, st, s?sa_strdup(sa, s):NULL));
     564             : }
     565             : 
     566             : sql_exp *
     567      745382 : exp_atom_clob(allocator *sa, const char *s)
     568             : {
     569      745382 :         sql_subtype clob;
     570             : 
     571      745382 :         sql_find_subtype(&clob, "varchar", 0, 0);
     572     1489169 :         return exp_atom(sa, atom_string(sa, &clob, s?sa_strdup(sa, s):NULL));
     573             : }
     574             : 
     575             : sql_exp *
     576      268262 : exp_atom_ptr(allocator *sa, void *s)
     577             : {
     578      268262 :         sql_subtype *t = sql_bind_localtype("ptr");
     579      268262 :         return exp_atom(sa, atom_ptr(sa, t, s));
     580             : }
     581             : 
     582             : sql_exp *
     583        2164 : exp_atom_ref(allocator *sa, int i, sql_subtype *tpe)
     584             : {
     585        2164 :         sql_exp *e = exp_create(sa, e_atom);
     586        2164 :         if (e == NULL)
     587             :                 return NULL;
     588        2164 :         e->card = CARD_ATOM;
     589        2164 :         e->flag = i;
     590        2164 :         if (tpe)
     591        2164 :                 e->tpe = *tpe;
     592             :         return e;
     593             : }
     594             : 
     595             : sql_exp *
     596      108082 : exp_null(allocator *sa, sql_subtype *tpe)
     597             : {
     598      108082 :         atom *a = atom_general(sa, tpe, NULL, 0);
     599      108082 :         return exp_atom(sa, a);
     600             : }
     601             : 
     602             : sql_exp *
     603           2 : exp_zero(allocator *sa, sql_subtype *tpe)
     604             : {
     605           2 :         atom *a = atom_zero_value(sa, tpe);
     606           2 :         return exp_atom(sa, a);
     607             : }
     608             : 
     609             : atom *
     610         395 : exp_value(mvc *sql, sql_exp *e)
     611             : {
     612         395 :         if (!e || e->type != e_atom)
     613             :                 return NULL;
     614         384 :         if (e->l) { /* literal */
     615             :                 return e->l;
     616           0 :         } else if (e->r) { /* param (ie not set) */
     617           0 :                 sql_var_name *vname = (sql_var_name*) e->r;
     618             : 
     619           0 :                 assert(e->flag != 0 || vname->sname); /* global variables must have a schema */
     620           0 :                 sql_var *var = e->flag == 0 ? find_global_var(sql, mvc_bind_schema(sql, vname->sname), vname->name) :
     621           0 :                                                                           stack_find_var_at_level(sql, vname->name, e->flag);
     622           0 :                 if (var)
     623           0 :                         return &(var->var);
     624             :         }
     625             :         return NULL;
     626             : }
     627             : 
     628             : sql_exp *
     629      123440 : exp_param_or_declared(allocator *sa, const char *sname, const char *name, sql_subtype *tpe, int frame)
     630             : {
     631      123440 :         sql_var_name *vname;
     632      123440 :         sql_exp *e = exp_create(sa, e_atom);
     633      123440 :         if (e == NULL)
     634             :                 return NULL;
     635             : 
     636      123440 :         e->r = sa_alloc(sa, sizeof(sql_var_name));
     637      123440 :         vname = (sql_var_name*) e->r;
     638      123440 :         vname->sname = sname;
     639      123440 :         vname->name = name;
     640      123440 :         e->card = CARD_ATOM;
     641      123440 :         e->flag = frame;
     642      123440 :         if (tpe)
     643      123440 :                 e->tpe = *tpe;
     644             :         return e;
     645             : }
     646             : 
     647             : sql_exp *
     648      209315 : exp_values(allocator *sa, list *exps)
     649             : {
     650      209315 :         sql_exp *e = exp_create(sa, e_atom);
     651      209308 :         if (e == NULL)
     652             :                 return NULL;
     653      209308 :         e->card = exps_card(exps);
     654      209308 :         e->f = exps;
     655      209308 :         return e;
     656             : }
     657             : 
     658             : list *
     659       27845 : exp_get_values(sql_exp *e)
     660             : {
     661       27845 :         if (is_atom(e->type) && e->f)
     662             :                 return e->f;
     663             :         return NULL;
     664             : }
     665             : 
     666             : list *
     667       40768 : exp_types(allocator *sa, list *exps)
     668             : {
     669       40768 :         list *l = sa_list(sa);
     670             : 
     671       40768 :         if (exps)
     672       91240 :                 for (node *n = exps->h; n; n = n->next)
     673       50472 :                         list_append(l, exp_subtype(n->data));
     674       40768 :         return l;
     675             : }
     676             : 
     677             : int
     678     1044875 : have_nil(list *exps)
     679             : {
     680     1044875 :         int has_nil = 0;
     681             : 
     682     1044875 :         if (exps)
     683     2634831 :                 for (node *n = exps->h; n && !has_nil; n = n->next) {
     684     1589956 :                         sql_exp *e = n->data;
     685     1589956 :                         has_nil |= has_nil(e);
     686             :                 }
     687     1044875 :         return has_nil;
     688             : }
     689             : 
     690             : int
     691         212 : have_semantics(list *exps)
     692             : {
     693         212 :         int has_semantics = 0;
     694             : 
     695         212 :         if (exps)
     696          65 :                 for (node *n = exps->h; n && !has_semantics; n = n->next) {
     697          33 :                         sql_exp *e = n->data;
     698          66 :                         has_semantics |= is_compare(e->type) && is_semantics(e);
     699             :                 }
     700         212 :         return has_semantics;
     701             : }
     702             : 
     703             : sql_exp *
     704     6775968 : exp_column(allocator *sa, const char *rname, const char *cname, sql_subtype *t, unsigned int card, int has_nils, int unique, int intern)
     705             : {
     706     6775968 :         sql_exp *e = exp_create(sa, e_column);
     707             : 
     708     6775811 :         if (e == NULL)
     709             :                 return NULL;
     710     6775811 :         assert(cname);
     711     6775811 :         e->card = card;
     712     6775811 :         e->alias.name = cname;
     713     6775811 :         e->alias.rname = rname;
     714     6775811 :         e->r = (char*)e->alias.name;
     715     6775811 :         e->l = (char*)e->alias.rname;
     716     6775811 :         if (t)
     717     6775413 :                 e->tpe = *t;
     718     6775811 :         if (!has_nils)
     719     1945089 :                 set_has_no_nil(e);
     720     6775811 :         if (unique)
     721      908250 :                 set_unique(e);
     722     6775811 :         if (intern)
     723      578621 :                 set_intern(e);
     724             :         return e;
     725             : }
     726             : 
     727             : sql_exp *
     728     9769868 : exp_propagate(allocator *sa, sql_exp *ne, sql_exp *oe)
     729             : {
     730     9769868 :         if (has_label(oe) &&
     731      517929 :            (oe->alias.rname == ne->alias.rname || (oe->alias.rname && ne->alias.rname && strcmp(oe->alias.rname, ne->alias.rname) == 0)) &&
     732      510719 :            (oe->alias.name == ne->alias.name || (oe->alias.name && ne->alias.name && strcmp(oe->alias.name, ne->alias.name) == 0)))
     733      510719 :                 ne->alias.label = oe->alias.label;
     734     9769868 :         if (is_intern(oe))
     735      314243 :                 set_intern(ne);
     736     9769868 :         if (is_anti(oe))
     737        2291 :                 set_anti(ne);
     738     9769868 :         if (is_semantics(oe))
     739      654349 :                 set_semantics(ne);
     740     9769868 :         if (is_any(oe))
     741          44 :                 set_any(ne);
     742     9769868 :         if (is_symmetric(oe))
     743          16 :                 set_symmetric(ne);
     744     9769868 :         if (is_ascending(oe))
     745       19724 :                 set_ascending(ne);
     746     9769868 :         if (nulls_last(oe))
     747        4096 :                 set_nulls_last(ne);
     748     9769868 :         if (need_distinct(oe))
     749         670 :                 set_distinct(ne);
     750     9769868 :         if (zero_if_empty(oe))
     751           0 :                 set_zero_if_empty(ne);
     752     9769868 :         if (need_no_nil(oe))
     753       79561 :                 set_no_nil(ne);
     754     9769868 :         if (!has_nil(oe))
     755     5727970 :                 set_has_no_nil(ne);
     756     9769868 :         if (has_nil(oe))
     757     4041895 :                 set_has_nil(ne);
     758     9769868 :         if (is_unique(oe))
     759     1086645 :                 set_unique(ne);
     760     9769868 :         if (is_basecol(oe))
     761     8082536 :                 set_basecol(ne);
     762     9769868 :         ne->p = prop_copy(sa, oe->p);
     763     9769867 :         return ne;
     764             : }
     765             : 
     766             : static sql_exp *
     767     6623796 : exp_ref_by_label(allocator *sa, sql_exp *o)
     768             : {
     769     6623796 :         sql_exp *e = exp_create(sa, e_column);
     770             : 
     771     6623796 :         if (e == NULL)
     772             :                 return NULL;
     773     6623796 :         e->card = o->card;
     774     6623796 :         e->alias = o->alias;
     775     6623796 :         assert(e->alias.label);
     776     6623796 :         e->r = (char*)e->alias.name;
     777     6623796 :         e->l = (char*)e->alias.rname;
     778     6623796 :         e->nid = o->alias.label;
     779     6623796 :         assert(e->nid);
     780     6623796 :         sql_subtype *t = exp_subtype(o);
     781     6623797 :         if (t)
     782     6623682 :                 e->tpe = *t;
     783     6623797 :         if (!has_nil(o))
     784     4037656 :                 set_has_no_nil(e);
     785     6623797 :         if (has_nil(o))
     786     2586141 :                 set_has_nil(e);
     787     6623797 :         if (is_unique(o))
     788      860206 :                 set_unique(e);
     789     6623797 :         if (is_intern(o))
     790      279117 :                 set_intern(e);
     791     6623797 :         return exp_propagate(sa, e, o);
     792             : }
     793             : 
     794             : sql_exp *
     795     6623797 : exp_ref(mvc *sql, sql_exp *e)
     796             : {
     797     6623797 :         if (!has_label(e) && !exp_name(e))
     798        2258 :                 exp_label(sql->sa, e, ++sql->label);
     799     6623797 :         if (e->alias.label)
     800     6623797 :                 return exp_ref_by_label(sql->sa, e);
     801           0 :         sql_exp *ne = exp_propagate(sql->sa, exp_column(sql->sa, exp_relname(e), exp_name(e), exp_subtype(e), exp_card(e), has_nil(e), is_unique(e), is_intern(e)), e);
     802           0 :         if (ne) {
     803           0 :                 ne->nid = e->alias.label;
     804           0 :                 assert(ne->nid);
     805           0 :                 assert(!ne->nid || ne->alias.name);
     806           0 :                 ne->alias.label = ne->nid;
     807             :         }
     808             :         return ne;
     809             : }
     810             : 
     811             : sql_exp *
     812       13868 : exp_ref_save(mvc *sql, sql_exp *e)
     813             : {
     814       13868 :         if (e->type == e_column)
     815             :                 return e;
     816       10274 :         if (is_atom(e->type))
     817        5195 :                 return exp_copy(sql, e);
     818        5079 :         if (!e->alias.label || !exp_name(e))
     819           8 :                 exp_label(sql->sa, e, ++sql->label);
     820        5079 :         if (e->type != e_column) /* ref as referenced within the (same) rank expression */
     821        5079 :                 e->ref = 1;
     822        5079 :         sql_exp *ne = exp_ref(sql, e);
     823        5079 :         if (ne && is_freevar(e))
     824           0 :                 set_freevar(ne, is_freevar(e)-1);
     825             :         return ne;
     826             : }
     827             : 
     828             : sql_exp *
     829     2057051 : exp_alias(mvc *sql, const char *arname, const char *acname, const char *org_rname, const char *org_cname, sql_subtype *t, unsigned int card, int has_nils, int unique, int intern)
     830             : {
     831     2057051 :         sql_exp *e = exp_column(sql->sa, org_rname, org_cname, t, card, has_nils, unique, intern);
     832             : 
     833     2056949 :         if (e == NULL)
     834             :                 return NULL;
     835     2056949 :         assert(acname && org_cname);
     836     2056949 :         exp_setname(sql, e, (arname)?arname:org_rname, acname);
     837     2056949 :         return e;
     838             : }
     839             : 
     840             : sql_exp *
     841           0 : exp_alias_ref(mvc *sql, sql_exp *e)
     842             : {
     843           0 :         const char *tname = exp_relname(e);
     844           0 :         const char *cname = exp_name(e);
     845             : 
     846           0 :         if (!has_label(e))
     847           0 :                 exp_label(sql->sa, e, ++sql->label);
     848           0 :         sql_exp *ne = exp_ref(sql, e);
     849           0 :         if (ne == NULL)
     850             :                 return NULL;
     851           0 :         exp_setname(sql, ne, tname, cname);
     852           0 :         return ne;
     853             : }
     854             : 
     855             : sql_exp *
     856       16148 : exp_set(allocator *sa, const char *sname, const char *name, sql_exp *val, int level)
     857             : {
     858       16148 :         sql_exp *e = exp_create(sa, e_psm);
     859             : 
     860       16148 :         if (e == NULL)
     861             :                 return NULL;
     862       16148 :         e->alias.rname = sname;
     863       16148 :         e->alias.name = name;
     864       16148 :         e->l = val;
     865       16148 :         e->flag = PSM_SET + SET_PSM_LEVEL(level);
     866       16148 :         return e;
     867             : }
     868             : 
     869             : sql_exp *
     870        9523 : exp_var(allocator *sa, const char *sname, const char *name, sql_subtype *type, int level)
     871             : {
     872        9523 :         sql_exp *e = exp_create(sa, e_psm);
     873             : 
     874        9523 :         if (e == NULL)
     875             :                 return NULL;
     876        9523 :         e->alias.rname = sname;
     877        9523 :         e->alias.name = name;
     878        9523 :         e->tpe = *type;
     879        9523 :         e->flag = PSM_VAR + SET_PSM_LEVEL(level);
     880        9523 :         return e;
     881             : }
     882             : 
     883             : sql_exp *
     884         119 : exp_table(allocator *sa, const char *name, sql_table *t, int level)
     885             : {
     886         119 :         sql_exp *e = exp_create(sa, e_psm);
     887             : 
     888         119 :         if (e == NULL)
     889             :                 return NULL;
     890         119 :         e->alias.rname = NULL;
     891         119 :         e->alias.name = name;
     892         119 :         e->f = t;
     893         119 :         e->flag = PSM_VAR + SET_PSM_LEVEL(level);
     894         119 :         return e;
     895             : }
     896             : 
     897             : sql_exp *
     898       23338 : exp_return(allocator *sa, sql_exp *val, int level)
     899             : {
     900       23338 :         sql_exp *e = exp_create(sa, e_psm);
     901             : 
     902       23338 :         if (e == NULL)
     903             :                 return NULL;
     904       23338 :         e->l = val;
     905       23338 :         e->flag = PSM_RETURN + SET_PSM_LEVEL(level);
     906       23338 :         return e;
     907             : }
     908             : 
     909             : sql_exp *
     910        1019 : exp_while(allocator *sa, sql_exp *cond, list *stmts)
     911             : {
     912        1019 :         sql_exp *e = exp_create(sa, e_psm);
     913             : 
     914        1019 :         if (e == NULL)
     915             :                 return NULL;
     916        1019 :         e->l = cond;
     917        1019 :         e->r = stmts;
     918        1019 :         e->flag = PSM_WHILE;
     919        1019 :         return e;
     920             : }
     921             : 
     922             : sql_exp *
     923       11661 : exp_if(allocator *sa, sql_exp *cond, list *if_stmts, list *else_stmts)
     924             : {
     925       11661 :         sql_exp *e = exp_create(sa, e_psm);
     926             : 
     927       11661 :         if (e == NULL)
     928             :                 return NULL;
     929       11661 :         e->l = cond;
     930       11661 :         e->r = if_stmts;
     931       11661 :         e->f = else_stmts;
     932       11661 :         e->flag = PSM_IF;
     933       11661 :         return e;
     934             : }
     935             : 
     936             : sql_exp *
     937       78179 : exp_rel(mvc *sql, sql_rel *rel)
     938             : {
     939       78179 :         sql_exp *e = exp_create(sql->sa, e_psm);
     940             : 
     941       78179 :         if (e == NULL)
     942             :                 return NULL;
     943       78179 :         e->l = rel;
     944       78179 :         e->flag = PSM_REL;
     945       78179 :         e->card = is_single(rel)?CARD_ATOM:rel->card;
     946       78179 :         assert(rel);
     947       78179 :         if (is_topn(rel->op))
     948           3 :                 rel = rel->l;
     949       78179 :         if (is_project(rel->op)) {
     950       59723 :                 sql_exp *last = rel->exps->t->data;
     951       59723 :                 sql_subtype *t = exp_subtype(last);
     952       59722 :                 e->tpe = t ? *t : (sql_subtype) {0};
     953             :         }
     954             :         return e;
     955             : }
     956             : 
     957             : sql_exp *
     958         157 : exp_exception(allocator *sa, sql_exp *cond, const char *error_message)
     959             : {
     960         157 :         sql_exp *e = exp_create(sa, e_psm);
     961             : 
     962         157 :         if (e == NULL)
     963             :                 return NULL;
     964         157 :         e->l = cond;
     965         157 :         e->r = sa_strdup(sa, error_message);
     966         157 :         e->flag = PSM_EXCEPTION;
     967         157 :         return e;
     968             : }
     969             : 
     970             : /* Set a name (alias) for the expression, such that we can refer
     971             :    to this expression by this simple name.
     972             :  */
     973             : void
     974     3586634 : exp_setname(mvc *sql, sql_exp *e, const char *rname, const char *name )
     975             : {
     976     3586634 :         assert(name || rname);
     977     3586634 :         e->alias.label = -(sql->nid++);
     978             :         //e->alias.label = 0;
     979     3586634 :         if (name)
     980     3424631 :                 e->alias.name = name;
     981     3586634 :         e->alias.rname = (rname);
     982     3586634 : }
     983             : 
     984             : void
     985      162126 : noninternexp_setname(mvc *sql, sql_exp *e, const char *rname, const char *name )
     986             : {
     987      162126 :         if (!is_intern(e))
     988      162124 :                 exp_setname(sql, e, rname, name);
     989      162126 : }
     990             : 
     991             : void
     992      647757 : exp_setalias(sql_exp *e, int label, const char *rname, const char *name )
     993             : {
     994      647757 :         e->alias.label = label;
     995      647757 :         assert(e->alias.label);
     996      647757 :         e->alias.name = name;
     997      647757 :         e->alias.rname = rname;
     998      647757 : }
     999             : 
    1000             : void
    1001     4315672 : exp_prop_alias(allocator *sa, sql_exp *e, sql_exp *oe )
    1002             : {
    1003     4315672 :         e->ref = oe->ref;
    1004     4315672 :         if (oe->alias.name == NULL && exp_has_rel(oe)) {
    1005        7756 :                 sql_rel *r = exp_rel_get_rel(sa, oe);
    1006        7756 :                 if (!is_project(r->op))
    1007             :                         return ;
    1008        7756 :                 oe = r->exps->t->data;
    1009             :         }
    1010     4315672 :         e->alias = oe->alias;
    1011             : }
    1012             : 
    1013             : str
    1014     1995421 : number2name(str s, int len, int i)
    1015             : {
    1016     1995421 :         s[--len] = 0;
    1017     6083643 :         while(i>0) {
    1018     4088222 :                 s[--len] = '0' + (i & 7);
    1019     4088222 :                 i >>= 3;
    1020             :         }
    1021     1995421 :         s[--len] = '%';
    1022     1995421 :         return s + len;
    1023             : }
    1024             : 
    1025             : void
    1026           0 : exp_setrelname(allocator *sa, sql_exp *e, int nr)
    1027             : {
    1028           0 :         char name[16], *nme;
    1029             : 
    1030           0 :         nme = number2name(name, sizeof(name), nr);
    1031           0 :         e->alias.label = 0;
    1032           0 :         e->alias.rname = sa_strdup(sa, nme);
    1033           0 : }
    1034             : 
    1035             : char *
    1036     1934381 : make_label(allocator *sa, int nr)
    1037             : {
    1038     1934381 :         char name[16], *nme;
    1039             : 
    1040     1934381 :         nme = number2name(name, sizeof(name), nr);
    1041     1934336 :         return sa_strdup(sa, nme);
    1042             : }
    1043             : 
    1044             : sql_exp*
    1045     1924716 : exp_label(allocator *sa, sql_exp *e, int nr)
    1046             : {
    1047     1924716 :         assert(nr > 0);
    1048             :         //assert (e->alias.label == 0);
    1049     1924716 :         e->alias.label = nr;
    1050     1924716 :         e->alias.rname = e->alias.name = make_label(sa, nr);
    1051     1924801 :         return e;
    1052             : }
    1053             : 
    1054             : list*
    1055       52061 : exps_label(mvc *sql, list *exps)
    1056             : {
    1057       52061 :         if (!exps)
    1058             :                 return NULL;
    1059             : 
    1060       52061 :         int nr = sql->label+1;
    1061       52061 :         sql->label += list_length(exps);
    1062      119872 :         for (node *n = exps->h; n; n = n->next)
    1063       67811 :                 n->data = exp_label(sql->sa, n->data, nr++);
    1064       52061 :         list_hash_clear(exps);
    1065       52061 :         return exps;
    1066             : }
    1067             : 
    1068             : void
    1069       20837 : exp_swap( sql_exp *e )
    1070             : {
    1071       20837 :         sql_exp *s = e->l;
    1072             : 
    1073       20837 :         e->l = e->r;
    1074       20837 :         e->r = s;
    1075       20837 :         e->flag = swap_compare((comp_type)e->flag);
    1076       20837 :         assert(!e->f);
    1077       20837 : }
    1078             : 
    1079             : sql_subtype *
    1080    33916155 : exp_subtype( sql_exp *e )
    1081             : {
    1082    33916203 :         switch(e->type) {
    1083     7880043 :         case e_atom: {
    1084     7880043 :                 if (e->l) {
    1085     7152821 :                         atom *a = e->l;
    1086     7152821 :                         return atom_type(a);
    1087      727222 :                 } else if (e->tpe.type) { /* atom reference */
    1088      725363 :                         return &e->tpe;
    1089        1859 :                 } else if (e->f) {
    1090          48 :                         list *vals = exp_get_values(e);
    1091          48 :                         if (!list_empty(vals))
    1092          48 :                                 return exp_subtype(vals->h->data);
    1093             :                 }
    1094             :                 break;
    1095             :         }
    1096    21364500 :         case e_convert:
    1097             :         case e_column:
    1098    21364500 :                 if (e->tpe.type)
    1099    21364389 :                         return &e->tpe;
    1100             :                 break;
    1101     4538376 :         case e_aggr:
    1102             :         case e_func: {
    1103     4538376 :                 if (e->f) {
    1104     4538376 :                         sql_subfunc *f = e->f;
    1105     4538376 :                         if (f->res && list_length(f->res) == 1)
    1106     4527839 :                                 return f->res->h->data;
    1107             :                 }
    1108             :                 return NULL;
    1109             :         }
    1110        7237 :         case e_cmp:
    1111        7237 :                 return sql_bind_localtype("bit");
    1112      126047 :         case e_psm:
    1113      126047 :                 if (e->tpe.type)
    1114      126032 :                         return &e->tpe;
    1115             :                 /* fall through */
    1116             :         default:
    1117             :                 return NULL;
    1118             :         }
    1119             :         return NULL;
    1120             : }
    1121             : 
    1122             : const char *
    1123    34355380 : exp_name( sql_exp *e )
    1124             : {
    1125    34369257 :         if (e->alias.name)
    1126             :                 return e->alias.name;
    1127     1496839 :         if (e->type == e_convert && e->l)
    1128             :                 return exp_name(e->l);
    1129     1492852 :         if (e->type == e_psm && e->l) { /* subquery return name of last expression */
    1130        9890 :                 sql_rel *r = e->l;
    1131        9890 :                 if (is_project(r->op))
    1132        9890 :                         return exp_name(r->exps->t->data);
    1133             :         }
    1134             :         return NULL;
    1135             : }
    1136             : 
    1137             : const char *
    1138     3803405 : exp_relname( sql_exp *e )
    1139             : {
    1140     3803417 :         if (e->alias.rname)
    1141             :                 return e->alias.rname;
    1142      454619 :         if (!e->alias.name && e->type == e_convert && e->l)
    1143             :                 return exp_relname(e->l);
    1144      454607 :         if (!e->alias.name && e->type == e_psm && e->l) { /* subquery return name of last expression */
    1145           0 :                 sql_rel *r = e->l;
    1146           0 :                 if (is_project(r->op))
    1147           0 :                         return exp_relname(r->exps->t->data);
    1148             :         }
    1149             :         return NULL;
    1150             : }
    1151             : 
    1152             : const char *
    1153       17065 : exp_find_rel_name(sql_exp *e)
    1154             : {
    1155       17065 :         if (e->alias.rname)
    1156             :                 return e->alias.rname;
    1157         467 :         switch(e->type) {
    1158             :         case e_column:
    1159             :                 break;
    1160           0 :         case e_convert:
    1161           0 :                 return exp_find_rel_name(e->l);
    1162             :         default:
    1163             :                 return NULL;
    1164             :         }
    1165             :         return NULL;
    1166             : }
    1167             : 
    1168             : unsigned int
    1169     1833726 : exp_card( sql_exp *e )
    1170             : {
    1171     1833726 :         return e->card;
    1172             : }
    1173             : 
    1174             : unsigned int
    1175     1519970 : exp_get_label( sql_exp *e )
    1176             : {
    1177     1519982 :         if (e->alias.label)
    1178     1519970 :                 return e->alias.label;
    1179          12 :         if (e->type == e_convert && e->l)
    1180             :                 return exp_get_label(e->l);
    1181           0 :         if (e->type == e_psm && e->l) { /* subquery return name of last expression */
    1182           0 :                 sql_rel *r = e->l;
    1183           0 :                 if (is_project(r->op))
    1184           0 :                         return exp_get_label(r->exps->t->data);
    1185             :         }
    1186             :         return 0;
    1187             : }
    1188             : 
    1189             : 
    1190             : const char *
    1191           0 : exp_func_name( sql_exp *e )
    1192             : {
    1193           0 :         if (e->type == e_func && e->f) {
    1194           0 :                 sql_subfunc *f = e->f;
    1195           0 :                 return f->func->base.name;
    1196             :         }
    1197           0 :         if (e->alias.name)
    1198             :                 return e->alias.name;
    1199           0 :         if (e->type == e_convert && e->l)
    1200           0 :                 return exp_name(e->l);
    1201             :         return NULL;
    1202             : }
    1203             : 
    1204             : int
    1205    48950295 : exp_cmp( sql_exp *e1, sql_exp *e2)
    1206             : {
    1207    48950295 :         return (e1 == e2)?0:-1;
    1208             : }
    1209             : 
    1210             : int
    1211      230269 : exp_equal( sql_exp *e1, sql_exp *e2)
    1212             : {
    1213      230269 :         if (e1 == e2)
    1214             :                 return 0;
    1215      230269 :         if (e1->alias.label && e1->alias.label == e2->alias.label)
    1216        3743 :                 return 0;
    1217             :         return -1;
    1218             :         if (e1->alias.rname && e2->alias.rname && strcmp(e1->alias.rname, e2->alias.rname) == 0)
    1219             :                 if (e1->alias.name && e2->alias.name && strcmp(e1->alias.name, e2->alias.name) == 0)
    1220             :                         return 0;
    1221             :         if (!e1->alias.rname && !e2->alias.rname && /*has_label(e1) &&*/ e1->alias.label == e2->alias.label && e1->alias.name && e2->alias.name)
    1222             :                 return strcmp(e1->alias.name, e2->alias.name);
    1223             :         return -1;
    1224             : }
    1225             : 
    1226             : int
    1227    48950162 : exp_match( sql_exp *e1, sql_exp *e2)
    1228             : {
    1229    48950162 :         if (exp_cmp(e1, e2) == 0)
    1230             :                 return 1;
    1231    48703643 :         if (e1->type == e2->type && e1->type == e_column) {
    1232    24382725 :                 if (e1->nid && e1->nid == e2->nid)
    1233             :                         return 1;
    1234    23171942 :                 if (e1->alias.label != e2->alias.label || !e1->alias.label || !e2->alias.label)
    1235             :                         return 0;
    1236             :                 return 1;
    1237             :         }
    1238    24320918 :         if (e1->type == e2->type && e1->type == e_func) {
    1239     8534555 :                 if (is_identity(e1, NULL) && is_identity(e2, NULL)) {
    1240           0 :                         list *args1 = e1->l;
    1241           0 :                         list *args2 = e2->l;
    1242             : 
    1243           0 :                         if (list_length(args1) == list_length(args2) && list_length(args1) == 1) {
    1244           0 :                                 sql_exp *ne1 = args1->h->data;
    1245           0 :                                 sql_exp *ne2 = args2->h->data;
    1246             : 
    1247           0 :                                 if (exp_match(ne1,ne2))
    1248             :                                         return 1;
    1249             :                         }
    1250             :                 }
    1251             :         }
    1252             :         return 0;
    1253             : }
    1254             : 
    1255             : /* list already contains matching expression */
    1256             : sql_exp*
    1257      163312 : exps_find_exp( list *l, sql_exp *e)
    1258             : {
    1259      163312 :         node *n;
    1260             : 
    1261      163312 :         if (!l || !l->h)
    1262             :                 return NULL;
    1263             : 
    1264      397154 :         for(n=l->h; n; n = n->next) {
    1265      357068 :                 if (exp_match(n->data, e) || exp_refers(n->data, e))
    1266      110472 :                         return n->data;
    1267             :         }
    1268             :         return NULL;
    1269             : }
    1270             : 
    1271             : /* c refers to the parent p */
    1272             : int
    1273     3495580 : exp_refers( sql_exp *p, sql_exp *c)
    1274             : {
    1275     3495580 :         if (c->type == e_column && c->nid)
    1276      398277 :                 return c->nid == p->alias.label;
    1277             :         return 0;
    1278             : }
    1279             : 
    1280             : sql_exp*
    1281         218 : exps_refers(sql_exp *p, list *l)
    1282             : {
    1283         218 :         node *n;
    1284             : 
    1285         218 :         if (!l || !l->h)
    1286             :                 return NULL;
    1287             : 
    1288         532 :         for(n=l->h; n; n = n->next) {
    1289         318 :                 if (exp_refers(p, n->data))
    1290           4 :                         return n->data;
    1291             :         }
    1292             :         return NULL;
    1293             : }
    1294             : 
    1295             : int
    1296           0 : exp_match_col_exps( sql_exp *e, list *l)
    1297             : {
    1298           0 :         node *n;
    1299             : 
    1300           0 :         for(n=l->h; n; n = n->next) {
    1301           0 :                 sql_exp *re = n->data;
    1302           0 :                 sql_exp *re_r = re->r;
    1303             : 
    1304           0 :                 if (re->type == e_cmp && re->flag == cmp_or)
    1305           0 :                         return exp_match_col_exps(e, re->l) &&
    1306           0 :                                exp_match_col_exps(e, re->r);
    1307             : 
    1308           0 :                 if (re->type != e_cmp || !re_r || re_r->card != 1 || !exp_match_exp(e, re->l))
    1309           0 :                         return 0;
    1310             :         }
    1311             :         return 1;
    1312             : }
    1313             : 
    1314             : int
    1315       10817 : exps_match_col_exps( sql_exp *e1, sql_exp *e2)
    1316             : {
    1317       10817 :         sql_exp *e1_r = e1->r;
    1318       10817 :         sql_exp *e2_r = e2->r;
    1319             : 
    1320       10817 :         if (e1->type != e_cmp || e2->type != e_cmp)
    1321             :                 return 0;
    1322             : 
    1323       10746 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1324        5994 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1325        5067 :                 return exp_match_exp(e1->l, e2->l);
    1326             : 
    1327        5679 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1328         927 :             (e2->flag == cmp_in || e2->flag == cmp_notin))
    1329         845 :                 return exp_match_exp(e1->l, e2->l);
    1330        4834 :         if ((e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1331        2331 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1332        1579 :                 return exp_match_exp(e1->l, e2->l);
    1333             : 
    1334        3255 :         if ((e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1335         752 :             (e2->flag == cmp_in || e2->flag == cmp_notin))
    1336         752 :                 return exp_match_exp(e1->l, e2->l);
    1337             : 
    1338        2503 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1339          82 :             e2->flag == cmp_or)
    1340           0 :                 return exp_match_col_exps(e1->l, e2->l) &&
    1341           0 :                        exp_match_col_exps(e1->l, e2->r);
    1342             : 
    1343        2503 :         if (e1->flag == cmp_or &&
    1344           0 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1345           0 :                 return exp_match_col_exps(e2->l, e1->l) &&
    1346           0 :                        exp_match_col_exps(e2->l, e1->r);
    1347             : 
    1348        2503 :         if (e1->flag == cmp_or && e2->flag == cmp_or) {
    1349           0 :                 list *l = e1->l, *r = e1->r;
    1350           0 :                 sql_exp *el = l->h->data;
    1351           0 :                 sql_exp *er = r->h->data;
    1352             : 
    1353           0 :                 return list_length(l) == 1 && list_length(r) == 1 &&
    1354           0 :                        exps_match_col_exps(el, e2) &&
    1355           0 :                        exps_match_col_exps(er, e2);
    1356             :         }
    1357             :         return 0;
    1358             : }
    1359             : 
    1360             : int
    1361       47556 : exp_match_list( list *l, list *r)
    1362             : {
    1363       47556 :         node *n, *m;
    1364       47556 :         char *lu, *ru;
    1365       47556 :         int lc = 0, rc = 0, match = 0;
    1366             : 
    1367       47556 :         if (!l || !r)
    1368           0 :                 return l == r;
    1369       47556 :         if (list_length(l) != list_length(r) || list_length(l) == 0 || list_length(r) == 0)
    1370         601 :                 return 0;
    1371       46955 :         if (list_length(l) > 10 || list_length(r) > 10)
    1372           5 :                 return 0;/* to expensive */
    1373             : 
    1374       46950 :         lu = ZNEW_ARRAY(char, list_length(l));
    1375       46950 :         ru = ZNEW_ARRAY(char, list_length(r));
    1376       46950 :         if (!lu || !ru) {
    1377           0 :                 _DELETE(lu);
    1378           0 :                 _DELETE(ru);
    1379           0 :                 return 0;
    1380             :         }
    1381      137761 :         for (n = l->h, lc = 0; n; n = n->next, lc++) {
    1382       90811 :                 sql_exp *le = n->data;
    1383             : 
    1384      270310 :                 for ( m = r->h, rc = 0; m; m = m->next, rc++) {
    1385      179499 :                         sql_exp *re = m->data;
    1386             : 
    1387      179499 :                         if (!ru[rc] && exp_match_exp(le,re)) {
    1388        6715 :                                 lu[lc] = 1;
    1389        6715 :                                 ru[rc] = 1;
    1390        6715 :                                 match = 1;
    1391             :                         }
    1392             :                 }
    1393             :         }
    1394       54112 :         for (n = l->h, lc = 0; n && match; n = n->next, lc++)
    1395        7162 :                 if (!lu[lc])
    1396        1274 :                         match = 0;
    1397       52360 :         for (n = r->h, rc = 0; n && match; n = n->next, rc++)
    1398        5410 :                 if (!ru[rc])
    1399           0 :                         match = 0;
    1400       46950 :         _DELETE(lu);
    1401       46950 :         _DELETE(ru);
    1402       46950 :         return match;
    1403             : }
    1404             : 
    1405             : static int
    1406     2368622 : exps_equal( list *l, list *r)
    1407             : {
    1408     2368622 :         node *n, *m;
    1409             : 
    1410     2368622 :         if (!l || !r)
    1411       50123 :                 return l == r;
    1412     2318499 :         if (list_length(l) != list_length(r))
    1413             :                 return 0;
    1414     3408182 :         for (n = l->h, m = r->h; n && m; n = n->next, m = m->next) {
    1415     3362020 :                 sql_exp *le = n->data, *re = m->data;
    1416             : 
    1417     3362020 :                 if (!exp_match_exp(le,re))
    1418             :                         return 0;
    1419             :         }
    1420             :         return 1;
    1421             : }
    1422             : 
    1423             : int
    1424    45373976 : exp_match_exp_semantics( sql_exp *e1, sql_exp *e2, bool semantics)
    1425             : {
    1426    45373976 :         if (exp_match(e1, e2))
    1427             :                 return 1;
    1428             : 
    1429    44180327 :         if (is_ascending(e1) != is_ascending(e2) ||
    1430    44180323 :                 nulls_last(e1) != nulls_last(e2) ||
    1431    44180323 :                 zero_if_empty(e1) != zero_if_empty(e2) ||
    1432    44180323 :                 need_no_nil(e1) != need_no_nil(e2) ||
    1433    44003810 :                 is_anti(e1) != is_anti(e2) ||
    1434    43999982 :                 (semantics && is_semantics(e1) != is_semantics(e2)) ||
    1435    33018684 :                 (semantics && is_any(e1) != is_any(e2)) ||
    1436    33018763 :                 is_symmetric(e1) != is_symmetric(e2) ||
    1437    33018746 :                 is_unique(e1) != is_unique(e2) ||
    1438             :                 need_distinct(e1) != need_distinct(e2))
    1439             :                 return 0;
    1440             : 
    1441    32436794 :         if (e1->type == e2->type) {
    1442    24260061 :                 switch(e1->type) {
    1443      346435 :                 case e_cmp:
    1444      579683 :                         if (e1->flag == e2->flag && !is_complex_exp(e1->flag) &&
    1445      237511 :                             exp_match_exp(e1->l, e2->l) && exp_match_exp(e1->r, e2->r) &&
    1446        1010 :                             ((!e1->f && !e2->f) || (e1->f && e2->f && exp_match_exp(e1->f, e2->f))))
    1447        1003 :                                 return 1;
    1448      348904 :                         else if (e1->flag == e2->flag && e1->flag == cmp_or &&
    1449        3483 :                             exp_match_list(e1->l, e2->l) && exp_match_list(e1->r, e2->r))
    1450             :                                 return 1;
    1451      345427 :                         else if (e1->flag == e2->flag &&
    1452      242677 :                                 (e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1453        3454 :                             exp_match_exp(e1->l, e2->l) && exp_match_list(e1->r, e2->r))
    1454             :                                 return 1;
    1455      574516 :                         else if (e1->flag == e2->flag && (e1->flag == cmp_equal || e1->flag == cmp_notequal) &&
    1456      229130 :                                 exp_match_exp(e1->l, e2->r) && exp_match_exp(e1->r, e2->l))
    1457             :                                 return 1; /* = and <> operations are reflective, so exp_match_exp can be called crossed */
    1458             :                         break;
    1459      290672 :                 case e_convert:
    1460      351637 :                         if (!subtype_cmp(exp_totype(e1), exp_totype(e2)) &&
    1461       91284 :                             !subtype_cmp(exp_fromtype(e1), exp_fromtype(e2)) &&
    1462       30319 :                             exp_match_exp(e1->l, e2->l))
    1463             :                                 return 1;
    1464             :                         break;
    1465       57165 :                 case e_aggr:
    1466       93389 :                         if (!subfunc_cmp(e1->f, e2->f) && /* equal aggregation*/
    1467       36224 :                             exps_equal(e1->l, e2->l))
    1468             :                                 return 1;
    1469             :                         break;
    1470     4338085 :                 case e_func: {
    1471     4338085 :                         sql_subfunc *e1f = (sql_subfunc*) e1->f;
    1472     4338085 :                         const char *sname = e1f->func->s ? e1f->func->s->base.name : NULL;
    1473     4338085 :                         int (*comp)(list*, list*) = is_commutative(sname, e1f->func->base.name) ? exp_match_list : exps_equal;
    1474             : 
    1475     8676170 :                         if (!e1f->func->side_effect &&
    1476     6665511 :                                 !subfunc_cmp(e1f, e2->f) && /* equal functions */
    1477     2375994 :                                 comp(e1->l, e2->l) &&
    1478             :                                 /* optional order by expressions */
    1479       48568 :                                 exps_equal(e1->r, e2->r))
    1480             :                                         return 1;
    1481             :                         } break;
    1482     1051175 :                 case e_atom:
    1483     1051175 :                         if (e1->l && e2->l && !atom_cmp(e1->l, e2->l))
    1484             :                                 return 1;
    1485     1010059 :                         if (e1->f && e2->f && exps_equal(e1->f, e2->f))
    1486             :                                 return 1;
    1487     1010058 :                         if (e1->r && e2->r && e1->flag == e2->flag && !subtype_cmp(&e1->tpe, &e2->tpe)) {
    1488          54 :                                 sql_var_name *v1 = (sql_var_name*) e1->r, *v2 = (sql_var_name*) e2->r;
    1489          54 :                                 if (((!v1->sname && !v2->sname) || (v1->sname && v2->sname && strcmp(v1->sname, v2->sname) == 0)) &&
    1490          54 :                                         ((!v1->name && !v2->name) || (v1->name && v2->name && strcmp(v1->name, v2->name) == 0)))
    1491             :                                         return 1;
    1492             :                         }
    1493     1010058 :                         if (!e1->l && !e1->r && !e1->f && !e2->l && !e2->r && !e2->f && e1->flag == e2->flag && !subtype_cmp(&e1->tpe, &e2->tpe))
    1494             :                                 return 1;
    1495             :                         break;
    1496             :                 default:
    1497             :                         break;
    1498             :                 }
    1499             :         }
    1500             :         return 0;
    1501             : }
    1502             : 
    1503             : int
    1504    45081902 : exp_match_exp( sql_exp *e1, sql_exp *e2)
    1505             : {
    1506    45081902 :         return exp_match_exp_semantics( e1, e2, true);
    1507             : }
    1508             : 
    1509             : sql_exp *
    1510      144782 : exps_any_match(list *l, sql_exp *e)
    1511             : {
    1512      144782 :         if (!l)
    1513             :                 return NULL;
    1514      562707 :         for (node *n = l->h; n ; n = n->next) {
    1515      510102 :                 sql_exp *ne = (sql_exp *) n->data;
    1516      510102 :                 if (exp_match_exp(ne, e))
    1517       92177 :                         return ne;
    1518             :         }
    1519             :         return NULL;
    1520             : }
    1521             : 
    1522             : static int
    1523          24 : exps_are_joins( list *l )
    1524             : {
    1525          24 :         if (l)
    1526          52 :                 for (node *n = l->h; n; n = n->next) {
    1527          28 :                         sql_exp *e = n->data;
    1528             : 
    1529          28 :                         if (exp_is_join_exp(e))
    1530             :                                 return -1;
    1531             :                 }
    1532             :         return 0;
    1533             : }
    1534             : 
    1535             : int
    1536         266 : exp_is_join_exp(sql_exp *e)
    1537             : {
    1538         266 :         if (exp_is_join(e, NULL) == 0)
    1539             :                 return 0;
    1540          24 :         if (e->type == e_cmp && e->flag == cmp_or && e->card >= CARD_AGGR)
    1541          12 :                 if (exps_are_joins(e->l) == 0 && exps_are_joins(e->r) == 0)
    1542             :                         return 0;
    1543             :         return -1;
    1544             : }
    1545             : 
    1546             : static int
    1547      770617 : exp_is_complex_select( sql_exp *e )
    1548             : {
    1549      791572 :         switch (e->type) {
    1550         457 :         case e_atom: {
    1551         457 :                 if (e->f) {
    1552           0 :                         int r = (e->card == CARD_ATOM);
    1553           0 :                         list *l = e->f;
    1554             : 
    1555           0 :                         if (r)
    1556           0 :                                 for (node *n = l->h; n && !r; n = n->next)
    1557           0 :                                         r |= exp_is_complex_select(n->data);
    1558           0 :                         return r;
    1559             :                 }
    1560             :                 return 0;
    1561             :         }
    1562       20955 :         case e_convert:
    1563       20955 :                 return exp_is_complex_select(e->l);
    1564        2043 :         case e_func:
    1565             :         case e_aggr:
    1566             :         {
    1567        2043 :                 int r = (e->card == CARD_ATOM);
    1568        2043 :                 list *l = e->l;
    1569             : 
    1570        2043 :                 if (r && l)
    1571          39 :                         for (node *n = l->h; n && !r; n = n->next)
    1572           0 :                                 r |= exp_is_complex_select(n->data);
    1573             :                 return r;
    1574             :         }
    1575             :         case e_psm:
    1576             :                 return 1;
    1577             :         case e_column:
    1578             :         case e_cmp:
    1579             :         default:
    1580             :                 return 0;
    1581             :         }
    1582             : }
    1583             : 
    1584             : static int
    1585      385314 : complex_select(sql_exp *e)
    1586             : {
    1587      385314 :         sql_exp *l = e->l, *r = e->r;
    1588             : 
    1589      385314 :         if (exp_is_complex_select(l) || exp_is_complex_select(r))
    1590          39 :                 return 1;
    1591             :         return 0;
    1592             : }
    1593             : 
    1594             : static int
    1595         929 : distinct_rel(sql_exp *e, const char **rname)
    1596             : {
    1597        1083 :         const char *e_rname = NULL;
    1598             : 
    1599        1083 :         switch(e->type) {
    1600         651 :         case e_column:
    1601         651 :                 e_rname = exp_relname(e);
    1602             : 
    1603         651 :                 if (*rname && e_rname && strcmp(*rname, e_rname) == 0)
    1604             :                         return 1;
    1605         504 :                 if (!*rname) {
    1606         321 :                         *rname = e_rname;
    1607         321 :                         return 1;
    1608             :                 }
    1609             :                 break;
    1610         145 :         case e_aggr:
    1611             :         case e_func:
    1612         145 :                 if (e->l) {
    1613         145 :                         int m = 1;
    1614         145 :                         list *l = e->l;
    1615         145 :                         node *n;
    1616             : 
    1617         438 :                         for(n=l->h; n && m; n = n->next) {
    1618         293 :                                 sql_exp *ae = n->data;
    1619             : 
    1620         293 :                                 m = distinct_rel(ae, rname);
    1621             :                         }
    1622         145 :                         return m;
    1623             :                 }
    1624             :                 return 0;
    1625             :         case e_atom:
    1626             :                 return 1;
    1627         154 :         case e_convert:
    1628         154 :                 return distinct_rel(e->l, rname);
    1629             :         default:
    1630             :                 return 0;
    1631             :         }
    1632             :         return 0;
    1633             : }
    1634             : 
    1635             : int
    1636    20262159 : rel_has_exp(sql_rel *rel, sql_exp *e, bool subexp)
    1637             : {
    1638    20262159 :         if (rel_find_exp_and_corresponding_rel(rel, e, subexp, NULL, NULL))
    1639     4437296 :                 return 0;
    1640             :         return -1;
    1641             : }
    1642             : 
    1643             : int
    1644           0 : rel_has_exps(sql_rel *rel, list *exps, bool subexp)
    1645             : {
    1646           0 :         if (list_empty(exps))
    1647             :                 return 0;
    1648           0 :         for (node *n = exps->h; n; n = n->next)
    1649           0 :                 if (rel_has_exp(rel, n->data, subexp) >= 0)
    1650             :                         return 0;
    1651             :         return -1;
    1652             : }
    1653             : 
    1654             : int
    1655           0 : rel_has_all_exps(sql_rel *rel, list *exps)
    1656             : {
    1657           0 :         if (list_empty(exps))
    1658             :                 return 1;
    1659           0 :         for (node *n = exps->h; n; n = n->next)
    1660           0 :                 if (rel_has_exp(rel, n->data, false) < 0)
    1661             :                         return 0;
    1662             :         return 1;
    1663             : }
    1664             : 
    1665             : static int
    1666    15317121 : rel_has_exp2(sql_rel *rel, sql_exp *e)
    1667             : {
    1668    15317121 :         return rel_has_exp(rel, e, false);
    1669             : }
    1670             : 
    1671             : sql_rel *
    1672     5808808 : find_rel(list *rels, sql_exp *e)
    1673             : {
    1674     5808808 :         node *n = list_find(rels, e, (fcmp)&rel_has_exp2);
    1675     5808808 :         if (n)
    1676     3306331 :                 return n->data;
    1677             :         return NULL;
    1678             : }
    1679             : 
    1680             : sql_rel *
    1681           0 : find_one_rel(list *rels, sql_exp *e)
    1682             : {
    1683           0 :         node *n;
    1684           0 :         sql_rel *fnd = NULL;
    1685             : 
    1686           0 :         for(n = rels->h; n; n = n->next) {
    1687           0 :                 if (rel_has_exp(n->data, e, false) == 0) {
    1688           0 :                         if (fnd)
    1689             :                                 return NULL;
    1690           0 :                         fnd = n->data;
    1691             :                 }
    1692             :         }
    1693             :         return fnd;
    1694             : }
    1695             : 
    1696             : static int
    1697         326 : exp_is_rangejoin(sql_exp *e, list *rels)
    1698             : {
    1699             :         /* assume e is a e_cmp with 3 args
    1700             :          * Need to check e->r and e->f only touch one table.
    1701             :          */
    1702         326 :         const char *rname = 0;
    1703             : 
    1704         326 :         if (distinct_rel(e->r, &rname) && distinct_rel(e->f, &rname))
    1705             :                 return 0;
    1706         183 :         if (rels) {
    1707         138 :                 sql_rel *r = find_rel(rels, e->r);
    1708         138 :                 sql_rel *f = find_rel(rels, e->f);
    1709         138 :                 if (r && f && r == f)
    1710             :                         return 0;
    1711             :         }
    1712             :         return -1;
    1713             : }
    1714             : 
    1715             : int
    1716      386954 : exp_is_join(sql_exp *e, list *rels)
    1717             : {
    1718             :         /* only simple compare expressions, ie not or lists
    1719             :                 or range expressions (e->f)
    1720             :          */
    1721      386954 :         if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r && !e->f && e->card >= CARD_AGGR && !complex_select(e))
    1722             :                 return 0;
    1723        2005 :         if (e->type == e_cmp && e->flag == cmp_filter && e->l && e->r && e->card >= CARD_AGGR)
    1724             :                 return 0;
    1725             :         /* range expression */
    1726        1827 :         if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r && e->f && e->card >= CARD_AGGR && !complex_select(e))
    1727         326 :                 return exp_is_rangejoin(e, rels);
    1728             :         return -1;
    1729             : }
    1730             : 
    1731             : int
    1732      380739 : exp_is_eqjoin(sql_exp *e)
    1733             : {
    1734      380739 :         if (e->flag == cmp_equal) {
    1735      370917 :                 sql_exp *l = e->l;
    1736      370917 :                 sql_exp *r = e->r;
    1737             : 
    1738      370917 :                 if (!is_func(l->type) && !is_func(r->type))
    1739      369802 :                         return 0;
    1740             :         }
    1741             :         return -1;
    1742             : }
    1743             : 
    1744             : sql_exp *
    1745      231984 : exps_find_prop(list *exps, rel_prop kind)
    1746             : {
    1747      231984 :         if (list_empty(exps))
    1748             :                 return NULL;
    1749      462701 :         for (node *n = exps->h ; n ; n = n->next) {
    1750      231984 :                 sql_exp *e = n->data;
    1751             : 
    1752      231984 :                 if (find_prop(e->p, kind))
    1753        1267 :                         return e;
    1754             :         }
    1755             :         return NULL;
    1756             : }
    1757             : 
    1758             : /* check is one of the exps can be found in this relation */
    1759             : static sql_exp* rel_find_exp_and_corresponding_rel_(sql_rel *rel, sql_exp *e, bool subexp, sql_rel **res);
    1760             : 
    1761             : static bool
    1762      596328 : rel_find_exps_and_corresponding_rel_(sql_rel *rel, list *l, bool subexp, sql_rel **res)
    1763             : {
    1764      596328 :         int all = 1;
    1765             : 
    1766      596328 :         if (list_empty(l))
    1767             :                 return true;
    1768     1607330 :         for(node *n = l->h; n && (subexp || all); n = n->next) {
    1769     1020093 :                 sql_exp *ne = rel_find_exp_and_corresponding_rel_(rel, n->data, subexp, res);
    1770     1020093 :                 if (subexp && ne)
    1771             :                         return true;
    1772     1011002 :                 all &= (ne?1:0);
    1773             :         }
    1774      587237 :         if (all)
    1775             :                 return true;
    1776             :         return false;
    1777             : }
    1778             : 
    1779             : static sql_exp *
    1780    78643623 : rel_find_exp_and_corresponding_rel_(sql_rel *rel, sql_exp *e, bool subexp, sql_rel **res)
    1781             : {
    1782    78643623 :         sql_exp *ne = NULL;
    1783             : 
    1784    78643623 :         if (!rel)
    1785             :                 return NULL;
    1786    78643511 :         switch(e->type) {
    1787    76343798 :         case e_column:
    1788    76343798 :                 if (is_basetable(rel->op) && !rel->exps) {
    1789       16467 :                         assert(e->nid);
    1790       16467 :                         if (rel_base_has_nid(rel, e->nid))
    1791    76343777 :                                 ne = e;
    1792    96039916 :                 } else if ((!list_empty(rel->exps) && (is_project(rel->op) || is_base(rel->op))) ||
    1793    20096740 :                                         (!list_empty(rel->attr) && is_join(rel->op))) {
    1794    56998880 :                         list *l = rel->attr ? rel->attr : rel->exps;
    1795    56998880 :                         assert(e->nid);
    1796    56998880 :                         ne = exps_bind_nid(l, e->nid);
    1797             :                 }
    1798    76343777 :                 if (ne && res)
    1799       69122 :                         *res = rel;
    1800             :                 return ne;
    1801     1089312 :         case e_convert:
    1802     1089312 :                 return rel_find_exp_and_corresponding_rel_(rel, e->l, subexp, res);
    1803      600461 :         case e_aggr:
    1804             :         case e_func:
    1805      600461 :                 if (e->l)
    1806      596313 :                         if (rel_find_exps_and_corresponding_rel_(rel, e->l, subexp, res))
    1807             :                                 return e;
    1808             :                 return NULL;
    1809         447 :         case e_cmp:
    1810         447 :                 if (!subexp)
    1811             :                         return NULL;
    1812             : 
    1813          30 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    1814          13 :                         if (rel_find_exps_and_corresponding_rel_(rel, e->l, subexp, res) ||
    1815           3 :                                 rel_find_exps_and_corresponding_rel_(rel, e->r, subexp, res))
    1816          10 :                                 return e;
    1817          20 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    1818           4 :                         if (rel_find_exp_and_corresponding_rel_(rel, e->l, subexp, res) ||
    1819           2 :                                 rel_find_exps_and_corresponding_rel_(rel, e->r, subexp, res))
    1820           2 :                                 return e;
    1821          23 :                 } else if (rel_find_exp_and_corresponding_rel_(rel, e->l, subexp, res) ||
    1822           5 :                             rel_find_exp_and_corresponding_rel_(rel, e->r, subexp, res) ||
    1823           2 :                             (!e->f || rel_find_exp_and_corresponding_rel_(rel, e->f, subexp, res))) {
    1824          16 :                                 return e;
    1825             :                 }
    1826             :                 return NULL;
    1827             :         case e_psm:
    1828             :                 return NULL;
    1829      608883 :         case e_atom:
    1830      608883 :                 if (e->f) { /* values */
    1831          12 :                         list *l = e->f;
    1832          12 :                         node *n = l->h;
    1833             : 
    1834          12 :                         ne = n->data;
    1835          31 :                         while ((subexp || ne != NULL) && n != NULL) {
    1836          19 :                                 ne = rel_find_exp_and_corresponding_rel_(rel, n->data, subexp, res);
    1837          19 :                                 if (subexp && ne)
    1838             :                                         break;
    1839          19 :                                 n = n->next;
    1840             :                         }
    1841          12 :                         return ne;
    1842             :                 }
    1843             :                 return e;
    1844             :         }
    1845             :         return ne;
    1846             : }
    1847             : 
    1848             : sql_exp *
    1849    76534152 : rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, bool subexp, sql_rel **res, bool *under_join)
    1850             : {
    1851    76534152 :         sql_exp *ne = rel_find_exp_and_corresponding_rel_(rel, e, subexp, res);
    1852             : 
    1853    76534142 :         if (rel && !ne) {
    1854    55051564 :                 switch(rel->op) {
    1855    13274554 :                 case op_left:
    1856             :                 case op_right:
    1857             :                 case op_full:
    1858             :                 case op_join:
    1859             :                 case op_semi:
    1860             :                 case op_anti:
    1861    13274554 :                         ne = rel_find_exp_and_corresponding_rel(rel->l, e, subexp, res, under_join);
    1862    13274554 :                         if (!ne && is_join(rel->op))
    1863     8504397 :                                 ne = rel_find_exp_and_corresponding_rel(rel->r, e, subexp, res, under_join);
    1864             :                         break;
    1865             :                 case op_table:
    1866             :                 case op_basetable:
    1867             :                         break;
    1868      276369 :                 case op_munion:
    1869     1531731 :                         for (node* n = ((list*)rel->l)->h; n && !ne; n = n->next)
    1870     1255362 :                                 ne = rel_find_exp_and_corresponding_rel(n->data, e, subexp, res, under_join);
    1871             :                         break;
    1872    14681257 :                 default:
    1873    14681257 :                         if (!is_project(rel->op) && rel->l)
    1874     6426597 :                                 ne = rel_find_exp_and_corresponding_rel(rel->l, e, subexp, res, under_join);
    1875             :                 }
    1876             :         }
    1877    76534142 :         if (ne && under_join && is_join(rel->op))
    1878     2963043 :                 *under_join = true;
    1879    76534142 :         return ne;
    1880             : }
    1881             : 
    1882             : sql_exp *
    1883    21597263 : rel_find_exp(sql_rel *rel, sql_exp *e)
    1884             : {
    1885    21597263 :         return rel_find_exp_and_corresponding_rel(rel, e, false, NULL, NULL);
    1886             : }
    1887             : 
    1888             : bool
    1889       64037 : rel_find_nid(sql_rel *rel, int nid)
    1890             : {
    1891       64452 :         if (rel) {
    1892       63976 :                 switch(rel->op) {
    1893        5525 :                 case op_left:
    1894             :                 case op_right:
    1895             :                 case op_full:
    1896             :                 case op_join:
    1897             :                 case op_semi:
    1898             :                 case op_anti:
    1899        5525 :                         if (rel_find_nid(rel->l, nid))
    1900             :                                 return true;
    1901         499 :                         if (is_join(rel->op))
    1902         415 :                                 return rel_find_nid(rel->r, nid);
    1903             :                         break;
    1904       55125 :                 case op_table:
    1905             :                 case op_basetable:
    1906             :                 case op_munion:
    1907             :                 case op_union:
    1908             :                 case op_inter:
    1909             :                 case op_except:
    1910             :                 case op_project:
    1911             :                 case op_groupby:
    1912       55125 :                         if (rel->exps) {
    1913       55125 :                                 if (exps_bind_nid(rel->exps, nid))
    1914             :                                         return true;
    1915           0 :                         } else if (rel->op == op_basetable)
    1916           0 :                                 return rel_base_has_nid(rel, nid);
    1917             :                         break;
    1918        3326 :                 case op_select:
    1919             :                 case op_topn:
    1920             :                 case op_sample:
    1921        3326 :                         if (rel_find_nid(rel->l, nid))
    1922             :                                 return true;
    1923             :                         break;
    1924             :                 case op_ddl:
    1925             :                 case op_insert:
    1926             :                 case op_update:
    1927             :                 case op_delete:
    1928             :                 case op_truncate:
    1929             :                 case op_merge:
    1930             :                         return false;
    1931             : 
    1932             :                 }
    1933             :         }
    1934             :         return false;
    1935             : }
    1936             : 
    1937             : int
    1938     3905495 : exp_is_true(sql_exp *e)
    1939             : {
    1940     3905495 :         if (e->type == e_atom && e->l)
    1941       46831 :                 return atom_is_true(e->l);
    1942     3858664 :         if (e->type == e_cmp && e->flag == cmp_equal)
    1943     3117933 :                 return (exp_is_true(e->l) && exp_is_true(e->r) && exp_match_exp(e->l, e->r));
    1944             :         return 0;
    1945             : }
    1946             : 
    1947             : static inline bool
    1948      237419 : exp_is_cmp_exp_is_false(sql_exp* e)
    1949             : {
    1950      237419 :         sql_exp *l = e->l;
    1951      237419 :         sql_exp *r = e->r;
    1952      237419 :         assert(e->type == e_cmp && e->f == NULL && l && r);
    1953             : 
    1954             :         /* Handle 'v is x' and 'v is not x' expressions.
    1955             :         * Other cases in is-semantics are unspecified.
    1956             :         */
    1957      237419 :         if (e->flag != cmp_equal && e->flag != cmp_notequal)
    1958             :                 return false;
    1959      237419 :         if (e->flag == cmp_equal && !is_anti(e))
    1960      371546 :                 return ((exp_is_null(l) && exp_is_not_null(r)) || (exp_is_not_null(l) && exp_is_null(r)));
    1961       51646 :         if ((e->flag == cmp_notequal && !is_anti(e)) || (e->flag == cmp_equal && is_anti(e)))
    1962      103240 :                 return exp_is_null(l) && exp_is_null(r);
    1963             :         return false;
    1964             : }
    1965             : 
    1966             : static inline bool
    1967     5496729 : exp_single_bound_cmp_exp_is_false(sql_exp* e)
    1968             : {
    1969     5496729 :     assert(e->type == e_cmp);
    1970     5496729 :     sql_exp* l = e->l;
    1971     5496729 :     sql_exp* r = e->r;
    1972     5496729 :     assert(e->f == NULL);
    1973     5496729 :     assert (l && r);
    1974             : 
    1975     5496729 :     return exp_is_null(l) || exp_is_null(r);
    1976             : }
    1977             : 
    1978             : static inline bool
    1979       74728 : exp_two_sided_bound_cmp_exp_is_false(sql_exp* e)
    1980             : {
    1981       74728 :     assert(e->type == e_cmp);
    1982       74728 :     sql_exp* v = e->l;
    1983       74728 :     sql_exp* l = e->r;
    1984       74728 :     sql_exp* h = e->f;
    1985       74728 :     assert (v && l && h);
    1986             : 
    1987       74728 :     return is_anti(e) ? exp_is_null(v) || (exp_is_null(l) && exp_is_null(h)) : false;
    1988             : }
    1989             : 
    1990             : static inline bool
    1991     5822144 : exp_regular_cmp_exp_is_false(sql_exp* e)
    1992             : {
    1993     5822144 :     assert(e->type == e_cmp);
    1994             : 
    1995     5822144 :     if (is_semantics(e) && !is_any(e)) return exp_is_cmp_exp_is_false(e);
    1996     5584725 :         if (is_any(e)) return false;
    1997     5571457 :     if (e -> f)         return exp_two_sided_bound_cmp_exp_is_false(e);
    1998     5496729 :     else                return exp_single_bound_cmp_exp_is_false(e);
    1999             : }
    2000             : 
    2001             : static inline bool
    2002      597550 : exp_or_exp_is_false(sql_exp* e)
    2003             : {
    2004      597550 :     assert(e->type == e_cmp && e->flag == cmp_or);
    2005             : 
    2006      597550 :         list* left = e->l;
    2007      597550 :         list* right = e->r;
    2008             : 
    2009      597550 :         bool left_is_false = false;
    2010     1246600 :         for(node* n = left->h; n; n=n->next) {
    2011      649666 :                 if (exp_is_false(n->data)) {
    2012             :                         left_is_false=true;
    2013             :                         break;
    2014             :                 }
    2015             :         }
    2016             : 
    2017      597550 :         if (!left_is_false) {
    2018             :                 return false;
    2019             :         }
    2020             : 
    2021        1180 :         for(node* n = right->h; n; n=n->next) {
    2022         645 :                 if (exp_is_false(n->data)) {
    2023             :                         return true;
    2024             :                 }
    2025             :         }
    2026             : 
    2027             :     return false;
    2028             : }
    2029             : 
    2030             : static inline bool
    2031     6745505 : exp_cmp_exp_is_false(sql_exp* e)
    2032             : {
    2033     6745505 :     assert(e->type == e_cmp);
    2034             : 
    2035     6745505 :     switch (e->flag) {
    2036     5822144 :     case cmp_gt:
    2037             :     case cmp_gte:
    2038             :     case cmp_lte:
    2039             :     case cmp_lt:
    2040             :     case cmp_equal:
    2041             :     case cmp_notequal:
    2042     5822144 :                 return exp_regular_cmp_exp_is_false(e);
    2043      597550 :     case cmp_or:
    2044      597550 :                 return exp_or_exp_is_false(e);
    2045             :     default:
    2046             :                 return false;
    2047             :         }
    2048             : }
    2049             : 
    2050             : int
    2051     6838708 : exp_is_false(sql_exp *e)
    2052             : {
    2053     6838708 :         if (e->type == e_atom && e->l)
    2054       46332 :                 return atom_is_false(e->l);
    2055     6792376 :         else if (e->type == e_cmp)
    2056     6745505 :                 return exp_cmp_exp_is_false(e);
    2057             :         return 0;
    2058             : }
    2059             : 
    2060             : int
    2061       17805 : exp_is_zero(sql_exp *e)
    2062             : {
    2063       17805 :         if (e->type == e_atom && e->l)
    2064       17528 :                 return atom_is_zero(e->l);
    2065             :         return 0;
    2066             : }
    2067             : 
    2068             : int
    2069      332366 : exp_is_not_null(sql_exp *e)
    2070             : {
    2071      332552 :         if (!has_nil(e))
    2072             :                 return true;
    2073             : 
    2074      103265 :         switch (e->type) {
    2075        3063 :         case e_atom:
    2076        3063 :                 if (e->f) /* values list */
    2077             :                         return false;
    2078        3063 :                 if (e->l)
    2079        2773 :                         return !(atom_null(e->l));
    2080             :                 return false;
    2081         186 :         case e_convert:
    2082         186 :                 return exp_is_not_null(e->l);
    2083         646 :         case e_func:
    2084         646 :                 if (!is_semantics(e) && e->l) {
    2085         258 :                         list *l = e->l;
    2086         303 :                         for (node *n = l->h; n; n=n->next) {
    2087         301 :                                 sql_exp *p = n->data;
    2088         301 :                                 if (!exp_is_not_null(p))
    2089             :                                         return false;
    2090             :                         }
    2091             :                         return true;
    2092             :                 }
    2093             :                 return false;
    2094             :         case e_aggr:
    2095             :         case e_column:
    2096             :         case e_cmp:
    2097             :         case e_psm:
    2098             :                 return false;
    2099             :         }
    2100             :         return false;
    2101             : }
    2102             : 
    2103             : static int
    2104        8263 : exps_have_null(list *l)
    2105             : {
    2106        8263 :         if (!l)
    2107             :                 return false;
    2108       17502 :         for(node *n = l->h; n; n = n->next)
    2109        9243 :                 if (exp_is_null(n->data))
    2110             :                         return true;
    2111             :         return false;
    2112             : }
    2113             : 
    2114             : int
    2115    12288899 : exp_is_null(sql_exp *e )
    2116             : {
    2117    12331874 :         if (!has_nil(e))
    2118             :                 return false;
    2119             : 
    2120     1623119 :         switch (e->type) {
    2121      167518 :         case e_atom:
    2122      167518 :                 if (e->f) /* values list */
    2123             :                         return 0;
    2124      167517 :                 if (e->l)
    2125       93333 :                         return (atom_null(e->l));
    2126             :                 return 0;
    2127       42975 :         case e_convert:
    2128       42975 :                 return exp_is_null(e->l);
    2129      115086 :         case e_func:
    2130      115086 :                 if (!is_semantics(e) && e->l) {
    2131             :                         /* This is a call to a function with no-nil semantics.
    2132             :                          * If one of the parameters is null the expression itself is null
    2133             :                          */
    2134      100382 :                         list* l = e->l;
    2135      300295 :                         for(node* n = l->h; n; n=n->next) {
    2136      200080 :                                 sql_exp* p = n->data;
    2137      200080 :                                 if (exp_is_null(p)) {
    2138             :                                         return true;
    2139             :                                 }
    2140             :                         }
    2141             :                 }
    2142             :                 return 0;
    2143       60029 :         case e_cmp:
    2144       60029 :                 if (!is_semantics(e)) {
    2145       56790 :                         if (e->flag == cmp_or || e->flag == cmp_filter) {
    2146       14842 :                                 return (exps_have_null(e->l) && exps_have_null(e->r));
    2147       49369 :                         } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2148        3522 :                                 return ((e->flag == cmp_in && exp_is_null(e->l)) ||
    2149        3520 :                                                 (e->flag == cmp_notin && (exp_is_null(e->l) || exps_have_null(e->r))));
    2150       45847 :                         } else if (e->f) {
    2151        7174 :                                 return exp_is_null(e->l) && exp_is_null(e->r) && exp_is_null(e->f);
    2152             :                         } else {
    2153       42262 :                                 return exp_is_null(e->l) || exp_is_null(e->r);
    2154             :                         }
    2155             :                 }
    2156             :                 return 0;
    2157             :         case e_aggr:
    2158             :         case e_column:
    2159             :         case e_psm:
    2160             :                 return 0;
    2161             :         }
    2162             :         return 0;
    2163             : }
    2164             : 
    2165             : int
    2166     1790015 : exp_is_rel( sql_exp *e )
    2167             : {
    2168     1799156 :         if (e) {
    2169     1799156 :                 switch(e->type){
    2170        9141 :                 case e_convert:
    2171        9141 :                         return exp_is_rel(e->l);
    2172      302914 :                 case e_psm:
    2173      302914 :                         return e->flag == PSM_REL && e->l;
    2174             :                 default:
    2175             :                         return 0;
    2176             :                 }
    2177             :         }
    2178             :         return 0;
    2179             : }
    2180             : 
    2181             : int
    2182        6707 : exps_one_is_rel(list *exps)
    2183             : {
    2184        6707 :         if (list_empty(exps))
    2185             :                 return 0;
    2186       20018 :         for(node *n = exps->h ; n ; n = n->next)
    2187       13320 :                 if (exp_is_rel(n->data))
    2188             :                         return 1;
    2189             :         return 0;
    2190             : }
    2191             : 
    2192             : int
    2193     8986671 : exp_is_atom( sql_exp *e )
    2194             : {
    2195     9347989 :         switch (e->type) {
    2196     2050584 :         case e_atom:
    2197     2050584 :                 if (e->f) /* values list */
    2198       12823 :                         return exps_are_atoms(e->f);
    2199             :                 return 1;
    2200      361318 :         case e_convert:
    2201      361318 :                 return exp_is_atom(e->l);
    2202     1091219 :         case e_func:
    2203             :         case e_aggr:
    2204     1091219 :                 return e->card == CARD_ATOM && exps_are_atoms(e->l);
    2205        2709 :         case e_cmp:
    2206        2709 :                 if (e->card != CARD_ATOM)
    2207             :                         return 0;
    2208         157 :                 if (e->flag == cmp_or || e->flag == cmp_filter)
    2209          82 :                         return exps_are_atoms(e->l) && exps_are_atoms(e->r);
    2210          79 :                 if (e->flag == cmp_in || e->flag == cmp_notin)
    2211           0 :                         return exp_is_atom(e->l) && exps_are_atoms(e->r);
    2212          79 :                 return exp_is_atom(e->l) && exp_is_atom(e->r) && (!e->f || exp_is_atom(e->f));
    2213             :         case e_column:
    2214             :         case e_psm:
    2215             :                 return 0;
    2216             :         }
    2217             :         return 0;
    2218             : }
    2219             : 
    2220             : static int
    2221           1 : exps_are_aggr(sql_rel *r, list *exps)
    2222             : {
    2223           1 :         int aggr = 1;
    2224           1 :         if (!list_empty(exps))
    2225           3 :                 for(node *n=exps->h; n && aggr; n=n->next)
    2226           2 :                         aggr &= exp_is_aggr(r, n->data);
    2227           1 :         return aggr;
    2228             : }
    2229             : 
    2230             : /* is expression e an aggregated result of r */
    2231             : int
    2232          11 : exp_is_aggr(sql_rel *r, sql_exp *e)
    2233             : {
    2234          11 :         sql_exp *ne = NULL;
    2235             : 
    2236          11 :         switch (e->type) {
    2237             :         case e_atom:
    2238             :                 return true;
    2239           0 :         case e_convert:
    2240           0 :                 return exp_is_aggr(r, e->l);
    2241           1 :         case e_func:
    2242           1 :                 return exps_are_aggr(r, e->l);
    2243             :         case e_aggr:
    2244             :                 return true;
    2245           0 :         case e_cmp:
    2246           0 :                 if (e->card != CARD_ATOM)
    2247             :                         return false;
    2248           0 :                 if (e->flag == cmp_or || e->flag == cmp_filter)
    2249           0 :                         return exps_are_aggr(r, e->l) && exps_are_aggr(r, e->r);
    2250           0 :                 if (e->flag == cmp_in || e->flag == cmp_notin)
    2251           0 :                         return exp_is_aggr(r, e->l) && exps_are_aggr(r, e->r);
    2252           0 :                 return exp_is_aggr(r, e->l) && exp_is_aggr(r, e->r) && (!e->f || exp_is_aggr(r, e->f));
    2253           9 :         case e_column:
    2254           9 :                 if (e->freevar)
    2255             :                         return true;
    2256           9 :                 ne = rel_find_exp(r, e);
    2257           9 :                 if (ne) /* found local */
    2258             :                         return true;
    2259             :                 else
    2260             :                         return false;
    2261             :         case e_psm:
    2262             :                 return false;
    2263             :         }
    2264             :         return false;
    2265             : }
    2266             : 
    2267             : static int
    2268          19 : exps_have_aggr(sql_rel *r, list *exps)
    2269             : {
    2270          19 :         int aggr = 0;
    2271          19 :         if (!list_empty(exps))
    2272          63 :                 for(node *n=exps->h; n && !aggr; n=n->next)
    2273          44 :                         aggr |= exp_has_aggr(r, n->data);
    2274          19 :         return aggr;
    2275             : }
    2276             : 
    2277             : int
    2278          80 : exp_has_aggr(sql_rel *r, sql_exp *e )
    2279             : {
    2280          87 :         sql_exp *ne = NULL;
    2281             : 
    2282          87 :         switch (e->type) {
    2283             :         case e_atom:
    2284             :                 return false;
    2285           7 :         case e_convert:
    2286           7 :                 return exp_has_aggr(r, e->l);
    2287          19 :         case e_func:
    2288          19 :                 return exps_have_aggr(r, e->l);
    2289             :         case e_aggr:
    2290             :                 return true;
    2291           0 :         case e_cmp:
    2292           0 :                 if (e->card != CARD_ATOM)
    2293             :                         return false;
    2294           0 :                 if (e->flag == cmp_or || e->flag == cmp_filter)
    2295           0 :                         return exps_have_aggr(r, e->l) && exps_have_aggr(r, e->r);
    2296           0 :                 if (e->flag == cmp_in || e->flag == cmp_notin)
    2297           0 :                         return exp_has_aggr(r, e->l) && exps_have_aggr(r, e->r);
    2298           0 :                 return exp_has_aggr(r, e->l) && exp_has_aggr(r, e->r) && (!e->f || exp_has_aggr(r, e->f));
    2299          34 :         case e_column:
    2300          34 :                 if (e->freevar)
    2301             :                         return false;
    2302          21 :                 ne = rel_find_exp(r->l, e);
    2303          21 :                 if (ne) /* found lower */
    2304             :                         return false;
    2305             :                 else
    2306             :                         return true;
    2307             :         case e_psm:
    2308             :                 return false;
    2309             :         }
    2310             :         return false;
    2311             : }
    2312             : 
    2313             : int
    2314    20406527 : exp_has_rel( sql_exp *e )
    2315             : {
    2316    20775238 :         if (!e)
    2317             :                 return 0;
    2318    20775238 :         switch(e->type){
    2319     1959667 :         case e_func:
    2320             :         case e_aggr:
    2321     1959667 :                 return exps_have_rel_exp(e->l);
    2322      689922 :         case e_cmp:
    2323      689922 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2324       69491 :                         return (exps_have_rel_exp(e->l) || exps_have_rel_exp(e->r));
    2325      620885 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2326       39777 :                         return (exp_has_rel(e->l) || exps_have_rel_exp(e->r));
    2327             :                 } else {
    2328     1162216 :                         return (exp_has_rel(e->l) || exp_has_rel(e->r) || (e->f && exp_has_rel(e->f)));
    2329             :                 }
    2330      368711 :         case e_convert:
    2331      368711 :                 return exp_has_rel(e->l);
    2332      123489 :         case e_psm:
    2333      123489 :                 return exp_is_rel(e);
    2334     9563365 :         case e_atom:
    2335     9563365 :                 return (e->f && exps_have_rel_exp(e->f));
    2336             :         case e_column:
    2337             :                 return 0;
    2338             :         }
    2339             :         return 0;
    2340             : }
    2341             : 
    2342             : int
    2343     2639330 : exps_have_rel_exp( list *exps)
    2344             : {
    2345     2639330 :         if (list_empty(exps))
    2346             :                 return 0;
    2347     9473126 :         for(node *n=exps->h; n; n=n->next) {
    2348     6927193 :                 sql_exp *e = n->data;
    2349             : 
    2350     6927193 :                 if (exp_has_rel(e))
    2351             :                         return 1;
    2352             :         }
    2353             :         return 0;
    2354             : }
    2355             : 
    2356             : static sql_rel *
    2357         570 : exps_rel_get_rel(allocator *sa, list *exps )
    2358             : {
    2359         570 :         sql_rel *r = NULL, *xp = NULL;
    2360             : 
    2361         570 :         if (list_empty(exps))
    2362             :                 return NULL;
    2363        1674 :         for (node *n = exps->h; n; n=n->next){
    2364        1104 :                 sql_exp *e = n->data;
    2365             : 
    2366        1104 :                 if (exp_has_rel(e)) {
    2367         576 :                         if (!(r = exp_rel_get_rel(sa, e)))
    2368             :                                 return NULL;
    2369         576 :                         if (xp) {
    2370           6 :                                 xp = rel_crossproduct(sa, xp, r, op_full);
    2371           6 :                                 set_processed(xp);
    2372             :                         } else {
    2373             :                                 xp = r;
    2374             :                         }
    2375             :                 }
    2376             :         }
    2377             :         return xp;
    2378             : }
    2379             : 
    2380             : int
    2381          60 : exp_rel_depth(sql_exp *e)
    2382             : {
    2383          60 :         if (!e)
    2384             :                 return 0;
    2385          60 :         switch(e->type){
    2386             :         case e_func:
    2387             :         case e_aggr:
    2388             :         case e_cmp:
    2389             :                 return 1;
    2390             :         case e_convert:
    2391             :                 return 0;
    2392          39 :         case e_psm:
    2393          39 :                 if (exp_is_rel(e))
    2394             :                         return 0;
    2395             :                 return 1;
    2396             :         case e_atom:
    2397             :         case e_column:
    2398             :                 return 0;
    2399             :         }
    2400             :         return 0;
    2401             : }
    2402             : 
    2403             : sql_rel *
    2404       76821 : exp_rel_get_rel(allocator *sa, sql_exp *e)
    2405             : {
    2406       77776 :         if (!e)
    2407             :                 return NULL;
    2408             : 
    2409       77776 :         switch(e->type){
    2410         542 :         case e_func:
    2411             :         case e_aggr:
    2412         542 :                 return exps_rel_get_rel(sa, e->l);
    2413          38 :         case e_cmp: {
    2414          38 :                 sql_rel *r = NULL, *xp = NULL;
    2415             : 
    2416          38 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2417          11 :                         if (exps_have_rel_exp(e->l))
    2418           7 :                                 xp = exps_rel_get_rel(sa, e->l);
    2419          11 :                         if (exps_have_rel_exp(e->r)) {
    2420           6 :                                 if (!(r = exps_rel_get_rel(sa, e->r)))
    2421             :                                         return NULL;
    2422           6 :                                 if (xp) {
    2423           2 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2424           2 :                                         set_processed(xp);
    2425             :                                 } else {
    2426             :                                         xp = r;
    2427             :                                 }
    2428             :                         }
    2429          27 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2430           0 :                         if (exp_has_rel(e->l))
    2431           0 :                                 xp = exp_rel_get_rel(sa, e->l);
    2432           0 :                         if (exps_have_rel_exp(e->r)) {
    2433           0 :                                 if (!(r = exps_rel_get_rel(sa, e->r)))
    2434             :                                         return NULL;
    2435           0 :                                 if (xp) {
    2436           0 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2437           0 :                                         set_processed(xp);
    2438             :                                 } else {
    2439             :                                         xp = r;
    2440             :                                 }
    2441             :                         }
    2442             :                 } else {
    2443          27 :                         if (exp_has_rel(e->l))
    2444          25 :                                 xp = exp_rel_get_rel(sa, e->l);
    2445          27 :                         if (exp_has_rel(e->r)) {
    2446           7 :                                 if (!(r = exp_rel_get_rel(sa, e->r)))
    2447             :                                         return NULL;
    2448           7 :                                 if (xp) {
    2449           5 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2450           5 :                                         set_processed(xp);
    2451             :                                 } else {
    2452             :                                         xp = r;
    2453             :                                 }
    2454             :                         }
    2455          27 :                         if (e->f && exp_has_rel(e->f)) {
    2456           0 :                                 if (!(r = exp_rel_get_rel(sa, e->f)))
    2457             :                                         return NULL;
    2458           0 :                                 if (xp) {
    2459           0 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2460           0 :                                         set_processed(xp);
    2461             :                                 } else {
    2462             :                                         xp = r;
    2463             :                                 }
    2464             :                         }
    2465             :                 }
    2466             :                 return xp;
    2467             :         }
    2468         955 :         case e_convert:
    2469         955 :                 return exp_rel_get_rel(sa, e->l);
    2470       76226 :         case e_psm:
    2471       76226 :                 if (exp_is_rel(e))
    2472       76226 :                         return e->l;
    2473             :                 return NULL;
    2474          15 :         case e_atom:
    2475          15 :                 if (e->f && exps_have_rel_exp(e->f))
    2476          15 :                         return exps_rel_get_rel(sa, e->f);
    2477             :                 return NULL;
    2478             :         case e_column:
    2479             :                 return NULL;
    2480             :         }
    2481             :         return NULL;
    2482             : }
    2483             : 
    2484             : static void exp_rel_update_set_freevar(sql_exp *e);
    2485             : 
    2486             : static void
    2487         921 : exps_rel_update_set_freevar(list *exps)
    2488             : {
    2489         921 :         if (!list_empty(exps))
    2490        3003 :                 for (node *n=exps->h; n ; n=n->next)
    2491        2082 :                         exp_rel_update_set_freevar(n->data);
    2492         921 : }
    2493             : 
    2494             : static void
    2495        2372 : exp_rel_update_set_freevar(sql_exp *e)
    2496             : {
    2497        2384 :         if (!e)
    2498             :                 return ;
    2499             : 
    2500        2384 :         switch(e->type){
    2501         919 :         case e_func:
    2502             :         case e_aggr:
    2503         919 :                 exps_rel_update_set_freevar(e->l);
    2504         919 :                 break;
    2505           8 :         case e_cmp:
    2506           8 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2507           0 :                         exps_rel_update_set_freevar(e->l);
    2508           0 :                         exps_rel_update_set_freevar(e->r);
    2509           8 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2510           0 :                         exp_rel_update_set_freevar(e->l);
    2511           0 :                         exps_rel_update_set_freevar(e->r);
    2512             :                 } else {
    2513           8 :                         exp_rel_update_set_freevar(e->l);
    2514           8 :                         exp_rel_update_set_freevar(e->r);
    2515           8 :                         if (e->f)
    2516             :                                 exp_rel_update_set_freevar(e->f);
    2517             :                 }
    2518             :                 break;
    2519           9 :         case e_convert:
    2520           9 :                 exp_rel_update_set_freevar(e->l);
    2521           9 :                 break;
    2522        1166 :         case e_atom:
    2523        1166 :                 if (e->f)
    2524           2 :                         exps_rel_update_set_freevar(e->f);
    2525             :                 break;
    2526         282 :         case e_column:
    2527         282 :                 set_freevar(e, 1);
    2528         282 :                 break;
    2529             :         case e_psm:
    2530             :                 break;
    2531             :         }
    2532             : }
    2533             : 
    2534             : static list *
    2535         570 : exp_rel_update_exps(mvc *sql, list *exps, bool up)
    2536             : {
    2537         570 :         if (list_empty(exps))
    2538             :                 return exps;
    2539        1674 :         for (node *n = exps->h; n; n=n->next){
    2540        1104 :                 sql_exp *e = n->data;
    2541             : 
    2542        1104 :                 if (exp_has_rel(e))
    2543         576 :                         n->data = exp_rel_update_exp(sql, e, up);
    2544         528 :                 else if (!exp_is_atom(e) && !up)
    2545         268 :                         exp_rel_update_set_freevar(e);
    2546             :         }
    2547             :         return exps;
    2548             : }
    2549             : 
    2550             : static sql_exp *
    2551          57 : exp_rel_update_exp_(mvc *sql, sql_exp *e, bool up)
    2552             : {
    2553          57 :         if (exp_has_rel(e))
    2554          31 :                 e = exp_rel_update_exp(sql, e, up);
    2555          26 :         else if (!exp_is_atom(e) && !up)
    2556           6 :                 exp_rel_update_set_freevar(e);
    2557          57 :         return e;
    2558             : }
    2559             : 
    2560             : sql_exp *
    2561       13369 : exp_rel_update_exp(mvc *sql, sql_exp *e, bool up)
    2562             : {
    2563       13369 :         if (!e)
    2564             :                 return NULL;
    2565             : 
    2566       13369 :         switch(e->type){
    2567         542 :         case e_func:
    2568             :         case e_aggr:
    2569         542 :                 if (exps_have_rel_exp(e->l))
    2570         542 :                         e->l = exp_rel_update_exps(sql, e->l, up);
    2571             :                 return e;
    2572          37 :         case e_cmp:
    2573          37 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2574          11 :                         if (exps_have_rel_exp(e->l))
    2575           7 :                                 e->l = exp_rel_update_exps(sql, e->l, up);
    2576          11 :                         if (exps_have_rel_exp(e->r))
    2577           6 :                                 e->r = exp_rel_update_exps(sql, e->r, up);
    2578          26 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2579           0 :                         if (exp_has_rel(e->l))
    2580           0 :                                 e->l = exp_rel_update_exp(sql, e->l, up);
    2581           0 :                         if (exps_have_rel_exp(e->r))
    2582           0 :                                 e->r = exp_rel_update_exps(sql, e->r, up);
    2583             :                 } else {
    2584             :                         //if (exp_has_rel(e->l))
    2585          26 :                                 e->l = exp_rel_update_exp_(sql, e->l, up);
    2586             :                         //if (exp_has_rel(e->r))
    2587          26 :                                 e->r = exp_rel_update_exp_(sql, e->r, up);
    2588          26 :                         if (e->f /*&& exp_has_rel(e->f)*/)
    2589           5 :                                 e->f = exp_rel_update_exp_(sql, e->f, up);
    2590             :                 }
    2591             :                 return e;
    2592         955 :         case e_convert:
    2593         955 :                 if (exp_has_rel(e->l))
    2594         955 :                         e->l = exp_rel_update_exp(sql, e->l, up);
    2595             :                 return e;
    2596       11820 :         case e_psm:
    2597       11820 :                 if (exp_is_rel(e)) {
    2598       11820 :                         sql_rel *r = exp_rel_get_rel(sql->sa, e), *nr = r;
    2599       11820 :                         if (is_topn(r->op)) {
    2600           2 :                                 nr = r->l;
    2601           2 :                                 if (nr && !is_project(nr->op))
    2602           0 :                                         r->l = nr = rel_project(sql->sa, nr, rel_projections(sql, nr, NULL, 1, 0));
    2603             :                         }
    2604       11820 :                         e = nr->exps->t->data;
    2605       11820 :                         e = exp_ref(sql, e);
    2606       11820 :                         if (up)
    2607           0 :                                 set_freevar(e, 1);
    2608       11820 :                         return e;
    2609             :                 }
    2610             :                 return e;
    2611          15 :         case e_atom:
    2612          15 :                 if (e->f && exps_have_rel_exp(e->f))
    2613          15 :                         e->f = exp_rel_update_exps(sql, e->f, up);
    2614             :                 return e;
    2615             :         case e_column:
    2616             :                 return e;
    2617             :         }
    2618             :         return e;
    2619             : }
    2620             : 
    2621             : sql_exp *
    2622        4099 : exp_rel_label(mvc *sql, sql_exp *e)
    2623             : {
    2624        4099 :         if (exp_is_rel(e))
    2625        4099 :                 e->l = rel_label(sql, e->l, 1);
    2626        4099 :         return e;
    2627             : }
    2628             : 
    2629             : int
    2630      147010 : exps_are_atoms( list *exps)
    2631             : {
    2632      147010 :         int atoms = 1;
    2633      147010 :         if (!list_empty(exps))
    2634      429844 :                 for(node *n=exps->h; n && atoms; n=n->next)
    2635      312757 :                         atoms &= exp_is_atom(n->data);
    2636      147010 :         return atoms;
    2637             : }
    2638             : 
    2639             : int
    2640         144 : exps_have_func(list *exps)
    2641             : {
    2642         144 :         if (list_empty(exps))
    2643             :                 return 0;
    2644         175 :         for(node *n=exps->h; n; n=n->next) {
    2645         148 :                 sql_exp *e = n->data;
    2646             : 
    2647         148 :                 if (exp_has_func(e))
    2648             :                         return 1;
    2649             :         }
    2650             :         return 0;
    2651             : }
    2652             : 
    2653             : static int exp_has_func_or_cmp(sql_exp *e, bool cmp);
    2654             : 
    2655             : static int
    2656       68287 : exps_have_func_or_cmp(list *exps, bool cmp)
    2657             : {
    2658       68287 :         if (list_empty(exps))
    2659             :                 return 0;
    2660      195680 :         for(node *n=exps->h; n; n=n->next) {
    2661      136897 :                 sql_exp *e = n->data;
    2662             : 
    2663      136897 :                 if (exp_has_func_or_cmp(e, cmp))
    2664             :                         return 1;
    2665             :         }
    2666             :         return 0;
    2667             : }
    2668             : 
    2669             : static int
    2670     2166864 : exp_has_func_or_cmp(sql_exp *e, bool cmp)
    2671             : {
    2672     2166864 :         if (!e)
    2673             :                 return 0;
    2674     2166864 :         switch (e->type) {
    2675      307263 :         case e_atom:
    2676      307263 :                 if (e->f)
    2677           4 :                         return exps_have_func_or_cmp(e->f, true);
    2678             :                 return 0;
    2679       16131 :         case e_convert:
    2680             :                 {
    2681       16131 :                         sql_subtype *t = exp_totype(e);
    2682       16131 :                         sql_subtype *f = exp_fromtype(e);
    2683       16131 :                         if (t->type->eclass == EC_FLT && (f->type->eclass == EC_DEC || f->type->eclass == EC_NUM))
    2684         170 :                                 return exp_has_func_or_cmp(e->l, cmp);
    2685       15961 :                         if (f->type->localtype > t->type->localtype)
    2686             :                                 return true;
    2687             :                 }
    2688       13778 :                 return exp_has_func_or_cmp(e->l, cmp);
    2689             :         case e_func:
    2690             :                 return 1;
    2691       20072 :         case e_aggr:
    2692       20072 :                 if (e->l)
    2693       17251 :                         return exps_have_func_or_cmp(e->l, true);
    2694             :                 return 0;
    2695      270538 :         case e_cmp:
    2696      270538 :                 if (cmp)
    2697             :                         return 1;
    2698      261133 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2699       22086 :                         return (exps_have_func_or_cmp(e->l, true) || exps_have_func_or_cmp(e->r, true));
    2700      248472 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2701       35194 :                         return (exp_has_func_or_cmp(e->l, true) || exps_have_func_or_cmp(e->r, true));
    2702             :                 } else {
    2703      426668 :                         return (exp_has_func_or_cmp(e->l, true) || exp_has_func_or_cmp(e->r, true) ||
    2704      198180 :                                         (e->f && exp_has_func_or_cmp(e->f, true)));
    2705             :                 }
    2706             :         case e_column:
    2707             :         case e_psm:
    2708             :                 return 0;
    2709             :         }
    2710             :         return 0;
    2711             : }
    2712             : 
    2713             : int
    2714     1566554 : exp_has_func(sql_exp *e)
    2715             : {
    2716     1566554 :         return exp_has_func_or_cmp(e, false);
    2717             : }
    2718             : 
    2719             : static int
    2720      720752 : exps_have_sideeffect( list *exps)
    2721             : {
    2722      720752 :         node *n;
    2723      720752 :         int has_sideeffect = 0;
    2724             : 
    2725     2213821 :         for(n=exps->h; n && !has_sideeffect; n=n->next)
    2726     1493069 :                 has_sideeffect |= exp_has_sideeffect(n->data);
    2727      720752 :         return has_sideeffect;
    2728             : }
    2729             : 
    2730             : int
    2731     1677857 : exp_has_sideeffect( sql_exp *e )
    2732             : {
    2733     1702705 :         switch (e->type) {
    2734       24848 :         case e_convert:
    2735       24848 :                 return exp_has_sideeffect(e->l);
    2736      720791 :         case e_func:
    2737             :                 {
    2738      720791 :                         sql_subfunc *f = e->f;
    2739             : 
    2740      720791 :                         if (f->func->side_effect)
    2741             :                                 return 1;
    2742      720777 :                         if (e->l)
    2743      720752 :                                 return exps_have_sideeffect(e->l);
    2744             :                         return 0;
    2745             :                 }
    2746      471883 :         case e_atom:
    2747      471883 :                 if (e->f)
    2748           0 :                         return exps_have_sideeffect(e->f);
    2749             :                 return 0;
    2750             :         case e_aggr:
    2751             :         case e_cmp:
    2752             :         case e_column:
    2753             :         case e_psm:
    2754             :                 return 0;
    2755             :         }
    2756             :         return 0;
    2757             : }
    2758             : 
    2759             : bool
    2760     1033622 : exps_have_unsafe(list *exps, bool allow_identity, bool card)
    2761             : {
    2762     1033622 :         int unsafe = 0;
    2763             : 
    2764     1033622 :         if (list_empty(exps))
    2765             :                 return 0;
    2766     3548320 :         for (node *n = exps->h; n && !unsafe; n = n->next)
    2767     2535244 :                 unsafe |= exp_unsafe(n->data, allow_identity, card);
    2768     1013076 :         return unsafe;
    2769             : }
    2770             : 
    2771             : bool
    2772    12389255 : exp_unsafe(sql_exp *e, bool allow_identity, bool card)
    2773             : {
    2774    12389255 :         switch (e->type) {
    2775      762740 :         case e_convert:
    2776      762740 :                 if (card) {
    2777        9025 :                         sql_subtype *t = exp_totype(e);
    2778        9025 :                         sql_subtype *f = exp_fromtype(e);
    2779        9025 :                         if (t->type->eclass == EC_FLT && (f->type->eclass == EC_DEC || f->type->eclass == EC_NUM))
    2780             :                                 return false;
    2781        8944 :                         if (f->type->localtype > t->type->localtype)
    2782             :                                 return true;
    2783             :                         return false;
    2784             :                 }
    2785      753715 :                 return exp_unsafe(e->l, allow_identity, card);
    2786      990514 :         case e_aggr:
    2787             :         case e_func: {
    2788      990514 :                 sql_subfunc *f = e->f;
    2789             : 
    2790      990514 :                 if (IS_ANALYTIC(f->func) || !LANG_INT_OR_MAL(f->func->lang) || f->func->side_effect || (!allow_identity && is_identity(e, NULL)))
    2791       53171 :                         return 1;
    2792      937343 :                 return exps_have_unsafe(e->l, allow_identity, card);
    2793       52108 :         } break;
    2794       52108 :         case e_cmp: {
    2795       52108 :                 if (e->flag == cmp_in || e->flag == cmp_notin) {
    2796        6357 :                         return exp_unsafe(e->l, allow_identity, card) || exps_have_unsafe(e->r, allow_identity, card);
    2797       45751 :                 } else if (e->flag == cmp_or || e->flag == cmp_filter) {
    2798       10562 :                         return exps_have_unsafe(e->l, allow_identity, card) || exps_have_unsafe(e->r, allow_identity, card);
    2799             :                 } else {
    2800       70394 :                         return exp_unsafe(e->l, allow_identity, card) || exp_unsafe(e->r, allow_identity, card) || (e->f && exp_unsafe(e->f, allow_identity, card));
    2801             :                 }
    2802     1102919 :         } break;
    2803     1102919 :         case e_atom: {
    2804     1102919 :                 if (e->f)
    2805           0 :                         return exps_have_unsafe(e->f, allow_identity, card);
    2806             :                 return 0;
    2807             :         } break;
    2808             :         case e_column:
    2809             :         case e_psm:
    2810             :                 return 0;
    2811             :         }
    2812             :         return 0;
    2813             : }
    2814             : 
    2815             : static inline int
    2816     3488500 : exp_key( sql_exp *e )
    2817             : {
    2818     3488500 :         if (e->alias.name)
    2819     3488499 :                 return hash_key(e->alias.name);
    2820             :         return 0;
    2821             : }
    2822             : 
    2823             : sql_exp *
    2824          82 : exps_uses_nid(list *exps, int nid)
    2825             : {
    2826          82 :         if (exps) {
    2827         153 :                 for (node *en = exps->h; en; en = en->next ) {
    2828         147 :                         sql_exp *e = en->data;
    2829             : 
    2830         147 :                         if (e->nid == nid)
    2831          76 :                                 return e;
    2832             :                 }
    2833             :         }
    2834             :         return NULL;
    2835             : }
    2836             : 
    2837             : sql_exp *
    2838    70607571 : exps_bind_nid(list *exps, int nid)
    2839             : {
    2840    70607571 :         if (exps) {
    2841  5429909753 :                 for (node *en = exps->h; en; en = en->next ) {
    2842  5388335482 :                         sql_exp *e = en->data;
    2843             : 
    2844  5388335482 :                         if (e->alias.label == nid)
    2845    28678184 :                                 return e;
    2846             :                 }
    2847             :         }
    2848             :         return NULL;
    2849             : }
    2850             : 
    2851             : sql_exp *
    2852      957561 : exps_bind_column(list *exps, const char *cname, int *ambiguous, int *multiple, int no_tname)
    2853             : {
    2854      957561 :         sql_exp *res = NULL;
    2855             : 
    2856      957561 :         if (exps && cname) {
    2857      957560 :                 node *en;
    2858             : 
    2859      957560 :                 if (exps) {
    2860      957560 :                         if (!exps->ht && list_length(exps) > HASH_MIN_SIZE) {
    2861      108293 :                                 exps->ht = hash_new(exps->sa, list_length(exps), (fkeyvalue)&exp_key);
    2862      108293 :                                 if (exps->ht == NULL)
    2863             :                                         return NULL;
    2864      817370 :                                 for (en = exps->h; en; en = en->next ) {
    2865      709077 :                                         sql_exp *e = en->data;
    2866      709077 :                                         if (e->alias.name) {
    2867      709077 :                                                 int key = exp_key(e);
    2868             : 
    2869      709077 :                                                 if (hash_add(exps->ht, key, e) == NULL)
    2870             :                                                         return NULL;
    2871             :                                         }
    2872             :                                 }
    2873             :                         }
    2874      957560 :                         if (exps->ht) {
    2875      425786 :                                 int key = hash_key(cname);
    2876      425786 :                                 sql_hash_e *he = exps->ht->buckets[key&(exps->ht->size-1)];
    2877             : 
    2878      829170 :                                 for (; he; he = he->chain) {
    2879      403388 :                                         sql_exp *e = he->value;
    2880             : 
    2881      403388 :                                         if (e->alias.name && strcmp(e->alias.name, cname) == 0 && (!no_tname || !e->alias.rname)) {
    2882      145046 :                                                 if (res && multiple)
    2883           4 :                                                         *multiple = 1;
    2884      145046 :                                                 if (!res)
    2885      145046 :                                                         res = e;
    2886             : 
    2887      145046 :                                                 if (res && res != e && e->alias.rname && res->alias.rname && strcmp(e->alias.rname, res->alias.rname) != 0 ) {
    2888           4 :                                                         if (ambiguous)
    2889           4 :                                                                 *ambiguous = 1;
    2890           4 :                                                         return NULL;
    2891             :                                                 }
    2892             :                                                 res = e;
    2893             :                                         }
    2894             :                                 }
    2895      425782 :                                 return res;
    2896             :                         }
    2897             :                 }
    2898     1551000 :                 for (en = exps->h; en; en = en->next ) {
    2899     1019231 :                         sql_exp *e = en->data;
    2900             : 
    2901     1019231 :                         if (e->alias.name && strcmp(e->alias.name, cname) == 0 && (!no_tname || !e->alias.rname)) {
    2902       43689 :                                 if (res && multiple)
    2903           8 :                                         *multiple = 1;
    2904       43689 :                                 if (!res)
    2905       43689 :                                         res = e;
    2906             : 
    2907       43689 :                                 if (res && res != e && e->alias.rname && res->alias.rname && strcmp(e->alias.rname, res->alias.rname) != 0 ) {
    2908           5 :                                         if (ambiguous)
    2909           5 :                                                 *ambiguous = 1;
    2910           5 :                                         return NULL;
    2911             :                                 }
    2912             :                                 res = e;
    2913             :                         }
    2914             :                 }
    2915             :         }
    2916             :         return res;
    2917             : }
    2918             : 
    2919             : sql_exp *
    2920     1644324 : exps_bind_column2(list *exps, const char *rname, const char *cname, int *multiple)
    2921             : {
    2922     1644324 :         sql_exp *res = NULL;
    2923             : 
    2924     1644324 :         if (exps) {
    2925     1644294 :                 node *en;
    2926             : 
    2927     1644294 :                 if (!exps->ht && list_length(exps) > HASH_MIN_SIZE) {
    2928      127329 :                         exps->ht = hash_new(exps->sa, list_length(exps), (fkeyvalue)&exp_key);
    2929      127329 :                         if (exps->ht == NULL)
    2930             :                                 return res;
    2931             : 
    2932     2142601 :                         for (en = exps->h; en; en = en->next ) {
    2933     2015272 :                                 sql_exp *e = en->data;
    2934     2015272 :                                 if (e->alias.name) {
    2935     2015272 :                                         int key = exp_key(e);
    2936             : 
    2937     2015272 :                                         if (hash_add(exps->ht, key, e) == NULL)
    2938             :                                                 return res;
    2939             :                                 }
    2940             :                         }
    2941             :                 }
    2942     1644294 :                 if (exps->ht) {
    2943      985556 :                         int key = hash_key(cname);
    2944      985556 :                         sql_hash_e *he = exps->ht->buckets[key&(exps->ht->size-1)];
    2945             : 
    2946     2773596 :                         for (; he; he = he->chain) {
    2947     1790152 :                                 sql_exp *e = he->value;
    2948             : 
    2949     1790152 :                                 if (e && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) {
    2950      724525 :                                         if (res && multiple)
    2951           0 :                                                 *multiple = 1;
    2952      724525 :                                         if (!res)
    2953             :                                                 res = e;
    2954      724525 :                                         if (res && has_label(res)) /* aliases maybe used multiple times without problems */
    2955        2112 :                                                 return res;
    2956             :                                 }
    2957             :                         }
    2958      983444 :                         return res;
    2959             :                 }
    2960     2195473 :                 for (en = exps->h; en; en = en->next ) {
    2961     1543917 :                         sql_exp *e = en->data;
    2962             : 
    2963     1543917 :                         if (e && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) {
    2964      442851 :                                 if (res && multiple)
    2965           1 :                                         *multiple = 1;
    2966      442851 :                                 if (!res)
    2967             :                                         res = e;
    2968      442851 :                                 if (res && has_label(res)) /* aliases maybe used multiple times without problems */
    2969        7182 :                                         return res;
    2970             :                         }
    2971             :                 }
    2972             :         }
    2973             :         return res;
    2974             : }
    2975             : 
    2976             : /* find an column based on the original name, not the alias it got */
    2977             : sql_exp *
    2978           0 : exps_bind_alias( list *exps, const char *rname, const char *cname )
    2979             : {
    2980           0 :         if (exps) {
    2981           0 :                 node *en;
    2982             : 
    2983           0 :                 for (en = exps->h; en; en = en->next ) {
    2984           0 :                         sql_exp *e = en->data;
    2985             : 
    2986           0 :                         if (e && is_column(e->type) && !rname && e->r && strcmp(e->r, cname) == 0)
    2987             :                         {
    2988           0 :                                 assert(0);
    2989             :                                 return e;
    2990             :                         }
    2991           0 :                         if (e && e->type == e_column && rname && e->l && e->r && strcmp(e->r, cname) == 0 && strcmp(e->l, rname) == 0) {
    2992           0 :                                 assert(0);
    2993             :                                 return e;
    2994             :                         }
    2995             :                 }
    2996             :         }
    2997           0 :         return NULL;
    2998             : }
    2999             : 
    3000             : unsigned int
    3001     3234207 : exps_card( list *l )
    3002             : {
    3003     3234207 :         node *n;
    3004     3234207 :         unsigned int card = CARD_ATOM;
    3005             : 
    3006    14374985 :         if (l) for(n = l->h; n; n = n->next) {
    3007    11140778 :                 sql_exp *e = n->data;
    3008             : 
    3009    11140778 :                 if (e && card < e->card)
    3010    11140778 :                         card = e->card;
    3011             :         }
    3012     3234207 :         return card;
    3013             : }
    3014             : 
    3015             : void
    3016       43184 : exps_fix_card( list *exps, unsigned int card)
    3017             : {
    3018       43184 :         if (exps)
    3019     1060339 :                 for (node *n = exps->h; n; n = n->next) {
    3020     1017155 :                 sql_exp *e = n->data;
    3021             : 
    3022     1017155 :                 if (e && e->card > card)
    3023           0 :                         e->card = card;
    3024             :         }
    3025       43184 : }
    3026             : 
    3027             : void
    3028        4043 : exps_setcard( list *exps, unsigned int card)
    3029             : {
    3030        4043 :         if (exps)
    3031       23834 :                 for (node *n = exps->h; n; n = n->next) {
    3032       19791 :                         sql_exp *e = n->data;
    3033             : 
    3034       19791 :                         if (e && e->card != CARD_ATOM)
    3035       19762 :                                 e->card = card;
    3036             :                 }
    3037        4043 : }
    3038             : 
    3039             : int
    3040           0 : exps_intern(list *exps)
    3041             : {
    3042           0 :         if (exps)
    3043           0 :                 for (node *n=exps->h; n; n = n->next) {
    3044           0 :                         sql_exp *e = n->data;
    3045             : 
    3046           0 :                         if (is_intern(e))
    3047             :                                 return 1;
    3048             :                 }
    3049             :         return 0;
    3050             : }
    3051             : 
    3052             : sql_exp *
    3053        3497 : exps_find_one_multi_exp(list *exps)
    3054             : {
    3055        3497 :         sql_exp *l = NULL;
    3056        3497 :         int skip = 0;
    3057             : 
    3058             :         /* Find one and only 1 expression with card > CARD_ATOM */
    3059        3497 :         if (!list_empty(exps)) {
    3060        7189 :                 for (node *m = exps->h ; m && !skip ; m = m->next) {
    3061        3692 :                         sql_exp *e = m->data;
    3062             : 
    3063        3692 :                         if (e->card > CARD_ATOM) {
    3064        3464 :                                 skip |= l != NULL;
    3065        3464 :                                 l = e;
    3066             :                         }
    3067             :                 }
    3068             :         }
    3069        3497 :         if (skip)
    3070           6 :                 l = NULL;
    3071        3497 :         return l;
    3072             : }
    3073             : 
    3074             : const char *
    3075      128097 : compare_func( comp_type t, int anti )
    3076             : {
    3077      128097 :         switch(t) {
    3078       73758 :         case cmp_equal:
    3079       73758 :                 return anti?"<>":"=";
    3080        8002 :         case cmp_lt:
    3081        8002 :                 return anti?">":"<";
    3082        2102 :         case cmp_lte:
    3083        2102 :                 return anti?">=":"<=";
    3084        1159 :         case cmp_gte:
    3085        1159 :                 return anti?"<=":">=";
    3086       31122 :         case cmp_gt:
    3087       31122 :                 return anti?"<":">";
    3088       11954 :         case cmp_notequal:
    3089       11954 :                 return anti?"=":"<>";
    3090             :         default:
    3091             :                 return NULL;
    3092             :         }
    3093             : }
    3094             : 
    3095             : int
    3096     9481113 : is_identity( sql_exp *e, sql_rel *r)
    3097             : {
    3098     9491925 :         switch(e->type) {
    3099       36898 :         case e_column:
    3100       36898 :                 if (r && is_project(r->op) && !is_set(r->op)) {
    3101       13634 :                         sql_exp *re = NULL;
    3102       13634 :                         assert(e->nid);
    3103       13634 :                         re = exps_bind_nid(r->exps, e->nid);
    3104       13634 :                         if (re)
    3105       10812 :                                 return is_identity(re, r->l);
    3106             :                 }
    3107             :                 return 0;
    3108     9447998 :         case e_func: {
    3109     9447998 :                 sql_subfunc *f = e->f;
    3110     9447998 :                 return !f->func->s && strcmp(f->func->base.name, "identity") == 0;
    3111             :         }
    3112             :         default:
    3113             :                 return 0;
    3114             :         }
    3115             : }
    3116             : 
    3117             : list *
    3118          14 : exps_alias(mvc *sql, list *exps)
    3119             : {
    3120          14 :         list *nl = new_exp_list(sql->sa);
    3121             : 
    3122          14 :         if (exps)
    3123          58 :                 for (node *n = exps->h; n; n = n->next) {
    3124          44 :                         sql_exp *e = n->data, *ne;
    3125             : 
    3126          44 :                         assert(exp_name(e));
    3127          44 :                         ne = exp_ref(sql, e);
    3128          44 :                         append(nl, ne);
    3129             :                 }
    3130          14 :         return nl;
    3131             : }
    3132             : 
    3133             : list *
    3134      140250 : exps_copy(mvc *sql, list *exps)
    3135             : {
    3136      140250 :         list *nl;
    3137             : 
    3138      140250 :         if (mvc_highwater(sql))
    3139           0 :                 return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3140             : 
    3141      140250 :         if (!exps)
    3142             :                 return NULL;
    3143      122069 :         nl = new_exp_list(sql->sa);
    3144      551097 :         for (node *n = exps->h; n; n = n->next) {
    3145      429028 :                 sql_exp *arg = n->data;
    3146             : 
    3147      429028 :                 arg = exp_copy(sql, arg);
    3148      429028 :                 if (!arg)
    3149             :                         return NULL;
    3150      429028 :                 append(nl, arg);
    3151             :         }
    3152             :         return nl;
    3153             : }
    3154             : 
    3155             : sql_exp *
    3156     2594022 : exp_copy(mvc *sql, sql_exp * e)
    3157             : {
    3158     2594022 :         sql_exp *l, *r, *r2, *ne = NULL;
    3159             : 
    3160     2594022 :         if (mvc_highwater(sql))
    3161           0 :                 return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3162             : 
    3163     2594022 :         if (!e)
    3164             :                 return NULL;
    3165     2594022 :         switch(e->type){
    3166     2235055 :         case e_column:
    3167     2235055 :                 ne = exp_column(sql->sa, e->l, e->r, exp_subtype(e), e->card, has_nil(e), is_unique(e), is_intern(e));
    3168     2235055 :                 ne->flag = e->flag;
    3169     2235055 :                 ne->alias.label = e->alias.label;
    3170     2235055 :                 ne->nid = e->nid;
    3171     2235055 :                 break;
    3172       43108 :         case e_cmp:
    3173       43108 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    3174        3300 :                         list *l = exps_copy(sql, e->l);
    3175        3300 :                         list *r = exps_copy(sql, e->r);
    3176             : 
    3177        3300 :                         if (e->flag == cmp_filter)
    3178         590 :                                 ne = exp_filter(sql->sa, l, r, e->f, is_anti(e));
    3179             :                         else
    3180        2710 :                                 ne = exp_or(sql->sa, l, r, is_anti(e));
    3181       39808 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    3182        1414 :                         sql_exp *l = exp_copy(sql, e->l);
    3183        1414 :                         list *r = exps_copy(sql, e->r);
    3184             : 
    3185        1414 :                         ne = exp_in(sql->sa, l, r, e->flag);
    3186             :                 } else {
    3187       38394 :                         l = exp_copy(sql, e->l);
    3188       38394 :                         r = exp_copy(sql, e->r);
    3189             : 
    3190       38394 :                         if (e->f) {
    3191         687 :                                 r2 = exp_copy(sql, e->f);
    3192         687 :                                 ne = exp_compare2(sql->sa, l, r, r2, e->flag, is_symmetric(e));
    3193             :                         } else {
    3194       37707 :                                 ne = exp_compare(sql->sa, l, r, e->flag);
    3195             :                         }
    3196             :                 }
    3197             :                 break;
    3198       27839 :         case e_convert:
    3199       27839 :                 ne = exp_convert(sql, exp_copy(sql, e->l), exp_fromtype(e), exp_totype(e));
    3200       27839 :                 break;
    3201       13467 :         case e_aggr:
    3202             :         case e_func: {
    3203       13467 :                 list *l = exps_copy(sql, e->l);
    3204             : 
    3205       13467 :                 if (e->type == e_func)
    3206       11523 :                         ne = exp_op(sql->sa, l, e->f);
    3207             :                 else
    3208        1944 :                         ne = exp_aggr(sql->sa, l, e->f, need_distinct(e), need_no_nil(e), e->card, has_nil(e));
    3209       13467 :                 if (e->r) { /* copy obe and gbe lists */
    3210           1 :                         list *er = (list*) e->r;
    3211           1 :                         assert(list_length(er) <= 2);
    3212           1 :                         if (list_length(er) == 2)
    3213           0 :                                 ne->r = list_append(list_append(sa_list(sql->sa), exps_copy(sql, er->h->data)), exps_copy(sql, er->h->next->data));
    3214             :                         else
    3215           1 :                                 ne->r = list_append(sa_list(sql->sa), exps_copy(sql, er->h->data));
    3216             :                 }
    3217             :                 break;
    3218             :         }
    3219      274549 :         case e_atom:
    3220      274549 :                 if (e->l)
    3221      270521 :                         ne = exp_atom(sql->sa, e->l);
    3222        4028 :                 else if (e->r) {
    3223        3472 :                         sql_var_name *vname = (sql_var_name*) e->r;
    3224        3472 :                         ne = exp_param_or_declared(sql->sa, vname->sname, vname->name, &e->tpe, e->flag);
    3225         556 :                 } else if (e->f)
    3226           3 :                         ne = exp_values(sql->sa, exps_copy(sql, e->f));
    3227             :                 else
    3228         553 :                         ne = exp_atom_ref(sql->sa, e->flag, &e->tpe);
    3229             :                 break;
    3230           4 :         case e_psm:
    3231           4 :                 if (e->flag & PSM_SET) {
    3232           0 :                         ne = exp_set(sql->sa, e->alias.rname, e->alias.name, exp_copy(sql, e->l), GET_PSM_LEVEL(e->flag));
    3233           4 :                 } else if (e->flag & PSM_VAR) {
    3234           0 :                         if (e->f)
    3235           0 :                                 ne = exp_table(sql->sa, e->alias.name, e->f, GET_PSM_LEVEL(e->flag));
    3236             :                         else
    3237           0 :                                 ne = exp_var(sql->sa, e->alias.rname, e->alias.name, &e->tpe, GET_PSM_LEVEL(e->flag));
    3238           4 :                 } else if (e->flag & PSM_RETURN) {
    3239           0 :                         ne = exp_return(sql->sa, exp_copy(sql, e->l), GET_PSM_LEVEL(e->flag));
    3240           4 :                 } else if (e->flag & PSM_WHILE) {
    3241           0 :                         ne = exp_while(sql->sa, exp_copy(sql, e->l), exps_copy(sql, e->r));
    3242           4 :                 } else if (e->flag & PSM_IF) {
    3243           0 :                         ne = exp_if(sql->sa, exp_copy(sql, e->l), exps_copy(sql, e->r), exps_copy(sql, e->f));
    3244           4 :                 } else if (e->flag & PSM_REL) {
    3245           4 :                         if (!e->alias.label)
    3246           4 :                                 exp_label(sql->sa, e, ++sql->label);
    3247           4 :                         return exp_ref(sql, e);
    3248           0 :                 } else if (e->flag & PSM_EXCEPTION) {
    3249           0 :                         ne = exp_exception(sql->sa, exp_copy(sql, e->l), (const char *) e->r);
    3250             :                 }
    3251             :                 break;
    3252             :         }
    3253     2594018 :         if (!ne)
    3254           0 :                 return ne;
    3255     2594018 :         if (e->alias.name)
    3256     2391229 :                 exp_prop_alias(sql->sa, ne, e);
    3257     2594018 :         ne = exp_propagate(sql->sa, ne, e);
    3258     2594018 :         if (is_freevar(e))
    3259        8261 :                 set_freevar(ne, is_freevar(e)-1);
    3260             :         return ne;
    3261             : }
    3262             : 
    3263             : /* scaling for the division operator */
    3264             : static sql_exp *
    3265        2604 : exp_scale_algebra(mvc *sql, sql_subfunc *f, sql_rel *rel, sql_exp *l, sql_exp *r)
    3266             : {
    3267        2604 :         sql_subtype *lt = exp_subtype(l);
    3268        2604 :         sql_subtype *rt = exp_subtype(r);
    3269             : 
    3270        2604 :         if (!EC_INTERVAL(lt->type->eclass) && lt->type->scale == SCALE_FIX && (lt->scale || rt->scale) &&
    3271         338 :                 strcmp(sql_func_imp(f->func), "/") == 0) {
    3272         170 :                 sql_subtype *res = f->res->h->data;
    3273         170 :                 unsigned int scale, digits, digL, scaleL;
    3274         170 :                 sql_subtype nlt;
    3275             : 
    3276             :                 /* scale fixing may require a larger type ! */
    3277             :                 /* TODO make '3' setable by user (division_minimal_scale or so) */
    3278         170 :                 scaleL = (lt->scale < 3) ? 3 : lt->scale;
    3279         170 :                 scaleL += (scaleL < rt->scale)?(rt->scale - scaleL):0;
    3280         170 :                 scale = scaleL;
    3281         170 :                 scaleL += rt->scale;
    3282         170 :                 digL = lt->digits + (scaleL - lt->scale);
    3283         170 :                 digits = (digL > rt->digits) ? digL : rt->digits;
    3284             : 
    3285             :                 /* HACK alert: digits should be less than max */
    3286             : #ifdef HAVE_HGE
    3287         170 :                 if (res->type->radix == 10 && digits > 38)
    3288         170 :                         digits = 38;
    3289         170 :                 if (res->type->radix == 2 && digits > 127)
    3290         170 :                         digits = 127;
    3291             : #else
    3292             :                 if (res->type->radix == 10 && digits > 18)
    3293             :                         digits = 18;
    3294             :                 if (res->type->radix == 2 && digits > 63)
    3295             :                         digits = 63;
    3296             : #endif
    3297             : 
    3298         170 :                 sql_find_subtype(&nlt, lt->type->base.name, digL, scaleL);
    3299         170 :                 if (nlt.digits < scaleL)
    3300           2 :                         return sql_error(sql, 01, SQLSTATE(42000) "Scale (%d) overflows type", scaleL);
    3301         168 :                 l = exp_check_type(sql, &nlt, rel, l, type_equal);
    3302             : 
    3303         168 :                 sql_find_subtype(res, lt->type->base.name, digits, scale);
    3304        2434 :         } else if (lt->type->scale == SCALE_FIX) {
    3305        2236 :                 sql_subtype *res = f->res->h->data;
    3306        2236 :                 if (res->type->eclass == EC_NUM)
    3307        2215 :                         res->digits = MAX(lt->digits, rt->digits);
    3308             :         }
    3309             :         return l;
    3310             : }
    3311             : 
    3312             : sql_exp *
    3313        2604 : exps_scale_algebra(mvc *sql, sql_subfunc *f, sql_rel *rel, list *exps)
    3314             : {
    3315        2604 :         if (list_length(exps) != 2)
    3316             :                 return NULL;
    3317        2604 :         sql_exp *e = exp_scale_algebra(sql, f, rel, exps->h->data, exps->h->next->data);
    3318        2604 :         if (e)
    3319        2602 :                 exps->h->data = e;
    3320             :         return e;
    3321             : }
    3322             : 
    3323             : void
    3324      181313 : exps_digits_add(sql_subfunc *f, list *exps)
    3325             : {
    3326             :         /* concat and friends need larger results */
    3327      181313 :         if (!f->func->res)
    3328             :                 return;
    3329      181313 :         int digits = 0;
    3330      323391 :         for(node *n = exps->h; n; n = n->next) {
    3331      264544 :                 sql_subtype *t = exp_subtype(n->data);
    3332             : 
    3333      264544 :                 if (!t->digits) {
    3334             :                         digits = 0;
    3335             :                         break;
    3336             :                 }
    3337      142078 :                 digits += t->digits;
    3338             :         }
    3339      181313 :         sql_subtype *res = f->res->h->data;
    3340      181313 :         res->digits = digits;
    3341             : }
    3342             : 
    3343             : void
    3344       25185 : exps_sum_scales(sql_subfunc *f, list *exps)
    3345             : {
    3346             :         /* sum scales and digits for multiply operation */
    3347       25185 :         sql_arg *ares = f->func->res->h->data;
    3348             : 
    3349       25185 :         if (ares->type.type->scale == SCALE_FIX && strcmp(sql_func_imp(f->func), "*") == 0) {
    3350       23886 :                 unsigned int digits = 0, scale = 0;
    3351       23886 :                 sql_type *largesttype = ares->type.type;
    3352             : 
    3353       71658 :                 for(node *n = exps->h; n; n = n->next) {
    3354       47772 :                         sql_exp *e = n->data;
    3355       47772 :                         sql_subtype *t = exp_subtype(e);
    3356             : 
    3357       47772 :                         scale += t->scale;
    3358       47772 :                         digits += t->digits;
    3359       47772 :                         if (largesttype->localtype < t->type->localtype)
    3360           0 :                                 largesttype = t->type;
    3361             :                 }
    3362       23886 :                 sql_subtype *res = f->res->h->data;
    3363             : 
    3364       23886 :                 res->scale = scale;
    3365       23886 :                 res->digits = digits;
    3366             : 
    3367             :                 /* HACK alert: digits should be less than max */
    3368             : #ifdef HAVE_HGE
    3369       23886 :                 if (ares->type.type->radix == 10 && res->digits > 38) {
    3370        2473 :                         res->digits = 38;
    3371        2473 :                         res->scale = MIN(res->scale, res->digits - 1);
    3372             :                 }
    3373       23886 :                 if (ares->type.type->radix == 2 && res->digits > 127) {
    3374          25 :                         res->digits = 127;
    3375          25 :                         res->scale = MIN(res->scale, res->digits - 1);
    3376             :                 }
    3377             : #else
    3378             :                 if (ares->type.type->radix == 10 && res->digits > 18) {
    3379             :                         res->digits = 18;
    3380             :                         res->scale = MIN(res->scale, res->digits - 1);
    3381             :                 }
    3382             :                 if (ares->type.type->radix == 2 && res->digits > 63) {
    3383             :                         res->digits = 63;
    3384             :                         res->scale = MIN(res->scale, res->digits - 1);
    3385             :                 }
    3386             : #endif
    3387             : 
    3388       23886 :                 sql_subtype t;
    3389             :                 /* numeric types are fixed length */
    3390       23886 :                 if (ares->type.type->eclass == EC_NUM) {
    3391             : #ifdef HAVE_HGE
    3392       21121 :                         if (ares->type.type->localtype == TYPE_hge && res->digits == 127)
    3393          25 :                                 t = *sql_bind_localtype("hge");
    3394             :                         else
    3395             : #endif
    3396       21096 :                         if (ares->type.type->localtype == TYPE_lng && res->digits == 63)
    3397           3 :                                 t = *sql_bind_localtype("lng");
    3398       21093 :                         else if (res->type->digits >= res->digits)
    3399        8854 :                                 t = *res; /* we cannot reduce types! */
    3400             :                         else
    3401       12239 :                                 sql_find_numeric(&t, ares->type.type->localtype, res->digits);
    3402             :                 } else {
    3403        2765 :                         if (res->digits > largesttype->digits)
    3404         218 :                                 sql_find_subtype(&t, largesttype->base.name, res->digits, res->scale);
    3405             :                         else
    3406        2547 :                                 sql_init_subtype(&t, largesttype, res->digits, res->scale);
    3407             :                 }
    3408       23886 :                 *res = t;
    3409             :         }
    3410       25185 : }
    3411             : 
    3412             : void
    3413      111651 : exps_max_bits(sql_subfunc *f, list *exps)
    3414             : {
    3415             :         /* + and - have max_bits + 1 */
    3416      111651 :         if (!f->func->res)
    3417             :                 return;
    3418      111651 :         unsigned int digits = 0;
    3419      334953 :         for(node *n = exps->h; n; n = n->next) {
    3420      223302 :                 sql_subtype *t = exp_subtype(n->data);
    3421             : 
    3422      223302 :                 if (!t)
    3423           0 :                         continue;
    3424      223302 :                 if (digits < t->digits)
    3425      223302 :                         digits = t->digits;
    3426             :         }
    3427             :         /* + and - (because of negative numbers) could need one extra bit (or digit) */
    3428      111651 :         digits += 1;
    3429      111651 :         sql_subtype *res = f->res->h->data;
    3430      111651 :         if (digits > res->type->digits)
    3431       47694 :                 res = sql_find_numeric(res, res->type->localtype, digits);
    3432             :         else
    3433       63957 :                 res->digits = digits;
    3434             : }
    3435             : 
    3436             : void
    3437       19015 : exps_inout(sql_subfunc *f, list *exps)
    3438             : {
    3439             :         /* output == first input */
    3440       19015 :         if (!f->func->res)
    3441             :                 return;
    3442       19015 :         sql_subtype *res = f->res->h->data;
    3443       19015 :         bool is_decimal = (res->type->eclass == EC_DEC);
    3444       19015 :         unsigned int digits = 0, scale = 0;
    3445       19015 :         sql_type *largesttype = NULL;
    3446       19015 :         for(node *n = exps->h; n; n = n->next) {
    3447       19015 :                 sql_subtype *t = exp_subtype(n->data);
    3448             : 
    3449       19015 :                 if (!t)
    3450           0 :                         continue;
    3451             : 
    3452       19015 :                 if (is_decimal && t->type->eclass == EC_DEC && (!largesttype || largesttype->localtype < t->type->localtype))
    3453         390 :                         largesttype = t->type;
    3454         390 :                 if (is_decimal && t->type->eclass == EC_NUM) {
    3455           0 :                         unsigned int d = bits2digits(t->digits);
    3456           0 :                         digits = d>digits?d:digits;
    3457       19015 :                 } else if (digits < t->digits)
    3458             :                         digits = t->digits;
    3459       19015 :                 if (scale < t->scale)
    3460             :                         scale = t->scale;
    3461             :                 break;
    3462             :         }
    3463       19015 :         if (digits > res->digits || scale > res->scale) {
    3464        9203 :                 if (largesttype)
    3465         376 :                         sql_init_subtype(res, largesttype, digits, scale);
    3466             :                 else
    3467        8827 :                         sql_find_subtype(res, res->type->base.name, digits, scale);
    3468             :         } else
    3469        9812 :                 res->digits = digits;
    3470             : }
    3471             : 
    3472             : /* for aggregates we can reduce the result types size based on real digits/bits used number of known input rows */
    3473             : void
    3474        9313 : exps_largest_int(sql_subfunc *f, list *exps, lng cnt)
    3475             : {
    3476        9313 :         if (!f->func->res || cnt == 0)
    3477             :                 return;
    3478         552 :         sql_subtype *res = f->res->h->data;
    3479         552 :         if (res->type->eclass != EC_DEC && res->type->eclass != EC_NUM)
    3480             :                 return;
    3481         476 :         bool is_decimal = (res->type->eclass == EC_DEC);
    3482         476 :         unsigned int digits = 0, scale = 0, mdigits = is_decimal ? decimal_digits(cnt) : number_bits(cnt);
    3483         476 :         sql_type *largesttype = NULL;
    3484         476 :         for(node *n = exps->h; n; n = n->next) {
    3485         476 :                 sql_subtype *t = exp_subtype(n->data);
    3486             : 
    3487         476 :                 if (!t)
    3488           0 :                         continue;
    3489             : 
    3490         476 :                 largesttype = t->type;
    3491         476 :                 if (is_decimal && t->type->eclass == EC_NUM) {
    3492           0 :                         unsigned int d = bits2digits(t->digits);
    3493           0 :                         digits = d>digits?d:digits;
    3494         476 :                 } else if (digits < t->digits)
    3495             :                         digits = t->digits;
    3496         476 :                 if (scale < t->scale)
    3497             :                         scale = t->scale;
    3498             :                 break;
    3499             :         }
    3500         476 :         digits += mdigits;
    3501         476 :         if (largesttype && digits <= largesttype->digits)
    3502         412 :                 sql_init_subtype(res, largesttype, digits, scale);
    3503          64 :         else if (is_decimal)
    3504           8 :                 sql_find_subtype(res, res->type->base.name, digits, scale);
    3505             :         else
    3506          56 :                 sql_find_numeric(res, 1, digits);
    3507             : }
    3508             : 
    3509             : #define is_addition(fname) (strcmp(fname, "sql_add") == 0)
    3510             : #define is_subtraction(fname) (strcmp(fname, "sql_sub") == 0)
    3511             : void
    3512      270489 : exps_scale_fix(sql_subfunc *f, list *exps, sql_subtype *atp)
    3513             : {
    3514      270489 :         if (!f->func->res)
    3515             :                 return;
    3516             : 
    3517      270489 :         sql_subtype *res = f->res->h->data;
    3518      270489 :         if (res->type->eclass != EC_ANY && res->type->eclass != EC_DEC)
    3519             :                 return;
    3520             : 
    3521       61595 :         unsigned int digits = 0, scale = 0;
    3522       61595 :         sql_type *largesttype = NULL;
    3523      239620 :         for(node *n = exps->h; n; n = n->next) {
    3524      178025 :                 sql_subtype *t = exp_subtype(n->data);
    3525             : 
    3526      178025 :                 if (!t)
    3527           0 :                         continue;
    3528      178025 :                 if (digits < t->digits)
    3529             :                         digits = t->digits;
    3530      178025 :                 if (scale < t->scale)
    3531             :                         scale = t->scale;
    3532      178025 :                 if (t->type->eclass == EC_DEC && (!largesttype || largesttype->localtype < t->type->localtype))
    3533      178025 :                         largesttype = t->type;
    3534             :         }
    3535       61595 :         res->scale = scale;
    3536       61595 :         if (res->type->eclass == EC_DEC)
    3537         646 :                 digits += (is_addition(f->func->base.name) || is_subtraction(f->func->base.name));
    3538       61595 :         if (digits > res->type->digits) {
    3539       61273 :                 if (largesttype && largesttype->localtype > res->type->localtype)
    3540          75 :                         sql_init_subtype(res, largesttype, digits, scale);
    3541             :                 else
    3542       61198 :                         sql_find_subtype(res, res->type->localtype?res->type->base.name:atp->type->base.name, digits, scale);
    3543         322 :         } else if (res->type->eclass == EC_DEC || res->type->eclass == EC_NUM)
    3544         252 :                 res->digits = digits;
    3545             : }
    3546             : 
    3547             : int
    3548      126378 : exp_aggr_is_count(sql_exp *e)
    3549             : {
    3550      126378 :         if (e->type == e_aggr && !((sql_subfunc *)e->f)->func->s && strcmp(((sql_subfunc *)e->f)->func->base.name, "count") == 0)
    3551       34757 :                 return 1;
    3552             :         return 0;
    3553             : }
    3554             : 
    3555             : list *
    3556       66762 : check_distinct_exp_names(mvc *sql, list *exps)
    3557             : {
    3558       66762 :         list *distinct_exps = NULL;
    3559       66762 :         bool duplicates = false;
    3560             : 
    3561       66762 :         if (list_length(exps) < 2) {
    3562             :                 return exps; /* always true */
    3563       64976 :         } else if (list_length(exps) < 5) {
    3564       14340 :                 distinct_exps = list_distinct(exps, (fcmp) exp_equal, (fdup) NULL);
    3565             :         } else { /* for longer lists, use hashing */
    3566       50636 :                 sql_hash *ht = hash_new(sql->ta, list_length(exps), (fkeyvalue)&exp_key);
    3567             : 
    3568      501123 :                 for (node *n = exps->h; n && !duplicates; n = n->next) {
    3569      450487 :                         sql_exp *e = n->data;
    3570      450487 :                         int key = ht->key(e);
    3571      450487 :                         sql_hash_e *he = ht->buckets[key&(ht->size-1)];
    3572             : 
    3573      581205 :                         for (; he && !duplicates; he = he->chain) {
    3574      130718 :                                 sql_exp *f = he->value;
    3575             : 
    3576      130718 :                                 if (!exp_equal(e, f))
    3577           0 :                                         duplicates = true;
    3578             :                         }
    3579      450487 :                         hash_add(ht, key, e);
    3580             :                 }
    3581             :         }
    3582       64976 :         if ((distinct_exps && list_length(distinct_exps) != list_length(exps)) || duplicates)
    3583           1 :                 return NULL;
    3584             :         return exps;
    3585             : }
    3586             : 
    3587             : static int rel_find_parameter(mvc *sql, sql_subtype *type, sql_rel *rel, int nid, const char *relname, const char *expname);
    3588             : 
    3589             : static int
    3590        1634 : set_exp_type(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *e)
    3591             : {
    3592        1640 :         if (mvc_highwater(sql)) {
    3593           0 :                 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3594           0 :                 return -1;
    3595             :         }
    3596        1640 :         if (e->type == e_column) {
    3597          60 :                 const char *nrname = (const char*) e->l, *nename = (const char*) e->r;
    3598             :                 /* find all the column references and set the type */
    3599          60 :                 e->tpe = *type;
    3600          60 :                 assert(e->nid);
    3601          60 :                 return rel_find_parameter(sql, type, rel, e->nid, nrname, nename);
    3602        1580 :         } else if (e->type == e_atom && e->f) {
    3603          25 :                 list *atoms = e->f;
    3604          25 :                 if (!list_empty(atoms))
    3605          61 :                         for (node *n = atoms->h; n; n = n->next)
    3606          36 :                                 if (set_exp_type(sql, type, rel, n->data) < 0) /* set recursively */
    3607             :                                         return -1;
    3608          25 :                 e->tpe = *type;
    3609          25 :                 return 1; /* on a list of atoms, everything should be found */
    3610        1555 :         } else if (e->type == e_atom && !e->l && !e->r && !e->f) {
    3611        1549 :                 e->tpe = *type;
    3612        1549 :                 return set_type_param(sql, type, e->flag) == 0 ? 1 : 0;
    3613           6 :         } else if (exp_is_rel(e)) { /* for relation expressions, restart cycle */
    3614           6 :                 rel = (sql_rel*) e->l;
    3615             :                 /* limiting to these cases */
    3616           6 :                 if (!is_project(rel->op) || list_length(rel->exps) != 1)
    3617           0 :                         return 0;
    3618           6 :                 sql_exp *re = rel->exps->h->data;
    3619             : 
    3620           6 :                 e->tpe = *type;
    3621           6 :                 return set_exp_type(sql, type, rel, re); /* set recursively */
    3622             :         }
    3623             :         return 0;
    3624             : }
    3625             : 
    3626             : int
    3627        1542 : rel_set_type_param(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *exp, int upcast)
    3628             : {
    3629        1542 :         if (!type || !exp || (exp->type != e_atom && exp->type != e_column && !exp_is_rel(exp)))
    3630           0 :                 return -1;
    3631             : 
    3632             :         /* use largest numeric types */
    3633        1542 :         if (upcast && type->type->eclass == EC_NUM)
    3634             : #ifdef HAVE_HGE
    3635           9 :                 type = sql_bind_localtype("hge");
    3636             : #else
    3637             :                 type = sql_bind_localtype("lng");
    3638             : #endif
    3639           6 :         else if (upcast && type->type->eclass == EC_FLT)
    3640           1 :                 type = sql_bind_localtype("dbl");
    3641             : 
    3642             :         /* TODO we could use the sql_query* struct to set parameters used as freevars,
    3643             :            but it requires to change a lot of interfaces */
    3644             :         /* if (is_freevar(exp))
    3645             :                 rel = query_fetch_outer(query, is_freevar(exp)-1); */
    3646        1542 :         return set_exp_type(sql, type, rel, exp);
    3647             : }
    3648             : 
    3649             : /* try to do an in-place conversion
    3650             :  *
    3651             :  * in-place conversion is only possible if the exp is a variable.
    3652             :  * This is only done to be able to map more cached queries onto the same
    3653             :  * interface.
    3654             :  */
    3655             : sql_exp *
    3656     4873881 : exp_convert_inplace(mvc *sql, sql_subtype *t, sql_exp *exp)
    3657             : {
    3658     4873881 :         atom *a, *na;
    3659             : 
    3660             :         /* exclude named variables and variable lists */
    3661     4873881 :         if (exp->type != e_atom || exp->r /* named */ || exp->f /* list */ || !exp->l /* not direct atom */)
    3662             :                 return NULL;
    3663             : 
    3664     2724779 :         a = exp->l;
    3665     2724779 :         if (!a->isnull && t->scale && t->type->eclass != EC_FLT)
    3666             :                 return NULL;
    3667             : 
    3668     2719505 :         if ((na = atom_cast(sql->sa, a, t))) {
    3669     2716669 :                 exp->l = na;
    3670     2716669 :                 return exp;
    3671             :         }
    3672             :         return NULL;
    3673             : }
    3674             : 
    3675             : sql_exp *
    3676           0 : exp_numeric_supertype(mvc *sql, sql_exp *e )
    3677             : {
    3678           0 :         sql_subtype *tp = exp_subtype(e);
    3679             : 
    3680           0 :         if (tp->type->eclass == EC_DEC) {
    3681           0 :                 sql_subtype *dtp = sql_bind_localtype("dbl");
    3682             : 
    3683           0 :                 return exp_check_type(sql, dtp, NULL, e, type_cast);
    3684             :         }
    3685           0 :         if (tp->type->eclass == EC_NUM) {
    3686             : #ifdef HAVE_HGE
    3687           0 :                 sql_subtype *ltp = sql_bind_localtype("hge");
    3688             : #else
    3689             :                 sql_subtype *ltp = sql_bind_localtype("lng");
    3690             : #endif
    3691             : 
    3692           0 :                 return exp_check_type(sql, ltp, NULL, e, type_cast);
    3693             :         }
    3694             :         return e;
    3695             : }
    3696             : 
    3697             : sql_exp *
    3698     4873843 : exp_check_type(mvc *sql, sql_subtype *t, sql_rel *rel, sql_exp *exp, check_type tpe)
    3699             : {
    3700     4873843 :         int c, err = 0;
    3701     4873843 :         sql_exp* nexp = NULL;
    3702     4873843 :         sql_subtype *fromtype = exp_subtype(exp);
    3703             : 
    3704     4873768 :         if ((!fromtype || !fromtype->type) && rel_set_type_param(sql, t, rel, exp, 0) == 0)
    3705             :                 return exp;
    3706             : 
    3707             :         /* first try cheap internal (in-place) conversions ! */
    3708     4873767 :         if ((nexp = exp_convert_inplace(sql, t, exp)) != NULL)
    3709             :                 return nexp;
    3710             : 
    3711     2157225 :         if (fromtype && subtype_cmp(t, fromtype) != 0) {
    3712      254805 :                 if (EC_INTERVAL(fromtype->type->eclass) && (t->type->eclass == EC_NUM || t->type->eclass == EC_POS) && t->digits < fromtype->digits) {
    3713             :                         err = 1; /* conversion from interval to num depends on the number of digits */
    3714             :                 } else {
    3715      254805 :                         c = sql_type_convert(fromtype->type->eclass, t->type->eclass);
    3716      254805 :                         if (!c || (c == 2 && tpe == type_set) || (c == 3 && tpe != type_cast)) {
    3717             :                                 err = 1;
    3718             :                         } else {
    3719      254290 :                                 exp = exp_convert(sql, exp, fromtype, t);
    3720             :                         }
    3721             :                 }
    3722             :         }
    3723      254290 :         if (err) {
    3724         515 :                 const char *name = (exp->type == e_column && !has_label(exp)) ? exp_name(exp) : "%";
    3725         578 :                 sql_exp *res = sql_error( sql, 03, SQLSTATE(42000) "types %s(%u,%u) and %s(%u,%u) are not equal%s%s%s",
    3726         515 :                         fromtype->type->base.name,
    3727             :                         fromtype->digits,
    3728             :                         fromtype->scale,
    3729         515 :                         t->type->base.name,
    3730             :                         t->digits,
    3731             :                         t->scale,
    3732             :                         (name[0] != '%' ? " for column '" : ""),
    3733             :                         (name[0] != '%' ? name : ""),
    3734         515 :                         (name[0] != '%' ? "'" : "")
    3735             :                 );
    3736         515 :                 return res;
    3737             :         }
    3738             :         return exp;
    3739             : }
    3740             : 
    3741             : sql_exp *
    3742        6998 : exp_values_set_supertype(mvc *sql, sql_exp *values, sql_subtype *opt_super)
    3743             : {
    3744        6998 :         assert(is_values(values));
    3745        6998 :         list *vals = exp_get_values(values), *nexps;
    3746        6998 :         sql_subtype *tpe = opt_super?opt_super:exp_subtype(vals->h->data);
    3747             : 
    3748        6998 :         if (!opt_super && tpe)
    3749        6898 :                 values->tpe = *tpe;
    3750             : 
    3751       30400 :         for (node *m = vals->h; m; m = m->next) {
    3752       23402 :                 sql_exp *e = m->data;
    3753       23402 :                 sql_subtype super, *ttpe;
    3754             : 
    3755             :                 /* if the expression is a parameter set its type */
    3756       23402 :                 if (tpe && e->type == e_atom && !e->l && !e->r && !e->f && !e->tpe.type) {
    3757           4 :                         if (set_type_param(sql, tpe, e->flag) == 0)
    3758           4 :                                 e->tpe = *tpe;
    3759             :                         else
    3760           0 :                                 return NULL;
    3761             :                 }
    3762       23402 :                 ttpe = exp_subtype(e);
    3763       23402 :                 if (tpe && ttpe) {
    3764       23349 :                         supertype(&super, ttpe, tpe);
    3765       23349 :                         values->tpe = super;
    3766       23349 :                         tpe = &values->tpe;
    3767             :                 } else {
    3768             :                         tpe = ttpe;
    3769             :                 }
    3770             :         }
    3771             : 
    3772        6998 :         if (tpe) {
    3773             :                 /* if the expression is a parameter set its type */
    3774       30313 :                 for (node *m = vals->h; m; m = m->next) {
    3775       23353 :                         sql_exp *e = m->data;
    3776       23353 :                         if (e->type == e_atom && !e->l && !e->r && !e->f && !e->tpe.type) {
    3777           1 :                                 if (set_type_param(sql, tpe, e->flag) == 0)
    3778           1 :                                         e->tpe = *tpe;
    3779             :                                 else
    3780             :                                         return NULL;
    3781             :                         }
    3782             :                 }
    3783        6960 :                 values->tpe = *tpe;
    3784        6960 :                 nexps = sa_list(sql->sa);
    3785       30308 :                 for (node *m = vals->h; m; m = m->next) {
    3786       23351 :                         sql_exp *e = m->data;
    3787       23351 :                         e = exp_check_type(sql, &values->tpe, NULL, e, type_equal);
    3788       23351 :                         if (!e)
    3789             :                                 return NULL;
    3790       23348 :                         exp_label(sql->sa, e, ++sql->label);
    3791       23348 :                         append(nexps, e);
    3792             :                 }
    3793        6957 :                 values->f = nexps;
    3794             :         }
    3795             :         return values;
    3796             : }
    3797             : 
    3798             : /* return -1 on error, 0 not found, 1 found */
    3799             : static int
    3800          86 : rel_find_parameter(mvc *sql, sql_subtype *type, sql_rel *rel, int nid, const char *relname, const char *expname)
    3801             : {
    3802         138 :         int res = 0;
    3803             : 
    3804         138 :         if (mvc_highwater(sql)) {
    3805           0 :                 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3806           0 :                 return -1;
    3807             :         }
    3808         138 :         if (!rel)
    3809             :                 return 0;
    3810             : 
    3811         135 :         const char *nrname = relname, *nename = expname;
    3812         135 :         if (is_project(rel->op) && !list_empty(rel->exps)) {
    3813         111 :                 sql_exp *e = NULL;
    3814             : 
    3815         111 :                 assert(nid);
    3816         111 :                 e = exps_bind_nid(rel->exps, nid);
    3817         111 :                 if (!e)
    3818             :                         return 0; /* not found */
    3819         108 :                 if (is_mset(rel->op)) { /* TODO for set relations this needs further improvement */
    3820           0 :                         (void) sql_error(sql, 10, SQLSTATE(42000) "Cannot set parameter types under set relations at the moment");
    3821           0 :                         return -1;
    3822             :                 }
    3823             :                 /* set order by column types */
    3824         108 :                 if (is_simple_project(rel->op) && !list_empty(rel->r)) {
    3825           0 :                         sql_exp *ordere = NULL;
    3826           0 :                         ordere = exps_bind_nid(rel->r, nid);
    3827           0 :                         if (ordere && ordere->type == e_column)
    3828           0 :                                 ordere->tpe = *type;
    3829             :                 }
    3830         108 :                 if (e->type == e_column) {
    3831          52 :                         nid = e->nid;
    3832          52 :                         nrname = (const char*) e->l;
    3833          52 :                         nename = (const char*) e->r;
    3834          52 :                         e->tpe = *type;
    3835          52 :                         res = 1; /* found */
    3836          56 :                 } else if ((e->type == e_atom || exp_is_rel(e)) && (res = set_exp_type(sql, type, rel, e)) <= 0) {
    3837             :                         return res; /* don't search further */
    3838             :                 }
    3839             :                 /* group by columns can have aliases! */
    3840         108 :                 if (is_groupby(rel->op) && !list_empty(rel->r)) {
    3841           0 :                         e = exps_bind_nid(rel->r, nid);
    3842           0 :                         if (!e)
    3843             :                                 return res; /* don't search further */
    3844           0 :                         if (e->type == e_column) {
    3845           0 :                                 nid = e->nid;
    3846           0 :                                 nrname = (const char*) e->l;
    3847           0 :                                 nename = (const char*) e->r;
    3848           0 :                                 e->tpe = *type;
    3849           0 :                         } else if ((e->type == e_atom || exp_is_rel(e)) && (res = set_exp_type(sql, type, rel, e)) <= 0) {
    3850             :                                 return res; /* don't search further */
    3851             :                         }
    3852             :                 }
    3853         108 :                 if (e->type != e_column)
    3854             :                         return res; /* don't search further */
    3855             :         }
    3856             : 
    3857          76 :         switch (rel->op) {
    3858          14 :                 case op_join:
    3859             :                 case op_left:
    3860             :                 case op_right:
    3861             :                 case op_full:
    3862          14 :                         if (rel->l)
    3863          14 :                                 res = rel_find_parameter(sql, type, rel->l, nid, nrname, nename);
    3864          14 :                         if (rel->r && res <= 0) { /* try other relation if not found */
    3865          12 :                                 int err = sql->session->status, lres = res;
    3866          12 :                                 char buf[ERRSIZE];
    3867             : 
    3868          12 :                                 strcpy(buf, sql->errstr); /* keep error found and try other join relation */
    3869          12 :                                 sql->session->status = 0;
    3870          12 :                                 sql->errstr[0] = '\0';
    3871          12 :                                 res = rel_find_parameter(sql, type, rel->r, nid, nrname, nename);
    3872          12 :                                 if (res == 0) { /* parameter wasn't found, set error */
    3873           1 :                                         res = lres;
    3874           1 :                                         sql->session->status = err;
    3875           1 :                                         strcpy(sql->errstr, buf);
    3876             :                                 }
    3877             :                         }
    3878             :                         break;
    3879          52 :                 case op_semi:
    3880             :                 case op_anti:
    3881             :                 case op_groupby:
    3882             :                 case op_project:
    3883             :                 case op_select:
    3884             :                 case op_topn:
    3885             :                 case op_sample:
    3886          52 :                         if (rel->l)
    3887             :                                 res = rel_find_parameter(sql, type, rel->l, nid, nrname, nename);
    3888             :                         break;
    3889           0 :                 case op_union: /* TODO for set relations this needs further improvement */
    3890             :                 case op_inter:
    3891             :                 case op_except:
    3892             :                 case op_munion: {
    3893           0 :                         (void) sql_error(sql, 10, SQLSTATE(42000) "Cannot set parameter types under set relations at the moment");
    3894           0 :                         return -1;
    3895             :                 }
    3896             :                 default: /* For table returning functions, the type must be set when the relation is created */
    3897             :                         return 0;
    3898             :         }
    3899             :         return res;
    3900             : }
    3901             : 
    3902             : sql_exp *
    3903       18008 : list_find_exp( list *exps, sql_exp *e)
    3904             : {
    3905       18008 :         if (e->type != e_column)
    3906             :                 return NULL;
    3907       17967 :         return exps_bind_nid(exps, e->nid);
    3908             : }

Generated by: LCOV version 1.14