Skip to content

Commit acd8e44

Browse files
authored
GH-40886: [R] Cryptic error when creating Arrow array from POSIXct with invalid time zones (#49714)
### Rationale for this change Horrible error with invalid timezones ### What changes are included in this PR? Do more checking of type ### Are these changes tested? Yup ### Are there any user-facing changes? No ### AI usage Done with Codex, but I went through it myself and am happy with it. * GitHub Issue: #40886 Authored-by: Nic Crane <thisisnic@gmail.com> Signed-off-by: Nic Crane <thisisnic@gmail.com>
1 parent 3433a65 commit acd8e44

2 files changed

Lines changed: 23 additions & 0 deletions

File tree

r/src/type_infer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ std::shared_ptr<arrow::DataType> InferArrowTypeFromVector<INTSXP>(SEXP x) {
7272
if (Rf_isNull(tzone_sexp)) {
7373
auto systzone_sexp = cpp11::package("base")["Sys.timezone"];
7474
return timestamp(TimeUnit::MICRO, CHAR(STRING_ELT(systzone_sexp(), 0)));
75+
} else if (TYPEOF(tzone_sexp) != STRSXP) {
76+
cpp11::stop("`tzone` attribute of a `POSIXct` vector must be a character vector");
7577
} else {
7678
return timestamp(TimeUnit::MICRO, CHAR(STRING_ELT(tzone_sexp, 0)));
7779
}
@@ -89,6 +91,8 @@ std::shared_ptr<arrow::DataType> InferArrowTypeFromVector<REALSXP>(SEXP x) {
8991
if (Rf_isNull(tzone_sexp)) {
9092
auto systzone_sexp = cpp11::package("base")["Sys.timezone"];
9193
return timestamp(TimeUnit::MICRO, CHAR(STRING_ELT(systzone_sexp(), 0)));
94+
} else if (TYPEOF(tzone_sexp) != STRSXP) {
95+
cpp11::stop("`tzone` attribute of a `POSIXct` vector must be a character vector");
9296
} else {
9397
return timestamp(TimeUnit::MICRO, CHAR(STRING_ELT(tzone_sexp, 0)));
9498
}

r/tests/testthat/test-type.R

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,25 @@ test_that("infer_type() infers from R type", {
5353
)
5454
})
5555

56+
test_that("infer_type() errors clearly for POSIXct with invalid tzone", {
57+
x <- as.POSIXct("2019-02-14 13:55:05", tz = "UTC")
58+
attr(x, "tzone") <- 123
59+
60+
expect_error(
61+
infer_type(x),
62+
"`tzone` attribute of a `POSIXct` vector must be a character vector"
63+
)
64+
65+
# Also check zero-length POSIXct
66+
x <- as.POSIXct(x = NULL)
67+
attr(x, "tzone") <- 123
68+
69+
expect_error(
70+
infer_type(x),
71+
"`tzone` attribute of a `POSIXct` vector must be a character vector"
72+
)
73+
})
74+
5675
test_that("infer_type() default method errors for unknown classes", {
5776
vec <- structure(list(), class = "class_not_supported")
5877

0 commit comments

Comments
 (0)