Changeset: b51a633cc2b0 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b51a633cc2b0
Modified Files:
        sql/backends/monet5/sql_statement.c
        sql/server/rel_optimizer.c
        testing/Mtest.py.in
Branch: nospare
Log Message:

merged


diffs (truncated from 1642 to 300 lines):

diff --git a/clients/Tests/MAL-signatures.stable.out 
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -676,8 +676,7 @@ stdout of test 'MAL-signatures` in direc
 [ "algebra",   "thetajoin",    "command algebra.thetajoin(X_1:bat[:any_1], 
X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:int, X_6:bit, 
X_7:lng):bat[:oid] ",      "ALGthetajoin1;",       ""      ]
 [ "algebra",   "thetajoin",    "command algebra.thetajoin(X_2:bat[:any_1], 
X_3:bat[:any_1], X_4:bat[:oid], X_5:bat[:oid], X_6:int, X_7:bit, X_8:lng) 
(X_0:bat[:oid], X_1:bat[:oid]) ", "ALGthetajoin;",        ""      ]
 [ "algebra",   "thetaselect",  "command algebra.thetaselect(X_1:bat[:any_1], 
X_2:bat[:oid], X_3:any_1, X_4:str):bat[:oid] ",   "ALGthetaselect2;",     ""    
  ]
-[ "algebra",   "unique",       "command 
algebra.unique(X_1:bat[:any_1]):bat[:oid] ",   "ALGunique1;",  ""      ]
-[ "algebra",   "unique",       "command algebra.unique(X_1:bat[:any_1], 
X_2:bat[:oid]):bat[:oid] ",    "ALGunique2;",  ""      ]
+[ "algebra",   "unique",       "command algebra.unique(X_1:bat[:any_1], 
X_2:bat[:oid]):bat[:oid] ",    "ALGunique;",   ""      ]
 [ "bat",       "append",       "command bat.append(X_1:bat[:any_1], 
X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:any_1] ",    
"BKCappend_cand_force_wrap;",   ""      ]
 [ "bat",       "append",       "command bat.append(X_1:bat[:any_1], 
X_2:bat[:any_1], X_3:bat[:oid]):bat[:any_1] ",     "BKCappend_cand_wrap;", ""   
   ]
 [ "bat",       "append",       "command bat.append(X_1:bat[:any_1], 
X_2:bat[:any_1], X_3:bit):bat[:any_1] ",   "BKCappend_force_wrap;",        ""   
   ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128 
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -789,8 +789,7 @@ stdout of test 'MAL-signatures` in direc
 [ "algebra",   "thetajoin",    "command algebra.thetajoin(X_1:bat[:any_1], 
X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:int, X_6:bit, 
X_7:lng):bat[:oid] ",      "ALGthetajoin1;",       ""      ]
 [ "algebra",   "thetajoin",    "command algebra.thetajoin(X_2:bat[:any_1], 
X_3:bat[:any_1], X_4:bat[:oid], X_5:bat[:oid], X_6:int, X_7:bit, X_8:lng) 
(X_0:bat[:oid], X_1:bat[:oid]) ", "ALGthetajoin;",        ""      ]
 [ "algebra",   "thetaselect",  "command algebra.thetaselect(X_1:bat[:any_1], 
X_2:bat[:oid], X_3:any_1, X_4:str):bat[:oid] ",   "ALGthetaselect2;",     ""    
  ]
-[ "algebra",   "unique",       "command 
algebra.unique(X_1:bat[:any_1]):bat[:oid] ",   "ALGunique1;",  ""      ]
-[ "algebra",   "unique",       "command algebra.unique(X_1:bat[:any_1], 
X_2:bat[:oid]):bat[:oid] ",    "ALGunique2;",  ""      ]
+[ "algebra",   "unique",       "command algebra.unique(X_1:bat[:any_1], 
X_2:bat[:oid]):bat[:oid] ",    "ALGunique;",   ""      ]
 [ "bat",       "append",       "command bat.append(X_1:bat[:any_1], 
X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:any_1] ",    
"BKCappend_cand_force_wrap;",   ""      ]
 [ "bat",       "append",       "command bat.append(X_1:bat[:any_1], 
X_2:bat[:any_1], X_3:bat[:oid]):bat[:any_1] ",     "BKCappend_cand_wrap;", ""   
   ]
 [ "bat",       "append",       "command bat.append(X_1:bat[:any_1], 
X_2:bat[:any_1], X_3:bit):bat[:any_1] ",   "BKCappend_force_wrap;",        ""   
   ]
