CurtHagenlocher opened a new pull request, #470:
URL: https://github.com/apache/arrow-dotnet/pull/470

   ## What's Changed
   
   A zero-length `string`, `binary`, `large_string`, `large_binary`, `list`, 
`large_list` or `map` array may have an empty (0-byte) offsets buffer. Arrow 
C++ and nanoarrow write such arrays to IPC, and `ArrowStreamReader` reads them. 
#462 reported that concatenating them fails, and #465 fixes that. Auditing the 
rest of the library for the same input found three more failures, which this PR 
fixes.
   
   - **C Data export.** `CArrowArrayExporter` exported the empty offsets buffer 
as a null pointer. The spec allows a null pointer only where the buffer's size 
"would be 0". Arrow C++ computes the size of an offsets buffer as `offset + 
length + 1` offsets, so pyarrow rejects the export: `ArrowArrayStruct contains 
null data pointer for a buffer with non-zero computed size`. The exporter now 
exports `offset + 1` zeroed offsets in its place.
   - **C Data import.** `CArrowArrayImporter` read `offsets[length]` without 
checking for null. That hit a `Debug.Assert` in Debug builds and threw 
`NullReferenceException` in Release, including on a .NET → .NET round trip of 
an array read from IPC. For lists, it wrapped the null pointer in a non-empty 
buffer. The importer now accepts a null offsets buffer for a zero-length array, 
since older versions of this library produce one. For a non-empty array it 
throws `InvalidOperationException`.
   - **`ValueOffsets`.** The public accessor on `BinaryArray`, 
`LargeBinaryArray`, `ListArray` and `LargeListArray`, and so on string and map 
arrays, threw `ArgumentOutOfRangeException`. It now returns a single zero 
offset, keeping the `Length + 1` invariant. Internal callers already checked 
for zero length first.
   
   ### Tests
   The tests use zero-length arrays of each affected type with empty offsets 
buffers, including nested children (`list<string>`, `map<string, int32>`):
   - `ValueOffsetsOfZeroLengthArrayWithEmptyOffsets`
   - `ExportZeroLengthArrayWithEmptyOffsets`: the exported offsets are non-null 
and zero, and the array imports back.
   - `ImportZeroLengthArrayWithNullOffsets` and 
`ImportNonEmptyArrayWithNullOffsetsThrows`
   - A Python interop test, `ExportZeroLengthArrayWithEmptyOffsets`: pyarrow 
imports each exported array and validates it with `validate(full=True)`. It 
fails without this change with the C++ error quoted above.
   
   I also ran a wider check outside the test suite. pyarrow wrote zero-length 
arrays with minimal buffers for 26 types to IPC. .NET read them, round-tripped 
each through the C Data interface, and concatenated it with normal data, and 
pyarrow validated the results. With this change all types pass except `null`, 
which fails for an unrelated reason fixed in #469.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   
   Co-Authored-By: Claude Opus 5.5 <[email protected]>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to