Path: blob/main/crates/polars-compute/src/horizontal_flatten/struct_.rs
6939 views
use super::*;12/// # Safety3/// All preconditions in [`super::horizontal_flatten_unchecked`]4pub(super) unsafe fn horizontal_flatten_unchecked(5arrays: &[StructArray],6widths: &[usize],7output_height: usize,8) -> StructArray {9// For StructArrays, we perform the flatten operation individually for every field in the struct10// as well as on the outer validity. We then construct the result array from the individual11// result parts.1213let dtype = arrays[0].dtype();1415let field_arrays: Vec<&[Box<dyn Array>]> = arrays16.iter()17.inspect(|x| debug_assert_eq!(x.dtype(), dtype))18.map(|x| x.values())19.collect::<Vec<_>>();2021let n_fields = field_arrays[0].len();2223let mut scratch = Vec::with_capacity(field_arrays.len());24// Safety: We can take by index as all struct arrays have the same columns names in the same25// order.26// Note: `field_arrays` can be empty for 0-field structs.27let field_arrays = (0..n_fields)28.map(|i| {29scratch.clear();30scratch.extend(field_arrays.iter().map(|v| v[i].clone()));3132super::horizontal_flatten_unchecked(&scratch, widths, output_height)33})34.collect::<Vec<_>>();3536let validity = if arrays.iter().any(|x| x.validity().is_some()) {37let max_height = output_height * widths.iter().fold(0usize, |a, b| a.max(*b));38let mut shared_validity = None;3940// We need to create BooleanArrays from the Bitmaps for dispatch.41let validities: Vec<BooleanArray> = arrays42.iter()43.map(|x| {44x.validity().cloned().unwrap_or_else(|| {45if shared_validity.is_none() {46shared_validity = Some(Bitmap::new_with_value(true, max_height))47};48// We have to slice to exact length to pass an assertion.49shared_validity.clone().unwrap().sliced(0, x.len())50})51})52.map(|x| BooleanArray::from_inner_unchecked(ArrowDataType::Boolean, x, None))53.collect::<Vec<_>>();5455Some(56super::horizontal_flatten_unchecked_impl_generic::<BooleanArray>(57&validities,58widths,59output_height,60&ArrowDataType::Boolean,61)62.as_any()63.downcast_ref::<BooleanArray>()64.unwrap()65.values()66.clone(),67)68} else {69None70};7172StructArray::new(73dtype.clone(),74if n_fields == 0 {75output_height * widths.iter().copied().sum::<usize>()76} else {77debug_assert_eq!(78field_arrays[0].len(),79output_height * widths.iter().copied().sum::<usize>()80);8182field_arrays[0].len()83},84field_arrays,85validity,86)87}888990