@@ -26,7 +26,7 @@ use datafusion_expr::ColumnarValue;
2626use std:: fmt:: { Debug , Display } ;
2727
2828use arrow:: array:: {
29- make_array, Array , ArrayRef , BooleanArray , MutableArrayData , UInt64Array ,
29+ make_array, Array , ArrayRef , BooleanArray , MutableArrayData , NullArray , UInt64Array ,
3030} ;
3131use arrow:: compute:: { and_kleene, is_not_null, take, SlicesIterator } ;
3232use std:: any:: Any ;
@@ -85,6 +85,10 @@ pub trait PhysicalExpr: Send + Sync + Display + Debug {
8585/// * `mask` - Boolean values used to determine where to put the `truthy` values
8686/// * `truthy` - All values of this array are to scatter according to `mask` into final result.
8787fn scatter ( mask : & BooleanArray , truthy : & dyn Array ) -> Result < ArrayRef > {
88+ if truthy. data_type ( ) == & DataType :: Null {
89+ return Ok ( Arc :: new ( NullArray :: new ( mask. len ( ) ) ) ) ;
90+ }
91+
8892 let truthy = truthy. data ( ) ;
8993
9094 // update the mask so that any null values become false
@@ -192,4 +196,18 @@ mod tests {
192196 assert_eq ! ( & expected, result) ;
193197 Ok ( ( ) )
194198 }
199+
200+ #[ test]
201+ fn scatter_null ( ) -> Result < ( ) > {
202+ let truthy = Arc :: new ( NullArray :: new ( 3 ) ) ;
203+ let mask = BooleanArray :: from ( vec ! [ true , true , false , false , true ] ) ;
204+
205+ // the output array is expected to be the same length as the mask array
206+ let expected = NullArray :: new ( 5 ) ;
207+ let result = scatter ( & mask, truthy. as_ref ( ) ) ?;
208+ let result = result. as_any ( ) . downcast_ref :: < NullArray > ( ) . unwrap ( ) ;
209+
210+ assert_eq ! ( & expected, result) ;
211+ Ok ( ( ) )
212+ }
195213}
0 commit comments