@@ -32,8 +32,8 @@ use datafusion_expr::expr::ScalarFunction;
3232use datafusion_expr:: logical_plan:: builder:: table_scan_with_filters;
3333use datafusion_expr:: simplify:: SimplifyInfo ;
3434use datafusion_expr:: {
35- Cast , ColumnarValue , ExprSchemable , LogicalPlan , LogicalPlanBuilder , ScalarUDF ,
36- Volatility , table_scan,
35+ Cast , ColumnarValue , ExprSchemable , LogicalPlan , LogicalPlanBuilder , Projection ,
36+ ScalarUDF , Volatility , table_scan,
3737} ;
3838use datafusion_functions:: math;
3939use datafusion_optimizer:: optimizer:: Optimizer ;
@@ -528,47 +528,68 @@ fn multiple_now() -> Result<()> {
528528 Ok ( ( ) )
529529}
530530
531+ /// Unwraps an alias expression to get the inner expression
532+ fn unrwap_aliases ( expr : & Expr ) -> & Expr {
533+ match expr {
534+ Expr :: Alias ( alias) => unrwap_aliases ( & alias. expr ) ,
535+ expr => expr,
536+ }
537+ }
538+
531539/// Test that `now()` is simplified to a literal when execution start time is set,
532540/// but remains as an expression when no execution start time is available.
533541#[ test]
534542fn now_simplification_with_and_without_start_time ( ) {
535- let schema = expr_test_schema ( ) ;
543+ let plan = LogicalPlanBuilder :: empty ( false )
544+ . project ( vec ! [ now( ) ] )
545+ . unwrap ( )
546+ . build ( )
547+ . unwrap ( ) ;
536548
537549 // Case 1: With execution start time set, now() should be simplified to a literal
538550 {
539- let start_time = Utc :: now ( ) ;
540- let info = MyInfo {
541- schema : Arc :: clone ( & schema) ,
542- execution_props : ExecutionProps :: new ( )
543- . with_query_execution_start_time ( start_time) ,
551+ let time = DateTime :: < Utc > :: from_timestamp_nanos ( 123 ) ;
552+ let ctx: OptimizerContext =
553+ OptimizerContext :: new ( ) . with_query_execution_start_time ( time) ;
554+ let optimizer = SimplifyExpressions { } ;
555+ let simplified = optimizer
556+ . rewrite ( plan. clone ( ) , & ctx)
557+ . expect ( "simplify should succeed" )
558+ . data ;
559+ let LogicalPlan :: Projection ( Projection { expr, .. } ) = simplified else {
560+ panic ! ( "Expected Projection plan" ) ;
544561 } ;
545- let simplifier = ExprSimplifier :: new ( info) ;
546- let simplified = simplifier. simplify ( now ( ) ) . expect ( "simplify should succeed" ) ;
547-
562+ assert_eq ! ( expr. len( ) , 1 ) ;
563+ let simplified = unrwap_aliases ( expr. first ( ) . unwrap ( ) ) ;
548564 // Should be a literal timestamp
549565 match simplified {
550566 Expr :: Literal ( ScalarValue :: TimestampNanosecond ( Some ( ts) , _) , _) => {
551- assert_eq ! ( ts, start_time . timestamp_nanos_opt( ) . unwrap( ) ) ;
567+ assert_eq ! ( * ts, time . timestamp_nanos_opt( ) . unwrap( ) ) ;
552568 }
553569 other => panic ! ( "Expected timestamp literal, got: {other:?}" ) ,
554570 }
555571 }
556572
557573 // Case 2: Without execution start time, now() should remain as a function call
558574 {
559- let info = MyInfo {
560- schema : Arc :: clone ( & schema) ,
561- execution_props : ExecutionProps :: new ( ) , // No start time set
575+ let ctx: OptimizerContext =
576+ OptimizerContext :: new ( ) . without_query_execution_start_time ( ) ;
577+ let optimizer = SimplifyExpressions { } ;
578+ let simplified = optimizer
579+ . rewrite ( plan, & ctx)
580+ . expect ( "simplify should succeed" )
581+ . data ;
582+ let LogicalPlan :: Projection ( Projection { expr, .. } ) = simplified else {
583+ panic ! ( "Expected Projection plan" ) ;
562584 } ;
563- let simplifier = ExprSimplifier :: new ( info) ;
564- let simplified = simplifier. simplify ( now ( ) ) . expect ( "simplify should succeed" ) ;
565-
566- // Should remain as a scalar function (not simplified)
585+ assert_eq ! ( expr. len( ) , 1 ) ;
586+ let simplified = unrwap_aliases ( expr. first ( ) . unwrap ( ) ) ;
587+ // Should still be a now() function call
567588 match simplified {
568- Expr :: ScalarFunction ( func) => {
589+ Expr :: ScalarFunction ( ScalarFunction { func, .. } ) => {
569590 assert_eq ! ( func. name( ) , "now" ) ;
570591 }
571- other => panic ! ( "Expected now() to remain unsimplified , got: {other:?}" ) ,
592+ other => panic ! ( "Expected now() function call , got: {other:?}" ) ,
572593 }
573594 }
574595}
0 commit comments