18
18
//! Defines physical expressions that can evaluated at runtime during query execution
19
19
20
20
use std:: any:: Any ;
21
- use std:: convert:: TryFrom ;
22
21
use std:: sync:: Arc ;
23
22
24
23
use crate :: { AggregateExpr , PhysicalExpr } ;
@@ -219,23 +218,26 @@ impl PartialEq<dyn Any> for BoolAnd {
219
218
220
219
#[ derive( Debug ) ]
221
220
struct BoolAndAccumulator {
222
- bool_and : ScalarValue ,
221
+ acc : Option < bool > ,
223
222
}
224
223
225
224
impl BoolAndAccumulator {
226
225
/// new bool_and accumulator
227
226
pub fn try_new ( data_type : & DataType ) -> Result < Self > {
228
- Ok ( Self {
229
- bool_and : ScalarValue :: try_from ( data_type) ?,
230
- } )
227
+ assert_eq ! ( data_type, & DataType :: Boolean ) ;
228
+ Ok ( Self { acc : None } )
231
229
}
232
230
}
233
231
234
232
impl Accumulator for BoolAndAccumulator {
235
233
fn update_batch ( & mut self , values : & [ ArrayRef ] ) -> Result < ( ) > {
236
234
let values = & values[ 0 ] ;
237
- let delta = & bool_and_batch ( values) ?;
238
- self . bool_and = self . bool_and . and ( delta) ?;
235
+ self . acc = match ( self . acc , bool_and_batch ( values) ?) {
236
+ ( None , ScalarValue :: Boolean ( v) ) => v,
237
+ ( Some ( v) , ScalarValue :: Boolean ( None ) ) => Some ( v) ,
238
+ ( Some ( a) , ScalarValue :: Boolean ( Some ( b) ) ) => Some ( a && b) ,
239
+ _ => unreachable ! ( ) ,
240
+ } ;
239
241
Ok ( ( ) )
240
242
}
241
243
@@ -244,16 +246,15 @@ impl Accumulator for BoolAndAccumulator {
244
246
}
245
247
246
248
fn state ( & self ) -> Result < Vec < ScalarValue > > {
247
- Ok ( vec ! [ self . bool_and . clone ( ) ] )
249
+ Ok ( vec ! [ ScalarValue :: Boolean ( self . acc ) ] )
248
250
}
249
251
250
252
fn evaluate ( & self ) -> Result < ScalarValue > {
251
- Ok ( self . bool_and . clone ( ) )
253
+ Ok ( ScalarValue :: Boolean ( self . acc ) )
252
254
}
253
255
254
256
fn size ( & self ) -> usize {
255
- std:: mem:: size_of_val ( self ) - std:: mem:: size_of_val ( & self . bool_and )
256
- + self . bool_and . size ( )
257
+ std:: mem:: size_of_val ( self )
257
258
}
258
259
}
259
260
@@ -413,27 +414,30 @@ impl PartialEq<dyn Any> for BoolOr {
413
414
414
415
#[ derive( Debug ) ]
415
416
struct BoolOrAccumulator {
416
- bool_or : ScalarValue ,
417
+ acc : Option < bool > ,
417
418
}
418
419
419
420
impl BoolOrAccumulator {
420
421
/// new bool_or accumulator
421
422
pub fn try_new ( data_type : & DataType ) -> Result < Self > {
422
- Ok ( Self {
423
- bool_or : ScalarValue :: try_from ( data_type) ?,
424
- } )
423
+ assert_eq ! ( data_type, & DataType :: Boolean ) ;
424
+ Ok ( Self { acc : None } )
425
425
}
426
426
}
427
427
428
428
impl Accumulator for BoolOrAccumulator {
429
429
fn state ( & self ) -> Result < Vec < ScalarValue > > {
430
- Ok ( vec ! [ self . bool_or . clone ( ) ] )
430
+ Ok ( vec ! [ ScalarValue :: Boolean ( self . acc ) ] )
431
431
}
432
432
433
433
fn update_batch ( & mut self , values : & [ ArrayRef ] ) -> Result < ( ) > {
434
434
let values = & values[ 0 ] ;
435
- let delta = bool_or_batch ( values) ?;
436
- self . bool_or = self . bool_or . or ( & delta) ?;
435
+ self . acc = match ( self . acc , bool_or_batch ( values) ?) {
436
+ ( None , ScalarValue :: Boolean ( v) ) => v,
437
+ ( Some ( v) , ScalarValue :: Boolean ( None ) ) => Some ( v) ,
438
+ ( Some ( a) , ScalarValue :: Boolean ( Some ( b) ) ) => Some ( a || b) ,
439
+ _ => unreachable ! ( ) ,
440
+ } ;
437
441
Ok ( ( ) )
438
442
}
439
443
@@ -442,12 +446,11 @@ impl Accumulator for BoolOrAccumulator {
442
446
}
443
447
444
448
fn evaluate ( & self ) -> Result < ScalarValue > {
445
- Ok ( self . bool_or . clone ( ) )
449
+ Ok ( ScalarValue :: Boolean ( self . acc ) )
446
450
}
447
451
448
452
fn size ( & self ) -> usize {
449
- std:: mem:: size_of_val ( self ) - std:: mem:: size_of_val ( & self . bool_or )
450
- + self . bool_or . size ( )
453
+ std:: mem:: size_of_val ( self )
451
454
}
452
455
}
453
456
0 commit comments