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/arrow-datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new e4bf3fa3b1 refactor: Expr::InSubquery to use a struct (#6295)
e4bf3fa3b1 is described below

commit e4bf3fa3b13f7b25509aed47dc3a27a2da2bbd35
Author: Chuanle Chen <[email protected]>
AuthorDate: Tue May 9 18:10:34 2023 +0800

    refactor: Expr::InSubquery to use a struct (#6295)
    
    Co-authored-by: jackwener <[email protected]>
---
 datafusion/core/src/datasource/listing/helpers.rs  |  2 +-
 datafusion/core/src/physical_plan/planner.rs       |  2 +-
 datafusion/expr/src/expr.rs                        | 45 +++++++++++++-------
 datafusion/expr/src/expr_fn.rs                     | 24 +++++------
 datafusion/expr/src/expr_schema.rs                 |  6 +--
 datafusion/expr/src/logical_plan/plan.rs           |  5 ++-
 datafusion/expr/src/tree_node/expr.rs              | 13 +++---
 datafusion/expr/src/utils.rs                       |  4 +-
 datafusion/optimizer/README.md                     |  2 +-
 .../optimizer/src/analyzer/count_wildcard_rule.rs  | 14 +++----
 .../optimizer/src/analyzer/inline_table_scan.rs    | 13 +++---
 datafusion/optimizer/src/analyzer/mod.rs           |  3 +-
 datafusion/optimizer/src/analyzer/type_coercion.rs | 48 +++++++++++-----------
 datafusion/optimizer/src/decorrelate_where_in.rs   |  5 ++-
 datafusion/optimizer/src/push_down_filter.rs       |  2 +-
 .../src/simplify_expressions/expr_simplifier.rs    | 10 ++---
 datafusion/proto/src/logical_plan/to_proto.rs      |  4 +-
 datafusion/sql/src/expr/subquery.rs                |  7 ++--
 datafusion/sql/src/utils.rs                        | 14 +++----
 19 files changed, 119 insertions(+), 104 deletions(-)

diff --git a/datafusion/core/src/datasource/listing/helpers.rs 
b/datafusion/core/src/datasource/listing/helpers.rs
index f4995f7411..427940d4b7 100644
--- a/datafusion/core/src/datasource/listing/helpers.rs
+++ b/datafusion/core/src/datasource/listing/helpers.rs
@@ -90,7 +90,7 @@ pub fn expr_applicable_for_cols(col_names: &[String], expr: 
&Expr) -> bool {
             | Expr::SimilarTo { .. }
             | Expr::InList { .. }
             | Expr::Exists { .. }
-            | Expr::InSubquery { .. }
+            | Expr::InSubquery(_)
             | Expr::ScalarSubquery(_)
             | Expr::GetIndexedField { .. }
             | Expr::GroupingSet(_)
diff --git a/datafusion/core/src/physical_plan/planner.rs 
b/datafusion/core/src/physical_plan/planner.rs
index ebbd40fd25..7f99b4e574 100644
--- a/datafusion/core/src/physical_plan/planner.rs
+++ b/datafusion/core/src/physical_plan/planner.rs
@@ -258,7 +258,7 @@ fn create_physical_name(e: &Expr, is_first_expr: bool) -> 
Result<String> {
         Expr::Exists { .. } => Err(DataFusionError::NotImplemented(
             "EXISTS is not yet supported in the physical plan".to_string(),
         )),
-        Expr::InSubquery { .. } => Err(DataFusionError::NotImplemented(
+        Expr::InSubquery(_) => Err(DataFusionError::NotImplemented(
             "IN subquery is not yet supported in the physical 
plan".to_string(),
         )),
         Expr::ScalarSubquery(_) => Err(DataFusionError::NotImplemented(
diff --git a/datafusion/expr/src/expr.rs b/datafusion/expr/src/expr.rs
index c182e80f5f..8b6562285b 100644
--- a/datafusion/expr/src/expr.rs
+++ b/datafusion/expr/src/expr.rs
@@ -165,14 +165,7 @@ pub enum Expr {
     /// EXISTS subquery
     Exists(Exists),
     /// IN subquery
-    InSubquery {
-        /// The expression to compare
-        expr: Box<Expr>,
-        /// subquery that will produce a single column of data to compare 
against
-        subquery: Subquery,
-        /// Whether the expression is negated
-        negated: bool,
-    },
+    InSubquery(InSubquery),
     /// Scalar subquery
     ScalarSubquery(Subquery),
     /// Represents a reference to all fields in a schema.
@@ -547,6 +540,28 @@ impl InList {
     }
 }
 
+/// IN subquery
+#[derive(Clone, PartialEq, Eq, Hash)]
+pub struct InSubquery {
+    /// The expression to compare
+    pub expr: Box<Expr>,
+    /// Subquery that will produce a single column of data to compare against
+    pub subquery: Subquery,
+    /// Whether the expression is negated
+    pub negated: bool,
+}
+
+impl InSubquery {
+    /// Create a new InSubquery expression
+    pub fn new(expr: Box<Expr>, subquery: Subquery, negated: bool) -> Self {
+        Self {
+            expr,
+            subquery,
+            negated,
+        }
+    }
+}
+
 /// Grouping sets
 /// See 
<https://www.postgresql.org/docs/current/queries-table-expressions.html#QUERIES-GROUPING-SETS>
 /// for Postgres definition.
@@ -636,7 +651,7 @@ impl Expr {
             Expr::GetIndexedField { .. } => "GetIndexedField",
             Expr::GroupingSet(..) => "GroupingSet",
             Expr::InList { .. } => "InList",
-            Expr::InSubquery { .. } => "InSubquery",
+            Expr::InSubquery(..) => "InSubquery",
             Expr::IsNotNull(..) => "IsNotNull",
             Expr::IsNull(..) => "IsNull",
             Expr::Like { .. } => "Like",
@@ -956,16 +971,16 @@ impl fmt::Debug for Expr {
                 subquery,
                 negated: false,
             }) => write!(f, "EXISTS ({subquery:?})"),
-            Expr::InSubquery {
+            Expr::InSubquery(InSubquery {
                 expr,
                 subquery,
                 negated: true,
-            } => write!(f, "{expr:?} NOT IN ({subquery:?})"),
-            Expr::InSubquery {
+            }) => write!(f, "{expr:?} NOT IN ({subquery:?})"),
+            Expr::InSubquery(InSubquery {
                 expr,
                 subquery,
                 negated: false,
-            } => write!(f, "{expr:?} IN ({subquery:?})"),
+            }) => write!(f, "{expr:?} IN ({subquery:?})"),
             Expr::ScalarSubquery(subquery) => write!(f, "({subquery:?})"),
             Expr::BinaryExpr(expr) => write!(f, "{expr}"),
             Expr::Sort(Sort {
@@ -1334,8 +1349,8 @@ fn create_name(e: &Expr) -> Result<String> {
         }
         Expr::Exists(Exists { negated: true, .. }) => Ok("NOT 
EXISTS".to_string()),
         Expr::Exists(Exists { negated: false, .. }) => 
Ok("EXISTS".to_string()),
-        Expr::InSubquery { negated: true, .. } => Ok("NOT IN".to_string()),
-        Expr::InSubquery { negated: false, .. } => Ok("IN".to_string()),
+        Expr::InSubquery(InSubquery { negated: true, .. }) => Ok("NOT 
IN".to_string()),
+        Expr::InSubquery(InSubquery { negated: false, .. }) => 
Ok("IN".to_string()),
         Expr::ScalarSubquery(subquery) => {
             Ok(subquery.subquery.schema().field(0).name().clone())
         }
diff --git a/datafusion/expr/src/expr_fn.rs b/datafusion/expr/src/expr_fn.rs
index f224942cd2..1d781e6f0b 100644
--- a/datafusion/expr/src/expr_fn.rs
+++ b/datafusion/expr/src/expr_fn.rs
@@ -18,8 +18,8 @@
 //! Functions for creating logical expressions
 
 use crate::expr::{
-    AggregateFunction, BinaryExpr, Cast, Exists, GroupingSet, InList, 
ScalarFunction,
-    TryCast,
+    AggregateFunction, BinaryExpr, Cast, Exists, GroupingSet, InList, 
InSubquery,
+    ScalarFunction, TryCast,
 };
 use crate::{
     aggregate_function, built_in_function, 
conditional_expressions::CaseBuilder,
@@ -328,27 +328,27 @@ pub fn not_exists(subquery: Arc<LogicalPlan>) -> Expr {
 /// Create an IN subquery expression
 pub fn in_subquery(expr: Expr, subquery: Arc<LogicalPlan>) -> Expr {
     let outer_ref_columns = subquery.all_out_ref_exprs();
-    Expr::InSubquery {
-        expr: Box::new(expr),
-        subquery: Subquery {
+    Expr::InSubquery(InSubquery::new(
+        Box::new(expr),
+        Subquery {
             subquery,
             outer_ref_columns,
         },
-        negated: false,
-    }
+        false,
+    ))
 }
 
 /// Create a NOT IN subquery expression
 pub fn not_in_subquery(expr: Expr, subquery: Arc<LogicalPlan>) -> Expr {
     let outer_ref_columns = subquery.all_out_ref_exprs();
-    Expr::InSubquery {
-        expr: Box::new(expr),
-        subquery: Subquery {
+    Expr::InSubquery(InSubquery::new(
+        Box::new(expr),
+        Subquery {
             subquery,
             outer_ref_columns,
         },
-        negated: true,
-    }
+        true,
+    ))
 }
 
 /// Create a scalar subquery expression
diff --git a/datafusion/expr/src/expr_schema.rs 
b/datafusion/expr/src/expr_schema.rs
index 36dda847ab..8b6afdec94 100644
--- a/datafusion/expr/src/expr_schema.rs
+++ b/datafusion/expr/src/expr_schema.rs
@@ -18,7 +18,7 @@
 use super::{Between, Expr, Like};
 use crate::expr::{
     AggregateFunction, AggregateUDF, BinaryExpr, Cast, GetIndexedField, InList,
-    ScalarFunction, ScalarUDF, Sort, TryCast, WindowFunction,
+    InSubquery, ScalarFunction, ScalarUDF, Sort, TryCast, WindowFunction,
 };
 use crate::field_util::get_indexed_field;
 use crate::type_coercion::binary::get_result_type;
@@ -133,7 +133,7 @@ impl ExprSchemable for Expr {
             Expr::Not(_)
             | Expr::IsNull(_)
             | Expr::Exists { .. }
-            | Expr::InSubquery { .. }
+            | Expr::InSubquery(_)
             | Expr::Between { .. }
             | Expr::InList { .. }
             | Expr::IsNotNull(_)
@@ -232,7 +232,7 @@ impl ExprSchemable for Expr {
             | Expr::IsNotUnknown(_)
             | Expr::Exists { .. }
             | Expr::Placeholder { .. } => Ok(true),
-            Expr::InSubquery { expr, .. } => expr.nullable(input_schema),
+            Expr::InSubquery(InSubquery { expr, .. }) => 
expr.nullable(input_schema),
             Expr::ScalarSubquery(subquery) => {
                 Ok(subquery.subquery.schema().field(0).is_nullable())
             }
diff --git a/datafusion/expr/src/logical_plan/plan.rs 
b/datafusion/expr/src/logical_plan/plan.rs
index f1fdc62546..fdd875ca84 100644
--- a/datafusion/expr/src/logical_plan/plan.rs
+++ b/datafusion/expr/src/logical_plan/plan.rs
@@ -16,6 +16,7 @@
 // under the License.
 
 use crate::expr::Exists;
+use crate::expr::InSubquery;
 ///! Logical plan types
 use crate::logical_plan::display::{GraphvizVisitor, IndentVisitor};
 use crate::logical_plan::extension::UserDefinedLogicalNode;
@@ -546,7 +547,7 @@ impl LogicalPlan {
             inspect_expr_pre(expr, |expr| {
                 match expr {
                     Expr::Exists(Exists { subquery, .. })
-                    | Expr::InSubquery { subquery, .. }
+                    | Expr::InSubquery(InSubquery { subquery, .. })
                     | Expr::ScalarSubquery(subquery) => {
                         // use a synthetic plan so the collector sees a
                         // LogicalPlan::Subquery (even though it is
@@ -572,7 +573,7 @@ impl LogicalPlan {
             inspect_expr_pre(expr, |expr| {
                 match expr {
                     Expr::Exists(Exists { subquery, .. })
-                    | Expr::InSubquery { subquery, .. }
+                    | Expr::InSubquery(InSubquery { subquery, .. })
                     | Expr::ScalarSubquery(subquery) => {
                         // use a synthetic plan so the visitor sees a
                         // LogicalPlan::Subquery (even though it is
diff --git a/datafusion/expr/src/tree_node/expr.rs 
b/datafusion/expr/src/tree_node/expr.rs
index ecd90254dc..7bc9edf4c2 100644
--- a/datafusion/expr/src/tree_node/expr.rs
+++ b/datafusion/expr/src/tree_node/expr.rs
@@ -19,7 +19,8 @@
 
 use crate::expr::{
     AggregateFunction, AggregateUDF, Between, BinaryExpr, Case, Cast, 
GetIndexedField,
-    GroupingSet, InList, Like, ScalarFunction, ScalarUDF, Sort, TryCast, 
WindowFunction,
+    GroupingSet, InList, InSubquery, Like, ScalarFunction, ScalarUDF, Sort, 
TryCast,
+    WindowFunction,
 };
 use crate::Expr;
 use datafusion_common::tree_node::VisitRecursion;
@@ -45,7 +46,7 @@ impl TreeNode for Expr {
             | Expr::Cast(Cast { expr, .. })
             | Expr::TryCast(TryCast { expr, .. })
             | Expr::Sort(Sort { expr, .. })
-            | Expr::InSubquery { expr, .. } => vec![expr.as_ref().clone()],
+            | Expr::InSubquery(InSubquery{ expr, .. }) => 
vec![expr.as_ref().clone()],
             Expr::GetIndexedField(GetIndexedField { expr, .. }) => {
                 vec![expr.as_ref().clone()]
             }
@@ -149,15 +150,15 @@ impl TreeNode for Expr {
             Expr::Column(_) => self,
             Expr::OuterReferenceColumn(_, _) => self,
             Expr::Exists { .. } => self,
-            Expr::InSubquery {
+            Expr::InSubquery(InSubquery {
                 expr,
                 subquery,
                 negated,
-            } => Expr::InSubquery {
-                expr: transform_boxed(expr, &mut transform)?,
+            }) => Expr::InSubquery(InSubquery::new(
+                transform_boxed(expr, &mut transform)?,
                 subquery,
                 negated,
-            },
+            )),
             Expr::ScalarSubquery(_) => self,
             Expr::ScalarVariable(ty, names) => Expr::ScalarVariable(ty, names),
             Expr::Literal(value) => Expr::Literal(value),
diff --git a/datafusion/expr/src/utils.rs b/datafusion/expr/src/utils.rs
index 7698297b79..06f9ccd11c 100644
--- a/datafusion/expr/src/utils.rs
+++ b/datafusion/expr/src/utils.rs
@@ -303,7 +303,7 @@ pub fn expr_to_columns(expr: &Expr, accum: &mut 
HashSet<Column>) -> Result<()> {
             | Expr::AggregateUDF { .. }
             | Expr::InList { .. }
             | Expr::Exists { .. }
-            | Expr::InSubquery { .. }
+            | Expr::InSubquery(_)
             | Expr::ScalarSubquery(_)
             | Expr::Wildcard
             | Expr::QualifiedWildcard { .. }
@@ -704,7 +704,7 @@ pub fn from_plan(
                     match expr {
                         Expr::Exists { .. }
                         | Expr::ScalarSubquery(_)
-                        | Expr::InSubquery { .. } => {
+                        | Expr::InSubquery(_) => {
                             // subqueries could contain aliases so we don't 
recurse into those
                             Ok(RewriteRecursion::Stop)
                         }
diff --git a/datafusion/optimizer/README.md b/datafusion/optimizer/README.md
index 01c6f6dd26..c8baae03ef 100644
--- a/datafusion/optimizer/README.md
+++ b/datafusion/optimizer/README.md
@@ -201,7 +201,7 @@ fn extract_subquery_filters(expression: &Expr, extracted: 
&mut Vec<Expr>) -> Res
 
     impl ExpressionVisitor for InSubqueryVisitor<'_> {
         fn pre_visit(self, expr: &Expr) -> Result<Recursion<Self>> {
-            if let Expr::InSubquery { .. } = expr {
+            if let Expr::InSubquery(_) = expr {
                 self.accum.push(expr.to_owned());
             }
             Ok(Recursion::Continue(self))
diff --git a/datafusion/optimizer/src/analyzer/count_wildcard_rule.rs 
b/datafusion/optimizer/src/analyzer/count_wildcard_rule.rs
index 46cae6f2f1..3b0e334618 100644
--- a/datafusion/optimizer/src/analyzer/count_wildcard_rule.rs
+++ b/datafusion/optimizer/src/analyzer/count_wildcard_rule.rs
@@ -18,9 +18,9 @@
 use datafusion_common::config::ConfigOptions;
 use datafusion_common::tree_node::{Transformed, TreeNode, TreeNodeRewriter};
 use datafusion_common::{Column, DFField, DFSchema, DFSchemaRef, Result};
-use datafusion_expr::expr::AggregateFunction;
+use datafusion_expr::expr::{AggregateFunction, InSubquery};
 use datafusion_expr::utils::COUNT_STAR_EXPANSION;
-use datafusion_expr::Expr::{InSubquery, ScalarSubquery};
+use datafusion_expr::Expr::ScalarSubquery;
 use datafusion_expr::{
     aggregate_function, count, expr, lit, window_function, Aggregate, Expr, 
Filter,
     LogicalPlan, Projection, Sort, Subquery, Window,
@@ -191,25 +191,25 @@ impl TreeNodeRewriter for CountWildcardRewriter {
                     outer_ref_columns,
                 })
             }
-            InSubquery {
+            Expr::InSubquery(InSubquery {
                 expr,
                 subquery,
                 negated,
-            } => {
+            }) => {
                 let new_plan = subquery
                     .subquery
                     .as_ref()
                     .clone()
                     .transform_down(&analyze_internal)?;
 
-                InSubquery {
+                Expr::InSubquery(InSubquery::new(
                     expr,
-                    subquery: Subquery {
+                    Subquery {
                         subquery: Arc::new(new_plan),
                         outer_ref_columns: subquery.outer_ref_columns,
                     },
                     negated,
-                }
+                ))
             }
             Expr::Exists(expr::Exists { subquery, negated }) => {
                 let new_plan = subquery
diff --git a/datafusion/optimizer/src/analyzer/inline_table_scan.rs 
b/datafusion/optimizer/src/analyzer/inline_table_scan.rs
index b202283d8f..3d0dabdd37 100644
--- a/datafusion/optimizer/src/analyzer/inline_table_scan.rs
+++ b/datafusion/optimizer/src/analyzer/inline_table_scan.rs
@@ -24,6 +24,7 @@ use datafusion_common::config::ConfigOptions;
 use datafusion_common::tree_node::{Transformed, TreeNode};
 use datafusion_common::Result;
 use datafusion_expr::expr::Exists;
+use datafusion_expr::expr::InSubquery;
 use datafusion_expr::{
     logical_plan::LogicalPlan, Expr, Filter, LogicalPlanBuilder, TableScan,
 };
@@ -91,19 +92,17 @@ fn rewrite_subquery(expr: Expr) -> 
Result<Transformed<Expr>> {
             let subquery = subquery.with_plan(Arc::new(new_plan));
             Ok(Transformed::Yes(Expr::Exists(Exists { subquery, negated })))
         }
-        Expr::InSubquery {
+        Expr::InSubquery(InSubquery {
             expr,
             subquery,
             negated,
-        } => {
+        }) => {
             let plan = subquery.subquery.as_ref().clone();
             let new_plan = plan.transform_up(&analyze_internal)?;
             let subquery = subquery.with_plan(Arc::new(new_plan));
-            Ok(Transformed::Yes(Expr::InSubquery {
-                expr,
-                subquery,
-                negated,
-            }))
+            Ok(Transformed::Yes(Expr::InSubquery(InSubquery::new(
+                expr, subquery, negated,
+            ))))
         }
         Expr::ScalarSubquery(subquery) => {
             let plan = subquery.subquery.as_ref().clone();
diff --git a/datafusion/optimizer/src/analyzer/mod.rs 
b/datafusion/optimizer/src/analyzer/mod.rs
index a19c3f6268..436bb3a060 100644
--- a/datafusion/optimizer/src/analyzer/mod.rs
+++ b/datafusion/optimizer/src/analyzer/mod.rs
@@ -30,6 +30,7 @@ use datafusion_common::config::ConfigOptions;
 use datafusion_common::tree_node::{TreeNode, VisitRecursion};
 use datafusion_common::{DataFusionError, Result};
 use datafusion_expr::expr::Exists;
+use datafusion_expr::expr::InSubquery;
 use datafusion_expr::utils::inspect_expr_pre;
 use datafusion_expr::{Expr, LogicalPlan};
 use log::debug;
@@ -121,7 +122,7 @@ fn check_plan(plan: &LogicalPlan) -> Result<()> {
             // recursively look for subqueries
             inspect_expr_pre(expr, |expr| match expr {
                 Expr::Exists(Exists { subquery, .. })
-                | Expr::InSubquery { subquery, .. }
+                | Expr::InSubquery(InSubquery { subquery, .. })
                 | Expr::ScalarSubquery(subquery) => {
                     check_subquery_expr(plan, &subquery.subquery, expr)
                 }
diff --git a/datafusion/optimizer/src/analyzer/type_coercion.rs 
b/datafusion/optimizer/src/analyzer/type_coercion.rs
index f42bc96dcb..6de095cccd 100644
--- a/datafusion/optimizer/src/analyzer/type_coercion.rs
+++ b/datafusion/optimizer/src/analyzer/type_coercion.rs
@@ -25,8 +25,8 @@ use datafusion_common::config::ConfigOptions;
 use datafusion_common::tree_node::{RewriteRecursion, TreeNodeRewriter};
 use datafusion_common::{DFSchema, DFSchemaRef, DataFusionError, Result, 
ScalarValue};
 use datafusion_expr::expr::{
-    self, Between, BinaryExpr, Case, Exists, InList, Like, ScalarFunction, 
ScalarUDF,
-    WindowFunction,
+    self, Between, BinaryExpr, Case, Exists, InList, InSubquery, Like, 
ScalarFunction,
+    ScalarUDF, WindowFunction,
 };
 use datafusion_expr::expr_schema::cast_subquery;
 use datafusion_expr::logical_plan::Subquery;
@@ -144,11 +144,11 @@ impl TreeNodeRewriter for TypeCoercionRewriter {
                     negated,
                 }))
             }
-            Expr::InSubquery {
+            Expr::InSubquery(InSubquery {
                 expr,
                 subquery,
                 negated,
-            } => {
+            }) => {
                 let new_plan = analyze_internal(&self.schema, 
&subquery.subquery)?;
                 let expr_type = expr.get_type(&self.schema)?;
                 let subquery_type = new_plan.schema().field(0).data_type();
@@ -161,11 +161,11 @@ impl TreeNodeRewriter for TypeCoercionRewriter {
                     subquery: Arc::new(new_plan),
                     outer_ref_columns: subquery.outer_ref_columns,
                 };
-                Ok(Expr::InSubquery {
-                    expr: Box::new(expr.cast_to(&common_type, &self.schema)?),
-                    subquery: cast_subquery(new_subquery, &common_type)?,
+                Ok(Expr::InSubquery(InSubquery::new(
+                    Box::new(expr.cast_to(&common_type, &self.schema)?),
+                    cast_subquery(new_subquery, &common_type)?,
                     negated,
-                })
+                )))
             }
             Expr::IsTrue(expr) => {
                 let expr = is_true(get_casted_expr_for_bool_op(&expr, 
&self.schema)?);
@@ -739,7 +739,7 @@ mod test {
 
     use datafusion_common::tree_node::TreeNode;
     use datafusion_common::{DFField, DFSchema, DFSchemaRef, Result, 
ScalarValue};
-    use datafusion_expr::expr::{self, Like, ScalarFunction};
+    use datafusion_expr::expr::{self, InSubquery, Like, ScalarFunction};
     use datafusion_expr::{
         cast, col, concat, concat_ws, create_udaf, is_true,
         AccumulatorFunctionImplementation, AggregateFunction, AggregateUDF, 
BinaryExpr,
@@ -1452,14 +1452,14 @@ mod test {
         let empty_int32 = empty_with_type(DataType::Int32);
         let empty_int64 = empty_with_type(DataType::Int64);
 
-        let in_subquery_expr = Expr::InSubquery {
-            expr: Box::new(col("a")),
-            subquery: Subquery {
+        let in_subquery_expr = Expr::InSubquery(InSubquery::new(
+            Box::new(col("a")),
+            Subquery {
                 subquery: empty_int32,
                 outer_ref_columns: vec![],
             },
-            negated: false,
-        };
+            false,
+        ));
         let plan = LogicalPlan::Filter(Filter::try_new(in_subquery_expr, 
empty_int64)?);
         // add cast for subquery
         let expected = "\
@@ -1477,14 +1477,14 @@ mod test {
         let empty_int32 = empty_with_type(DataType::Int32);
         let empty_int64 = empty_with_type(DataType::Int64);
 
-        let in_subquery_expr = Expr::InSubquery {
-            expr: Box::new(col("a")),
-            subquery: Subquery {
+        let in_subquery_expr = Expr::InSubquery(InSubquery::new(
+            Box::new(col("a")),
+            Subquery {
                 subquery: empty_int64,
                 outer_ref_columns: vec![],
             },
-            negated: false,
-        };
+            false,
+        ));
         let plan = LogicalPlan::Filter(Filter::try_new(in_subquery_expr, 
empty_int32)?);
         // add cast for subquery
         let expected = "\
@@ -1501,14 +1501,14 @@ mod test {
         let empty_inside = empty_with_type(DataType::Decimal128(10, 5));
         let empty_outside = empty_with_type(DataType::Decimal128(8, 8));
 
-        let in_subquery_expr = Expr::InSubquery {
-            expr: Box::new(col("a")),
-            subquery: Subquery {
+        let in_subquery_expr = Expr::InSubquery(InSubquery::new(
+            Box::new(col("a")),
+            Subquery {
                 subquery: empty_inside,
                 outer_ref_columns: vec![],
             },
-            negated: false,
-        };
+            false,
+        ));
         let plan = LogicalPlan::Filter(Filter::try_new(in_subquery_expr, 
empty_outside)?);
         // add cast for subquery
         let expected = "Filter: CAST(a AS Decimal128(13, 8)) IN (<subquery>)\
diff --git a/datafusion/optimizer/src/decorrelate_where_in.rs 
b/datafusion/optimizer/src/decorrelate_where_in.rs
index 6dbbbf9bf9..0d9b472cf4 100644
--- a/datafusion/optimizer/src/decorrelate_where_in.rs
+++ b/datafusion/optimizer/src/decorrelate_where_in.rs
@@ -23,6 +23,7 @@ use crate::utils::{
 };
 use crate::{OptimizerConfig, OptimizerRule};
 use datafusion_common::{context, Column, Result};
+use datafusion_expr::expr::InSubquery;
 use datafusion_expr::expr_rewriter::unnormalize_col;
 use datafusion_expr::logical_plan::{JoinType, Projection, Subquery};
 use datafusion_expr::{Expr, Filter, LogicalPlan, LogicalPlanBuilder};
@@ -59,11 +60,11 @@ impl DecorrelateWhereIn {
         let mut others = vec![];
         for it in filters.iter() {
             match it {
-                Expr::InSubquery {
+                Expr::InSubquery(InSubquery {
                     expr,
                     subquery,
                     negated,
-                } => {
+                }) => {
                     let subquery_plan = self
                         .try_optimize(&subquery.subquery, config)?
                         .map(Arc::new)
diff --git a/datafusion/optimizer/src/push_down_filter.rs 
b/datafusion/optimizer/src/push_down_filter.rs
index 2f3524a8d2..d724c59d0d 100644
--- a/datafusion/optimizer/src/push_down_filter.rs
+++ b/datafusion/optimizer/src/push_down_filter.rs
@@ -157,7 +157,7 @@ fn can_evaluate_as_join_condition(predicate: &Expr) -> 
Result<bool> {
         | Expr::Placeholder { .. }
         | Expr::ScalarVariable(_, _) => Ok(VisitRecursion::Skip),
         Expr::Exists { .. }
-        | Expr::InSubquery { .. }
+        | Expr::InSubquery(_)
         | Expr::ScalarSubquery(_)
         | Expr::OuterReferenceColumn(_, _)
         | Expr::ScalarUDF(..) => {
diff --git a/datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs 
b/datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs
index 75055b6404..07391a2d77 100644
--- a/datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs
+++ b/datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs
@@ -28,7 +28,7 @@ use arrow::{
 };
 use datafusion_common::tree_node::{RewriteRecursion, TreeNode, 
TreeNodeRewriter};
 use datafusion_common::{DFSchema, DFSchemaRef, DataFusionError, Result, 
ScalarValue};
-use datafusion_expr::expr::{InList, ScalarFunction};
+use datafusion_expr::expr::{InList, InSubquery, ScalarFunction};
 use datafusion_expr::{
     and, expr, lit, or, BinaryExpr, BuiltinScalarFunction, ColumnarValue, 
Expr, Like,
     Volatility,
@@ -258,7 +258,7 @@ impl<'a> ConstEvaluator<'a> {
             | Expr::Column(_)
             | Expr::OuterReferenceColumn(_, _)
             | Expr::Exists { .. }
-            | Expr::InSubquery { .. }
+            | Expr::InSubquery(_)
             | Expr::ScalarSubquery(_)
             | Expr::WindowFunction { .. }
             | Expr::Sort { .. }
@@ -408,11 +408,7 @@ impl<'a, S: SimplifyInfo> TreeNodeRewriter for 
Simplifier<'a, S> {
                 && matches!(list.first(), Some(Expr::ScalarSubquery { .. })) =>
             {
                 let Expr::ScalarSubquery(subquery) = list.remove(0) else { 
unreachable!() };
-                Expr::InSubquery {
-                    expr,
-                    subquery,
-                    negated,
-                }
+                Expr::InSubquery(InSubquery::new(expr, subquery, negated))
             }
 
             // if expr is a single column reference:
diff --git a/datafusion/proto/src/logical_plan/to_proto.rs 
b/datafusion/proto/src/logical_plan/to_proto.rs
index 4c40931b3e..263acd58dc 100644
--- a/datafusion/proto/src/logical_plan/to_proto.rs
+++ b/datafusion/proto/src/logical_plan/to_proto.rs
@@ -895,12 +895,12 @@ impl TryFrom<&Expr> for protobuf::LogicalExprNode {
                 expr_type: Some(ExprType::Wildcard(true)),
             },
             Expr::ScalarSubquery(_)
-            | Expr::InSubquery { .. }
+            | Expr::InSubquery(_)
             | Expr::Exists { .. }
             | Expr::OuterReferenceColumn { .. } => {
                 // we would need to add logical plan operators to 
datafusion.proto to support this
                 // see discussion in 
https://github.com/apache/arrow-datafusion/issues/2565
-                return Err(Error::General("Proto serialization error: 
Expr::ScalarSubquery(_) | Expr::InSubquery { .. } | Expr::Exists { .. } | 
Exp:OuterReferenceColumn not supported".to_string()));
+                return Err(Error::General("Proto serialization error: 
Expr::ScalarSubquery(_) | Expr::InSubquery(_) | Expr::Exists { .. } | 
Exp:OuterReferenceColumn not supported".to_string()));
             }
             Expr::GetIndexedField(GetIndexedField { key, expr }) => Self {
                 expr_type: Some(ExprType::GetIndexedField(Box::new(
diff --git a/datafusion/sql/src/expr/subquery.rs 
b/datafusion/sql/src/expr/subquery.rs
index 48960aceda..d34065d92f 100644
--- a/datafusion/sql/src/expr/subquery.rs
+++ b/datafusion/sql/src/expr/subquery.rs
@@ -18,6 +18,7 @@
 use crate::planner::{ContextProvider, PlannerContext, SqlToRel};
 use datafusion_common::{DFSchema, Result};
 use datafusion_expr::expr::Exists;
+use datafusion_expr::expr::InSubquery;
 use datafusion_expr::{Expr, Subquery};
 use sqlparser::ast::Expr as SQLExpr;
 use sqlparser::ast::Query;
@@ -59,14 +60,14 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
         let outer_ref_columns = sub_plan.all_out_ref_exprs();
         planner_context.set_outer_query_schema(old_outer_query_schema);
         let expr = Box::new(self.sql_to_expr(expr, input_schema, 
planner_context)?);
-        Ok(Expr::InSubquery {
+        Ok(Expr::InSubquery(InSubquery::new(
             expr,
-            subquery: Subquery {
+            Subquery {
                 subquery: Arc::new(sub_plan),
                 outer_ref_columns,
             },
             negated,
-        })
+        )))
     }
 
     pub(super) fn parse_scalar_subquery(
diff --git a/datafusion/sql/src/utils.rs b/datafusion/sql/src/utils.rs
index 78f25905db..1bfff37b48 100644
--- a/datafusion/sql/src/utils.rs
+++ b/datafusion/sql/src/utils.rs
@@ -23,7 +23,7 @@ use sqlparser::ast::Ident;
 use datafusion_common::{DataFusionError, Result, ScalarValue};
 use datafusion_expr::expr::{
     AggregateFunction, AggregateUDF, Between, BinaryExpr, Case, 
GetIndexedField,
-    GroupingSet, InList, Like, ScalarFunction, ScalarUDF, WindowFunction,
+    GroupingSet, InList, InSubquery, Like, ScalarFunction, ScalarUDF, 
WindowFunction,
 };
 use datafusion_expr::expr::{Cast, Sort};
 use datafusion_expr::utils::{expr_as_column_expr, find_column_exprs};
@@ -368,15 +368,15 @@ where
             | Expr::ScalarVariable(_, _)
             | Expr::Exists { .. }
             | Expr::ScalarSubquery(_) => Ok(expr.clone()),
-            Expr::InSubquery {
+            Expr::InSubquery(InSubquery {
                 expr: nested_expr,
                 subquery,
                 negated,
-            } => Ok(Expr::InSubquery {
-                expr: Box::new(clone_with_replacement(nested_expr, 
replacement_fn)?),
-                subquery: subquery.clone(),
-                negated: *negated,
-            }),
+            }) => Ok(Expr::InSubquery(InSubquery::new(
+                Box::new(clone_with_replacement(nested_expr, replacement_fn)?),
+                subquery.clone(),
+                *negated,
+            ))),
             Expr::Wildcard => Ok(Expr::Wildcard),
             Expr::QualifiedWildcard { .. } => Ok(expr.clone()),
             Expr::GetIndexedField(GetIndexedField { key, expr }) => {

Reply via email to