Changeset: 3dbc36f15c4b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/3dbc36f15c4b
Modified Files:
        sql/backends/monet5/sql.c
        sql/backends/monet5/sql.h
        sql/backends/monet5/sql_bincopyconvert.c
        sql/backends/monet5/sql_bincopyconvert.h
        sql/backends/monet5/sql_bincopyfrom.c
Branch: copyintobinary
Log Message:

Implement COPY INTO BINARY for the trivial types


diffs (truncated from 378 to 300 lines):

diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -3084,18 +3084,6 @@ bat2return(MalStkPtr stk, InstrPtr pci, 
 static const char fwftsep[2] = {STREAM_FWF_FIELD_SEP, '\0'};
 static const char fwfrsep[2] = {STREAM_FWF_RECORD_SEP, '\0'};
 
-static str
-mvc_export_bin_column_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci)
-{
-       (void)cntxt;
-       (void)mb;
-       (void)stk;
-       (void)pci;
-
-       throw(SQL, "sql.export_bin_column", SQLSTATE(42000) "not implemented");
-}
-
-
 /* str mvc_import_table_wrap(int *res, sql_table **t, unsigned char* *T, 
unsigned char* *R, unsigned char* *S, unsigned char* *N, str *fname, lng *sz, 
lng *offset, int *besteffort, str *fixed_width, int *onclient, int *escape); */
 str
 mvc_import_table_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
@@ -5201,8 +5189,8 @@ static mel_func sql_init_funcs[] = {
  pattern("sql", "exportChunk", mvc_export_chunk_wrap, true, "Export a chunk of 
the result set (in order) to stream s", args(1,3, 
arg("",void),arg("s",streams),arg("res_id",int))),
  pattern("sql", "exportChunk", mvc_export_chunk_wrap, true, "Export a chunk of 
the result set (in order) to stream s", args(1,5, 
arg("",void),arg("s",streams),arg("res_id",int),arg("offset",int),arg("nr",int))),
  pattern("sql", "exportOperation", mvc_export_operation_wrap, true, "Export 
result of schema/transaction queries", args(1,1, arg("",void))),
- pattern("sql", "export_bin_column", mvc_export_bin_column_wrap, true, "export 
column as binary", args(1, 5, arg("", lng), batargany("col", 1), 
arg("byteswap", bit), arg("filename", str), arg("onclient", int))),
- pattern("sql", "export_bin_column", mvc_export_bin_column_wrap, true, "export 
column as binary", args(1, 5, arg("", lng), argany("val", 1), arg("byteswap", 
bit), arg("filename", str), arg("onclient", int))),
+ pattern("sql", "export_bin_column", mvc_bin_export_column_wrap, true, "export 
column as binary", args(1, 5, arg("", lng), batargany("col", 1), 
arg("byteswap", bit), arg("filename", str), arg("onclient", int))),
+ pattern("sql", "export_bin_column", mvc_bin_export_column_wrap, true, "export 
column as binary", args(1, 5, arg("", lng), argany("val", 1), arg("byteswap", 
bit), arg("filename", str), arg("onclient", int))),
  pattern("sql", "affectedRows", mvc_affected_rows_wrap, true, "export the 
number of affected rows by the current query", args(1,3, 
arg("",int),arg("mvc",int),arg("nr",lng))),
  pattern("sql", "copy_from", mvc_import_table_wrap, true, "Import a table from 
bstream s with the \ngiven tuple and seperators (sep/rsep)", args(1,13, 
batvarargany("",0),arg("t",ptr),arg("sep",str),arg("rsep",str),arg("ssep",str),arg("ns",str),arg("fname",str),arg("nr",lng),arg("offset",lng),arg("best",int),arg("fwf",str),arg("onclient",int),arg("escape",int))),
  //we use bat.single now
diff --git a/sql/backends/monet5/sql.h b/sql/backends/monet5/sql.h
--- a/sql/backends/monet5/sql.h
+++ b/sql/backends/monet5/sql.h
@@ -93,6 +93,7 @@ extern str mvc_export_row_wrap(Client cn
 extern str mvc_import_table_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, 
InstrPtr pci);
 extern str mvc_bin_import_table_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr 
stk, InstrPtr pci);
 extern str mvc_bin_import_column_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr 
