diff --git a/arrow-array/src/array/struct_array.rs b/arrow-array/src/array/struct_array.rs index 284c3b26a946..0e586ed1ef96 100644 --- a/arrow-array/src/array/struct_array.rs +++ b/arrow-array/src/array/struct_array.rs @@ -197,6 +197,23 @@ impl StructArray { } } + /// Create a new [`StructArray`] containing no fields + /// + /// # Panics + /// + /// If `len != nulls.len()` + pub fn new_empty_fields(len: usize, nulls: Option) -> Self { + if let Some(n) = &nulls { + assert_eq!(len, n.len()) + } + Self { + len, + data_type: DataType::Struct(Fields::empty()), + fields: vec![], + nulls, + } + } + /// Deconstruct this array into its constituent parts pub fn into_parts(self) -> (Fields, Vec, Option) { let f = match self.data_type { diff --git a/arrow-array/src/builder/struct_builder.rs b/arrow-array/src/builder/struct_builder.rs index 0c878e621056..7aa91dacaa8c 100644 --- a/arrow-array/src/builder/struct_builder.rs +++ b/arrow-array/src/builder/struct_builder.rs @@ -233,6 +233,12 @@ impl StructBuilder { /// Builds the `StructArray` and reset this builder. pub fn finish(&mut self) -> StructArray { self.validate_content(); + if self.fields.is_empty() { + return StructArray::new_empty_fields( + self.len(), + self.null_buffer_builder.finish(), + ); + } let arrays = self.field_builders.iter_mut().map(|f| f.finish()).collect(); let nulls = self.null_buffer_builder.finish(); @@ -243,6 +249,13 @@ impl StructBuilder { pub fn finish_cloned(&self) -> StructArray { self.validate_content(); + if self.fields.is_empty() { + return StructArray::new_empty_fields( + self.len(), + self.null_buffer_builder.finish_cloned(), + ); + } + let arrays = self .field_builders .iter() @@ -591,4 +604,19 @@ mod tests { let mut sa = StructBuilder::new(fields, field_builders); sa.finish(); } + + #[test] + fn test_empty() { + let mut builder = StructBuilder::new(Fields::empty(), vec![]); + builder.append(true); + builder.append(false); + + let a1 = builder.finish_cloned(); + let a2 = builder.finish(); + assert_eq!(a1, a2); + assert_eq!(a1.len(), 2); + assert_eq!(a1.null_count(), 1); + assert!(a1.is_valid(0)); + assert!(a1.is_null(1)); + } }