diff --git a/arrow-array/src/array/byte_view_array.rs b/arrow-array/src/array/byte_view_array.rs index 09f0f56ba3ac..54a9a943247d 100644 --- a/arrow-array/src/array/byte_view_array.rs +++ b/arrow-array/src/array/byte_view_array.rs @@ -967,15 +967,16 @@ impl<'a, T: ByteViewType + ?Sized> IntoIterator for &'a GenericByteViewArray } impl From for GenericByteViewArray { - fn from(value: ArrayData) -> Self { - let views = value.buffers()[0].clone(); - let views = ScalarBuffer::new(views, value.offset(), value.len()); - let buffers = value.buffers()[1..].to_vec().into(); + fn from(data: ArrayData) -> Self { + let (_data_type, len, nulls, offset, mut buffers, _child_data) = data.into_parts(); + let views = buffers.remove(0); // need to maintain order of remaining buffers + let buffers = Arc::from(buffers); + let views = ScalarBuffer::new(views, offset, len); Self { data_type: T::DATA_TYPE, views, buffers, - nulls: value.nulls().cloned(), + nulls, phantom: Default::default(), } } diff --git a/arrow-array/src/array/struct_array.rs b/arrow-array/src/array/struct_array.rs index 6ad1ead0d250..a738a733218a 100644 --- a/arrow-array/src/array/struct_array.rs +++ b/arrow-array/src/array/struct_array.rs @@ -347,25 +347,26 @@ impl StructArray { impl From for StructArray { fn from(data: ArrayData) -> Self { - let parent_offset = data.offset(); - let parent_len = data.len(); + let (data_type, len, nulls, offset, _buffers, child_data) = data.into_parts(); - let fields = data - .child_data() - .iter() + let parent_offset = offset; + let parent_len = len; + + let fields = child_data + .into_iter() .map(|cd| { if parent_offset != 0 || parent_len != cd.len() { make_array(cd.slice(parent_offset, parent_len)) } else { - make_array(cd.clone()) + make_array(cd) } }) .collect(); Self { - len: data.len(), - data_type: data.data_type().clone(), - nulls: data.nulls().cloned(), + len, + data_type, + nulls, fields, } } diff --git a/arrow-data/src/data.rs b/arrow-data/src/data.rs index df3b2c578f36..15996d546614 100644 --- a/arrow-data/src/data.rs +++ b/arrow-data/src/data.rs @@ -309,6 +309,9 @@ impl ArrayData { /// /// Note: This is a low level API and most users of the arrow crate should create /// arrays using the builders found in [arrow_array](https://docs.rs/arrow-array) + /// or [`ArrayDataBuilder`]. + /// + /// See also [`Self::into_parts`] to recover the fields pub fn try_new( data_type: DataType, len: usize, @@ -351,6 +354,33 @@ impl ArrayData { Ok(new_self) } + /// Return the constituent parts of this ArrayData + /// + /// This is the inverse of [`ArrayData::try_new`]. + /// + /// Returns `(data_type, len, nulls, offset, buffers, child_data)` + pub fn into_parts( + self, + ) -> ( + DataType, + usize, + Option, + usize, + Vec, + Vec, + ) { + let Self { + data_type, + len, + nulls, + offset, + buffers, + child_data, + } = self; + + (data_type, len, nulls, offset, buffers, child_data) + } + /// Returns a builder to construct a [`ArrayData`] instance of the same [`DataType`] #[inline] pub const fn builder(data_type: DataType) -> ArrayDataBuilder {