From bf448ea93574ddaaf41a092c4894a6e66c950664 Mon Sep 17 00:00:00 2001
From: Denis Smirnov <sd@picodata.io>
Date: Fri, 17 Dec 2021 12:01:32 +0700
Subject: [PATCH] refactoring: move tree traversal to a separate module.

---
 src/ir.rs           | 106 +------------------------------------------
 src/ir/traversal.rs | 108 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+), 105 deletions(-)
 create mode 100644 src/ir/traversal.rs

diff --git a/src/ir.rs b/src/ir.rs
index 82ed8306d4..b092c3ea6c 100644
--- a/src/ir.rs
+++ b/src/ir.rs
@@ -6,6 +6,7 @@ pub mod distribution;
 pub mod expression;
 pub mod operator;
 pub mod relation;
+pub mod traversal;
 pub mod value;
 
 use crate::errors::QueryPlannerError;
@@ -14,7 +15,6 @@ use expression::Expression;
 use operator::Relational;
 use relation::Table;
 use serde::{Deserialize, Serialize};
-use std::cell::RefCell;
 use std::collections::{HashMap, HashSet};
 
 /// Plan tree node.
@@ -533,109 +533,5 @@ impl Plan {
     }
 }
 
-/// Plan node iterator over its branches.
-///
-/// For example, inner join returns at first a left child, then
-/// the right one. But a relation scan doesn't have any children
-/// and stop iteration at the moment.
-///
-/// We need this iterator to traverse plan tree with `traversal` crate.
-#[derive(Debug)]
-pub struct BranchIterator<'n> {
-    node: &'n Node,
-    step: RefCell<usize>,
-    plan: &'n Plan,
-}
-
-#[allow(dead_code)]
-impl<'n> BranchIterator<'n> {
-    /// Constructor for a new branch iterator instance.
-    #[must_use]
-    pub fn new(node: &'n Node, plan: &'n Plan) -> Self {
-        BranchIterator {
-            node,
-            step: RefCell::new(0),
-            plan,
-        }
-    }
-}
-
-impl<'n> Iterator for BranchIterator<'n> {
-    type Item = &'n Node;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        let get_next_child = |children: &Vec<usize>| -> Option<&Node> {
-            let current_step = *self.step.borrow();
-            let child = children.get(current_step);
-            child.and_then(|pos| {
-                let node = self.plan.nodes.get(*pos);
-                *self.step.borrow_mut() += 1;
-                node
-            })
-        };
-
-        match self.node {
-            Node::Expression(expr) => match expr {
-                Expression::Alias { child, .. } => {
-                    let current_step = *self.step.borrow();
-                    if current_step == 0 {
-                        *self.step.borrow_mut() += 1;
-                        return self.plan.nodes.get(*child);
-                    }
-                    None
-                }
-                Expression::Bool { left, right, .. } => {
-                    let current_step = *self.step.borrow();
-                    if current_step == 0 {
-                        *self.step.borrow_mut() += 1;
-                        return self.plan.nodes.get(*left);
-                    } else if current_step == 1 {
-                        *self.step.borrow_mut() += 1;
-                        return self.plan.nodes.get(*right);
-                    }
-                    None
-                }
-                Expression::Constant { .. } | Expression::Reference { .. } => None,
-                Expression::Row { list, .. } => {
-                    let current_step = *self.step.borrow();
-                    if let Some(node) = list.get(current_step) {
-                        *self.step.borrow_mut() += 1;
-                        return self.plan.nodes.get(*node);
-                    }
-                    None
-                }
-            },
-            Node::Relational(rel) => match rel {
-                Relational::InnerJoin {
-                    children,
-                    condition,
-                    ..
-                } => {
-                    let current_step = *self.step.borrow();
-                    if current_step == 0 || current_step == 1 {
-                        return get_next_child(children);
-                    } else if current_step == 2 {
-                        *self.step.borrow_mut() += 1;
-                        return self.plan.nodes.get(*condition);
-                    }
-                    None
-                }
-                Relational::ScanRelation { .. } => None,
-                Relational::ScanSubQuery { children, .. }
-                | Relational::Motion { children, .. }
-                | Relational::Selection { children, .. }
-                | Relational::Projection { children, .. } => get_next_child(children),
-                Relational::UnionAll { children, .. } => {
-                    let current_step = *self.step.borrow();
-                    if current_step == 0 || current_step == 1 {
-                        return get_next_child(children);
-                    }
-                    None
-                }
-            },
-        }
-    }
-}
-
 #[cfg(test)]
 mod tests;
