@@ -151,7 +151,9 @@ use crate::reader::binary_array::{
151151} ;
152152use crate :: reader:: boolean_array:: BooleanArrayDecoder ;
153153use crate :: reader:: decimal_array:: DecimalArrayDecoder ;
154- use crate :: reader:: list_array:: { ListArrayDecoder , ListViewArrayDecoder } ;
154+ use crate :: reader:: list_array:: {
155+ FixedSizeListArrayDecoder , ListArrayDecoder , ListViewArrayDecoder ,
156+ } ;
155157use crate :: reader:: map_array:: MapArrayDecoder ;
156158use crate :: reader:: null_array:: NullArrayDecoder ;
157159use crate :: reader:: primitive_array:: PrimitiveArrayDecoder ;
@@ -835,6 +837,7 @@ fn make_decoder(
835837 DataType :: LargeList ( _) => Ok ( Box :: new( ListArrayDecoder :: <i64 >:: new( ctx, data_type, is_nullable) ?) ) ,
836838 DataType :: ListView ( _) => Ok ( Box :: new( ListViewArrayDecoder :: <i32 >:: new( ctx, data_type, is_nullable) ?) ) ,
837839 DataType :: LargeListView ( _) => Ok ( Box :: new( ListViewArrayDecoder :: <i64 >:: new( ctx, data_type, is_nullable) ?) ) ,
840+ DataType :: FixedSizeList ( _, _) => Ok ( Box :: new( FixedSizeListArrayDecoder :: new( ctx, data_type, is_nullable) ?) ) ,
838841 DataType :: Struct ( _) => Ok ( Box :: new( StructArrayDecoder :: new( ctx, data_type, is_nullable) ?) ) ,
839842 DataType :: Binary => Ok ( Box :: new( BinaryArrayDecoder :: <i32 >:: default ( ) ) ) ,
840843 DataType :: LargeBinary => Ok ( Box :: new( BinaryArrayDecoder :: <i64 >:: default ( ) ) ) ,
@@ -2308,6 +2311,152 @@ mod tests {
23082311 assert_read_list_view :: < i64 > ( ) ;
23092312 }
23102313
2314+ #[ test]
2315+ fn test_fixed_size_list ( ) {
2316+ let buf = r#"
2317+ {"a": [1, 2, 3]}
2318+ {"a": [4, 5, 6]}
2319+ {"a": [7, 8, 9]}
2320+ "# ;
2321+
2322+ let field = Field :: new_list_field ( DataType :: Int32 , true ) ;
2323+ let schema = Arc :: new ( Schema :: new ( vec ! [ Field :: new(
2324+ "a" ,
2325+ DataType :: FixedSizeList ( Arc :: new( field) , 3 ) ,
2326+ false ,
2327+ ) ] ) ) ;
2328+
2329+ let batches = do_read ( buf, 1024 , false , false , schema) ;
2330+ assert_eq ! ( batches. len( ) , 1 ) ;
2331+
2332+ let col = batches[ 0 ] . column ( 0 ) . as_fixed_size_list ( ) ;
2333+ assert_eq ! ( col. len( ) , 3 ) ;
2334+ assert_eq ! ( col. value_length( ) , 3 ) ;
2335+
2336+ let values = col. values ( ) . as_primitive :: < Int32Type > ( ) ;
2337+ assert_eq ! ( values. values( ) , & [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] ) ;
2338+ }
2339+
2340+ #[ test]
2341+ fn test_fixed_size_list_nullable ( ) {
2342+ let buf = r#"
2343+ {"a": [1, 2]}
2344+ {"a": null}
2345+ {"a": [3, null]}
2346+ "# ;
2347+
2348+ let field = Field :: new_list_field ( DataType :: Int32 , true ) ;
2349+ let schema = Arc :: new ( Schema :: new ( vec ! [ Field :: new(
2350+ "a" ,
2351+ DataType :: FixedSizeList ( Arc :: new( field) , 2 ) ,
2352+ true ,
2353+ ) ] ) ) ;
2354+
2355+ let batches = do_read ( buf, 1024 , false , false , schema) ;
2356+ assert_eq ! ( batches. len( ) , 1 ) ;
2357+
2358+ let col = batches[ 0 ] . column ( 0 ) . as_fixed_size_list ( ) ;
2359+ assert_eq ! ( col. len( ) , 3 ) ;
2360+ assert ! ( col. is_valid( 0 ) ) ;
2361+ assert ! ( col. is_null( 1 ) ) ;
2362+ assert ! ( col. is_valid( 2 ) ) ;
2363+
2364+ let values = col. values ( ) . as_primitive :: < Int32Type > ( ) ;
2365+ assert_eq ! ( values. value( 0 ) , 1 ) ;
2366+ assert_eq ! ( values. value( 1 ) , 2 ) ;
2367+ assert_eq ! ( values. value( 4 ) , 3 ) ;
2368+ assert ! ( values. is_null( 5 ) ) ;
2369+ }
2370+
2371+ #[ test]
2372+ fn test_fixed_size_list_wrong_size ( ) {
2373+ let buf = r#"{"a": [1, 2, 3]}"# ;
2374+
2375+ let field = Field :: new_list_field ( DataType :: Int32 , true ) ;
2376+ let schema = Arc :: new ( Schema :: new ( vec ! [ Field :: new(
2377+ "a" ,
2378+ DataType :: FixedSizeList ( Arc :: new( field) , 2 ) ,
2379+ false ,
2380+ ) ] ) ) ;
2381+
2382+ let err = ReaderBuilder :: new ( schema)
2383+ . build ( Cursor :: new ( buf. as_bytes ( ) ) )
2384+ . unwrap ( )
2385+ . next ( )
2386+ . unwrap ( )
2387+ . unwrap_err ( ) ;
2388+
2389+ assert ! ( err. to_string( ) . contains( "expected 2 but got 3" ) , "{}" , err) ;
2390+ }
2391+
2392+ #[ test]
2393+ fn test_fixed_size_list_nested ( ) {
2394+ let buf = r#"
2395+ {"a": [[1, 2], [3, 4]]}
2396+ {"a": [[5, 6], [7, 8]]}
2397+ "# ;
2398+
2399+ let inner_field = Field :: new_list_field ( DataType :: Int32 , true ) ;
2400+ let inner_type = DataType :: FixedSizeList ( Arc :: new ( inner_field) , 2 ) ;
2401+ let outer_field = Arc :: new ( Field :: new_list_field ( inner_type. clone ( ) , true ) ) ;
2402+ let schema = Arc :: new ( Schema :: new ( vec ! [ Field :: new(
2403+ "a" ,
2404+ DataType :: FixedSizeList ( outer_field, 2 ) ,
2405+ false ,
2406+ ) ] ) ) ;
2407+
2408+ let batches = do_read ( buf, 1024 , false , false , schema) ;
2409+ assert_eq ! ( batches. len( ) , 1 ) ;
2410+
2411+ let col = batches[ 0 ] . column ( 0 ) . as_fixed_size_list ( ) ;
2412+ assert_eq ! ( col. len( ) , 2 ) ;
2413+ assert_eq ! ( col. value_length( ) , 2 ) ;
2414+
2415+ let inner = col. values ( ) . as_fixed_size_list ( ) ;
2416+ assert_eq ! ( inner. len( ) , 4 ) ;
2417+ assert_eq ! ( inner. value_length( ) , 2 ) ;
2418+
2419+ let values = inner. values ( ) . as_primitive :: < Int32Type > ( ) ;
2420+ assert_eq ! ( values. values( ) , & [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] ) ;
2421+ }
2422+
2423+ #[ test]
2424+ fn test_fixed_size_list_ignore_type_conflicts ( ) {
2425+ let field = Field :: new ( "item" , DataType :: Int32 , true ) ;
2426+ let schema = Arc :: new ( Schema :: new ( vec ! [ Field :: new(
2427+ "a" ,
2428+ DataType :: FixedSizeList ( Arc :: new( field) , 2 ) ,
2429+ true ,
2430+ ) ] ) ) ;
2431+
2432+ let json = vec ! [
2433+ json!( { "a" : [ 1 , 2 ] } ) ,
2434+ json!( { "a" : "not a list" } ) ,
2435+ json!( { "a" : 42 } ) ,
2436+ json!( { "a" : [ 6 , 7 ] } ) ,
2437+ ] ;
2438+
2439+ let mut decoder = ReaderBuilder :: new ( schema)
2440+ . with_ignore_type_conflicts ( true )
2441+ . build_decoder ( )
2442+ . unwrap ( ) ;
2443+ decoder. serialize ( & json) . unwrap ( ) ;
2444+ let batch = decoder. flush ( ) . unwrap ( ) . unwrap ( ) ;
2445+
2446+ let col = batch. column ( 0 ) . as_fixed_size_list ( ) ;
2447+ assert_eq ! ( col. len( ) , 4 ) ;
2448+ assert ! ( col. is_valid( 0 ) ) ;
2449+ assert ! ( col. is_null( 1 ) ) ; // string -> null
2450+ assert ! ( col. is_null( 2 ) ) ; // number -> null
2451+ assert ! ( col. is_valid( 3 ) ) ;
2452+
2453+ let values = col. values ( ) . as_primitive :: < Int32Type > ( ) ;
2454+ assert_eq ! ( values. value( 0 ) , 1 ) ;
2455+ assert_eq ! ( values. value( 1 ) , 2 ) ;
2456+ assert_eq ! ( values. value( 6 ) , 6 ) ;
2457+ assert_eq ! ( values. value( 7 ) , 7 ) ;
2458+ }
2459+
23112460 #[ test]
23122461 fn test_skip_empty_lines ( ) {
23132462 let schema = Schema :: new ( vec ! [ Field :: new( "a" , DataType :: Int64 , true ) ] ) ;
@@ -3256,6 +3405,11 @@ mod tests {
32563405 DataType :: List ( Arc :: new ( Field :: new ( "item" , DataType :: Int32 , true ) ) ) ,
32573406 false ,
32583407 ) ,
3408+ Field :: new (
3409+ "fixed_size_list" ,
3410+ DataType :: FixedSizeList ( Arc :: new ( Field :: new ( "item" , DataType :: Int32 , true ) ) , 2 ) ,
3411+ false ,
3412+ ) ,
32593413 Field :: new (
32603414 "map" ,
32613415 DataType :: Map (
@@ -3312,6 +3466,11 @@ mod tests {
33123466 DataType :: List ( Arc :: new ( Field :: new ( "item" , DataType :: Int32 , true ) ) ) ,
33133467 true ,
33143468 ) ,
3469+ Field :: new (
3470+ "fixed_size_list" ,
3471+ DataType :: FixedSizeList ( Arc :: new ( Field :: new ( "item" , DataType :: Int32 , true ) ) , 2 ) ,
3472+ true ,
3473+ ) ,
33153474 Field :: new (
33163475 "map" ,
33173476 DataType :: Map (
0 commit comments