Changeset: d2b933f5fa50 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/d2b933f5fa50
Modified Files:
        sql/backends/monet5/copy.c
        sql/backends/monet5/copy.h
        sql/backends/monet5/copy_convert.c
        sql/backends/monet5/copy_convert_num.h
        sql/backends/monet5/rel_copy.c
Branch: copyparpipe
Log Message:

Add specialized integer parsing


diffs (258 lines):

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
@@ -968,6 +968,30 @@ static mel_func copy_init_funcs[] = {
         batarg("block", bte), batarg("offsets", int), arg("digits", int), 
arg("scale", int), arg("type", hge)
  )),
 #endif
+
+ command("copy", "parse_integer", COPYparse_integer_bte, false, "Parse as an 
integer", args(1, 4,
+        batarg("", bte),
+        batarg("block", bte), batarg("offsets", int), arg("type", bte)
+ )),
+ command("copy", "parse_integer", COPYparse_integer_sht, false, "Parse as an 
integer", args(1, 4,
+        batarg("", sht),
+        batarg("block", bte), batarg("offsets", int), arg("type", sht)
+ )),
+ command("copy", "parse_integer", COPYparse_integer_int, false, "Parse as an 
integer", args(1, 4,
+        batarg("", int),
+        batarg("block", bte), batarg("offsets", int), arg("type", int)
+ )),
+ command("copy", "parse_integer", COPYparse_integer_lng, false, "Parse as an 
integer", args(1, 4,
+        batarg("", lng),
+        batarg("block", bte), batarg("offsets", int), arg("type", lng)
+ )),
+ #ifdef HAVE_HGE
+ command("copy", "parse_integer", COPYparse_integer_hge, false, "Parse as an 
integer", args(1, 4,
+        batarg("", hge),
+        batarg("block", bte), batarg("offsets", int), arg("type", hge)
+ )),
+#endif
+
  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
@@ -33,6 +33,13 @@ str parse_fixed_width_column(bat *ret, c
 
 
 extern str COPYparse_generic(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
+extern str COPYparse_integer_bte(bat *parsed_bat_id, bat *block_bat_id, bat 
*offsets_bat_id, int *dummy);
+extern str COPYparse_integer_sht(bat *parsed_bat_id, bat *block_bat_id, bat 
*offsets_bat_id, int *dummy);
+extern str COPYparse_integer_int(bat *parsed_bat_id, bat *block_bat_id, bat 
*offsets_bat_id, int *dummy);
+extern str COPYparse_integer_lng(bat *parsed_bat_id, bat *block_bat_id, bat 
*offsets_bat_id, int *dummy);
+#ifdef HAVE_HGE
+extern str COPYparse_integer_hge(bat *parsed_bat_id, bat *block_bat_id, bat 
*offsets_bat_id, int *dummy);
+#endif
 extern str COPYparse_decimal_bte(bat *parsed_bat_id, bat *block_bat_id, bat 
*offsets_bat_id, int *digits_p, int *scale_p, int *dummy);
 extern str COPYparse_decimal_sht(bat *parsed_bat_id, bat *block_bat_id, bat 
*offsets_bat_id, int *digits_p, int *scale_p, int *dummy);
 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);
@@ -48,4 +55,15 @@ struct decimal_parms {
 };
 
 
+#ifdef __GNUC__
+/* __builtin_expect returns its first argument; it is expected to be
+ * equal to the second argument */
+#define unlikely(expr) __builtin_expect((expr) != 0, 0)
+#define likely(expr)   __builtin_expect((expr) != 0, 1)
+#else
+#define unlikely(expr) (expr)
+#define likely(expr)   (expr)
+#endif
+
+
 #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
@@ -132,23 +132,33 @@ end:
 }
 
 #define TMPL_TYPE bte
+#define TMPL_NIL bte_nil
+#define TMPL_MAX GDK_bte_max
 #define TMPL_SUFFIXED(s) s##_bte
 #include "copy_convert_num.h"
 
 #define TMPL_TYPE sht
+#define TMPL_NIL sht_nil
+#define TMPL_MAX GDK_sht_max
 #define TMPL_SUFFIXED(s) s##_sht
 #include "copy_convert_num.h"
 
 #define TMPL_TYPE int
+#define TMPL_NIL int_nil
+#define TMPL_MAX GDK_int_max
 #define TMPL_SUFFIXED(s) s##_int
 #include "copy_convert_num.h"
 
 #define TMPL_TYPE lng
+#define TMPL_NIL lng_nil
+#define TMPL_MAX GDK_lng_max
 #define TMPL_SUFFIXED(s) s##_lng
 #include "copy_convert_num.h"
 
 #ifdef HAVE_HGE
 #define TMPL_TYPE hge
+#define TMPL_NIL hge_nil
+#define TMPL_MAX GDK_hge_max
 #define TMPL_SUFFIXED(s) s##_hge
 #include "copy_convert_num.h"
 #endif
diff --git a/sql/backends/monet5/copy_convert_num.h 
b/sql/backends/monet5/copy_convert_num.h
--- a/sql/backends/monet5/copy_convert_num.h
+++ b/sql/backends/monet5/copy_convert_num.h
@@ -1,14 +1,64 @@
 
 
-#if !defined(TMPL_TYPE) || !defined(TMPL_SUFFIXED)
+#if !defined(TMPL_TYPE) || !defined(TMPL_SUFFIXED) || !defined TMPL_NIL || 
!defined(TMPL_MAX)
 #error "This file is a template, it cannot be included standalone"
 #endif
 
 
