@@ -38,6 +38,7 @@ use crate::single_distinct_to_groupby::SingleDistinctToGroupBy;
3838use crate :: type_coercion:: TypeCoercion ;
3939use crate :: unwrap_cast_in_comparison:: UnwrapCastInComparison ;
4040use chrono:: { DateTime , Utc } ;
41+ use datafusion_common:: config:: ConfigOptions ;
4142use datafusion_common:: { DataFusionError , Result } ;
4243use datafusion_expr:: logical_plan:: LogicalPlan ;
4344use log:: { debug, trace, warn} ;
@@ -74,14 +75,7 @@ pub trait OptimizerConfig {
7475 /// time is used as the value for now()
7576 fn query_execution_start_time ( & self ) -> DateTime < Utc > ;
7677
77- /// Returns false if the given rule should be skipped
78- fn rule_enabled ( & self , name : & str ) -> bool ;
79-
80- /// The optimizer will skip failing rules if this returns true
81- fn skip_failing_rules ( & self ) -> bool ;
82-
83- /// How many times to attempt to optimize the plan
84- fn max_passes ( & self ) -> u8 ;
78+ fn options ( & self ) -> & ConfigOptions ;
8579}
8680
8781/// A standalone [`OptimizerConfig`] that can be used independently
@@ -91,28 +85,25 @@ pub struct OptimizerContext {
9185 /// Query execution start time that can be used to rewrite
9286 /// expressions such as `now()` to use a literal value instead
9387 query_execution_start_time : DateTime < Utc > ,
94- /// Option to skip rules that produce errors
95- skip_failing_rules : bool ,
96- /// Specify whether to enable the filter_null_keys rule
97- filter_null_keys : bool ,
98- /// Maximum number of times to run optimizer against a plan
99- max_passes : u8 ,
88+
89+ options : ConfigOptions ,
10090}
10191
10292impl OptimizerContext {
10393 /// Create optimizer config
10494 pub fn new ( ) -> Self {
95+ let mut options = ConfigOptions :: default ( ) ;
96+ options. optimizer . filter_null_join_keys = true ;
97+
10598 Self {
10699 query_execution_start_time : Utc :: now ( ) ,
107- skip_failing_rules : true ,
108- filter_null_keys : true ,
109- max_passes : 3 ,
100+ options,
110101 }
111102 }
112103
113104 /// Specify whether to enable the filter_null_keys rule
114105 pub fn filter_null_keys ( mut self , filter_null_keys : bool ) -> Self {
115- self . filter_null_keys = filter_null_keys;
106+ self . options . optimizer . filter_null_join_keys = filter_null_keys;
116107 self
117108 }
118109
@@ -129,13 +120,13 @@ impl OptimizerContext {
129120 /// Specify whether the optimizer should skip rules that produce
130121 /// errors, or fail the query
131122 pub fn with_skip_failing_rules ( mut self , b : bool ) -> Self {
132- self . skip_failing_rules = b;
123+ self . options . optimizer . skip_failed_rules = b;
133124 self
134125 }
135126
136127 /// Specify how many times to attempt to optimize the plan
137128 pub fn with_max_passes ( mut self , v : u8 ) -> Self {
138- self . max_passes = v;
129+ self . options . optimizer . max_passes = v as usize ;
139130 self
140131 }
141132}
@@ -152,16 +143,8 @@ impl OptimizerConfig for OptimizerContext {
152143 self . query_execution_start_time
153144 }
154145
155- fn rule_enabled ( & self , name : & str ) -> bool {
156- self . filter_null_keys || name != FilterNullJoinKeys :: NAME
157- }
158-
159- fn skip_failing_rules ( & self ) -> bool {
160- self . skip_failing_rules
161- }
162-
163- fn max_passes ( & self ) -> u8 {
164- self . max_passes
146+ fn options ( & self ) -> & ConfigOptions {
147+ & self . options
165148 }
166149}
167150
@@ -271,18 +254,15 @@ impl Optimizer {
271254 where
272255 F : FnMut ( & LogicalPlan , & dyn OptimizerRule ) ,
273256 {
257+ let options = config. options ( ) ;
274258 let start_time = Instant :: now ( ) ;
275259 let mut plan_str = format ! ( "{}" , plan. display_indent( ) ) ;
276260 let mut new_plan = plan. clone ( ) ;
277261 let mut i = 0 ;
278- while i < config . max_passes ( ) {
262+ while i < options . optimizer . max_passes {
279263 log_plan ( & format ! ( "Optimizer input (pass {i})" ) , & new_plan) ;
280264
281265 for rule in & self . rules {
282- if !config. rule_enabled ( rule. name ( ) ) {
283- debug ! ( "Skipping rule {} due to optimizer config" , rule. name( ) ) ;
284- continue ;
285- }
286266 let result = self . optimize_recursively ( rule, & new_plan, config) ;
287267
288268 match result {
@@ -308,7 +288,7 @@ impl Optimizer {
308288 ) ;
309289 }
310290 Err ( ref e) => {
311- if config . skip_failing_rules ( ) {
291+ if options . optimizer . skip_failed_rules {
312292 // Note to future readers: if you see this warning it signals a
313293 // bug in the DataFusion optimizer. Please consider filing a ticket
314294 // https://github.com/apache/arrow-datafusion
0 commit comments