LCOV - code coverage report
Current view: top level - sql/backends/monet5 - sql_statement.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2191 2432 90.1 %
Date: 2021-10-13 02:24:04 Functions: 94 97 96.9 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : #include "monetdb_config.h"
      10             : #include "sql_mem.h"
      11             : #include "sql_stack.h"
      12             : #include "sql_statement.h"
      13             : #include "sql_gencode.h"
      14             : #include "rel_rel.h"
      15             : #include "rel_exp.h"
      16             : #include "rel_prop.h"
      17             : #include "rel_unnest.h"
      18             : #include "rel_optimizer.h"
      19             : 
      20             : #include "mal_namespace.h"
      21             : #include "mal_builder.h"
      22             : #include "mal_debugger.h"
      23             : #include "opt_prelude.h"
      24             : 
      25             : /*
      26             :  * Some utility routines to generate code
      27             :  * The equality operator in MAL is '==' instead of '='.
      28             :  */
      29             : static const char *
      30             : convertMultiplexMod(const char *mod, const char *op)
      31             : {
      32       12712 :         if (strcmp(op, "=") == 0)
      33           0 :                 return "calc";
      34             :         return mod;
      35             : }
      36             : 
      37             : static const char *
      38             : convertMultiplexFcn(const char *op)
      39             : {
      40       12712 :         if (strcmp(op, "=") == 0)
      41       19632 :                 return "==";
      42             :         return op;
      43             : }
      44             : 
      45             : static const char *
      46             : convertOperator(const char *op)
      47             : {
      48       80616 :         if (strcmp(op, "=") == 0)
      49        6550 :                 return "==";
      50             :         return op;
      51             : }
      52             : 
      53             : static InstrPtr
      54       12666 : multiplex2(MalBlkPtr mb, const char *mod, const char *name, int o1, int o2, int rtype)
      55             : {
      56             :         InstrPtr q = NULL;
      57             : 
      58       12666 :         q = newStmt(mb, malRef, multiplexRef);
      59       12666 :         if (q == NULL)
      60             :                 return NULL;
      61       12666 :         setVarType(mb, getArg(q, 0), newBatType(rtype));
      62       12666 :         q = pushStr(mb, q, convertMultiplexMod(mod, name));
      63       12666 :         q = pushStr(mb, q, convertMultiplexFcn(name));
      64       12666 :         q = pushArgument(mb, q, o1);
      65       12666 :         q = pushArgument(mb, q, o2);
      66       12666 :         return q;
      67             : }
      68             : 
      69             : static InstrPtr
      70       59112 : dump_1(MalBlkPtr mb, const char *mod, const char *name, stmt *o1)
      71             : {
      72             :         InstrPtr q = NULL;
      73             : 
      74       59112 :         if (o1->nr < 0)
      75             :                 return NULL;
      76       59112 :         q = newStmt(mb, mod, name);
      77       59112 :         q = pushArgument(mb, q, o1->nr);
      78       59112 :         return q;
      79             : }
      80             : 
      81             : static InstrPtr
      82      170924 : dump_2(MalBlkPtr mb, const char *mod, const char *name, stmt *o1, stmt *o2)
      83             : {
      84             :         InstrPtr q = NULL;
      85             : 
      86      170924 :         if (o1->nr < 0 || o2->nr < 0)
      87             :                 return NULL;
      88      170924 :         q = newStmt(mb, mod, name);
      89      170924 :         q = pushArgument(mb, q, o1->nr);
      90      170924 :         q = pushArgument(mb, q, o2->nr);
      91      170924 :         return q;
      92             : }
      93             : 
      94             : static InstrPtr
      95         240 : pushPtr(MalBlkPtr mb, InstrPtr q, ptr val)
      96             : {
      97             :         int _t;
      98             :         ValRecord cst;
      99             : 
     100         240 :         if (q == NULL)
     101             :                 return NULL;
     102         240 :         cst.vtype= TYPE_ptr;
     103         240 :         cst.val.pval = val;
     104         240 :         cst.len = 0;
     105         240 :         _t = defConstant(mb, TYPE_ptr, &cst);
     106         240 :         if( _t >= 0)
     107         240 :                 return pushArgument(mb, q, _t);
     108             :         return q;
     109             : }
     110             : 
     111             : static InstrPtr
     112     1766998 : pushSchema(MalBlkPtr mb, InstrPtr q, sql_table *t)
     113             : {
     114     1766998 :         if (t->s)
     115     1766998 :                 return pushArgument(mb, q, getStrConstant(mb,t->s->base.name));
     116             :         else
     117           0 :                 return pushNil(mb, q, TYPE_str);
     118             : }
     119             : 
     120             : int
     121       19461 : stmt_key(stmt *s)
     122             : {
     123       19461 :         const char *nme = column_name(NULL, s);
     124             : 
     125       19461 :         return hash_key(nme);
     126             : }
     127             : 
     128             : /* #TODO make proper traversal operations */
     129             : stmt *
     130         128 : stmt_atom_string(backend *be, const char *S)
     131             : {
     132         128 :         const char *s = sa_strdup(be->mvc->sa, S);
     133             :         sql_subtype t;
     134             : 
     135         128 :         sql_find_subtype(&t, "varchar", _strlen(s), 0);
     136         128 :         return stmt_atom(be, atom_string(be->mvc->sa, &t, s));
     137             : }
     138             : 
     139             : stmt *
     140       10492 : stmt_atom_string_nil(backend *be)
     141             : {
     142             :         sql_subtype t;
     143             : 
     144       10492 :         sql_find_subtype(&t, "clob", 0, 0);
     145       10492 :         return stmt_atom(be, atom_string(be->mvc->sa, &t, NULL));
     146             : }
     147             : 
     148             : stmt *
     149        6751 : stmt_atom_int(backend *be, int i)
     150             : {
     151             :         sql_subtype t;
     152             : 
     153        6751 :         sql_find_subtype(&t, "int", 32, 0);
     154        6751 :         return stmt_atom(be, atom_int(be->mvc->sa, &t, i));
     155             : }
     156             : 
     157             : stmt *
     158       82672 : stmt_atom_lng(backend *be, lng i)
     159             : {
     160             :         sql_subtype t;
     161             : 
     162       82672 :         sql_find_subtype(&t, "bigint", 64, 0);
     163       82672 :         return stmt_atom(be, atom_int(be->mvc->sa, &t, i));
     164             : }
     165             : 
     166             : stmt *
     167          13 : stmt_atom_lng_nil(backend *be)
     168             : {
     169             :         sql_subtype t;
     170             : 
     171          13 :         sql_find_subtype(&t, "bigint", 64, 0);
     172          13 :         return stmt_atom(be, atom_general(be->mvc->sa, &t, NULL));
     173             : }
     174             : 
     175             : stmt *
     176       35421 : stmt_bool(backend *be, int b)
     177             : {
     178             :         sql_subtype t;
     179             : 
     180       35421 :         sql_find_subtype(&t, "boolean", 0, 0);
     181       35421 :         if (b) {
     182       35421 :                 return stmt_atom(be, atom_bool(be->mvc->sa, &t, TRUE));
     183             :         } else {
     184           0 :                 return stmt_atom(be, atom_bool(be->mvc->sa, &t, FALSE));
     185             :         }
     186             : }
     187             : 
     188             : static stmt *
     189    13310800 : stmt_create(sql_allocator *sa, st_type type)
     190             : {
     191    13310800 :         stmt *s = SA_NEW(sa, stmt);
     192             : 
     193    13310801 :         if (!s)
     194             :                 return NULL;
     195    13310801 :         *s = (stmt) {
     196             :                 .type = type,
     197             :         };
     198    13310801 :         return s;
     199             : }
     200             : 
     201             : stmt *
     202       32874 : stmt_group(backend *be, stmt *s, stmt *grp, stmt *ext, stmt *cnt, int done)
     203             : {
     204       32874 :         MalBlkPtr mb = be->mb;
     205             :         InstrPtr q = NULL;
     206             : 
     207       32874 :         if (s->nr < 0)
     208             :                 return NULL;
     209       32874 :         if (grp && (grp->nr < 0 || ext->nr < 0 || cnt->nr < 0))
     210             :                 return NULL;
     211             : 
     212       32874 :         q = newStmt(mb, groupRef, done ? grp ? subgroupdoneRef : groupdoneRef : grp ? subgroupRef : groupRef);
     213       32874 :         if(!q)
     214             :                 return NULL;
     215             : 
     216             :         /* output variables extent and hist */
     217       32874 :         q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
     218       32874 :         q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
     219       32874 :         q = pushArgument(mb, q, s->nr);
     220       32874 :         if (grp)
     221        9919 :                 q = pushArgument(mb, q, grp->nr);
     222       32874 :         if (q) {
     223       32874 :                 stmt *ns = stmt_create(be->mvc->sa, st_group);
     224       32874 :                 if (ns == NULL) {
     225           0 :                         freeInstruction(q);
     226           0 :                         return NULL;
     227             :                 }
     228             : 
     229       32874 :                 ns->op1 = s;
     230             : 
     231       32874 :                 if (grp) {
     232        9919 :                         ns->op2 = grp;
     233        9919 :                         ns->op3 = ext;
     234        9919 :                         ns->op4.stval = cnt;
     235             :                 }
     236       32874 :                 ns->nrcols = s->nrcols;
     237       32874 :                 ns->key = 0;
     238       32874 :                 ns->q = q;
     239       32874 :                 ns->nr = getDestVar(q);
     240       32874 :                 return ns;
     241             :         }
     242             :         return NULL;
     243             : }
     244             : 
     245             : stmt *
     246          65 : stmt_unique(backend *be, stmt *s)
     247             : {
     248          65 :         MalBlkPtr mb = be->mb;
     249             :         InstrPtr q = NULL;
     250             : 
     251          65 :         if (s->nr < 0)
     252             :                 return NULL;
     253             : 
     254          65 :         q = newStmt(mb, algebraRef, uniqueRef);
     255          65 :         if(!q)
     256             :                 return NULL;
     257             : 
     258          65 :         q = pushArgument(mb, q, s->nr);
     259          65 :         q = pushNil(mb, q, TYPE_bat); /* candidate list */
     260          65 :         if (q) {
     261          65 :                 stmt *ns = stmt_create(be->mvc->sa, st_unique);
     262          65 :                 if (ns == NULL) {
     263           0 :                         freeInstruction(q);
     264           0 :                         return NULL;
     265             :                 }
     266             : 
     267          65 :                 ns->op1 = s;
     268          65 :                 ns->nrcols = s->nrcols;
     269          65 :                 ns->key = 1;
     270          65 :                 ns->q = q;
     271          65 :                 ns->nr = getDestVar(q);
     272          65 :                 return ns;
     273             :         }
     274             :         return NULL;
     275             : }
     276             : 
     277             : stmt *
     278           0 : stmt_none(backend *be)
     279             : {
     280           0 :         return stmt_create(be->mvc->sa, st_none);
     281             : }
     282             : 
     283             : static int
     284          55 : create_bat(MalBlkPtr mb, int tt)
     285             : {
     286          55 :         InstrPtr q = newStmt(mb, batRef, newRef);
     287             : 
     288          55 :         if (q == NULL)
     289             :                 return -1;
     290          55 :         setVarType(mb, getArg(q, 0), newBatType(tt));
     291          55 :         q = pushType(mb, q, tt);
     292          55 :         return getDestVar(q);
     293             : }
     294             : 
     295             : static int *
     296          20 : dump_table(sql_allocator *sa, MalBlkPtr mb, sql_table *t)
     297             : {
     298             :         int i = 0;
     299             :         node *n;
     300          20 :         int *l = SA_NEW_ARRAY(sa, int, ol_length(t->columns) + 1);
     301             : 
     302          20 :         if (!l)
     303             :                 return NULL;
     304             : 
     305             :         /* tid column */
     306          20 :         if ((l[i++] = create_bat(mb, TYPE_oid)) < 0)
     307             :                 return NULL;
     308             : 
     309          55 :         for (n = ol_first_node(t->columns); n; n = n->next) {
     310          35 :                 sql_column *c = n->data;
     311             : 
     312          35 :                 if ((l[i++] = create_bat(mb, c->type.type->localtype)) < 0)
     313             :                         return NULL;
     314             :         }
     315             :         return l;
     316             : }
     317             : 
     318             : stmt *
     319        3144 : stmt_var(backend *be, const char *sname, const char *varname, sql_subtype *t, int declare, int level)
     320             : {
     321        3144 :         MalBlkPtr mb = be->mb;
     322             :         InstrPtr q = NULL;
     323             :         char *buf;
     324             : 
     325        3144 :         if (level == 0) { /* global */
     326         922 :                 int tt = t->type->localtype;
     327             : 
     328         922 :                 assert(sname);
     329         922 :                 q = newStmt(mb, sqlRef, getVariableRef);
     330         922 :                 q = pushArgument(mb, q, be->mvc_var);
     331         922 :                 q = pushStr(mb, q, sname); /* all global variables have a schema */
     332         922 :                 q = pushStr(mb, q, varname);
     333         922 :                 if (q == NULL)
     334             :                         return NULL;
     335         922 :                 setVarType(mb, getArg(q, 0), tt);
     336        2222 :         } else if (!declare) {
     337             :                 char levelstr[16];
     338             : 
     339        1767 :                 assert(!sname);
     340        1767 :                 snprintf(levelstr, sizeof(levelstr), "%d", level);
     341        1767 :                 buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
     342        1767 :                 if (!buf)
     343           0 :                         return NULL;
     344        1767 :                 stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
     345        1767 :                 q = newAssignment(mb);
     346        1767 :                 q = pushArgumentId(mb, q, buf);
     347             :         } else {
     348         455 :                 int tt = t->type->localtype;
     349             :                 char levelstr[16];
     350             : 
     351         455 :                 assert(!sname);
     352         455 :                 snprintf(levelstr, sizeof(levelstr), "%d", level);
     353         455 :                 buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
     354         455 :                 if (!buf)
     355           0 :                         return NULL;
     356         455 :                 stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
     357             : 
     358         455 :                 q = newInstruction(mb, NULL, NULL);
     359         455 :                 if (q == NULL) {
     360             :                         return NULL;
     361             :                 }
     362         455 :                 q->argc = q->retc = 0;
     363         455 :                 q = pushArgumentId(mb, q, buf);
     364         455 :                 q = pushNil(mb, q, tt);
     365         455 :                 pushInstruction(mb, q);
     366         455 :                 if (q == NULL)
     367             :                         return NULL;
     368         455 :                 q->retc++;
     369             :         }
     370        3144 :         if (q) {
     371        3144 :                 stmt *s = stmt_create(be->mvc->sa, st_var);
     372        3144 :                 if (s == NULL) {
     373           0 :                         freeInstruction(q);
     374           0 :                         return NULL;
     375             :                 }
     376             : 
     377        3144 :                 if (t)
     378        3144 :                         s->op4.typeval = *t;
     379             :                 else
     380           0 :                         s->op4.typeval.type = NULL;
     381        3144 :                 s->flag = declare + (level << 1);
     382        3144 :                 s->key = 1;
     383        3144 :                 s->q = q;
     384        3144 :                 s->nr = getDestVar(q);
     385        3144 :                 return s;
     386             :         }
     387             :         return NULL;
     388             : }
     389             : 
     390             : stmt *
     391          20 : stmt_vars(backend *be, const char *varname, sql_table *t, int declare, int level)
     392             : {
     393          20 :         MalBlkPtr mb = be->mb;
     394             :         InstrPtr q = NULL;
     395             :         int *l;
     396             : 
     397             :         (void)varname;
     398             :         /* declared table */
     399          20 :         if ((l = dump_table(be->mvc->sa, mb, t)) != NULL) {
     400          20 :                 stmt *s = stmt_create(be->mvc->sa, st_var);
     401             : 
     402          20 :                 if (s == NULL) {
     403           0 :                         freeInstruction(q);
     404           0 :                         return NULL;
     405             :                 }
     406             : 
     407          20 :                 ATOMIC_PTR_SET(&t->data, l);
     408             :                 /*
     409             :                 s->op2 = (stmt*)l;
     410             :                 s->op3 = (stmt*)t;
     411             :                 */
     412          20 :                 s->flag = declare + (level << 1);
     413          20 :                 s->key = 1;
     414          20 :                 s->nr = l[0];
     415          20 :                 return s;
     416             :         }
     417             :         return NULL;
     418             : }
     419             : 
     420             : stmt *
     421         523 : stmt_varnr(backend *be, int nr, sql_subtype *t)
     422             : {
     423         523 :         MalBlkPtr mb = be->mb;
     424         523 :         InstrPtr q = newAssignment(mb);
     425             :         char buf[IDLENGTH];
     426             : 
     427         523 :         if (!q)
     428             :                 return NULL;
     429             : 
     430         523 :         (void) snprintf(buf, sizeof(buf), "A%d", nr);
     431         523 :         q = pushArgumentId(mb, q, buf);
     432         523 :         if (q) {
     433         523 :                 stmt *s = stmt_create(be->mvc->sa, st_var);
     434         523 :                 if (s == NULL) {
     435           0 :                         freeInstruction(q);
     436           0 :                         return NULL;
     437             :                 }
     438             : 
     439         523 :                 s->op1 = NULL;
     440         523 :                 if (t)
     441         523 :                         s->op4.typeval = *t;
     442             :                 else
     443           0 :                         s->op4.typeval.type = NULL;
     444         523 :                 s->flag = nr;
     445         523 :                 s->key = 1;
     446         523 :                 s->q = q;
     447         523 :                 s->nr = getDestVar(q);
     448         523 :                 return s;
     449             :         }
     450             :         return NULL;
     451             : }
     452             : 
     453             : stmt *
     454         339 : stmt_table(backend *be, stmt *cols, int temp)
     455             : {
     456         339 :         stmt *s = stmt_create(be->mvc->sa, st_table);
     457         339 :         MalBlkPtr mb = be->mb;
     458             : 
     459         339 :         if (s == NULL || cols->nr < 0)
     460             :                 return NULL;
     461             : 
     462         339 :         if (cols->type != st_list) {
     463           0 :             InstrPtr q = newAssignment(mb);
     464           0 :                 q = newStmt(mb, sqlRef, printRef);
     465           0 :                 q = pushStr(mb, q, "not a valid output list\n");
     466           0 :                 if (q == NULL)
     467             :                         return NULL;
     468             :         }
     469         339 :         s->op1 = cols;
     470         339 :         s->flag = temp;
     471         339 :         s->nr = cols->nr;
     472         339 :         s->nrcols = cols->nrcols;
     473         339 :         return s;
     474             : }
     475             : 
     476             : stmt *
     477      273569 : stmt_temp(backend *be, sql_subtype *t)
     478             : {
     479      273569 :         int tt = t->type->localtype;
     480      273569 :         MalBlkPtr mb = be->mb;
     481      273569 :         InstrPtr q = newStmt(mb, batRef, newRef);
     482             : 
     483      273569 :         if (q == NULL)
     484             :                 return NULL;
     485      273569 :         setVarType(mb, getArg(q, 0), newBatType(tt));
     486      273569 :         q = pushType(mb, q, tt);
     487      273569 :         if (q) {
     488      273569 :                 stmt *s = stmt_create(be->mvc->sa, st_temp);
     489             : 
     490      273569 :                 if (s == NULL) {
     491           0 :                         freeInstruction(q);
     492           0 :                         return NULL;
     493             :                 }
     494      273569 :                 s->op4.typeval = *t;
     495      273569 :                 s->nrcols = 1;
     496      273569 :                 s->q = q;
     497      273569 :                 s->nr = getDestVar(q);
     498      273569 :                 return s;
     499             :         }
     500             :         return NULL;
     501             : }
     502             : 
     503             : stmt *
     504      176888 : stmt_tid(backend *be, sql_table *t, int partition)
     505             : {
     506             :         int tt = TYPE_oid;
     507      176888 :         MalBlkPtr mb = be->mb;
     508             :         InstrPtr q;
     509             : 
     510      176888 :         if (!t->s && ATOMIC_PTR_GET(&t->data)) { /* declared table */
     511          16 :                 stmt *s = stmt_create(be->mvc->sa, st_tid);
     512          16 :                 int *l = ATOMIC_PTR_GET(&t->data);
     513             : 
     514          16 :                 if (s == NULL) {
     515             :                         return NULL;
     516             :                 }
     517          16 :                 assert(partition == 0);
     518          16 :                 s->partition = partition;
     519          16 :                 s->op4.tval = t;
     520          16 :                 s->nrcols = 1;
     521          16 :                 s->nr = l[0];
     522          16 :                 return s;
     523             :         }
     524      176872 :         q = newStmt(mb, sqlRef, tidRef);
     525      176872 :         if (q == NULL)
     526             :                 return NULL;
     527      176872 :         setVarType(mb, getArg(q, 0), newBatType(tt));
     528      176872 :         q = pushArgument(mb, q, be->mvc_var);
     529      176872 :         q = pushSchema(mb, q, t);
     530      176872 :         q = pushStr(mb, q, t->base.name);
     531      176872 :         if (q == NULL)
     532             :                 return NULL;
     533      176872 :         if (t && isTable(t) && partition) {
     534       66653 :                 sql_trans *tr = be->mvc->session->tr;
     535       66653 :                 sqlstore *store = tr->store;
     536       66653 :                 BUN rows = (BUN) store->storage_api.count_col(tr, ol_first_node(t->columns)->data, QUICK);
     537       66653 :                 setRowCnt(mb,getArg(q,0),rows);
     538             :         }
     539             : 
     540      176872 :         stmt *s = stmt_create(be->mvc->sa, st_tid);
     541      176872 :         if (s == NULL) {
     542           0 :                 freeInstruction(q);
     543           0 :                 return NULL;
     544             :         }
     545             : 
     546      176872 :         s->partition = partition;
     547      176872 :         s->op4.tval = t;
     548      176872 :         s->nrcols = 1;
     549      176872 :         s->nr = getDestVar(q);
     550      176872 :         s->q = q;
     551      176872 :         return s;
     552             : }
     553             : 
     554             : stmt *
     555     1004730 : stmt_bat(backend *be, sql_column *c, int access, int partition)
     556             : {
     557     1004730 :         int tt = c->type.type->localtype;
     558     1004730 :         MalBlkPtr mb = be->mb;
     559             :         InstrPtr q;
     560             : 
     561             :         /* for read access tid.project(col) */
     562     1004730 :         if (!c->t->s && ATOMIC_PTR_GET(&c->t->data)) { /* declared table */
     563          23 :                 stmt *s = stmt_create(be->mvc->sa, st_bat);
     564          23 :                 int *l = ATOMIC_PTR_GET(&c->t->data);
     565             : 
     566          23 :                 if (s == NULL) {
     567             :                         return NULL;
     568             :                 }
     569          23 :                 assert(partition == 0);
     570          23 :                 s->partition = partition;
     571          23 :                 s->op4.cval = c;
     572          23 :                 s->nrcols = 1;
     573          23 :                 s->flag = access;
     574          23 :                 s->nr = l[c->colnr+1];
     575          23 :                 s->tname = c->t?c->t->base.name:NULL;
     576          23 :                 s->cname = c->base.name;
     577          23 :                 return s;
     578             :         }
     579     1004707 :         q = newStmtArgs(mb, sqlRef, bindRef, 9);
     580     1004707 :         if (q == NULL)
     581             :                 return NULL;
     582     1004707 :         if (access == RD_UPD_ID) {
     583      482554 :                 q = pushReturn(mb, q, newTmpVariable(mb, newBatType(tt)));
     584             :         } else {
     585      522153 :                 setVarType(mb, getArg(q, 0), newBatType(tt));
     586             :         }
     587     1004707 :         q = pushArgument(mb, q, be->mvc_var);
     588     1004707 :         q = pushSchema(mb, q, c->t);
     589     1004707 :         q = pushArgument(mb, q, getStrConstant(mb,c->t->base.name));
     590     1004707 :         q = pushArgument(mb, q, getStrConstant(mb,c->base.name));
     591     1004706 :         q = pushArgument(mb, q, getIntConstant(mb,access));
     592     1004705 :         if (q == NULL)
     593             :                 return NULL;
     594             : 
     595     1004705 :         if (access == RD_UPD_ID) {
     596      482553 :                 setVarType(mb, getArg(q, 1), newBatType(tt));
     597             :         }
     598     1004705 :         if (partition) {
     599      444145 :                 sql_trans *tr = be->mvc->session->tr;
     600      444145 :                 sqlstore *store = tr->store;
     601             : 
     602      444145 :                 if (c && isTable(c->t)) {
     603      444145 :                         BUN rows = (BUN) store->storage_api.count_col(tr, c, QUICK);
     604      444145 :                         setRowCnt(mb,getArg(q,0),rows);
     605             :                 }
     606             :         }
     607             : 
     608     1004705 :         stmt *s = stmt_create(be->mvc->sa, st_bat);
     609     1004706 :         if (s == NULL) {
     610           0 :                 freeInstruction(q);
     611           0 :                 return NULL;
     612             :         }
     613             : 
     614     1004706 :         s->partition = partition;
     615     1004706 :         s->op4.cval = c;
     616     1004706 :         s->nrcols = 1;
     617     1004706 :         s->flag = access;
     618     1004706 :         s->nr = getDestVar(q);
     619     1004706 :         s->q = q;
     620     1004706 :         s->tname = c->t->base.name;
     621     1004706 :         s->cname = c->base.name;
     622     1004706 :         return s;
     623             : }
     624             : 
     625             : stmt *
     626        6679 : stmt_idxbat(backend *be, sql_idx *i, int access, int partition)
     627             : {
     628        6679 :         int tt = hash_index(i->type)?TYPE_lng:TYPE_oid;
     629        6679 :         MalBlkPtr mb = be->mb;
     630        6679 :         InstrPtr q = newStmtArgs(mb, sqlRef, bindidxRef, 9);
     631             : 
     632        6679 :         if (q == NULL)
     633             :                 return NULL;
     634             : 
     635        6679 :         if (access == RD_UPD_ID) {
     636        2980 :                 q = pushReturn(mb, q, newTmpVariable(mb, newBatType(tt)));
     637             :         } else {
     638        3699 :                 setVarType(mb, getArg(q, 0), newBatType(tt));
     639             :         }
     640             : 
     641        6679 :         q = pushArgument(mb, q, be->mvc_var);
     642        6679 :         q = pushSchema(mb, q, i->t);
     643        6679 :         q = pushArgument(mb, q, getStrConstant(mb, i->t->base.name));
     644        6679 :         q = pushArgument(mb, q, getStrConstant(mb, i->base.name));
     645        6679 :         q = pushArgument(mb, q, getIntConstant(mb, access));
     646        6679 :         if (q == NULL)
     647             :                 return NULL;
     648             : 
     649        6679 :         if (access == RD_UPD_ID) {
     650        2980 :                 setVarType(mb, getArg(q, 1), newBatType(tt));
     651             :         }
     652        6679 :         if (partition) {
     653        3727 :                 sql_trans *tr = be->mvc->session->tr;
     654        3727 :                 sqlstore *store = tr->store;
     655             : 
     656        3727 :                 if (i && isTable(i->t)) {
     657        3727 :                         BUN rows = (BUN) store->storage_api.count_idx(tr, i, QUICK);
     658        3727 :                         setRowCnt(mb,getArg(q,0),rows);
     659             :                 }
     660             :         }
     661             : 
     662        6679 :         stmt *s = stmt_create(be->mvc->sa, st_idxbat);
     663        6679 :         if (s == NULL) {
     664           0 :                 freeInstruction(q);
     665           0 :                 return NULL;
     666             :         }
     667             : 
     668        6679 :         s->partition = partition;
     669        6679 :         s->op4.idxval = i;
     670        6679 :         s->nrcols = 1;
     671        6679 :         s->flag = access;
     672        6679 :         s->nr = getDestVar(q);
     673        6679 :         s->q = q;
     674        6679 :         s->tname = i->t->base.name;
     675        6679 :         s->cname = i->base.name;
     676        6679 :         return s;
     677             : }
     678             : 
     679             : stmt *
     680      506247 : stmt_append_col(backend *be, sql_column *c, stmt *offset, stmt *b, int *mvc_var_update, int fake)
     681             : {
     682      506247 :         MalBlkPtr mb = be->mb;
     683             :         InstrPtr q = NULL;
     684             : 
     685      506247 :         if (b->nr < 0)
     686             :                 return NULL;
     687             : 
     688      506247 :         if (!c->t->s && ATOMIC_PTR_GET(&c->t->data)) { /* declared table */
     689          23 :                 int *l = ATOMIC_PTR_GET(&c->t->data);
     690             : 
     691          23 :                 if (c->colnr == 0) { /* append to tid column */
     692          18 :                         q = newStmt(mb, sqlRef, growRef);
     693          18 :                         q = pushArgument(mb, q, l[0]);
     694          18 :                         q = pushArgument(mb, q, b->nr);
     695             :                 }
     696          23 :                 q = newStmt(mb, batRef, appendRef);
     697          23 :                 q = pushArgument(mb, q, l[c->colnr+1]);
     698          23 :                 q = pushArgument(mb, q, b->nr);
     699          23 :                 q = pushBit(mb, q, TRUE);
     700          23 :                 if (q)
     701          23 :                         getArg(q,0) = l[c->colnr+1];
     702      506224 :         } else if (!fake) {     /* fake append */
     703      506224 :                 if (offset->nr < 0)
     704             :                         return NULL;
     705      506224 :                 q = newStmt(mb, sqlRef, appendRef);
     706      506224 :                 q = pushArgument(mb, q, be->mvc_var);
     707      506224 :                 if (q == NULL)
     708             :                         return NULL;
     709      506224 :                 int tmpvar = newTmpVariable(mb, TYPE_int);
     710      506224 :                 getArg(q, 0) = tmpvar;
     711      506224 :                 if (mvc_var_update != NULL)
     712      506224 :                         *mvc_var_update = tmpvar;
     713      506224 :                 q = pushSchema(mb, q, c->t);
     714      506224 :                 q = pushStr(mb, q, c->t->base.name);
     715      506224 :                 q = pushStr(mb, q, c->base.name);
     716      506224 :                 q = pushArgument(mb, q, offset->nr);
     717             :                 /* also the offsets */
     718      506224 :                 assert(offset->q->retc == 2);
     719      506224 :                 q = pushArgument(mb, q, getArg(offset->q, 1));
     720      506224 :                 q = pushArgument(mb, q, b->nr);
     721      506224 :                 if (q == NULL)
     722             :                         return NULL;
     723      506224 :                 if (mvc_var_update != NULL)
     724      506224 :                         *mvc_var_update = getDestVar(q);
     725             :         } else {
     726             :                 return b;
     727             :         }
     728      506247 :         if (q) {
     729      506247 :                 stmt *s = stmt_create(be->mvc->sa, st_append_col);
     730             : 
     731      506247 :                 if (s == NULL) {
     732           0 :                         freeInstruction(q);
     733           0 :                         return NULL;
     734             :                 }
     735      506247 :                 s->op1 = b;
     736      506247 :                 s->op2 = offset;
     737      506247 :                 s->op4.cval = c;
     738      506247 :                 s->q = q;
     739      506247 :                 s->nr = getDestVar(q);
     740      506247 :                 return s;
     741             :         }
     742             :         return NULL;
     743             : }
     744             : 
     745             : stmt *
     746        2193 : stmt_append_idx(backend *be, sql_idx *i, stmt *offset, stmt *b)
     747             : {
     748        2193 :         MalBlkPtr mb = be->mb;
     749             :         InstrPtr q = NULL;
     750             : 
     751        2193 :         if (offset->nr < 0 || b->nr < 0)
     752             :                 return NULL;
     753             : 
     754        2193 :         q = newStmt(mb, sqlRef, appendRef);
     755        2193 :         q = pushArgument(mb, q, be->mvc_var);
     756        2193 :         if (q == NULL)
     757             :                 return NULL;
     758        2193 :         getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
     759        2193 :         q = pushSchema(mb, q, i->t);
     760        2193 :         q = pushStr(mb, q, i->t->base.name);
     761        2193 :         q = pushStr(mb, q, sa_strconcat(be->mvc->sa, "%", i->base.name));
     762        2193 :         q = pushArgument(mb, q, offset->nr);
     763             :         /* also the offsets */
     764        2193 :         assert(offset->q->retc == 2);
     765        2193 :         q = pushArgument(mb, q, getArg(offset->q, 1));
     766        2193 :         q = pushArgument(mb, q, b->nr);
     767        2193 :         if (q == NULL)
     768             :                 return NULL;
     769        2193 :         be->mvc_var = getDestVar(q);
     770             : 
     771        2193 :         stmt *s = stmt_create(be->mvc->sa, st_append_idx);
     772        2193 :         if (s == NULL) {
     773           0 :                 freeInstruction(q);
     774           0 :                 return NULL;
     775             :         }
     776             : 
     777        2193 :         s->op1 = b;
     778        2193 :         s->op2 = offset;
     779        2193 :         s->op4.idxval = i;
     780        2193 :         s->q = q;
     781        2193 :         s->nr = getDestVar(q);
     782        2193 :         return s;
     783             : }
     784             : 
     785             : stmt *
     786        2943 : stmt_update_col(backend *be, sql_column *c, stmt *tids, stmt *upd)
     787             : {
     788        2943 :         MalBlkPtr mb = be->mb;
     789             :         InstrPtr q = NULL;
     790             : 
     791        2943 :         if (tids->nr < 0 || upd->nr < 0)
     792             :                 return NULL;
     793             : 
     794        2944 :         if (!c->t->s && ATOMIC_PTR_GET(&c->t->data)) { /* declared table */
     795           1 :                 int *l = ATOMIC_PTR_GET(&c->t->data);
     796             : 
     797           1 :                 q = newStmt(mb, batRef, replaceRef);
     798           1 :                 q = pushArgument(mb, q, l[c->colnr+1]);
     799           1 :                 q = pushArgument(mb, q, tids->nr);
     800           1 :                 q = pushArgument(mb, q, upd->nr);
     801             :         } else {
     802        2942 :                 q = newStmt(mb, sqlRef, updateRef);
     803        2942 :                 q = pushArgument(mb, q, be->mvc_var);
     804        2942 :                 if (q == NULL)
     805             :                         return NULL;
     806        2942 :                 getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
     807        2942 :                 q = pushSchema(mb, q, c->t);
     808        2942 :                 q = pushStr(mb, q, c->t->base.name);
     809        2942 :                 q = pushStr(mb, q, c->base.name);
     810        2942 :                 q = pushArgument(mb, q, tids->nr);
     811        2942 :                 q = pushArgument(mb, q, upd->nr);
     812        2942 :                 if (q == NULL)
     813             :                         return NULL;
     814        2942 :                 be->mvc_var = getDestVar(q);
     815             :         }
     816        2943 :         if (q){
     817        2943 :                 stmt *s = stmt_create(be->mvc->sa, st_update_col);
     818             : 
     819        2943 :                 if (s == NULL) {
     820           0 :                         freeInstruction(q);
     821           0 :                         return NULL;
     822             :                 }
     823        2943 :                 s->op1 = tids;
     824        2943 :                 s->op2 = upd;
     825        2943 :                 s->op4.cval = c;
     826        2943 :                 s->q = q;
     827        2943 :                 s->nr = getDestVar(q);
     828        2943 :                 return s;
     829             :         }
     830             :         return NULL;
     831             : }
     832             : 
     833             : 
     834             : stmt *
     835         781 : stmt_update_idx(backend *be, sql_idx *i, stmt *tids, stmt *upd)
     836             : {
     837         781 :         MalBlkPtr mb = be->mb;
     838             :         InstrPtr q = NULL;
     839             : 
     840         781 :         if (tids->nr < 0 || upd->nr < 0)
     841             :                 return NULL;
     842             : 
     843         781 :         q = newStmt(mb, sqlRef, updateRef);
     844         781 :         q = pushArgument(mb, q, be->mvc_var);
     845         781 :         if (q == NULL)
     846             :                 return NULL;
     847         781 :         getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
     848         781 :         q = pushSchema(mb, q, i->t);
     849         781 :         q = pushStr(mb, q, i->t->base.name);
     850         781 :         q = pushStr(mb, q, sa_strconcat(be->mvc->sa, "%", i->base.name));
     851         781 :         q = pushArgument(mb, q, tids->nr);
     852         781 :         q = pushArgument(mb, q, upd->nr);
     853         781 :         if (q == NULL)
     854             :                 return NULL;
     855         781 :         be->mvc_var = getDestVar(q);
     856         781 :         stmt *s = stmt_create(be->mvc->sa, st_update_idx);
     857         781 :         if (s == NULL) {
     858           0 :                 freeInstruction(q);
     859           0 :                 return NULL;
     860             :         }
     861             : 
     862         781 :         s->op1 = tids;
     863         781 :         s->op2 = upd;
     864         781 :         s->op4.idxval = i;
     865         781 :         s->q = q;
     866         781 :         s->nr = getDestVar(q);
     867         781 :         return s;
     868             : }
     869             : 
     870             : stmt *
     871         344 : stmt_delete(backend *be, sql_table *t, stmt *tids)
     872             : {
     873         344 :         MalBlkPtr mb = be->mb;
     874             :         InstrPtr q = NULL;
     875             : 
     876         344 :         if (tids->nr < 0)
     877             :                 return NULL;
     878             : 
     879         345 :         if (!t->s && ATOMIC_PTR_GET(&t->data)) { /* declared table */
     880           1 :                 int *l = ATOMIC_PTR_GET(&t->data);
     881             : 
     882           1 :                 q = newStmt(mb, batRef, deleteRef);
     883           1 :                 q = pushArgument(mb, q, l[0]);
     884           1 :                 q = pushArgument(mb, q, tids->nr);
     885             :         } else {
     886         343 :                 q = newStmt(mb, sqlRef, deleteRef);
     887         343 :                 q = pushArgument(mb, q, be->mvc_var);
     888         343 :                 if (q == NULL)
     889             :                         return NULL;
     890         343 :                 getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
     891         343 :                 q = pushSchema(mb, q, t);
     892         343 :                 q = pushStr(mb, q, t->base.name);
     893         343 :                 q = pushArgument(mb, q, tids->nr);
     894         343 :                 if (q == NULL)
     895             :                         return NULL;
     896         343 :                 be->mvc_var = getDestVar(q);
     897             :         }
     898         344 :         if (q) {
     899         344 :                 stmt *s = stmt_create(be->mvc->sa, st_delete);
     900         344 :                 if (s == NULL) {
     901           0 :                         freeInstruction(q);
     902           0 :                         return NULL;
     903             :                 }
     904             : 
     905         344 :                 s->op1 = tids;
     906         344 :                 s->op4.tval = t;
     907         344 :                 s->q = q;
     908         344 :                 s->nr = getDestVar(q);
     909         344 :                 return s;
     910             :         }
     911             :         return NULL;
     912             : }
     913             : 
     914             : stmt *
     915      114763 : stmt_const(backend *be, stmt *s, stmt *val)
     916             : {
     917             :         InstrPtr q = NULL;
     918      114763 :         MalBlkPtr mb = be->mb;
     919             : 
     920      114763 :         if (val)
     921      114763 :                 q = dump_2(mb, algebraRef, projectRef, s, val);
     922             :         else
     923           0 :                 q = dump_1(mb, algebraRef, projectRef, s);
     924      114763 :         if (q) {
     925      114763 :                 stmt *ns = stmt_create(be->mvc->sa, st_const);
     926      114763 :                 if (ns == NULL) {
     927           0 :                         freeInstruction(q);
     928           0 :                         return NULL;
     929             :                 }
     930             : 
     931      114763 :                 ns->op1 = s;
     932      114763 :                 ns->op2 = val;
     933      114763 :                 ns->nrcols = s->nrcols;
     934      114763 :                 ns->key = s->key;
     935      114763 :                 ns->aggr = s->aggr;
     936      114763 :                 ns->q = q;
     937      114763 :                 ns->nr = getDestVar(q);
     938      114763 :                 ns->tname = val->tname;
     939      114763 :                 ns->cname = val->cname;
     940      114763 :                 return ns;
     941             :         }
     942             :         return NULL;
     943             : }
     944             : 
     945             : stmt *
     946        2454 : stmt_gen_group(backend *be, stmt *gids, stmt *cnts)
     947             : {
     948        2454 :         MalBlkPtr mb = be->mb;
     949        2454 :         InstrPtr q = dump_2(mb, algebraRef, groupbyRef, gids, cnts);
     950             : 
     951        2454 :         if (q) {
     952        2454 :                 stmt *ns = stmt_create(be->mvc->sa, st_gen_group);
     953        2454 :                 if (ns == NULL) {
     954           0 :                         freeInstruction(q);
     955           0 :                         return NULL;
     956             :                 }
     957             : 
     958        2454 :                 ns->op1 = gids;
     959        2454 :                 ns->op2 = cnts;
     960             : 
     961        2454 :                 ns->nrcols = gids->nrcols;
     962        2454 :                 ns->key = 0;
     963        2454 :                 ns->aggr = 0;
     964        2454 :                 ns->q = q;
     965        2454 :                 ns->nr = getDestVar(q);
     966        2454 :                 return ns;
     967             :         }
     968             :         return NULL;
     969             : }
     970             : 
     971             : stmt *
     972       59112 : stmt_mirror(backend *be, stmt *s)
     973             : {
     974       59112 :         MalBlkPtr mb = be->mb;
     975       59112 :         InstrPtr q = dump_1(mb, batRef, mirrorRef, s);
     976             : 
     977       59112 :         if (q) {
     978       59112 :                 stmt *ns = stmt_create(be->mvc->sa, st_mirror);
     979       59112 :                 if (ns == NULL) {
     980           0 :                         freeInstruction(q);
     981           0 :                         return NULL;
     982             :                 }
     983             : 
     984       59112 :                 ns->op1 = s;
     985       59112 :                 ns->nrcols = 2;
     986       59112 :                 ns->key = s->key;
     987       59112 :                 ns->aggr = s->aggr;
     988       59112 :                 ns->q = q;
     989       59112 :                 ns->nr = getDestVar(q);
     990       59112 :                 return ns;
     991             :         }
     992             :         return NULL;
     993             : }
     994             : 
     995             : stmt *
     996      402688 : stmt_result(backend *be, stmt *s, int nr)
     997             : {
     998             :         stmt *ns;
     999             : 
    1000      402688 :         if (s->type == st_join && s->flag == cmp_joined) {
    1001        6944 :                 if (nr)
    1002        3297 :                         return s->op2;
    1003        3647 :                 return s->op1;
    1004             :         }
    1005             : 
    1006      395744 :         if (s->op1->nr < 0)
    1007             :                 return NULL;
    1008             : 
    1009      395744 :         ns = stmt_create(be->mvc->sa, st_result);
    1010      395744 :         if(!ns) {
    1011             :                 return NULL;
    1012             :         }
    1013      395744 :         if (s->op1->type == st_join && s->op1->flag == cmp_joined) {
    1014           0 :                 assert(0);
    1015      395744 :         } else if (nr) {
    1016      243831 :                 int v = getArg(s->q, nr);
    1017             : 
    1018      243831 :                 assert(s->q->retc > nr);
    1019      243831 :                 ns->nr = v;
    1020             :         } else {
    1021      151913 :                 ns->nr = s->nr;
    1022             :         }
    1023      395744 :         ns->op1 = s;
    1024      395744 :         ns->flag = nr;
    1025      395744 :         ns->nrcols = s->nrcols;
    1026      395744 :         ns->key = s->key;
    1027      395744 :         ns->aggr = s->aggr;
    1028      395744 :         return ns;
    1029             : }
    1030             : 
    1031             : 
    1032             : /* limit maybe atom nil */
    1033             : stmt *
    1034        1568 : stmt_limit(backend *be, stmt *col, stmt *piv, stmt *gid, stmt *offset, stmt *limit, int distinct, int dir, int nullslast, int last, int order)
    1035             : {
    1036        1568 :         MalBlkPtr mb = be->mb;
    1037             :         InstrPtr q = NULL;
    1038             :         int l, p, g, c;
    1039             : 
    1040        1568 :         if (col->nr < 0 || offset->nr < 0 || limit->nr < 0)
    1041             :                 return NULL;
    1042        1568 :         if (piv && (piv->nr < 0 || gid->nr < 0))
    1043             :                 return NULL;
    1044             : 
    1045             :         c = (col) ? col->nr : 0;
    1046        1568 :         p = (piv) ? piv->nr : 0;
    1047        1568 :         g = (gid) ? gid->nr : 0;
    1048             : 
    1049             :         /* first insert single value into a bat */
    1050        1568 :         if (col->nrcols == 0) {
    1051           0 :                 int k, tt = tail_type(col)->type->localtype;
    1052             : 
    1053           0 :                 q = newStmt(mb, batRef, newRef);
    1054           0 :                 if (q == NULL)
    1055             :                         return NULL;
    1056           0 :                 setVarType(mb, getArg(q, 0), newBatType(tt));
    1057           0 :                 q = pushType(mb, q, tt);
    1058           0 :                 if (q == NULL)
    1059             :                         return NULL;
    1060           0 :                 k = getDestVar(q);
    1061             : 
    1062           0 :                 q = newStmt(mb, batRef, appendRef);
    1063           0 :                 q = pushArgument(mb, q, k);
    1064           0 :                 q = pushArgument(mb, q, c);
    1065           0 :                 if (q == NULL)
    1066             :                         return NULL;
    1067             :                 c = k;
    1068             :         }
    1069        1568 :         if (order) {
    1070             :                 int topn = 0;
    1071             : 
    1072         788 :                 q = newStmt(mb, calcRef, plusRef);
    1073         788 :                 q = pushArgument(mb, q, offset->nr);
    1074         788 :                 q = pushArgument(mb, q, limit->nr);
    1075         788 :                 if (q == NULL)
    1076             :                         return NULL;
    1077         788 :                 topn = getDestVar(q);
    1078             : 
    1079         788 :                 q = newStmtArgs(mb, algebraRef, firstnRef, 9);
    1080         788 :                 if (!last) /* we need the groups for the next firstn */
    1081         476 :                         q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    1082         788 :                 q = pushArgument(mb, q, c);
    1083         788 :                 if (p)
    1084         476 :                         q = pushArgument(mb, q, p);
    1085             :                 else
    1086         312 :                         q = pushNil(mb, q, TYPE_bat);
    1087         788 :                 if (g)
    1088         476 :                         q = pushArgument(mb, q, g);
    1089             :                 else
    1090         312 :                         q = pushNil(mb, q, TYPE_bat);
    1091         788 :                 q = pushArgument(mb, q, topn);
    1092         788 :                 q = pushBit(mb, q, dir);
    1093         788 :                 q = pushBit(mb, q, nullslast);
    1094         788 :                 q = pushBit(mb, q, distinct != 0);
    1095             : 
    1096         788 :                 if (q == NULL)
    1097             :                         return NULL;
    1098         788 :                 l = getArg(q, 0);
    1099             :                 l = getDestVar(q);
    1100             :         } else {
    1101             :                 int len;
    1102             : 
    1103         780 :                 q = newStmt(mb, calcRef, plusRef);
    1104         780 :                 q = pushArgument(mb, q, offset->nr);
    1105         780 :                 q = pushArgument(mb, q, limit->nr);
    1106         780 :                 if (q == NULL)
    1107             :                         return NULL;
    1108         780 :                 len = getDestVar(q);
    1109             : 
    1110             :                 /* since both arguments of algebra.subslice are
    1111             :                    inclusive correct the LIMIT value by
    1112             :                    subtracting 1 */
    1113         780 :                 q = newStmt(mb, calcRef, minusRef);
    1114         780 :                 q = pushArgument(mb, q, len);
    1115         780 :                 q = pushInt(mb, q, 1);
    1116         780 :                 if (q == NULL)
    1117             :                         return NULL;
    1118         780 :                 len = getDestVar(q);
    1119             : 
    1120         780 :                 q = newStmt(mb, algebraRef, subsliceRef);
    1121         780 :                 q = pushArgument(mb, q, c);
    1122         780 :                 q = pushArgument(mb, q, offset->nr);
    1123         780 :                 q = pushArgument(mb, q, len);
    1124         780 :                 if (q == NULL)
    1125             :                         return NULL;
    1126         780 :                 l = getDestVar(q);
    1127             :         }
    1128             :         /* retrieve the single values again */
    1129        1568 :         if (col->nrcols == 0) {
    1130           0 :                 q = newStmt(mb, algebraRef, findRef);
    1131           0 :                 q = pushArgument(mb, q, l);
    1132           0 :                 q = pushOid(mb, q, 0);
    1133           0 :                 if (q == NULL)
    1134             :                         return NULL;
    1135           0 :                 l = getDestVar(q);
    1136             :         }
    1137             : 
    1138        2660 :         stmt *ns = stmt_create(be->mvc->sa, piv?st_limit2:st_limit);
    1139        1568 :         if (ns == NULL) {
    1140           0 :                 freeInstruction(q);
    1141           0 :                 return NULL;
    1142             :         }
    1143             : 
    1144        1568 :         ns->op1 = col;
    1145        1568 :         ns->op2 = offset;
    1146        1568 :         ns->op3 = limit;
    1147        1568 :         ns->nrcols = col->nrcols;
    1148        1568 :         ns->key = col->key;
    1149        1568 :         ns->aggr = col->aggr;
    1150        1568 :         ns->q = q;
    1151        1568 :         ns->nr = l;
    1152        1568 :         return ns;
    1153             : }
    1154             : 
    1155             : stmt *
    1156          21 : stmt_sample(backend *be, stmt *s, stmt *sample, stmt *seed)
    1157             : {
    1158          21 :         MalBlkPtr mb = be->mb;
    1159             :         InstrPtr q = NULL;
    1160             : 
    1161          21 :         if (s->nr < 0 || sample->nr < 0)
    1162             :                 return NULL;
    1163          21 :         q = newStmt(mb, sampleRef, subuniformRef);
    1164          21 :         q = pushArgument(mb, q, s->nr);
    1165          21 :         q = pushArgument(mb, q, sample->nr);
    1166             : 
    1167          21 :         if (seed) {
    1168          12 :                 if (seed->nr < 0)
    1169             :                         return NULL;
    1170             : 
    1171          12 :                 q = pushArgument(mb, q, seed->nr);
    1172             :         }
    1173             : 
    1174          21 :         if (q) {
    1175          21 :                 stmt *ns = stmt_create(be->mvc->sa, st_sample);
    1176          21 :                 if (ns == NULL) {
    1177           0 :                         freeInstruction(q);
    1178           0 :                         return NULL;
    1179             :                 }
    1180             : 
    1181          21 :                 ns->op1 = s;
    1182          21 :                 ns->op2 = sample;
    1183             : 
    1184          21 :                 if (seed) {
    1185          12 :                         ns->op3 = seed;
    1186             :                 }
    1187             : 
    1188          21 :                 ns->nrcols = s->nrcols;
    1189          21 :                 ns->key = s->key;
    1190          21 :                 ns->aggr = s->aggr;
    1191          21 :                 ns->flag = 0;
    1192          21 :                 ns->q = q;
    1193          21 :                 ns->nr = getDestVar(q);
    1194          21 :                 return ns;
    1195             :         }
    1196             :         return NULL;
    1197             : }
    1198             : 
    1199             : 
    1200             : stmt *
    1201       15354 : stmt_order(backend *be, stmt *s, int direction, int nullslast)
    1202             : {
    1203       15354 :         MalBlkPtr mb = be->mb;
    1204             :         InstrPtr q = NULL;
    1205             : 
    1206       15354 :         if (s->nr < 0)
    1207             :                 return NULL;
    1208       15354 :         q = newStmt(mb, algebraRef, sortRef);
    1209             :         /* both ordered result and oid's order en subgroups */
    1210       15354 :         q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    1211       15354 :         q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    1212       15354 :         q = pushArgument(mb, q, s->nr);
    1213       15354 :         q = pushBit(mb, q, !direction);
    1214       15354 :         q = pushBit(mb, q, nullslast);
    1215       15354 :         q = pushBit(mb, q, FALSE);
    1216       15354 :         if (q == NULL)
    1217             :                 return NULL;
    1218             : 
    1219             : 
    1220       15354 :         stmt *ns = stmt_create(be->mvc->sa, st_order);
    1221       15354 :         if (ns == NULL) {
    1222           0 :                 freeInstruction(q);
    1223           0 :                 return NULL;
    1224             :         }
    1225             : 
    1226       15354 :         ns->op1 = s;
    1227       15354 :         ns->flag = direction;
    1228       15354 :         ns->nrcols = s->nrcols;
    1229       15354 :         ns->key = s->key;
    1230       15354 :         ns->aggr = s->aggr;
    1231       15354 :         ns->q = q;
    1232       15354 :         ns->nr = getDestVar(q);
    1233       15354 :         return ns;
    1234             : }
    1235             : 
    1236             : stmt *
    1237       17298 : stmt_reorder(backend *be, stmt *s, int direction, int nullslast, stmt *orderby_ids, stmt *orderby_grp)
    1238             : {
    1239       17298 :         MalBlkPtr mb = be->mb;
    1240             :         InstrPtr q = NULL;
    1241             : 
    1242       17298 :         if (s->nr < 0 || orderby_ids->nr < 0 || orderby_grp->nr < 0)
    1243             :                 return NULL;
    1244       17298 :         q = newStmtArgs(mb, algebraRef, sortRef, 9);
    1245             :         /* both ordered result and oid's order en subgroups */
    1246       17298 :         q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    1247       17298 :         q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    1248       17298 :         q = pushArgument(mb, q, s->nr);
    1249       17298 :         q = pushArgument(mb, q, orderby_ids->nr);
    1250       17298 :         q = pushArgument(mb, q, orderby_grp->nr);
    1251       17298 :         q = pushBit(mb, q, !direction);
    1252       17298 :         q = pushBit(mb, q, nullslast);
    1253       17298 :         q = pushBit(mb, q, FALSE);
    1254       17298 :         if (q == NULL)
    1255             :                 return NULL;
    1256             : 
    1257       17298 :         stmt *ns = stmt_create(be->mvc->sa, st_reorder);
    1258       17298 :         if (ns == NULL) {
    1259           0 :                 freeInstruction(q);
    1260           0 :                 return NULL;
    1261             :         }
    1262             : 
    1263       17298 :         ns->op1 = s;
    1264       17298 :         ns->op2 = orderby_ids;
    1265       17298 :         ns->op3 = orderby_grp;
    1266       17298 :         ns->flag = direction;
    1267       17298 :         ns->nrcols = s->nrcols;
    1268       17298 :         ns->key = s->key;
    1269       17298 :         ns->aggr = s->aggr;
    1270       17298 :         ns->nr = getDestVar(q);
    1271       17298 :         ns->q = q;
    1272       17298 :         return ns;
    1273             : }
    1274             : 
    1275             : stmt *
    1276     2399250 : stmt_atom(backend *be, atom *a)
    1277             : {
    1278     2399250 :         MalBlkPtr mb = be->mb;
    1279     2399250 :         InstrPtr q = EC_TEMP_FRAC(atom_type(a)->type->eclass) ? newStmt(mb, calcRef, atom_type(a)->type->impl) : newAssignment(mb);
    1280             : 
    1281     2399250 :         if (!q)
    1282             :                 return NULL;
    1283     2399250 :         if (atom_null(a)) {
    1284      146371 :                 q = pushNil(mb, q, atom_type(a)->type->localtype);
    1285             :         } else {
    1286             :                 int k;
    1287     2252879 :                 if ((k = constantAtom(be, mb, a)) == -1) {
    1288           0 :                         freeInstruction(q);
    1289           0 :                         return NULL;
    1290             :                 }
    1291     2252879 :                 q = pushArgument(mb, q, k);
    1292             :         }
    1293             :         /* digits of the result timestamp/daytime */
    1294     2399250 :         if (EC_TEMP_FRAC(atom_type(a)->type->eclass))
    1295       47308 :                 q = pushInt(mb, q, atom_type(a)->digits);
    1296     2399250 :         if (q) {
    1297     2399250 :                 stmt *s = stmt_create(be->mvc->sa, st_atom);
    1298     2399250 :                 if (s == NULL) {
    1299           0 :                         freeInstruction(q);
    1300           0 :                         return NULL;
    1301             :                 }
    1302             : 
    1303     2399250 :                 s->op4.aval = a;
    1304     2399250 :                 s->key = 1;          /* values are also unique */
    1305     2399250 :                 s->q = q;
    1306     2399250 :                 s->nr = getDestVar(q);
    1307     2399250 :                 return s;
    1308             :         }
    1309             :         return NULL;
    1310             : }
    1311             : 
    1312             : stmt *
    1313         423 : stmt_genselect(backend *be, stmt *lops, stmt *rops, sql_subfunc *f, stmt *sub, int anti)
    1314             : {
    1315         423 :         MalBlkPtr mb = be->mb;
    1316             :         InstrPtr q = NULL;
    1317             :         const char *mod, *op;
    1318             :         node *n;
    1319             :         int k;
    1320             : 
    1321         423 :         if (backend_create_subfunc(be, f, NULL) < 0)
    1322             :                 return NULL;
    1323         423 :         op = sql_func_imp(f->func);
    1324         423 :         mod = sql_func_mod(f->func);
    1325             : 
    1326         423 :         if (rops->nrcols >= 1) {
    1327             :                 bit need_not = FALSE;
    1328             : 
    1329             :                 int narg = 3;
    1330          50 :                 for (n = lops->op4.lval->h; n; n = n->next)
    1331          25 :                         narg++;
    1332         100 :                 for (n = rops->op4.lval->h; n; n = n->next)
    1333          75 :                         narg++;
    1334          25 :                 q = newStmtArgs(mb, malRef, multiplexRef, narg);
    1335          25 :                 setVarType(mb, getArg(q, 0), newBatType(TYPE_bit));
    1336          25 :                 q = pushStr(mb, q, convertMultiplexMod(mod, op));
    1337          25 :                 q = pushStr(mb, q, convertMultiplexFcn(op));
    1338          50 :                 for (n = lops->op4.lval->h; n; n = n->next) {
    1339          25 :                         stmt *op = n->data;
    1340             : 
    1341          25 :                         q = pushArgument(mb, q, op->nr);
    1342             :                 }
    1343         100 :                 for (n = rops->op4.lval->h; n; n = n->next) {
    1344          75 :                         stmt *op = n->data;
    1345             : 
    1346          75 :                         q = pushArgument(mb, q, op->nr);
    1347             :                 }
    1348          25 :                 k = getDestVar(q);
    1349             : 
    1350          25 :                 q = newStmtArgs(mb, algebraRef, selectRef, 9);
    1351          25 :                 q = pushArgument(mb, q, k);
    1352          25 :                 if (sub)
    1353           6 :                         q = pushArgument(mb, q, sub->nr);
    1354          25 :                 q = pushBit(mb, q, !need_not);
    1355          25 :                 q = pushBit(mb, q, !need_not);
    1356          25 :                 q = pushBit(mb, q, TRUE);
    1357          25 :                 q = pushBit(mb, q, TRUE);
    1358          25 :                 q = pushBit(mb, q, anti);
    1359             :         } else {
    1360             :                 node *n;
    1361             : 
    1362         398 :                 op = sa_strconcat(be->mvc->sa, op, selectRef);
    1363         398 :                 q = newStmtArgs(mb, mod, convertOperator(op), 9);
    1364             :                 // push pointer to the SQL structure into the MAL call
    1365             :                 // allows getting argument names for example
    1366         398 :                 if (LANG_EXT(f->func->lang))
    1367           0 :                         q = pushPtr(mb, q, f); // nothing to see here, please move along
    1368             :                 // f->query contains the R code to be run
    1369         398 :                 if (f->func->lang == FUNC_LANG_R || f->func->lang >= FUNC_LANG_PY)
    1370           0 :                         q = pushStr(mb, q, f->func->query);
    1371             : 
    1372         796 :                 for (n = lops->op4.lval->h; n; n = n->next) {
    1373         398 :                         stmt *op = n->data;
    1374             : 
    1375         398 :                         q = pushArgument(mb, q, op->nr);
    1376             :                 }
    1377             :                 /* candidate lists */
    1378         398 :                 if (sub)
    1379         295 :                         q = pushArgument(mb, q, sub->nr);
    1380             :                 else
    1381         103 :                         q = pushNil(mb, q, TYPE_bat);
    1382             : 
    1383        1592 :                 for (n = rops->op4.lval->h; n; n = n->next) {
    1384        1194 :                         stmt *op = n->data;
    1385             : 
    1386        1194 :                         q = pushArgument(mb, q, op->nr);
    1387             :                 }
    1388             : 
    1389         398 :                 q = pushBit(mb, q, anti);
    1390             :         }
    1391             : 
    1392         423 :         if (q) {
    1393         423 :                 stmt *s = stmt_create(be->mvc->sa, st_uselect);
    1394         423 :                 if (s == NULL) {
    1395           0 :                         freeInstruction(q);
    1396           0 :                         return NULL;
    1397             :                 }
    1398             : 
    1399         423 :                 s->op1 = lops;
    1400         423 :                 s->op2 = rops;
    1401         423 :                 s->op3 = sub;
    1402         423 :                 s->key = lops->nrcols == 0 && rops->nrcols == 0;
    1403         423 :                 s->flag = cmp_filter;
    1404         423 :                 s->nrcols = lops->nrcols;
    1405         423 :                 s->nr = getDestVar(q);
    1406         423 :                 s->q = q;
    1407         423 :                 s->cand = sub;
    1408         423 :                 return s;
    1409             :         }
    1410             :         return NULL;
    1411             : }
    1412             : 
    1413             : stmt *
    1414      213935 : stmt_uselect(backend *be, stmt *op1, stmt *op2, comp_type cmptype, stmt *sub, int anti, int is_semantics)
    1415             : {
    1416      213935 :         MalBlkPtr mb = be->mb;
    1417             :         InstrPtr q = NULL;
    1418             :         int l, r;
    1419             :         stmt *sel = sub;
    1420             : 
    1421      213935 :         if (op1->nr < 0 || op2->nr < 0 || (sub && sub->nr < 0))
    1422             :                 return NULL;
    1423             :         l = op1->nr;
    1424             :         r = op2->nr;
    1425             : 
    1426      213935 :         if (op2->nrcols >= 1 && op1->nrcols == 0) { /* swap */
    1427             :                 stmt *v = op1;
    1428             :                 op1 = op2;
    1429             :                 op2 = v;
    1430             :                 int n = l;
    1431             :                 l = r;
    1432             :                 r = n;
    1433          46 :                 cmptype = swap_compare(cmptype);
    1434             :         }
    1435      213935 :         if (op2->nrcols >= 1) {
    1436             :                 bit need_not = FALSE;
    1437       12666 :                 const char *mod = calcRef;
    1438             :                 const char *op = "=";
    1439             :                 int k;
    1440             : 
    1441       12666 :                 switch (cmptype) {
    1442             :                 case mark_in:
    1443             :                 case mark_notin:
    1444             :                 case cmp_equal:
    1445             :                         op = "=";
    1446             :                         break;
    1447          75 :                 case cmp_notequal:
    1448             :                         op = "!=";
    1449          75 :                         break;
    1450        1915 :                 case cmp_lt:
    1451             :                         op = "<";
    1452        1915 :                         break;
    1453         762 :                 case cmp_lte:
    1454             :                         op = "<=";
    1455         762 :                         break;
    1456        3769 :                 case cmp_gt:
    1457             :                         op = ">";
    1458        3769 :                         break;
    1459         754 :                 case cmp_gte:
    1460             :                         op = ">=";
    1461         754 :                         break;
    1462           0 :                 default:
    1463           0 :                         TRC_ERROR(SQL_EXECUTION, "Unknown operator\n");
    1464             :                 }
    1465             : 
    1466       12666 :                 if ((q = multiplex2(mb, mod, convertOperator(op), l, r, TYPE_bit)) == NULL)
    1467             :                         return NULL;
    1468       12666 :                 if (sub && (op1->cand || op2->cand)) {
    1469        1530 :                         if (op1->cand && !op2->cand) {
    1470         238 :                                 if (op1->nrcols > 0)
    1471         238 :                                         q = pushNil(mb, q, TYPE_bat);
    1472         238 :                                 q = pushArgument(mb, q, sub->nr);
    1473        1292 :                         } else if (!op1->cand && op2->cand) {
    1474          11 :                                 q = pushArgument(mb, q, sub->nr);
    1475          11 :                                 if (op2->nrcols > 0)
    1476          11 :                                         q = pushNil(mb, q, TYPE_bat);
    1477             :                         }
    1478             :                         sub = NULL;
    1479             :                 }
    1480       12666 :                 if (is_semantics)
    1481           3 :                         q = pushBit(mb, q, TRUE);
    1482       12666 :                 k = getDestVar(q);
    1483             : 
    1484       12666 :                 q = newStmtArgs(mb, algebraRef, selectRef, 9);
    1485       12666 :                 q = pushArgument(mb, q, k);
    1486       12666 :                 if (sub)
    1487        4203 :                         q = pushArgument(mb, q, sub->nr);
    1488       12666 :                 q = pushBit(mb, q, !need_not);
    1489       12666 :                 q = pushBit(mb, q, !need_not);
    1490       12666 :                 q = pushBit(mb, q, TRUE);
    1491       12666 :                 q = pushBit(mb, q, TRUE);
    1492       12666 :                 q = pushBit(mb, q, anti);
    1493       12666 :                 if (q == NULL)
    1494             :                         return NULL;
    1495             :                 k = getDestVar(q);
    1496             :         } else {
    1497      201269 :                 assert (cmptype != cmp_filter);
    1498      201269 :                 if (is_semantics) {
    1499       20522 :                         assert(cmptype == cmp_equal || cmptype == cmp_notequal);
    1500       20522 :                         if (cmptype == cmp_notequal)
    1501           0 :                                 anti = !anti;
    1502       20522 :                         q = newStmtArgs(mb, algebraRef, selectRef, 9);
    1503       20522 :                         q = pushArgument(mb, q, l);
    1504       20522 :                         if (sub && !op1->cand) {
    1505        4246 :                                 q = pushArgument(mb, q, sub->nr);
    1506             :                         } else {
    1507       16276 :                                 assert(!sub || op1->cand == sub);
    1508             :                                 sub = NULL;
    1509             :                         }
    1510       20522 :                         q = pushArgument(mb, q, r);
    1511       20522 :                         q = pushArgument(mb, q, r);
    1512       20522 :                         q = pushBit(mb, q, TRUE);
    1513       20522 :                         q = pushBit(mb, q, TRUE);
    1514       20522 :                         q = pushBit(mb, q, anti);
    1515             :                 } else {
    1516      180747 :                         q = newStmt(mb, algebraRef, thetaselectRef);
    1517      180747 :                         q = pushArgument(mb, q, l);
    1518      180747 :                         if (sub && !op1->cand) {
    1519      135382 :                                 q = pushArgument(mb, q, sub->nr);
    1520             :                         } else {
    1521       45365 :                                 assert(!sub || op1->cand == sub);
    1522       45365 :                                 q = pushNil(mb, q, TYPE_bat);
    1523             :                                 sub = NULL;
    1524             :                         }
    1525      180747 :                         q = pushArgument(mb, q, r);
    1526      180747 :                         switch (cmptype) {
    1527      141189 :                         case mark_in:
    1528             :                         case mark_notin: /* we use a anti join, todo handle null (not) in empty semantics */
    1529             :                         case cmp_equal:
    1530      281553 :                                 q = pushStr(mb, q, anti?"!=":"==");
    1531      141189 :                                 break;
    1532       32468 :                         case cmp_notequal:
    1533       64936 :                                 q = pushStr(mb, q, anti?"==":"!=");
    1534       32468 :                                 break;
    1535         489 :                         case cmp_lt:
    1536         977 :                                 q = pushStr(mb, q, anti?">=":"<");
    1537         489 :                                 break;
    1538          98 :                         case cmp_lte:
    1539         196 :                                 q = pushStr(mb, q, anti?">":"<=");
    1540          98 :                                 break;
    1541        6182 :                         case cmp_gt:
    1542       12364 :                                 q = pushStr(mb, q, anti?"<=":">");
    1543        6182 :                                 break;
    1544         321 :                         case cmp_gte:
    1545         637 :                                 q = pushStr(mb, q, anti?"<":">=");
    1546         321 :                                 break;
    1547           0 :                         default:
    1548           0 :                                 TRC_ERROR(SQL_EXECUTION, "Impossible select compare\n");
    1549           0 :                                 if (q)
    1550           0 :                                         freeInstruction(q);
    1551             :                                 q = NULL;
    1552             :                         }
    1553             :                 }
    1554      201269 :                 if (q == NULL)
    1555           0 :                         return NULL;
    1556             :         }
    1557             : 
    1558      213935 :         stmt *s = stmt_create(be->mvc->sa, st_uselect);
    1559      213935 :         if (s == NULL) {
    1560           0 :                 freeInstruction(q);
    1561           0 :                 return NULL;
    1562             :         }
    1563             : 
    1564      213935 :         s->op1 = op1;
    1565      213935 :         s->op2 = op2;
    1566      213935 :         s->op3 = sub;
    1567      213935 :         s->flag = cmptype;
    1568      213935 :         s->key = op1->nrcols == 0 && op2->nrcols == 0;
    1569      213935 :         s->nrcols = op1->nrcols;
    1570      213935 :         s->nr = getDestVar(q);
    1571      213935 :         s->q = q;
    1572      213935 :         s->cand = sub;
    1573      213935 :         if (!sub && sel) /* project back the old ids */
    1574        1862 :                 return stmt_project(be, s, sel);
    1575             :         return s;
    1576             : }
    1577             : 
    1578             : /*
    1579             : static int
    1580             : range_join_convertable(stmt *s, stmt **base, stmt **L, stmt **H)
    1581             : {
    1582             :         int ls = 0, hs = 0;
    1583             :         stmt *l = NULL, *h = NULL;
    1584             :         stmt *bl = s->op2, *bh = s->op3;
    1585             :         int tt = tail_type(s->op2)->type->localtype;
    1586             : 
    1587             : #ifdef HAVE_HGE
    1588             :         if (tt > TYPE_hge)
    1589             : #else
    1590             :         if (tt > TYPE_lng)
    1591             : #endif
    1592             :                 return 0;
    1593             :         if (s->op2->type == st_Nop && list_length(s->op2->op1->op4.lval) == 2) {
    1594             :                 bl = s->op2->op1->op4.lval->h->data;
    1595             :                 l = s->op2->op1->op4.lval->t->data;
    1596             :         }
    1597             :         if (s->op3->type == st_Nop && list_length(s->op3->op1->op4.lval) == 2) {
    1598             :                 bh = s->op3->op1->op4.lval->h->data;
    1599             :                 h = s->op3->op1->op4.lval->t->data;
    1600             :         }
    1601             : 
    1602             :         if (((ls = (l && strcmp(s->op2->op4.funcval->func->base.name, "sql_sub") == 0 && l->nrcols == 0)) || (hs = (h && strcmp(s->op3->op4.funcval->func->base.name, "sql_add") == 0 && h->nrcols == 0))) && (ls || hs) && bl == bh) {
    1603             :                 *base = bl;
    1604             :                 *L = l;
    1605             :                 *H = h;
    1606             :                 return 1;
    1607             :         }
    1608             :         return 0;
    1609             : }
    1610             : 
    1611             : static int
    1612             : argumentZero(MalBlkPtr mb, int tpe)
    1613             : {
    1614             :         ValRecord cst;
    1615             :         str msg;
    1616             : 
    1617             :         cst.vtype = TYPE_int;
    1618             :         cst.val.ival = 0;
    1619             :         msg = convertConstant(tpe, &cst);
    1620             :         if( msg)
    1621             :                 freeException(msg); // will not be called
    1622             :         return defConstant(mb, tpe, &cst);
    1623             : }
    1624             : */
    1625             : 
    1626             : static InstrPtr
    1627        5137 : select2_join2(backend *be, stmt *op1, stmt *op2, stmt *op3, int cmp, stmt **Sub, int anti, int symmetric, int swapped, int type, int reduce)
    1628             : {
    1629        5137 :         MalBlkPtr mb = be->mb;
    1630             :         InstrPtr p, q;
    1631             :         int l;
    1632        5137 :         const char *cmd = (type == st_uselect2) ? selectRef : rangejoinRef;
    1633        5137 :         stmt *sub = (Sub)?*Sub:NULL;
    1634             : 
    1635        5137 :         if (op1->nr < 0 || (sub && sub->nr < 0))
    1636             :                 return NULL;
    1637             :         l = op1->nr;
    1638        5137 :         if ((symmetric || op2->nrcols > 0 || op3->nrcols > 0 || !reduce) && (type == st_uselect2)) {
    1639             :                 int k;
    1640        3584 :                 int nrcols = (op1->nrcols || op2->nrcols || op3->nrcols);
    1641             : 
    1642        3584 :                 if (op2->nr < 0 || op3->nr < 0)
    1643             :                         return NULL;
    1644             : 
    1645        3584 :                 if (nrcols)
    1646        3542 :                         p = newStmtArgs(mb, batcalcRef, betweenRef, 12);
    1647             :                 else
    1648          42 :                         p = newStmtArgs(mb, calcRef, betweenRef, 9);
    1649        3584 :                 p = pushArgument(mb, p, l);
    1650        3584 :                 p = pushArgument(mb, p, op2->nr);
    1651        3584 :                 p = pushArgument(mb, p, op3->nr);
    1652             : 
    1653             :                 /* cands */
    1654        3584 :                 if ((sub && !reduce) || op1->cand || op2->cand || op3->cand) { /* some already handled the previous selection */
    1655        1522 :                         if (op1->cand && op1->nrcols)
    1656        1385 :                                 p = pushNil(mb, p, TYPE_bat);
    1657         137 :                         else if (op1->nrcols)
    1658         137 :                                 p = pushArgument(mb, p, sub->nr);
    1659        1522 :                         if (op2->nrcols) {
    1660        1421 :                                 if (op2->cand)
    1661        1220 :                                         p = pushNil(mb, p, TYPE_bat);
    1662             :                                 else if (op2->nrcols)
    1663         201 :                                         p = pushArgument(mb, p, sub->nr);
    1664             :                         }
    1665        1522 :                         if (op3->nrcols) {
    1666        1415 :                                 if (op3->cand)
    1667        1314 :                                         p = pushNil(mb, p, TYPE_bat);
    1668             :                                 else if (op3->nrcols)
    1669         101 :                                         p = pushArgument(mb, p, sub->nr);
    1670             :                         }
    1671             :                         sub = NULL;
    1672             :                 }
    1673             : 
    1674        3584 :                 p = pushBit(mb, p, (symmetric)?TRUE:FALSE); /* symmetric */
    1675        3584 :                 p = pushBit(mb, p, (cmp & 1) != 0);     /* lo inclusive */
    1676        3584 :                 p = pushBit(mb, p, (cmp & 2) != 0);     /* hi inclusive */
    1677        3584 :                 p = pushBit(mb, p, FALSE);                  /* nils_false */
    1678        3584 :                 p = pushBit(mb, p, (anti)?TRUE:FALSE);      /* anti */
    1679        3584 :                 if (!reduce)
    1680             :                         return p;
    1681        3366 :                 k = getDestVar(p);
    1682             : 
    1683        3366 :                 q = newStmtArgs(mb, algebraRef, selectRef, 9);
    1684        3366 :                 q = pushArgument(mb, q, k);
    1685        3366 :                 if (sub)
    1686         873 :                         q = pushArgument(mb, q, sub->nr);
    1687        3366 :                 q = pushBit(mb, q, TRUE);
    1688        3366 :                 q = pushBit(mb, q, TRUE);
    1689        3366 :                 q = pushBit(mb, q, TRUE);
    1690        3366 :                 q = pushBit(mb, q, TRUE);
    1691        3366 :                 q = pushBit(mb, q, FALSE);
    1692        3366 :                 if (q == NULL)
    1693             :                         return NULL;
    1694             :         } else {
    1695             :                 /* if st_join2 try to convert to bandjoin */
    1696             :                 /* ie check if we subtract/add a constant, to the
    1697             :                 same column */
    1698             :                 /* move this optimization into the relational phase! */
    1699             :         /*
    1700             :                 stmt *base, *low = NULL, *high = NULL;
    1701             :                 if (type == st_join2 && range_join_convertable(s, &base, &low, &high)) {
    1702             :                         int tt = tail_type(base)->type->localtype;
    1703             : 
    1704             :                         if ((rs = _dumpstmt(sql, mb, base)) < 0)
    1705             :                                 return -1;
    1706             :                         if (low) {
    1707             :                                 if ((r1 = _dumpstmt(sql, mb, low)) < 0)
    1708             :                                         return -1;
    1709             :                         } else
    1710             :                                 r1 = argumentZero(mb, tt);
    1711             :                         if (high) {
    1712             :                                 if ((r2 = _dumpstmt(sql, mb, high)) < 0)
    1713             :                                         return -1;
    1714             :                         } else
    1715             :                                 r2 = argumentZero(mb, tt);
    1716             :                         cmd = bandjoinRef;
    1717             :                 }
    1718             :         */
    1719             : 
    1720        1553 :                 int r1 = op2->nr;
    1721        1553 :                 int r2 = op3->nr;
    1722             :                 int rs = 0;
    1723        1553 :                 q = newStmtArgs(mb, algebraRef, cmd, 12);
    1724        1553 :                 if (type == st_join2)
    1725          59 :                         q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    1726        1553 :                 q = pushArgument(mb, q, l);
    1727        1553 :                 if (sub) {
    1728        1227 :                         int cand = op1->cand || op2->cand || op3->cand;
    1729             :                         if (cand) {
    1730           9 :                                 if (op1->nrcols && !op1->cand) {
    1731           0 :                                         assert(0);
    1732             :                                 }
    1733           9 :                                 if (op2->nrcols && !op2->cand) {
    1734           0 :                                         assert(0);
    1735             :                                 }
    1736           9 :                                 if (op3->nrcols && !op3->cand) {
    1737           0 :                                         assert(0);
    1738             :                                 }
    1739             :                                 sub = NULL;
    1740             :                         }
    1741             :                 }
    1742        1544 :                 if (sub) /* only for uselect2 */
    1743        1218 :                         q = pushArgument(mb, q, sub->nr);
    1744             :                 if (rs) {
    1745             :                         q = pushArgument(mb, q, rs);
    1746             :                 } else {
    1747        1553 :                         q = pushArgument(mb, q, r1);
    1748        1553 :                         q = pushArgument(mb, q, r2);
    1749             :                 }
    1750        1553 :                 if (type == st_join2) {
    1751          59 :                         q = pushNil(mb, q, TYPE_bat);
    1752          59 :                         q = pushNil(mb, q, TYPE_bat);
    1753             :                 }
    1754             : 
    1755        1553 :                 switch (cmp & 3) {
    1756          54 :                 case 0:
    1757          54 :                         q = pushBit(mb, q, FALSE);
    1758          54 :                         q = pushBit(mb, q, FALSE);
    1759          54 :                         break;
    1760         222 :                 case 1:
    1761         222 :                         q = pushBit(mb, q, TRUE);
    1762         222 :                         q = pushBit(mb, q, FALSE);
    1763         222 :                         break;
    1764          16 :                 case 2:
    1765          16 :                         q = pushBit(mb, q, FALSE);
    1766          16 :                         q = pushBit(mb, q, TRUE);
    1767          16 :                         break;
    1768        1261 :                 case 3:
    1769        1261 :                         q = pushBit(mb, q, TRUE);
    1770        1261 :                         q = pushBit(mb, q, TRUE);
    1771        1261 :                         break;
    1772             :                 }
    1773        1553 :                 q = pushBit(mb, q, anti);
    1774        1553 :                 if (type == st_uselect2) {
    1775        1494 :                         q = pushBit(mb, q, TRUE); /* all nil's are != */
    1776             :                 } else {
    1777          59 :                         q = pushBit(mb, q, (symmetric)?TRUE:FALSE);
    1778             :                 }
    1779        1553 :                 if (type == st_join2)
    1780          59 :                         q = pushNil(mb, q, TYPE_lng); /* estimate */
    1781        1553 :                 if (q == NULL)
    1782             :                         return NULL;
    1783        1553 :                 if (swapped) {
    1784           1 :                         InstrPtr r = newInstruction(mb,  NULL, NULL);
    1785           1 :                         if (r == NULL)
    1786             :                                 return NULL;
    1787           1 :                         getArg(r, 0) = newTmpVariable(mb, TYPE_any);
    1788           1 :                         r = pushReturn(mb, r, newTmpVariable(mb, TYPE_any));
    1789           1 :                         r = pushArgument(mb, r, getArg(q,1));
    1790           1 :                         r = pushArgument(mb, r, getArg(q,0));
    1791           1 :                         pushInstruction(mb, r);
    1792             :                         q = r;
    1793             :                 }
    1794             :         }
    1795        4919 :         if (Sub)
    1796        4860 :                 *Sub = sub;
    1797             :         return q;
    1798             : }
    1799             : 
    1800             : stmt *
    1801        5078 : stmt_uselect2(backend *be, stmt *op1, stmt *op2, stmt *op3, int cmp, stmt *sub, int anti, int symmetric, int reduce)
    1802             : {
    1803        5078 :         stmt *sel = sub;
    1804        5078 :         InstrPtr q = select2_join2(be, op1, op2, op3, cmp, &sub, anti, symmetric, 0, st_uselect2, reduce);
    1805             : 
    1806        5078 :         if (q) {
    1807        5078 :                 stmt *s = stmt_create(be->mvc->sa, st_uselect2);
    1808        5078 :                 if (s == NULL) {
    1809           0 :                         freeInstruction(q);
    1810           0 :                         return NULL;
    1811             :                 }
    1812             : 
    1813        5078 :                 s->op1 = op1;
    1814        5078 :                 s->op2 = op2;
    1815        5078 :                 s->op3 = op3;
    1816        5078 :                 s->op4.stval = sub;
    1817        5078 :                 s->flag = cmp;
    1818        5078 :                 s->nrcols = op1->nrcols;
    1819        5078 :                 s->key = op1->nrcols == 0 && op2->nrcols == 0 && op3->nrcols == 0;
    1820        5078 :                 s->nr = getDestVar(q);
    1821        5078 :                 s->q = q;
    1822        5078 :                 s->cand = sub;
    1823        5078 :                 s->reduce = reduce;
    1824        5078 :                 if (!sub && sel) /* project back the old ids */
    1825        1406 :                         return stmt_project(be, s, sel);
    1826             :                 return s;
    1827             :         }
    1828             :         return NULL;
    1829             : }
    1830             : 
    1831             : stmt *
    1832       53707 : stmt_tunion(backend *be, stmt *op1, stmt *op2)
    1833             : {
    1834             :         InstrPtr q = NULL;
    1835       53707 :         MalBlkPtr mb = be->mb;
    1836             : 
    1837       53707 :         q = dump_2(mb, batRef, mergecandRef, op1, op2);
    1838       53707 :         if (q) {
    1839       53707 :                 stmt *s = stmt_create(be->mvc->sa, st_tunion);
    1840       53707 :                 if (s == NULL) {
    1841           0 :                         freeInstruction(q);
    1842           0 :                         return NULL;
    1843             :                 }
    1844             : 
    1845       53707 :                 s->op1 = op1;
    1846       53707 :                 s->op2 = op2;
    1847       53707 :                 s->nrcols = op1->nrcols;
    1848       53707 :                 s->key = op1->key;
    1849       53707 :                 s->aggr = op1->aggr;
    1850       53707 :                 s->nr = getDestVar(q);
    1851       53707 :                 s->q = q;
    1852       53707 :                 return s;
    1853             :         }
    1854             :         return NULL;
    1855             : }
    1856             : 
    1857             : stmt *
    1858       45119 : stmt_tdiff(backend *be, stmt *op1, stmt *op2, stmt *lcand)
    1859             : {
    1860             :         InstrPtr q = NULL;
    1861       45119 :         MalBlkPtr mb = be->mb;
    1862             : 
    1863       45119 :         if (op1->nr < 0 || op2->nr < 0)
    1864             :                 return NULL;
    1865       45119 :         q = newStmt(mb, algebraRef, differenceRef);
    1866       45119 :         q = pushArgument(mb, q, op1->nr); /* left */
    1867       45119 :         q = pushArgument(mb, q, op2->nr); /* right */
    1868       45119 :         if (lcand)
    1869           8 :                 q = pushArgument(mb, q, lcand->nr); /* left */
    1870             :         else
    1871       45111 :                 q = pushNil(mb, q, TYPE_bat); /* left candidate */
    1872       45119 :         q = pushNil(mb, q, TYPE_bat); /* right candidate */
    1873       45119 :         q = pushBit(mb, q, FALSE);    /* nil matches */
    1874       45119 :         q = pushBit(mb, q, FALSE);    /* do not clear nils */
    1875       45119 :         q = pushNil(mb, q, TYPE_lng); /* estimate */
    1876             : 
    1877       45119 :         if (q) {
    1878       45119 :                 stmt *s = stmt_create(be->mvc->sa, st_tdiff);
    1879       45119 :                 if (s == NULL) {
    1880           0 :                         freeInstruction(q);
    1881           0 :                         return NULL;
    1882             :                 }
    1883             : 
    1884       45119 :                 s->op1 = op1;
    1885       45119 :                 s->op2 = op2;
    1886       45119 :                 s->nrcols = op1->nrcols;
    1887       45119 :                 s->key = op1->key;
    1888       45119 :                 s->aggr = op1->aggr;
    1889       45119 :                 s->nr = getDestVar(q);
    1890       45119 :                 s->q = q;
    1891       45119 :                 return s;
    1892             :         }
    1893             :         return NULL;
    1894             : }
    1895             : 
    1896             : stmt *
    1897        2050 : stmt_tdiff2(backend *be, stmt *op1, stmt *op2, stmt *lcand)
    1898             : {
    1899             :         InstrPtr q = NULL;
    1900        2050 :         MalBlkPtr mb = be->mb;
    1901             : 
    1902        2050 :         if (op1->nr < 0 || op2->nr < 0)
    1903             :                 return NULL;
    1904        2050 :         q = newStmt(mb, algebraRef, differenceRef);
    1905        2050 :         q = pushArgument(mb, q, op1->nr); /* left */
    1906        2050 :         q = pushArgument(mb, q, op2->nr); /* right */
    1907        2050 :         if (lcand)
    1908           0 :                 q = pushArgument(mb, q, lcand->nr); /* left */
    1909             :         else
    1910        2050 :                 q = pushNil(mb, q, TYPE_bat); /* left candidate */
    1911        2050 :         q = pushNil(mb, q, TYPE_bat); /* right candidate */
    1912        2050 :         q = pushBit(mb, q, FALSE);     /* nil matches */
    1913        2050 :         q = pushBit(mb, q, TRUE);     /* not in */
    1914        2050 :         q = pushNil(mb, q, TYPE_lng); /* estimate */
    1915             : 
    1916        2050 :         if (q) {
    1917        2050 :                 stmt *s = stmt_create(be->mvc->sa, st_tdiff);
    1918        2050 :                 if (s == NULL) {
    1919           0 :                         freeInstruction(q);
    1920           0 :                         return NULL;
    1921             :                 }
    1922             : 
    1923        2050 :                 s->op1 = op1;
    1924        2050 :                 s->op2 = op2;
    1925        2050 :                 s->nrcols = op1->nrcols;
    1926        2050 :                 s->key = op1->key;
    1927        2050 :                 s->aggr = op1->aggr;
    1928        2050 :                 s->nr = getDestVar(q);
    1929        2050 :                 s->q = q;
    1930        2050 :                 return s;
    1931             :         }
    1932             :         return NULL;
    1933             : }
    1934             : 
    1935             : stmt *
    1936        1382 : stmt_tinter(backend *be, stmt *op1, stmt *op2, bool single)
    1937             : {
    1938             :         InstrPtr q = NULL;
    1939        1382 :         MalBlkPtr mb = be->mb;
    1940             : 
    1941        1382 :         if (op1->nr < 0 || op2->nr < 0)
    1942             :                 return NULL;
    1943        1382 :         q = newStmt(mb, algebraRef, intersectRef);
    1944        1382 :         q = pushArgument(mb, q, op1->nr); /* left */
    1945        1382 :         q = pushArgument(mb, q, op2->nr); /* right */
    1946        1382 :         q = pushNil(mb, q, TYPE_bat); /* left candidate */
    1947        1382 :         q = pushNil(mb, q, TYPE_bat); /* right candidate */
    1948        1382 :         q = pushBit(mb, q, FALSE);    /* nil matches */
    1949        1382 :         q = pushBit(mb, q, single?TRUE:FALSE);    /* max_one */
    1950        1382 :         q = pushNil(mb, q, TYPE_lng); /* estimate */
    1951             : 
    1952        1382 :         if (q) {
    1953        1382 :                 stmt *s = stmt_create(be->mvc->sa, st_tinter);
    1954        1382 :                 if (s == NULL) {
    1955           0 :                         freeInstruction(q);
    1956           0 :                         return NULL;
    1957             :                 }
    1958             : 
    1959        1382 :                 s->op1 = op1;
    1960        1382 :                 s->op2 = op2;
    1961        1382 :                 s->nrcols = op1->nrcols;
    1962        1382 :                 s->key = op1->key;
    1963        1382 :                 s->aggr = op1->aggr;
    1964        1382 :                 s->nr = getDestVar(q);
    1965        1382 :                 s->q = q;
    1966        1382 :                 return s;
    1967             :         }
    1968             :         return NULL;
    1969             : }
    1970             : 
    1971             : stmt *
    1972      133475 : stmt_join_cand(backend *be, stmt *op1, stmt *op2, stmt *lcand, stmt *rcand, int anti, comp_type cmptype, int need_left, int is_semantics, bool single)
    1973             : {
    1974      133475 :         MalBlkPtr mb = be->mb;
    1975             :         InstrPtr q = NULL;
    1976      133475 :         const char *sjt = joinRef;
    1977             : 
    1978             :         (void)anti;
    1979             : 
    1980      133475 :         if (need_left) {
    1981             :                 cmptype = cmp_equal;
    1982         649 :                 sjt = leftjoinRef;
    1983             :         }
    1984      133475 :         if (op1->nr < 0 || op2->nr < 0)
    1985             :                 return NULL;
    1986             : 
    1987      133475 :         assert (!single || cmptype == cmp_all);
    1988             : 
    1989      133475 :         switch (cmptype) {
    1990      113332 :         case mark_in:
    1991             :         case mark_notin: /* we use a anti join, todo handle null (not) in empty */
    1992             :         case cmp_equal:
    1993      113332 :                 q = newStmt(mb, algebraRef, sjt);
    1994      113332 :                 q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    1995      113332 :                 q = pushArgument(mb, q, op1->nr);
    1996      113332 :                 q = pushArgument(mb, q, op2->nr);
    1997      113332 :                 if (!lcand)
    1998      112248 :                         q = pushNil(mb, q, TYPE_bat);
    1999             :                 else
    2000        1084 :                         q = pushArgument(mb, q, lcand->nr);
    2001      113332 :                 if (!rcand)
    2002      113332 :                         q = pushNil(mb, q, TYPE_bat);
    2003             :                 else
    2004           0 :                         q = pushArgument(mb, q, rcand->nr);
    2005      113332 :                 q = pushBit(mb, q, is_semantics?TRUE:FALSE);
    2006      113332 :                 q = pushNil(mb, q, TYPE_lng);
    2007      113332 :                 if (q == NULL)
    2008             :                         return NULL;
    2009             :                 break;
    2010          40 :         case cmp_notequal:
    2011          40 :                 q = newStmtArgs(mb, algebraRef, thetajoinRef, 9);
    2012          40 :                 q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    2013          40 :                 q = pushArgument(mb, q, op1->nr);
    2014          40 :                 q = pushArgument(mb, q, op2->nr);
    2015          40 :                 if (!lcand)
    2016          40 :                         q = pushNil(mb, q, TYPE_bat);
    2017             :                 else
    2018           0 :                         q = pushArgument(mb, q, lcand->nr);
    2019          40 :                 if (!rcand)
    2020          40 :                         q = pushNil(mb, q, TYPE_bat);
    2021             :                 else
    2022           0 :                         q = pushArgument(mb, q, rcand->nr);
    2023          40 :                 q = pushInt(mb, q, JOIN_NE);
    2024          40 :                 q = pushBit(mb, q, is_semantics?TRUE:FALSE);
    2025          40 :                 q = pushNil(mb, q, TYPE_lng);
    2026          40 :                 if (q == NULL)
    2027             :                         return NULL;
    2028             :                 break;
    2029        2844 :         case cmp_lt:
    2030             :         case cmp_lte:
    2031             :         case cmp_gt:
    2032             :         case cmp_gte:
    2033        2844 :                 q = newStmtArgs(mb, algebraRef, thetajoinRef, 9);
    2034        2844 :                 q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    2035        2844 :                 q = pushArgument(mb, q, op1->nr);
    2036        2844 :                 q = pushArgument(mb, q, op2->nr);
    2037        2844 :                 if (!lcand)
    2038        2844 :                         q = pushNil(mb, q, TYPE_bat);
    2039             :                 else
    2040           0 :                         q = pushArgument(mb, q, lcand->nr);
    2041        2844 :                 if (!rcand)
    2042        2844 :                         q = pushNil(mb, q, TYPE_bat);
    2043             :                 else
    2044           0 :                         q = pushArgument(mb, q, rcand->nr);
    2045        2844 :                 if (cmptype == cmp_lt)
    2046        1068 :                         q = pushInt(mb, q, JOIN_LT);
    2047        1776 :                 else if (cmptype == cmp_lte)
    2048           7 :                         q = pushInt(mb, q, JOIN_LE);
    2049        1769 :                 else if (cmptype == cmp_gt)
    2050        1764 :                         q = pushInt(mb, q, JOIN_GT);
    2051           5 :                 else if (cmptype == cmp_gte)
    2052           5 :                         q = pushInt(mb, q, JOIN_GE);
    2053        2844 :                 q = pushBit(mb, q, is_semantics?TRUE:FALSE);
    2054        2844 :                 q = pushNil(mb, q, TYPE_lng);
    2055        2844 :                 if (q == NULL)
    2056             :                         return NULL;
    2057             :                 break;
    2058       13612 :         case cmp_all:   /* aka cross table */
    2059       13612 :                 q = newStmt(mb, algebraRef, crossRef);
    2060       13612 :                 q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    2061       13612 :                 q = pushArgument(mb, q, op1->nr);
    2062       13612 :                 q = pushArgument(mb, q, op2->nr);
    2063       13612 :                 q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
    2064       13612 :                 assert(!lcand && !rcand);
    2065       13612 :                 if (q == NULL)
    2066             :                         return NULL;
    2067             :                 break;
    2068        3647 :         case cmp_joined:
    2069        3647 :                 q = op1->q;
    2070        3647 :                 break;
    2071           0 :         default:
    2072           0 :                 TRC_ERROR(SQL_EXECUTION, "Impossible action\n");
    2073             :         }
    2074      133475 :         if (q) {
    2075      133475 :                 stmt *s = stmt_create(be->mvc->sa, st_join);
    2076      133475 :                 if (s == NULL) {
    2077           0 :                         freeInstruction(q);
    2078           0 :                         return NULL;
    2079             :                 }
    2080             : 
    2081      133475 :                 s->op1 = op1;
    2082      133475 :                 s->op2 = op2;
    2083      133475 :                 s->flag = cmptype;
    2084      133475 :                 s->key = 0;
    2085      133475 :                 s->nrcols = 2;
    2086      133475 :                 s->nr = getDestVar(q);
    2087      133475 :                 s->q = q;
    2088      133475 :                 return s;
    2089             :         }
    2090             :         return NULL;
    2091             : }
    2092             : 
    2093             : stmt *
    2094      131539 : stmt_join(backend *be, stmt *l, stmt *r, int anti, comp_type cmptype, int need_left, int is_semantics, bool single)
    2095             : {
    2096      131539 :         return stmt_join_cand(be, l, r, NULL, NULL, anti, cmptype, need_left, is_semantics, single);
    2097             : }
    2098             : 
    2099             : stmt *
    2100        1439 : stmt_semijoin(backend *be, stmt *op1, stmt *op2, stmt *lcand, stmt *rcand, int is_semantics, bool single)
    2101             : {
    2102        1439 :         MalBlkPtr mb = be->mb;
    2103             :         InstrPtr q = NULL;
    2104             : 
    2105        1439 :         if (op1->nr < 0 || op2->nr < 0)
    2106             :                 return NULL;
    2107             : 
    2108        1439 :         if (single) {
    2109         268 :                 q = newStmtArgs(mb, algebraRef, semijoinRef, 9);
    2110         268 :                 q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    2111             :         } else
    2112        1171 :                 q = newStmt(mb, algebraRef, intersectRef);
    2113        1439 :         q = pushArgument(mb, q, op1->nr);
    2114        1439 :         q = pushArgument(mb, q, op2->nr);
    2115        1439 :         if (lcand)
    2116        1171 :                 q = pushArgument(mb, q, lcand->nr);
    2117             :         else
    2118         268 :                 q = pushNil(mb, q, TYPE_bat);
    2119        1439 :         if (rcand)
    2120           0 :                 q = pushArgument(mb, q, rcand->nr);
    2121             :         else
    2122        1439 :                 q = pushNil(mb, q, TYPE_bat);
    2123        1439 :         q = pushBit(mb, q, is_semantics?TRUE:FALSE);
    2124        1439 :         q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
    2125        1439 :         q = pushNil(mb, q, TYPE_lng);
    2126        1439 :         if (q == NULL)
    2127             :                 return NULL;
    2128             : 
    2129        1439 :         stmt *s = stmt_create(be->mvc->sa, st_semijoin);
    2130        1439 :         if (s == NULL) {
    2131           0 :                 freeInstruction(q);
    2132           0 :                 return NULL;
    2133             :         }
    2134             : 
    2135        1439 :         s->op1 = op1;
    2136        1439 :         s->op2 = op2;
    2137        1439 :         s->flag = cmp_equal;
    2138        1439 :         s->key = 0;
    2139        1439 :         s->nrcols = 1;
    2140        1439 :         if (single)
    2141         268 :                 s->nrcols = 2;
    2142        1439 :         s->nr = getDestVar(q);
    2143        1439 :         s->q = q;
    2144        1439 :         return s;
    2145             : }
    2146             : 
    2147             : static InstrPtr
    2148     3952224 : stmt_project_join(backend *be, stmt *op1, stmt *op2, bool delta)
    2149             : {
    2150     3952224 :         MalBlkPtr mb = be->mb;
    2151             :         InstrPtr q = NULL;
    2152             : 
    2153     3952224 :         if (op1->nr < 0 || op2->nr < 0)
    2154             :                 return NULL;
    2155             :         /* delta bat */
    2156     3952224 :         if (delta) {
    2157      485534 :                 int uval = getArg(op2->q, 1);
    2158             : 
    2159      485534 :                 q = newStmt(mb, sqlRef, deltaRef);
    2160      485534 :                 q = pushArgument(mb, q, op1->nr);
    2161      485534 :                 q = pushArgument(mb, q, op2->nr);
    2162      485534 :                 q = pushArgument(mb, q, uval);
    2163             :         } else {
    2164             :                 /* projections, ie left is void headed */
    2165     3466690 :                 q = newStmt(mb, algebraRef, projectionRef);
    2166     3466690 :                 q = pushArgument(mb, q, op1->nr);
    2167     3466690 :                 q = pushArgument(mb, q, op2->nr);
    2168     3466690 :                 if (q == NULL)
    2169           0 :                         return NULL;
    2170             :         }
    2171             :         return q;
    2172             : }
    2173             : 
    2174             : stmt *
    2175     3467858 : stmt_project(backend *be, stmt *op1, stmt *op2)
    2176             : {
    2177     3467858 :         if (!op2->nrcols)
    2178        1168 :                 return stmt_const(be, op1, op2);
    2179     3466690 :         InstrPtr q = stmt_project_join(be, op1, op2, false);
    2180     3466690 :         if (q) {
    2181     3466690 :                 stmt *s = stmt_create(be->mvc->sa, st_join);
    2182     3466689 :                 if (s == NULL) {
    2183           0 :                         freeInstruction(q);
    2184           0 :                         return NULL;
    2185             :                 }
    2186             : 
    2187     3466689 :                 s->op1 = op1;
    2188     3466689 :                 s->op2 = op2;
    2189     3466689 :                 s->flag = cmp_project;
    2190     3466689 :                 s->key = 0;
    2191     3466689 :                 s->nrcols = MAX(op1->nrcols,op2->nrcols);
    2192     3466689 :                 s->nr = getDestVar(q);
    2193     3466689 :                 s->q = q;
    2194     3466689 :                 s->tname = op2->tname;
    2195     3466689 :                 s->cname = op2->cname;
    2196     3466689 :                 return s;
    2197             :         }
    2198             :         return NULL;
    2199             : }
    2200             : 
    2201             : stmt *
    2202      485534 : stmt_project_delta(backend *be, stmt *col, stmt *upd)
    2203             : {
    2204      485534 :         InstrPtr q = stmt_project_join(be, col, upd, true);
    2205      485534 :         if (q) {
    2206      485534 :                 stmt *s = stmt_create(be->mvc->sa, st_join);
    2207      485534 :                 if (s == NULL) {
    2208           0 :                         freeInstruction(q);
    2209           0 :                         return NULL;
    2210             :                 }
    2211             : 
    2212      485534 :                 s->op1 = col;
    2213      485534 :                 s->op2 = upd;
    2214      485534 :                 s->flag = cmp_project;
    2215      485534 :                 s->key = 0;
    2216      485534 :                 s->nrcols = 2;
    2217      485534 :                 s->nr = getDestVar(q);
    2218      485534 :                 s->q = q;
    2219      485534 :                 s->tname = col->tname;
    2220      485534 :                 s->cname = col->cname;
    2221      485534 :                 return s;
    2222             :         }
    2223             :         return NULL;
    2224             : }
    2225             : 
    2226             : stmt *
    2227          43 : stmt_left_project(backend *be, stmt *op1, stmt *op2, stmt *op3)
    2228             : {
    2229          43 :         MalBlkPtr mb = be->mb;
    2230             :         InstrPtr q = NULL;
    2231          43 :         if (op1->nr < 0 || op2->nr < 0 || op3->nr < 0)
    2232             :                 return NULL;
    2233             : 
    2234          43 :         q = newStmt(mb, sqlRef, projectRef);
    2235          43 :         q = pushArgument(mb, q, op1->nr);
    2236          43 :         q = pushArgument(mb, q, op2->nr);
    2237          43 :         q = pushArgument(mb, q, op3->nr);
    2238             : 
    2239          43 :         if (q){
    2240          43 :                 stmt *s = stmt_create(be->mvc->sa, st_join);
    2241          43 :                 if (s == NULL) {
    2242           0 :                         freeInstruction(q);
    2243           0 :                         return NULL;
    2244             :                 }
    2245             : 
    2246          43 :                 s->op1 = op1;
    2247          43 :                 s->op2 = op2;
    2248          43 :                 s->op3 = op3;
    2249          43 :                 s->flag = cmp_left_project;
    2250          43 :                 s->key = 0;
    2251          43 :                 s->nrcols = 2;
    2252          43 :                 s->nr = getDestVar(q);
    2253          43 :                 s->q = q;
    2254          43 :                 return s;
    2255             :         }
    2256             :         return NULL;
    2257             : }
    2258             : 
    2259             : stmt *
    2260          59 : stmt_join2(backend *be, stmt *l, stmt *ra, stmt *rb, int cmp, int anti, int symmetric, int swapped)
    2261             : {
    2262          59 :         InstrPtr q = select2_join2(be, l, ra, rb, cmp, NULL, anti, symmetric, swapped, st_join2, 1/*reduce semantics*/);
    2263          59 :         if (q) {
    2264          59 :                 stmt *s = stmt_create(be->mvc->sa, st_join2);
    2265          59 :                 if (s == NULL) {
    2266           0 :                         freeInstruction(q);
    2267           0 :                         return NULL;
    2268             :                 }
    2269             : 
    2270          59 :                 s->op1 = l;
    2271          59 :                 s->op2 = ra;
    2272          59 :                 s->op3 = rb;
    2273          59 :                 s->flag = cmp;
    2274          59 :                 s->nrcols = 2;
    2275          59 :                 s->nr = getDestVar(q);
    2276          59 :                 s->q = q;
    2277          59 :                 s->reduce = 1;
    2278          59 :                 return s;
    2279             :         }
    2280             :         return NULL;
    2281             : }
    2282             : 
    2283             : stmt *
    2284          20 : stmt_genjoin(backend *be, stmt *l, stmt *r, sql_subfunc *op, int anti, int swapped)
    2285             : {
    2286          20 :         MalBlkPtr mb = be->mb;
    2287             :         InstrPtr q = NULL;
    2288             :         const char *mod, *fimp;
    2289             :         node *n;
    2290             : 
    2291          20 :         if (backend_create_subfunc(be, op, NULL) < 0)
    2292             :                 return NULL;
    2293          20 :         mod = sql_func_mod(op->func);
    2294          20 :         fimp = sql_func_imp(op->func);
    2295          20 :         fimp = sa_strconcat(be->mvc->sa, fimp, "join");
    2296             : 
    2297             :         /* filter qualifying tuples, return oids of h and tail */
    2298          20 :         q = newStmtArgs(mb, mod, fimp, list_length(l->op4.lval) + list_length(r->op4.lval) + 7);
    2299          20 :         q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
    2300          40 :         for (n = l->op4.lval->h; n; n = n->next) {
    2301          20 :                 stmt *op = n->data;
    2302             : 
    2303          20 :                 q = pushArgument(mb, q, op->nr);
    2304             :         }
    2305             : 
    2306          80 :         for (n = r->op4.lval->h; n; n = n->next) {
    2307          60 :                 stmt *op = n->data;
    2308             : 
    2309          60 :                 q = pushArgument(mb, q, op->nr);
    2310             :         }
    2311          20 :         q = pushNil(mb, q, TYPE_bat); /* candidate lists */
    2312          20 :         q = pushNil(mb, q, TYPE_bat); /* candidate lists */
    2313          20 :         q = pushBit(mb, q, TRUE);     /* nil_matches */
    2314          20 :         q = pushNil(mb, q, TYPE_lng); /* estimate */
    2315          20 :         q = pushBit(mb, q, anti?TRUE:FALSE); /* 'not' matching */
    2316             : 
    2317          20 :         if (swapped) {
    2318           4 :                 InstrPtr r = newInstruction(mb,  NULL, NULL);
    2319           4 :                 if (r == NULL)
    2320             :                         return NULL;
    2321           4 :                 getArg(r, 0) = newTmpVariable(mb, TYPE_any);
    2322           4 :                 r = pushReturn(mb, r, newTmpVariable(mb, TYPE_any));
    2323           4 :                 r = pushArgument(mb, r, getArg(q,1));
    2324           4 :                 r = pushArgument(mb, r, getArg(q,0));
    2325           4 :                 pushInstruction(mb, r);
    2326             :                 q = r;
    2327             :         }
    2328             : 
    2329          20 :         if (q) {
    2330          20 :                 stmt *s = stmt_create(be->mvc->sa, st_joinN);
    2331          20 :                 if (s == NULL) {
    2332           0 :                         freeInstruction(q);
    2333           0 :                         return NULL;
    2334             :                 }
    2335             : 
    2336          20 :                 s->op1 = l;
    2337          20 :                 s->op2 = r;
    2338          20 :                 s->op4.funcval = op;
    2339          20 :                 s->nrcols = 2;
    2340          20 :                 if (swapped)
    2341           4 :                         s->flag |= SWAPPED;
    2342          20 :                 s->nr = getDestVar(q);
    2343          20 :                 s->q = q;
    2344          20 :                 return s;
    2345             :         }
    2346             :         return NULL;
    2347             : }
    2348             : 
    2349             : stmt *
    2350       25753 : stmt_rs_column(backend *be, stmt *rs, int i, sql_subtype *tpe)
    2351             : {
    2352             :         InstrPtr q = NULL;
    2353             : 
    2354       25753 :         if (rs->nr < 0)
    2355             :                 return NULL;
    2356       25753 :         q = rs->q;
    2357       25753 :         if (q) {
    2358       25753 :                 stmt *s = stmt_create(be->mvc->sa, st_rs_column);
    2359       25753 :                 if (s == NULL) {
    2360           0 :                         freeInstruction(q);
    2361           0 :                         return NULL;
    2362             :                 }
    2363             : 
    2364       25753 :                 s->op1 = rs;
    2365       25753 :                 s->op4.typeval = *tpe;
    2366       25753 :                 s->flag = i;
    2367       25753 :                 s->nrcols = 1;
    2368       25753 :                 s->key = 0;
    2369       25753 :                 s->q = q;
    2370       25753 :                 s->nr = getArg(q, s->flag);
    2371       25753 :                 return s;
    2372             :         }
    2373             :         return NULL;
    2374             : }
    2375             : 
    2376             : /*
    2377             :  * The dump_header produces a sequence of instructions for
    2378             :  * the front-end to prepare presentation of a result table.
    2379             :  *
    2380             :  * A secondary scheme is added to assemblt all information
    2381             :  * in columns first. Then it can be returned to the environment.
    2382             :  */
    2383             : #define NEWRESULTSET
    2384             : 
    2385             : #define meta(P, Id, Tpe, Args)                                          \
    2386             :         do {                                                                                    \
    2387             :                 P = newStmtArgs(mb, batRef, packRef, Args);     \
    2388             :                 Id = getArg(P,0);                                                       \
    2389             :                 setVarType(mb, Id, newBatType(Tpe));            \
    2390             :                 setVarFixed(mb, Id);                                            \
    2391             :                 list = pushArgument(mb, list, Id);                      \
    2392             :         } while (0)
    2393             : 
    2394             : #define metaInfo(P,Tpe,Val)                                             \
    2395             :         do {                                                                            \
    2396             :                 P = push##Tpe(mb, P, Val);                              \
    2397             :         } while (0)
    2398             : 
    2399             : 
    2400             : static int
    2401          12 : dump_export_header(mvc *sql, MalBlkPtr mb, list *l, int file, const char * format, const char * sep,const char * rsep,const char * ssep,const char * ns, int onclient)
    2402             : {
    2403             :         node *n;
    2404             :         bool error = false;
    2405             :         int ret = -1;
    2406             :         int args;
    2407             : 
    2408             :         // gather the meta information
    2409             :         int tblId, nmeId, tpeId, lenId, scaleId;
    2410             :         InstrPtr list;
    2411             :         InstrPtr tblPtr, nmePtr, tpePtr, lenPtr, scalePtr;
    2412             : 
    2413          12 :         args = list_length(l) + 1;
    2414             : 
    2415          12 :         list = newInstructionArgs(mb, sqlRef, export_tableRef, args + 13);
    2416          12 :         getArg(list,0) = newTmpVariable(mb,TYPE_int);
    2417          12 :         if( file >= 0){
    2418          12 :                 list = pushArgument(mb, list, file);
    2419          12 :                 list = pushStr(mb, list, format);
    2420          12 :                 list = pushStr(mb, list, sep);
    2421          12 :                 list = pushStr(mb, list, rsep);
    2422          12 :                 list = pushStr(mb, list, ssep);
    2423          12 :                 list = pushStr(mb, list, ns);
    2424          12 :                 list = pushInt(mb, list, onclient);
    2425             :         }
    2426          12 :         meta(tblPtr, tblId, TYPE_str, args);
    2427          12 :         meta(nmePtr, nmeId, TYPE_str, args);
    2428          12 :         meta(tpePtr, tpeId, TYPE_str, args);
    2429          12 :         meta(lenPtr, lenId, TYPE_int, args);
    2430          12 :         meta(scalePtr, scaleId, TYPE_int, args);
    2431             :         if(tblPtr == NULL || nmePtr == NULL || tpePtr == NULL || lenPtr == NULL || scalePtr == NULL)
    2432             :                 return -1;
    2433             : 
    2434          36 :         for (n = l->h; n; n = n->next) {
    2435          24 :                 stmt *c = n->data;
    2436          24 :                 sql_subtype *t = tail_type(c);
    2437          24 :                 const char *tname = table_name(sql->sa, c);
    2438          24 :                 const char *sname = schema_name(sql->sa, c);
    2439             :                 const char *_empty = "";
    2440          24 :                 const char *tn = (tname) ? tname : _empty;
    2441          24 :                 const char *sn = (sname) ? sname : _empty;
    2442          24 :                 const char *cn = column_name(sql->sa, c);
    2443          24 :                 const char *ntn = sql_escape_ident(sql->ta, tn);
    2444          24 :                 const char *nsn = sql_escape_ident(sql->ta, sn);
    2445             :                 size_t fqtnl;
    2446             :                 char *fqtn = NULL;
    2447             : 
    2448          24 :                 if (ntn && nsn && (fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1) ){
    2449          24 :                         fqtn = SA_NEW_ARRAY(sql->ta, char, fqtnl);
    2450          24 :                         if(fqtn) {
    2451          24 :                                 snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
    2452          24 :                                 metaInfo(tblPtr, Str, fqtn);
    2453          24 :                                 metaInfo(nmePtr, Str, cn);
    2454          24 :                                 metaInfo(tpePtr, Str, (t->type->localtype == TYPE_void ? "char" : t->type->base.name));
    2455          24 :                                 metaInfo(lenPtr, Int, t->digits);
    2456          24 :                                 metaInfo(scalePtr, Int, t->scale);
    2457          24 :                                 list = pushArgument(mb, list, c->nr);
    2458             :                         } else
    2459             :                                 error = true;
    2460             :                 } else
    2461             :                         error = true;
    2462          24 :                 if(error)
    2463             :                         return -1;
    2464             :         }
    2465          12 :         sa_reset(sql->ta);
    2466          12 :         ret = getArg(list,0);
    2467          12 :         pushInstruction(mb,list);
    2468          12 :         return ret;
    2469             : }
    2470             : 
    2471             : 
    2472             : stmt *
    2473          12 : stmt_export(backend *be, stmt *t, const char *sep, const char *rsep, const char *ssep, const char *null_string, int onclient, stmt *file)
    2474             : {
    2475          12 :         MalBlkPtr mb = be->mb;
    2476             :         InstrPtr q = NULL;
    2477             :         int fnr;
    2478             :         list *l;
    2479             : 
    2480          12 :         if (t->nr < 0)
    2481             :                 return NULL;
    2482          12 :         l = t->op4.lval;
    2483          12 :         if (file) {
    2484           3 :                 if (file->nr < 0)
    2485             :                         return NULL;
    2486             :                 fnr = file->nr;
    2487             :         } else {
    2488           9 :                 q = newAssignment(mb);
    2489           9 :                 q = pushStr(mb,q,"stdout");
    2490           9 :                 fnr = getArg(q,0);
    2491             :         }
    2492          12 :         if (t->type == st_list) {
    2493          12 :                 if (dump_export_header(be->mvc, mb, l, fnr, "csv", sep, rsep, ssep, null_string, onclient) < 0)
    2494             :                         return NULL;
    2495             :         } else {
    2496           0 :                 q = newStmt(mb, sqlRef, raiseRef);
    2497           0 :                 q = pushStr(mb, q, "not a valid output list\n");
    2498           0 :                 if (q == NULL)
    2499             :                         return NULL;
    2500             :         }
    2501          12 :         if (q) {
    2502           9 :                 stmt *s = stmt_create(be->mvc->sa, st_export);
    2503           9 :                 if(!s) {
    2504           0 :                         freeInstruction(q);
    2505           0 :                         return NULL;
    2506             :                 }
    2507           9 :                 s->op1 = t;
    2508           9 :                 s->op2 = file;
    2509           9 :                 s->q = q;
    2510           9 :                 s->nr = 1;
    2511           9 :                 return s;
    2512             :         }
    2513             :         return NULL;
    2514             : }
    2515             : 
    2516             : stmt *
    2517        2687 : stmt_trans(backend *be, int type, stmt *chain, stmt *name)
    2518             : {
    2519        2687 :         MalBlkPtr mb = be->mb;
    2520             :         InstrPtr q = NULL;
    2521             : 
    2522        2687 :         if (chain->nr < 0)
    2523             :                 return NULL;
    2524             : 
    2525        2687 :         switch(type){
    2526          13 :         case ddl_release:
    2527          13 :                 q = newStmt(mb, sqlRef, transaction_releaseRef);
    2528          13 :                 break;
    2529         423 :         case ddl_commit:
    2530         423 :                 q = newStmt(mb, sqlRef, transaction_commitRef);
    2531         423 :                 break;
    2532         974 :         case ddl_rollback:
    2533         974 :                 q = newStmt(mb, sqlRef, transaction_rollbackRef);
    2534         974 :                 break;
    2535        1277 :         case ddl_trans:
    2536        1277 :                 q = newStmt(mb, sqlRef, transaction_beginRef);
    2537        1277 :                 break;
    2538           0 :         default:
    2539           0 :                 TRC_ERROR(SQL_EXECUTION, "Unknown transaction type\n");
    2540             :         }
    2541        2687 :         q = pushArgument(mb, q, chain->nr);
    2542        2687 :         if (name)
    2543          61 :                 q = pushArgument(mb, q, name->nr);
    2544             :         else
    2545        2626 :                 q = pushNil(mb, q, TYPE_str);
    2546        2687 :         if (q) {
    2547        2687 :                 stmt *s = stmt_create(be->mvc->sa, st_trans);
    2548        2687 :                 if(!s) {
    2549           0 :                         freeInstruction(q);
    2550           0 :                         return NULL;
    2551             :                 }
    2552        2687 :                 s->op1 = chain;
    2553        2687 :                 s->op2 = name;
    2554        2687 :                 s->flag = type;
    2555        2687 :                 s->q = q;
    2556        2687 :                 s->nr = getDestVar(q);
    2557        2687 :                 return s;
    2558             :         }
    2559             :         return NULL;
    2560             : }
    2561             : 
    2562             : stmt *
    2563      203710 : stmt_catalog(backend *be, int type, stmt *args)
    2564             : {
    2565      203710 :         MalBlkPtr mb = be->mb;
    2566             :         InstrPtr q = NULL;
    2567             :         node *n;
    2568             : 
    2569      203710 :         if (args->nr < 0)
    2570             :                 return NULL;
    2571             : 
    2572             :         /* cast them into properly named operations */
    2573             :         const char *ref;
    2574      203710 :         switch(type){
    2575         294 :         case ddl_create_seq:                    ref = create_seqRef;            break;
    2576          43 :         case ddl_alter_seq:                             ref = alter_seqRef;                     break;
    2577          31 :         case ddl_drop_seq:                              ref = drop_seqRef;                      break;
    2578        1091 :         case ddl_create_schema:                 ref = create_schemaRef;         break;
    2579         159 :         case ddl_drop_schema:                   ref = drop_schemaRef;           break;
    2580        8321 :         case ddl_create_table:                  ref = create_tableRef;          break;
    2581       16617 :         case ddl_create_view:                   ref = create_viewRef;           break;
    2582        3137 :         case ddl_drop_table:                    ref = drop_tableRef;            break;
    2583         672 :         case ddl_drop_view:                             ref = drop_viewRef;                     break;
    2584         146 :         case ddl_drop_constraint:               ref = drop_constraintRef;       break;
    2585        1278 :         case ddl_alter_table:                   ref = alter_tableRef;           break;
    2586         749 :         case ddl_create_type:                   ref = create_typeRef;           break;
    2587           1 :         case ddl_drop_type:                             ref = drop_typeRef;                     break;
    2588          36 :         case ddl_grant_roles:                   ref = grant_rolesRef;           break;
    2589          10 :         case ddl_revoke_roles:                  ref = revoke_rolesRef;          break;
    2590        9435 :         case ddl_grant:                                 ref = grantRef;                         break;
    2591          15 :         case ddl_revoke:                                ref = revokeRef;                        break;
    2592       65999 :         case ddl_grant_func:                    ref = grant_functionRef;        break;
    2593           1 :         case ddl_revoke_func:                   ref = revoke_functionRef;       break;
    2594         272 :         case ddl_create_user:                   ref = create_userRef;           break;
    2595          79 :         case ddl_drop_user:                             ref = drop_userRef;                     break;
    2596          59 :         case ddl_alter_user:                    ref = alter_userRef;            break;
    2597           5 :         case ddl_rename_user:                   ref = rename_userRef;           break;
    2598          21 :         case ddl_create_role:                   ref = create_roleRef;           break;
    2599          18 :         case ddl_drop_role:                             ref = drop_roleRef;                     break;
    2600         132 :         case ddl_drop_index:                    ref = drop_indexRef;            break;
    2601         851 :         case ddl_drop_function:                 ref = drop_functionRef;         break;
    2602       91346 :         case ddl_create_function:               ref = create_functionRef;       break;
    2603         480 :         case ddl_create_trigger:                ref = create_triggerRef;        break;
    2604          80 :         case ddl_drop_trigger:                  ref = drop_triggerRef;          break;
    2605         206 :         case ddl_alter_table_add_table: ref = alter_add_tableRef;       break;
    2606         149 :         case ddl_alter_table_del_table: ref = alter_del_tableRef;       break;
    2607        1572 :         case ddl_alter_table_set_access:ref = alter_set_tableRef;       break;
    2608         198 :         case ddl_alter_table_add_range_partition: ref = alter_add_range_partitionRef; break;
    2609          53 :         case ddl_alter_table_add_list_partition: ref = alter_add_value_partitionRef; break;
    2610          89 :         case ddl_comment_on:                    ref = comment_onRef;            break;
    2611           7 :         case ddl_rename_schema:                 ref = rename_schemaRef;         break;
    2612          45 :         case ddl_rename_table:                  ref = rename_tableRef;          break;
    2613          13 :         case ddl_rename_column:                 ref = rename_columnRef;         break;
    2614           0 :         default:
    2615           0 :                 TRC_ERROR(SQL_EXECUTION, "Unknown catalog operation\n");
    2616           0 :                 return NULL;
    2617             :         }
    2618      203710 :         q = newStmtArgs(mb, sqlcatalogRef, ref, list_length(args->op4.lval) + 1);
    2619             :         // pass all arguments as before
    2620     1197817 :         for (n = args->op4.lval->h; n; n = n->next) {
    2621      994107 :                 stmt *c = n->data;
    2622             : 
    2623      994107 :                 q = pushArgument(mb, q, c->nr);
    2624             :         }
    2625      203710 :         if (q) {
    2626      203710 :                 stmt *s = stmt_create(be->mvc->sa, st_catalog);
    2627      203710 :                 if(!s) {
    2628           0 :                         freeInstruction(q);
    2629           0 :                         return NULL;
    2630             :                 }
    2631      203710 :                 s->op1 = args;
    2632      203710 :                 s->flag = type;
    2633      203710 :                 s->q = q;
    2634      203710 :                 s->nr = getDestVar(q);
    2635      203710 :                 return s;
    2636             :         }
    2637             :         return NULL;
    2638             : }
    2639             : 
    2640             : void
    2641     1645747 : stmt_set_nrcols(stmt *s)
    2642             : {
    2643             :         unsigned nrcols = 0;
    2644             :         int key = 1;
    2645             :         node *n;
    2646     1645747 :         list *l = s->op4.lval;
    2647             : 
    2648     1645747 :         assert(s->type == st_list);
    2649     8735831 :         for (n = l->h; n; n = n->next) {
    2650     7090084 :                 stmt *f = n->data;
    2651             : 
    2652     7090084 :                 if (!f)
    2653           0 :                         continue;
    2654     7090084 :                 if (f->nrcols > nrcols)
    2655             :                         nrcols = f->nrcols;
    2656     7090084 :                 key &= f->key;
    2657     7090084 :                 s->nr = f->nr;
    2658             :         }
    2659     1645747 :         s->nrcols = nrcols;
    2660     1645747 :         s->key = key;
    2661     1645747 : }
    2662             : 
    2663             : stmt *
    2664     1346666 : stmt_list(backend *be, list *l)
    2665             : {
    2666     1346666 :         stmt *s = stmt_create(be->mvc->sa, st_list);
    2667     1346666 :         if(!s) {
    2668             :                 return NULL;
    2669             :         }
    2670     1346666 :         s->op4.lval = l;
    2671     1346666 :         stmt_set_nrcols(s);
    2672     1346666 :         return s;
    2673             : }
    2674             : 
    2675             : static InstrPtr
    2676       50100 : dump_header(mvc *sql, MalBlkPtr mb, list *l)
    2677             : {
    2678             :         node *n;
    2679             :         bool error = false;
    2680             :         // gather the meta information
    2681             :         int tblId, nmeId, tpeId, lenId, scaleId;
    2682             :         int args;
    2683             :         InstrPtr list;
    2684             :         InstrPtr tblPtr, nmePtr, tpePtr, lenPtr, scalePtr;
    2685             : 
    2686       50100 :         args = list_length(l) + 1;
    2687             : 
    2688       50100 :         list = newInstructionArgs(mb,sqlRef, resultSetRef, args + 5);
    2689       50100 :         if(!list) {
    2690             :                 return NULL;
    2691             :         }
    2692       50100 :         getArg(list,0) = newTmpVariable(mb,TYPE_int);
    2693       50100 :         meta(tblPtr, tblId, TYPE_str, args);
    2694       50100 :         meta(nmePtr, nmeId, TYPE_str, args);
    2695       50100 :         meta(tpePtr, tpeId, TYPE_str, args);
    2696       50100 :         meta(lenPtr, lenId, TYPE_int, args);
    2697       50100 :         meta(scalePtr, scaleId, TYPE_int, args);
    2698             :         if(tblPtr == NULL || nmePtr == NULL || tpePtr == NULL || lenPtr == NULL || scalePtr == NULL)
    2699             :                 return NULL;
    2700             : 
    2701      271869 :         for (n = l->h; n; n = n->next) {
    2702      221769 :                 stmt *c = n->data;
    2703      221769 :                 sql_subtype *t = tail_type(c);
    2704      221769 :                 const char *tname = table_name(sql->sa, c);
    2705      221769 :                 const char *sname = schema_name(sql->sa, c);
    2706             :                 const char *_empty = "";
    2707      221769 :                 const char *tn = (tname) ? tname : _empty;
    2708      221769 :                 const char *sn = (sname) ? sname : _empty;
    2709      221769 :                 const char *cn = column_name(sql->sa, c);
    2710      221769 :                 const char *ntn = sql_escape_ident(sql->ta, tn);
    2711      221769 :                 const char *nsn = sql_escape_ident(sql->ta, sn);
    2712             :                 size_t fqtnl;
    2713             :                 char *fqtn = NULL;
    2714             : 
    2715      221769 :                 if (ntn && nsn && (fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1) ){
    2716      221769 :                         fqtn = SA_NEW_ARRAY(sql->ta, char, fqtnl);
    2717      221769 :                         if(fqtn) {
    2718      221769 :                                 snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
    2719      221769 :                                 metaInfo(tblPtr,Str,fqtn);
    2720      221769 :                                 metaInfo(nmePtr,Str,cn);
    2721      221769 :                                 metaInfo(tpePtr,Str,(t->type->localtype == TYPE_void ? "char" : t->type->base.name));
    2722      221769 :                                 metaInfo(lenPtr,Int,t->digits);
    2723      221769 :                                 metaInfo(scalePtr,Int,t->scale);
    2724      221769 :                                 list = pushArgument(mb,list,c->nr);
    2725             :                         } else
    2726             :                                 error = true;
    2727             :                 } else
    2728             :                         error = true;
    2729      221769 :                 if (error)
    2730             :                         return NULL;
    2731             :         }
    2732       50100 :         sa_reset(sql->ta);
    2733       50100 :         pushInstruction(mb,list);
    2734       50100 :         return list;
    2735             : }
    2736             : 
    2737             : int
    2738       78221 : stmt_output(backend *be, stmt *lst)
    2739             : {
    2740       78221 :         MalBlkPtr mb = be->mb;
    2741             :         InstrPtr q = NULL;
    2742       78221 :         list *l = lst->op4.lval;
    2743       78221 :         int cnt = list_length(l), ok = 0;
    2744       78221 :         node *n = l->h;
    2745       78221 :         stmt *first = n->data;
    2746             : 
    2747             :         /* single value result, has a fast exit */
    2748       78221 :         if (cnt == 1 && first->nrcols <= 0 ){
    2749             :                 stmt *c = n->data;
    2750       28121 :                 sql_subtype *t = tail_type(c);
    2751       28121 :                 const char *tname = table_name(be->mvc->sa, c);
    2752       28121 :                 const char *sname = schema_name(be->mvc->sa, c);
    2753             :                 const char *_empty = "";
    2754       28121 :                 const char *tn = (tname) ? tname : _empty;
    2755       28121 :                 const char *sn = (sname) ? sname : _empty;
    2756       28121 :                 const char *cn = column_name(be->mvc->sa, c);
    2757       28121 :                 const char *ntn = sql_escape_ident(be->mvc->ta, tn);
    2758       28121 :                 const char *nsn = sql_escape_ident(be->mvc->ta, sn);
    2759             :                 size_t fqtnl;
    2760             :                 char *fqtn = NULL;
    2761             : 
    2762       28121 :                 if (ntn && nsn) {
    2763       28121 :                         fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1;
    2764       28121 :                         fqtn = SA_NEW_ARRAY(be->mvc->ta, char, fqtnl);
    2765       28120 :                         if (fqtn) {
    2766             :                                 ok = 1;
    2767       28121 :                                 snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
    2768             : 
    2769       28121 :                                 q = newStmt(mb, sqlRef, resultSetRef);
    2770       28121 :                                 getArg(q,0) = newTmpVariable(mb,TYPE_int);
    2771             :                                 if (q) {
    2772       28121 :                                         q = pushStr(mb, q, fqtn);
    2773       28121 :                                         q = pushStr(mb, q, cn);
    2774       28121 :                                         q = pushStr(mb, q, t->type->localtype == TYPE_void ? "char" : t->type->base.name);
    2775       28121 :                                         q = pushInt(mb, q, t->digits);
    2776       28121 :                                         q = pushInt(mb, q, t->scale);
    2777       28121 :                                         q = pushInt(mb, q, t->type->eclass);
    2778       28121 :                                         q = pushArgument(mb, q, c->nr);
    2779             :                                 }
    2780             :                         }
    2781             :                 }
    2782       28120 :                 sa_reset(be->mvc->ta);
    2783       28121 :                 if (!ok)
    2784             :                         return -1;
    2785             :         } else {
    2786       50100 :                 if ((q = dump_header(be->mvc, mb, l)) == NULL)
    2787           0 :                         return -1;
    2788             :         }
    2789             :         return 0;
    2790             : }
    2791             : 
    2792             : int
    2793       68966 : stmt_affected_rows(backend *be, int lastnr)
    2794             : {
    2795       68966 :         MalBlkPtr mb = be->mb;
    2796             :         InstrPtr q = NULL;
    2797             : 
    2798       68966 :         q = newStmt(mb, sqlRef, affectedRowsRef);
    2799       68966 :         q = pushArgument(mb, q, be->mvc_var);
    2800       68966 :         if (q == NULL)
    2801             :                 return -1;
    2802       68966 :         getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
    2803       68966 :         q = pushArgument(mb, q, lastnr);
    2804       68966 :         if (q == NULL)
    2805             :                 return -1;
    2806       68966 :         be->mvc_var = getDestVar(q);
    2807       68966 :         return 0;
    2808             : }
    2809             : 
    2810             : stmt *
    2811      539061 : stmt_append(backend *be, stmt *c, stmt *a)
    2812             : {
    2813      539061 :         MalBlkPtr mb = be->mb;
    2814             :         InstrPtr q = NULL;
    2815             : 
    2816      539061 :         if (c->nr < 0 || a->nr < 0)
    2817             :                 return NULL;
    2818      539061 :         q = newStmt(mb, batRef, appendRef);
    2819      539061 :         q = pushArgument(mb, q, c->nr);
    2820      539061 :         q = pushArgument(mb, q, a->nr);
    2821      539061 :         q = pushBit(mb, q, TRUE);
    2822      539061 :         if (q) {
    2823      539061 :                 stmt *s = stmt_create(be->mvc->sa, st_append);
    2824      539061 :                 if(!s) {
    2825           0 :                         freeInstruction(q);
    2826           0 :                         return NULL;
    2827             :                 }
    2828      539061 :                 s->op1 = c;
    2829      539061 :                 s->op2 = a;
    2830      539061 :                 s->nrcols = c->nrcols;
    2831      539061 :                 s->key = c->key;
    2832      539061 :                 s->nr = getDestVar(q);
    2833      539061 :                 s->q = q;
    2834      539061 :                 return s;
    2835             :         }
    2836             :         return NULL;
    2837             : }
    2838             : 
    2839             : stmt *
    2840        7235 : stmt_append_bulk(backend *be, stmt *c, list *l)
    2841             : {
    2842        7235 :         MalBlkPtr mb = be->mb;
    2843             :         InstrPtr q = NULL;
    2844             :         bool needs_columns = false;
    2845             : 
    2846        7235 :         if (c->nr < 0)
    2847             :                 return NULL;
    2848             : 
    2849             :         /* currently appendBulk accepts its inputs all either scalar or vectors
    2850             :            if there is one vector and any scala, then the scalars mut be upgraded to vectors */
    2851      345631 :         for (node *n = l->h; n; n = n->next) {
    2852      338396 :                 stmt *t = n->data;
    2853      338396 :                 needs_columns |= t->nrcols > 0;
    2854             :         }
    2855        7235 :         if (needs_columns) {
    2856          13 :                 for (node *n = l->h; n; n = n->next) {
    2857           9 :                         stmt *t = n->data;
    2858           9 :                         if (t->nrcols == 0)
    2859           2 :                                 n->data = const_column(be, t);
    2860             :                 }
    2861             :         }
    2862             : 
    2863        7235 :         q = newStmtArgs(mb, batRef, appendBulkRef, list_length(l) + 3);
    2864        7235 :         q = pushArgument(mb, q, c->nr);
    2865        7235 :         q = pushBit(mb, q, TRUE);
    2866      345631 :         for (node *n = l->h ; n ; n = n->next) {
    2867      338396 :                 stmt *a = n->data;
    2868      338396 :                 q = pushArgument(mb, q, a->nr);
    2869             :         }
    2870        7235 :         if (q) {
    2871        7235 :                 stmt *s = stmt_create(be->mvc->sa, st_append_bulk);
    2872        7235 :                 if(!s) {
    2873           0 :                         freeInstruction(q);
    2874           0 :                         return NULL;
    2875             :                 }
    2876        7235 :                 s->op1 = c;
    2877        7235 :                 s->op4.lval = l;
    2878        7235 :                 s->nrcols = c->nrcols;
    2879        7235 :                 s->key = c->key;
    2880        7235 :                 s->nr = getDestVar(q);
    2881        7235 :                 s->q = q;
    2882        7235 :                 return s;
    2883             :         }
    2884             :         return NULL;
    2885             : }
    2886             : 
    2887             : stmt *
    2888       66076 : stmt_claim(backend *be, sql_table *t, stmt *cnt)
    2889             : {
    2890       66076 :         MalBlkPtr mb = be->mb;
    2891             :         InstrPtr q = NULL;
    2892             : 
    2893       66076 :         if (!t || cnt->nr < 0)
    2894             :                 return NULL;
    2895       66076 :         if (!t->s) /* declared table */
    2896           0 :                 assert(0);
    2897       66076 :         q = newStmtArgs(mb, sqlRef, claimRef, 6);
    2898             :         /* returns offset or offsets */
    2899       66076 :         q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_oid)));
    2900       66076 :         q = pushArgument(mb, q, be->mvc_var);
    2901       66076 :         q = pushSchema(mb, q, t);
    2902       66076 :         q = pushStr(mb, q, t->base.name);
    2903       66076 :         q = pushArgument(mb, q, cnt->nr);
    2904       66076 :         if (q) {
    2905       66076 :                 stmt *s = stmt_create(be->mvc->sa, st_claim);
    2906       66076 :                 if(!s) {
    2907           0 :                         freeInstruction(q);
    2908           0 :                         return NULL;
    2909             :                 }
    2910       66076 :                 s->op1 = cnt;
    2911       66076 :                 s->op4.tval = t;
    2912       66076 :                 s->nr = getDestVar(q);
    2913       66076 :                 s->q = q;
    2914       66076 :                 return s;
    2915             :         }
    2916             :         return NULL;
    2917             : }
    2918             : 
    2919             : stmt *
    2920       36742 : stmt_replace(backend *be, stmt *r, stmt *id, stmt *val)
    2921             : {
    2922       36742 :         MalBlkPtr mb = be->mb;
    2923             :         InstrPtr q = NULL;
    2924             : 
    2925       36742 :         if (r->nr < 0)
    2926             :                 return NULL;
    2927             : 
    2928       36742 :         q = newStmt(mb, batRef, replaceRef);
    2929       36742 :         q = pushArgument(mb, q, r->nr);
    2930       36742 :         q = pushArgument(mb, q, id->nr);
    2931       36742 :         q = pushArgument(mb, q, val->nr);
    2932       36742 :         q = pushBit(mb, q, TRUE); /* forced */
    2933       36742 :         if (q) {
    2934       36742 :                 stmt *s = stmt_create(be->mvc->sa, st_replace);
    2935       36742 :                 if(!s) {
    2936           0 :                         freeInstruction(q);
    2937           0 :                         return NULL;
    2938             :                 }
    2939       36742 :                 s->op1 = r;
    2940       36742 :                 s->op2 = id;
    2941       36742 :                 s->op3 = val;
    2942       36742 :                 s->nrcols = r->nrcols;
    2943       36742 :                 s->key = r->key;
    2944       36742 :                 s->nr = getDestVar(q);
    2945       36742 :                 s->q = q;
    2946       36742 :                 s->cand = r->cand;
    2947       36742 :                 return s;
    2948             :         }
    2949             :         return NULL;
    2950             : }
    2951             : 
    2952             : stmt *
    2953         183 : stmt_table_clear(backend *be, sql_table *t)
    2954             : {
    2955         183 :         MalBlkPtr mb = be->mb;
    2956             :         InstrPtr q = NULL;
    2957             : 
    2958         183 :         if (!t->s && ATOMIC_PTR_GET(&t->data)) { /* declared table */
    2959           2 :                 int *l = ATOMIC_PTR_GET(&t->data), cnt = ol_length(t->columns)+1;
    2960             : 
    2961           6 :                 for (int i = 0; i < cnt; i++) {
    2962           4 :                         q = newStmt(mb, batRef, deleteRef);
    2963           4 :                         q = pushArgument(mb, q, l[i]);
    2964             :                 }
    2965             :         } else {
    2966         181 :                 q = newStmt(mb, sqlRef, clear_tableRef);
    2967         181 :                 q = pushSchema(mb, q, t);
    2968         181 :                 q = pushStr(mb, q, t->base.name);
    2969             :         }
    2970         183 :         if (q) {
    2971         183 :                 stmt *s = stmt_create(be->mvc->sa, st_table_clear);
    2972             : 
    2973         183 :                 if(!s) {
    2974           0 :                         freeInstruction(q);
    2975           0 :                         return NULL;
    2976             :                 }
    2977         183 :                 s->op4.tval = t;
    2978         183 :                 s->nrcols = 0;
    2979         183 :                 s->nr = getDestVar(q);
    2980         183 :                 s->q = q;
    2981         183 :                 return s;
    2982             :         }
    2983             :         return NULL;
    2984             : }
    2985             : 
    2986             : stmt *
    2987       28265 : stmt_exception(backend *be, stmt *cond, const char *errstr, int errcode)
    2988             : {
    2989       28265 :         MalBlkPtr mb = be->mb;
    2990             :         InstrPtr q = NULL;
    2991             : 
    2992       28265 :         if (cond->nr < 0)
    2993             :                 return NULL;
    2994             : 
    2995             :         /* if(bit(l)) { error(r);}  ==raising an exception */
    2996       28265 :         q = newStmt(mb, sqlRef, assertRef);
    2997       28265 :         q = pushArgument(mb, q, cond->nr);
    2998       28265 :         q = pushStr(mb, q, errstr);
    2999       28265 :         if (q) {
    3000       28265 :                 stmt *s = stmt_create(be->mvc->sa, st_exception);
    3001       28265 :                 if(!s) {
    3002           0 :                         freeInstruction(q);
    3003           0 :                         return NULL;
    3004             :                 }
    3005             :                 assert(cond);
    3006       28265 :                 s->op1 = cond;
    3007             :                 (void)errcode;
    3008       28265 :                 s->nrcols = 0;
    3009       28265 :                 s->q = q;
    3010       28265 :                 s->nr = getDestVar(q);
    3011       28265 :                 return s;
    3012             :         }
    3013             :         return NULL;
    3014             : }
    3015             : 
    3016             : /* The type setting is not propagated to statements such as st_bat and st_append,
    3017             :         because they are not considered projections */
    3018             : static void
    3019       48071 : tail_set_type(stmt *st, sql_subtype *t)
    3020             : {
    3021             :         for (;;) {
    3022      114352 :                 switch (st->type) {
    3023        6084 :                 case st_const:
    3024        6084 :                         st = st->op2;
    3025        6084 :                         continue;
    3026       23673 :                 case st_alias:
    3027             :                 case st_gen_group:
    3028             :                 case st_order:
    3029       23673 :                         st = st->op1;
    3030       23673 :                         continue;
    3031           0 :                 case st_list:
    3032           0 :                         st = st->op4.lval->h->data;
    3033           0 :                         continue;
    3034       36524 :                 case st_join:
    3035             :                 case st_join2:
    3036             :                 case st_joinN:
    3037       36524 :                         if (st->flag == cmp_project) {
    3038       36524 :                                 st = st->op2;
    3039       36524 :                                 continue;
    3040             :                         }
    3041             :                         return;
    3042        3555 :                 case st_aggr:
    3043             :                 case st_Nop: {
    3044        3555 :                         list *res = st->op4.funcval->res;
    3045             : 
    3046        3555 :                         if (res && list_length(res) == 1)
    3047        3555 :                                 res->h->data = t;
    3048             :                         return;
    3049             :                 }
    3050        9181 :                 case st_atom:
    3051        9181 :                         atom_set_type(st->op4.aval, t);
    3052        9181 :                         return;
    3053         110 :                 case st_convert:
    3054             :                 case st_temp:
    3055             :                 case st_single:
    3056         110 :                         st->op4.typeval = *t;
    3057         110 :                         return;
    3058         756 :                 case st_var:
    3059         756 :                         if (st->op4.typeval.type)
    3060         756 :                                 st->op4.typeval = *t;
    3061             :                         return;
    3062             :                 default:
    3063             :                         return;
    3064             :                 }
    3065             :         }
    3066             : }
    3067             : 
    3068             : #define trivial_string_conversion(x) ((x) == EC_BIT || (x) == EC_CHAR || (x) == EC_STRING || (x) == EC_NUM || (x) == EC_POS || (x) == EC_FLT \
    3069             :                                                                           || (x) == EC_DATE || (x) == EC_BLOB || (x) == EC_MONTH)
    3070             : 
    3071             : stmt *
    3072      152175 : stmt_convert(backend *be, stmt *v, stmt *sel, sql_subtype *f, sql_subtype *t)
    3073             : {
    3074      152175 :         MalBlkPtr mb = be->mb;
    3075             :         InstrPtr q = NULL;
    3076      152175 :         const char *convert = t->type->impl;
    3077      152175 :         int pushed = (v->cand && v->cand == sel), no_candidates = 0;
    3078             :         /* convert types and make sure they are rounded up correctly */
    3079             : 
    3080      152175 :         if (v->nr < 0)
    3081             :                 return NULL;
    3082             : 
    3083      152175 :         if (f->type->eclass != EC_EXTERNAL && t->type->eclass != EC_EXTERNAL &&
    3084             :                 /* general cases */
    3085      151883 :                 ((t->type->localtype == f->type->localtype && t->type->eclass == f->type->eclass &&
    3086      151883 :                 !EC_INTERVAL(f->type->eclass) && f->type->eclass != EC_DEC && (t->digits == 0 || f->digits == t->digits) && type_has_tz(t) == type_has_tz(f)) ||
    3087             :                 /* trivial decimal cases */
    3088        1674 :                 (f->type->eclass == EC_DEC && t->type->eclass == EC_DEC && f->scale == t->scale && f->type->localtype == t->type->localtype) ||
    3089             :                 /* trivial string cases */
    3090      148837 :                 (EC_VARCHAR(f->type->eclass) && EC_VARCHAR(t->type->eclass) && (t->digits == 0 || (f->digits > 0 && t->digits >= f->digits))))) {
    3091             :                 /* set output type. Despite the MAL code already being generated, the output type may still be checked */
    3092       48071 :                 tail_set_type(v, t);
    3093       48071 :                 return v;
    3094             :         }
    3095             : 
    3096             :         /* external types have sqlname convert functions,
    3097             :            these can generate errors (fromstr cannot) */
    3098      104104 :         if (t->type->eclass == EC_EXTERNAL)
    3099         273 :                 convert = t->type->base.name;
    3100      103831 :         else if (t->type->eclass == EC_MONTH)
    3101             :                 convert = "month_interval";
    3102      103823 :         else if (t->type->eclass == EC_SEC)
    3103             :                 convert = "second_interval";
    3104             : 
    3105      104104 :         no_candidates = t->type->eclass == EC_EXTERNAL && strcmp(convert, "uuid") != 0; /* uuids conversions support candidate lists */
    3106             : 
    3107             :         /* Lookup the sql convert function, there is no need
    3108             :          * for single value vs bat, this is handled by the
    3109             :          * mal function resolution */
    3110      104104 :         if (v->nrcols == 0 && (!sel || sel->nrcols == 0)) {       /* simple calc */
    3111        8721 :                 q = newStmtArgs(mb, calcRef, convert, 13);
    3112       95404 :         } else if ((v->nrcols > 0 || (sel && sel->nrcols > 0)) && no_candidates) {
    3113          21 :                 int type = t->type->localtype;
    3114             : 
    3115             :                 /* with our current implementation, all internal SQL types have candidate list support on their conversions */
    3116          21 :                 if (sel && !pushed) {
    3117             :                         pushed = 1;
    3118           0 :                         v = stmt_project(be, sel, v);
    3119           0 :                         v->cand = sel;
    3120             :                 }
    3121          21 :                 q = newStmtArgs(mb, malRef, multiplexRef, 15);
    3122          21 :                 if (q == NULL)
    3123             :                         return NULL;
    3124          21 :                 setVarType(mb, getArg(q, 0), newBatType(type));
    3125          21 :                 q = pushStr(mb, q, convertMultiplexMod(calcRef, convert));
    3126          21 :                 q = pushStr(mb, q, convertMultiplexFcn(convert));
    3127             :         } else {
    3128       95362 :                 if (v->nrcols == 0 && sel && !pushed) {
    3129             :                         pushed = 1;
    3130         252 :                         v = stmt_project(be, sel, v);
    3131         252 :                         v->cand = sel;
    3132             :                 }
    3133       95362 :                 q = newStmtArgs(mb, batcalcRef, convert, 13);
    3134             :         }
    3135             : 
    3136             :         /* convert to string is complex, we need full type info and mvc for the timezone */
    3137      104104 :         if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0)) {
    3138         985 :                 q = pushInt(mb, q, f->type->eclass);
    3139         985 :                 q = pushInt(mb, q, f->digits);
    3140         985 :                 q = pushInt(mb, q, f->scale);
    3141         985 :                 q = pushInt(mb, q, type_has_tz(f));
    3142      103119 :         } else if (f->type->eclass == EC_DEC) {
    3143             :                 /* scale of the current decimal */
    3144        1474 :                 q = pushInt(mb, q, f->scale);
    3145      101645 :         } else if (f->type->eclass == EC_SEC && (EC_COMPUTE(t->type->eclass) || t->type->eclass == EC_DEC)) {
    3146             :                 /* scale of the current decimal */
    3147           0 :                 q = pushInt(mb, q, 3);
    3148             :         }
    3149      104104 :         q = pushArgument(mb, q, v->nr);
    3150      104104 :         if (sel && !pushed && !v->cand) {
    3151       23078 :                 q = pushArgument(mb, q, sel->nr);
    3152       23078 :                 pushed = 1;
    3153       81026 :         } else if (v->nrcols > 0 && !no_candidates) {
    3154       72284 :                 q = pushNil(mb, q, TYPE_bat);
    3155             :         }
    3156      104104 :         if (t->type->eclass == EC_DEC || EC_TEMP_FRAC(t->type->eclass) || EC_INTERVAL(t->type->eclass)) {
    3157             :                 /* digits, scale of the result decimal */
    3158        3193 :                 q = pushInt(mb, q, t->digits);
    3159        3193 :                 if (!EC_TEMP_FRAC(t->type->eclass))
    3160        2769 :                         q = pushInt(mb, q, t->scale);
    3161             :         }
    3162             :         /* convert to string, give error on to large strings */
    3163      104104 :         if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0))
    3164         985 :                 q = pushInt(mb, q, t->digits);
    3165             :         /* convert a string to a time(stamp) with time zone */
    3166      104104 :         if (EC_VARCHAR(f->type->eclass) && EC_TEMP_TZ(t->type->eclass))
    3167         122 :                 q = pushInt(mb, q, type_has_tz(t));
    3168      104104 :         if (t->type->eclass == EC_GEOM) {
    3169             :                 /* push the type and coordinates of the column */
    3170         689 :                 q = pushInt(mb, q, t->digits);
    3171             :                 /* push the SRID of the whole columns */
    3172         689 :                 q = pushInt(mb, q, t->scale);
    3173             :                 /* push the type and coordinates of the inserted value */
    3174             :                 //q = pushInt(mb, q, f->digits);
    3175             :                 /* push the SRID of the inserted value */
    3176             :                 //q = pushInt(mb, q, f->scale);
    3177             :                 /* we decided to create the EWKB type also used by PostGIS and has the SRID provided by the user inside alreay */
    3178             :                 /* push the SRID provided for this value */
    3179             :                 /* GEOS library is able to store in the returned wkb the type an
    3180             :                  * number if coordinates but not the SRID so SRID should be provided
    3181             :                  * from this level */
    3182             : /*              if(be->argc > 1)
    3183             :                         f->scale = ((ValRecord)((atom*)(be->mvc)->args[1])->data).val.ival;
    3184             : 
    3185             :                         q = pushInt(mb, q, f->digits);
    3186             :                         q = pushInt(mb, q, f->scale);
    3187             : */                      //q = pushInt(mb, q, ((ValRecord)((atom*)(be->mvc)->args[1])->data).val.ival);
    3188             :         }
    3189      104104 :         if (q) {
    3190      104104 :                 stmt *s = stmt_create(be->mvc->sa, st_convert);
    3191      104104 :                 if(!s) {
    3192           0 :                         freeInstruction(q);
    3193           0 :                         return NULL;
    3194             :                 }
    3195      104104 :                 s->op1 = v;
    3196      104104 :                 s->nrcols = 0;       /* function without arguments returns single value */
    3197      104104 :                 s->key = v->key;
    3198      104104 :                 s->nrcols = v->nrcols;
    3199      104104 :                 s->aggr = v->aggr;
    3200      104104 :                 s->op4.typeval = *t;
    3201      104104 :                 s->nr = getDestVar(q);
    3202      104104 :                 s->q = q;
    3203      104104 :                 s->cand = pushed ? sel : NULL;
    3204      104104 :                 return s;
    3205             :         }
    3206             :         return NULL;
    3207             : }
    3208             : 
    3209             : stmt *
    3210       21832 : stmt_unop(backend *be, stmt *op1, stmt *sel, sql_subfunc *op)
    3211             : {
    3212       21832 :         list *ops = sa_list(be->mvc->sa);
    3213       21832 :         list_append(ops, op1);
    3214       21832 :         stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op);
    3215       21832 :         if (!r->cand)
    3216       21832 :                 r->cand = op1->cand;
    3217       21832 :         return r;
    3218             : }
    3219             : 
    3220             : stmt *
    3221       29239 : stmt_binop(backend *be, stmt *op1, stmt *op2, stmt *sel, sql_subfunc *op)
    3222             : {
    3223       29239 :         list *ops = sa_list(be->mvc->sa);
    3224       29239 :         list_append(ops, op1);
    3225       29239 :         list_append(ops, op2);
    3226       29239 :         stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op);
    3227       29239 :         if (!r->cand)
    3228       29239 :                 r->cand = op1->cand?op1->cand:op2->cand;
    3229       29239 :         return r;
    3230             : }
    3231             : 
    3232             : stmt *
    3233      202877 : stmt_Nop(backend *be, stmt *ops, stmt *sel, sql_subfunc *f)
    3234             : {
    3235      202877 :         MalBlkPtr mb = be->mb;
    3236             :         InstrPtr q = NULL;
    3237             :         const char *mod, *fimp;
    3238             :         sql_subtype *tpe = NULL;
    3239      202877 :         int push_cands = can_push_cands(sel, f);
    3240             : 
    3241             :         node *n;
    3242             :         stmt *o = NULL;
    3243             : 
    3244      202877 :         if (list_length(ops->op4.lval)) {
    3245      591842 :                 for (n = ops->op4.lval->h, o = n->data; n; n = n->next) {
    3246      394475 :                         stmt *c = n->data;
    3247             : 
    3248      394475 :                         if (c && o->nrcols < c->nrcols)
    3249             :                                 o = c;
    3250             :                 }
    3251             :         }
    3252             : 
    3253             :         /* handle nullif */
    3254      202877 :         if (list_length(ops->op4.lval) == 2 &&
    3255      121941 :                 f->func->mod && strcmp(f->func->mod, "") == 0 && f->func->imp && strcmp(f->func->imp, "") == 0) {
    3256          92 :                 stmt *e1 = ops->op4.lval->h->data;
    3257          92 :                 stmt *e2 = ops->op4.lval->h->next->data;
    3258             :                 int nrcols = 0;
    3259             : 
    3260          92 :                 nrcols = e1->nrcols>e2->nrcols ? e1->nrcols:e2->nrcols;
    3261             :                 /* nullif(e1,e2) -> ifthenelse(e1==e2),NULL,e1) */
    3262          92 :                 if (strcmp(f->func->base.name, "nullif") == 0) {
    3263          92 :                         const char *mod = (!nrcols)?calcRef:batcalcRef;
    3264          92 :                         sql_subtype *t = tail_type(e1);
    3265          92 :                         int tt = t->type->localtype;
    3266          92 :                         q = newStmt(mb, mod, "==");
    3267          92 :                         q = pushArgument(mb, q, e1->nr);
    3268          92 :                         q = pushArgument(mb, q, e2->nr);
    3269          92 :                         int nr = getDestVar(q);
    3270             : 
    3271          92 :                         q = newStmt(mb, mod, "ifthenelse");
    3272          92 :                         q = pushArgument(mb, q, nr);
    3273          92 :                         q = pushNil(mb, q, tt);
    3274          92 :                         q = pushArgument(mb, q, e1->nr);
    3275             :                 }
    3276             :         }
    3277          92 :         if (!q) {
    3278      202785 :                 if (backend_create_subfunc(be, f, ops->op4.lval) < 0)
    3279             :                         return NULL;
    3280      202783 :                 mod = sql_func_mod(f->func);
    3281      202783 :                 fimp = sql_func_imp(f->func);
    3282      202783 :                 if (o && o->nrcols > 0 && f->func->type != F_LOADER && f->func->type != F_PROC) {
    3283      135231 :                         sql_subtype *res = f->res->h->data;
    3284             :                         fimp = convertMultiplexFcn(fimp);
    3285             :                         q = NULL;
    3286      135231 :                         if (strcmp(fimp, "rotate_xor_hash") == 0 &&
    3287       16546 :                                 strcmp(mod, calcRef) == 0 &&
    3288        8273 :                                 (q = newStmt(mb, mkeyRef, bulk_rotate_xor_hashRef)) == NULL)
    3289             :                                 return NULL;
    3290             :                         if (!q) {
    3291      126958 :                                 if (f->func->type == F_UNION)
    3292          22 :                                         q = newStmtArgs(mb, batmalRef, multiplexRef, (f->res && list_length(f->res) ? list_length(f->res) : 1) + list_length(ops->op4.lval) + 6);
    3293             :                                 else
    3294      126936 :                                         q = newStmtArgs(mb, malRef, multiplexRef, (f->res && list_length(f->res) ? list_length(f->res) : 1) + list_length(ops->op4.lval) + 6);
    3295      126958 :                                 if (q == NULL)
    3296             :                                         return NULL;
    3297      126958 :                                 setVarType(mb, getArg(q, 0), newBatType(res->type->localtype));
    3298      126958 :                                 q = pushStr(mb, q, mod);
    3299      126958 :                                 q = pushStr(mb, q, fimp);
    3300             :                         } else {
    3301        8273 :                                 setVarType(mb, getArg(q, 0), newBatType(res->type->localtype));
    3302             :                         }
    3303             :                 } else {
    3304             :                         fimp = convertOperator(fimp);
    3305       67552 :                         q = newStmtArgs(mb, mod, fimp, (f->res && list_length(f->res) ? list_length(f->res) : 1) + list_length(ops->op4.lval) + 4);
    3306             : 
    3307       67552 :                         if (f->res && list_length(f->res)) {
    3308       59106 :                                 sql_subtype *res = f->res->h->data;
    3309             : 
    3310       59106 :                                 setVarType(mb, getArg(q, 0), res->type->localtype);
    3311             :                         }
    3312             :                 }
    3313      202783 :                 if (LANG_EXT(f->func->lang))
    3314         201 :                         q = pushPtr(mb, q, f);
    3315      202783 :                 if (f->func->lang == FUNC_LANG_C) {
    3316          33 :                         q = pushBit(mb, q, 0);
    3317      202750 :                 } else if (f->func->lang == FUNC_LANG_CPP) {
    3318           1 :                         q = pushBit(mb, q, 1);
    3319             :                 }
    3320      202783 :                 if (f->func->lang == FUNC_LANG_R || f->func->lang >= FUNC_LANG_PY ||
    3321             :                         f->func->lang == FUNC_LANG_C || f->func->lang == FUNC_LANG_CPP) {
    3322         201 :                         q = pushStr(mb, q, f->func->query);
    3323             :                 }
    3324             :                 /* first dynamic output of copy* functions */
    3325      202783 :                 if (f->func->type == F_UNION || (f->func->type == F_LOADER && f->res != NULL))
    3326        6180 :                         q = table_func_create_result(mb, q, f->func, f->res);
    3327      202783 :                 if (list_length(ops->op4.lval))
    3328      197275 :                         tpe = tail_type(ops->op4.lval->h->data);
    3329             : 
    3330      597074 :                 for (n = ops->op4.lval->h; n; n = n->next) {
    3331      394291 :                         stmt *op = n->data;
    3332      394291 :                         q = pushArgument(mb, q, op->nr);
    3333             :                 }
    3334             :                 /* push candidate lists if that's the case */
    3335      202783 :                 if (f->func->type == F_FUNC && f->func->lang == FUNC_LANG_INT && push_cands) {
    3336       68085 :                         for (n = ops->op4.lval->h; n; n = n->next) {
    3337       45181 :                                 stmt *op = n->data;
    3338             : 
    3339       45181 :                                 if (op->nrcols > 0) {
    3340       25106 :                                         if (op->cand && op->cand == sel) {
    3341       16435 :                                                 q = pushNil(mb, q, TYPE_bat);
    3342             :                                         } else {
    3343        8671 :                                                 q = pushArgument(mb, q, sel->nr);
    3344             :                                         }
    3345             :                                 }
    3346             :                         }
    3347             :                 }
    3348             :                 /* special case for round function on decimals */
    3349      202783 :                 if (strcmp(fimp, "round") == 0 && tpe && tpe->type->eclass == EC_DEC && ops->op4.lval->h && ops->op4.lval->h->data) {
    3350          44 :                         q = pushInt(mb, q, tpe->digits);
    3351          44 :                         q = pushInt(mb, q, tpe->scale);
    3352             :                 }
    3353             :         }
    3354             : 
    3355      202875 :         if (q) {
    3356      202875 :                 stmt *s = stmt_create(be->mvc->sa, st_Nop);
    3357      202875 :                 if(!s) {
    3358           0 :                         freeInstruction(q);
    3359           0 :                         return NULL;
    3360             :                 }
    3361      202875 :                 s->op1 = ops;
    3362      202875 :                 if (o) {
    3363      197367 :                         s->nrcols = o->nrcols;
    3364      197367 :                         s->key = o->key;
    3365      197367 :                         s->aggr = o->aggr;
    3366             :                 } else {
    3367        5508 :                         s->nrcols = 0;
    3368        5508 :                         s->key = 1;
    3369             :                 }
    3370      202875 :                 s->op4.funcval = f;
    3371      202875 :                 s->nr = getDestVar(q);
    3372      202875 :                 s->q = q;
    3373      202875 :                 if (sel && push_cands && s->nrcols)
    3374       21412 :                         s->cand = sel;
    3375      202875 :                 return s;
    3376             :         }
    3377             :         return NULL;
    3378             : }
    3379             : 
    3380             : stmt *
    3381           8 : stmt_direct_func(backend *be, InstrPtr q)
    3382             : {
    3383           8 :         if (q) {
    3384           8 :                 stmt *s = stmt_create(be->mvc->sa, st_func);
    3385           8 :                 if(!s) {
    3386           0 :                         freeInstruction(q);
    3387           0 :                         return NULL;
    3388             :                 }
    3389           8 :                 s->flag = op_union;
    3390           8 :                 s->nrcols = 3;
    3391           8 :                 s->nr = getDestVar(q);
    3392           8 :                 s->q = q;
    3393           8 :                 return s;
    3394             :         }
    3395             :         return NULL;
    3396             : }
    3397             : 
    3398             : stmt *
    3399         125 : stmt_func(backend *be, stmt *ops, const char *name, sql_rel *rel, int f_union)
    3400             : {
    3401         125 :         MalBlkPtr mb = be->mb;
    3402             :         InstrPtr q = NULL;
    3403             :         const char *mod = "user";
    3404             :         node *n;
    3405             :         prop *p = NULL;
    3406             : 
    3407             :         /* dump args */
    3408         125 :         if (ops && ops->nr < 0)
    3409             :                 return NULL;
    3410             : 
    3411         125 :         if ((p = find_prop(rel->p, PROP_REMOTE)))
    3412         125 :                 rel->p = prop_remove(rel->p, p);
    3413             :         /* sql_processrelation may split projections, so make sure the topmost relation only contains references */
    3414         125 :         rel = rel_project(be->mvc->sa, rel, rel_projections(be->mvc, rel, NULL, 1, 1));
    3415         125 :         if (!(rel = sql_processrelation(be->mvc, rel, 1, 1)))
    3416             :                 return NULL;
    3417         125 :         if (p) {
    3418         125 :                 p->p = rel->p;
    3419         125 :                 rel->p = p;
    3420             :         }
    3421             : 
    3422         125 :         if (monet5_create_relational_function(be->mvc, mod, name, rel, ops, NULL, 1) < 0)
    3423             :                 return NULL;
    3424             : 
    3425         125 :         if (f_union)
    3426           0 :                 q = newStmt(mb, batmalRef, multiplexRef);
    3427             :         else
    3428         125 :                 q = newStmt(mb, mod, name);
    3429         125 :         q = relational_func_create_result(be->mvc, mb, q, rel);
    3430         125 :         if (f_union) {
    3431           0 :                 q = pushStr(mb, q, mod);
    3432           0 :                 q = pushStr(mb, q, name);
    3433             :         }
    3434         125 :         if (ops) {
    3435         147 :                 for (n = ops->op4.lval->h; n; n = n->next) {
    3436          22 :                         stmt *op = n->data;
    3437             : 
    3438          22 :                         q = pushArgument(mb, q, op->nr);
    3439             :                 }
    3440             :         }
    3441             : 
    3442         125 :         if (q) {
    3443             :                 node *n;
    3444         125 :                 sql_allocator *sa = be->mvc->sa;
    3445         125 :                 stmt *o = NULL, *s = stmt_create(sa, st_func);
    3446         125 :                 if(!s) {
    3447           0 :                         freeInstruction(q);
    3448           0 :                         return NULL;
    3449             :                 }
    3450         125 :                 s->op1 = ops;
    3451         125 :                 s->op2 = stmt_atom_string(be, name);
    3452         125 :                 s->op4.rel = rel;
    3453         125 :                 s->flag = f_union;
    3454         125 :                 if (ops && list_length(ops->op4.lval)) {
    3455          32 :                         for (n = ops->op4.lval->h, o = n->data; n; n = n->next) {
    3456          22 :                                 stmt *c = n->data;
    3457             : 
    3458          22 :                                 if (o->nrcols < c->nrcols)
    3459             :                                         o = c;
    3460             :                         }
    3461             :                 }
    3462             : 
    3463          10 :                 if (o) {
    3464          10 :                         s->nrcols = o->nrcols;
    3465          10 :                         s->key = o->key;
    3466          10 :                         s->aggr = o->aggr;
    3467             :                 } else {
    3468         115 :                         s->nrcols = 0;
    3469         115 :                         s->key = 1;
    3470             :                 }
    3471         125 :                 s->nr = getDestVar(q);
    3472         125 :                 s->q = q;
    3473         125 :                 return s;
    3474             :         }
    3475             :         return NULL;
    3476             : }
    3477             : 
    3478             : stmt *
    3479       48943 : stmt_aggr(backend *be, stmt *op1, stmt *grp, stmt *ext, sql_subfunc *op, int reduce, int no_nil, int nil_if_empty)
    3480             : {
    3481       48943 :         MalBlkPtr mb = be->mb;
    3482             :         InstrPtr q = NULL;
    3483             :         const char *mod, *aggrfunc;
    3484       48943 :         sql_subtype *res = op->res->h->data;
    3485       48943 :         int restype = res->type->localtype;
    3486             :         bool complex_aggr = false;
    3487             :         bool abort_on_error;
    3488             :         int *stmt_nr = NULL;
    3489             :         int avg = 0;
    3490             : 
    3491       48943 :         if (op1->nr < 0)
    3492             :                 return NULL;
    3493       48943 :         if (backend_create_subfunc(be, op, NULL) < 0)
    3494             :                 return NULL;
    3495       48943 :         mod = op->func->mod;
    3496       48943 :         aggrfunc = op->func->imp;
    3497             : 
    3498       48943 :         if (strcmp(aggrfunc, "avg") == 0)
    3499             :                 avg = 1;
    3500       47514 :         if (avg || strcmp(aggrfunc, "sum") == 0 || strcmp(aggrfunc, "prod") == 0
    3501       40851 :                 || strcmp(aggrfunc, "str_group_concat") == 0)
    3502             :                 complex_aggr = true;
    3503       48943 :         if (restype == TYPE_dbl)
    3504             :                 avg = 0;
    3505             :         /* some "sub" aggregates have an extra argument "abort_on_error" */
    3506       40728 :         abort_on_error = complex_aggr || strncmp(aggrfunc, "stdev", 5) == 0 || strncmp(aggrfunc, "variance", 8) == 0 ||
    3507       89626 :                                         strncmp(aggrfunc, "covariance", 10) == 0 || strncmp(aggrfunc, "corr", 4) == 0;
    3508             : 
    3509       48943 :         int argc = 1
    3510       48943 :                 + 2 * avg
    3511       48943 :                 + (LANG_EXT(op->func->lang) != 0)
    3512       48943 :                 + 2 * (op->func->lang == FUNC_LANG_C || op->func->lang == FUNC_LANG_CPP)
    3513       48943 :                 + (op->func->lang == FUNC_LANG_PY || op->func->lang == FUNC_LANG_R)
    3514       48943 :                 + (op1->type != st_list ? 1 : list_length(op1->op4.lval))
    3515       48943 :                 + (grp ? 4 : avg + 1);
    3516             : 
    3517       48943 :         if (ext) {
    3518        8225 :                 char *aggrF = SA_NEW_ARRAY(be->mvc->sa, char, strlen(aggrfunc) + 4);
    3519        8225 :                 if (!aggrF)
    3520             :                         return NULL;
    3521        8225 :                 stpcpy(stpcpy(aggrF, "sub"), aggrfunc);
    3522             :                 aggrfunc = aggrF;
    3523        8225 :                 if (grp && (grp->nr < 0 || ext->nr < 0))
    3524             :                         return NULL;
    3525             : 
    3526        8225 :                 q = newStmtArgs(mb, mod, aggrfunc, argc);
    3527        8225 :                 if (q == NULL)
    3528             :                         return NULL;
    3529        8225 :                 setVarType(mb, getArg(q, 0), newBatType(restype));
    3530        8225 :                 if (avg) { /* for avg also return rest and count */
    3531         127 :                         q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_lng)));
    3532         127 :                         q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_lng)));
    3533             :                 }
    3534             :         } else {
    3535       40718 :                 q = newStmtArgs(mb, mod, aggrfunc, argc);
    3536       40718 :                 if (q == NULL)
    3537             :                         return NULL;
    3538       40718 :                 if (complex_aggr) {
    3539        5751 :                         setVarType(mb, getArg(q, 0), restype);
    3540        5751 :                         if (avg) { /* for avg also return rest and count */
    3541          57 :                                 q = pushReturn(mb, q, newTmpVariable(mb, TYPE_lng));
    3542          57 :                                 q = pushReturn(mb, q, newTmpVariable(mb, TYPE_lng));
    3543             :                         }
    3544             :                 }
    3545             :         }
    3546             : 
    3547       48943 :         if (LANG_EXT(op->func->lang))
    3548          39 :                 q = pushPtr(mb, q, op->func);
    3549       48943 :         if (op->func->lang == FUNC_LANG_R ||
    3550       48909 :                 op->func->lang >= FUNC_LANG_PY ||
    3551             :                 op->func->lang == FUNC_LANG_C ||
    3552             :                 op->func->lang == FUNC_LANG_CPP) {
    3553          39 :                 if (!grp) {
    3554          16 :                         setVarType(mb, getArg(q, 0), restype);
    3555             :                 }
    3556          39 :                 if (op->func->lang == FUNC_LANG_C) {
    3557           5 :                         q = pushBit(mb, q, 0);
    3558          34 :                 } else if (op->func->lang == FUNC_LANG_CPP) {
    3559           0 :                         q = pushBit(mb, q, 1);
    3560             :                 }
    3561          39 :                 q = pushStr(mb, q, op->func->query);
    3562             :         }
    3563             : 
    3564       48943 :         if (op1->type != st_list) {
    3565       42495 :                 q = pushArgument(mb, q, op1->nr);
    3566             :         } else {
    3567             :                 int i;
    3568             :                 node *n;
    3569             : 
    3570       13549 :                 for (i=0, n = op1->op4.lval->h; n; n = n->next, i++) {
    3571        7101 :                         stmt *op = n->data;
    3572             : 
    3573             :                         if (stmt_nr)
    3574             :                                 q = pushArgument(mb, q, stmt_nr[i]);
    3575             :                         else
    3576        7101 :                                 q = pushArgument(mb, q, op->nr);
    3577             :                 }
    3578             :         }
    3579       48943 :         if (grp) {
    3580        8225 :                 q = pushArgument(mb, q, grp->nr);
    3581        8225 :                 q = pushArgument(mb, q, ext->nr);
    3582        8225 :                 if (avg) /* push nil candidates */
    3583         127 :                         q = pushNil(mb, q, TYPE_bat);
    3584        8225 :                 if (q == NULL)
    3585             :                         return NULL;
    3586        8225 :                 q = pushBit(mb, q, no_nil);
    3587        8225 :                 if (!avg && abort_on_error)
    3588        2462 :                         q = pushBit(mb, q, TRUE);
    3589       40718 :         } else if (no_nil && strncmp(aggrfunc, "count", 5) == 0) {
    3590         124 :                 q = pushBit(mb, q, no_nil);
    3591       40594 :         } else if (!nil_if_empty && strncmp(aggrfunc, "sum", 3) == 0) {
    3592           0 :                 q = pushBit(mb, q, FALSE);
    3593       40594 :         } else if (avg) { /* push candidates */
    3594          57 :                 q = pushNil(mb, q, TYPE_bat);
    3595          57 :                 q = pushBit(mb, q, no_nil);
    3596             :         }
    3597       48943 :         if (q) {
    3598       48943 :                 stmt *s = stmt_create(be->mvc->sa, st_aggr);
    3599       48943 :                 if(!s) {
    3600           0 :                         freeInstruction(q);
    3601           0 :                         return NULL;
    3602             :                 }
    3603       48943 :                 s->op1 = op1;
    3604       48943 :                 if (grp) {
    3605        8225 :                         s->op2 = grp;
    3606        8225 :                         s->op3 = ext;
    3607        8225 :                         s->nrcols = 1;
    3608             :                 } else {
    3609       40718 :                         if (!reduce)
    3610           0 :                                 s->nrcols = 1;
    3611             :                 }
    3612       48943 :                 s->key = reduce;
    3613       48943 :                 s->aggr = reduce;
    3614       48943 :                 s->flag = no_nil;
    3615       48943 :                 s->op4.funcval = op;
    3616       48943 :                 s->nr = getDestVar(q);
    3617       48943 :                 s->q = q;
    3618       48943 :                 return s;
    3619             :         }
    3620             :         return NULL;
    3621             : }
    3622             : 
    3623             : static stmt *
    3624     1258367 : stmt_alias_(backend *be, stmt *op1, const char *tname, const char *alias)
    3625             : {
    3626     1258367 :         stmt *s = stmt_create(be->mvc->sa, st_alias);
    3627     1258366 :         if(!s) {
    3628             :                 return NULL;
    3629             :         }
    3630     1258366 :         s->op1 = op1;
    3631     1258366 :         s->nrcols = op1->nrcols;
    3632     1258366 :         s->key = op1->key;
    3633     1258366 :         s->aggr = op1->aggr;
    3634             : 
    3635     1258366 :         s->tname = tname;
    3636     1258366 :         s->cname = alias;
    3637     1258366 :         s->nr = op1->nr;
    3638     1258366 :         s->q = op1->q;
    3639     1258366 :         return s;
    3640             : }
    3641             : 
    3642             : stmt *
    3643     4272952 : stmt_alias(backend *be, stmt *op1, const char *tname, const char *alias)
    3644             : {
    3645     4272952 :         if (((!op1->tname && !tname) ||
    3646     3210781 :             (op1->tname && tname && strcmp(op1->tname, tname)==0)) &&
    3647     3042383 :             op1->cname && strcmp(op1->cname, alias)==0)
    3648             :                 return op1;
    3649     1258367 :         return stmt_alias_(be, op1, tname, alias);
    3650             : }
    3651             : 
    3652             : sql_subtype *
    3653     1404342 : tail_type(stmt *st)
    3654             : {
    3655             :         for (;;) {
    3656     5718930 :                 switch (st->type) {
    3657       20606 :                 case st_const:
    3658       20606 :                         st = st->op2;
    3659       20606 :                         continue;
    3660        4219 :                 case st_uselect:
    3661             :                 case st_semijoin:
    3662             :                 case st_limit:
    3663             :                 case st_limit2:
    3664             :                 case st_sample:
    3665             :                 case st_tunion:
    3666             :                 case st_tdiff:
    3667             :                 case st_tinter:
    3668        4219 :                         return sql_bind_localtype("oid");
    3669         565 :                 case st_uselect2:
    3670         565 :                         if (!st->reduce)
    3671          46 :                                 return sql_bind_localtype("bit");
    3672         519 :                         return sql_bind_localtype("oid");
    3673     1444012 :                 case st_append:
    3674             :                 case st_append_bulk:
    3675             :                 case st_replace:
    3676             :                 case st_alias:
    3677             :                 case st_gen_group:
    3678             :                 case st_order:
    3679     1444012 :                         st = st->op1;
    3680     1444012 :                         continue;
    3681           0 :                 case st_list:
    3682           0 :                         st = st->op4.lval->h->data;
    3683           0 :                         continue;
    3684      676792 :                 case st_bat:
    3685      676792 :                         return &st->op4.cval->type;
    3686        2040 :                 case st_idxbat:
    3687        2040 :                         if (hash_index(st->op4.idxval->type)) {
    3688         236 :                                 return sql_bind_localtype("lng");
    3689        1804 :                         } else if (oid_index(st->op4.idxval->type)) {
    3690        1804 :                                 return sql_bind_localtype("oid");
    3691             :                         }
    3692             :                         /* fall through */
    3693             :                 case st_join:
    3694             :                 case st_join2:
    3695             :                 case st_joinN:
    3696     2850013 :                         if (st->flag == cmp_project) {
    3697     2849970 :                                 st = st->op2;
    3698     2849970 :                                 continue;
    3699             :                         }
    3700             :                         /* fall through */
    3701             :                 case st_reorder:
    3702             :                 case st_group:
    3703             :                 case st_result:
    3704             :                 case st_tid:
    3705             :                 case st_mirror:
    3706       13892 :                         return sql_bind_localtype("oid");
    3707           0 :                 case st_table_clear:
    3708           0 :                         return sql_bind_localtype("lng");
    3709      138035 :                 case st_aggr:
    3710             :                 case st_Nop: {
    3711      138035 :                         list *res = st->op4.funcval->res;
    3712             : 
    3713      138035 :                         if (res && list_length(res) == 1)
    3714      138035 :                                 return res->h->data;
    3715             : 
    3716             :                         return NULL;
    3717             :                 }
    3718       82630 :                 case st_atom:
    3719       82630 :                         return atom_type(st->op4.aval);
    3720      484633 :                 case st_convert:
    3721             :                 case st_temp:
    3722             :                 case st_single:
    3723             :                 case st_rs_column:
    3724      484633 :                         return &st->op4.typeval;
    3725        1535 :                 case st_var:
    3726        1535 :                         if (st->op4.typeval.type)
    3727        1535 :                                 return &st->op4.typeval;
    3728             :                         /* fall through */
    3729             :                 case st_exception:
    3730             :                         return NULL;
    3731           1 :                 case st_table:
    3732           1 :                         return sql_bind_localtype("bat");
    3733             :                 default:
    3734           0 :                         assert(0);
    3735             :                         return NULL;
    3736             :                 }
    3737             :         }
    3738             : }
    3739             : 
    3740             : int
    3741        4449 : stmt_has_null(stmt *s)
    3742             : {
    3743        7851 :         switch (s->type) {
    3744             :         case st_aggr:
    3745             :         case st_Nop:
    3746             :         case st_semijoin:
    3747             :         case st_uselect:
    3748             :         case st_uselect2:
    3749             :         case st_atom:
    3750             :                 return 0;
    3751        3402 :         case st_join:
    3752        3402 :                 return stmt_has_null(s->op2);
    3753        2883 :         case st_bat:
    3754        2883 :                 return s->op4.cval->null;
    3755             : 
    3756        1566 :         default:
    3757        1566 :                 return 1;
    3758             :         }
    3759             : }
    3760             : 
    3761             : static const char *
    3762           0 : func_name(sql_allocator *sa, const char *n1, const char *n2)
    3763             : {
    3764           0 :         size_t l1 = _strlen(n1), l2;
    3765             : 
    3766           0 :         if (!sa)
    3767             :                 return n1;
    3768           0 :         if (!n2)
    3769           0 :                 return sa_strdup(sa, n1);
    3770           0 :         l2 = _strlen(n2);
    3771             : 
    3772           0 :         if (l2 > 16) {               /* only support short names */
    3773           0 :                 char *ns = SA_NEW_ARRAY(sa, char, l2 + 1);
    3774           0 :                 if(!ns)
    3775             :                         return NULL;
    3776           0 :                 snprintf(ns, l2 + 1, "%s", n2);
    3777           0 :                 return ns;
    3778             :         } else {
    3779           0 :                 char *ns = SA_NEW_ARRAY(sa, char, l1 + l2 + 2), *s = ns;
    3780           0 :                 if(!ns)
    3781             :                         return NULL;
    3782           0 :                 snprintf(ns, l1 + l2 + 2, "%s_%s", n1, n2);
    3783           0 :                 return s;
    3784             :         }
    3785             : }
    3786             : 
    3787             : const char *_column_name(sql_allocator *sa, stmt *st);
    3788             : 
    3789             : const char *
    3790     9595565 : column_name(sql_allocator *sa, stmt *st)
    3791             : {
    3792     9595565 :         if (!st->cname)
    3793           0 :                 st->cname = _column_name(sa, st);
    3794     9595565 :         return st->cname;
    3795             : }
    3796             : 
    3797             : const char *
    3798           0 : _column_name(sql_allocator *sa, stmt *st)
    3799             : {
    3800           0 :         switch (st->type) {
    3801           0 :         case st_order:
    3802             :         case st_reorder:
    3803           0 :                 return column_name(sa, st->op1);
    3804           0 :         case st_const:
    3805             :         case st_join:
    3806             :         case st_join2:
    3807             :         case st_joinN:
    3808           0 :                 return column_name(sa, st->op2);
    3809             : 
    3810           0 :         case st_mirror:
    3811             :         case st_group:
    3812             :         case st_result:
    3813             :         case st_append:
    3814             :         case st_append_bulk:
    3815             :         case st_replace:
    3816             :         case st_gen_group:
    3817             :         case st_semijoin:
    3818             :         case st_uselect:
    3819             :         case st_uselect2:
    3820             :         case st_limit:
    3821             :         case st_limit2:
    3822             :         case st_sample:
    3823             :         case st_tunion:
    3824             :         case st_tdiff:
    3825             :         case st_tinter:
    3826             :         case st_convert:
    3827           0 :                 return column_name(sa, st->op1);
    3828           0 :         case st_Nop:
    3829             :         case st_aggr:
    3830             :         {
    3831           0 :                 const char *cn = column_name(sa, st->op1);
    3832           0 :                 return func_name(sa, st->op4.funcval->func->base.name, cn);
    3833             :         }
    3834           0 :         case st_alias:
    3835           0 :                 if (st->op3)
    3836           0 :                         return column_name(sa, st->op3);
    3837             :                 break;
    3838           0 :         case st_bat:
    3839           0 :                 return st->op4.cval->base.name;
    3840           0 :         case st_atom:
    3841           0 :                 if (st->op4.aval->data.vtype == TYPE_str)
    3842           0 :                         return atom2string(sa, st->op4.aval);
    3843             :                 /* fall through */
    3844             :         case st_var:
    3845             :         case st_temp:
    3846             :         case st_single:
    3847           0 :                 if (sa)
    3848           0 :                         return sa_strdup(sa, "single_value");
    3849             :                 return "single_value";
    3850             : 
    3851           0 :         case st_list:
    3852           0 :                 if (list_length(st->op4.lval))
    3853           0 :                         return column_name(sa, st->op4.lval->h->data);
    3854             :                 /* fall through */
    3855             :         case st_rs_column:
    3856             :                 return NULL;
    3857             :         default:
    3858             :                 return NULL;
    3859             :         }
    3860             :         return NULL;
    3861             : }
    3862             : 
    3863             : const char *
    3864     4871578 : table_name(sql_allocator *sa, stmt *st)
    3865             : {
    3866             :         (void)sa;
    3867     4871578 :         return st->tname;
    3868             : }
    3869             : 
    3870             : const char *
    3871      249914 : schema_name(sql_allocator *sa, stmt *st)
    3872             : {
    3873     1719322 :         switch (st->type) {
    3874     1015858 :         case st_const:
    3875             :         case st_semijoin:
    3876             :         case st_join:
    3877             :         case st_join2:
    3878             :         case st_joinN:
    3879     1015858 :                 return schema_name(sa, st->op2);
    3880      229382 :         case st_mirror:
    3881             :         case st_group:
    3882             :         case st_result:
    3883             :         case st_append:
    3884             :         case st_append_bulk:
    3885             :         case st_replace:
    3886             :         case st_gen_group:
    3887             :         case st_uselect:
    3888             :         case st_uselect2:
    3889             :         case st_limit:
    3890             :         case st_limit2:
    3891             :         case st_sample:
    3892             :         case st_tunion:
    3893             :         case st_tdiff:
    3894             :         case st_tinter:
    3895             :         case st_convert:
    3896             :         case st_Nop:
    3897             :         case st_aggr:
    3898      229382 :                 return schema_name(sa, st->op1);
    3899      183051 :         case st_alias:
    3900             :                 /* there are no schema aliases, ie look into the base column */
    3901      183051 :                 return schema_name(sa, st->op1);
    3902      122667 :         case st_bat:
    3903      122667 :                 return st->op4.cval->t->s->base.name;
    3904             :         case st_atom:
    3905             :                 return NULL;
    3906             :         case st_var:
    3907             :         case st_temp:
    3908             :         case st_single:
    3909             :                 return NULL;
    3910       41199 :         case st_list:
    3911       41199 :                 if (list_length(st->op4.lval))
    3912       41117 :                         return schema_name(sa, st->op4.lval->h->data);
    3913             :                 return NULL;
    3914             :         default:
    3915             :                 return NULL;
    3916             :         }
    3917             : }
    3918             : 
    3919             : stmt *
    3920        1304 : stmt_cond(backend *be, stmt *cond, stmt *outer, int loop /* 0 if, 1 while */, int anti )
    3921             : {
    3922        1304 :         MalBlkPtr mb = be->mb;
    3923             :         InstrPtr q = NULL;
    3924             : 
    3925        1304 :         if (cond->nr < 0)
    3926             :                 return NULL;
    3927        1304 :         if (anti) {
    3928          21 :                 sql_subtype *bt = sql_bind_localtype("bit");
    3929          21 :                 sql_subfunc *not = sql_bind_func(be->mvc, "sys", "not", bt, NULL, F_FUNC);
    3930          21 :                 sql_subfunc *or = sql_bind_func(be->mvc, "sys", "or", bt, bt, F_FUNC);
    3931          21 :                 sql_subfunc *isnull = sql_bind_func(be->mvc, "sys", "isnull", bt, NULL, F_FUNC);
    3932          21 :                 cond = stmt_binop(be,
    3933             :                         stmt_unop(be, cond, NULL, not),
    3934             :                         stmt_unop(be, cond, NULL, isnull), NULL, or);
    3935             :         }
    3936        1304 :         if (!loop) {    /* if */
    3937        1291 :                 q = newAssignment(mb);
    3938        1291 :                 if (q == NULL)
    3939             :                         return NULL;
    3940        1291 :                 q->barrier = BARRIERsymbol;
    3941        1291 :                 q = pushArgument(mb, q, cond->nr);
    3942             :         } else {        /* while */
    3943             :                 int c;
    3944             : 
    3945          13 :                 if (outer->nr < 0)
    3946             :                         return NULL;
    3947             :                 /* leave barrier */
    3948          13 :                 q = newStmt(mb, calcRef, notRef);
    3949          13 :                 q = pushArgument(mb, q, cond->nr);
    3950          13 :                 if (q == NULL)
    3951             :                         return NULL;
    3952          13 :                 c = getArg(q, 0);
    3953             : 
    3954          13 :                 q = newAssignment(mb);
    3955          13 :                 if (q == NULL)
    3956             :                         return NULL;
    3957          13 :                 getArg(q, 0) = outer->nr;
    3958          13 :                 q->barrier = LEAVEsymbol;
    3959          13 :                 q = pushArgument(mb, q, c);
    3960             :         }
    3961        1304 :         if (q){
    3962        1304 :                 stmt *s = stmt_create(be->mvc->sa, st_cond);
    3963        1304 :                 if(!s) {
    3964           0 :                         freeInstruction(q);
    3965           0 :                         return NULL;
    3966             :                 }
    3967        1304 :                 s->flag = loop;
    3968        1304 :                 s->op1 = cond;
    3969        1304 :                 s->nr = getArg(q, 0);
    3970        1304 :                 return s;
    3971             :         }
    3972             :         return NULL;
    3973             : }
    3974             : 
    3975             : stmt *
    3976        1304 : stmt_control_end(backend *be, stmt *cond)
    3977             : {
    3978        1304 :         MalBlkPtr mb = be->mb;
    3979             :         InstrPtr q = NULL;
    3980             : 
    3981        1304 :         if (cond->nr < 0)
    3982             :                 return NULL;
    3983             : 
    3984        1304 :         if (cond->flag) {    /* while */
    3985             :                 /* redo barrier */
    3986          13 :                 q = newAssignment(mb);
    3987          13 :                 if (q == NULL)
    3988             :                         return NULL;
    3989          13 :                 getArg(q, 0) = cond->nr;
    3990          13 :                 q->argc = q->retc = 1;
    3991          13 :                 q->barrier = REDOsymbol;
    3992          13 :                 q = pushBit(mb, q, TRUE);
    3993          13 :                 if (q == NULL)
    3994             :                         return NULL;
    3995             :         } else {
    3996        1291 :                 q = newAssignment(mb);
    3997        1291 :                 if (q == NULL)
    3998             :                         return NULL;
    3999        1291 :                 getArg(q, 0) = cond->nr;
    4000        1291 :                 q->argc = q->retc = 1;
    4001        1291 :                 q->barrier = EXITsymbol;
    4002             :         }
    4003        1304 :         q = newStmt(mb, sqlRef, mvcRef);
    4004        1304 :         if (q == NULL)
    4005             :                 return NULL;
    4006        1304 :         be->mvc_var = getDestVar(q);
    4007        1304 :         stmt *s = stmt_create(be->mvc->sa, st_control_end);
    4008        1304 :         if(!s) {
    4009           0 :                 freeInstruction(q);
    4010           0 :                 return NULL;
    4011             :         }
    4012        1304 :         s->op1 = cond;
    4013        1304 :         s->nr = getArg(q, 0);
    4014        1304 :         return s;
    4015             : }
    4016             : 
    4017             : 
    4018             : static InstrPtr
    4019         177 : dump_cols(MalBlkPtr mb, list *l, InstrPtr q)
    4020             : {
    4021             :         int i;
    4022             :         node *n;
    4023             : 
    4024         177 :         if (q == NULL)
    4025             :                 return NULL;
    4026         177 :         q->retc = q->argc = 0;
    4027        1579 :         for (i = 0, n = l->h; n; n = n->next, i++) {
    4028        1402 :                 stmt *c = n->data;
    4029             : 
    4030        1402 :                 q = pushArgument(mb, q, c->nr);
    4031             :         }
    4032         177 :         if (q == NULL)
    4033             :                 return NULL;
    4034         177 :         q->retc = q->argc;
    4035             :         /* Lets make it a propper assignment */
    4036        1579 :         for (i = 0, n = l->h; n; n = n->next, i++) {
    4037        1402 :                 stmt *c = n->data;
    4038             : 
    4039        1402 :                 q = pushArgument(mb, q, c->nr);
    4040             :         }
    4041             :         return q;
    4042             : }
    4043             : 
    4044             : stmt *
    4045         591 : stmt_return(backend *be, stmt *val, int nr_declared_tables)
    4046             : {
    4047         591 :         MalBlkPtr mb = be->mb;
    4048             :         InstrPtr q = NULL;
    4049             : 
    4050         591 :         if (val->nr < 0)
    4051             :                 return NULL;
    4052         591 :         int args = val->type == st_table ? 2 * list_length(val->op1->op4.lval) : 0;
    4053             :         if (args < MAXARG)
    4054             :                 args = MAXARG;
    4055         591 :         q = newInstructionArgs(mb, NULL, NULL, args);
    4056         591 :         if (q == NULL)
    4057             :                 return NULL;
    4058         591 :         q->barrier= RETURNsymbol;
    4059         591 :         if (val->type == st_table) {
    4060         177 :                 list *l = val->op1->op4.lval;
    4061             : 
    4062         177 :                 q = dump_cols(mb, l, q);
    4063             :         } else {
    4064         414 :                 getArg(q, 0) = getArg(getInstrPtr(mb, 0), 0);
    4065         414 :                 q = pushArgument(mb, q, val->nr);
    4066             :         }
    4067         591 :         if (q == NULL)
    4068             :                 return NULL;
    4069         591 :         pushInstruction(mb, q);
    4070             : 
    4071         591 :         stmt *s = stmt_create(be->mvc->sa, st_return);
    4072         591 :         if(!s) {
    4073           0 :                 freeInstruction(q);
    4074           0 :                 return NULL;
    4075             :         }
    4076         591 :         s->op1 = val;
    4077         591 :         s->flag = nr_declared_tables;
    4078         591 :         s->nr = getDestVar(q);
    4079         591 :         s->q = q;
    4080         591 :         return s;
    4081             : }
    4082             : 
    4083             : stmt *
    4084        1609 : stmt_assign(backend *be, const char *sname, const char *varname, stmt *val, int level)
    4085             : {
    4086        1609 :         MalBlkPtr mb = be->mb;
    4087             :         InstrPtr q = NULL;
    4088             : 
    4089        1609 :         if (val && val->nr < 0)
    4090             :                 return NULL;
    4091        1609 :         if (level != 0) {
    4092             :                 char *buf,  levelstr[16];
    4093             : 
    4094        1198 :                 if (!val) {
    4095             :                         /* drop declared table */
    4096           0 :                         assert(0);
    4097             :                 }
    4098             : 
    4099        1198 :                 assert(!sname);
    4100        1198 :                 snprintf(levelstr, sizeof(levelstr), "%d", level);
    4101        1198 :                 buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
    4102        1198 :                 if (!buf)
    4103           0 :                         return NULL;
    4104        1198 :                 stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
    4105        1198 :                 q = newInstruction(mb, NULL, NULL);
    4106        1198 :                 if (q == NULL) {
    4107             :                         return NULL;
    4108             :                 }
    4109        1198 :                 q->argc = q->retc = 0;
    4110        1198 :                 q = pushArgumentId(mb, q, buf);
    4111        1198 :                 if (q == NULL)
    4112             :                         return NULL;
    4113        1198 :                 pushInstruction(mb, q);
    4114        1198 :                 if (mb->errors)
    4115             :                         return NULL;
    4116        1198 :                 q->retc++;
    4117             :         } else {
    4118         411 :                 assert(sname); /* all global variables have a schema */
    4119         411 :                 q = newStmt(mb, sqlRef, setVariableRef);
    4120         411 :                 q = pushArgument(mb, q, be->mvc_var);
    4121         411 :                 q = pushStr(mb, q, sname);
    4122         411 :                 q = pushStr(mb, q, varname);
    4123         411 :                 if (q == NULL)
    4124             :                         return NULL;
    4125         411 :                 getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
    4126             :                 be->mvc_var = getDestVar(q);
    4127             :         }
    4128        1609 :         q = pushArgument(mb, q, val->nr);
    4129        1609 :         if (q){
    4130        1609 :                 stmt *s = stmt_create(be->mvc->sa, st_assign);
    4131        1609 :                 if(!s) {
    4132           0 :                         freeInstruction(q);
    4133           0 :                         return NULL;
    4134             :                 }
    4135        1609 :                 s->op2 = val;
    4136        1609 :                 s->flag = (level << 1);
    4137        1609 :                 s->q = q;
    4138        1609 :                 s->nr = 1;
    4139        1609 :                 return s;
    4140             :         }
    4141             :         return NULL;
    4142             : }
    4143             : 
    4144             : stmt *
    4145        9300 : const_column(backend *be, stmt *val)
    4146             : {
    4147        9300 :         sql_subtype *ct = tail_type(val);
    4148        9300 :         MalBlkPtr mb = be->mb;
    4149             :         InstrPtr q = NULL;
    4150        9300 :         int tt = ct->type->localtype;
    4151             : 
    4152        9300 :         if (val->nr < 0)
    4153             :                 return NULL;
    4154        9300 :         q = newStmt(mb, batRef, singleRef);
    4155        9300 :         if (q == NULL)
    4156             :                 return NULL;
    4157        9300 :         setVarType(mb, getArg(q, 0), newBatType(tt));
    4158        9300 :         q = pushArgument(mb, q, val->nr);
    4159        9300 :         if (q) {
    4160        9300 :                 stmt *s = stmt_create(be->mvc->sa, st_single);
    4161        9300 :                 if(!s) {
    4162           0 :                         freeInstruction(q);
    4163           0 :                         return NULL;
    4164             :                 }
    4165        9300 :                 s->op1 = val;
    4166        9300 :                 s->op4.typeval = *ct;
    4167        9300 :                 s->nrcols = 1;
    4168             : 
    4169        9300 :                 s->tname = val->tname;
    4170        9300 :                 s->cname = val->cname;
    4171        9300 :                 s->nr = getDestVar(q);
    4172        9300 :                 s->q = q;
    4173        9300 :                 return s;
    4174             :         }
    4175             :         return NULL;
    4176             : }
    4177             : 
    4178             : stmt *
    4179          31 : stmt_fetch(backend *be, stmt *val)
    4180             : {
    4181             :         sql_subtype *ct;
    4182          31 :         MalBlkPtr mb = be->mb;
    4183             :         InstrPtr q = NULL;
    4184             :         int tt;
    4185             : 
    4186          31 :         if (val->nr < 0)
    4187             :                 return NULL;
    4188             :         /* pick from first column on a table case */
    4189          31 :         if (val->type == st_table) {
    4190           1 :                 if (list_length(val->op1->op4.lval) > 1)
    4191             :                         return NULL;
    4192           1 :                 val = val->op1->op4.lval->h->data;
    4193             :         }
    4194          31 :         ct = tail_type(val);
    4195          31 :         tt = ct->type->localtype;
    4196             : 
    4197          31 :         q = newStmt(mb, algebraRef, fetchRef);
    4198          31 :         if (q == NULL)
    4199             :                 return NULL;
    4200          31 :         setVarType(mb, getArg(q, 0), tt);
    4201          31 :         q = pushArgument(mb, q, val->nr);
    4202          31 :         q = pushOid(mb, q, 0);
    4203          31 :         if (q) {
    4204          31 :                 stmt *s = stmt_create(be->mvc->sa, st_single);
    4205          31 :                 if(!s) {
    4206           0 :                         freeInstruction(q);
    4207           0 :                         return NULL;
    4208             :                 }
    4209          31 :                 s->op1 = val;
    4210          31 :                 s->op4.typeval = *ct;
    4211          31 :                 s->nrcols = 0;
    4212             : 
    4213          31 :                 s->tname = val->tname;
    4214          31 :                 s->cname = val->cname;
    4215          31 :                 s->nr = getDestVar(q);
    4216          31 :                 s->q = q;
    4217          31 :                 return s;
    4218             :         }
    4219             :         return NULL;
    4220             : }

Generated by: LCOV version 1.14