Changeset: 34e8de7aaaff for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=34e8de7aaaff
Added Files:
        clients/R/MonetDB.R/R/dbapply.R
        clients/R/MonetDB.R/man/dbApply.Rd
        clients/R/Tests/dbapply.R
        clients/R/Tests/dbapply.reqtests
        clients/R/Tests/dbapply.stable.err
        clients/R/Tests/dbapply.stable.out
        sql/test/BugTracker-2015/Tests/epoch_now.Bug-3740.sql
        sql/test/BugTracker-2015/Tests/epoch_now.Bug-3740.stable.err
        sql/test/BugTracker-2015/Tests/epoch_now.Bug-3740.stable.out
        sql/test/BugTracker-2015/Tests/mergejoin_NULL.Bug-3747.sql
        sql/test/BugTracker-2015/Tests/mergejoin_NULL.Bug-3747.stable.err
        sql/test/BugTracker-2015/Tests/mergejoin_NULL.Bug-3747.stable.out
        sql/test/BugTracker-2015/Tests/null_is_null.Bug-3739.sql
        sql/test/BugTracker-2015/Tests/null_is_null.Bug-3739.stable.err
        sql/test/BugTracker-2015/Tests/null_is_null.Bug-3739.stable.out
        sql/test/BugTracker-2015/Tests/savepoint.Bug-3738-1.sql
        sql/test/BugTracker-2015/Tests/savepoint.Bug-3738-1.stable.err
        sql/test/BugTracker-2015/Tests/savepoint.Bug-3738-1.stable.out
        sql/test/BugTracker-2015/Tests/savepoint.Bug-3738-2.sql
        sql/test/BugTracker-2015/Tests/savepoint.Bug-3738-2.stable.err
        sql/test/BugTracker-2015/Tests/savepoint.Bug-3738-2.stable.out
