Skip to content

GH-48832: [R] Fix crash with zero-length POSIXct tzone attribute#49619

Merged
thisisnic merged 3 commits intoapache:mainfrom
thisisnic:GH-48832_zero_length_bug
Apr 2, 2026
Merged

GH-48832: [R] Fix crash with zero-length POSIXct tzone attribute#49619
thisisnic merged 3 commits intoapache:mainfrom
thisisnic:GH-48832_zero_length_bug

Conversation

@thisisnic
Copy link
Copy Markdown
Member

@thisisnic thisisnic commented Mar 30, 2026

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

@thisisnic thisisnic requested a review from jonkeane as a code owner March 30, 2026 14:26
@thisisnic
Copy link
Copy Markdown
Member Author

FYI, I used Claude to generate this PR. I am not super familiar with the .cpp code it modified, but it looks convincing, and the tests replicate the original error.

@thisisnic thisisnic marked this pull request as draft March 30, 2026 14:33
@thisisnic thisisnic marked this pull request as ready for review March 30, 2026 15:29
Comment on lines +96 to +97
} else if (Rf_inherits(x, "POSIXct")) {
return POSIXCT;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, huh I wonder if this type is new? Or maybe I "just" forgot about it when I made these changes?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 says that it's not new, but historically, POSIXct was always REALSXP (backed by a double) until R 4.5.2, but now for zero-length POSIXct objects that's no longer the case, so it needs checking in the INTSXP path.

Or, with more detail:

So in R 4.5.0, R changed as.POSIXct({}) (i.e., zero-length POSIXct) to be internally stored as integer (INTSXP) rather than double (REALSXP). This is a deliberate change for consistency - zero-length date-time objects don't need the full double precision since they have no actual values to store.

@github-actions github-actions bot added awaiting changes Awaiting changes and removed awaiting committer review Awaiting committer review labels Mar 30, 2026
@jonkeane
Copy link
Copy Markdown
Member

@github-actions crossbow submit test-r-versions

@github-actions
Copy link
Copy Markdown

Revision: 8e29ee5

Submitted crossbow builds: ursacomputing/crossbow @ actions-c0634dd2bf

Task Status
test-r-versions GitHub Actions

@thisisnic
Copy link
Copy Markdown
Member Author


══ Warnings ════════════════════════════════════════════════════════════════════
── Warning ('test-gcs.R:122:1'): (code run outside of `test_that()`) ───────────
error in running command
Backtrace:
    ▆
 1. ├─testthat::skip_if_not(system("storage-testbench -h") == 0, message = "googleapis-storage-testbench is not installed.") at test-gcs.R:122:1
 2. │ └─base::isTRUE(condition)
 3. └─base::system("storage-testbench -h")

══ Failed tests ════════════════════════════════════════════════════════════════
── Error ('test-s3.R:49:5'): read/write Feather on S3 ──────────────────────────
Error: IOError: When initiating multiple part upload for key '1774901280.20806/test.feather' in bucket 'arrow-datasets': AWS Error ACCESS_DENIED during CreateMultipartUpload operation: User: arn:aws:iam::855673865593:user/crossbow is not authorized to perform: s3:PutObject on resource: "arn:aws:s3:::arrow-datasets/1774901280.20806/test.feather" because no identity-based policy allows the s3:PutObject action (Request ID: YHWYK1PAJ4PQ4RTW)
Backtrace:
    ▆
 1. └─arrow::write_feather(example_data, bucket_uri(now, "test.feather")) at test-s3.R:49:5
 2.   └─arrow:::make_output_stream(sink)
 3.     └─fs_and_path$fs$OpenOutputStream(fs_and_path$path)
 4.       └─arrow:::fs___FileSystem__OpenOutputStream(self, clean_path_rel(path))
── Error ('test-s3.R:55:5'): read/write Parquet on S3 ──────────────────────────
Error: IOError: When initiating multiple part upload for key '1774901280.20806/test.parquet' in bucket 'arrow-datasets': AWS Error ACCESS_DENIED during CreateMultipartUpload operation: User: arn:aws:iam::855673865593:user/crossbow is not authorized to perform: s3:PutObject on resource: "arn:aws:s3:::arrow-datasets/1774901280.20806/test.parquet" because no identity-based policy allows the s3:PutObject action (Request ID: YHWZWQHNDRM7CJ24)
Backtrace:
    ▆
 1. └─arrow::write_parquet(example_data, bucket_uri(now, "test.parquet")) at test-s3.R:55:5
 2.   └─arrow:::make_output_stream(sink)
 3.     └─fs_and_path$fs$OpenOutputStream(fs_and_path$path)
 4.       └─arrow:::fs___FileSystem__OpenOutputStream(self, clean_path_rel(path))
── Error ('test-s3.R:60:5'): RandomAccessFile$ReadMetadata() works for S3FileSystem ──
Error: IOError: Path does not exist 'arrow-datasets/1774901280.20806/test.parquet'. Detail: [errno 2] No such file or directory
Backtrace:
    ▆
 1. └─bucket$OpenInputFile(paste0(now, "/", "test.parquet")) at test-s3.R:60:5
 2.   └─arrow:::fs___FileSystem__OpenInputFile(self, clean_path_rel(path))
── Error ('test-s3.R:44:1'): (code run outside of `test_that()`) ───────────────
Error: IOError: Path does not exist 'arrow-datasets/1774901280.20806/'. Detail: [errno 2] No such file or directory
Backtrace:
    ▆
 1. └─bucket$DeleteDir(now) at test-s3.R:44:1
 2.   └─arrow:::fs___FileSystem__DeleteDir(self, clean_path_rel(path))

[ FAIL 4 | WARN 1 | SKIP 30 | PASS 8080 ]
Error:
! Test failures.
Warning messages:
1: In for (i in seq_len(n)) { :
  closing unused connection 4 (/tmp/Rtmp0rl4Xk/file8f9832b0767c/part-0.csv)
2: In for (i in seq_len(n)) { :
  closing unused connection 5 (/tmp/Rtmp0rl4Xk/file8f986ad76486/part-0.tsv)
3: In for (i in seq_len(n)) { :
  closing unused connection 4 (/tmp/Rtmp0rl4Xk/file8f986bbb0db0/part-0.csv)
Execution halted

1 error ✖ | 0 warnings ✔ | 2 notes ✖

Failures look unrelated; I need to update some bucket settings. Probably worth getting that done and retriggering CI here though to make sure this isn't a new thing in 4.5.2.

@jonkeane
Copy link
Copy Markdown
Member

I need to update some bucket settings. Probably worth getting that done and retriggering CI here though to make sure this isn't a new thing in 4.5.2.

Thanks for this! I was going to make an issue when I triggered these but then got distracted. It sounds like you know what's up there — I could guess but I haven't dug too much into it

Copy link
Copy Markdown
Member

@jonkeane jonkeane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, forgot to actually approve this.

@github-actions github-actions bot added awaiting merge Awaiting merge and removed awaiting changes Awaiting changes labels Apr 1, 2026
@thisisnic
Copy link
Copy Markdown
Member Author

@github-actions crossbow submit test-r-versions

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 1, 2026

Revision: 8e29ee5

Submitted crossbow builds: ursacomputing/crossbow @ actions-8e361a7bbb

Task Status
test-r-versions GitHub Actions

@thisisnic thisisnic force-pushed the GH-48832_zero_length_bug branch from 8e29ee5 to e1f0d16 Compare April 2, 2026 12:19
@thisisnic
Copy link
Copy Markdown
Member Author

Needs rebasing...will try again

@thisisnic
Copy link
Copy Markdown
Member Author

@github-actions crossbow submit test-r-versions

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 2, 2026

Revision: e1f0d16

Submitted crossbow builds: ursacomputing/crossbow @ actions-a2f34c245b

Task Status
test-r-versions GitHub Actions

@github-actions github-actions bot added awaiting changes Awaiting changes and removed awaiting merge Awaiting merge labels Apr 2, 2026
@thisisnic thisisnic merged commit d035788 into apache:main Apr 2, 2026
16 checks passed
@thisisnic thisisnic removed the awaiting changes Awaiting changes label Apr 2, 2026
@conbench-apache-arrow
Copy link
Copy Markdown

After merging your PR, Conbench analyzed the 3 benchmarking runs that have been run so far on merge-commit d035788.

There were 4 benchmark results with an error:

There were no benchmark performance regressions. 🎉

The full Conbench report has more details. It also includes information about 2 possible false positives for unstable benchmarks that are known to sometimes produce them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants