Changeset: 86ca45e0400f for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=86ca45e0400f
Modified Files:
        clients/R/MonetDB.R/R/dbi.R
        clients/R/MonetDB.R/R/dplyr.R
        monetdb5/extras/rapi/converters.c
        tools/embedded/embedded.c
        tools/embedded/embedded.h
        tools/embedded/rpackage/R/monetdb.R
        tools/embedded/rpackage/tests/testthat/test_dbi.R
        tools/embedded/rpackage/tests/testthat/test_lowlevel.R
Branch: embedded
Log Message:

Querying, not really converting SEXP. Needed for dplyr support


diffs (237 lines):

diff --git a/clients/R/MonetDB.R/R/dbi.R b/clients/R/MonetDB.R/R/dbi.R
--- a/clients/R/MonetDB.R/R/dbi.R
+++ b/clients/R/MonetDB.R/R/dbi.R
@@ -230,7 +230,7 @@ setMethod("dbReadTable", "MonetDBConnect
   name <- quoteIfNeeded(conn, name)
   if (!dbExistsTable(conn, name))
     stop(paste0("Unknown table: ", name));
-  dbGetQuery(conn, paste0("SELECT * FROM ", name))
+  dbGetQuery(conn, paste0("SELECT * FROM ", name), ...)
 })
 
 # This one does all the work in this class