Modified Files:
        clients/R/MonetDB.R/DESCRIPTION
        clients/R/MonetDB.R/NAMESPACE
        clients/R/MonetDB.R/NEWS
        clients/R/MonetDB.R/R/control.R
        clients/R/MonetDB.R/R/dbi.R
        clients/R/MonetDB.R/R/dplyr.R
        clients/R/Tests/All
        clients/R/Tests/dbi.R
        clients/R/Tests/dbi.stable.err
        clients/R/Tests/dbi.stable.out
        clients/R/Tests/dplyr.R
        clients/R/Tests/dplyr.stable.out
        clients/Tests/SQL-dump.stable.out
        clients/Tests/SQL-dump.stable.out.int128
        clients/Tests/exports.stable.out
        clients/nodejs/monetdb/mapiclient.js
        clients/nodejs/monetdb/package.json
        clients/odbc/driver/SQLTables.c
        gdk/gdk_bbp.c
        gdk/gdk_join.c
        gdk/gdk_search.c
        gdk/gdk_select.c
        geom/monetdb5/geom.c
        java/build.xml
        java/src/nl/cwi/monetdb/jdbc/MonetDatabaseMetaData.java
        monetdb5/extras/rapi/Tests/rapi01.stable.err
        monetdb5/extras/rapi/rapi.c
        monetdb5/mal/Tests/recycle00.stable.out
        monetdb5/mal/Tests/tst661.stable.out
        monetdb5/mal/Tests/tst662.stable.out
        monetdb5/mal/Tests/tst903.stable.out
        monetdb5/mal/mal_builder.c
        monetdb5/mal/mal_function.c
        monetdb5/mal/mal_instruction.c
        monetdb5/modules/kernel/algebra.c
        monetdb5/modules/mal/Tests/partition.stable.out
        monetdb5/modules/mal/Tests/remote03.stable.out.int128
        monetdb5/modules/mal/Tests/remote04.stable.out
        monetdb5/optimizer/Tests/CMexample.stable.out
        monetdb5/optimizer/Tests/CXexample.stable.out
        monetdb5/optimizer/Tests/DCexample.stable.out
        monetdb5/optimizer/Tests/DCexample2.stable.out
        monetdb5/optimizer/Tests/FTexample.stable.out
        monetdb5/optimizer/Tests/GCexample01.stable.out
        monetdb5/optimizer/Tests/JPexample.stable.out
        monetdb5/optimizer/Tests/Mexample.stable.out
        monetdb5/optimizer/Tests/cst00.stable.out
        monetdb5/optimizer/Tests/cst01.stable.out
        monetdb5/optimizer/Tests/cst02.stable.out
        monetdb5/optimizer/Tests/dataflow.stable.out
        monetdb5/optimizer/Tests/dataflow3.stable.out
        monetdb5/optimizer/Tests/garbage.stable.out
        monetdb5/optimizer/Tests/inline00.stable.out
        monetdb5/optimizer/Tests/inline01.stable.out
        monetdb5/optimizer/Tests/inline02.stable.out
        monetdb5/optimizer/Tests/inline03.stable.out
        monetdb5/optimizer/Tests/inline04.stable.out
        monetdb5/optimizer/Tests/inline05.stable.out
        monetdb5/optimizer/Tests/inline06.stable.out
        monetdb5/optimizer/Tests/inline07.stable.out
        monetdb5/optimizer/Tests/inline08.stable.out
        monetdb5/optimizer/Tests/inline09.stable.out
        monetdb5/optimizer/Tests/inline10.stable.out
        monetdb5/optimizer/Tests/inlineCst.stable.out
        monetdb5/optimizer/Tests/inlineIfthen.stable.out
        monetdb5/optimizer/Tests/manifold2.stable.out
        monetdb5/optimizer/Tests/remap.stable.out
        monetdb5/optimizer/Tests/tst4005.stable.out
        monetdb5/optimizer/Tests/tst4600.stable.out
        monetdb5/optimizer/Tests/tst4601.stable.out
        monetdb5/optimizer/Tests/tst4630.stable.out
        monetdb5/scheduler/Tests/sched00.stable.out
        monetdb5/tests/gdkTests/Tests/selecttst.stable.out
        sql/backends/monet5/Tests/optimizers.stable.err
        sql/backends/monet5/Tests/rapi09.stable.err
        sql/backends/monet5/UDF/Tests/udf-reverse.stable.out
        sql/backends/monet5/generator/generator.c
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_gencode.c
        sql/backends/monet5/sql_upgrades.c
        sql/benchmarks/ssbm/Tests/01-explain.stable.out
        sql/benchmarks/ssbm/Tests/01-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/02-explain.stable.out
        sql/benchmarks/ssbm/Tests/02-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/03-explain.stable.out
        sql/benchmarks/ssbm/Tests/03-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/04-explain.stable.out
        sql/benchmarks/ssbm/Tests/04-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/05-explain.stable.out
        sql/benchmarks/ssbm/Tests/05-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/06-explain.stable.out
        sql/benchmarks/ssbm/Tests/06-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/07-explain.stable.out
        sql/benchmarks/ssbm/Tests/07-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/08-explain.stable.out
        sql/benchmarks/ssbm/Tests/08-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/09-explain.stable.out
        sql/benchmarks/ssbm/Tests/09-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/10-explain.stable.out
        sql/benchmarks/ssbm/Tests/10-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/11-explain.stable.out
        sql/benchmarks/ssbm/Tests/11-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/12-explain.stable.out
        sql/benchmarks/ssbm/Tests/12-explain.stable.out.int128
        sql/benchmarks/ssbm/Tests/13-explain.stable.out
        sql/benchmarks/ssbm/Tests/13-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/01-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/02-explain.stable.out
        sql/benchmarks/tpch/Tests/03-explain.stable.out
        sql/benchmarks/tpch/Tests/03-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/04-explain.stable.out
        sql/benchmarks/tpch/Tests/05-explain.stable.out
        sql/benchmarks/tpch/Tests/05-explain.stable.out.32bit
        sql/benchmarks/tpch/Tests/05-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/06-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/07-explain.stable.out
        sql/benchmarks/tpch/Tests/07-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/08-explain.stable.out
        sql/benchmarks/tpch/Tests/08-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/09-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/10-explain.stable.out
        sql/benchmarks/tpch/Tests/10-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/11-explain.stable.out
        sql/benchmarks/tpch/Tests/11-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/12-explain.stable.out
        sql/benchmarks/tpch/Tests/12-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/13-explain.stable.out
        sql/benchmarks/tpch/Tests/13-explain.stable.out.32bit
        sql/benchmarks/tpch/Tests/14-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/15-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/16-explain.stable.out
        sql/benchmarks/tpch/Tests/16-explain.stable.out.32bit
        sql/benchmarks/tpch/Tests/17-explain.stable.out
        sql/benchmarks/tpch/Tests/17-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/18-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/19-explain.stable.out
        sql/benchmarks/tpch/Tests/19-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/20-explain.stable.out
        sql/benchmarks/tpch/Tests/20-explain.stable.out.32bit
        sql/benchmarks/tpch/Tests/20-explain.stable.out.int128
        sql/benchmarks/tpch/Tests/21-explain.stable.out
        sql/benchmarks/tpch/Tests/21-explain.stable.out.32bit
        sql/benchmarks/tpch/Tests/22-explain.stable.out
        sql/benchmarks/tpch/Tests/22-explain.stable.out.32bit
        sql/benchmarks/tpch/Tests/22-explain.stable.out.int128
        sql/jdbc/tests/Tests/Test_Dobjects.stable.out
        sql/scripts/17_temporal.sql
        sql/server/rel_optimizer.c
        sql/server/rel_select.c
        sql/server/sql_mvc.c
        sql/storage/bat/bat_storage.c
        sql/storage/bat/bat_table.c
        sql/storage/bat/bat_utils.c
        sql/storage/store.c
        sql/test/BugDay_2005-10-06_2.9.3/Tests/max_min_sum_null.SF-1123132.sql
        
