LCOV - code coverage report
Current view: top level - sql/server - rel_exp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1796 2053 87.5 %
Date: 2025-03-26 20:06:40 Functions: 169 184 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, 2025 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      831259 : compare_str2type(const char *compare_op)
      24             : {
      25      831259 :         comp_type type = cmp_filter;
      26             : 
      27      831259 :         if (compare_op[0] == '=') {
      28             :                 type = cmp_equal;
      29      148434 :         } else if (compare_op[0] == '<') {
      30       90977 :                 type = cmp_lt;
      31       90977 :                 if (compare_op[1] == '>')
      32             :                         type = cmp_notequal;
      33       23589 :                 else if (compare_op[1] == '=')
      34        4177 :                         type = cmp_lte;
      35       57457 :         } else if (compare_op[0] == '>') {
      36       57457 :                 type = cmp_gt;
      37       57457 :                 if (compare_op[1] == '=')
      38        3355 :                         type = cmp_gte;
      39             :         }
      40      831259 :         return type;
      41             : }
      42             : 
      43             : comp_type
      44       52760 : swap_compare( comp_type t )
      45             : {
      46       52760 :         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           0 : negate_compare( comp_type t )
      66             : {
      67           0 :         switch(t) {
      68             :         case cmp_equal:
      69             :                 return cmp_notequal;
      70           0 :         case cmp_notequal:
      71           0 :                 return cmp_equal;
      72           0 :         case cmp_lt:
      73           0 :                 return cmp_gte;
      74           0 :         case cmp_lte:
      75           0 :                 return cmp_gt;
      76           0 :         case cmp_gte:
      77           0 :                 return cmp_lt;
      78           0 :         case cmp_gt:
      79           0 :                 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        3190 : range2lcompare( int r )
      93             : {
      94        3190 :         if (r&1) {
      95             :                 return cmp_gte;
      96             :         } else {
      97        1216 :                 return cmp_gt;
      98             :         }
      99             : }
     100             : 
     101             : comp_type
     102        3247 : range2rcompare( int r )
     103             : {
     104        3247 :         if (r&2) {
     105             :                 return cmp_lte;
     106             :         } else {
     107        1253 :                 return cmp_lt;
     108             :         }
     109             : }
     110             : 
     111             : int
     112        1913 : compare2range( int l, int r )
     113             : {
     114        1913 :         if (l == cmp_gt) {
     115        1790 :                 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          99 : compare_funcs2range(const char *l_op, const char *r_op)
     130             : {
     131          99 :         assert(l_op[0] == '>' && r_op[0] == '<');
     132          99 :         if (!l_op[1] && !r_op[1])
     133             :                 return 0;
     134          97 :         if (!l_op[1] && r_op[1] == '=')
     135             :                 return 2;
     136          97 :         if (l_op[1] == '=' && !r_op[1])
     137             :                 return 1;
     138           5 :         if (l_op[1] == '=' && r_op[1] == '=')
     139             :                 return 3;
     140           0 :         assert(0);
     141             :         return 0;
     142             : }
     143             : 
     144             : static sql_exp *
     145    21689550 : exp_create(allocator *sa, int type)
     146             : {
     147    21689550 :         sql_exp *e = SA_NEW(sa, sql_exp);
     148             : 
     149    21689339 :         if (!e)
     150             :                 return NULL;
     151    21689339 :         *e = (sql_exp) {
     152    21689339 :                 .type = (expression_type) type,
     153             :         };
     154    21689339 :         return e;
     155             : }
     156             : 
     157             : sql_exp *
     158      486516 : exp_compare(allocator *sa, sql_exp *l, sql_exp *r, int cmptype)
     159             : {
     160      486516 :         sql_exp *e = exp_create(sa, e_cmp);
     161      486516 :         if (e == NULL)
     162             :                 return NULL;
     163      486516 :         e->card = MAX(l->card,r->card);
     164      486516 :         e->l = l;
     165      486516 :         e->r = r;
     166      486516 :         e->flag = cmptype;
     167      486516 :         if (!has_nil(l) && !has_nil(r))
     168      351006 :                 set_has_no_nil(e);
     169             :         return e;
     170             : }
     171             : 
     172             : sql_exp *
     173        6690 : exp_compare2(allocator *sa, sql_exp *l, sql_exp *r, sql_exp *f, int cmptype, int symmetric)
     174             : {
     175        6690 :         sql_exp *e = exp_create(sa, e_cmp);
     176        6690 :         if (e == NULL)
     177             :                 return NULL;
     178        6690 :         assert(f);
     179        6690 :         e->card = MAX(MAX(l->card,r->card),f->card);
     180        6690 :         e->l = l;
     181        6690 :         e->r = r;
     182        6690 :         e->f = f;
     183        6690 :         e->flag = cmptype;
     184        6690 :         if (symmetric)
     185          75 :                 set_symmetric(e);
     186        6690 :         if (!has_nil(l) && !has_nil(r) && !has_nil(f))
     187        1615 :                 set_has_no_nil(e);
     188             :         return e;
     189             : }
     190             : 
     191             : sql_exp *
     192        7644 : exp_filter(allocator *sa, list *l, list *r, sql_subfunc *f, int anti)
     193             : {
     194        7644 :         sql_exp *e = exp_create(sa, e_cmp);
     195             : 
     196        7644 :         if (e == NULL)
     197             :                 return NULL;
     198        7644 :         e->card = MAX(exps_card(l),exps_card(r));
     199        7644 :         if (!r) { /* split l */
     200        1526 :                 list *nl = sa_list(sa), *nr = sa_list(sa);
     201        1526 :                 node *n = l->h;
     202        1526 :                 append(nl, n->data); /* sofar only first is left */
     203        3884 :                 for(n = n->next; n; n = n->next)
     204        2358 :                         append(nr, n->data);
     205             :                 l = nl;
     206             :                 r = nr;
     207             :         }
     208        7644 :         e->l = l;
     209        7644 :         e->r = r;
     210        7644 :         e->f = f;
     211        7644 :         e->flag = cmp_filter;
     212        7644 :         if (anti)
     213        1109 :                 set_anti(e);
     214        7644 :         if (!have_nil(l) && !have_nil(r))
     215        4921 :                 set_has_no_nil(e);
     216             :         return e;
     217             : }
     218             : 
     219             : sql_exp *
     220       50888 : exp_or(allocator *sa, list *l, list *r, int anti)
     221             : {
     222       50888 :         sql_exp *e = exp_create(sa, e_cmp);
     223             : 
     224       50888 :         if (e == NULL)
     225             :                 return NULL;
     226       50888 :         e->card = MAX(exps_card(l),exps_card(r));
     227       50888 :         e->l = l;
     228       50888 :         e->r = r;
     229       50888 :         e->flag = cmp_or;
     230       50888 :         if (anti)
     231           2 :                 set_anti(e);
     232       50888 :         if (!have_nil(l) && !have_nil(r))
     233       31251 :                 set_has_no_nil(e);
     234             :         return e;
     235             : }
     236             : 
     237             : sql_exp *
     238       28997 : exp_in(allocator *sa, sql_exp *l, list *r, int cmptype)
     239             : {
     240       28997 :         sql_exp *e = exp_create(sa, e_cmp);
     241       28997 :         unsigned int exps_card = CARD_ATOM;
     242             : 
     243       28997 :         if (e == NULL)
     244             :                 return NULL;
     245             : 
     246             :         /* ignore the cardinalites of sub-relations */
     247      139042 :         for (node *n = r->h; n ; n = n->next) {
     248      110045 :                 sql_exp *next = n->data;
     249             : 
     250      110045 :                 if (!exp_is_rel(next) && exps_card < next->card)
     251      110045 :                         exps_card = next->card;
     252             :         }
     253       28997 :         e->card = MAX(l->card, exps_card);
     254       28997 :         e->l = l;
     255       28997 :         e->r = r;
     256       28997 :         assert( cmptype == cmp_in || cmptype == cmp_notin);
     257       28997 :         e->flag = cmptype;
     258       28997 :         if (!has_nil(l) && !have_nil(r))
     259       21852 :                 set_has_no_nil(e);
     260             :         return e;
     261             : }
     262             : 
     263             : sql_exp *
     264       37100 : exp_in_func(mvc *sql, sql_exp *le, sql_exp *vals, int anyequal, int is_tuple)
     265             : {
     266       37100 :         sql_subfunc *a_func = NULL;
     267       37100 :         sql_exp *e = le;
     268             : 
     269       37100 :         if (is_tuple) {
     270        4210 :                 list *l = exp_get_values(e);
     271        4210 :                 e = l->h->data;
     272             :         }
     273       43262 :         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       37100 :         e = exp_binop(sql->sa, le, vals, a_func);
     276       37100 :         if (e) {
     277       37100 :                 unsigned int exps_card = CARD_ATOM;
     278             : 
     279             :                 /* ignore the cardinalites of sub-relations */
     280       37100 :                 if (vals->type == e_atom && vals->f) {
     281      181483 :                         for (node *n = ((list*)vals->f)->h ; n ; n = n->next) {
     282      144383 :                                 sql_exp *next = n->data;
     283             : 
     284      144383 :                                 if (!exp_is_rel(next) && exps_card < next->card)
     285      144383 :                                         exps_card = next->card;
     286             :                         }
     287           0 :                 } else if (!exp_is_rel(vals))
     288           0 :                         exps_card = vals->card;
     289             : 
     290       37100 :                 e->card = MAX(le->card, exps_card);
     291       37100 :                 if (!has_nil(le) && !has_nil(vals))
     292           0 :                         set_has_no_nil(e);
     293             :         }
     294             :         return e;
     295             : }
     296             : 
     297             : sql_exp *
     298        5658 : exp_in_aggr(mvc *sql, sql_exp *le, sql_exp *vals, int anyequal, int is_tuple)
     299             : {
     300        5658 :         sql_subfunc *a_func = NULL;
     301        5658 :         sql_exp *e = le;
     302             : 
     303        5658 :         if (is_tuple) {
     304           0 :                 list *l = exp_get_values(e);
     305           0 :                 e = l->h->data;
     306             :         }
     307        5667 :         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        5658 :         e = exp_aggr2(sql->sa, le, vals, a_func, need_distinct(e), need_no_nil(e), e->card, has_nil(e));
     310        5658 :         if (e) {
     311        5658 :                 unsigned int exps_card = CARD_ATOM;
     312             : 
     313             :                 /* ignore the cardinalites of sub-relations */
     314        5658 :                 if (vals->type == e_atom && vals->f) {
     315       32016 :                         for (node *n = ((list*)vals->f)->h ; n ; n = n->next) {
     316       26358 :                                 sql_exp *next = n->data;
     317             : 
     318       26358 :                                 if (!exp_is_rel(next) && exps_card < next->card)
     319       26358 :                                         exps_card = next->card;
     320             :                         }
     321           0 :                 } else if (!exp_is_rel(vals))
     322           0 :                         exps_card = vals->card;
     323             : 
     324        5658 :                 e->card = MAX(le->card, exps_card);
     325        5658 :                 if (!has_nil(le) && !has_nil(vals))
     326           0 :                         set_has_no_nil(e);
     327             :         }
     328             :         return e;
     329             : }
     330             : 
     331             : sql_exp *
     332      132195 : exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, const char *compareop, int quantifier)
     333             : {
     334      132195 :         sql_subfunc *cmp_func = sql_bind_func(sql, "sys", compareop, exp_subtype(le), exp_subtype(le), F_FUNC, true, true);
     335      132195 :         sql_exp *e = NULL;
     336             : 
     337      132195 :         if (cmp_func == NULL)
     338             :                 return NULL;
     339             : 
     340      132195 :         e = exp_binop(sql->sa, le, re, cmp_func);
     341      132195 :         if (e) {
     342      132195 :                 e->flag = quantifier;
     343             :                 /* At ANY and ALL operators, the cardinality on the right side is ignored if it is a sub-relation */
     344      132195 :                 e->card = quantifier && exp_is_rel(re) ? le->card : MAX(le->card, re->card);
     345      132195 :                 if (!has_nil(le) && !has_nil(re))
     346       87331 :                         set_has_no_nil(e);
     347             :         }
     348             :         return e;
     349             : }
     350             : 
     351             : static sql_subtype*
     352      896306 : dup_subtype(allocator *sa, sql_subtype *st)
     353             : {
     354      896306 :         sql_subtype *res = SA_NEW(sa, sql_subtype);
     355             : 
     356      896306 :         if (res == NULL)
     357             :                 return NULL;
     358      896306 :         *res = *st;
     359      896306 :         return res;
     360             : }
     361             : 
     362             : sql_exp *
     363      448153 : exp_convert(mvc *sql, sql_exp *exp, sql_subtype *fromtype, sql_subtype *totype )
     364             : {
     365      448153 :         sql_exp *e = exp_create(sql->sa, e_convert);
     366      448153 :         if (e == NULL)
     367             :                 return NULL;
     368      448153 :         e->card = exp->card;
     369      448153 :         e->l = exp;
     370      448153 :         totype = dup_subtype(sql->sa, totype);
     371      448153 :         e->r = append(append(sa_list(sql->sa), dup_subtype(sql->sa, fromtype)),totype);
     372      448153 :         e->tpe = *totype;
     373      448153 :         e->alias = exp->alias;
     374      448153 :         if (e->alias.label)
     375      294771 :                 e->alias.label = -(sql->nid++);
     376      448153 :         if (!has_nil(exp))
     377      176711 :                 set_has_no_nil(e);
     378             :         return e;
     379             : }
     380             : 
     381             : sql_exp *
     382     1172215 : exp_op( allocator *sa, list *l, sql_subfunc *f )
     383             : {
     384     1172215 :         if (f->func->type == F_FILT)
     385        1526 :                 return exp_filter(sa, l, NULL, f, false);
     386     1170689 :         sql_exp *e = exp_create(sa, e_func);
     387     1170689 :         if (e == NULL)
     388             :                 return NULL;
     389     1170689 :         e->card = exps_card(l);
     390     1170689 :         e->l = l;
     391     1170689 :         e->f = f;
     392     1170689 :         e->semantics = f->func->semantics;
     393     1170689 :         if (!is_semantics(e) && !is_any(e) && l && !have_nil(l))
     394      279729 :                 set_has_no_nil(e);
     395             :         return e;
     396             : }
     397             : 
     398             : sql_exp *
     399       12761 : exp_rank_op( allocator *sa, list *l, list *gbe, list *obe, sql_subfunc *f )
     400             : {
     401       12761 :         sql_exp *e = exp_create(sa, e_func);
     402       12761 :         if (e == NULL)
     403             :                 return NULL;
     404       12761 :         e->card = list_empty(l)?CARD_MULTI:exps_card(l);
     405       12761 :         e->l = l;
     406       12761 :         e->r = append(append(sa_list(sa), gbe), obe);
     407       12761 :         e->f = f;
     408       12761 :         if (!f->func->s && strcmp(f->func->base.name, "count") == 0)
     409         180 :                 set_has_no_nil(e);
     410       12761 :         e->semantics = f->func->semantics;
     411       12761 :         return e;
     412             : }
     413             : 
     414             : sql_exp *
     415       65344 : exp_aggr( allocator *sa, list *l, sql_subfunc *a, int distinct, int no_nils, unsigned int card, int has_nils )
     416             : {
     417       65344 :         sql_exp *e = exp_create(sa, e_aggr);
     418       65344 :         if (e == NULL)
     419             :                 return NULL;
     420       65344 :         e->card = card;
     421       65344 :         e->l = l;
     422       65344 :         e->f = a;
     423       65344 :         e->semantics = a->func->semantics;
     424       65344 :         if (distinct)
     425         373 :                 set_distinct(e);
     426       65344 :         if (no_nils)
     427       28535 :                 set_no_nil(e);
     428       65344 :         if ((!a->func->semantics && !has_nils) || (!a->func->s && strcmp(a->func->base.name, "count") == 0))
     429       26683 :                 set_has_no_nil(e);
     430             :         return e;
     431             : }
     432             : 
     433             : sql_exp *
     434     5146100 : exp_atom(allocator *sa, atom *a)
     435             : {
     436     5146100 :         sql_exp *e = exp_create(sa, e_atom);
     437     5145980 :         if (e == NULL)
     438             :                 return NULL;
     439     5145980 :         e->card = CARD_ATOM;
     440     5145980 :         e->tpe = a->tpe;
     441     5145980 :         e->l = a;
     442     5145980 :         if (!a->isnull)
     443     4864936 :                 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      152841 : exp_atom_bool(allocator *sa, int b)
     468             : {
     469      152841 :         sql_subtype bt;
     470             : 
     471      152841 :         sql_find_subtype(&bt, "boolean", 0, 0);
     472      152841 :         if (b)
     473       99924 :                 return exp_atom(sa, atom_bool(sa, &bt, TRUE ));
     474             :         else
     475       52917 :                 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      880260 : exp_atom_int(allocator *sa, int i)
     498             : {
     499      880260 :         sql_subtype it;
     500             : 
     501      880260 :         sql_find_subtype(&it, "int", 9, 0);
     502      880261 :         return exp_atom(sa, atom_int(sa, &it, i ));
     503             : }
     504             : 
     505             : sql_exp *
     506       16498 : exp_atom_lng(allocator *sa, lng i)
     507             : {
     508       16498 :         sql_subtype it;
     509             : 
     510             : #ifdef HAVE_HGE
     511       16498 :         sql_find_subtype(&it, "bigint", 18, 0);
     512             : #else
     513             :         sql_find_subtype(&it, "bigint", 19, 0);
     514             : #endif
     515       16500 :         return exp_atom(sa, atom_int(sa, &it, i ));
     516             : }
     517             : 
     518             : sql_exp *
     519        4598 : exp_atom_oid(allocator *sa, oid i)
     520             : {
     521        4598 :         sql_subtype it;
     522             : 
     523             : #if SIZEOF_OID == SIZEOF_INT
     524             :         sql_find_subtype(&it, "oid", 31, 0);
     525             : #else
     526        4598 :         sql_find_subtype(&it, "oid", 63, 0);
     527             : #endif
     528        4598 :         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       86945 : exp_atom_str(allocator *sa, const char *s, sql_subtype *st)
     562             : {
     563      169258 :         return exp_atom(sa, atom_string(sa, st, s?sa_strdup(sa, s):NULL));
     564             : }
     565             : 
     566             : sql_exp *
     567      765664 : exp_atom_clob(allocator *sa, const char *s)
     568             : {
     569      765664 :         sql_subtype clob;
     570             : 
     571      765664 :         sql_find_subtype(&clob, "varchar", 0, 0);
     572     1529721 :         return exp_atom(sa, atom_string(sa, &clob, s?sa_strdup(sa, s):NULL));
     573             : }
     574             : 
     575             : sql_exp *
     576      275576 : exp_atom_ptr(allocator *sa, void *s)
     577             : {
     578      275576 :         sql_subtype *t = sql_bind_localtype("ptr");
     579      275576 :         return exp_atom(sa, atom_ptr(sa, t, s));
     580             : }
     581             : 
     582             : sql_exp *
     583        2159 : exp_atom_ref(allocator *sa, int i, sql_subtype *tpe)
     584             : {
     585        2159 :         sql_exp *e = exp_create(sa, e_atom);
     586        2159 :         if (e == NULL)
     587             :                 return NULL;
     588        2159 :         e->card = CARD_ATOM;
     589        2159 :         e->flag = i;
     590        2159 :         if (tpe)
     591        2159 :                 e->tpe = *tpe;
     592             :         return e;
     593             : }
     594             : 
     595             : sql_exp *
     596      112393 : exp_null(allocator *sa, sql_subtype *tpe)
     597             : {
     598      112393 :         atom *a = atom_general(sa, tpe, NULL, 0);
     599      112393 :         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         391 : exp_value(mvc *sql, sql_exp *e)
     611             : {
     612         391 :         if (!e || e->type != e_atom)
     613             :                 return NULL;
     614         386 :         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      126604 : exp_param_or_declared(allocator *sa, const char *sname, const char *name, sql_subtype *tpe, int frame)
     630             : {
     631      126604 :         sql_var_name *vname;
     632      126604 :         sql_exp *e = exp_create(sa, e_atom);
     633      126604 :         if (e == NULL)
     634             :                 return NULL;
     635             : 
     636      126604 :         e->r = sa_alloc(sa, sizeof(sql_var_name));
     637      126604 :         vname = (sql_var_name*) e->r;
     638      126604 :         vname->sname = sname;
     639      126604 :         vname->name = name;
     640      126604 :         e->card = CARD_ATOM;
     641      126604 :         e->flag = frame;
     642      126604 :         if (tpe)
     643      126604 :                 e->tpe = *tpe;
     644             :         return e;
     645             : }
     646             : 
     647             : sql_exp *
     648      217090 : exp_values(allocator *sa, list *exps)
     649             : {
     650      217090 :         sql_exp *e = exp_create(sa, e_atom);
     651      217086 :         if (e == NULL)
     652             :                 return NULL;
     653      217086 :         e->card = exps_card(exps);
     654      217088 :         e->f = exps;
     655      217088 :         return e;
     656             : }
     657             : 
     658             : list *
     659       31876 : exp_get_values(sql_exp *e)
     660             : {
     661       31876 :         if (is_atom(e->type) && e->f)
     662             :                 return e->f;
     663             :         return NULL;
     664             : }
     665             : 
     666             : list *
     667       39232 : exp_types(allocator *sa, list *exps)
     668             : {
     669       39232 :         list *l = sa_list(sa);
     670             : 
     671       39232 :         if (exps)
     672       88705 :                 for (node *n = exps->h; n; n = n->next)
     673       49473 :                         list_append(l, exp_subtype(n->data));
     674       39232 :         return l;
     675             : }
     676             : 
     677             : int
     678     1072065 : have_nil(list *exps)
     679             : {
     680     1072065 :         int has_nil = 0;
     681             : 
     682     1072065 :         if (exps)
     683     2718232 :                 for (node *n = exps->h; n && !has_nil; n = n->next) {
     684     1646167 :                         sql_exp *e = n->data;
     685     1646167 :                         has_nil |= has_nil(e);
     686             :                 }
     687     1072065 :         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     7109021 : 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     7109021 :         sql_exp *e = exp_create(sa, e_column);
     707             : 
     708     7108800 :         if (e == NULL)
     709             :                 return NULL;
     710     7108800 :         assert(cname);
     711     7108800 :         e->card = card;
     712     7108800 :         e->alias.name = cname;
     713     7108800 :         e->alias.rname = rname;
     714     7108800 :         e->r = (char*)e->alias.name;
     715     7108800 :         e->l = (char*)e->alias.rname;
     716     7108800 :         if (t)
     717     7108400 :                 e->tpe = *t;
     718     7108800 :         if (!has_nils)
     719     2008964 :                 set_has_no_nil(e);
     720     7108800 :         if (unique)
     721      948313 :                 set_unique(e);
     722     7108800 :         if (intern)
     723      601876 :                 set_intern(e);
     724             :         return e;
     725             : }
     726             : 
     727             : sql_exp *
     728     9997049 : exp_propagate(allocator *sa, sql_exp *ne, sql_exp *oe)
     729             : {
     730     9997049 :         if (has_label(oe) &&
     731      528519 :            (oe->alias.rname == ne->alias.rname || (oe->alias.rname && ne->alias.rname && strcmp(oe->alias.rname, ne->alias.rname) == 0)) &&
     732      521029 :            (oe->alias.name == ne->alias.name || (oe->alias.name && ne->alias.name && strcmp(oe->alias.name, ne->alias.name) == 0)))
     733      521029 :                 ne->alias.label = oe->alias.label;
     734     9997049 :         if (is_intern(oe))
     735      289954 :                 set_intern(ne);
     736     9997049 :         if (is_anti(oe))
     737        3218 :                 set_anti(ne);
     738     9997049 :         if (is_semantics(oe))
     739      664937 :                 set_semantics(ne);
     740     9997049 :         if (is_any(oe))
     741          44 :                 set_any(ne);
     742     9997049 :         if (is_symmetric(oe))
     743          11 :                 set_symmetric(ne);
     744     9997049 :         if (is_partitioning(oe))
     745        1522 :                 set_partitioning(ne);
     746     9997049 :         if (is_ascending(oe))
     747        8938 :                 set_ascending(ne);
     748     9997049 :         if (nulls_last(oe))
     749        1818 :                 set_nulls_last(ne);
     750     9997049 :         if (need_distinct(oe))
     751         666 :                 set_distinct(ne);
     752     9997049 :         if (zero_if_empty(oe))
     753           0 :                 set_zero_if_empty(ne);
     754     9997049 :         if (need_no_nil(oe))
     755      102704 :                 set_no_nil(ne);
     756     9997049 :         if (!has_nil(oe))
     757     5836076 :                 set_has_no_nil(ne);
     758     9997049 :         if (has_nil(oe))
     759     4160973 :                 set_has_nil(ne);
     760     9997049 :         if (is_unique(oe))
     761     1078839 :                 set_unique(ne);
     762     9997049 :         if (is_basecol(oe))
     763     8246423 :                 set_basecol(ne);
     764     9997049 :         ne->p = prop_copy(sa, oe->p);
     765     9997050 :         return ne;
     766             : }
     767             : 
     768             : static sql_exp *
     769     6664853 : exp_ref_by_label(allocator *sa, sql_exp *o)
     770             : {
     771     6664853 :         sql_exp *e = exp_create(sa, e_column);
     772             : 
     773     6664854 :         if (e == NULL)
     774             :                 return NULL;
     775     6664854 :         e->card = o->card;
     776     6664854 :         e->alias = o->alias;
     777     6664854 :         assert(e->alias.label);
     778     6664854 :         e->r = (char*)e->alias.name;
     779     6664854 :         e->l = (char*)e->alias.rname;
     780     6664854 :         e->nid = o->alias.label;
     781     6664854 :         assert(e->nid);
     782     6664854 :         sql_subtype *t = exp_subtype(o);
     783     6664854 :         if (t)
     784     6664715 :                 e->tpe = *t;
     785     6664854 :         if (!has_nil(o))
     786     4042238 :                 set_has_no_nil(e);
     787     6664854 :         if (has_nil(o))
     788     2622616 :                 set_has_nil(e);
     789     6664854 :         if (is_unique(o))
     790      839719 :                 set_unique(e);
     791     6664854 :         if (is_intern(o))
     792      254046 :                 set_intern(e);
     793     6664854 :         return exp_propagate(sa, e, o);
     794             : }
     795             : 
     796             : sql_exp *
     797     6664853 : exp_ref(mvc *sql, sql_exp *e)
     798             : {
     799     6664853 :         if (!has_label(e) && !exp_name(e))
     800        2297 :                 exp_label(sql->sa, e, ++sql->label);
     801     6664853 :         if (e->alias.label)
     802     6664853 :                 return exp_ref_by_label(sql->sa, e);
     803           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);
     804           0 :         if (ne) {
     805           0 :                 ne->nid = e->alias.label;
     806           0 :                 assert(ne->nid);
     807           0 :                 assert(!ne->nid || ne->alias.name);
     808           0 :                 ne->alias.label = ne->nid;
     809             :         }
     810             :         return ne;
     811             : }
     812             : 
     813             : sql_exp *
     814        3923 : exp_ref_save(mvc *sql, sql_exp *e)
     815             : {
     816        3923 :         if (e->type == e_column)
     817             :                 return e;
     818        2122 :         if (is_atom(e->type))
     819        1119 :                 return exp_copy(sql, e);
     820        1003 :         if (!e->alias.label || !exp_name(e))
     821           8 :                 exp_label(sql->sa, e, ++sql->label);
     822        1003 :         if (e->type != e_column) /* ref as referenced within the (same) rank expression */
     823        1003 :                 e->ref = 1;
     824        1003 :         sql_exp *ne = exp_ref(sql, e);
     825        1003 :         if (ne && is_freevar(e))
     826           0 :                 set_freevar(ne, is_freevar(e)-1);
     827             :         return ne;
     828             : }
     829             : 
     830             : sql_exp *
     831     2212983 : 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)
     832             : {
     833     2212983 :         sql_exp *e = exp_column(sql->sa, org_rname, org_cname, t, card, has_nils, unique, intern);
     834             : 
     835     2212876 :         if (e == NULL)
     836             :                 return NULL;
     837     2212876 :         assert(acname && org_cname);
     838     2212876 :         exp_setname(sql, e, (arname)?arname:org_rname, acname);
     839     2212876 :         return e;
     840             : }
     841             : 
     842             : sql_exp *
     843           2 : exp_alias_ref(mvc *sql, sql_exp *e)
     844             : {
     845           2 :         const char *tname = exp_relname(e);
     846           2 :         const char *cname = exp_name(e);
     847             : 
     848           2 :         if (!has_label(e))
     849           2 :                 exp_label(sql->sa, e, ++sql->label);
     850           2 :         sql_exp *ne = exp_ref(sql, e);
     851           2 :         if (ne == NULL)
     852             :                 return NULL;
     853           2 :         exp_setname(sql, ne, tname, cname);
     854           2 :         return ne;
     855             : }
     856             : 
     857             : sql_exp *
     858       16425 : exp_set(allocator *sa, const char *sname, const char *name, sql_exp *val, int level)
     859             : {
     860       16425 :         sql_exp *e = exp_create(sa, e_psm);
     861             : 
     862       16425 :         if (e == NULL)
     863             :                 return NULL;
     864       16425 :         e->alias.rname = sname;
     865       16425 :         e->alias.name = name;
     866       16425 :         e->l = val;
     867       16425 :         e->flag = PSM_SET + SET_PSM_LEVEL(level);
     868       16425 :         return e;
     869             : }
     870             : 
     871             : sql_exp *
     872        9667 : exp_var(allocator *sa, const char *sname, const char *name, sql_subtype *type, int level)
     873             : {
     874        9667 :         sql_exp *e = exp_create(sa, e_psm);
     875             : 
     876        9667 :         if (e == NULL)
     877             :                 return NULL;
     878        9667 :         e->alias.rname = sname;
     879        9667 :         e->alias.name = name;
     880        9667 :         e->tpe = *type;
     881        9667 :         e->flag = PSM_VAR + SET_PSM_LEVEL(level);
     882        9667 :         return e;
     883             : }
     884             : 
     885             : sql_exp *
     886         119 : exp_table(allocator *sa, const char *name, sql_table *t, int level)
     887             : {
     888         119 :         sql_exp *e = exp_create(sa, e_psm);
     889             : 
     890         119 :         if (e == NULL)
     891             :                 return NULL;
     892         119 :         e->alias.rname = NULL;
     893         119 :         e->alias.name = name;
     894         119 :         e->f = t;
     895         119 :         e->flag = PSM_VAR + SET_PSM_LEVEL(level);
     896         119 :         return e;
     897             : }
     898             : 
     899             : sql_exp *
     900       24732 : exp_return(allocator *sa, sql_exp *val, int level)
     901             : {
     902       24732 :         sql_exp *e = exp_create(sa, e_psm);
     903             : 
     904       24732 :         if (e == NULL)
     905             :                 return NULL;
     906       24732 :         e->l = val;
     907       24732 :         e->flag = PSM_RETURN + SET_PSM_LEVEL(level);
     908       24732 :         return e;
     909             : }
     910             : 
     911             : sql_exp *
     912        1035 : exp_while(allocator *sa, sql_exp *cond, list *stmts)
     913             : {
     914        1035 :         sql_exp *e = exp_create(sa, e_psm);
     915             : 
     916        1035 :         if (e == NULL)
     917             :                 return NULL;
     918        1035 :         e->l = cond;
     919        1035 :         e->r = stmts;
     920        1035 :         e->flag = PSM_WHILE;
     921        1035 :         return e;
     922             : }
     923             : 
     924             : sql_exp *
     925       11885 : exp_if(allocator *sa, sql_exp *cond, list *if_stmts, list *else_stmts)
     926             : {
     927       11885 :         sql_exp *e = exp_create(sa, e_psm);
     928             : 
     929       11885 :         if (e == NULL)
     930             :                 return NULL;
     931       11885 :         e->l = cond;
     932       11885 :         e->r = if_stmts;
     933       11885 :         e->f = else_stmts;
     934       11885 :         e->flag = PSM_IF;
     935       11885 :         return e;
     936             : }
     937             : 
     938             : sql_exp *
     939       82252 : exp_rel(mvc *sql, sql_rel *rel)
     940             : {
     941       82252 :         sql_exp *e = exp_create(sql->sa, e_psm);
     942             : 
     943       82252 :         if (e == NULL)
     944             :                 return NULL;
     945       82252 :         e->l = rel;
     946       82252 :         e->flag = PSM_REL;
     947       82252 :         e->card = is_single(rel)?CARD_ATOM:rel->card;
     948       82252 :         assert(rel);
     949       82252 :         if (is_topn(rel->op))
     950           4 :                 rel = rel->l;
     951       82252 :         if (is_project(rel->op)) {
     952       63034 :                 sql_exp *last = rel->exps->t->data;
     953       63034 :                 sql_subtype *t = exp_subtype(last);
     954       63034 :                 e->tpe = t ? *t : (sql_subtype) {0};
     955             :         }
     956             :         return e;
     957             : }
     958             : 
     959             : sql_exp *
     960         157 : exp_exception(allocator *sa, sql_exp *cond, const char *error_message)
     961             : {
     962         157 :         sql_exp *e = exp_create(sa, e_psm);
     963             : 
     964         157 :         if (e == NULL)
     965             :                 return NULL;
     966         157 :         e->l = cond;
     967         157 :         e->r = sa_strdup(sa, error_message);
     968         157 :         e->flag = PSM_EXCEPTION;
     969         157 :         return e;
     970             : }
     971             : 
     972             : /* Set a name (alias) for the expression, such that we can refer
     973             :    to this expression by this simple name.
     974             :  */
     975             : void
     976     3768891 : exp_setname(mvc *sql, sql_exp *e, const char *rname, const char *name )
     977             : {
     978     3768891 :         assert(name || rname);
     979     3768891 :         e->alias.label = -(sql->nid++);
     980             :         //e->alias.label = 0;
     981     3768891 :         if (name)
     982     3623755 :                 e->alias.name = name;
     983     3768891 :         e->alias.rname = (rname);
     984     3768891 : }
     985             : 
     986             : void
     987      145264 : noninternexp_setname(mvc *sql, sql_exp *e, const char *rname, const char *name )
     988             : {
     989      145264 :         if (!is_intern(e))
     990      145262 :                 exp_setname(sql, e, rname, name);
     991      145264 : }
     992             : 
     993             : void
     994      671344 : exp_setalias(sql_exp *e, int label, const char *rname, const char *name )
     995             : {
     996      671344 :         e->alias.label = label;
     997      671344 :         assert(e->alias.label);
     998      671344 :         e->alias.name = name;
     999      671344 :         e->alias.rname = rname;
    1000      671344 : }
    1001             : 
    1002             : void
    1003     4499509 : exp_prop_alias(allocator *sa, sql_exp *e, sql_exp *oe )
    1004             : {
    1005     4499509 :         e->ref = oe->ref;
    1006     4499509 :         if (oe->alias.name == NULL && exp_has_rel(oe)) {
    1007        8185 :                 sql_rel *r = exp_rel_get_rel(sa, oe);
    1008        8185 :                 if (!is_project(r->op))
    1009             :                         return ;
    1010        8185 :                 oe = r->exps->t->data;
    1011             :         }
    1012     4499509 :         e->alias = oe->alias;
    1013             : }
    1014             : 
    1015             : str
    1016     2125178 : number2name(str s, int len, int i)
    1017             : {
    1018     2125178 :         s[--len] = 0;
    1019     6397110 :         while(i>0) {
    1020     4271932 :                 s[--len] = '0' + (i & 7);
    1021     4271932 :                 i >>= 3;
    1022             :         }
    1023     2125178 :         s[--len] = '%';
    1024     2125178 :         return s + len;
    1025             : }
    1026             : 
    1027             : void
    1028           0 : exp_setrelname(allocator *sa, sql_exp *e, int nr)
    1029             : {
    1030           0 :         char name[16], *nme;
    1031             : 
    1032           0 :         nme = number2name(name, sizeof(name), nr);
    1033           0 :         e->alias.label = 0;
    1034           0 :         e->alias.rname = sa_strdup(sa, nme);
    1035           0 : }
    1036             : 
    1037             : char *
    1038     2063747 : make_label(allocator *sa, int nr)
    1039             : {
    1040     2063747 :         char name[16], *nme;
    1041             : 
    1042     2063747 :         nme = number2name(name, sizeof(name), nr);
    1043     2063717 :         return sa_strdup(sa, nme);
    1044             : }
    1045             : 
    1046             : sql_exp*
    1047     2053786 : exp_label(allocator *sa, sql_exp *e, int nr)
    1048             : {
    1049     2053786 :         assert(nr > 0);
    1050             :         //assert (e->alias.label == 0);
    1051     2053786 :         e->alias.label = nr;
    1052     2053786 :         e->alias.rname = e->alias.name = make_label(sa, nr);
    1053     2053839 :         return e;
    1054             : }
    1055             : 
    1056             : list*
    1057       55182 : exps_label(mvc *sql, list *exps)
    1058             : {
    1059       55182 :         if (!exps)
    1060             :                 return NULL;
    1061             : 
    1062       55182 :         int nr = sql->label+1;
    1063       55182 :         sql->label += list_length(exps);
    1064      126388 :         for (node *n = exps->h; n; n = n->next)
    1065       71206 :                 n->data = exp_label(sql->sa, n->data, nr++);
    1066       55182 :         list_hash_clear(exps);
    1067       55182 :         return exps;
    1068             : }
    1069             : 
    1070             : void
    1071       21259 : exp_swap( sql_exp *e )
    1072             : {
    1073       21259 :         sql_exp *s = e->l;
    1074             : 
    1075       21259 :         e->l = e->r;
    1076       21259 :         e->r = s;
    1077       21259 :         e->flag = swap_compare((comp_type)e->flag);
    1078       21259 :         assert(!e->f);
    1079       21259 : }
    1080             : 
    1081             : sql_subtype *
    1082    34884505 : exp_subtype( sql_exp *e )
    1083             : {
    1084    34886445 :         switch(e->type) {
    1085     8294034 :         case e_atom: {
    1086     8294034 :                 if (e->l) {
    1087     7583046 :                         atom *a = e->l;
    1088     7583046 :                         return atom_type(a);
    1089      710988 :                 } else if (e->tpe.type) { /* atom reference */
    1090      707257 :                         return &e->tpe;
    1091        3731 :                 } else if (e->f) {
    1092        1940 :                         list *vals = exp_get_values(e);
    1093        1940 :                         if (!list_empty(vals))
    1094        1940 :                                 return exp_subtype(vals->h->data);
    1095             :                 }
    1096             :                 break;
    1097             :         }
    1098    21805898 :         case e_convert:
    1099             :         case e_column:
    1100    21805898 :                 if (e->tpe.type)
    1101    21805765 :                         return &e->tpe;
    1102             :                 break;
    1103     4652050 :         case e_aggr:
    1104             :         case e_func: {
    1105     4652050 :                 if (e->f) {
    1106     4652050 :                         sql_subfunc *f = e->f;
    1107     4652050 :                         if (f->res && list_length(f->res) == 1)
    1108     4608612 :                                 return f->res->h->data;
    1109             :                 }
    1110             :                 return NULL;
    1111             :         }
    1112        7476 :         case e_cmp:
    1113        7476 :                 return sql_bind_localtype("bit");
    1114      126987 :         case e_psm:
    1115      126987 :                 if (e->tpe.type)
    1116      126972 :                         return &e->tpe;
    1117             :                 /* fall through */
    1118             :         default:
    1119             :                 return NULL;
    1120             :         }
    1121             :         return NULL;
    1122             : }
    1123             : 
    1124             : const char *
    1125    35525861 : exp_name( sql_exp *e )
    1126             : {
    1127    35540279 :         if (e->alias.name)
    1128             :                 return e->alias.name;
    1129     1609712 :         if (e->type == e_convert && e->l)
    1130             :                 return exp_name(e->l);
    1131     1605670 :         if (e->type == e_psm && e->l) { /* subquery return name of last expression */
    1132       10376 :                 sql_rel *r = e->l;
    1133       10376 :                 if (is_project(r->op))
    1134       10376 :                         return exp_name(r->exps->t->data);
    1135             :         }
    1136             :         return NULL;
    1137             : }
    1138             : 
    1139             : const char *
    1140     3961501 : exp_relname( sql_exp *e )
    1141             : {
    1142     3961513 :         if (e->alias.rname)
    1143             :                 return e->alias.rname;
    1144      479899 :         if (!e->alias.name && e->type == e_convert && e->l)
    1145             :                 return exp_relname(e->l);
    1146      479887 :         if (!e->alias.name && e->type == e_psm && e->l) { /* subquery return name of last expression */
    1147           0 :                 sql_rel *r = e->l;
    1148           0 :                 if (is_project(r->op))
    1149           0 :                         return exp_relname(r->exps->t->data);
    1150             :         }
    1151             :         return NULL;
    1152             : }
    1153             : 
    1154             : const char *
    1155       17211 : exp_find_rel_name(sql_exp *e)
    1156             : {
    1157       17211 :         if (e->alias.rname)
    1158             :                 return e->alias.rname;
    1159         549 :         switch(e->type) {
    1160             :         case e_column:
    1161             :                 break;
    1162           0 :         case e_convert:
    1163           0 :                 return exp_find_rel_name(e->l);
    1164             :         default:
    1165             :                 return NULL;
    1166             :         }
    1167             :         return NULL;
    1168             : }
    1169             : 
    1170             : unsigned int
    1171     1847908 : exp_card( sql_exp *e )
    1172             : {
    1173     1847908 :         return e->card;
    1174             : }
    1175             : 
    1176             : unsigned int
    1177     1638498 : exp_get_label( sql_exp *e )
    1178             : {
    1179     1638510 :         if (e->alias.label)
    1180     1638498 :                 return e->alias.label;
    1181          12 :         if (e->type == e_convert && e->l)
    1182             :                 return exp_get_label(e->l);
    1183           0 :         if (e->type == e_psm && e->l) { /* subquery return name of last expression */
    1184           0 :                 sql_rel *r = e->l;
    1185           0 :                 if (is_project(r->op))
    1186           0 :                         return exp_get_label(r->exps->t->data);
    1187             :         }
    1188             :         return 0;
    1189             : }
    1190             : 
    1191             : 
    1192             : const char *
    1193           0 : exp_func_name( sql_exp *e )
    1194             : {
    1195           0 :         if (e->type == e_func && e->f) {
    1196           0 :                 sql_subfunc *f = e->f;
    1197           0 :                 return f->func->base.name;
    1198             :         }
    1199           0 :         if (e->alias.name)
    1200             :                 return e->alias.name;
    1201           0 :         if (e->type == e_convert && e->l)
    1202           0 :                 return exp_name(e->l);
    1203             :         return NULL;
    1204             : }
    1205             : 
    1206             : int
    1207    49373361 : exp_cmp( sql_exp *e1, sql_exp *e2)
    1208             : {
    1209    49373361 :         return (e1 == e2)?0:-1;
    1210             : }
    1211             : 
    1212             : int
    1213      254800 : exp_equal( sql_exp *e1, sql_exp *e2)
    1214             : {
    1215      254800 :         if (e1 == e2)
    1216             :                 return 0;
    1217      254800 :         if (e1->alias.label && e1->alias.label == e2->alias.label)
    1218        8669 :                 return 0;
    1219             :         return -1;
    1220             : }
    1221             : 
    1222             : int
    1223       25782 : is_conflict( sql_exp *e1, sql_exp *e2)
    1224             : {
    1225       25782 :         if (e1->alias.label && e1->alias.label == e2->alias.label &&
    1226        2730 :                 e1->nid && e1->nid != e2->nid)
    1227           3 :                 return 0;
    1228             :         return -1;
    1229             : }
    1230             : 
    1231             : int
    1232    49373231 : exp_match( sql_exp *e1, sql_exp *e2)
    1233             : {
    1234    49373231 :         if (exp_cmp(e1, e2) == 0)
    1235             :                 return 1;
    1236    49129471 :         if (e1->type == e2->type && e1->type == e_column) {
    1237    24104023 :                 if (e1->nid && e1->nid == e2->nid)
    1238             :                         return 1;
    1239    22850012 :                 if (e1->alias.label != e2->alias.label || !e1->alias.label || !e2->alias.label)
    1240             :                         return 0;
    1241             :                 return 1;
    1242             :         }
    1243    25025448 :         if (e1->type == e2->type && e1->type == e_func) {
    1244     8836703 :                 if (is_identity(e1, NULL) && is_identity(e2, NULL)) {
    1245           0 :                         list *args1 = e1->l;
    1246           0 :                         list *args2 = e2->l;
    1247             : 
    1248           0 :                         if (list_length(args1) == list_length(args2) && list_length(args1) == 1) {
    1249           0 :                                 sql_exp *ne1 = args1->h->data;
    1250           0 :                                 sql_exp *ne2 = args2->h->data;
    1251             : 
    1252           0 :                                 if (exp_match(ne1,ne2))
    1253             :                                         return 1;
    1254             :                         }
    1255             :                 }
    1256             :         }
    1257             :         return 0;
    1258             : }
    1259             : 
    1260             : /* list already contains matching expression */
    1261             : sql_exp*
    1262      182930 : exps_find_exp( list *l, sql_exp *e)
    1263             : {
    1264      182930 :         node *n;
    1265             : 
    1266      182930 :         if (!l || !l->h)
    1267             :                 return NULL;
    1268             : 
    1269      419604 :         for(n=l->h; n; n = n->next) {
    1270      368638 :                 if (exp_match(n->data, e) || exp_refers(n->data, e))
    1271      113412 :                         return n->data;
    1272             :         }
    1273             :         return NULL;
    1274             : }
    1275             : 
    1276             : /* c refers to the parent p */
    1277             : int
    1278     3625487 : exp_refers( sql_exp *p, sql_exp *c)
    1279             : {
    1280     3625487 :         if (c->type == e_column && c->nid)
    1281      427642 :                 return c->nid == p->alias.label;
    1282             :         return 0;
    1283             : }
    1284             : 
    1285             : sql_exp*
    1286         216 : exps_refers(sql_exp *p, list *l)
    1287             : {
    1288         216 :         node *n;
    1289             : 
    1290         216 :         if (!l || !l->h)
    1291             :                 return NULL;
    1292             : 
    1293         528 :         for(n=l->h; n; n = n->next) {
    1294         316 :                 if (exp_refers(p, n->data))
    1295           4 :                         return n->data;
    1296             :         }
    1297             :         return NULL;
    1298             : }
    1299             : 
    1300             : int
    1301           0 : exp_match_col_exps( sql_exp *e, list *l)
    1302             : {
    1303           0 :         node *n;
    1304             : 
    1305           0 :         for(n=l->h; n; n = n->next) {
    1306           0 :                 sql_exp *re = n->data;
    1307           0 :                 sql_exp *re_r = re->r;
    1308             : 
    1309           0 :                 if (re->type == e_cmp && re->flag == cmp_or)
    1310           0 :                         return exp_match_col_exps(e, re->l) &&
    1311           0 :                                exp_match_col_exps(e, re->r);
    1312             : 
    1313           0 :                 if (re->type != e_cmp || !re_r || re_r->card != 1 || !exp_match_exp(e, re->l))
    1314           0 :                         return 0;
    1315             :         }
    1316             :         return 1;
    1317             : }
    1318             : 
    1319             : int
    1320        8919 : exps_match_col_exps( sql_exp *e1, sql_exp *e2)
    1321             : {
    1322        8919 :         sql_exp *e1_r = e1->r;
    1323        8919 :         sql_exp *e2_r = e2->r;
    1324             : 
    1325        8919 :         if (e1->type != e_cmp || e2->type != e_cmp)
    1326             :                 return 0;
    1327             : 
    1328        8848 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1329        3650 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1330        2837 :                 return exp_match_exp(e1->l, e2->l);
    1331             : 
    1332        6011 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1333         813 :             (e2->flag == cmp_in || e2->flag == cmp_notin))
    1334         729 :                 return exp_match_exp(e1->l, e2->l);
    1335        5282 :         if ((e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1336        2777 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1337        1934 :                 return exp_match_exp(e1->l, e2->l);
    1338             : 
    1339        3348 :         if ((e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1340         843 :             (e2->flag == cmp_in || e2->flag == cmp_notin))
    1341         843 :                 return exp_match_exp(e1->l, e2->l);
    1342             : 
    1343        2505 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1344          84 :             e2->flag == cmp_or)
    1345           0 :                 return exp_match_col_exps(e1->l, e2->l) &&
    1346           0 :                        exp_match_col_exps(e1->l, e2->r);
    1347             : 
    1348        2505 :         if (e1->flag == cmp_or &&
    1349           0 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1350           0 :                 return exp_match_col_exps(e2->l, e1->l) &&
    1351           0 :                        exp_match_col_exps(e2->l, e1->r);
    1352             : 
    1353        2505 :         if (e1->flag == cmp_or && e2->flag == cmp_or) {
    1354           0 :                 list *l = e1->l, *r = e1->r;
    1355           0 :                 sql_exp *el = l->h->data;
    1356           0 :                 sql_exp *er = r->h->data;
    1357             : 
    1358           0 :                 return list_length(l) == 1 && list_length(r) == 1 &&
    1359           0 :                        exps_match_col_exps(el, e2) &&
    1360           0 :                        exps_match_col_exps(er, e2);
    1361             :         }
    1362             :         return 0;
    1363             : }
    1364             : 
    1365             : int
    1366       45248 : exp_match_list( list *l, list *r)
    1367             : {
    1368       45248 :         node *n, *m;
    1369       45248 :         char *lu, *ru;
    1370       45248 :         int lc = 0, rc = 0, match = 0;
    1371             : 
    1372       45248 :         if (!l || !r)
    1373           0 :                 return l == r;
    1374       45248 :         if (list_length(l) != list_length(r) || list_length(l) == 0 || list_length(r) == 0)
    1375         231 :                 return 0;
    1376       45017 :         if (list_length(l) > 10 || list_length(r) > 10)
    1377           5 :                 return 0;/* to expensive */
    1378             : 
    1379       45012 :         lu = ZNEW_ARRAY(char, list_length(l));
    1380       45012 :         ru = ZNEW_ARRAY(char, list_length(r));
    1381       45012 :         if (!lu || !ru) {
    1382           0 :                 _DELETE(lu);
    1383           0 :                 _DELETE(ru);
    1384           0 :                 return 0;
    1385             :         }
    1386      133826 :         for (n = l->h, lc = 0; n; n = n->next, lc++) {
    1387       88814 :                 sql_exp *le = n->data;
    1388             : 
    1389      265864 :                 for ( m = r->h, rc = 0; m; m = m->next, rc++) {
    1390      177050 :                         sql_exp *re = m->data;
    1391             : 
    1392      177050 :                         if (!ru[rc] && exp_match_exp(le,re)) {
    1393        6707 :                                 lu[lc] = 1;
    1394        6707 :                                 ru[rc] = 1;
    1395        6707 :                                 match = 1;
    1396             :                         }
    1397             :                 }
    1398             :         }
    1399       52156 :         for (n = l->h, lc = 0; n && match; n = n->next, lc++)
    1400        7144 :                 if (!lu[lc])
    1401        1268 :                         match = 0;
    1402       50420 :         for (n = r->h, rc = 0; n && match; n = n->next, rc++)
    1403        5408 :                 if (!ru[rc])
    1404           0 :                         match = 0;
    1405       45012 :         _DELETE(lu);
    1406       45012 :         _DELETE(ru);
    1407       45012 :         return match;
    1408             : }
    1409             : 
    1410             : static int
    1411     2454687 : exps_equal( list *l, list *r)
    1412             : {
    1413     2454687 :         node *n, *m;
    1414             : 
    1415     2454687 :         if (!l || !r)
    1416       52364 :                 return l == r;
    1417     2402323 :         if (list_length(l) != list_length(r))
    1418             :                 return 0;
    1419     3533188 :         for (n = l->h, m = r->h; n && m; n = n->next, m = m->next) {
    1420     3484782 :                 sql_exp *le = n->data, *re = m->data;
    1421             : 
    1422     3484782 :                 if (!exp_match_exp(le,re))
    1423             :                         return 0;
    1424             :         }
    1425             :         return 1;
    1426             : }
    1427             : 
    1428             : int
    1429    45800178 : exp_match_exp_semantics( sql_exp *e1, sql_exp *e2, bool semantics)
    1430             : {
    1431    45800178 :         if (exp_match(e1, e2))
    1432             :                 return 1;
    1433             : 
    1434    44553842 :         if (is_ascending(e1) != is_ascending(e2) ||
    1435    44541436 :                 nulls_last(e1) != nulls_last(e2) ||
    1436    44541436 :                 zero_if_empty(e1) != zero_if_empty(e2) ||
    1437    44351080 :                 need_no_nil(e1) != need_no_nil(e2) ||
    1438    44351080 :                 is_anti(e1) != is_anti(e2) ||
    1439    44347272 :                 (semantics && is_semantics(e1) != is_semantics(e2)) ||
    1440    33033782 :                 (semantics && is_any(e1) != is_any(e2)) ||
    1441    33033712 :                 is_symmetric(e1) != is_symmetric(e2) ||
    1442    33033700 :                 is_unique(e1) != is_unique(e2) ||
    1443             :                 need_distinct(e1) != need_distinct(e2))
    1444             :                 return 0;
    1445             : 
    1446    32451507 :         if (e1->type == e2->type) {
    1447    24059200 :                 switch(e1->type) {
    1448      317199 :                 case e_cmp:
    1449      538208 :                         if (e1->flag == e2->flag && !is_complex_exp(e1->flag) &&
    1450      223361 :                             exp_match_exp(e1->l, e2->l) && exp_match_exp(e1->r, e2->r) &&
    1451         260 :                             ((!e1->f && !e2->f) || (e1->f && e2->f && exp_match_exp(e1->f, e2->f))))
    1452         253 :                                 return 1;
    1453      318355 :                         else if (e1->flag == e2->flag && e1->flag == cmp_or &&
    1454        1421 :                             exp_match_list(e1->l, e2->l) && exp_match_list(e1->r, e2->r))
    1455             :                                 return 1;
    1456      316940 :                         else if (e1->flag == e2->flag &&
    1457      226732 :                                 (e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1458        1989 :                             exp_match_exp(e1->l, e2->l) && exp_match_list(e1->r, e2->r))
    1459             :                                 return 1;
    1460      534544 :                         else if (e1->flag == e2->flag && (e1->flag == cmp_equal || e1->flag == cmp_notequal) &&
    1461      217646 :                                 exp_match_exp(e1->l, e2->r) && exp_match_exp(e1->r, e2->l))
    1462             :                                 return 1; /* = and <> operations are reflective, so exp_match_exp can be called crossed */
    1463             :                         break;
    1464      299417 :                 case e_convert:
    1465      361610 :                         if (!subtype_cmp(exp_totype(e1), exp_totype(e2)) &&
    1466       92890 :                             !subtype_cmp(exp_fromtype(e1), exp_fromtype(e2)) &&
    1467       30697 :                             exp_match_exp(e1->l, e2->l))
    1468             :                                 return 1;
    1469             :                         break;
    1470       56714 :                 case e_aggr:
    1471       93331 :                         if (!subfunc_cmp(e1->f, e2->f) && /* equal aggregation*/
    1472       36617 :                             exps_equal(e1->l, e2->l))
    1473             :                                 return 1;
    1474             :                         break;
    1475     4488348 :                 case e_func: {
    1476     4488348 :                         sql_subfunc *e1f = (sql_subfunc*) e1->f;
    1477     4488348 :                         const char *sname = e1f->func->s ? e1f->func->s->base.name : NULL;
    1478     4488348 :                         int (*comp)(list*, list*) = is_commutative(sname, e1f->func->base.name) ? exp_match_list : exps_equal;
    1479             : 
    1480     8976696 :                         if (!e1f->func->side_effect &&
    1481     6899222 :                                 !subfunc_cmp(e1f, e2->f) && /* equal functions */
    1482     2461681 :                                 comp(e1->l, e2->l) &&
    1483             :                                 /* optional order by expressions */
    1484       50807 :                                 exps_equal(e1->r, e2->r))
    1485             :                                         return 1;
    1486             :                         } break;
    1487     1086609 :                 case e_atom:
    1488     1086609 :                         if (e1->l && e2->l && !atom_cmp(e1->l, e2->l))
    1489             :                                 return 1;
    1490     1044384 :                         if (e1->f && e2->f && exps_equal(e1->f, e2->f))
    1491             :                                 return 1;
    1492     1044383 :                         if (e1->r && e2->r && e1->flag == e2->flag && !subtype_cmp(&e1->tpe, &e2->tpe)) {
    1493          54 :                                 sql_var_name *v1 = (sql_var_name*) e1->r, *v2 = (sql_var_name*) e2->r;
    1494          54 :                                 if (((!v1->sname && !v2->sname) || (v1->sname && v2->sname && strcmp(v1->sname, v2->sname) == 0)) &&
    1495          54 :                                         ((!v1->name && !v2->name) || (v1->name && v2->name && strcmp(v1->name, v2->name) == 0)))
    1496             :                                         return 1;
    1497             :                         }
    1498     1044383 :                         if (!e1->l && !e1->r && !e1->f && !e2->l && !e2->r && !e2->f && e1->flag == e2->flag && !subtype_cmp(&e1->tpe, &e2->tpe))
    1499             :                                 return 1;
    1500             :                         break;
    1501             :                 default:
    1502             :                         break;
    1503             :                 }
    1504             :         }
    1505             :         return 0;
    1506             : }
    1507             : 
    1508             : int
    1509    45520606 : exp_match_exp( sql_exp *e1, sql_exp *e2)
    1510             : {
    1511    45520606 :         return exp_match_exp_semantics( e1, e2, true);
    1512             : }
    1513             : 
    1514             : sql_exp *
    1515      164435 : exps_any_match(list *l, sql_exp *e)
    1516             : {
    1517      164435 :         if (!l)
    1518             :                 return NULL;
    1519      623896 :         for (node *n = l->h; n ; n = n->next) {
    1520      566501 :                 sql_exp *ne = (sql_exp *) n->data;
    1521      566501 :                 if (exp_match_exp(ne, e))
    1522      107040 :                         return ne;
    1523             :         }
    1524             :         return NULL;
    1525             : }
    1526             : 
    1527             : static int
    1528          24 : exps_are_joins( list *l )
    1529             : {
    1530          24 :         if (l)
    1531          52 :                 for (node *n = l->h; n; n = n->next) {
    1532          28 :                         sql_exp *e = n->data;
    1533             : 
    1534          28 :                         if (exp_is_join_exp(e))
    1535             :                                 return -1;
    1536             :                 }
    1537             :         return 0;
    1538             : }
    1539             : 
    1540             : int
    1541         201 : exp_is_join_exp(sql_exp *e)
    1542             : {
    1543         201 :         if (exp_is_join(e, NULL) == 0)
    1544             :                 return 0;
    1545          26 :         if (e->type == e_cmp && e->flag == cmp_or && e->card >= CARD_AGGR)
    1546          12 :                 if (exps_are_joins(e->l) == 0 && exps_are_joins(e->r) == 0)
    1547             :                         return 0;
    1548             :         return -1;
    1549             : }
    1550             : 
    1551             : static int
    1552      783351 : exp_is_complex_select( sql_exp *e )
    1553             : {
    1554      805060 :         switch (e->type) {
    1555         467 :         case e_atom: {
    1556         467 :                 if (e->f) {
    1557           0 :                         int r = (e->card == CARD_ATOM);
    1558           0 :                         list *l = e->f;
    1559             : 
    1560           0 :                         if (r)
    1561           0 :                                 for (node *n = l->h; n && !r; n = n->next)
    1562           0 :                                         r |= exp_is_complex_select(n->data);
    1563           0 :                         return r;
    1564             :                 }
    1565             :                 return 0;
    1566             :         }
    1567       21709 :         case e_convert:
    1568       21709 :                 return exp_is_complex_select(e->l);
    1569        2081 :         case e_func:
    1570             :         case e_aggr:
    1571             :         {
    1572        2081 :                 int r = (e->card == CARD_ATOM);
    1573        2081 :                 list *l = e->l;
    1574             : 
    1575        2081 :                 if (r && l)
    1576          47 :                         for (node *n = l->h; n && !r; n = n->next)
    1577           0 :                                 r |= exp_is_complex_select(n->data);
    1578             :                 return r;
    1579             :         }
    1580             :         case e_psm:
    1581             :                 return 1;
    1582             :         case e_column:
    1583             :         case e_cmp:
    1584             :         default:
    1585             :                 return 0;
    1586             :         }
    1587             : }
    1588             : 
    1589             : static int
    1590      391682 : complex_select(sql_exp *e)
    1591             : {
    1592      391682 :         sql_exp *l = e->l, *r = e->r;
    1593             : 
    1594      391682 :         if (exp_is_complex_select(l) || exp_is_complex_select(r))
    1595          47 :                 return 1;
    1596             :         return 0;
    1597             : }
    1598             : 
    1599             : static int
    1600         909 : distinct_rel(sql_exp *e, const char **rname)
    1601             : {
    1602        1049 :         const char *e_rname = NULL;
    1603             : 
    1604        1049 :         switch(e->type) {
    1605         637 :         case e_column:
    1606         637 :                 e_rname = exp_relname(e);
    1607             : 
    1608         637 :                 if (*rname && e_rname && strcmp(*rname, e_rname) == 0)
    1609             :                         return 1;
    1610         492 :                 if (!*rname) {
    1611         313 :                         *rname = e_rname;
    1612         313 :                         return 1;
    1613             :                 }
    1614             :                 break;
    1615         141 :         case e_aggr:
    1616             :         case e_func:
    1617         141 :                 if (e->l) {
    1618         141 :                         int m = 1;
    1619         141 :                         list *l = e->l;
    1620         141 :                         node *n;
    1621             : 
    1622         426 :                         for(n=l->h; n && m; n = n->next) {
    1623         285 :                                 sql_exp *ae = n->data;
    1624             : 
    1625         285 :                                 m = distinct_rel(ae, rname);
    1626             :                         }
    1627         141 :                         return m;
    1628             :                 }
    1629             :                 return 0;
    1630             :         case e_atom:
    1631             :                 return 1;
    1632         140 :         case e_convert:
    1633         140 :                 return distinct_rel(e->l, rname);
    1634             :         default:
    1635             :                 return 0;
    1636             :         }
    1637             :         return 0;
    1638             : }
    1639             : 
    1640             : int
    1641    20487436 : rel_has_exp(sql_rel *rel, sql_exp *e, bool subexp)
    1642             : {
    1643    20487436 :         if (rel_find_exp_and_corresponding_rel(rel, e, subexp, NULL, NULL))
    1644     4534173 :                 return 0;
    1645             :         return -1;
    1646             : }
    1647             : 
    1648             : int
    1649           0 : rel_has_exps(sql_rel *rel, list *exps, bool subexp)
    1650             : {
    1651           0 :         if (list_empty(exps))
    1652             :                 return 0;
    1653           0 :         for (node *n = exps->h; n; n = n->next)
    1654           0 :                 if (rel_has_exp(rel, n->data, subexp) >= 0)
    1655             :                         return 0;
    1656             :         return -1;
    1657             : }
    1658             : 
    1659             : int
    1660           0 : rel_has_all_exps(sql_rel *rel, list *exps)
    1661             : {
    1662           0 :         if (list_empty(exps))
    1663             :                 return 1;
    1664           0 :         for (node *n = exps->h; n; n = n->next)
    1665           0 :                 if (rel_has_exp(rel, n->data, false) < 0)
    1666             :                         return 0;
    1667             :         return 1;
    1668             : }
    1669             : 
    1670             : static int
    1671    15470739 : rel_has_exp2(sql_rel *rel, sql_exp *e)
    1672             : {
    1673    15470739 :         return rel_has_exp(rel, e, false);
    1674             : }
    1675             : 
    1676             : sql_rel *
    1677     5889480 : find_rel(list *rels, sql_exp *e)
    1678             : {
    1679     5889480 :         node *n = list_find(rels, e, (fcmp)&rel_has_exp2);
    1680     5889480 :         if (n)
    1681     3373592 :                 return n->data;
    1682             :         return NULL;
    1683             : }
    1684             : 
    1685             : sql_rel *
    1686           0 : find_one_rel(list *rels, sql_exp *e)
    1687             : {
    1688           0 :         node *n;
    1689           0 :         sql_rel *fnd = NULL;
    1690             : 
    1691           0 :         for(n = rels->h; n; n = n->next) {
    1692           0 :                 if (rel_has_exp(n->data, e, false) == 0) {
    1693           0 :                         if (fnd)
    1694             :                                 return NULL;
    1695           0 :                         fnd = n->data;
    1696             :                 }
    1697             :         }
    1698             :         return fnd;
    1699             : }
    1700             : 
    1701             : static int
    1702         318 : exp_is_rangejoin(sql_exp *e, list *rels)
    1703             : {
    1704             :         /* assume e is a e_cmp with 3 args
    1705             :          * Need to check e->r and e->f only touch one table.
    1706             :          */
    1707         318 :         const char *rname = 0;
    1708             : 
    1709         318 :         if (distinct_rel(e->r, &rname) && distinct_rel(e->f, &rname))
    1710             :                 return 0;
    1711         179 :         if (rels) {
    1712         137 :                 sql_rel *r = find_rel(rels, e->r);
    1713         137 :                 sql_rel *f = find_rel(rels, e->f);
    1714         137 :                 if (r && f && r == f)
    1715             :                         return 0;
    1716             :         }
    1717             :         return -1;
    1718             : }
    1719             : 
    1720             : int
    1721      393426 : exp_is_join(sql_exp *e, list *rels)
    1722             : {
    1723             :         /* only simple compare expressions, ie not or lists
    1724             :                 or range expressions (e->f)
    1725             :          */
    1726      393426 :         if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r && !e->f && e->card >= CARD_AGGR && !complex_select(e))
    1727             :                 return 0;
    1728        2109 :         if (e->type == e_cmp && e->flag == cmp_filter && e->l && e->r && e->card >= CARD_AGGR)
    1729             :                 return 0;
    1730             :         /* range expression */
    1731        1963 :         if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r && e->f && e->card >= CARD_AGGR && !complex_select(e))
    1732         318 :                 return exp_is_rangejoin(e, rels);
    1733             :         return -1;
    1734             : }
    1735             : 
    1736             : int
    1737      387325 : exp_is_eqjoin(sql_exp *e)
    1738             : {
    1739      387325 :         if (e->flag == cmp_equal) {
    1740      377510 :                 sql_exp *l = e->l;
    1741      377510 :                 sql_exp *r = e->r;
    1742             : 
    1743      377510 :                 if (!is_func(l->type) && !is_func(r->type))
    1744      376379 :                         return 0;
    1745             :         }
    1746             :         return -1;
    1747             : }
    1748             : 
    1749             : sql_exp *
    1750      236576 : exps_find_prop(list *exps, rel_prop kind)
    1751             : {
    1752      236576 :         if (list_empty(exps))
    1753             :                 return NULL;
    1754      471885 :         for (node *n = exps->h ; n ; n = n->next) {
    1755      236576 :                 sql_exp *e = n->data;
    1756             : 
    1757      236576 :                 if (find_prop(e->p, kind))
    1758        1267 :                         return e;
    1759             :         }
    1760             :         return NULL;
    1761             : }
    1762             : 
    1763             : /* check is one of the exps can be found in this relation */
    1764             : static sql_exp* rel_find_exp_and_corresponding_rel_(sql_rel *rel, sql_exp *e, bool subexp, sql_rel **res);
    1765             : 
    1766             : static bool
    1767      632426 : rel_find_exps_and_corresponding_rel_(sql_rel *rel, list *l, bool subexp, sql_rel **res)
    1768             : {
    1769      632426 :         int all = 1;
    1770             : 
    1771      632426 :         if (list_empty(l))
    1772             :                 return true;
    1773     1694119 :         for(node *n = l->h; n && (subexp || all); n = n->next) {
    1774     1081682 :                 sql_exp *ne = rel_find_exp_and_corresponding_rel_(rel, n->data, subexp, res);
    1775     1081682 :                 if (subexp && ne)
    1776             :                         return true;
    1777     1065905 :                 all &= (ne?1:0);
    1778             :         }
    1779      612437 :         if (all)
    1780             :                 return true;
    1781             :         return false;
    1782             : }
    1783             : 
    1784             : static sql_exp *
    1785    79744877 : rel_find_exp_and_corresponding_rel_(sql_rel *rel, sql_exp *e, bool subexp, sql_rel **res)
    1786             : {
    1787    79744877 :         sql_exp *ne = NULL;
    1788             : 
    1789    79744877 :         if (!rel)
    1790             :                 return NULL;
    1791    79744763 :         switch(e->type) {
    1792    77341132 :         case e_column:
    1793    77341132 :                 if (is_basetable(rel->op) && !rel->exps) {
    1794       26718 :                         assert(e->nid);
    1795       26718 :                         if (rel_base_has_nid(rel, e->nid))
    1796    77341084 :                                 ne = e;
    1797    97203151 :                 } else if ((!list_empty(rel->exps) && (is_project(rel->op) || is_base(rel->op))) ||
    1798    20278836 :                                         (!list_empty(rel->attr) && is_join(rel->op))) {
    1799    57815732 :                         list *l = rel->attr ? rel->attr : rel->exps;
    1800    57815732 :                         assert(e->nid);
    1801    57815732 :                         ne = exps_bind_nid(l, e->nid);
    1802             :                 }
    1803    77341084 :                 if (ne && res)
    1804       70788 :                         *res = rel;
    1805             :                 return ne;
    1806     1132028 :         case e_convert:
    1807     1132028 :                 return rel_find_exp_and_corresponding_rel_(rel, e->l, subexp, res);
    1808      632408 :         case e_aggr:
    1809             :         case e_func:
    1810      632408 :                 if (e->l)
    1811      632408 :                         if (rel_find_exps_and_corresponding_rel_(rel, e->l, subexp, res))
    1812             :                                 return e;
    1813             :                 return NULL;
    1814         429 :         case e_cmp:
    1815         429 :                 if (!subexp)
    1816             :                         return NULL;
    1817             : 
    1818          34 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    1819          16 :                         if (rel_find_exps_and_corresponding_rel_(rel, e->l, subexp, res) ||
    1820           4 :                                 rel_find_exps_and_corresponding_rel_(rel, e->r, subexp, res))
    1821          12 :                                 return e;
    1822          22 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    1823           4 :                         if (rel_find_exp_and_corresponding_rel_(rel, e->l, subexp, res) ||
    1824           2 :                                 rel_find_exps_and_corresponding_rel_(rel, e->r, subexp, res))
    1825           2 :                                 return e;
    1826          26 :                 } else if (rel_find_exp_and_corresponding_rel_(rel, e->l, subexp, res) ||
    1827           6 :                             rel_find_exp_and_corresponding_rel_(rel, e->r, subexp, res) ||
    1828           2 :                             (!e->f || rel_find_exp_and_corresponding_rel_(rel, e->f, subexp, res))) {
    1829          18 :                                 return e;
    1830             :                 }
    1831             :                 return NULL;
    1832             :         case e_psm:
    1833             :                 return NULL;
    1834      638706 :         case e_atom:
    1835      638706 :                 if (e->f) { /* values */
    1836          12 :                         list *l = e->f;
    1837          12 :                         node *n = l->h;
    1838             : 
    1839          12 :                         ne = n->data;
    1840          31 :                         while ((subexp || ne != NULL) && n != NULL) {
    1841          19 :                                 ne = rel_find_exp_and_corresponding_rel_(rel, n->data, subexp, res);
    1842          19 :                                 if (subexp && ne)
    1843             :                                         break;
    1844          19 :                                 n = n->next;
    1845             :                         }
    1846          12 :                         return ne;
    1847             :                 }
    1848             :                 return e;
    1849             :         }
    1850             :         return ne;
    1851             : }
    1852             : 
    1853             : sql_exp *
    1854    77531091 : rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, bool subexp, sql_rel **res, bool *under_join)
    1855             : {
    1856    77531091 :         sql_exp *ne = rel_find_exp_and_corresponding_rel_(rel, e, subexp, res);
    1857             : 
    1858    77531056 :         if (rel && !ne) {
    1859    55634323 :                 switch(rel->op) {
    1860    13377922 :                 case op_left:
    1861             :                 case op_right:
    1862             :                 case op_full:
    1863             :                 case op_join:
    1864             :                 case op_semi:
    1865             :                 case op_anti:
    1866    13377922 :                         ne = rel_find_exp_and_corresponding_rel(rel->l, e, subexp, res, under_join);
    1867    13377922 :                         if (!ne && is_join(rel->op))
    1868     8552698 :                                 ne = rel_find_exp_and_corresponding_rel(rel->r, e, subexp, res, under_join);
    1869             :                         break;
    1870             :                 case op_table:
    1871             :                 case op_basetable:
    1872             :                         break;
    1873      284247 :                 case op_munion:
    1874     1555717 :                         for (node* n = ((list*)rel->l)->h; n && !ne; n = n->next)
    1875     1271470 :                                 ne = rel_find_exp_and_corresponding_rel(n->data, e, subexp, res, under_join);
    1876             :                         break;
    1877    14940767 :                 default:
    1878    14940767 :                         if (!is_project(rel->op) && rel->l)
    1879     6489229 :                                 ne = rel_find_exp_and_corresponding_rel(rel->l, e, subexp, res, under_join);
    1880             :                 }
    1881             :         }
    1882    77531055 :         if (ne && under_join && is_join(rel->op))
    1883     2975735 :                 *under_join = true;
    1884    77531055 :         return ne;
    1885             : }
    1886             : 
    1887             : sql_exp *
    1888    22132304 : rel_find_exp(sql_rel *rel, sql_exp *e)
    1889             : {
    1890    22132304 :         return rel_find_exp_and_corresponding_rel(rel, e, false, NULL, NULL);
    1891             : }
    1892             : 
    1893             : bool
    1894       66091 : rel_find_nid(sql_rel *rel, int nid)
    1895             : {
    1896       66502 :         if (rel) {
    1897       66018 :                 switch(rel->op) {
    1898        5605 :                 case op_left:
    1899             :                 case op_right:
    1900             :                 case op_full:
    1901             :                 case op_join:
    1902             :                 case op_semi:
    1903             :                 case op_anti:
    1904        5605 :                         if (rel_find_nid(rel->l, nid))
    1905             :                                 return true;
    1906         495 :                         if (is_join(rel->op))
    1907         411 :                                 return rel_find_nid(rel->r, nid);
    1908             :                         break;
    1909       57044 :                 case op_table:
    1910             :                 case op_basetable:
    1911             :                 case op_munion:
    1912             :                 case op_union:
    1913             :                 case op_inter:
    1914             :                 case op_except:
    1915             :                 case op_project:
    1916             :                 case op_groupby:
    1917       57044 :                         if (rel->exps) {
    1918       57044 :                                 if (exps_bind_nid(rel->exps, nid))
    1919             :                                         return true;
    1920           0 :                         } else if (rel->op == op_basetable)
    1921           0 :                                 return rel_base_has_nid(rel, nid);
    1922             :                         break;
    1923        3369 :                 case op_select:
    1924             :                 case op_topn:
    1925             :                 case op_sample:
    1926        3369 :                         if (rel_find_nid(rel->l, nid))
    1927             :                                 return true;
    1928             :                         break;
    1929             :                 case op_ddl:
    1930             :                 case op_insert:
    1931             :                 case op_update:
    1932             :                 case op_delete:
    1933             :                 case op_truncate:
    1934             :                 case op_merge:
    1935             :                         return false;
    1936             : 
    1937             :                 }
    1938             :         }
    1939             :         return false;
    1940             : }
    1941             : 
    1942             : int
    1943     3831675 : exp_is_true(sql_exp *e)
    1944             : {
    1945     3831675 :         if (e->type == e_atom && e->l)
    1946       50967 :                 return atom_is_true(e->l);
    1947     3780708 :         if (e->type == e_cmp && e->flag == cmp_equal)
    1948     3159743 :                 return (exp_is_true(e->l) && exp_is_true(e->r) && exp_match_exp(e->l, e->r));
    1949             :         return 0;
    1950             : }
    1951             : 
    1952             : static inline bool
    1953      238655 : exp_is_cmp_exp_is_false(sql_exp* e)
    1954             : {
    1955      238655 :         sql_exp *l = e->l;
    1956      238655 :         sql_exp *r = e->r;
    1957      238655 :         assert(e->type == e_cmp && e->f == NULL && l && r);
    1958             : 
    1959             :         /* Handle 'v is x' and 'v is not x' expressions.
    1960             :         * Other cases in is-semantics are unspecified.
    1961             :         */
    1962      238655 :         if (e->flag != cmp_equal && e->flag != cmp_notequal)
    1963             :                 return false;
    1964      238655 :         if (e->flag == cmp_equal && !is_anti(e))
    1965      372858 :                 return ((exp_is_null(l) && exp_is_not_null(r)) || (exp_is_not_null(l) && exp_is_null(r)));
    1966       52226 :         if ((e->flag == cmp_notequal && !is_anti(e)) || (e->flag == cmp_equal && is_anti(e)))
    1967      104309 :                 return exp_is_null(l) && exp_is_null(r);
    1968             :         return false;
    1969             : }
    1970             : 
    1971             : static inline bool
    1972     5409361 : exp_single_bound_cmp_exp_is_false(sql_exp* e)
    1973             : {
    1974     5409361 :     assert(e->type == e_cmp);
    1975     5409361 :     sql_exp* l = e->l;
    1976     5409361 :     sql_exp* r = e->r;
    1977     5409361 :     assert(e->f == NULL);
    1978     5409361 :     assert (l && r);
    1979             : 
    1980     5409361 :     return exp_is_null(l) || exp_is_null(r);
    1981             : }
    1982             : 
    1983             : static inline bool
    1984       74537 : exp_two_sided_bound_cmp_exp_is_false(sql_exp* e)
    1985             : {
    1986       74537 :     assert(e->type == e_cmp);
    1987       74537 :     sql_exp* v = e->l;
    1988       74537 :     sql_exp* l = e->r;
    1989       74537 :     sql_exp* h = e->f;
    1990       74537 :     assert (v && l && h);
    1991             : 
    1992       74537 :     return is_anti(e) ? exp_is_null(v) || (exp_is_null(l) && exp_is_null(h)) : false;
    1993             : }
    1994             : 
    1995             : static inline bool
    1996     5736047 : exp_regular_cmp_exp_is_false(sql_exp* e)
    1997             : {
    1998     5736047 :     assert(e->type == e_cmp);
    1999             : 
    2000     5736047 :     if (is_semantics(e) && !is_any(e)) return exp_is_cmp_exp_is_false(e);
    2001     5497392 :         if (is_any(e)) return false;
    2002     5483898 :     if (e -> f)         return exp_two_sided_bound_cmp_exp_is_false(e);
    2003     5409361 :     else                return exp_single_bound_cmp_exp_is_false(e);
    2004             : }
    2005             : 
    2006             : static inline bool
    2007      442089 : exp_or_exp_is_false(sql_exp* e)
    2008             : {
    2009      442089 :     assert(e->type == e_cmp && e->flag == cmp_or);
    2010             : 
    2011      442089 :         list* left = e->l;
    2012      442089 :         list* right = e->r;
    2013             : 
    2014      442089 :         bool left_is_false = false;
    2015      929115 :         for(node* n = left->h; n; n=n->next) {
    2016      487640 :                 if (exp_is_false(n->data)) {
    2017             :                         left_is_false=true;
    2018             :                         break;
    2019             :                 }
    2020             :         }
    2021             : 
    2022      442089 :         if (!left_is_false) {
    2023             :                 return false;
    2024             :         }
    2025             : 
    2026        1176 :         for(node* n = right->h; n; n=n->next) {
    2027         643 :                 if (exp_is_false(n->data)) {
    2028             :                         return true;
    2029             :                 }
    2030             :         }
    2031             : 
    2032             :     return false;
    2033             : }
    2034             : 
    2035             : static inline bool
    2036     6516754 : exp_cmp_exp_is_false(sql_exp* e)
    2037             : {
    2038     6516754 :     assert(e->type == e_cmp);
    2039             : 
    2040     6516754 :     switch (e->flag) {
    2041     5736047 :     case cmp_gt:
    2042             :     case cmp_gte:
    2043             :     case cmp_lte:
    2044             :     case cmp_lt:
    2045             :     case cmp_equal:
    2046             :     case cmp_notequal:
    2047     5736047 :                 return exp_regular_cmp_exp_is_false(e);
    2048      442089 :     case cmp_or:
    2049      442089 :                 return exp_or_exp_is_false(e);
    2050             :     default:
    2051             :                 return false;
    2052             :         }
    2053             : }
    2054             : 
    2055             : int
    2056     6613689 : exp_is_false(sql_exp *e)
    2057             : {
    2058     6613689 :         if (e->type == e_atom && e->l)
    2059       48813 :                 return atom_is_false(e->l);
    2060     6564876 :         else if (e->type == e_cmp)
    2061     6516754 :                 return exp_cmp_exp_is_false(e);
    2062             :         return 0;
    2063             : }
    2064             : 
    2065             : int
    2066       17977 : exp_is_zero(sql_exp *e)
    2067             : {
    2068       17977 :         if (e->type == e_atom && e->l)
    2069       17709 :                 return atom_is_zero(e->l);
    2070             :         return 0;
    2071             : }
    2072             : 
    2073             : int
    2074      338149 : exp_is_not_null(sql_exp *e)
    2075             : {
    2076      338336 :         if (!has_nil(e))
    2077             :                 return true;
    2078             : 
    2079      104477 :         switch (e->type) {
    2080        3091 :         case e_atom:
    2081        3091 :                 if (e->f) /* values list */
    2082             :                         return false;
    2083        3091 :                 if (e->l)
    2084        2801 :                         return !(atom_null(e->l));
    2085             :                 return false;
    2086         187 :         case e_convert:
    2087         187 :                 return exp_is_not_null(e->l);
    2088        2519 :         case e_func:
    2089        2519 :                 if (!is_semantics(e) && e->l) {
    2090         271 :                         list *l = e->l;
    2091         318 :                         for (node *n = l->h; n; n=n->next) {
    2092         315 :                                 sql_exp *p = n->data;
    2093         315 :                                 if (!exp_is_not_null(p))
    2094             :                                         return false;
    2095             :                         }
    2096             :                         return true;
    2097             :                 }
    2098             :                 return false;
    2099             :         case e_aggr:
    2100             :         case e_column:
    2101             :         case e_cmp:
    2102             :         case e_psm:
    2103             :                 return false;
    2104             :         }
    2105             :         return false;
    2106             : }
    2107             : 
    2108             : static int
    2109        8367 : exps_have_null(list *l)
    2110             : {
    2111        8367 :         if (!l)
    2112             :                 return false;
    2113       17717 :         for(node *n = l->h; n; n = n->next)
    2114        9354 :                 if (exp_is_null(n->data))
    2115             :                         return true;
    2116             :         return false;
    2117             : }
    2118             : 
    2119             : int
    2120    12136847 : exp_is_null(sql_exp *e )
    2121             : {
    2122    12180834 :         if (!has_nil(e))
    2123             :                 return false;
    2124             : 
    2125     1661834 :         switch (e->type) {
    2126      170034 :         case e_atom:
    2127      170034 :                 if (e->f) /* values list */
    2128             :                         return 0;
    2129      169955 :                 if (e->l)
    2130       94592 :                         return (atom_null(e->l));
    2131             :                 return 0;
    2132       43987 :         case e_convert:
    2133       43987 :                 return exp_is_null(e->l);
    2134      136452 :         case e_func:
    2135      136452 :                 if (!is_semantics(e) && e->l) {
    2136             :                         /* This is a call to a function with no-nil semantics.
    2137             :                          * If one of the parameters is null the expression itself is null
    2138             :                          */
    2139      101484 :                         list* l = e->l;
    2140      303560 :                         for(node* n = l->h; n; n=n->next) {
    2141      202265 :                                 sql_exp* p = n->data;
    2142      202265 :                                 if (exp_is_null(p)) {
    2143             :                                         return true;
    2144             :                                 }
    2145             :                         }
    2146             :                 }
    2147             :                 return 0;
    2148       64378 :         case e_cmp:
    2149       64378 :                 if (!is_semantics(e)) {
    2150       61045 :                         if (e->flag == cmp_or || e->flag == cmp_filter) {
    2151       15028 :                                 return (exps_have_null(e->l) && exps_have_null(e->r));
    2152       53531 :                         } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2153        3813 :                                 return ((e->flag == cmp_in && exp_is_null(e->l)) ||
    2154        3811 :                                                 (e->flag == cmp_notin && (exp_is_null(e->l) || exps_have_null(e->r))));
    2155       49718 :                         } else if (e->f) {
    2156        7395 :                                 return exp_is_null(e->l) && exp_is_null(e->r) && exp_is_null(e->f);
    2157             :                         } else {
    2158       46022 :                                 return exp_is_null(e->l) || exp_is_null(e->r);
    2159             :                         }
    2160             :                 }
    2161             :                 return 0;
    2162             :         case e_aggr:
    2163             :         case e_column:
    2164             :         case e_psm:
    2165             :                 return 0;
    2166             :         }
    2167             :         return 0;
    2168             : }
    2169             : 
    2170             : int
    2171     1853648 : exp_is_rel( sql_exp *e )
    2172             : {
    2173     1863097 :         if (e) {
    2174     1863097 :                 switch(e->type){
    2175        9449 :                 case e_convert:
    2176        9449 :                         return exp_is_rel(e->l);
    2177      320031 :                 case e_psm:
    2178      320031 :                         return e->flag == PSM_REL && e->l;
    2179             :                 default:
    2180             :                         return 0;
    2181             :                 }
    2182             :         }
    2183             :         return 0;
    2184             : }
    2185             : 
    2186             : int
    2187        7273 : exps_one_is_rel(list *exps)
    2188             : {
    2189        7273 :         if (list_empty(exps))
    2190             :                 return 0;
    2191       21719 :         for(node *n = exps->h ; n ; n = n->next)
    2192       14455 :                 if (exp_is_rel(n->data))
    2193             :                         return 1;
    2194             :         return 0;
    2195             : }
    2196             : 
    2197             : int
    2198     9112561 : exp_is_atom( sql_exp *e )
    2199             : {
    2200     9486930 :         switch (e->type) {
    2201     2075671 :         case e_atom:
    2202     2075671 :                 if (e->f) /* values list */
    2203       13143 :                         return exps_are_atoms(e->f);
    2204             :                 return 1;
    2205      374369 :         case e_convert:
    2206      374369 :                 return exp_is_atom(e->l);
    2207     1112854 :         case e_func:
    2208             :         case e_aggr:
    2209     1112854 :                 return e->card == CARD_ATOM && exps_are_atoms(e->l);
    2210        2751 :         case e_cmp:
    2211        2751 :                 if (e->card != CARD_ATOM)
    2212             :                         return 0;
    2213         160 :                 if (e->flag == cmp_or || e->flag == cmp_filter)
    2214          85 :                         return exps_are_atoms(e->l) && exps_are_atoms(e->r);
    2215          79 :                 if (e->flag == cmp_in || e->flag == cmp_notin)
    2216           0 :                         return exp_is_atom(e->l) && exps_are_atoms(e->r);
    2217          79 :                 return exp_is_atom(e->l) && exp_is_atom(e->r) && (!e->f || exp_is_atom(e->f));
    2218             :         case e_column:
    2219             :         case e_psm:
    2220             :                 return 0;
    2221             :         }
    2222             :         return 0;
    2223             : }
    2224             : 
    2225             : static int
    2226           1 : exps_are_aggr(sql_rel *r, list *exps)
    2227             : {
    2228           1 :         int aggr = 1;
    2229           1 :         if (!list_empty(exps))
    2230           3 :                 for(node *n=exps->h; n && aggr; n=n->next)
    2231           2 :                         aggr &= exp_is_aggr(r, n->data);
    2232           1 :         return aggr;
    2233             : }
    2234             : 
    2235             : /* is expression e an aggregated result of r */
    2236             : int
    2237          11 : exp_is_aggr(sql_rel *r, sql_exp *e)
    2238             : {
    2239          11 :         sql_exp *ne = NULL;
    2240             : 
    2241          11 :         switch (e->type) {
    2242             :         case e_atom:
    2243             :                 return true;
    2244           0 :         case e_convert:
    2245           0 :                 return exp_is_aggr(r, e->l);
    2246           1 :         case e_func:
    2247           1 :                 return exps_are_aggr(r, e->l);
    2248             :         case e_aggr:
    2249             :                 return true;
    2250           0 :         case e_cmp:
    2251           0 :                 if (e->card != CARD_ATOM)
    2252             :                         return false;
    2253           0 :                 if (e->flag == cmp_or || e->flag == cmp_filter)
    2254           0 :                         return exps_are_aggr(r, e->l) && exps_are_aggr(r, e->r);
    2255           0 :                 if (e->flag == cmp_in || e->flag == cmp_notin)
    2256           0 :                         return exp_is_aggr(r, e->l) && exps_are_aggr(r, e->r);
    2257           0 :                 return exp_is_aggr(r, e->l) && exp_is_aggr(r, e->r) && (!e->f || exp_is_aggr(r, e->f));
    2258           9 :         case e_column:
    2259           9 :                 if (e->freevar)
    2260             :                         return true;
    2261           9 :                 ne = rel_find_exp(r, e);
    2262           9 :                 if (ne) /* found local */
    2263             :                         return true;
    2264             :                 else
    2265             :                         return false;
    2266             :         case e_psm:
    2267             :                 return false;
    2268             :         }
    2269             :         return false;
    2270             : }
    2271             : 
    2272             : static int
    2273          19 : exps_have_aggr(sql_rel *r, list *exps)
    2274             : {
    2275          19 :         int aggr = 0;
    2276          19 :         if (!list_empty(exps))
    2277          63 :                 for(node *n=exps->h; n && !aggr; n=n->next)
    2278          44 :                         aggr |= exp_has_aggr(r, n->data);
    2279          19 :         return aggr;
    2280             : }
    2281             : 
    2282             : int
    2283          80 : exp_has_aggr(sql_rel *r, sql_exp *e )
    2284             : {
    2285          87 :         sql_exp *ne = NULL;
    2286             : 
    2287          87 :         switch (e->type) {
    2288             :         case e_atom:
    2289             :                 return false;
    2290           7 :         case e_convert:
    2291           7 :                 return exp_has_aggr(r, e->l);
    2292          19 :         case e_func:
    2293          19 :                 return exps_have_aggr(r, e->l);
    2294             :         case e_aggr:
    2295             :                 return true;
    2296           0 :         case e_cmp:
    2297           0 :                 if (e->card != CARD_ATOM)
    2298             :                         return false;
    2299           0 :                 if (e->flag == cmp_or || e->flag == cmp_filter)
    2300           0 :                         return exps_have_aggr(r, e->l) && exps_have_aggr(r, e->r);
    2301           0 :                 if (e->flag == cmp_in || e->flag == cmp_notin)
    2302           0 :                         return exp_has_aggr(r, e->l) && exps_have_aggr(r, e->r);
    2303           0 :                 return exp_has_aggr(r, e->l) && exp_has_aggr(r, e->r) && (!e->f || exp_has_aggr(r, e->f));
    2304          34 :         case e_column:
    2305          34 :                 if (e->freevar)
    2306             :                         return false;
    2307          21 :                 ne = rel_find_exp(r->l, e);
    2308          21 :                 if (ne) /* found lower */
    2309             :                         return false;
    2310             :                 else
    2311             :                         return true;
    2312             :         case e_psm:
    2313             :                 return false;
    2314             :         }
    2315             :         return false;
    2316             : }
    2317             : 
    2318             : int
    2319    21501344 : exp_has_rel( sql_exp *e )
    2320             : {
    2321    21879478 :         if (!e)
    2322             :                 return 0;
    2323    21879478 :         switch(e->type){
    2324     2266070 :         case e_func:
    2325             :         case e_aggr:
    2326     2266070 :                 return exps_have_rel_exp(e->l);
    2327      663296 :         case e_cmp:
    2328      663296 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2329       60580 :                         return (exps_have_rel_exp(e->l) || exps_have_rel_exp(e->r));
    2330      603170 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2331       37450 :                         return (exp_has_rel(e->l) || exps_have_rel_exp(e->r));
    2332             :                 } else {
    2333     1131440 :                         return (exp_has_rel(e->l) || exp_has_rel(e->r) || (e->f && exp_has_rel(e->f)));
    2334             :                 }
    2335      378134 :         case e_convert:
    2336      378134 :                 return exp_has_rel(e->l);
    2337      128688 :         case e_psm:
    2338      128688 :                 return exp_is_rel(e);
    2339    10097589 :         case e_atom:
    2340    10097589 :                 return (e->f && exps_have_rel_exp(e->f));
    2341             :         case e_column:
    2342             :                 return 0;
    2343             :         }
    2344             :         return 0;
    2345             : }
    2346             : 
    2347             : int
    2348     2934867 : exps_have_rel_exp( list *exps)
    2349             : {
    2350     2934867 :         if (list_empty(exps))
    2351             :                 return 0;
    2352    10345113 :         for(node *n=exps->h; n; n=n->next) {
    2353     7508803 :                 sql_exp *e = n->data;
    2354             : 
    2355     7508803 :                 if (exp_has_rel(e))
    2356             :                         return 1;
    2357             :         }
    2358             :         return 0;
    2359             : }
    2360             : 
    2361             : static sql_rel *
    2362         579 : exps_rel_get_rel(allocator *sa, list *exps )
    2363             : {
    2364         579 :         sql_rel *r = NULL, *xp = NULL;
    2365             : 
    2366         579 :         if (list_empty(exps))
    2367             :                 return NULL;
    2368        1700 :         for (node *n = exps->h; n; n=n->next){
    2369        1121 :                 sql_exp *e = n->data;
    2370             : 
    2371        1121 :                 if (exp_has_rel(e)) {
    2372         585 :                         if (!(r = exp_rel_get_rel(sa, e)))
    2373             :                                 return NULL;
    2374         585 :                         if (xp) {
    2375           6 :                                 xp = rel_crossproduct(sa, xp, r, op_full);
    2376           6 :                                 set_processed(xp);
    2377             :                         } else {
    2378             :                                 xp = r;
    2379             :                         }
    2380             :                 }
    2381             :         }
    2382             :         return xp;
    2383             : }
    2384             : 
    2385             : int
    2386          62 : exp_rel_depth(sql_exp *e)
    2387             : {
    2388          62 :         if (!e)
    2389             :                 return 0;
    2390          62 :         switch(e->type){
    2391             :         case e_func:
    2392             :         case e_aggr:
    2393             :         case e_cmp:
    2394             :                 return 1;
    2395             :         case e_convert:
    2396             :                 return 0;
    2397          41 :         case e_psm:
    2398          41 :                 if (exp_is_rel(e))
    2399             :                         return 0;
    2400             :                 return 1;
    2401             :         case e_atom:
    2402             :         case e_column:
    2403             :                 return 0;
    2404             :         }
    2405             :         return 0;
    2406             : }
    2407             : 
    2408             : sql_rel *
    2409       80966 : exp_rel_get_rel(allocator *sa, sql_exp *e)
    2410             : {
    2411       82074 :         if (!e)
    2412             :                 return NULL;
    2413             : 
    2414       82074 :         switch(e->type){
    2415         551 :         case e_func:
    2416             :         case e_aggr:
    2417         551 :                 return exps_rel_get_rel(sa, e->l);
    2418          38 :         case e_cmp: {
    2419          38 :                 sql_rel *r = NULL, *xp = NULL;
    2420             : 
    2421          38 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2422          11 :                         if (exps_have_rel_exp(e->l))
    2423           7 :                                 xp = exps_rel_get_rel(sa, e->l);
    2424          11 :                         if (exps_have_rel_exp(e->r)) {
    2425           6 :                                 if (!(r = exps_rel_get_rel(sa, e->r)))
    2426             :                                         return NULL;
    2427           6 :                                 if (xp) {
    2428           2 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2429           2 :                                         set_processed(xp);
    2430             :                                 } else {
    2431             :                                         xp = r;
    2432             :                                 }
    2433             :                         }
    2434          27 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2435           0 :                         if (exp_has_rel(e->l))
    2436           0 :                                 xp = exp_rel_get_rel(sa, e->l);
    2437           0 :                         if (exps_have_rel_exp(e->r)) {
    2438           0 :                                 if (!(r = exps_rel_get_rel(sa, e->r)))
    2439             :                                         return NULL;
    2440           0 :                                 if (xp) {
    2441           0 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2442           0 :                                         set_processed(xp);
    2443             :                                 } else {
    2444             :                                         xp = r;
    2445             :                                 }
    2446             :                         }
    2447             :                 } else {
    2448          27 :                         if (exp_has_rel(e->l))
    2449          25 :                                 xp = exp_rel_get_rel(sa, e->l);
    2450          27 :                         if (exp_has_rel(e->r)) {
    2451           7 :                                 if (!(r = exp_rel_get_rel(sa, e->r)))
    2452             :                                         return NULL;
    2453           7 :                                 if (xp) {
    2454           5 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2455           5 :                                         set_processed(xp);
    2456             :                                 } else {
    2457             :                                         xp = r;
    2458             :                                 }
    2459             :                         }
    2460          27 :                         if (e->f && exp_has_rel(e->f)) {
    2461           0 :                                 if (!(r = exp_rel_get_rel(sa, e->f)))
    2462             :                                         return NULL;
    2463           0 :                                 if (xp) {
    2464           0 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2465           0 :                                         set_processed(xp);
    2466             :                                 } else {
    2467             :                                         xp = r;
    2468             :                                 }
    2469             :                         }
    2470             :                 }
    2471             :                 return xp;
    2472             :         }
    2473        1108 :         case e_convert:
    2474        1108 :                 return exp_rel_get_rel(sa, e->l);
    2475       80362 :         case e_psm:
    2476       80362 :                 if (exp_is_rel(e))
    2477       80362 :                         return e->l;
    2478             :                 return NULL;
    2479          15 :         case e_atom:
    2480          15 :                 if (e->f && exps_have_rel_exp(e->f))
    2481          15 :                         return exps_rel_get_rel(sa, e->f);
    2482             :                 return NULL;
    2483             :         case e_column:
    2484             :                 return NULL;
    2485             :         }
    2486             :         return NULL;
    2487             : }
    2488             : 
    2489             : static void exp_rel_update_set_freevar(sql_exp *e);
    2490             : 
    2491             : static void
    2492         938 : exps_rel_update_set_freevar(list *exps)
    2493             : {
    2494         938 :         if (!list_empty(exps))
    2495        3057 :                 for (node *n=exps->h; n ; n=n->next)
    2496        2119 :                         exp_rel_update_set_freevar(n->data);
    2497         938 : }
    2498             : 
    2499             : static void
    2500        2413 : exp_rel_update_set_freevar(sql_exp *e)
    2501             : {
    2502        2425 :         if (!e)
    2503             :                 return ;
    2504             : 
    2505        2425 :         switch(e->type){
    2506         936 :         case e_func:
    2507             :         case e_aggr:
    2508         936 :                 exps_rel_update_set_freevar(e->l);
    2509         936 :                 break;
    2510           8 :         case e_cmp:
    2511           8 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2512           0 :                         exps_rel_update_set_freevar(e->l);
    2513           0 :                         exps_rel_update_set_freevar(e->r);
    2514           8 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2515           0 :                         exp_rel_update_set_freevar(e->l);
    2516           0 :                         exps_rel_update_set_freevar(e->r);
    2517             :                 } else {
    2518           8 :                         exp_rel_update_set_freevar(e->l);
    2519           8 :                         exp_rel_update_set_freevar(e->r);
    2520           8 :                         if (e->f)
    2521             :                                 exp_rel_update_set_freevar(e->f);
    2522             :                 }
    2523             :                 break;
    2524           9 :         case e_convert:
    2525           9 :                 exp_rel_update_set_freevar(e->l);
    2526           9 :                 break;
    2527        1186 :         case e_atom:
    2528        1186 :                 if (e->f)
    2529           2 :                         exps_rel_update_set_freevar(e->f);
    2530             :                 break;
    2531         286 :         case e_column:
    2532         286 :                 set_freevar(e, 1);
    2533         286 :                 break;
    2534             :         case e_psm:
    2535             :                 break;
    2536             :         }
    2537             : }
    2538             : 
    2539             : static list *
    2540         579 : exp_rel_update_exps(mvc *sql, list *exps, bool up)
    2541             : {
    2542         579 :         if (list_empty(exps))
    2543             :                 return exps;
    2544        1700 :         for (node *n = exps->h; n; n=n->next){
    2545        1121 :                 sql_exp *e = n->data;
    2546             : 
    2547        1121 :                 if (exp_has_rel(e))
    2548         585 :                         n->data = exp_rel_update_exp(sql, e, up);
    2549         536 :                 else if (!exp_is_atom(e) && !up)
    2550         272 :                         exp_rel_update_set_freevar(e);
    2551             :         }
    2552             :         return exps;
    2553             : }
    2554             : 
    2555             : static sql_exp *
    2556          57 : exp_rel_update_exp_(mvc *sql, sql_exp *e, bool up)
    2557             : {
    2558          57 :         if (exp_has_rel(e))
    2559          31 :                 e = exp_rel_update_exp(sql, e, up);
    2560          26 :         else if (!exp_is_atom(e) && !up)
    2561           6 :                 exp_rel_update_set_freevar(e);
    2562          57 :         return e;
    2563             : }
    2564             : 
    2565             : sql_exp *
    2566       13969 : exp_rel_update_exp(mvc *sql, sql_exp *e, bool up)
    2567             : {
    2568       13969 :         if (!e)
    2569             :                 return NULL;
    2570             : 
    2571       13969 :         switch(e->type){
    2572         551 :         case e_func:
    2573             :         case e_aggr:
    2574         551 :                 if (exps_have_rel_exp(e->l))
    2575         551 :                         e->l = exp_rel_update_exps(sql, e->l, up);
    2576             :                 return e;
    2577          37 :         case e_cmp:
    2578          37 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2579          11 :                         if (exps_have_rel_exp(e->l))
    2580           7 :                                 e->l = exp_rel_update_exps(sql, e->l, up);
    2581          11 :                         if (exps_have_rel_exp(e->r))
    2582           6 :                                 e->r = exp_rel_update_exps(sql, e->r, up);
    2583          26 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2584           0 :                         if (exp_has_rel(e->l))
    2585           0 :                                 e->l = exp_rel_update_exp(sql, e->l, up);
    2586           0 :                         if (exps_have_rel_exp(e->r))
    2587           0 :                                 e->r = exp_rel_update_exps(sql, e->r, up);
    2588             :                 } else {
    2589             :                         //if (exp_has_rel(e->l))
    2590          26 :                                 e->l = exp_rel_update_exp_(sql, e->l, up);
    2591             :                         //if (exp_has_rel(e->r))
    2592          26 :                                 e->r = exp_rel_update_exp_(sql, e->r, up);
    2593          26 :                         if (e->f /*&& exp_has_rel(e->f)*/)
    2594           5 :                                 e->f = exp_rel_update_exp_(sql, e->f, up);
    2595             :                 }
    2596             :                 return e;
    2597        1108 :         case e_convert:
    2598        1108 :                 if (exp_has_rel(e->l))
    2599        1108 :                         e->l = exp_rel_update_exp(sql, e->l, up);
    2600             :                 return e;
    2601       12258 :         case e_psm:
    2602       12258 :                 if (exp_is_rel(e)) {
    2603       12258 :                         sql_rel *r = exp_rel_get_rel(sql->sa, e), *nr = r;
    2604       12258 :                         if (is_topn(r->op)) {
    2605           2 :                                 nr = r->l;
    2606           2 :                                 if (nr && !is_project(nr->op))
    2607           0 :                                         r->l = nr = rel_project(sql->sa, nr, rel_projections(sql, nr, NULL, 1, 0));
    2608             :                         }
    2609       12258 :                         e = nr->exps->t->data;
    2610       12258 :                         e = exp_ref(sql, e);
    2611       12258 :                         if (up)
    2612           0 :                                 set_freevar(e, 1);
    2613       12258 :                         return e;
    2614             :                 }
    2615             :                 return e;
    2616          15 :         case e_atom:
    2617          15 :                 if (e->f && exps_have_rel_exp(e->f))
    2618          15 :                         e->f = exp_rel_update_exps(sql, e->f, up);
    2619             :                 return e;
    2620             :         case e_column:
    2621             :                 return e;
    2622             :         }
    2623             :         return e;
    2624             : }
    2625             : 
    2626             : sql_exp *
    2627        4214 : exp_rel_label(mvc *sql, sql_exp *e)
    2628             : {
    2629        4214 :         if (exp_is_rel(e))
    2630        4214 :                 e->l = rel_label(sql, e->l, 1);
    2631        4214 :         return e;
    2632             : }
    2633             : 
    2634             : int
    2635      149194 : exps_are_atoms( list *exps)
    2636             : {
    2637      149194 :         int atoms = 1;
    2638      149194 :         if (!list_empty(exps))
    2639      412518 :                 for(node *n=exps->h; n && atoms; n=n->next)
    2640      294924 :                         atoms &= exp_is_atom(n->data);
    2641      149194 :         return atoms;
    2642             : }
    2643             : 
    2644             : int
    2645         151 : exps_have_func(list *exps)
    2646             : {
    2647         151 :         if (list_empty(exps))
    2648             :                 return 0;
    2649         183 :         for(node *n=exps->h; n; n=n->next) {
    2650         155 :                 sql_exp *e = n->data;
    2651             : 
    2652         155 :                 if (exp_has_func(e))
    2653             :                         return 1;
    2654             :         }
    2655             :         return 0;
    2656             : }
    2657             : 
    2658             : static int exp_has_func_or_cmp(sql_exp *e, bool cmp);
    2659             : 
    2660             : static int
    2661       68527 : exps_have_func_or_cmp(list *exps, bool cmp)
    2662             : {
    2663       68527 :         if (list_empty(exps))
    2664             :                 return 0;
    2665      194195 :         for(node *n=exps->h; n; n=n->next) {
    2666      133972 :                 sql_exp *e = n->data;
    2667             : 
    2668      133972 :                 if (exp_has_func_or_cmp(e, cmp))
    2669             :                         return 1;
    2670             :         }
    2671             :         return 0;
    2672             : }
    2673             : 
    2674             : static int
    2675     2091460 : exp_has_func_or_cmp(sql_exp *e, bool cmp)
    2676             : {
    2677     2091460 :         if (!e)
    2678             :                 return 0;
    2679     2091460 :         switch (e->type) {
    2680      305038 :         case e_atom:
    2681      305038 :                 if (e->f)
    2682           0 :                         return exps_have_func_or_cmp(e->f, true);
    2683             :                 return 0;
    2684       16737 :         case e_convert:
    2685             :                 {
    2686       16737 :                         sql_subtype *t = exp_totype(e);
    2687       16737 :                         sql_subtype *f = exp_fromtype(e);
    2688       16737 :                         if (t->type->eclass == EC_FLT && (f->type->eclass == EC_DEC || f->type->eclass == EC_NUM))
    2689         166 :                                 return exp_has_func_or_cmp(e->l, cmp);
    2690       16571 :                         if (f->type->localtype > t->type->localtype)
    2691             :                                 return true;
    2692             :                 }
    2693       14357 :                 return exp_has_func_or_cmp(e->l, cmp);
    2694             :         case e_func:
    2695             :                 return 1;
    2696       20909 :         case e_aggr:
    2697       20909 :                 if (e->l)
    2698       18070 :                         return exps_have_func_or_cmp(e->l, true);
    2699             :                 return 0;
    2700      271780 :         case e_cmp:
    2701      271780 :                 if (cmp)
    2702             :                         return 1;
    2703      263570 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2704       20131 :                         return (exps_have_func_or_cmp(e->l, true) || exps_have_func_or_cmp(e->r, true));
    2705      251664 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2706       34929 :                         return (exp_has_func_or_cmp(e->l, true) || exps_have_func_or_cmp(e->r, true));
    2707             :                 } else {
    2708      433584 :                         return (exp_has_func_or_cmp(e->l, true) || exp_has_func_or_cmp(e->r, true) ||
    2709      199404 :                                         (e->f && exp_has_func_or_cmp(e->f, true)));
    2710             :                 }
    2711             :         case e_column:
    2712             :         case e_psm:
    2713             :                 return 0;
    2714             :         }
    2715             :         return 0;
    2716             : }
    2717             : 
    2718             : int
    2719     1489096 : exp_has_func(sql_exp *e)
    2720             : {
    2721     1489096 :         return exp_has_func_or_cmp(e, false);
    2722             : }
    2723             : 
    2724             : static int
    2725      773510 : exps_have_sideeffect( list *exps)
    2726             : {
    2727      773510 :         node *n;
    2728      773510 :         int has_sideeffect = 0;
    2729             : 
    2730     2372734 :         for(n=exps->h; n && !has_sideeffect; n=n->next)
    2731     1599224 :                 has_sideeffect |= exp_has_sideeffect(n->data);
    2732      773510 :         return has_sideeffect;
    2733             : }
    2734             : 
    2735             : int
    2736     1790169 : exp_has_sideeffect( sql_exp *e )
    2737             : {
    2738     1815309 :         switch (e->type) {
    2739       25140 :         case e_convert:
    2740       25140 :                 return exp_has_sideeffect(e->l);
    2741      773526 :         case e_func:
    2742             :                 {
    2743      773526 :                         sql_subfunc *f = e->f;
    2744             : 
    2745      773526 :                         if (f->func->side_effect)
    2746             :                                 return 1;
    2747      773512 :                         if (e->l)
    2748      773510 :                                 return exps_have_sideeffect(e->l);
    2749             :                         return 0;
    2750             :                 }
    2751      503080 :         case e_atom:
    2752      503080 :                 if (e->f)
    2753           0 :                         return exps_have_sideeffect(e->f);
    2754             :                 return 0;
    2755             :         case e_aggr:
    2756             :         case e_cmp:
    2757             :         case e_column:
    2758             :         case e_psm:
    2759             :                 return 0;
    2760             :         }
    2761             :         return 0;
    2762             : }
    2763             : 
    2764             : bool
    2765     1066629 : exps_have_unsafe(list *exps, bool allow_identity, bool card)
    2766             : {
    2767     1066629 :         int unsafe = 0;
    2768             : 
    2769     1066629 :         if (list_empty(exps))
    2770             :                 return 0;
    2771     3717758 :         for (node *n = exps->h; n && !unsafe; n = n->next)
    2772     2671960 :                 unsafe |= exp_unsafe(n->data, allow_identity, card);
    2773     1045798 :         return unsafe;
    2774             : }
    2775             : 
    2776             : bool
    2777    12827312 : exp_unsafe(sql_exp *e, bool allow_identity, bool card)
    2778             : {
    2779    12827312 :         switch (e->type) {
    2780      797980 :         case e_convert:
    2781      797980 :                 if (card) {
    2782        9086 :                         sql_subtype *t = exp_totype(e);
    2783        9086 :                         sql_subtype *f = exp_fromtype(e);
    2784        9086 :                         if (t->type->eclass == EC_FLT && (f->type->eclass == EC_DEC || f->type->eclass == EC_NUM))
    2785             :                                 return false;
    2786        9001 :                         if (f->type->localtype > t->type->localtype)
    2787             :                                 return true;
    2788             :                         return false;
    2789             :                 }
    2790      788894 :                 return exp_unsafe(e->l, allow_identity, card);
    2791     1001450 :         case e_aggr:
    2792             :         case e_func: {
    2793     1001450 :                 sql_subfunc *f = e->f;
    2794             : 
    2795     1001450 :                 if (IS_ANALYTIC(f->func) || !LANG_INT_OR_MAL(f->func->lang) || f->func->side_effect || (!allow_identity && is_identity(e, NULL)))
    2796       46078 :                         return 1;
    2797      955372 :                 return exps_have_unsafe(e->l, allow_identity, card);
    2798       51913 :         } break;
    2799       51913 :         case e_cmp: {
    2800       51913 :                 if (e->flag == cmp_in || e->flag == cmp_notin) {
    2801        6593 :                         return exp_unsafe(e->l, allow_identity, card) || exps_have_unsafe(e->r, allow_identity, card);
    2802       45320 :                 } else if (e->flag == cmp_or || e->flag == cmp_filter) {
    2803       10388 :                         return exps_have_unsafe(e->l, allow_identity, card) || exps_have_unsafe(e->r, allow_identity, card);
    2804             :                 } else {
    2805       69896 :                         return exp_unsafe(e->l, allow_identity, card) || exp_unsafe(e->r, allow_identity, card) || (e->f && exp_unsafe(e->f, allow_identity, card));
    2806             :                 }
    2807     1165606 :         } break;
    2808     1165606 :         case e_atom: {
    2809     1165606 :                 if (e->f)
    2810        8331 :                         return exps_have_unsafe(e->f, allow_identity, card);
    2811             :                 return 0;
    2812             :         } break;
    2813             :         case e_column:
    2814             :         case e_psm:
    2815             :                 return 0;
    2816             :         }
    2817             :         return 0;
    2818             : }
    2819             : 
    2820             : static inline int
    2821     3598257 : exp_key( sql_exp *e )
    2822             : {
    2823     3598257 :         if (e->alias.name)
    2824     3598256 :                 return hash_key(e->alias.name);
    2825             :         return 0;
    2826             : }
    2827             : 
    2828             : sql_exp *
    2829          82 : exps_uses_nid(list *exps, int nid)
    2830             : {
    2831          82 :         if (exps) {
    2832         153 :                 for (node *en = exps->h; en; en = en->next ) {
    2833         147 :                         sql_exp *e = en->data;
    2834             : 
    2835         147 :                         if (e->nid == nid)
    2836          76 :                                 return e;
    2837             :                 }
    2838             :         }
    2839             :         return NULL;
    2840             : }
    2841             : 
    2842             : sql_exp *
    2843    71919432 : exps_bind_nid(list *exps, int nid)
    2844             : {
    2845    71919432 :         if (exps) {
    2846  5434737251 :                 for (node *en = exps->h; en; en = en->next ) {
    2847  5392595519 :                         sql_exp *e = en->data;
    2848             : 
    2849  5392595519 :                         if (e->alias.label == nid)
    2850    29405963 :                                 return e;
    2851             :                 }
    2852             :         }
    2853             :         return NULL;
    2854             : }
    2855             : 
    2856             : sql_exp *
    2857     1020036 : exps_bind_column(list *exps, const char *cname, int *ambiguous, int *multiple, int no_tname)
    2858             : {
    2859     1020036 :         sql_exp *res = NULL;
    2860             : 
    2861     1020036 :         if (exps && cname) {
    2862     1020035 :                 node *en;
    2863             : 
    2864     1020035 :                 if (exps) {
    2865     1020035 :                         if (!exps->ht && list_length(exps) > HASH_MIN_SIZE) {
    2866      111831 :                                 exps->ht = hash_new(exps->sa, list_length(exps), (fkeyvalue)&exp_key);
    2867      111831 :                                 if (exps->ht == NULL)
    2868             :                                         return NULL;
    2869      842998 :                                 for (en = exps->h; en; en = en->next ) {
    2870      731167 :                                         sql_exp *e = en->data;
    2871      731167 :                                         if (e->alias.name) {
    2872      731167 :                                                 int key = exp_key(e);
    2873             : 
    2874      731167 :                                                 if (hash_add(exps->ht, key, e) == NULL)
    2875             :                                                         return NULL;
    2876             :                                         }
    2877             :                                 }
    2878             :                         }
    2879     1020035 :                         if (exps->ht) {
    2880      436355 :                                 int key = hash_key(cname);
    2881      436355 :                                 sql_hash_e *he = exps->ht->buckets[key&(exps->ht->size-1)];
    2882             : 
    2883      843996 :                                 for (; he; he = he->chain) {
    2884      407645 :                                         sql_exp *e = he->value;
    2885             : 
    2886      407645 :                                         if (e->alias.name && strcmp(e->alias.name, cname) == 0 && (!no_tname || !e->alias.rname)) {
    2887      144201 :                                                 if (res && multiple)
    2888           4 :                                                         *multiple = 1;
    2889      144201 :                                                 if (!res)
    2890      144201 :                                                         res = e;
    2891             : 
    2892      144201 :                                                 if (res && res != e && e->alias.rname && res->alias.rname && strcmp(e->alias.rname, res->alias.rname) != 0 ) {
    2893           4 :                                                         if (ambiguous)
    2894           4 :                                                                 *ambiguous = 1;
    2895           4 :                                                         return NULL;
    2896             :                                                 }
    2897             :                                                 res = e;
    2898             :                                         }
    2899             :                                 }
    2900      436351 :                                 return res;
    2901             :                         }
    2902             :                 }
    2903     1707656 :                 for (en = exps->h; en; en = en->next ) {
    2904     1123981 :                         sql_exp *e = en->data;
    2905             : 
    2906     1123981 :                         if (e->alias.name && strcmp(e->alias.name, cname) == 0 && (!no_tname || !e->alias.rname)) {
    2907       64342 :                                 if (res && multiple)
    2908           8 :                                         *multiple = 1;
    2909       64342 :                                 if (!res)
    2910       64342 :                                         res = e;
    2911             : 
    2912       64342 :                                 if (res && res != e && e->alias.rname && res->alias.rname && strcmp(e->alias.rname, res->alias.rname) != 0 ) {
    2913           5 :                                         if (ambiguous)
    2914           5 :                                                 *ambiguous = 1;
    2915           5 :                                         return NULL;
    2916             :                                 }
    2917             :                                 res = e;
    2918             :                         }
    2919             :                 }
    2920             :         }
    2921             :         return res;
    2922             : }
    2923             : 
    2924             : sql_exp *
    2925     1767028 : exps_bind_column2(list *exps, const char *rname, const char *cname, int *multiple)
    2926             : {
    2927     1767028 :         sql_exp *res = NULL;
    2928             : 
    2929     1767028 :         if (exps) {
    2930     1766998 :                 node *en;
    2931             : 
    2932     1766998 :                 if (!exps->ht && list_length(exps) > HASH_MIN_SIZE) {
    2933      131725 :                         exps->ht = hash_new(exps->sa, list_length(exps), (fkeyvalue)&exp_key);
    2934      131725 :                         if (exps->ht == NULL)
    2935             :                                 return res;
    2936             : 
    2937     2203389 :                         for (en = exps->h; en; en = en->next ) {
    2938     2071664 :                                 sql_exp *e = en->data;
    2939     2071664 :                                 if (e->alias.name) {
    2940     2071664 :                                         int key = exp_key(e);
    2941             : 
    2942     2071664 :                                         if (hash_add(exps->ht, key, e) == NULL)
    2943             :                                                 return res;
    2944             :                                 }
    2945             :                         }
    2946             :                 }
    2947     1766997 :                 if (exps->ht) {
    2948     1047777 :                         int key = hash_key(cname);
    2949     1047777 :                         sql_hash_e *he = exps->ht->buckets[key&(exps->ht->size-1)];
    2950             : 
    2951     2922899 :                         for (; he; he = he->chain) {
    2952     1877293 :                                 sql_exp *e = he->value;
    2953             : 
    2954     1877293 :                                 if (e && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) {
    2955      767944 :                                         if (res && multiple)
    2956           0 :                                                 *multiple = 1;
    2957      767944 :                                         if (!res)
    2958             :                                                 res = e;
    2959      767944 :                                         if (res && has_label(res)) /* aliases maybe used multiple times without problems */
    2960        2171 :                                                 return res;
    2961             :                                 }
    2962             :                         }
    2963     1045606 :                         return res;
    2964             :                 }
    2965     2454496 :                 for (en = exps->h; en; en = en->next ) {
    2966     1742643 :                         sql_exp *e = en->data;
    2967             : 
    2968     1742643 :                         if (e && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) {
    2969      492983 :                                 if (res && multiple)
    2970           1 :                                         *multiple = 1;
    2971      492983 :                                 if (!res)
    2972             :                                         res = e;
    2973      492983 :                                 if (res && has_label(res)) /* aliases maybe used multiple times without problems */
    2974        7367 :                                         return res;
    2975             :                         }
    2976             :                 }
    2977             :         }
    2978             :         return res;
    2979             : }
    2980             : 
    2981             : /* find an column based on the original name, not the alias it got */
    2982             : sql_exp *
    2983           0 : exps_bind_alias( list *exps, const char *rname, const char *cname )
    2984             : {
    2985           0 :         if (exps) {
    2986           0 :                 node *en;
    2987             : 
    2988           0 :                 for (en = exps->h; en; en = en->next ) {
    2989           0 :                         sql_exp *e = en->data;
    2990             : 
    2991           0 :                         if (e && is_column(e->type) && !rname && e->r && strcmp(e->r, cname) == 0)
    2992             :                         {
    2993           0 :                                 assert(0);
    2994             :                                 return e;
    2995             :                         }
    2996           0 :                         if (e && e->type == e_column && rname && e->l && e->r && strcmp(e->r, cname) == 0 && strcmp(e->l, rname) == 0) {
    2997           0 :                                 assert(0);
    2998             :                                 return e;
    2999             :                         }
    3000             :                 }
    3001             :         }
    3002           0 :         return NULL;
    3003             : }
    3004             : 
    3005             : unsigned int
    3006     3366474 : exps_card( list *l )
    3007             : {
    3008     3366474 :         node *n;
    3009     3366474 :         unsigned int card = CARD_ATOM;
    3010             : 
    3011    14983575 :         if (l) for(n = l->h; n; n = n->next) {
    3012    11617101 :                 sql_exp *e = n->data;
    3013             : 
    3014    11617101 :                 if (e && card < e->card)
    3015    11617101 :                         card = e->card;
    3016             :         }
    3017     3366474 :         return card;
    3018             : }
    3019             : 
    3020             : void
    3021       43360 : exps_fix_card( list *exps, unsigned int card)
    3022             : {
    3023       43360 :         if (exps)
    3024     1076157 :                 for (node *n = exps->h; n; n = n->next) {
    3025     1032797 :                 sql_exp *e = n->data;
    3026             : 
    3027     1032797 :                 if (e && e->card > card)
    3028           0 :                         e->card = card;
    3029             :         }
    3030       43360 : }
    3031             : 
    3032             : void
    3033        6174 : exps_setcard( list *exps, unsigned int card)
    3034             : {
    3035        6174 :         if (exps)
    3036       31600 :                 for (node *n = exps->h; n; n = n->next) {
    3037       25426 :                         sql_exp *e = n->data;
    3038             : 
    3039       25426 :                         if (e && e->card != CARD_ATOM)
    3040       25395 :                                 e->card = card;
    3041             :                 }
    3042        6174 : }
    3043             : 
    3044             : int
    3045           0 : exps_intern(list *exps)
    3046             : {
    3047           0 :         if (exps)
    3048           0 :                 for (node *n=exps->h; n; n = n->next) {
    3049           0 :                         sql_exp *e = n->data;
    3050             : 
    3051           0 :                         if (is_intern(e))
    3052             :                                 return 1;
    3053             :                 }
    3054             :         return 0;
    3055             : }
    3056             : 
    3057             : sql_exp *
    3058        3598 : exps_find_one_multi_exp(list *exps)
    3059             : {
    3060        3598 :         sql_exp *l = NULL;
    3061        3598 :         int skip = 0;
    3062             : 
    3063             :         /* Find one and only 1 expression with card > CARD_ATOM */
    3064        3598 :         if (!list_empty(exps)) {
    3065        7209 :                 for (node *m = exps->h ; m && !skip ; m = m->next) {
    3066        3611 :                         sql_exp *e = m->data;
    3067             : 
    3068        3611 :                         if (e->card > CARD_ATOM) {
    3069        3607 :                                 skip |= l != NULL;
    3070        3607 :                                 l = e;
    3071             :                         }
    3072             :                 }
    3073             :         }
    3074        3598 :         if (skip)
    3075           9 :                 l = NULL;
    3076        3598 :         return l;
    3077             : }
    3078             : 
    3079             : const char *
    3080      131873 : compare_func( comp_type t, int anti )
    3081             : {
    3082      131873 :         switch(t) {
    3083       83805 :         case cmp_equal:
    3084       83805 :                 return anti?"<>":"=";
    3085        8195 :         case cmp_lt:
    3086        8195 :                 return anti?">":"<";
    3087        2119 :         case cmp_lte:
    3088        2119 :                 return anti?">=":"<=";
    3089        1180 :         case cmp_gte:
    3090        1180 :                 return anti?"<=":">=";
    3091       32063 :         case cmp_gt:
    3092       32063 :                 return anti?"<":">";
    3093        4511 :         case cmp_notequal:
    3094        4511 :                 return anti?"=":"<>";
    3095             :         default:
    3096             :                 return NULL;
    3097             :         }
    3098             : }
    3099             : 
    3100             : int
    3101     9802327 : is_identity( sql_exp *e, sql_rel *r)
    3102             : {
    3103     9813217 :         switch(e->type) {
    3104       38136 :         case e_column:
    3105       38136 :                 if (r && is_project(r->op) && !is_set(r->op)) {
    3106       13725 :                         sql_exp *re = NULL;
    3107       13725 :                         assert(e->nid);
    3108       13725 :                         re = exps_bind_nid(r->exps, e->nid);
    3109       13725 :                         if (re)
    3110       10890 :                                 return is_identity(re, r->l);
    3111             :                 }
    3112             :                 return 0;
    3113     9768039 :         case e_func: {
    3114     9768039 :                 sql_subfunc *f = e->f;
    3115     9768039 :                 return !f->func->s && strcmp(f->func->base.name, "identity") == 0;
    3116             :         }
    3117             :         default:
    3118             :                 return 0;
    3119             :         }
    3120             : }
    3121             : 
    3122             : list *
    3123          69 : exps_alias(mvc *sql, list *exps)
    3124             : {
    3125          69 :         list *nl = new_exp_list(sql->sa);
    3126             : 
    3127          69 :         if (exps)
    3128         330 :                 for (node *n = exps->h; n; n = n->next) {
    3129         261 :                         sql_exp *e = n->data, *ne;
    3130             : 
    3131         261 :                         assert(exp_name(e));
    3132         261 :                         ne = exp_ref(sql, e);
    3133         261 :                         append(nl, ne);
    3134             :                 }
    3135          69 :         return nl;
    3136             : }
    3137             : 
    3138             : list *
    3139      143667 : exps_copy(mvc *sql, list *exps)
    3140             : {
    3141      143667 :         list *nl;
    3142             : 
    3143      143667 :         if (mvc_highwater(sql))
    3144           0 :                 return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3145             : 
    3146      143667 :         if (!exps)
    3147             :                 return NULL;
    3148      125187 :         nl = new_exp_list(sql->sa);
    3149      574843 :         for (node *n = exps->h; n; n = n->next) {
    3150      449656 :                 sql_exp *arg = n->data;
    3151             : 
    3152      449656 :                 arg = exp_copy(sql, arg);
    3153      449656 :                 if (!arg)
    3154             :                         return NULL;
    3155      449656 :                 append(nl, arg);
    3156             :         }
    3157             :         return nl;
    3158             : }
    3159             : 
    3160             : sql_exp *
    3161     2714675 : exp_copy(mvc *sql, sql_exp * e)
    3162             : {
    3163     2714675 :         sql_exp *l, *r, *r2, *ne = NULL;
    3164             : 
    3165     2714675 :         if (mvc_highwater(sql))
    3166           0 :                 return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3167             : 
    3168     2714675 :         if (!e)
    3169             :                 return NULL;
    3170     2714675 :         switch(e->type){
    3171     2330578 :         case e_column:
    3172     2330578 :                 ne = exp_column(sql->sa, e->l, e->r, exp_subtype(e), e->card, has_nil(e), is_unique(e), is_intern(e));
    3173     2330578 :                 ne->flag = e->flag;
    3174     2330578 :                 ne->alias.label = e->alias.label;
    3175     2330578 :                 ne->nid = e->nid;
    3176     2330578 :                 break;
    3177       42574 :         case e_cmp:
    3178       42574 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    3179        2693 :                         list *l = exps_copy(sql, e->l);
    3180        2693 :                         list *r = exps_copy(sql, e->r);
    3181             : 
    3182        2693 :                         if (e->flag == cmp_filter)
    3183         698 :                                 ne = exp_filter(sql->sa, l, r, e->f, is_anti(e));
    3184             :                         else
    3185        1995 :                                 ne = exp_or(sql->sa, l, r, is_anti(e));
    3186       39881 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    3187        1436 :                         sql_exp *l = exp_copy(sql, e->l);
    3188        1436 :                         list *r = exps_copy(sql, e->r);
    3189             : 
    3190        1436 :                         ne = exp_in(sql->sa, l, r, e->flag);
    3191             :                 } else {
    3192       38445 :                         l = exp_copy(sql, e->l);
    3193       38445 :                         r = exp_copy(sql, e->r);
    3194             : 
    3195       38445 :                         if (e->f) {
    3196         691 :                                 r2 = exp_copy(sql, e->f);
    3197         691 :                                 ne = exp_compare2(sql->sa, l, r, r2, e->flag, is_symmetric(e));
    3198             :                         } else {
    3199       37754 :                                 ne = exp_compare(sql->sa, l, r, e->flag);
    3200             :                         }
    3201             :                 }
    3202             :                 break;
    3203       29315 :         case e_convert:
    3204       29315 :                 ne = exp_convert(sql, exp_copy(sql, e->l), exp_fromtype(e), exp_totype(e));
    3205       29315 :                 break;
    3206       13656 :         case e_aggr:
    3207             :         case e_func: {
    3208       13656 :                 list *l = exps_copy(sql, e->l);
    3209             : 
    3210       13656 :                 if (e->type == e_func)
    3211       11876 :                         ne = exp_op(sql->sa, l, e->f);
    3212             :                 else
    3213        1780 :                         ne = exp_aggr(sql->sa, l, e->f, need_distinct(e), need_no_nil(e), e->card, has_nil(e));
    3214       13656 :                 if (e->r) { /* copy obe and gbe lists */
    3215           1 :                         list *er = (list*) e->r;
    3216           1 :                         assert(list_length(er) <= 2);
    3217           1 :                         if (list_length(er) == 2)
    3218           0 :                                 ne->r = list_append(list_append(sa_list(sql->sa), exps_copy(sql, er->h->data)), exps_copy(sql, er->h->next->data));
    3219             :                         else
    3220           1 :                                 ne->r = list_append(sa_list(sql->sa), exps_copy(sql, er->h->data));
    3221             :                 }
    3222             :                 break;
    3223             :         }
    3224      298548 :         case e_atom:
    3225      298548 :                 if (e->l)
    3226      293618 :                         ne = exp_atom(sql->sa, e->l);
    3227        4930 :                 else if (e->r) {
    3228        3622 :                         sql_var_name *vname = (sql_var_name*) e->r;
    3229        3622 :                         ne = exp_param_or_declared(sql->sa, vname->sname, vname->name, &e->tpe, e->flag);
    3230        1308 :                 } else if (e->f)
    3231         759 :                         ne = exp_values(sql->sa, exps_copy(sql, e->f));
    3232             :                 else
    3233         549 :                         ne = exp_atom_ref(sql->sa, e->flag, &e->tpe);
    3234             :                 break;
    3235           4 :         case e_psm:
    3236           4 :                 if (e->flag & PSM_SET) {
    3237           0 :                         ne = exp_set(sql->sa, e->alias.rname, e->alias.name, exp_copy(sql, e->l), GET_PSM_LEVEL(e->flag));
    3238           4 :                 } else if (e->flag & PSM_VAR) {
    3239           0 :                         if (e->f)
    3240           0 :                                 ne = exp_table(sql->sa, e->alias.name, e->f, GET_PSM_LEVEL(e->flag));
    3241             :                         else
    3242           0 :                                 ne = exp_var(sql->sa, e->alias.rname, e->alias.name, &e->tpe, GET_PSM_LEVEL(e->flag));
    3243           4 :                 } else if (e->flag & PSM_RETURN) {
    3244           0 :                         ne = exp_return(sql->sa, exp_copy(sql, e->l), GET_PSM_LEVEL(e->flag));
    3245           4 :                 } else if (e->flag & PSM_WHILE) {
    3246           0 :                         ne = exp_while(sql->sa, exp_copy(sql, e->l), exps_copy(sql, e->r));
    3247           4 :                 } else if (e->flag & PSM_IF) {
    3248           0 :                         ne = exp_if(sql->sa, exp_copy(sql, e->l), exps_copy(sql, e->r), exps_copy(sql, e->f));
    3249           4 :                 } else if (e->flag & PSM_REL) {
    3250           4 :                         if (!e->alias.label)
    3251           4 :                                 exp_label(sql->sa, e, ++sql->label);
    3252           4 :                         return exp_ref(sql, e);
    3253           0 :                 } else if (e->flag & PSM_EXCEPTION) {
    3254           0 :                         ne = exp_exception(sql->sa, exp_copy(sql, e->l), (const char *) e->r);
    3255             :                 }
    3256             :                 break;
    3257             :         }
    3258     2714671 :         if (!ne)
    3259           0 :                 return ne;
    3260     2714671 :         if (e->alias.name)
    3261     2490195 :                 exp_prop_alias(sql->sa, ne, e);
    3262     2714671 :         ne = exp_propagate(sql->sa, ne, e);
    3263     2714671 :         if (is_freevar(e))
    3264        8369 :                 set_freevar(ne, is_freevar(e)-1);
    3265             :         return ne;
    3266             : }
    3267             : 
    3268             : /* scaling for the division operator */
    3269             : static sql_exp *
    3270        2625 : exp_scale_algebra(mvc *sql, sql_subfunc *f, sql_rel *rel, sql_exp *l, sql_exp *r)
    3271             : {
    3272        2625 :         sql_subtype *lt = exp_subtype(l);
    3273        2625 :         sql_subtype *rt = exp_subtype(r);
    3274             : 
    3275        2625 :         if (!EC_INTERVAL(lt->type->eclass) && lt->type->scale == SCALE_FIX &&
    3276        2573 :                 (lt->scale || rt->scale) && strcmp(sql_func_imp(f->func), "/") == 0) {
    3277         170 :                 sql_subtype *res = f->res->h->data;
    3278         170 :                 unsigned int scale, digits, digL, scaleL;
    3279         170 :                 sql_subtype nlt;
    3280             : 
    3281             :                 /* scale fixing may require a larger type ! */
    3282         170 :                 scaleL = (lt->scale < sql->div_min_scale) ? sql->div_min_scale : lt->scale;
    3283         170 :                 scaleL += (scaleL < rt->scale) ? rt->scale - scaleL : 0;
    3284         170 :                 scale = scaleL;
    3285         170 :                 scaleL += rt->scale;
    3286         170 :                 digL = lt->digits + (scaleL - lt->scale);
    3287         170 :                 digits = (digL > rt->digits) ? digL : rt->digits;
    3288             : 
    3289             :                 /* HACK alert: digits should be less than max */
    3290             : #ifdef HAVE_HGE
    3291         170 :                 if (res->type->radix == 10 && digits > 38)
    3292         170 :                         digits = 38;
    3293         170 :                 if (res->type->radix == 2 && digits > 127)
    3294         170 :                         digits = 127;
    3295             : #else
    3296             :                 if (res->type->radix == 10 && digits > 18)
    3297             :                         digits = 18;
    3298             :                 if (res->type->radix == 2 && digits > 63)
    3299             :                         digits = 63;
    3300             : #endif
    3301             : 
    3302         170 :                 sql_find_subtype(&nlt, lt->type->base.name, digL, scaleL);
    3303         170 :                 if (nlt.digits < scaleL)
    3304           2 :                         return sql_error(sql, 01, SQLSTATE(42000) "Scale (%d) overflows type", scaleL);
    3305         168 :                 l = exp_check_type(sql, &nlt, rel, l, type_equal);
    3306             : 
    3307         168 :                 sql_find_subtype(res, lt->type->base.name, digits, scale);
    3308        2455 :         } else if (lt->type->scale == SCALE_FIX) {
    3309        2256 :                 sql_subtype *res = f->res->h->data;
    3310        2256 :                 if (res->type->eclass == EC_NUM)
    3311        2235 :                         res->digits = MAX(lt->digits, rt->digits);
    3312             :         }
    3313             :         return l;
    3314             : }
    3315             : 
    3316             : sql_exp *
    3317        2625 : exps_scale_algebra(mvc *sql, sql_subfunc *f, sql_rel *rel, list *exps)
    3318             : {
    3319        2625 :         if (list_length(exps) != 2)
    3320             :                 return NULL;
    3321        2625 :         sql_exp *e = exp_scale_algebra(sql, f, rel, exps->h->data, exps->h->next->data);
    3322        2625 :         if (e)
    3323        2623 :                 exps->h->data = e;
    3324             :         return e;
    3325             : }
    3326             : 
    3327             : void
    3328      188947 : exps_digits_add(sql_subfunc *f, list *exps)
    3329             : {
    3330             :         /* concat and friends need larger results */
    3331      188947 :         if (!f->func->res)
    3332             :                 return;
    3333      188947 :         int digits = 0;
    3334      336197 :         for(node *n = exps->h; n; n = n->next) {
    3335      275262 :                 sql_subtype *t = exp_subtype(n->data);
    3336             : 
    3337      275262 :                 if (!t->digits) {
    3338             :                         digits = 0;
    3339             :                         break;
    3340             :                 }
    3341      147250 :                 digits += t->digits;
    3342             :         }
    3343      188947 :         sql_subtype *res = f->res->h->data;
    3344      188947 :         res->digits = digits;
    3345             : }
    3346             : 
    3347             : void
    3348       25384 : exps_sum_scales(sql_subfunc *f, list *exps)
    3349             : {
    3350             :         /* sum scales and digits for multiply operation */
    3351       25384 :         sql_arg *ares = f->func->res->h->data;
    3352             : 
    3353       25384 :         if (ares->type.type->scale == SCALE_FIX && strcmp(sql_func_imp(f->func), "*") == 0) {
    3354       24077 :                 unsigned int digits = 0, scale = 0;
    3355       24077 :                 sql_type *largesttype = ares->type.type;
    3356             : 
    3357       72231 :                 for(node *n = exps->h; n; n = n->next) {
    3358       48154 :                         sql_exp *e = n->data;
    3359       48154 :                         sql_subtype *t = exp_subtype(e);
    3360             : 
    3361       48154 :                         scale += t->scale;
    3362       48154 :                         digits += t->digits;
    3363       48154 :                         if (largesttype->localtype < t->type->localtype)
    3364           0 :                                 largesttype = t->type;
    3365             :                 }
    3366       24077 :                 sql_subtype *res = f->res->h->data;
    3367             : 
    3368       24077 :                 res->scale = scale;
    3369       24077 :                 res->digits = digits;
    3370             : 
    3371             :                 /* HACK alert: digits should be less than max */
    3372             : #ifdef HAVE_HGE
    3373       24077 :                 if (ares->type.type->radix == 10 && res->digits > 38) {
    3374        2513 :                         res->digits = 38;
    3375        2513 :                         res->scale = MIN(res->scale, res->digits - 1);
    3376             :                 }
    3377       24077 :                 if (ares->type.type->radix == 2 && res->digits > 127) {
    3378          25 :                         res->digits = 127;
    3379          25 :                         res->scale = MIN(res->scale, res->digits - 1);
    3380             :                 }
    3381             : #else
    3382             :                 if (ares->type.type->radix == 10 && res->digits > 18) {
    3383             :                         res->digits = 18;
    3384             :                         res->scale = MIN(res->scale, res->digits - 1);
    3385             :                 }
    3386             :                 if (ares->type.type->radix == 2 && res->digits > 63) {
    3387             :                         res->digits = 63;
    3388             :                         res->scale = MIN(res->scale, res->digits - 1);
    3389             :                 }
    3390             : #endif
    3391             : 
    3392       24077 :                 sql_subtype t;
    3393             :                 /* numeric types are fixed length */
    3394       24077 :                 if (ares->type.type->eclass == EC_NUM) {
    3395             : #ifdef HAVE_HGE
    3396       21276 :                         if (ares->type.type->localtype == TYPE_hge && res->digits == 127)
    3397          25 :                                 t = *sql_bind_localtype("hge");
    3398             :                         else
    3399             : #endif
    3400       21251 :                         if (ares->type.type->localtype == TYPE_lng && res->digits == 63)
    3401           3 :                                 t = *sql_bind_localtype("lng");
    3402       21248 :                         else if (res->type->digits >= res->digits)
    3403        8856 :                                 t = *res; /* we cannot reduce types! */
    3404             :                         else
    3405       12392 :                                 sql_find_numeric(&t, ares->type.type->localtype, res->digits);
    3406             :                 } else {
    3407        2801 :                         if (res->digits > largesttype->digits)
    3408         215 :                                 sql_find_subtype(&t, largesttype->base.name, res->digits, res->scale);
    3409             :                         else
    3410        2586 :                                 sql_init_subtype(&t, largesttype, res->digits, res->scale);
    3411             :                 }
    3412       24077 :                 *res = t;
    3413             :         }
    3414       25384 : }
    3415             : 
    3416             : void
    3417      114560 : exps_max_bits(sql_subfunc *f, list *exps)
    3418             : {
    3419             :         /* + and - have max_bits + 1 */
    3420      114560 :         if (!f->func->res)
    3421             :                 return;
    3422      114560 :         unsigned int digits = 0;
    3423      343680 :         for(node *n = exps->h; n; n = n->next) {
    3424      229120 :                 sql_subtype *t = exp_subtype(n->data);
    3425             : 
    3426      229120 :                 if (!t)
    3427           0 :                         continue;
    3428      229120 :                 if (digits < t->digits)
    3429      229120 :                         digits = t->digits;
    3430             :         }
    3431             :         /* + and - (because of negative numbers) could need one extra bit (or digit) */
    3432      114560 :         digits += 1;
    3433      114560 :         sql_subtype *res = f->res->h->data;
    3434      114560 :         if (digits > res->type->digits)
    3435       49578 :                 res = sql_find_numeric(res, res->type->localtype, digits);
    3436             :         else
    3437       64982 :                 res->digits = digits;
    3438             : }
    3439             : 
    3440             : void
    3441       19792 : exps_inout(sql_subfunc *f, list *exps)
    3442             : {
    3443             :         /* output == first input */
    3444       19792 :         if (!f->func->res)
    3445             :                 return;
    3446       19792 :         sql_subtype *res = f->res->h->data;
    3447       19792 :         bool is_decimal = (res->type->eclass == EC_DEC);
    3448       19792 :         unsigned int digits = 0, scale = 0;
    3449       19792 :         sql_type *largesttype = NULL;
    3450       19792 :         for(node *n = exps->h; n; n = n->next) {
    3451       19792 :                 sql_subtype *t = exp_subtype(n->data);
    3452             : 
    3453       19792 :                 if (!t)
    3454           0 :                         continue;
    3455             : 
    3456       19792 :                 if (is_decimal && t->type->eclass == EC_DEC && (!largesttype || largesttype->localtype < t->type->localtype))
    3457         399 :                         largesttype = t->type;
    3458         399 :                 if (is_decimal && t->type->eclass == EC_NUM) {
    3459           0 :                         unsigned int d = bits2digits(t->digits);
    3460           0 :                         digits = d>digits?d:digits;
    3461       19792 :                 } else if (digits < t->digits)
    3462             :                         digits = t->digits;
    3463       19792 :                 if (scale < t->scale)
    3464             :                         scale = t->scale;
    3465             :                 break;
    3466             :         }
    3467       19792 :         if (digits > res->digits || scale > res->scale) {
    3468        9540 :                 if (largesttype)
    3469         385 :                         sql_init_subtype(res, largesttype, digits, scale);
    3470             :                 else
    3471        9155 :                         sql_find_subtype(res, res->type->base.name, digits, scale);
    3472             :         } else
    3473       10252 :                 res->digits = digits;
    3474             : }
    3475             : 
    3476             : /* for aggregates we can reduce the result types size based on real digits/bits used number of known input rows */
    3477             : void
    3478        9487 : exps_largest_int(sql_subfunc *f, list *exps, lng cnt)
    3479             : {
    3480        9487 :         if (!f->func->res || cnt == 0)
    3481             :                 return;
    3482         571 :         sql_subtype *res = f->res->h->data;
    3483         571 :         if (res->type->eclass != EC_DEC && res->type->eclass != EC_NUM)
    3484             :                 return;
    3485         495 :         bool is_decimal = (res->type->eclass == EC_DEC);
    3486         495 :         unsigned int digits = 0, scale = 0, mdigits = is_decimal ? decimal_digits(cnt) : number_bits(cnt);
    3487         495 :         sql_type *largesttype = NULL;
    3488         495 :         for(node *n = exps->h; n; n = n->next) {
    3489         495 :                 sql_subtype *t = exp_subtype(n->data);
    3490             : 
    3491         495 :                 if (!t)
    3492           0 :                         continue;
    3493             : 
    3494         495 :                 largesttype = t->type;
    3495         495 :                 if (is_decimal && t->type->eclass == EC_NUM) {
    3496           0 :                         unsigned int d = bits2digits(t->digits);
    3497           0 :                         digits = d>digits?d:digits;
    3498         495 :                 } else if (digits < t->digits)
    3499             :                         digits = t->digits;
    3500         495 :                 if (scale < t->scale)
    3501             :                         scale = t->scale;
    3502             :                 break;
    3503             :         }
    3504         495 :         digits += mdigits;
    3505         495 :         if (largesttype && digits <= largesttype->digits)
    3506         421 :                 sql_init_subtype(res, largesttype, digits, scale);
    3507          74 :         else if (is_decimal)
    3508           8 :                 sql_find_subtype(res, res->type->base.name, digits, scale);
    3509             :         else
    3510          66 :                 sql_find_numeric(res, 1, digits);
    3511             : }
    3512             : 
    3513             : #define is_addition(fname) (strcmp(fname, "sql_add") == 0)
    3514             : #define is_subtraction(fname) (strcmp(fname, "sql_sub") == 0)
    3515             : void
    3516      299011 : exps_scale_fix(sql_subfunc *f, list *exps, sql_subtype *atp)
    3517             : {
    3518      299011 :         if (!f->func->res)
    3519             :                 return;
    3520             : 
    3521      299011 :         sql_subtype *res = f->res->h->data;
    3522      299011 :         if (res->type->eclass != EC_ANY && res->type->eclass != EC_DEC)
    3523             :                 return;
    3524             : 
    3525       61959 :         unsigned int digits = 0, scale = 0;
    3526       61959 :         sql_type *largesttype = NULL;
    3527      244757 :         for(node *n = exps->h; n; n = n->next) {
    3528      182798 :                 sql_subtype *t = exp_subtype(n->data);
    3529             : 
    3530      182798 :                 if (!t)
    3531           0 :                         continue;
    3532      182798 :                 if (digits < t->digits)
    3533             :                         digits = t->digits;
    3534      182798 :                 if (scale < t->scale)
    3535             :                         scale = t->scale;
    3536      182798 :                 if (t->type->eclass == EC_DEC && (!largesttype || largesttype->localtype < t->type->localtype))
    3537      182798 :                         largesttype = t->type;
    3538             :         }
    3539       61959 :         res->scale = scale;
    3540       61959 :         if (res->type->eclass == EC_DEC)
    3541         646 :                 digits += (is_addition(f->func->base.name) || is_subtraction(f->func->base.name));
    3542       61959 :         if (digits > res->type->digits) {
    3543       61637 :                 if (largesttype && largesttype->localtype > res->type->localtype)
    3544          75 :                         sql_init_subtype(res, largesttype, digits, scale);
    3545             :                 else
    3546       61562 :                         sql_find_subtype(res, res->type->localtype?res->type->base.name:atp->type->base.name, digits, scale);
    3547         322 :         } else if (res->type->eclass == EC_DEC || res->type->eclass == EC_NUM)
    3548         252 :                 res->digits = digits;
    3549             : }
    3550             : 
    3551             : int
    3552      128271 : exp_aggr_is_count(sql_exp *e)
    3553             : {
    3554      128271 :         if (e->type == e_aggr && !((sql_subfunc *)e->f)->func->s && strcmp(((sql_subfunc *)e->f)->func->base.name, "count") == 0)
    3555       35186 :                 return 1;
    3556             :         return 0;
    3557             : }
    3558             : 
    3559             : list *
    3560       68845 : check_distinct_exp_names(mvc *sql, list *exps)
    3561             : {
    3562       68845 :         list *distinct_exps = NULL;
    3563       68845 :         bool duplicates = false;
    3564             : 
    3565       68845 :         if (list_length(exps) < 2) {
    3566             :                 return exps; /* always true */
    3567       66955 :         } else if (list_length(exps) < 5) {
    3568       15294 :                 distinct_exps = list_distinct(exps, (fcmp) exp_equal, (fdup) NULL);
    3569             :         } else { /* for longer lists, use hashing */
    3570       51661 :                 sql_hash *ht = hash_new(sql->ta, list_length(exps), (fkeyvalue)&exp_key);
    3571             : 
    3572      510654 :                 for (node *n = exps->h; n && !duplicates; n = n->next) {
    3573      458994 :                         sql_exp *e = n->data;
    3574      458994 :                         int key = ht->key(e);
    3575      458996 :                         sql_hash_e *he = ht->buckets[key&(ht->size-1)];
    3576             : 
    3577      593367 :                         for (; he && !duplicates; he = he->chain) {
    3578      134371 :                                 sql_exp *f = he->value;
    3579             : 
    3580      134371 :                                 if (!exp_equal(e, f))
    3581           0 :                                         duplicates = true;
    3582             :                         }
    3583      458996 :                         hash_add(ht, key, e);
    3584             :                 }
    3585             :         }
    3586       66954 :         if ((distinct_exps && list_length(distinct_exps) != list_length(exps)) || duplicates)
    3587           1 :                 return NULL;
    3588             :         return exps;
    3589             : }
    3590             : 
    3591             : static int rel_find_parameter(mvc *sql, sql_subtype *type, sql_rel *rel, int nid, const char *relname, const char *expname);
    3592             : 
    3593             : static int
    3594        1633 : set_exp_type(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *e)
    3595             : {
    3596        1639 :         if (mvc_highwater(sql)) {
    3597           0 :                 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3598           0 :                 return -1;
    3599             :         }
    3600        1639 :         if (e->type == e_column) {
    3601          60 :                 const char *nrname = (const char*) e->l, *nename = (const char*) e->r;
    3602             :                 /* find all the column references and set the type */
    3603          60 :                 e->tpe = *type;
    3604          60 :                 assert(e->nid);
    3605          60 :                 return rel_find_parameter(sql, type, rel, e->nid, nrname, nename);
    3606        1579 :         } else if (e->type == e_atom && e->f) {
    3607          25 :                 list *atoms = e->f;
    3608          25 :                 if (!list_empty(atoms))
    3609          61 :                         for (node *n = atoms->h; n; n = n->next)
    3610          36 :                                 if (set_exp_type(sql, type, rel, n->data) < 0) /* set recursively */
    3611             :                                         return -1;
    3612          25 :                 e->tpe = *type;
    3613          25 :                 return 1; /* on a list of atoms, everything should be found */
    3614        1554 :         } else if (e->type == e_atom && !e->l && !e->r && !e->f) {
    3615        1548 :                 e->tpe = *type;
    3616        1548 :                 return set_type_param(sql, type, e->flag) == 0 ? 1 : 0;
    3617           6 :         } else if (exp_is_rel(e)) { /* for relation expressions, restart cycle */
    3618           6 :                 rel = (sql_rel*) e->l;
    3619             :                 /* limiting to these cases */
    3620           6 :                 if (!is_project(rel->op) || list_length(rel->exps) != 1)
    3621           0 :                         return 0;
    3622           6 :                 sql_exp *re = rel->exps->h->data;
    3623             : 
    3624           6 :                 e->tpe = *type;
    3625           6 :                 return set_exp_type(sql, type, rel, re); /* set recursively */
    3626             :         }
    3627             :         return 0;
    3628             : }
    3629             : 
    3630             : int
    3631        1541 : rel_set_type_param(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *exp, int upcast)
    3632             : {
    3633        1541 :         if (!type || !exp || (exp->type != e_atom && exp->type != e_column && !exp_is_rel(exp)))
    3634           0 :                 return -1;
    3635             : 
    3636             :         /* use largest numeric types */
    3637        1541 :         if (upcast && type->type->eclass == EC_NUM)
    3638             : #ifdef HAVE_HGE
    3639           9 :                 type = sql_bind_localtype("hge");
    3640             : #else
    3641             :                 type = sql_bind_localtype("lng");
    3642             : #endif
    3643           6 :         else if (upcast && type->type->eclass == EC_FLT)
    3644           1 :                 type = sql_bind_localtype("dbl");
    3645             : 
    3646             :         /* TODO we could use the sql_query* struct to set parameters used as freevars,
    3647             :            but it requires to change a lot of interfaces */
    3648             :         /* if (is_freevar(exp))
    3649             :                 rel = query_fetch_outer(query, is_freevar(exp)-1); */
    3650        1541 :         return set_exp_type(sql, type, rel, exp);
    3651             : }
    3652             : 
    3653             : /* try to do an in-place conversion
    3654             :  *
    3655             :  * in-place conversion is only possible if the exp is a variable.
    3656             :  * This is only done to be able to map more cached queries onto the same
    3657             :  * interface.
    3658             :  */
    3659             : sql_exp *
    3660     5287708 : exp_convert_inplace(mvc *sql, sql_subtype *t, sql_exp *exp)
    3661             : {
    3662     5287708 :         atom *a, *na;
    3663             : 
    3664             :         /* exclude named variables and variable lists */
    3665     5287708 :         if (exp->type != e_atom || exp->r /* named */ || exp->f /* list */ || !exp->l /* not direct atom */)
    3666             :                 return NULL;
    3667             : 
    3668     3025827 :         a = exp->l;
    3669     3025827 :         if (!a->isnull && t->scale && t->type->eclass != EC_FLT)
    3670             :                 return NULL;
    3671             : 
    3672     3020475 :         if ((na = atom_cast(sql->sa, a, t))) {
    3673     3017460 :                 exp->l = na;
    3674     3017460 :                 return exp;
    3675             :         }
    3676             :         return NULL;
    3677             : }
    3678             : 
    3679             : sql_exp *
    3680           0 : exp_numeric_supertype(mvc *sql, sql_exp *e )
    3681             : {
    3682           0 :         sql_subtype *tp = exp_subtype(e);
    3683             : 
    3684           0 :         if (tp->type->eclass == EC_DEC) {
    3685           0 :                 sql_subtype *dtp = sql_bind_localtype("dbl");
    3686             : 
    3687           0 :                 return exp_check_type(sql, dtp, NULL, e, type_cast);
    3688             :         }
    3689           0 :         if (tp->type->eclass == EC_NUM) {
    3690             : #ifdef HAVE_HGE
    3691           0 :                 sql_subtype *ltp = sql_bind_localtype("hge");
    3692             : #else
    3693             :                 sql_subtype *ltp = sql_bind_localtype("lng");
    3694             : #endif
    3695             : 
    3696           0 :                 return exp_check_type(sql, ltp, NULL, e, type_cast);
    3697             :         }
    3698             :         return e;
    3699             : }
    3700             : 
    3701             : sql_exp *
    3702     5287654 : exp_check_type(mvc *sql, sql_subtype *t, sql_rel *rel, sql_exp *exp, check_type tpe)
    3703             : {
    3704     5287654 :         int c, err = 0;
    3705     5287654 :         sql_exp* nexp = NULL;
    3706     5287654 :         sql_subtype *fromtype = exp_subtype(exp);
    3707             : 
    3708     5287622 :         if ((!fromtype || !fromtype->type) && rel_set_type_param(sql, t, rel, exp, 0) == 0)
    3709             :                 return exp;
    3710             : 
    3711             :         /* first try cheap internal (in-place) conversions ! */
    3712     5287621 :         if ((nexp = exp_convert_inplace(sql, t, exp)) != NULL)
    3713             :                 return nexp;
    3714             : 
    3715     2270231 :         if (fromtype && subtype_cmp(t, fromtype) != 0) {
    3716      267768 :                 if (EC_INTERVAL(fromtype->type->eclass) && (t->type->eclass == EC_NUM || t->type->eclass == EC_POS) && t->digits < fromtype->digits) {
    3717             :                         err = 1; /* conversion from interval to num depends on the number of digits */
    3718             :                 } else {
    3719      267768 :                         c = sql_type_convert(fromtype->type->eclass, t->type->eclass);
    3720      267768 :                         if (!c || (c == 2 && tpe == type_set) || (c == 3 && tpe != type_cast)) {
    3721             :                                 err = 1;
    3722             :                         } else {
    3723      267254 :                                 exp = exp_convert(sql, exp, fromtype, t);
    3724             :                         }
    3725             :                 }
    3726             :         }
    3727      267254 :         if (err) {
    3728         514 :                 const char *name = (exp->type == e_column && !has_label(exp)) ? exp_name(exp) : "%";
    3729         576 :                 sql_exp *res = sql_error( sql, 03, SQLSTATE(42000) "types %s(%u,%u) and %s(%u,%u) are not equal%s%s%s",
    3730         514 :                         fromtype->type->base.name,
    3731             :                         fromtype->digits,
    3732             :                         fromtype->scale,
    3733         514 :                         t->type->base.name,
    3734             :                         t->digits,
    3735             :                         t->scale,
    3736             :                         (name[0] != '%' ? " for column '" : ""),
    3737             :                         (name[0] != '%' ? name : ""),
    3738         514 :                         (name[0] != '%' ? "'" : "")
    3739             :                 );
    3740         514 :                 return res;
    3741             :         }
    3742             :         return exp;
    3743             : }
    3744             : 
    3745             : sql_exp *
    3746        8590 : exp_values_set_supertype(mvc *sql, sql_exp *values, sql_subtype *opt_super)
    3747             : {
    3748        8590 :         assert(is_values(values));
    3749        8590 :         list *vals = exp_get_values(values), *nexps;
    3750        8590 :         sql_subtype *tpe = opt_super?opt_super:exp_subtype(vals->h->data);
    3751             : 
    3752        8590 :         if (!opt_super && tpe)
    3753        8490 :                 values->tpe = *tpe;
    3754             : 
    3755       34195 :         for (node *m = vals->h; m; m = m->next) {
    3756       25605 :                 sql_exp *e = m->data;
    3757       25605 :                 sql_subtype super, *ttpe;
    3758             : 
    3759             :                 /* if the expression is a parameter set its type */
    3760       25605 :                 if (tpe && e->type == e_atom && !e->l && !e->r && !e->f && !e->tpe.type) {
    3761           4 :                         if (set_type_param(sql, tpe, e->flag) == 0)
    3762           4 :                                 e->tpe = *tpe;
    3763             :                         else
    3764           0 :                                 return NULL;
    3765             :                 }
    3766       25605 :                 ttpe = exp_subtype(e);
    3767       25605 :                 if (tpe && ttpe) {
    3768       25552 :                         supertype(&super, ttpe, tpe);
    3769       25552 :                         values->tpe = super;
    3770       25552 :                         tpe = &values->tpe;
    3771             :                 } else {
    3772             :                         tpe = ttpe;
    3773             :                 }
    3774             :         }
    3775             : 
    3776        8590 :         if (tpe) {
    3777             :                 /* if the expression is a parameter set its type */
    3778       34108 :                 for (node *m = vals->h; m; m = m->next) {
    3779       25556 :                         sql_exp *e = m->data;
    3780       25556 :                         if (e->type == e_atom && !e->l && !e->r && !e->f && !e->tpe.type) {
    3781           1 :                                 if (set_type_param(sql, tpe, e->flag) == 0)
    3782           1 :                                         e->tpe = *tpe;
    3783             :                                 else
    3784             :                                         return NULL;
    3785             :                         }
    3786             :                 }
    3787        8552 :                 values->tpe = *tpe;
    3788        8552 :                 nexps = sa_list(sql->sa);
    3789       34103 :                 for (node *m = vals->h; m; m = m->next) {
    3790       25554 :                         sql_exp *e = m->data;
    3791       25554 :                         e = exp_check_type(sql, &values->tpe, NULL, e, type_equal);
    3792       25554 :                         if (!e)
    3793             :                                 return NULL;
    3794       25551 :                         exp_label(sql->sa, e, ++sql->label);
    3795       25551 :                         append(nexps, e);
    3796             :                 }
    3797        8549 :                 values->f = nexps;
    3798             :         }
    3799             :         return values;
    3800             : }
    3801             : 
    3802             : /* return -1 on error, 0 not found, 1 found */
    3803             : static int
    3804          86 : rel_find_parameter(mvc *sql, sql_subtype *type, sql_rel *rel, int nid, const char *relname, const char *expname)
    3805             : {
    3806         138 :         int res = 0;
    3807             : 
    3808         138 :         if (mvc_highwater(sql)) {
    3809           0 :                 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3810           0 :                 return -1;
    3811             :         }
    3812         138 :         if (!rel)
    3813             :                 return 0;
    3814             : 
    3815         135 :         const char *nrname = relname, *nename = expname;
    3816         135 :         if (is_project(rel->op) && !list_empty(rel->exps)) {
    3817         111 :                 sql_exp *e = NULL;
    3818             : 
    3819         111 :                 assert(nid);
    3820         111 :                 e = exps_bind_nid(rel->exps, nid);
    3821         111 :                 if (!e)
    3822             :                         return 0; /* not found */
    3823         108 :                 if (is_mset(rel->op)) { /* TODO for set relations this needs further improvement */
    3824           0 :                         (void) sql_error(sql, 10, SQLSTATE(42000) "Cannot set parameter types under set relations at the moment");
    3825           0 :                         return -1;
    3826             :                 }
    3827             :                 /* set order by column types */
    3828         108 :                 if (is_simple_project(rel->op) && !list_empty(rel->r)) {
    3829           0 :                         sql_exp *ordere = NULL;
    3830           0 :                         ordere = exps_bind_nid(rel->r, nid);
    3831           0 :                         if (ordere && ordere->type == e_column)
    3832           0 :                                 ordere->tpe = *type;
    3833             :                 }
    3834         108 :                 if (e->type == e_column) {
    3835          52 :                         nid = e->nid;
    3836          52 :                         nrname = (const char*) e->l;
    3837          52 :                         nename = (const char*) e->r;
    3838          52 :                         e->tpe = *type;
    3839          52 :                         res = 1; /* found */
    3840          56 :                 } else if ((e->type == e_atom || exp_is_rel(e)) && (res = set_exp_type(sql, type, rel, e)) <= 0) {
    3841             :                         return res; /* don't search further */
    3842             :                 }
    3843             :                 /* group by columns can have aliases! */
    3844         108 :                 if (is_groupby(rel->op) && !list_empty(rel->r)) {
    3845           0 :                         e = exps_bind_nid(rel->r, nid);
    3846           0 :                         if (!e)
    3847             :                                 return res; /* don't search further */
    3848           0 :                         if (e->type == e_column) {
    3849           0 :                                 nid = e->nid;
    3850           0 :                                 nrname = (const char*) e->l;
    3851           0 :                                 nename = (const char*) e->r;
    3852           0 :                                 e->tpe = *type;
    3853           0 :                         } else if ((e->type == e_atom || exp_is_rel(e)) && (res = set_exp_type(sql, type, rel, e)) <= 0) {
    3854             :                                 return res; /* don't search further */
    3855             :                         }
    3856             :                 }
    3857         108 :                 if (e->type != e_column)
    3858             :                         return res; /* don't search further */
    3859             :         }
    3860             : 
    3861          76 :         switch (rel->op) {
    3862          14 :                 case op_join:
    3863             :                 case op_left:
    3864             :                 case op_right:
    3865             :                 case op_full:
    3866          14 :                         if (rel->l)
    3867          14 :                                 res = rel_find_parameter(sql, type, rel->l, nid, nrname, nename);
    3868          14 :                         if (rel->r && res <= 0) { /* try other relation if not found */
    3869          12 :                                 int err = sql->session->status, lres = res;
    3870          12 :                                 char buf[ERRSIZE];
    3871             : 
    3872          12 :                                 strcpy(buf, sql->errstr); /* keep error found and try other join relation */
    3873          12 :                                 sql->session->status = 0;
    3874          12 :                                 sql->errstr[0] = '\0';
    3875          12 :                                 res = rel_find_parameter(sql, type, rel->r, nid, nrname, nename);
    3876          12 :                                 if (res == 0) { /* parameter wasn't found, set error */
    3877           1 :                                         res = lres;
    3878           1 :                                         sql->session->status = err;
    3879           1 :                                         strcpy(sql->errstr, buf);
    3880             :                                 }
    3881             :                         }
    3882             :                         break;
    3883          52 :                 case op_semi:
    3884             :                 case op_anti:
    3885             :                 case op_groupby:
    3886             :                 case op_project:
    3887             :                 case op_select:
    3888             :                 case op_topn:
    3889             :                 case op_sample:
    3890          52 :                         if (rel->l)
    3891             :                                 res = rel_find_parameter(sql, type, rel->l, nid, nrname, nename);
    3892             :                         break;
    3893           0 :                 case op_union: /* TODO for set relations this needs further improvement */
    3894             :                 case op_inter:
    3895             :                 case op_except:
    3896             :                 case op_munion: {
    3897           0 :                         (void) sql_error(sql, 10, SQLSTATE(42000) "Cannot set parameter types under set relations at the moment");
    3898           0 :                         return -1;
    3899             :                 }
    3900             :                 default: /* For table returning functions, the type must be set when the relation is created */
    3901             :                         return 0;
    3902             :         }
    3903             :         return res;
    3904             : }
    3905             : 
    3906             : sql_exp *
    3907       19792 : list_find_exp( list *exps, sql_exp *e)
    3908             : {
    3909       19792 :         if (e->type != e_column)
    3910             :                 return NULL;
    3911       19751 :         return exps_bind_nid(exps, e->nid);
    3912             : }

Generated by: LCOV version 1.14