20
20
use std:: hash:: { Hash , Hasher } ;
21
21
use std:: { any:: Any , sync:: Arc } ;
22
22
23
- use arrow:: compute;
24
23
use arrow:: {
25
24
datatypes:: { DataType , Schema } ,
26
25
record_batch:: RecordBatch ,
27
26
} ;
28
- use arrow_array:: { Array , ArrayRef , BooleanArray , Int8Array , UnionArray } ;
29
- use arrow_buffer:: { BooleanBuffer , ScalarBuffer } ;
30
- use arrow_ord:: cmp;
31
27
32
28
use crate :: physical_expr:: down_cast_any_ref;
33
29
use crate :: PhysicalExpr ;
@@ -77,9 +73,9 @@ impl PhysicalExpr for IsNullExpr {
77
73
fn evaluate ( & self , batch : & RecordBatch ) -> Result < ColumnarValue > {
78
74
let arg = self . arg . evaluate ( batch) ?;
79
75
match arg {
80
- ColumnarValue :: Array ( array) => {
81
- Ok ( ColumnarValue :: Array ( Arc :: new ( compute_is_null ( array) ?) ) )
82
- }
76
+ ColumnarValue :: Array ( array) => Ok ( ColumnarValue :: Array ( Arc :: new (
77
+ arrow :: compute :: is_null ( & array) ?,
78
+ ) ) ) ,
83
79
ColumnarValue :: Scalar ( scalar) => Ok ( ColumnarValue :: Scalar (
84
80
ScalarValue :: Boolean ( Some ( scalar. is_null ( ) ) ) ,
85
81
) ) ,
@@ -103,65 +99,6 @@ impl PhysicalExpr for IsNullExpr {
103
99
}
104
100
}
105
101
106
- /// workaround <https://github.com/apache/arrow-rs/issues/6017>,
107
- /// this can be replaced with a direct call to `arrow::compute::is_null` once it's fixed.
108
- pub ( crate ) fn compute_is_null ( array : ArrayRef ) -> Result < BooleanArray > {
109
- if let Some ( union_array) = array. as_any ( ) . downcast_ref :: < UnionArray > ( ) {
110
- if let Some ( offsets) = union_array. offsets ( ) {
111
- dense_union_is_null ( union_array, offsets)
112
- } else {
113
- sparse_union_is_null ( union_array)
114
- }
115
- } else {
116
- compute:: is_null ( array. as_ref ( ) ) . map_err ( Into :: into)
117
- }
118
- }
119
-
120
- /// workaround <https://github.com/apache/arrow-rs/issues/6017>,
121
- /// this can be replaced with a direct call to `arrow::compute::is_not_null` once it's fixed.
122
- pub ( crate ) fn compute_is_not_null ( array : ArrayRef ) -> Result < BooleanArray > {
123
- if array. as_any ( ) . is :: < UnionArray > ( ) {
124
- compute:: not ( & compute_is_null ( array) ?) . map_err ( Into :: into)
125
- } else {
126
- compute:: is_not_null ( array. as_ref ( ) ) . map_err ( Into :: into)
127
- }
128
- }
129
-
130
- fn dense_union_is_null (
131
- union_array : & UnionArray ,
132
- offsets : & ScalarBuffer < i32 > ,
133
- ) -> Result < BooleanArray > {
134
- let child_arrays = ( 0 ..union_array. type_names ( ) . len ( ) )
135
- . map ( |type_id| {
136
- compute:: is_null ( & union_array. child ( type_id as i8 ) ) . map_err ( Into :: into)
137
- } )
138
- . collect :: < Result < Vec < BooleanArray > > > ( ) ?;
139
-
140
- let buffer: BooleanBuffer = offsets
141
- . iter ( )
142
- . zip ( union_array. type_ids ( ) )
143
- . map ( |( offset, type_id) | child_arrays[ * type_id as usize ] . value ( * offset as usize ) )
144
- . collect ( ) ;
145
-
146
- Ok ( BooleanArray :: new ( buffer, None ) )
147
- }
148
-
149
- fn sparse_union_is_null ( union_array : & UnionArray ) -> Result < BooleanArray > {
150
- let type_ids = Int8Array :: new ( union_array. type_ids ( ) . clone ( ) , None ) ;
151
-
152
- let mut union_is_null =
153
- BooleanArray :: new ( BooleanBuffer :: new_unset ( union_array. len ( ) ) , None ) ;
154
- for type_id in 0 ..union_array. type_names ( ) . len ( ) {
155
- let type_id = type_id as i8 ;
156
- let union_is_child = cmp:: eq ( & type_ids, & Int8Array :: new_scalar ( type_id) ) ?;
157
- let child = union_array. child ( type_id) ;
158
- let child_array_is_null = compute:: is_null ( & child) ?;
159
- let child_is_null = compute:: and ( & union_is_child, & child_array_is_null) ?;
160
- union_is_null = compute:: or ( & union_is_null, & child_is_null) ?;
161
- }
162
- Ok ( union_is_null)
163
- }
164
-
165
102
impl PartialEq < dyn Any > for IsNullExpr {
166
103
fn eq ( & self , other : & dyn Any ) -> bool {
167
104
down_cast_any_ref ( other)
@@ -184,7 +121,7 @@ mod tests {
184
121
array:: { BooleanArray , StringArray } ,
185
122
datatypes:: * ,
186
123
} ;
187
- use arrow_array:: { Float64Array , Int32Array } ;
124
+ use arrow_array:: { Array , Float64Array , Int32Array , UnionArray } ;
188
125
use arrow_buffer:: ScalarBuffer ;
189
126
use datafusion_common:: cast:: as_boolean_array;
190
127
@@ -243,8 +180,7 @@ mod tests {
243
180
let array =
244
181
UnionArray :: try_new ( union_fields ( ) , type_ids, None , children) . unwrap ( ) ;
245
182
246
- let array_ref = Arc :: new ( array) as ArrayRef ;
247
- let result = compute_is_null ( array_ref) . unwrap ( ) ;
183
+ let result = arrow:: compute:: is_null ( & array) . unwrap ( ) ;
248
184
249
185
let expected =
250
186
& BooleanArray :: from ( vec ! [ false , true , false , false , true , true , false ] ) ;
@@ -272,8 +208,7 @@ mod tests {
272
208
UnionArray :: try_new ( union_fields ( ) , type_ids, Some ( offsets) , children)
273
209
. unwrap ( ) ;
274
210
275
- let array_ref = Arc :: new ( array) as ArrayRef ;
276
- let result = compute_is_null ( array_ref) . unwrap ( ) ;
211
+ let result = arrow:: compute:: is_null ( & array) . unwrap ( ) ;
277
212
278
213
let expected = & BooleanArray :: from ( vec ! [ false , true , false , true , false , true ] ) ;
279
214
assert_eq ! ( expected, & result) ;
0 commit comments