LCOV - code coverage report
Current view: top level - sql/server - rel_exp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1487 1716 86.7 %
Date: 2021-10-13 02:24:04 Functions: 155 166 93.4 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : #include "monetdb_config.h"
      10             : #include "sql_relation.h"
      11             : #include "sql_semantic.h"
      12             : #include "rel_exp.h"
      13             : #include "rel_rel.h"
      14             : #include "rel_basetable.h"
      15             : #include "rel_prop.h"
      16             : #include "rel_unnest.h"
      17             : #include "rel_optimizer.h"
      18             : #include "rel_distribute.h"
      19             : 
      20             : comp_type
      21      780262 : compare_str2type(const char *compare_op)
      22             : {
      23             :         comp_type type = cmp_filter;
      24             : 
      25      780262 :         if (compare_op[0] == '=') {
      26             :                 type = cmp_equal;
      27      145796 :         } else if (compare_op[0] == '<') {
      28             :                 type = cmp_lt;
      29       94677 :                 if (compare_op[1] == '>')
      30             :                         type = cmp_notequal;
      31       18176 :                 else if (compare_op[1] == '=')
      32             :                         type = cmp_lte;
      33       51119 :         } else if (compare_op[0] == '>') {
      34             :                 type = cmp_gt;
      35       51119 :                 if (compare_op[1] == '=')
      36             :                         type = cmp_gte;
      37             :         }
      38      780262 :         return type;
      39             : }
      40             : 
      41             : comp_type
      42       34157 : swap_compare( comp_type t )
      43             : {
      44             :         switch(t) {
      45             :         case cmp_equal:
      46             :                 return cmp_equal;
      47             :         case cmp_lt:
      48             :                 return cmp_gt;
      49             :         case cmp_lte:
      50             :                 return cmp_gte;
      51             :         case cmp_gte:
      52             :                 return cmp_lte;
      53             :         case cmp_gt:
      54             :                 return cmp_lt;
      55             :         case cmp_notequal:
      56             :                 return cmp_notequal;
      57             :         default:
      58             :                 return cmp_equal;
      59             :         }
      60             : }
      61             : 
      62             : comp_type
      63        7685 : negate_compare( comp_type t )
      64             : {
      65        7685 :         switch(t) {
      66             :         case cmp_equal:
      67             :                 return cmp_notequal;
      68          56 :         case cmp_notequal:
      69          56 :                 return cmp_equal;
      70           2 :         case cmp_lt:
      71           2 :                 return cmp_gte;
      72           5 :         case cmp_lte:
      73           5 :                 return cmp_gt;
      74           2 :         case cmp_gte:
      75           2 :                 return cmp_lt;
      76           3 :         case cmp_gt:
      77           3 :                 return cmp_lte;
      78             : 
      79           0 :         case cmp_in:
      80           0 :                 return cmp_notin;
      81           0 :         case cmp_notin:
      82           0 :                 return cmp_in;
      83             : 
      84           0 :         case mark_in:
      85           0 :                 return mark_notin;
      86           0 :         case mark_notin:
      87           0 :                 return mark_in;
      88             : 
      89           0 :         default:
      90           0 :                 return t;
      91             :         }
      92             : }
      93             : 
      94             : comp_type
      95         146 : range2lcompare( int r )
      96             : {
      97         146 :         if (r&1) {
      98             :                 return cmp_gte;
      99             :         } else {
     100          24 :                 return cmp_gt;
     101             :         }
     102             : }
     103             : 
     104             : comp_type
     105         203 : range2rcompare( int r )
     106             : {
     107         203 :         if (r&2) {
     108             :                 return cmp_lte;
     109             :         } else {
     110          49 :                 return cmp_lt;
     111             :         }
     112             : }
     113             : 
     114             : int
     115        1911 : compare2range( int l, int r )
     116             : {
     117        1911 :         if (l == cmp_gt) {
     118        1786 :                 if (r == cmp_lt)
     119             :                         return 0;
     120          28 :                 else if (r == cmp_lte)
     121          28 :                         return 2;
     122         125 :         } else if (l == cmp_gte) {
     123         125 :                 if (r == cmp_lt)
     124             :                         return 1;
     125          83 :                 else if (r == cmp_lte)
     126          83 :                         return 3;
     127             :         }
     128             :         return -1;
     129             : }
     130             : 
     131             : int
     132         107 : compare_funcs2range(const char *l_op, const char *r_op)
     133             : {
     134         107 :         assert(l_op[0] == '>' && r_op[0] == '<');
     135         107 :         if (!l_op[1] && !r_op[1])
     136             :                 return 0;
     137         105 :         if (!l_op[1] && r_op[1] == '=')
     138             :                 return 2;
     139         105 :         if (l_op[1] == '=' && !r_op[1])
     140             :                 return 1;
     141          13 :         if (l_op[1] == '=' && r_op[1] == '=')
     142             :                 return 3;
     143           0 :         assert(0);
     144             :         return 0;
     145             : }
     146             : 
     147             : static sql_exp *
     148    19691321 : exp_create(sql_allocator *sa, int type)
     149             : {
     150    19691321 :         sql_exp *e = SA_NEW(sa, sql_exp);
     151             : 
     152    19691322 :         if (!e)
     153             :                 return NULL;
     154    19691322 :         *e = (sql_exp) {
     155    19691322 :                 .type = (expression_type) type,
     156             :         };
     157    19691322 :         return e;
     158             : }
     159             : 
     160             : sql_exp *
     161      482942 : exp_compare(sql_allocator *sa, sql_exp *l, sql_exp *r, int cmptype)
     162             : {
     163      482942 :         sql_exp *e = exp_create(sa, e_cmp);
     164      482942 :         if (e == NULL)
     165             :                 return NULL;
     166      482942 :         e->card = MAX(l->card,r->card);
     167      482942 :         e->l = l;
     168      482942 :         e->r = r;
     169      482942 :         e->flag = cmptype;
     170      482942 :         if (!has_nil(l) && !has_nil(r))
     171       15118 :                 set_has_no_nil(e);
     172             :         return e;
     173             : }
     174             : 
     175             : sql_exp *
     176        5909 : exp_compare2(sql_allocator *sa, sql_exp *l, sql_exp *r, sql_exp *f, int cmptype, int symmetric)
     177             : {
     178        5909 :         sql_exp *e = exp_create(sa, e_cmp);
     179        5909 :         if (e == NULL)
     180             :                 return NULL;
     181        5909 :         assert(f);
     182        5909 :         e->card = MAX(MAX(l->card,r->card),f->card);
     183        5909 :         e->l = l;
     184        5909 :         e->r = r;
     185        5909 :         e->f = f;
     186        5909 :         e->flag = cmptype;
     187        5909 :         if (symmetric)
     188          72 :                 set_symmetric(e);
     189        5909 :         if (!has_nil(l) && !has_nil(r) && !has_nil(f))
     190         304 :                 set_has_no_nil(e);
     191             :         return e;
     192             : }
     193             : 
     194             : sql_exp *
     195         767 : exp_filter(sql_allocator *sa, list *l, list *r, sql_subfunc *f, int anti)
     196             : {
     197         767 :         sql_exp *e = exp_create(sa, e_cmp);
     198             : 
     199         767 :         if (e == NULL)
     200             :                 return NULL;
     201         767 :         e->card = MAX(exps_card(l),exps_card(r));
     202         767 :         e->l = l;
     203         767 :         e->r = r;
     204         767 :         e->f = f;
     205         767 :         e->flag = cmp_filter;
     206         767 :         if (anti)
     207          56 :                 set_anti(e);
     208         767 :         if (!have_nil(l) && !have_nil(r))
     209         173 :                 set_has_no_nil(e);
     210             :         return e;
     211             : }
     212             : 
     213             : sql_exp *
     214       87717 : exp_or(sql_allocator *sa, list *l, list *r, int anti)
     215             : {
     216       87717 :         sql_exp *e = exp_create(sa, e_cmp);
     217             : 
     218       87717 :         if (e == NULL)
     219             :                 return NULL;
     220       87717 :         e->card = MAX(exps_card(l),exps_card(r));
     221       87717 :         e->l = l;
     222       87717 :         e->r = r;
     223       87717 :         e->flag = cmp_or;
     224       87717 :         if (anti)
     225           0 :                 set_anti(e);
     226       87717 :         if (!have_nil(l) && !have_nil(r))
     227        1121 :                 set_has_no_nil(e);
     228             :         return e;
     229             : }
     230             : 
     231             : sql_exp *
     232       29143 : exp_in(sql_allocator *sa, sql_exp *l, list *r, int cmptype)
     233             : {
     234       29143 :         sql_exp *e = exp_create(sa, e_cmp);
     235             :         unsigned int exps_card = CARD_ATOM;
     236             : 
     237       29143 :         if (e == NULL)
     238             :                 return NULL;
     239             : 
     240             :         /* ignore the cardinalites of sub-relations */
     241      139121 :         for (node *n = r->h; n ; n = n->next) {
     242      109978 :                 sql_exp *next = n->data;
     243             : 
     244      109978 :                 if (!exp_is_rel(next) && exps_card < next->card)
     245             :                         exps_card = next->card;
     246             :         }
     247       29143 :         e->card = MAX(l->card, exps_card);
     248       29143 :         e->l = l;
     249       29143 :         e->r = r;
     250       29143 :         assert( cmptype == cmp_in || cmptype == cmp_notin);
     251       29143 :         e->flag = cmptype;
     252       29143 :         if (!has_nil(l) && !have_nil(r))
     253         998 :                 set_has_no_nil(e);
     254             :         return e;
     255             : }
     256             : 
     257             : sql_exp *
     258       23297 : exp_in_func(mvc *sql, sql_exp *le, sql_exp *vals, int anyequal, int is_tuple)
     259             : {
     260             :         sql_subfunc *a_func = NULL;
     261             :         sql_exp *e = le;
     262             : 
     263       23297 :         if (is_tuple) {
     264        4598 :                 list *l = exp_get_values(e);
     265        4598 :                 e = l->h->data;
     266             :         }
     267       30283 :         a_func = sql_bind_func(sql, "sys", anyequal ? "sql_anyequal" : "sql_not_anyequal", exp_subtype(e), exp_subtype(e), F_FUNC);
     268       23297 :         if (!a_func)
     269           0 :                 return sql_error(sql, 02, SQLSTATE(42000) "(NOT) IN operator on type %s missing", exp_subtype(le)->type->base.name);
     270       23297 :         e = exp_binop(sql->sa, le, vals, a_func);
     271       23297 :         if (e) {
     272             :                 unsigned int exps_card = CARD_ATOM;
     273             : 
     274             :                 /* ignore the cardinalites of sub-relations */
     275       23297 :                 if (vals->type == e_atom && vals->f) {
     276       71217 :                         for (node *n = ((list*)vals->f)->h ; n ; n = n->next) {
     277       52026 :                                 sql_exp *next = n->data;
     278             : 
     279       52026 :                                 if (!exp_is_rel(next) && exps_card < next->card)
     280             :                                         exps_card = next->card;
     281             :                         }
     282        4106 :                 } else if (!exp_is_rel(vals))
     283        4106 :                         exps_card = vals->card;
     284             : 
     285       23297 :                 e->card = MAX(le->card, exps_card);
     286       23297 :                 if (!has_nil(le) && !has_nil(vals))
     287         100 :                         set_has_no_nil(e);
     288             :         }
     289             :         return e;
     290             : }
     291             : 
     292             : sql_exp *
     293      232488 : exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, const char *compareop, int quantifier)
     294             : {
     295      232488 :         sql_subfunc *cmp_func = sql_bind_func(sql, "sys", compareop, exp_subtype(le), exp_subtype(le), F_FUNC);
     296             :         sql_exp *e;
     297             : 
     298      232488 :         assert(cmp_func);
     299      232488 :         e = exp_binop(sql->sa, le, re, cmp_func);
     300      232488 :         if (e) {
     301      232488 :                 e->flag = quantifier;
     302             :                 /* At ANY and ALL operators, the cardinality on the right side is ignored if it is a sub-relation */
     303      232488 :                 e->card = quantifier && exp_is_rel(re) ? le->card : MAX(le->card, re->card);
     304      232488 :                 if (!has_nil(le) && !has_nil(re))
     305        5248 :                         set_has_no_nil(e);
     306             :         }
     307      232488 :         return e;
     308             : }
     309             : 
     310             : static sql_subtype*
     311     1181874 : dup_subtype(sql_allocator *sa, sql_subtype *st)
     312             : {
     313     1181874 :         sql_subtype *res = SA_NEW(sa, sql_subtype);
     314             : 
     315     1181874 :         if (res == NULL)
     316             :                 return NULL;
     317     1181874 :         *res = *st;
     318     1181874 :         return res;
     319             : }
     320             : 
     321             : sql_exp *
     322      590937 : exp_convert(sql_allocator *sa, sql_exp *exp, sql_subtype *fromtype, sql_subtype *totype )
     323             : {
     324      590937 :         sql_exp *e = exp_create(sa, e_convert);
     325      590937 :         if (e == NULL)
     326             :                 return NULL;
     327      590937 :         e->card = exp->card;
     328      590937 :         e->l = exp;
     329      590937 :         totype = dup_subtype(sa, totype);
     330      590937 :         e->r = append(append(sa_list(sa), dup_subtype(sa, fromtype)),totype);
     331      590937 :         e->tpe = *totype;
     332      590937 :         e->alias = exp->alias;
     333      590937 :         if (!has_nil(exp))
     334       83313 :                 set_has_no_nil(e);
     335             :         return e;
     336             : }
     337             : 
     338             : sql_exp *
     339      983242 : exp_op( sql_allocator *sa, list *l, sql_subfunc *f )
     340             : {
     341      983242 :         sql_exp *e = exp_create(sa, e_func);
     342      983242 :         if (e == NULL)
     343             :                 return NULL;
     344      983242 :         e->card = exps_card(l);
     345      983242 :         e->l = l;
     346      983242 :         e->f = f;
     347      983242 :         e->semantics = f->func->semantics;
     348      983242 :         if (!is_semantics(e) && l && !have_nil(l))
     349       30031 :                 set_has_no_nil(e);
     350             :         return e;
     351             : }
     352             : 
     353             : sql_exp *
     354       15248 : exp_rank_op( sql_allocator *sa, list *l, list *gbe, list *obe, sql_subfunc *f )
     355             : {
     356       15248 :         sql_exp *e = exp_create(sa, e_func);
     357       15248 :         if (e == NULL)
     358             :                 return NULL;
     359       15248 :         e->card = exps_card(l);
     360       15248 :         e->l = l;
     361       15248 :         e->r = append(append(sa_list(sa), gbe), obe);
     362       15248 :         e->f = f;
     363       15248 :         e->semantics = f->func->semantics;
     364       15248 :         return e;
     365             : }
     366             : 
     367             : sql_exp *
     368       52003 : exp_aggr( sql_allocator *sa, list *l, sql_subfunc *a, int distinct, int no_nils, unsigned int card, int has_nils )
     369             : {
     370       52003 :         sql_exp *e = exp_create(sa, e_aggr);
     371       52003 :         if (e == NULL)
     372             :                 return NULL;
     373       52003 :         e->card = card;
     374       52003 :         e->l = l;
     375       52003 :         e->f = a;
     376       52003 :         e->semantics = a->func->semantics;
     377       52003 :         if (distinct)
     378         360 :                 set_distinct(e);
     379       52003 :         if (no_nils)
     380       21968 :                 set_no_nil(e);
     381       52003 :         if ((!a->func->semantics && !has_nils) || (!a->func->s && strcmp(a->func->base.name, "count") == 0))
     382       22522 :                 set_has_no_nil(e);
     383             :         return e;
     384             : }
     385             : 
     386             : sql_exp *
     387     3359505 : exp_atom(sql_allocator *sa, atom *a)
     388             : {
     389     3359505 :         sql_exp *e = exp_create(sa, e_atom);
     390     3359505 :         if (e == NULL)
     391             :                 return NULL;
     392     3359505 :         e->card = CARD_ATOM;
     393     3359505 :         e->tpe = a->tpe;
     394     3359505 :         e->l = a;
     395     3359505 :         if (!a->isnull)
     396     3234275 :                 set_has_no_nil(e);
     397     3359505 :         set_unique(e);
     398     3359505 :         return e;
     399             : }
     400             : 
     401             : sql_exp *
     402           0 : exp_atom_max(sql_allocator *sa, sql_subtype *tpe)
     403             : {
     404           0 :         if (tpe->type->localtype == TYPE_bte) {
     405           0 :                 return exp_atom_bte(sa, GDK_bte_max);
     406           0 :         } else if (tpe->type->localtype == TYPE_sht) {
     407           0 :                 return exp_atom_sht(sa, GDK_sht_max);
     408           0 :         } else if (tpe->type->localtype == TYPE_int) {
     409           0 :                 return exp_atom_int(sa, GDK_int_max);
     410           0 :         } else if (tpe->type->localtype == TYPE_lng) {
     411           0 :                 return exp_atom_lng(sa, GDK_lng_max);
     412             : #ifdef HAVE_HGE
     413           0 :         } else if (tpe->type->localtype == TYPE_hge) {
     414           0 :                 return exp_atom_hge(sa, GDK_hge_max);
     415             : #endif
     416             :         }
     417             :         return NULL;
     418             : }
     419             : 
     420             : sql_exp *
     421       82406 : exp_atom_bool(sql_allocator *sa, int b)
     422             : {
     423             :         sql_subtype bt;
     424             : 
     425       82406 :         sql_find_subtype(&bt, "boolean", 0, 0);
     426       82406 :         if (b)
     427       47467 :                 return exp_atom(sa, atom_bool(sa, &bt, TRUE ));
     428             :         else
     429       34939 :                 return exp_atom(sa, atom_bool(sa, &bt, FALSE ));
     430             : }
     431             : 
     432             : sql_exp *
     433           0 : exp_atom_bte(sql_allocator *sa, bte i)
     434             : {
     435             :         sql_subtype it;
     436             : 
     437           0 :         sql_find_subtype(&it, "tinyint", 3, 0);
     438           0 :         return exp_atom(sa, atom_int(sa, &it, i ));
     439             : }
     440             : 
     441             : sql_exp *
     442           0 : exp_atom_sht(sql_allocator *sa, sht i)
     443             : {
     444             :         sql_subtype it;
     445             : 
     446           0 :         sql_find_subtype(&it, "smallint", 5, 0);
     447           0 :         return exp_atom(sa, atom_int(sa, &it, i ));
     448             : }
     449             : 
     450             : sql_exp *
     451      550132 : exp_atom_int(sql_allocator *sa, int i)
     452             : {
     453             :         sql_subtype it;
     454             : 
     455      550132 :         sql_find_subtype(&it, "int", 9, 0);
     456      550132 :         return exp_atom(sa, atom_int(sa, &it, i ));
     457             : }
     458             : 
     459             : sql_exp *
     460       10039 : exp_atom_lng(sql_allocator *sa, lng i)
     461             : {
     462             :         sql_subtype it;
     463             : 
     464             : #ifdef HAVE_HGE
     465       10039 :         sql_find_subtype(&it, "bigint", 18, 0);
     466             : #else
     467             :         sql_find_subtype(&it, "bigint", 19, 0);
     468             : #endif
     469       10039 :         return exp_atom(sa, atom_int(sa, &it, i ));
     470             : }
     471             : 
     472             : sql_exp *
     473       13138 : exp_atom_oid(sql_allocator *sa, oid i)
     474             : {
     475             :         sql_subtype it;
     476             : 
     477             : #if SIZEOF_OID == SIZEOF_INT
     478             :         sql_find_subtype(&it, "oid", 31, 0);
     479             : #else
     480       13138 :         sql_find_subtype(&it, "oid", 63, 0);
     481             : #endif
     482       13138 :         return exp_atom(sa, atom_int(sa, &it, i ));
     483             : }
     484             : 
     485             : #ifdef HAVE_HGE
     486             : sql_exp *
     487           1 : exp_atom_hge(sql_allocator *sa, hge i)
     488             : {
     489             :         sql_subtype it;
     490             : 
     491           1 :         sql_find_subtype(&it, "hugeint", 39, 0);
     492           1 :         return exp_atom(sa, atom_int(sa, &it, i ));
     493             : }
     494             : #endif
     495             : 
     496             : sql_exp *
     497           0 : exp_atom_flt(sql_allocator *sa, flt f)
     498             : {
     499             :         sql_subtype it;
     500             : 
     501           0 :         sql_find_subtype(&it, "real", 24, 0);
     502           0 :         return exp_atom(sa, atom_float(sa, &it, (dbl)f ));
     503             : }
     504             : 
     505             : sql_exp *
     506           0 : exp_atom_dbl(sql_allocator *sa, dbl f)
     507             : {
     508             :         sql_subtype it;
     509             : 
     510           0 :         sql_find_subtype(&it, "double", 53, 0);
     511           0 :         return exp_atom(sa, atom_float(sa, &it, (dbl)f ));
     512             : }
     513             : 
     514             : sql_exp *
     515       66591 : exp_atom_str(sql_allocator *sa, const char *s, sql_subtype *st)
     516             : {
     517       66591 :         return exp_atom(sa, atom_string(sa, st, s?sa_strdup(sa, s):NULL));
     518             : }
     519             : 
     520             : sql_exp *
     521      535052 : exp_atom_clob(sql_allocator *sa, const char *s)
     522             : {
     523             :         sql_subtype clob;
     524             : 
     525      535052 :         sql_find_subtype(&clob, "clob", 0, 0);
     526      535052 :         return exp_atom(sa, atom_string(sa, &clob, s?sa_strdup(sa, s):NULL));
     527             : }
     528             : 
     529             : sql_exp *
     530      204166 : exp_atom_ptr(sql_allocator *sa, void *s)
     531             : {
     532      204166 :         sql_subtype *t = sql_bind_localtype("ptr");
     533      204166 :         return exp_atom(sa, atom_ptr(sa, t, s));
     534             : }
     535             : 
     536             : sql_exp *
     537         617 : exp_atom_ref(sql_allocator *sa, int i, sql_subtype *tpe)
     538             : {
     539         617 :         sql_exp *e = exp_create(sa, e_atom);
     540         617 :         if (e == NULL)
     541             :                 return NULL;
     542         617 :         e->card = CARD_ATOM;
     543         617 :         e->flag = i;
     544         617 :         if (tpe)
     545          42 :                 e->tpe = *tpe;
     546             :         return e;
     547             : }
     548             : 
     549             : sql_exp *
     550       19409 : exp_null(sql_allocator *sa, sql_subtype *tpe)
     551             : {
     552       19409 :         atom *a = atom_general(sa, tpe, NULL);
     553       19409 :         return exp_atom(sa, a);
     554             : }
     555             : 
     556             : sql_exp *
     557           2 : exp_zero(sql_allocator *sa, sql_subtype *tpe)
     558             : {
     559           2 :         atom *a = atom_zero_value(sa, tpe);
     560           2 :         return exp_atom(sa, a);
     561             : }
     562             : 
     563             : atom *
     564         531 : exp_value(mvc *sql, sql_exp *e)
     565             : {
     566         531 :         if (!e || e->type != e_atom)
     567             :                 return NULL;
     568         529 :         if (e->l) {     /* literal */
     569             :                 return e->l;
     570          52 :         } else if (e->r) { /* param (ie not set) */
     571             :                 sql_var_name *vname = (sql_var_name*) e->r;
     572             :                 sql_var *var;
     573             : 
     574          52 :                 assert(e->flag != 0 || vname->sname); /* global variables must have a schema */
     575          52 :                 if (e->flag == 0 && (var = find_global_var(sql, mvc_bind_schema(sql, vname->sname), vname->name))) /* global variable */
     576           0 :                         return &(var->var);
     577          52 :                 return NULL;
     578             :         }
     579             :         return NULL;
     580             : }
     581             : 
     582             : sql_exp *
     583      103052 : exp_param_or_declared(sql_allocator *sa, const char *sname, const char *name, sql_subtype *tpe, int frame)
     584             : {
     585             :         sql_var_name *vname;
     586      103052 :         sql_exp *e = exp_create(sa, e_atom);
     587      103052 :         if (e == NULL)
     588             :                 return NULL;
     589             : 
     590      103052 :         e->r = sa_alloc(sa, sizeof(sql_var_name));
     591             :         vname = (sql_var_name*) e->r;
     592      103052 :         vname->sname = sname;
     593      103052 :         vname->name = name;
     594      103052 :         e->card = CARD_ATOM;
     595      103052 :         e->flag = frame;
     596      103052 :         if (tpe)
     597      103052 :                 e->tpe = *tpe;
     598             :         return e;
     599             : }
     600             : 
     601             : sql_exp *
     602       55322 : exp_values(sql_allocator *sa, list *exps)
     603             : {
     604       55322 :         sql_exp *e = exp_create(sa, e_atom);
     605       55322 :         if (e == NULL)
     606             :                 return NULL;
     607       55322 :         e->card = exps_card(exps);
     608       55322 :         e->f = exps;
     609       55322 :         return e;
     610             : }
     611             : 
     612             : list *
     613       28210 : exp_get_values(sql_exp *e)
     614             : {
     615       28210 :         if (is_atom(e->type) && e->f)
     616       28210 :                 return e->f;
     617             :         return NULL;
     618             : }
     619             : 
     620             : list *
     621       34740 : exp_types(sql_allocator *sa, list *exps)
     622             : {
     623       34740 :         list *l = sa_list(sa);
     624             : 
     625       34740 :         if (exps)
     626       77686 :                 for (node *n = exps->h; n; n = n->next)
     627       42946 :                         list_append(l, exp_subtype(n->data));
     628       34740 :         return l;
     629             : }
     630             : 
     631             : int
     632      776179 : have_nil(list *exps)
     633             : {
     634             :         int has_nil = 0;
     635             : 
     636      776179 :         if (exps)
     637     1634489 :                 for (node *n = exps->h; n && !has_nil; n = n->next) {
     638      858310 :                         sql_exp *e = n->data;
     639      858310 :                         has_nil |= has_nil(e);
     640             :                 }
     641      776179 :         return has_nil;
     642             : }
     643             : 
     644             : int
     645           1 : have_semantics(list *exps)
     646             : {
     647             :         int has_semantics = 0;
     648             : 
     649           1 :         if (exps)
     650           2 :                 for (node *n = exps->h; n && !has_semantics; n = n->next) {
     651           1 :                         sql_exp *e = n->data;
     652           2 :                         has_semantics |= is_compare(e->type) && is_semantics(e);
     653             :                 }
     654           1 :         return has_semantics;
     655             : }
     656             : 
     657             : sql_exp *
     658    13801750 : exp_column(sql_allocator *sa, const char *rname, const char *cname, sql_subtype *t, unsigned int card, int has_nils, int unique, int intern)
     659             : {
     660    13801750 :         sql_exp *e = exp_create(sa, e_column);
     661             : 
     662    13801750 :         if (e == NULL)
     663             :                 return NULL;
     664    13801750 :         assert(cname);
     665    13801750 :         e->card = card;
     666    13801750 :         e->alias.name = cname;
     667    13801750 :         e->alias.rname = rname;
     668    13801750 :         e->r = (char*)e->alias.name;
     669    13801750 :         e->l = (char*)e->alias.rname;
     670    13801750 :         if (t)
     671    13801459 :                 e->tpe = *t;
     672    13801750 :         if (!has_nils)
     673     2034453 :                 set_has_no_nil(e);
     674    13801750 :         if (unique)
     675     1348589 :                 set_unique(e);
     676    13801750 :         if (intern)
     677      944102 :                 set_intern(e);
     678             :         return e;
     679             : }
     680             : 
     681             : sql_exp *
     682     9875873 : exp_propagate(sql_allocator *sa, sql_exp *ne, sql_exp *oe)
     683             : {
     684     9875873 :         if (has_label(oe) &&
     685      659962 :            (oe->alias.rname == ne->alias.rname || (oe->alias.rname && ne->alias.rname && strcmp(oe->alias.rname, ne->alias.rname) == 0)) &&
     686      650024 :            (oe->alias.name == ne->alias.name || (oe->alias.name && ne->alias.name && strcmp(oe->alias.name, ne->alias.name) == 0)))
     687      649966 :                 ne->alias.label = oe->alias.label;
     688     9875873 :         if (is_intern(oe))
     689      397595 :                 set_intern(ne);
     690     9875873 :         if (is_anti(oe))
     691        6791 :                 set_anti(ne);
     692     9875873 :         if (is_semantics(oe))
     693      838809 :                 set_semantics(ne);
     694     9875873 :         if (is_symmetric(oe))
     695          12 :                 set_symmetric(ne);
     696     9875873 :         if (is_ascending(oe))
     697       20896 :                 set_ascending(ne);
     698     9875873 :         if (nulls_last(oe))
     699        4661 :                 set_nulls_last(ne);
     700     9875873 :         if (need_distinct(oe))
     701         670 :                 set_distinct(ne);
     702     9875873 :         if (zero_if_empty(oe))
     703           0 :                 set_zero_if_empty(ne);
     704     9875873 :         if (need_no_nil(oe))
     705       64941 :                 set_no_nil(ne);
     706     9875873 :         if (!has_nil(oe))
     707     1507294 :                 set_has_no_nil(ne);
     708     9875873 :         if (is_unique(oe))
     709     1010045 :                 set_unique(ne);
     710     9875873 :         if (is_basecol(oe))
     711     8298211 :                 set_basecol(ne);
     712     9875873 :         ne->p = prop_copy(sa, oe->p);
     713     9875873 :         return ne;
     714             : }
     715             : 
     716             : sql_exp *
     717      474108 : exp_ref(mvc *sql, sql_exp *e)
     718             : {
     719      474108 :         if (!exp_name(e))
     720        2754 :                 exp_label(sql->sa, e, ++sql->label);
     721      474108 :         return 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);
     722             : }
     723             : 
     724             : sql_exp *
     725       11021 : exp_ref_save(mvc *sql, sql_exp *e)
     726             : {
     727       11021 :         if (is_atom(e->type))
     728        3956 :                 return exp_copy(sql, e);
     729        7065 :         if (!exp_name(e) || is_convert(e->type))
     730          71 :                 exp_label(sql->sa, e, ++sql->label);
     731        7065 :         if (e->type != e_column)
     732        3843 :                 e->ref = 1;
     733        7065 :         sql_exp *ne = exp_ref(sql, e);
     734        7065 :         if (ne && is_freevar(e))
     735          22 :                 set_freevar(ne, is_freevar(e)-1);
     736             :         return ne;
     737             : }
     738             : 
     739             : sql_exp *
     740     4179981 : exp_alias(sql_allocator *sa, const char *arname, const char *acname, const char *org_rname, const char *org_cname, sql_subtype *t, unsigned int card, int has_nils, int unique, int intern)
     741             : {
     742     4179981 :         sql_exp *e = exp_column(sa, org_rname, org_cname, t, card, has_nils, unique, intern);
     743             : 
     744     4179981 :         if (e == NULL)
     745             :                 return NULL;
     746     4179981 :         assert(acname && org_cname);
     747     4193481 :         exp_setname(sa, e, (arname)?arname:org_rname, acname);
     748     4179981 :         return e;
     749             : }
     750             : 
     751             : sql_exp *
     752     6497274 : exp_alias_or_copy( mvc *sql, const char *tname, const char *cname, sql_rel *orel, sql_exp *old)
     753             : {
     754             :         sql_exp *ne = NULL;
     755             : 
     756     6497274 :         if (!tname)
     757     5873159 :                 tname = exp_relname(old);
     758             : 
     759     6497274 :         if (!cname && exp_name(old) && has_label(old)) {
     760           0 :                 ne = exp_column(sql->sa, exp_relname(old), exp_name(old), exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, has_nil(old), is_unique(old), is_intern(old));
     761           0 :                 return exp_propagate(sql->sa, ne, old);
     762     6497274 :         } else if (!cname) {
     763       25231 :                 exp_label(sql->sa, old, ++sql->label);
     764       25231 :                 ne = exp_column(sql->sa, exp_relname(old), exp_name(old), exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, has_nil(old), is_unique(old), is_intern(old));
     765       25231 :                 return exp_propagate(sql->sa, ne, old);
     766     6472043 :         } else if (cname && !old->alias.name) {
     767        3090 :                 exp_setname(sql->sa, old, tname, cname);
     768             :         }
     769     6472043 :         ne = exp_column(sql->sa, tname, cname, exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, has_nil(old), is_unique(old), is_intern(old));
     770     6472043 :         return exp_propagate(sql->sa, ne, old);
     771             : }
     772             : 
     773             : sql_exp *
     774           0 : exp_alias_ref(mvc *sql, sql_exp *e)
     775             : {
     776             :         sql_exp *ne = NULL;
     777           0 :         const char *tname = exp_relname(e);
     778           0 :         const char *cname = exp_name(e);
     779             : 
     780           0 :         if (!has_label(e))
     781           0 :                 exp_label(sql->sa, e, ++sql->label);
     782           0 :         ne = exp_ref(sql, e);
     783           0 :         exp_setname(sql->sa, ne, tname, cname);
     784           0 :         return exp_propagate(sql->sa, ne, e);
     785             : }
     786             : 
     787             : sql_exp *
     788       15145 : exp_set(sql_allocator *sa, const char *sname, const char *name, sql_exp *val, int level)
     789             : {
     790       15145 :         sql_exp *e = exp_create(sa, e_psm);
     791             : 
     792       15145 :         if (e == NULL)
     793             :                 return NULL;
     794       15145 :         e->alias.rname = sname;
     795       15145 :         e->alias.name = name;
     796       15145 :         e->l = val;
     797       15145 :         e->flag = PSM_SET + SET_PSM_LEVEL(level);
     798       15145 :         return e;
     799             : }
     800             : 
     801             : sql_exp *
     802        8192 : exp_var(sql_allocator *sa, const char *sname, const char *name, sql_subtype *type, int level)
     803             : {
     804        8192 :         sql_exp *e = exp_create(sa, e_psm);
     805             : 
     806        8192 :         if (e == NULL)
     807             :                 return NULL;
     808        8192 :         e->alias.rname = sname;
     809        8192 :         e->alias.name = name;
     810        8192 :         e->tpe = *type;
     811        8192 :         e->flag = PSM_VAR + SET_PSM_LEVEL(level);
     812        8192 :         return e;
     813             : }
     814             : 
     815             : sql_exp *
     816         105 : exp_table(sql_allocator *sa, const char *name, sql_table *t, int level)
     817             : {
     818         105 :         sql_exp *e = exp_create(sa, e_psm);
     819             : 
     820         105 :         if (e == NULL)
     821             :                 return NULL;
     822         105 :         e->alias.rname = NULL;
     823         105 :         e->alias.name = name;
     824         105 :         e->f = t;
     825         105 :         e->flag = PSM_VAR + SET_PSM_LEVEL(level);
     826         105 :         return e;
     827             : }
     828             : 
     829             : sql_exp *
     830       18973 : exp_return(sql_allocator *sa, sql_exp *val, int level)
     831             : {
     832       18973 :         sql_exp *e = exp_create(sa, e_psm);
     833             : 
     834       18973 :         if (e == NULL)
     835             :                 return NULL;
     836       18973 :         e->l = val;
     837       18973 :         e->flag = PSM_RETURN + SET_PSM_LEVEL(level);
     838       18973 :         return e;
     839             : }
     840             : 
     841             : sql_exp *
     842         949 : exp_while(sql_allocator *sa, sql_exp *cond, list *stmts)
     843             : {
     844         949 :         sql_exp *e = exp_create(sa, e_psm);
     845             : 
     846         949 :         if (e == NULL)
     847             :                 return NULL;
     848         949 :         e->l = cond;
     849         949 :         e->r = stmts;
     850         949 :         e->flag = PSM_WHILE;
     851         949 :         return e;
     852             : }
     853             : 
     854             : sql_exp *
     855        9570 : exp_if(sql_allocator *sa, sql_exp *cond, list *if_stmts, list *else_stmts)
     856             : {
     857        9570 :         sql_exp *e = exp_create(sa, e_psm);
     858             : 
     859        9570 :         if (e == NULL)
     860             :                 return NULL;
     861        9570 :         e->l = cond;
     862        9570 :         e->r = if_stmts;
     863        9570 :         e->f = else_stmts;
     864        9570 :         e->flag = PSM_IF;
     865        9570 :         return e;
     866             : }
     867             : 
     868             : sql_exp *
     869       69834 : exp_rel(mvc *sql, sql_rel *rel)
     870             : {
     871       69834 :         sql_exp *e = exp_create(sql->sa, e_psm);
     872             : 
     873       69834 :         if (e == NULL)
     874             :                 return NULL;
     875       69834 :         e->l = rel;
     876       69834 :         e->flag = PSM_REL;
     877       69834 :         e->card = is_single(rel)?CARD_ATOM:rel->card;
     878             :         assert(rel);
     879       69834 :         if (is_project(rel->op)) {
     880       54541 :                 sql_exp *last = rel->exps->t->data;
     881       54541 :                 sql_subtype *t = exp_subtype(last);
     882       54541 :                 e->tpe = t ? *t : (sql_subtype) {0};
     883             :         }
     884             :         return e;
     885             : }
     886             : 
     887             : sql_exp *
     888         400 : exp_exception(sql_allocator *sa, sql_exp *cond, const char *error_message)
     889             : {
     890         400 :         sql_exp *e = exp_create(sa, e_psm);
     891             : 
     892         400 :         if (e == NULL)
     893             :                 return NULL;
     894         400 :         e->l = cond;
     895         400 :         e->r = sa_strdup(sa, error_message);
     896         400 :         e->flag = PSM_EXCEPTION;
     897         400 :         return e;
     898             : }
     899             : 
     900             : /* Set a name (alias) for the expression, such that we can refer
     901             :    to this expression by this simple name.
     902             :  */
     903             : void
     904     4989098 : exp_setname(sql_allocator *sa, sql_exp *e, const char *rname, const char *name )
     905             : {
     906     4989098 :         e->alias.label = 0;
     907     4989098 :         if (name)
     908     4869358 :                 e->alias.name = sa_strdup(sa, name);
     909     4989098 :         e->alias.rname = (rname)?sa_strdup(sa, rname):NULL;
     910     4989098 : }
     911             : 
     912             : void
     913      119701 : noninternexp_setname(sql_allocator *sa, sql_exp *e, const char *rname, const char *name )
     914             : {
     915      119701 :         if (!is_intern(e))
     916      119699 :                 exp_setname(sa, e, rname, name);
     917      119701 : }
     918             : 
     919             : void
     920      589311 : exp_setalias(sql_exp *e, const char *rname, const char *name )
     921             : {
     922      589311 :         e->alias.label = 0;
     923      589311 :         e->alias.name = name;
     924      589311 :         e->alias.rname = rname;
     925      589311 : }
     926             : 
     927             : void
     928     2303361 : exp_prop_alias(sql_allocator *sa, sql_exp *e, sql_exp *oe )
     929             : {
     930     2303361 :         e->ref = oe->ref;
     931     2303361 :         if (oe->alias.name == NULL && exp_has_rel(oe)) {
     932        9770 :                 sql_rel *r = exp_rel_get_rel(sa, oe);
     933        9770 :                 if (!is_project(r->op))
     934             :                         return ;
     935        9770 :                 oe = r->exps->t->data;
     936             :         }
     937     2303361 :         e->alias = oe->alias;
     938             : }
     939             : 
     940             : str
     941     3187710 : number2name(str s, int len, int i)
     942             : {
     943     3187710 :         s[--len] = 0;
     944    10037983 :         while(i>0) {
     945     6850273 :                 s[--len] = '0' + (i & 7);
     946     6850273 :                 i >>= 3;
     947             :         }
     948     3187710 :         s[--len] = '%';
     949     3187710 :         return s + len;
     950             : }
     951             : 
     952             : void
     953     1889268 : exp_setrelname(sql_allocator *sa, sql_exp *e, int nr)
     954             : {
     955             :         char name[16], *nme;
     956             : 
     957     1889268 :         nme = number2name(name, sizeof(name), nr);
     958     1889268 :         e->alias.label = 0;
     959     1889268 :         e->alias.rname = sa_strdup(sa, nme);
     960     1889268 : }
     961             : 
     962             : char *
     963     1256637 : make_label(sql_allocator *sa, int nr)
     964             : {
     965             :         char name[16], *nme;
     966             : 
     967     1256637 :         nme = number2name(name, sizeof(name), nr);
     968     1256637 :         return sa_strdup(sa, nme);
     969             : }
     970             : 
     971             : sql_exp*
     972     1249047 : exp_label(sql_allocator *sa, sql_exp *e, int nr)
     973             : {
     974     1249047 :         assert(nr > 0);
     975     1249047 :         e->alias.label = nr;
     976     1249047 :         e->alias.rname = e->alias.name = make_label(sa, nr);
     977     1249047 :         return e;
     978             : }
     979             : 
     980             : sql_exp*
     981           0 : exp_label_table(sql_allocator *sa, sql_exp *e, int nr)
     982             : {
     983           0 :         e->alias.rname = make_label(sa, nr);
     984           0 :         return e;
     985             : }
     986             : 
     987             : list*
     988        6804 : exps_label(sql_allocator *sa, list *exps, int nr)
     989             : {
     990             :         node *n;
     991             : 
     992        6804 :         if (!exps)
     993             :                 return NULL;
     994       18787 :         for (n = exps->h; n; n = n->next)
     995       11983 :                 n->data = exp_label(sa, n->data, nr++);
     996             :         return exps;
     997             : }
     998             : 
     999             : void
    1000           0 : exp_swap( sql_exp *e )
    1001             : {
    1002           0 :         sql_exp *s = e->l;
    1003             : 
    1004           0 :         e->l = e->r;
    1005           0 :         e->r = s;
    1006           0 :         e->flag = swap_compare((comp_type)e->flag);
    1007           0 : }
    1008             : 
    1009             : sql_subtype *
    1010    20183598 : exp_subtype( sql_exp *e )
    1011             : {
    1012    20183611 :         switch(e->type) {
    1013     3972902 :         case e_atom: {
    1014     3972902 :                 if (e->l) {
    1015             :                         atom *a = e->l;
    1016     3708449 :                         return atom_type(a);
    1017      264453 :                 } else if (e->tpe.type) { /* atom reference */
    1018      263745 :                         return &e->tpe;
    1019         708 :                 } else if (e->f) {
    1020          13 :                         list *vals = exp_get_values(e);
    1021          13 :                         if (!list_empty(vals))
    1022          13 :                                 return exp_subtype(vals->h->data);
    1023             :                 }
    1024             :                 break;
    1025             :         }
    1026    14069836 :         case e_convert:
    1027             :         case e_column:
    1028    14069836 :                 if (e->tpe.type)
    1029    14069752 :                         return &e->tpe;
    1030             :                 break;
    1031     2070874 :         case e_aggr:
    1032             :         case e_func: {
    1033     2070874 :                 if (e->f) {
    1034             :                         sql_subfunc *f = e->f;
    1035     2070874 :                         if (f->res && list_length(f->res) == 1)
    1036     2060432 :                                 return f->res->h->data;
    1037             :                 }
    1038             :                 return NULL;
    1039             :         }
    1040         323 :         case e_cmp:
    1041         323 :                 return sql_bind_localtype("bit");
    1042       69676 :         case e_psm:
    1043       69676 :                 if (e->tpe.type)
    1044       69656 :                         return &e->tpe;
    1045             :                 /* fall through */
    1046             :         default:
    1047             :                 return NULL;
    1048             :         }
    1049             :         return NULL;
    1050             : }
    1051             : 
    1052             : const char *
    1053    23566792 : exp_name( sql_exp *e )
    1054             : {
    1055    23586231 :         if (e->alias.name)
    1056             :                 return e->alias.name;
    1057     1263315 :         if (e->type == e_convert && e->l)
    1058             :                 return exp_name(e->l);
    1059     1256840 :         if (e->type == e_psm && e->l) { /* subquery return name of last expression */
    1060             :                 sql_rel *r = e->l;
    1061       12964 :                 if (is_project(r->op))
    1062       12964 :                         return exp_name(r->exps->t->data);
    1063             :         }
    1064             :         return NULL;
    1065             : }
    1066             : 
    1067             : const char *
    1068    16445547 : exp_relname( sql_exp *e )
    1069             : {
    1070    16448909 :         if (e->alias.rname)
    1071             :                 return e->alias.rname;
    1072      378419 :         if (!e->alias.name && e->type == e_convert && e->l)
    1073             :                 return exp_relname(e->l);
    1074      376193 :         if (!e->alias.name && e->type == e_psm && e->l) { /* subquery return name of last expression */
    1075             :                 sql_rel *r = e->l;
    1076        1136 :                 if (is_project(r->op))
    1077        1136 :                         return exp_relname(r->exps->t->data);
    1078             :         }
    1079             :         return NULL;
    1080             : }
    1081             : 
    1082             : const char *
    1083       21098 : exp_find_rel_name(sql_exp *e)
    1084             : {
    1085       21098 :         if (e->alias.rname)
    1086             :                 return e->alias.rname;
    1087        1312 :         switch(e->type) {
    1088             :         case e_column:
    1089             :                 break;
    1090           0 :         case e_convert:
    1091           0 :                 return exp_find_rel_name(e->l);
    1092             :         default:
    1093             :                 return NULL;
    1094             :         }
    1095             :         return NULL;
    1096             : }
    1097             : 
    1098             : unsigned int
    1099     7324279 : exp_card( sql_exp *e )
    1100             : {
    1101     7324279 :         return e->card;
    1102             : }
    1103             : 
    1104             : const char *
    1105           0 : exp_func_name( sql_exp *e )
    1106             : {
    1107           0 :         if (e->type == e_func && e->f) {
    1108             :                 sql_subfunc *f = e->f;
    1109           0 :                 return f->func->base.name;
    1110             :         }
    1111           0 :         if (e->alias.name)
    1112             :                 return e->alias.name;
    1113           0 :         if (e->type == e_convert && e->l)
    1114           0 :                 return exp_name(e->l);
    1115             :         return NULL;
    1116             : }
    1117             : 
    1118             : int
    1119     3532911 : exp_cmp( sql_exp *e1, sql_exp *e2)
    1120             : {
    1121     3532911 :         return (e1 == e2)?0:-1;
    1122             : }
    1123             : 
    1124             : #define alias_cmp(e1, e2) \
    1125             :         do { \
    1126             :                 if (e1->alias.rname && e2->alias.rname && strcmp(e1->alias.rname, e2->alias.rname) == 0) \
    1127             :                         return strcmp(e1->alias.name, e2->alias.name); \
    1128             :                 if (!e1->alias.rname && !e2->alias.rname && e1->alias.label == e2->alias.label && e1->alias.name && e2->alias.name) \
    1129             :                         return strcmp(e1->alias.name, e2->alias.name); \
    1130             :         } while (0);
    1131             : 
    1132             : int
    1133      185760 : exp_equal( sql_exp *e1, sql_exp *e2)
    1134             : {
    1135      185760 :         if (e1 == e2)
    1136             :                 return 0;
    1137      185760 :         alias_cmp(e1, e2);
    1138             :         return -1;
    1139             : }
    1140             : 
    1141             : int
    1142     3532829 : exp_match( sql_exp *e1, sql_exp *e2)
    1143             : {
    1144     3532829 :         if (exp_cmp(e1, e2) == 0)
    1145             :                 return 1;
    1146     3483203 :         if (e1->type == e2->type && e1->type == e_column) {
    1147      796521 :                 if (e1->l != e2->l && (!e1->l || !e2->l || strcmp(e1->l, e2->l) != 0))
    1148             :                         return 0;
    1149      453971 :                 if (!e1->r || !e2->r || strcmp(e1->r, e2->r) != 0)
    1150             :                         return 0;
    1151      158583 :                 return 1;
    1152             :         }
    1153     2686682 :         if (e1->type == e2->type && e1->type == e_func) {
    1154      712690 :                 if (is_identity(e1, NULL) && is_identity(e2, NULL)) {
    1155           0 :                         list *args1 = e1->l;
    1156           0 :                         list *args2 = e2->l;
    1157             : 
    1158           0 :                         if (list_length(args1) == list_length(args2) && list_length(args1) == 1) {
    1159           0 :                                 sql_exp *ne1 = args1->h->data;
    1160           0 :                                 sql_exp *ne2 = args2->h->data;
    1161             : 
    1162           0 :                                 if (exp_match(ne1,ne2))
    1163           0 :                                         return 1;
    1164             :                         }
    1165             :                 }
    1166             :         }
    1167             :         return 0;
    1168             : }
    1169             : 
    1170             : /* list already contains matching expression */
    1171             : sql_exp*
    1172       80758 : exps_find_exp( list *l, sql_exp *e)
    1173             : {
    1174             :         node *n;
    1175             : 
    1176       80758 :         if (!l || !l->h)
    1177             :                 return NULL;
    1178             : 
    1179      239805 :         for(n=l->h; n; n = n->next) {
    1180      238451 :                 if (exp_match(n->data, e) || exp_refers(n->data, e))
    1181       79014 :                         return n->data;
    1182             :         }
    1183             :         return NULL;
    1184             : }
    1185             : 
    1186             : 
    1187             : /* c refers to the parent p */
    1188             : int
    1189      467794 : exp_refers( sql_exp *p, sql_exp *c)
    1190             : {
    1191      467794 :         if (c->type == e_column) {
    1192      200990 :                 if (!p->alias.name || !c->r || strcmp(p->alias.name, c->r) != 0)
    1193             :                         return 0;
    1194       23867 :                 if (c->l && ((p->alias.rname && strcmp(p->alias.rname, c->l) != 0) || (!p->alias.rname && strcmp(p->l, c->l) != 0)))
    1195             :                         return 0;
    1196        8890 :                 return 1;
    1197             :         }
    1198             :         return 0;
    1199             : }
    1200             : 
    1201             : int
    1202           0 : exp_match_col_exps( sql_exp *e, list *l)
    1203             : {
    1204             :         node *n;
    1205             : 
    1206           0 :         for(n=l->h; n; n = n->next) {
    1207           0 :                 sql_exp *re = n->data;
    1208           0 :                 sql_exp *re_r = re->r;
    1209             : 
    1210           0 :                 if (re->type == e_cmp && re->flag == cmp_or)
    1211           0 :                         return exp_match_col_exps(e, re->l) &&
    1212           0 :                                exp_match_col_exps(e, re->r);
    1213             : 
    1214           0 :                 if (re->type != e_cmp || !re_r || re_r->card != 1 || !exp_match_exp(e, re->l))
    1215           0 :                         return 0;
    1216             :         }
    1217             :         return 1;
    1218             : }
    1219             : 
    1220             : int
    1221       11165 : exps_match_col_exps( sql_exp *e1, sql_exp *e2)
    1222             : {
    1223       11165 :         sql_exp *e1_r = e1->r;
    1224       11165 :         sql_exp *e2_r = e2->r;
    1225             : 
    1226       11165 :         if (e1->type != e_cmp || e2->type != e_cmp)
    1227             :                 return 0;
    1228             : 
    1229       11165 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1230        7002 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1231        6157 :                 return exp_match_exp(e1->l, e2->l);
    1232             : 
    1233        5008 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1234         845 :             (e2->flag == cmp_in || e2->flag == cmp_notin))
    1235         840 :                 return exp_match_exp(e1->l, e2->l);
    1236        4168 :         if ((e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1237        2120 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1238        1594 :                 return exp_match_exp(e1->l, e2->l);
    1239             : 
    1240        2574 :         if ((e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1241         526 :             (e2->flag == cmp_in || e2->flag == cmp_notin))
    1242         526 :                 return exp_match_exp(e1->l, e2->l);
    1243             : 
    1244        2048 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1245           5 :             e2->flag == cmp_or)
    1246           0 :                 return exp_match_col_exps(e1->l, e2->l) &&
    1247           0 :                        exp_match_col_exps(e1->l, e2->r);
    1248             : 
    1249        2048 :         if (e1->flag == cmp_or &&
    1250           0 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1251           0 :                 return exp_match_col_exps(e2->l, e1->l) &&
    1252           0 :                        exp_match_col_exps(e2->l, e1->r);
    1253             : 
    1254        2048 :         if (e1->flag == cmp_or && e2->flag == cmp_or) {
    1255           0 :                 list *l = e1->l, *r = e1->r;
    1256           0 :                 sql_exp *el = l->h->data;
    1257           0 :                 sql_exp *er = r->h->data;
    1258             : 
    1259           0 :                 return list_length(l) == 1 && list_length(r) == 1 &&
    1260           0 :                        exps_match_col_exps(el, e2) &&
    1261           0 :                        exps_match_col_exps(er, e2);
    1262             :         }
    1263             :         return 0;
    1264             : }
    1265             : 
    1266             : int
    1267       30107 : exp_match_list( list *l, list *r)
    1268             : {
    1269             :         node *n, *m;
    1270             :         char *lu, *ru;
    1271             :         int lc = 0, rc = 0, match = 0;
    1272             : 
    1273       30107 :         if (!l || !r)
    1274          25 :                 return l == r;
    1275       30082 :         if (list_length(l) != list_length(r) || list_length(l) == 0 || list_length(r) == 0)
    1276         366 :                 return 0;
    1277       29716 :         lu = ZNEW_ARRAY(char, list_length(l));
    1278       29716 :         ru = ZNEW_ARRAY(char, list_length(r));
    1279       29716 :         if (!lu || !ru) {
    1280           0 :                 _DELETE(lu);
    1281           0 :                 _DELETE(ru);
    1282           0 :                 return 0;
    1283             :         }
    1284       95228 :         for (n = l->h, lc = 0; n; n = n->next, lc++) {
    1285       65512 :                 sql_exp *le = n->data;
    1286             : 
    1287      233708 :                 for ( m = r->h, rc = 0; m; m = m->next, rc++) {
    1288      168196 :                         sql_exp *re = m->data;
    1289             : 
    1290      168196 :                         if (!ru[rc] && exp_match_exp(le,re)) {
    1291        6150 :                                 lu[lc] = 1;
    1292        6150 :                                 ru[rc] = 1;
    1293             :                                 match = 1;
    1294             :                         }
    1295             :                 }
    1296             :         }
    1297       36665 :         for (n = l->h, lc = 0; n && match; n = n->next, lc++)
    1298        6949 :                 if (!lu[lc])
    1299             :                         match = 0;
    1300       33622 :         for (n = r->h, rc = 0; n && match; n = n->next, rc++)
    1301        3906 :                 if (!ru[rc])
    1302             :                         match = 0;
    1303       29716 :         _DELETE(lu);
    1304       29716 :         _DELETE(ru);
    1305       29716 :         return match;
    1306             : }
    1307             : 
    1308             : static int
    1309      177465 : exps_equal( list *l, list *r)
    1310             : {
    1311             :         node *n, *m;
    1312             : 
    1313      177465 :         if (!l || !r)
    1314       28856 :                 return l == r;
    1315      148609 :         if (list_length(l) != list_length(r))
    1316             :                 return 0;
    1317      201280 :         for (n = l->h, m = r->h; n && m; n = n->next, m = m->next) {
    1318      175693 :                 sql_exp *le = n->data, *re = m->data;
    1319             : 
    1320      175693 :                 if (!exp_match_exp(le,re))
    1321             :                         return 0;
    1322             :         }
    1323             :         return 1;
    1324             : }
    1325             : 
    1326             : int
    1327     3217683 : exp_match_exp( sql_exp *e1, sql_exp *e2)
    1328             : {
    1329     3217683 :         if (exp_match(e1, e2))
    1330             :                 return 1;
    1331     3107128 :         if (is_ascending(e1) != is_ascending(e2) || nulls_last(e1) != nulls_last(e2) || zero_if_empty(e1) != zero_if_empty(e2) ||
    1332     3016493 :                 need_no_nil(e1) != need_no_nil(e2) || is_anti(e1) != is_anti(e2) || is_semantics(e1) != is_semantics(e2) ||
    1333     2216804 :                 is_symmetric(e1) != is_symmetric(e2) || is_unique(e1) != is_unique(e2) || need_distinct(e1) != need_distinct(e2))
    1334             :                 return 0;
    1335     2101375 :         if (e1->type == e2->type) {
    1336     1271860 :                 switch(e1->type) {
    1337       49830 :                 case e_cmp:
    1338       65414 :                         if (e1->flag == e2->flag && !is_complex_exp(e1->flag) &&
    1339       17311 :                             exp_match_exp(e1->l, e2->l) && exp_match_exp(e1->r, e2->r) &&
    1340          64 :                             ((!e1->f && !e2->f) || (e1->f && e2->f && exp_match_exp(e1->f, e2->f))))
    1341          61 :                                 return 1;
    1342       51222 :                         else if (e1->flag == e2->flag && e1->flag == cmp_or &&
    1343        1454 :                             exp_match_list(e1->l, e2->l) && exp_match_list(e1->r, e2->r))
    1344             :                                 return 1;
    1345       49768 :                         else if (e1->flag == e2->flag &&
    1346       18941 :                                 (e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1347        1144 :                             exp_match_exp(e1->l, e2->l) && exp_match_list(e1->r, e2->r))
    1348             :                                 return 1;
    1349       64065 :                         else if (e1->flag == e2->flag && (e1->flag == cmp_equal || e1->flag == cmp_notequal) &&
    1350       14310 :                                 exp_match_exp(e1->l, e2->r) && exp_match_exp(e1->r, e2->l))
    1351           1 :                                 return 1; /* = and <> operations are reflective, so exp_match_exp can be called crossed */
    1352             :                         break;
    1353      195237 :                 case e_convert:
    1354      288606 :                         if (!subtype_cmp(exp_totype(e1), exp_totype(e2)) &&
    1355      162525 :                             !subtype_cmp(exp_fromtype(e1), exp_fromtype(e2)) &&
    1356       69156 :                             exp_match_exp(e1->l, e2->l))
    1357        3824 :                                 return 1;
    1358             :                         break;
    1359       79041 :                 case e_aggr:
    1360      120075 :                         if (!subfunc_cmp(e1->f, e2->f) && /* equal aggregation*/
    1361       41034 :                             exps_equal(e1->l, e2->l))
    1362        1811 :                                 return 1;
    1363             :                         break;
    1364      392055 :                 case e_func: {
    1365      392055 :                         sql_subfunc *e1f = (sql_subfunc*) e1->f;
    1366      392055 :                         const char *sname = e1f->func->s ? e1f->func->s->base.name : NULL;
    1367      392055 :                         int (*comp)(list*, list*) = is_commutative(sname, e1f->func->base.name) ? exp_match_list : exps_equal;
    1368             : 
    1369      784110 :                         if (!e1f->func->side_effect &&
    1370      525324 :                                 !subfunc_cmp(e1f, e2->f) && /* equal functions */
    1371      160538 :                                 comp(e1->l, e2->l) &&
    1372             :                                 /* optional order by expressions */
    1373       27269 :                                 exps_equal(e1->r, e2->r))
    1374       27269 :                                         return 1;
    1375             :                         } break;
    1376      111773 :                 case e_atom:
    1377      111773 :                         if (e1->l && e2->l && !atom_cmp(e1->l, e2->l))
    1378             :                                 return 1;
    1379       82708 :                         if (e1->f && e2->f && exp_match_list(e1->f, e2->f))
    1380             :                                 return 1;
    1381       82679 :                         if (e1->r && e2->r && e1->flag == e2->flag && !subtype_cmp(&e1->tpe, &e2->tpe)) {
    1382           0 :                                 sql_var_name *v1 = (sql_var_name*) e1->r, *v2 = (sql_var_name*) e2->r;
    1383           0 :                                 if (((!v1->sname && !v2->sname) || (v1->sname && v2->sname && strcmp(v1->sname, v2->sname) == 0)) &&
    1384           0 :                                         ((!v1->name && !v2->name) || (v1->name && v2->name && strcmp(v1->name, v2->name) == 0)))
    1385             :                                         return 1;
    1386             :                         }
    1387       82679 :                         if (!e1->l && !e1->r && !e1->f && !e2->l && !e2->r && !e2->f && e1->flag == e2->flag && !subtype_cmp(&e1->tpe, &e2->tpe))
    1388           0 :                                 return 1;
    1389             :                         break;
    1390             :                 default:
    1391             :                         break;
    1392             :                 }
    1393      829515 :         }
    1394             :         return 0;
    1395             : }
    1396             : 
    1397             : sql_exp *
    1398      119659 : exps_any_match(list *l, sql_exp *e)
    1399             : {
    1400      119659 :         if (!l)
    1401             :                 return NULL;
    1402      378696 :         for (node *n = l->h; n ; n = n->next) {
    1403      328419 :                 sql_exp *ne = (sql_exp *) n->data;
    1404      328419 :                 if (exp_match_exp(ne, e))
    1405       69382 :                         return ne;
    1406             :         }
    1407             :         return NULL;
    1408             : }
    1409             : 
    1410             : static int
    1411         123 : exp_no_alias(sql_exp *e1, sql_exp *e2)
    1412             : {
    1413         123 :         alias_cmp(e1, e2);
    1414             :         /* at least one of the expressions don't have an alias, so there's a match */
    1415             :         return 0;
    1416             : }
    1417             : 
    1418             : sql_exp *
    1419       18205 : exps_any_match_same_or_no_alias(list *l, sql_exp *e)
    1420             : {
    1421       18205 :         if (!l)
    1422             :                 return NULL;
    1423       50941 :         for (node *n = l->h; n ; n = n->next) {
    1424       32829 :                 sql_exp *ne = (sql_exp *) n->data;
    1425       32829 :                 if ((exp_match(ne, e) || exp_refers(ne, e) || exp_match_exp(ne, e)) && exp_no_alias(e, ne) == 0)
    1426          93 :                         return ne;
    1427             :         }
    1428             :         return NULL;
    1429             : }
    1430             : 
    1431             : static int
    1432           6 : exps_are_joins( list *l )
    1433             : {
    1434           6 :         if (l)
    1435          15 :                 for (node *n = l->h; n; n = n->next) {
    1436           9 :                         sql_exp *e = n->data;
    1437             : 
    1438           9 :                         if (exp_is_join_exp(e))
    1439             :                                 return -1;
    1440             :                 }
    1441             :         return 0;
    1442             : }
    1443             : 
    1444             : int
    1445         195 : exp_is_join_exp(sql_exp *e)
    1446             : {
    1447         195 :         if (exp_is_join(e, NULL) == 0)
    1448             :                 return 0;
    1449          14 :         if (e->type == e_cmp && e->flag == cmp_or && e->card >= CARD_AGGR)
    1450           3 :                 if (exps_are_joins(e->l) == 0 && exps_are_joins(e->r) == 0)
    1451           3 :                         return 0;
    1452             :         return -1;
    1453             : }
    1454             : 
    1455             : static int
    1456      571823 : exp_is_complex_select( sql_exp *e )
    1457             : {
    1458      611214 :         switch (e->type) {
    1459         320 :         case e_atom: {
    1460         320 :                 if (e->f) {
    1461           0 :                         int r = (e->card == CARD_ATOM);
    1462             :                         list *l = e->f;
    1463             : 
    1464           0 :                         if (r)
    1465           0 :                                 for (node *n = l->h; n && !r; n = n->next)
    1466           0 :                                         r |= exp_is_complex_select(n->data);
    1467           0 :                         return r;
    1468             :                 }
    1469             :                 return 0;
    1470             :         }
    1471       39391 :         case e_convert:
    1472       39391 :                 return exp_is_complex_select(e->l);
    1473        1177 :         case e_func:
    1474             :         case e_aggr:
    1475             :         {
    1476        1177 :                 int r = (e->card == CARD_ATOM);
    1477        1177 :                 list *l = e->l;
    1478             : 
    1479        1177 :                 if (r && l)
    1480          15 :                         for (node *n = l->h; n && !r; n = n->next)
    1481           0 :                                 r |= exp_is_complex_select(n->data);
    1482             :                 return r;
    1483             :         }
    1484             :         case e_psm:
    1485             :                 return 1;
    1486      570326 :         case e_column:
    1487             :         case e_cmp:
    1488             :         default:
    1489      570326 :                 return 0;
    1490             :         }
    1491             : }
    1492             : 
    1493             : static int
    1494      285913 : complex_select(sql_exp *e)
    1495             : {
    1496      285913 :         sql_exp *l = e->l, *r = e->r;
    1497             : 
    1498      285913 :         if (exp_is_complex_select(l) || exp_is_complex_select(r))
    1499          15 :                 return 1;
    1500             :         return 0;
    1501             : }
    1502             : 
    1503             : static int
    1504         919 : distinct_rel(sql_exp *e, const char **rname)
    1505             : {
    1506             :         const char *e_rname = NULL;
    1507             : 
    1508        1161 :         switch(e->type) {
    1509         657 :         case e_column:
    1510         657 :                 e_rname = exp_relname(e);
    1511             : 
    1512         657 :                 if (*rname && e_rname && strcmp(*rname, e_rname) == 0)
    1513             :                         return 1;
    1514         509 :                 if (!*rname) {
    1515         321 :                         *rname = e_rname;
    1516         321 :                         return 1;
    1517             :                 }
    1518             :                 break;
    1519         144 :         case e_aggr:
    1520             :         case e_func:
    1521         144 :                 if (e->l) {
    1522             :                         int m = 1;
    1523             :                         list *l = e->l;
    1524             :                         node *n;
    1525             : 
    1526         437 :                         for(n=l->h; n && m; n = n->next) {
    1527         293 :                                 sql_exp *ae = n->data;
    1528             : 
    1529         293 :                                 m = distinct_rel(ae, rname);
    1530             :                         }
    1531         144 :                         return m;
    1532             :                 }
    1533             :                 return 0;
    1534             :         case e_atom:
    1535             :                 return 1;
    1536         242 :         case e_convert:
    1537         242 :                 return distinct_rel(e->l, rname);
    1538           0 :         default:
    1539           0 :                 return 0;
    1540             :         }
    1541             :         return 0;
    1542             : }
    1543             : 
    1544             : int
    1545    41724515 : rel_has_exp(sql_rel *rel, sql_exp *e)
    1546             : {
    1547    41724515 :         if (rel_find_exp(rel, e) != NULL)
    1548     4524138 :                 return 0;
    1549             :         return -1;
    1550             : }
    1551             : 
    1552             : int
    1553           3 : rel_has_exps(sql_rel *rel, list *exps)
    1554             : {
    1555           3 :         if (list_empty(exps))
    1556             :                 return 0;
    1557           3 :         for (node *n = exps->h; n; n = n->next)
    1558           3 :                 if (rel_has_exp(rel, n->data) >= 0)
    1559             :                         return 0;
    1560             :         return -1;
    1561             : }
    1562             : 
    1563             : int
    1564        5303 : rel_has_all_exps(sql_rel *rel, list *exps)
    1565             : {
    1566        5303 :         if (list_empty(exps))
    1567             :                 return 1;
    1568       10628 :         for (node *n = exps->h; n; n = n->next)
    1569       10606 :                 if (rel_has_exp(rel, n->data) < 0)
    1570             :                         return 0;
    1571             :         return 1;
    1572             : }
    1573             : 
    1574             : sql_rel *
    1575     6293999 : find_rel(list *rels, sql_exp *e)
    1576             : {
    1577     6293999 :         node *n = list_find(rels, e, (fcmp)&rel_has_exp);
    1578     6293999 :         if (n)
    1579     3904420 :                 return n->data;
    1580             :         return NULL;
    1581             : }
    1582             : 
    1583             : sql_rel *
    1584      253590 : find_one_rel(list *rels, sql_exp *e)
    1585             : {
    1586             :         node *n;
    1587             :         sql_rel *fnd = NULL;
    1588             : 
    1589      933129 :         for(n = rels->h; n; n = n->next) {
    1590      679618 :                 if (rel_has_exp(n->data, e) == 0) {
    1591      253523 :                         if (fnd)
    1592             :                                 return NULL;
    1593      253444 :                         fnd = n->data;
    1594             :                 }
    1595             :         }
    1596             :         return fnd;
    1597             : }
    1598             : 
    1599             : static int
    1600         321 : exp_is_rangejoin(sql_exp *e, list *rels)
    1601             : {
    1602             :         /* assume e is a e_cmp with 3 args
    1603             :          * Need to check e->r and e->f only touch one table.
    1604             :          */
    1605         321 :         const char *rname = 0;
    1606             : 
    1607         321 :         if (distinct_rel(e->r, &rname) && distinct_rel(e->f, &rname))
    1608             :                 return 0;
    1609         188 :         if (rels) {
    1610         127 :                 sql_rel *r = find_rel(rels, e->r);
    1611         127 :                 sql_rel *f = find_rel(rels, e->f);
    1612         127 :                 if (r && f && r == f)
    1613          98 :                         return 0;
    1614             :         }
    1615             :         return -1;
    1616             : }
    1617             : 
    1618             : int
    1619      287176 : exp_is_join(sql_exp *e, list *rels)
    1620             : {
    1621             :         /* only simple compare expressions, ie not or lists
    1622             :                 or range expressions (e->f)
    1623             :          */
    1624      287176 :         if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r && !e->f && e->card >= CARD_AGGR && !complex_select(e))
    1625             :                 return 0;
    1626        1599 :         if (e->type == e_cmp && e->flag == cmp_filter && e->l && e->r && e->card >= CARD_AGGR)
    1627             :                 return 0;
    1628             :         /* range expression */
    1629        1506 :         if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r && e->f && e->card >= CARD_AGGR && !complex_select(e))
    1630         321 :                 return exp_is_rangejoin(e, rels);
    1631             :         return -1;
    1632             : }
    1633             : 
    1634             : int
    1635      281270 : exp_is_eqjoin(sql_exp *e)
    1636             : {
    1637      281270 :         if (e->flag == cmp_equal) {
    1638      272314 :                 sql_exp *l = e->l;
    1639      272314 :                 sql_exp *r = e->r;
    1640             : 
    1641      272314 :                 if (!is_func(l->type) && !is_func(r->type))
    1642      271806 :                         return 0;
    1643             :         }
    1644             :         return -1;
    1645             : }
    1646             : 
    1647             : sql_exp *
    1648      232162 : exps_find_prop(list *exps, rel_prop kind)
    1649             : {
    1650      232162 :         if (list_empty(exps))
    1651             :                 return NULL;
    1652      462806 :         for (node *n = exps->h ; n ; n = n->next) {
    1653      232162 :                 sql_exp *e = n->data;
    1654             : 
    1655      232162 :                 if (find_prop(e->p, kind))
    1656        1518 :                         return e;
    1657             :         }
    1658             :         return NULL;
    1659             : }
    1660             : 
    1661             : static sql_exp *
    1662   159368620 : rel_find_exp_and_corresponding_rel_(sql_rel *rel, sql_exp *e, sql_rel **res)
    1663             : {
    1664             :         sql_exp *ne = NULL;
    1665             : 
    1666   160974058 :         if (!rel)
    1667             :                 return NULL;
    1668   160973915 :         switch(e->type) {
    1669   158240807 :         case e_column:
    1670   158240807 :                 if (is_basetable(rel->op) && !rel->exps) {
    1671         496 :                         if (e->l) {
    1672         496 :                                 if (rel_base_bind_column2_(rel, e->l, e->r))
    1673             :                                         ne = e;
    1674           0 :                         } else if (rel_base_bind_column_(rel, e->r))
    1675             :                                 ne = e;
    1676   158240311 :                 } else if (rel->exps && (is_project(rel->op) || is_base(rel->op))) {
    1677   107626944 :                         if (e->l) {
    1678   106770730 :                                 ne = exps_bind_column2(rel->exps, e->l, e->r, NULL);
    1679             :                         } else {
    1680      856214 :                                 ne = exps_bind_column(rel->exps, e->r, NULL, NULL, 1);
    1681             :                         }
    1682             :                 }
    1683   158240809 :                 if (ne && res)
    1684        1156 :                         *res = rel;
    1685             :                 return ne;
    1686     1605438 :         case e_convert:
    1687     1605438 :                 return rel_find_exp_and_corresponding_rel_(rel, e->l, res);
    1688      596264 :         case e_aggr:
    1689             :         case e_func:
    1690      596264 :                 if (e->l) {
    1691             :                         list *l = e->l;
    1692      593392 :                         node *n = l->h;
    1693             : 
    1694      593392 :                         ne = n->data;
    1695     1607597 :                         while (ne != NULL && n != NULL) {
    1696     1014205 :                                 ne = rel_find_exp_and_corresponding_rel_(rel, n->data, res);
    1697     1014205 :                                 n = n->next;
    1698             :                         }
    1699      593392 :                         return ne;
    1700             :                 }
    1701             :                 break;
    1702             :                 /* fall through */
    1703             :         case e_cmp:
    1704             :         case e_psm:
    1705             :                 return NULL;
    1706      530800 :         case e_atom:
    1707      530800 :                 if (e->f) { /* values */
    1708             :                         list *l = e->f;
    1709        6944 :                         node *n = l->h;
    1710             : 
    1711        6944 :                         ne = n->data;
    1712       16119 :                         while (ne != NULL && n != NULL) {
    1713        9175 :                                 ne = rel_find_exp_and_corresponding_rel_(rel, n->data, res);
    1714        9175 :                                 n = n->next;
    1715             :                         }
    1716        6944 :                         return ne;
    1717             :                 }
    1718             :                 return e;
    1719             :         }
    1720             :         return ne;
    1721             : }
    1722             : 
    1723             : sql_exp *
    1724   145873942 : rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, sql_rel **res, bool *under_join)
    1725             : {
    1726   158345239 :         sql_exp *ne = rel_find_exp_and_corresponding_rel_(rel, e, res);
    1727             : 
    1728   158345246 :         if (rel && !ne) {
    1729   129614306 :                 switch(rel->op) {
    1730    38142146 :                 case op_left:
    1731             :                 case op_right:
    1732             :                 case op_full:
    1733             :                 case op_join:
    1734             :                 case op_semi:
    1735             :                 case op_anti:
    1736    38142146 :                         ne = rel_find_exp_and_corresponding_rel(rel->l, e, res, under_join);
    1737    38142146 :                         if (!ne && is_join(rel->op))
    1738    30024251 :                                 ne = rel_find_exp_and_corresponding_rel(rel->r, e, res, under_join);
    1739    38142146 :                         if (ne && under_join)
    1740     8561906 :                                 *under_join = true;
    1741             :                         break;
    1742             :                 case op_table:
    1743             :                 case op_basetable:
    1744             :                         break;
    1745    20688162 :                 default:
    1746    20688162 :                         if (!is_project(rel->op) && rel->l)
    1747             :                                 ne = rel_find_exp_and_corresponding_rel(rel->l, e, res, under_join);
    1748             :                 }
    1749             :         }
    1750   145873949 :         return ne;
    1751             : }
    1752             : 
    1753             : sql_exp *
    1754    60525846 : rel_find_exp(sql_rel *rel, sql_exp *e)
    1755             : {
    1756    60525846 :         return rel_find_exp_and_corresponding_rel(rel, e, NULL, NULL);
    1757             : }
    1758             : 
    1759             : int
    1760     7307470 : exp_is_true(sql_exp *e)
    1761             : {
    1762     7307470 :         if (e->type == e_atom && e->l)
    1763       11243 :                 return atom_is_true(e->l);
    1764     7296227 :         if (e->type == e_cmp && e->flag == cmp_equal)
    1765     3090049 :                 return (exp_is_true(e->l) && exp_is_true(e->r) && exp_match_exp(e->l, e->r));
    1766             :         return 0;
    1767             : }
    1768             : 
    1769             : static inline bool
    1770      702271 : exp_is_cmp_exp_is_false(sql_exp* e)
    1771             : {
    1772      702271 :         sql_exp *l = e->l;
    1773      702271 :         sql_exp *r = e->r;
    1774      702271 :         assert(e->type == e_cmp && e->f == NULL && l && r);
    1775             : 
    1776             :         /* Handle 'v is x' and 'v is not x' expressions.
    1777             :         * Other cases in is-semantics are unspecified.
    1778             :         */
    1779      702271 :         if (e->flag != cmp_equal && e->flag != cmp_notequal)
    1780             :                 return false;
    1781      702271 :         if (e->flag == cmp_equal && !is_anti(e))
    1782      672752 :                 return ((exp_is_null(l) && exp_is_not_null(r)) || (exp_is_not_null(l) && exp_is_null(r)));
    1783       31842 :         if (((e->flag == cmp_notequal) && !is_anti(e)) || ((e->flag == cmp_equal) && is_anti(e)) )
    1784       31842 :                 return ((exp_is_null(l) && exp_is_null(r)) || (exp_is_not_null(l) && exp_is_not_null(r)));
    1785             :         return false;
    1786             : }
    1787             : 
    1788             : static inline bool
    1789     5968149 : exp_single_bound_cmp_exp_is_false(sql_exp* e) {
    1790     5968149 :     assert(e->type == e_cmp);
    1791     5968149 :     sql_exp* l = e->l;
    1792     5968149 :     sql_exp* r = e->r;
    1793     5968149 :     assert(e->f == NULL);
    1794     5968149 :     assert (l && r);
    1795             : 
    1796     5968149 :     return exp_is_null(l) || exp_is_null(r);
    1797             : }
    1798             : 
    1799             : static inline bool
    1800       61223 : exp_two_sided_bound_cmp_exp_is_false(sql_exp* e) {
    1801       61223 :     assert(e->type == e_cmp);
    1802       61223 :     sql_exp* v = e->l;
    1803       61223 :     sql_exp* l = e->r;
    1804       61223 :     sql_exp* h = e->f;
    1805       61223 :     assert (v && l && h);
    1806             : 
    1807       61296 :     return is_anti(e) ? exp_is_null(v) || (exp_is_null(l) && exp_is_null(h)) : exp_is_null(l) || exp_is_null(v) || exp_is_null(h);
    1808             : }
    1809             : 
    1810             : static inline bool
    1811     6731643 : exp_regular_cmp_exp_is_false(sql_exp* e) {
    1812     6731643 :     assert(e->type == e_cmp);
    1813             : 
    1814     6731643 :     if (is_semantics(e))return exp_is_cmp_exp_is_false(e);
    1815     6029372 :     if (e -> f)         return exp_two_sided_bound_cmp_exp_is_false(e);
    1816     5968149 :     else                return exp_single_bound_cmp_exp_is_false(e);
    1817             : }
    1818             : 
    1819             : static inline bool
    1820      559578 : exp_or_exp_is_false(sql_exp* e) {
    1821      559578 :     assert(e->type == e_cmp && e->flag == cmp_or);
    1822             : 
    1823      559578 :         list* left = e->l;
    1824      559578 :         list* right = e->r;
    1825             : 
    1826             :         bool left_is_false = false;
    1827     1168420 :         for(node* n = left->h; n; n=n->next) {
    1828      608992 :                 if (exp_is_false(n->data)) {
    1829             :                         left_is_false=true;
    1830             :                         break;
    1831             :                 }
    1832             :         }
    1833             : 
    1834      559578 :         if (!left_is_false) {
    1835             :                 return false;
    1836             :         }
    1837             : 
    1838         284 :         for(node* n = right->h; n; n=n->next) {
    1839         162 :                 if (exp_is_false(n->data)) {
    1840             :                         return true;
    1841             :                 }
    1842             :         }
    1843             : 
    1844             :     return false;
    1845             : }
    1846             : 
    1847             : static inline bool
    1848     7711953 : exp_cmp_exp_is_false(sql_exp* e) {
    1849     7711953 :     assert(e->type == e_cmp);
    1850             : 
    1851     7711953 :     switch (e->flag) {
    1852     6731643 :     case cmp_gt:
    1853             :     case cmp_gte:
    1854             :     case cmp_lte:
    1855             :     case cmp_lt:
    1856             :     case cmp_equal:
    1857             :     case cmp_notequal:
    1858     6731643 :         return exp_regular_cmp_exp_is_false(e);
    1859      559578 :     case cmp_or:
    1860      559578 :         return exp_or_exp_is_false(e);
    1861             :     default:
    1862             :         return false;
    1863             :         }
    1864             : }
    1865             : 
    1866             : int
    1867     7767592 : exp_is_false(sql_exp *e)
    1868             : {
    1869     7767592 :         if (e->type == e_atom && e->l)
    1870        8206 :                 return atom_is_false(e->l);
    1871     7759386 :         else if (e->type == e_cmp)
    1872     7711953 :                 return exp_cmp_exp_is_false(e);
    1873             :         return 0;
    1874             : }
    1875             : 
    1876             : int
    1877       17303 : exp_is_zero(sql_exp *e)
    1878             : {
    1879       17303 :         if (e->type == e_atom && e->l)
    1880       16874 :                 return atom_is_zero(e->l);
    1881             :         return 0;
    1882             : }
    1883             : 
    1884             : int
    1885      880838 : exp_is_not_null(sql_exp *e)
    1886             : {
    1887      883728 :         if (!has_nil(e))
    1888             :                 return true;
    1889             : 
    1890      877354 :         switch (e->type) {
    1891        3539 :         case e_atom:
    1892        3539 :                 if (e->f) /* values list */
    1893             :                         return false;
    1894        3539 :                 if (e->l)
    1895        3110 :                         return !(atom_null(e->l));
    1896             :                 return false;
    1897        2890 :         case e_convert:
    1898        2890 :                 return exp_is_not_null(e->l);
    1899      147571 :         case e_func:
    1900      147571 :                 if (!is_semantics(e) && e->l) {
    1901             :                         list *l = e->l;
    1902      147266 :                         for (node *n = l->h; n; n=n->next) {
    1903      147266 :                                 sql_exp *p = n->data;
    1904      147266 :                                 if (!exp_is_not_null(p))
    1905             :                                         return false;
    1906             :                         }
    1907             :                         return true;
    1908             :                 }
    1909             :                 return false;
    1910             :         case e_aggr:
    1911             :         case e_column:
    1912             :         case e_cmp:
    1913             :         case e_psm:
    1914             :                 return false;
    1915             :         }
    1916             :         return false;
    1917             : }
    1918             : 
    1919             : int
    1920    14949286 : exp_is_null(sql_exp *e )
    1921             : {
    1922    15944650 :         if (!has_nil(e))
    1923             :                 return false;
    1924             : 
    1925    11958207 :         switch (e->type) {
    1926      100520 :         case e_atom:
    1927      100520 :                 if (e->f) /* values list */
    1928             :                         return 0;
    1929      100520 :                 if (e->l)
    1930       25220 :                         return (atom_null(e->l));
    1931             :                 return 0;
    1932      995364 :         case e_convert:
    1933      995364 :                 return exp_is_null(e->l);
    1934      774936 :         case e_func:
    1935      774936 :                 if (!is_semantics(e) && e->l) {
    1936             :                         /* This is a call to a function with no-nil semantics.
    1937             :                          * If one of the parameters is null the expression itself is null
    1938             :                          */
    1939             :                         list* l = e->l;
    1940     2280074 :                         for(node* n = l->h; n; n=n->next) {
    1941     1518184 :                                 sql_exp* p = n->data;
    1942     1518184 :                                 if (exp_is_null(p)) {
    1943             :                                         return true;
    1944             :                                 }
    1945             :                         }
    1946             :                 }
    1947             :                 return 0;
    1948             :         case e_aggr:
    1949             :         case e_column:
    1950             :         case e_cmp:
    1951             :         case e_psm:
    1952             :                 return 0;
    1953             :         }
    1954             :         return 0;
    1955             : }
    1956             : 
    1957             : int
    1958    21314411 : exp_is_rel( sql_exp *e )
    1959             : {
    1960    21819071 :         if (e) {
    1961    21819071 :                 switch(e->type){
    1962      504660 :                 case e_convert:
    1963      504660 :                         return exp_is_rel(e->l);
    1964      376834 :                 case e_psm:
    1965      376834 :                         return e->flag == PSM_REL && e->l;
    1966             :                 default:
    1967             :                         return 0;
    1968             :                 }
    1969             :         }
    1970             :         return 0;
    1971             : }
    1972             : 
    1973             : int
    1974         908 : exps_one_is_rel(list *exps)
    1975             : {
    1976         908 :         if (list_empty(exps))
    1977             :                 return 0;
    1978        2702 :         for(node *n = exps->h ; n ; n = n->next)
    1979        1802 :                 if (exp_is_rel(n->data))
    1980             :                         return 1;
    1981             :         return 0;
    1982             : }
    1983             : 
    1984             : int
    1985     5019405 : exp_is_atom( sql_exp *e )
    1986             : {
    1987     5447966 :         switch (e->type) {
    1988      717860 :         case e_atom:
    1989      717860 :                 if (e->f) /* values list */
    1990       12164 :                         return 0;
    1991             :                 return 1;
    1992      428561 :         case e_convert:
    1993      428561 :                 return exp_is_atom(e->l);
    1994      858783 :         case e_func:
    1995             :         case e_aggr:
    1996      858783 :                 return e->card == CARD_ATOM && exps_are_atoms(e->l);
    1997         134 :         case e_cmp:
    1998         134 :                 if (e->card != CARD_ATOM)
    1999             :                         return 0;
    2000          56 :                 if (e->flag == cmp_or || e->flag == cmp_filter)
    2001           0 :                         return exps_are_atoms(e->l) && exps_are_atoms(e->r);
    2002          56 :                 if (e->flag == cmp_in || e->flag == cmp_notin)
    2003           0 :                         return exp_is_atom(e->l) && exps_are_atoms(e->r);
    2004          56 :                 return exp_is_atom(e->l) && exp_is_atom(e->r) && (!e->f || exp_is_atom(e->f));
    2005             :         case e_column:
    2006             :         case e_psm:
    2007             :                 return 0;
    2008             :         }
    2009             :         return 0;
    2010             : }
    2011             : 
    2012             : int
    2013    38306113 : exp_has_rel( sql_exp *e )
    2014             : {
    2015    40222211 :         if (!e)
    2016             :                 return 0;
    2017    40220878 :         switch(e->type){
    2018     4922985 :         case e_func:
    2019             :         case e_aggr:
    2020     4922985 :                 return exps_have_rel_exp(e->l);
    2021     1674056 :         case e_cmp:
    2022     1674056 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2023       73994 :                         return (exps_have_rel_exp(e->l) || exps_have_rel_exp(e->r));
    2024     1600062 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2025      128607 :                         return (exp_has_rel(e->l) || exps_have_rel_exp(e->r));
    2026             :                 } else {
    2027     1471455 :                         return (exp_has_rel(e->l) || exp_has_rel(e->r) || (e->f && exp_has_rel(e->f)));
    2028             :                 }
    2029     1916098 :         case e_convert:
    2030     1916098 :                 return exp_has_rel(e->l);
    2031      141768 :         case e_psm:
    2032      141768 :                 return exp_is_rel(e);
    2033    10478537 :         case e_atom:
    2034    10478537 :                 return (e->f && exps_have_rel_exp(e->f));
    2035             :         case e_column:
    2036             :                 return 0;
    2037             :         }
    2038             :         return 0;
    2039             : }
    2040             : 
    2041             : int
    2042     5415108 : exps_have_rel_exp( list *exps)
    2043             : {
    2044     5415108 :         if (list_empty(exps))
    2045             :                 return 0;
    2046    16561402 :         for(node *n=exps->h; n; n=n->next) {
    2047    11249840 :                 sql_exp *e = n->data;
    2048             : 
    2049    11249840 :                 if (exp_has_rel(e))
    2050             :                         return 1;
    2051             :         }
    2052             :         return 0;
    2053             : }
    2054             : 
    2055             : static sql_rel *
    2056         437 : exps_rel_get_rel(sql_allocator *sa, list *exps )
    2057             : {
    2058             :         sql_rel *r = NULL, *xp = NULL;
    2059             : 
    2060         437 :         if (list_empty(exps))
    2061             :                 return NULL;
    2062        1316 :         for (node *n = exps->h; n; n=n->next){
    2063         879 :                 sql_exp *e = n->data;
    2064             : 
    2065         879 :                 if (exp_has_rel(e)) {
    2066         441 :                         if (!(r = exp_rel_get_rel(sa, e)))
    2067             :                                 return NULL;
    2068         441 :                         xp = xp ? rel_crossproduct(sa, xp, r, op_full) : r;
    2069             :                 }
    2070             :         }
    2071             :         return xp;
    2072             : }
    2073             : 
    2074             : int
    2075          40 : exp_rel_depth(sql_exp *e)
    2076             : {
    2077          40 :         if (!e)
    2078             :                 return 0;
    2079          40 :         switch(e->type){
    2080             :         case e_func:
    2081             :         case e_aggr:
    2082             :         case e_cmp:
    2083             :                 return 1;
    2084           3 :         case e_convert:
    2085           3 :                 return 0;
    2086          27 :         case e_psm:
    2087          27 :                 if (exp_is_rel(e))
    2088          27 :                         return 0;
    2089             :                 return 1;
    2090           0 :         case e_atom:
    2091             :         case e_column:
    2092           0 :                 return 0;
    2093             :         }
    2094           0 :         return 0;
    2095             : }
    2096             : 
    2097             : sql_rel *
    2098       90676 : exp_rel_get_rel(sql_allocator *sa, sql_exp *e)
    2099             : {
    2100       92955 :         if (!e)
    2101             :                 return NULL;
    2102             : 
    2103       92955 :         switch(e->type){
    2104         437 :         case e_func:
    2105             :         case e_aggr:
    2106         437 :                 return exps_rel_get_rel(sa, e->l);
    2107           2 :         case e_cmp: {
    2108             :                 sql_rel *r = NULL, *xp = NULL;
    2109             : 
    2110           2 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2111           0 :                         if (exps_have_rel_exp(e->l))
    2112           0 :                                 xp = exps_rel_get_rel(sa, e->l);
    2113           0 :                         if (exps_have_rel_exp(e->r)) {
    2114           0 :                                 if (!(r = exps_rel_get_rel(sa, e->r)))
    2115             :                                         return NULL;
    2116           0 :                                 xp = xp ? rel_crossproduct(sa, xp, r, op_join) : r;
    2117             :                         }
    2118           2 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2119           0 :                         if (exp_has_rel(e->l))
    2120           0 :                                 xp = exp_rel_get_rel(sa, e->l);
    2121           0 :                         if (exps_have_rel_exp(e->r)) {
    2122           0 :                                 if (!(r = exps_rel_get_rel(sa, e->r)))
    2123             :                                         return NULL;
    2124           0 :                                 xp = xp ? rel_crossproduct(sa, xp, r, op_join) : r;
    2125             :                         }
    2126             :                 } else {
    2127           2 :                         if (exp_has_rel(e->l))
    2128           2 :                                 xp = exp_rel_get_rel(sa, e->l);
    2129           2 :                         if (exp_has_rel(e->r)) {
    2130           2 :                                 if (!(r = exp_rel_get_rel(sa, e->r)))
    2131             :                                         return NULL;
    2132           2 :                                 xp = xp ? rel_crossproduct(sa, xp, r, op_join) : r;
    2133             :                         }
    2134           2 :                         if (e->f && exp_has_rel(e->f)) {
    2135           0 :                                 if (!(r = exp_rel_get_rel(sa, e->f)))
    2136             :                                         return NULL;
    2137           0 :                                 xp = xp ? rel_crossproduct(sa, xp, r, op_join) : r;
    2138             :                         }
    2139             :                 }
    2140             :                 return xp;
    2141             :         }
    2142        2279 :         case e_convert:
    2143        2279 :                 return exp_rel_get_rel(sa, e->l);
    2144       90237 :         case e_psm:
    2145       90237 :                 if (exp_is_rel(e))
    2146       90237 :                         return e->l;
    2147             :                 return NULL;
    2148           0 :         case e_atom:
    2149           0 :                 if (e->f && exps_have_rel_exp(e->f))
    2150           0 :                         return exps_rel_get_rel(sa, e->f);
    2151             :                 return NULL;
    2152             :         case e_column:
    2153             :                 return NULL;
    2154             :         }
    2155             :         return NULL;
    2156             : }
    2157             : 
    2158             : static void exp_rel_update_set_freevar(sql_exp *e);
    2159             : 
    2160             : static void
    2161         845 : exps_rel_update_set_freevar(list *exps)
    2162             : {
    2163         845 :         if (!list_empty(exps))
    2164        2748 :                 for (node *n=exps->h; n ; n=n->next)
    2165        1903 :                         exp_rel_update_set_freevar(n->data);
    2166         845 : }
    2167             : 
    2168             : static void
    2169        2125 : exp_rel_update_set_freevar(sql_exp *e)
    2170             : {
    2171        2130 :         if (!e)
    2172             :                 return ;
    2173             : 
    2174        2130 :         switch(e->type){
    2175         845 :         case e_func:
    2176             :         case e_aggr:
    2177         845 :                 exps_rel_update_set_freevar(e->l);
    2178         845 :                 break;
    2179           0 :         case e_cmp:
    2180           0 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2181           0 :                         exps_rel_update_set_freevar(e->l);
    2182           0 :                         exps_rel_update_set_freevar(e->r);
    2183           0 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2184           0 :                         exp_rel_update_set_freevar(e->l);
    2185           0 :                         exps_rel_update_set_freevar(e->r);
    2186             :                 } else {
    2187           0 :                         exp_rel_update_set_freevar(e->l);
    2188           0 :                         exp_rel_update_set_freevar(e->r);
    2189           0 :                         if (e->f)
    2190             :                                 exp_rel_update_set_freevar(e->f);
    2191             :                 }
    2192             :                 break;
    2193           5 :         case e_convert:
    2194           5 :                 exp_rel_update_set_freevar(e->l);
    2195           5 :                 break;
    2196        1057 :         case e_atom:
    2197        1057 :                 if (e->f)
    2198           0 :                         exps_rel_update_set_freevar(e->f);
    2199             :                 break;
    2200         223 :         case e_column:
    2201         223 :                 set_freevar(e, 1);
    2202         223 :                 break;
    2203             :         case e_psm:
    2204             :                 break;
    2205             :         }
    2206        2125 : }
    2207             : 
    2208             : static list *
    2209         437 : exp_rel_update_exps(mvc *sql, list *exps)
    2210             : {
    2211         437 :         if (list_empty(exps))
    2212             :                 return exps;
    2213        1316 :         for (node *n = exps->h; n; n=n->next){
    2214         879 :                 sql_exp *e = n->data;
    2215             : 
    2216         879 :                 if (exp_has_rel(e))
    2217         441 :                         n->data = exp_rel_update_exp(sql, e);
    2218         438 :                 else if (!exp_is_atom(e))
    2219         222 :                         exp_rel_update_set_freevar(e);
    2220             :         }
    2221             :         return exps;
    2222             : }
    2223             : 
    2224             : sql_exp *
    2225       15712 : exp_rel_update_exp(mvc *sql, sql_exp *e)
    2226             : {
    2227       15712 :         if (!e)
    2228             :                 return NULL;
    2229             : 
    2230       15712 :         switch(e->type){
    2231         437 :         case e_func:
    2232             :         case e_aggr:
    2233         437 :                 if (exps_have_rel_exp(e->l))
    2234         437 :                         e->l = exp_rel_update_exps(sql, e->l);
    2235             :                 return e;
    2236           2 :         case e_cmp:
    2237           2 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2238           0 :                         if (exps_have_rel_exp(e->l))
    2239           0 :                                 e->l = exp_rel_update_exps(sql, e->l);
    2240           0 :                         if (exps_have_rel_exp(e->r))
    2241           0 :                                 e->r = exp_rel_update_exps(sql, e->r);
    2242           2 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2243           0 :                         if (exp_has_rel(e->l))
    2244           0 :                                 e->l = exp_rel_update_exp(sql, e->l);
    2245           0 :                         if (exps_have_rel_exp(e->r))
    2246           0 :                                 e->r = exp_rel_update_exps(sql, e->r);
    2247             :                 } else {
    2248           2 :                         if (exp_has_rel(e->l))
    2249           2 :                                 e->l = exp_rel_update_exp(sql, e->l);
    2250           2 :                         if (exp_has_rel(e->r))
    2251           2 :                                 e->r = exp_rel_update_exp(sql, e->r);
    2252           2 :                         if (e->f && exp_has_rel(e->f))
    2253           0 :                                 e->f = exp_rel_update_exp(sql, e->f);
    2254             :                 }
    2255             :                 return e;
    2256        2237 :         case e_convert:
    2257        2237 :                 if (exp_has_rel(e->l))
    2258        2237 :                         e->l = exp_rel_update_exp(sql, e->l);
    2259             :                 return e;
    2260       13036 :         case e_psm:
    2261       13036 :                 if (exp_is_rel(e)) {
    2262       13036 :                         sql_rel *r = exp_rel_get_rel(sql->sa, e);
    2263       13036 :                         e = r->exps->t->data;
    2264       13036 :                         return exp_ref(sql, e);
    2265             :                 }
    2266             :                 return e;
    2267           0 :         case e_atom:
    2268           0 :                 if (e->f && exps_have_rel_exp(e->f))
    2269           0 :                         e->f = exp_rel_update_exps(sql, e->f);
    2270             :                 return e;
    2271             :         case e_column:
    2272             :                 return e;
    2273             :         }
    2274             :         return e;
    2275             : }
    2276             : 
    2277             : sql_exp *
    2278        2776 : exp_rel_label(mvc *sql, sql_exp *e)
    2279             : {
    2280        2776 :         if (exp_is_rel(e)) {
    2281        2776 :                 sql_rel *r = e->l;
    2282             : 
    2283        2776 :                 e->l = r = rel_label(sql, r, 1);
    2284             :         }
    2285        2776 :         return e;
    2286             : }
    2287             : 
    2288             : int
    2289      120060 : exps_are_atoms( list *exps)
    2290             : {
    2291             :         int atoms = 1;
    2292      120060 :         if (!list_empty(exps))
    2293      325041 :                 for(node *n=exps->h; n && atoms; n=n->next)
    2294      237441 :                         atoms &= exp_is_atom(n->data);
    2295      120063 :         return atoms;
    2296             : }
    2297             : 
    2298             : int
    2299       40140 : exps_have_func(list *exps)
    2300             : {
    2301       40140 :         if (list_empty(exps))
    2302             :                 return 0;
    2303      107010 :         for(node *n=exps->h; n; n=n->next) {
    2304       69991 :                 sql_exp *e = n->data;
    2305             : 
    2306       69991 :                 if (exp_has_func(e))
    2307             :                         return 1;
    2308             :         }
    2309             :         return 0;
    2310             : }
    2311             : 
    2312             : int
    2313     1357419 : exp_has_func(sql_exp *e)
    2314             : {
    2315     1394608 :         if (!e)
    2316             :                 return 0;
    2317     1394608 :         switch (e->type) {
    2318      113517 :         case e_atom:
    2319      113517 :                 if (e->f)
    2320          25 :                         return exps_have_func(e->f);
    2321             :                 return 0;
    2322       37189 :         case e_convert:
    2323       37189 :                 return exp_has_func(e->l);
    2324             :         case e_func:
    2325             :                 return 1;
    2326       16352 :         case e_aggr:
    2327       16352 :                 if (e->l)
    2328       13663 :                         return exps_have_func(e->l);
    2329             :                 return 0;
    2330      154510 :         case e_cmp:
    2331      154510 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2332        8640 :                         return (exps_have_func(e->l) || exps_have_func(e->r));
    2333      145870 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2334       11469 :                         return (exp_has_func(e->l) || exps_have_func(e->r));
    2335             :                 } else {
    2336      134401 :                         return (exp_has_func(e->l) || exp_has_func(e->r) ||
    2337      128573 :                                         (e->f && exp_has_func(e->f)));
    2338             :                 }
    2339     1039094 :         case e_column:
    2340             :         case e_psm:
    2341     1039094 :                 return 0;
    2342             :         }
    2343           0 :         return 0;
    2344             : }
    2345             : 
    2346             : static int
    2347      166449 : exps_has_sideeffect( list *exps)
    2348             : {
    2349             :         node *n;
    2350             :         int has_sideeffect = 0;
    2351             : 
    2352      496865 :         for(n=exps->h; n && !has_sideeffect; n=n->next)
    2353      330416 :                 has_sideeffect |= exp_has_sideeffect(n->data);
    2354      166449 :         return has_sideeffect;
    2355             : }
    2356             : 
    2357             : int
    2358      392833 : exp_has_sideeffect( sql_exp *e )
    2359             : {
    2360      457604 :         switch (e->type) {
    2361       64771 :         case e_convert:
    2362       64771 :                 return exp_has_sideeffect(e->l);
    2363      166458 :         case e_func:
    2364             :                 {
    2365      166458 :                         sql_subfunc *f = e->f;
    2366             : 
    2367      166458 :                         if (f->func->side_effect)
    2368             :                                 return 1;
    2369      166453 :                         if (e->l)
    2370      166449 :                                 return exps_has_sideeffect(e->l);
    2371             :                         return 0;
    2372             :                 }
    2373       93015 :         case e_atom:
    2374       93015 :                 if (e->f)
    2375           0 :                         return exps_has_sideeffect(e->f);
    2376             :                 return 0;
    2377             :         case e_aggr:
    2378             :         case e_cmp:
    2379             :         case e_column:
    2380             :         case e_psm:
    2381             :                 return 0;
    2382             :         }
    2383             :         return 0;
    2384             : }
    2385             : 
    2386             : int
    2387     1144898 : exps_have_unsafe(list *exps, int allow_identity)
    2388             : {
    2389             :         int unsafe = 0;
    2390             : 
    2391     1144898 :         if (list_empty(exps))
    2392             :                 return 0;
    2393     3856516 :         for (node *n = exps->h; n && !unsafe; n = n->next)
    2394     2714497 :                 unsafe |= exp_unsafe(n->data, allow_identity);
    2395             :         return unsafe;
    2396             : }
    2397             : 
    2398             : int
    2399    13055319 : exp_unsafe(sql_exp *e, int allow_identity)
    2400             : {
    2401    14440842 :         switch (e->type) {
    2402     1385523 :         case e_convert:
    2403     1385523 :                 return exp_unsafe(e->l, allow_identity);
    2404     1173834 :         case e_aggr:
    2405             :         case e_func: {
    2406     1173834 :                 sql_subfunc *f = e->f;
    2407             : 
    2408     1173834 :                 if (IS_ANALYTIC(f->func) || (!allow_identity && is_identity(e, NULL)))
    2409      108982 :                         return 1;
    2410     1064851 :                 return exps_have_unsafe(e->l, allow_identity);
    2411             :         } break;
    2412         217 :         case e_cmp: {
    2413         217 :                 if (e->flag == cmp_in || e->flag == cmp_notin) {
    2414           0 :                         return exp_unsafe(e->l, allow_identity) || exps_have_unsafe(e->r, allow_identity);
    2415         217 :                 } else if (e->flag == cmp_or || e->flag == cmp_filter) {
    2416           0 :                         return exps_have_unsafe(e->l, allow_identity) || exps_have_unsafe(e->r, allow_identity);
    2417             :                 } else {
    2418         217 :                         return exp_unsafe(e->l, allow_identity) || exp_unsafe(e->r, allow_identity) || (e->f && exp_unsafe(e->f, allow_identity));
    2419             :                 }
    2420             :         } break;
    2421      918363 :         case e_atom: {
    2422      918363 :                 if (e->f)
    2423         112 :                         return exps_have_unsafe(e->f, allow_identity);
    2424             :                 return 0;
    2425             :         } break;
    2426             :         case e_column:
    2427             :         case e_psm:
    2428             :                 return 0;
    2429             :         }
    2430             :         return 0;
    2431             : }
    2432             : 
    2433             : static inline int
    2434    10401500 : exp_key( sql_exp *e )
    2435             : {
    2436    10401500 :         if (e->alias.name)
    2437    10401423 :                 return hash_key(e->alias.name);
    2438             :         return 0;
    2439             : }
    2440             : 
    2441             : sql_exp *
    2442     2931649 : exps_bind_column(list *exps, const char *cname, int *ambiguous, int *multiple, int no_tname)
    2443             : {
    2444             :         sql_exp *res = NULL;
    2445             : 
    2446     2931649 :         if (exps && cname) {
    2447             :                 node *en;
    2448             : 
    2449             :                 if (exps) {
    2450     2931648 :                         if (!exps->ht && list_length(exps) > HASH_MIN_SIZE) {
    2451      107537 :                                 exps->ht = hash_new(exps->sa, list_length(exps), (fkeyvalue)&exp_key);
    2452      107537 :                                 if (exps->ht == NULL)
    2453             :                                         return NULL;
    2454      813103 :                                 for (en = exps->h; en; en = en->next ) {
    2455      705566 :                                         sql_exp *e = en->data;
    2456      705566 :                                         if (e->alias.name) {
    2457      705565 :                                                 int key = exp_key(e);
    2458             : 
    2459      705565 :                                                 if (hash_add(exps->ht, key, e) == NULL)
    2460             :                                                         return NULL;
    2461             :                                         }
    2462             :                                 }
    2463             :                         }
    2464     2931648 :                         if (exps->ht) {
    2465     1901643 :                                 int key = hash_key(cname);
    2466     1901643 :                                 sql_hash_e *he = exps->ht->buckets[key&(exps->ht->size-1)];
    2467             : 
    2468     4295263 :                                 for (; he; he = he->chain) {
    2469     2393624 :                                         sql_exp *e = he->value;
    2470             : 
    2471     2393624 :                                         if (e->alias.name && strcmp(e->alias.name, cname) == 0 && (!no_tname || !e->alias.rname)) {
    2472      703418 :                                                 if (res && multiple)
    2473           4 :                                                         *multiple = 1;
    2474      703418 :                                                 if (!res)
    2475             :                                                         res = e;
    2476             : 
    2477      703418 :                                                 if (res && res != e && e->alias.rname && res->alias.rname && strcmp(e->alias.rname, res->alias.rname) != 0 ) {
    2478           4 :                                                         if (ambiguous)
    2479           4 :                                                                 *ambiguous = 1;
    2480           4 :                                                         return NULL;
    2481             :                                                 }
    2482             :                                                 res = e;
    2483             :                                         }
    2484             :                                 }
    2485     1901639 :                                 return res;
    2486             :                         }
    2487             :                 }
    2488     3840275 :                 for (en = exps->h; en; en = en->next ) {
    2489     2810271 :                         sql_exp *e = en->data;
    2490             : 
    2491     2810271 :                         if (e->alias.name && strcmp(e->alias.name, cname) == 0 && (!no_tname || !e->alias.rname)) {
    2492       69094 :                                 if (res && multiple)
    2493           4 :                                         *multiple = 1;
    2494       69094 :                                 if (!res)
    2495             :                                         res = e;
    2496             : 
    2497       69094 :                                 if (res && res != e && e->alias.rname && res->alias.rname && strcmp(e->alias.rname, res->alias.rname) != 0 ) {
    2498           1 :                                         if (ambiguous)
    2499           1 :                                                 *ambiguous = 1;
    2500           1 :                                         return NULL;
    2501             :                                 }
    2502             :                                 res = e;
    2503             :                         }
    2504             :                 }
    2505             :         }
    2506             :         return res;
    2507             : }
    2508             : 
    2509             : sql_exp *
    2510   122314405 : exps_bind_column2(list *exps, const char *rname, const char *cname, int *multiple)
    2511             : {
    2512             :         sql_exp *res = NULL;
    2513             : 
    2514   122314405 :         if (exps) {
    2515             :                 node *en;
    2516             : 
    2517             :                 if (exps) {
    2518   122314376 :                         if (!exps->ht && list_length(exps) > HASH_MIN_SIZE) {
    2519      631434 :                                 exps->ht = hash_new(exps->sa, list_length(exps), (fkeyvalue)&exp_key);
    2520      631434 :                                 if (exps->ht == NULL)
    2521             :                                         return res;
    2522             : 
    2523     8760514 :                                 for (en = exps->h; en; en = en->next ) {
    2524     8129080 :                                         sql_exp *e = en->data;
    2525     8129080 :                                         if (e->alias.name) {
    2526     8116760 :                                                 int key = exp_key(e);
    2527             : 
    2528     8116759 :                                                 if (hash_add(exps->ht, key, e) == NULL)
    2529             :                                                         return res;
    2530             :                                         }
    2531             :                                 }
    2532             :                         }
    2533   122314376 :                         if (exps->ht) {
    2534    38654292 :                                 int key = hash_key(cname);
    2535    38654292 :                                 sql_hash_e *he = exps->ht->buckets[key&(exps->ht->size-1)];
    2536             : 
    2537   242174676 :                                 for (; he; he = he->chain) {
    2538   203520384 :                                         sql_exp *e = he->value;
    2539             : 
    2540   203520384 :                                         if (e && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) {
    2541    24756123 :                                                 if (res && multiple)
    2542           0 :                                                         *multiple = 1;
    2543    24756123 :                                                 if (!res)
    2544             :                                                         res = e;
    2545             :                                         }
    2546             :                                 }
    2547    38654292 :                                 return res;
    2548             :                         }
    2549             :                 }
    2550   385060450 :                 for (en = exps->h; en; en = en->next ) {
    2551   301400366 :                         sql_exp *e = en->data;
    2552             : 
    2553   301400366 :                         if (e && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) {
    2554    12637552 :                                 if (res && multiple)
    2555           1 :                                         *multiple = 1;
    2556    12637552 :                                 if (!res)
    2557             :                                         res = e;
    2558             :                         }
    2559             :                 }
    2560             :         }
    2561             :         return res;
    2562             : }
    2563             : 
    2564             : /* find an column based on the original name, not the alias it got */
    2565             : sql_exp *
    2566         308 : exps_bind_alias( list *exps, const char *rname, const char *cname )
    2567             : {
    2568         308 :         if (exps) {
    2569             :                 node *en;
    2570             : 
    2571         715 :                 for (en = exps->h; en; en = en->next ) {
    2572         413 :                         sql_exp *e = en->data;
    2573             : 
    2574         413 :                         if (e && is_column(e->type) && !rname && e->r && strcmp(e->r, cname) == 0)
    2575           0 :                                 return e;
    2576         413 :                         if (e && e->type == e_column && rname && e->l && e->r && strcmp(e->r, cname) == 0 && strcmp(e->l, rname) == 0) {
    2577           6 :                                 return e;
    2578             :                         }
    2579             :                 }
    2580             :         }
    2581             :         return NULL;
    2582             : }
    2583             : 
    2584             : unsigned int
    2585     3791496 : exps_card( list *l )
    2586             : {
    2587             :         node *n;
    2588             :         unsigned int card = CARD_ATOM;
    2589             : 
    2590    15602001 :         if (l) for(n = l->h; n; n = n->next) {
    2591    11810505 :                 sql_exp *e = n->data;
    2592             : 
    2593    11810505 :                 if (e && card < e->card)
    2594             :                         card = e->card;
    2595             :         }
    2596     3791496 :         return card;
    2597             : }
    2598             : 
    2599             : void
    2600       43775 : exps_fix_card( list *exps, unsigned int card)
    2601             : {
    2602       43775 :         if (exps)
    2603     1164997 :                 for (node *n = exps->h; n; n = n->next) {
    2604     1121222 :                 sql_exp *e = n->data;
    2605             : 
    2606     1121222 :                 if (e && e->card > card)
    2607           0 :                         e->card = card;
    2608             :         }
    2609       43775 : }
    2610             : 
    2611             : void
    2612        2833 : exps_setcard( list *exps, unsigned int card)
    2613             : {
    2614        2833 :         if (exps)
    2615       18843 :                 for (node *n = exps->h; n; n = n->next) {
    2616       16010 :                         sql_exp *e = n->data;
    2617             : 
    2618       16010 :                         if (e && e->card != CARD_ATOM)
    2619       15982 :                                 e->card = card;
    2620             :                 }
    2621        2833 : }
    2622             : 
    2623             : int
    2624           0 : exps_intern(list *exps)
    2625             : {
    2626           0 :         if (exps)
    2627           0 :                 for (node *n=exps->h; n; n = n->next) {
    2628           0 :                         sql_exp *e = n->data;
    2629             : 
    2630           0 :                         if (is_intern(e))
    2631             :                                 return 1;
    2632             :                 }
    2633             :         return 0;
    2634             : }
    2635             : 
    2636             : sql_exp *
    2637         337 : exps_find_one_multi_exp(list *exps)
    2638             : {
    2639             :         sql_exp *l = NULL;
    2640             :         int skip = 0;
    2641             : 
    2642             :         /* Find one and only 1 expression with card > CARD_ATOM */
    2643         337 :         if (!list_empty(exps)) {
    2644         805 :                 for (node *m = exps->h ; m && !skip ; m = m->next) {
    2645         468 :                         sql_exp *e = m->data;
    2646             : 
    2647         468 :                         if (e->card > CARD_ATOM) {
    2648         335 :                                 skip |= l != NULL;
    2649             :                                 l = e;
    2650             :                         }
    2651             :                 }
    2652             :         }
    2653         337 :         if (skip)
    2654             :                 l = NULL;
    2655         337 :         return l;
    2656             : }
    2657             : 
    2658             : const char *
    2659       86584 : compare_func( comp_type t, int anti )
    2660             : {
    2661       86584 :         switch(t) {
    2662       49249 :         case mark_in:
    2663             :         case cmp_equal:
    2664       49249 :                 return anti?"<>":"=";
    2665        3754 :         case cmp_lt:
    2666        3754 :                 return anti?">":"<";
    2667        1176 :         case cmp_lte:
    2668        1176 :                 return anti?">=":"<=";
    2669        1009 :         case cmp_gte:
    2670        1009 :                 return anti?"<=":">=";
    2671       19260 :         case cmp_gt:
    2672       19260 :                 return anti?"<":">";
    2673       12136 :         case mark_notin:
    2674             :         case cmp_notequal:
    2675       12136 :                 return anti?"=":"<>";
    2676             :         default:
    2677             :                 return NULL;
    2678             :         }
    2679             : }
    2680             : 
    2681             : int
    2682     1788025 : is_identity( sql_exp *e, sql_rel *r)
    2683             : {
    2684     1912539 :         switch(e->type) {
    2685      236612 :         case e_column:
    2686      236612 :                 if (r && is_project(r->op)) {
    2687             :                         sql_exp *re = NULL;
    2688      171409 :                         if (e->l)
    2689      171375 :                                 re = exps_bind_column2(r->exps, e->l, e->r, NULL);
    2690      171409 :                         if (!re && has_label(e))
    2691         121 :                                 re = exps_bind_column(r->exps, e->r, NULL, NULL, 1);
    2692      171409 :                         if (re)
    2693      124514 :                                 return is_identity(re, r->l);
    2694             :                 }
    2695             :                 return 0;
    2696     1674557 :         case e_func: {
    2697     1674557 :                 sql_subfunc *f = e->f;
    2698     1674557 :                 return !f->func->s && strcmp(f->func->base.name, "identity") == 0;
    2699             :         }
    2700             :         default:
    2701             :                 return 0;
    2702             :         }
    2703             : }
    2704             : 
    2705             : list *
    2706         128 : exps_alias(mvc *sql, list *exps)
    2707             : {
    2708         128 :         list *nl = new_exp_list(sql->sa);
    2709             : 
    2710         128 :         if (exps)
    2711         740 :                 for (node *n = exps->h; n; n = n->next) {
    2712         612 :                         sql_exp *e = n->data, *ne;
    2713             : 
    2714         612 :                         assert(exp_name(e));
    2715         612 :                         ne = exp_ref(sql, e);
    2716         612 :                         append(nl, ne);
    2717             :                 }
    2718         128 :         return nl;
    2719             : }
    2720             : 
    2721             : list *
    2722      148047 : exps_copy(mvc *sql, list *exps)
    2723             : {
    2724             :         list *nl;
    2725             : 
    2726      148047 :         if (THRhighwater())
    2727           0 :                 return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    2728             : 
    2729      148047 :         if (!exps)
    2730             :                 return NULL;
    2731      143883 :         nl = new_exp_list(sql->sa);
    2732      590353 :         for (node *n = exps->h; n; n = n->next) {
    2733      446470 :                 sql_exp *arg = n->data;
    2734             : 
    2735      446470 :                 arg = exp_copy(sql, arg);
    2736      446470 :                 if (!arg)
    2737             :                         return NULL;
    2738      446470 :                 append(nl, arg);
    2739             :         }
    2740             :         return nl;
    2741             : }
    2742             : 
    2743             : sql_exp *
    2744      764157 : exp_copy(mvc *sql, sql_exp * e)
    2745             : {
    2746             :         sql_exp *l, *r, *r2, *ne = NULL;
    2747             : 
    2748      764157 :         if (THRhighwater())
    2749           0 :                 return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    2750             : 
    2751      764157 :         if (!e)
    2752             :                 return NULL;
    2753      764157 :         switch(e->type){
    2754      455052 :         case e_column:
    2755      455052 :                 ne = exp_column(sql->sa, e->l, e->r, exp_subtype(e), e->card, has_nil(e), is_unique(e), is_intern(e));
    2756      455052 :                 ne->flag = e->flag;
    2757      455052 :                 break;
    2758       57352 :         case e_cmp:
    2759       57352 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2760        3793 :                         list *l = exps_copy(sql, e->l);
    2761        3793 :                         list *r = exps_copy(sql, e->r);
    2762             : 
    2763        3793 :                         if (e->flag == cmp_filter)
    2764         195 :                                 ne = exp_filter(sql->sa, l, r, e->f, is_anti(e));
    2765             :                         else
    2766        3598 :                                 ne = exp_or(sql->sa, l, r, is_anti(e));
    2767       53559 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2768        5058 :                         sql_exp *l = exp_copy(sql, e->l);
    2769        5058 :                         list *r = exps_copy(sql, e->r);
    2770             : 
    2771        5058 :                         ne = exp_in(sql->sa, l, r, e->flag);
    2772             :                 } else {
    2773       48501 :                         l = exp_copy(sql, e->l);
    2774       48501 :                         r = exp_copy(sql, e->r);
    2775             : 
    2776       48501 :                         if (e->f) {
    2777         224 :                                 r2 = exp_copy(sql, e->f);
    2778         224 :                                 ne = exp_compare2(sql->sa, l, r, r2, e->flag, is_symmetric(e));
    2779             :                         } else {
    2780       48277 :                                 ne = exp_compare(sql->sa, l, r, e->flag);
    2781             :                         }
    2782             :                 }
    2783             :                 break;
    2784       34556 :         case e_convert:
    2785       34556 :                 ne = exp_convert(sql->sa, exp_copy(sql, e->l), exp_fromtype(e), exp_totype(e));
    2786       34556 :                 break;
    2787       19699 :         case e_aggr:
    2788             :         case e_func: {
    2789       19699 :                 list *l = exps_copy(sql, e->l);
    2790             : 
    2791       19699 :                 if (e->type == e_func)
    2792       17407 :                         ne = exp_op(sql->sa, l, e->f);
    2793             :                 else
    2794        2292 :                         ne = exp_aggr(sql->sa, l, e->f, need_distinct(e), need_no_nil(e), e->card, has_nil(e));
    2795       19699 :                 if (e->r) { /* copy obe and gbe lists */
    2796             :                         list *er = (list*) e->r;
    2797           0 :                         assert(list_length(er) == 2);
    2798           0 :                         ne->r = list_append(list_append(sa_list(sql->sa), exps_copy(sql, er->h->data)), exps_copy(sql, er->h->next->data));
    2799             :                 }
    2800             :                 break;
    2801             :         }
    2802      197496 :         case e_atom:
    2803      197496 :                 if (e->l)
    2804      190750 :                         ne = exp_atom(sql->sa, e->l);
    2805        6746 :                 else if (e->r) {
    2806             :                         sql_var_name *vname = (sql_var_name*) e->r;
    2807        6702 :                         ne = exp_param_or_declared(sql->sa, vname->sname, vname->name, &e->tpe, e->flag);
    2808          44 :                 } else if (e->f)
    2809           2 :                         ne = exp_values(sql->sa, exps_copy(sql, e->f));
    2810             :                 else
    2811          42 :                         ne = exp_atom_ref(sql->sa, e->flag, &e->tpe);
    2812             :                 break;
    2813           2 :         case e_psm:
    2814           2 :                 if (e->flag & PSM_SET) {
    2815           0 :                         ne = exp_set(sql->sa, e->alias.rname, e->alias.name, exp_copy(sql, e->l), GET_PSM_LEVEL(e->flag));
    2816           2 :                 } else if (e->flag & PSM_VAR) {
    2817           0 :                         if (e->f)
    2818           0 :                                 ne = exp_table(sql->sa, e->alias.name, e->f, GET_PSM_LEVEL(e->flag));
    2819             :                         else
    2820           0 :                                 ne = exp_var(sql->sa, e->alias.rname, e->alias.name, &e->tpe, GET_PSM_LEVEL(e->flag));
    2821           2 :                 } else if (e->flag & PSM_RETURN) {
    2822           0 :                         ne = exp_return(sql->sa, exp_copy(sql, e->l), GET_PSM_LEVEL(e->flag));
    2823           2 :                 } else if (e->flag & PSM_WHILE) {
    2824           0 :                         ne = exp_while(sql->sa, exp_copy(sql, e->l), exps_copy(sql, e->r));
    2825           2 :                 } else if (e->flag & PSM_IF) {
    2826           0 :                         ne = exp_if(sql->sa, exp_copy(sql, e->l), exps_copy(sql, e->r), exps_copy(sql, e->f));
    2827           2 :                 } else if (e->flag & PSM_REL) {
    2828           2 :                         return exp_ref(sql, e);
    2829           0 :                 } else if (e->flag & PSM_EXCEPTION) {
    2830           0 :                         ne = exp_exception(sql->sa, exp_copy(sql, e->l), sa_strdup(sql->sa, (const char *) e->r));
    2831             :                 }
    2832             :                 break;
    2833             :         }
    2834      764155 :         if (!ne)
    2835           0 :                 return ne;
    2836      764155 :         if (e->alias.name)
    2837      536070 :                 exp_prop_alias(sql->sa, ne, e);
    2838      764155 :         ne = exp_propagate(sql->sa, ne, e);
    2839      764155 :         if (is_freevar(e))
    2840       19266 :                 set_freevar(ne, is_freevar(e)-1);
    2841             :         return ne;
    2842             : }
    2843             : 
    2844             : atom *
    2845         951 : exp_flatten(mvc *sql, sql_exp *e)
    2846             : {
    2847         951 :         if (e->type == e_atom) {
    2848         522 :                 atom *v =  exp_value(sql, e);
    2849             : 
    2850         522 :                 if (v)
    2851         470 :                         return atom_dup(sql->sa, v);
    2852         429 :         } else if (e->type == e_convert) {
    2853         136 :                 atom *v = exp_flatten(sql, e->l);
    2854             : 
    2855         136 :                 if (v && atom_cast(sql->sa, v, exp_subtype(e)))
    2856             :                         return v;
    2857         104 :                 return NULL;
    2858         293 :         } else if (e->type == e_func) {
    2859         261 :                 sql_subfunc *f = e->f;
    2860         261 :                 list *l = e->l;
    2861         261 :                 sql_arg *res = (f->func->res)?(f->func->res->h->data):NULL;
    2862             : 
    2863             :                 /* TODO handle date + x months */
    2864         261 :                 if (!f->func->s && strcmp(f->func->base.name, "sql_add") == 0 && list_length(l) == 2 && res && EC_NUMBER(res->type.type->eclass)) {
    2865          18 :                         atom *l1 = exp_flatten(sql, l->h->data);
    2866          18 :                         atom *l2 = exp_flatten(sql, l->h->next->data);
    2867          18 :                         if (l1 && l2)
    2868           0 :                                 return atom_add(l1,l2);
    2869         243 :                 } else if (!f->func->s && strcmp(f->func->base.name, "sql_sub") == 0 && list_length(l) == 2 && res && EC_NUMBER(res->type.type->eclass)) {
    2870          17 :                         atom *l1 = exp_flatten(sql, l->h->data);
    2871          17 :                         atom *l2 = exp_flatten(sql, l->h->next->data);
    2872          17 :                         if (l1 && l2)
    2873          17 :                                 return atom_sub(l1,l2);
    2874             :                 }
    2875             :         }
    2876             :         return NULL;
    2877             : }
    2878             : 
    2879             : sql_exp *
    2880        2457 : exp_scale_algebra(mvc *sql, sql_subfunc *f, sql_rel *rel, sql_exp *l, sql_exp *r)
    2881             : {
    2882        2457 :         sql_subtype *lt = exp_subtype(l);
    2883        2457 :         sql_subtype *rt = exp_subtype(r);
    2884             : 
    2885        2457 :         if (lt->type->scale == SCALE_FIX && rt->scale &&
    2886         136 :                 strcmp(f->func->imp, "/") == 0) {
    2887         136 :                 sql_subtype *res = f->res->h->data;
    2888             :                 unsigned int scale, digits, digL, scaleL;
    2889             :                 sql_subtype nlt;
    2890             : 
    2891             :                 /* scale fixing may require a larger type ! */
    2892         136 :                 scaleL = (lt->scale < 3) ? 3 : lt->scale;
    2893             :                 scale = scaleL;
    2894         136 :                 scaleL += rt->scale;
    2895         136 :                 digL = lt->digits + (scaleL - lt->scale);
    2896         136 :                 digits = (digL > rt->digits) ? digL : rt->digits;
    2897             : 
    2898             :                 /* HACK alert: digits should be less than max */
    2899             : #ifdef HAVE_HGE
    2900         136 :                 if (res->type->radix == 10 && digits > 39)
    2901             :                         digits = 39;
    2902         136 :                 if (res->type->radix == 2 && digits > 128)
    2903             :                         digits = 128;
    2904             : #else
    2905             :                 if (res->type->radix == 10 && digits > 19)
    2906             :                         digits = 19;
    2907             :                 if (res->type->radix == 2 && digits > 64)
    2908             :                         digits = 64;
    2909             : #endif
    2910             : 
    2911         136 :                 sql_find_subtype(&nlt, lt->type->base.name, digL, scaleL);
    2912         136 :                 if (nlt.digits < scaleL)
    2913           2 :                         return sql_error(sql, 01, SQLSTATE(42000) "Scale (%d) overflows type", scaleL);
    2914         134 :                 l = exp_check_type(sql, &nlt, rel, l, type_equal);
    2915             : 
    2916         134 :                 sql_find_subtype(res, lt->type->base.name, digits, scale);
    2917             :         }
    2918             :         return l;
    2919             : }
    2920             : 
    2921             : void
    2922       22204 : exp_sum_scales(sql_subfunc *f, sql_exp *l, sql_exp *r)
    2923             : {
    2924       22204 :         sql_arg *ares = f->func->res->h->data;
    2925             : 
    2926       22204 :         if (strcmp(f->func->imp, "*") == 0 && ares->type.type->scale == SCALE_FIX) {
    2927             :                 sql_subtype t;
    2928       20990 :                 sql_subtype *lt = exp_subtype(l);
    2929       20990 :                 sql_subtype *rt = exp_subtype(r);
    2930       20990 :                 sql_subtype *res = f->res->h->data;
    2931             : 
    2932       20990 :                 res->scale = lt->scale + rt->scale;
    2933       20990 :                 res->digits = lt->digits + rt->digits;
    2934             : 
    2935             :                 /* HACK alert: digits should be less than max */
    2936             : #ifdef HAVE_HGE
    2937       20990 :                 if (ares->type.type->radix == 10 && res->digits > 39) {
    2938        2105 :                         res->digits = 39;
    2939        2105 :                         res->scale = MIN(res->scale, res->digits - 1);
    2940             :                 }
    2941       20990 :                 if (ares->type.type->radix == 2 && res->digits > 128) {
    2942          68 :                         res->digits = 128;
    2943          68 :                         res->scale = MIN(res->scale, res->digits - 1);
    2944             :                 }
    2945             : #else
    2946             :                 if (ares->type.type->radix == 10 && res->digits > 19) {
    2947             :                         res->digits = 19;
    2948             :                         res->scale = MIN(res->scale, res->digits - 1);
    2949             :                 }
    2950             :                 if (ares->type.type->radix == 2 && res->digits > 64) {
    2951             :                         res->digits = 64;
    2952             :                         res->scale = MIN(res->scale, res->digits - 1);
    2953             :                 }
    2954             : #endif
    2955             : 
    2956             :                 /* numeric types are fixed length */
    2957       20990 :                 if (ares->type.type->eclass == EC_NUM) {
    2958             : #ifdef HAVE_HGE
    2959       18644 :                         if (ares->type.type->localtype == TYPE_hge && res->digits == 128)
    2960          68 :                                 t = *sql_bind_localtype("hge");
    2961             :                         else
    2962             : #endif
    2963       18576 :                         if (ares->type.type->localtype == TYPE_lng && res->digits == 64)
    2964           0 :                                 t = *sql_bind_localtype("lng");
    2965             :                         else
    2966       18576 :                                 sql_find_numeric(&t, ares->type.type->localtype, res->digits);
    2967             :                 } else {
    2968        2346 :                         sql_find_subtype(&t, ares->type.type->base.name, res->digits, res->scale);
    2969             :                 }
    2970       20990 :                 *res = t;
    2971             :         }
    2972       22204 : }
    2973             : 
    2974             : int
    2975      328057 : exp_aggr_is_count(sql_exp *e)
    2976             : {
    2977      328057 :         if (e->type == e_aggr && !((sql_subfunc *)e->f)->func->s && strcmp(((sql_subfunc *)e->f)->func->base.name, "count") == 0)
    2978       29148 :                 return 1;
    2979             :         return 0;
    2980             : }
    2981             : 
    2982             : list *
    2983       41750 : check_distinct_exp_names(mvc *sql, list *exps)
    2984             : {
    2985             :         list *distinct_exps = NULL;
    2986             :         bool duplicates = false;
    2987             : 
    2988       41750 :         if (list_length(exps) < 2) {
    2989             :                 return exps; /* always true */
    2990       40205 :         } else if (list_length(exps) < 5) {
    2991       12776 :                 distinct_exps = list_distinct(exps, (fcmp) exp_equal, (fdup) NULL);
    2992             :         } else { /* for longer lists, use hashing */
    2993       27429 :                 sql_hash *ht = hash_new(sql->ta, list_length(exps), (fkeyvalue)&exp_key);
    2994             : 
    2995      322689 :                 for (node *n = exps->h; n && !duplicates; n = n->next) {
    2996      295260 :                         sql_exp *e = n->data;
    2997      295260 :                         int key = ht->key(e);
    2998      295260 :                         sql_hash_e *he = ht->buckets[key&(ht->size-1)];
    2999             : 
    3000      399176 :                         for (; he && !duplicates; he = he->chain) {
    3001      103916 :                                 sql_exp *f = he->value;
    3002             : 
    3003      103916 :                                 if (!exp_equal(e, f))
    3004             :                                         duplicates = true;
    3005             :                         }
    3006      295260 :                         hash_add(ht, key, e);
    3007             :                 }
    3008             :         }
    3009       40205 :         if ((distinct_exps && list_length(distinct_exps) != list_length(exps)) || duplicates)
    3010           5 :                 return NULL;
    3011             :         return exps;
    3012             : }
    3013             : 
    3014             : void
    3015         244 : exps_reset_freevar(list *exps)
    3016             : {
    3017         244 :         if (exps)
    3018         489 :                 for(node *n=exps->h; n; n=n->next) {
    3019         245 :                         sql_exp *e = n->data;
    3020             : 
    3021             :                         /*later use case per type */
    3022         245 :                         reset_freevar(e);
    3023             :                 }
    3024         244 : }
    3025             : 
    3026             : int
    3027         532 : rel_set_type_param(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *rel_exp, int upcast)
    3028             : {
    3029             :         sql_rel *r = rel;
    3030         532 :         int is_rel = exp_is_rel(rel_exp);
    3031             : 
    3032         532 :         if (!type || !rel_exp || (rel_exp->type != e_atom && rel_exp->type != e_column && !is_rel))
    3033             :                 return -1;
    3034             : 
    3035             :         /* use largest numeric types */
    3036         532 :         if (upcast && type->type->eclass == EC_NUM)
    3037             : #ifdef HAVE_HGE
    3038           6 :                 type = sql_bind_localtype("hge");
    3039             : #else
    3040             :                 type = sql_bind_localtype("lng");
    3041             : #endif
    3042         532 :         if (upcast && type->type->eclass == EC_FLT)
    3043           0 :                 type = sql_bind_localtype("dbl");
    3044             : 
    3045         532 :         if (is_rel)
    3046           7 :                 r = (sql_rel*) rel_exp->l;
    3047             : 
    3048         566 :         if ((rel_exp->type == e_atom && (rel_exp->l || rel_exp->r || rel_exp->f)) || rel_exp->type == e_column || is_rel) {
    3049             :                 /* it's not a parameter set possible parameters below */
    3050          34 :                 const char *relname = exp_relname(rel_exp), *expname = exp_name(rel_exp);
    3051          34 :                 if (rel_set_type_recurse(sql, type, r, &relname, &expname) < 0)
    3052           0 :                         return -1;
    3053         498 :         } else if (set_type_param(sql, type, rel_exp->flag) != 0)
    3054             :                 return -1;
    3055             : 
    3056         532 :         rel_exp->tpe = *type;
    3057         532 :         return 0;
    3058             : }
    3059             : 
    3060             : /* try to do an in-place conversion
    3061             :  *
    3062             :  * in-place conversion is only possible if the exp is a variable.
    3063             :  * This is only done to be able to map more cached queries onto the same
    3064             :  * interface.
    3065             :  */
    3066             : 
    3067             : static void
    3068     1926390 : convert_atom(atom *a, sql_subtype *rt)
    3069             : {
    3070     1926390 :         if (atom_null(a)) {
    3071       17500 :                 if (a->data.vtype != rt->type->localtype) {
    3072             :                         const void *p;
    3073             : 
    3074           0 :                         a->data.vtype = rt->type->localtype;
    3075           0 :                         p = ATOMnilptr(a->data.vtype);
    3076           0 :                         VALset(&a->data, a->data.vtype, (ptr) p);
    3077             :                 }
    3078             :         }
    3079     1926390 :         a->tpe = *rt;
    3080     1926390 : }
    3081             : 
    3082             : sql_exp *
    3083     3081083 : exp_convert_inplace(mvc *sql, sql_subtype *t, sql_exp *exp)
    3084             : {
    3085             :         atom *a;
    3086             : 
    3087             :         /* exclude named variables and variable lists */
    3088     3081083 :         if (exp->type != e_atom || exp->r /* named */ || exp->f /* list */ || !exp->l /* not direct atom */)
    3089             :                 return NULL;
    3090             : 
    3091             :         a = exp->l;
    3092     1934511 :         if (!a->isnull && t->scale && t->type->eclass != EC_FLT)
    3093             :                 return NULL;
    3094             : 
    3095     1930288 :         if (a && atom_cast(sql->sa, a, t)) {
    3096     1926390 :                 convert_atom(a, t);
    3097     1926390 :                 exp->tpe = *t;
    3098     1926390 :                 return exp;
    3099             :         }
    3100             :         return NULL;
    3101             : }
    3102             : 
    3103             : sql_exp *
    3104          92 : exp_numeric_supertype(mvc *sql, sql_exp *e )
    3105             : {
    3106          92 :         sql_subtype *tp = exp_subtype(e);
    3107             : 
    3108          92 :         if (tp->type->eclass == EC_DEC) {
    3109          20 :                 sql_subtype *dtp = sql_bind_localtype("dbl");
    3110             : 
    3111          20 :                 return exp_check_type(sql, dtp, NULL, e, type_cast);
    3112             :         }
    3113          72 :         if (tp->type->eclass == EC_NUM) {
    3114             : #ifdef HAVE_HGE
    3115          30 :                 sql_subtype *ltp = sql_bind_localtype("hge");
    3116             : #else
    3117             :                 sql_subtype *ltp = sql_bind_localtype("lng");
    3118             : #endif
    3119             : 
    3120          30 :                 return exp_check_type(sql, ltp, NULL, e, type_cast);
    3121             :         }
    3122             :         return e;
    3123             : }
    3124             : 
    3125             : sql_exp *
    3126     3078408 : exp_check_type(mvc *sql, sql_subtype *t, sql_rel *rel, sql_exp *exp, check_type tpe)
    3127             : {
    3128             :         int c, err = 0;
    3129             :         sql_exp* nexp = NULL;
    3130     3078408 :         sql_subtype *fromtype = exp_subtype(exp);
    3131             : 
    3132     3078408 :         if ((!fromtype || !fromtype->type) && rel_set_type_param(sql, t, rel, exp, 0) == 0)
    3133             :                 return exp;
    3134             : 
    3135             :         /* first try cheap internal (in-place) conversions ! */
    3136     3078071 :         if ((nexp = exp_convert_inplace(sql, t, exp)) != NULL)
    3137             :                 return nexp;
    3138             : 
    3139     1151688 :         if (fromtype && subtype_cmp(t, fromtype) != 0) {
    3140      420230 :                 if (EC_INTERVAL(fromtype->type->eclass) && (t->type->eclass == EC_NUM || t->type->eclass == EC_POS) && t->digits < fromtype->digits) {
    3141             :                         err = 1; /* conversion from interval to num depends on the number of digits */
    3142             :                 } else {
    3143      420228 :                         c = sql_type_convert(fromtype->type->eclass, t->type->eclass);
    3144      420228 :                         if (!c || (c == 2 && tpe == type_set) || (c == 3 && tpe != type_cast)) {
    3145             :                                 err = 1;
    3146             :                         } else {
    3147      419340 :                                 exp = exp_convert(sql->sa, exp, fromtype, t);
    3148             :                         }
    3149             :                 }
    3150             :         }
    3151             :         if (err) {
    3152         890 :                 const char *name = (exp->type == e_column && !has_label(exp)) ? exp_name(exp) : "%";
    3153        1144 :                 sql_exp *res = sql_error( sql, 03, SQLSTATE(42000) "types %s(%u,%u) and %s(%u,%u) are not equal%s%s%s",
    3154         890 :                         fromtype->type->base.name,
    3155             :                         fromtype->digits,
    3156             :                         fromtype->scale,
    3157         890 :                         t->type->base.name,
    3158             :                         t->digits,
    3159             :                         t->scale,
    3160             :                         (name[0] != '%' ? " for column '" : ""),
    3161             :                         (name[0] != '%' ? name : ""),
    3162         890 :                         (name[0] != '%' ? "'" : "")
    3163             :                 );
    3164         890 :                 return res;
    3165             :         }
    3166             :         return exp;
    3167             : }
    3168             : 
    3169             : sql_exp *
    3170        6150 : exp_values_set_supertype(mvc *sql, sql_exp *values, sql_subtype *opt_super)
    3171             : {
    3172        6150 :         assert(is_values(values));
    3173        6150 :         list *vals = exp_get_values(values), *nexps;
    3174        6150 :         sql_subtype *tpe = opt_super?opt_super:exp_subtype(vals->h->data);
    3175             : 
    3176        6150 :         if (!opt_super && tpe)
    3177        6069 :                 values->tpe = *tpe;
    3178             : 
    3179       26473 :         for (node *m = vals->h; m; m = m->next) {
    3180       20323 :                 sql_exp *e = m->data;
    3181             :                 sql_subtype super, *ttpe;
    3182             : 
    3183             :                 /* if the expression is a parameter set its type */
    3184       20323 :                 if (tpe && e->type == e_atom && !e->l && !e->r && !e->f && !e->tpe.type) {
    3185           1 :                         if (set_type_param(sql, tpe, e->flag) == 0)
    3186           1 :                                 e->tpe = *tpe;
    3187             :                         else
    3188           0 :                                 return NULL;
    3189             :                 }
    3190       20323 :                 ttpe = exp_subtype(e);
    3191       20323 :                 if (tpe && ttpe) {
    3192       20291 :                         supertype(&super, ttpe, tpe);
    3193       20291 :                         values->tpe = super;
    3194       20291 :                         tpe = &values->tpe;
    3195             :                 } else {
    3196             :                         tpe = ttpe;
    3197             :                 }
    3198             :         }
    3199             : 
    3200        6150 :         if (tpe) {
    3201             :                 /* if the expression is a parameter set its type */
    3202       26419 :                 for (node *m = vals->h; m; m = m->next) {
    3203       20295 :                         sql_exp *e = m->data;
    3204       20295 :                         if (e->type == e_atom && !e->l && !e->r && !e->f && !e->tpe.type) {
    3205           1 :                                 if (set_type_param(sql, tpe, e->flag) == 0)
    3206           1 :                                         e->tpe = *tpe;
    3207             :                                 else
    3208             :                                         return NULL;
    3209             :                         }
    3210             :                 }
    3211        6124 :                 values->tpe = *tpe;
    3212        6124 :                 nexps = sa_list(sql->sa);
    3213       26414 :                 for (node *m = vals->h; m; m = m->next) {
    3214       20293 :                         sql_exp *e = m->data;
    3215       20293 :                         e = exp_check_type(sql, &values->tpe, NULL, e, type_equal);
    3216       20293 :                         if (!e)
    3217             :                                 return NULL;
    3218       20290 :                         exp_label(sql->sa, e, ++sql->label);
    3219       20290 :                         append(nexps, e);
    3220             :                 }
    3221        6121 :                 values->f = nexps;
    3222             :         }
    3223             :         return values;
    3224             : }
    3225             : 
    3226             : static int
    3227         133 : exp_set_list_recurse(mvc *sql, sql_subtype *type, sql_exp *e, const char **relname, const char** expname)
    3228             : {
    3229         133 :         if (THRhighwater()) {
    3230           0 :                 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3231           0 :                 return -1;
    3232             :         }
    3233         133 :         assert(*relname && *expname);
    3234         133 :         if (!e)
    3235             :                 return 0;
    3236             : 
    3237         133 :         if (exp_is_rel(e)) {
    3238             :                 /* Try to set parameters on the list of projections of the subquery. For now I won't go any further, ugh */
    3239           1 :                 sql_rel *r = exp_rel_get_rel(sql->sa, e);
    3240           1 :                 if ((is_simple_project(r->op) || is_groupby(r->op)) && list_length(r->exps) == 1) {
    3241           2 :                         for (node *n = r->exps->h; n; n = n->next)
    3242           1 :                                 if (exp_set_list_recurse(sql, type, (sql_exp *) n->data, relname, expname) < 0)
    3243             :                                         return -1;
    3244             :                 }
    3245         132 :         } else if (e->type == e_atom) {
    3246         132 :                 if (e->f) {
    3247          71 :                         const char *next_rel = exp_relname(e), *next_exp = exp_name(e);
    3248          71 :                         if (next_rel && next_exp && !strcmp(next_rel, *relname) && !strcmp(next_exp, *expname))
    3249          30 :                                 for (node *n = ((list *) e->f)->h; n; n = n->next)
    3250          16 :                                         if (exp_set_list_recurse(sql, type, (sql_exp *) n->data, relname, expname) < 0)
    3251             :                                                 return -1;
    3252             :                 }
    3253         132 :                 if (e->f && !e->tpe.type) {
    3254          26 :                         e->tpe = *type;
    3255         106 :                 } else if (!e->l && !e->r && !e->f && !e->tpe.type) {
    3256          28 :                         if (set_type_param(sql, type, e->flag) == 0)
    3257          28 :                                 e->tpe = *type;
    3258             :                         else
    3259             :                                 return -1;
    3260             :                 }
    3261             :         }
    3262             :         return 0;
    3263             : }
    3264             : 
    3265             : static int
    3266         337 : exp_set_type_recurse(mvc *sql, sql_subtype *type, sql_exp *e, const char **relname, const char** expname)
    3267             : {
    3268         337 :         if (THRhighwater()) {
    3269           0 :                 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3270           0 :                 return -1;
    3271             :         }
    3272         337 :         assert(*relname && *expname);
    3273         337 :         if (!e)
    3274             :                 return 0;
    3275             : 
    3276         337 :         switch (e->type) {
    3277         128 :                 case e_atom: {
    3278         128 :                         const char *next_exp = exp_name(e);
    3279         128 :                         if (e->f || !next_exp || !strcmp(next_exp, *expname)) {
    3280         116 :                                 if (!e->f && next_exp)
    3281          11 :                                         *expname = next_exp;
    3282         116 :                                 return exp_set_list_recurse(sql, type, e, relname, expname);
    3283             :                         }
    3284             :                 } break;
    3285         175 :                 case e_convert:
    3286             :                 case e_column: {
    3287             :                         /* if the column pretended is found, set its type */
    3288         175 :                         const char *next_rel = exp_relname(e), *next_exp = exp_name(e);
    3289         175 :                         if (next_rel && *relname && !strcmp(next_rel, *relname)) {
    3290          73 :                                 *relname = (e->type == e_column && e->l) ? (const char*) e->l : next_rel;
    3291          73 :                                 if (next_exp && !strcmp(next_exp, *expname)) {
    3292           7 :                                         *expname = (e->type == e_column && e->r) ? (const char*) e->r : next_exp;
    3293           7 :                                         if (e->type == e_column && !e->tpe.type) {
    3294           6 :                                                 if (set_type_param(sql, type, e->flag) == 0)
    3295           6 :                                                         e->tpe = *type;
    3296             :                                                 else
    3297             :                                                         return -1;
    3298             :                                         }
    3299             :                                 }
    3300             :                         }
    3301         175 :                         if (e->type == e_convert)
    3302          14 :                                 exp_set_type_recurse(sql, type, e->l, relname, expname);
    3303             :                 } break;
    3304           2 :                 case e_psm: {
    3305           2 :                         if (e->flag & PSM_RETURN) {
    3306           0 :                                 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
    3307           0 :                                         exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
    3308           2 :                         } else if (e->flag & PSM_WHILE) {
    3309           0 :                                 exp_set_type_recurse(sql, type, e->l, relname, expname);
    3310           0 :                                 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
    3311           0 :                                         exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
    3312           2 :                         } else if (e->flag & PSM_IF) {
    3313           0 :                                 exp_set_type_recurse(sql, type, e->l, relname, expname);
    3314           0 :                                 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
    3315           0 :                                         exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
    3316           0 :                                 if (e->f)
    3317           0 :                                         for(node *n = ((list*)e->f)->h ; n ; n = n->next)
    3318           0 :                                                 exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
    3319           2 :                         } else if (e->flag & PSM_REL) {
    3320           2 :                                 rel_set_type_recurse(sql, type, e->l, relname, expname);
    3321           0 :                         } else if (e->flag & PSM_EXCEPTION) {
    3322           0 :                                 exp_set_type_recurse(sql, type, e->l, relname, expname);
    3323             :                         }
    3324             :                 } break;
    3325           2 :                 case e_aggr:
    3326             :                 case e_func: {
    3327           2 :                         if (e->l)
    3328           7 :                                 for(node *n = ((list*)e->l)->h ; n ; n = n->next)
    3329           5 :                                         exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
    3330           2 :                         if (e->type == e_func && e->r)
    3331           0 :                                 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
    3332           0 :                                         exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
    3333             :                 } break;
    3334          30 :                 case e_cmp: {
    3335          30 :                         if (e->flag == cmp_in || e->flag == cmp_notin) {
    3336           0 :                                 exp_set_type_recurse(sql, type, e->l, relname, expname);
    3337           0 :                                 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
    3338           0 :                                         exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
    3339          30 :                         } else if (e->flag == cmp_or || e->flag == cmp_filter) {
    3340           0 :                                 for(node *n = ((list*)e->l)->h ; n ; n = n->next)
    3341           0 :                                         exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
    3342           0 :                                 for(node *n = ((list*)e->r)->h ; n ; n = n->next)
    3343           0 :                                         exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
    3344             :                         } else {
    3345          30 :                                 if(e->l)
    3346          30 :                                         exp_set_type_recurse(sql, type, e->l, relname, expname);
    3347          30 :                                 if(e->r)
    3348          30 :                                         exp_set_type_recurse(sql, type, e->r, relname, expname);
    3349          30 :                                 if(e->f)
    3350           2 :                                         exp_set_type_recurse(sql, type, e->f, relname, expname);
    3351             :                         }
    3352             :                 } break;
    3353             :         }
    3354             :         return 0;
    3355             : }
    3356             : 
    3357             : int
    3358         136 : rel_set_type_recurse(mvc *sql, sql_subtype *type, sql_rel *rel, const char **relname, const char **expname)
    3359             : {
    3360         136 :         if (THRhighwater()) {
    3361           0 :                 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3362           0 :                 return -1;
    3363             :         }
    3364         136 :         assert(*relname && *expname);
    3365         136 :         if (!rel)
    3366             :                 return 0;
    3367             : 
    3368         128 :         if (rel->exps)
    3369         336 :                 for (node *n = rel->exps->h; n; n = n->next)
    3370         256 :                         exp_set_type_recurse(sql, type, (sql_exp*) n->data, relname, expname);
    3371             : 
    3372         128 :         switch (rel->op) {
    3373             :                 case op_basetable:
    3374             :                 case op_truncate:
    3375             :                         break;
    3376           0 :                 case op_table:
    3377           0 :                         if (IS_TABLE_PROD_FUNC(rel->flag) || rel->flag == TABLE_FROM_RELATION)
    3378           0 :                                 if (rel->l)
    3379           0 :                                         rel_set_type_recurse(sql, type, rel->l, relname, expname);
    3380             :                         break;
    3381          24 :                 case op_join:
    3382             :                 case op_left:
    3383             :                 case op_right:
    3384             :                 case op_full:
    3385             :                 case op_semi:
    3386             :                 case op_anti:
    3387             :                 case op_union:
    3388             :                 case op_inter:
    3389             :                 case op_except:
    3390             :                 case op_merge:
    3391          24 :                         if (rel->l)
    3392          24 :                                 rel_set_type_recurse(sql, type, rel->l, relname, expname);
    3393          24 :                         if (rel->r)
    3394          24 :                                 rel_set_type_recurse(sql, type, rel->r, relname, expname);
    3395             :                         break;
    3396          69 :                 case op_groupby:
    3397             :                 case op_project:
    3398             :                 case op_select:
    3399             :                 case op_topn:
    3400             :                 case op_sample:
    3401          69 :                         if (rel->l)
    3402          52 :                                 rel_set_type_recurse(sql, type, rel->l, relname, expname);
    3403             :                         break;
    3404           0 :                 case op_insert:
    3405             :                 case op_update:
    3406             :                 case op_delete:
    3407           0 :                         if (rel->r)
    3408           0 :                                 rel_set_type_recurse(sql, type, rel->r, relname, expname);
    3409             :                         break;
    3410           0 :                 case op_ddl:
    3411           0 :                         if (rel->flag == ddl_output || rel->flag == ddl_create_seq || rel->flag == ddl_alter_seq || rel->flag == ddl_alter_table || rel->flag == ddl_create_table || rel->flag == ddl_create_view) {
    3412           0 :                                 if (rel->l)
    3413           0 :                                         rel_set_type_recurse(sql, type, rel->l, relname, expname);
    3414           0 :                         } else if (rel->flag == ddl_list || rel->flag == ddl_exception) {
    3415           0 :                                 if (rel->l)
    3416           0 :                                         rel_set_type_recurse(sql, type, rel->l, relname, expname);
    3417           0 :                                 if (rel->r)
    3418           0 :                                         rel_set_type_recurse(sql, type, rel->r, relname, expname);
    3419             :                         }
    3420             :                         break;
    3421             :         }
    3422             :         return 0;
    3423             : }

Generated by: LCOV version 1.14