NOSSLETTER.techLIVE
back to archive

feat: [ElemNull 1] store element-nullable and nested Array fields as native Arrow lists

Language: Go+11147 -1302feature
concepts demonstrated
Go modules and package managementData serialization with Apache ArrowSchema design and validationHandling nested and nullable data structures
The Issue & Context

Previously, Milvus stored nested arrays and element-level nullable fields using per-row protobuf blobs, limiting efficient handling of nested and nullable data in arrays, especially for Array<Array<T>> and element-nullable arrays.

Root Cause Analysis

The old storage format used single-level, element-non-nullable arrays serialized as per-row proto binaries, which could not represent nested arrays or element-level nullability efficiently. This was due to legacy assumptions in FieldMeta and serialization paths that only supported flat arrays without element-level nulls, forcing complex and inefficient per-row blob storage.

Solution Strategy & Architectural Pattern

This PR introduces native Arrow list representations for element-nullable scalar arrays and nested arrays by extending FieldMeta to route these fields to a new ColumnarArrayChunk that supports leaf validity and native integer widths. The storage layer serializes nested lists with per-level nullable flags, and the proxy enforces schema rules allowing element-nullable only within ArrayOfStruct subfields. The change also updates serialization, deserialization, and compaction logic to handle these new native list formats, replacing per-row proto blobs with Arrow ListArray buffers and validity bitmaps.

Key Takeaway for Contributors

When dealing with nested and nullable collections at scale, leveraging a columnar, hierarchical data format like Arrow lists with explicit validity bitmaps enables more efficient storage and processing than opaque per-row blobs, but requires careful schema enforcement and storage-layer support for multi-level nullability.