LCOV - code coverage report
Current view: top level - sql/server - rel_exp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1596 1783 89.5 %
Date: 2024-04-25 20:03:45 Functions: 156 166 94.0 %

          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 "rel_exp.h"
      17             : #include "rel_rel.h"
      18             : #include "rel_basetable.h"
      19             : #include "rel_prop.h"
      20             : 
      21             : comp_type
      22      811021 : compare_str2type(const char *compare_op)
      23             : {
      24      811021 :         comp_type type = cmp_filter;
      25             : 
      26      811021 :         if (compare_op[0] == '=') {
      27             :                 type = cmp_equal;
      28      159328 :         } else if (compare_op[0] == '<') {
      29      102030 :                 type = cmp_lt;
      30      102030 :                 if (compare_op[1] == '>')
      31             :                         type = cmp_notequal;
      32       23121 :                 else if (compare_op[1] == '=')
      33        4160 :                         type = cmp_lte;
      34       57298 :         } else if (compare_op[0] == '>') {
      35       57298 :                 type = cmp_gt;
      36       57298 :                 if (compare_op[1] == '=')
      37        3307 :                         type = cmp_gte;
      38             :         }
      39      811021 :         return type;
      40             : }
      41             : 
      42             : comp_type
      43       50907 : swap_compare( comp_type t )
      44             : {
      45       50907 :         switch(t) {
      46             :         case cmp_equal:
      47             :                 return cmp_equal;
      48             :         case cmp_lt:
      49             :                 return cmp_gt;
      50             :         case cmp_lte:
      51             :                 return cmp_gte;
      52             :         case cmp_gte:
      53             :                 return cmp_lte;
      54             :         case cmp_gt:
      55             :                 return cmp_lt;
      56             :         case cmp_notequal:
      57             :                 return cmp_notequal;
      58             :         default:
      59             :                 return cmp_equal;
      60             :         }
      61             : }
      62             : 
      63             : comp_type
      64        7654 : negate_compare( comp_type t )
      65             : {
      66        7654 :         switch(t) {
      67             :         case cmp_equal:
      68             :                 return cmp_notequal;
      69          24 :         case cmp_notequal:
      70          24 :                 return cmp_equal;
      71           2 :         case cmp_lt:
      72           2 :                 return cmp_gte;
      73           5 :         case cmp_lte:
      74           5 :                 return cmp_gt;
      75           2 :         case cmp_gte:
      76           2 :                 return cmp_lt;
      77           3 :         case cmp_gt:
      78           3 :                 return cmp_lte;
      79             : 
      80           0 :         case cmp_in:
      81           0 :                 return cmp_notin;
      82           0 :         case cmp_notin:
      83           0 :                 return cmp_in;
      84             : 
      85           0 :         default:
      86           0 :                 return t;
      87             :         }
      88             : }
      89             : 
      90             : comp_type
      91        3153 : range2lcompare( int r )
      92             : {
      93        3153 :         if (r&1) {
      94             :                 return cmp_gte;
      95             :         } else {
      96        1169 :                 return cmp_gt;
      97             :         }
      98             : }
      99             : 
     100             : comp_type
     101        3210 : range2rcompare( int r )
     102             : {
     103        3210 :         if (r&2) {
     104             :                 return cmp_lte;
     105             :         } else {
     106        1206 :                 return cmp_lt;
     107             :         }
     108             : }
     109             : 
     110             : int
     111        1917 : compare2range( int l, int r )
     112             : {
     113        1917 :         if (l == cmp_gt) {
     114        1789 :                 if (r == cmp_lt)
     115             :                         return 0;
     116          28 :                 else if (r == cmp_lte)
     117          28 :                         return 2;
     118         128 :         } else if (l == cmp_gte) {
     119         128 :                 if (r == cmp_lt)
     120             :                         return 1;
     121          86 :                 else if (r == cmp_lte)
     122          86 :                         return 3;
     123             :         }
     124             :         return -1;
     125             : }
     126             : 
     127             : int
     128         108 : compare_funcs2range(const char *l_op, const char *r_op)
     129             : {
     130         108 :         assert(l_op[0] == '>' && r_op[0] == '<');
     131         108 :         if (!l_op[1] && !r_op[1])
     132             :                 return 0;
     133         105 :         if (!l_op[1] && r_op[1] == '=')
     134             :                 return 2;
     135         105 :         if (l_op[1] == '=' && !r_op[1])
     136             :                 return 1;
     137          13 :         if (l_op[1] == '=' && r_op[1] == '=')
     138             :                 return 3;
     139           0 :         assert(0);
     140             :         return 0;
     141             : }
     142             : 
     143             : static sql_exp *
     144    20659731 : exp_create(sql_allocator *sa, int type)
     145             : {
     146    20659731 :         sql_exp *e = SA_NEW(sa, sql_exp);
     147             : 
     148    20659553 :         if (!e)
     149             :                 return NULL;
     150    20659553 :         *e = (sql_exp) {
     151    20659553 :                 .type = (expression_type) type,
     152             :         };
     153    20659553 :         return e;
     154             : }
     155             : 
     156             : sql_exp *
     157      455952 : exp_compare(sql_allocator *sa, sql_exp *l, sql_exp *r, int cmptype)
     158             : {
     159      455952 :         sql_exp *e = exp_create(sa, e_cmp);
     160      455952 :         if (e == NULL)
     161             :                 return NULL;
     162      455952 :         e->card = MAX(l->card,r->card);
     163      455952 :         e->l = l;
     164      455952 :         e->r = r;
     165      455952 :         e->flag = cmptype;
     166      455952 :         if (!has_nil(l) && !has_nil(r))
     167       15339 :                 set_has_no_nil(e);
     168             :         return e;
     169             : }
     170             : 
     171             : sql_exp *
     172        6588 : exp_compare2(sql_allocator *sa, sql_exp *l, sql_exp *r, sql_exp *f, int cmptype, int symmetric)
     173             : {
     174        6588 :         sql_exp *e = exp_create(sa, e_cmp);
     175        6588 :         if (e == NULL)
     176             :                 return NULL;
     177        6588 :         assert(f);
     178        6588 :         e->card = MAX(MAX(l->card,r->card),f->card);
     179        6588 :         e->l = l;
     180        6588 :         e->r = r;
     181        6588 :         e->f = f;
     182        6588 :         e->flag = cmptype;
     183        6588 :         if (symmetric)
     184          77 :                 set_symmetric(e);
     185        6588 :         if (!has_nil(l) && !has_nil(r) && !has_nil(f))
     186         305 :                 set_has_no_nil(e);
     187             :         return e;
     188             : }
     189             : 
     190             : sql_exp *
     191        5144 : exp_filter(sql_allocator *sa, list *l, list *r, sql_subfunc *f, int anti)
     192             : {
     193        5144 :         sql_exp *e = exp_create(sa, e_cmp);
     194             : 
     195        5144 :         if (e == NULL)
     196             :                 return NULL;
     197        5144 :         e->card = MAX(exps_card(l),exps_card(r));
     198        5144 :         e->l = l;
     199        5144 :         e->r = r;
     200        5144 :         e->f = f;
     201        5144 :         e->flag = cmp_filter;
     202        5144 :         if (anti)
     203         752 :                 set_anti(e);
     204        5144 :         if (!have_nil(l) && !have_nil(r))
     205        2354 :                 set_has_no_nil(e);
     206             :         return e;
     207             : }
     208             : 
     209             : sql_exp *
     210       64842 : exp_or(sql_allocator *sa, list *l, list *r, int anti)
     211             : {
     212       64842 :         sql_exp *e = exp_create(sa, e_cmp);
     213             : 
     214       64842 :         if (e == NULL)
     215             :                 return NULL;
     216       64842 :         e->card = MAX(exps_card(l),exps_card(r));
     217       64842 :         e->l = l;
     218       64842 :         e->r = r;
     219       64842 :         e->flag = cmp_or;
     220       64842 :         if (anti)
     221           0 :                 set_anti(e);
     222       64842 :         if (!have_nil(l) && !have_nil(r))
     223        1116 :                 set_has_no_nil(e);
     224             :         return e;
     225             : }
     226             : 
     227             : sql_exp *
     228       28086 : exp_in(sql_allocator *sa, sql_exp *l, list *r, int cmptype)
     229             : {
     230       28086 :         sql_exp *e = exp_create(sa, e_cmp);
     231       28086 :         unsigned int exps_card = CARD_ATOM;
     232             : 
     233       28086 :         if (e == NULL)
     234             :                 return NULL;
     235             : 
     236             :         /* ignore the cardinalites of sub-relations */
     237      164986 :         for (node *n = r->h; n ; n = n->next) {
     238      136900 :                 sql_exp *next = n->data;
     239             : 
     240      136900 :                 if (!exp_is_rel(next) && exps_card < next->card)
     241      136900 :                         exps_card = next->card;
     242             :         }
     243       28086 :         e->card = MAX(l->card, exps_card);
     244       28086 :         e->l = l;
     245       28086 :         e->r = r;
     246       28086 :         assert( cmptype == cmp_in || cmptype == cmp_notin);
     247       28086 :         e->flag = cmptype;
     248       28086 :         if (!has_nil(l) && !have_nil(r))
     249        1133 :                 set_has_no_nil(e);
     250             :         return e;
     251             : }
     252             : 
     253             : sql_exp *
     254       36771 : exp_in_func(mvc *sql, sql_exp *le, sql_exp *vals, int anyequal, int is_tuple)
     255             : {
     256       36771 :         sql_subfunc *a_func = NULL;
     257       36771 :         sql_exp *e = le;
     258             : 
     259       36771 :         if (is_tuple) {
     260        5495 :                 list *l = exp_get_values(e);
     261        5495 :                 e = l->h->data;
     262             :         }
     263       43739 :         if (!(a_func = sql_bind_func(sql, "sys", anyequal ? "sql_anyequal" : "sql_not_anyequal", exp_subtype(e), exp_subtype(e), F_FUNC, true)))
     264           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");
     265       36771 :         e = exp_binop(sql->sa, le, vals, a_func);
     266       36771 :         if (e) {
     267       36771 :                 unsigned int exps_card = CARD_ATOM;
     268             : 
     269             :                 /* ignore the cardinalites of sub-relations */
     270       36771 :                 if (vals->type == e_atom && vals->f) {
     271      162701 :                         for (node *n = ((list*)vals->f)->h ; n ; n = n->next) {
     272      128793 :                                 sql_exp *next = n->data;
     273             : 
     274      128793 :                                 if (!exp_is_rel(next) && exps_card < next->card)
     275      128793 :                                         exps_card = next->card;
     276             :                         }
     277        2863 :                 } else if (!exp_is_rel(vals))
     278        2863 :                         exps_card = vals->card;
     279             : 
     280       36771 :                 e->card = MAX(le->card, exps_card);
     281       36771 :                 if (!has_nil(le) && !has_nil(vals))
     282          84 :                         set_has_no_nil(e);
     283             :         }
     284             :         return e;
     285             : }
     286             : 
     287             : sql_exp *
     288        5466 : exp_in_aggr(mvc *sql, sql_exp *le, sql_exp *vals, int anyequal, int is_tuple)
     289             : {
     290        5466 :         sql_subfunc *a_func = NULL;
     291        5466 :         sql_exp *e = le;
     292             : 
     293        5466 :         if (is_tuple) {
     294           0 :                 list *l = exp_get_values(e);
     295           0 :                 e = l->h->data;
     296             :         }
     297        5475 :         if (!(a_func = sql_bind_func(sql, "sys", anyequal ? "anyequal" : "allnotequal", exp_subtype(e), exp_subtype(e), F_AGGR, true)))
     298           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");
     299        5466 :         e = exp_aggr2(sql->sa, le, vals, a_func, need_distinct(e), need_no_nil(e), e->card, has_nil(e));
     300        5466 :         if (e) {
     301        5466 :                 unsigned int exps_card = CARD_ATOM;
     302             : 
     303             :                 /* ignore the cardinalites of sub-relations */
     304        5466 :                 if (vals->type == e_atom && vals->f) {
     305       30928 :                         for (node *n = ((list*)vals->f)->h ; n ; n = n->next) {
     306       25462 :                                 sql_exp *next = n->data;
     307             : 
     308       25462 :                                 if (!exp_is_rel(next) && exps_card < next->card)
     309       25462 :                                         exps_card = next->card;
     310             :                         }
     311           0 :                 } else if (!exp_is_rel(vals))
     312           0 :                         exps_card = vals->card;
     313             : 
     314        5466 :                 e->card = MAX(le->card, exps_card);
     315        5466 :                 if (!has_nil(le) && !has_nil(vals))
     316           0 :                         set_has_no_nil(e);
     317             :         }
     318             :         return e;
     319             : }
     320             : 
     321             : sql_exp *
     322      125676 : exp_compare_func(mvc *sql, sql_exp *le, sql_exp *re, const char *compareop, int quantifier)
     323             : {
     324      125676 :         sql_subfunc *cmp_func = sql_bind_func(sql, "sys", compareop, exp_subtype(le), exp_subtype(le), F_FUNC, true);
     325      125676 :         sql_exp *e = NULL;
     326             : 
     327      125676 :         if (cmp_func == NULL)
     328             :                 return NULL;
     329             : 
     330      125676 :         e = exp_binop(sql->sa, le, re, cmp_func);
     331      125676 :         if (e) {
     332      125676 :                 e->flag = quantifier;
     333             :                 /* At ANY and ALL operators, the cardinality on the right side is ignored if it is a sub-relation */
     334      125676 :                 e->card = quantifier && exp_is_rel(re) ? le->card : MAX(le->card, re->card);
     335      125676 :                 if (!has_nil(le) && !has_nil(re))
     336        3142 :                         set_has_no_nil(e);
     337             :         }
     338             :         return e;
     339             : }
     340             : 
     341             : static sql_subtype*
     342     1332916 : dup_subtype(sql_allocator *sa, sql_subtype *st)
     343             : {
     344     1332916 :         sql_subtype *res = SA_NEW(sa, sql_subtype);
     345             : 
     346     1332916 :         if (res == NULL)
     347             :                 return NULL;
     348     1332916 :         *res = *st;
     349     1332916 :         return res;
     350             : }
     351             : 
     352             : sql_exp *
     353      666458 : exp_convert(sql_allocator *sa, sql_exp *exp, sql_subtype *fromtype, sql_subtype *totype )
     354             : {
     355      666458 :         sql_exp *e = exp_create(sa, e_convert);
     356      666458 :         if (e == NULL)
     357             :                 return NULL;
     358      666458 :         e->card = exp->card;
     359      666458 :         e->l = exp;
     360      666458 :         totype = dup_subtype(sa, totype);
     361      666458 :         e->r = append(append(sa_list(sa), dup_subtype(sa, fromtype)),totype);
     362      666458 :         e->tpe = *totype;
     363      666458 :         e->alias = exp->alias;
     364      666458 :         if (!has_nil(exp))
     365       82541 :                 set_has_no_nil(e);
     366             :         return e;
     367             : }
     368             : 
     369             : sql_exp *
     370     1142696 : exp_op( sql_allocator *sa, list *l, sql_subfunc *f )
     371             : {
     372     1142696 :         sql_exp *e = exp_create(sa, e_func);
     373     1142696 :         if (e == NULL)
     374             :                 return NULL;
     375     1142696 :         e->card = exps_card(l);
     376     1142696 :         e->l = l;
     377     1142696 :         e->f = f;
     378     1142696 :         e->semantics = f->func->semantics;
     379     1142696 :         if (!is_semantics(e) && !is_any(e) && l && !have_nil(l))
     380       35606 :                 set_has_no_nil(e);
     381             :         return e;
     382             : }
     383             : 
     384             : sql_exp *
     385       17493 : exp_rank_op( sql_allocator *sa, list *l, list *gbe, list *obe, sql_subfunc *f )
     386             : {
     387       17493 :         sql_exp *e = exp_create(sa, e_func);
     388       17493 :         if (e == NULL)
     389             :                 return NULL;
     390       17493 :         e->card = list_empty(l)?CARD_MULTI:exps_card(l);
     391       17493 :         e->l = l;
     392       17493 :         e->r = append(append(sa_list(sa), gbe), obe);
     393       17493 :         e->f = f;
     394       17493 :         if (!f->func->s && strcmp(f->func->base.name, "count") == 0)
     395         179 :                 set_has_no_nil(e);
     396       17493 :         e->semantics = f->func->semantics;
     397       17493 :         return e;
     398             : }
     399             : 
     400             : sql_exp *
     401       59724 : exp_aggr( sql_allocator *sa, list *l, sql_subfunc *a, int distinct, int no_nils, unsigned int card, int has_nils )
     402             : {
     403       59724 :         sql_exp *e = exp_create(sa, e_aggr);
     404       59724 :         if (e == NULL)
     405             :                 return NULL;
     406       59724 :         e->card = card;
     407       59724 :         e->l = l;
     408       59724 :         e->f = a;
     409       59724 :         e->semantics = a->func->semantics;
     410       59724 :         if (distinct)
     411         373 :                 set_distinct(e);
     412       59724 :         if (no_nils)
     413       24793 :                 set_no_nil(e);
     414       59724 :         if ((!a->func->semantics && !has_nils) || (!a->func->s && strcmp(a->func->base.name, "count") == 0))
     415       23195 :                 set_has_no_nil(e);
     416             :         return e;
     417             : }
     418             : 
     419             : sql_exp *
     420     4770715 : exp_atom(sql_allocator *sa, atom *a)
     421             : {
     422     4770715 :         sql_exp *e = exp_create(sa, e_atom);
     423     4770539 :         if (e == NULL)
     424             :                 return NULL;
     425     4770539 :         e->card = CARD_ATOM;
     426     4770539 :         e->tpe = a->tpe;
     427     4770539 :         e->l = a;
     428     4770539 :         if (!a->isnull)
     429     4561761 :                 set_has_no_nil(e);
     430             :         return e;
     431             : }
     432             : 
     433             : sql_exp *
     434           0 : exp_atom_max(sql_allocator *sa, sql_subtype *tpe)
     435             : {
     436           0 :         if (tpe->type->localtype == TYPE_bte) {
     437           0 :                 return exp_atom_bte(sa, GDK_bte_max);
     438             :         } else if (tpe->type->localtype == TYPE_sht) {
     439           0 :                 return exp_atom_sht(sa, GDK_sht_max);
     440             :         } else if (tpe->type->localtype == TYPE_int) {
     441           0 :                 return exp_atom_int(sa, GDK_int_max);
     442             :         } else if (tpe->type->localtype == TYPE_lng) {
     443           0 :                 return exp_atom_lng(sa, GDK_lng_max);
     444             : #ifdef HAVE_HGE
     445             :         } else if (tpe->type->localtype == TYPE_hge) {
     446           0 :                 return exp_atom_hge(sa, GDK_hge_max);
     447             : #endif
     448             :         }
     449             :         return NULL;
     450             : }
     451             : 
     452             : sql_exp *
     453      129493 : exp_atom_bool(sql_allocator *sa, int b)
     454             : {
     455      129493 :         sql_subtype bt;
     456             : 
     457      129493 :         sql_find_subtype(&bt, "boolean", 0, 0);
     458      129489 :         if (b)
     459       84775 :                 return exp_atom(sa, atom_bool(sa, &bt, TRUE ));
     460             :         else
     461       44714 :                 return exp_atom(sa, atom_bool(sa, &bt, FALSE ));
     462             : }
     463             : 
     464             : sql_exp *
     465           0 : exp_atom_bte(sql_allocator *sa, bte i)
     466             : {
     467           0 :         sql_subtype it;
     468             : 
     469           0 :         sql_find_subtype(&it, "tinyint", 3, 0);
     470           0 :         return exp_atom(sa, atom_int(sa, &it, i ));
     471             : }
     472             : 
     473             : sql_exp *
     474           0 : exp_atom_sht(sql_allocator *sa, sht i)
     475             : {
     476           0 :         sql_subtype it;
     477             : 
     478           0 :         sql_find_subtype(&it, "smallint", 5, 0);
     479           0 :         return exp_atom(sa, atom_int(sa, &it, i ));
     480             : }
     481             : 
     482             : sql_exp *
     483      820634 : exp_atom_int(sql_allocator *sa, int i)
     484             : {
     485      820634 :         sql_subtype it;
     486             : 
     487      820634 :         sql_find_subtype(&it, "int", 9, 0);
     488      820636 :         return exp_atom(sa, atom_int(sa, &it, i ));
     489             : }
     490             : 
     491             : sql_exp *
     492       15290 : exp_atom_lng(sql_allocator *sa, lng i)
     493             : {
     494       15290 :         sql_subtype it;
     495             : 
     496             : #ifdef HAVE_HGE
     497       15290 :         sql_find_subtype(&it, "bigint", 18, 0);
     498             : #else
     499             :         sql_find_subtype(&it, "bigint", 19, 0);
     500             : #endif
     501       15291 :         return exp_atom(sa, atom_int(sa, &it, i ));
     502             : }
     503             : 
     504             : sql_exp *
     505       15814 : exp_atom_oid(sql_allocator *sa, oid i)
     506             : {
     507       15814 :         sql_subtype it;
     508             : 
     509             : #if SIZEOF_OID == SIZEOF_INT
     510             :         sql_find_subtype(&it, "oid", 31, 0);
     511             : #else
     512       15814 :         sql_find_subtype(&it, "oid", 63, 0);
     513             : #endif
     514       15814 :         return exp_atom(sa, atom_int(sa, &it, i ));
     515             : }
     516             : 
     517             : #ifdef HAVE_HGE
     518             : sql_exp *
     519           1 : exp_atom_hge(sql_allocator *sa, hge i)
     520             : {
     521           1 :         sql_subtype it;
     522             : 
     523           1 :         sql_find_subtype(&it, "hugeint", 39, 0);
     524           1 :         return exp_atom(sa, atom_int(sa, &it, i ));
     525             : }
     526             : #endif
     527             : 
     528             : sql_exp *
     529           0 : exp_atom_flt(sql_allocator *sa, flt f)
     530             : {
     531           0 :         sql_subtype it;
     532             : 
     533           0 :         sql_find_subtype(&it, "real", 24, 0);
     534           0 :         return exp_atom(sa, atom_float(sa, &it, (dbl)f ));
     535             : }
     536             : 
     537             : sql_exp *
     538           0 : exp_atom_dbl(sql_allocator *sa, dbl f)
     539             : {
     540           0 :         sql_subtype it;
     541             : 
     542           0 :         sql_find_subtype(&it, "double", 53, 0);
     543           0 :         return exp_atom(sa, atom_float(sa, &it, (dbl)f ));
     544             : }
     545             : 
     546             : sql_exp *
     547       81121 : exp_atom_str(sql_allocator *sa, const char *s, sql_subtype *st)
     548             : {
     549      158899 :         return exp_atom(sa, atom_string(sa, st, s?sa_strdup(sa, s):NULL));
     550             : }
     551             : 
     552             : sql_exp *
     553      700497 : exp_atom_clob(sql_allocator *sa, const char *s)
     554             : {
     555      700497 :         sql_subtype clob;
     556             : 
     557      700497 :         sql_find_subtype(&clob, "clob", 0, 0);
     558     1399531 :         return exp_atom(sa, atom_string(sa, &clob, s?sa_strdup(sa, s):NULL));
     559             : }
     560             : 
     561             : sql_exp *
     562      255755 : exp_atom_ptr(sql_allocator *sa, void *s)
     563             : {
     564      255755 :         sql_subtype *t = sql_bind_localtype("ptr");
     565      255755 :         return exp_atom(sa, atom_ptr(sa, t, s));
     566             : }
     567             : 
     568             : sql_exp *
     569        1663 : exp_atom_ref(sql_allocator *sa, int i, sql_subtype *tpe)
     570             : {
     571        1663 :         sql_exp *e = exp_create(sa, e_atom);
     572        1663 :         if (e == NULL)
     573             :                 return NULL;
     574        1663 :         e->card = CARD_ATOM;
     575        1663 :         e->flag = i;
     576        1663 :         if (tpe)
     577        1663 :                 e->tpe = *tpe;
     578             :         return e;
     579             : }
     580             : 
     581             : sql_exp *
     582      111035 : exp_null(sql_allocator *sa, sql_subtype *tpe)
     583             : {
     584      111035 :         atom *a = atom_general(sa, tpe, NULL);
     585      111035 :         return exp_atom(sa, a);
     586             : }
     587             : 
     588             : sql_exp *
     589           2 : exp_zero(sql_allocator *sa, sql_subtype *tpe)
     590             : {
     591           2 :         atom *a = atom_zero_value(sa, tpe);
     592           2 :         return exp_atom(sa, a);
     593             : }
     594             : 
     595             : atom *
     596         568 : exp_value(mvc *sql, sql_exp *e)
     597             : {
     598         568 :         if (!e || e->type != e_atom)
     599             :                 return NULL;
     600         554 :         if (e->l) { /* literal */
     601             :                 return e->l;
     602          50 :         } else if (e->r) { /* param (ie not set) */
     603          50 :                 sql_var_name *vname = (sql_var_name*) e->r;
     604             : 
     605          50 :                 assert(e->flag != 0 || vname->sname); /* global variables must have a schema */
     606          50 :                 sql_var *var = e->flag == 0 ? find_global_var(sql, mvc_bind_schema(sql, vname->sname), vname->name) :
     607          50 :                                                                           stack_find_var_at_level(sql, vname->name, e->flag);
     608          50 :                 if (var)
     609           0 :                         return &(var->var);
     610             :         }
     611             :         return NULL;
     612             : }
     613             : 
     614             : sql_exp *
     615      151233 : exp_param_or_declared(sql_allocator *sa, const char *sname, const char *name, sql_subtype *tpe, int frame)
     616             : {
     617      151233 :         sql_var_name *vname;
     618      151233 :         sql_exp *e = exp_create(sa, e_atom);
     619      151233 :         if (e == NULL)
     620             :                 return NULL;
     621             : 
     622      151233 :         e->r = sa_alloc(sa, sizeof(sql_var_name));
     623      151233 :         vname = (sql_var_name*) e->r;
     624      151233 :         vname->sname = sname;
     625      151233 :         vname->name = name;
     626      151233 :         e->card = CARD_ATOM;
     627      151233 :         e->flag = frame;
     628      151233 :         if (tpe)
     629      151233 :                 e->tpe = *tpe;
     630             :         return e;
     631             : }
     632             : 
     633             : sql_exp *
     634      209695 : exp_values(sql_allocator *sa, list *exps)
     635             : {
     636      209695 :         sql_exp *e = exp_create(sa, e_atom);
     637      209692 :         if (e == NULL)
     638             :                 return NULL;
     639      209692 :         e->card = exps_card(exps);
     640      209698 :         e->f = exps;
     641      209698 :         return e;
     642             : }
     643             : 
     644             : list *
     645       27282 : exp_get_values(sql_exp *e)
     646             : {
     647       27282 :         if (is_atom(e->type) && e->f)
     648             :                 return e->f;
     649             :         return NULL;
     650             : }
     651             : 
     652             : list *
     653       40152 : exp_types(sql_allocator *sa, list *exps)
     654             : {
     655       40152 :         list *l = sa_list(sa);
     656             : 
     657       40152 :         if (exps)
     658       89789 :                 for (node *n = exps->h; n; n = n->next)
     659       49637 :                         list_append(l, exp_subtype(n->data));
     660       40152 :         return l;
     661             : }
     662             : 
     663             : int
     664      987198 : have_nil(list *exps)
     665             : {
     666      987198 :         int has_nil = 0;
     667             : 
     668      987198 :         if (exps)
     669     2134188 :                 for (node *n = exps->h; n && !has_nil; n = n->next) {
     670     1146990 :                         sql_exp *e = n->data;
     671     1146990 :                         has_nil |= has_nil(e);
     672             :                 }
     673      987198 :         return has_nil;
     674             : }
     675             : 
     676             : int
     677           3 : have_semantics(list *exps)
     678             : {
     679           3 :         int has_semantics = 0;
     680             : 
     681           3 :         if (exps)
     682           4 :                 for (node *n = exps->h; n && !has_semantics; n = n->next) {
     683           2 :                         sql_exp *e = n->data;
     684           4 :                         has_semantics |= is_compare(e->type) && is_semantics(e);
     685             :                 }
     686           3 :         return has_semantics;
     687             : }
     688             : 
     689             : sql_exp *
     690    12942459 : exp_column(sql_allocator *sa, const char *rname, const char *cname, sql_subtype *t, unsigned int card, int has_nils, int unique, int intern)
     691             : {
     692    12942459 :         sql_exp *e = exp_create(sa, e_column);
     693             : 
     694    12942347 :         if (e == NULL)
     695             :                 return NULL;
     696    12942347 :         assert(cname);
     697    12942347 :         e->card = card;
     698    12942347 :         e->alias.name = cname;
     699    12942347 :         e->alias.rname = rname;
     700    12942347 :         e->r = (char*)e->alias.name;
     701    12942347 :         e->l = (char*)e->alias.rname;
     702    12942347 :         if (t)
     703    12941838 :                 e->tpe = *t;
     704    12942347 :         if (!has_nils)
     705     1712956 :                 set_has_no_nil(e);
     706    12942347 :         if (unique)
     707      952047 :                 set_unique(e);
     708    12942347 :         if (intern)
     709      824350 :                 set_intern(e);
     710             :         return e;
     711             : }
     712             : 
     713             : sql_exp *
     714     9236364 : exp_propagate(sql_allocator *sa, sql_exp *ne, sql_exp *oe)
     715             : {
     716     9236364 :         if (has_label(oe) &&
     717      583742 :            (oe->alias.rname == ne->alias.rname || (oe->alias.rname && ne->alias.rname && strcmp(oe->alias.rname, ne->alias.rname) == 0)) &&
     718      570250 :            (oe->alias.name == ne->alias.name || (oe->alias.name && ne->alias.name && strcmp(oe->alias.name, ne->alias.name) == 0)))
     719      570199 :                 ne->alias.label = oe->alias.label;
     720     9236364 :         if (is_intern(oe))
     721      285589 :                 set_intern(ne);
     722     9236364 :         if (is_anti(oe))
     723        5139 :                 set_anti(ne);
     724     9236364 :         if (is_semantics(oe))
     725      552812 :                 set_semantics(ne);
     726     9236364 :         if (is_any(oe))
     727          23 :                 set_any(ne);
     728     9236364 :         if (is_symmetric(oe))
     729          16 :                 set_symmetric(ne);
     730     9236364 :         if (is_ascending(oe))
     731       19589 :                 set_ascending(ne);
     732     9236364 :         if (nulls_last(oe))
     733        4049 :                 set_nulls_last(ne);
     734     9236364 :         if (need_distinct(oe))
     735         690 :                 set_distinct(ne);
     736     9236364 :         if (zero_if_empty(oe))
     737           0 :                 set_zero_if_empty(ne);
     738     9236364 :         if (need_no_nil(oe))
     739       80239 :                 set_no_nil(ne);
     740     9236364 :         if (!has_nil(oe))
     741     1238671 :                 set_has_no_nil(ne);
     742     9236364 :         if (is_unique(oe))
     743      259924 :                 set_unique(ne);
     744     9236364 :         if (is_basecol(oe))
     745     7511111 :                 set_basecol(ne);
     746     9236364 :         ne->p = prop_copy(sa, oe->p);
     747     9236363 :         return ne;
     748             : }
     749             : 
     750             : sql_exp *
     751      630292 : exp_ref(mvc *sql, sql_exp *e)
     752             : {
     753      630292 :         if (!exp_name(e))
     754        6196 :                 exp_label(sql->sa, e, ++sql->label);
     755      630292 :         return exp_propagate(sql->sa, exp_column(sql->sa, exp_relname(e), exp_name(e), exp_subtype(e), exp_card(e), has_nil(e), is_unique(e), is_intern(e)), e);
     756             : }
     757             : 
     758             : sql_exp *
     759       13438 : exp_ref_save(mvc *sql, sql_exp *e)
     760             : {
     761       13438 :         if (is_atom(e->type))
     762        5028 :                 return exp_copy(sql, e);
     763        8410 :         if (!exp_name(e) || is_convert(e->type))
     764          72 :                 exp_label(sql->sa, e, ++sql->label);
     765        8410 :         if (e->type != e_column)
     766        4915 :                 e->ref = 1;
     767        8410 :         sql_exp *ne = exp_ref(sql, e);
     768        8410 :         if (ne && is_freevar(e))
     769          34 :                 set_freevar(ne, is_freevar(e)-1);
     770             :         return ne;
     771             : }
     772             : 
     773             : sql_exp *
     774     3330252 : exp_alias(sql_allocator *sa, const char *arname, const char *acname, const char *org_rname, const char *org_cname, sql_subtype *t, unsigned int card, int has_nils, int unique, int intern)
     775             : {
     776     3330252 :         sql_exp *e = exp_column(sa, org_rname, org_cname, t, card, has_nils, unique, intern);
     777             : 
     778     3330219 :         if (e == NULL)
     779             :                 return NULL;
     780     3330219 :         assert(acname && org_cname);
     781     3330219 :         exp_setname(sa, e, (arname)?arname:org_rname, acname);
     782     3330219 :         return e;
     783             : }
     784             : 
     785             : sql_exp *
     786     6182024 : exp_alias_or_copy( mvc *sql, const char *tname, const char *cname, sql_rel *orel, sql_exp *old)
     787             : {
     788     6182024 :         sql_exp *ne = NULL;
     789             : 
     790     6182024 :         if (!tname)
     791     5465749 :                 tname = exp_relname(old);
     792             : 
     793     6182025 :         if (!cname && exp_name(old) && has_label(old)) {
     794           0 :                 ne = exp_column(sql->sa, exp_relname(old), exp_name(old), exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, has_nil(old), is_unique(old), is_intern(old));
     795           0 :                 return exp_propagate(sql->sa, ne, old);
     796     6182025 :         } else if (!cname) {
     797       21317 :                 exp_label(sql->sa, old, ++sql->label);
     798       21317 :                 ne = exp_column(sql->sa, exp_relname(old), exp_name(old), exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, has_nil(old), is_unique(old), is_intern(old));
     799       21317 :                 return exp_propagate(sql->sa, ne, old);
     800     6160708 :         } else if (cname && !old->alias.name) {
     801        1829 :                 exp_setname(sql->sa, old, tname, cname);
     802             :         }
     803     6160708 :         ne = exp_column(sql->sa, tname, cname, exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, has_nil(old), is_unique(old), is_intern(old));
     804     6160710 :         return exp_propagate(sql->sa, ne, old);
     805             : }
     806             : 
     807             : sql_exp *
     808           0 : exp_alias_ref(mvc *sql, sql_exp *e)
     809             : {
     810           0 :         sql_exp *ne = NULL;
     811           0 :         const char *tname = exp_relname(e);
     812           0 :         const char *cname = exp_name(e);
     813             : 
     814           0 :         if (!has_label(e))
     815           0 :                 exp_label(sql->sa, e, ++sql->label);
     816           0 :         ne = exp_ref(sql, e);
     817           0 :         exp_setname(sql->sa, ne, tname, cname);
     818           0 :         return exp_propagate(sql->sa, ne, e);
     819             : }
     820             : 
     821             : sql_exp *
     822       15966 : exp_set(sql_allocator *sa, const char *sname, const char *name, sql_exp *val, int level)
     823             : {
     824       15966 :         sql_exp *e = exp_create(sa, e_psm);
     825             : 
     826       15966 :         if (e == NULL)
     827             :                 return NULL;
     828       15966 :         e->alias.rname = sname;
     829       15966 :         e->alias.name = name;
     830       15966 :         e->l = val;
     831       15966 :         e->flag = PSM_SET + SET_PSM_LEVEL(level);
     832       15966 :         return e;
     833             : }
     834             : 
     835             : sql_exp *
     836        9410 : exp_var(sql_allocator *sa, const char *sname, const char *name, sql_subtype *type, int level)
     837             : {
     838        9410 :         sql_exp *e = exp_create(sa, e_psm);
     839             : 
     840        9410 :         if (e == NULL)
     841             :                 return NULL;
     842        9410 :         e->alias.rname = sname;
     843        9410 :         e->alias.name = name;
     844        9410 :         e->tpe = *type;
     845        9410 :         e->flag = PSM_VAR + SET_PSM_LEVEL(level);
     846        9410 :         return e;
     847             : }
     848             : 
     849             : sql_exp *
     850         105 : exp_table(sql_allocator *sa, const char *name, sql_table *t, int level)
     851             : {
     852         105 :         sql_exp *e = exp_create(sa, e_psm);
     853             : 
     854         105 :         if (e == NULL)
     855             :                 return NULL;
     856         105 :         e->alias.rname = NULL;
     857         105 :         e->alias.name = name;
     858         105 :         e->f = t;
     859         105 :         e->flag = PSM_VAR + SET_PSM_LEVEL(level);
     860         105 :         return e;
     861             : }
     862             : 
     863             : sql_exp *
     864       22853 : exp_return(sql_allocator *sa, sql_exp *val, int level)
     865             : {
     866       22853 :         sql_exp *e = exp_create(sa, e_psm);
     867             : 
     868       22853 :         if (e == NULL)
     869             :                 return NULL;
     870       22853 :         e->l = val;
     871       22853 :         e->flag = PSM_RETURN + SET_PSM_LEVEL(level);
     872       22853 :         return e;
     873             : }
     874             : 
     875             : sql_exp *
     876        1005 : exp_while(sql_allocator *sa, sql_exp *cond, list *stmts)
     877             : {
     878        1005 :         sql_exp *e = exp_create(sa, e_psm);
     879             : 
     880        1005 :         if (e == NULL)
     881             :                 return NULL;
     882        1005 :         e->l = cond;
     883        1005 :         e->r = stmts;
     884        1005 :         e->flag = PSM_WHILE;
     885        1005 :         return e;
     886             : }
     887             : 
     888             : sql_exp *
     889       11501 : exp_if(sql_allocator *sa, sql_exp *cond, list *if_stmts, list *else_stmts)
     890             : {
     891       11501 :         sql_exp *e = exp_create(sa, e_psm);
     892             : 
     893       11501 :         if (e == NULL)
     894             :                 return NULL;
     895       11501 :         e->l = cond;
     896       11501 :         e->r = if_stmts;
     897       11501 :         e->f = else_stmts;
     898       11501 :         e->flag = PSM_IF;
     899       11501 :         return e;
     900             : }
     901             : 
     902             : sql_exp *
     903       76377 : exp_rel(mvc *sql, sql_rel *rel)
     904             : {
     905       76377 :         sql_exp *e = exp_create(sql->sa, e_psm);
     906             : 
     907       76377 :         if (e == NULL)
     908             :                 return NULL;
     909       76377 :         e->l = rel;
     910       76377 :         e->flag = PSM_REL;
     911       76377 :         e->card = is_single(rel)?CARD_ATOM:rel->card;
     912       76377 :         assert(rel);
     913       76377 :         if (is_topn(rel->op))
     914           3 :                 rel = rel->l;
     915       76377 :         if (is_project(rel->op)) {
     916       58373 :                 sql_exp *last = rel->exps->t->data;
     917       58373 :                 sql_subtype *t = exp_subtype(last);
     918       58373 :                 e->tpe = t ? *t : (sql_subtype) {0};
     919             :         }
     920             :         return e;
     921             : }
     922             : 
     923             : sql_exp *
     924         149 : exp_exception(sql_allocator *sa, sql_exp *cond, const char *error_message)
     925             : {
     926         149 :         sql_exp *e = exp_create(sa, e_psm);
     927             : 
     928         149 :         if (e == NULL)
     929             :                 return NULL;
     930         149 :         e->l = cond;
     931         149 :         e->r = sa_strdup(sa, error_message);
     932         149 :         e->flag = PSM_EXCEPTION;
     933         149 :         return e;
     934             : }
     935             : 
     936             : /* Set a name (alias) for the expression, such that we can refer
     937             :    to this expression by this simple name.
     938             :  */
     939             : void
     940     4437931 : exp_setname(sql_allocator *sa, sql_exp *e, const char *rname, const char *name )
     941             : {
     942     4437931 :         e->alias.label = 0;
     943     4437931 :         if (name)
     944     4278546 :                 e->alias.name = sa_strdup(sa, name);
     945     4437923 :         e->alias.rname = (rname)?sa_strdup(sa, rname):NULL;
     946     4437902 : }
     947             : 
     948             : void
     949      156223 : noninternexp_setname(sql_allocator *sa, sql_exp *e, const char *rname, const char *name )
     950             : {
     951      156223 :         if (!is_intern(e))
     952      156221 :                 exp_setname(sa, e, rname, name);
     953      156223 : }
     954             : 
     955             : void
     956      568423 : exp_setalias(sql_exp *e, const char *rname, const char *name )
     957             : {
     958      568423 :         e->alias.label = 0;
     959      568423 :         e->alias.name = name;
     960      568423 :         e->alias.rname = rname;
     961      568423 : }
     962             : 
     963             : void
     964     1774154 : exp_prop_alias(sql_allocator *sa, sql_exp *e, sql_exp *oe )
     965             : {
     966     1774154 :         e->ref = oe->ref;
     967     1774154 :         if (oe->alias.name == NULL && exp_has_rel(oe)) {
     968        7667 :                 sql_rel *r = exp_rel_get_rel(sa, oe);
     969        7667 :                 if (!is_project(r->op))
     970             :                         return ;
     971        7667 :                 oe = r->exps->t->data;
     972             :         }
     973     1774154 :         e->alias = oe->alias;
     974             : }
     975             : 
     976             : str
     977     4067211 : number2name(str s, int len, int i)
     978             : {
     979     4067211 :         s[--len] = 0;
     980    12361013 :         while(i>0) {
     981     8293802 :                 s[--len] = '0' + (i & 7);
     982     8293802 :                 i >>= 3;
     983             :         }
     984     4067211 :         s[--len] = '%';
     985     4067211 :         return s + len;
     986             : }
     987             : 
     988             : void
     989     2030600 : exp_setrelname(sql_allocator *sa, sql_exp *e, int nr)
     990             : {
     991     2030600 :         char name[16], *nme;
     992             : 
     993     2030600 :         nme = number2name(name, sizeof(name), nr);
     994     2030600 :         e->alias.label = 0;
     995     2030600 :         e->alias.rname = sa_strdup(sa, nme);
     996     2030600 : }
     997             : 
     998             : char *
     999     1979599 : make_label(sql_allocator *sa, int nr)
    1000             : {
    1001     1979599 :         char name[16], *nme;
    1002             : 
    1003     1979599 :         nme = number2name(name, sizeof(name), nr);
    1004     1979605 :         return sa_strdup(sa, nme);
    1005             : }
    1006             : 
    1007             : sql_exp*
    1008     1970358 : exp_label(sql_allocator *sa, sql_exp *e, int nr)
    1009             : {
    1010     1970358 :         assert(nr > 0);
    1011     1970358 :         e->alias.label = nr;
    1012     1970358 :         e->alias.rname = e->alias.name = make_label(sa, nr);
    1013     1970420 :         return e;
    1014             : }
    1015             : 
    1016             : list*
    1017        4257 : exps_label(sql_allocator *sa, list *exps, int nr)
    1018             : {
    1019        4257 :         if (!exps)
    1020             :                 return NULL;
    1021       11573 :         for (node *n = exps->h; n; n = n->next)
    1022        7316 :                 n->data = exp_label(sa, n->data, nr++);
    1023        4257 :         list_hash_clear(exps);
    1024        4257 :         return exps;
    1025             : }
    1026             : 
    1027             : void
    1028       20774 : exp_swap( sql_exp *e )
    1029             : {
    1030       20774 :         sql_exp *s = e->l;
    1031             : 
    1032       20774 :         e->l = e->r;
    1033       20774 :         e->r = s;
    1034       20774 :         e->flag = swap_compare((comp_type)e->flag);
    1035       20774 :         assert(!e->f);
    1036       20774 : }
    1037             : 
    1038             : sql_subtype *
    1039    25864884 : exp_subtype( sql_exp *e )
    1040             : {
    1041    25864924 :         switch(e->type) {
    1042     7031586 :         case e_atom: {
    1043     7031586 :                 if (e->l) {
    1044     6473945 :                         atom *a = e->l;
    1045     6473945 :                         return atom_type(a);
    1046      557641 :                 } else if (e->tpe.type) { /* atom reference */
    1047      555859 :                         return &e->tpe;
    1048        1782 :                 } else if (e->f) {
    1049          40 :                         list *vals = exp_get_values(e);
    1050          40 :                         if (!list_empty(vals))
    1051          40 :                                 return exp_subtype(vals->h->data);
    1052             :                 }
    1053             :                 break;
    1054             :         }
    1055    15962115 :         case e_convert:
    1056             :         case e_column:
    1057    15962115 :                 if (e->tpe.type)
    1058    15962006 :                         return &e->tpe;
    1059             :                 break;
    1060     2797360 :         case e_aggr:
    1061             :         case e_func: {
    1062     2797360 :                 if (e->f) {
    1063     2797360 :                         sql_subfunc *f = e->f;
    1064     2797360 :                         if (f->res && list_length(f->res) == 1)
    1065     2786953 :                                 return f->res->h->data;
    1066             :                 }
    1067             :                 return NULL;
    1068             :         }
    1069         356 :         case e_cmp:
    1070         356 :                 return sql_bind_localtype("bit");
    1071       73507 :         case e_psm:
    1072       73507 :                 if (e->tpe.type)
    1073       73492 :                         return &e->tpe;
    1074             :                 /* fall through */
    1075             :         default:
    1076             :                 return NULL;
    1077             :         }
    1078             :         return NULL;
    1079             : }
    1080             : 
    1081             : const char *
    1082    40306037 : exp_name( sql_exp *e )
    1083             : {
    1084    40322189 :         if (e->alias.name)
    1085             :                 return e->alias.name;
    1086     1589711 :         if (e->type == e_convert && e->l)
    1087             :                 return exp_name(e->l);
    1088     1584615 :         if (e->type == e_psm && e->l) { /* subquery return name of last expression */
    1089       11056 :                 sql_rel *r = e->l;
    1090       11056 :                 if (is_project(r->op))
    1091       11056 :                         return exp_name(r->exps->t->data);
    1092             :         }
    1093             :         return NULL;
    1094             : }
    1095             : 
    1096             : const char *
    1097    16945174 : exp_relname( sql_exp *e )
    1098             : {
    1099    16947312 :         if (e->alias.rname)
    1100             :                 return e->alias.rname;
    1101      617234 :         if (!e->alias.name && e->type == e_convert && e->l)
    1102             :                 return exp_relname(e->l);
    1103      616266 :         if (!e->alias.name && e->type == e_psm && e->l) { /* subquery return name of last expression */
    1104        1170 :                 sql_rel *r = e->l;
    1105        1170 :                 if (is_project(r->op))
    1106        1170 :                         return exp_relname(r->exps->t->data);
    1107             :         }
    1108             :         return NULL;
    1109             : }
    1110             : 
    1111             : const char *
    1112       16944 : exp_find_rel_name(sql_exp *e)
    1113             : {
    1114       16944 :         if (e->alias.rname)
    1115             :                 return e->alias.rname;
    1116         470 :         switch(e->type) {
    1117             :         case e_column:
    1118             :                 break;
    1119           0 :         case e_convert:
    1120           0 :                 return exp_find_rel_name(e->l);
    1121             :         default:
    1122             :                 return NULL;
    1123             :         }
    1124             :         return NULL;
    1125             : }
    1126             : 
    1127             : unsigned int
    1128     2668471 : exp_card( sql_exp *e )
    1129             : {
    1130     2668471 :         return e->card;
    1131             : }
    1132             : 
    1133             : const char *
    1134           0 : exp_func_name( sql_exp *e )
    1135             : {
    1136           0 :         if (e->type == e_func && e->f) {
    1137           0 :                 sql_subfunc *f = e->f;
    1138           0 :                 return f->func->base.name;
    1139             :         }
    1140           0 :         if (e->alias.name)
    1141             :                 return e->alias.name;
    1142           0 :         if (e->type == e_convert && e->l)
    1143           0 :                 return exp_name(e->l);
    1144             :         return NULL;
    1145             : }
    1146             : 
    1147             : int
    1148    54852602 : exp_cmp( sql_exp *e1, sql_exp *e2)
    1149             : {
    1150    54852602 :         return (e1 == e2)?0:-1;
    1151             : }
    1152             : 
    1153             : int
    1154      228598 : exp_equal( sql_exp *e1, sql_exp *e2)
    1155             : {
    1156      228598 :         if (e1 == e2)
    1157             :                 return 0;
    1158      228598 :         if (e1->alias.rname && e2->alias.rname && strcmp(e1->alias.rname, e2->alias.rname) == 0)
    1159      171536 :                 return strcmp(e1->alias.name, e2->alias.name);
    1160       57062 :         if (!e1->alias.rname && !e2->alias.rname && e1->alias.label == e2->alias.label && e1->alias.name && e2->alias.name)
    1161         585 :                 return strcmp(e1->alias.name, e2->alias.name);
    1162             :         return -1;
    1163             : }
    1164             : 
    1165             : int
    1166    54852504 : exp_match( sql_exp *e1, sql_exp *e2)
    1167             : {
    1168    54852504 :         if (exp_cmp(e1, e2) == 0)
    1169             :                 return 1;
    1170    54812739 :         if (e1->type == e2->type && e1->type == e_column) {
    1171    26127294 :                 if (e1->l != e2->l && (!e1->l || !e2->l || strcmp(e1->l, e2->l) != 0))
    1172             :                         return 0;
    1173    14934190 :                 if (!e1->r || !e2->r || strcmp(e1->r, e2->r) != 0)
    1174             :                         return 0;
    1175             :                 return 1;
    1176             :         }
    1177    28685445 :         if (e1->type == e2->type && e1->type == e_func) {
    1178     8784737 :                 if (is_identity(e1, NULL) && is_identity(e2, NULL)) {
    1179           0 :                         list *args1 = e1->l;
    1180           0 :                         list *args2 = e2->l;
    1181             : 
    1182           0 :                         if (list_length(args1) == list_length(args2) && list_length(args1) == 1) {
    1183           0 :                                 sql_exp *ne1 = args1->h->data;
    1184           0 :                                 sql_exp *ne2 = args2->h->data;
    1185             : 
    1186           0 :                                 if (exp_match(ne1,ne2))
    1187             :                                         return 1;
    1188             :                         }
    1189             :                 }
    1190             :         }
    1191             :         return 0;
    1192             : }
    1193             : 
    1194             : /* list already contains matching expression */
    1195             : sql_exp*
    1196      433796 : exps_find_exp( list *l, sql_exp *e)
    1197             : {
    1198      433796 :         node *n;
    1199             : 
    1200      433796 :         if (!l || !l->h)
    1201             :                 return NULL;
    1202             : 
    1203     1055484 :         for(n=l->h; n; n = n->next) {
    1204      984814 :                 if (exp_match(n->data, e) || exp_refers(n->data, e))
    1205      350186 :                         return n->data;
    1206             :         }
    1207             :         return NULL;
    1208             : }
    1209             : 
    1210             : 
    1211             : /* c refers to the parent p */
    1212             : int
    1213     4641984 : exp_refers( sql_exp *p, sql_exp *c)
    1214             : {
    1215     4641984 :         if (c->type == e_column) {
    1216             :                 // at first they need to have the same expression names
    1217      891462 :                 if (!p->alias.name || !c->r || strcmp(p->alias.name, c->r) != 0)
    1218             :                         return 0;
    1219       80957 :                 if (!c->l)
    1220             :                         return 1;
    1221             :                 // then compare the relation names
    1222       68968 :                 if (c->l && (p->alias.rname || p->l)) {
    1223             :                         // if the parent has an alias for the relation name compare with the child's relation name
    1224       68967 :                         if (p->alias.rname && strcmp(p->alias.rname, c->l) != 0)
    1225             :                                 return 0;
    1226             :                         // if the parent does NOT have a relation name alias compare his relation name with the child's
    1227       46264 :                         if (!p->alias.rname && p->l && (strcmp(p->l, c->l) != 0 || strcmp(p->alias.name, p->r) !=0))
    1228             :                                 return 0;
    1229       46229 :                         return 1;
    1230             :                 }
    1231             :         }
    1232             :         return 0;
    1233             : }
    1234             : 
    1235             : int
    1236           0 : exp_match_col_exps( sql_exp *e, list *l)
    1237             : {
    1238           0 :         node *n;
    1239             : 
    1240           0 :         for(n=l->h; n; n = n->next) {
    1241           0 :                 sql_exp *re = n->data;
    1242           0 :                 sql_exp *re_r = re->r;
    1243             : 
    1244           0 :                 if (re->type == e_cmp && re->flag == cmp_or)
    1245           0 :                         return exp_match_col_exps(e, re->l) &&
    1246           0 :                                exp_match_col_exps(e, re->r);
    1247             : 
    1248           0 :                 if (re->type != e_cmp || !re_r || re_r->card != 1 || !exp_match_exp(e, re->l))
    1249           0 :                         return 0;
    1250             :         }
    1251             :         return 1;
    1252             : }
    1253             : 
    1254             : int
    1255       11381 : exps_match_col_exps( sql_exp *e1, sql_exp *e2)
    1256             : {
    1257       11381 :         sql_exp *e1_r = e1->r;
    1258       11381 :         sql_exp *e2_r = e2->r;
    1259             : 
    1260       11381 :         if (e1->type != e_cmp || e2->type != e_cmp)
    1261             :                 return 0;
    1262             : 
    1263       11381 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1264        6097 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1265        5169 :                 return exp_match_exp(e1->l, e2->l);
    1266             : 
    1267        6212 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1268         928 :             (e2->flag == cmp_in || e2->flag == cmp_notin))
    1269         845 :                 return exp_match_exp(e1->l, e2->l);
    1270        5367 :         if ((e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1271        2861 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1272        2333 :                 return exp_match_exp(e1->l, e2->l);
    1273             : 
    1274        3034 :         if ((e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1275         528 :             (e2->flag == cmp_in || e2->flag == cmp_notin))
    1276         528 :                 return exp_match_exp(e1->l, e2->l);
    1277             : 
    1278        2506 :         if (!is_complex_exp(e1->flag) && e1_r && e1_r->card == CARD_ATOM &&
    1279          83 :             e2->flag == cmp_or)
    1280           0 :                 return exp_match_col_exps(e1->l, e2->l) &&
    1281           0 :                        exp_match_col_exps(e1->l, e2->r);
    1282             : 
    1283        2506 :         if (e1->flag == cmp_or &&
    1284           0 :             !is_complex_exp(e2->flag) && e2_r && e2_r->card == CARD_ATOM)
    1285           0 :                 return exp_match_col_exps(e2->l, e1->l) &&
    1286           0 :                        exp_match_col_exps(e2->l, e1->r);
    1287             : 
    1288        2506 :         if (e1->flag == cmp_or && e2->flag == cmp_or) {
    1289           0 :                 list *l = e1->l, *r = e1->r;
    1290           0 :                 sql_exp *el = l->h->data;
    1291           0 :                 sql_exp *er = r->h->data;
    1292             : 
    1293           0 :                 return list_length(l) == 1 && list_length(r) == 1 &&
    1294           0 :                        exps_match_col_exps(el, e2) &&
    1295           0 :                        exps_match_col_exps(er, e2);
    1296             :         }
    1297             :         return 0;
    1298             : }
    1299             : 
    1300             : int
    1301       30446 : exp_match_list( list *l, list *r)
    1302             : {
    1303       30446 :         node *n, *m;
    1304       30446 :         char *lu, *ru;
    1305       30446 :         int lc = 0, rc = 0, match = 0;
    1306             : 
    1307       30446 :         if (!l || !r)
    1308          11 :                 return l == r;
    1309       30435 :         if (list_length(l) != list_length(r) || list_length(l) == 0 || list_length(r) == 0)
    1310         580 :                 return 0;
    1311       29855 :         if (list_length(l) > 10 || list_length(r) > 10)
    1312           5 :                 return 0;/* to expensive */
    1313             : 
    1314       29850 :         lu = ZNEW_ARRAY(char, list_length(l));
    1315       29850 :         ru = ZNEW_ARRAY(char, list_length(r));
    1316       29850 :         if (!lu || !ru) {
    1317           0 :                 _DELETE(lu);
    1318           0 :                 _DELETE(ru);
    1319           0 :                 return 0;
    1320             :         }
    1321       86397 :         for (n = l->h, lc = 0; n; n = n->next, lc++) {
    1322       56547 :                 sql_exp *le = n->data;
    1323             : 
    1324      167454 :                 for ( m = r->h, rc = 0; m; m = m->next, rc++) {
    1325      110907 :                         sql_exp *re = m->data;
    1326             : 
    1327      110907 :                         if (!ru[rc] && exp_match_exp(le,re)) {
    1328        7516 :                                 lu[lc] = 1;
    1329        7516 :                                 ru[rc] = 1;
    1330        7516 :                                 match = 1;
    1331             :                         }
    1332             :                 }
    1333             :         }
    1334       38270 :         for (n = l->h, lc = 0; n && match; n = n->next, lc++)
    1335        8420 :                 if (!lu[lc])
    1336        2211 :                         match = 0;
    1337       35124 :         for (n = r->h, rc = 0; n && match; n = n->next, rc++)
    1338        5274 :                 if (!ru[rc])
    1339           0 :                         match = 0;
    1340       29850 :         _DELETE(lu);
    1341       29850 :         _DELETE(ru);
    1342       29850 :         return match;
    1343             : }
    1344             : 
    1345             : static int
    1346     2435238 : exps_equal( list *l, list *r)
    1347             : {
    1348     2435238 :         node *n, *m;
    1349             : 
    1350     2435238 :         if (!l || !r)
    1351       51056 :                 return l == r;
    1352     2384182 :         if (list_length(l) != list_length(r))
    1353             :                 return 0;
    1354     3501791 :         for (n = l->h, m = r->h; n && m; n = n->next, m = m->next) {
    1355     3454274 :                 sql_exp *le = n->data, *re = m->data;
    1356             : 
    1357     3454274 :                 if (!exp_match_exp(le,re))
    1358             :                         return 0;
    1359             :         }
    1360             :         return 1;
    1361             : }
    1362             : 
    1363             : int
    1364    50552793 : exp_match_exp_semantics( sql_exp *e1, sql_exp *e2, bool semantics)
    1365             : {
    1366    50552793 :         if (exp_match(e1, e2))
    1367             :                 return 1;
    1368    49303748 :         if (is_ascending(e1) != is_ascending(e2) || nulls_last(e1) != nulls_last(e2) || zero_if_empty(e1) != zero_if_empty(e2) ||
    1369    49303744 :                 need_no_nil(e1) != need_no_nil(e2) || is_anti(e1) != is_anti(e2) || (semantics && is_semantics(e1) != is_semantics(e2)) ||
    1370    36345903 :                 (semantics && is_any(e1) != is_any(e2)) ||
    1371    36675975 :                 is_symmetric(e1) != is_symmetric(e2) || is_unique(e1) != is_unique(e2) || need_distinct(e1) != need_distinct(e2))
    1372             :                 return 0;
    1373    36547710 :         if (e1->type == e2->type) {
    1374    25996126 :                 switch(e1->type) {
    1375      387712 :                 case e_cmp:
    1376      641943 :                         if (e1->flag == e2->flag && !is_complex_exp(e1->flag) &&
    1377      258700 :                             exp_match_exp(e1->l, e2->l) && exp_match_exp(e1->r, e2->r) &&
    1378         971 :                             ((!e1->f && !e2->f) || (e1->f && e2->f && exp_match_exp(e1->f, e2->f))))
    1379         964 :                                 return 1;
    1380      390278 :                         else if (e1->flag == e2->flag && e1->flag == cmp_or &&
    1381        3540 :                             exp_match_list(e1->l, e2->l) && exp_match_list(e1->r, e2->r))
    1382             :                                 return 1;
    1383      386745 :                         else if (e1->flag == e2->flag &&
    1384      261955 :                                 (e1->flag == cmp_in || e1->flag == cmp_notin) &&
    1385        3017 :                             exp_match_exp(e1->l, e2->l) && exp_match_list(e1->r, e2->r))
    1386             :                                 return 1;
    1387      636921 :                         else if (e1->flag == e2->flag && (e1->flag == cmp_equal || e1->flag == cmp_notequal) &&
    1388      250223 :                                 exp_match_exp(e1->l, e2->r) && exp_match_exp(e1->r, e2->l))
    1389             :                                 return 1; /* = and <> operations are reflective, so exp_match_exp can be called crossed */
    1390             :                         break;
    1391     1070735 :                 case e_convert:
    1392     1270246 :                         if (!subtype_cmp(exp_totype(e1), exp_totype(e2)) &&
    1393      346948 :                             !subtype_cmp(exp_fromtype(e1), exp_fromtype(e2)) &&
    1394      147437 :                             exp_match_exp(e1->l, e2->l))
    1395             :                                 return 1;
    1396             :                         break;
    1397       56520 :                 case e_aggr:
    1398       93966 :                         if (!subfunc_cmp(e1->f, e2->f) && /* equal aggregation*/
    1399       37446 :                             exps_equal(e1->l, e2->l))
    1400             :                                 return 1;
    1401             :                         break;
    1402     4417604 :                 case e_func: {
    1403     4417604 :                         sql_subfunc *e1f = (sql_subfunc*) e1->f;
    1404     4417604 :                         const char *sname = e1f->func->s ? e1f->func->s->base.name : NULL;
    1405     4417604 :                         int (*comp)(list*, list*) = is_commutative(sname, e1f->func->base.name) ? exp_match_list : exps_equal;
    1406             : 
    1407     8835208 :                         if (!e1f->func->side_effect &&
    1408     6786846 :                                 !subfunc_cmp(e1f, e2->f) && /* equal functions */
    1409     2419062 :                                 comp(e1->l, e2->l) &&
    1410             :                                 /* optional order by expressions */
    1411       49820 :                                 exps_equal(e1->r, e2->r))
    1412             :                                         return 1;
    1413             :                         } break;
    1414     1072374 :                 case e_atom:
    1415     1072374 :                         if (e1->l && e2->l && !atom_cmp(e1->l, e2->l))
    1416             :                                 return 1;
    1417     1040562 :                         if (e1->f && e2->f && exps_equal(e1->f, e2->f))
    1418             :                                 return 1;
    1419     1040529 :                         if (e1->r && e2->r && e1->flag == e2->flag && !subtype_cmp(&e1->tpe, &e2->tpe)) {
    1420           0 :                                 sql_var_name *v1 = (sql_var_name*) e1->r, *v2 = (sql_var_name*) e2->r;
    1421           0 :                                 if (((!v1->sname && !v2->sname) || (v1->sname && v2->sname && strcmp(v1->sname, v2->sname) == 0)) &&
    1422           0 :                                         ((!v1->name && !v2->name) || (v1->name && v2->name && strcmp(v1->name, v2->name) == 0)))
    1423             :                                         return 1;
    1424             :                         }
    1425     1040529 :                         if (!e1->l && !e1->r && !e1->f && !e2->l && !e2->r && !e2->f && e1->flag == e2->flag && !subtype_cmp(&e1->tpe, &e2->tpe))
    1426             :                                 return 1;
    1427             :                         break;
    1428             :                 default:
    1429             :                         break;
    1430             :                 }
    1431             :         }
    1432             :         return 0;
    1433             : }
    1434             : 
    1435             : int
    1436    50219335 : exp_match_exp( sql_exp *e1, sql_exp *e2)
    1437             : {
    1438    50219335 :         return exp_match_exp_semantics( e1, e2, true);
    1439             : }
    1440             : 
    1441             : sql_exp *
    1442      141269 : exps_any_match(list *l, sql_exp *e)
    1443             : {
    1444      141269 :         if (!l)
    1445             :                 return NULL;
    1446      552459 :         for (node *n = l->h; n ; n = n->next) {
    1447      500355 :                 sql_exp *ne = (sql_exp *) n->data;
    1448      500355 :                 if (exp_match_exp(ne, e))
    1449       89165 :                         return ne;
    1450             :         }
    1451             :         return NULL;
    1452             : }
    1453             : 
    1454             : static int
    1455          26 : exps_are_joins( list *l )
    1456             : {
    1457          26 :         if (l)
    1458          57 :                 for (node *n = l->h; n; n = n->next) {
    1459          31 :                         sql_exp *e = n->data;
    1460             : 
    1461          31 :                         if (exp_is_join_exp(e))
    1462             :                                 return -1;
    1463             :                 }
    1464             :         return 0;
    1465             : }
    1466             : 
    1467             : int
    1468         246 : exp_is_join_exp(sql_exp *e)
    1469             : {
    1470         246 :         if (exp_is_join(e, NULL) == 0)
    1471             :                 return 0;
    1472          30 :         if (e->type == e_cmp && e->flag == cmp_or && e->card >= CARD_AGGR)
    1473          13 :                 if (exps_are_joins(e->l) == 0 && exps_are_joins(e->r) == 0)
    1474             :                         return 0;
    1475             :         return -1;
    1476             : }
    1477             : 
    1478             : static int
    1479      814006 : exp_is_complex_select( sql_exp *e )
    1480             : {
    1481      832742 :         switch (e->type) {
    1482         518 :         case e_atom: {
    1483         518 :                 if (e->f) {
    1484           0 :                         int r = (e->card == CARD_ATOM);
    1485           0 :                         list *l = e->f;
    1486             : 
    1487           0 :                         if (r)
    1488           0 :                                 for (node *n = l->h; n && !r; n = n->next)
    1489           0 :                                         r |= exp_is_complex_select(n->data);
    1490           0 :                         return r;
    1491             :                 }
    1492             :                 return 0;
    1493             :         }
    1494       18736 :         case e_convert:
    1495       18736 :                 return exp_is_complex_select(e->l);
    1496        2050 :         case e_func:
    1497             :         case e_aggr:
    1498             :         {
    1499        2050 :                 int r = (e->card == CARD_ATOM);
    1500        2050 :                 list *l = e->l;
    1501             : 
    1502        2050 :                 if (r && l)
    1503          22 :                         for (node *n = l->h; n && !r; n = n->next)
    1504           0 :                                 r |= exp_is_complex_select(n->data);
    1505             :                 return r;
    1506             :         }
    1507             :         case e_psm:
    1508             :                 return 1;
    1509             :         case e_column:
    1510             :         case e_cmp:
    1511             :         default:
    1512             :                 return 0;
    1513             :         }
    1514             : }
    1515             : 
    1516             : static int
    1517      407008 : complex_select(sql_exp *e)
    1518             : {
    1519      407008 :         sql_exp *l = e->l, *r = e->r;
    1520             : 
    1521      407008 :         if (exp_is_complex_select(l) || exp_is_complex_select(r))
    1522          22 :                 return 1;
    1523             :         return 0;
    1524             : }
    1525             : 
    1526             : static int
    1527         955 : distinct_rel(sql_exp *e, const char **rname)
    1528             : {
    1529        1164 :         const char *e_rname = NULL;
    1530             : 
    1531        1164 :         switch(e->type) {
    1532         675 :         case e_column:
    1533         675 :                 e_rname = exp_relname(e);
    1534             : 
    1535         675 :                 if (*rname && e_rname && strcmp(*rname, e_rname) == 0)
    1536             :                         return 1;
    1537         551 :                 if (!*rname) {
    1538         333 :                         *rname = e_rname;
    1539         333 :                         return 1;
    1540             :                 }
    1541             :                 break;
    1542         147 :         case e_aggr:
    1543             :         case e_func:
    1544         147 :                 if (e->l) {
    1545         147 :                         int m = 1;
    1546         147 :                         list *l = e->l;
    1547         147 :                         node *n;
    1548             : 
    1549         444 :                         for(n=l->h; n && m; n = n->next) {
    1550         297 :                                 sql_exp *ae = n->data;
    1551             : 
    1552         297 :                                 m = distinct_rel(ae, rname);
    1553             :                         }
    1554         147 :                         return m;
    1555             :                 }
    1556             :                 return 0;
    1557             :         case e_atom:
    1558             :                 return 1;
    1559         209 :         case e_convert:
    1560         209 :                 return distinct_rel(e->l, rname);
    1561             :         default:
    1562             :                 return 0;
    1563             :         }
    1564             :         return 0;
    1565             : }
    1566             : 
    1567             : int
    1568    44967989 : rel_has_exp(sql_rel *rel, sql_exp *e, bool subexp)
    1569             : {
    1570    44967989 :         if (rel_find_exp_and_corresponding_rel(rel, e, subexp, NULL, NULL))
    1571     5769272 :                 return 0;
    1572             :         return -1;
    1573             : }
    1574             : 
    1575             : int
    1576           0 : rel_has_exps(sql_rel *rel, list *exps, bool subexp)
    1577             : {
    1578           0 :         if (list_empty(exps))
    1579             :                 return 0;
    1580           0 :         for (node *n = exps->h; n; n = n->next)
    1581           0 :                 if (rel_has_exp(rel, n->data, subexp) >= 0)
    1582             :                         return 0;
    1583             :         return -1;
    1584             : }
    1585             : 
    1586             : int
    1587        4646 : rel_has_all_exps(sql_rel *rel, list *exps)
    1588             : {
    1589        4646 :         if (list_empty(exps))
    1590             :                 return 1;
    1591        9363 :         for (node *n = exps->h; n; n = n->next)
    1592        9291 :                 if (rel_has_exp(rel, n->data, false) < 0)
    1593             :                         return 0;
    1594             :         return 1;
    1595             : }
    1596             : 
    1597             : static int
    1598    33443659 : rel_has_exp2(sql_rel *rel, sql_exp *e)
    1599             : {
    1600    33443659 :         return rel_has_exp(rel, e, false);
    1601             : }
    1602             : 
    1603             : sql_rel *
    1604     7552745 : find_rel(list *rels, sql_exp *e)
    1605             : {
    1606     7552745 :         node *n = list_find(rels, e, (fcmp)&rel_has_exp2);
    1607     7552745 :         if (n)
    1608     4876883 :                 return n->data;
    1609             :         return NULL;
    1610             : }
    1611             : 
    1612             : sql_rel *
    1613      286358 : find_one_rel(list *rels, sql_exp *e)
    1614             : {
    1615      286358 :         node *n;
    1616      286358 :         sql_rel *fnd = NULL;
    1617             : 
    1618     1122783 :         for(n = rels->h; n; n = n->next) {
    1619      836481 :                 if (rel_has_exp(n->data, e, false) == 0) {
    1620      286231 :                         if (fnd)
    1621             :                                 return NULL;
    1622      286175 :                         fnd = n->data;
    1623             :                 }
    1624             :         }
    1625             :         return fnd;
    1626             : }
    1627             : 
    1628             : static int
    1629         338 : exp_is_rangejoin(sql_exp *e, list *rels)
    1630             : {
    1631             :         /* assume e is a e_cmp with 3 args
    1632             :          * Need to check e->r and e->f only touch one table.
    1633             :          */
    1634         338 :         const char *rname = 0;
    1635             : 
    1636         338 :         if (distinct_rel(e->r, &rname) && distinct_rel(e->f, &rname))
    1637             :                 return 0;
    1638         218 :         if (rels) {
    1639         150 :                 sql_rel *r = find_rel(rels, e->r);
    1640         150 :                 sql_rel *f = find_rel(rels, e->f);
    1641         150 :                 if (r && f && r == f)
    1642             :                         return 0;
    1643             :         }
    1644             :         return -1;
    1645             : }
    1646             : 
    1647             : int
    1648      408702 : exp_is_join(sql_exp *e, list *rels)
    1649             : {
    1650             :         /* only simple compare expressions, ie not or lists
    1651             :                 or range expressions (e->f)
    1652             :          */
    1653      408702 :         if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r && !e->f && e->card >= CARD_AGGR && !complex_select(e))
    1654             :                 return 0;
    1655        2054 :         if (e->type == e_cmp && e->flag == cmp_filter && e->l && e->r && e->card >= CARD_AGGR)
    1656             :                 return 0;
    1657             :         /* range expression */
    1658        1903 :         if (e->type == e_cmp && !is_complex_exp(e->flag) && e->l && e->r && e->f && e->card >= CARD_AGGR && !complex_select(e))
    1659         338 :                 return exp_is_rangejoin(e, rels);
    1660             :         return -1;
    1661             : }
    1662             : 
    1663             : int
    1664      402628 : exp_is_eqjoin(sql_exp *e)
    1665             : {
    1666      402628 :         if (e->flag == cmp_equal) {
    1667      393519 :                 sql_exp *l = e->l;
    1668      393519 :                 sql_exp *r = e->r;
    1669             : 
    1670      393519 :                 if (!is_func(l->type) && !is_func(r->type))
    1671      392413 :                         return 0;
    1672             :         }
    1673             :         return -1;
    1674             : }
    1675             : 
    1676             : sql_exp *
    1677      268192 : exps_find_prop(list *exps, rel_prop kind)
    1678             : {
    1679      268192 :         if (list_empty(exps))
    1680             :                 return NULL;
    1681      535047 :         for (node *n = exps->h ; n ; n = n->next) {
    1682      268192 :                 sql_exp *e = n->data;
    1683             : 
    1684      268192 :                 if (find_prop(e->p, kind))
    1685        1337 :                         return e;
    1686             :         }
    1687             :         return NULL;
    1688             : }
    1689             : 
    1690             : static sql_exp *
    1691   148427363 : rel_find_exp_and_corresponding_rel_(sql_rel *rel, sql_exp *e, bool subexp, sql_rel **res)
    1692             : {
    1693   148427363 :         sql_exp *ne = NULL;
    1694             : 
    1695   148427363 :         if (!rel)
    1696             :                 return NULL;
    1697   148427282 :         switch(e->type) {
    1698   146092419 :         case e_column:
    1699   146092419 :                 if (is_basetable(rel->op) && !rel->exps) {
    1700       16253 :                         if (e->l) {
    1701       16251 :                                 if (rel_base_bind_column2_(rel, e->l, e->r))
    1702       14232 :                                         ne = e;
    1703           2 :                         } else if (rel_base_bind_column_(rel, e->r))
    1704       14232 :                                 ne = e;
    1705   189124514 :                 } else if ((!list_empty(rel->exps) && (is_project(rel->op) || is_base(rel->op))) ||
    1706    44611324 :                                         (!list_empty(rel->attr) && is_join(rel->op))) {
    1707   104590748 :                         list *l = rel->attr ? rel->attr : rel->exps;
    1708   104590748 :                         if (e->l) {
    1709   103112427 :                                 ne = exps_bind_column2(l, e->l, e->r, NULL);
    1710             :                         } else {
    1711     1478321 :                                 ne = exps_bind_column(l, e->r, NULL, NULL, 1);
    1712             :                         }
    1713             :                 }
    1714   146092337 :                 if (ne && res)
    1715       70965 :                         *res = rel;
    1716             :                 return ne;
    1717     1201000 :         case e_convert:
    1718     1201000 :                 return rel_find_exp_and_corresponding_rel_(rel, e->l, subexp, res);
    1719      605991 :         case e_aggr:
    1720             :         case e_func:
    1721      605991 :                 if (e->l) {
    1722      602717 :                         list *l = e->l;
    1723      602717 :                         node *n = l->h;
    1724             : 
    1725      602717 :                         ne = n->data;
    1726     1608618 :                         while ((subexp || ne != NULL) && n != NULL) {
    1727     1014303 :                                 ne = rel_find_exp_and_corresponding_rel_(rel, n->data, subexp, res);
    1728     1014303 :                                 if (subexp && ne)
    1729             :                                         break;
    1730     1005901 :                                 n = n->next;
    1731             :                         }
    1732      602717 :                         return ne;
    1733             :                 }
    1734             :                 break;
    1735             :                 /* fall through */
    1736             :         case e_cmp:
    1737             :         case e_psm:
    1738             :                 return NULL;
    1739      527260 :         case e_atom:
    1740      527260 :                 if (e->f) { /* values */
    1741        7504 :                         list *l = e->f;
    1742        7504 :                         node *n = l->h;
    1743             : 
    1744        7504 :                         ne = n->data;
    1745       17232 :                         while ((subexp || ne != NULL) && n != NULL) {
    1746        9728 :                                 ne = rel_find_exp_and_corresponding_rel_(rel, n->data, subexp, res);
    1747        9728 :                                 if (subexp && ne)
    1748             :                                         break;
    1749        9728 :                                 n = n->next;
    1750             :                         }
    1751        7504 :                         return ne;
    1752             :                 }
    1753             :                 return e;
    1754             :         }
    1755             :         return ne;
    1756             : }
    1757             : 
    1758             : sql_exp *
    1759   146202301 : rel_find_exp_and_corresponding_rel(sql_rel *rel, sql_exp *e, bool subexp, sql_rel **res, bool *under_join)
    1760             : {
    1761   146202301 :         sql_exp *ne = rel_find_exp_and_corresponding_rel_(rel, e, subexp, res);
    1762             : 
    1763   146202255 :         if (rel && !ne) {
    1764   121224225 :                 switch(rel->op) {
    1765    32245438 :                 case op_left:
    1766             :                 case op_right:
    1767             :                 case op_full:
    1768             :                 case op_join:
    1769             :                 case op_semi:
    1770             :                 case op_anti:
    1771    32245438 :                         ne = rel_find_exp_and_corresponding_rel(rel->l, e, subexp, res, under_join);
    1772    32245438 :                         if (!ne && is_join(rel->op))
    1773    26718522 :                                 ne = rel_find_exp_and_corresponding_rel(rel->r, e, subexp, res, under_join);
    1774             :                         break;
    1775             :                 case op_table:
    1776             :                 case op_basetable:
    1777             :                         break;
    1778    19106457 :                 default:
    1779    19106457 :                         if (!is_project(rel->op) && rel->l)
    1780    10659350 :                                 ne = rel_find_exp_and_corresponding_rel(rel->l, e, subexp, res, under_join);
    1781             :                 }
    1782             :         }
    1783   146202255 :         if (ne && under_join && is_join(rel->op))
    1784     2900307 :                 *under_join = true;
    1785   146202255 :         return ne;
    1786             : }
    1787             : 
    1788             : sql_exp *
    1789    26465540 : rel_find_exp(sql_rel *rel, sql_exp *e)
    1790             : {
    1791    26465540 :         return rel_find_exp_and_corresponding_rel(rel, e, false, NULL, NULL);
    1792             : }
    1793             : 
    1794             : int
    1795     4237594 : exp_is_true(sql_exp *e)
    1796             : {
    1797     4237594 :         if (e->type == e_atom && e->l)
    1798       13754 :                 return atom_is_true(e->l);
    1799     4223840 :         if (e->type == e_cmp && e->flag == cmp_equal)
    1800     3460095 :                 return (exp_is_true(e->l) && exp_is_true(e->r) && exp_match_exp(e->l, e->r));
    1801             :         return 0;
    1802             : }
    1803             : 
    1804             : static inline bool
    1805      417491 : exp_is_cmp_exp_is_false(sql_exp* e)
    1806             : {
    1807      417491 :         sql_exp *l = e->l;
    1808      417491 :         sql_exp *r = e->r;
    1809      417491 :         assert(e->type == e_cmp && e->f == NULL && l && r);
    1810             : 
    1811             :         /* Handle 'v is x' and 'v is not x' expressions.
    1812             :         * Other cases in is-semantics are unspecified.
    1813             :         */
    1814      417491 :         if (e->flag != cmp_equal && e->flag != cmp_notequal)
    1815             :                 return false;
    1816      417491 :         if (e->flag == cmp_equal && !is_anti(e))
    1817      572458 :                 return ((exp_is_null(l) && exp_is_not_null(r)) || (exp_is_not_null(l) && exp_is_null(r)));
    1818      131262 :         if ((e->flag == cmp_notequal && !is_anti(e)) || (e->flag == cmp_equal && is_anti(e)))
    1819      262472 :                 return exp_is_null(l) && exp_is_null(r);
    1820             :         return false;
    1821             : }
    1822             : 
    1823             : static inline bool
    1824     7066429 : exp_single_bound_cmp_exp_is_false(sql_exp* e) {
    1825     7066429 :     assert(e->type == e_cmp);
    1826     7066429 :     sql_exp* l = e->l;
    1827     7066429 :     sql_exp* r = e->r;
    1828     7066429 :     assert(e->f == NULL);
    1829     7066429 :     assert (l && r);
    1830             : 
    1831     7066429 :     return exp_is_null(l) || exp_is_null(r);
    1832             : }
    1833             : 
    1834             : static inline bool
    1835       89371 : exp_two_sided_bound_cmp_exp_is_false(sql_exp* e) {
    1836       89371 :     assert(e->type == e_cmp);
    1837       89371 :     sql_exp* v = e->l;
    1838       89371 :     sql_exp* l = e->r;
    1839       89371 :     sql_exp* h = e->f;
    1840       89371 :     assert (v && l && h);
    1841             : 
    1842       89371 :     return is_anti(e) ? exp_is_null(v) || (exp_is_null(l) && exp_is_null(h)) : false;
    1843             : }
    1844             : 
    1845             : static inline bool
    1846     7594075 : exp_regular_cmp_exp_is_false(sql_exp* e) {
    1847     7594075 :     assert(e->type == e_cmp);
    1848             : 
    1849     7594075 :     if (is_semantics(e) && !is_any(e)) return exp_is_cmp_exp_is_false(e);
    1850     7176584 :         if (is_any(e)) return false;
    1851     7155800 :     if (e -> f)         return exp_two_sided_bound_cmp_exp_is_false(e);
    1852     7066429 :     else                return exp_single_bound_cmp_exp_is_false(e);
    1853             : }
    1854             : 
    1855             : static inline bool
    1856      609331 : exp_or_exp_is_false(sql_exp* e) {
    1857      609331 :     assert(e->type == e_cmp && e->flag == cmp_or);
    1858             : 
    1859      609331 :         list* left = e->l;
    1860      609331 :         list* right = e->r;
    1861             : 
    1862      609331 :         bool left_is_false = false;
    1863     1273352 :         for(node* n = left->h; n; n=n->next) {
    1864      666044 :                 if (exp_is_false(n->data)) {
    1865             :                         left_is_false=true;
    1866             :                         break;
    1867             :                 }
    1868             :         }
    1869             : 
    1870      609331 :         if (!left_is_false) {
    1871             :                 return false;
    1872             :         }
    1873             : 
    1874        3966 :         for(node* n = right->h; n; n=n->next) {
    1875        2031 :                 if (exp_is_false(n->data)) {
    1876             :                         return true;
    1877             :                 }
    1878             :         }
    1879             : 
    1880             :     return false;
    1881             : }
    1882             : 
    1883             : static inline bool
    1884     8614277 : exp_cmp_exp_is_false(sql_exp* e) {
    1885     8614277 :     assert(e->type == e_cmp);
    1886             : 
    1887     8614277 :     switch (e->flag) {
    1888     7594075 :     case cmp_gt:
    1889             :     case cmp_gte:
    1890             :     case cmp_lte:
    1891             :     case cmp_lt:
    1892             :     case cmp_equal:
    1893             :     case cmp_notequal:
    1894     7594075 :                 return exp_regular_cmp_exp_is_false(e);
    1895      609331 :     case cmp_or:
    1896      609331 :                 return exp_or_exp_is_false(e);
    1897             :     default:
    1898             :                 return false;
    1899             :         }
    1900             : }
    1901             : 
    1902             : int
    1903     8683402 : exp_is_false(sql_exp *e)
    1904             : {
    1905     8683402 :         if (e->type == e_atom && e->l)
    1906       19857 :                 return atom_is_false(e->l);
    1907     8663545 :         else if (e->type == e_cmp)
    1908     8614277 :                 return exp_cmp_exp_is_false(e);
    1909             :         return 0;
    1910             : }
    1911             : 
    1912             : int
    1913       18046 : exp_is_zero(sql_exp *e)
    1914             : {
    1915       18046 :         if (e->type == e_atom && e->l)
    1916       17657 :                 return atom_is_zero(e->l);
    1917             :         return 0;
    1918             : }
    1919             : 
    1920             : int
    1921      414906 : exp_is_not_null(sql_exp *e)
    1922             : {
    1923      427499 :         if (!has_nil(e))
    1924             :                 return true;
    1925             : 
    1926      386773 :         switch (e->type) {
    1927        2663 :         case e_atom:
    1928        2663 :                 if (e->f) /* values list */
    1929             :                         return false;
    1930        2663 :                 if (e->l)
    1931        2415 :                         return !(atom_null(e->l));
    1932             :                 return false;
    1933       12593 :         case e_convert:
    1934       12593 :                 return exp_is_not_null(e->l);
    1935        1123 :         case e_func:
    1936        1123 :                 if (!is_semantics(e) && e->l) {
    1937         622 :                         list *l = e->l;
    1938         683 :                         for (node *n = l->h; n; n=n->next) {
    1939         683 :                                 sql_exp *p = n->data;
    1940         683 :                                 if (!exp_is_not_null(p))
    1941             :                                         return false;
    1942             :                         }
    1943             :                         return true;
    1944             :                 }
    1945             :                 return false;
    1946             :         case e_aggr:
    1947             :         case e_column:
    1948             :         case e_cmp:
    1949             :         case e_psm:
    1950             :                 return false;
    1951             :         }
    1952             :         return false;
    1953             : }
    1954             : 
    1955             : int
    1956    15923963 : exp_is_null(sql_exp *e )
    1957             : {
    1958    16501821 :         if (!has_nil(e))
    1959             :                 return false;
    1960             : 
    1961    10951608 :         switch (e->type) {
    1962      132866 :         case e_atom:
    1963      132866 :                 if (e->f) /* values list */
    1964             :                         return 0;
    1965      132866 :                 if (e->l)
    1966       20683 :                         return (atom_null(e->l));
    1967             :                 return 0;
    1968      577858 :         case e_convert:
    1969      577858 :                 return exp_is_null(e->l);
    1970      289701 :         case e_func:
    1971      289701 :                 if (!is_semantics(e) && e->l) {
    1972             :                         /* This is a call to a function with no-nil semantics.
    1973             :                          * If one of the parameters is null the expression itself is null
    1974             :                          */
    1975      274483 :                         list* l = e->l;
    1976      819804 :                         for(node* n = l->h; n; n=n->next) {
    1977      545484 :                                 sql_exp* p = n->data;
    1978      545484 :                                 if (exp_is_null(p)) {
    1979             :                                         return true;
    1980             :                                 }
    1981             :                         }
    1982             :                 }
    1983             :                 return 0;
    1984             :         case e_aggr:
    1985             :         case e_column:
    1986             :         case e_cmp:
    1987             :         case e_psm:
    1988             :                 return 0;
    1989             :         }
    1990             :         return 0;
    1991             : }
    1992             : 
    1993             : int
    1994     1839720 : exp_is_rel( sql_exp *e )
    1995             : {
    1996     1849395 :         if (e) {
    1997     1849395 :                 switch(e->type){
    1998        9675 :                 case e_convert:
    1999        9675 :                         return exp_is_rel(e->l);
    2000      334543 :                 case e_psm:
    2001      334543 :                         return e->flag == PSM_REL && e->l;
    2002             :                 default:
    2003             :                         return 0;
    2004             :                 }
    2005             :         }
    2006             :         return 0;
    2007             : }
    2008             : 
    2009             : int
    2010        7216 : exps_one_is_rel(list *exps)
    2011             : {
    2012        7216 :         if (list_empty(exps))
    2013             :                 return 0;
    2014       21547 :         for(node *n = exps->h ; n ; n = n->next)
    2015       14339 :                 if (exp_is_rel(n->data))
    2016             :                         return 1;
    2017             :         return 0;
    2018             : }
    2019             : 
    2020             : int
    2021     8627281 : exp_is_atom( sql_exp *e )
    2022             : {
    2023     9271231 :         switch (e->type) {
    2024     1204060 :         case e_atom:
    2025     1204060 :                 if (e->f) /* values list */
    2026             :                         return 0;
    2027             :                 return 1;
    2028      643950 :         case e_convert:
    2029      643950 :                 return exp_is_atom(e->l);
    2030     1238805 :         case e_func:
    2031             :         case e_aggr:
    2032     1238805 :                 return e->card == CARD_ATOM && exps_are_atoms(e->l);
    2033         222 :         case e_cmp:
    2034         222 :                 if (e->card != CARD_ATOM)
    2035             :                         return 0;
    2036          65 :                 if (e->flag == cmp_or || e->flag == cmp_filter)
    2037           0 :                         return exps_are_atoms(e->l) && exps_are_atoms(e->r);
    2038          65 :                 if (e->flag == cmp_in || e->flag == cmp_notin)
    2039           0 :                         return exp_is_atom(e->l) && exps_are_atoms(e->r);
    2040          65 :                 return exp_is_atom(e->l) && exp_is_atom(e->r) && (!e->f || exp_is_atom(e->f));
    2041             :         case e_column:
    2042             :         case e_psm:
    2043             :                 return 0;
    2044             :         }
    2045             :         return 0;
    2046             : }
    2047             : 
    2048             : int
    2049    31444075 : exp_has_rel( sql_exp *e )
    2050             : {
    2051    33428848 :         if (!e)
    2052             :                 return 0;
    2053    33427296 :         switch(e->type){
    2054     4724604 :         case e_func:
    2055             :         case e_aggr:
    2056     4724604 :                 return exps_have_rel_exp(e->l);
    2057      668755 :         case e_cmp:
    2058      668755 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2059       67691 :                         return (exps_have_rel_exp(e->l) || exps_have_rel_exp(e->r));
    2060      601550 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2061       36870 :                         return (exp_has_rel(e->l) || exps_have_rel_exp(e->r));
    2062             :                 } else {
    2063     1129360 :                         return (exp_has_rel(e->l) || exp_has_rel(e->r) || (e->f && exp_has_rel(e->f)));
    2064             :                 }
    2065     1984773 :         case e_convert:
    2066     1984773 :                 return exp_has_rel(e->l);
    2067      166817 :         case e_psm:
    2068      166817 :                 return exp_is_rel(e);
    2069    14269062 :         case e_atom:
    2070    14269062 :                 return (e->f && exps_have_rel_exp(e->f));
    2071             :         case e_column:
    2072             :                 return 0;
    2073             :         }
    2074             :         return 0;
    2075             : }
    2076             : 
    2077             : int
    2078     5473924 : exps_have_rel_exp( list *exps)
    2079             : {
    2080     5473924 :         if (list_empty(exps))
    2081             :                 return 0;
    2082    18750571 :         for(node *n=exps->h; n; n=n->next) {
    2083    13397782 :                 sql_exp *e = n->data;
    2084             : 
    2085    13397782 :                 if (exp_has_rel(e))
    2086             :                         return 1;
    2087             :         }
    2088             :         return 0;
    2089             : }
    2090             : 
    2091             : static sql_rel *
    2092         556 : exps_rel_get_rel(sql_allocator *sa, list *exps )
    2093             : {
    2094         556 :         sql_rel *r = NULL, *xp = NULL;
    2095             : 
    2096         556 :         if (list_empty(exps))
    2097             :                 return NULL;
    2098        1637 :         for (node *n = exps->h; n; n=n->next){
    2099        1081 :                 sql_exp *e = n->data;
    2100             : 
    2101        1081 :                 if (exp_has_rel(e)) {
    2102         561 :                         if (!(r = exp_rel_get_rel(sa, e)))
    2103             :                                 return NULL;
    2104         561 :                         if (xp) {
    2105           5 :                                 xp = rel_crossproduct(sa, xp, r, op_full);
    2106           5 :                                 set_processed(xp);
    2107             :                         } else {
    2108             :                                 xp = r;
    2109             :                         }
    2110             :                 }
    2111             :         }
    2112             :         return xp;
    2113             : }
    2114             : 
    2115             : int
    2116          47 : exp_rel_depth(sql_exp *e)
    2117             : {
    2118          47 :         if (!e)
    2119             :                 return 0;
    2120          47 :         switch(e->type){
    2121             :         case e_func:
    2122             :         case e_aggr:
    2123             :         case e_cmp:
    2124             :                 return 1;
    2125             :         case e_convert:
    2126             :                 return 0;
    2127          33 :         case e_psm:
    2128          33 :                 if (exp_is_rel(e))
    2129             :                         return 0;
    2130             :                 return 1;
    2131             :         case e_atom:
    2132             :         case e_column:
    2133             :                 return 0;
    2134             :         }
    2135             :         return 0;
    2136             : }
    2137             : 
    2138             : sql_rel *
    2139       73111 : exp_rel_get_rel(sql_allocator *sa, sql_exp *e)
    2140             : {
    2141       74046 :         if (!e)
    2142             :                 return NULL;
    2143             : 
    2144       74046 :         switch(e->type){
    2145         528 :         case e_func:
    2146             :         case e_aggr:
    2147         528 :                 return exps_rel_get_rel(sa, e->l);
    2148          37 :         case e_cmp: {
    2149          37 :                 sql_rel *r = NULL, *xp = NULL;
    2150             : 
    2151          37 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2152          12 :                         if (exps_have_rel_exp(e->l))
    2153           6 :                                 xp = exps_rel_get_rel(sa, e->l);
    2154          12 :                         if (exps_have_rel_exp(e->r)) {
    2155           7 :                                 if (!(r = exps_rel_get_rel(sa, e->r)))
    2156             :                                         return NULL;
    2157           7 :                                 if (xp) {
    2158           1 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2159           1 :                                         set_processed(xp);
    2160             :                                 } else {
    2161             :                                         xp = r;
    2162             :                                 }
    2163             :                         }
    2164          25 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2165           0 :                         if (exp_has_rel(e->l))
    2166           0 :                                 xp = exp_rel_get_rel(sa, e->l);
    2167           0 :                         if (exps_have_rel_exp(e->r)) {
    2168           0 :                                 if (!(r = exps_rel_get_rel(sa, e->r)))
    2169             :                                         return NULL;
    2170           0 :                                 if (xp) {
    2171           0 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2172           0 :                                         set_processed(xp);
    2173             :                                 } else {
    2174             :                                         xp = r;
    2175             :                                 }
    2176             :                         }
    2177             :                 } else {
    2178          25 :                         if (exp_has_rel(e->l))
    2179          23 :                                 xp = exp_rel_get_rel(sa, e->l);
    2180          25 :                         if (exp_has_rel(e->r)) {
    2181           7 :                                 if (!(r = exp_rel_get_rel(sa, e->r)))
    2182             :                                         return NULL;
    2183           7 :                                 if (xp) {
    2184           5 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2185           5 :                                         set_processed(xp);
    2186             :                                 } else {
    2187             :                                         xp = r;
    2188             :                                 }
    2189             :                         }
    2190          25 :                         if (e->f && exp_has_rel(e->f)) {
    2191           0 :                                 if (!(r = exp_rel_get_rel(sa, e->f)))
    2192             :                                         return NULL;
    2193           0 :                                 if (xp) {
    2194           0 :                                         xp = rel_crossproduct(sa, xp, r, op_join);
    2195           0 :                                         set_processed(xp);
    2196             :                                 } else {
    2197             :                                         xp = r;
    2198             :                                 }
    2199             :                         }
    2200             :                 }
    2201             :                 return xp;
    2202             :         }
    2203         935 :         case e_convert:
    2204         935 :                 return exp_rel_get_rel(sa, e->l);
    2205       72531 :         case e_psm:
    2206       72531 :                 if (exp_is_rel(e))
    2207       72531 :                         return e->l;
    2208             :                 return NULL;
    2209          15 :         case e_atom:
    2210          15 :                 if (e->f && exps_have_rel_exp(e->f))
    2211          15 :                         return exps_rel_get_rel(sa, e->f);
    2212             :                 return NULL;
    2213             :         case e_column:
    2214             :                 return NULL;
    2215             :         }
    2216             :         return NULL;
    2217             : }
    2218             : 
    2219             : static void exp_rel_update_set_freevar(sql_exp *e);
    2220             : 
    2221             : static void
    2222         909 : exps_rel_update_set_freevar(list *exps)
    2223             : {
    2224         909 :         if (!list_empty(exps))
    2225        2956 :                 for (node *n=exps->h; n ; n=n->next)
    2226        2047 :                         exp_rel_update_set_freevar(n->data);
    2227         909 : }
    2228             : 
    2229             : static void
    2230        2333 : exp_rel_update_set_freevar(sql_exp *e)
    2231             : {
    2232        2346 :         if (!e)
    2233             :                 return ;
    2234             : 
    2235        2346 :         switch(e->type){
    2236         906 :         case e_func:
    2237             :         case e_aggr:
    2238         906 :                 exps_rel_update_set_freevar(e->l);
    2239         906 :                 break;
    2240           8 :         case e_cmp:
    2241           8 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2242           0 :                         exps_rel_update_set_freevar(e->l);
    2243           0 :                         exps_rel_update_set_freevar(e->r);
    2244           8 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2245           0 :                         exp_rel_update_set_freevar(e->l);
    2246           0 :                         exps_rel_update_set_freevar(e->r);
    2247             :                 } else {
    2248           8 :                         exp_rel_update_set_freevar(e->l);
    2249           8 :                         exp_rel_update_set_freevar(e->r);
    2250           8 :                         if (e->f)
    2251             :                                 exp_rel_update_set_freevar(e->f);
    2252             :                 }
    2253             :                 break;
    2254          10 :         case e_convert:
    2255          10 :                 exp_rel_update_set_freevar(e->l);
    2256          10 :                 break;
    2257        1145 :         case e_atom:
    2258        1145 :                 if (e->f)
    2259           3 :                         exps_rel_update_set_freevar(e->f);
    2260             :                 break;
    2261         277 :         case e_column:
    2262         277 :                 set_freevar(e, 1);
    2263         277 :                 break;
    2264             :         case e_psm:
    2265             :                 break;
    2266             :         }
    2267             : }
    2268             : 
    2269             : static list *
    2270         556 : exp_rel_update_exps(mvc *sql, list *exps, bool up)
    2271             : {
    2272         556 :         if (list_empty(exps))
    2273             :                 return exps;
    2274        1637 :         for (node *n = exps->h; n; n=n->next){
    2275        1081 :                 sql_exp *e = n->data;
    2276             : 
    2277        1081 :                 if (exp_has_rel(e))
    2278         561 :                         n->data = exp_rel_update_exp(sql, e, up);
    2279         520 :                 else if (!exp_is_atom(e) && !up)
    2280         264 :                         exp_rel_update_set_freevar(e);
    2281             :         }
    2282             :         return exps;
    2283             : }
    2284             : 
    2285             : static sql_exp *
    2286          53 : exp_rel_update_exp_(mvc *sql, sql_exp *e, bool up)
    2287             : {
    2288          53 :         if (exp_has_rel(e))
    2289          29 :                 e = exp_rel_update_exp(sql, e, up);
    2290          24 :         else if (!exp_is_atom(e) && !up)
    2291           6 :                 exp_rel_update_set_freevar(e);
    2292          53 :         return e;
    2293             : }
    2294             : 
    2295             : sql_exp *
    2296       12650 : exp_rel_update_exp(mvc *sql, sql_exp *e, bool up)
    2297             : {
    2298       12650 :         if (!e)
    2299             :                 return NULL;
    2300             : 
    2301       12650 :         switch(e->type){
    2302         528 :         case e_func:
    2303             :         case e_aggr:
    2304         528 :                 if (exps_have_rel_exp(e->l))
    2305         528 :                         e->l = exp_rel_update_exps(sql, e->l, up);
    2306             :                 return e;
    2307          36 :         case e_cmp:
    2308          36 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2309          12 :                         if (exps_have_rel_exp(e->l))
    2310           6 :                                 e->l = exp_rel_update_exps(sql, e->l, up);
    2311          12 :                         if (exps_have_rel_exp(e->r))
    2312           7 :                                 e->r = exp_rel_update_exps(sql, e->r, up);
    2313          24 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2314           0 :                         if (exp_has_rel(e->l))
    2315           0 :                                 e->l = exp_rel_update_exp(sql, e->l, up);
    2316           0 :                         if (exps_have_rel_exp(e->r))
    2317           0 :                                 e->r = exp_rel_update_exps(sql, e->r, up);
    2318             :                 } else {
    2319             :                         //if (exp_has_rel(e->l))
    2320          24 :                                 e->l = exp_rel_update_exp_(sql, e->l, up);
    2321             :                         //if (exp_has_rel(e->r))
    2322          24 :                                 e->r = exp_rel_update_exp_(sql, e->r, up);
    2323          24 :                         if (e->f /*&& exp_has_rel(e->f)*/)
    2324           5 :                                 e->f = exp_rel_update_exp_(sql, e->f, up);
    2325             :                 }
    2326             :                 return e;
    2327         935 :         case e_convert:
    2328         935 :                 if (exp_has_rel(e->l))
    2329         935 :                         e->l = exp_rel_update_exp(sql, e->l, up);
    2330             :                 return e;
    2331       11136 :         case e_psm:
    2332       11136 :                 if (exp_is_rel(e)) {
    2333       11136 :                         sql_rel *r = exp_rel_get_rel(sql->sa, e), *nr = r;
    2334       11136 :                         if (is_topn(r->op)) {
    2335           2 :                                 nr = r->l;
    2336           2 :                                 if (nr && !is_project(nr->op))
    2337           0 :                                         r->l = nr = rel_project(sql->sa, nr, rel_projections(sql, nr, NULL, 1, 0));
    2338             :                         }
    2339       11136 :                         e = nr->exps->t->data;
    2340       11136 :                         e = exp_ref(sql, e);
    2341       11136 :                         if (up)
    2342           0 :                                 set_freevar(e, 1);
    2343       11136 :                         return e;
    2344             :                 }
    2345             :                 return e;
    2346          15 :         case e_atom:
    2347          15 :                 if (e->f && exps_have_rel_exp(e->f))
    2348          15 :                         e->f = exp_rel_update_exps(sql, e->f, up);
    2349             :                 return e;
    2350             :         case e_column:
    2351             :                 return e;
    2352             :         }
    2353             :         return e;
    2354             : }
    2355             : 
    2356             : sql_exp *
    2357        3757 : exp_rel_label(mvc *sql, sql_exp *e)
    2358             : {
    2359        3757 :         if (exp_is_rel(e))
    2360        3757 :                 e->l = rel_label(sql, e->l, 1);
    2361        3757 :         return e;
    2362             : }
    2363             : 
    2364             : int
    2365      161886 : exps_are_atoms( list *exps)
    2366             : {
    2367      161886 :         int atoms = 1;
    2368      161886 :         if (!list_empty(exps))
    2369      388094 :                 for(node *n=exps->h; n && atoms; n=n->next)
    2370      274188 :                         atoms &= exp_is_atom(n->data);
    2371      161886 :         return atoms;
    2372             : }
    2373             : 
    2374             : int
    2375          90 : exps_have_func(list *exps)
    2376             : {
    2377          90 :         if (list_empty(exps))
    2378             :                 return 0;
    2379         138 :         for(node *n=exps->h; n; n=n->next) {
    2380         104 :                 sql_exp *e = n->data;
    2381             : 
    2382         104 :                 if (exp_has_func(e))
    2383             :                         return 1;
    2384             :         }
    2385             :         return 0;
    2386             : }
    2387             : 
    2388             : static int exp_has_func_or_cmp(sql_exp *e, bool cmp);
    2389             : 
    2390             : static int
    2391       63623 : exps_have_func_or_cmp(list *exps, bool cmp)
    2392             : {
    2393       63623 :         if (list_empty(exps))
    2394             :                 return 0;
    2395      185594 :         for(node *n=exps->h; n; n=n->next) {
    2396      131220 :                 sql_exp *e = n->data;
    2397             : 
    2398      131220 :                 if (exp_has_func_or_cmp(e, cmp))
    2399             :                         return 1;
    2400             :         }
    2401             :         return 0;
    2402             : }
    2403             : 
    2404             : static int
    2405     2112071 : exp_has_func_or_cmp(sql_exp *e, bool cmp)
    2406             : {
    2407     2112071 :         if (!e)
    2408             :                 return 0;
    2409     2112071 :         switch (e->type) {
    2410      309201 :         case e_atom:
    2411      309201 :                 if (e->f)
    2412           0 :                         return exps_have_func_or_cmp(e->f, true);
    2413             :                 return 0;
    2414       60423 :         case e_convert:
    2415       60423 :                 return exp_has_func_or_cmp(e->l, cmp);
    2416             :         case e_func:
    2417             :                 return 1;
    2418       15758 :         case e_aggr:
    2419       15758 :                 if (e->l)
    2420       13232 :                         return exps_have_func_or_cmp(e->l, true);
    2421             :                 return 0;
    2422      270189 :         case e_cmp:
    2423      270189 :                 if (cmp)
    2424             :                         return 1;
    2425      261045 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2426       21808 :                         return (exps_have_func_or_cmp(e->l, true) || exps_have_func_or_cmp(e->r, true));
    2427      248421 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2428       34371 :                         return (exp_has_func_or_cmp(e->l, true) || exps_have_func_or_cmp(e->r, true));
    2429             :                 } else {
    2430      428194 :                         return (exp_has_func_or_cmp(e->l, true) || exp_has_func_or_cmp(e->r, true) ||
    2431      198527 :                                         (e->f && exp_has_func_or_cmp(e->f, true)));
    2432             :                 }
    2433             :         case e_column:
    2434             :         case e_psm:
    2435             :                 return 0;
    2436             :         }
    2437             :         return 0;
    2438             : }
    2439             : 
    2440             : int
    2441     1470746 : exp_has_func(sql_exp *e)
    2442             : {
    2443     1470746 :         return exp_has_func_or_cmp(e, false);
    2444             : }
    2445             : 
    2446             : static int
    2447      754834 : exps_has_sideeffect( list *exps)
    2448             : {
    2449      754834 :         node *n;
    2450      754834 :         int has_sideeffect = 0;
    2451             : 
    2452     2317332 :         for(n=exps->h; n && !has_sideeffect; n=n->next)
    2453     1562498 :                 has_sideeffect |= exp_has_sideeffect(n->data);
    2454      754834 :         return has_sideeffect;
    2455             : }
    2456             : 
    2457             : int
    2458     1751891 : exp_has_sideeffect( sql_exp *e )
    2459             : {
    2460     2126890 :         switch (e->type) {
    2461      374999 :         case e_convert:
    2462      374999 :                 return exp_has_sideeffect(e->l);
    2463      754859 :         case e_func:
    2464             :                 {
    2465      754859 :                         sql_subfunc *f = e->f;
    2466             : 
    2467      754859 :                         if (f->func->side_effect)
    2468             :                                 return 1;
    2469      754845 :                         if (e->l)
    2470      754834 :                                 return exps_has_sideeffect(e->l);
    2471             :                         return 0;
    2472             :                 }
    2473      494848 :         case e_atom:
    2474      494848 :                 if (e->f)
    2475           0 :                         return exps_has_sideeffect(e->f);
    2476             :                 return 0;
    2477             :         case e_aggr:
    2478             :         case e_cmp:
    2479             :         case e_column:
    2480             :         case e_psm:
    2481             :                 return 0;
    2482             :         }
    2483             :         return 0;
    2484             : }
    2485             : 
    2486             : int
    2487     1015901 : exps_have_unsafe(list *exps, int allow_identity)
    2488             : {
    2489     1015901 :         int unsafe = 0;
    2490             : 
    2491     1015901 :         if (list_empty(exps))
    2492             :                 return 0;
    2493     3519030 :         for (node *n = exps->h; n && !unsafe; n = n->next)
    2494     2510211 :                 unsafe |= exp_unsafe(n->data, allow_identity);
    2495             :         return unsafe;
    2496             : }
    2497             : 
    2498             : int
    2499    11477054 : exp_unsafe(sql_exp *e, int allow_identity)
    2500             : {
    2501    12704001 :         switch (e->type) {
    2502     1226947 :         case e_convert:
    2503     1226947 :                 return exp_unsafe(e->l, allow_identity);
    2504     1071391 :         case e_aggr:
    2505             :         case e_func: {
    2506     1071391 :                 sql_subfunc *f = e->f;
    2507             : 
    2508     1071391 :                 if (IS_ANALYTIC(f->func) || !LANG_INT_OR_MAL(f->func->lang) || f->func->side_effect || (!allow_identity && is_identity(e, NULL)))
    2509      112055 :                         return 1;
    2510      959336 :                 return exps_have_unsafe(e->l, allow_identity);
    2511         320 :         } break;
    2512         320 :         case e_cmp: {
    2513         320 :                 if (e->flag == cmp_in || e->flag == cmp_notin) {
    2514           0 :                         return exp_unsafe(e->l, allow_identity) || exps_have_unsafe(e->r, allow_identity);
    2515         320 :                 } else if (e->flag == cmp_or || e->flag == cmp_filter) {
    2516           0 :                         return exps_have_unsafe(e->l, allow_identity) || exps_have_unsafe(e->r, allow_identity);
    2517             :                 } else {
    2518         640 :                         return exp_unsafe(e->l, allow_identity) || exp_unsafe(e->r, allow_identity) || (e->f && exp_unsafe(e->f, allow_identity));
    2519             :                 }
    2520      930021 :         } break;
    2521      930021 :         case e_atom: {
    2522      930021 :                 if (e->f)
    2523           0 :                         return exps_have_unsafe(e->f, allow_identity);
    2524             :                 return 0;
    2525             :         } break;
    2526             :         case e_column:
    2527             :         case e_psm:
    2528             :                 return 0;
    2529             :         }
    2530             :         return 0;
    2531             : }
    2532             : 
    2533             : static inline int
    2534     9714358 : exp_key( sql_exp *e )
    2535             : {
    2536     9714358 :         if (e->alias.name)
    2537     9714133 :                 return hash_key(e->alias.name);
    2538             :         return 0;
    2539             : }
    2540             : 
    2541             : sql_exp *
    2542     3470047 : exps_bind_column(list *exps, const char *cname, int *ambiguous, int *multiple, int no_tname)
    2543             : {
    2544     3470047 :         sql_exp *res = NULL;
    2545             : 
    2546     3470047 :         if (exps && cname) {
    2547     3469075 :                 node *en;
    2548             : 
    2549     3469075 :                 if (exps) {
    2550     3469075 :                         if (!exps->ht && list_length(exps) > HASH_MIN_SIZE) {
    2551      125501 :                                 exps->ht = hash_new(exps->sa, list_length(exps), (fkeyvalue)&exp_key);
    2552      125501 :                                 if (exps->ht == NULL)
    2553             :                                         return NULL;
    2554     1198484 :                                 for (en = exps->h; en; en = en->next ) {
    2555     1072983 :                                         sql_exp *e = en->data;
    2556     1072983 :                                         if (e->alias.name) {
    2557     1072983 :                                                 int key = exp_key(e);
    2558             : 
    2559     1072983 :                                                 if (hash_add(exps->ht, key, e) == NULL)
    2560             :                                                         return NULL;
    2561             :                                         }
    2562             :                                 }
    2563             :                         }
    2564     3469075 :                         if (exps->ht) {
    2565     2603590 :                                 int key = hash_key(cname);
    2566     2603590 :                                 sql_hash_e *he = exps->ht->buckets[key&(exps->ht->size-1)];
    2567             : 
    2568     6097306 :                                 for (; he; he = he->chain) {
    2569     3493720 :                                         sql_exp *e = he->value;
    2570             : 
    2571     3493720 :                                         if (e->alias.name && strcmp(e->alias.name, cname) == 0 && (!no_tname || !e->alias.rname)) {
    2572     1346765 :                                                 if (res && multiple)
    2573           4 :                                                         *multiple = 1;
    2574     1346765 :                                                 if (!res)
    2575     1346765 :                                                         res = e;
    2576             : 
    2577     1346765 :                                                 if (res && res != e && e->alias.rname && res->alias.rname && strcmp(e->alias.rname, res->alias.rname) != 0 ) {
    2578           4 :                                                         if (ambiguous)
    2579           4 :                                                                 *ambiguous = 1;
    2580           4 :                                                         return NULL;
    2581             :                                                 }
    2582             :                                                 res = e;
    2583             :                                         }
    2584             :                                 }
    2585     2603586 :                                 return res;
    2586             :                         }
    2587             :                 }
    2588     2950931 :                 for (en = exps->h; en; en = en->next ) {
    2589     2085451 :                         sql_exp *e = en->data;
    2590             : 
    2591     2085451 :                         if (e->alias.name && strcmp(e->alias.name, cname) == 0 && (!no_tname || !e->alias.rname)) {
    2592       81196 :                                 if (res && multiple)
    2593           8 :                                         *multiple = 1;
    2594       81196 :                                 if (!res)
    2595       81196 :                                         res = e;
    2596             : 
    2597       81196 :                                 if (res && res != e && e->alias.rname && res->alias.rname && strcmp(e->alias.rname, res->alias.rname) != 0 ) {
    2598           5 :                                         if (ambiguous)
    2599           5 :                                                 *ambiguous = 1;
    2600           5 :                                         return NULL;
    2601             :                                 }
    2602             :                                 res = e;
    2603             :                         }
    2604             :                 }
    2605             :         }
    2606             :         return res;
    2607             : }
    2608             : 
    2609             : sql_exp *
    2610   115218614 : exps_bind_column2(list *exps, const char *rname, const char *cname, int *multiple)
    2611             : {
    2612   115218614 :         sql_exp *res = NULL;
    2613             : 
    2614   115218614 :         if (exps) {
    2615   114990757 :                 node *en;
    2616             : 
    2617   114990757 :                 if (!exps->ht && list_length(exps) > HASH_MIN_SIZE) {
    2618      581073 :                         exps->ht = hash_new(exps->sa, list_length(exps), (fkeyvalue)&exp_key);
    2619      581071 :                         if (exps->ht == NULL)
    2620             :                                 return res;
    2621             : 
    2622     7646980 :                         for (en = exps->h; en; en = en->next ) {
    2623     7065911 :                                 sql_exp *e = en->data;
    2624     7065911 :                                 if (e->alias.name) {
    2625     7053086 :                                         int key = exp_key(e);
    2626             : 
    2627     7053085 :                                         if (hash_add(exps->ht, key, e) == NULL)
    2628             :                                                 return res;
    2629             :                                 }
    2630             :                         }
    2631             :                 }
    2632   114990748 :                 if (exps->ht) {
    2633    33829373 :                         int key = hash_key(cname);
    2634    33829373 :                         sql_hash_e *he = exps->ht->buckets[key&(exps->ht->size-1)];
    2635             : 
    2636    83521001 :                         for (; he; he = he->chain) {
    2637    50432179 :                                 sql_exp *e = he->value;
    2638             : 
    2639    50432179 :                                 if (e && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) {
    2640    20604656 :                                         if (res && multiple)
    2641           0 :                                                 *multiple = 1;
    2642    20604656 :                                         if (!res)
    2643             :                                                 res = e;
    2644    20604656 :                                         if (res && res->alias.label) /* aliases maybe used multiple times without problems */
    2645      740551 :                                                 return res;
    2646             :                                 }
    2647             :                         }
    2648    33088822 :                         return res;
    2649             :                 }
    2650   367573222 :                 for (en = exps->h; en; en = en->next ) {
    2651   288215938 :                         sql_exp *e = en->data;
    2652             : 
    2653   288215938 :                         if (e && e->alias.name && e->alias.rname && strcmp(e->alias.name, cname) == 0 && strcmp(e->alias.rname, rname) == 0) {
    2654    10039021 :                                 if (res && multiple)
    2655           2 :                                         *multiple = 1;
    2656    10039021 :                                 if (!res)
    2657             :                                         res = e;
    2658    10039021 :                                 if (res && res->alias.label) /* aliases maybe used multiple times without problems */
    2659     1804091 :                                         return res;
    2660             :                         }
    2661             :                 }
    2662             :         }
    2663             :         return res;
    2664             : }
    2665             : 
    2666             : /* find an column based on the original name, not the alias it got */
    2667             : sql_exp *
    2668         333 : exps_bind_alias( list *exps, const char *rname, const char *cname )
    2669             : {
    2670         333 :         if (exps) {
    2671         333 :                 node *en;
    2672             : 
    2673         746 :                 for (en = exps->h; en; en = en->next ) {
    2674         417 :                         sql_exp *e = en->data;
    2675             : 
    2676         417 :                         if (e && is_column(e->type) && !rname && e->r && strcmp(e->r, cname) == 0)
    2677           0 :                                 return e;
    2678         417 :                         if (e && e->type == e_column && rname && e->l && e->r && strcmp(e->r, cname) == 0 && strcmp(e->l, rname) == 0) {
    2679           4 :                                 return e;
    2680             :                         }
    2681             :                 }
    2682             :         }
    2683             :         return NULL;
    2684             : }
    2685             : 
    2686             : unsigned int
    2687     3260301 : exps_card( list *l )
    2688             : {
    2689     3260301 :         node *n;
    2690     3260301 :         unsigned int card = CARD_ATOM;
    2691             : 
    2692    14334950 :         if (l) for(n = l->h; n; n = n->next) {
    2693    11074649 :                 sql_exp *e = n->data;
    2694             : 
    2695    11074649 :                 if (e && card < e->card)
    2696    11074649 :                         card = e->card;
    2697             :         }
    2698     3260301 :         return card;
    2699             : }
    2700             : 
    2701             : void
    2702       39140 : exps_fix_card( list *exps, unsigned int card)
    2703             : {
    2704       39140 :         if (exps)
    2705      963402 :                 for (node *n = exps->h; n; n = n->next) {
    2706      924262 :                 sql_exp *e = n->data;
    2707             : 
    2708      924262 :                 if (e && e->card > card)
    2709           0 :                         e->card = card;
    2710             :         }
    2711       39140 : }
    2712             : 
    2713             : void
    2714        3976 : exps_setcard( list *exps, unsigned int card)
    2715             : {
    2716        3976 :         if (exps)
    2717       23326 :                 for (node *n = exps->h; n; n = n->next) {
    2718       19350 :                         sql_exp *e = n->data;
    2719             : 
    2720       19350 :                         if (e && e->card != CARD_ATOM)
    2721       19317 :                                 e->card = card;
    2722             :                 }
    2723        3976 : }
    2724             : 
    2725             : int
    2726           0 : exps_intern(list *exps)
    2727             : {
    2728           0 :         if (exps)
    2729           0 :                 for (node *n=exps->h; n; n = n->next) {
    2730           0 :                         sql_exp *e = n->data;
    2731             : 
    2732           0 :                         if (is_intern(e))
    2733             :                                 return 1;
    2734             :                 }
    2735             :         return 0;
    2736             : }
    2737             : 
    2738             : sql_exp *
    2739        1205 : exps_find_one_multi_exp(list *exps)
    2740             : {
    2741        1205 :         sql_exp *l = NULL;
    2742        1205 :         int skip = 0;
    2743             : 
    2744             :         /* Find one and only 1 expression with card > CARD_ATOM */
    2745        1205 :         if (!list_empty(exps)) {
    2746        2588 :                 for (node *m = exps->h ; m && !skip ; m = m->next) {
    2747        1383 :                         sql_exp *e = m->data;
    2748             : 
    2749        1383 :                         if (e->card > CARD_ATOM) {
    2750        1204 :                                 skip |= l != NULL;
    2751        1204 :                                 l = e;
    2752             :                         }
    2753             :                 }
    2754             :         }
    2755        1205 :         if (skip)
    2756           5 :                 l = NULL;
    2757        1205 :         return l;
    2758             : }
    2759             : 
    2760             : const char *
    2761      132989 : compare_func( comp_type t, int anti )
    2762             : {
    2763      132989 :         switch(t) {
    2764       79176 :         case cmp_equal:
    2765       79176 :                 return anti?"<>":"=";
    2766        7926 :         case cmp_lt:
    2767        7926 :                 return anti?">":"<";
    2768        2098 :         case cmp_lte:
    2769        2098 :                 return anti?">=":"<=";
    2770        1146 :         case cmp_gte:
    2771        1146 :                 return anti?"<=":">=";
    2772       30780 :         case cmp_gt:
    2773       30780 :                 return anti?"<":">";
    2774       11863 :         case cmp_notequal:
    2775       11863 :                 return anti?"=":"<>";
    2776             :         default:
    2777             :                 return NULL;
    2778             :         }
    2779             : }
    2780             : 
    2781             : int
    2782     9755376 : is_identity( sql_exp *e, sql_rel *r)
    2783             : {
    2784     9766616 :         switch(e->type) {
    2785       33212 :         case e_column:
    2786       33212 :                 if (r && is_project(r->op)) {
    2787       13347 :                         sql_exp *re = NULL;
    2788       13347 :                         if (e->l)
    2789       13252 :                                 re = exps_bind_column2(r->exps, e->l, e->r, NULL);
    2790       13347 :                         if (!re && has_label(e))
    2791         249 :                                 re = exps_bind_column(r->exps, e->r, NULL, NULL, 1);
    2792        2107 :                         if (re)
    2793       11240 :                                 return is_identity(re, r->l);
    2794             :                 }
    2795             :                 return 0;
    2796     9727971 :         case e_func: {
    2797     9727971 :                 sql_subfunc *f = e->f;
    2798     9727971 :                 return !f->func->s && strcmp(f->func->base.name, "identity") == 0;
    2799             :         }
    2800             :         default:
    2801             :                 return 0;
    2802             :         }
    2803             : }
    2804             : 
    2805             : list *
    2806         144 : exps_alias(mvc *sql, list *exps)
    2807             : {
    2808         144 :         list *nl = new_exp_list(sql->sa);
    2809             : 
    2810         144 :         if (exps)
    2811         882 :                 for (node *n = exps->h; n; n = n->next) {
    2812         738 :                         sql_exp *e = n->data, *ne;
    2813             : 
    2814         738 :                         assert(exp_name(e));
    2815         738 :                         ne = exp_ref(sql, e);
    2816         738 :                         append(nl, ne);
    2817             :                 }
    2818         144 :         return nl;
    2819             : }
    2820             : 
    2821             : list *
    2822      129795 : exps_copy(mvc *sql, list *exps)
    2823             : {
    2824      129795 :         list *nl;
    2825             : 
    2826      129795 :         if (mvc_highwater(sql))
    2827           0 :                 return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    2828             : 
    2829      129795 :         if (!exps)
    2830             :                 return NULL;
    2831      114045 :         nl = new_exp_list(sql->sa);
    2832      509180 :         for (node *n = exps->h; n; n = n->next) {
    2833      395135 :                 sql_exp *arg = n->data;
    2834             : 
    2835      395135 :                 arg = exp_copy(sql, arg);
    2836      395135 :                 if (!arg)
    2837             :                         return NULL;
    2838      395135 :                 append(nl, arg);
    2839             :         }
    2840             :         return nl;
    2841             : }
    2842             : 
    2843             : sql_exp *
    2844      657561 : exp_copy(mvc *sql, sql_exp * e)
    2845             : {
    2846      657561 :         sql_exp *l, *r, *r2, *ne = NULL;
    2847             : 
    2848      657561 :         if (mvc_highwater(sql))
    2849           0 :                 return sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    2850             : 
    2851      657561 :         if (!e)
    2852             :                 return NULL;
    2853      657561 :         switch(e->type){
    2854      400783 :         case e_column:
    2855      400783 :                 ne = exp_column(sql->sa, e->l, e->r, exp_subtype(e), e->card, has_nil(e), is_unique(e), is_intern(e));
    2856      400783 :                 ne->flag = e->flag;
    2857      400783 :                 break;
    2858       41086 :         case e_cmp:
    2859       41086 :                 if (e->flag == cmp_or || e->flag == cmp_filter) {
    2860        3241 :                         list *l = exps_copy(sql, e->l);
    2861        3241 :                         list *r = exps_copy(sql, e->r);
    2862             : 
    2863        3241 :                         if (e->flag == cmp_filter)
    2864         569 :                                 ne = exp_filter(sql->sa, l, r, e->f, is_anti(e));
    2865             :                         else
    2866        2672 :                                 ne = exp_or(sql->sa, l, r, is_anti(e));
    2867       37845 :                 } else if (e->flag == cmp_in || e->flag == cmp_notin) {
    2868        1135 :                         sql_exp *l = exp_copy(sql, e->l);
    2869        1135 :                         list *r = exps_copy(sql, e->r);
    2870             : 
    2871        1135 :                         ne = exp_in(sql->sa, l, r, e->flag);
    2872             :                 } else {
    2873       36710 :                         l = exp_copy(sql, e->l);
    2874       36710 :                         r = exp_copy(sql, e->r);
    2875             : 
    2876       36710 :                         if (e->f) {
    2877         658 :                                 r2 = exp_copy(sql, e->f);
    2878         658 :                                 ne = exp_compare2(sql->sa, l, r, r2, e->flag, is_symmetric(e));
    2879             :                         } else {
    2880       36052 :                                 ne = exp_compare(sql->sa, l, r, e->flag);
    2881             :                         }
    2882             :                 }
    2883             :                 break;
    2884       30938 :         case e_convert:
    2885       30938 :                 ne = exp_convert(sql->sa, exp_copy(sql, e->l), exp_fromtype(e), exp_totype(e));
    2886       30938 :                 break;
    2887       12179 :         case e_aggr:
    2888             :         case e_func: {
    2889       12179 :                 list *l = exps_copy(sql, e->l);
    2890             : 
    2891       12179 :                 if (e->type == e_func)
    2892       10402 :                         ne = exp_op(sql->sa, l, e->f);
    2893             :                 else
    2894        1777 :                         ne = exp_aggr(sql->sa, l, e->f, need_distinct(e), need_no_nil(e), e->card, has_nil(e));
    2895       12179 :                 if (e->r) { /* copy obe and gbe lists */
    2896           2 :                         list *er = (list*) e->r;
    2897           2 :                         assert(list_length(er) <= 2);
    2898           2 :                         if (list_length(er) == 2)
    2899           0 :                                 ne->r = list_append(list_append(sa_list(sql->sa), exps_copy(sql, er->h->data)), exps_copy(sql, er->h->next->data));
    2900             :                         else
    2901           2 :                                 ne->r = list_append(sa_list(sql->sa), exps_copy(sql, er->h->data));
    2902             :                 }
    2903             :                 break;
    2904             :         }
    2905      172571 :         case e_atom:
    2906      172571 :                 if (e->l)
    2907      168609 :                         ne = exp_atom(sql->sa, e->l);
    2908        3962 :                 else if (e->r) {
    2909        3906 :                         sql_var_name *vname = (sql_var_name*) e->r;
    2910        3906 :                         ne = exp_param_or_declared(sql->sa, vname->sname, vname->name, &e->tpe, e->flag);
    2911          56 :                 } else if (e->f)
    2912           3 :                         ne = exp_values(sql->sa, exps_copy(sql, e->f));
    2913             :                 else
    2914          53 :                         ne = exp_atom_ref(sql->sa, e->flag, &e->tpe);
    2915             :                 break;
    2916           4 :         case e_psm:
    2917           4 :                 if (e->flag & PSM_SET) {
    2918           0 :                         ne = exp_set(sql->sa, e->alias.rname, e->alias.name, exp_copy(sql, e->l), GET_PSM_LEVEL(e->flag));
    2919           4 :                 } else if (e->flag & PSM_VAR) {
    2920           0 :                         if (e->f)
    2921           0 :                                 ne = exp_table(sql->sa, e->alias.name, e->f, GET_PSM_LEVEL(e->flag));
    2922             :                         else
    2923           0 :                                 ne = exp_var(sql->sa, e->alias.rname, e->alias.name, &e->tpe, GET_PSM_LEVEL(e->flag));
    2924           4 :                 } else if (e->flag & PSM_RETURN) {
    2925           0 :                         ne = exp_return(sql->sa, exp_copy(sql, e->l), GET_PSM_LEVEL(e->flag));
    2926           4 :                 } else if (e->flag & PSM_WHILE) {
    2927           0 :                         ne = exp_while(sql->sa, exp_copy(sql, e->l), exps_copy(sql, e->r));
    2928           4 :                 } else if (e->flag & PSM_IF) {
    2929           0 :                         ne = exp_if(sql->sa, exp_copy(sql, e->l), exps_copy(sql, e->r), exps_copy(sql, e->f));
    2930           4 :                 } else if (e->flag & PSM_REL) {
    2931           4 :                         return exp_ref(sql, e);
    2932           0 :                 } else if (e->flag & PSM_EXCEPTION) {
    2933           0 :                         ne = exp_exception(sql->sa, exp_copy(sql, e->l), (const char *) e->r);
    2934             :                 }
    2935             :                 break;
    2936             :         }
    2937      657557 :         if (!ne)
    2938           0 :                 return ne;
    2939      657557 :         if (e->alias.name)
    2940      476843 :                 exp_prop_alias(sql->sa, ne, e);
    2941      657557 :         ne = exp_propagate(sql->sa, ne, e);
    2942      657557 :         if (is_freevar(e))
    2943        8248 :                 set_freevar(ne, is_freevar(e)-1);
    2944             :         return ne;
    2945             : }
    2946             : 
    2947             : sql_exp *
    2948        2593 : exp_scale_algebra(mvc *sql, sql_subfunc *f, sql_rel *rel, sql_exp *l, sql_exp *r)
    2949             : {
    2950        2593 :         sql_subtype *lt = exp_subtype(l);
    2951        2593 :         sql_subtype *rt = exp_subtype(r);
    2952             : 
    2953        2593 :         if (lt->type->scale == SCALE_FIX && rt->scale &&
    2954         145 :                 strcmp(sql_func_imp(f->func), "/") == 0) {
    2955         145 :                 sql_subtype *res = f->res->h->data;
    2956         145 :                 unsigned int scale, digits, digL, scaleL;
    2957         145 :                 sql_subtype nlt;
    2958             : 
    2959             :                 /* scale fixing may require a larger type ! */
    2960         145 :                 scaleL = (lt->scale < 3) ? 3 : lt->scale;
    2961         145 :                 scale = scaleL;
    2962         145 :                 scaleL += rt->scale;
    2963         145 :                 digL = lt->digits + (scaleL - lt->scale);
    2964         145 :                 digits = (digL > rt->digits) ? digL : rt->digits;
    2965             : 
    2966             :                 /* HACK alert: digits should be less than max */
    2967             : #ifdef HAVE_HGE
    2968         145 :                 if (res->type->radix == 10 && digits > 38)
    2969         145 :                         digits = 38;
    2970         145 :                 if (res->type->radix == 2 && digits > 128)
    2971         145 :                         digits = 128;
    2972             : #else
    2973             :                 if (res->type->radix == 10 && digits > 18)
    2974             :                         digits = 18;
    2975             :                 if (res->type->radix == 2 && digits > 64)
    2976             :                         digits = 64;
    2977             : #endif
    2978             : 
    2979         145 :                 sql_find_subtype(&nlt, lt->type->base.name, digL, scaleL);
    2980         145 :                 if (nlt.digits < scaleL)
    2981           2 :                         return sql_error(sql, 01, SQLSTATE(42000) "Scale (%d) overflows type", scaleL);
    2982         143 :                 l = exp_check_type(sql, &nlt, rel, l, type_equal);
    2983             : 
    2984         143 :                 sql_find_subtype(res, lt->type->base.name, digits, scale);
    2985             :         }
    2986             :         return l;
    2987             : }
    2988             : 
    2989             : void
    2990       24976 : exp_sum_scales(sql_subfunc *f, sql_exp *l, sql_exp *r)
    2991             : {
    2992       24976 :         sql_arg *ares = f->func->res->h->data;
    2993             : 
    2994       24976 :         if (ares->type.type->scale == SCALE_FIX && strcmp(sql_func_imp(f->func), "*") == 0) {
    2995       23750 :                 sql_subtype t;
    2996       23750 :                 sql_subtype *lt = exp_subtype(l);
    2997       23750 :                 sql_subtype *rt = exp_subtype(r);
    2998       23750 :                 sql_subtype *res = f->res->h->data;
    2999             : 
    3000       23750 :                 res->scale = lt->scale + rt->scale;
    3001       23750 :                 res->digits = lt->digits + rt->digits;
    3002             : 
    3003             :                 /* HACK alert: digits should be less than max */
    3004             : #ifdef HAVE_HGE
    3005       23750 :                 if (ares->type.type->radix == 10 && res->digits > 38) {
    3006        2456 :                         res->digits = 38;
    3007        2456 :                         res->scale = MIN(res->scale, res->digits - 1);
    3008             :                 }
    3009       23750 :                 if (ares->type.type->radix == 2 && res->digits > 128) {
    3010          79 :                         res->digits = 128;
    3011          79 :                         res->scale = MIN(res->scale, res->digits - 1);
    3012             :                 }
    3013             : #else
    3014             :                 if (ares->type.type->radix == 10 && res->digits > 18) {
    3015             :                         res->digits = 18;
    3016             :                         res->scale = MIN(res->scale, res->digits - 1);
    3017             :                 }
    3018             :                 if (ares->type.type->radix == 2 && res->digits > 64) {
    3019             :                         res->digits = 64;
    3020             :                         res->scale = MIN(res->scale, res->digits - 1);
    3021             :                 }
    3022             : #endif
    3023             : 
    3024             :                 /* numeric types are fixed length */
    3025       23750 :                 if (ares->type.type->eclass == EC_NUM) {
    3026             : #ifdef HAVE_HGE
    3027       21036 :                         if (ares->type.type->localtype == TYPE_hge && res->digits == 128)
    3028          79 :                                 t = *sql_bind_localtype("hge");
    3029             :                         else
    3030             : #endif
    3031       20957 :                         if (ares->type.type->localtype == TYPE_lng && res->digits == 64)
    3032           0 :                                 t = *sql_bind_localtype("lng");
    3033             :                         else
    3034       20957 :                                 sql_find_numeric(&t, ares->type.type->localtype, res->digits);
    3035             :                 } else {
    3036        2714 :                         sql_find_subtype(&t, ares->type.type->base.name, res->digits, res->scale);
    3037             :                 }
    3038       23750 :                 *res = t;
    3039             :         }
    3040       24976 : }
    3041             : 
    3042             : int
    3043      135008 : exp_aggr_is_count(sql_exp *e)
    3044             : {
    3045      135008 :         if (e->type == e_aggr && !((sql_subfunc *)e->f)->func->s && strcmp(((sql_subfunc *)e->f)->func->base.name, "count") == 0)
    3046       36541 :                 return 1;
    3047             :         return 0;
    3048             : }
    3049             : 
    3050             : list *
    3051       64447 : check_distinct_exp_names(mvc *sql, list *exps)
    3052             : {
    3053       64447 :         list *distinct_exps = NULL;
    3054       64447 :         bool duplicates = false;
    3055             : 
    3056       64447 :         if (list_length(exps) < 2) {
    3057             :                 return exps; /* always true */
    3058       62768 :         } else if (list_length(exps) < 5) {
    3059       13634 :                 distinct_exps = list_distinct(exps, (fcmp) exp_equal, (fdup) NULL);
    3060             :         } else { /* for longer lists, use hashing */
    3061       49135 :                 sql_hash *ht = hash_new(sql->ta, list_length(exps), (fkeyvalue)&exp_key);
    3062             : 
    3063      480322 :                 for (node *n = exps->h; n && !duplicates; n = n->next) {
    3064      431189 :                         sql_exp *e = n->data;
    3065      431189 :                         int key = ht->key(e);
    3066      431189 :                         sql_hash_e *he = ht->buckets[key&(ht->size-1)];
    3067             : 
    3068      554939 :                         for (; he && !duplicates; he = he->chain) {
    3069      123748 :                                 sql_exp *f = he->value;
    3070             : 
    3071      123748 :                                 if (!exp_equal(e, f))
    3072           1 :                                         duplicates = true;
    3073             :                         }
    3074      431191 :                         hash_add(ht, key, e);
    3075             :                 }
    3076             :         }
    3077       62767 :         if ((distinct_exps && list_length(distinct_exps) != list_length(exps)) || duplicates)
    3078           5 :                 return NULL;
    3079             :         return exps;
    3080             : }
    3081             : 
    3082             : static int rel_find_parameter(mvc *sql, sql_subtype *type, sql_rel *rel, const char *relname, const char *expname);
    3083             : 
    3084             : static int
    3085        1633 : set_exp_type(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *e)
    3086             : {
    3087        1639 :         if (mvc_highwater(sql)) {
    3088           0 :                 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3089           0 :                 return -1;
    3090             :         }
    3091        1639 :         if (e->type == e_column) {
    3092          60 :                 const char *nrname = (const char*) e->l, *nename = (const char*) e->r;
    3093             :                 /* find all the column references and set the type */
    3094          60 :                 e->tpe = *type;
    3095          60 :                 return rel_find_parameter(sql, type, rel, nrname, nename);
    3096        1579 :         } else if (e->type == e_atom && e->f) {
    3097          25 :                 list *atoms = e->f;
    3098          25 :                 if (!list_empty(atoms))
    3099          61 :                         for (node *n = atoms->h; n; n = n->next)
    3100          36 :                                 if (set_exp_type(sql, type, rel, n->data) < 0) /* set recursively */
    3101             :                                         return -1;
    3102          25 :                 e->tpe = *type;
    3103          25 :                 return 1; /* on a list of atoms, everything should be found */
    3104        1554 :         } else if (e->type == e_atom && !e->l && !e->r && !e->f) {
    3105        1548 :                 e->tpe = *type;
    3106        1548 :                 return set_type_param(sql, type, e->flag) == 0 ? 1 : 0;
    3107           6 :         } else if (exp_is_rel(e)) { /* for relation expressions, restart cycle */
    3108           6 :                 rel = (sql_rel*) e->l;
    3109             :                 /* limiting to these cases */
    3110           6 :                 if (!is_project(rel->op) || list_length(rel->exps) != 1)
    3111           0 :                         return 0;
    3112           6 :                 sql_exp *re = rel->exps->h->data;
    3113             : 
    3114           6 :                 e->tpe = *type;
    3115           6 :                 return set_exp_type(sql, type, rel, re); /* set recursively */
    3116             :         }
    3117             :         return 0;
    3118             : }
    3119             : 
    3120             : int
    3121        1541 : rel_set_type_param(mvc *sql, sql_subtype *type, sql_rel *rel, sql_exp *exp, int upcast)
    3122             : {
    3123        1541 :         if (!type || !exp || (exp->type != e_atom && exp->type != e_column && !exp_is_rel(exp)))
    3124           0 :                 return -1;
    3125             : 
    3126             :         /* use largest numeric types */
    3127        1541 :         if (upcast && type->type->eclass == EC_NUM)
    3128             : #ifdef HAVE_HGE
    3129           5 :                 type = sql_bind_localtype("hge");
    3130             : #else
    3131             :                 type = sql_bind_localtype("lng");
    3132             : #endif
    3133           9 :         else if (upcast && type->type->eclass == EC_FLT)
    3134           0 :                 type = sql_bind_localtype("dbl");
    3135             : 
    3136             :         /* TODO we could use the sql_query* struct to set paremeters used as freevars,
    3137             :            but it requires to change a lot of interfaces */
    3138             :         /* if (is_freevar(exp))
    3139             :                 rel = query_fetch_outer(query, is_freevar(exp)-1); */
    3140        1541 :         return set_exp_type(sql, type, rel, exp);
    3141             : }
    3142             : 
    3143             : /* try to do an in-place conversion
    3144             :  *
    3145             :  * in-place conversion is only possible if the exp is a variable.
    3146             :  * This is only done to be able to map more cached queries onto the same
    3147             :  * interface.
    3148             :  */
    3149             : sql_exp *
    3150     4346045 : exp_convert_inplace(mvc *sql, sql_subtype *t, sql_exp *exp)
    3151             : {
    3152     4346045 :         atom *a, *na;
    3153             : 
    3154             :         /* exclude named variables and variable lists */
    3155     4346045 :         if (exp->type != e_atom || exp->r /* named */ || exp->f /* list */ || !exp->l /* not direct atom */)
    3156             :                 return NULL;
    3157             : 
    3158     2725878 :         a = exp->l;
    3159     2725878 :         if (!a->isnull && t->scale && t->type->eclass != EC_FLT)
    3160             :                 return NULL;
    3161             : 
    3162     2721211 :         if ((na = atom_cast(sql->sa, a, t))) {
    3163     2717412 :                 exp->l = na;
    3164     2717412 :                 return exp;
    3165             :         }
    3166             :         return NULL;
    3167             : }
    3168             : 
    3169             : sql_exp *
    3170          72 : exp_numeric_supertype(mvc *sql, sql_exp *e )
    3171             : {
    3172          72 :         sql_subtype *tp = exp_subtype(e);
    3173             : 
    3174          72 :         if (tp->type->eclass == EC_DEC) {
    3175          21 :                 sql_subtype *dtp = sql_bind_localtype("dbl");
    3176             : 
    3177          21 :                 return exp_check_type(sql, dtp, NULL, e, type_cast);
    3178             :         }
    3179          51 :         if (tp->type->eclass == EC_NUM) {
    3180             : #ifdef HAVE_HGE
    3181          38 :                 sql_subtype *ltp = sql_bind_localtype("hge");
    3182             : #else
    3183             :                 sql_subtype *ltp = sql_bind_localtype("lng");
    3184             : #endif
    3185             : 
    3186          38 :                 return exp_check_type(sql, ltp, NULL, e, type_cast);
    3187             :         }
    3188             :         return e;
    3189             : }
    3190             : 
    3191             : sql_exp *
    3192     4345962 : exp_check_type(mvc *sql, sql_subtype *t, sql_rel *rel, sql_exp *exp, check_type tpe)
    3193             : {
    3194     4345962 :         int c, err = 0;
    3195     4345962 :         sql_exp* nexp = NULL;
    3196     4345962 :         sql_subtype *fromtype = exp_subtype(exp);
    3197             : 
    3198     4345900 :         if ((!fromtype || !fromtype->type) && rel_set_type_param(sql, t, rel, exp, 0) == 0)
    3199             :                 return exp;
    3200             : 
    3201             :         /* first try cheap internal (in-place) conversions ! */
    3202     4345896 :         if ((nexp = exp_convert_inplace(sql, t, exp)) != NULL)
    3203             :                 return nexp;
    3204             : 
    3205     1628654 :         if (fromtype && subtype_cmp(t, fromtype) != 0) {
    3206      512094 :                 if (EC_INTERVAL(fromtype->type->eclass) && (t->type->eclass == EC_NUM || t->type->eclass == EC_POS) && t->digits < fromtype->digits) {
    3207             :                         err = 1; /* conversion from interval to num depends on the number of digits */
    3208             :                 } else {
    3209      512092 :                         c = sql_type_convert(fromtype->type->eclass, t->type->eclass);
    3210      512092 :                         if (!c || (c == 2 && tpe == type_set) || (c == 3 && tpe != type_cast)) {
    3211             :                                 err = 1;
    3212             :                         } else {
    3213      511197 :                                 exp = exp_convert(sql->sa, exp, fromtype, t);
    3214             :                         }
    3215             :                 }
    3216             :         }
    3217      511197 :         if (err) {
    3218         897 :                 const char *name = (exp->type == e_column && !has_label(exp)) ? exp_name(exp) : "%";
    3219        1158 :                 sql_exp *res = sql_error( sql, 03, SQLSTATE(42000) "types %s(%u,%u) and %s(%u,%u) are not equal%s%s%s",
    3220         897 :                         fromtype->type->base.name,
    3221             :                         fromtype->digits,
    3222             :                         fromtype->scale,
    3223         897 :                         t->type->base.name,
    3224             :                         t->digits,
    3225             :                         t->scale,
    3226             :                         (name[0] != '%' ? " for column '" : ""),
    3227             :                         (name[0] != '%' ? name : ""),
    3228         897 :                         (name[0] != '%' ? "'" : "")
    3229             :                 );
    3230         897 :                 return res;
    3231             :         }
    3232             :         return exp;
    3233             : }
    3234             : 
    3235             : sql_exp *
    3236        6435 : exp_values_set_supertype(mvc *sql, sql_exp *values, sql_subtype *opt_super)
    3237             : {
    3238        6435 :         assert(is_values(values));
    3239        6435 :         list *vals = exp_get_values(values), *nexps;
    3240        6435 :         sql_subtype *tpe = opt_super?opt_super:exp_subtype(vals->h->data);
    3241             : 
    3242        6435 :         if (!opt_super && tpe)
    3243        6341 :                 values->tpe = *tpe;
    3244             : 
    3245       28549 :         for (node *m = vals->h; m; m = m->next) {
    3246       22114 :                 sql_exp *e = m->data;
    3247       22114 :                 sql_subtype super, *ttpe;
    3248             : 
    3249             :                 /* if the expression is a parameter set its type */
    3250       22114 :                 if (tpe && e->type == e_atom && !e->l && !e->r && !e->f && !e->tpe.type) {
    3251           4 :                         if (set_type_param(sql, tpe, e->flag) == 0)
    3252           4 :                                 e->tpe = *tpe;
    3253             :                         else
    3254           0 :                                 return NULL;
    3255             :                 }
    3256       22114 :                 ttpe = exp_subtype(e);
    3257       22114 :                 if (tpe && ttpe) {
    3258       22061 :                         supertype(&super, ttpe, tpe);
    3259       22061 :                         values->tpe = super;
    3260       22061 :                         tpe = &values->tpe;
    3261             :                 } else {
    3262             :                         tpe = ttpe;
    3263             :                 }
    3264             :         }
    3265             : 
    3266        6435 :         if (tpe) {
    3267             :                 /* if the expression is a parameter set its type */
    3268       28462 :                 for (node *m = vals->h; m; m = m->next) {
    3269       22065 :                         sql_exp *e = m->data;
    3270       22065 :                         if (e->type == e_atom && !e->l && !e->r && !e->f && !e->tpe.type) {
    3271           1 :                                 if (set_type_param(sql, tpe, e->flag) == 0)
    3272           1 :                                         e->tpe = *tpe;
    3273             :                                 else
    3274             :                                         return NULL;
    3275             :                         }
    3276             :                 }
    3277        6397 :                 values->tpe = *tpe;
    3278        6397 :                 nexps = sa_list(sql->sa);
    3279       28457 :                 for (node *m = vals->h; m; m = m->next) {
    3280       22063 :                         sql_exp *e = m->data;
    3281       22063 :                         e = exp_check_type(sql, &values->tpe, NULL, e, type_equal);
    3282       22063 :                         if (!e)
    3283             :                                 return NULL;
    3284       22060 :                         exp_label(sql->sa, e, ++sql->label);
    3285       22060 :                         append(nexps, e);
    3286             :                 }
    3287        6394 :                 values->f = nexps;
    3288             :         }
    3289             :         return values;
    3290             : }
    3291             : 
    3292             : /* return -1 on error, 0 not found, 1 found */
    3293             : static int
    3294          86 : rel_find_parameter(mvc *sql, sql_subtype *type, sql_rel *rel, const char *relname, const char *expname)
    3295             : {
    3296         138 :         int res = 0;
    3297             : 
    3298         138 :         if (mvc_highwater(sql)) {
    3299           0 :                 (void) sql_error(sql, 10, SQLSTATE(42000) "Query too complex: running out of stack space");
    3300           0 :                 return -1;
    3301             :         }
    3302         138 :         if (!rel)
    3303             :                 return 0;
    3304             : 
    3305         135 :         const char *nrname = relname, *nename = expname;
    3306         135 :         if (is_project(rel->op) && !list_empty(rel->exps)) {
    3307         111 :                 sql_exp *e = NULL;
    3308             : 
    3309         111 :                 if (nrname && nename) { /* find the column reference and propagate type setting */
    3310         111 :                         e = exps_bind_column2(rel->exps, nrname, nename, NULL);
    3311           0 :                 } else if (nename) {
    3312           0 :                         e = exps_bind_column(rel->exps, nename, NULL, NULL, 1);
    3313             :                 }
    3314         111 :                 if (!e)
    3315           3 :                         return 0; /* not found */
    3316         108 :                 if (is_set(rel->op)) { /* TODO for set relations this needs further improvement */
    3317           0 :                         (void) sql_error(sql, 10, SQLSTATE(42000) "Cannot set parameter types under set relations at the moment");
    3318           0 :                         return -1;
    3319             :                 }
    3320             :                 /* set order by column types */
    3321         108 :                 if (is_simple_project(rel->op) && !list_empty(rel->r)) {
    3322           0 :                         sql_exp *ordere = NULL;
    3323           0 :                         if (nrname && nename) {
    3324           0 :                                 ordere = exps_bind_column2(rel->r, nrname, nename, NULL);
    3325           0 :                         } else if (nename) {
    3326           0 :                                 ordere = exps_bind_column(rel->r, nename, NULL, NULL, 1);
    3327             :                         }
    3328           0 :                         if (ordere && ordere->type == e_column)
    3329           0 :                                 ordere->tpe = *type;
    3330             :                 }
    3331         108 :                 if (e->type == e_column) {
    3332          52 :                         nrname = (const char*) e->l;
    3333          52 :                         nename = (const char*) e->r;
    3334          52 :                         e->tpe = *type;
    3335          52 :                         res = 1; /* found */
    3336          56 :                 } else if ((e->type == e_atom || exp_is_rel(e)) && (res = set_exp_type(sql, type, rel, e)) <= 0) {
    3337             :                         return res; /* don't search further */
    3338             :                 }
    3339             :                 /* group by columns can have aliases! */
    3340         108 :                 if (is_groupby(rel->op) && !list_empty(rel->r)) {
    3341           0 :                         if (nrname && nename) {
    3342           0 :                                 e = exps_bind_column2(rel->r, nrname, nename, NULL);
    3343           0 :                         } else if (nename) {
    3344           0 :                                 e = exps_bind_column(rel->r, nename, NULL, NULL, 1);
    3345             :                         }
    3346           0 :                         if (!e)
    3347             :                                 return res; /* don't search further */
    3348           0 :                         if (e->type == e_column) {
    3349           0 :                                 nrname = (const char*) e->l;
    3350           0 :                                 nename = (const char*) e->r;
    3351           0 :                                 e->tpe = *type;
    3352           0 :                         } else if ((e->type == e_atom || exp_is_rel(e)) && (res = set_exp_type(sql, type, rel, e)) <= 0) {
    3353             :                                 return res; /* don't search further */
    3354             :                         }
    3355             :                 }
    3356         108 :                 if (e->type != e_column)
    3357             :                         return res; /* don't search further */
    3358             :         }
    3359             : 
    3360          76 :         switch (rel->op) {
    3361          14 :                 case op_join:
    3362             :                 case op_left:
    3363             :                 case op_right:
    3364             :                 case op_full:
    3365          14 :                         if (rel->l)
    3366          14 :                                 res = rel_find_parameter(sql, type, rel->l, nrname, nename);
    3367          14 :                         if (rel->r && res <= 0) { /* try other relation if not found */
    3368          12 :                                 int err = sql->session->status, lres = res;
    3369          12 :                                 char buf[ERRSIZE];
    3370             : 
    3371          12 :                                 strcpy(buf, sql->errstr); /* keep error found and try other join relation */
    3372          12 :                                 sql->session->status = 0;
    3373          12 :                                 sql->errstr[0] = '\0';
    3374          12 :                                 res = rel_find_parameter(sql, type, rel->r, nrname, nename);
    3375          12 :                                 if (res == 0) { /* parameter wasn't found, set error */
    3376           1 :                                         res = lres;
    3377           1 :                                         sql->session->status = err;
    3378           1 :                                         strcpy(sql->errstr, buf);
    3379             :                                 }
    3380             :                         }
    3381             :                         break;
    3382          52 :                 case op_semi:
    3383             :                 case op_anti:
    3384             :                 case op_groupby:
    3385             :                 case op_project:
    3386             :                 case op_select:
    3387             :                 case op_topn:
    3388             :                 case op_sample:
    3389          52 :                         if (rel->l)
    3390             :                                 res = rel_find_parameter(sql, type, rel->l, nrname, nename);
    3391             :                         break;
    3392           0 :                 case op_union: /* TODO for set relations this needs further improvement */
    3393             :                 case op_inter:
    3394             :                 case op_except: {
    3395           0 :                         (void) sql_error(sql, 10, SQLSTATE(42000) "Cannot set parameter types under set relations at the moment");
    3396           0 :                         return -1;
    3397             :                 }
    3398             :                 default: /* For table returning functions, the type must be set when the relation is created */
    3399             :                         return 0;
    3400             :         }
    3401             :         return res;
    3402             : }
    3403             : 
    3404             : sql_exp *
    3405       18515 : list_find_exp( list *exps, sql_exp *e)
    3406             : {
    3407       18515 :         sql_exp *ne = NULL;
    3408             : 
    3409       18515 :         if (e->type != e_column)
    3410             :                 return NULL;
    3411       18471 :         if (( e->l && (ne=exps_bind_column2(exps, e->l, e->r, NULL)) != NULL) ||
    3412       17926 :            ((!e->l && (ne=exps_bind_column(exps, e->r, NULL, NULL, 1)) != NULL)))
    3413         635 :                 return ne;
    3414             :         return NULL;
    3415             : }

Generated by: LCOV version 1.14