Changeset: 5686c027f964 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/5686c027f964
Added Files:
sql/backends/monet5/copy_convert_num.h
Modified Files:
sql/backends/monet5/CMakeLists.txt
sql/backends/monet5/copy.c
sql/backends/monet5/copy.h
sql/backends/monet5/copy_convert.c
sql/backends/monet5/rel_copy.c
Branch: copyparpipe
Log Message:
It works a little bit for int decimals
diffs (287 lines):
diff --git a/sql/backends/monet5/CMakeLists.txt
b/sql/backends/monet5/CMakeLists.txt
--- a/sql/backends/monet5/CMakeLists.txt
+++ b/sql/backends/monet5/CMakeLists.txt
@@ -158,7 +158,7 @@ target_sources(sql
for.c for.h
dict.c dict.h
copy.c copy.h
- copy_convert.c
+ copy_convert.c copy_convert_num.h
${MONETDB_CURRENT_SQL_SOURCES}
PUBLIC
${sql_public_headers})
diff --git a/sql/backends/monet5/copy.c b/sql/backends/monet5/copy.c
--- a/sql/backends/monet5/copy.c
+++ b/sql/backends/monet5/copy.c
@@ -772,6 +772,30 @@ end:
return msg;
}
+
+
+void
+copy_report_error(struct error_handling *restrict admin, int rel_row, _In_z_
_Printf_format_string_ const char *restrict format, ...)
+{
+ admin->count++;
+ if (admin->rel_row >= 0)
+ return;
+
+ admin->rel_row = rel_row;
+
+ char *buf = admin->message;
+ size_t buf_size = sizeof(admin->message);
+ va_list ap;
+ va_start(ap, format);
+ int ret = vsnprintf(buf, buf_size, format, ap);
+ va_end(ap);
+ if (ret < 0) {
+ snprintf(buf, buf_size, "an error [%d] occurred during error
reporting", ret);
+ }
+}
+
+
+
static str
COPYpair_assign(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
{
@@ -917,11 +941,16 @@ static mel_func copy_init_funcs[] = {
batarg("block", bte), arg("linecount", lng), arg("col_sep", str),
arg("line_sep", str), arg("quote", str), arg("null_repr", str), arg("escape",
bit)
)),
- pattern("copy", "parse_generic", COPYparse_generic, false, "Parse as an
integer", args(1, 4,
+ pattern("copy", "parse_generic", COPYparse_generic, false, "Parse using GDK's
atomFromStr", args(1, 4,
batargany("", 1),
batarg("block", bte), batarg("offsets", int), argany("type", 1)
)),
+ command("copy", "parse_decimal", COPYparse_decimal_int, false, "Parse as a
decimal", args(1, 6,
+ batarg("", int),
+ batarg("block", bte), batarg("offsets", int), arg("digits", int),
arg("scale", int), arg("type", int)
+ )),
+
command("copy", "set_blocksize", COPYset_blocksize, true, "set the COPY block
size", args(1, 2,
arg("blocksize", int)
)),
diff --git a/sql/backends/monet5/copy.h b/sql/backends/monet5/copy.h
--- a/sql/backends/monet5/copy.h
+++ b/sql/backends/monet5/copy.h
@@ -17,7 +17,25 @@
goto end; \
} while (0)
+
+struct error_handling {
+ int rel_row;
+ int count;
+ char message[512];
+};
+
+void copy_report_error(struct error_handling *restrict admin, int rel_row,
_In_z_ _Printf_format_string_ const char *restrict format, ...)
+ __attribute__((__format__(__printf__, 3, 4)));
+
+typedef str (*bulk_converter)(struct error_handling*, void *parms, int count,
void *dest, char *data, int *offsets);
+
+str parse_fixed_width_column(bat *ret, const char *fname, bat block_bat_id,
bat offsets_bat_id, int tpe, bulk_converter f, void *parms);
+
+
extern str COPYparse_generic(Client cntxt, MalBlkPtr mb, MalStkPtr stk,
InstrPtr pci);
+extern str COPYparse_decimal_int(bat *parsed_bat_id, bat *block_bat_id, bat
*offsets_bat_id, int *digits_p, int *scale_p, int *dummy);
+
+
#endif /*_COPY_H_*/
diff --git a/sql/backends/monet5/copy_convert.c
b/sql/backends/monet5/copy_convert.c
--- a/sql/backends/monet5/copy_convert.c
+++ b/sql/backends/monet5/copy_convert.c
@@ -15,6 +15,7 @@
#include "copy.h"
+#define INSIDE_COPY_CONVERT 1
str
COPYparse_generic(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
@@ -78,3 +79,57 @@ end:
BBPunfix(indices->batCacheid);
return msg;
}
+
+str
+parse_fixed_width_column(
+ bat *ret,
+ const char *fname,
+ bat block_bat_id, bat offsets_bat_id,
+ int tpe,
+ str (*f)(struct error_handling*, void*, int, void*, char*, int*),
+ void *fx)
+{
+ str msg = MAL_SUCCEED;
+ BAT *block_bat;
+ BAT *offsets_bat;
+ BAT *parsed_bat;
+ struct error_handling errors = {
+ .rel_row = -1,
+ };
+
+ block_bat = BATdescriptor(block_bat_id);
+ offsets_bat = BATdescriptor(offsets_bat_id);
+ if (!block_bat || !offsets_bat)
+ bailout(fname, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
+
+ parsed_bat = COLnew(0, tpe, BATcount(offsets_bat), TRANSIENT);
+ if (!parsed_bat)
+ bailout(fname, SQLSTATE(HY013) MAL_MALLOC_FAIL);
+
+ msg = f(&errors, fx, BATcount(offsets_bat), Tloc(parsed_bat, 0),
Tloc(block_bat, 0), Tloc(offsets_bat, 0));
+ if (msg != MAL_SUCCEED)
+ goto end;
+
+ BATsetcount(parsed_bat, BATcount(offsets_bat));
+
+ if (errors.count > 0)
+ bailout(fname, "At least %d conversion errors, example: %s",
errors.count, errors.message);
+
+end:
+ if (parsed_bat) {
+ if (msg == MAL_SUCCEED) {
+ *ret = parsed_bat->batCacheid;
+ BBPkeepref(parsed_bat->batCacheid);
+ } else {
+ BBPunfix(parsed_bat->batCacheid);
+ }
+ }
+ if (block_bat)
+ BBPunfix(block_bat->batCacheid);
+ if (offsets_bat)
+ BBPunfix(offsets_bat->batCacheid);
+ return msg;
+}
+
+
+#include "copy_convert_num.h"
diff --git a/sql/backends/monet5/copy_convert_num.h
b/sql/backends/monet5/copy_convert_num.h
new file mode 100644
--- /dev/null
+++ b/sql/backends/monet5/copy_convert_num.h
@@ -0,0 +1,109 @@
+
+#ifndef INSIDE_COPY_CONVERT
+
+#include "monetdb_config.h"
+#include "gdk.h"
+#include "mal.h"
+#include "mal_exception.h"
+#include "mal_interpreter.h"
+
+#include "copy.h"
+
+#endif
+
+#define TPE int
+#define STRINGIFY(S) #S
+#define GDK_TYPIFY(S) TYPE_##S
+#define TMPL_TYPE int;
+
+struct decimal_parms {
+ int digits;
+ int scale;
+};
+
+
+
+static int
+parse_one_decimal_int(struct error_handling *errors, struct decimal_parms
*parms, int rel_row, const char *s)
+{
+ int digits = parms->digits;
+ int scale = parms->scale;
+ int integer_digits = digits - scale;
+ bool neg = false;
+ TPE res = 0;
+
+ while(isspace((unsigned char) *s))
+ s++;
+
+ if (*s == '-'){
+ neg = true;
+ s++;
+ } else if (*s == '+'){
+ s++;
+ }
+
+ for (int i = 0; *s && *s != '.' && ((res == 0 && *s == '0') || i <
integer_digits); s++) {
+ if (!isdigit((unsigned char) *s))
+ break;
+ res *= 10;
+ res += (*s - '0');
+ if (res)
+ i++;
+ }
+ if (*s == '.') {
+ s++;
+ while (*s && isdigit((unsigned char) *s) && scale > 0) {
+ res *= 10;
+ res += *s++ - '0';
+ scale--;
+ }
+ }
+ while(*s && isspace((unsigned char) *s))
+ s++;
+ while (scale > 0) {
+ res *= 10;
+ scale--;
+ }
+ if (*s) {
+ copy_report_error(errors, rel_row, "trailing garbage: %s", s);
+ res = int_nil;
+ }
+ if (neg)
+ res = -res;
+ return res;
+}
+
+
+
+static str
+parse_many_decimal_int(struct error_handling *errors, void *parms_, int count,
void *dest_, char *data, int *offsets)
+{
+ struct decimal_parms *parms = parms_;
+ int *dest = dest_;
+
+ for (int i = 0; i < count; i++) {
+ int offset = offsets[i];
+ if (is_int_nil(offset)) {
+ dest[i] = int_nil;
+ continue;
+ }
+ dest[i] = parse_one_decimal_int(errors, parms, i, data +
offset);
+ }
+
+ return MAL_SUCCEED;
+}
+
+
+str
+COPYparse_decimal_int(
+ bat *parsed_bat_id,
+ bat *block_bat_id, bat *offsets_bat_id,
+ int *digits, int *scale,
+ int *dummy)
+{
+ struct decimal_parms myparms = {
+ .digits = *digits,
+ .scale = *scale,
+ };
+ return parse_fixed_width_column(parsed_bat_id,
"copy.parse_decimal_int", *block_bat_id, *offsets_bat_id, TYPE_int,
parse_many_decimal_int, &myparms);
+}
diff --git a/sql/backends/monet5/rel_copy.c b/sql/backends/monet5/rel_copy.c
--- a/sql/backends/monet5/rel_copy.c
+++ b/sql/backends/monet5/rel_copy.c
@@ -304,6 +304,7 @@ rel2bin_copyparpipe(backend *be, sql_rel
q = pushArgument(mb, q, var_indices);
q = pushInt(mb, q, col->type.digits);
q = pushInt(mb, q, col->type.scale);
+ q = pushNil(mb, q, col->type.type->localtype);
break;
default:
q = newStmt(mb, "copy", "parse_generic");
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]