Changeset: ab3f587d26ee for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ab3f587d26ee
Modified Files:
        sql/backends/monet5/sql_cast.c
        sql/backends/monet5/sql_result.c
        sql/backends/monet5/sql_result.h
Branch: alloc-less-str
Log Message:

Use size_t and return the new buffer length if it gets reallocated during the 
cast operation. Use a default buffer size for strings as well.


diffs (217 lines):

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
@@ -106,7 +106,7 @@ batstr_2_blob(bat *res, const bat *bid)
 }
 
 /* TODO get max size for all from type */
-static int
+static size_t
 str_buf_initial_capacity(sql_class eclass, int digits)
 {
        switch (eclass)
@@ -125,31 +125,38 @@ str_buf_initial_capacity(sql_class eclas
                case EC_TIMESTAMP:
                case EC_TIMESTAMP_TZ:
                        return 64;
-               default: /* includes EC_FLT */
+               case EC_FLT:
+                       return 128;
+               case EC_CHAR:
+               case EC_STRING:
+               case EC_BLOB:
+               case EC_GEOM:
+                       return 1024;
+               default:
                        return 128;
        }
 }
 
 static inline str
-SQLstr_cast_any_type(str *r, int rlen, mvc *m, sql_class eclass, int d, int s, 
int has_tz, ptr p, int tpe, int len)
+SQLstr_cast_any_type(str *r, size_t *rlen, mvc *m, sql_class eclass, int d, 
int s, int has_tz, ptr p, int tpe, int len)
 {
-       int sz = convert2str(m, eclass, d, s, has_tz, p, tpe, r, rlen);
-       if ((len > 0 && sz > len) || sz < 0)
+       ssize_t sz = convert2str(m, eclass, d, s, has_tz, p, tpe, r, rlen);
+       if ((len > 0 && sz > (ssize_t) len) || sz < 0)
                throw(SQL, "str_cast", SQLSTATE(22001) "value too long for type 
(var)char(%d)", len);
        return MAL_SUCCEED;
 }
 
 static inline str
-SQLstr_cast_str(str *r, int *rlen, str v, int len)
+SQLstr_cast_str(str *r, size_t *rlen, str v, int len)
 {
-       int intput_strlen;
+       size_t intput_strlen;
 
        if (!strNil(v) && len > 0 && str_utf8_length(v) > len)
                throw(SQL, "str_cast", SQLSTATE(22001) "value too long for type 
(var)char(%d)", len);
 
-       intput_strlen = (int) strlen(v) + 1;
+       intput_strlen = strlen(v) + 1;
        if (intput_strlen > *rlen) {
-               int newlen = ((intput_strlen + 1023) & ~1023); /* align to a 
multiple of 1024 bytes */
+               size_t newlen = ((intput_strlen + 1023) & ~1023); /* align to a 
multiple of 1024 bytes */
                str newr = GDKmalloc(newlen);
 
                if (!newr)
@@ -171,6 +178,7 @@ SQLstr_cast(Client cntxt, MalBlkPtr mb, 
        int has_tz = *getArgReference_int(stk, pci, 4), tpe = getArgType(mb, 
pci, 5), digits = *getArgReference_int(stk, pci, 6);
        ptr p = getArgReference(stk, pci, 5);
        mvc *m = NULL;
+       bool from_str = EC_VARCHAR(eclass) || tpe == TYPE_str;
 
        if ((msg = getSQLContext(cntxt, mb, &m, NULL)) != NULL)
                return msg;
@@ -179,22 +187,22 @@ SQLstr_cast(Client cntxt, MalBlkPtr mb, 
        if (ATOMextern(tpe))
                p = *(ptr *) p;
 
-       if (EC_VARCHAR(eclass) || tpe == TYPE_str) {
+       if (from_str) {
                r = (str) p;
                if (!strNil(r) && digits > 0 && str_utf8_length(r) > digits)
                        throw(SQL, "calc.str_cast", SQLSTATE(22001) "value too 
long for type (var)char(%d)", digits);
        } else {
-               int rlen = MAX(str_buf_initial_capacity(eclass, digits), (int) 
strlen(str_nil) + 1); /* don't reallocate on str_nil */
+               size_t rlen = MAX(str_buf_initial_capacity(eclass, digits), 
strlen(str_nil) + 1); /* don't reallocate on str_nil */
                if (!(r = GDKmalloc(rlen)))
                        throw(SQL, "calc.str_cast", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
-               if ((msg = SQLstr_cast_any_type(&r, rlen, m, eclass, d, s, 
has_tz, p, tpe, digits)) != MAL_SUCCEED) {
+               if ((msg = SQLstr_cast_any_type(&r, &rlen, m, eclass, d, s, 
has_tz, p, tpe, digits)) != MAL_SUCCEED) {
                        GDKfree(r);
                        return msg;
                }
        }
 
        *res = GDKstrdup(r);
-       if (!(EC_VARCHAR(eclass) || tpe == TYPE_str))
+       if (!from_str)
                GDKfree(r);
        if (!res)
                throw(SQL, "calc.str_cast", SQLSTATE(HY013) MAL_MALLOC_FAIL);
@@ -211,16 +219,14 @@ SQLbatstr_cast(Client cntxt, MalBlkPtr m
        str msg, r = NULL;
        bat *res = getArgReference_bat(stk, pci, 0);
        sql_class eclass = (sql_class) *getArgReference_int(stk, pci, 1);
-       int d1 = *getArgReference_int(stk, pci, 2), s1 = 
*getArgReference_int(stk, pci, 3);
-       int has_tz = *getArgReference_int(stk, pci, 4);
+       int d1 = *getArgReference_int(stk, pci, 2), s1 = 
*getArgReference_int(stk, pci, 3), has_tz = *getArgReference_int(stk, pci, 4);
        bat *bid = getArgReference_bat(stk, pci, 5), *sid = pci->argc == 7 ? 
NULL : getArgReference_bat(stk, pci, 6);
-       int digits = pci->argc == 7 ? *getArgReference_int(stk, pci, 6) : 
*getArgReference_int(stk, pci, 7);
-       int rlen = 0, tpe = getBatType(getArgType(mb, pci, 5));
+       int tpe = getBatType(getArgType(mb, pci, 5)), digits = pci->argc == 7 ? 
*getArgReference_int(stk, pci, 6) : *getArgReference_int(stk, pci, 7);
        struct canditer ci;
        BUN q;
-       int initial_capacity = MAX(str_buf_initial_capacity(eclass, digits), 
(int) strlen(str_nil) + 1); /* don't reallocate on str_nil */
        oid off;
        bool nils = false, from_str = EC_VARCHAR(eclass) || tpe == TYPE_str;
+       size_t rlen = MAX(str_buf_initial_capacity(eclass, digits), 
strlen(str_nil) + 1); /* don't reallocate on str_nil */
 
        if ((msg = getSQLContext(cntxt, mb, &m, NULL)) != NULL)
                return msg;
@@ -242,13 +248,10 @@ SQLbatstr_cast(Client cntxt, MalBlkPtr m
                goto bailout;
        }
 
-       assert(initial_capacity > 0);
-       if (!from_str) { /* for decimals and other fixed size types allocate 
once */
-               if (!(r = GDKmalloc(initial_capacity))) {
-                       msg = createException(SQL, "batcalc.str_cast", 
SQLSTATE(HY013) MAL_MALLOC_FAIL);
-                       goto bailout;
-               }
-               rlen = initial_capacity;
+       assert(rlen > 0);
+       if (!(r = GDKmalloc(rlen))) {
+               msg = createException(SQL, "batcalc.str_cast", SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
+               goto bailout;
        }
 
        for (BUN i = 0; i < q; i++) {
@@ -258,7 +261,7 @@ SQLbatstr_cast(Client cntxt, MalBlkPtr m
                if (from_str)
                        msg = SQLstr_cast_str(&r, &rlen, (str) v, digits);
                else
-                       msg = SQLstr_cast_any_type(&r, rlen, m, eclass, d1, s1, 
has_tz, v, tpe, digits);
+                       msg = SQLstr_cast_any_type(&r, &rlen, m, eclass, d1, 
s1, has_tz, v, tpe, digits);
 
                if (msg)
                        goto bailout;
diff --git a/sql/backends/monet5/sql_result.c b/sql/backends/monet5/sql_result.c
--- a/sql/backends/monet5/sql_result.c
+++ b/sql/backends/monet5/sql_result.c
@@ -1121,46 +1121,49 @@ mvc_send_hge(stream *s, hge cnt){
 }
 #endif
 
-int
-convert2str(mvc *m, sql_class eclass, int d, int sc, int has_tz, ptr p, int 
mtype, char **buf, int len)
+ssize_t
+convert2str(mvc *m, sql_class eclass, int d, int sc, int has_tz, ptr p, int 
mtype, char **buf, size_t *len)
 {
-       size_t len2 = (size_t) len;
        ssize_t l = 0;
 
        if (!p || ATOMcmp(mtype, ATOMnilptr(mtype), p) == 0) {
                (*buf)[0] = '\200';
                (*buf)[1] = 0;
        } else if (eclass == EC_DEC) {
-               l = dec_tostr((void *) (ptrdiff_t) sc, buf, &len2, mtype, p);
+               l = dec_tostr((void *) (ptrdiff_t) sc, buf, len, mtype, p);
        } else if (eclass == EC_TIME || eclass == EC_TIME_TZ) {
                struct time_res ts_res;
                ts_res.has_tz = has_tz;
                ts_res.fraction = d ? d - 1 : 0;
                ts_res.timezone = m->timezone;
-               l = sql_time_tostr((void *) &ts_res, buf, &len2, mtype, p);
+               l = sql_time_tostr((void *) &ts_res, buf, len, mtype, p);
        } else if (eclass == EC_TIMESTAMP || eclass == EC_TIMESTAMP_TZ) {
                struct time_res ts_res;
                ts_res.has_tz = has_tz;
                ts_res.fraction = d ? d - 1 : 0;
                ts_res.timezone = m->timezone;
-               l = sql_timestamp_tostr((void *) &ts_res, buf, &len2, mtype, p);
+               l = sql_timestamp_tostr((void *) &ts_res, buf, len, mtype, p);
        } else if (eclass == EC_SEC) {
-               l = dec_tostr((void *) (ptrdiff_t) 3, buf, &len2, mtype, p);
+               l = dec_tostr((void *) (ptrdiff_t) 3, buf, len, mtype, p);
        } else if (eclass == EC_BIT) {
                bit b = *(bit *) p;
-               if (len <= 0 || len > 5) {
-                       if (b)
+               if (*len == 0 || *len > 5) {
+                       if (b) {
                                strcpy(*buf, "true");
-                       else
+                               l = 4;
+                       } else {
                                strcpy(*buf, "false");
+                               l = 5;
+                       }
                } else {
                        (*buf)[0] = b?'t':'f';
                        (*buf)[1] = 0;
+                       l = 1;
                }
        } else {
-               l = (*BATatoms[mtype].atomToStr) (buf, &len2, p, false);
+               l = (*BATatoms[mtype].atomToStr) (buf, len, p, false);
        }
-       return (int) l;
+       return l;
 }
 
 static int
diff --git a/sql/backends/monet5/sql_result.h b/sql/backends/monet5/sql_result.h
--- a/sql/backends/monet5/sql_result.h
+++ b/sql/backends/monet5/sql_result.h
@@ -31,6 +31,6 @@ extern int mvc_result_table(backend *be,
 extern int mvc_result_column(backend *be, char *tn, char *name, char 
*typename, int digits, int scale, BAT *b);
 extern int mvc_result_value(backend *be, const char *tn, const char *name, 
const char *typename, int digits, int scale, ptr *p, int mtype);
 
-extern int convert2str(mvc *m, sql_class eclass, int d, int sc, int has_tz, 
ptr p, int mtype, char **buf, int len);
+extern ssize_t convert2str(mvc *m, sql_class eclass, int d, int sc, int 
has_tz, ptr p, int mtype, char **buf, size_t *len);
 
 #endif /* sql_result_H */
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to