metesynnada commented on code in PR #5322:
URL: https://github.com/apache/arrow-datafusion/pull/5322#discussion_r1119898906


##########
datafusion/physical-expr/src/utils.rs:
##########
@@ -235,6 +234,82 @@ pub fn ordering_satisfy_concrete<F: FnOnce() -> 
EquivalenceProperties>(
     }
 }
 
+#[derive(Clone, Debug)]
+pub struct ExprTreeNode<T> {
+    expr: Arc<dyn PhysicalExpr>,
+    data: Option<T>,
+    child_nodes: Vec<ExprTreeNode<T>>,
+}
+
+impl<T> ExprTreeNode<T> {
+    pub fn new(expr: Arc<dyn PhysicalExpr>) -> Self {
+        ExprTreeNode {
+            expr,
+            data: None,
+            child_nodes: vec![],
+        }
+    }
+
+    pub fn expression(&self) -> &Arc<dyn PhysicalExpr> {
+        &self.expr
+    }
+
+    pub fn children(&self) -> Vec<ExprTreeNode<T>> {
+        self.expr
+            .children()
+            .into_iter()
+            .map(ExprTreeNode::new)
+            .collect()
+    }
+}
+
+impl<T: Clone> TreeNodeRewritable for ExprTreeNode<T> {
+    fn map_children<F>(mut self, transform: F) -> Result<Self>
+    where
+        F: FnMut(Self) -> Result<Self>,
+    {
+        self.child_nodes = self
+            .children()
+            .into_iter()
+            .map(transform)
+            .collect::<Result<Vec<_>>>()?;
+        Ok(self)
+    }
+}
+
+/// This function converts the [PhysicalExpr] tree into a DAG by collecting 
identical
+/// expressions in one node. Caller specifies the node type in this DAG via the
+/// `constructor` argument, which constructs nodes in this DAG from the 
[ExprTreeNode]
+/// ancillary object.
+pub fn build_dag<T, F>(
+    expr: Arc<dyn PhysicalExpr>,
+    constructor: &F,
+) -> Result<(NodeIndex, StableGraph<T, usize>)>

Review Comment:
   Added.



##########
datafusion/physical-expr/src/rewrite.rs:
##########
@@ -113,6 +113,21 @@ pub trait TreeNodeRewritable: Clone {
         Ok(new_node)
     }
 
+    fn mutable_transform_up<F>(self, op: &mut F) -> Result<Self>
+    where
+        F: FnMut(Self) -> Result<Option<Self>>,
+    {
+        let after_op_children =
+            self.map_children(|node| node.mutable_transform_up(op))?;
+
+        let after_op_children_clone = after_op_children.clone();
+        let new_node = match op(after_op_children)? {
+            Some(value) => value,
+            None => after_op_children_clone,
+        };
+        Ok(new_node)
+    }
+

Review Comment:
   Added, you can check it.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to