This is an automated email from the ASF dual-hosted git repository.

alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new 08030f37fa Implement rewrite for EliminateOneUnion and EliminateJoin 
(#10184)
08030f37fa is described below

commit 08030f37fa34995af2ea43143922476ace82e39d
Author: Lordworms <[email protected]>
AuthorDate: Tue Apr 23 12:38:37 2024 -0500

    Implement rewrite for EliminateOneUnion and EliminateJoin (#10184)
    
    * implement rewrite for EliminateJoin
    
    * implement rewrite for eliminate_on_union
---
 datafusion/expr/src/logical_plan/tree_node.rs   |  2 +-
 datafusion/optimizer/src/eliminate_join.rs      | 51 ++++++++++++++++---------
 datafusion/optimizer/src/eliminate_one_union.rs | 30 ++++++++++-----
 3 files changed, 54 insertions(+), 29 deletions(-)

diff --git a/datafusion/expr/src/logical_plan/tree_node.rs 
b/datafusion/expr/src/logical_plan/tree_node.rs
index f5db5a2704..37a36c36ca 100644
--- a/datafusion/expr/src/logical_plan/tree_node.rs
+++ b/datafusion/expr/src/logical_plan/tree_node.rs
@@ -363,7 +363,7 @@ impl TreeNode for LogicalPlan {
 
 /// Converts a `Arc<LogicalPlan>` without copying, if possible. Copies the plan
 /// if there is a shared reference
-fn unwrap_arc(plan: Arc<LogicalPlan>) -> LogicalPlan {
+pub fn unwrap_arc(plan: Arc<LogicalPlan>) -> LogicalPlan {
     Arc::try_unwrap(plan)
         // if None is returned, there is another reference to this
         // LogicalPlan, so we can not own it, and must clone instead
diff --git a/datafusion/optimizer/src/eliminate_join.rs 
b/datafusion/optimizer/src/eliminate_join.rs
index caf45dda98..fea87e7587 100644
--- a/datafusion/optimizer/src/eliminate_join.rs
+++ b/datafusion/optimizer/src/eliminate_join.rs
@@ -18,7 +18,8 @@
 //! [`EliminateJoin`] rewrites `INNER JOIN` with `true`/`null`
 use crate::optimizer::ApplyOrder;
 use crate::{OptimizerConfig, OptimizerRule};
-use datafusion_common::{Result, ScalarValue};
+use datafusion_common::tree_node::Transformed;
+use datafusion_common::{internal_err, Result, ScalarValue};
 use datafusion_expr::JoinType::Inner;
 use datafusion_expr::{
     logical_plan::{EmptyRelation, LogicalPlan},
@@ -39,38 +40,50 @@ impl EliminateJoin {
 impl OptimizerRule for EliminateJoin {
     fn try_optimize(
         &self,
-        plan: &LogicalPlan,
+        _plan: &LogicalPlan,
         _config: &dyn OptimizerConfig,
     ) -> Result<Option<LogicalPlan>> {
+        internal_err!("Should have called EliminateJoin::rewrite")
+    }
+
+    fn name(&self) -> &str {
+        "eliminate_join"
+    }
+
+    fn apply_order(&self) -> Option<ApplyOrder> {
+        Some(ApplyOrder::TopDown)
+    }
+
+    fn rewrite(
+        &self,
+        plan: LogicalPlan,
+        _config: &dyn OptimizerConfig,
+    ) -> Result<Transformed<LogicalPlan>> {
         match plan {
             LogicalPlan::Join(join) if join.join_type == Inner && 
join.on.is_empty() => {
                 match join.filter {
                     Some(Expr::Literal(ScalarValue::Boolean(Some(true)))) => {
-                        Ok(Some(LogicalPlan::CrossJoin(CrossJoin {
-                            left: join.left.clone(),
-                            right: join.right.clone(),
-                            schema: join.schema.clone(),
+                        Ok(Transformed::yes(LogicalPlan::CrossJoin(CrossJoin {
+                            left: join.left,
+                            right: join.right,
+                            schema: join.schema,
                         })))
                     }
-                    Some(Expr::Literal(ScalarValue::Boolean(Some(false)))) => {
-                        Ok(Some(LogicalPlan::EmptyRelation(EmptyRelation {
+                    Some(Expr::Literal(ScalarValue::Boolean(Some(false)))) => 
Ok(
+                        
Transformed::yes(LogicalPlan::EmptyRelation(EmptyRelation {
                             produce_one_row: false,
-                            schema: join.schema.clone(),
-                        })))
-                    }
-                    _ => Ok(None),
+                            schema: join.schema,
+                        })),
+                    ),
+                    _ => Ok(Transformed::no(LogicalPlan::Join(join))),
                 }
             }
-            _ => Ok(None),
+            _ => Ok(Transformed::no(plan)),
         }
     }
 
-    fn name(&self) -> &str {
-        "eliminate_join"
-    }
-
-    fn apply_order(&self) -> Option<ApplyOrder> {
-        Some(ApplyOrder::TopDown)
+    fn supports_rewrite(&self) -> bool {
+        true
     }
 }
 
diff --git a/datafusion/optimizer/src/eliminate_one_union.rs 
b/datafusion/optimizer/src/eliminate_one_union.rs
index 95a3370ab1..11a9009cd9 100644
--- a/datafusion/optimizer/src/eliminate_one_union.rs
+++ b/datafusion/optimizer/src/eliminate_one_union.rs
@@ -17,8 +17,8 @@
 
 //! [`EliminateOneUnion`]  eliminates single element `Union`
 use crate::{OptimizerConfig, OptimizerRule};
-use datafusion_common::Result;
-use datafusion_expr::logical_plan::{LogicalPlan, Union};
+use datafusion_common::{internal_err, tree_node::Transformed, Result};
+use datafusion_expr::logical_plan::{tree_node::unwrap_arc, LogicalPlan, Union};
 
 use crate::optimizer::ApplyOrder;
 
@@ -36,21 +36,33 @@ impl EliminateOneUnion {
 impl OptimizerRule for EliminateOneUnion {
     fn try_optimize(
         &self,
-        plan: &LogicalPlan,
+        _plan: &LogicalPlan,
         _config: &dyn OptimizerConfig,
     ) -> Result<Option<LogicalPlan>> {
-        match plan {
-            LogicalPlan::Union(Union { inputs, .. }) if inputs.len() == 1 => {
-                Ok(inputs.first().map(|input| input.as_ref().clone()))
-            }
-            _ => Ok(None),
-        }
+        internal_err!("Should have called EliminateOneUnion::rewrite")
     }
 
     fn name(&self) -> &str {
         "eliminate_one_union"
     }
 
+    fn supports_rewrite(&self) -> bool {
+        true
+    }
+
+    fn rewrite(
+        &self,
+        plan: LogicalPlan,
+        _config: &dyn OptimizerConfig,
+    ) -> Result<Transformed<LogicalPlan>> {
+        match plan {
+            LogicalPlan::Union(Union { mut inputs, .. }) if inputs.len() == 1 
=> {
+                Ok(Transformed::yes(unwrap_arc(inputs.pop().unwrap())))
+            }
+            _ => Ok(Transformed::no(plan)),
+        }
+    }
+
     fn apply_order(&self) -> Option<ApplyOrder> {
         Some(ApplyOrder::TopDown)
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to