@@ -311,6 +311,15 @@ impl LevelInfoBuilder {
311311 nulls : Option < & NullBuffer > ,
312312 range : Range < usize > ,
313313 ) {
314+ // Fast path: entire list array is null; emit bulk null rep/def levels
315+ if nulls. is_some_and ( |nulls| nulls. null_count ( ) == nulls. len ( ) ) {
316+ let count = range. end - range. start ;
317+ child. visit_leaves ( |leaf| {
318+ leaf. extend_uniform_levels ( ctx. def_level - 2 , ctx. rep_level - 1 , count) ;
319+ } ) ;
320+ return ;
321+ }
322+
314323 let offsets = & offsets[ range. start ..range. end + 1 ] ;
315324
316325 let write_non_null_slice =
@@ -502,15 +511,20 @@ impl LevelInfoBuilder {
502511 range : Range < usize > ,
503512 ) {
504513 let write_null = |children : & mut [ LevelInfoBuilder ] , range : Range < usize > | {
514+ let len = range. end - range. start ;
505515 for child in children {
506516 child. visit_leaves ( |info| {
507- let len = range. end - range. start ;
508- info. append_def_level_run ( ctx. def_level - 1 , len) ;
509- info. append_rep_level_run ( ctx. rep_level , len) ;
517+ info. extend_uniform_levels ( ctx. def_level - 1 , ctx. rep_level , len) ;
510518 } )
511519 }
512520 } ;
513521
522+ // Fast path: entire struct array is null; emit bulk null def/rep levels
523+ if nulls. is_some_and ( |nulls| nulls. null_count ( ) == nulls. len ( ) ) {
524+ write_null ( children, range) ;
525+ return ;
526+ }
527+
514528 let write_non_null = |children : & mut [ LevelInfoBuilder ] , range : Range < usize > | {
515529 for child in children {
516530 child. write ( range. clone ( ) )
@@ -560,6 +574,15 @@ impl LevelInfoBuilder {
560574 nulls : Option < & NullBuffer > ,
561575 range : Range < usize > ,
562576 ) {
577+ // Fast path: entire fixed-size list array is null
578+ if nulls. is_some_and ( |nulls| nulls. null_count ( ) == nulls. len ( ) ) {
579+ let count = range. end - range. start ;
580+ child. visit_leaves ( |leaf| {
581+ leaf. extend_uniform_levels ( ctx. def_level - 2 , ctx. rep_level - 1 , count) ;
582+ } ) ;
583+ return ;
584+ }
585+
563586 let write_non_null = |child : & mut LevelInfoBuilder , start_idx : usize , end_idx : usize | {
564587 let values_start = start_idx * fixed_size;
565588 let values_end = end_idx * fixed_size;
@@ -638,6 +661,14 @@ impl LevelInfoBuilder {
638661 fn write_leaf ( info : & mut ArrayLevels , range : Range < usize > ) {
639662 let len = range. end - range. start ;
640663
664+ // Fast path: entire leaf array is null
665+ if let Some ( nulls) = & info. logical_nulls {
666+ if !matches ! ( info. def_levels, LevelData :: Absent ) && nulls. null_count ( ) == nulls. len ( ) {
667+ info. extend_uniform_levels ( info. max_def_level - 1 , info. max_rep_level , len) ;
668+ return ;
669+ }
670+ }
671+
641672 if matches ! ( info. def_levels, LevelData :: Absent ) {
642673 info. non_null_indices . extend ( range. clone ( ) ) ;
643674 } else {
@@ -972,6 +1003,12 @@ impl ArrayLevels {
9721003 }
9731004 }
9741005
1006+ /// Bulk-emit `count` uniform def/rep levels.
1007+ fn extend_uniform_levels ( & mut self , def_val : i16 , rep_val : i16 , count : usize ) {
1008+ self . def_levels . append_run ( def_val, count) ;
1009+ self . rep_levels . append_run ( rep_val, count) ;
1010+ }
1011+
9751012 fn append_def_level_run ( & mut self , value : i16 , count : usize ) {
9761013 self . def_levels . append_run ( value, count) ;
9771014 }
@@ -2442,4 +2479,161 @@ mod tests {
24422479 assert_eq ! ( sliced. non_null_indices, Vec :: <usize >:: new( ) ) ;
24432480 assert_eq ! ( sliced. array. len( ) , 0 ) ;
24442481 }
2482+
2483+ #[ test]
2484+ fn test_all_null_list ( ) {
2485+ // List<Int32> where every list slot is null.
2486+ // Schema: list (nullable) -> item (int32, nullable)
2487+ // Data: [null, null, null, null]
2488+ //
2489+ // Expected: max_def=3, max_rep=1, def/rep levels all 0.
2490+ let item_field = Arc :: new ( Field :: new_list_field ( DataType :: Int32 , true ) ) ;
2491+ let list = ListArray :: new_null ( item_field, 4 ) ;
2492+ let values = list. values ( ) . clone ( ) ;
2493+ let field = Field :: new ( "list" , list. data_type ( ) . clone ( ) , true ) ;
2494+ let array = Arc :: new ( list) as ArrayRef ;
2495+
2496+ let levels = calculate_array_levels ( & array, & field) . unwrap ( ) ;
2497+ assert_eq ! ( levels. len( ) , 1 ) ;
2498+
2499+ let logical_nulls = values. logical_nulls ( ) ;
2500+ let expected = ArrayLevels {
2501+ def_levels : LevelData :: Uniform { value : 0 , count : 4 } ,
2502+ rep_levels : LevelData :: Uniform { value : 0 , count : 4 } ,
2503+ non_null_indices : vec ! [ ] ,
2504+ max_def_level : 3 ,
2505+ max_rep_level : 1 ,
2506+ array : values,
2507+ logical_nulls,
2508+ } ;
2509+ assert_eq ! ( & levels[ 0 ] , & expected) ;
2510+ }
2511+
2512+ #[ test]
2513+ fn test_all_null_fixed_size_list ( ) {
2514+ // FixedSizeList<Int32; 2> where every list slot is null.
2515+ // Schema: list (nullable) -> item (int32, nullable)
2516+ // Data: [null, null, null]
2517+ //
2518+ // Expected: max_def=3, max_rep=1, def/rep levels all 0.
2519+ let item_field = Arc :: new ( Field :: new_list_field ( DataType :: Int32 , true ) ) ;
2520+ let list = FixedSizeListArray :: new_null ( item_field, 2 , 3 ) ;
2521+ let values = list. values ( ) . clone ( ) ;
2522+ let field = Field :: new ( "list" , list. data_type ( ) . clone ( ) , true ) ;
2523+ let array = Arc :: new ( list) as ArrayRef ;
2524+
2525+ let levels = calculate_array_levels ( & array, & field) . unwrap ( ) ;
2526+ assert_eq ! ( levels. len( ) , 1 ) ;
2527+
2528+ let logical_nulls = values. logical_nulls ( ) ;
2529+ let expected = ArrayLevels {
2530+ def_levels : LevelData :: Uniform { value : 0 , count : 3 } ,
2531+ rep_levels : LevelData :: Uniform { value : 0 , count : 3 } ,
2532+ non_null_indices : vec ! [ ] ,
2533+ max_def_level : 3 ,
2534+ max_rep_level : 1 ,
2535+ array : values,
2536+ logical_nulls,
2537+ } ;
2538+ assert_eq ! ( & levels[ 0 ] , & expected) ;
2539+ }
2540+
2541+ #[ test]
2542+ fn test_all_null_struct ( ) {
2543+ // Struct<Int32> where every struct slot is null.
2544+ // Schema: a (struct, nullable) -> c (int32, nullable)
2545+ // Data: [null, null, null, null]
2546+ //
2547+ // Expected: max_def=2, def_levels all 0 (struct is null → child never reached),
2548+ // leaf values are empty.
2549+ let c = Int32Array :: from ( vec ! [ None :: <i32 >; 4 ] ) ;
2550+ let leaf = Arc :: new ( c) as ArrayRef ;
2551+ let c_field = Arc :: new ( Field :: new ( "c" , DataType :: Int32 , true ) ) ;
2552+ let a = StructArray :: from ( ( vec ! [ ( c_field, leaf. clone( ) ) ] , Buffer :: from ( [ 0b00000000 ] ) ) ) ;
2553+ let a_field = Field :: new ( "a" , a. data_type ( ) . clone ( ) , true ) ;
2554+ let a_array = Arc :: new ( a) as ArrayRef ;
2555+
2556+ let levels = calculate_array_levels ( & a_array, & a_field) . unwrap ( ) ;
2557+ assert_eq ! ( levels. len( ) , 1 ) ;
2558+
2559+ let expected = ArrayLevels {
2560+ def_levels : LevelData :: Uniform { value : 0 , count : 4 } ,
2561+ rep_levels : LevelData :: Absent ,
2562+ non_null_indices : vec ! [ ] ,
2563+ max_def_level : 2 ,
2564+ max_rep_level : 0 ,
2565+ array : leaf,
2566+ logical_nulls : Some ( NullBuffer :: new_null ( 4 ) ) ,
2567+ } ;
2568+ assert_eq ! ( & levels[ 0 ] , & expected) ;
2569+ }
2570+
2571+ #[ test]
2572+ fn test_all_null_nested_struct ( ) {
2573+ // Struct<Struct<Int32>> where the outer struct is entirely null.
2574+ // Schema: a (struct, nullable) -> b (struct, nullable) -> c (int32, nullable)
2575+ // Data: [null, null, null]
2576+ //
2577+ // Expected: max_def=3, def_levels all 0.
2578+ let c = Int32Array :: from ( vec ! [ None :: <i32 >; 3 ] ) ;
2579+ let leaf = Arc :: new ( c) as ArrayRef ;
2580+ let c_field = Arc :: new ( Field :: new ( "c" , DataType :: Int32 , true ) ) ;
2581+ let b = StructArray :: from ( ( vec ! [ ( c_field, leaf. clone( ) ) ] , Buffer :: from ( [ 0b00000000 ] ) ) ) ;
2582+ let b_field = Arc :: new ( Field :: new ( "b" , b. data_type ( ) . clone ( ) , true ) ) ;
2583+ let a = StructArray :: from ( (
2584+ vec ! [ ( b_field, Arc :: new( b) as ArrayRef ) ] ,
2585+ Buffer :: from ( [ 0b00000000 ] ) ,
2586+ ) ) ;
2587+ let a_field = Field :: new ( "a" , a. data_type ( ) . clone ( ) , true ) ;
2588+ let a_array = Arc :: new ( a) as ArrayRef ;
2589+
2590+ let levels = calculate_array_levels ( & a_array, & a_field) . unwrap ( ) ;
2591+ assert_eq ! ( levels. len( ) , 1 ) ;
2592+
2593+ let expected = ArrayLevels {
2594+ def_levels : LevelData :: Uniform { value : 0 , count : 3 } ,
2595+ rep_levels : LevelData :: Absent ,
2596+ non_null_indices : vec ! [ ] ,
2597+ max_def_level : 3 ,
2598+ max_rep_level : 0 ,
2599+ array : leaf,
2600+ logical_nulls : Some ( NullBuffer :: new_null ( 3 ) ) ,
2601+ } ;
2602+ assert_eq ! ( & levels[ 0 ] , & expected) ;
2603+ }
2604+
2605+ #[ test]
2606+ fn test_all_null_struct_multiple_children ( ) {
2607+ // Struct with two leaf children, entirely null.
2608+ // Schema: a (struct, nullable) -> { c1 (int32, nullable), c2 (int32, nullable) }
2609+ // Data: [null, null]
2610+ //
2611+ // Both leaf columns should get uniform def_levels=0.
2612+ let c1 = Arc :: new ( Int32Array :: from ( vec ! [ None :: <i32 >; 2 ] ) ) as ArrayRef ;
2613+ let c2 = Arc :: new ( Int32Array :: from ( vec ! [ None :: <i32 >; 2 ] ) ) as ArrayRef ;
2614+ let c1_field = Arc :: new ( Field :: new ( "c1" , DataType :: Int32 , true ) ) ;
2615+ let c2_field = Arc :: new ( Field :: new ( "c2" , DataType :: Int32 , true ) ) ;
2616+ let a = StructArray :: from ( (
2617+ vec ! [ ( c1_field, c1. clone( ) ) , ( c2_field, c2. clone( ) ) ] ,
2618+ Buffer :: from ( [ 0b00000000 ] ) ,
2619+ ) ) ;
2620+ let a_field = Field :: new ( "a" , a. data_type ( ) . clone ( ) , true ) ;
2621+ let a_array = Arc :: new ( a) as ArrayRef ;
2622+
2623+ let levels = calculate_array_levels ( & a_array, & a_field) . unwrap ( ) ;
2624+ assert_eq ! ( levels. len( ) , 2 ) ;
2625+
2626+ for ( i, leaf) in [ c1, c2] . into_iter ( ) . enumerate ( ) {
2627+ let expected = ArrayLevels {
2628+ def_levels : LevelData :: Uniform { value : 0 , count : 2 } ,
2629+ rep_levels : LevelData :: Absent ,
2630+ non_null_indices : vec ! [ ] ,
2631+ max_def_level : 2 ,
2632+ max_rep_level : 0 ,
2633+ array : leaf,
2634+ logical_nulls : Some ( NullBuffer :: new_null ( 2 ) ) ,
2635+ } ;
2636+ assert_eq ! ( & levels[ i] , & expected, "leaf {i} mismatch" ) ;
2637+ }
2638+ }
24452639}
0 commit comments