@@ -10,6 +10,9 @@ use futures::StreamExt;
1010use futures:: pin_mut;
1111use vortex_array:: IntoArray ;
1212use vortex_array:: ToCanonical ;
13+ use vortex_array:: arrays:: BoolArray ;
14+ use vortex_array:: arrays:: DictArray ;
15+ use vortex_array:: arrays:: ListViewArray ;
1316use vortex_array:: arrays:: PrimitiveArray ;
1417use vortex_array:: arrays:: StructArray ;
1518use vortex_array:: dtype:: FieldNames ;
@@ -111,3 +114,52 @@ async fn test_file_roundtrip() {
111114 assert ! ( raw. nbytes( ) > compressed. nbytes( ) ) ;
112115 }
113116}
117+
118+ /// Regression test: writing a Dict<ListView> where the list has
119+ /// Validity::Array(BoolArray) and the dict codes are nullable used to fail
120+ /// with "Array vortex.fill_null does not support serialization".
121+ #[ tokio:: test]
122+ async fn test_dict_listview_validity_roundtrip ( ) {
123+ let elements = PrimitiveArray :: from_iter ( vec ! [ 1i32 , 2 , 3 , 4 , 5 ] ) . into_array ( ) ;
124+ let offsets = PrimitiveArray :: from_iter ( vec ! [ 0u32 , 2 , 4 ] ) . into_array ( ) ;
125+ let sizes = PrimitiveArray :: from_iter ( vec ! [ 2u32 , 2 , 1 ] ) . into_array ( ) ;
126+ let list_validity = Validity :: Array ( BoolArray :: from_iter ( [ true , false , true ] ) . into_array ( ) ) ;
127+ let listview = ListViewArray :: new ( elements, offsets, sizes, list_validity) . into_array ( ) ;
128+
129+ let codes = PrimitiveArray :: new (
130+ vortex_buffer:: buffer![ 0u32 , 0 , 1 , 0 , 2 ] ,
131+ Validity :: from_iter ( vec ! [ true , false , true , true , true ] ) ,
132+ )
133+ . into_array ( ) ;
134+
135+ let dict = DictArray :: new ( codes, listview) . into_array ( ) ;
136+
137+ let data = StructArray :: from_fields ( & [ ( "col" , dict) ] )
138+ . expect ( "from_fields" )
139+ . into_array ( ) ;
140+
141+ let mut bytes = Vec :: new ( ) ;
142+ SESSION
143+ . write_options ( )
144+ . write ( & mut bytes, data. to_array_stream ( ) )
145+ . await
146+ . expect ( "write should not fail with fill_null serialization error" ) ;
147+
148+ let bytes = ByteBuffer :: from ( bytes) ;
149+ let vxf = SESSION . open_options ( ) . open_buffer ( bytes) . expect ( "open" ) ;
150+
151+ let stream = vxf
152+ . scan ( )
153+ . expect ( "scan" )
154+ . into_stream ( )
155+ . expect ( "into_stream" ) ;
156+ pin_mut ! ( stream) ;
157+
158+ let chunk = stream
159+ . next ( )
160+ . await
161+ . unwrap ( )
162+ . expect ( "read back should succeed" ) ;
163+ vortex_array:: assert_arrays_eq!( data, chunk) ;
164+ assert ! ( stream. next( ) . await . is_none( ) , "expected a single chunk" ) ;
165+ }
0 commit comments