sql/test/BugDay_2005-11-09_2.8/Tests/ORDER_BY_evaluation_error.SF-1023658.stable.out
        
sql/test/BugDay_2005-12-19_2.9.3/Tests/weird_reponse_on_limit.SF-1314643.stable.out
        sql/test/BugTracker-2009/Tests/explain_gives_crash.SF-2741829.stable.out
        sql/test/BugTracker-2009/Tests/join_topn.SF-2654133.stable.out
        
sql/test/BugTracker-2010/Tests/LIMIT_OFFSET_big-endian.Bug-2622.stable.out
        
sql/test/BugTracker-2010/Tests/offset_limited_32bit.SF-2950579.stable.out
        
sql/test/BugTracker-2010/Tests/offset_limited_32bit.SF-2950579.stable.out.oid32
        sql/test/BugTracker-2011/Tests/crash_on_alias.Bug-2798.stable.out.int128
        sql/test/BugTracker-2011/Tests/func_iter_vs_bulk.Bug-2826.stable.out
        sql/test/BugTracker-2011/Tests/sqltables.Bug-2921.sql
        sql/test/BugTracker-2011/Tests/sqltables.Bug-2921.stable.out
        
sql/test/BugTracker-2012/Tests/rewrite_like_into_likesubselect.Bug-3179.stable.out
        sql/test/BugTracker-2013/Tests/between.Bug-3259.stable.out.int128
        sql/test/BugTracker-2013/Tests/swapped_likejoin.Bug-3375.stable.out
        sql/test/BugTracker-2014/Tests/nil_2dec_lng.Bug-3592.stable.out
        sql/test/BugTracker-2014/Tests/too_general_errmsg.Bug-3605.stable.err
        sql/test/BugTracker-2015/Tests/All
        sql/test/BugTracker/Tests/explain.SF-1739353.stable.out
        sql/test/BugTracker/Tests/jdbc_no_debug.SF-1739356.stable.out
        sql/test/BugTracker/Tests/jdbc_no_debug.SF-1739356.stable.out.32bit
        sql/test/BugTracker/Tests/like_exp.SF-1613949.stable.out
        sql/test/Dependencies/Tests/Dependencies.stable.out
        sql/test/Dependencies/Tests/Dependencies.stable.out.int128
        sql/test/Dependencies/dependency_DBobjects.sql
        sql/test/Tests/systemfunctions.stable.out
        sql/test/Tests/systemfunctions.stable.out.int128
        sql/test/bugs/Tests/groupby_having-bug-sf-947600.stable.err
        sql/test/bugs/Tests/groupby_having-bug-sf-947600.stable.out
        sql/test/bugs/Tests/select_orderby_alias-bug-sf-1024615.stable.out
        sql/test/bugs/Tests/subselect_ambigious_columns-bug-sf-949071.stable.out
        sql/test/bugs/groupby_having-bug-sf-947600.sql
        sql/test/bugs/subselect_ambigious_columns-bug-sf-949071.sql
        sql/test/leaks/Tests/check1.stable.out.int128
        sql/test/leaks/Tests/check2.stable.out.int128
        sql/test/leaks/Tests/check3.stable.out.int128
        sql/test/leaks/Tests/check4.stable.out.int128
        sql/test/leaks/Tests/check5.stable.out.int128
        sql/test/mapi/Tests/php_monetdb.stable.out
        sql/test/mergetables/Tests/mergequery.stable.out
        sql/test/pg_regress/Tests/timestamp.sql
        sql/test/pg_regress/Tests/timestamp.stable.out
        sql/test/pg_regress/Tests/timestamptz.sql
        sql/test/pg_regress/Tests/timestamptz.stable.out
        sql/test/testdb-upgrade-chain/Tests/upgrade.stable.out
        sql/test/testdb-upgrade-chain/Tests/upgrade.stable.out.int128
        sql/test/testdb-upgrade/Tests/upgrade.stable.out
        sql/test/testdb-upgrade/Tests/upgrade.stable.out.int128
        tools/merovingian/client/monetdb.c
        tools/merovingian/daemon/client.c
        tools/merovingian/daemon/merovingian.h
Branch: HTM
Log Message:

Merge with defualt branch


diffs (truncated from 18957 to 300 lines):

diff --git a/clients/R/MonetDB.R/DESCRIPTION b/clients/R/MonetDB.R/DESCRIPTION
--- a/clients/R/MonetDB.R/DESCRIPTION
+++ b/clients/R/MonetDB.R/DESCRIPTION
@@ -1,14 +1,16 @@
 Package: MonetDB.R
-Version: 0.9.9
+Version: 0.9.8
 Title: Connect MonetDB to R
 Authors@R: c(person("Hannes Muehleisen", role = c("aut", "cre"),email = 
"han...@cwi.nl"),
        person("Thomas Lumley", role = "ctb"),
        person("Anthony Damico", role = "ctb"))
 Author: Hannes Muehleisen [aut, cre], Thomas Lumley [ctb], Anthony Damico [ctb]
 Maintainer: Hannes Muehleisen <han...@cwi.nl>
-Depends: DBI (>= 0.3.1), digest (>= 0.6.4), methods, R (>= 3.1.1)
+Depends: DBI (>= 0.3.1)
+Imports: digest (>= 0.6.4), methods, codetools
 Enhances: dplyr (>= 0.3.0)
 Description: Allows to pull data from MonetDB into R. Includes a DBI 
implementation and a dplyr backend.
 License: MPL (== 1.1)
 URL: http://monetr.r-forge.r-project.org
 SystemRequirements: MonetDB, available from http://www.monetdb.org
+Collate: mapi.R dbi.R dbapply.R dplyr.R control.R
diff --git a/clients/R/MonetDB.R/NAMESPACE b/clients/R/MonetDB.R/NAMESPACE
--- a/clients/R/MonetDB.R/NAMESPACE
+++ b/clients/R/MonetDB.R/NAMESPACE
@@ -1,10 +1,10 @@
-import(DBI,digest,methods)
+import(DBI,digest,methods,codetools)
 
 # export only driver constructor, everything else is DBI stuff..
 export(MonetDB,MonetR,MonetDBR,MonetDB.R)
 export(monet.read.csv,monetdb.read.csv)
 # this one is not in the DBI
-exportMethods(dbSendUpdate,dbSendUpdateAsync,dbTransaction)
+exportMethods(dbSendUpdate,dbSendUpdateAsync,dbTransaction,mdbapply)
 # shorthands
 export(mc,mq)
 useDynLib(MonetDB.R)
diff --git a/clients/R/MonetDB.R/NEWS b/clients/R/MonetDB.R/NEWS
--- a/clients/R/MonetDB.R/NEWS
+++ b/clients/R/MonetDB.R/NEWS
@@ -1,10 +1,10 @@
-0.9.9
-- dbWriteTable now quotes column names
-
 0.9.8
 - Added support for esoteric data types such as MONTH_INTERVAL (Thanks, Roman)
 - Cleaned up SQL to R type mapping (we had this twice)
 - Now creating actual R integers if data fits
+- dbWriteTable now quotes table/column names if necessary, and outputs 
warnings if it did
+- New mdbapply function to automatically create and run embedded R functions 
in MonetDB
+- Fixes for dplyr backend
 
 0.9.7
 - Fixed crash on Windows (Sorry, everyone)
