Skip to content

Commit a17bbb8

Browse files
committed
fix recursion
1 parent 22a10ae commit a17bbb8

File tree

3 files changed

+20
-14
lines changed

3 files changed

+20
-14
lines changed

datafusion/common/src/tree_node.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ pub trait TreeNode: Sized {
215215
// Traverse children and then call f_up on self if necessary
216216
match pre_visited.tnr {
217217
TreeNodeRecursion::Continue => {
218-
// recurse to children and then apply f_up to self if needed
219-
self.mutate_children(|c| mutator.f_down(c))?
218+
// rewrite children recursively with mutator
219+
self.mutate_children(|c| c.mutate(mutator))?
220220
.try_transform_node_with(
221221
|_: ()| mutator.f_up(self),
222222
TreeNodeRecursion::Jump,

datafusion/expr/src/logical_plan/mutate.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,10 @@ where
193193
}
194194

195195
impl LogicalPlan {
196-
/// applies the closure `f` to each input of this node, in place
196+
/// applies the closure `f` to each input of this node, in place.
197+
///
198+
/// Inputs include both direct children as well as any embedded
199+
/// `LogicalPlan`s embedded in `Expr::Exists`, etc.
197200
///
198201
/// If Err is returned, the inputs may be in a partially modified state
199202
pub fn rewrite_inputs<F>(&mut self, mut f: F) -> Result<Transformed<()>>
@@ -225,11 +228,13 @@ impl LogicalPlan {
225228
rewrite_arc(input, &mut f)
226229
}
227230
LogicalPlan::Extension(extension) => todo!(),
228-
LogicalPlan::Union(Union { inputs, .. }) => inputs
229-
.iter_mut()
230-
.fold(Ok(Transformed::no(())), |acc, input| {
231-
acc.and_then(|acc| rewrite_arc(input, &mut f))
232-
}),
231+
LogicalPlan::Union(Union { inputs, .. }) => {
232+
inputs
233+
.iter_mut()
234+
.fold(Ok(Transformed::no(())), |acc, input| {
235+
acc.and_then(|acc| acc.and_then(|| rewrite_arc(input, &mut f)))
236+
})
237+
}
233238
LogicalPlan::Distinct(
234239
Distinct::All(input) | Distinct::On(DistinctOn { input, .. }),
235240
) => rewrite_arc(input, &mut f),

datafusion/optimizer/src/optimizer.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,11 @@ pub struct Optimizer {
185185
pub rules: Vec<Arc<dyn OptimizerRule + Send + Sync>>,
186186
}
187187

188-
/// If a rule is with `ApplyOrder`, it means the optimizer will derive to handle children instead of
189-
/// recursively handling in rule.
190-
/// We just need handle a subtree pattern itself.
188+
/// If a rule is with `ApplyOrder`, it means the optimizer will handle
189+
/// recursion. If it is `None` the rule must handle any required recursion
191190
///
192-
/// Notice: **sometime** result after optimize still can be optimized, we need apply again.
191+
/// Notice: **sometime** result after optimize still can be optimized, we need
192+
/// apply again.
193193
///
194194
/// Usage Example: Merge Limit (subtree pattern is: Limit-Limit)
195195
/// ```rust
@@ -345,7 +345,7 @@ fn optimize_in_place<'a>(
345345
rule.try_optimize(plan, config).map(|maybe_plan| {
346346
match maybe_plan {
347347
Some(new_plan) => {
348-
*plan = new_plan; // can avoid this copy with better OptimizerRule::try_optimize
348+
*plan = new_plan; // TODO avoid this copy with better OptimizerRule::try_optimize
349349
Transformed::yes(())
350350
}
351351
None => Transformed::no(()),
@@ -378,7 +378,8 @@ impl Optimizer {
378378
log_plan(&format!("Optimizer input (pass {i})"), &new_plan);
379379

380380
for rule in &self.rules {
381-
// If we need to skip failed rules, must copy plan
381+
// If we need to skip failed rules, must copy plan before attempting to rewrite
382+
// as rewriting is destructive
382383
let prev_plan = options
383384
.optimizer
384385
.skip_failed_rules

0 commit comments

Comments
 (0)