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

jeffreyvo 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 d76bfb1771 Allow creating zero-sized FixedSizeBinary arrays (#8927)
d76bfb1771 is described below

commit d76bfb17715261a9c907d1f5187d25a1de21df35
Author: Tobias Schwarzinger <[email protected]>
AuthorDate: Sat Nov 29 02:46:03 2025 +0100

    Allow creating zero-sized FixedSizeBinary arrays (#8927)
    
    # Which issue does this PR close?
    
    - Closes #8926 .
    
    Note that creating sch arrays was already possible with the builder API
    (see `test_fixed_size_binary_builder_with_zero_value_length`) but not
    directly with the Array API.
    
    # Rationale for this change
    
    Avoid panicking (divide by zero) in `FixedSizeBinaryArray::try_new(0,
    ...)`
    
    # What changes are included in this PR?
    
    Special case for `size == 0` in `FixedSizeBinaryArray::try_new`.
    
    # Are these changes tested?
    
    Yes, additional constructor tests.
    
    # Are there any user-facing changes?
    
    Yes, no panics and the ability to directly create FSB arrays with
    zero-length items.
---
 arrow-array/src/array/fixed_size_binary_array.rs | 36 +++++++++++++++++++++---
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/arrow-array/src/array/fixed_size_binary_array.rs 
b/arrow-array/src/array/fixed_size_binary_array.rs
index 600ac50eb0..d13cecb180 100644
--- a/arrow-array/src/array/fixed_size_binary_array.rs
+++ b/arrow-array/src/array/fixed_size_binary_array.rs
@@ -76,10 +76,14 @@ impl FixedSizeBinaryArray {
 
     /// Create a new [`FixedSizeBinaryArray`] from the provided parts, 
returning an error on failure
     ///
+    /// Creating an arrow with `size == 0` will try to get the length from the 
null buffer. If
+    /// no null buffer is provided, the resulting array will have length zero.
+    ///
     /// # Errors
     ///
     /// * `size < 0`
     /// * `values.len() / size != nulls.len()`
+    /// * `size == 0 && values.len() != 0`
     pub fn try_new(
         size: i32,
         values: Buffer,
@@ -90,7 +94,18 @@ impl FixedSizeBinaryArray {
             ArrowError::InvalidArgumentError(format!("Size cannot be negative, 
got {size}"))
         })?;
 
-        let len = values.len() / s;
+        let len = if s == 0 {
+            if !values.is_empty() {
+                return Err(ArrowError::InvalidArgumentError(
+                    "Buffer cannot have non-zero length if the item size is 
zero".to_owned(),
+                ));
+            }
+
+            // If the item size is zero, try to determine the length from the 
null buffer
+            nulls.as_ref().map(|n| n.len()).unwrap_or(0)
+        } else {
+            values.len() / s
+        };
         if let Some(n) = nulls.as_ref() {
             if n.len() != len {
                 return Err(ArrowError::InvalidArgumentError(format!(
@@ -672,11 +687,10 @@ impl<'a> IntoIterator for &'a FixedSizeBinaryArray {
 
 #[cfg(test)]
 mod tests {
+    use super::*;
     use crate::RecordBatch;
     use arrow_schema::{Field, Schema};
 
-    use super::*;
-
     #[test]
     fn test_fixed_size_binary_array() {
         let values: [u8; 15] = *b"hellotherearrow";
@@ -1002,10 +1016,24 @@ mod tests {
         );
 
         let nulls = NullBuffer::new_null(3);
-        let err = FixedSizeBinaryArray::try_new(2, buffer, 
Some(nulls)).unwrap_err();
+        let err = FixedSizeBinaryArray::try_new(2, buffer.clone(), 
Some(nulls)).unwrap_err();
         assert_eq!(
             err.to_string(),
             "Invalid argument error: Incorrect length of null buffer for 
FixedSizeBinaryArray, expected 5 got 3"
         );
+
+        let zero_sized = FixedSizeBinaryArray::new(0, Buffer::default(), None);
+        assert_eq!(zero_sized.len(), 0);
+
+        let nulls = NullBuffer::new_null(3);
+        let zero_sized_with_nulls = FixedSizeBinaryArray::new(0, 
Buffer::default(), Some(nulls));
+        assert_eq!(zero_sized_with_nulls.len(), 3);
+
+        let zero_sized_with_non_empty_buffer_err =
+            FixedSizeBinaryArray::try_new(0, buffer, None).unwrap_err();
+        assert_eq!(
+            zero_sized_with_non_empty_buffer_err.to_string(),
+            "Invalid argument error: Buffer cannot have non-zero length if the 
item size is zero"
+        );
     }
 }

Reply via email to