in crates/iceberg/src/arrow/value.rs [66:101]
fn r#struct(
&mut self,
_struct: &StructType,
array: &ArrayRef,
results: Vec<Vec<Option<Literal>>>,
) -> Result<Vec<Option<Literal>>> {
let row_len = results.first().map(|column| column.len()).unwrap_or(0);
if let Some(col) = results.iter().find(|col| col.len() != row_len) {
return Err(Error::new(
ErrorKind::DataInvalid,
"The struct columns have different row length",
)
.with_context("first col length", row_len.to_string())
.with_context("actual col length", col.len().to_string()));
}
let mut struct_literals = Vec::with_capacity(row_len);
let mut columns_iters = results
.into_iter()
.map(|column| column.into_iter())
.collect::<Vec<_>>();
for i in 0..row_len {
let mut literals = Vec::with_capacity(columns_iters.len());
for column_iter in columns_iters.iter_mut() {
literals.push(column_iter.next().unwrap());
}
if array.is_null(i) {
struct_literals.push(None);
} else {
struct_literals.push(Some(Literal::Struct(Struct::from_iter(literals))));
}
}
Ok(struct_literals)
}