@@ -301,7 +301,7 @@ setMethod("dbSendQuery", signature(conn=
 
 # This one does all the work in this class
 setMethod("dbSendQuery", signature(conn="MonetDBEmbeddedConnection", 
statement="character"),  
-          def=function(conn, statement, ..., list=NULL) {   
+          def=function(conn, statement, ..., list=NULL, notreally=F) {   
   if (!conn@connenv$open) {
     stop("This connection was closed.")
   }
@@ -312,7 +312,7 @@ setMethod("dbSendQuery", signature(conn=
   env <- NULL
   if (getOption("monetdb.debug.query", F)) message("QQ: '", statement, "'")
 
-  resp <- monetdb_embedded_query(statement)
+  resp <- monetdb_embedded_query(statement, notreally)
 
   env <- new.env(parent=emptyenv())
   if (resp$type == Q_TABLE) {
diff --git a/clients/R/MonetDB.R/R/dplyr.R b/clients/R/MonetDB.R/R/dplyr.R
--- a/clients/R/MonetDB.R/R/dplyr.R
+++ b/clients/R/MonetDB.R/R/dplyr.R
@@ -54,8 +54,7 @@ db_query_fields.MonetDBConnection <- fun
 }
 
 db_query_fields.MonetDBEmbeddedConnection <- function(con, sql, ...) {
-  # PREPARE does not work in embedded mode
-  names(dbGetQuery(con, dplyr::build_sql("SELECT * FROM ", sql, " WHERE 1=0")))
+  names(dbGetQuery(con, dplyr::build_sql("SELECT * FROM ", sql), notreally=T))
 }
 
 db_query_rows.MonetDBConnection <- function(con, sql, ...) {
@@ -63,14 +62,7 @@ db_query_rows.MonetDBConnection <- funct
 }
 
 db_query_rows.MonetDBEmbeddedConnection <- function(con, sql, ...) {
-  # TODO: is there a better way of doing this?
-  if (!grepl("^\\w*SELECT.*", as.character(sql), perl=T, ignore.case=T)) {
-    sql <- dplyr::build_sql("SELECT * FROM ", sql)
-  }
-  dbGetQuery(con, dplyr::build_sql("CREATE TEMPORARY TABLE dqrv AS ", sql, " 
WITH DATA"))
-  ct <- dbGetQuery(con, dplyr::build_sql("SELECT COUNT(*) AS ct FROM 
dqrv"))$ct[[1]]
-  dbGetQuery(con, dplyr::build_sql("DROP TABLE dqrv"))
-  return(ct)
+  attr(dbGetQuery(con, sql, notreally=T), "__rows")
 }
 
 db_insert_into.MonetDBConnection <- function(con, table, values, ...) {
diff --git a/monetdb5/extras/rapi/converters.c 
b/monetdb5/extras/rapi/converters.c
--- a/monetdb5/extras/rapi/converters.c
+++ b/monetdb5/extras/rapi/converters.c
@@ -1,31 +1,31 @@
 #include <Rdefines.h>
 #include "mal.h"
 
-#define BAT_TO_INTSXP(bat,tpe,retsxp)                                          
\
+#define BAT_TO_SXP(bat,tpe,retsxp,newfun,ptrfun,ctype,naval)\
        do {                                                                    
                                \
-               tpe v;  size_t j;                                               
                        \
-               retsxp = PROTECT(NEW_INTEGER(BATcount(bat)));           \
+               tpe v; size_t j;                                                
                        \
+               retsxp = PROTECT(newfun(BATcount(bat)));                    \
+               if (bat->T->nonil && !bat->T->nil) {                \
+                       for (j = 0; j < BATcount(bat); j++) {           \
+                               ptrfun(retsxp)[j] =                         \
+                               (ctype) ((tpe*) Tloc(bat, BUNfirst(bat)))[j];\
+                       }                                               \
+               } else {                                            \
                for (j = 0; j < BATcount(bat); j++) {                           
\
                        v = ((tpe*) Tloc(bat, BUNfirst(bat)))[j];               
\
                        if ( v == tpe##_nil)                                    
                \
-                               INTEGER_POINTER(retsxp)[j] =    NA_INTEGER; \
+                               ptrfun(retsxp)[j] = naval;                      
\
                        else                                                    
                                \
-                               INTEGER_POINTER(retsxp)[j] =    (int)v;         
\
-               }                                                               
                                        \
+                               ptrfun(retsxp)[j] = (ctype)v;               \
+               }}                                                              
                                        \
        } while (0)
 
+#define BAT_TO_INTSXP(bat,tpe,retsxp)                                          
\
+       BAT_TO_SXP(bat,tpe,retsxp,NEW_INTEGER,INTEGER_POINTER,int,NA_INTEGER)\
+
 #define BAT_TO_REALSXP(bat,tpe,retsxp)                                         
\
-       do {                                                                    
                                \
-               tpe v; size_t j;                                                
                        \
-               retsxp = PROTECT(NEW_NUMERIC(BATcount(bat)));           \
-               for (j = 0; j < BATcount(bat); j++) {                           
\
-                       v = ((tpe*) Tloc(bat, BUNfirst(bat)))[j];               
\
-                       if ( v == tpe##_nil)                                    
                \
-                               NUMERIC_POINTER(retsxp)[j] =    NA_REAL;        
\
-                       else                                                    
                                \
-                               NUMERIC_POINTER(retsxp)[j] =    (double)v;      
\
-               }                                                               
                                        \
-       } while (0)
+       BAT_TO_SXP(bat,tpe,retsxp,NEW_NUMERIC,NUMERIC_POINTER,double,NA_REAL)\
+
 
 #define SCALAR_TO_INTSXP(tpe,retsxp)                                   \
        do {                                                                    
                        \
@@ -102,14 +102,23 @@ static SEXP bat_to_sexp(BAT* b) {
                        BATiter li;
                        li = bat_iterator(b);
                        varvalue = PROTECT(NEW_STRING(BATcount(b)));
-                       BATloop(b, p, q) {
-                               const char *t = (const char *) BUNtail(li, p);
-                               if (ATOMcmp(TYPE_str, t, str_nil) == 0) {
-                                       SET_STRING_ELT(varvalue, j, NA_STRING);
-                               } else {
-                                       SET_STRING_ELT(varvalue, j, mkCharCE(t, 
CE_UTF8));
+
+                       if (b->T->nonil && !b->T->nil) {
+                               BATloop(b, p, q) {
+                                       SET_STRING_ELT(varvalue, j++, mkCharCE(
+                                               (const char *) BUNtail(li, p), 
CE_UTF8));
                                }
-                               j++;
+                       }
+                       else {
+                               BATloop(b, p, q) {
+                                       const char *t = (const char *) 
BUNtail(li, p);
+                                       if (ATOMcmp(TYPE_str, t, str_nil) == 0) 
{
+                                               SET_STRING_ELT(varvalue, j, 
NA_STRING);
+                                       } else {
+                                               SET_STRING_ELT(varvalue, j, 
mkCharCE(t, CE_UTF8));
+                                       }
+                                       j++;
+                               }
                        }
                }       break;
        }
diff --git a/tools/embedded/embedded.c b/tools/embedded/embedded.c
--- a/tools/embedded/embedded.c
+++ b/tools/embedded/embedded.c
@@ -221,7 +221,7 @@ SEXP monetdb_query_R(SEXP query, SEXP no
        char notreally = LOGICAL(notreallys)[0];
 
        if (err != NULL) { // there was an error
-               return mkCharCE(err, CE_UTF8);
+               return ScalarString(mkCharCE(err, CE_UTF8));
        }
        if (output && output->nr_cols > 0) {
                int i;
@@ -229,7 +229,7 @@ SEXP monetdb_query_R(SEXP query, SEXP no
                retlist = PROTECT(allocVector(VECSXP, output->nr_cols));
                names = PROTECT(NEW_STRING(output->nr_cols));
                SET_ATTR(retlist, install("__rows"),
-                               
Rf_ScalarReal(BATcount(BATdescriptor(output->cols[0].b))));
+                       
Rf_ScalarReal(BATcount(BATdescriptor(output->cols[0].b))));
                for (i = 0; i < output->nr_cols; i++) {
                        res_col col = output->cols[i];
                        BAT* b = BATdescriptor(col.b);
diff --git a/tools/embedded/embedded.h b/tools/embedded/embedded.h
--- a/tools/embedded/embedded.h
+++ b/tools/embedded/embedded.h
@@ -24,7 +24,7 @@ int monetdb_startup(char* dir, char sile
 char* monetdb_query(char* query, void** result);
 char* monetdb_append(const char* schema, const char* table, append_data *ad, 
int ncols);
 void monetdb_cleanup_result(void* output);
-SEXP monetdb_query_R(SEXP querysexp);
+SEXP monetdb_query_R(SEXP querysexp, SEXP notreally);
 SEXP monetdb_startup_R(SEXP dirsexp, SEXP silentsexp);
 SEXP monetdb_append_R(SEXP schemaname, SEXP tablename, SEXP tabledata);
 
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
@@ -24,7 +24,7 @@ monetdb_embedded_startup <- function(dir
        invisible(TRUE)
 }
 
-monetdb_embedded_query <- function(query, notreally) {
+monetdb_embedded_query <- function(query, notreally=F) {
        query <- as.character(query)
        if (length(query) != 1) {
                stop("Need a single query as parameter.")
@@ -47,7 +47,9 @@ monetdb_embedded_query <- function(query
        }
        if (is.list(res)) {
                resp$type <- 1 # Q_TABLE
-               resp$tuples <- as.data.frame(res, stringsAsFactors=F)
+               attr(res, "row.names") <- c(NA_integer_, length(res[[1]]))
+               class(res) <- "data.frame"
+               resp$tuples <- res
        }
        resp
 }
diff --git a/tools/embedded/rpackage/tests/testthat/test_dbi.R 
b/tools/embedded/rpackage/tests/testthat/test_dbi.R
--- a/tools/embedded/rpackage/tests/testthat/test_dbi.R
+++ b/tools/embedded/rpackage/tests/testthat/test_dbi.R
@@ -181,8 +181,8 @@ basicDf <- data.frame(
 
 test_that("round-trip leaves data.frame unchanged", {
        dbWriteTable(con, "t1", basicDf, row.names = FALSE)
-       expect_equal(dbGetQuery(con, "select * from t1"), basicDf)
-       expect_equal(dbReadTable(con, "t1"), basicDf)
+       expect_equivalent(dbGetQuery(con, "select * from t1"), basicDf)
+       expect_equivalent(dbReadTable(con, "t1"), basicDf)
        dbRemoveTable(con, "t1")
 })
 
@@ -190,7 +190,7 @@ test_that("NAs work in first row", {
        na_first <- basicDf[c(5, 1:4), ]
        rownames(na_first) <- NULL
        dbWriteTable(con, "t1", na_first, row.names = FALSE)
-       expect_equal(dbReadTable(con, "t1"), na_first)
+       expect_equivalent(dbReadTable(con, "t1"), na_first)
        dbRemoveTable(con, "t1")
 })
 
diff --git a/tools/embedded/rpackage/tests/testthat/test_lowlevel.R 
b/tools/embedded/rpackage/tests/testthat/test_lowlevel.R
--- a/tools/embedded/rpackage/tests/testthat/test_lowlevel.R
+++ b/tools/embedded/rpackage/tests/testthat/test_lowlevel.R
@@ -38,10 +38,10 @@ test_that("rollback works", {
        res <- monetdb_embedded_query("SELECT i FROM foo")
        expect_equal(res$tuples$i, 42)
        monetdb_embedded_query("ROLLBACK")
+       res <- monetdb_embedded_query("SELECT * FROM tables WHERE name='foo'")
+       expect_equal(nrow(res$tuples), 0)
        res <- monetdb_embedded_query("SELECT i FROM foo")
        expect_equal(res$type, "!")
-       res <- monetdb_embedded_query("SELECT * FROM tables WHERE name='foo'")
-       expect_equal(nrow(res$tuples), 0)
 })
 
 test_that("rollback with errors", {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to