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