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

Jefffrey 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 a5ba6a29d6 fix(arrow-array): `PrimitiveRunBuilder` was buggy after 
`finish` (#11326)
a5ba6a29d6 is described below

commit a5ba6a29d63671d4f8ef79f19b78257a8f19c70a
Author: Neil Conway <[email protected]>
AuthorDate: Thu Oct 1 22:23:13 2026 -0400

    fix(arrow-array): `PrimitiveRunBuilder` was buggy after `finish` (#11326)
    
    # Which issue does this PR close?
    
    - Closes #11325.
    
    # Rationale for this change
    
    `PrimitiveRunBuilder::finish` did not reset `prev_run_end_index`, so a
    reused builder kept the previous batch's last run index. That resulted
    in various misbehavior, like either dropping data or panicking, on a
    subsequent `finish` call.
    
    # What changes are included in this PR?
    
    See above.
    
    # Are these changes tested?
    
    Yes; new test added.
    
    # Are there any user-facing changes?
    
    No.
    
    # AI usage
    
    Issue spotted and fix developed with Claude Code (Opus 5.5); I have
    reviewed and understand the resulting code.
---
 arrow-array/src/builder/primitive_run_builder.rs | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/arrow-array/src/builder/primitive_run_builder.rs 
b/arrow-array/src/builder/primitive_run_builder.rs
index a78e5844ed..ec2f7febc5 100644
--- a/arrow-array/src/builder/primitive_run_builder.rs
+++ b/arrow-array/src/builder/primitive_run_builder.rs
@@ -200,9 +200,10 @@ where
         // write the last run end to the array.
         self.append_run_end();
 
-        // reset the run index to zero.
+        // reset the run indexes to zero.
         self.current_value = None;
         self.current_run_end_index = 0;
+        self.prev_run_end_index = 0;
 
         // build the run encoded array by adding run_ends and values array as 
its children.
         let run_ends_array = self.run_ends_builder.finish();
@@ -333,6 +334,23 @@ mod tests {
         );
     }
 
+    #[test]
+    fn test_reuse_after_finish() {
+        let mut builder = PrimitiveRunBuilder::<Int16Type, Int16Type>::new();
+        builder.extend([1, 2, 3].into_iter().map(Some));
+        builder.finish();
+
+        // A single run with the same length as the previous batch
+        builder.extend([7, 7, 7].into_iter().map(Some));
+        let array = builder.finish();
+        assert_eq!(array.len(), 3);
+        assert_eq!(array.run_ends().values(), &[3]);
+        assert_eq!(array.values().as_primitive::<Int16Type>().values(), &[7]);
+
+        // Nothing appended since the last finish
+        assert_eq!(builder.finish().len(), 0);
+    }
+
     #[test]
     #[should_panic(expected = "incompatible data type for builder")]
     fn test_override_data_type_invalid() {

Reply via email to