Skip to content

feat(csharp): implement AdbcErrorFromArrayStream for exported and imported streams - #4983

Merged
CurtHagenlocher merged 5 commits into
apache:mainfrom
CurtHagenlocher:csharp-error-from-array-stream
Oct 31, 2026
Merged

CurtHagenlocher merged 5 commits into
apache:mainfrom
CurtHagenlocher:csharp-error-from-array-stream

Conversation

@CurtHagenlocher

Copy link
Copy Markdown
Contributor

When a C# driver exported through CAdbcDriverExporter fails partway through reading a result stream, the error's status, vendor code, SQLSTATE and details are now preserved across the C ABI.

Exported streams no longer go through Arrow's CArrowArrayStreamExporter. They keep the exception from a failed get_next/get_schema, return an errno matching the status (e.g. ECANCELED for Cancelled), and report the error through AdbcErrorFromArrayStream. On the consumer side, CAdbcDriverImporter calls the driver's ErrorFromArrayStream when a read fails and throws an AdbcException with the status and details, falling back to the previous message-only exception for 1.0 drivers or when the driver returns null.

Because Apache.Arrow keeps the ArrowArrayStream callback fields internal, this adds internal structs with the same layout.

This PR was prepared with AI assistance (Claude Code).

Closes #4982

🤖 Generated with Claude Code

…orted streams

Streams exported by CAdbcDriverExporter now keep the exception from a
failed read, return an errno that matches its status, and report it
through AdbcErrorFromArrayStream. CAdbcDriverImporter calls
AdbcErrorFromArrayStream when a stream read fails, so the AdbcException
keeps its status, SQLSTATE, vendor code and details.

Closes apache#4982

Generated-by: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

In-process reads can deadlock, .NET Framework callback incompatibilities break stream interoperability and cleanup, and errors can lose vendor codes.

4 open issues
What changed in this PR

This PR adds C# support for AdbcErrorFromArrayStream, allowing stream failures to carry structured ADBC errors across the C ABI rather than only an error message.

Changes:

  • Adds ADBC-owned stream export callbacks with status-to-errno mapping and retained error details.
  • Imports structured stream errors, with message-only fallback for older drivers.
  • Adds round-trip and NativeAOT tests for stream errors, cancellation, and schema failures.
File Description
csharp/​test/​Apache.Arrow.Adbc.Tests/​ExportedDriverRoundTrip11Tests.cs Tests stream errors, cancellation, schema failures, and compatibility fallback.
csharp/​test/​AotInterop/​Apache.Arrow.Adbc.TestFixture.Tests/​AotFixtureTests.cs Tests structured stream errors across NativeAOT boundaries.
csharp/​test/​AotInterop/​Apache.Arrow.Adbc.TestFixture.Native/​FixtureDriver.cs Adds a failing stream fixture.
csharp/​src/​Apache.Arrow.Adbc/​C/​NativeArrowStructs.cs Defines native stream and array layouts for callback access.
csharp/​src/​Apache.Arrow.Adbc/​C/​Delegates.cs Adds stream callback delegate types.
csharp/​src/​Apache.Arrow.Adbc/​C/​CAdbcDriverImporter.Streams.cs Implements stream import, error translation, and cleanup.
csharp/​src/​Apache.Arrow.Adbc/​C/​CAdbcDriverImporter.cs Routes stream import and cleanup through the new wrapper.
csharp/​src/​Apache.Arrow.Adbc/​C/​CAdbcDriverExporter.Streams.cs Implements stream callbacks, retained errors, and errno mapping.
csharp/​src/​Apache.Arrow.Adbc/​C/​CAdbcDriverExporter.cs Registers ErrorFromArrayStream and delegates stream export to the new implementation.

Review effort: Balanced

…ET Framework

On .NET Framework, a callback created from a managed delegate can only be
called through a delegate of the same type, so use Apache.Arrow's stream
callback types for exported and imported streams. Also start the read on
a context-free thread when get_next is called on a thread with a
synchronization context.

Generated-by: Claude Opus 5.5 <noreply@anthropic.com>
The non-generic Marshal.GetDelegateForFunctionPointer returns the original
delegate for a managed callback without casting it, so the importer can
wrap a delegate of any type instead of looking up Apache.Arrow's types.

Generated-by: Claude Opus 5.5 <noreply@anthropic.com>
Generated-by: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

A critical stream-lifetime bug can release the native driver before stream consumption and later invoke invalid callbacks, so the implementation needs a reference-retention and cleanup fix.

1 open issue
4 resolved since last review

Review effort: Lite

An imported stream calls into the driver until it's released, including
ErrorFromArrayStream when a read fails, so hold a driver reference for
the stream's lifetime as the database, connection and statement do.

Generated-by: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The cross-target Arrow C stream callback and ABI-owned error-lifetime changes require .NET Framework, NativeAOT, and native driver-manager runtime coverage that is unavailable in this review environment.

No open issues 🎉

1 resolved since last review

Review effort: Lite

@CurtHagenlocher
CurtHagenlocher merged commit d9cb6a2 into apache:main Oct 31, 2026
9 checks passed
@CurtHagenlocher
CurtHagenlocher deleted the csharp-error-from-array-stream branch October 31, 2026 13:51
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.

csharp: implement AdbcErrorFromArrayStream so stream errors keep their status across the C ABI

2 participants