Repository navigation
fix(arrow-array): deprecate FixedSizeListArray::value_offset, which wraps past i32::MAX - #11070
Conversation
…::MAX value_offset narrows a usize offset to i32 with as, so past i32::MAX child values it returns a negative number. The avro FixedSizeList encoder cast that back to usize and panicked writing the batch. Deprecate it in favour of i * value_length() as usize, as was done for FixedSizeBinaryArray::value_offset, and panic instead of wrapping. The avro encoder and take work the offset out in usize, and take returns an error when it does not fit its u32 indices. Closes apache#11059.
| #[inline] | ||
| pub fn value_offset(&self, i: usize) -> i32 { | ||
| self.value_offset_at(i) as i32 | ||
| i32::try_from(self.value_offset_at(i)).expect("offset overflow") |
There was a problem hiding this comment.
It would be somewhat annoying if I were a user to start seeing panics (even though you could argue that is better than silent overflows 🤔 )
There was a problem hiding this comment.
fair. the deprecated method only panics past i32::MAX, where it used to hand back a negative offset and the avro writer turned that into an index near u64::MAX. FixedSizeBinaryArray::value_offset documents the same panic since 59.0.0. anyone who wants no panic at all can move to value_offset_at, which stays in usize. happy to leave the wrapping cast alone and only deprecate if you would rather not add a panic at all.
There was a problem hiding this comment.
for a minor release I think we should just deprecate the function and not change its behavior
Jefffrey asked for 60.0.0 rather than 60.1.0, and alamb asked for a public function that works the offset out correctly, so value_offset_at is public now and the deprecation note points at it.
alamb asked for a deprecation only in a minor release, so the wrapping cast comes back and the doc says what happens past i32::MAX instead. value_offset_at stays public as the accessor that never wraps.
Jefffrey asked for the removed asserts back rather than dropped, and for take to use the accessor too, so the tests and take both go through value_offset_at.
7dc218b to
7977909
Compare
|
Both restored through value_offset_at in 7977909, and take uses it now too. |
|
run benchmark take_kernels |
|
Thank you @Cintu07 |
|
🤖 Arrow criterion benchmark running (GKE) | trigger CPU Details (lscpu)Comparing fix/fixed-size-list-value-offset (7977909) to 4cd8be9 (merge-base) diff Run configurationrun benchmark take_kernelsBENCH_COMMAND=cargo bench --features=arrow,async,test_common,experimental,object_store --bench take_kernels File an issue against this benchmark runner |
|
🤖 Arrow criterion benchmark completed (GKE) | trigger Instance: Comparing fix/fixed-size-list-value-offset (7977909) to 4cd8be9 (merge-base) diff Run configurationrun benchmark take_kernelsCPU Details (lscpu)Details
Resource Usagebase (merge-base)
branch
File an issue against this benchmark runner |
…pache/arrow-rs#11070) Co-Authored-By: Claude Fable 5.1 <[email protected]>
Which issue does this PR close?
Rationale for this change
FixedSizeListArray::value_offset casts a usize offset to i32, so once a row starts past i32::MAX child values it returns a negative number. the avro FixedSizeList encoder cast that back to usize and panicked writing the batch.
What changes are included in this PR?
Are these changes tested?
yes. fixed_size_list_encoder_int32_sliced is new and covers the avro change. the overflow itself needs 384 MiB so it isn't a unit test, but the repro from the issue panics on 59.3.0 and writes the batch on this branch. arrow-array 972, arrow-select 446 and arrow-avro 515 tests pass, and clippy is clean.
Are there any user-facing changes?
FixedSizeListArray::value_offset is deprecated and panics past i32::MAX. take on a FixedSizeList returns an error past u32::MAX instead of wrapping.