Changeset: 6b3792643dcd for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6b3792643dcd Modified Files: clients/Tests/MAL-signatures.stable.out clients/Tests/MAL-signatures.stable.out.int128 clients/Tests/exports.stable.out monetdb5/modules/kernel/bat5.c monetdb5/modules/kernel/bat5.h monetdb5/modules/kernel/bat5.mal monetdb5/optimizer/opt_prelude.c monetdb5/optimizer/opt_prelude.h sql/backends/monet5/rel_bin.c sql/backends/monet5/sql_statement.c sql/backends/monet5/sql_statement.h sql/test/orderidx/Tests/simpletable.stable.out sql/test/orderidx/Tests/simpletable.stable.out.32bit sql/test/orderidx/Tests/smalltable.stable.out sql/test/orderidx/Tests/smalltable.stable.out.32bit Branch: default Log Message:
Implemented bat5.bulkAppend, which appends n-ary arguments into the input bat. I'm not checking the key,sorted and revsorted properties in favor for a faster append directly on the heap for exact numeric types. diffs (truncated from 482 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 @@ -673,6 +673,8 @@ stdout of test 'MAL-signatures` in direc [ "bat", "append", "command bat.append(X_1:bat[:any_1], X_2:any_1, X_3:bit):bat[:any_1] ", "BKCappend_val_force_wrap;", "" ] [ "bat", "append", "command bat.append(X_1:bat[:any_1], X_2:any_1):bat[:any_1] ", "BKCappend_val_wrap;", "" ] [ "bat", "append", "command bat.append(X_1:bat[:any_1], X_2:bat[:any_1]):bat[:any_1] ", "BKCappend_wrap;", "" ] +[ "bat", "appendBulk", "pattern bat.appendBulk(X_1:bat[:any_1], X_2:bit, X_3:any_1...):bat[:any_1] ", "BKCappend_bulk_force_wrap;", "" ] +[ "bat", "appendBulk", "pattern bat.appendBulk(X_1:bat[:any_1], X_2:bit, X_3:bat[:any_1]...):bat[:any_1] ", "BKCappend_bulk_force_wrap;", "" ] [ "bat", "attach", "command bat.attach(X_1:int, X_2:str):bat[:any_1] ", "BKCattach;", "" ] [ "bat", "delete", "command bat.delete(X_1:bat[:any_1], X_2:oid):bat[:any_1] ", "BKCdelete;", "" ] [ "bat", "delete", "command bat.delete(X_1:bat[:any_1]):bat[:any_1] ", "BKCdelete_all;", "" ] 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 @@ -783,6 +783,8 @@ stdout of test 'MAL-signatures` in direc [ "bat", "append", "command bat.append(X_1:bat[:any_1], X_2:any_1, X_3:bit):bat[:any_1] ", "BKCappend_val_force_wrap;", "" ] [ "bat", "append", "command bat.append(X_1:bat[:any_1], X_2:any_1):bat[:any_1] ", "BKCappend_val_wrap;", "" ] [ "bat", "append", "command bat.append(X_1:bat[:any_1], X_2:bat[:any_1]):bat[:any_1] ", "BKCappend_wrap;", "" ] +[ "bat", "appendBulk", "pattern bat.appendBulk(X_1:bat[:any_1], X_2:bit, X_3:any_1...):bat[:any_1] ", "BKCappend_bulk_force_wrap;", "" ] +[ "bat", "appendBulk", "pattern bat.appendBulk(X_1:bat[:any_1], X_2:bit, X_3:bat[:any_1]...):bat[:any_1] ", "BKCappend_bulk_force_wrap;", "" ] [ "bat", "attach", "command bat.attach(X_1:int, X_2:str):bat[:any_1] ", "BKCattach;", "" ] [ "bat", "delete", "command bat.delete(X_1:bat[:any_1], X_2:oid):bat[:any_1] ", "BKCdelete;", "" ] [ "bat", "delete", "command bat.delete(X_1:bat[:any_1]):bat[:any_1] ", "BKCdelete_all;", "" ] diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out --- a/clients/Tests/exports.stable.out +++ b/clients/Tests/exports.stable.out @@ -708,6 +708,7 @@ str BATPCREnotilike2(bat *ret, const bat str BATPCREnotlike(bat *ret, const bat *b, const str *pat, const str *esc); str BATPCREnotlike2(bat *ret, const bat *b, const str *pat); str BATinfo(BAT **key, BAT **val, const bat bid); +str BKCappend_bulk_force_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci); str BKCappend_cand_force_wrap(bat *r, const bat *bid, const bat *uid, const bat *sid, const bit *force); str BKCappend_cand_wrap(bat *r, const bat *bid, const bat *uid, const bat *sid); str BKCappend_force_wrap(bat *r, const bat *bid, const bat *uid, const bit *force); @@ -1618,6 +1619,7 @@ str alter_typeRef; str alter_userRef; str alter_viewRef; str andRef; +str appendBulkRef; str appendRef; str appendidxRef; str arrayRef; diff --git a/monetdb5/modules/kernel/bat5.c b/monetdb5/modules/kernel/bat5.c --- a/monetdb5/modules/kernel/bat5.c +++ b/monetdb5/modules/kernel/bat5.c @@ -31,7 +31,9 @@ #include "monetdb_config.h" #include "bat5.h" #include "mal_exception.h" +#include "mal_interpreter.h" #include "mal_debugger.h" +#include "gdk_time.h" /* set access mode to bat, replacing input with output */ static BAT * @@ -267,6 +269,135 @@ BKCappend_val_wrap(bat *r, const bat *bi return BKCappend_val_force_wrap(r, bid, u, NULL); } +#define append_bulk_imp_fixed_size(TPE) \ + do { \ + TPE *restrict heap; \ + total = count + inputs; \ + if (BATextend(b, total) != GDK_SUCCEED) { \ + BBPunfix(b->batCacheid); \ + throw(MAL,"bat.append_bulk", SQLSTATE(HY013) MAL_MALLOC_FAIL); \ + } \ + heap = Tloc(b, count); \ + for (int i = 3, args = pci->argc; i < args; i++, j++) { \ + TPE val = *(TPE*) getArgReference(stk,pci,i); \ + new_nil |= is_##TPE##_nil(val); \ + heap[j] = val; \ + } \ + } while (0) + +str +BKCappend_bulk_force_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) +{ + bat *r = getArgReference_bat(stk, pci, 0), *bid = getArgReference_bat(stk, pci, 1); + bit force = *getArgReference_bit(stk, pci, 2), new_nil = 0; + BAT *b, *c; + BUN inputs = (BUN)(pci->argc - 3), count = 0, total = 0, j = 0; + + (void) cntxt; + if ((b = BATdescriptor(*bid)) == NULL) + throw(MAL, "bat.append_bulk", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); + + if (inputs > 0) { + u_int8_t storage = ATOMstorage(b->ttype); + count = BATcount(b); + + if ((c = setaccess(b, BAT_WRITE)) == NULL) { + BBPunfix(b->batCacheid); + throw(MAL, "bat.append_bulk", OPERATION_FAILED); + } + b = c; + + if (isaBatType(getArgType(mb, pci, 3))) { /* use BATappend for the bulk case */ + gdk_return rt; + for (int i = 3, args = pci->argc; i < args; i++) { + BAT *d = BATdescriptor(*getArgReference_bat(stk, pci, i)); + if (!d) { + BBPunfix(b->batCacheid); + throw(MAL, "bat.append_bulk", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); + } + rt = BATappend(b, d, NULL, force); + BBPunfix(d->batCacheid); + if (rt != GDK_SUCCEED) { + BBPunfix(b->batCacheid); + throw(MAL,"bat.append_bulk", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + } + } else if (b->ttype < TYPE_str && storage == b->ttype) { + switch (b->ttype) { + case TYPE_bit: + append_bulk_imp_fixed_size(bit); + break; + case TYPE_bte: + append_bulk_imp_fixed_size(bte); + break; + case TYPE_sht: + append_bulk_imp_fixed_size(sht); + break; + case TYPE_int: + append_bulk_imp_fixed_size(int); + break; + case TYPE_lng: + append_bulk_imp_fixed_size(lng); + break; + case TYPE_oid: + append_bulk_imp_fixed_size(oid); + break; + case TYPE_flt: + append_bulk_imp_fixed_size(flt); + break; + case TYPE_dbl: + append_bulk_imp_fixed_size(dbl); + break; + case TYPE_date: + append_bulk_imp_fixed_size(date); + break; + case TYPE_daytime: + append_bulk_imp_fixed_size(daytime); + break; + case TYPE_timestamp: + append_bulk_imp_fixed_size(timestamp); + break; +#ifdef HAVE_HGE + case TYPE_hge: + append_bulk_imp_fixed_size(hge); + break; +#endif + default: + assert(0); + } + BATsetcount(b, total); + if (count == 0) { + b->tnil = new_nil; + b->tnonil = !new_nil; + } else { + b->tnil |= new_nil; + b->tnonil &= ~new_nil; + } + b->tkey = BATcount(b) <= 1; + b->tsorted = BATcount(b) <= 1; + b->trevsorted = BATcount(b) <= 1; + } else { /* non fixed size, use the conventional way */ + total = count + inputs; + if (BATextend(b, total) != GDK_SUCCEED) { + BBPunfix(b->batCacheid); + throw(MAL,"bat.append_bulk", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + for (int i = 3, args = pci->argc; i < args; i++) { + ptr u = getArgReference(stk,pci,i); + if (storage >= TYPE_str) + u = (ptr) *(str *) u; + if (BUNappend(b, u, force) != GDK_SUCCEED) { + BBPunfix(b->batCacheid); + throw(MAL,"bat.append_bulk", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + } + } + } + + BBPkeepref(*r = b->batCacheid); + return MAL_SUCCEED; +} + str BKCbun_inplace(bat *r, const bat *bid, const oid *id, const void *t) { @@ -1202,6 +1333,8 @@ mel_func bat5_init_funcs[] = { command("bat", "append", BKCappend_cand_wrap, false, "append the content of u with candidate list s to i", args(1,4, batargany("",1),batargany("i",1),batargany("u",1),batarg("s",oid))), command("bat", "append", BKCappend_cand_force_wrap, false, "append the content of u with candidate list s to i", args(1,5, batargany("",1),batargany("i",1),batargany("u",1),batarg("s",oid),arg("force",bit))), command("bat", "append", BKCappend_val_force_wrap, false, "append the value u to i", args(1,4, batargany("",1),batargany("i",1),argany("u",1),arg("force",bit))), + pattern("bat", "appendBulk", BKCappend_bulk_force_wrap, false, "append the arguments ins to i", args(1,4, batargany("",1), batargany("i",1),arg("force",bit),varargany("ins",1))), + pattern("bat", "appendBulk", BKCappend_bulk_force_wrap, false, "append the arguments ins to i", args(1,4, batargany("",1), batargany("i",1),arg("force",bit),batvarargany("ins",1))), command("bat", "attach", BKCattach, false, "Returns a new BAT with dense head and tail of the given type and uses\nthe given file to initialize the tail. The file will be owned by the\nserver.", args(1,3, batargany("",1),arg("tt",int),arg("heapfile",str))), command("bat", "densebat", BKCdensebat, false, "Creates a new [void,void] BAT of size 'sz'.", args(1,2, batarg("",oid),arg("sz",lng))), command("bat", "info", BKCinfo, false, "Produce a table containing information about a BAT in [attribute,value] format. \nIt contains all properties of the BAT record. ", args(2,3, batarg("",str),batarg("",str),batargany("b",1))), diff --git a/monetdb5/modules/kernel/bat5.h b/monetdb5/modules/kernel/bat5.h --- a/monetdb5/modules/kernel/bat5.h +++ b/monetdb5/modules/kernel/bat5.h @@ -10,6 +10,7 @@ #define _BAT_H_ #include "mal.h" +#include "mal_client.h" #include "gdk.h" mal_export str BKCnewBAT(bat *res, const int *tt, const BUN *cap, role_t role); @@ -25,6 +26,7 @@ mal_export str BKCappend_cand_wrap(bat * mal_export str BKCappend_cand_force_wrap(bat *r, const bat *bid, const bat *uid, const bat *sid, const bit *force); mal_export str BKCappend_val_wrap(bat *r, const bat *bid, const void *u); mal_export str BKCappend_val_force_wrap(bat *r, const bat *bid, const void *u, const bit *force); +mal_export str BKCappend_bulk_force_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci); mal_export str BKCbun_inplace(bat *r, const bat *bid, const oid *id, const void *t); mal_export str BKCbat_inplace(bat *r, const bat *bid, const bat *rid, const bat *uid); mal_export str BKCbun_inplace_force(bat *r, const bat *bid, const oid *id, const void *t, const bit *force); diff --git a/monetdb5/modules/kernel/bat5.mal b/monetdb5/modules/kernel/bat5.mal --- a/monetdb5/modules/kernel/bat5.mal +++ b/monetdb5/modules/kernel/bat5.mal @@ -60,6 +60,13 @@ command append(i:bat[:any_1], u:any_1, f address BKCappend_val_force_wrap comment "append the value u to i"; +pattern appendBulk( i:bat[:any_1], force:bit, ins:any_1... ) :bat[:any_1] +address BKCappend_bulk_force_wrap +comment "append the arguments ins to i"; + +pattern appendBulk( i:bat[:any_1], force:bit, ins:bat[:any_1]... ) :bat[:any_1] +address BKCappend_bulk_force_wrap +comment "append the arguments ins to i"; command attach(tt:int, heapfile:str) :bat[:any_1] address BKCattach diff --git a/monetdb5/optimizer/opt_prelude.c b/monetdb5/optimizer/opt_prelude.c --- a/monetdb5/optimizer/opt_prelude.c +++ b/monetdb5/optimizer/opt_prelude.c @@ -40,6 +40,7 @@ str alter_userRef; str alter_viewRef; str andRef; str appendidxRef; +str appendBulkRef; str appendRef; str arrayRef; str assertRef; @@ -346,6 +347,7 @@ void optimizerInit(void) alter_viewRef = putName("alter_view"); andRef = putName("and"); appendidxRef = putName("append_idxbat"); + appendBulkRef = putName("appendBulk"); appendRef = putName("append"); arrayRef = putName("array"); assertRef = putName("assert"); diff --git a/monetdb5/optimizer/opt_prelude.h b/monetdb5/optimizer/opt_prelude.h --- a/monetdb5/optimizer/opt_prelude.h +++ b/monetdb5/optimizer/opt_prelude.h @@ -36,6 +36,7 @@ mal_export str alter_userRef; mal_export str alter_viewRef; mal_export str andRef; mal_export str appendidxRef; +mal_export str appendBulkRef; mal_export str appendRef; mal_export str arrayRef; mal_export str assertRef; diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c --- a/sql/backends/monet5/rel_bin.c +++ b/sql/backends/monet5/rel_bin.c @@ -282,12 +282,11 @@ row2cols(backend *be, stmt *sub) static stmt* distinct_value_list(backend *be, list *vals, stmt ** last_null_value) { - node *n; + list *l = sa_list(be->mvc->sa); stmt *s; /* create bat append values */ - s = stmt_temp(be, exp_subtype(vals->h->data)); - for( n = vals->h; n; n = n->next) { + for (node *n = vals->h; n; n = n->next) { sql_exp *e = n->data; stmt *i = exp_bin(be, e, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0); @@ -297,9 +296,9 @@ distinct_value_list(backend *be, list *v if (!i) return NULL; - s = stmt_append(be, s, i); - } - + list_append(l, i); + } + s = stmt_append_bulk(be, stmt_temp(be, exp_subtype(vals->h->data)), l); /* Probably faster to filter out the values directly in the underlying list of atoms. But for now use groupby to filter out duplicate values. */ stmt* groupby = stmt_group(be, s, NULL, NULL, NULL, 1); @@ -473,15 +472,14 @@ handle_in_exps(backend *be, sql_exp *ce, static stmt * _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list