@@ -693,15 +693,21 @@ impl ArrayData {
693
693
///
694
694
/// This can be useful for when interacting with data sent over IPC or FFI, that may
695
695
/// not meet the minimum alignment requirements
696
+ ///
697
+ /// This also aligns buffers of children data
696
698
pub fn align_buffers ( & mut self ) {
697
699
let layout = layout ( & self . data_type ) ;
698
700
for ( buffer, spec) in self . buffers . iter_mut ( ) . zip ( & layout. buffers ) {
699
701
if let BufferSpec :: FixedWidth { alignment, .. } = spec {
700
702
if buffer. as_ptr ( ) . align_offset ( * alignment) != 0 {
701
- * buffer = Buffer :: from_slice_ref ( buffer. as_ref ( ) )
703
+ * buffer = Buffer :: from_slice_ref ( buffer. as_ref ( ) ) ;
702
704
}
703
705
}
704
706
}
707
+ // align children data recursively
708
+ for data in self . child_data . iter_mut ( ) {
709
+ data. align_buffers ( )
710
+ }
705
711
}
706
712
707
713
/// "cheap" validation of an `ArrayData`. Ensures buffers are
@@ -1961,7 +1967,7 @@ impl From<ArrayData> for ArrayDataBuilder {
1961
1967
#[ cfg( test) ]
1962
1968
mod tests {
1963
1969
use super :: * ;
1964
- use arrow_schema:: Field ;
1970
+ use arrow_schema:: { Field , Fields } ;
1965
1971
1966
1972
// See arrow/tests/array_data_validation.rs for test of array validation
1967
1973
@@ -2224,6 +2230,7 @@ mod tests {
2224
2230
} ;
2225
2231
data. validate_full ( ) . unwrap ( ) ;
2226
2232
2233
+ // break alignment in data
2227
2234
data. buffers [ 0 ] = sliced;
2228
2235
let err = data. validate ( ) . unwrap_err ( ) ;
2229
2236
@@ -2236,6 +2243,44 @@ mod tests {
2236
2243
data. validate_full ( ) . unwrap ( ) ;
2237
2244
}
2238
2245
2246
+ #[ test]
2247
+ fn test_alignment_struct ( ) {
2248
+ let buffer = Buffer :: from_vec ( vec ! [ 1_i32 , 2_i32 , 3_i32 ] ) ;
2249
+ let sliced = buffer. slice ( 1 ) ;
2250
+
2251
+ let child_data = ArrayData {
2252
+ data_type : DataType :: Int32 ,
2253
+ len : 0 ,
2254
+ offset : 0 ,
2255
+ buffers : vec ! [ buffer] ,
2256
+ child_data : vec ! [ ] ,
2257
+ nulls : None ,
2258
+ } ;
2259
+
2260
+ let schema = DataType :: Struct ( Fields :: from ( vec ! [ Field :: new( "a" , DataType :: Int32 , false ) ] ) ) ;
2261
+ let mut data = ArrayData {
2262
+ data_type : schema,
2263
+ len : 0 ,
2264
+ offset : 0 ,
2265
+ buffers : vec ! [ ] ,
2266
+ child_data : vec ! [ child_data] ,
2267
+ nulls : None ,
2268
+ } ;
2269
+ data. validate_full ( ) . unwrap ( ) ;
2270
+
2271
+ // break alignment in child data
2272
+ data. child_data [ 0 ] . buffers [ 0 ] = sliced;
2273
+ let err = data. validate ( ) . unwrap_err ( ) ;
2274
+
2275
+ assert_eq ! (
2276
+ err. to_string( ) ,
2277
+ "Invalid argument error: Misaligned buffers[0] in array of type Int32, offset from expected alignment of 4 by 1"
2278
+ ) ;
2279
+
2280
+ data. align_buffers ( ) ;
2281
+ data. validate_full ( ) . unwrap ( ) ;
2282
+ }
2283
+
2239
2284
#[ test]
2240
2285
fn test_null_view_types ( ) {
2241
2286
let array_len = 32 ;
0 commit comments