tidyverse / dbplyr

Database (DBI) backend for dplyr
https://dbplyr.tidyverse.org
Other
474 stars 173 forks source link

Oracle backend not treated correctly #1519

Open DSLituiev opened 3 months ago

DSLituiev commented 3 months ago

The oracle backend does not get recognised (v. 2.5.0 and main branch @HEAD)

When I force backend to Oracle it works, but I am not sure how to force it in tbl statement:

drv <- JDBC("oracle.jdbc.driver.OracleDriver", "~/lib/instantclient_19_8/ojdbc8.jar")
conn <- dbConnect(drv, 
                  "jdbc:oracle:thin:@host:port/...",
                  user=credentials$user,
                  password=credentials$pwd
)

conn
# <JDBCConnection>
attr(conn, "jc")
# [1] "Java-Object{oracle.jdbc.driver.T4CConnection@...}"

dim_xyz <- tbl(conn, in_schema("MYSCHEMA", "DIM_XYZ"))

dim_xyz

Trying to print the table gets an error:

Error in `collect()`:
! Failed to collect lazy table.
Caused by error in `dbSendQuery()`:
! Unable to retrieve JDBC result set
  JDBC ERROR: ORA-00933: SQL command not properly ended

  Statement: SELECT "DIM_XYZ".*
FROM "MYSCHEMA"."DIM_XYZ"
LIMIT 11

Here are some attempts to get to why it does not use the proper backend:

dbplyr:::test_translate_sql(head, con=conn)
# <SQL> "head"
> dbplyr:::sql_query_select(conn, sql("*"), ident("x"), where=ident("y"), limit=3)
<SQL> SELECT *
FROM "x"
WHERE (y)
LIMIT 3

> dbplyr:::sql_query_select.Oracle(conn, sql("*"), ident("x"), where=ident("y"), limit=3)
<SQL> SELECT *
FROM "x"
WHERE (y)
FETCH FIRST 3 ROWS ONLY
mf <- lazy_frame(x = 1, con = simulate_oracle())
> mf %>% head()
<SQL>
SELECT `df`.*
FROM `df`
FETCH FIRST 6 ROWS ONLY
DSLituiev commented 3 months ago

workaround: wrap the connection into a new S4 class with jc slot copied from the original connection object:

setClass("Oracle", slots=list(),
         contains = "JDBCConnection")
conn_fixed <- new("Oracle", jc = slot(conn, "jc"))