diff --git a/clients/examples/C/bincopydata.c b/clients/examples/C/bincopydata.c
--- a/clients/examples/C/bincopydata.c
+++ b/clients/examples/C/bincopydata.c
@@ -158,6 +158,7 @@ gen_large_strings(FILE *f, bool byteswap
                        fwrite(buf, n, 1, f);
                fputc(0, f);
        }
+       free(buf);
        (void)byteswap;
 }
 
@@ -173,7 +174,7 @@ gen_broken_strings(FILE *f, bool byteswa
                if (i == 123456)
                        fwrite(latin1, sizeof(latin1), 1, f);
                else
-                       fwrite(latin1, sizeof(utf8), 1, f);
+                       fwrite(utf8, sizeof(utf8), 1, f);
        }
 }
 
diff --git 
a/monetdb5/extras/mal_optimizer_template/Tests/opt_sql_append.stable.out.Windows
 
b/monetdb5/extras/mal_optimizer_template/Tests/opt_sql_append.stable.out.Windows
--- 
a/monetdb5/extras/mal_optimizer_template/Tests/opt_sql_append.stable.out.Windows
+++ 
b/monetdb5/extras/mal_optimizer_template/Tests/opt_sql_append.stable.out.Windows
@@ -10,21 +10,23 @@
 % .%1 # table_name
 % def # name
 % clob # type
-% 580 # length
+% 626 # length
 [ 
"optimizer.inline();optimizer.remap();optimizer.costModel();optimizer.coercions();optimizer.aliases();optimizer.evaluate();optimizer.emptybind();optimizer.pushselect();optimizer.aliases();optimizer.mergetable();optimizer.deadcode();optimizer.aliases();optimizer.constants();optimizer.commonTerms();optimizer.projectionpath();optimizer.deadcode();optimizer.reorder();optimizer.matpack();optimizer.querylog();optimizer.multiplex();optimizer.generator();optimizer.profiler();optimizer.candidates();optimizer.deadcode();optimizer.postfix();optimizer.wlc();optimizer.garbageCollector();"
       ]
 #explain copy into ttt from E'\\tmp/xyz';
 % .explain # table_name
 % mal # name
 % clob # type
-% 235 # length
+% 274 # length
 function user.main():void;
     querylog.define("explain copy into ttt from E\\'\\\\\\\\tmp/xyz\\';":str, 
"sequential_pipe":str, 22:int);
     X_4:int := sql.mvc();
-    (X_28:bat[:int], X_29:bat[:int], X_30:bat[:int]) := 
sql.copy_from(0x00000049B72361C0:ptr, "|":str, "\n":str, nil:str, "null":str, 
"\\tmp/xyz":str, -1:lng, 0:lng, 0:int, 0:int, nil:str, 0:int, 1:int);
-    X_32:int := sql.append(X_4:int, "sys":str, "ttt":str, 
"averylongcolumnnametomakeitlargeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":str,
 X_28:bat[:int]);
-    X_37:int := sql.append(X_32:int, "sys":str, "ttt":str, "b":str, 
X_29:bat[:int]);
-    X_40:int := sql.append(X_37:int, "sys":str, "ttt":str, "c":str, 
X_30:bat[:int]);
+    (X_28:bat[:int], X_29:bat[:int], X_30:bat[:int]) := 
sql.copy_from(0x0000025CF9E874C0:ptr, "|":str, "\n":str, nil:str, "null":str, 
"\\tmp/xyz":str, -1:lng, 0:lng, 0:int, 0:int, nil:str, 0:int, 1:int);
+    (X_86:int, X_85:ptr, X_90:ptr, X_93:ptr) := sql.append_prep(X_4:int, 
"sys":str, "ttt":str, 
"averylongcolumnnametomakeitlargeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":str,
 "b":str, "c":str);
