Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Validity taken into account when writing StructArray to json #511

Merged
merged 13 commits into from
Oct 10, 2021
Merged
12 changes: 11 additions & 1 deletion src/io/json/write/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ fn struct_array_to_jsonmap_array(array: &StructArray, row_count: usize) -> Vec<M
.take(row_count)
.collect::<Vec<Map<String, Value>>>();

// todo: use validity...
array
.values()
.iter()
Expand Down Expand Up @@ -299,6 +298,17 @@ fn set_column_for_json_rows(
.for_each(|(row, obj)| {
jorgecarleitao marked this conversation as resolved.
Show resolved Hide resolved
row.insert(col_name.to_string(), Value::Object(obj));
});

if let Some(validity) = array.validity() {
rows.iter_mut()
.zip(validity)
.filter(|(_, v)| !*v)
.for_each(|(row, _)| {
if let Some(value) = row.get_mut(col_name) {
*value = Value::Null;
}
});
}
}
DataType::List(_) => {
let array = array.as_any().downcast_ref::<ListArray<i32>>().unwrap();
Expand Down
49 changes: 49 additions & 0 deletions tests/it/io/json/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,55 @@ fn write_simple_rows() {
);
}

#[test]
fn write_nested_struct_with_validity() {
let inner = vec![
Field::new("c121", DataType::Utf8, false),
Field::new("c122", DataType::Int32, false),
];
let fields = vec![
Field::new("c11", DataType::Int32, false),
Field::new("c12", DataType::Struct(inner.clone()), false),
];
let schema = Schema::new(vec![
Field::new("c1", DataType::Struct(fields.clone()), false),
Field::new("c2", DataType::Utf8, false),
]);

let c1 = StructArray::from_data(
DataType::Struct(fields),
vec![
Arc::new(Int32Array::from(&[Some(1), None, Some(5)])),
Arc::new(StructArray::from_data(
DataType::Struct(inner),
vec![
Arc::new(Utf8Array::<i32>::from(&vec![None, Some("f"), Some("g")])),
Arc::new(Int32Array::from(&[Some(20), None, Some(43)])),
],
Some(Bitmap::from([false, true, true])),
)),
],
Some(Bitmap::from([true, true, false])),
);
let c2 = Utf8Array::<i32>::from(&vec![Some("a"), Some("b"), Some("c")]);

let batch = RecordBatch::try_new(Arc::new(schema), vec![Arc::new(c1), Arc::new(c2)]).unwrap();

let mut buf = Vec::new();
{
let mut writer = LineDelimitedWriter::new(&mut buf);
writer.write_batches(&[batch]).unwrap();
}

assert_eq!(
String::from_utf8(buf).unwrap(),
r#"{"c1":{"c11":1,"c12":null},"c2":"a"}
{"c1":{"c11":null,"c12":{"c121":"f","c122":null}},"c2":"b"}
{"c1":null,"c2":"c"}
"#
);
}

#[test]
fn write_nested_structs() {
let c121 = Field::new("c121", DataType::Utf8, false);
Expand Down