Changeset: 6447c3c48ece for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6447c3c48ece Modified Files: clients/Tests/MAL-signatures.stable.out clients/Tests/MAL-signatures.stable.out.int128 monetdb5/modules/atoms/blob.c sql/backends/monet5/sql_cast.c sql/test/SQLancer/Tests/sqlancer11.test Branch: default Log Message:
I forgot the bulk version for batcalc.blob with candidate list support. Also optimize sql cast between strings to do no copying when possible diffs (238 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 @@ -3768,6 +3768,7 @@ stdout of test 'MAL-signatures` in direc [ "batcalc", "bit_noerror", "pattern batcalc.bit_noerror(X_1:bat[:sht], X_2:bat[:oid]):bat[:bit] ", "CMDconvert_bit;", "" ] [ "batcalc", "bit_noerror", "pattern batcalc.bit_noerror(X_1:bat[:str]):bat[:bit] ", "CMDconvert_bit;", "" ] [ "batcalc", "bit_noerror", "pattern batcalc.bit_noerror(X_1:bat[:str], X_2:bat[:oid]):bat[:bit] ", "CMDconvert_bit;", "" ] +[ "batcalc", "blob", "command batcalc.blob(X_1:bat[:blob], X_2:bat[:oid]):bat[:blob] ", "BLOBblob_blob_bulk;", "" ] [ "batcalc", "blob", "command batcalc.blob(X_1:bat[:str], X_2:bat[:oid]):bat[:blob] ", "batstr_2_blob;", "" ] [ "batcalc", "bte", "pattern batcalc.bte(X_1:bat[:bit]):bat[:bte] ", "CMDconvertsignal_bte;", "" ] [ "batcalc", "bte", "pattern batcalc.bte(X_1:bat[:bit], X_2:bat[:oid]):bat[:bte] ", "CMDconvertsignal_bte;", "" ] 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 @@ -5388,6 +5388,7 @@ stdout of test 'MAL-signatures` in direc [ "batcalc", "bit_noerror", "pattern batcalc.bit_noerror(X_1:bat[:sht], X_2:bat[:oid]):bat[:bit] ", "CMDconvert_bit;", "" ] [ "batcalc", "bit_noerror", "pattern batcalc.bit_noerror(X_1:bat[:str]):bat[:bit] ", "CMDconvert_bit;", "" ] [ "batcalc", "bit_noerror", "pattern batcalc.bit_noerror(X_1:bat[:str], X_2:bat[:oid]):bat[:bit] ", "CMDconvert_bit;", "" ] +[ "batcalc", "blob", "command batcalc.blob(X_1:bat[:blob], X_2:bat[:oid]):bat[:blob] ", "BLOBblob_blob_bulk;", "" ] [ "batcalc", "blob", "command batcalc.blob(X_1:bat[:str], X_2:bat[:oid]):bat[:blob] ", "batstr_2_blob;", "" ] [ "batcalc", "bte", "pattern batcalc.bte(X_1:bat[:bit]):bat[:bte] ", "CMDconvertsignal_bte;", "" ] [ "batcalc", "bte", "pattern batcalc.bte(X_1:bat[:bit], X_2:bat[:oid]):bat[:bte] ", "CMDconvertsignal_bte;", "" ] diff --git a/monetdb5/modules/atoms/blob.c b/monetdb5/modules/atoms/blob.c --- a/monetdb5/modules/atoms/blob.c +++ b/monetdb5/modules/atoms/blob.c @@ -386,6 +386,80 @@ BLOBblob_blob(blob **d, blob **s) } static str +BLOBblob_blob_bulk(bat *res, const bat *bid, const bat *sid) +{ + BAT *b = NULL, *s = NULL, *dst = NULL; + BATiter bi; + str msg = NULL; + struct canditer ci; + BUN q; + oid off; + bool nils = false; + + if ((b = BATdescriptor(*bid)) == NULL) { + msg = createException(SQL, "batcalc.blob_blob_bulk", SQLSTATE(HY005) RUNTIME_OBJECT_MISSING); + goto bailout; + } + if (sid && !is_bat_nil(*sid)) { + if ((s = BATdescriptor(*sid)) == NULL) { + msg = createException(SQL, "batcalc.blob_blob_bulk", SQLSTATE(HY005) RUNTIME_OBJECT_MISSING); + goto bailout; + } + } else { + BBPkeepref(*res = b->batCacheid); /* nothing to convert, return */ + return MAL_SUCCEED; + } + off = b->hseqbase; + q = canditer_init(&ci, b, s); + bi = bat_iterator(b); + if (!(dst = COLnew(ci.hseq, TYPE_blob, q, TRANSIENT))) { + msg = createException(SQL, "batcalc.blob_blob_bulk", SQLSTATE(HY013) MAL_MALLOC_FAIL); + goto bailout; + } + + if (ci.tpe == cand_dense) { + for (BUN i = 0; i < q; i++) { + oid p = (canditer_next_dense(&ci) - off); + blob *v = (blob*) BUNtvar(bi, p); + + if (tfastins_nocheckVAR(dst, i, v, Tsize(dst)) != GDK_SUCCEED) { + msg = createException(SQL, "batcalc.blob_blob_bulk", SQLSTATE(HY013) MAL_MALLOC_FAIL); + goto bailout; + } + nils |= is_blob_nil(v); + } + } else { + for (BUN i = 0; i < q; i++) { + oid p = (canditer_next(&ci) - off); + blob *v = (blob*) BUNtvar(bi, p); + + if (tfastins_nocheckVAR(dst, i, v, Tsize(dst)) != GDK_SUCCEED) { + msg = createException(SQL, "batcalc.blob_blob_bulk", SQLSTATE(HY013) MAL_MALLOC_FAIL); + goto bailout; + } + nils |= is_blob_nil(v); + } + } + +bailout: + if (b) + BBPunfix(b->batCacheid); + if (s) + BBPunfix(s->batCacheid); + if (dst && !msg) { + BATsetcount(dst, q); + dst->tnil = nils; + dst->tnonil = !nils; + dst->tkey = BATcount(dst) <= 1; + dst->tsorted = BATcount(dst) <= 1; + dst->trevsorted = BATcount(dst) <= 1; + BBPkeepref(*res = dst->batCacheid); + } else if (dst) + BBPreclaim(dst); + return msg; +} + +static str BLOBblob_fromstr(blob **b, const char **s) { size_t len = 0; @@ -407,6 +481,7 @@ static mel_func blob_init_funcs[] = { command("batblob", "nitems", BLOBnitems_bulk, false, "", args(1,2, batarg("",int),batarg("b",blob))), command("blob", "prelude", BLOBprelude, false, "", args(1,1, arg("",void))), command("calc", "blob", BLOBblob_blob, false, "", args(1,2, arg("",blob),arg("b",blob))), + command("batcalc", "blob", BLOBblob_blob_bulk, false, "", args(1,3, batarg("",blob),batarg("b",blob),batarg("s",oid))), command("calc", "blob", BLOBblob_fromstr, false, "", args(1,2, arg("",blob),arg("s",str))), { .imp=NULL } }; diff --git a/sql/backends/monet5/sql_cast.c b/sql/backends/monet5/sql_cast.c --- a/sql/backends/monet5/sql_cast.c +++ b/sql/backends/monet5/sql_cast.c @@ -155,29 +155,6 @@ SQLstr_cast_any_type(str *r, size_t *rle return MAL_SUCCEED; } -static inline str -SQLstr_cast_str(str *r, size_t *rlen, str v, int len) -{ - size_t intput_strlen; - - if (len > 0 && str_utf8_length(v) > len) - throw(SQL, "str_cast", SQLSTATE(22001) "value too long for type (var)char(%d)", len); - - intput_strlen = strlen(v) + 1; - if (intput_strlen > *rlen) { - size_t newlen = ((intput_strlen + 1023) & ~1023); /* align to a multiple of 1024 bytes */ - str newr = GDKmalloc(newlen); - - if (!newr) - throw(SQL, "str_cast", SQLSTATE(HY013) MAL_MALLOC_FAIL); - GDKfree(*r); - *r = newr; - *rlen = newlen; - } - strcpy(*r, v); - return MAL_SUCCEED; -} - str SQLstr_cast(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { @@ -218,6 +195,12 @@ SQLstr_cast(Client cntxt, MalBlkPtr mb, return MAL_SUCCEED; } +#define SQLstr_cast_str(v, len) \ + if (len > 0 && str_utf8_length(v) > len) { \ + msg = createException(SQL, "batcalc.str_cast", SQLSTATE(22001) "value too long for type (var)char(%d)", len); \ + goto bailout; \ + } + /* str SQLbatstr_cast(int *res, int *eclass, int *d1, int *s1, int *has_tz, int *bid, int *digits); */ str SQLbatstr_cast(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) @@ -252,13 +235,25 @@ SQLbatstr_cast(Client cntxt, MalBlkPtr m off = b->hseqbase; q = canditer_init(&ci, b, s); bi = bat_iterator(b); + + if (from_str && (!sid || is_bat_nil(*sid))) { /* from string case, just do validation, if right, return */ + for (BUN i = 0; i < q; i++) { + str v = (str) BUNtvar(bi, i); + + if (!strNil(v)) + SQLstr_cast_str(v, digits); + } + BBPkeepref(*res = b->batCacheid); + return MAL_SUCCEED; + } + if (!(dst = COLnew(ci.hseq, TYPE_str, q, TRANSIENT))) { msg = createException(SQL, "batcalc.str_cast", SQLSTATE(HY013) MAL_MALLOC_FAIL); goto bailout; } assert(rlen > 0); - if (!(r = GDKmalloc(rlen))) { + if (!from_str && !(r = GDKmalloc(rlen))) { msg = createException(SQL, "batcalc.str_cast", SQLSTATE(HY013) MAL_MALLOC_FAIL); goto bailout; } @@ -276,9 +271,8 @@ SQLbatstr_cast(Client cntxt, MalBlkPtr m } nils = true; } else { - if ((msg = SQLstr_cast_str(&r, &rlen, v, digits)) != MAL_SUCCEED) - goto bailout; - if (tfastins_nocheckVAR(dst, i, r, Tsize(dst)) != GDK_SUCCEED) { + SQLstr_cast_str(v, digits); + if (tfastins_nocheckVAR(dst, i, v, Tsize(dst)) != GDK_SUCCEED) { msg = createException(SQL, "batcalc.str_cast", SQLSTATE(HY013) MAL_MALLOC_FAIL); goto bailout; } @@ -311,9 +305,8 @@ SQLbatstr_cast(Client cntxt, MalBlkPtr m } nils = true; } else { - if ((msg = SQLstr_cast_str(&r, &rlen, v, digits)) != MAL_SUCCEED) - goto bailout; - if (tfastins_nocheckVAR(dst, i, r, Tsize(dst)) != GDK_SUCCEED) { + SQLstr_cast_str(v, digits); + if (tfastins_nocheckVAR(dst, i, v, Tsize(dst)) != GDK_SUCCEED) { msg = createException(SQL, "batcalc.str_cast", SQLSTATE(HY013) MAL_MALLOC_FAIL); goto bailout; } diff --git a/sql/test/SQLancer/Tests/sqlancer11.test b/sql/test/SQLancer/Tests/sqlancer11.test --- a/sql/test/SQLancer/Tests/sqlancer11.test +++ b/sql/test/SQLancer/Tests/sqlancer11.test @@ -893,3 +893,23 @@ MERGE INTO t1 USING (SELECT * FROM t2) A statement ok ROLLBACK +statement ok +START TRANSACTION + +statement ok +CREATE TABLE "sys"."t0" ("c0" BIGINT,"c2" DECIMAL(18,3),"c4" BIGINT,"c5" VARCHAR(253)); + +statement ok +CREATE TABLE "sys"."t1" ("c2" BINARY LARGE OBJECT); + +statement ok +CREATE TABLE "sys"."t2" ("c2" BIGINT); + +statement ok +INSERT INTO "sys"."t2" VALUES (6),(7),(1),(1457323133),(8); + +statement ok +INSERT INTO t1(c2) VALUES(COALESCE(BLOB '23f0', ifthenelse(FALSE, BLOB '', BLOB '70'), COALESCE(BLOB 'f7b1FD', BLOB 'A0', BLOB '0c', BLOB '', BLOB ''))), (CASE WHEN NOT EXISTS (SELECT ALL l2t2.c2 FROM t2 AS l2t2, t0 AS l2t0, t1 AS l2t1 WHERE FALSE) THEN BLOB 'F0' ELSE (SELECT DISTINCT NULL WHERE TRUE) END); + +statement ok +ROLLBACK _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list