test_convert <- function(con, type, val) { val_comp <- val if (is.factor(val)) { val_comp <- as.character(val) } q <- dbSendQuery(con, sprintf("SELECT CAST(? AS %s) a", type)) dbBind(q, list(val)) res1 <- dbFetch(q) dbBind(q, list(NA)) res2 <- dbFetch(q) dbClearResult(q) expect_equal(res1[[1]][1], val_comp) expect_true(is.na(res2[[1]][1])) dbExecute(con, "DROP TABLE IF EXISTS bind_test") dbExecute(con, sprintf("CREATE TEMPORARY TABLE bind_test(i INTEGER, a %s)", type)) q <- dbSendStatement(con, "INSERT INTO bind_test VALUES ($1, $2)") dbBind(q, list(1, val)) dbBind(q, list(2, NA)) dbClearResult(q) res3 <- dbGetQuery(con, "SELECT a FROM bind_test ORDER BY i") dbExecute(con, "DROP TABLE bind_test") expect_equal(res3[[1]][1], val_comp) expect_true(is.na(res3[[1]][2])) } test_that("dbBind() works as expected for all types", { con <- dbConnect(duckdb()) on.exit(dbDisconnect(con, shutdown = TRUE)) test_convert(con, "BOOLEAN", TRUE) test_convert(con, "BOOLEAN", FALSE) test_convert(con, "INTEGER", 42L) test_convert(con, "INTEGER", 42) test_convert(con, "HUGEINT", 39218390) test_convert(con, "DOUBLE", 42L) test_convert(con, "DOUBLE", 42.2) test_convert(con, "STRING", "Hello, World") test_convert(con, "DATE", as.Date("2019-11-26")) test_convert(con, "TIMESTAMP", as.POSIXct("2019-11-26 21:11Z", "UTC")) }) test_that("dbBind() is called from dbGetQuery and dbExecute", { con <- dbConnect(duckdb()) on.exit(dbDisconnect(con, shutdown = TRUE)) res <- dbGetQuery(con, "SELECT CAST (? AS INTEGER), CAST(? AS STRING)", params = list(42, "Hello")) expect_equal(res[[1]][1], 42L) expect_equal(res[[2]][1], "Hello") res <- dbGetQuery(con, "SELECT CAST (? AS INTEGER), CAST(? AS STRING)", params = list(42, "Hello")) expect_equal(res[[1]][1], 42L) expect_equal(res[[2]][1], "Hello") q <- dbSendQuery(con, "SELECT CAST (? AS INTEGER), CAST(? AS STRING)", params = list(42, "Hello")) # already have a result res <- dbFetch(q) expect_equal(res[[1]][1], 42L) expect_equal(res[[2]][1], "Hello") # now bind again dbBind(q, list(43, "Holla")) res <- dbFetch(q) expect_equal(res[[1]][1], 43L) expect_equal(res[[2]][1], "Holla") dbClearResult(q) }) test_that("test blobs", { con <- dbConnect(duckdb()) on.exit(dbDisconnect(con, shutdown = TRUE)) res <- dbGetQuery(con, "SELECT BLOB 'hello'") expect_equal(res[[1]][[1]], charToRaw("hello")) }) test_that("various error cases for dbBind()", { con <- dbConnect(duckdb()) on.exit(dbDisconnect(con, shutdown = TRUE)) q <- dbSendQuery(con, "SELECT CAST (? AS INTEGER)") expect_error(dbFetch(q)) expect_error(dbBind(q, list())) expect_error(dbBind(q, list(1, 2))) expect_error(dbBind(q, list("asdf"))) expect_error(dbBind(q, list("asdf", "asdf"))) expect_error(dbBind(q)) expect_error(dbBind(q, "asdf")) dbClearResult(q) expect_error(dbGetQuery(con, "SELECT CAST (? AS INTEGER)", "asdf")) expect_error(dbGetQuery(con, "SELECT CAST (? AS INTEGER)", "asdf", "asdf")) expect_error(dbGetQuery(con, "SELECT CAST (? AS INTEGER)")) expect_error(dbGetQuery(con, "SELECT CAST (? AS INTEGER)", list())) expect_error(dbGetQuery(con, "SELECT CAST (? AS INTEGER)", list(1, 2))) expect_error(dbGetQuery(con, "SELECT CAST (? AS INTEGER)", list("asdf"))) expect_error(dbGetQuery(con, "SELECT CAST (? AS INTEGER)", list("asdf", "asdf"))) q <- dbSendQuery(con, "SELECT CAST (42 AS INTEGER)") res <- dbFetch(q) expect_equal(res[[1]][1], 42L) expect_error(dbBind(q, list())) expect_error(dbBind(q, list(1))) expect_error(dbBind(q, list("asdf"))) expect_error(dbBind(q)) expect_error(dbBind(q, 1)) expect_error(dbBind(q, "asdf")) dbClearResult(q) expect_error(dbGetQuery(con, "SELECT CAST (42 AS INTEGER)", 1)) expect_error(dbGetQuery(con, "SELECT CAST (42 AS INTEGER)", 1, 2)) expect_error(dbGetQuery(con, "SELECT CAST (42 AS INTEGER)", "asdf")) expect_error(dbGetQuery(con, "SELECT CAST (42 AS INTEGER)", "asdf", "asdf")) expect_error(dbGetQuery(con, "SELECT CAST (42 AS INTEGER)", list(1))) expect_error(dbGetQuery(con, "SELECT CAST (42 AS INTEGER)", list(1, 2))) expect_error(dbGetQuery(con, "SELECT CAST (42 AS INTEGER)", list("asdf"))) expect_error(dbGetQuery(con, "SELECT CAST (42 AS INTEGER)", list("asdf", "asdf"))) })