Changeset: b81504bd7fab for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b81504bd7fab
Modified Files:
        tools/embedded/embedded.c
        tools/embedded/embedded.h
        tools/embedded/rpackage/NAMESPACE
        tools/embedded/rpackage/R/monetdb.R
Branch: embedded
Log Message:

append functionality first stab


diffs (234 lines):

diff --git a/tools/embedded/embedded.c b/tools/embedded/embedded.c
--- a/tools/embedded/embedded.c
+++ b/tools/embedded/embedded.c
@@ -136,6 +136,35 @@ char* monetdb_query(char* query, void** 
        return res;
 }
 
+char* monetdb_append(char* schema, char* table, append_data *data, int ncols) {
+       int i;
+       MalBlkRecord mb;
+       MalStack     stk;
+       InstrRecord  pci;
+       str res = MAL_SUCCEED;
+
+       assert(table != NULL && append_data != NULL && ncols > 0);
+       for (i = 0; i < 6; i++) {
+               pci.argv[i] = i;
+       }
+
+       stk.stk[2].val.sval = schema;
+       stk.stk[3].val.sval = table;
+
+       for (i=0; i <ncols; i++) {
+               append_data ad = data[i];
+               stk.stk[4].val.sval = ad.colname;
+               stk.stk[5].vtype = TYPE_bat;
+               stk.stk[5].val.bval = ad.batid;
+
+               res = mvc_append_wrap(&mal_clients[0], mb, stk, pci);
+               if (res != NULL) {
+                       break;
+               }
+       }
+       return res;
+}
+
 void monetdb_cleanup_result(void* output) {
        (*res_table_destroy_ptr)((res_table*) output);
 }
@@ -167,6 +196,33 @@ void monetdb_cleanup_result(void* output
        } while (0)
 
 
+#define SXP_TO_BAT(tpe,access_fun,na_check)                                    
                        \
