@@ -48,7 +48,7 @@ use crate::utils::log_plan;
4848use datafusion_common:: alias:: AliasGenerator ;
4949use datafusion_common:: config:: ConfigOptions ;
5050use datafusion_common:: instant:: Instant ;
51- use datafusion_common:: { DFSchema , DataFusionError , Result } ;
51+ use datafusion_common:: { internal_err , DFSchema , DataFusionError , Result } ;
5252use datafusion_expr:: logical_plan:: LogicalPlan ;
5353
5454use chrono:: { DateTime , Utc } ;
@@ -80,12 +80,28 @@ pub trait OptimizerRule {
8080 /// A human readable name for this optimizer rule
8181 fn name ( & self ) -> & str ;
8282
83- /// How should the rule be applied by the optimizer? See comments on [`ApplyOrder`] for details.
83+ /// How should the rule be applied by the optimizer? See comments on
84+ /// [`ApplyOrder`] for details.
8485 ///
85- /// If a rule use default None, it should traverse recursively plan inside itself
86+ /// If returns `None`, the default, the rule must handle recursion itself
8687 fn apply_order ( & self ) -> Option < ApplyOrder > {
8788 None
8889 }
90+
91+ /// Does this rule support rewriting owned plans (rather than by reference)?
92+ fn supports_owned ( & self ) -> bool {
93+ false
94+ }
95+
96+ /// if supports_owned returns true, the Optimizer calls
97+ /// [`Self::try_optimize_owned`] instead of [`Self::try_optimize`]
98+ fn try_optimize_owned (
99+ & self ,
100+ _plan : LogicalPlan ,
101+ _config : & dyn OptimizerConfig ,
102+ ) -> Result < Transformed < LogicalPlan > , DataFusionError > {
103+ internal_err ! ( "try_optimized_owned is not implemented for {}" , self . name( ) )
104+ }
89105}
90106
91107/// Options to control the DataFusion Optimizer.
@@ -297,7 +313,10 @@ fn optimize_plan_node(
297313 rule : & dyn OptimizerRule ,
298314 config : & dyn OptimizerConfig ,
299315) -> Result < Transformed < LogicalPlan > > {
300- // TODO: introduce a better API to OptimizerRule to allow rewriting by ownership
316+ if rule. supports_owned ( ) {
317+ return rule. try_optimize_owned ( plan, config) ;
318+ }
319+
301320 rule. try_optimize ( & plan, config) . map ( |maybe_plan| {
302321 match maybe_plan {
303322 Some ( new_plan) => {
0 commit comments