diff --git a/src/ir/traversal.rs b/src/ir/traversal.rs
new file mode 100644
index 0000000000..c201fba5ab
--- /dev/null
+++ b/src/ir/traversal.rs
@@ -0,0 +1,108 @@
+use super::expression::Expression;
+use super::operator::Relational;
+use super::{Node, Plan};
+use std::cell::RefCell;
+
+/// Plan node iterator over its branches.
+///
+/// For example, inner join returns at first a left child, then
+/// the right one. But a relation scan doesn't have any children
+/// and stop iteration at the moment.
+///
+/// We need this iterator to traverse plan tree with `traversal` crate.
+#[derive(Debug)]
+pub struct BranchIterator<'n> {
+    node: &'n Node,
+    step: RefCell<usize>,
+    plan: &'n Plan,
+}
+
+#[allow(dead_code)]
+impl<'n> BranchIterator<'n> {
+    /// Constructor for a new branch iterator instance.
+    #[must_use]
+    pub fn new(node: &'n Node, plan: &'n Plan) -> Self {
+        BranchIterator {
+            node,
+            step: RefCell::new(0),
+            plan,
+        }
+    }
+}
+
+impl<'n> Iterator for BranchIterator<'n> {
+    type Item = &'n Node;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let get_next_child = |children: &Vec<usize>| -> Option<&Node> {
+            let current_step = *self.step.borrow();
+            let child = children.get(current_step);
+            child.and_then(|pos| {
+                let node = self.plan.nodes.get(*pos);
+                *self.step.borrow_mut() += 1;
+                node
+            })
+        };
+
+        match self.node {
+            Node::Expression(expr) => match expr {
+                Expression::Alias { child, .. } => {
+                    let current_step = *self.step.borrow();
+                    if current_step == 0 {
+                        *self.step.borrow_mut() += 1;
+                        return self.plan.nodes.get(*child);
+                    }
+                    None
+                }
+                Expression::Bool { left, right, .. } => {
+                    let current_step = *self.step.borrow();
+                    if current_step == 0 {
+                        *self.step.borrow_mut() += 1;
+                        return self.plan.nodes.get(*left);
+                    } else if current_step == 1 {
+                        *self.step.borrow_mut() += 1;
+                        return self.plan.nodes.get(*right);
+                    }
+                    None
+                }
+                Expression::Constant { .. } | Expression::Reference { .. } => None,
+                Expression::Row { list, .. } => {
+                    let current_step = *self.step.borrow();
+                    if let Some(node) = list.get(current_step) {
+                        *self.step.borrow_mut() += 1;
+                        return self.plan.nodes.get(*node);
+                    }
+                    None
+                }
+            },
+            Node::Relational(rel) => match rel {
+                Relational::InnerJoin {
+                    children,
+                    condition,
+                    ..
+                } => {
+                    let current_step = *self.step.borrow();
+                    if current_step == 0 || current_step == 1 {
+                        return get_next_child(children);
+                    } else if current_step == 2 {
+                        *self.step.borrow_mut() += 1;
+                        return self.plan.nodes.get(*condition);
+                    }
+                    None
+                }
+                Relational::ScanRelation { .. } => None,
+                Relational::ScanSubQuery { children, .. }
+                | Relational::Motion { children, .. }
+                | Relational::Selection { children, .. }
+                | Relational::Projection { children, .. } => get_next_child(children),
+                Relational::UnionAll { children, .. } => {
+                    let current_step = *self.step.borrow();
+                    if current_step == 0 || current_step == 1 {
+                        return get_next_child(children);
+                    }
+                    None
+                }
+            },
+        }
+    }
+}
-- 
GitLab