Changeset: 64432fe168db for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=64432fe168db Added Files: clients/R/MonetDB.R/R/dbapply.R clients/R/Tests/dbapply.R clients/R/Tests/dbapply.stable.err clients/R/Tests/dbapply.stable.out common/utils/strptime.c sql/test/BugTracker-2015/Tests/cast_to_num.Bug-3744.sql sql/test/BugTracker-2015/Tests/cast_to_num.Bug-3744.stable.err sql/test/BugTracker-2015/Tests/cast_to_num.Bug-3744.stable.out sql/test/BugTracker-2015/Tests/div_zero.Bug-3742.sql sql/test/BugTracker-2015/Tests/div_zero.Bug-3742.stable.err sql/test/BugTracker-2015/Tests/div_zero.Bug-3742.stable.out Removed Files: sql/test/BugTracker-2012/Tests/date_script_test.Bug-2973.stable.err.Windows sql/test/BugTracker-2012/Tests/date_script_test.Bug-2973.stable.out.Windows Modified Files: .hgignore MonetDB.spec NT/Makefile NT/installer32/MonetDB-ODBC-Installer.vdproj NT/installer32/MonetDB5-Geom-Module.vdproj NT/installer32/MonetDB5-SQL-Installer.vdproj NT/installer64/MonetDB-ODBC-Installer.vdproj NT/installer64/MonetDB5-Geom-Module.vdproj NT/rules.msc clients/R/MonetDB.R/DESCRIPTION clients/R/MonetDB.R/NAMESPACE clients/R/MonetDB.R/NEWS 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.int128 clients/Tests/exports.stable.out clients/mapiclient/Makefile.ag clients/mapiclient/eventparser.c common/utils/Makefile.ag configure.ag gdk/gdk.h gdk/gdk_bbp.c gdk/gdk_join.c gdk/gdk_logger.c gdk/gdk_logger.h gdk/gdk_private.h gdk/gdk_search.c gdk/gdk_storage.c gdk/gdk_utils.c gdk/gdk_utils.h 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_builder.h monetdb5/mal/mal_function.c monetdb5/mal/mal_instruction.c monetdb5/mal/mal_parser.c monetdb5/mal/mal_session.c monetdb5/modules/atoms/mtime.c monetdb5/modules/kernel/logger.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/optimizer/opt_pipes.c monetdb5/scheduler/Tests/sched00.stable.out sql/backends/monet5/Tests/optimizers.stable.err sql/backends/monet5/UDF/Tests/udf-reverse.stable.out sql/backends/monet5/sql_cast_impl_down_from_int.h sql/backends/monet5/sql_gencode.c sql/backends/monet5/sql_scenario.c sql/benchmarks/ssbm/Tests/01-explain.stable.out.int128 sql/benchmarks/ssbm/Tests/02-explain.stable.out.int128 sql/benchmarks/ssbm/Tests/03-explain.stable.out.int128 sql/benchmarks/ssbm/Tests/04-explain.stable.out.int128 sql/benchmarks/ssbm/Tests/05-explain.stable.out.int128 sql/benchmarks/ssbm/Tests/06-explain.stable.out.int128 sql/benchmarks/ssbm/Tests/07-explain.stable.out.int128 sql/benchmarks/ssbm/Tests/08-explain.stable.out.int128 sql/benchmarks/ssbm/Tests/09-explain.stable.out.int128 sql/benchmarks/ssbm/Tests/10-explain.stable.out.int128 sql/benchmarks/ssbm/Tests/11-explain.stable.out.int128 sql/benchmarks/ssbm/Tests/12-explain.stable.out.int128 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.int128 sql/benchmarks/tpch/Tests/04-explain.stable.out 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.int128 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.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.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/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/22-explain.stable.out sql/benchmarks/tpch/Tests/22-explain.stable.out.32bit sql/benchmarks/tpch/Tests/22-explain.stable.out.int128 sql/common/sql_types.c sql/jdbc/tests/Tests/Test_Dobjects.stable.out sql/scripts/99_system.sql sql/server/sql_mvc.c sql/storage/bat/bat_logger.c sql/storage/bat/bat_logger.h sql/storage/restrict/restrict_logger.c sql/storage/sql_storage.h sql/storage/store.c sql/test/BugTracker-2009/Tests/reorder.SF-2770608.sql sql/test/BugTracker-2009/Tests/table-leftovers.SF-2779462.sql sql/test/BugTracker-2010/Tests/LIMIT_OFFSET_big-endian.Bug-2622.stable.out 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-2012/Tests/incorrect_cast_from_double_to_int.Bug-2579.stable.err sql/test/BugTracker-2012/Tests/incorrect_cast_from_double_to_int.Bug-2579.stable.out sql/test/BugTracker-2012/Tests/now_results_in_illegal_argument.Bug-2978.sql sql/test/BugTracker-2012/Tests/now_results_in_illegal_argument.Bug-2978.stable.err sql/test/BugTracker-2012/Tests/now_results_in_illegal_argument.Bug-2978.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-2014/Tests/nil_2dec_lng.Bug-3592.stable.out 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/Tests/systemfunctions.stable.out sql/test/leaks/Tests/check0.stable.out sql/test/leaks/Tests/check0.stable.out.int128 sql/test/leaks/Tests/check1.stable.out sql/test/leaks/Tests/check1.stable.out.int128 sql/test/leaks/Tests/check2.stable.out sql/test/leaks/Tests/check2.stable.out.int128 sql/test/leaks/Tests/check3.stable.out sql/test/leaks/Tests/check3.stable.out.int128 sql/test/leaks/Tests/check4.stable.out sql/test/leaks/Tests/check4.stable.out.int128 sql/test/leaks/Tests/check5.stable.out sql/test/leaks/Tests/check5.stable.out.int128 sql/test/leaks/Tests/drop3.stable.out sql/test/leaks/Tests/drop3.stable.out.int128 sql/test/leaks/Tests/select1.stable.out sql/test/leaks/Tests/select1.stable.out.int128 sql/test/leaks/Tests/select2.stable.out sql/test/leaks/Tests/select2.stable.out.int128 sql/test/leaks/Tests/temp1.stable.out sql/test/leaks/Tests/temp1.stable.out.int128 sql/test/leaks/Tests/temp2.stable.out sql/test/leaks/Tests/temp2.stable.out.int128 sql/test/leaks/Tests/temp3.stable.out sql/test/leaks/Tests/temp3.stable.out.int128 sql/test/mapi/Tests/perl_dbi.SQL.bat sql/test/mergetables/Tests/mergequery.stable.out sql/test/pg_regress/Tests/date.stable.err sql/test/pg_regress/Tests/time.stable.err 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/pg_regress/Tests/timetz.stable.err testing/Mtest.py.in tools/merovingian/daemon/argvcmds.c tools/merovingian/daemon/argvcmds.h tools/merovingian/daemon/discoveryrunner.c tools/merovingian/daemon/discoveryrunner.h tools/merovingian/daemon/forkmserver.c tools/merovingian/daemon/merovingian.c tools/merovingian/utils/properties.c tools/merovingian/utils/properties.h tools/merovingian/utils/utils.c tools/merovingian/utils/utils.h tools/mserver/Makefile.ag Branch: leftmart Log Message:
merge with default diffs (truncated from 16700 to 300 lines): diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -91,3 +91,8 @@ NT/sql NT/testing NT/tools NT/unistd.h + +syntax: regexp +^java/build$ +syntax: regexp +^java/target$ diff --git a/MonetDB.spec b/MonetDB.spec --- a/MonetDB.spec +++ b/MonetDB.spec @@ -901,7 +901,6 @@ developer, but if you do want to test, t %{configure} \ --enable-assert=no \ - --enable-bits=%{bits} \ --enable-console=yes \ --enable-debug=no \ --enable-developer=no \ diff --git a/NT/Makefile b/NT/Makefile --- a/NT/Makefile +++ b/NT/Makefile @@ -24,7 +24,6 @@ install: targetdirs all $(INSTALL) .monetdb "$(sysconfdir)" $(INSTALL) ..\NT\installer$(bits)\*.sln "$(prefix)" $(INSTALL) ..\NT\installer$(bits)\*.vdproj "$(prefix)" - -if exist "C:\Program Files (x86)" if $(bits)==32 cd "$(prefix)"&&C:\cygwin\bin\sed.exe -i "s/Program Files/Program Files (x86)/" *.vdproj $(srcdir)\Makefile.msc: "$(srcdir)\Makefile.ag" cd "$(srcdir)"&&set PYTHONPATH=buildtools\autogen&&python buildtools\autogen\autogen.py diff --git a/NT/installer32/MonetDB-ODBC-Installer.vdproj b/NT/installer32/MonetDB-ODBC-Installer.vdproj --- a/NT/installer32/MonetDB-ODBC-Installer.vdproj +++ b/NT/installer32/MonetDB-ODBC-Installer.vdproj @@ -1207,7 +1207,7 @@ { "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" - "SourcePath" = "8:C:\\Program Files\\Common Files\\Merge Modules\\Microsoft_VC100_CRT_x86.msm" + "SourcePath" = "8:C:\\Program Files (x86)\\Common Files\\Merge Modules\\Microsoft_VC100_CRT_x86.msm" "Properties" { } diff --git a/NT/installer32/MonetDB5-Geom-Module.vdproj b/NT/installer32/MonetDB5-Geom-Module.vdproj --- a/NT/installer32/MonetDB5-Geom-Module.vdproj +++ b/NT/installer32/MonetDB5-Geom-Module.vdproj @@ -999,7 +999,7 @@ { "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" - "SourcePath" = "8:C:\\Program Files\\Common Files\\Merge Modules\\Microsoft_VC100_CRT_x86.msm" + "SourcePath" = "8:C:\\Program Files (x86)\\Common Files\\Merge Modules\\Microsoft_VC100_CRT_x86.msm" "Properties" { } diff --git a/NT/installer32/MonetDB5-SQL-Installer.vdproj b/NT/installer32/MonetDB5-SQL-Installer.vdproj --- a/NT/installer32/MonetDB5-SQL-Installer.vdproj +++ b/NT/installer32/MonetDB5-SQL-Installer.vdproj @@ -4927,7 +4927,7 @@ { "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" - "SourcePath" = "8:C:\\Program Files\\Common Files\\Merge Modules\\Microsoft_VC100_CRT_x86.msm" + "SourcePath" = "8:C:\\Program Files (x86)\\Common Files\\Merge Modules\\Microsoft_VC100_CRT_x86.msm" "Properties" { } diff --git a/NT/installer64/MonetDB-ODBC-Installer.vdproj b/NT/installer64/MonetDB-ODBC-Installer.vdproj --- a/NT/installer64/MonetDB-ODBC-Installer.vdproj +++ b/NT/installer64/MonetDB-ODBC-Installer.vdproj @@ -1207,7 +1207,7 @@ { "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" - "SourcePath" = "8:C:\\Program Files\\Common Files\\Merge Modules\\Microsoft_VC100_CRT_x64.msm" + "SourcePath" = "8:C:\\Program Files (x86)\\Common Files\\Merge Modules\\Microsoft_VC100_CRT_x64.msm" "Properties" { } diff --git a/NT/installer64/MonetDB5-Geom-Module.vdproj b/NT/installer64/MonetDB5-Geom-Module.vdproj --- a/NT/installer64/MonetDB5-Geom-Module.vdproj +++ b/NT/installer64/MonetDB5-Geom-Module.vdproj @@ -999,7 +999,7 @@ { "UseDynamicProperties" = "11:TRUE" "IsDependency" = "11:FALSE" - "SourcePath" = "8:C:\\Program Files\\Common Files\\Merge Modules\\Microsoft_VC100_CRT_x64.msm" + "SourcePath" = "8:C:\\Program Files (x86)\\Common Files\\Merge Modules\\Microsoft_VC100_CRT_x64.msm" "Properties" { } diff --git a/NT/rules.msc b/NT/rules.msc --- a/NT/rules.msc +++ b/NT/rules.msc @@ -439,7 +439,7 @@ create_winconfig_conds_new_py: update_winconfig_conds_py: create_winconfig_conds_new_py if not exist "$(TOPDIR)\winconfig_conds.py" $(CP) "$(TOPDIR)\winconfig_conds_new.py" "$(TOPDIR)\winconfig_conds.py" - C:\cygwin\bin\cmp.exe -s "$(TOPDIR)\winconfig_conds_new.py" "$(TOPDIR)\winconfig_conds.py" || \ + cmp -s "$(TOPDIR)\winconfig_conds_new.py" "$(TOPDIR)\winconfig_conds.py" || \ $(CP) "$(TOPDIR)\winconfig_conds_new.py" "$(TOPDIR)\winconfig_conds.py" CONFIGURE=$(PYTHON) $(CONFIGURE_PY) \ 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 @@ -6,9 +6,10 @@ Authors@R: c(person("Hannes Muehleisen", 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), digest (>= 0.6.4), methods, R (>= 3.1.1), 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,dbApply) # 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,5 +1,6 @@ 0.9.9 -- dbWriteTable now quotes column names +- dbWriteTable now quotes table/column names if necessary, and outputs warnings if it did +- New dbApply function to automatically create embedded R functions in MonetDB 0.9.8 - Added support for esoteric data types such as MONTH_INTERVAL (Thanks, Roman) 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,66 @@ +.encodeGlobals <- function(name) { + vars <- findGlobals(name,merge=F)$variables + if (length(vars) < 1) { + return(NA) + } + if (getOption("monetdb.debug.query",FALSE)) + message("Variable(s) ",paste0(vars,collapse=", ")) + + # TODO: optionally inline serialized context for remote dbs + res <- tempfile() + save(list=vars,file=res,envir=environment(name),compress=T) + return(res) +} + +if (is.null(getGeneric("dbApply"))) setGeneric("dbApply", function(conn, ...) + standardGeneric("dbApply")) + +setMethod("dbApply", signature(conn="MonetDBConnection"), def=function(conn, table, rettype, fun) { + # generate unique function name + dbfunname <- "__r_dapply_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 + sfilename <- .encodeGlobals(fun) + if (!is.na(sfilename)) { + dbrcode <- paste0(dbrcode,'# load serialized global variables\nload("',sfilename,'")\n') + } + # get source of user function and append + dbrcode <- paste0(dbrcode,"# user-supplied function\n.userfun <- ",paste0(deparse(fun),collapse="\n"),"\n# calling user function\nreturn(.userfun(.dbdata))\n") + + # find out things about the table, then wrap the r function + res <- dbSendQuery(conn,paste0("SELECT * FROM ",table," LIMIT 1")) + dbnames <- res@env$info$names + dbtypes <- res@env$info$dbtypes + dbfun <- paste0("CREATE FUNCTION ",dbfunname,"(",paste0(dbnames," ", dbtypes, collapse=", "), + ") \nRETURNS TABLE(retval ",rettype,") LANGUAGE R {\n# rename arguments\n.dbdata <- data.frame(", + paste0(dbnames, collapse=", "),")\n",dbrcode,"};\n") + # call the function we just created + dbsel <- paste0("SELECT * FROM ", dbfunname, "( (SELECT * FROM ", table, " AS t) );\n") + # ok, talk to DB (EZ) + dbBegin(conn) + dbSendQuery(conn,dbfun) + res <- dbGetQuery(conn,dbsel) + dbRollback(conn) + return(res[,1]) +}) + + 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 @@ -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, ...) { _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list