stk, InstrPtr pci);
+extern str mvc_bin_export_column_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr 
stk, InstrPtr pci);
 extern str setVariable(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
 extern str getVariable(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
 extern str sql_variables(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
diff --git a/sql/backends/monet5/sql_bincopyconvert.c 
b/sql/backends/monet5/sql_bincopyconvert.c
--- a/sql/backends/monet5/sql_bincopyconvert.c
+++ b/sql/backends/monet5/sql_bincopyconvert.c
@@ -233,6 +233,7 @@ append_text(BAT *bat, char *start)
 static str
 load_zero_terminated_text(BAT *bat, stream *s, int *eof_reached)
 {
+       const char *mal_operator = "sql.importColumn";
        str msg = MAL_SUCCEED;
        bstream *bs = NULL;
 
@@ -287,7 +288,7 @@ end:
 
 
 
-static struct type_rec type_recs[] = {
+static struct type_record_t type_recs[] = {
        // no conversion, no byteswapping
        { "bte", "bte", .decoder=NULL, },
        { "uuid", "uuid", .decoder=NULL, },
@@ -313,11 +314,11 @@ static struct type_rec type_recs[] = {
 };
 
 
-struct type_rec*
-find_type_rec(str name)
+type_record_t*
+find_type_rec(const char *name)
 {
-       struct type_rec *end = (struct type_rec*)((char *)type_recs + 
sizeof(type_recs));
-       for (struct type_rec *t = &type_recs[0]; t < end; t++)
+       struct type_record_t *end = (struct type_record_t*)((char *)type_recs + 
sizeof(type_recs));
+       for (struct type_record_t *t = &type_recs[0]; t < end; t++)
                if (strcmp(t->method, name) == 0)
                        return t;
        return NULL;
diff --git a/sql/backends/monet5/sql_bincopyconvert.h 
b/sql/backends/monet5/sql_bincopyconvert.h
--- a/sql/backends/monet5/sql_bincopyconvert.h
+++ b/sql/backends/monet5/sql_bincopyconvert.h
@@ -38,23 +38,30 @@
 typedef str (*bincopy_decoder_t)(void *dst,void *src, size_t count, bool 
byteswap);
 typedef str (*bincopy_loader_t)(BAT *bat, stream *s, int *eof_reached);
 
-struct type_rec {
+typedef str (*bincopy_encoder_t)(void *dst, void *src, size_t count, bool 
byteswap);
+typedef str (*bincopy_dumper_t)(BAT *bat, stream *s);
+
+struct type_record_t {
        char *method;
        char *gdk_type;
        size_t record_size;
        bool trivial_if_no_byteswap;
+
        bincopy_decoder_t decoder;
        bincopy_loader_t loader;
-};
 
-extern struct type_rec *find_type_rec(str name);
+       bincopy_encoder_t encoder;
+       bincopy_dumper_t dumper;
+};
+typedef const struct type_record_t type_record_t;
+
+extern type_record_t *find_type_rec(const char *name);
 
 
 #define bailout(...) do { \
-               msg = createException(MAL, "sql.importColumn", SQLSTATE(42000) 
__VA_ARGS__); \
+               msg = createException(MAL, mal_operator, SQLSTATE(42000) 
__VA_ARGS__); \
                goto end; \
        } while (0)
 
 
-
 #endif
diff --git a/sql/backends/monet5/sql_bincopyfrom.c 
b/sql/backends/monet5/sql_bincopyfrom.c
--- a/sql/backends/monet5/sql_bincopyfrom.c
+++ b/sql/backends/monet5/sql_bincopyfrom.c
@@ -12,6 +12,7 @@
 
 #include "monetdb_config.h"
 #include "mapi_prompt.h"
+#include "gdk.h"
 #include "sql.h"
 #include "mal_backend.h"
 #include "mal_interpreter.h"
@@ -23,6 +24,7 @@
 static str
 load_trivial(BAT *bat, stream *s, BUN rows_estimate, int *eof_seen)
 {
+       const char *mal_operator = "sql.importColumn";
        str msg = MAL_SUCCEED;
        int tt = BATttype(bat);
        const size_t asz = (size_t) ATOMsize(tt);
@@ -94,6 +96,7 @@ end:
 static str
 load_fixed_width(BAT *bat, stream *s, bool byteswap, bincopy_decoder_t 
convert, size_t record_size, int *eof_reached)
 {
+       const char *mal_operator = "sql.importColumn";
        str msg = MAL_SUCCEED;
        bstream *bs = NULL;
 
@@ -158,10 +161,11 @@ end:
 
 
 static str
-load_column(struct type_rec *rec, const char *name, BAT *bat, stream *s, bool 
byteswap, BUN rows_estimate, int *eof_reached)
+load_column(type_record_t *rec, const char *name, BAT *bat, stream *s, bool 
byteswap, BUN rows_estimate, int *eof_reached)
 {
+       const char *mal_operator = "sql.importColumn";
+       BUN orig_count, new_count;
        str msg = MAL_SUCCEED;
-       BUN orig_count, new_count;
        BUN rows_added;
 
        orig_count = BATcount(bat);
@@ -199,16 +203,17 @@ load_column(struct type_rec *rec, const 
 /* Import a single file into a new BAT.
  */
 static str
-importColumn(backend *be, bat *ret, BUN *retcnt, str method, bool byteswap, 
str path, int onclient,  BUN nrows)
+import_column(backend *be, bat *ret, BUN *retcnt, str method, bool byteswap, 
str path, int onclient,  BUN nrows)
 {
        // In this function we create the BAT and open the file, and tidy
        // up when things go wrong. The actual work happens in load_column().
 
+       const str mal_operator = "sql.importColumn";
+
        // These are managed by the end: block.
        str msg = MAL_SUCCEED;
        int gdk_type;
        BAT *bat = NULL;
-       stream *stream_to_close = NULL;
        int eof_reached = -1; // 1 = read to the end; 0 = stopped reading 
early; -1 = unset, a bug.
 
        // This one is not managed by the end: block
@@ -219,7 +224,7 @@ importColumn(backend *be, bat *ret, BUN 
        *retcnt = 0;
 
        // Figure out what kind of data we have
-       struct type_rec *rec = find_type_rec(method);
+       type_record_t *rec = find_type_rec(method);
        if (rec == NULL)
                bailout("COPY BINARY FROM not implemented for '%s'", method);
 
@@ -233,13 +238,12 @@ importColumn(backend *be, bat *ret, BUN 
 
        // Open the input stream
        if (onclient) {
-               s = stream_to_close = mapi_request_upload(path, true, 
be->mvc->scanner.rs, be->mvc->scanner.ws);
+               s = mapi_request_upload(path, true, be->mvc->scanner.rs, 
be->mvc->scanner.ws);
        } else {
-               s = stream_to_close = open_rstream(path);
+               s = open_rstream(path);
        }
        if (!s) {
-               msg = mnstr_error(NULL);
-               goto end;
+               bailout("%s", mnstr_peek_error(NULL));
        }
 
        // Do the work
@@ -253,8 +257,8 @@ importColumn(backend *be, bat *ret, BUN 
 
        // Fall through into the end block which will clean things up
 end:
-       if (stream_to_close)
-               close_stream(stream_to_close);
+       if (s)
+               close_stream(s);
 
        // Manage the return values and `bat`.
        if (msg == MAL_SUCCEED) {
@@ -294,7 +298,159 @@ mvc_bin_import_column_wrap(Client cntxt,
 
        backend *be = cntxt->sqlcontext;
 
-       return importColumn(be, ret, retcnt, method, byteswap, path, onclient, 
nrows);
+       return import_column(be, ret, retcnt, method, byteswap, path, onclient, 
nrows);
+}
+
+
+
+
+
+static str
+dump_trivial(BAT *b, stream *s)
+{
+       const char *mal_operator = "sql.export_bin_column";
+       str msg = MAL_SUCCEED;
+
+       int tpe = BATttype(b);
+       assert(!ATOMvarsized(tpe));
+
+       char *start = Tloc(b, 0);
+       char *end = Tloc(b, BATcount(b));
+
+       char *p = start;
+       while (p < end) {
+               ssize_t nwritten = mnstr_write(s, p, 1, end - p);
+               if (nwritten < 0)
+                       bailout("%s", mnstr_peek_error(s));
+               if (nwritten == 0)
+                       bailout("Unexpected EOF on %s", mnstr_name(s));
+               p += nwritten;
+       }
+
+end:
+       return msg;
+}
+
+static str
+dump_fixed_width(BAT *b, stream *s, bool byteswap, bincopy_encoder_t encoder, 
size_t record_size)
+{
+       const char *mal_operator = "sql.export_bin_column";
+       (void)b;
+       (void)s;
+       (void)byteswap;
+       (void)encoder;
+       (void)record_size;
+       throw(SQL, mal_operator, "dump_fixed_width not implemented");
+}
+
+static str
+dump_column(const struct type_record_t *rec, BAT *b, bool byteswap, stream *s)
+{
+       str msg = MAL_SUCCEED;
+
+       // cannot have loader AND converter
+       assert(rec->decoder == NULL || rec->loader == NULL);
+
+       // loaders cannot be trivial
+       assert( rec->loader == NULL || !rec->trivial_if_no_byteswap);
+
+       // Temporary measure while not all dumpers have been implemented
+       assert(rec->dumper || rec->encoder || rec->trivial_if_no_byteswap || 
BATttype(b) == TYPE_bit);
+
+       if (rec->dumper) {
+               msg = rec->dumper(b, s);
+       } else if (rec->encoder == NULL || (rec->trivial_if_no_byteswap && 
!byteswap)) {
+               msg = dump_trivial(b, s);
+       } else {
+               msg = dump_fixed_width(b, s, byteswap, rec->encoder, 
rec->record_size);
+       }
+
+       return msg;
+}
+
+
+static str
+export_column(backend *be, BAT *b, bool byteswap, str filename, bool onclient)
+{
+       const char *mal_operator = "sql.export_bin_column";
+       str msg = MAL_SUCCEED;
+       stream *s = NULL;
+
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to