+    X_88:ptr := sql.append_exec(X_85:ptr, X_28:bat[:int]);
+    X_91:ptr := sql.append_exec(X_90:ptr, X_29:bat[:int]);
+    X_94:ptr := sql.append_exec(X_93:ptr, X_30:bat[:int]);
     X_42:lng := aggr.count(X_30:bat[:int]);
+    X_40:int := sql.append_finish(X_86:int, X_88:ptr, X_91:ptr, X_94:ptr);
     sql.affectedRows(X_40:int, X_42:lng);
 end user.main;
 #inline               actions= 0 time=0 usec 
@@ -57,15 +59,17 @@ end user.main;
 % .explain # table_name
 % mal # name
 % clob # type
-% 235 # length
+% 274 # length
 function user.main():void;
     querylog.define("explain copy into ttt from 
E\\'a:\\\\\\\\tmp/xyz\\';":str, "sequential_pipe":str, 22:int);
     X_4:int := sql.mvc();
-    (X_28:bat[:int], X_29:bat[:int], X_30:bat[:int]) := 
sql.copy_from(0x00000049B72361C0:ptr, "|":str, "\n":str, nil:str, "null":str, 
"a:\\tmp/xyz":str, -1:lng, 0:lng, 0:int, 0:int, nil:str, 0:int, 1:int);
-    X_32:int := sql.append(X_4:int, "sys":str, "ttt":str, 
"averylongcolumnnametomakeitlargeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":str,
 X_28:bat[:int]);
-    X_37:int := sql.append(X_32:int, "sys":str, "ttt":str, "b":str, 
X_29:bat[:int]);
-    X_40:int := sql.append(X_37:int, "sys":str, "ttt":str, "c":str, 
X_30:bat[:int]);
+    (X_28:bat[:int], X_29:bat[:int], X_30:bat[:int]) := 
sql.copy_from(0x0000025CF9E874C0:ptr, "|":str, "\n":str, nil:str, "null":str, 
"a:\\tmp/xyz":str, -1:lng, 0:lng, 0:int, 0:int, nil:str, 0:int, 1:int);
+    (X_86:int, X_85:ptr, X_90:ptr, X_93:ptr) := sql.append_prep(X_4:int, 
"sys":str, "ttt":str, 
"averylongcolumnnametomakeitlargeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":str,
 "b":str, "c":str);
+    X_88:ptr := sql.append_exec(X_85:ptr, X_28:bat[:int]);
+    X_91:ptr := sql.append_exec(X_90:ptr, X_29:bat[:int]);
+    X_94:ptr := sql.append_exec(X_93:ptr, X_30:bat[:int]);
     X_42:lng := aggr.count(X_30:bat[:int]);
+    X_40:int := sql.append_finish(X_86:int, X_88:ptr, X_91:ptr, X_94:ptr);
     sql.affectedRows(X_40:int, X_42:lng);
 end user.main;
 #inline               actions= 0 time=1 usec 
@@ -108,22 +112,24 @@ end user.main;
 % .%1 # table_name
 % def # name
 % clob # type
-% 603 # length
-[ 
"optimizer.inline();optimizer.remap();optimizer.costModel();optimizer.coercions();optimizer.aliases();optimizer.evaluate();optimizer.emptybind();optimizer.pushselect();optimizer.aliases();optimizer.mergetable();optimizer.deadcode();optimizer.aliases();optimizer.constants();optimizer.commonTerms();optimizer.projectionpath();optimizer.deadcode();optimizer.reorder();optimizer.matpack();optimizer.querylog();optimizer.multiplex();optimizer.generator();optimizer.profiler();optimizer.candidates();optimizer.deadcode();optimizer.postfix();optimizer.wlc();optimizer.sql_append();optimizer.garbageCollector();"
        ]
+% 649 # length
+[ 
"optimizer.inline();optimizer.remap();optimizer.costModel();optimizer.coercions();optimizer.aliases();optimizer.evaluate();optimizer.emptybind();optimizer.pushselect();optimizer.aliases();optimizer.mergetable();optimizer.bincopyfrom();optimizer.parappend();optimizer.deadcode();optimizer.aliases();optimizer.constants();optimizer.commonTerms();optimizer.projectionpath();optimizer.deadcode();optimizer.reorder();optimizer.matpack();optimizer.querylog();optimizer.multiplex();optimizer.generator();optimizer.profiler();optimizer.candidates();optimizer.deadcode();optimizer.postfix();optimizer.wlc();optimizer.sql_append();optimizer.garbageCollector();"
  ]
 #rollback;
 #explain copy into ttt from E'\\tmp/xyz';
 % .explain # table_name
 % mal # name
 % clob # type
-% 235 # length
+% 274 # length
 function user.main():void;
     querylog.define("explain copy into ttt from E\\'\\\\\\\\tmp/xyz\\';":str, 
"user_0":str, 22:int);
     X_4:int := sql.mvc();
-    (X_28:bat[:int], X_29:bat[:int], X_30:bat[:int]) := 
sql.copy_from(0x00000049B72361C0:ptr, "|":str, "\n":str, nil:str, "null":str, 
"\\tmp/xyz":str, -1:lng, 0:lng, 0:int, 0:int, nil:str, 0:int, 1:int);
-    X_32:int := sql.append(X_4:int, "sys":str, "ttt":str, 
"averylongcolumnnametomakeitlargeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":str,
 X_28:bat[:int]);
-    X_37:int := sql.append(X_32:int, "sys":str, "ttt":str, "b":str, 
X_29:bat[:int]);
+    (X_28:bat[:int], X_29:bat[:int], X_30:bat[:int]) := 
sql.copy_from(0x0000023F54B19930:ptr, "|":str, "\n":str, nil:str, "null":str, 
"\\tmp/xyz":str, -1:lng, 0:lng, 0:int, 0:int, nil:str, 0:int, 1:int);
+    (X_87:int, X_86:ptr, X_91:ptr, X_94:ptr) := sql.append_prep(X_4:int, 
"sys":str, "ttt":str, 
"averylongcolumnnametomakeitlargeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":str,
 "b":str, "c":str);
+    X_89:ptr := sql.append_exec(X_86:ptr, X_28:bat[:int]);
+    X_92:ptr := sql.append_exec(X_91:ptr, X_29:bat[:int]);
+    X_95:ptr := sql.append_exec(X_94:ptr, X_30:bat[:int]);
     X_42:lng := aggr.count(X_30:bat[:int]);
-    X_40:int := sql.append(X_37:int, "sys":str, "ttt":str, "c":str, 
X_30:bat[:int]);
+    X_40:int := sql.append_finish(X_87:int, X_89:ptr, X_92:ptr, X_95:ptr);
     sql.affectedRows(X_40:int, X_42:lng);
 end user.main;
 #inline               actions= 0 time=0 usec 
@@ -157,15 +163,17 @@ end user.main;
 % .explain # table_name
 % mal # name
 % clob # type
-% 235 # length
+% 274 # length
 function user.main():void;
     querylog.define("explain copy into ttt from \\'Z:/tmp/xyz\\';":str, 
"user_0":str, 22:int);
     X_4:int := sql.mvc();
-    (X_28:bat[:int], X_29:bat[:int], X_30:bat[:int]) := 
sql.copy_from(0x00000049B72361C0:ptr, "|":str, "\n":str, nil:str, "null":str, 
"Z:/tmp/xyz":str, -1:lng, 0:lng, 0:int, 0:int, nil:str, 0:int, 1:int);
-    X_32:int := sql.append(X_4:int, "sys":str, "ttt":str, 
"averylongcolumnnametomakeitlargeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":str,
 X_28:bat[:int]);
-    X_37:int := sql.append(X_32:int, "sys":str, "ttt":str, "b":str, 
X_29:bat[:int]);
+    (X_28:bat[:int], X_29:bat[:int], X_30:bat[:int]) := 
sql.copy_from(0x0000023F54B19930:ptr, "|":str, "\n":str, nil:str, "null":str, 
"Z:/tmp/xyz":str, -1:lng, 0:lng, 0:int, 0:int, nil:str, 0:int, 1:int);
+    (X_87:int, X_86:ptr, X_91:ptr, X_94:ptr) := sql.append_prep(X_4:int, 
"sys":str, "ttt":str, 
"averylongcolumnnametomakeitlargeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":str,
 "b":str, "c":str);
+    X_89:ptr := sql.append_exec(X_86:ptr, X_28:bat[:int]);
+    X_92:ptr := sql.append_exec(X_91:ptr, X_29:bat[:int]);
+    X_95:ptr := sql.append_exec(X_94:ptr, X_30:bat[:int]);
     X_42:lng := aggr.count(X_30:bat[:int]);
-    X_40:int := sql.append(X_37:int, "sys":str, "ttt":str, "c":str, 
X_30:bat[:int]);
+    X_40:int := sql.append_finish(X_87:int, X_89:ptr, X_92:ptr, X_95:ptr);
     sql.affectedRows(X_40:int, X_42:lng);
 end user.main;
 #inline               actions= 0 time=0 usec 
diff --git a/monetdb5/modules/kernel/algebra.c 
b/monetdb5/modules/kernel/algebra.c
--- a/monetdb5/modules/kernel/algebra.c
+++ b/monetdb5/modules/kernel/algebra.c
@@ -750,7 +750,7 @@ ALGcopy(bat *result, const bat *bid)
 }
 
 static str
