in crates/core/src/avro_to_arrow/arrow_array_reader.rs [280:373]
fn list_array_string_array_builder<D>(
&self,
data_type: &DataType,
col_name: &str,
rows: RecordSlice,
) -> ArrowResult<ArrayRef>
where
D: ArrowPrimitiveType + ArrowDictionaryKeyType,
{
let mut builder: Box<dyn ArrayBuilder> = match data_type {
DataType::Utf8 => {
let values_builder = StringBuilder::with_capacity(rows.len(), 5);
Box::new(ListBuilder::new(values_builder))
}
DataType::Dictionary(_, _) => {
let values_builder = self.build_string_dictionary_builder::<D>(rows.len() * 5);
Box::new(ListBuilder::new(values_builder))
}
e => {
return Err(SchemaError(format!(
"Nested list data builder type is not supported: {e:?}"
)))
}
};
for row in rows {
if let Some(value) = self.field_lookup(col_name, row) {
let value = maybe_resolve_union(value);
// value can be an array or a scalar
let vals: Vec<Option<String>> = if let Value::String(v) = value {
vec![Some(v.to_string())]
} else if let Value::Array(n) = value {
n.iter()
.map(resolve_string)
.collect::<ArrowResult<Vec<Option<String>>>>()?
.into_iter()
.collect::<Vec<Option<String>>>()
} else if let Value::Null = value {
vec![None]
} else if !matches!(value, Value::Record(_)) {
vec![resolve_string(value)?]
} else {
return Err(SchemaError(
"Only scalars are currently supported in Avro arrays".to_string(),
));
};
// TODO: ARROW-10335: APIs of dictionary arrays and others are different. Unify
// them.
match data_type {
DataType::Utf8 => {
let builder = builder
.as_any_mut()
.downcast_mut::<ListBuilder<StringBuilder>>()
.ok_or_else(||SchemaError(
"Cast failed for ListBuilder<StringBuilder> during nested data parsing".to_string(),
))?;
for val in vals {
if let Some(v) = val {
builder.values().append_value(&v)
} else {
builder.values().append_null()
};
}
// Append to the list
builder.append(true);
}
DataType::Dictionary(_, _) => {
let builder = builder.as_any_mut().downcast_mut::<ListBuilder<StringDictionaryBuilder<D>>>().ok_or_else(||SchemaError(
"Cast failed for ListBuilder<StringDictionaryBuilder> during nested data parsing".to_string(),
))?;
for val in vals {
if let Some(v) = val {
let _ = builder.values().append(&v)?;
} else {
builder.values().append_null()
};
}
// Append to the list
builder.append(true);
}
e => {
return Err(SchemaError(format!(
"Nested list data builder type is not supported: {e:?}"
)))
}
}
}
}
Ok(builder.finish() as ArrayRef)
}