@@ -26,6 +26,7 @@ use std::borrow::Cow;
2626use std:: collections:: HashSet ;
2727use std:: ops:: Not ;
2828use std:: sync:: Arc ;
29+ use std:: sync:: LazyLock ;
2930
3031use datafusion_common:: config:: ConfigOptions ;
3132use datafusion_common:: nested_struct:: has_one_of_more_common_fields;
@@ -498,8 +499,6 @@ struct ConstEvaluator {
498499 /// The `config_options` are passed from the session to allow scalar functions
499500 /// to access configuration like timezone.
500501 execution_props : ExecutionProps ,
501- input_schema : DFSchema ,
502- input_batch : RecordBatch ,
503502}
504503
505504/// The simplify result of ConstEvaluator
@@ -575,6 +574,19 @@ impl TreeNodeRewriter for ConstEvaluator {
575574 }
576575}
577576
577+ static DUMMY_SCHEMA : LazyLock < Arc < Schema > > =
578+ LazyLock :: new ( || Arc :: new ( Schema :: new ( vec ! [ Field :: new( "." , DataType :: Null , true ) ] ) ) ) ;
579+
580+ static DUMMY_DF_SCHEMA : LazyLock < DFSchema > =
581+ LazyLock :: new ( || DFSchema :: try_from ( Arc :: clone ( & * DUMMY_SCHEMA ) ) . unwrap ( ) ) ;
582+
583+ static DUMMY_BATCH : LazyLock < RecordBatch > = LazyLock :: new ( || {
584+ // Need a single "input" row to produce a single output row
585+ let col = new_null_array ( & DataType :: Null , 1 ) ;
586+ let input_batch = RecordBatch :: try_new ( DUMMY_SCHEMA . clone ( ) , vec ! [ col] ) . unwrap ( ) ;
587+ input_batch
588+ } ) ;
589+
578590impl ConstEvaluator {
579591 /// Create a new `ConstantEvaluator`.
580592 ///
@@ -588,25 +600,13 @@ impl ConstEvaluator {
588600 pub fn try_new ( config_options : Option < Arc < ConfigOptions > > ) -> Result < Self > {
589601 // The dummy column name is unused and doesn't matter as only
590602 // expressions without column references can be evaluated
591- static DUMMY_COL_NAME : & str = "." ;
592- let schema = Arc :: new ( Schema :: new ( vec ! [ Field :: new(
593- DUMMY_COL_NAME ,
594- DataType :: Null ,
595- true ,
596- ) ] ) ) ;
597- let input_schema = DFSchema :: try_from ( Arc :: clone ( & schema) ) ?;
598- // Need a single "input" row to produce a single output row
599- let col = new_null_array ( & DataType :: Null , 1 ) ;
600- let input_batch = RecordBatch :: try_new ( schema, vec ! [ col] ) ?;
601603
602604 let mut execution_props = ExecutionProps :: new ( ) ;
603605 execution_props. config_options = config_options;
604606
605607 Ok ( Self {
606608 can_evaluate : vec ! [ ] ,
607609 execution_props,
608- input_schema,
609- input_batch,
610610 } )
611611 }
612612
@@ -702,16 +702,13 @@ impl ConstEvaluator {
702702 return ConstSimplifyResult :: NotSimplified ( s, m) ;
703703 }
704704
705- let phys_expr = match create_physical_expr (
706- & expr,
707- & self . input_schema ,
708- & self . execution_props ,
709- ) {
710- Ok ( e) => e,
711- Err ( err) => return ConstSimplifyResult :: SimplifyRuntimeError ( err, expr) ,
712- } ;
705+ let phys_expr =
706+ match create_physical_expr ( & expr, & DUMMY_DF_SCHEMA , & self . execution_props ) {
707+ Ok ( e) => e,
708+ Err ( err) => return ConstSimplifyResult :: SimplifyRuntimeError ( err, expr) ,
709+ } ;
713710 let metadata = phys_expr
714- . return_field ( self . input_batch . schema_ref ( ) )
711+ . return_field ( DUMMY_BATCH . schema_ref ( ) )
715712 . ok ( )
716713 . and_then ( |f| {
717714 let m = f. metadata ( ) ;
@@ -720,7 +717,7 @@ impl ConstEvaluator {
720717 false => Some ( FieldMetadata :: from ( m) ) ,
721718 }
722719 } ) ;
723- let col_val = match phys_expr. evaluate ( & self . input_batch ) {
720+ let col_val = match phys_expr. evaluate ( & & DUMMY_BATCH ) {
724721 Ok ( v) => v,
725722 Err ( err) => return ConstSimplifyResult :: SimplifyRuntimeError ( err, expr) ,
726723 } ;
@@ -1698,10 +1695,11 @@ impl TreeNodeRewriter for Simplifier<'_> {
16981695 {
16991696 // Repeated occurrences of wildcard are redundant so remove them
17001697 // exp LIKE '%%' --> exp LIKE '%'
1701- let simplified_pattern = Regex :: new ( "%%+" )
1702- . unwrap ( )
1703- . replace_all ( pattern_str, "%" )
1704- . to_string ( ) ;
1698+
1699+ static LIKE_REGEX : LazyLock < Regex > =
1700+ LazyLock :: new ( || Regex :: new ( "%%+" ) . unwrap ( ) ) ;
1701+ let simplified_pattern =
1702+ LIKE_REGEX . replace_all ( pattern_str, "%" ) . to_string ( ) ;
17051703 Transformed :: yes ( Expr :: Like ( Like {
17061704 pattern : Box :: new (
17071705 string_scalar. to_expr ( & simplified_pattern) ,
0 commit comments