+       do {                                                                    
                                                        \
+               tpe *p, prev = tpe##_nil;                                       
                                        \
+               b = BATnew(TYPE_void, TYPE_##tpe, cnt, TRANSIENT);              
                \
+               BATseqbase(b, 0); b->T->nil = 0; b->T->nonil = 1; b->tkey = 0;  
\
+               b->tsorted = 1; b->trevsorted = 1;                              
                                \
+               p = (tpe*) Tloc(b, BUNfirst(b));                                
                                \
+               for( j =0; j< (int) cnt; j++, p++){                             
                                \
+                       *p = (tpe) access_fun(ret_col)[j];                      
                                \
+                       if (na_check){ b->T->nil = 1;   b->T->nonil = 0;        
*p= tpe##_nil;} \
+                       if (j > 0){                                             
                                                        \
+                               if ( *p > prev && b->trevsorted){               
                                \
+                                       b->trevsorted = 0;                      
                                                \
+                                       if (*p != prev +1) b->tdense = 0;       
                                \
+                               } else                                          
                                                        \
+                                       if ( *p < prev && b->tsorted){          
                                \
+                                               b->tsorted = 0;                 
                                                \
+                                               b->tdense = 0;                  
                                                \
+                                       }                                       
                                                                \
+                       }                                                       
                                                                \
+                       prev = *p;                                              
                                                        \
+               }                                                               
                                                                \
+               BATsetcount(b,cnt);                                             
                                                \
+               BATsettrivprop(b);                                              
                                                \
+       } while (0)
+
+
 SEXP monetdb_query_R(SEXP query) {
        res_table* output = NULL;
        char* err = monetdb_query((char*)CHAR(STRING_ELT(query, 0)), 
(void**)&output);
@@ -247,3 +303,107 @@ SEXP monetdb_startup_R(SEXP dirsexp, SEX
        res = monetdb_startup((char*) dir, silent);
        return ScalarInteger(res);
 }
+
+str monetdb_get_columns(char* schema_name, char *table_name, int 
*column_count, char ***column_names, int **column_types) {
+       Client c = &mal_clients[0];
+       mvc *m;
+       sql_schema *s;
+       sql_table *t;
+       char *msg = MAL_SUCCEED;
+       int columns;
+       int i;
+
+       assert(column_count != NULL && column_names != NULL && column_types != 
NULL);
+
+       if ((msg = getSQLContext(c, NULL, &m, NULL)) != NULL)
+               return msg;
+
+       s = mvc_bind_schema(m, schema_name);
+       if (s == NULL)
+               msg = createException(MAL, "embedded", "Missing schema!");
+       t = mvc_bind_table(m, s, table_name);
+       if (t == NULL)
+               msg = createException(MAL, "embedded", "Could not find table 
%s", table_name);
+
+       columns = t->columns.set->cnt;
+       *column_count = columns;
+       *column_names = GDKzalloc(sizeof(char*) * columns);
+       *column_types = GDKzalloc(sizeof(int) * columns);
+
+       if (*column_names == NULL || *column_types == NULL) {
+               return MAL_MALLOC_FAIL;
+       }
+
+       for(i = 0; i < columns; i++) {
+               int acol = ((sql_column*)t->columns.set->h->data)[i].colnr;
+               *column_names[acol] = 
((sql_base*)t->columns.set->h->data)[i].name;
+               *column_types[acol] = 
((sql_column*)t->columns.set->h->data)[i].type.type->localtype;
+       }
+       return msg;
+}
+
+SEXP monetdb_append_R(SEXP schemasexp, SEXP namesexp, SEXP tabledatasexp) {
+       const char *schema = NULL, *name = NULL;
+       str msg;
+       int ncols, nrows, i, j;
+       BAT *b;
+       BUN cnt;
+       append_data *ad = NULL;
+       int t_column_count;
+       char** t_column_names = NULL;
+       int* t_column_types = NULL;
+
+       if (!IS_CHARACTER(schemasexp) || !IS_CHARACTER(namesexp)) {
+               return ScalarInteger(-1);
+       }
+       schema = CHAR(STRING_ELT(schemasexp, 0));
+       name = CHAR(STRING_ELT(namesexp, 0));
+
+       ncols = LENGTH(tabledatasexp);
+       nrows = LENGTH(VECTOR_ELT(tabledatasexp, 0));
+
+       msg = monetdb_get_columns(schema, name, &t_column_count, 
&t_column_names, &t_column_types);
+       if (msg != MAL_SUCCEED)
+               goto wrapup;
+
+       if (t_column_count != ncols) {
+               msg = GDKstrdup("Unequal number of columns"); // TODO: add 
counts here
+               goto wrapup;
+       }
+
+       ad = GDKmalloc(ncols * sizeof(append_data));
+
+       for (i = 0; i < ncols; i++) {
+               SEXP ret_col = VECTOR_ELT(tabledatasexp, i);
+               int bat_type = t_column_types[i];
+               cnt = (BUN) nrows;
+
+               // hand over the vector into a BAT
+               switch (bat_type) {
+               case TYPE_int: {
+                       if (!IS_INTEGER(ret_col)) {
+                               msg =
+                                       createException(MAL, "rapi.eval",
+                                                                       "wrong 
R column type for column %d, expected INTeger, got %s.",
+                                                                       i, 
rtypename(TYPEOF(ret_col)));
+                               goto wrapup;
+                       }
+                       SXP_TO_BAT(int, INTEGER_POINTER, *p==NA_INTEGER);
+                       break;
+               }
+               }
+               ad[i].colname = t_column_names[i];
+               ad[i].batid = b->batCacheid;
+       }
+
+       monetdb_append(schema, name, ad, ncols);
+       wrapup:
+               if (t_column_names != NULL) {
+                       GDKfree(t_column_names);
+               }
+               if (t_column_types != NULL) {
+                       GDKfree(t_column_types);
+               }
+               return ScalarString(mkCharCE(msg, CE_UTF8));
+}
+
diff --git a/tools/embedded/embedded.h b/tools/embedded/embedded.h
--- a/tools/embedded/embedded.h
+++ b/tools/embedded/embedded.h
@@ -15,10 +15,17 @@
 
 #include <Rdefines.h>
 
+typedef struct append_data {
+       char* colname;
+       ssize_t batid;
+} append_data;
+
 int monetdb_startup(char* dir, char silent);
 char* monetdb_query(char* query, void** result);
+char* monetdb_append(char* schema, char* table, *append_data, int ncols);
 void monetdb_cleanup_result(void* output);
 SEXP monetdb_query_R(SEXP querysexp);
 SEXP monetdb_startup_R(SEXP dirsexp, SEXP silentsexp);
+SEXP monetdb_append_R(SEXP schemaname, SEXP tablename, SEXP tabledata);
 
 #endif
diff --git a/tools/embedded/rpackage/NAMESPACE 
b/tools/embedded/rpackage/NAMESPACE
--- a/tools/embedded/rpackage/NAMESPACE
+++ b/tools/embedded/rpackage/NAMESPACE
@@ -1,3 +1,4 @@
 useDynLib(MonetDB)
 export(monetdb_embedded_startup)
 export(monetdb_embedded_query)
+export(monetdb_embedded_append)
diff --git a/tools/embedded/rpackage/R/monetdb.R 
b/tools/embedded/rpackage/R/monetdb.R
--- a/tools/embedded/rpackage/R/monetdb.R
+++ b/tools/embedded/rpackage/R/monetdb.R
@@ -47,3 +47,20 @@ monetdb_embedded_query <- function(query
        }
        resp
 }
+
+
+monetdb_embedded_append <- function(table, tdata, schema="sys") {
+       table <- as.character(table)
+       if (length(table) != 1) {
+               stop("Need a single table name as parameter.")
+       }
+       schema <- as.character(schema)
+       if (length(schema) != 1) {
+               stop("Need a single schema name as parameter.")
+       }
+       if (!is.data.frame(tdata)) {
+               stop("Need a data frame as tdata parameter.")
+       }
+
+       .Call("monetdb_append_R", schema, table, tdata)
+}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to