LCOV - code coverage report
Current view: top level - monetdb5/optimizer - opt_pushselect.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 244 485 50.3 %
Date: 2021-10-13 02:24:04 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : #include "monetdb_config.h"
      10             : #include "opt_pushselect.h"
      11             : #include "mal_interpreter.h"  /* for showErrors() */
      12             : 
      13             : static InstrPtr
      14      102917 : PushArgument(MalBlkPtr mb, InstrPtr p, int arg, int pos)
      15             : {
      16             :         int i;
      17             : 
      18      102917 :         p = pushArgument(mb, p, arg); /* push at end */
      19      411668 :         for (i = p->argc-1; i > pos; i--)
      20      308751 :                 getArg(p, i) = getArg(p, i-1);
      21      102917 :         getArg(p, pos) = arg;
      22      102917 :         return p;
      23             : }
      24             : 
      25             : #if 0
      26             : static InstrPtr
      27             : PushNil(MalBlkPtr mb, InstrPtr p, int pos, int tpe)
      28             : {
      29             :         int i, arg;
      30             : 
      31             :         p = pushNil(mb, p, tpe); /* push at end */
      32             :         arg = getArg(p, p->argc-1);
      33             :         for (i = p->argc-1; i > pos; i--)
      34             :                 getArg(p, i) = getArg(p, i-1);
      35             :         getArg(p, pos) = arg;
      36             :         return p;
      37             : }
      38             : #endif
      39             : 
      40             : static InstrPtr
      41       28273 : ReplaceWithNil(MalBlkPtr mb, InstrPtr p, int pos, int tpe)
      42             : {
      43       28273 :         p = pushNil(mb, p, tpe); /* push at end */
      44       28273 :         getArg(p, pos) = getArg(p, p->argc-1);
      45       28273 :         p->argc--;
      46       28273 :         return p;
      47             : }
      48             : 
      49             : 
      50             : #define MAX_TABLES 64
      51             : 
      52             : typedef struct subselect_t {
      53             :         int nr;
      54             :         int tid[MAX_TABLES];
      55             :         int subselect[MAX_TABLES];
      56             : } subselect_t;
      57             : 
      58             : static int
      59        4281 : subselect_add( subselect_t *subselects, int tid, int subselect )
      60             : {
      61             :         int i;
      62             : 
      63        4514 :         for (i = 0; i<subselects->nr; i++) {
      64         612 :                 if (subselects->tid[i] == tid) {
      65         379 :                         if (subselects->subselect[i] == subselect)
      66             :                                 return i;
      67             :                         else
      68         379 :                                 return -1;
      69             :                 }
      70             :         }
      71        3902 :         if (i >= MAX_TABLES)
      72             :                 return -1;
      73        3902 :         subselects->nr++;
      74        3902 :         subselects->tid[i] = tid;
      75        3902 :         subselects->subselect[i] = subselect;
      76        3902 :         return i;
      77             : }
      78             : 
      79             : #if 0
      80             : static int
      81             : subselect_find_tids( subselect_t *subselects, int subselect)
      82             : {
      83             :         int i;
      84             : 
      85             :         for (i = 0; i<subselects->nr; i++) {
      86             :                 if (subselects->subselect[i] == subselect) {
      87             :                         return subselects->tid[i];
      88             :                 }
      89             :         }
      90             :         return -1;
      91             : }
      92             : 
      93             : static int
      94             : subselect_find_subselect( subselect_t *subselects, int tid)
      95             : {
      96             :         int i;
      97             : 
      98             :         for (i = 0; i<subselects->nr; i++) {
      99             :                 if (subselects->tid[i] == tid) {
     100             :                         return subselects->subselect[i];
     101             :                 }
     102             :         }
     103             :         return -1;
     104             : }
     105             : #endif
     106             : 
     107             : static int
     108    28148489 : lastbat_arg(MalBlkPtr mb, InstrPtr p)
     109             : {
     110             :         int i = 0;
     111    36340168 :         for (i=p->retc; i<p->argc; i++) {
     112    17679543 :                 int type = getArgType(mb, p, i);
     113    17679543 :                 if (!isaBatType(type) && type != TYPE_bat)
     114             :                         break;
     115             :         }
     116    28148489 :         if (i < p->argc)
     117     9487864 :                 return i-1;
     118             :         return 0;
     119             : }
     120             : 
     121             : /* check for updates inbetween assignment to variables newv and oldv */
     122             : static int
     123             : no_updates(InstrPtr *old, int *vars, int oldv, int newv)
     124             : {
     125             :         while(newv > oldv) {
     126             :                 InstrPtr q = old[vars[newv]];
     127             : 
     128             :                 if (isUpdateInstruction(q))
     129             :                         return 0;
     130             :                 newv = getArg(q, 1);
     131             :         }
     132             :         return 1;
     133             : }
     134             : 
     135             : #define isIntersect(p) (getModuleId(p) == algebraRef && getFunctionId(p) == intersectRef)
     136             : 
     137             : str
     138      353093 : OPTpushselectImplementation(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     139             : {
     140             :         int i, j, limit, slimit, actions=0, *vars, *nvars = NULL, *slices = NULL, push_down_delta = 0, nr_topn = 0, nr_likes = 0, no_mito = 0;
     141             :         char *rslices = NULL, *oclean = NULL;
     142             :         InstrPtr p, *old = NULL;
     143             :         subselect_t subselects;
     144             :         str msg = MAL_SUCCEED;
     145             : 
     146      353093 :         subselects = (subselect_t) {0};
     147      353093 :         if( mb->errors)
     148             :                 return MAL_SUCCEED;
     149             : 
     150      353093 :         no_mito = !isOptimizerEnabled(mb, mitosisRef);
     151             :         (void) stk;
     152      353092 :         vars= (int*) GDKzalloc(sizeof(int)* mb->vtop);
     153      353093 :         if( vars == NULL)
     154           0 :                 throw(MAL,"optimizer.pushselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     155             : 
     156      353093 :         limit = mb->stop;
     157      353093 :         slimit= mb->ssize;
     158      353093 :         old = mb->stmt;
     159             : 
     160             :         /* check for bailout conditions */
     161    14959533 :         for (i = 1; i < limit; i++) {
     162             :                 int lastbat;
     163    14627894 :                 p = old[i];
     164             : 
     165    29395151 :                 for (j = 0; j<p->retc; j++) {
     166    14767257 :                         int res = getArg(p, j);
     167    14767257 :                         vars[res] = i;
     168             :                 }
     169             : 
     170    14627894 :                 if (getModuleId(p) == algebraRef &&
     171     1499041 :                         ((!no_mito && getFunctionId(p) == intersectRef) ||
     172     1558324 :                          getFunctionId(p) == differenceRef)) {
     173       21075 :                         GDKfree(vars);
     174       21075 :                         goto wrapup;
     175             :                 }
     176             : 
     177    14606819 :                 if (isSlice(p))
     178         465 :                         nr_topn++;
     179             : 
     180    14606820 :                 if (isLikeOp(p))
     181         125 :                         nr_likes++;
     182             : 
     183    14606819 :                 if (no_mito && isIntersect(p))
     184           1 :                         push_down_delta++;
     185             : 
     186    14606819 :                 if ((getModuleId(p) == sqlRef && getFunctionId(p) == deltaRef) ||
     187     4044480 :                         (no_mito && getModuleId(p) == matRef && getFunctionId(p) == packRef && p->argc == (p->retc+2)))
     188      214378 :                         push_down_delta++;
     189             : 
     190             :                 if (/* DISABLES CODE */ (0) && getModuleId(p) == sqlRef && getFunctionId(p) == tidRef) { /* rewrite equal table ids */
     191             :                         int sname = getArg(p, 2), tname = getArg(p, 3), s;
     192             : 
     193             :                         for (s = 0; s < subselects.nr; s++) {
     194             :                                 InstrPtr q = old[vars[subselects.tid[s]]];
     195             :                                 int Qsname = getArg(q, 2), Qtname = getArg(q, 3);
     196             : 
     197             :                                 if (no_updates(old, vars, getArg(q,1), getArg(p,1)) &&
     198             :                                         ((sname == Qsname && tname == Qtname) ||
     199             :                                         (/* DISABLES CODE */ (0) && strcmp(getVarConstant(mb, sname).val.sval, getVarConstant(mb, Qsname).val.sval) == 0 &&
     200             :                                          strcmp(getVarConstant(mb, tname).val.sval, getVarConstant(mb, Qtname).val.sval) == 0))) {
     201             :                                         clrFunction(p);
     202             :                                         p->retc = 1;
     203             :                                         p->argc = 2;
     204             :                                         getArg(p, 1) = getArg(q, 0);
     205             :                                         break;
     206             :                                 }
     207             :                         }
     208             :                 }
     209    14606819 :                 lastbat = lastbat_arg(mb, p);
     210    14606819 :                 if (isSelect(p) && p->retc == 1 &&
     211      489930 :                         /* no cand list */ getArgType(mb, p, lastbat) != newBatType(TYPE_oid)) {
     212      373926 :                         int i1 = getArg(p, 1), tid = 0;
     213      373926 :                         InstrPtr q = old[vars[i1]];
     214             : 
     215             :                         /* find the table ids */
     216      373926 :                         while(!tid) {
     217      398337 :                                 if (getModuleId(q) == algebraRef && getFunctionId(q) == projectionRef) {
     218       20761 :                                         int i1 = getArg(q, 1);
     219       20761 :                                         InstrPtr s = old[vars[i1]];
     220             : 
     221       20761 :                                         if (getModuleId(s) == sqlRef && getFunctionId(s) == tidRef)
     222             :                                                 tid = getArg(q, 1);
     223       20761 :                                         if (s->argc == 2 && s->retc == 1) {
     224           0 :                                                 int i1 = getArg(s, 1);
     225           0 :                                                 InstrPtr s = old[vars[i1]];
     226           0 :                                                 if (getModuleId(s) == sqlRef && getFunctionId(s) == tidRef)
     227             :                                                         tid = getArg(q, 1);
     228             :                                         }
     229             :                                         break;
     230      377576 :                                 } else if (isMapOp(q) && q->retc == 1 && q->argc >= 2 && isaBatType(getArgType(mb, q, 1))) {
     231             :                                         int i1 = getArg(q, 1);
     232       24325 :                                         q = old[vars[i1]];
     233      353251 :                                 } else if (isMapOp(q) && q->retc == 1 && q->argc >= 3 && isaBatType(getArgType(mb, q, 2))) {
     234             :                                         int i2 = getArg(q, 2);
     235          86 :                                         q = old[vars[i2]];
     236             :                                 } else {
     237             :                                         break;
     238             :                                 }
     239             :                         }
     240      373926 :                         if (tid && subselect_add(&subselects, tid, getArg(p, 0)) < 0) {
     241         379 :                                 GDKfree(vars);
     242         379 :                                 goto wrapup;
     243             :                         }
     244             :                 }
     245             :                 /* left hand side */
     246    14606440 :                 if ( (GDKdebug & (1<<15)) &&
     247           0 :                          isMatJoinOp(p) && p->retc == 2) {
     248           0 :                         int i1 = getArg(p, 2), tid = 0;
     249           0 :                         InstrPtr q = old[vars[i1]];
     250             : 
     251             :                         /* find the table ids */
     252           0 :                         while(!tid) {
     253           0 :                                 if (getModuleId(q) == algebraRef && getFunctionId(q) == projectionRef) {
     254           0 :                                         int i1 = getArg(q, 1);
     255           0 :                                         InstrPtr s = old[vars[i1]];
     256             : 
     257           0 :                                         if (getModuleId(s) == sqlRef && getFunctionId(s) == tidRef)
     258             :                                                 tid = getArg(q, 1);
     259             :                                         break;
     260           0 :                                 } else if (isMapOp(q) && q->argc >= 2 && isaBatType(getArgType(mb, q, 1))) {
     261             :                                         int i1 = getArg(q, 1);
     262           0 :                                         q = old[vars[i1]];
     263           0 :                                 } else if (isMapOp(q) && q->argc >= 3 && isaBatType(getArgType(mb, q, 2))) {
     264             :                                         int i2 = getArg(q, 2);
     265           0 :                                         q = old[vars[i2]];
     266             :                                 } else {
     267             :                                         break;
     268             :                                 }
     269             :                         }
     270           0 :                         if (tid && subselect_add(&subselects, tid, getArg(p, 0)) < 0) {
     271           0 :                                 GDKfree(vars);
     272           0 :                                 goto wrapup;
     273             :                         }
     274             :                 }
     275             :                 /* right hand side */
     276    14606440 :                 if ( (GDKdebug & (1<<15)) &&
     277           0 :                          isMatJoinOp(p) && p->retc == 2) {
     278           0 :                         int i1 = getArg(p, 3), tid = 0;
     279           0 :                         InstrPtr q = old[vars[i1]];
     280             : 
     281             :                         /* find the table ids */
     282           0 :                         while(!tid) {
     283           0 :                                 if (getModuleId(q) == algebraRef && getFunctionId(q) == projectionRef) {
     284           0 :                                         int i1 = getArg(q, 1);
     285           0 :                                         InstrPtr s = old[vars[i1]];
     286             : 
     287           0 :                                         if (getModuleId(s) == sqlRef && getFunctionId(s) == tidRef)
     288             :                                                 tid = getArg(q, 1);
     289             :                                         break;
     290           0 :                                 } else if (isMapOp(q) && q->argc >= 2 && isaBatType(getArgType(mb, q, 1))) {
     291             :                                         int i1 = getArg(q, 1);
     292           0 :                                         q = old[vars[i1]];
     293           0 :                                 } else if (isMapOp(q) && q->argc >= 3 && isaBatType(getArgType(mb, q, 2))) {
     294             :                                         int i2 = getArg(q, 2);
     295           0 :                                         q = old[vars[i2]];
     296             :                                 } else {
     297             :                                         break;
     298             :                                 }
     299             :                         }
     300           0 :                         if (tid && subselect_add(&subselects, tid, getArg(p, 1)) < 0) {
     301           0 :                                 GDKfree(vars);
     302           0 :                                 goto wrapup;
     303             :                         }
     304             :                 }
     305             :         }
     306             : 
     307      331639 :         if (nr_likes || subselects.nr) {
     308        2893 :                 if (newMalBlkStmt(mb, mb->ssize) <0 ) {
     309           0 :                         GDKfree(vars);
     310           0 :                         goto wrapup;
     311             :                 }
     312             : 
     313        2893 :                 pushInstruction(mb,old[0]);
     314             : 
     315      155575 :                 for (i = 1; i < limit; i++) {
     316      152682 :                         p = old[i];
     317             : 
     318             :                         /* rewrite batalgebra.like + [theta]select -> likeselect */
     319      152682 :                         if (getModuleId(p) == algebraRef && p->retc == 1 &&
     320        9637 :                                 (getFunctionId(p) == selectRef || getFunctionId(p) == thetaselectRef)) {
     321        4691 :                                 int var = getArg(p, 1);
     322        4691 :                                 InstrPtr q = mb->stmt[vars[var]]; /* BEWARE: the optimizer may not add or remove statements ! */
     323             : 
     324        4691 :                                 if (isLikeOp(q) &&
     325          16 :                                         !isaBatType(getArgType(mb, q, 2)) && isVarConstant(mb, getArg(q, 2)) && /* pattern is a value */
     326          10 :                                         isVarConstant(mb, getArg(q, 3)) && /* escape is a value */
     327          10 :                                         isVarConstant(mb, getArg(q, 4)) && /* isensitive flag is a value */
     328          10 :                                         strcmp(getVarName(mb, getArg(q,0)), getVarName(mb, getArg(p,1))) == 0 /* the output variable from batalgebra.like is the input one for [theta]select */) {
     329          10 :                                         int has_cand = (getArgType(mb, p, 2) == newBatType(TYPE_oid)), offset = 0, anti = (getFunctionId(q)[0] == 'n');
     330          10 :                                         bit ignore_case = *(bit*)getVarValue(mb, getArg(q, 4)), selectok = TRUE;
     331             : 
     332             :                                         /* TODO at the moment we cannot convert if the select statement has NULL semantics
     333             :                                                 we can convert it into VAL is NULL or PATTERN is NULL or ESCAPE is NULL
     334             :                                         */
     335          10 :                                         if (getFunctionId(p) == selectRef && isVarConstant(mb, getArg(p, 2 + has_cand)) &&
     336           3 :                                                 isVarConstant(mb, getArg(p, 3 + has_cand)) && isVarConstant(mb, getArg(p, 4 + has_cand)) &&
     337           6 :                                                 isVarConstant(mb, getArg(p, 5 + has_cand)) && isVarConstant(mb, getArg(p, 6 + has_cand)) &&
     338           3 :                                                 (p->argc < (has_cand ? 9 : 8) || isVarConstant(mb, getArg(p, 7 + has_cand)))) {
     339           3 :                                                 bit low = *(bit*)getVarValue(mb, getArg(p, 2 + has_cand)), high = *(bit*)getVarValue(mb, getArg(p, 3 + has_cand));
     340           3 :                                                 bit li = *(bit*)getVarValue(mb, getArg(p, 4 + has_cand)), hi = *(bit*)getVarValue(mb, getArg(p, 5 + has_cand));
     341           3 :                                                 bit santi = *(bit*)getVarValue(mb, getArg(p, 6 + has_cand));
     342           3 :                                                 bit sunknown = (p->argc == (has_cand ? 9 : 8)) ? 0 : *(bit*)getVarValue(mb, getArg(p, 7 + has_cand));
     343             : 
     344             :                                                 /* semantic or not symmetric cases, it cannot be converted */
     345           3 :                                                 if (is_bit_nil(low) || is_bit_nil(li) || is_bit_nil(santi) || low != high || li != hi || sunknown)
     346             :                                                         selectok = FALSE;
     347             : 
     348             :                                                 /* there are no negative candidate lists so on = false situations swap anti flag */
     349           3 :                                                 if (low == 0)
     350           0 :                                                         anti = !anti;
     351           3 :                                                 if (li == 0)
     352           0 :                                                         anti = !anti;
     353           3 :                                                 if (santi)
     354           0 :                                                         anti = !anti;
     355           7 :                                         } else if (getFunctionId(p) == thetaselectRef &&
     356           7 :                                                            isVarConstant(mb, getArg(p, 3)) && isVarConstant(mb, getArg(p, 4))) {
     357           6 :                                                 bit truth_value = *(bit*)getVarValue(mb, getArg(p, 3));
     358           6 :                                                 str comparison = (str)getVarValue(mb, getArg(p, 4));
     359             : 
     360             :                                                 /* there are no negative candidate lists so on = false situations swap anti flag */
     361           6 :                                                 if (truth_value == 0)
     362           2 :                                                         anti = !anti;
     363           4 :                                                 else if (is_bit_nil(truth_value))
     364             :                                                         selectok = FALSE;
     365           6 :                                                 if (strcmp(comparison, "<>") == 0)
     366           0 :                                                         anti = !anti;
     367           6 :                                                 else if (strcmp(comparison, "==") != 0)
     368             :                                                         selectok = FALSE;
     369             :                                         } else {
     370             :                                                 selectok = FALSE;
     371             :                                         }
     372             : 
     373           9 :                                         if (selectok) {
     374           6 :                                                 InstrPtr r = newInstruction(mb, algebraRef, likeselectRef);
     375           6 :                                                 getArg(r,0) = getArg(p,0);
     376           6 :                                                 r = addArgument(mb, r, getArg(q, 1));
     377           6 :                                                 if (has_cand) {
     378           5 :                                                         r = addArgument(mb, r, getArg(p, 2));
     379             :                                                         offset = 1;
     380           1 :                                                 } else if (isaBatType(getArgType(mb, q, 1))) { /* likeselect calls have a candidate parameter */
     381           1 :                                                         r = pushNil(mb, r, TYPE_bat);
     382             :                                                         offset = 1;
     383             :                                                 }
     384          24 :                                                 for(int a = 2; a<q->argc; a++)
     385          18 :                                                         r = addArgument(mb, r, getArg(q, a));
     386           6 :                                                 if (r->argc < (4+offset))
     387           0 :                                                         r = pushStr(mb, r, (str)getVarValue(mb, getArg(q, 3)));
     388           6 :                                                 if (r->argc < (5+offset))
     389           0 :                                                         r = pushBit(mb, r, ignore_case);
     390           6 :                                                 if (r->argc < (6+offset))
     391           6 :                                                         r = pushBit(mb, r, anti);
     392           6 :                                                 freeInstruction(p);
     393             :                                                 p = r;
     394           6 :                                                 actions++;
     395             :                                         }
     396             :                                 }
     397             :                         }
     398             : 
     399             :                         /* inject table ids into subselect
     400             :                          * s = subselect(c, C1..) => subselect(c, t, C1..)
     401             :                          */
     402             : #if 0
     403             :                         if (isSelect(p) && p->retc == 1) {
     404             :                                 int tid = 0;
     405             : 
     406             :                                 if ((tid = subselect_find_tids(&subselects, getArg(p, 0))) >= 0) {
     407             :                                         int lastbat = lastbat_arg(mb, p);
     408             :                                         if (getArgType(mb, p, lastbat) == TYPE_bat) /* empty candidate list bat_nil */
     409             :                                                 getArg(p, lastbat) = tid;
     410             :                                         else
     411             :                                                 p = PushArgument(mb, p, tid, lastbat+1);
     412             :                                         /* make sure to resolve again */
     413             :                                         p->token = ASSIGNsymbol;
     414             :                                         p->typechk = TYPE_UNKNOWN;
     415             :                                         p->fcn = NULL;
     416             :                                         p->blk = NULL;
     417             :                                         actions++;
     418             :                                 }
     419             :                         } else if ( (GDKdebug & (1<<15)) && isMatJoinOp(p) && p->retc == 2) {
     420             :                                 int ltid = 0, rtid = 0, done = 0;
     421             :                                 int range = 0;
     422             : 
     423             :                                 if ((ltid = subselect_find_tids(&subselects, getArg(p, 0))) >= 0 &&
     424             :                                                 (rtid = subselect_find_tids(&subselects, getArg(p, 1))) >= 0) {
     425             :                                         p = PushArgument(mb, p, ltid, 4+range);
     426             :                                         p = PushArgument(mb, p, rtid, 5+range);
     427             :                                         done = 1;
     428             :                                 } else if ((ltid = subselect_find_tids(&subselects, getArg(p, 0))) >= 0) {
     429             :                                         p = PushArgument(mb, p, ltid, 4+range);
     430             :                                         p = PushNil(mb, p, 5+range, TYPE_bat);
     431             :                                         done = 1;
     432             :                                 } else if ((rtid = subselect_find_tids(&subselects, getArg(p, 1))) >= 0) {
     433             :                                         p = PushNil(mb, p, 4+range, TYPE_bat);
     434             :                                         p = PushArgument(mb, p, rtid, 5+range);
     435             :                                         done = 1;
     436             :                                 }
     437             :                                 if (done) {
     438             :                                         p = pushBit(mb, p, FALSE); /* do not match nils */
     439             :                                         p = pushNil(mb, p, TYPE_lng); /* no estimate */
     440             : 
     441             :                                         /* make sure to resolve again */
     442             :                                         p->token = ASSIGNsymbol;
     443             :                                         p->typechk = TYPE_UNKNOWN;
     444             :                                         p->fcn = NULL;
     445             :                                         p->blk = NULL;
     446             :                                         actions++;
     447             :                                 }
     448             :                         }
     449             :                         /* Projections involving rewriten table ids need to be flattend
     450             :                          * l = projection(t, c); => l = c;
     451             :                          * and
     452             :                          * l = projection(s, ntids); => l = s;
     453             :                          */
     454             :                         else if (getModuleId(p) == algebraRef && getFunctionId(p) == projectionRef) {
     455             :                                 int var = getArg(p, 1);
     456             : 
     457             :                                 if (subselect_find_subselect(&subselects, var) > 0) {
     458             :                                         InstrPtr q = newAssignment(mb);
     459             : 
     460             :                                         getArg(q, 0) = getArg(p, 0);
     461             :                                         (void) addArgument(mb, q, getArg(p, 2));
     462             :                                         actions++;
     463             :                                         freeInstruction(p);
     464             :                                         continue;
     465             :                                 } else { /* deletes/updates use table ids */
     466             :                                         int var = getArg(p, 2);
     467             :                                         InstrPtr q = mb->stmt[vars[var]]; /* BEWARE: the optimizer may not add or remove statements ! */
     468             : 
     469             :                                         if (q->token == ASSIGNsymbol) {
     470             :                                                 var = getArg(q, 1);
     471             :                                                 q = mb->stmt[vars[var]];
     472             :                                         }
     473             :                                         if (subselect_find_subselect(&subselects, var) > 0) {
     474             :                                                 InstrPtr qq = newAssignment(mb);
     475             :                                                 /* TODO: check result */
     476             : 
     477             :                                                 getArg(qq, 0) = getArg(p, 0);
     478             :                                                 (void) addArgument(mb, qq, getArg(p, 1));
     479             :                                                 actions++;
     480             :                                                 freeInstruction(p);
     481             :                                                 continue;
     482             :                                         }
     483             :                                         /* c = sql.delta(b,uid,uval);
     484             :                                          * l = projection(x, c);
     485             :                                          * into
     486             :                                          * l = sql.projectdelta(x,b,uid,uval);
     487             :                                          */
     488             :                                         else if (getModuleId(q) == sqlRef && getFunctionId(q) == deltaRef && q->argc == 4) {
     489             :                                                 q = copyInstruction(q);
     490             :                                                 if( q == NULL){
     491             :                                                         for (; i<limit; i++)
     492             :                                                                 if (old[i])
     493             :                                                                         pushInstruction(mb,old[i]);
     494             :                                                         GDKfree(old);
     495             :                                                         GDKfree(vars);
     496             :                                                         throw(MAL,"optimizer.pushselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     497             :                                                 }
     498             : 
     499             :                                                 setFunctionId(q, projectdeltaRef);
     500             :                                                 getArg(q, 0) = getArg(p, 0);
     501             :                                                 q = PushArgument(mb, q, getArg(p, 1), 1);
     502             :                                                 freeInstruction(p);
     503             :                                                 p = q;
     504             :                                                 actions++;
     505             :                                         }
     506             :                                 }
     507             :                         }
     508             : #endif
     509      152682 :                         pushInstruction(mb,p);
     510             :                 }
     511             :                 for (; i<limit; i++)
     512             :                         if (old[i])
     513             :                                 pushInstruction(mb,old[i]);
     514      592790 :                 for (; i<slimit; i++)
     515      589897 :                         if (old[i])
     516           0 :                                 freeInstruction(old[i]);
     517        2893 :                 GDKfree(old);
     518        2893 :                 if (!push_down_delta) {
     519        2877 :                         GDKfree(vars);
     520        2877 :                         goto wrapup;
     521             :                 }
     522             :         }
     523             : 
     524             :         /* now push selects through delta's */
     525      328762 :         limit = mb->stop;
     526      328762 :         slimit= mb->ssize;
     527      328762 :         old = mb->stmt;
     528             : 
     529      328762 :         nvars = (int*) GDKzalloc(sizeof(int)* mb->vtop);
     530      328762 :         slices = (int*) GDKzalloc(sizeof(int)* mb->vtop);
     531      328762 :         rslices = (char*) GDKzalloc(sizeof(char)* mb->vtop);
     532      328762 :         oclean = (char*) GDKzalloc(sizeof(char)* mb->vtop);
     533      328762 :         if (!nvars || !slices || !rslices || !oclean || newMalBlkStmt(mb, mb->stop+(5*push_down_delta)+(2*nr_topn)) <0 ) {
     534           0 :                 mb->stmt = old;
     535           0 :                 GDKfree(vars);
     536           0 :                 GDKfree(nvars);
     537           0 :                 GDKfree(slices);
     538           0 :                 GDKfree(rslices);
     539           0 :                 GDKfree(oclean);
     540           0 :                 goto wrapup;
     541             :         }
     542      328762 :         pushInstruction(mb,old[0]);
     543             : 
     544    13870488 :         for (i = 1; i < limit; i++) {
     545             :                 int lastbat;
     546    13541726 :                 p = old[i];
     547             : 
     548    27078409 :                 for (j = 0; j<p->retc; j++) {
     549    13536683 :                         int res = getArg(p, j);
     550    13536683 :                         vars[res] = i;
     551             :                 }
     552             : 
     553             :                 /* push subslice under projectdelta */
     554    13541726 :                 if (isSlice(p) && p->retc == 1) {
     555         364 :                         int var = getArg(p, 1);
     556         364 :                         InstrPtr q = old[vars[var]];
     557         364 :                         if (q && getModuleId(q) == sqlRef && getFunctionId(q) == projectdeltaRef) {
     558           0 :                                 InstrPtr r = copyInstruction(p);
     559           0 :                                 InstrPtr s = copyInstruction(q);
     560             : 
     561           0 :                                 rslices[getArg(q,0)] = 1; /* mark projectdelta as rewriten */
     562           0 :                                 rslices[getArg(p,0)] = 1; /* mark slice as rewriten */
     563             : 
     564           0 :                                 if (r == NULL || s == NULL){
     565           0 :                                         GDKfree(vars);
     566           0 :                                         GDKfree(nvars);
     567           0 :                                         GDKfree(slices);
     568           0 :                                         GDKfree(rslices);
     569           0 :                                         GDKfree(oclean);
     570           0 :                                         GDKfree(old);
     571           0 :                                         freeInstruction(r);
     572           0 :                                         freeInstruction(s);
     573           0 :                                         throw(MAL,"optimizer.pushselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     574             :                                 }
     575             : 
     576             :                                 /* slice the candidates */
     577           0 :                                 setFunctionId(r, sliceRef);
     578           0 :                                 nvars[getArg(p,0)] =  getArg(r, 0) =
     579           0 :                                 newTmpVariable(mb, getArgType(mb, r, 0));
     580           0 :                                 slices[getArg(q, 1)] = getArg(p, 0);
     581             : 
     582           0 :                                 setVarCList(mb,getArg(r,0));
     583           0 :                                 getArg(r, 1) = getArg(s, 1);
     584           0 :                                 pushInstruction(mb,r);
     585             : 
     586           0 :                                 nvars[getArg(q,0)] =  getArg(s, 0) =
     587           0 :                                 newTmpVariable(mb, getArgType(mb, s, 0));
     588           0 :                                 getArg(s, 1) = getArg(r, 0); /* use result of slice */
     589           0 :                                 pushInstruction(mb, s);
     590           0 :                                 oclean[i] = 1;
     591           0 :                                 actions++;
     592           0 :                                 continue;
     593             :                         }
     594             :                 }
     595             :                 /* Leftfetchjoins involving rewriten sliced candidates ids need to be flattend
     596             :                  * l = projection(t, c); => l = c;
     597             :                  * and
     598             :                  * l = projection(s, ntids); => l = s;
     599             :                  */
     600    13541379 :                 else if (getModuleId(p) == algebraRef && getFunctionId(p) == projectionRef) {
     601     1009575 :                         int var = getArg(p, 1);
     602     1009575 :                         InstrPtr r = old[vars[var]], q;
     603             : 
     604     1009575 :                         if (r && isSlice(r) && rslices[var] && getArg(r, 0) == getArg(p, 1)) {
     605           0 :                                 int col = getArg(p, 2);
     606             : 
     607           0 :                                 if (!rslices[col]) { /* was the deltaproject rewriten (sliced) */
     608           0 :                                         InstrPtr s = old[vars[col]], u = NULL;
     609             : 
     610           0 :                                         if (s && getModuleId(s) == algebraRef && getFunctionId(s) == projectRef) {
     611           0 :                                                 col = getArg(s, 1);
     612             :                                                 u = s;
     613           0 :                                                 s = old[vars[col]];
     614             :                                         }
     615           0 :                                         if (s && getModuleId(s) == sqlRef && getFunctionId(s) == projectdeltaRef) {
     616           0 :                                                 InstrPtr t = copyInstruction(s);
     617           0 :                                                 if (t == NULL){
     618           0 :                                                         GDKfree(vars);
     619           0 :                                                         GDKfree(nvars);
     620           0 :                                                         GDKfree(slices);
     621           0 :                                                         GDKfree(rslices);
     622           0 :                                                         GDKfree(oclean);
     623           0 :                                                         GDKfree(old);
     624           0 :                                                         throw(MAL,"optimizer.pushselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     625             :                                                 }
     626             : 
     627           0 :                                                 getArg(t, 1) = nvars[getArg(r, 0)]; /* use result of slice */
     628           0 :                                                 rslices[col] = 1;
     629           0 :                                                 nvars[getArg(s,0)] =  getArg(t, 0) =
     630           0 :                                                 newTmpVariable(mb, getArgType(mb, t, 0));
     631           0 :                                                 pushInstruction(mb, t);
     632           0 :                                                 if (u) { /* add again */
     633           0 :                                                         if((t = copyInstruction(u)) == NULL) {
     634           0 :                                                                 GDKfree(vars);
     635           0 :                                                                 GDKfree(nvars);
     636           0 :                                                                 GDKfree(slices);
     637           0 :                                                                 GDKfree(rslices);
     638           0 :                                                                 GDKfree(oclean);
     639           0 :                                                                 GDKfree(old);
     640           0 :                                                                 throw(MAL,"optimizer.pushselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     641             :                                                         }
     642           0 :                                                         getArg(t, 1) = nvars[getArg(t,1)];
     643           0 :                                                         pushInstruction(mb, t);
     644             :                                                 }
     645             :                                         }
     646             :                                 }
     647           0 :                                 q = newAssignment(mb);
     648           0 :                                 getArg(q, 0) = getArg(p, 0);
     649           0 :                                 (void) addArgument(mb, q, getArg(p, 2));
     650           0 :                                 if (nvars[getArg(p, 2)] > 0)
     651           0 :                                         getArg(q, 1) = nvars[getArg(p, 2)];
     652           0 :                                 oclean[i] = 1;
     653           0 :                                 actions++;
     654           0 :                                 continue;
     655             :                         }
     656    12531804 :                 } else if (p->argc >= 2 && slices[getArg(p, 1)] != 0) {
     657             :                         /* use new slice candidate list */
     658           0 :                         assert(slices[getArg(p,1)] == nvars[getArg(p,1)]);
     659           0 :                         getArg(p, 1) = slices[getArg(p, 1)];
     660             :                 }
     661             :                 /* remap */
     662    31279902 :                 for (j = p->retc; j<p->argc; j++) {
     663    17738159 :                         int var = getArg(p, j);
     664    17738159 :                         if (nvars[var] > 0) {
     665           0 :                                 getArg(p, j) = nvars[var];
     666             :                         }
     667             :                 }
     668             : 
     669             :                 /* c = delta(b, uid, uvl)
     670             :                  * s = select(c, C1..)
     671             :                  *
     672             :                  * nc = select(b, C1..)
     673             :                  * nu = select(uvl, C1..)
     674             :                  * s = subdelta(nc, uid, nu);
     675             :                  *
     676             :                  * doesn't handle Xselect(x, .. z, C1.. cases) ie multicolumn selects
     677             :                  *
     678             :                  * also handle (if no_mito)
     679             :                  * c = pack(b, ins)
     680             :                  * s = select(c, C1..)
     681             :                  */
     682    13541743 :                 lastbat = lastbat_arg(mb, p);
     683    13541743 :                 if (isSelect(p) && p->retc == 1 && lastbat == 2) {
     684       69610 :                         int var = getArg(p, 1);
     685       69610 :                         InstrPtr q = old[vars[var]];
     686             : 
     687       69610 :                         if (q && q->token == ASSIGNsymbol) {
     688       32415 :                                 var = getArg(q, 1);
     689       32415 :                                 q = old[vars[var]];
     690             :                         }
     691       69610 :                         if (no_mito && q && getModuleId(q) == matRef && getFunctionId(q) == packRef && q->argc == (q->retc+2)) {
     692           0 :                                 InstrPtr r = copyInstruction(p);
     693           0 :                                 InstrPtr t = copyInstruction(p);
     694             : 
     695           0 :                                 if( r == NULL || t == NULL){
     696           0 :                                         freeInstruction(r);
     697           0 :                                         freeInstruction(t);
     698           0 :                                         GDKfree(vars);
     699           0 :                                         GDKfree(nvars);
     700           0 :                                         GDKfree(slices);
     701           0 :                                         GDKfree(rslices);
     702           0 :                                         GDKfree(oclean);
     703           0 :                                         GDKfree(old);
     704           0 :                                         throw(MAL,"optimizer.pushselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     705             :                                 }
     706           0 :                                 getArg(r, 0) = newTmpVariable(mb, newBatType(TYPE_oid));
     707           0 :                                 setVarCList(mb,getArg(r,0));
     708           0 :                                 getArg(r, 1) = getArg(q, 1); /* column */
     709           0 :                                 r->typechk = TYPE_UNKNOWN;
     710           0 :                                 pushInstruction(mb,r);
     711           0 :                                 getArg(t, 0) = newTmpVariable(mb, newBatType(TYPE_oid));
     712           0 :                                 setVarCList(mb,getArg(t,0));
     713           0 :                                 getArg(t, 1) = getArg(q, 2); /* inserts */
     714           0 :                                 pushInstruction(mb,t);
     715             : 
     716           0 :                                 InstrPtr u = copyInstruction(q); /* pack result */
     717           0 :                                 getArg(u, 0) = getArg(p,0);
     718           0 :                                 getArg(u, 1) = getArg(r,0);
     719           0 :                                 getArg(u, 2) = getArg(t,0);
     720           0 :                                 u->typechk = TYPE_UNKNOWN;
     721           0 :                                 pushInstruction(mb,u);
     722           0 :                                 oclean[i] = 1;
     723           0 :                                 continue;
     724       69610 :                         } else if (q && getModuleId(q) == sqlRef && getFunctionId(q) == deltaRef) {
     725       28272 :                                 InstrPtr r = copyInstruction(p);
     726       28273 :                                 InstrPtr s = copyInstruction(p);
     727       28273 :                                 InstrPtr u = copyInstruction(q);
     728             : 
     729       28273 :                                 if( r == NULL || s == NULL ||u == NULL){
     730           0 :                                         freeInstruction(r);
     731           0 :                                         freeInstruction(s);
     732           0 :                                         freeInstruction(u);
     733           0 :                                         GDKfree(vars);
     734           0 :                                         GDKfree(nvars);
     735           0 :                                         GDKfree(slices);
     736           0 :                                         GDKfree(rslices);
     737           0 :                                         GDKfree(oclean);
     738           0 :                                         GDKfree(old);
     739           0 :                                         throw(MAL,"optimizer.pushselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     740             :                                 }
     741       28273 :                                 getArg(r, 0) = newTmpVariable(mb, newBatType(TYPE_oid));
     742       28273 :                                 setVarCList(mb,getArg(r,0));
     743       28273 :                                 getArg(r, 1) = getArg(q, 1); /* column */
     744       28273 :                                 r->typechk = TYPE_UNKNOWN;
     745       28273 :                                 pushInstruction(mb,r);
     746       28273 :                                 getArg(s, 0) = newTmpVariable(mb, newBatType(TYPE_oid));
     747       28273 :                                 setVarCList(mb,getArg(s,0));
     748       28273 :                                 getArg(s, 1) = getArg(q, 3); /* updates */
     749       28273 :                                 s = ReplaceWithNil(mb, s, 2, TYPE_bat); /* no candidate list */
     750       28273 :                                 setArgType(mb, s, 2, newBatType(TYPE_oid));
     751             :                                 /* make sure to resolve again */
     752       28273 :                                 s->token = ASSIGNsymbol;
     753       28273 :                                 s->typechk = TYPE_UNKNOWN;
     754       28273 :                                 s->fcn = NULL;
     755       28273 :                                 s->blk = NULL;
     756       28273 :                                 pushInstruction(mb,s);
     757             : 
     758       28273 :                                 setFunctionId(u, subdeltaRef);
     759       28273 :                                 getArg(u, 0) = getArg(p,0);
     760       28273 :                                 getArg(u, 1) = getArg(r,0);
     761       28273 :                                 getArg(u, 2) = getArg(p,2); /* pre-cands */
     762       28273 :                                 getArg(u, 3) = getArg(q,2); /* update ids */
     763       28273 :                                 u = pushArgument(mb, u, getArg(s,0)); /* selected updated values ids */
     764       28273 :                                 u->token = ASSIGNsymbol;
     765       28273 :                                 u->typechk = TYPE_UNKNOWN;
     766       28273 :                                 u->fcn = NULL;
     767       28273 :                                 u->blk = NULL;
     768       28273 :                                 pushInstruction(mb,u);
     769       28273 :                                 oclean[i] = 1;
     770       28273 :                                 continue;
     771             :                         }
     772    13472118 :                 } else if (getModuleId(p) == algebraRef && getFunctionId(p) == projectionRef) {
     773     1009575 :                         int id = getArg(p, 1);
     774     1009575 :                         InstrPtr s = old[vars[id]];
     775     1009575 :                         int var = getArg(p, 2);
     776     1009575 :                         InstrPtr q = old[vars[var]];
     777             : 
     778     1009575 :                         if (no_mito &&
     779       33255 :                                 getModuleId(q) == matRef && getFunctionId(q) == packRef && q->argc == 3 &&
     780           0 :                                 getModuleId(s) == matRef && getFunctionId(s) == packRef && s->argc == 3) {
     781           0 :                                 InstrPtr r = copyInstruction(p);
     782           0 :                                 InstrPtr t = copyInstruction(p);
     783             : 
     784           0 :                                 if( r == NULL || t == NULL){
     785           0 :                                         freeInstruction(r);
     786           0 :                                         freeInstruction(t);
     787           0 :                                         GDKfree(vars);
     788           0 :                                         GDKfree(nvars);
     789           0 :                                         GDKfree(slices);
     790           0 :                                         GDKfree(rslices);
     791           0 :                                         GDKfree(oclean);
     792           0 :                                         GDKfree(old);
     793           0 :                                         throw(MAL,"optimizer.pushselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     794             :                                 }
     795           0 :                                 getArg(r, 0) = newTmpVariable(mb, getArgType(mb, p, 0));
     796           0 :                                 setVarCList(mb,getArg(r,0));
     797           0 :                                 getArg(r, 1) = getArg(s, 1);
     798           0 :                                 getArg(r, 2) = getArg(q, 1); /* column */
     799           0 :                                 r->typechk = TYPE_UNKNOWN;
     800           0 :                                 pushInstruction(mb,r);
     801           0 :                                 getArg(t, 0) = newTmpVariable(mb, getArgType(mb, p, 0));
     802           0 :                                 setVarCList(mb,getArg(t,0));
     803           0 :                                 getArg(t, 1) = getArg(s, 2);
     804           0 :                                 getArg(t, 2) = getArg(q, 2); /* inserts */
     805           0 :                                 pushInstruction(mb,t);
     806             : 
     807           0 :                                 InstrPtr u = copyInstruction(q); /* pack result */
     808           0 :                                 getArg(u, 0) = getArg(p,0);
     809           0 :                                 getArg(u, 1) = getArg(r,0);
     810           0 :                                 getArg(u, 2) = getArg(t,0);
     811           0 :                                 u->typechk = TYPE_UNKNOWN;
     812           0 :                                 pushInstruction(mb,u);
     813           0 :                                 oclean[i] = 1;
     814           0 :                                 continue;
     815     1009575 :                         } else if (getModuleId(q) == sqlRef && getFunctionId(q) == deltaRef && q->argc == 4) {
     816      102917 :                                 q = copyInstruction(q);
     817      102917 :                                 if( q == NULL){
     818           0 :                                         GDKfree(vars);
     819           0 :                                         GDKfree(nvars);
     820           0 :                                         GDKfree(slices);
     821           0 :                                         GDKfree(rslices);
     822           0 :                                         GDKfree(oclean);
     823           0 :                                         GDKfree(old);
     824           0 :                                         throw(MAL,"optimizer.pushselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     825             :                                 }
     826      102917 :                                 setFunctionId(q, projectdeltaRef);
     827      102917 :                                 getArg(q, 0) = getArg(p, 0);
     828      102917 :                                 q = PushArgument(mb, q, getArg(p, 1), 1);
     829             :                                 p = q;
     830      102917 :                                 oclean[i] = 1;
     831      102917 :                                 actions++;
     832             :                         }
     833    12462543 :                 } else if (isIntersect(p) && p->retc == 1 && lastbat == 4) {
     834             :                 /* l = delta(b, uid, uvl)
     835             :                  * s = intersect(l, r, li, ..)
     836             :                  *
     837             :                  * nc = intersect(b, r, li..)
     838             :                  * nu = intersect(uvl, r, ..)
     839             :                  * s = subdelta(nc, li, uid, nu);
     840             :                  */
     841           1 :                         int var = getArg(p, 1);
     842           1 :                         InstrPtr q = old[vars[var]];
     843             : 
     844           1 :                         if (q && q->token == ASSIGNsymbol) {
     845           0 :                                 var = getArg(q, 1);
     846           0 :                                 q = old[vars[var]];
     847             :                         }
     848           1 :                         if (q && getModuleId(q) == sqlRef && getFunctionId(q) == deltaRef) {
     849           0 :                                 InstrPtr r = copyInstruction(p);
     850           0 :                                 InstrPtr s = copyInstruction(p);
     851           0 :                                 InstrPtr u = copyInstruction(q);
     852             : 
     853           0 :                                 if( r == NULL || s == NULL || u == NULL){
     854           0 :                                         freeInstruction(r);
     855           0 :                                         freeInstruction(s);
     856           0 :                                         freeInstruction(u);
     857           0 :                                         GDKfree(vars);
     858           0 :                                         GDKfree(nvars);
     859           0 :                                         GDKfree(slices);
     860           0 :                                         GDKfree(rslices);
     861           0 :                                         GDKfree(oclean);
     862           0 :                                         GDKfree(old);
     863           0 :                                         throw(MAL,"optimizer.pushselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     864             :                                 }
     865           0 :                                 getArg(r, 0) = newTmpVariable(mb, newBatType(TYPE_oid));
     866           0 :                                 setVarCList(mb,getArg(r,0));
     867           0 :                                 getArg(r, 1) = getArg(q, 1); /* column */
     868           0 :                                 r->typechk = TYPE_UNKNOWN;
     869           0 :                                 pushInstruction(mb,r);
     870           0 :                                 getArg(s, 0) = newTmpVariable(mb, newBatType(TYPE_oid));
     871           0 :                                 setVarCList(mb,getArg(s,0));
     872           0 :                                 getArg(s, 1) = getArg(q, 3); /* updates */
     873           0 :                                 s = ReplaceWithNil(mb, s, 3, TYPE_bat); /* no candidate list */
     874           0 :                                 setArgType(mb, s, 3, newBatType(TYPE_oid));
     875             :                                 /* make sure to resolve again */
     876           0 :                                 s->token = ASSIGNsymbol;
     877           0 :                                 s->typechk = TYPE_UNKNOWN;
     878           0 :                                 s->fcn = NULL;
     879           0 :                                 s->blk = NULL;
     880           0 :                                 pushInstruction(mb,s);
     881             : 
     882           0 :                                 setFunctionId(u, subdeltaRef);
     883           0 :                                 getArg(u, 0) = getArg(p,0);
     884           0 :                                 getArg(u, 1) = getArg(r,0);
     885           0 :                                 getArg(u, 2) = getArg(p,3); /* pre-cands */
     886           0 :                                 getArg(u, 3) = getArg(q,2); /* update ids */
     887             :                                 //getArg(u, 4) = getArg(s,0);
     888           0 :                                 p = pushArgument(mb, u, getArg(s,0)); /* push at end */
     889           0 :                                 u->typechk = TYPE_UNKNOWN;
     890           0 :                                 pushInstruction(mb,u);
     891           0 :                                 oclean[i] = 1;
     892           0 :                                 continue;
     893             :                         }
     894             :                 }
     895    13513456 :                 assert (p == old[i] || oclean[i]);
     896    13513456 :                 pushInstruction(mb,p);
     897             :         }
     898    13870519 :         for (j=1; j<i; j++)
     899    13541757 :                 if (old[j] && oclean[j])
     900      131190 :                         freeInstruction(old[j]);
     901    73248274 :         for (; i<slimit; i++)
     902    72919512 :                 if (old[i])
     903           0 :                         pushInstruction(mb, old[i]);
     904      328762 :         GDKfree(vars);
     905      328762 :         GDKfree(nvars);
     906      328762 :         GDKfree(slices);
     907      328762 :         GDKfree(rslices);
     908      328762 :         GDKfree(oclean);
     909      328762 :         GDKfree(old);
     910             : 
     911             :         /* Defense line against incorrect plans */
     912      328762 :         if (actions > 0) {
     913       16799 :                 msg = chkTypes(cntxt->usermodule, mb, FALSE);
     914       16799 :                 if (msg == MAL_SUCCEED)
     915       16799 :                         msg = chkFlow(mb);
     916       16799 :                 if( msg == MAL_SUCCEED)
     917       16799 :                         msg = chkDeclarations(mb);
     918             :         }
     919      311963 : wrapup:
     920             :         /* keep actions taken as a fake argument*/
     921      353093 :         (void) pushInt(mb, pci, actions);
     922      353093 :         return msg;
     923             : }

Generated by: LCOV version 1.14