This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/main by this push:
     new 9827aaad30 fix(arrow-data): account for FixedSizeList parent offset in 
MutableArrayData (#11636)
9827aaad30 is described below

commit 9827aaad30258bf348a0d4f2b792505d6d24a88f
Author: Chang Yong Lik <[email protected]>
AuthorDate: Sat Oct 17 07:45:08 2026 +0000

    fix(arrow-data): account for FixedSizeList parent offset in 
MutableArrayData (#11636)
    
    # Which issue does this PR close?
    
    - Closes #11588.
    
    # Rationale for this change
    
    `MutableArrayData::extend` on a `FixedSizeList` with a nonzero parent
    offset copied the child values from the start of the child instead of
    from the offset.
    
    # What changes are included in this PR?
    
    `build_extend` in `transform/fixed_size_list.rs` adds `array.offset()`
    to `start` before computing the child range, the same way #10934 did for
    structs.
    
    # Are these changes tested?
    
    Yes, `test_extend_fixed_size_list_accounts_for_parent_offset` in
    `arrow-data/src/data.rs` (next to the struct test from #10934). It fails
    without the fix.
    
    # Are there any significant user-facing changes?
    
    No.
    
    AI use: I used Claude Code to find the cause and write the fix and test.
    I reviewed the change and checked that the test fails without the fix.
---
 arrow-data/src/data.rs                      | 23 +++++++++++++++++++++++
 arrow-data/src/transform/fixed_size_list.rs | 21 ++++++++++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/arrow-data/src/data.rs b/arrow-data/src/data.rs
index d58bdcf963..6d34884808 100644
--- a/arrow-data/src/data.rs
+++ b/arrow-data/src/data.rs
@@ -2760,6 +2760,29 @@ mod tests {
         assert_eq!(output.child_data()[0].buffer::<i32>(0), &[1, 2, 3, 4]);
     }
 
+    #[test]
+    fn test_extend_fixed_size_list_accounts_for_parent_offset() {
+        let field = Arc::new(Field::new("item", DataType::Int32, false));
+        let child = ArrayData::builder(DataType::Int32)
+            .len(6)
+            .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5]))
+            .build()
+            .unwrap();
+
+        let data = ArrayData::builder(DataType::FixedSizeList(field, 2))
+            .len(2)
+            .offset(1)
+            .add_child_data(child)
+            .build()
+            .unwrap();
+
+        let mut mutable = MutableArrayData::new(vec![&data], false, 
data.len());
+        mutable.try_extend(0, 0, data.len()).unwrap();
+        let output = mutable.freeze();
+
+        assert_eq!(output.child_data()[0].buffer::<i32>(0), &[2, 3, 4, 5]);
+    }
+
     #[test]
     fn test_null_count() {
         let mut bit_v: [u8; 2] = [0; 2];
diff --git a/arrow-data/src/transform/fixed_size_list.rs 
b/arrow-data/src/transform/fixed_size_list.rs
index de791884b9..f5234ec712 100644
--- a/arrow-data/src/transform/fixed_size_list.rs
+++ b/arrow-data/src/transform/fixed_size_list.rs
@@ -25,11 +25,30 @@ pub(super) fn build_extend(array: &ArrayData) -> Extend<'_> 
{
         DataType::FixedSizeList(_, i) => *i as usize,
         _ => unreachable!(),
     };
+    let offset = array.offset();
 
     Box::new(
         move |mutable: &mut _MutableArrayData, index: usize, start: usize, 
len: usize| {
+            let start = start.checked_add(offset).ok_or_else(|| {
+                ArrowError::InvalidArgumentError(format!(
+                    "fixed size list offset {offset} with start {start} 
overflows usize"
+                ))
+            })?;
+            let end = start.checked_add(len).ok_or_else(|| {
+                ArrowError::InvalidArgumentError(format!(
+                    "fixed size list start {start} with length {len} overflows 
usize"
+                ))
+            })?;
+            let (child_start, child_end) = start
+                .checked_mul(size)
+                .zip(end.checked_mul(size))
+                .ok_or_else(|| {
+                    ArrowError::InvalidArgumentError(format!(
+                        "fixed size list range {start}..{end} with size {size} 
overflows usize"
+                    ))
+                })?;
             for child in &mut mutable.child_data {
-                child.try_extend(index, start * size, (start + len) * size)?;
+                child.try_extend(index, child_start, child_end)?;
             }
             Ok(())
         },

Reply via email to