diff --git a/clients/R/MonetDB.R/R/control.R b/clients/R/MonetDB.R/R/control.R
--- a/clients/R/MonetDB.R/R/control.R
+++ b/clients/R/MonetDB.R/R/control.R
@@ -5,7 +5,7 @@ monetdb.server.start <-
       if( !file.exists( bat.file ) ) stop( paste( bat.file , "does not exist. 
Run monetdb.server.setup() to create a batch file." ) )
       
       # uugly, find path of pid file again by parsing shell script.
-      sc <- read.table(bat.file,sep="\n",stringsAsFactors=F)
+      sc <- utils::read.table(bat.file,sep="\n",stringsAsFactors=F)
       pidfile <- substring(sc[[2,1]],11)
       
       # run script
diff --git a/clients/R/MonetDB.R/R/dbapply.R b/clients/R/MonetDB.R/R/dbapply.R
new file mode 100644
--- /dev/null
+++ b/clients/R/MonetDB.R/R/dbapply.R
@@ -0,0 +1,79 @@
+# TOOD: support running this on a select in addition to table?
+# TODO: support remote dbs, find out whether its local via canary file
+# TODO: don't actually construct the data frame but use attr/class trick to 
save copying
+
+if (is.null(getGeneric("mdbapply"))) setGeneric("mdbapply", function(conn, 
table, fun, ...) 
+  standardGeneric("mdbapply"))
+
+setMethod("mdbapply", signature(conn="MonetDBConnection"),  def=function(conn, 
table, fun, ...) {
+  # make sure table exists
+  if (!dbExistsTable(conn, table)) {
+    stop("Table ", table, " does not exist.")
+  }
+
+  # generate unique function name
+  dbfunname <- "mdbapply_autogen_"
+  while (dbGetQuery(conn, paste0("select count(*) from functions where 
name='", dbfunname, "'"))[[1]] > 0)
+    dbfunname <- paste0(dbfunname, sample(letters, 1))
+
+  # test R integration with dummy function
+  dbBegin(conn)
+  dbSendQuery(conn,paste0("CREATE FUNCTION ", dbfunname, "() RETURNS TABLE(d 
INTEGER) LANGUAGE R {1L}"))
+  res <- dbGetQuery(conn,paste0("SELECT * FROM ", dbfunname, "()"))[[1]]
+  dbRollback(conn)
+
+  # now generate the UDF
+  # find packages loaded here and load them on the server as well
+  toloadpkgs <- 
setdiff(unique(sapply(strsplit(grep("^package:",search(),value=T),":"),function(x)
 
x[[2]])),c("base","stats","methods","utils","codetools","graphics","grDevices","datasets","MonetDB.R","DBI","digest"))
+  dbrcode <- ''
+  if (length(toloadpkgs) > 0) {
+    if (getOption("monetdb.debug.query",FALSE)) 
+      message("Package(s)  ",paste0(toloadpkgs,collapse=", "))
+    dbrcode <- paste0('# loading packages\ninvisible(lapply(setdiff(',
+                      paste0(deparse(toloadpkgs),collapse=""),
+                      ',unique(sapply(strsplit(grep("^package:", search(), 
value=T),":"), function(x) x[[2]]))), function(pname) library(pname, 
character.only=T, quietly=T)))\n')
+  }
+  # serialize global variables into ascii string, and add the code to scan it 
again into the current env
+  vars <- codetools::findGlobals(fun, merge=F)$variables
+  mdbapply_dotdot <- list(...)
+  if (length(mdbapply_dotdot) > 0) {
+    vars <- c(vars,"mdbapply_dotdot")
+    assign("mdbapply_dotdot", mdbapply_dotdot, envir=environment(fun))
+  }
+  sfilename <- NA
+  if (length(vars) > 0) {
+    if (getOption("monetdb.debug.query",FALSE)) 
+      message("Variable(s) ",paste0(vars,collapse=", "))
+    sfilename <- tempfile()
+    save(list=vars,file=sfilename,envir=environment(fun), compress=T)
+    dbrcode <- paste0(dbrcode, '# load serialized global variable(s) ', 
paste(vars, collapse=", "), '\nload("', sfilename, '")\n')
+  }
+
+  rfilename <- tempfile()
+  # get source of user function and append
+  dbrcode <- paste0(dbrcode, "# user-supplied function\nmdbapply_userfun <- ", 
paste0(deparse(fun), collapse="\n"), 
+    "\n# calling user function\nsaveRDS(do.call(mdbapply_userfun, 
if(exists('mdbapply_dotdot')){c(list(mdbapply_dbdata), mdbapply_dotdot)} 
else{list(mdbapply_dbdata)}),file=\"", rfilename, "\")\nreturn(42L)\n")
+  
+  # find out things about the table, then wrap the R function
+  query <- paste0("SELECT * FROM ", table, " AS t")
+  res <- monetdb_queryinfo(conn, query)
+  dbfun <- paste0("CREATE FUNCTION ", dbfunname,"(", 
paste0(dbQuoteIdentifier(conn, res$names)," ", res$dbtypes, collapse=", "),
+                  ") \nRETURNS TABLE(retval INTEGER) LANGUAGE R {\n# rename 
arguments\nmdbapply_dbdata <- data.frame(",
+                  paste0(res$names, collapse=", "),", stringsAsFactors=F)\n", 
dbrcode, "};\n")
+  # call the function we just created
+  dbsel <- paste0("SELECT * FROM ", dbfunname, "( (",query,") );\n")
+  # ok, talk to DB (easiest part of this)
+  res <- NA
+  dbBegin(conn)
+  tryCatch({
+    dbSendQuery(conn, dbfun)
+    dbGetQuery(conn, dbsel)
+    res <- readRDS(rfilename)
+  }, finally={
+    dbRollback(conn)
+    file.remove(stats::na.omit(c(sfilename, rfilename)))
+  })
+  res
+})
+
+
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
@@ -22,8 +22,8 @@ setMethod("dbUnloadDriver", "MonetDBDriv
 
 setMethod("dbGetInfo", "MonetDBDriver", def=function(dbObj, ...)
   list(name="MonetDBDriver", 
-       driver.version=packageVersion("MonetDB.R"), 
-       DBI.version=packageVersion("DBI"), 
+       driver.version=utils::packageVersion("MonetDB.R"), 
+       DBI.version=utils::packageVersion("DBI"), 
        client.version="NA", 
        max.connections=125) # R can only handle 128 connections, three of 
which are pre-allocated
 )
@@ -205,7 +205,7 @@ setMethod("dbListFields", "MonetDBConnec
 setMethod("dbExistsTable", "MonetDBConnection", def=function(conn, name, ...) {
   # TODO: this is evil... 
   return(tolower(gsub("(^\"|\"$)","",as.character(name))) %in% 
-    tolower(dbListTables(conn,sys_tables=T)))
+    tolower(dbListTables(conn, sys_tables=T)))
 })
 
 setMethod("dbGetException", "MonetDBConnection", def=function(conn, ...) {
@@ -215,7 +215,7 @@ setMethod("dbGetException", "MonetDBConn
 setMethod("dbReadTable", "MonetDBConnection", def=function(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
@@ -281,20 +281,28 @@ setMethod("dbSendQuery", signature(conn=
     }
   }
 
-  return(new("MonetDBResult", env=env))
+  invisible(new("MonetDBResult", env=env))
   })
 
 
 
 # quoting
-setMethod("dbQuoteIdentifier", c("MonetDBConnection", "character"), 
function(conn, x, ...) {
-  qts <- !grepl("^[a-z][a-z0-9_]+$",x,perl=T)
-  x[qts] <- paste('"', gsub('"', '""', x[qts], fixed = TRUE), '"', sep = "")
-  SQL(x)
-})
+quoteIfNeeded <- function(conn, x, ...) {
+  chars <- !grepl("^[A-Za-z][A-Za-z0-9_]*$", x, perl=T) && 
!grepl("^\"[^\"]*\"$", x, perl=T)
+  if (any(chars)) {
+    message("Identifier(s) ", paste(x[chars], collapse=", "), " contain 
reserved SQL characters and need to be quoted.")
+  }
+  reserved <- toupper(x) %in% .SQL92Keywords
+  if (any(reserved)) {
+    message("Identifier(s) ", paste(x[reserved], collapse=", "), " are 
reserved SQL keywords and need to be quoted.")
+  }
+  qts <- reserved || chars
+  x[qts] <- dbQuoteIdentifier(conn, x[qts])
+  x
+}
 
-# overload as per DBI documentation
-setMethod("dbQuoteIdentifier", c("MonetDBConnection", "SQL"), function(conn, 
x, ...) {x})
+# # overload as per DBI documentation
+# setMethod("dbQuoteIdentifier", c("MonetDBConnection", "SQL"), function(conn, 
x, ...) {x})
 
 # adapted from RMonetDB, very useful...
 setMethod("dbWriteTable", "MonetDBConnection", def=function(conn, name, value, 
overwrite=FALSE, 
@@ -310,7 +318,8 @@ setMethod("dbWriteTable", "MonetDBConnec
   if (overwrite && append) {
     stop("Setting both overwrite and append to true makes no sense.")
   }
-  qname <- make.db.names(conn, name)
+
+  qname <- quoteIfNeeded(conn, name)
   if (dbExistsTable(conn, qname)) {
     if (overwrite) dbRemoveTable(conn, qname)
     if (!overwrite && !append) stop("Table ", qname, " already exists. Set 
overwrite=TRUE if you want 
@@ -319,7 +328,7 @@ setMethod("dbWriteTable", "MonetDBConnec
   }
   if (!dbExistsTable(conn, qname)) {
     fts <- sapply(value, dbDataType, dbObj=conn)
-    fdef <- paste('"', make.db.names(conn, names(value)), '"', fts, 
collapse=', ')
+    fdef <- paste(quoteIfNeeded(conn, names(value)), fts, collapse=', ')
     ct <- paste("CREATE TABLE ", qname, " (", fdef, ")", sep= '')
     dbSendUpdate(conn, ct)
   }
@@ -458,8 +467,8 @@ monetdbRtype <- function(dbType) {
 }
 
 setMethod("fetch", signature(res="MonetDBResult", n="numeric"), 
def=function(res, n, ...) {
-  # dbGetQuery() still calls fetch(), thus no error message yet 
-  # warning("fetch() is deprecated, use dbFetch()")
+  # DBI on CRAN still uses fetch()
+  # message("fetch() is deprecated, use dbFetch()")
   dbFetch(res, n, ...)
 })
 
@@ -568,7 +577,7 @@ setMethod("dbFetch", signature(res="Mone
   
   # if (getOption("monetdb.profile", T))  .profiler_clear()
 
-  return(df)
+  df
 })
 
 
@@ -615,7 +624,7 @@ monet.read.csv <- monetdb.read.csv <- fu
                                                delim=",", newline="\\n", 
quote="\"", create=TRUE, ...){
   
   if (length(na.strings)>1) stop("na.strings must be of length 1")
-  headers <- lapply(files, read.csv, sep=delim, na.strings=na.strings, 
quote=quote, nrows=nrow.check, 
+  headers <- lapply(files, utils::read.csv, sep=delim, na.strings=na.strings, 
quote=quote, nrows=nrow.check, 
                     ...)
 
   if (!missing(nrows)) {
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
@@ -13,7 +13,9 @@ src_translate_env.src_monetdb <- functio
       n = function() dplyr::sql("COUNT(*)"),
       sd =  dplyr::sql_prefix("STDDEV_SAMP"),
       var = dplyr::sql_prefix("VAR_SAMP"),
-      median = dplyr::sql_prefix("MEDIAN")
+      median = dplyr::sql_prefix("MEDIAN"),
+      n_distinct = function(x) {dplyr::build_sql(dplyr::sql("count(distinct 
"), 
+        x, dplyr::sql(")"))}
     )
   )
 }
diff --git a/clients/R/MonetDB.R/man/dbApply.Rd 
b/clients/R/MonetDB.R/man/dbApply.Rd
new file mode 100644
--- /dev/null
+++ b/clients/R/MonetDB.R/man/dbApply.Rd
@@ -0,0 +1,35 @@
+\name{mdbapply}
+\alias{mdbapply}
+\alias{mdbapply,MonetDBConnection-method}
+
+\title{
+  Apply a R function to a MonetDB table.
+}
+\description{
+\code{dbApply} is used to switch the data from the normal auto-commiting mode 
into transactional mode. Here, changes to the database will not be permanent 
until \code{dbCommit} is called. If the changes are not to be kept around, you 
can use \code{dbRollback} to undo all the changes since \code{dbTransaction} 
was called.
+  
+}
+\usage{
+  mdbapply(conn, table, fun, ...)
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to