@@ -26,7 +26,7 @@ use datafusion_expr::ColumnarValue;
26
26
use std:: fmt:: { Debug , Display } ;
27
27
28
28
use arrow:: array:: {
29
- make_array, Array , ArrayRef , BooleanArray , MutableArrayData , UInt64Array ,
29
+ make_array, Array , ArrayRef , BooleanArray , MutableArrayData , NullArray , UInt64Array ,
30
30
} ;
31
31
use arrow:: compute:: { and_kleene, is_not_null, take, SlicesIterator } ;
32
32
use std:: any:: Any ;
@@ -85,6 +85,10 @@ pub trait PhysicalExpr: Send + Sync + Display + Debug {
85
85
/// * `mask` - Boolean values used to determine where to put the `truthy` values
86
86
/// * `truthy` - All values of this array are to scatter according to `mask` into final result.
87
87
fn 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
+
88
92
let truthy = truthy. data ( ) ;
89
93
90
94
// update the mask so that any null values become false
@@ -192,4 +196,18 @@ mod tests {
192
196
assert_eq ! ( & expected, result) ;
193
197
Ok ( ( ) )
194
198
}
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
+ }
195
213
}
0 commit comments