diff --git a/R/backend-dbplyr__duckdb_connection.R b/R/backend-dbplyr__duckdb_connection.R index a36bf377a..25c1e262c 100644 --- a/R/backend-dbplyr__duckdb_connection.R +++ b/R/backend-dbplyr__duckdb_connection.R @@ -275,10 +275,10 @@ sql_translation.duckdb_connection <- function(con) { # clock add_days = function(x, n, ...) { - build_sql("DATE_ADD(", !!x, ", INTERVAL '", n ," day')") + build_sql("DATE_ADD(", !!x, ", INTERVAL (", n ,") day)") }, add_years = function(x, n, ...) { - build_sql("DATE_ADD(", !!x, ", INTERVAL '", n ," year')") + build_sql("DATE_ADD(", !!x, ", INTERVAL (", n ,") year)") }, get_year = function(x) { build_sql("DATE_PART('year', ", !!x, ")") @@ -302,6 +302,17 @@ sql_translation.duckdb_connection <- function(con) { build_sql("DATEDIFF('day', ", !!start, ", " ,!!end, ")") }, + date_build = function(year, month = 1L, day = 1L, ..., invalid = NULL) { + dbplyr:::check_unsupported_arg(invalid, allow_null = TRUE) + rlang::check_dots_empty() + build_sql("MAKE_DATE(CAST(", year, " AS INTEGER), CAST(", month, " AS INTEGER), CAST(", day, " AS INTEGER))") + + }, + difftime = function(time1, time2, tz, units = "days") { + dbplyr:::check_unsupported_arg(tz) + dbplyr:::check_unsupported_arg(units, allowed = "days") + build_sql("DATEDIFF('day', ", !!time2, ", " ,!!time1, ")") + }, # stringr functions str_c = sql_paste(""), diff --git a/tests/testthat/test-backend-dbplyr__duckdb_connection.R b/tests/testthat/test-backend-dbplyr__duckdb_connection.R index 0a4435c1e..c2ef68d42 100644 --- a/tests/testthat/test-backend-dbplyr__duckdb_connection.R +++ b/tests/testthat/test-backend-dbplyr__duckdb_connection.R @@ -141,11 +141,12 @@ test_that("custom clock functions translated correctly", { translate <- function(...) dbplyr::translate_sql(..., con = con) sql <- function(...) dbplyr::sql(...) - expect_equal(translate(add_days(x, 1L)), sql(r"{DATE_ADD(x, INTERVAL '1 day')}")) - expect_equal(translate(add_days(x, 2L)), sql(r"{DATE_ADD(x, INTERVAL '2 day')}")) + m <- 1 + expect_equal(translate(add_days(x, m)), sql(r"{DATE_ADD(x, INTERVAL (m) day)}")) + expect_equal(translate(add_days(x, 2L)), sql(r"{DATE_ADD(x, INTERVAL (2) day)}")) - expect_equal(translate(add_years(x, 1L)), sql(r"{DATE_ADD(x, INTERVAL '1 year')}")) - expect_equal(translate(add_years(x, 2L)), sql(r"{DATE_ADD(x, INTERVAL '2 year')}")) + expect_equal(translate(add_years(x, m)), sql(r"{DATE_ADD(x, INTERVAL (m) year)}")) + expect_equal(translate(add_years(x, 2L)), sql(r"{DATE_ADD(x, INTERVAL (2) year)}")) expect_equal(translate(get_day(x)), sql(r"{DATE_PART('day', x)}")) expect_equal(translate(get_month(x)), sql(r"{DATE_PART('month', x)}")) @@ -156,6 +157,10 @@ test_that("custom clock functions translated correctly", { precision = "day")), sql(r"{DATEDIFF('day', start, end)}")) + expect_equal(translate(difftime(time1 = "time1", time2 = "time2", units = "days")), sql(r"{DATEDIFF('day', time2, time1)}")) + expect_equal(translate(date_build(year = 2000, month = 08, day = 08)), sql(r"{MAKE_DATE(CAST(2000.0 AS INTEGER), CAST(8.0 AS INTEGER), CAST(8.0 AS INTEGER))}")) + expect_equal(translate(date_build(year = 2000)), sql(r"{MAKE_DATE(CAST(2000.0 AS INTEGER), CAST(1 AS INTEGER), CAST(1 AS INTEGER))}")) + test_data <- data.frame( person = 1L, date_1 = as.Date("2000-01-01"), @@ -197,6 +202,9 @@ test_that("custom clock functions translated correctly", { precision = "day", n = 5))) + expect_error(translate(date_build(year = 2000, month = 08, day = 08, invalid = "next-day"))) + expect_error(translate(difftime(time1, time2, units = "secs"))) + expect_error(translate(difftime(time1, time2, tz = Sys.timezone()))) }) # stringr functions