+static TMPL_TYPE
+TMPL_SUFFIXED(parse_one_integer) (struct error_handling *errors, int rel_row, 
const char *value)
+{
+       bool pos = true;
+       TMPL_TYPE acc = 0;
+       const char *s = value;
+
+       while(isspace((unsigned char) *s))
+               s++;
+
+       if (*s == '-') {
+               pos = false;
+               s++;
+       } else if (*s == '+') {
+               s++;
+       }
+
+       while (isdigit((unsigned char) *s)) {
+               // int is safe because of promotion rules
+               int digit = *s - '0';
+               if (unlikely(acc >= (TMPL_MAX / 10))) {
+                       copy_report_error(errors, rel_row, "overflow: %s", 
value);
+                       return TMPL_NIL;
+               }
+               TMPL_TYPE new_acc = 10 * acc + digit;
+               acc = new_acc;
+               s++;
+       }
+
+       if (*s == '.') {
+               s++;
+               while (*s == '0')
+                       s++;
+       }
+
+       while (isspace((unsigned char) *s))
+               s++;
+
+       if (*s != '\0') {
+               copy_report_error(errors, rel_row, "trailing garbage: %s", s);
+               acc = TMPL_NIL;
+       }
+
+       if (!pos)
+               acc = -acc;
+
+       return acc;
+}
+
 
 static TMPL_TYPE
-TMPL_SUFFIXED(parse_one_decimal) (struct error_handling *errors, struct 
decimal_parms *parms, int rel_row, const char *s)
+TMPL_SUFFIXED(parse_one_decimal) (struct error_handling *errors, struct 
decimal_parms *parms, int rel_row, const char *value)
 {
+       const char *s = value;
        int digits = parms->digits;
        int scale = parms->scale;
        int integer_digits = digits - scale;
@@ -49,7 +99,7 @@ TMPL_SUFFIXED(parse_one_decimal) (struct
        }
        if (*s) {
                copy_report_error(errors, rel_row, "trailing garbage: %s", s);
-               res = int_nil;
+               res = TMPL_NIL;
        }
        if (neg)
                res = -res;
@@ -59,7 +109,7 @@ TMPL_SUFFIXED(parse_one_decimal) (struct
 
 
 static str
-TMPL_SUFFIXED(parse_many_decimal) (struct error_handling *errors, void 
*parms_, int count, void *dest_, char *data, int *offsets)
+TMPL_SUFFIXED(parse_many_decimals) (struct error_handling *errors, void 
*parms_, int count, void *dest_, char *data, int *offsets)
 {
        struct decimal_parms *parms = parms_;
        TMPL_TYPE *dest = dest_;
@@ -76,6 +126,24 @@ TMPL_SUFFIXED(parse_many_decimal) (struc
        return MAL_SUCCEED;
 }
 
+static str
+TMPL_SUFFIXED(parse_many_integers) (struct error_handling *errors, void 
*parms, int count, void *dest_, char *data, int *offsets)
+{
+       (void)parms;
+       TMPL_TYPE *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] = TMPL_SUFFIXED(parse_one_integer)(errors, i, data + 
offset);
+       }
+
+       return MAL_SUCCEED;
+}
+
 
 str
 TMPL_SUFFIXED(COPYparse_decimal) (
@@ -91,9 +159,23 @@ TMPL_SUFFIXED(COPYparse_decimal) (
        return parse_fixed_width_column(
                parsed_bat_id, "copy.parse_decimal",
                *block_bat_id, *offsets_bat_id,
-               TMPL_SUFFIXED(TYPE), TMPL_SUFFIXED(parse_many_decimal), 
&myparms);
+               TMPL_SUFFIXED(TYPE), TMPL_SUFFIXED(parse_many_decimals), 
&myparms);
+}
+
+str
+TMPL_SUFFIXED(COPYparse_integer) (
+       bat *parsed_bat_id,
+       bat *block_bat_id, bat *offsets_bat_id,
+       int *dummy)
+{
+       return parse_fixed_width_column(
+               parsed_bat_id, "copy.parse_integer",
+               *block_bat_id, *offsets_bat_id,
+               TMPL_SUFFIXED(TYPE), TMPL_SUFFIXED(parse_many_integers), NULL);
 }
 
 
 #undef TMPL_TYPE
+#undef TMPL_NIL
+#undef TMPL_MAX
 #undef TMPL_SUFFIXED
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
@@ -298,6 +298,12 @@ rel2bin_copyparpipe(backend *be, sql_rel
                const char *column_name = col->base.name;
 
                switch (type->eclass) {
+                       case EC_NUM:
+                               q = newStmt(mb, "copy", "parse_integer");
+                               q = pushArgument(mb, q, loop_vars.our_block);
+                               q = pushArgument(mb, q, var_indices);
+                               q = pushNil(mb, q, col->type.type->localtype);
+                               break;
                        case EC_DEC:
                                q = newStmt(mb, "copy", "parse_decimal");
                                q = pushArgument(mb, q, loop_vars.our_block);
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to