Skip to content

Commit

Permalink
Allow db_query_fields to work with queries and tables
Browse files Browse the repository at this point in the history
Fixes #218
  • Loading branch information
hadley committed Apr 12, 2018
1 parent d311384 commit b23c220
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 3 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Expand Up @@ -43,6 +43,8 @@ The old API has been soft-deprecated - it will continue to work, but no further

## Other bug fixes and improvements

* The dplyr interface can work with literal SQL once more (#218).

* The DBI interface has been updated to use the new low-level API.
This means that it defaults to using modern SQL not legacy SQL.
Use `use_legacy_sql = TRUE` in `DBI::dbConnect()` if you need to use
Expand Down
6 changes: 5 additions & 1 deletion R/bq-query.R
Expand Up @@ -82,7 +82,7 @@ bq_dataset_query <- function(x, query,

# Similar to bq_perform_query: except uses dryRun, and hence result
# processing is totally different
bq_query_fields <- function(query, x, ..., use_legacy_sql = FALSE) {
bq_query_fields <- function(query, x, ..., default_dataset = NULL, use_legacy_sql = FALSE) {
assert_that(is.string(x), is.string(query))

url <- bq_path(x, jobs = "")
Expand All @@ -91,6 +91,10 @@ bq_query_fields <- function(query, x, ..., use_legacy_sql = FALSE) {
query = unbox(query),
useLegacySql = unbox(use_legacy_sql)
)
if (!is.null(default_dataset)) {
query$defaultDataset <- datasetReference(default_dataset)
}

body <- list(configuration = list(query = query, dryRun = TRUE))

res <- bq_post(
Expand Down
11 changes: 9 additions & 2 deletions R/dplyr.R
Expand Up @@ -60,8 +60,15 @@ tbl.src_bigquery <- function(src, from, ...) {

# registered onLoad
db_query_fields.BigQueryConnection <- function(con, sql) {
info <- get_table(con@project, con@dataset, sql)
vapply(info$schema$fields, "[[", "name", FUN.VALUE = character(1))
if (dbplyr::is.sql(sql)) {
ds <- bq_dataset(con@project, con@dataset)
fields <- bq_query_fields(sql, con@billing, default_dataset = ds)
} else {
tb <- bq_table(con@project, con@dataset, sql)
fields <- bq_table_fields(tb)
}

vapply(fields, "[[", "name", FUN.VALUE = character(1))
}

# SQL translation -------------------------------------------------------------
Expand Down
12 changes: 12 additions & 0 deletions tests/testthat/test-dplyr.R
@@ -1,5 +1,17 @@
context("dplyr.R")

test_that("can work with literal SQL", {
con_us <- DBI::dbConnect(
dbi_driver(),
project = "bigquery-public-data",
dataset = "utility_us",
billing = bq_test_project()
)

x <- tbl(con_us, sql("SELECT * FROM country_code_iso"))
expect_true("fips_code" %in% dbplyr::op_vars(x))
})

test_that("casting uses bigquery types", {
skip_if_not_installed("dbplyr")

Expand Down

0 comments on commit b23c220

Please sign in to comment.