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"
+ );
}
}