-ALGunique2(bat *result, const bat *bid, const bat *sid)
+ALGunique(bat *result, const bat *bid, const bat *sid)
 {
        BAT *b, *s = NULL, *bn = NULL;
 
@@ -773,12 +773,6 @@ ALGunique2(bat *result, const bat *bid, 
 }
 
 static str
-ALGunique1(bat *result, const bat *bid)
-{
-       return ALGunique2(result, bid, NULL);
-}
-
-static str
 ALGcrossproduct(bat *l, bat *r, const bat *left, const bat *right, const bit 
*max_one)
 {
        BAT *L, *R, *bn1, *bn2 = NULL;
@@ -1410,8 +1404,7 @@ mel_func algebra_init_funcs[] = {
  command("algebra", "sort", ALGsort31, false, "Returns a copy of the BAT 
sorted on tail values.\nThe order is descending if the reverse bit is 
set.\nThis is a stable sort if the stable bit is set.", args(1,7, 
batargany("",1),batargany("b",1),batarg("o",oid),batarg("g",oid),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
  command("algebra", "sort", ALGsort32, false, "Returns a copy of the BAT 
sorted on tail values and a BAT that\nspecifies how the input was 
reordered.\nThe order is descending if the reverse bit is set.\nThis is a 
stable sort if the stable bit is set.", args(2,8, 
batargany("",1),batarg("",oid),batargany("b",1),batarg("o",oid),batarg("g",oid),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
  command("algebra", "sort", ALGsort33, false, "Returns a copy of the BAT 
sorted on tail values, a BAT that specifies\nhow the input was reordered, and a 
BAT with group information.\nThe order is descending if the reverse bit is 
set.\nThis is a stable sort if the stable bit is set.", args(3,9, 
batargany("",1),batarg("",oid),batarg("",oid),batargany("b",1),batarg("o",oid),batarg("g",oid),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
- command("algebra", "unique", ALGunique2, false, "Select all unique values 
from the tail of the first input.\nInput is a dense-headed BAT, the second 
input is a\ndense-headed BAT with sorted tail, output is a dense-headed\nBAT 
with in the tail the head value of the input BAT that was\nselected.  The 
output BAT is sorted on the tail value.  The\nsecond input BAT is a list of 
candidates.", args(1,3, batarg("",oid),batargany("b",1),batarg("s",oid))),
- command("algebra", "unique", ALGunique1, false, "Select all unique values 
from the tail of the input.\nInput is a dense-headed BAT, output is a 
dense-headed BAT with\nin the tail the head value of the input BAT that was 
selected.\nThe output BAT is sorted on the tail value.", args(1,2, 
batarg("",oid),batargany("b",1))),
+ command("algebra", "unique", ALGunique, false, "Select all unique values from 
the tail of the first input.\nInput is a dense-headed BAT, the second input is 
a\ndense-headed BAT with sorted tail, output is a dense-headed\nBAT with in the 
tail the head value of the input BAT that was\nselected.  The output BAT is 
sorted on the tail value.  The\nsecond input BAT is a list of candidates.", 
args(1,3, batarg("",oid),batargany("b",1),batarg("s",oid))),
  command("algebra", "crossproduct", ALGcrossproduct2, false, "Returns 2 
columns with all BUNs, consisting of the head-oids\nfrom 'left' and 'right' for 
which there are BUNs in 'left'\nand 'right' with equal tails", args(2,5, 
batarg("l",oid),batarg("r",oid),batargany("left",1),batargany("right",2),arg("max_one",bit))),
  command("algebra", "crossproduct", ALGcrossproduct1, false, "Compute the 
cross product of both input bats; but only produce left output", args(1,4, 
batarg("",oid),batargany("left",1),batargany("right",2),arg("max_one",bit))),
  command("algebra", "join", ALGjoin, false, "Join", args(2,8, 
batarg("",oid),batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
diff --git a/monetdb5/modules/kernel/batstr.c b/monetdb5/modules/kernel/batstr.c
--- a/monetdb5/modules/kernel/batstr.c
+++ b/monetdb5/modules/kernel/batstr.c
@@ -1191,6 +1191,7 @@ do_batstr_batint_conststr_str(Client cnt
                }
        }
 bailout:
+       GDKfree(buf);
        finalize_ouput(res, bn, msg, nils, q);
        unfix_inputs(4, left, ls, right, rs);
        return msg;
@@ -1648,13 +1649,13 @@ bailout:
 }
 
 static str
-STRbatPrefix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) 
+STRbatPrefix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
        return prefix_or_suffix(cntxt, mb, stk, pci, "batstr.startsWith", 
str_is_prefix);
 }
 
 static str
-STRbatSuffix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) 
+STRbatSuffix(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
        return prefix_or_suffix(cntxt, mb, stk, pci, "batstr.endsWith", 
str_is_suffix);
 }
@@ -2976,13 +2977,13 @@ STRbatSubstitute(Client cntxt, MalBlkPtr
                msg = createException(MAL, "batstr.substritute", 
SQLSTATE(HY005) RUNTIME_OBJECT_MISSING);
                goto bailout;
        }
-       if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1))) || 
(sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2))) || 
+       if ((sid1 && !is_bat_nil(*sid1) && !(arg1s = BATdescriptor(*sid1))) || 
(sid2 && !is_bat_nil(*sid2) && !(arg2s = BATdescriptor(*sid2))) ||
                (sid3 && !is_bat_nil(*sid3) && !(arg2s = BATdescriptor(*sid3))) 
|| (sid4 && !is_bat_nil(*sid4) && !(arg4s = BATdescriptor(*sid4)))) {
                msg = createException(MAL, "batstr.substritute", 
SQLSTATE(HY005) RUNTIME_OBJECT_MISSING);
                goto bailout;
        }
        q = canditer_init(&ci1, arg1, arg1s);
