dbplyr local eval unexpected behavior

So I got bit by a breaking change in dbplyr. In 1.4.0 there was a breaking change that impacts where eval happens in dbplyr (local vs on the server).

This code used to work in 1.3 but now breaks:

library(tidyverse)
#> Registered S3 methods overwritten by 'ggplot2':
#>   method         from 
#>   [.quosures     rlang
#>   c.quosures     rlang
#>   print.quosures rlang
testfun <- function(tab, tst_input){
  en_tst <- dplyr::enquo(tst_input)
  tab %>%
    filter(!!en_tst > 15) -> out
  return(out)
}

con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
copy_to(con, mtcars)

mtcars2 <- tbl(con, "mtcars")
testfun(tab = mtcars2, tst_input = mpg)
#> Error in call[[1]]: object of type 'symbol' is not subsettable

but that's easy enough to fix by replacing
filter(!!en_tst > 15)

with

filter(local(!!en_tst) > 15)

Not a huge deal, but it was really tricky for me to debug. And while I'm not super well versed in tidy development, I'm typically reasonably competent. So I was a little surprised how hard this was to figure out.

In the release notes there's mention of changes that break subsetting:

Subsetting ( [[ , $ , and [ ) functions are no longer evaluated locally.

So what changed that makes using !! in dbplyr problematic? Is it the subsetting change mentioned above or is it something else altogether?

FWIW, after the change I mention above, the code works great like this:


library(tidyverse)
#> Registered S3 methods overwritten by 'ggplot2':
#>   method         from 
#>   [.quosures     rlang
#>   c.quosures     rlang
#>   print.quosures rlang
testfun <- function(tab, tst_input){
  en_tst <- dplyr::enquo(tst_input)
  tab %>%
    filter(local(!!en_tst) > 15) -> out
  return(out)
}

con <- DBI::dbConnect(RSQLite::SQLite(), ":memory:")
copy_to(con, mtcars)

mtcars2 <- tbl(con, "mtcars")

testfun(tab = mtcars2, tst_input = mpg)
#> # Source:   lazy query [?? x 11]
#> # Database: sqlite 3.22.0 [:memory:]
#>      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
#>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#>  1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
#>  2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
#>  3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
#>  4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
#>  5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
#>  6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
#>  7  24.4     4  147.    62  3.69  3.19  20       1     0     4     2
#>  8  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
#>  9  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
#> 10  17.8     6  168.   123  3.92  3.44  18.9     1     0     4     4
#> # … with more rows

Created on 2019-06-07 by the reprex package (v0.3.0)

2 Likes

Hey JD,

Thanks for digging down into this one. It sounds like it'd be useful to at the very least expand upon this in the release notes (including the replace-this-with-that) pattern, and (if possible) maybe throw a better error message.

Would you mind filing as an issue in dbplyr?

no problem at all. I didn't start there because I wasn't really sure what was going on or if it was me just not being able to grok the change. I'll go over there and link to it from here.

1 Like

Crossposted over in GitHub.

2 Likes

seems to be a bug... I am so used to the bug being the loose nut behind the keyboard that I find myself shocked.

3 Likes

Hi @jdlong, it seems the bug is now fix in dev version.
If so, could you mark this as solved maybe ?

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.