@@ -49,6 +49,12 @@ impl ParquetVariant {
4949pub struct ParquetVariantMetadata {
5050 /// Whether the un-shredded `value` child is present.
5151 pub has_value : bool ,
52+ /// Whether the `value` child is nullable.
53+ ///
54+ /// In partially-shredded layouts, rows whose data lives entirely in `typed_value` have a
55+ /// null `value` slot, so the Arrow field is marked nullable. This flag preserves that
56+ /// distinction across serialization round-trips.
57+ pub value_nullable : bool ,
5258 /// DType of the shredded `typed_value`, if present.
5359 ///
5460 /// This is required to deserialize non-variant shredded children.
@@ -63,6 +69,9 @@ struct ParquetVariantMetadataProto {
6369 /// DType of the shredded `typed_value`, if present.
6470 #[ prost( message, optional, tag = "2" ) ]
6571 pub typed_value_dtype : Option < pb:: DType > ,
72+ /// Whether the `value` child is nullable.
73+ #[ prost( bool , tag = "3" ) ]
74+ pub value_nullable : bool ,
6675}
6776
6877vtable ! ( ParquetVariant ) ;
@@ -194,6 +203,10 @@ impl VTable for ParquetVariant {
194203 fn metadata ( array : & ParquetVariantArray ) -> VortexResult < Self :: Metadata > {
195204 Ok ( ParquetVariantMetadata {
196205 has_value : array. value . is_some ( ) ,
206+ value_nullable : array
207+ . value
208+ . as_ref ( )
209+ . is_some_and ( |v| v. dtype ( ) . is_nullable ( ) ) ,
197210 typed_value_dtype : array. typed_value . as_ref ( ) . map ( |tv| tv. dtype ( ) . clone ( ) ) ,
198211 } )
199212 }
@@ -208,6 +221,7 @@ impl VTable for ParquetVariant {
208221 ParquetVariantMetadataProto {
209222 has_value : metadata. has_value ,
210223 typed_value_dtype,
224+ value_nullable : metadata. value_nullable ,
211225 }
212226 . encode_to_vec ( ) ,
213227 ) )
@@ -227,6 +241,7 @@ impl VTable for ParquetVariant {
227241 } ;
228242 Ok ( ParquetVariantMetadata {
229243 has_value : proto. has_value ,
244+ value_nullable : proto. value_nullable ,
230245 typed_value_dtype,
231246 } )
232247 }
@@ -264,7 +279,11 @@ impl VTable for ParquetVariant {
264279 child_idx += 1 ;
265280
266281 let value = if metadata. has_value {
267- let v = children. get ( child_idx, & DType :: Binary ( Nullability :: NonNullable ) , len) ?;
282+ let v = children. get (
283+ child_idx,
284+ & DType :: Binary ( metadata. value_nullable . into ( ) ) ,
285+ len,
286+ ) ?;
268287 child_idx += 1 ;
269288 Some ( v)
270289 } else {
0 commit comments