csharp: BindStream/Bind statements fail with 'Fatal error. System.AccessViolationException: Attempted to read or write protected memory.'
- Dominant language
- C#
- Stars
- 627
- Forks
- 217
- Avg merge
- 17h
- Merged PRs (30d)
- 57
Description
### What would you like help with?
Hi there! I've tried and failed to correctly execute the `BindStream` method from the C# `C` wrapper API with multiple types of input streams in order to bulk ingest from an Arrow stream into DuckDb. If I use the mock stream implementation found [here](https://github.com/apache/arrow-adbc/blob/5248c3457e00770d4b5bc215e5f71013f449d1ca/csharp/test/Apache.Arrow.Adbc.Tests/Client/ClientTests.cs#L86), my code will work. Otherwise, 'real' file and memory stream reads fail every time with the following error:
```
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at Apache.Arrow.C.CArrowArrayExporter.ReleaseArray(Apache.Arrow.C.CArrowArray*)
```
I can read that stack trace just fine and understand the problem it describes, but I can't easily debug the failure of the native code in regard to free'ing memory from my current IDE (Rider). I realize the C# code is less documented and less mature than some of the other runtimes supported by ADBC (and DuckDB), so I suspect I might be calling the API or creating my stream without following a specific pattern that may be required? Here's an example of how I'm attempting to use the API that leads to this error. My code is calling the `C` API from C# running on .NET 8 on macOS:
```
public static async Task Main()
{
// Load the DuckDB driver following the pattern from the test directory
using var driver = CAdbcDriverImporter.Load("/local/path/libduckdb-osx-universal/libduckdb.dylib",
"duckdb_adbc_init");
// Open a local persistent DB
using var duckDb =
driver.Open(new Dictionary { { "path", "/local/path/test.db" } });
using var connection = duckDb.Connect(null);
// Create a new table on ingest
using var statement = connection.BulkIngest("temp_table", BulkIngestMode.Create);
// Create a file stream that reads in some sample Arrow stream data from the arrow-experiments repo
// Note: if I mock this stream as mentioned above, I can get this code to work. In that scenario, no native memory access is involved in the stream binding
await using var fileStream = new FileStream("/local/path/arrow-commits.arrows", FileMode.Open,
FileAccess.ReadWrite);
// Read the stream, bind it, execute the ingest
using var reader = new ArrowStreamReader(fileStream);
statement.BindStream(reader);
await statement.ExecuteUpdateAsync();
}
```
Contributor guide
Assessment
This issue has not been assessed yet.