Skip to content

Commit d035788

Browse files
authored
GH-48832: [R] Fix crash with zero-length POSIXct tzone attribute (#49619)
### Rationale for this change In R 4.5.2+, `as.POSIXct(x = NULL)` creates a zero-length `POSIXct` with `INTSXP` (integer) type, not `REALSXP` (double). The `GetVectorType()` function in `r_to_arrow.cpp` only checked for `POSIXct` in the `REALSXP` branch, so it misclassified zero-length `POSIXct` as `INT32`. ### What changes are included in this PR? Map any `POSIXct` object to correct class by adding the check to the `INTSXP` branch of `GetVectorType()` ### Are these changes tested? Yes ### Are there any user-facing changes? No * GitHub Issue: #48832 Authored-by: Nic Crane <thisisnic@gmail.com> Signed-off-by: Nic Crane <thisisnic@gmail.com>
1 parent 75c8ede commit d035788

File tree

4 files changed

+25
-2
lines changed

4 files changed

+25
-2
lines changed

r/src/arrowExports.cpp

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

r/src/r_to_arrow.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ RVectorType GetVectorType(SEXP x) {
9393
return FACTOR;
9494
} else if (Rf_inherits(x, "Date")) {
9595
return DATE_INT;
96+
} else if (Rf_inherits(x, "POSIXct")) {
97+
return POSIXCT;
9698
}
9799
return INT32;
98100
case STRSXP:

r/tests/testthat/test-Array.R

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,17 @@ test_that("array uses local timezone for POSIXct without timezone", {
324324
})
325325
})
326326

327+
test_that("zero-length POSIXct can be converted (GH-48832)", {
328+
# In R 4.5.2+, zero-length POSIXct vectors are integer type, not double
329+
x <- as.POSIXct(x = NULL)
330+
331+
# Should behave the same as non-empty POSIXct with empty tzone
332+
expect_type_equal(infer_type(x), timestamp("us"))
333+
arr <- Array$create(x)
334+
expect_equal(arr$length(), 0L)
335+
expect_type_equal(arr, timestamp("us"))
336+
})
337+
327338
test_that("Timezone handling in Arrow roundtrip (ARROW-3543)", {
328339
# Write a feather file as that's what the initial bug report used
329340
df <- tibble::tibble(

r/tests/testthat/test-parquet.R

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@ test_that("write_parquet() can truncate timestamps", {
129129
expect_equal(as.data.frame(tab), as.data.frame(new))
130130
})
131131

132+
test_that("write_parquet() works with zero-length POSIXct (GH-48832)", {
133+
# In R 4.5.2+, zero-length POSIXct vectors are integer type, not double
134+
tf <- tempfile()
135+
on.exit(unlink(tf))
136+
137+
expect_no_error(write_parquet(data.frame(x = as.POSIXct(x = NULL)), tf))
138+
result <- read_parquet(tf)
139+
expect_equal(nrow(result), 0)
140+
})
141+
132142
test_that("make_valid_parquet_version()", {
133143
expect_equal(
134144
make_valid_parquet_version("1.0"),

0 commit comments

Comments
 (0)