LCOV - code coverage report
Current view: top level - sql/server - rel_exp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1796 2049 87.7 %
Date: 2024-11-15 19:37:45 Functions: 168 183 91.8 %

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

Generated by: LCOV version 1.14