-       if (canditer_init(&ci2, arg2, arg2s) != q || ci1.hseq != ci2.hseq || 
canditer_init(&ci3, arg3, arg3s) != q || 
+       if (canditer_init(&ci2, arg2, arg2s) != q || ci1.hseq != ci2.hseq || 
canditer_init(&ci3, arg3, arg3s) != q ||
                ci2.hseq != ci3.hseq || canditer_init(&ci4, arg4, arg4s) != q 
|| ci3.hseq != ci4.hseq) {
                msg = createException(MAL, "batstr.substritute", 
ILLEGAL_ARGUMENT " Requires bats of identical size");
                goto bailout;
@@ -3572,13 +3573,13 @@ STRbatInsert(Client cntxt, MalBlkPtr mb,
                msg = createException(MAL, "batstr.insert", SQLSTATE(HY005) 
RUNTIME_OBJECT_MISSING);
                goto bailout;
        }
-       if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) || 
(sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2))) || 
+       if ((sid1 && !is_bat_nil(*sid1) && !(ls = BATdescriptor(*sid1))) || 
(sid2 && !is_bat_nil(*sid2) && !(rs = BATdescriptor(*sid2))) ||
                (sid3 && !is_bat_nil(*sid3) && !(ss = BATdescriptor(*sid3))) || 
(sid4 && !is_bat_nil(*sid4) && !(ns = BATdescriptor(*sid4)))) {
                msg = createException(MAL, "batstr.insert", SQLSTATE(HY005) 
RUNTIME_OBJECT_MISSING);
                goto bailout;
        }
        q = canditer_init(&ci1, left, ls);
