diff --git a/NEWS.md b/NEWS.md index e08ad2d69..a70ed7323 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # dbplyr (development version) +* Corrected translation of `stringr::str_like()` to use case-sensitive + `LIKE` when argument `ignore_case` is set as `FALSE` (@edward-burn, #1488). + * `clock::add_years()` translates to correct SQL on Spark (@ablack3, #1510). * Translations for `as.double()` and `as.character()` with Teradata previously diff --git a/R/backend-.R b/R/backend-.R index 3557e252d..3ce0b50a4 100644 --- a/R/backend-.R +++ b/R/backend-.R @@ -280,11 +280,16 @@ base_scalar <- sql_translator( str_trim = sql_str_trim, str_c = sql_paste(""), str_sub = sql_str_sub("SUBSTR"), - str_like = function(string, pattern, ignore_case = TRUE) { + # https://docs.getdbt.com/sql-reference/like is typically case sensitive (#1490) + str_like = function(string, pattern, ignore_case = FALSE) { if (isTRUE(ignore_case)) { - sql_expr(!!string %LIKE% !!pattern) + cli_abort(c( + "Backend does not support case insensitive {.fn str_like}.", + i = "Set {.code ignore_case = FALSE} for case sensitive match.", + i = "Use {.fn tolower} on both arguments to achieve a case insensitive match." + )) } else { - cli::cli_abort("Backend only supports case insensitve {.fn str_like}.") + sql_expr(!!string %LIKE% !!pattern) } }, diff --git a/tests/testthat/_snaps/backend-.md b/tests/testthat/_snaps/backend-.md index aab4ac1e7..3760aa7ae 100644 --- a/tests/testthat/_snaps/backend-.md +++ b/tests/testthat/_snaps/backend-.md @@ -47,13 +47,15 @@ Error in `x$id`: ! $ operator is invalid for atomic vectors -# can translate case insensitive like +# can only translate case sensitive str_like Code - test_translate_sql(str_like(x, "abc", ignore_case = FALSE)) + test_translate_sql(str_like(x, "abc", ignore_case = TRUE)) Condition Error in `str_like()`: - ! Backend only supports case insensitve `str_like()`. + ! Backend does not support case insensitive `str_like()`. + i Set `ignore_case = FALSE` for case sensitive match. + i Use `tolower()` on both arguments to achieve a case insensitive match. # default raw escapes translated correctly diff --git a/tests/testthat/test-backend-.R b/tests/testthat/test-backend-.R index 6b284a44e..5f9b3324f 100644 --- a/tests/testthat/test-backend-.R +++ b/tests/testthat/test-backend-.R @@ -101,11 +101,18 @@ test_that("lead and lag translate n to integers", { # strings ----------------------------------------------------------------- -test_that("can translate case insensitive like", { +test_that("can only translate case sensitive str_like", { local_con(simulate_dbi()) - test_translate_sql(str_like(x, "abc")) - expect_snapshot( + expect_equal( test_translate_sql(str_like(x, "abc", ignore_case = FALSE)), + sql("`x` LIKE 'abc'") + ) + expect_equal( + test_translate_sql(str_like(x, "ABC", ignore_case = FALSE)), + sql("`x` LIKE 'ABC'") + ) + expect_snapshot( + test_translate_sql(str_like(x, "abc", ignore_case = TRUE)), error = TRUE ) })