R/spec-meta-bind.R

# Generated by helper-dev.R, do not edit by hand
# Sources: R/spec-meta-bind-.R, R/spec-meta-bind-expr.R, R/spec-meta-bind-runner.R

# This file is generated during load_all() if it's older than the sources

spec_meta_bind <- list(
  bind_return_value = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:18>
    # @return
    # `dbBind()` returns the result set,
    # invisibly,
    # for queries issued by [dbSendQuery()] or [dbSendQueryArrow()] and
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1L
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      expect_error(dbFetch(res))
      expect_equal(dbGetRowCount(res), 0)
      expect_true(dbIsValid(res))
      expect_false(dbHasCompleted(res))
      bind_res <- withVisible(dbBind(res, bind_values))
      expect_identical(res, bind_res$value)
      expect_false(bind_res$visible)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_return_value_statement = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:36>
    # also for data manipulation statements issued by
    # [dbSendStatement()].
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1L
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      data <- data.frame(a = rep(1:5, 1:5), b = 1:15)
      table_name <- random_table_name()
      dbWriteTable(con, table_name, data, temporary = TRUE)
      sql <- paste0("UPDATE ", dbQuoteIdentifier(con, table_name), " SET b = b + 1 WHERE ")
      sql <- paste0(sql, "a = ", placeholder[[1L]])
      res <- dbSendStatement(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      expect_identical(dbGetRowsAffected(res), NA_integer_)
      expect_true(dbIsValid(res))
      expect_false(dbHasCompleted(res))
      bind_res <- withVisible(dbBind(res, bind_values))
      expect_identical(res, bind_res$value)
      expect_false(bind_res$visible)
      rows_affected <- dbGetRowsAffected(res)
      if (!isTRUE(allow_na_rows_affected) || !is.na(rows_affected)) {
        expect_equal(rows_affected, 1L)
      }
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_too_many = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:53>
    # @section Failure modes:
    # Binding too many
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1L
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      bind_values_patched <- if (is.null(names(bind_values))) {
        c(bind_values, bind_values[[1L]])
      } else {
        c(bind_values, bogus = bind_values[[1L]])
      }
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      expect_error(dbBind(res, bind_values_patched), ".*")
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_not_enough = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:72>
    # or not enough values,
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1:2
      placeholder <- placeholder_fun(2L)
      names(bind_values) <- names(placeholder)
      bind_values_patched <- bind_values[-1L]
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      expect_error(dbBind(res, bind_values_patched), ".*")
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_wrong_name = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:86>
    # or parameters with wrong names
    placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1L
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      bind_values_patched <- stats::setNames(bind_values, paste0("bogus", names(bind_values)))
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      expect_error(dbBind(res, bind_values_patched), ".*")
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_multi_row_unequal_length = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:101>
    # or unequal length,
    # also raises an error.
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected
    for (placeholder_fun in placeholder_funs) {
      bind_values <- list(1:3, 2:4)
      placeholder <- placeholder_fun(2L)
      names(bind_values) <- names(placeholder)
      bind_values_patched <- {
        bind_values[[2]] <- bind_values[[2]][-1]
        bind_values
      }
      data <- data.frame(a = rep(1:5, 1:5), b = 1:15)
      table_name <- random_table_name()
      dbWriteTable(con, table_name, data, temporary = TRUE)
      sql <- paste0("UPDATE ", dbQuoteIdentifier(con, table_name), " SET b = b + 1 WHERE ")
      sql <- paste0(sql, "a = ", placeholder[[1L]], " AND ")
      sql <- paste0(sql, "b = ", placeholder[[2L]])
      res <- dbSendStatement(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      expect_error(dbBind(res, bind_values_patched), ".*")
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_named_param_unnamed_placeholders = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:118>
    # If the placeholders in the query are named,
    # all parameter values must have names
    placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1L
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      bind_values_patched <- stats::setNames(bind_values, NULL)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      expect_error(dbBind(res, bind_values_patched), ".*")
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_named_param_empty_placeholders = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:134>
    # (which must not be empty
    placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- list(1L, 2L)
      placeholder <- placeholder_fun(2L)
      names(bind_values) <- names(placeholder)
      bind_values_patched <- {
        names(bind_values)[[1]] <- ""
        bind_values
      }
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      expect_error(dbBind(res, bind_values_patched), ".*")
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_named_param_na_placeholders = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:150>
    # or `NA`),
    placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- list(1L, 2L)
      placeholder <- placeholder_fun(2L)
      names(bind_values) <- names(placeholder)
      bind_values_patched <- {
        names(bind_values)[[1]] <- NA
        bind_values
      }
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      expect_error(dbBind(res, bind_values_patched), ".*")
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_unnamed_param_named_placeholders = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:166>
    # and vice versa,
    # otherwise an error is raised.
    placeholder_funs <- get_placeholder_funs(ctx, requires_names = FALSE)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1L
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      bind_values_patched <- stats::setNames(bind_values, letters[seq_along(bind_values)])
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      expect_error(dbBind(res, bind_values_patched), ".*")
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_premature_clear = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:187>
    # Calling `dbBind()` on a result set already cleared by [dbClearResult()]
    # also raises an error.
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1L
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a")
      res <- dbSendQuery(con, sql)
      dbClearResult(res)
      expect_error(dbBind(res, bind_values), ".*")
    }
  },
  bind_multi_row = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:200>
    # @section Specification:
    # The elements of the `params` argument do not need to be scalars,
    # vectors of arbitrary length
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- list(1:3)
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 3L)
      result <- data.frame(a = c(1.5, 2.5, 2.5))
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_multi_row_zero_length = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:211>
    # (including length 0)
    # are supported.
    # For queries, calling `dbFetch()` binding such parameters returns
    # concatenated results, equivalent to binding and fetching for each set
    # of values and connecting via [rbind()].
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- list(integer(0), integer(0))
      placeholder <- placeholder_fun(2L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 0L)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_multi_row_statement = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:227>
    # For data manipulation statements, `dbGetRowsAffected()` returns the
    # total number of rows affected if binding non-scalar parameters.
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected
    for (placeholder_fun in placeholder_funs) {
      bind_values <- list(1:3)
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      data <- data.frame(a = rep(1:5, 1:5), b = 1:15)
      table_name <- random_table_name()
      dbWriteTable(con, table_name, data, temporary = TRUE)
      sql <- paste0("UPDATE ", dbQuoteIdentifier(con, table_name), " SET b = b + 1 WHERE ")
      sql <- paste0(sql, "a = ", placeholder[[1L]])
      res <- dbSendStatement(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows_affected <- dbGetRowsAffected(res)
      if (!isTRUE(allow_na_rows_affected) || !is.na(rows_affected)) {
        expect_equal(rows_affected, 6L)
      }
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_repeated = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:239>
    # `dbBind()` also accepts repeated calls on the same result set
    # for both queries
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1L
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5)
      expect_equal(rows, result)
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_repeated_statement = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:252>
    # and data manipulation statements,
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1L
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      data <- data.frame(a = rep(1:5, 1:5), b = 1:15)
      table_name <- random_table_name()
      dbWriteTable(con, table_name, data, temporary = TRUE)
      sql <- paste0("UPDATE ", dbQuoteIdentifier(con, table_name), " SET b = b + 1 WHERE ")
      sql <- paste0(sql, "a = ", placeholder[[1L]])
      res <- dbSendStatement(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows_affected <- dbGetRowsAffected(res)
      if (!isTRUE(allow_na_rows_affected) || !is.na(rows_affected)) {
        expect_equal(rows_affected, 1L)
      }
      dbBind(res, bind_values)
      rows_affected <- dbGetRowsAffected(res)
      if (!isTRUE(allow_na_rows_affected) || !is.na(rows_affected)) {
        expect_equal(rows_affected, 1L)
      }
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_repeated_untouched = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:265>
    # even if no results are fetched between calls to `dbBind()`,
    # for both queries
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1L
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_repeated_untouched_statement = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:280>
    # and data manipulation statements.
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    allow_na_rows_affected <- ctx$tweaks$allow_na_rows_affected
    for (placeholder_fun in placeholder_funs) {
      bind_values <- 1L
      placeholder <- placeholder_fun(1L)
      names(bind_values) <- names(placeholder)
      data <- data.frame(a = rep(1:5, 1:5), b = 1:15)
      table_name <- random_table_name()
      dbWriteTable(con, table_name, data, temporary = TRUE)
      sql <- paste0("UPDATE ", dbQuoteIdentifier(con, table_name), " SET b = b + 1 WHERE ")
      sql <- paste0(sql, "a = ", placeholder[[1L]])
      res <- dbSendStatement(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      dbBind(res, bind_values)
      rows_affected <- dbGetRowsAffected(res)
      if (!isTRUE(allow_na_rows_affected) || !is.na(rows_affected)) {
        expect_equal(rows_affected, 1L)
      }
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_named_param_shuffle = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:296>
    # If the placeholders in the query are named,
    # their order in the `params` argument is not important.
    placeholder_funs <- get_placeholder_funs(ctx, requires_names = TRUE)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- c(1.5, 2.5, 3.5, NA)
      placeholder <- placeholder_fun(4L)
      names(bind_values) <- names(placeholder)
      bind_values_patched <- bind_values[c(3, 1, 2, 4)]
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[4L] <- paste0("(", is_null_check(placeholder[4L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values_patched)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_integer = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:312>
    # At least the following data types are accepted on input (including [NA]):
    # - [integer]
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- c(1L, 2L, 3L, NA)
      placeholder <- placeholder_fun(4L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[4L] <- paste0("(", is_null_check(placeholder[4L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_numeric = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:322>
    # - [numeric]
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- c(1.5, 2.5, 3.5, NA)
      placeholder <- placeholder_fun(4L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[4L] <- paste0("(", is_null_check(placeholder[4L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_logical = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:331>
    # - [logical] for Boolean values
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- c(TRUE, FALSE, NA)
      placeholder <- placeholder_fun(3L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[3L] <- paste0("(", is_null_check(placeholder[3L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_character = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:340>
    # - [character]
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- c("\U{41A}\U{438}\U{440}\U{438}\U{43B}\U{43B}", "M\U{FC}ller", "M\U{FC}ller", "\U{6211}\U{662F}\U{8C01}", "ASCII", NA)
      placeholder <- placeholder_fun(6L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[6L] <- paste0("(", is_null_check(placeholder[6L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[5L]], " THEN 1.5 ELSE 2.5 END AS e, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[6L]], " THEN 1.5 ELSE 2.5 END AS f")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5, e = 1.5, f = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_character_escape = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:349>
    # (also with special characters such as spaces, newlines, quotes, and backslashes)
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- c(" ", "\n", "\r", "\b", "'", "\"", "[", "]", "\\", NA)
      placeholder <- placeholder_fun(10L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[10L] <- paste0("(", is_null_check(placeholder[10L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[5L]], " THEN 1.5 ELSE 2.5 END AS e, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[6L]], " THEN 1.5 ELSE 2.5 END AS f, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[7L]], " THEN 1.5 ELSE 2.5 END AS g, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[8L]], " THEN 1.5 ELSE 2.5 END AS h, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[9L]], " THEN 1.5 ELSE 2.5 END AS i, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[10L]], " THEN 1.5 ELSE 2.5 END AS j")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5, e = 1.5, f = 1.5, g = 1.5, h = 1.5, i = 1.5, j = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_factor = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:358>
    # - [factor] (bound as character,
    # with warning)
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- list(factor("\U{41A}\U{438}\U{440}\U{438}\U{43B}\U{43B}"), factor("M\U{FC}ller"), factor("M\U{FC}ller"), factor("\U{6211}\U{662F}\U{8C01}"), factor("ASCII"), factor(NA_character_))
      placeholder <- placeholder_fun(6L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[6L] <- paste0("(", is_null_check(placeholder[6L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[5L]], " THEN 1.5 ELSE 2.5 END AS e, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[6L]], " THEN 1.5 ELSE 2.5 END AS f")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      suppressWarnings(expect_warning(dbBind(res, bind_values)))
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5, e = 1.5, f = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_date = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:370>
    # - [Date]
    skip_if(!isTRUE(ctx$tweaks$date_typed))
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- as.Date(c("2023-12-17", "2023-12-18", "2023-12-19", NA))
      placeholder <- placeholder_fun(4L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[4L] <- paste0("(", is_null_check(placeholder[4L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_date_integer = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:380>
    # (also when stored internally as integer)
    skip_if(!isTRUE(ctx$tweaks$date_typed))
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- structure(c(18618L, 18619L, 18620L, NA), class = "Date")
      placeholder <- placeholder_fun(4L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[4L] <- paste0("(", is_null_check(placeholder[4L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_timestamp = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:390>
    # - [POSIXct] timestamps
    skip_if(!isTRUE(ctx$tweaks$timestamp_typed))
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- as.POSIXct(c("2023-12-17 02:40:22", "2023-12-17 02:40:23", "2023-12-17 02:40:24", NA))
      placeholder <- placeholder_fun(4L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[4L] <- paste0("(", is_null_check(placeholder[4L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_timestamp_lt = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:406>
    # - [POSIXlt] timestamps
    skip_if(!isTRUE(ctx$tweaks$timestamp_typed))
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- list(structure(as.POSIXlt(as.POSIXct("2023-12-17 02:40:49")), balanced = TRUE), structure(as.POSIXlt(as.POSIXct("2023-12-17 02:40:50")), balanced = TRUE), structure(as.POSIXlt(as.POSIXct("2023-12-17 02:40:51")), balanced = TRUE), structure(as.POSIXlt(NA_character_), balanced = TRUE))
      placeholder <- placeholder_fun(4L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[4L] <- paste0("(", is_null_check(placeholder[4L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_time_seconds = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:422>
    # - [difftime] values
    skip_if(!isTRUE(ctx$tweaks$time_typed))
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- structure(c(1, 2, 3, NA), class = "difftime", units = "secs")
      placeholder <- placeholder_fun(4L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[4L] <- paste0("(", is_null_check(placeholder[4L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_time_hours = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:433>
    # (also with units other than seconds
    skip_if(!isTRUE(ctx$tweaks$time_typed))
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- structure(c(1, 2, 3, NA), class = "difftime", units = "hours")
      placeholder <- placeholder_fun(4L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[4L] <- paste0("(", is_null_check(placeholder[4L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_time_minutes_integer = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:444>
    # and with the value stored as integer)
    skip_if(!isTRUE(ctx$tweaks$time_typed))
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    for (placeholder_fun in placeholder_funs) {
      bind_values <- structure(c(1, 2, 3, NA), class = "difftime", units = "mins")
      placeholder <- placeholder_fun(4L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", placeholder, " = ", placeholder_values, ")")
      result_check[4L] <- paste0("(", is_null_check(placeholder[4L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[4L]], " THEN 1.5 ELSE 2.5 END AS d")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5, d = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_raw = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:455>
    # - lists of [raw] for blobs (with `NULL` entries for SQL NULL values)
    skip_if(isTRUE(ctx$tweaks$omit_blob_tests))
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    cast_fun <- ctx$tweaks$blob_cast
    for (placeholder_fun in placeholder_funs) {
      bind_values <- list(list(as.raw(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))), list(raw(3)), list(NULL))
      placeholder <- placeholder_fun(3L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", cast_fun(placeholder), " = ", placeholder_values, ")")
      result_check[3L] <- paste0("(", is_null_check(cast_fun(placeholder)[3L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  bind_blob = function(ctx, con) {
    # <R/spec-meta-bind-expr.R:467>
    # - objects of type [blob::blob]
    skip_if(isTRUE(ctx$tweaks$omit_blob_tests))
    placeholder_funs <- get_placeholder_funs(ctx)
    is_null_check <- ctx$tweaks$is_null_check
    cast_fun <- ctx$tweaks$blob_cast
    for (placeholder_fun in placeholder_funs) {
      bind_values <- list(
        structure(vctrs::list_of(as.raw(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), .ptype = raw(0)), class = c("blob", "vctrs_list_of", "vctrs_vctr", "list")),
        structure(vctrs::list_of(raw(3), .ptype = raw(0)), class = c("blob", "vctrs_list_of", "vctrs_vctr", "list")),
        structure(vctrs::list_of(NULL, .ptype = raw(0)), class = c("blob", "vctrs_list_of", "vctrs_vctr", "list"))
      )
      placeholder <- placeholder_fun(3L)
      names(bind_values) <- names(placeholder)
      placeholder_values <- map_chr(bind_values, function(x) DBI::dbQuoteLiteral(con, x[1]))
      result_check <- paste0("(", cast_fun(placeholder), " = ", placeholder_values, ")")
      result_check[3L] <- paste0("(", is_null_check(cast_fun(placeholder)[3L]), ")")
      sql <- "SELECT "
      sql <- paste0(sql, "CASE WHEN ", result_check[[1L]], " THEN 1.5 ELSE 2.5 END AS a, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[2L]], " THEN 1.5 ELSE 2.5 END AS b, ")
      sql <- paste0(sql, "CASE WHEN ", result_check[[3L]], " THEN 1.5 ELSE 2.5 END AS c")
      res <- dbSendQuery(con, sql)
      on.exit(if (!is.null(res)) expect_error(dbClearResult(res), NA))
      dbBind(res, bind_values)
      rows <- check_df(dbFetch(res))
      expect_equal(nrow(rows), 1L)
      result <- data.frame(a = 1.5, b = 1.5, c = 1.5)
      expect_equal(rows, result)
      expect_error(dbClearResult(res), NA)
      res <- NULL
    }
  },
  NULL
)
r-dbi/DBItest documentation built on April 15, 2024, 11:26 a.m.