From bfe7edb7acf7dee76d01b9609f738d90d28d5c07 Mon Sep 17 00:00:00 2001 From: Rupert Williams Date: Mon, 1 Jun 2026 15:56:00 +0000 Subject: [PATCH 1/2] fvsOL: fix dbWriteTable() temp-table writes for RSQLite >= 3 On current RSQLite, writing a temp table by passing a schema-qualified name as `DBI::SQL("temp.X")` fails: Error: Named parameters not used in query: name Reproduced on R 4.6.0, RSQLite 3.53.1, DBI 1.3.0 (P3M snapshot 2026-05-27). The DBI-idiomatic form dbWriteTable(con, "X", df, temporary = TRUE, overwrite = TRUE) works and keeps the table queryable as `temp.X`, so all downstream `select ... from temp.X` reads continue to resolve correctly. This converts all 11 affected call sites: server.R (6) fvsRunUtilities.R (2) externalCallable.R (2) writeKeyFile.R (1) Each converted write keeps the base name its downstream queries reference (e.g. write "RunStds" -> read temp.RunStds). No behaviour change to the temp-table contents; only the call form. --- fvsOL/R/externalCallable.R | 4 ++-- fvsOL/R/fvsRunUtilities.R | 4 ++-- fvsOL/R/server.R | 12 ++++++------ fvsOL/R/writeKeyFile.R | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/fvsOL/R/externalCallable.R b/fvsOL/R/externalCallable.R index 927827e..e5920cd 100644 --- a/fvsOL/R/externalCallable.R +++ b/fvsOL/R/externalCallable.R @@ -71,7 +71,7 @@ extnMakeRun <- function (prjDir=getwd(),title=NULL,standIDs=NULL, dbExecute(dbcon,'drop table if exists temp.Stds') qry = paste0("select ",paste(fields,collapse=",")," from ",stdInit, ' where lower(variant) like "%',tolower(variant),'%"') - dbWriteTable(dbcon,DBI::SQL("temp.Stds"),data.frame(SelStds = standIDs)) + dbWriteTable(dbcon,"Stds",data.frame(SelStds = standIDs),temporary=TRUE,overwrite=TRUE) qry = paste0(qry," and ",sidid," in (select SelStds from temp.Stds)") fvsInit = try(dbGetQuery(dbcon,qry)) @@ -847,7 +847,7 @@ extnAddStands <- function(prjDir=getwd(),runUUID,stands, unlist(lapply(fvsRun$stands,function(x) x$sid)))) if (nrow(getStds) == 0) return(nadd) - dbWriteTable(dbcon,name=DBI::SQL("temp.getStds"),value=getStds,overwrite=TRUE) + dbWriteTable(dbcon,name="getStds",value=getStds,temporary=TRUE,overwrite=TRUE) variant = substring(fvsRun$FVSpgm,4) dbExecute(dbcon,'drop table if exists temp.Stds') qry = paste0("select ",paste(fields,collapse=",")," from ",stdInit, diff --git a/fvsOL/R/fvsRunUtilities.R b/fvsOL/R/fvsRunUtilities.R index f6d898a..5b78f90 100644 --- a/fvsOL/R/fvsRunUtilities.R +++ b/fvsOL/R/fvsRunUtilities.R @@ -1339,7 +1339,7 @@ cat ("globals$fvsRun$refreshDB=",globals$fvsRun$refreshDB,"\n") dbExecute(dbGlb$dbIcon,'drop table if exists temp.Stds') if (length(input$inStds)) { - dbWriteTable(dbGlb$dbIcon,DBI::SQL("temp.Stds"),data.frame(SelStds = input$inStds)) + dbWriteTable(dbGlb$dbIcon,"Stds",data.frame(SelStds = input$inStds),temporary=TRUE,overwrite=TRUE) } else return() } else { # use if inAddGrp @@ -1356,7 +1356,7 @@ cat ("globals$fvsRun$refreshDB=",globals$fvsRun$refreshDB,"\n") } if (length(stds) == 0) return() dbExecute(dbGlb$dbIcon,'drop table if exists temp.Stds') - dbWriteTable(dbGlb$dbIcon,DBI::SQL("temp.Stds"),data.frame(SelStds = stds)) + dbWriteTable(dbGlb$dbIcon,"Stds",data.frame(SelStds = stds),temporary=TRUE,overwrite=TRUE) } qry = paste0('select ',paste0(fields,collapse=","),' from ',stdInit, ' where ',sidid,' in (select SelStds from temp.Stds)') diff --git a/fvsOL/R/server.R b/fvsOL/R/server.R index 584f523..559c17a 100644 --- a/fvsOL/R/server.R +++ b/fvsOL/R/server.R @@ -2480,7 +2480,7 @@ cat ("in reloadStandSelection\n") if (class(grps) == "try-error" || is.null(grps) || nrow(grps) == 0) { dbExecute(dbGlb$dbIcon,"drop table if exists temp.Grps") - dbWriteTable(dbGlb$dbIcon,DBI::SQL("temp.Grps"),data.frame(Stand_ID="",Grp="")) + dbWriteTable(dbGlb$dbIcon,"Grps",data.frame(Stand_ID="",Grp=""),temporary=TRUE,overwrite=TRUE) updateSelectInput(session=session, inputId="inGrps",choices=list()) updateSelectInput(session=session, inputId="ExtGroups",choices=list()) updateSelectInput(session=session, inputId="inStds",list()) @@ -2514,7 +2514,7 @@ cat ("in reloadStandSelection\n") "StandPlot_ID" else "Stand_ID","Grp") dd = as.data.frame(dd) dbExecute(dbGlb$dbIcon,"drop table if exists temp.Grps") - dbWriteTable(dbGlb$dbIcon,DBI::SQL("temp.Grps"),dd) + dbWriteTable(dbGlb$dbIcon,"Grps",dd,temporary=TRUE,overwrite=TRUE) selGrp = dbGetQuery(dbGlb$dbIcon, 'select distinct Grp from temp.Grps order by Grp')[,1] @@ -2545,7 +2545,7 @@ cat ("inGrps inAnyAll inStdFindBut\n") updateSelectInput(session=session, inputId="inStds", choices=list()) } else { dbExecute(dbGlb$dbIcon,"drop table if exists temp.SGrps") - dbWriteTable(dbGlb$dbIcon,DBI::SQL("temp.SGrps"),data.frame(SelGrps = input$inGrps)) + dbWriteTable(dbGlb$dbIcon,"SGrps",data.frame(SelGrps = input$inGrps),temporary=TRUE,overwrite=TRUE) sid = if (input$inTabs %in% c("FVS_PlotInit","FVS_PlotInit_Plot")) "StandPlot_ID" else "Stand_ID" stds = try(dbGetQuery(dbGlb$dbIcon,paste0('select ',sid,' from temp.Grps ', @@ -2584,7 +2584,7 @@ cat ("input$inStdFind=",input$inStdFind,"\n") } else{ dbExecute(dbGlb$dbIcon,"drop table if exists temp.SEGrps") - dbWriteTable(dbGlb$dbIcon,DBI::SQL("temp.SEGrps"),data.frame(SelGrps = input$ExtGroups)) + dbWriteTable(dbGlb$dbIcon,"SEGrps",data.frame(SelGrps = input$ExtGroups),temporary=TRUE,overwrite=TRUE) sid = if (input$inTabs %in% c("FVS_PlotInit","FVS_PlotInit_Plot"))"StandPlot_ID" else "Stand_ID" stds = try(dbGetQuery(dbGlb$dbIcon,paste0('select distinct ',sid,' from temp.Grps ', 'where Grp in (select SelGrps from temp.SEGrps)'))) @@ -5644,7 +5644,7 @@ cat ("mapDsRunList input$mapDsRunList=",input$mapDsRunList,"\n") # if there are reps (same stand more than once), just use the first rep, ignore the others cases = cases[!duplicated(cases$StandID),] dbExecute(dbGlb$dbOcon,"drop table if exists temp.mapsCases") - dbWriteTable(dbGlb$dbOcon,DBI::SQL("temp.mapsCases"),cases[,1,drop=FALSE]) + dbWriteTable(dbGlb$dbOcon,"mapsCases",cases[,1,drop=FALSE],temporary=TRUE,overwrite=TRUE) tabs = setdiff(myListTables(dbGlb$dbOcon), c("CmpSummary","FVS_Cases","CmpSummary_East")) tables = list() @@ -5794,7 +5794,7 @@ cat ("left to get: length(uidsToGet)=",length(uidsToGet), }) if (is.null(inInit)) inInit = getTableName(dbGlb$dbIcon,"FVS_StandInit") cat ("mapDsRunList trying to use the table=",inInit,"\n") - dbWriteTable(dbGlb$dbIcon,DBI::SQL("temp.uidsToGet"),data.frame(stds=uidsToGet),overwrite=TRUE) + dbWriteTable(dbGlb$dbIcon,"uidsToGet",data.frame(stds=uidsToGet),temporary=TRUE,overwrite=TRUE) sid = if (inInit %in% c("FVS_PlotInit","FVS_PlotInit_Plot")) "StandPlot_ID" else "Stand_ID" qry = paste0("select distinct ",sid," as Stand_ID,Latitude,Longitude from ",inInit, diff --git a/fvsOL/R/writeKeyFile.R b/fvsOL/R/writeKeyFile.R index 30b92e5..2689056 100644 --- a/fvsOL/R/writeKeyFile.R +++ b/fvsOL/R/writeKeyFile.R @@ -433,7 +433,7 @@ writeKeyFile <- function (globals,dbIcon,keyFileName=NULL,verbose=TRUE) if (length(stds)==0) return(paste0("No stands to process. Run =", globals$fvsRun$title," uuid=",globals$fvsRun$uuid)) dbExecute(dbIcon,'drop table if exists temp.RunStds') - dbWriteTable(dbIcon,DBI::SQL("temp.RunStds"),data.frame(RunStds = stds)) + dbWriteTable(dbIcon,"RunStds",data.frame(RunStds = stds),temporary=TRUE,overwrite=TRUE) # get the preferred ids depending on the table that was used to build the run intable=toupper(globals$fvsRun$refreshDB) From abe9a55388b4e492abd297a0d57f759ad715e692 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 2 Jun 2026 19:45:56 +0000 Subject: [PATCH 2/2] fvsOL: fix dbWriteTable() in the XLSX-export handler for RSQLite >= 3 The "Output .xlsx for current run" download handler (output$dlFVSOutxlsx) built its CaseID filter table with dbWriteTable(name=DBI::SQL(casesToGet), ...). Passing a DBI::SQL() object as the table name throws "Named parameters not used in query: name" on RSQLite >= 3 -- the same error already fixed at the 11 temp.* sites -- so the export crashed the moment a user clicked the button. It also carried an overwirte= typo (overwrite never applied). The handler attached a per-pid/uuid :memory: database solely to hold that one table, then detached it. Replace that with a session-private temporary table (the same temporary=TRUE pattern as the other sites; temp tables are per- connection, so no cross-session collision), drop the now-unused attach/detach, and fix the typo. https://claude.ai/code/session_011C6wxKosiwHnEYvAPJfmcW --- fvsOL/R/server.R | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/fvsOL/R/server.R b/fvsOL/R/server.R index 559c17a..85f0ccb 100644 --- a/fvsOL/R/server.R +++ b/fvsOL/R/server.R @@ -4823,10 +4823,9 @@ cat ("in buildKeywords, oReopn=",oReopn," kwPname=",kwPname,"\n") "where KeywordFile = '",globals$fvsRun$uuid,"';")) if (nrow(cases) == 0) return() cat ("download run as xlsx, ncases=",nrow(cases),"\n") - tmp = paste0("tmp",gsub("-","",runuuid),Sys.getpid(),"genoutput") - dbExecute(dbGlb$dbOcon,paste0("attach database ':memory:' as ",tmp)) - casesToGet = paste0(tmp,".casesToGet") - dbWriteTable(dbGlb$dbOcon,name=DBI::SQL(casesToGet),value=cases,overwirte=TRUE) + casesToGet = "temp.casesToGet" + dbExecute(dbGlb$dbOcon,"drop table if exists temp.casesToGet") + dbWriteTable(dbGlb$dbOcon,"casesToGet",cases,temporary=TRUE,overwrite=TRUE) out = list() cmpYes = if ("CmpMetaData" %in% tabs) { @@ -4845,7 +4844,6 @@ cat ("download run as xlsx, ncases=",nrow(cases),"\n") out[[tab]] = dat cat ("qry=",qry," class(dat)=",class(dat),"\n") } - dbExecute(dbGlb$dbOcon,paste0("detach database ",tmp,";")) if (length(out)) write.xlsx(file=tf,out) }, contentType=NULL) ## dlPrjBackup