Skip to content

feat(rust/ffi): implement ErrorFromArrayStream on the driver exporter - #4

Closed
fornwall wants to merge 1 commit into
mainfrom
feat/error-from-array-stream
Closed

feat(rust/ffi): implement ErrorFromArrayStream on the driver exporter#4
fornwall wants to merge 1 commit into
mainfrom
feat/error-from-array-stream

Conversation

@fornwall

@fornwall fornwall commented Jul 7, 2026

Copy link
Copy Markdown
Owner

What

The exported driver left the ADBC 1.1.0 ErrorFromArrayStream slot as None
(rust/ffi/src/driver_exporter.rs, previously a TODO). That slot is the
mechanism a consumer uses to recover the full AdbcError — status, vendor
code, structured details — when a result stream fails mid-iteration. Without
it, everything a Rust driver attaches to its adbc_core::error::Error during
streaming is reduced to an errno + message string for any foreign driver
manager (the error is wrapped in ArrowError::ExternalError, and arrow-rs's
FFI_ArrowArrayStream only carries the Display string across FFI).

How

  • Wrap every exported reader (LastErrorReader) so that whenever iteration
    yields an ArrowError::ExternalError carrying an adbc_core::error::Error,
    the full error is stashed in a shared slot.
  • Back each exported stream with ExportedArrayStreamPrivateData, which
    delegates schema/array export to an inner arrow-produced stream and keeps the
    last-error slot reachable.
  • Implement ErrorFromArrayStream to materialize an FFI_AdbcError from the
    retained Error (reusing the existing TryFrom<Error> / ErrorPrivateData
    machinery) and write the ADBC status. The returned error is owned by the
    stream and released with it, matching the ADBC contract that the pointer is
    valid until the next call or stream release.

Testing

  • New test_error_from_array_stream drives the exported C driver directly
    (the Rust driver manager imports streams via arrow's ArrowArrayStreamReader,
    which has no notion of this ADBC-specific entry point) and asserts message,
    status, vendor code, sqlstate and structured details all survive.
  • The dummy driver gains a STREAM_ERROR_QUERY trigger to produce a
    mid-stream failure.
  • Verified clean under Miri (no UB, no leaks) across the full
    stream+error lifecycle. Full adbc_dummy suite and cargo build --workspace
    pass.

Relationship to apache#4475 / apache/arrow-rs#10300

This is the natural complement to apache#4475:
that PR fixes the error code (mapping Status::CancelledECANCELED
instead of the arrow-rs catch-all EINVAL); this PR recovers the error
object. Both extract the adbc_core::error::Error from the
ArrowError::ExternalError source chain, so if apache#4475 lands first (introducing
its custom exported_stream.rs), these should be reconciled: the last-error
retention here would fold into that custom stream's private data rather than
layering a second wrapper on top of FFI_ArrowArrayStream::new.

🤖 Generated with Claude Code

The exported driver left the ADBC 1.1.0 `ErrorFromArrayStream` slot as
`None`, so when a result stream failed mid-iteration everything a Rust
driver attached to its `adbc_core::error::Error` (status, vendor code,
structured details) was reduced to an errno plus a message string for any
foreign driver manager.

Wrap every exported reader in a stream whose private data retains the last
`adbc_core::error::Error` seen during iteration (recovered from the
`ArrowError::ExternalError` source chain), and implement the slot to
materialize an `FFI_AdbcError` from it, reusing the existing
`TryFrom<Error>` / `ErrorPrivateData` machinery. The returned error is kept
alive by the stream and released with it, per the ADBC contract.

This is the natural complement to apache#4475/#10300: those fix the error *code*
(errno mapping); this recovers the error *object*.

The dummy driver gains a failing-stream trigger (`STREAM_ERROR_QUERY`) and a
test drives the exported C driver directly to assert the full error --
message, status, vendor code, sqlstate and structured details -- is
recovered via `ErrorFromArrayStream` after the stream fails.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@fornwall fornwall closed this Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant