LCOV - code coverage report
Current view: top level - sql/backends/monet5 - sql_statement.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2776 3340 83.1 %
Date: 2024-04-25 20:03:45 Functions: 106 108 98.1 %

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

Generated by: LCOV version 1.14