From 3878b57a33e1a9dac78b66886d680bfbcdbe467b Mon Sep 17 00:00:00 2001 From: edward-burn <9583964+edward-burn@users.noreply.github.com> Date: Sat, 4 May 2024 20:05:41 +0100 Subject: [PATCH 1/5] date_count_between translation --- R/backend-mssql.R | 12 ++++++++++++ R/backend-postgres.R | 12 ++++++++++++ R/backend-redshift.R | 12 ++++++++++++ R/backend-snowflake.R | 12 ++++++++++++ R/backend-spark-sql.R | 12 ++++++++++++ tests/testthat/test-backend-mssql.R | 4 ++++ tests/testthat/test-backend-postgres.R | 4 ++++ tests/testthat/test-backend-redshift.R | 4 ++++ tests/testthat/test-backend-snowflake.R | 4 ++++ tests/testthat/test-backend-spark-sql.R | 4 ++++ 10 files changed, 80 insertions(+) diff --git a/R/backend-mssql.R b/R/backend-mssql.R index 1850e6d89..35d85fa78 100644 --- a/R/backend-mssql.R +++ b/R/backend-mssql.R @@ -372,6 +372,18 @@ simulate_mssql <- function(version = "15.0") { get_day = function(x) { sql_expr(DATEPART(DAY, !!x)) }, + date_count_between = function(start, end, precision, ..., n = 1L){ + + check_dots_empty() + if (precision != "day") { + cli::cli_abort('The only supported value for {.arg precision} on SQL backends is "day"') + } + if (n != 1) { + cli::cli_abort('The only supported value for {.arg n} on SQL backends is "1"') + } + + sql_expr(DATEDIFF(DAY, !!start, !!end)) + }, difftime = function(time1, time2, tz, units = "days") { diff --git a/R/backend-postgres.R b/R/backend-postgres.R index 5f9f0ba6f..70ef0bfb5 100644 --- a/R/backend-postgres.R +++ b/R/backend-postgres.R @@ -248,6 +248,18 @@ sql_translation.PqConnection <- function(con) { date_build = function(year, month = 1L, day = 1L, ..., invalid = NULL) { sql_expr(make_date(!!year, !!month, !!day)) }, + date_count_between = function(start, end, precision, ..., n = 1L){ + + check_dots_empty() + if (precision != "day") { + cli::cli_abort('The only supported value for {.arg precision} on SQL backends is "day"') + } + if (n != 1) { + cli::cli_abort('The only supported value for {.arg n} on SQL backends is "1"') + } + + sql_expr(!!end - !!start) + }, get_year = function(x) { sql_expr(date_part('year', !!x)) }, diff --git a/R/backend-redshift.R b/R/backend-redshift.R index b3f35d3c5..09f3640f9 100644 --- a/R/backend-redshift.R +++ b/R/backend-redshift.R @@ -83,6 +83,18 @@ sql_translation.RedshiftConnection <- function(con) { get_day = function(x) { sql_expr(DATE_PART('day', !!x)) }, + date_count_between = function(start, end, precision, ..., n = 1L){ + + check_dots_empty() + if (precision != "day") { + cli::cli_abort('The only supported value for {.arg precision} on SQL backends is "day"') + } + if (n != 1) { + cli::cli_abort('The only supported value for {.arg n} on SQL backends is "1"') + } + + sql_expr(DATEDIFF(DAY, !!start, !!end)) + }, difftime = function(time1, time2, tz, units = "days") { diff --git a/R/backend-snowflake.R b/R/backend-snowflake.R index afb696f2d..0e396292b 100644 --- a/R/backend-snowflake.R +++ b/R/backend-snowflake.R @@ -232,6 +232,18 @@ sql_translation.Snowflake <- function(con) { get_day = function(x) { sql_expr(DATE_PART(DAY, !!x)) }, + date_count_between = function(start, end, precision, ..., n = 1L){ + + check_dots_empty() + if (precision != "day") { + cli::cli_abort('The only supported value for {.arg precision} on SQL backends is "day"') + } + if (n != 1) { + cli::cli_abort('The only supported value for {.arg n} on SQL backends is "1"') + } + + sql_expr(DATEDIFF(DAY, !!start, !!end)) + }, difftime = function(time1, time2, tz, units = "days") { diff --git a/R/backend-spark-sql.R b/R/backend-spark-sql.R index 8cd9288d1..c162f5ac0 100644 --- a/R/backend-spark-sql.R +++ b/R/backend-spark-sql.R @@ -58,6 +58,18 @@ simulate_spark_sql <- function() simulate_dbi("Spark SQL") get_day = function(x) { sql_expr(date_part('DAY', !!x)) }, + date_count_between = function(start, end, precision, ..., n = 1L){ + + check_dots_empty() + if (precision != "day") { + cli::cli_abort('The only supported value for {.arg precision} on SQL backends is "day"') + } + if (n != 1) { + cli::cli_abort('The only supported value for {.arg n} on SQL backends is "1"') + } + + sql_expr(datediff(!!end, !!start)) + }, difftime = function(time1, time2, tz, units = "days") { diff --git a/tests/testthat/test-backend-mssql.R b/tests/testthat/test-backend-mssql.R index bab3508d3..a39ae258c 100644 --- a/tests/testthat/test-backend-mssql.R +++ b/tests/testthat/test-backend-mssql.R @@ -139,6 +139,10 @@ test_that("custom clock functions translated correctly", { expect_equal(test_translate_sql(get_year(date_column)), sql("DATEPART(YEAR, `date_column`)")) expect_equal(test_translate_sql(get_month(date_column)), sql("DATEPART(MONTH, `date_column`)")) expect_equal(test_translate_sql(get_day(date_column)), sql("DATEPART(DAY, `date_column`)")) + expect_equal(test_translate_sql(date_count_between(date_column_1, date_column_2, "day")), + sql("DATEDIFF(DAY, `date_column_1`, `date_column_2`)")) + expect_error(test_translate_sql(date_count_between(date_column_1, date_column_2, "year"))) + expect_error(test_translate_sql(date_count_between(date_column_1, date_column_2, "day", n = 5))) }) test_that("difftime is translated correctly", { diff --git a/tests/testthat/test-backend-postgres.R b/tests/testthat/test-backend-postgres.R index 0517f195e..e9f137398 100644 --- a/tests/testthat/test-backend-postgres.R +++ b/tests/testthat/test-backend-postgres.R @@ -98,6 +98,10 @@ test_that("custom clock functions translated correctly", { expect_equal(test_translate_sql(get_year(date_column)), sql("DATE_PART('year', `date_column`)")) expect_equal(test_translate_sql(get_month(date_column)), sql("DATE_PART('month', `date_column`)")) expect_equal(test_translate_sql(get_day(date_column)), sql("DATE_PART('day', `date_column`)")) + expect_equal(test_translate_sql(date_count_between(date_column_1, date_column_2, "day")), + sql("`date_column_2` - `date_column_1`")) + expect_error(test_translate_sql(date_count_between(date_column_1, date_column_2, "year"))) + expect_error(test_translate_sql(date_count_between(date_column_1, date_column_2, "day", n = 5))) }) test_that("difftime is translated correctly", { diff --git a/tests/testthat/test-backend-redshift.R b/tests/testthat/test-backend-redshift.R index f2b5a9699..7f586a738 100644 --- a/tests/testthat/test-backend-redshift.R +++ b/tests/testthat/test-backend-redshift.R @@ -68,6 +68,10 @@ test_that("custom clock functions translated correctly", { expect_equal(test_translate_sql(get_year(date_column)), sql("DATE_PART('year', `date_column`)")) expect_equal(test_translate_sql(get_month(date_column)), sql("DATE_PART('month', `date_column`)")) expect_equal(test_translate_sql(get_day(date_column)), sql("DATE_PART('day', `date_column`)")) + expect_equal(test_translate_sql(date_count_between(date_column_1, date_column_2, "day")), + sql("DATEDIFF(DAY, `date_column_1`, `date_column_2`)")) + expect_error(test_translate_sql(date_count_between(date_column_1, date_column_2, "year"))) + expect_error(test_translate_sql(date_count_between(date_column_1, date_column_2, "day", n = 5))) }) test_that("difftime is translated correctly", { diff --git a/tests/testthat/test-backend-snowflake.R b/tests/testthat/test-backend-snowflake.R index 37c50828f..ac4facc5c 100644 --- a/tests/testthat/test-backend-snowflake.R +++ b/tests/testthat/test-backend-snowflake.R @@ -112,6 +112,10 @@ test_that("custom clock functions translated correctly", { expect_equal(test_translate_sql(get_year(date_column)), sql("DATE_PART(YEAR, `date_column`)")) expect_equal(test_translate_sql(get_month(date_column)), sql("DATE_PART(MONTH, `date_column`)")) expect_equal(test_translate_sql(get_day(date_column)), sql("DATE_PART(DAY, `date_column`)")) + expect_equal(test_translate_sql(date_count_between(date_column_1, date_column_2, "day")), + sql("DATEDIFF(DAY, `date_column_1`, `date_column_2`)")) + expect_error(test_translate_sql(date_count_between(date_column_1, date_column_2, "year"))) + expect_error(test_translate_sql(date_count_between(date_column_1, date_column_2, "day", n = 5))) }) test_that("difftime is translated correctly", { diff --git a/tests/testthat/test-backend-spark-sql.R b/tests/testthat/test-backend-spark-sql.R index e1276c7a0..5332457d3 100644 --- a/tests/testthat/test-backend-spark-sql.R +++ b/tests/testthat/test-backend-spark-sql.R @@ -8,6 +8,10 @@ test_that("custom clock functions translated correctly", { expect_equal(test_translate_sql(get_year(date_column)), sql("DATE_PART('YEAR', `date_column`)")) expect_equal(test_translate_sql(get_month(date_column)), sql("DATE_PART('MONTH', `date_column`)")) expect_equal(test_translate_sql(get_day(date_column)), sql("DATE_PART('DAY', `date_column`)")) + expect_equal(test_translate_sql(date_count_between(date_column_1, date_column_2, "day")), + sql("DATEDIFF(`date_column_2`, `date_column_1`)")) + expect_error(test_translate_sql(date_count_between(date_column_1, date_column_2, "year"))) + expect_error(test_translate_sql(date_count_between(date_column_1, date_column_2, "day", n = 5))) }) test_that("difftime is translated correctly", { From 19bd18b92e5ca960f7a686adaf7df8077067d92d Mon Sep 17 00:00:00 2001 From: edward-burn <9583964+edward-burn@users.noreply.github.com> Date: Sat, 4 May 2024 20:48:45 +0100 Subject: [PATCH 2/5] update news --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index dae72d35d..1f749bac5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,7 @@ * `across(everything())` doesn't select grouping columns created via `.by` in `summarise()` (@mgirlich, #1493). +* New translations of clock function `date_count_between()` for SQL server, Redshift, Snowflake, Postgres, and Spark (@edward-burn, #1495). # dbplyr 2.5.0 From 8092731c399d32c87b4582041a5e3b2e6f1d0bb0 Mon Sep 17 00:00:00 2001 From: edward-burn <9583964+edward-burn@users.noreply.github.com> Date: Wed, 16 Oct 2024 08:20:42 +0100 Subject: [PATCH 3/5] Update NEWS.md Co-authored-by: Simon P. Couch --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 88314da09..70164c416 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,7 +2,9 @@ * `across(everything())` doesn't select grouping columns created via `.by` in `summarise()` (@mgirlich, #1493). + * New translations of clock function `date_count_between()` for SQL server, Redshift, Snowflake, Postgres, and Spark (@edward-burn, #1495). + * Spark SQL backend now supports persisting tables with `compute(x, name = I("x.y.z"), temporary = FALSE)` (@zacdav-db, #1502). From 03a41fe7f2dbbb2fe17b2ed16233270b48eed9f6 Mon Sep 17 00:00:00 2001 From: edward-burn <9583964+edward-burn@users.noreply.github.com> Date: Wed, 16 Oct 2024 08:21:33 +0100 Subject: [PATCH 4/5] Update R/backend-mssql.R Co-authored-by: Simon P. Couch --- R/backend-mssql.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/backend-mssql.R b/R/backend-mssql.R index 35d85fa78..35485f684 100644 --- a/R/backend-mssql.R +++ b/R/backend-mssql.R @@ -376,7 +376,7 @@ simulate_mssql <- function(version = "15.0") { check_dots_empty() if (precision != "day") { - cli::cli_abort('The only supported value for {.arg precision} on SQL backends is "day"') + cli_abort("{.arg precision} must be {.val day} on SQL backends.") } if (n != 1) { cli::cli_abort('The only supported value for {.arg n} on SQL backends is "1"') From 9fafafd0c4604d3b238985eb60dad27a183e6237 Mon Sep 17 00:00:00 2001 From: edward-burn <9583964+edward-burn@users.noreply.github.com> Date: Wed, 16 Oct 2024 08:36:30 +0100 Subject: [PATCH 5/5] update error messages --- R/backend-mssql.R | 2 +- R/backend-postgres.R | 4 ++-- R/backend-redshift.R | 4 ++-- R/backend-snowflake.R | 4 ++-- R/backend-spark-sql.R | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/R/backend-mssql.R b/R/backend-mssql.R index 35485f684..015c1f2a0 100644 --- a/R/backend-mssql.R +++ b/R/backend-mssql.R @@ -379,7 +379,7 @@ simulate_mssql <- function(version = "15.0") { cli_abort("{.arg precision} must be {.val day} on SQL backends.") } if (n != 1) { - cli::cli_abort('The only supported value for {.arg n} on SQL backends is "1"') + cli_abort("{.arg n} must be {.val 1} on SQL backends.") } sql_expr(DATEDIFF(DAY, !!start, !!end)) diff --git a/R/backend-postgres.R b/R/backend-postgres.R index 70ef0bfb5..b93289a0b 100644 --- a/R/backend-postgres.R +++ b/R/backend-postgres.R @@ -252,10 +252,10 @@ sql_translation.PqConnection <- function(con) { check_dots_empty() if (precision != "day") { - cli::cli_abort('The only supported value for {.arg precision} on SQL backends is "day"') + cli_abort("{.arg precision} must be {.val day} on SQL backends.") } if (n != 1) { - cli::cli_abort('The only supported value for {.arg n} on SQL backends is "1"') + cli_abort("{.arg n} must be {.val 1} on SQL backends.") } sql_expr(!!end - !!start) diff --git a/R/backend-redshift.R b/R/backend-redshift.R index 09f3640f9..c1ff03a21 100644 --- a/R/backend-redshift.R +++ b/R/backend-redshift.R @@ -87,10 +87,10 @@ sql_translation.RedshiftConnection <- function(con) { check_dots_empty() if (precision != "day") { - cli::cli_abort('The only supported value for {.arg precision} on SQL backends is "day"') + cli_abort("{.arg precision} must be {.val day} on SQL backends.") } if (n != 1) { - cli::cli_abort('The only supported value for {.arg n} on SQL backends is "1"') + cli_abort("{.arg n} must be {.val 1} on SQL backends.") } sql_expr(DATEDIFF(DAY, !!start, !!end)) diff --git a/R/backend-snowflake.R b/R/backend-snowflake.R index 0e396292b..ddd4e70dd 100644 --- a/R/backend-snowflake.R +++ b/R/backend-snowflake.R @@ -236,10 +236,10 @@ sql_translation.Snowflake <- function(con) { check_dots_empty() if (precision != "day") { - cli::cli_abort('The only supported value for {.arg precision} on SQL backends is "day"') + cli_abort("{.arg precision} must be {.val day} on SQL backends.") } if (n != 1) { - cli::cli_abort('The only supported value for {.arg n} on SQL backends is "1"') + cli_abort("{.arg n} must be {.val 1} on SQL backends.") } sql_expr(DATEDIFF(DAY, !!start, !!end)) diff --git a/R/backend-spark-sql.R b/R/backend-spark-sql.R index 10be0967d..c551f830a 100644 --- a/R/backend-spark-sql.R +++ b/R/backend-spark-sql.R @@ -62,10 +62,10 @@ simulate_spark_sql <- function() simulate_dbi("Spark SQL") check_dots_empty() if (precision != "day") { - cli::cli_abort('The only supported value for {.arg precision} on SQL backends is "day"') + cli_abort("{.arg precision} must be {.val day} on SQL backends.") } if (n != 1) { - cli::cli_abort('The only supported value for {.arg n} on SQL backends is "1"') + cli_abort("{.arg n} must be {.val 1} on SQL backends.") } sql_expr(datediff(!!end, !!start))