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

tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/master by this push:
     new ebcc4a5851 Align buffers in ArrayData.child_data as well (#6462)
ebcc4a5851 is described below

commit ebcc4a585136cd1d9696c38c41f71c9ced181f57
Author: Enrico Minack <[email protected]>
AuthorDate: Fri Sep 27 10:47:30 2024 +0200

    Align buffers in ArrayData.child_data as well (#6462)
---
 arrow-data/src/data.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 47 insertions(+), 2 deletions(-)

diff --git a/arrow-data/src/data.rs b/arrow-data/src/data.rs
index 8c9e002e21..8af2a91cf1 100644
--- a/arrow-data/src/data.rs
+++ b/arrow-data/src/data.rs
@@ -693,15 +693,21 @@ impl ArrayData {
     ///
     /// This can be useful for when interacting with data sent over IPC or 
FFI, that may
     /// not meet the minimum alignment requirements
+    ///
+    /// This also aligns buffers of children data
     pub fn align_buffers(&mut self) {
         let layout = layout(&self.data_type);
         for (buffer, spec) in self.buffers.iter_mut().zip(&layout.buffers) {
             if let BufferSpec::FixedWidth { alignment, .. } = spec {
                 if buffer.as_ptr().align_offset(*alignment) != 0 {
-                    *buffer = Buffer::from_slice_ref(buffer.as_ref())
+                    *buffer = Buffer::from_slice_ref(buffer.as_ref());
                 }
             }
         }
+        // align children data recursively
+        for data in self.child_data.iter_mut() {
+            data.align_buffers()
+        }
     }
 
     /// "cheap" validation of an `ArrayData`. Ensures buffers are
@@ -1961,7 +1967,7 @@ impl From<ArrayData> for ArrayDataBuilder {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use arrow_schema::Field;
+    use arrow_schema::{Field, Fields};
 
     // See arrow/tests/array_data_validation.rs for test of array validation
 
@@ -2224,6 +2230,7 @@ mod tests {
         };
         data.validate_full().unwrap();
 
+        // break alignment in data
         data.buffers[0] = sliced;
         let err = data.validate().unwrap_err();
 
@@ -2236,6 +2243,44 @@ mod tests {
         data.validate_full().unwrap();
     }
 
+    #[test]
+    fn test_alignment_struct() {
+        let buffer = Buffer::from_vec(vec![1_i32, 2_i32, 3_i32]);
+        let sliced = buffer.slice(1);
+
+        let child_data = ArrayData {
+            data_type: DataType::Int32,
+            len: 0,
+            offset: 0,
+            buffers: vec![buffer],
+            child_data: vec![],
+            nulls: None,
+        };
+
+        let schema = DataType::Struct(Fields::from(vec![Field::new("a", 
DataType::Int32, false)]));
+        let mut data = ArrayData {
+            data_type: schema,
+            len: 0,
+            offset: 0,
+            buffers: vec![],
+            child_data: vec![child_data],
+            nulls: None,
+        };
+        data.validate_full().unwrap();
+
+        // break alignment in child data
+        data.child_data[0].buffers[0] = sliced;
+        let err = data.validate().unwrap_err();
+
+        assert_eq!(
+            err.to_string(),
+            "Invalid argument error: Misaligned buffers[0] in array of type 
Int32, offset from expected alignment of 4 by 1"
+        );
+
+        data.align_buffers();
+        data.validate_full().unwrap();
+    }
+
     #[test]
     fn test_null_view_types() {
         let array_len = 32;

Reply via email to