15
15
// specific language governing permissions and limitations
16
16
// under the License.
17
17
18
- //! Optimizer rule to replace `where false` on a plan with an empty relation.
18
+ //! Optimizer rule to replace `where false or null ` on a plan with an empty relation.
19
19
//! This saves time in planning and executing the query.
20
20
//! Note that this rule should be applied after simplify expressions optimizer rule.
21
21
use crate :: optimizer:: ApplyOrder ;
@@ -27,7 +27,7 @@ use datafusion_expr::{
27
27
28
28
use crate :: { OptimizerConfig , OptimizerRule } ;
29
29
30
- /// Optimization rule that eliminate the scalar value (true/false) filter with an [LogicalPlan::EmptyRelation]
30
+ /// Optimization rule that eliminate the scalar value (true/false/null ) filter with an [LogicalPlan::EmptyRelation]
31
31
#[ derive( Default ) ]
32
32
pub struct EliminateFilter ;
33
33
@@ -46,20 +46,22 @@ impl OptimizerRule for EliminateFilter {
46
46
) -> Result < Option < LogicalPlan > > {
47
47
match plan {
48
48
LogicalPlan :: Filter ( Filter {
49
- predicate : Expr :: Literal ( ScalarValue :: Boolean ( Some ( v ) ) ) ,
49
+ predicate : Expr :: Literal ( ScalarValue :: Boolean ( v ) ) ,
50
50
input,
51
51
..
52
52
} ) => {
53
53
match * v {
54
54
// input also can be filter, apply again
55
- true => Ok ( Some (
55
+ Some ( true ) => Ok ( Some (
56
56
self . try_optimize ( input, _config) ?
57
57
. unwrap_or_else ( || input. as_ref ( ) . clone ( ) ) ,
58
58
) ) ,
59
- false => Ok ( Some ( LogicalPlan :: EmptyRelation ( EmptyRelation {
60
- produce_one_row : false ,
61
- schema : input. schema ( ) . clone ( ) ,
62
- } ) ) ) ,
59
+ Some ( false ) | None => {
60
+ Ok ( Some ( LogicalPlan :: EmptyRelation ( EmptyRelation {
61
+ produce_one_row : false ,
62
+ schema : input. schema ( ) . clone ( ) ,
63
+ } ) ) )
64
+ }
63
65
}
64
66
}
65
67
_ => Ok ( None ) ,
@@ -105,6 +107,21 @@ mod tests {
105
107
assert_optimized_plan_equal ( & plan, expected)
106
108
}
107
109
110
+ #[ test]
111
+ fn filter_null ( ) -> Result < ( ) > {
112
+ let filter_expr = Expr :: Literal ( ScalarValue :: Boolean ( None ) ) ;
113
+
114
+ let table_scan = test_table_scan ( ) . unwrap ( ) ;
115
+ let plan = LogicalPlanBuilder :: from ( table_scan)
116
+ . aggregate ( vec ! [ col( "a" ) ] , vec ! [ sum( col( "b" ) ) ] ) ?
117
+ . filter ( filter_expr) ?
118
+ . build ( ) ?;
119
+
120
+ // No aggregate / scan / limit
121
+ let expected = "EmptyRelation" ;
122
+ assert_optimized_plan_equal ( & plan, expected)
123
+ }
124
+
108
125
#[ test]
109
126
fn filter_false_nested ( ) -> Result < ( ) > {
110
127
let filter_expr = Expr :: Literal ( ScalarValue :: Boolean ( Some ( false ) ) ) ;
0 commit comments