diff --git a/r/src/type_infer.cpp b/r/src/type_infer.cpp index a8334387c52..76a1499305e 100644 --- a/r/src/type_infer.cpp +++ b/r/src/type_infer.cpp @@ -72,6 +72,8 @@ std::shared_ptr InferArrowTypeFromVector(SEXP x) { if (Rf_isNull(tzone_sexp)) { auto systzone_sexp = cpp11::package("base")["Sys.timezone"]; return timestamp(TimeUnit::MICRO, CHAR(STRING_ELT(systzone_sexp(), 0))); + } else if (TYPEOF(tzone_sexp) != STRSXP) { + cpp11::stop("`tzone` attribute of a `POSIXct` vector must be a character vector"); } else { return timestamp(TimeUnit::MICRO, CHAR(STRING_ELT(tzone_sexp, 0))); } @@ -89,6 +91,8 @@ std::shared_ptr InferArrowTypeFromVector(SEXP x) { if (Rf_isNull(tzone_sexp)) { auto systzone_sexp = cpp11::package("base")["Sys.timezone"]; return timestamp(TimeUnit::MICRO, CHAR(STRING_ELT(systzone_sexp(), 0))); + } else if (TYPEOF(tzone_sexp) != STRSXP) { + cpp11::stop("`tzone` attribute of a `POSIXct` vector must be a character vector"); } else { return timestamp(TimeUnit::MICRO, CHAR(STRING_ELT(tzone_sexp, 0))); } diff --git a/r/tests/testthat/test-type.R b/r/tests/testthat/test-type.R index 96968830f3d..bebc27178af 100644 --- a/r/tests/testthat/test-type.R +++ b/r/tests/testthat/test-type.R @@ -53,6 +53,26 @@ test_that("infer_type() infers from R type", { ) }) +test_that("infer_type() errors clearly for POSIXct with invalid tzone", { + x <- as.POSIXct("2019-02-14 13:55:05", tz = "UTC") + attr(x, "tzone") <- 123 + + expect_error( + infer_type(x), + "`tzone` attribute of a `POSIXct` vector must be a character vector" + ) +}) + +test_that("infer_type() errors clearly for zero-length POSIXct with invalid tzone", { + x <- as.POSIXct(x = NULL) + attr(x, "tzone") <- 123 + + expect_error( + infer_type(x), + "`tzone` attribute of a `POSIXct` vector must be a character vector" + ) +}) + test_that("infer_type() default method errors for unknown classes", { vec <- structure(list(), class = "class_not_supported")