-       if (canditer_init(&ci2, start, ss) != q || ci1.hseq != ci2.hseq || 
canditer_init(&ci3, nchars, ns) != q || 
+       if (canditer_init(&ci2, start, ss) != q || ci1.hseq != ci2.hseq || 
canditer_init(&ci3, nchars, ns) != q ||
                ci2.hseq != ci3.hseq || canditer_init(&ci4, right, rs) != q || 
ci3.hseq != ci4.hseq) {
                msg = createException(MAL, "batstr.insert", ILLEGAL_ARGUMENT " 
Requires bats of identical size");
                goto bailout;
diff --git a/sql/backends/monet5/sql_statement.c 
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -281,6 +281,7 @@ stmt_unique(backend *be, stmt *s)
                return NULL;
 
        q = pushArgument(mb, q, s->nr);
+       q = pushNil(mb, q, TYPE_bat); /* candidate list */
        if (q) {
                stmt *ns = stmt_create(be->mvc->sa, st_unique);
                if (ns == NULL) {
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -1729,25 +1729,22 @@ exp_is_true(sql_exp *e)
 }
 
 static inline bool
-exp_is_cmp_exp_is_false(sql_exp* e) {
-    assert(e->type == e_cmp);
-    assert(e->semantics && (e->flag == cmp_equal || e->flag == cmp_notequal));
-    assert(e->f == NULL);
-    sql_exp* l = e->l;
-    sql_exp* r = e->r;
-    assert (l && r);
-
-    /* Handle 'v is x' and 'v is not x' expressions.
-     * Other cases in is-semantics are unspecified.
-     */
-    if (e->flag == cmp_equal && !e->anti) {
-        return ((exp_is_null(l) && exp_is_not_null(r)) || (exp_is_not_null(l) 
&& exp_is_null(r)));
-    }
-    if (((e->flag == cmp_notequal) && !e->anti) || ((e->flag == cmp_equal) && 
e->anti) ) {
-        return ((exp_is_null(l) && exp_is_null(r)) || (exp_is_not_null(l) && 
exp_is_not_null(r)));
-    }
-
-    return false;
+exp_is_cmp_exp_is_false(sql_exp* e)
+{
+       sql_exp *l = e->l;
+       sql_exp *r = e->r;
+       assert(e->type == e_cmp && e->f == NULL && l && r);
+
+       /* Handle 'v is x' and 'v is not x' expressions.
+       * Other cases in is-semantics are unspecified.
+       */
+       if (e->flag != cmp_equal && e->flag != cmp_notequal)
+               return false;
+       if (e->flag == cmp_equal && !e->anti)
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to