From 35083016df37dbe6b5d0d14f91d3afc2691d65e5 Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Thu, 15 Feb 2024 08:46:39 -0600 Subject: [PATCH] Revert #1292 If ROWNUM is used, we need to wrap it in a subquery, and I don't think that's worth it, given that the version of Oracle that supports FETCH FIRST is now 10 years old. Fixes #1436 --- NEWS.md | 4 ++++ R/backend-oracle.R | 10 +++++----- tests/testthat/_snaps/backend-oracle.md | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/NEWS.md b/NEWS.md index b1050c0b2..0a744f208 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ # dbplyr (development version) +* Oracle once again translates `head()` to `FETCH FIRST`. This does require + Oracle 12c, but it actually works, compared to the approach using `ROWNUM` + from #1292 (#1436). + * The databricks backend now supports creating non-temporary tables too (#1418). * Clearer error if you attempt to embed non-atomic vectors inside of a generated diff --git a/R/backend-oracle.R b/R/backend-oracle.R index 91000ff0f..cad33049c 100644 --- a/R/backend-oracle.R +++ b/R/backend-oracle.R @@ -48,11 +48,6 @@ sql_query_select.Oracle <- function(con, subquery = FALSE, lvl = 0) { - if (!is.null(limit)) { - limit <- as.integer(limit) - where = c(paste0("ROWNUM <= ", limit), where) - } - sql_select_clauses(con, select = sql_clause_select(con, select, distinct), from = sql_clause_from(from), @@ -61,6 +56,11 @@ sql_query_select.Oracle <- function(con, having = sql_clause_having(having), window = sql_clause_window(window), order_by = sql_clause_order_by(order_by, subquery, limit), + # Requires Oracle 12c, released in 2013 + limit = if (!is.null(limit)) { + limit <- format(as.integer(limit)) + glue_sql2(con, "FETCH FIRST {limit} ROWS ONLY") + }, lvl = lvl ) } diff --git a/tests/testthat/_snaps/backend-oracle.md b/tests/testthat/_snaps/backend-oracle.md index e50731905..aa17cd6b4 100644 --- a/tests/testthat/_snaps/backend-oracle.md +++ b/tests/testthat/_snaps/backend-oracle.md @@ -17,7 +17,7 @@ SELECT `df`.* FROM `df` - WHERE (ROWNUM <= 6) + FETCH FIRST 6 ROWS ONLY # `sql_query_upsert()` is correct