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

translate_sql, as.character in combination with %in% #3205

Closed
jessekps opened this issue Nov 13, 2017 · 5 comments
Closed

translate_sql, as.character in combination with %in% #3205

jessekps opened this issue Nov 13, 2017 · 5 comments
Labels
bug an unexpected problem or unintended behavior

Comments

@jessekps
Copy link

dbplyr
version 1.1.0

If I use %in% in combination with as.character, translate_sql generates SQL that is not valid for sqlite

library(RSQLite)
library(dbplyr)
db = dbConnect(SQLite(), ':memory:')

translate_sql(booklet_id %in% as.character(1:4), con=db )
#> <SQL> "booklet_id" IN CAST((1, 2, 3, 4) AS TEXT)

In postgres and possibly other dbms this would be accepted but not in sqlite where it should be:

"booklet_id" IN( CAST(1 AS TEXT), CAST(2 AS TEXT), CAST(3 AS TEXT), CAST(4 AS TEXT))

(running it through partial_eval and translate_sql_ gives the exact same problem)

Thanks for the very nice package by the way!

@krlmlr krlmlr added bug an unexpected problem or unintended behavior database labels Dec 12, 2017
@krlmlr
Copy link
Member

krlmlr commented Dec 12, 2017

Thanks, confirmed. I'm seeing on PostgreSQL:

> echo "SELECT '1' in cast((1, 2, 3, 4) as text)" | psql
ERROR:  syntax error at or near "cast"
LINE 1: SELECT '1' in cast((1, 2, 3, 4) as text)
> echo "SELECT '1' in (cast(1 as text), cast(2 as text))" | psql
 ?column? 
----------
 t
(1 row)

Seems we need to adapt it there, too (at least).

@edgararuiz-zz
Copy link

Hi @jessekps / @krlmlr - I don't see a way for dbplyr to know to override passing a translated vector function, such as as.character(), without any input from the user.

Having said that, there is a way to make sure that the R function is evaluated prior sending it to the query, and that's by using rlang 's !!:

library(RSQLite)                                            
library(dbplyr)                                             
library(rlang)                                              
                                                            
db <- dbConnect(SQLite(), ':memory:')                       
                                                            
translate_sql(booklet_id %in% !! as.character(1:4), con=db )
#> <SQL> `booklet_id` IN ('1', '2', '3', '4')
                                                            
dbDisconnect(db)    

@jessekps
Copy link
Author

Ok, thanks for looking into it anyway, much appreciated. I know about the !! but unfortunately I'm passing through an r statement from users of my package so I have no control over that. And since I'm trying to take some of the sql complexity away from the user, I don't want to replace it by them having to learn about !!.

Currently I'm fixing the translate_sql output with regular expressions. It works fine for my package but it's not a structural solution you would want I expect.

@hadley
Copy link
Member

hadley commented May 20, 2018

This is currently out of scope for dbplyr sql translation.

@hadley hadley closed this as completed May 20, 2018
@lock
Copy link

lock bot commented Nov 16, 2018

This old issue has been automatically locked. If you believe you have found a related problem, please file a new issue (with reprex) and link to this issue. https://reprex.tidyverse.org/

@lock lock bot locked and limited conversation to collaborators Nov 16, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

4 participants