Changeset: 1513c46f4eb0 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/1513c46f4eb0 Removed Files: monetdb5/modules/atoms/blob.h Modified Files: clients/Tests/MAL-signatures-hge.test clients/Tests/MAL-signatures.test clients/Tests/exports.stable.out gdk/ChangeLog gdk/gdk.h gdk/gdk_atoms.c gdk/gdk_atoms.h monetdb5/mal/mal_type.c monetdb5/modules/atoms/CMakeLists.txt monetdb5/modules/atoms/blob.c sql/backends/monet5/UDF/capi/capi.c sql/backends/monet5/UDF/pyapi3/conversion3.c sql/backends/monet5/UDF/pyapi3/pyheader.h sql/backends/monet5/sql.h sql/server/sql_atom.c tools/monetdbe/monetdbe.c Branch: default Log Message:
The BLOB type has been moved into the GDK layer. diffs (truncated from 871 to 300 lines): diff --git a/clients/Tests/MAL-signatures-hge.test b/clients/Tests/MAL-signatures-hge.test --- a/clients/Tests/MAL-signatures-hge.test +++ b/clients/Tests/MAL-signatures-hge.test @@ -46038,11 +46038,6 @@ command blob.nitems(X_0:blob):int BLOBnitems; get the number of bytes in this blob. blob -prelude -command blob.prelude():void -BLOBprelude; -(empty) -blob toblob command blob.toblob(X_0:str):blob BLOBtoblob; diff --git a/clients/Tests/MAL-signatures.test b/clients/Tests/MAL-signatures.test --- a/clients/Tests/MAL-signatures.test +++ b/clients/Tests/MAL-signatures.test @@ -33243,11 +33243,6 @@ command blob.nitems(X_0:blob):int BLOBnitems; get the number of bytes in this blob. blob -prelude -command blob.prelude():void -BLOBprelude; -(empty) -blob toblob command blob.toblob(X_0:str):blob BLOBtoblob; 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 @@ -458,6 +458,7 @@ ssize_t batFromStr(const char *src, size ssize_t batToStr(str *dst, size_t *len, const bat *src, bool external); ssize_t bitFromStr(const char *src, size_t *len, bit **dst, bool external); ssize_t bitToStr(str *dst, size_t *len, const bit *src, bool external); +size_t blobsize(size_t nitems) __attribute__((__const__)); ssize_t bteFromStr(const char *src, size_t *len, bte **dst, bool external); ssize_t bteToStr(str *dst, size_t *len, const bte *src, bool external); const bte bte_nil; @@ -744,7 +745,6 @@ str BKCreuseBAT(bat *ret, const bat *bid str BKCsetName(void *r, const bat *bid, const char *const *s); str BKCsetPersistent(void *r, const bat *bid); str BKCshrinkBAT(bat *ret, const bat *bid, const bat *did); -ssize_t BLOBtostr(str *tostr, size_t *l, const void *pin, bool external); str CLTsessions(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci); str CLTshutdown(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci); str COPYrejects(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci); @@ -809,7 +809,6 @@ str TRNsubcommit(bit *ret, bat *bid); str TRNtrans_abort(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p); str TRNtrans_clean(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p); str TRNtrans_commit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr p); -int TYPE_blob; int TYPE_xml; UserStats USRstats; str WLCcommit(int clientid); @@ -874,7 +873,6 @@ const char *betweenRef; const char *bindRef; const char *binddbatRef; const char *bindidxRef; -var_t blobsize(size_t nitems); const char *blockRef; const char *bpmRef; const char *bstreamRef; diff --git a/gdk/ChangeLog b/gdk/ChangeLog --- a/gdk/ChangeLog +++ b/gdk/ChangeLog @@ -1,6 +1,9 @@ # ChangeLog file for GDK # This file is updated with Maddlog +* Mon Jan 31 2022 Sjoerd Mullender <[email protected]> +- The BLOB type has been moved into the GDK layer. + * Tue Jan 25 2022 Sjoerd Mullender <[email protected]> - When adding or subtracting months from a date or timestamp value, clamp the result to the calculated month instead of wrapping to the diff --git a/gdk/gdk.h b/gdk/gdk.h --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -457,6 +457,7 @@ enum { TYPE_timestamp, TYPE_uuid, TYPE_str, + TYPE_blob, TYPE_any = 255, /* limit types to <255! */ }; @@ -503,6 +504,12 @@ typedef union { #endif } uuid; +typedef struct { + size_t nitems; + char data[FLEXIBLE_ARRAY_MEMBER] __attribute__((__nonstring__)); +} blob; +gdk_export size_t blobsize(size_t nitems) __attribute__((__const__)); + #define SIZEOF_LNG 8 #define LL_CONSTANT(val) INT64_C(val) #define LLFMT "%" PRId64 diff --git a/gdk/gdk_atoms.c b/gdk/gdk_atoms.c --- a/gdk/gdk_atoms.c +++ b/gdk/gdk_atoms.c @@ -1390,6 +1390,252 @@ UUIDtoString(str *retval, size_t *len, c return UUID_STRLEN; } +static const blob blob_nil = { + ~(size_t) 0 +}; + +size_t +blobsize(size_t nitems) +{ + if (nitems == ~(size_t) 0) + nitems = 0; + assert(offsetof(blob, data) + nitems <= VAR_MAX); + return (size_t) (offsetof(blob, data) + nitems); +} + +static int +BLOBcmp(const void *L, const void *R) +{ + const blob *l = L, *r = R; + int c; + if (is_blob_nil(r)) + return !is_blob_nil(l); + if (is_blob_nil(l)) + return -1; + if (l->nitems < r->nitems) { + c = memcmp(l->data, r->data, l->nitems); + if (c == 0) + return -1; + } else { + c = memcmp(l->data, r->data, r->nitems); + if (c == 0) + return l->nitems > r->nitems; + } + return c; +} + +static void +BLOBdel(Heap *h, var_t *idx) +{ + HEAP_free(h, *idx); +} + +static BUN +BLOBhash(const void *B) +{ + const blob *b = B; + return (BUN) b->nitems; +} + +static void * +BLOBread(void *A, size_t *dstlen, stream *s, size_t cnt) +{ + blob *a = A; + int len; + + (void) cnt; + assert(cnt == 1); + if (mnstr_readInt(s, &len) != 1 || len < 0) + return NULL; + if (a == NULL || *dstlen < (size_t) len) { + if ((a = GDKrealloc(a, (size_t) len)) == NULL) + return NULL; + *dstlen = (size_t) len; + } + if (mnstr_read(s, (char *) a, (size_t) len, 1) != 1) { + GDKfree(a); + return NULL; + } + return a; +} + +static gdk_return +BLOBwrite(const void *A, stream *s, size_t cnt) +{ + const blob *a = A; + size_t len = blobsize(a->nitems); + + (void) cnt; + assert(cnt == 1); + if (!mnstr_writeInt(s, (int) len) /* 64bit: check for overflow */ || + mnstr_write(s, a, len, 1) < 0) + return GDK_FAIL; + return GDK_SUCCEED; +} + +static size_t +BLOBlength(const void *P) +{ + const blob *p = P; + size_t l = blobsize(p->nitems); /* 64bit: check for overflow */ + assert(l <= (size_t) GDK_int_max); + return l; +} + +static gdk_return +BLOBheap(Heap *heap, size_t capacity) +{ + return HEAP_initialize(heap, capacity, 0, (int) sizeof(var_t)); +} + +static var_t +BLOBput(BAT *b, var_t *bun, const void *VAL) +{ + const blob *val = VAL; + char *base = NULL; + + *bun = HEAP_malloc(b, blobsize(val->nitems)); + base = b->tvheap->base; + if (*bun != (var_t) -1) { + memcpy(&base[*bun], val, blobsize(val->nitems)); + b->tvheap->dirty = true; + } + return *bun; +} + +static ssize_t +BLOBtostr(str *tostr, size_t *l, const void *P, bool external) +{ + static const char hexit[] = "0123456789ABCDEF"; + const blob *p = P; + char *s; + size_t i; + size_t expectedlen; + + if (is_blob_nil(p)) + expectedlen = external ? 4 : 2; + else + expectedlen = p->nitems * 2 + 1; + if (*l < expectedlen || *tostr == NULL) { + GDKfree(*tostr); + *tostr = GDKmalloc(expectedlen); + if (*tostr == NULL) + return -1; + *l = expectedlen; + } + if (is_blob_nil(p)) { + if (external) { + strcpy(*tostr, "nil"); + return 3; + } + strcpy(*tostr, str_nil); + return 1; + } + + s = *tostr; + + for (i = 0; i < p->nitems; i++) { + int val = (p->data[i] >> 4) & 15; + + *s++ = hexit[val]; + val = p->data[i] & 15; + *s++ = hexit[val]; + } + *s = '\0'; + return (ssize_t) (s - *tostr); +} + +static ssize_t +BLOBfromstr(const char *instr, size_t *l, void **VAL, bool external) +{ + blob **val = (blob **) VAL; + size_t i; + size_t nitems; + size_t nbytes; + blob *result; + const char *s = instr; + + if (strNil(instr) || (external && strncmp(instr, "nil", 3) == 0)) { + nbytes = blobsize(0); + if (*l < nbytes || *val == NULL) { + GDKfree(*val); + if ((*val = GDKmalloc(nbytes)) == NULL) + return -1; + } + **val = blob_nil; + return strNil(instr) ? 1 : 3; + } + + /* count hexits and check for hexits/space */ + for (i = nitems = 0; instr[i]; i++) { + if (isxdigit((unsigned char) instr[i])) + nitems++; + else if (!isspace((unsigned char) instr[i])) { + GDKerror("Illegal char (not a hexadecimal digit) in blob\n"); + return -1; + } + } + if (nitems % 2 != 0) { + GDKerror("Illegal blob length '%zu' (should be even)\n", nitems); + return -1; + } + nitems /= 2; + nbytes = blobsize(nitems); _______________________________________________ checkin-list mailing list [email protected] https://www.monetdb.org/mailman/listinfo/checkin-list
