1717
1818//! Constant folding and algebraic simplification 
1919
20- use  std:: sync:: Arc ; 
21- 
2220use  arrow:: datatypes:: DataType ; 
2321
2422use  crate :: error:: Result ; 
2523use  crate :: execution:: context:: ExecutionProps ; 
2624use  crate :: logical_plan:: { DFSchemaRef ,  Expr ,  ExprRewriter ,  LogicalPlan ,  Operator } ; 
2725use  crate :: optimizer:: optimizer:: OptimizerRule ; 
2826use  crate :: optimizer:: utils; 
29- use  crate :: physical_plan:: functions:: BuiltinScalarFunction ; 
3027use  crate :: scalar:: ScalarValue ; 
3128
3229/// Simplifies plans by rewriting [`Expr`]`s evaluating constants 
@@ -61,18 +58,14 @@ impl OptimizerRule for ConstantFolding {
6158        // children plans. 
6259        let  mut  simplifier = Simplifier  { 
6360            schemas :  plan. all_schemas ( ) , 
64-             execution_props, 
6561        } ; 
6662
67-         let  mut  const_evaluator = utils:: ConstEvaluator :: new ( ) ; 
63+         let  mut  const_evaluator = utils:: ConstEvaluator :: new ( execution_props ) ; 
6864
6965        match  plan { 
70-             LogicalPlan :: Filter  {  predicate,  input }  => Ok ( LogicalPlan :: Filter  { 
71-                 predicate :  predicate. clone ( ) . rewrite ( & mut  simplifier) ?, 
72-                 input :  Arc :: new ( self . optimize ( input,  execution_props) ?) , 
73-             } ) , 
74-             // Rest: recurse into plan, apply optimization where possible 
75-             LogicalPlan :: Projection  {  .. } 
66+             // Recurse into plan, apply optimization where possible 
67+             LogicalPlan :: Filter  {  .. } 
68+             | LogicalPlan :: Projection  {  .. } 
7669            | LogicalPlan :: Window  {  .. } 
7770            | LogicalPlan :: Aggregate  {  .. } 
7871            | LogicalPlan :: Repartition  {  .. } 
@@ -130,7 +123,6 @@ impl OptimizerRule for ConstantFolding {
130123struct  Simplifier < ' a >  { 
131124    /// input schemas 
132125schemas :  Vec < & ' a  DFSchemaRef > , 
133-     execution_props :  & ' a  ExecutionProps , 
134126} 
135127
136128impl < ' a >  Simplifier < ' a >  { 
@@ -228,15 +220,6 @@ impl<'a> ExprRewriter for Simplifier<'a> {
228220                    Expr :: Not ( inner) 
229221                } 
230222            } 
231-             // convert now() --> the time in `ExecutionProps` 
232-             Expr :: ScalarFunction  { 
233-                 fun :  BuiltinScalarFunction :: Now , 
234-                 ..
235-             }  => Expr :: Literal ( ScalarValue :: TimestampNanosecond ( Some ( 
236-                 self . execution_props 
237-                     . query_execution_start_time 
238-                     . timestamp_nanos ( ) , 
239-             ) ) ) , 
240223            expr => { 
241224                // no additional rewrites possible 
242225                expr
@@ -248,10 +231,13 @@ impl<'a> ExprRewriter for Simplifier<'a> {
248231
249232#[ cfg( test) ]  
250233mod  tests { 
234+     use  std:: sync:: Arc ; 
235+ 
251236    use  super :: * ; 
252237    use  crate :: { 
253238        assert_contains, 
254239        logical_plan:: { col,  lit,  max,  min,  DFField ,  DFSchema ,  LogicalPlanBuilder } , 
240+         physical_plan:: functions:: BuiltinScalarFunction , 
255241    } ; 
256242
257243    use  arrow:: datatypes:: * ; 
@@ -282,7 +268,6 @@ mod tests {
282268        let  schema = expr_test_schema ( ) ; 
283269        let  mut  rewriter = Simplifier  { 
284270            schemas :  vec ! [ & schema] , 
285-             execution_props :  & ExecutionProps :: new ( ) , 
286271        } ; 
287272
288273        assert_eq ! ( 
@@ -298,7 +283,6 @@ mod tests {
298283        let  schema = expr_test_schema ( ) ; 
299284        let  mut  rewriter = Simplifier  { 
300285            schemas :  vec ! [ & schema] , 
301-             execution_props :  & ExecutionProps :: new ( ) , 
302286        } ; 
303287
304288        // x = null is always null 
@@ -334,7 +318,6 @@ mod tests {
334318        let  schema = expr_test_schema ( ) ; 
335319        let  mut  rewriter = Simplifier  { 
336320            schemas :  vec ! [ & schema] , 
337-             execution_props :  & ExecutionProps :: new ( ) , 
338321        } ; 
339322
340323        assert_eq ! ( col( "c2" ) . get_type( & schema) ?,  DataType :: Boolean ) ; 
@@ -365,7 +348,6 @@ mod tests {
365348        let  schema = expr_test_schema ( ) ; 
366349        let  mut  rewriter = Simplifier  { 
367350            schemas :  vec ! [ & schema] , 
368-             execution_props :  & ExecutionProps :: new ( ) , 
369351        } ; 
370352
371353        // When one of the operand is not of boolean type, folding the other boolean constant will 
@@ -405,7 +387,6 @@ mod tests {
405387        let  schema = expr_test_schema ( ) ; 
406388        let  mut  rewriter = Simplifier  { 
407389            schemas :  vec ! [ & schema] , 
408-             execution_props :  & ExecutionProps :: new ( ) , 
409390        } ; 
410391
411392        assert_eq ! ( col( "c2" ) . get_type( & schema) ?,  DataType :: Boolean ) ; 
@@ -441,7 +422,6 @@ mod tests {
441422        let  schema = expr_test_schema ( ) ; 
442423        let  mut  rewriter = Simplifier  { 
443424            schemas :  vec ! [ & schema] , 
444-             execution_props :  & ExecutionProps :: new ( ) , 
445425        } ; 
446426
447427        // when one of the operand is not of boolean type, folding the other boolean constant will 
@@ -477,7 +457,6 @@ mod tests {
477457        let  schema = expr_test_schema ( ) ; 
478458        let  mut  rewriter = Simplifier  { 
479459            schemas :  vec ! [ & schema] , 
480-             execution_props :  & ExecutionProps :: new ( ) , 
481460        } ; 
482461
483462        assert_eq ! ( 
@@ -753,27 +732,6 @@ mod tests {
753732        } 
754733    } 
755734
756-     #[ test]  
757-     fn  single_now_expr ( )  { 
758-         let  table_scan = test_table_scan ( ) . unwrap ( ) ; 
759-         let  proj = vec ! [ now_expr( ) ] ; 
760-         let  time = Utc :: now ( ) ; 
761-         let  plan = LogicalPlanBuilder :: from ( table_scan) 
762-             . project ( proj) 
763-             . unwrap ( ) 
764-             . build ( ) 
765-             . unwrap ( ) ; 
766- 
767-         let  expected = format ! ( 
768-             "Projection: TimestampNanosecond({})\  
769- \n   TableScan: test projection=None", 
770-             time. timestamp_nanos( ) 
771-         ) ; 
772-         let  actual = get_optimized_plan_formatted ( & plan,  & time) ; 
773- 
774-         assert_eq ! ( expected,  actual) ; 
775-     } 
776- 
777735    #[ test]  
778736    fn  multiple_now_expr ( )  { 
779737        let  table_scan = test_table_scan ( ) . unwrap ( ) ; 
@@ -838,17 +796,16 @@ mod tests {
838796        //  now() < cast(to_timestamp(...) as int) + 5000000000 
839797        let  plan = LogicalPlanBuilder :: from ( table_scan) 
840798            . filter ( 
841-                 now_expr ( ) 
799+                 cast_to_int64_expr ( now_expr ( ) ) 
842800                    . lt ( cast_to_int64_expr ( to_timestamp_expr ( ts_string) )  + lit ( 50000 ) ) , 
843801            ) 
844802            . unwrap ( ) 
845803            . build ( ) 
846804            . unwrap ( ) ; 
847805
848-         // Note that constant folder should be able to run again and fold 
849-         // this whole expression down to a single constant; 
850-         // https://github.com/apache/arrow-datafusion/issues/1160 
851-         let  expected = "Filter: TimestampNanosecond(1599566400000000000) < CAST(totimestamp(Utf8(\" 2020-09-08T12:05:00+00:00\" )) AS Int64) + Int32(50000)\  
806+         // Note that constant folder runs and folds the entire 
807+         // expression down to a single constant (true) 
808+         let  expected = "Filter: Boolean(true)\  
852809\n   TableScan: test projection=None"; 
853810        let  actual = get_optimized_plan_formatted ( & plan,  & time) ; 
854811
0 commit comments