Changeset: 09e4382b22de for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/09e4382b22de
Modified Files:
sql/backends/monet5/sql_copyinto.c
sql/backends/monet5/sql_copyinto_dec_tmpl.h
Branch: directappend
Log Message:
Introduce ConversionResult and get rid of make_it_nil
This makes things much clearer
diffs (truncated from 490 to 300 lines):
diff --git a/sql/backends/monet5/sql_copyinto.c
b/sql/backends/monet5/sql_copyinto.c
--- a/sql/backends/monet5/sql_copyinto.c
+++ b/sql/backends/monet5/sql_copyinto.c
@@ -94,6 +94,21 @@ typedef struct Table_t {
BAT *complaints; /* lines that did not match the
required input */
} Tablet;
+/*
+ * Conversion result.
+ */
+typedef enum {
+ /* An error occurred, the import should be aborted */
+ ConversionFailed,
+ /* The result of the conversion should be considered nil.
+ * The state of the destination buffer is indeterminate.
+ */
+ ConversionNull,
+ /* The converted value has been written to the destination buffer */
+ ConversionOk,
+
+} ConversionResult;
+
struct directappend {
mvc *mvc;
@@ -810,29 +825,21 @@ SQLload_error(READERtask *task, lng idx,
}
static void report_append_failed(READERtask *task, Column *fmt, int idx, lng
col);
-static int report_conversion_failed(READERtask *task, Column *fmt, int idx,
lng col, char *s);
+static ConversionResult report_conversion_failed(READERtask *task, Column
*fmt, int idx, lng col, char *s);
-static inline void
-make_it_nil(Column *fmt, void **dst, size_t *dst_len)
+static void
+set_nil(Column *c, void *dst)
{
- if (fmt->c)
- fmt->c->tnonil = false;
- if (*dst_len >= fmt->nil_len)
- memcpy(*dst, fmt->nildata, fmt->nil_len);
- else {
- GDKfree(*dst);
- *dst_len = 0;
- }
+ memcpy(dst, c->nildata, c->nil_len);
}
// -1 means error, 0 means fully done, 1 means please parse *unescaped
-static inline int
-prepare_conversion(READERtask *task, Column *fmt, int col, int idx, void
**dst, size_t *dst_len, char **unescaped) {
+static inline ConversionResult
+prepare_conversion(READERtask *task, Column *fmt, int col, int idx, char
**unescaped) {
char *s = task->fields[col][idx];
if (s == NULL) {
- make_it_nil(fmt, dst, dst_len);
- return 0;
+ return ConversionNull;
}
size_t slen = strlen(s);
@@ -842,43 +849,39 @@ prepare_conversion(READERtask *task, Col
// reallocate scratch space if necessary
size_t needed = slen + 1;
if (adjust_scratch_buffer(&task->scratch, needed, needed / 2)
== NULL) {
- int ret = report_conversion_failed(task, fmt, idx, col
+ 1, "ALLOCATION FAILURE");
- make_it_nil(fmt, dst, dst_len);
- return ret;
+ ConversionResult res = report_conversion_failed(task,
fmt, idx, col + 1, "ALLOCATION FAILURE");
+ return res;
}
// unescape into the scratch space
if (GDKstrFromStr((unsigned char*)task->scratch.data, (unsigned
char*)s, slen) < 0) {
- int ret = report_conversion_failed(task, fmt, idx, col
+ 1, s);
- make_it_nil(fmt, dst, dst_len);
- return ret;
+ ConversionResult res = report_conversion_failed(task,
fmt, idx, col + 1, s);
+ return res;
}
*unescaped = task->scratch.data;
}
- return 1;
+ return ConversionOk;
}
-static inline int
-SQLconvert_val(READERtask *task, Column *fmt, int col, int idx, void **dst,
size_t *dst_len) {
+static inline ConversionResult
+SQLconvert_val(READERtask *task, Column *fmt, int col, int idx) {
char *unescaped = NULL;
- int ret = prepare_conversion(task, fmt, col, idx, dst, dst_len,
&unescaped);
- if (ret <= 0) {
- // < 0 means error, 0 means fully handled
- return ret;
+ ConversionResult res = prepare_conversion(task, fmt, col, idx,
&unescaped);
+ if (res == ConversionFailed) {
+ return res;
}
// convert using the frstr callback.
- void *p = fmt->frstr(fmt, fmt->adt, dst, dst_len, unescaped);
+ void *p = fmt->frstr(fmt, fmt->adt, &fmt->data, &fmt->len, unescaped);
if (p == NULL) {
- int ret = report_conversion_failed(task, fmt, idx, col + 1,
unescaped);
- make_it_nil(fmt, dst, dst_len);
- return ret;
+ ConversionResult res = report_conversion_failed(task, fmt, idx,
col + 1, unescaped);
+ return res;
}
- return 0;
+ return ConversionOk;
}
-static int
+static ConversionResult
report_conversion_failed(READERtask *task, Column *fmt, int idx, lng col, char
*s)
{
char buf[1024];
@@ -901,7 +904,7 @@ report_conversion_failed(READERtask *tas
; /* ignore error here:
we're already not best effort */
}
GDKfree(err);
- return -1;
+ return ConversionFailed;
}
mycpstr(scpy, s);
s = scpy;
@@ -924,12 +927,12 @@ report_conversion_failed(READERtask *tas
GDKfree(err);
task->besteffort = 0; /* no longer best effort */
MT_lock_unset(&errorlock);
- return -1;
+ return ConversionFailed;
}
MT_lock_unset(&errorlock);
}
GDKfree(err);
- return task->besteffort ? 0 : -1;
+ return task->besteffort ? ConversionNull : ConversionFailed;
}
static void
@@ -956,23 +959,25 @@ report_append_failed(READERtask *task, C
}
-static int
+static ConversionResult
SQLworker_onebyone_column(READERtask *task, int col)
{
Column *fmt = &task->as->format[col];
int count = task->top[task->cur];
for (int i = 0; i < count; i++) {
- if (SQLconvert_val(task, fmt, col, i, &fmt->data, &fmt->len) <
0)
- return -1;
- const void *value = fmt->data ? fmt->data : fmt->nildata;
+ ConversionResult res = SQLconvert_val(task, fmt, col, i);
+ if (res == ConversionFailed)
+ return ConversionFailed;
+
+ const void *value = res == ConversionOk ? fmt->data :
fmt->nildata;
str msg = directappend_append_one(task->directappend, i, value,
fmt->appendcol);
if (msg != MAL_SUCCEED) {
report_append_failed(task, fmt, i, col + 1);
- return -1;
+ return ConversionFailed;
}
}
- return 0;
+ return ConversionOk;
}
#define TMPL_TYPE bte
@@ -1001,31 +1006,34 @@ SQLworker_onebyone_column(READERtask *ta
-static int
+static ConversionResult
bulk_convert_frstr(READERtask *task, Column *c, int col, int count, size_t
width)
{
void *cursor = task->primary.data;
size_t w = width;
for (int i = 0; i < count; i++) {
char *unescaped = NULL;
- int ret = prepare_conversion(task, c, col, i, &cursor, &w,
&unescaped);
- if (ret > 0) {
+ ConversionResult res = prepare_conversion(task, c, col, i,
&unescaped);
+ if (res == ConversionOk) {
void *p = c->frstr(c, c->adt, &cursor, &w, unescaped);
if (p == NULL) {
- ret = report_conversion_failed(task, c, i, col
+ 1, unescaped);
- make_it_nil(c, &cursor, &w);
+ res = report_conversion_failed(task, c, i, col
+ 1, unescaped);
+ set_nil(c, cursor);
}
}
- if (ret < 0) {
- return -1;
+ if (res == ConversionFailed) {
+ return res;
+ }
+ if (res == ConversionNull) {
+ set_nil(c, cursor);
}
assert(w == width); // should not have attempted to reallocate!
cursor = (char*)cursor + width;
}
- return 0;
+ return ConversionOk;
}
-static int
+static ConversionResult
SQLworker_fixedwidth_column(READERtask *task, int col)
{
Column *c = &task->as->format[col];
@@ -1038,48 +1046,49 @@ SQLworker_fixedwidth_column(READERtask *
if (adjust_scratch_buffer(&task->primary, allocation_size, 0) == NULL) {
tablet_error(task, lng_nil, lng_nil, int_nil, "cannot allocate
memory", "");
- return -1;
+ return ConversionFailed;
}
- int ret;
+ ConversionResult res;
if (c->column->type.type->eclass == EC_DEC) {
switch (c->adt) {
case TYPE_bte:
- ret = bulk_convert_bte_dec(task, c, col, count,
width, t->digits, t->scale);
+ res = bulk_convert_bte_dec(task, c, col, count,
width, t->digits, t->scale);
break;
case TYPE_sht:
- ret = bulk_convert_sht_dec(task, c, col, count,
width, t->digits, t->scale);
+ res = bulk_convert_sht_dec(task, c, col, count,
width, t->digits, t->scale);
break;
case TYPE_int:
- ret = bulk_convert_int_dec(task, c, col, count,
width, t->digits, t->scale);
+ res = bulk_convert_int_dec(task, c, col, count,
width, t->digits, t->scale);
break;
case TYPE_lng:
- ret = bulk_convert_lng_dec(task, c, col, count,
width, t->digits, t->scale);
+ res = bulk_convert_lng_dec(task, c, col, count,
width, t->digits, t->scale);
break;
case TYPE_hge:
- ret = bulk_convert_hge_dec(task, c, col, count,
width, t->digits, t->scale);
+ res = bulk_convert_hge_dec(task, c, col, count,
width, t->digits, t->scale);
break;
default:
assert(0 && "unexpected column type for
decimal");
- return -1;
+ return ConversionFailed;
}
} else {
- ret = bulk_convert_frstr(task, c, col, count, width);
+ res = bulk_convert_frstr(task, c, col, count, width);
+
}
- if (ret < 0)
- return ret;
+ if (res == ConversionFailed)
+ return res;
// Now insert it.
str msg = directappend_append_batch(task->directappend,
task->primary.data, count, width, c->appendcol);
if (msg != MAL_SUCCEED) {
tablet_error(task, lng_nil, lng_nil, col, "bulk insert failed",
msg);
- return -1;
+ return ConversionFailed;
}
- return 0;
+ return ConversionOk;
}
-static int
+static ConversionResult
SQLworker_str_column(READERtask *task, int col)
{
Column *c = &task->as->format[col];
@@ -1091,7 +1100,7 @@ SQLworker_str_column(READERtask *task, i
size_t secondary_size = 0;
for (int i = 0; i < count; i++) {
- size_t max_field_size = c->nil_len;
+ size_t max_field_size = c->nil_len; // includes trailing \0
char *v = task->fields[col][i];
if (v) {
max_field_size += strlen(v) + 1;
@@ -1101,11 +1110,11 @@ SQLworker_str_column(READERtask *task, i
if (adjust_scratch_buffer(&task->primary, primary_size, 0) == NULL) {
tablet_error(task, lng_nil, lng_nil, int_nil, "cannot allocate
memory", NULL);
- return -1;
+ return ConversionFailed;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list