@@ -9,7 +9,9 @@ use std::sync::Arc;
99use reader:: StructReader ;
1010use vortex_array:: { ArrayContext , DeserializeMetadata , EmptyMetadata } ;
1111use vortex_dtype:: { DType , Field , FieldMask , Nullability , StructFields } ;
12- use vortex_error:: { VortexExpect , VortexResult , vortex_bail, vortex_err, vortex_panic} ;
12+ use vortex_error:: {
13+ VortexExpect , VortexResult , vortex_bail, vortex_ensure, vortex_err, vortex_panic,
14+ } ;
1315
1416use crate :: children:: { LayoutChildren , OwnedLayoutChildren } ;
1517use crate :: segments:: { SegmentId , SegmentSource } ;
@@ -49,7 +51,8 @@ impl VTable for StructVTable {
4951 }
5052
5153 fn nchildren ( layout : & Self :: Layout ) -> usize {
52- layout. struct_fields ( ) . nfields ( )
54+ let validity_children = if layout. dtype . is_nullable ( ) { 1 } else { 0 } ;
55+ layout. struct_fields ( ) . nfields ( ) + validity_children
5356 }
5457
5558 fn child ( layout : & Self :: Layout , index : usize ) -> VortexResult < LayoutRef > {
@@ -115,13 +118,15 @@ impl VTable for StructVTable {
115118 let struct_dt = dtype
116119 . as_struct_fields_opt ( )
117120 . ok_or_else ( || vortex_err ! ( "Expected struct dtype" ) ) ?;
118- if children. nchildren ( ) != struct_dt. nfields ( ) {
119- vortex_bail ! (
120- "Struct layout has {} children, but dtype has {} fields" ,
121- children. nchildren( ) ,
122- struct_dt. nfields( )
123- ) ;
124- }
121+
122+ let expected_children = struct_dt. nfields ( ) + ( dtype. is_nullable ( ) as usize ) ;
123+ vortex_ensure ! (
124+ children. nchildren( ) == expected_children,
125+ "Struct layout has {} children, but dtype has {} fields" ,
126+ children. nchildren( ) ,
127+ struct_dt. nfields( )
128+ ) ;
129+
125130 Ok ( StructLayout {
126131 row_count,
127132 dtype : dtype. clone ( ) ,
0 commit comments