This is an automated email from the ASF dual-hosted git repository.

thisisnic pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 0abf0de0ee3 GH-38358: [R] NotImplemented: Function 'if_else' has no 
kernel matching input types (bool, bool, date32[day]) (#51292)
0abf0de0ee3 is described below

commit 0abf0de0ee35e776b11004a8657a0eeeb02b08ce
Author: Nic Crane <[email protected]>
AuthorDate: Thu Sep 17 15:21:32 2026 -0500

    GH-38358: [R] NotImplemented: Function 'if_else' has no kernel matching 
input types (bool, bool, date32[day]) (#51292)
    
    ### Rationale for this change
    
    Error message which occurred for `if_else()` when an `NA` was incorrectly 
mapped to a logical one, not the right type
    
    ### What changes are included in this PR?
    
    cast `NA` to desired type
    
    ### Are these changes tested?
    
    Yep
    
    ### Are there any user-facing changes?
    
    Yep
    * GitHub Issue: #38358
    
    Authored-by: Nic Crane <[email protected]>
    Signed-off-by: Nic Crane <[email protected]>
---
 r/R/dplyr-funcs-simple.R                        |  8 ++++++++
 r/tests/testthat/test-dplyr-funcs-conditional.R | 23 +++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/r/R/dplyr-funcs-simple.R b/r/R/dplyr-funcs-simple.R
index 1f17bf216d7..e556c7418de 100644
--- a/r/R/dplyr-funcs-simple.R
+++ b/r/R/dplyr-funcs-simple.R
@@ -188,6 +188,14 @@ common_type <- function(exprs) {
 }
 
 cast_or_parse <- function(x, type) {
+  # A null scalar (e.g. a bare `NA`, which is logical) carries no data, so
+  # skip the value cast and just create a null of the target type. This
+  # avoids unsupported casts like bool -> date32 (GH-38358). Only Scalars
+  # have `is_valid`; Arrays (e.g. from the `%in%` binding) take the normal 
path.
+  if (inherits(x, "Scalar") && !x$is_valid) {
+    return(Scalar$create(NULL)$cast(type))
+  }
+
   to_type_id <- type$id
   if (to_type_id %in% c(Type[["DECIMAL32"]], Type[["DECIMAL64"]], 
Type[["DECIMAL128"]], Type[["DECIMAL256"]])) {
     # TODO: determine the minimum size of decimal (or integer) required to
diff --git a/r/tests/testthat/test-dplyr-funcs-conditional.R 
b/r/tests/testthat/test-dplyr-funcs-conditional.R
index f7d5b4d6b95..e746a845fa2 100644
--- a/r/tests/testthat/test-dplyr-funcs-conditional.R
+++ b/r/tests/testthat/test-dplyr-funcs-conditional.R
@@ -876,3 +876,26 @@ test_that("recode_values()", {
     class = "arrow_not_supported"
   )
 })
+
+test_that("if_else with logical NA and a date/timestamp column", {
+  # GH-38358: a bare `NA` is logical and can't be cast to date32, so
+  # if_else(bool, bool, date32) had no matching kernel
+  date_tbl <- tibble::tibble(
+    date = as.Date(c("2013-01-01", "2013-01-02", "2033-01-03", "2013-01-04")),
+    ts = as.POSIXct(
+      c("2013-01-01 01:00:00", "2013-01-02 02:00:00", "2033-01-03 03:00:00", 
"2013-01-04 04:00:00"),
+      tz = "UTC"
+    )
+  )
+
+  compare_dplyr_binding(
+    .input |>
+      mutate(
+        date2 = if_else(date > as.Date("2014-01-01"), NA, date),
+        date3 = if_else(date > as.Date("2014-01-01"), date, NA),
+        ts2 = if_else(ts > as.POSIXct("2014-01-01", tz = "UTC"), NA, ts)
+      ) |>
+      collect(),
+    date_tbl
+  )
+})

Reply via email to