@@ -84,6 +84,21 @@ impl NullBuffer {
8484 }
8585 }
8686
87+ /// Computes the union of the nulls in multiple optional [`NullBuffer`]s
88+ ///
89+ /// See [`union`](Self::union)
90+ pub fn union_many ( nulls : & [ Option < & NullBuffer > ] ) -> Option < NullBuffer > {
91+ // Unwrap to BooleanBuffer because BitAndAssign is not implemented for NullBuffer
92+ let buffers: Vec < & BooleanBuffer > = nulls
93+ . iter ( )
94+ . filter_map ( |nb| nb. map ( NullBuffer :: inner) )
95+ . collect ( ) ;
96+ if buffers. is_empty ( ) {
97+ return None ;
98+ }
99+ Some ( Self :: new ( BooleanBuffer :: bitand_many ( & buffers) ) )
100+ }
101+
87102 /// Returns true if all nulls in `other` also exist in self
88103 pub fn contains ( & self , other : & NullBuffer ) -> bool {
89104 if other. null_count == 0 {
@@ -336,4 +351,51 @@ mod tests {
336351 let result = NullBuffer :: from_unsliced_buffer ( buf, 0 ) ;
337352 assert ! ( result. is_none( ) ) ;
338353 }
354+
355+ #[ test]
356+ fn test_union_many_all_none ( ) {
357+ let result = NullBuffer :: union_many ( & [ None , None , None ] ) ;
358+ assert ! ( result. is_none( ) ) ;
359+ }
360+
361+ #[ test]
362+ fn test_union_many_single_some ( ) {
363+ let a = NullBuffer :: from ( & [ true , false , true , true ] ) ;
364+ let result = NullBuffer :: union_many ( & [ Some ( & a) ] ) ;
365+ assert_eq ! ( result, Some ( a) ) ;
366+ }
367+
368+ #[ test]
369+ fn test_union_many_two_inputs ( ) {
370+ let a = NullBuffer :: from ( & [ true , false , true , true ] ) ;
371+ let b = NullBuffer :: from ( & [ true , true , false , true ] ) ;
372+ let result = NullBuffer :: union_many ( & [ Some ( & a) , Some ( & b) ] ) ;
373+ let expected = NullBuffer :: union ( Some ( & a) , Some ( & b) ) ;
374+ assert_eq ! ( result, expected) ;
375+ }
376+
377+ #[ test]
378+ fn test_union_many_three_inputs ( ) {
379+ let a = NullBuffer :: from ( & [ true , false , true , true ] ) ;
380+ let b = NullBuffer :: from ( & [ true , true , false , true ] ) ;
381+ let c = NullBuffer :: from ( & [ false , true , true , true ] ) ;
382+ let result = NullBuffer :: union_many ( & [ Some ( & a) , Some ( & b) , Some ( & c) ] ) ;
383+ let expected = NullBuffer :: from ( & [ false , false , false , true ] ) ;
384+ assert_eq ! ( result, Some ( expected) ) ;
385+ }
386+
387+ #[ test]
388+ fn test_union_many_mixed_none ( ) {
389+ let a = NullBuffer :: from ( & [ true , false , true , true ] ) ;
390+ let b = NullBuffer :: from ( & [ false , true , true , true ] ) ;
391+ let result = NullBuffer :: union_many ( & [ Some ( & a) , None , Some ( & b) ] ) ;
392+ let expected = NullBuffer :: union ( Some ( & a) , Some ( & b) ) ;
393+ assert_eq ! ( result, expected) ;
394+ }
395+
396+ #[ test]
397+ fn test_union_many_empty_slice ( ) {
398+ let result = NullBuffer :: union_many ( & [ ] ) ;
399+ assert ! ( result. is_none( ) ) ;
400+ }
339401}
0 commit comments