Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug using prefixed function names with dbplyr #1022

Closed
akgold opened this issue Oct 17, 2022 · 4 comments
Closed

Bug using prefixed function names with dbplyr #1022

akgold opened this issue Oct 17, 2022 · 4 comments
Assignees
Labels
bug an unexpected problem or unintended behavior func trans 🌍 Translation of individual functions to SQL
Milestone

Comments

@akgold
Copy link

akgold commented Oct 17, 2022

When using functions in dplyr against databases, prefixing certain functions seems to cause those functions to evaluate variable names in the global context, not the context of the data frame.

This isn't quite reprex-able, because I am not including making the connection.

In my case, con is a connection to a Postgres database using RPostgres. I suspect that doesn't matter based on how the error is showing up.

df <- tbl(con, "my_table")
> df %>% mutate(status = paste(subject, "abc")) #this works
# Source:   lazy query [?? x 18]
# Database: postgres [db@db.rds.amazonaws.com:5432/postgres]
... #excluded for confidentiality
> df %>% mutate(status = base::paste(subject, "abc"))
Error in base::paste(subject, "abc") : object 'subject' not found
@hadley
Copy link
Member

hadley commented Oct 17, 2022

Reprex with actual function involved in original problem:

library(dbplyr)
library(dplyr, warn.conflicts = FALSE)

df <- lazy_frame(subject = "x", con = simulate_postgres())
df %>% mutate(status = stringr::str_detect(subject, "abc"))
#> <SQL>
#> SELECT *, `subject` ~ 'abc' AS `status`
#> FROM `df`

Created on 2022-10-17 with reprex v2.0.2

Which does work

@hadley hadley added bug an unexpected problem or unintended behavior func trans 🌍 Translation of individual functions to SQL labels Dec 5, 2022
@mgirlich
Copy link
Collaborator

@hadley There is a test that basically tests that functions with the base namespace are evaluated locally:

test_that("namespace operators always evaluated locally", {
  lf <- lazy_frame(x = 1, y = 2)

  expect_equal(partial_eval(quote(base::sum(1, 2)), lf), 3)
  expect_equal(partial_eval(quote(base:::sum(1, 2)), lf), 3)
})

but there is also the test to strip namespaces

test_that("namespaced calls to dplyr functions are stripped", {
  lf <- lazy_frame(x = 1, y = 2)

  expect_equal(partial_eval(quote(dplyr::n()), lf), expr(n()))
  expect_equal(partial_eval(quote(base::round(x)), lf), expr(round(x)))
  # hack to avoid check complaining about not declared imports
  expect_equal(partial_eval(rlang::parse_expr("stringr::str_to_lower(x)"), lf), expr(str_to_lower(x)))
  expect_equal(partial_eval(rlang::parse_expr("lubridate::today()"), lf), expr(today()))
})

Changing this might be a breaking change... What do you think?

@mgirlich mgirlich self-assigned this Oct 27, 2023
@mgirlich mgirlich added this to the 2.5.0 milestone Oct 27, 2023
@hadley
Copy link
Member

hadley commented Oct 27, 2023

I'm guessing I just missed this in #197; I don't think the base namespace should be an exception to the general rule. It seems unlikely to break much code since I don't think many people will have prefixed with base::.

@mgirlich
Copy link
Collaborator

Closed by 2dfcfba

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug an unexpected problem or unintended behavior func trans 🌍 Translation of individual functions to SQL
Projects
None yet
Development

No branches or pull requests

3 participants