@@ -105,14 +105,18 @@ impl RangeFilter {
105
105
}
106
106
107
107
#[ tracing:: instrument( level = "debug" , name = "range_filter_eval" , skip_all) ]
108
- pub fn eval ( & self , stats : & StatisticsOfColumns ) -> Result < bool > {
108
+ pub fn eval ( & self , stats : & StatisticsOfColumns , row_count : u64 ) -> Result < bool > {
109
109
let mut columns = Vec :: with_capacity ( self . stat_columns . len ( ) ) ;
110
110
for col in self . stat_columns . iter ( ) {
111
- let val_opt = col. apply_stat_value ( stats, self . origin . clone ( ) ) ?;
112
- if val_opt. is_none ( ) {
113
- return Ok ( true ) ;
111
+ if col. stat_type == StatType :: RowCount {
112
+ columns. push ( Series :: from_data ( vec ! [ row_count] ) ) ;
113
+ } else {
114
+ let val_opt = col. apply_stat_value ( stats, self . origin . clone ( ) ) ?;
115
+ if val_opt. is_none ( ) {
116
+ return Ok ( true ) ;
117
+ }
118
+ columns. push ( val_opt. unwrap ( ) ) ;
114
119
}
115
- columns. push ( val_opt. unwrap ( ) ) ;
116
120
}
117
121
let data_block = DataBlock :: create ( self . schema . clone ( ) , columns) ;
118
122
let executed_data_block = self . executor . execute ( & data_block) ?;
@@ -135,7 +139,7 @@ pub fn build_verifiable_expr(
135
139
136
140
let ( exprs, op) = match expr {
137
141
Expression :: Literal { .. } => return expr. clone ( ) ,
138
- Expression :: ScalarFunction { op, args } => ( args . clone ( ) , op . clone ( ) ) ,
142
+ Expression :: ScalarFunction { op, args } => try_convert_is_null ( op , args . clone ( ) ) ,
139
143
Expression :: BinaryExpression { left, op, right } => match op. to_lowercase ( ) . as_str ( ) {
140
144
"and" => {
141
145
let left = build_verifiable_expr ( left, schema, stat_columns) ;
@@ -173,11 +177,30 @@ fn inverse_operator(op: &str) -> Result<&str> {
173
177
}
174
178
}
175
179
180
+ /// Try to convert `not(is_not_null)` to `is_null`.
181
+ fn try_convert_is_null ( op : & str , args : Vec < Expression > ) -> ( Vec < Expression > , String ) {
182
+ // `is null` will be converted to `not(is not null)` in the parser.
183
+ // we should convert it back to `is null` here.
184
+ if op == "not" && args. len ( ) == 1 {
185
+ if let Expression :: ScalarFunction {
186
+ op : inner_op,
187
+ args : inner_args,
188
+ } = & args[ 0 ]
189
+ {
190
+ if inner_op == "is_not_null" {
191
+ return ( inner_args. clone ( ) , String :: from ( "is_null" ) ) ;
192
+ }
193
+ }
194
+ }
195
+ ( args, String :: from ( op) )
196
+ }
197
+
176
198
#[ derive( Debug , Copy , Clone , PartialEq ) ]
177
199
enum StatType {
178
200
Min ,
179
201
Max ,
180
202
Nulls ,
203
+ RowCount ,
181
204
}
182
205
183
206
impl fmt:: Display for StatType {
@@ -186,6 +209,7 @@ impl fmt::Display for StatType {
186
209
StatType :: Min => write ! ( f, "min" ) ,
187
210
StatType :: Max => write ! ( f, "max" ) ,
188
211
StatType :: Nulls => write ! ( f, "nulls" ) ,
212
+ StatType :: RowCount => write ! ( f, "row_count" ) ,
189
213
}
190
214
}
191
215
}
@@ -209,7 +233,7 @@ impl StatColumn {
209
233
expr : Expression ,
210
234
) -> Self {
211
235
let column_new = format ! ( "{}_{}" , stat_type, field. name( ) ) ;
212
- let data_type = if matches ! ( stat_type, StatType :: Nulls ) {
236
+ let data_type = if matches ! ( stat_type, StatType :: Nulls | StatType :: RowCount ) {
213
237
u64:: to_data_type ( )
214
238
} else {
215
239
field. data_type ( ) . clone ( )
@@ -400,15 +424,16 @@ impl<'a> VerifiableExprBuilder<'a> {
400
424
// TODO: support in/not in.
401
425
match self . op {
402
426
"is_null" => {
427
+ // should_keep: col.null_count > 0
403
428
let nulls_expr = self . nulls_column_expr ( 0 ) ?;
404
429
let scalar_expr = lit ( 0u64 ) ;
405
430
Ok ( nulls_expr. gt ( scalar_expr) )
406
431
}
407
432
"is_not_null" => {
408
- let left_min = self . min_column_expr ( 0 ) ? ;
409
- Ok ( Expression :: create_scalar_function ( "is_not_null" , vec ! [
410
- left_min ,
411
- ] ) )
433
+ // should_keep: col.null_count != col.row_count
434
+ let nulls_expr = self . nulls_column_expr ( 0 ) ? ;
435
+ let row_count_expr = self . row_count_column_expr ( 0 ) ? ;
436
+ Ok ( nulls_expr . not_eq ( row_count_expr ) )
412
437
}
413
438
"=" => {
414
439
// left = right => min_left <= max_right and max_left >= min_right
@@ -582,6 +607,10 @@ impl<'a> VerifiableExprBuilder<'a> {
582
607
fn nulls_column_expr ( & mut self , index : usize ) -> Result < Expression > {
583
608
self . stat_column_expr ( StatType :: Nulls , index)
584
609
}
610
+
611
+ fn row_count_column_expr ( & mut self , index : usize ) -> Result < Expression > {
612
+ self . stat_column_expr ( StatType :: RowCount , index)
613
+ }
585
614
}
586
615
587
616
fn is_like_pattern_escape ( c : u8 ) -> bool {
0 commit comments