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

alamb 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 3577093f26 fix(arrow-select): handle all-empty run arrays in 
concat_run_arrays (#10782)
3577093f26 is described below

commit 3577093f26591aee806a9133c891b6b8e5255477
Author: Thor <[email protected]>
AuthorDate: Mon Aug 24 16:56:55 2026 -0500

    fix(arrow-select): handle all-empty run arrays in concat_run_arrays (#10782)
    
    concat_run_arrays filters out any input RunArray whose run_ends() is
    empty before concatenating their values. When every input is filtered
    out this way (e.g. concatenating two zero-length slices of a nested
    RunEndEncoded struct field), the resulting values_slices is empty and
    falls through to concat(&[]), which errors because a type-erased &[&dyn
    Array] with no elements carries no DataType to build a result from.
    
    Add an early return for the empty-after-filter case, building a valid
    zero-length array from the original (non-empty) input's DataType
    instead.
    
    # Which issue does this PR close?
    
    <!--
    We generally require a GitHub issue to be filed for all bug fixes and
    enhancements and this helps us generate change logs for our releases.
    You can link an issue to this PR using the GitHub syntax.
    -->
    
    - Closes #10781.
    
    # Rationale for this change
    
    `concat_run_arrays` should return a valid array instead of an error when
    empty run_ends are passed into it.
    
    # What changes are included in this PR?
    
    A small empty run arrays check that returns an empty array of the data
    type instead.
    
    # Are these changes tested?
    
    Yes a unit test was added
    
    # Are there any user-facing changes?
    
    No
    
    ---------
    
    Co-authored-by: Jeffrey Vo <[email protected]>
---
 arrow-select/src/concat.rs | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arrow-select/src/concat.rs b/arrow-select/src/concat.rs
index e1384edbc5..eece5ffbaf 100644
--- a/arrow-select/src/concat.rs
+++ b/arrow-select/src/concat.rs
@@ -424,6 +424,12 @@ where
         .filter(|x| !x.run_ends().is_empty())
         .collect();
 
+    if run_arrays.is_empty() {
+        // If all input arrays are empty then handle here otherwise we
+        // lose the type below
+        return Ok(new_empty_array(arrays[0].data_type()));
+    }
+
     // The run ends need to be adjusted by the sum of the lengths of the 
previous arrays.
     let needed_run_end_adjustments = std::iter::once(R::default_value())
         .chain(
@@ -1905,6 +1911,24 @@ mod tests {
         assert_eq!(expected, actual);
     }
 
+    #[test]
+    fn test_concat_run_array_all_empty() {
+        let run_ends1 = Int32Array::from(vec![2, 4]);
+        let values1 = Int32Array::from(vec![10, 20]);
+        let array1 = RunArray::try_new(&run_ends1, &values1).unwrap();
+        let array1 = array1.slice(0, 0);
+
+        let run_ends2 = Int32Array::from(vec![1, 4]);
+        let values2 = Int32Array::from(vec![30, 40]);
+        let array2 = RunArray::try_new(&run_ends2, &values2).unwrap();
+        let array2 = array2.slice(0, 0);
+
+        let result = concat(&[&array1, &array2]).unwrap();
+        let result_run_array: &arrow_array::RunArray<Int32Type> = 
result.as_run();
+        assert_eq!(result_run_array.len(), 0);
+        assert_eq!(result_run_array.data_type(), array1.data_type());
+    }
+
     #[test]
     fn test_concat_run_array_matching_first_last_value() {
         // Create a run array with run ends [2, 4, 7] and values [10, 20, 30]

Reply via email to