You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ja...@apache.org on 2023/05/09 09:11:58 UTC

[arrow-datafusion] branch main updated: refactor: Expr::InList to use a struct (#6293)

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

jakevin 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 729c0f8923 refactor: Expr::InList to use a struct (#6293)
729c0f8923 is described below

commit 729c0f892359adab4114fe7a76f0caa705f93e82
Author: jakevin <ja...@gmail.com>
AuthorDate: Tue May 9 17:11:51 2023 +0800

    refactor: Expr::InList to use a struct (#6293)
---
 datafusion/core/src/physical_optimizer/pruning.rs  | 47 ++++++++++------------
 datafusion/core/src/physical_plan/planner.rs       |  6 +--
 datafusion/expr/src/expr.rs                        | 45 +++++++++++++--------
 datafusion/expr/src/expr_fn.rs                     |  9 ++---
 datafusion/expr/src/expr_schema.rs                 |  6 +--
 datafusion/expr/src/tree_node/expr.rs              | 24 +++++------
 datafusion/optimizer/src/analyzer/type_coercion.rs | 14 +++----
 .../src/simplify_expressions/expr_simplifier.rs    | 14 +++----
 .../optimizer/src/simplify_expressions/utils.rs    |  6 +--
 .../optimizer/src/unwrap_cast_in_comparison.rs     |  6 +--
 datafusion/physical-expr/src/planner.rs            |  6 +--
 datafusion/proto/src/logical_plan/from_proto.rs    | 12 +++---
 datafusion/proto/src/logical_plan/mod.rs           | 12 +++---
 datafusion/proto/src/logical_plan/to_proto.rs      |  8 ++--
 datafusion/sql/src/expr/mod.rs                     | 13 +++---
 datafusion/sql/src/utils.rs                        | 15 ++++---
 16 files changed, 122 insertions(+), 121 deletions(-)

diff --git a/datafusion/core/src/physical_optimizer/pruning.rs b/datafusion/core/src/physical_optimizer/pruning.rs
index 5fe3a72c69..8260619a1b 100644
--- a/datafusion/core/src/physical_optimizer/pruning.rs
+++ b/datafusion/core/src/physical_optimizer/pruning.rs
@@ -943,6 +943,7 @@ mod tests {
         datatypes::{DataType, TimeUnit},
     };
     use datafusion_common::{ScalarValue, ToDFSchema};
+    use datafusion_expr::expr::InList;
     use datafusion_expr::{cast, is_null, try_cast, Expr};
     use datafusion_physical_expr::create_physical_expr;
     use datafusion_physical_expr::execution_props::ExecutionProps;
@@ -1660,11 +1661,11 @@ mod tests {
             Field::new("c2", DataType::Int32, false),
         ]);
         // test c1 in(1, 2, 3)
-        let expr = Expr::InList {
-            expr: Box::new(col("c1")),
-            list: vec![lit(1), lit(2), lit(3)],
-            negated: false,
-        };
+        let expr = Expr::InList(InList::new(
+            Box::new(col("c1")),
+            vec![lit(1), lit(2), lit(3)],
+            false,
+        ));
         let expected_expr = "c1_min@0 <= 1 AND 1 <= c1_max@1 OR c1_min@0 <= 2 AND 2 <= c1_max@1 OR c1_min@0 <= 3 AND 3 <= c1_max@1";
         let predicate_expr = test_build_predicate_expression(
             &expr,
@@ -1683,11 +1684,7 @@ mod tests {
             Field::new("c2", DataType::Int32, false),
         ]);
         // test c1 in()
-        let expr = Expr::InList {
-            expr: Box::new(col("c1")),
-            list: vec![],
-            negated: false,
-        };
+        let expr = Expr::InList(InList::new(Box::new(col("c1")), vec![], false));
         let expected_expr = "true";
         let predicate_expr = test_build_predicate_expression(
             &expr,
@@ -1706,11 +1703,11 @@ mod tests {
             Field::new("c2", DataType::Int32, false),
         ]);
         // test c1 not in(1, 2, 3)
-        let expr = Expr::InList {
-            expr: Box::new(col("c1")),
-            list: vec![lit(1), lit(2), lit(3)],
-            negated: true,
-        };
+        let expr = Expr::InList(InList::new(
+            Box::new(col("c1")),
+            vec![lit(1), lit(2), lit(3)],
+            true,
+        ));
         let expected_expr = "(c1_min@0 != 1 OR 1 != c1_max@1) \
         AND (c1_min@0 != 2 OR 2 != c1_max@1) \
         AND (c1_min@0 != 3 OR 3 != c1_max@1)";
@@ -1777,15 +1774,15 @@ mod tests {
     fn row_group_predicate_cast_list() -> Result<()> {
         let schema = Schema::new(vec![Field::new("c1", DataType::Int32, false)]);
         // test cast(c1 as int64) in int64(1, 2, 3)
-        let expr = Expr::InList {
-            expr: Box::new(cast(col("c1"), DataType::Int64)),
-            list: vec![
+        let expr = Expr::InList(InList::new(
+            Box::new(cast(col("c1"), DataType::Int64)),
+            vec![
                 lit(ScalarValue::Int64(Some(1))),
                 lit(ScalarValue::Int64(Some(2))),
                 lit(ScalarValue::Int64(Some(3))),
             ],
-            negated: false,
-        };
+            false,
+        ));
         let expected_expr = "CAST(c1_min@0 AS Int64) <= 1 AND 1 <= CAST(c1_max@1 AS Int64) OR CAST(c1_min@0 AS Int64) <= 2 AND 2 <= CAST(c1_max@1 AS Int64) OR CAST(c1_min@0 AS Int64) <= 3 AND 3 <= CAST(c1_max@1 AS Int64)";
         let predicate_expr = test_build_predicate_expression(
             &expr,
@@ -1794,15 +1791,15 @@ mod tests {
         );
         assert_eq!(predicate_expr.to_string(), expected_expr);
 
-        let expr = Expr::InList {
-            expr: Box::new(cast(col("c1"), DataType::Int64)),
-            list: vec![
+        let expr = Expr::InList(InList::new(
+            Box::new(cast(col("c1"), DataType::Int64)),
+            vec![
                 lit(ScalarValue::Int64(Some(1))),
                 lit(ScalarValue::Int64(Some(2))),
                 lit(ScalarValue::Int64(Some(3))),
             ],
-            negated: true,
-        };
+            true,
+        ));
         let expected_expr =
             "(CAST(c1_min@0 AS Int64) != 1 OR 1 != CAST(c1_max@1 AS Int64)) \
         AND (CAST(c1_min@0 AS Int64) != 2 OR 2 != CAST(c1_max@1 AS Int64)) \
diff --git a/datafusion/core/src/physical_plan/planner.rs b/datafusion/core/src/physical_plan/planner.rs
index 51832087cf..ebbd40fd25 100644
--- a/datafusion/core/src/physical_plan/planner.rs
+++ b/datafusion/core/src/physical_plan/planner.rs
@@ -63,7 +63,7 @@ use async_trait::async_trait;
 use datafusion_common::{DFSchema, ScalarValue};
 use datafusion_expr::expr::{
     self, AggregateFunction, AggregateUDF, Between, BinaryExpr, Cast, GetIndexedField,
-    GroupingSet, Like, ScalarUDF, TryCast, WindowFunction,
+    GroupingSet, InList, Like, ScalarUDF, TryCast, WindowFunction,
 };
 use datafusion_expr::expr_rewriter::unnormalize_cols;
 use datafusion_expr::logical_plan::builder::wrap_projection_for_join_if_necessary;
@@ -242,11 +242,11 @@ fn create_physical_name(e: &Expr, is_first_expr: bool) -> Result<String> {
             }
         },
 
-        Expr::InList {
+        Expr::InList(InList {
             expr,
             list,
             negated,
-        } => {
+        }) => {
             let expr = create_physical_name(expr, false)?;
             let list = list.iter().map(|expr| create_physical_name(expr, false));
             if *negated {
diff --git a/datafusion/expr/src/expr.rs b/datafusion/expr/src/expr.rs
index fa28810d16..c182e80f5f 100644
--- a/datafusion/expr/src/expr.rs
+++ b/datafusion/expr/src/expr.rs
@@ -161,14 +161,7 @@ pub enum Expr {
     /// aggregate function
     AggregateUDF(AggregateUDF),
     /// Returns whether the list contains the expr value.
-    InList {
-        /// The expression to compare
-        expr: Box<Expr>,
-        /// A list of values to compare against
-        list: Vec<Expr>,
-        /// Whether the expression is negated
-        negated: bool,
-    },
+    InList(InList),
     /// EXISTS subquery
     Exists(Exists),
     /// IN subquery
@@ -532,6 +525,28 @@ impl AggregateUDF {
     }
 }
 
+/// InList expression
+#[derive(Clone, PartialEq, Eq, Hash)]
+pub struct InList {
+    /// The expression to compare
+    pub expr: Box<Expr>,
+    /// The list of values to compare against
+    pub list: Vec<Expr>,
+    /// Whether the expression is negated
+    pub negated: bool,
+}
+
+impl InList {
+    /// Create a new InList expression
+    pub fn new(expr: Box<Expr>, list: Vec<Expr>, negated: bool) -> Self {
+        Self {
+            expr,
+            list,
+            negated,
+        }
+    }
+}
+
 /// Grouping sets
 /// See <https://www.postgresql.org/docs/current/queries-table-expressions.html#QUERIES-GROUPING-SETS>
 /// for Postgres definition.
@@ -762,11 +777,7 @@ impl Expr {
     /// Return `self IN <list>` if `negated` is false, otherwise
     /// return `self NOT IN <list>`.a
     pub fn in_list(self, list: Vec<Expr>, negated: bool) -> Expr {
-        Expr::InList {
-            expr: Box::new(self),
-            list,
-            negated,
-        }
+        Expr::InList(InList::new(Box::new(self), list, negated))
     }
 
     /// Return `IsNull(Box(self))
@@ -1085,11 +1096,11 @@ impl fmt::Debug for Expr {
                     write!(f, " SIMILAR TO {pattern:?}")
                 }
             }
-            Expr::InList {
+            Expr::InList(InList {
                 expr,
                 list,
                 negated,
-            } => {
+            }) => {
                 if *negated {
                     write!(f, "{expr:?} NOT IN ({list:?})")
                 } else {
@@ -1396,11 +1407,11 @@ fn create_name(e: &Expr) -> Result<String> {
                 Ok(format!("GROUPING SETS ({})", list_of_names.join(", ")))
             }
         },
-        Expr::InList {
+        Expr::InList(InList {
             expr,
             list,
             negated,
-        } => {
+        }) => {
             let expr = create_name(expr)?;
             let list = list.iter().map(create_name);
             if *negated {
diff --git a/datafusion/expr/src/expr_fn.rs b/datafusion/expr/src/expr_fn.rs
index e6026f41cd..f224942cd2 100644
--- a/datafusion/expr/src/expr_fn.rs
+++ b/datafusion/expr/src/expr_fn.rs
@@ -18,7 +18,8 @@
 //! Functions for creating logical expressions
 
 use crate::expr::{
-    AggregateFunction, BinaryExpr, Cast, Exists, GroupingSet, ScalarFunction, TryCast,
+    AggregateFunction, BinaryExpr, Cast, Exists, GroupingSet, InList, ScalarFunction,
+    TryCast,
 };
 use crate::{
     aggregate_function, built_in_function, conditional_expressions::CaseBuilder,
@@ -207,11 +208,7 @@ pub fn count_distinct(expr: Expr) -> Expr {
 
 /// Create an in_list expression
 pub fn in_list(expr: Expr, list: Vec<Expr>, negated: bool) -> Expr {
-    Expr::InList {
-        expr: Box::new(expr),
-        list,
-        negated,
-    }
+    Expr::InList(InList::new(Box::new(expr), list, negated))
 }
 
 /// Concatenates the text representations of all the arguments. NULL arguments are ignored.
diff --git a/datafusion/expr/src/expr_schema.rs b/datafusion/expr/src/expr_schema.rs
index 9b91f85210..36dda847ab 100644
--- a/datafusion/expr/src/expr_schema.rs
+++ b/datafusion/expr/src/expr_schema.rs
@@ -17,8 +17,8 @@
 
 use super::{Between, Expr, Like};
 use crate::expr::{
-    AggregateFunction, AggregateUDF, BinaryExpr, Cast, GetIndexedField, ScalarFunction,
-    ScalarUDF, Sort, TryCast, WindowFunction,
+    AggregateFunction, AggregateUDF, BinaryExpr, Cast, GetIndexedField, InList,
+    ScalarFunction, ScalarUDF, Sort, TryCast, WindowFunction,
 };
 use crate::field_util::get_indexed_field;
 use crate::type_coercion::binary::get_result_type;
@@ -192,7 +192,7 @@ impl ExprSchemable for Expr {
             | Expr::Not(expr)
             | Expr::Negative(expr)
             | Expr::Sort(Sort { expr, .. })
-            | Expr::InList { expr, .. } => expr.nullable(input_schema),
+            | Expr::InList(InList { expr, .. }) => expr.nullable(input_schema),
             Expr::Between(Between { expr, .. }) => expr.nullable(input_schema),
             Expr::Column(c) => input_schema.nullable(c),
             Expr::OuterReferenceColumn(_, _) => Ok(true),
diff --git a/datafusion/expr/src/tree_node/expr.rs b/datafusion/expr/src/tree_node/expr.rs
index 3f17340060..ecd90254dc 100644
--- a/datafusion/expr/src/tree_node/expr.rs
+++ b/datafusion/expr/src/tree_node/expr.rs
@@ -19,7 +19,7 @@
 
 use crate::expr::{
     AggregateFunction, AggregateUDF, Between, BinaryExpr, Case, Cast, GetIndexedField,
-    GroupingSet, Like, ScalarFunction, ScalarUDF, Sort, TryCast, WindowFunction,
+    GroupingSet, InList, Like, ScalarFunction, ScalarUDF, Sort, TryCast, WindowFunction,
 };
 use crate::Expr;
 use datafusion_common::tree_node::VisitRecursion;
@@ -97,7 +97,7 @@ impl TreeNode for Expr {
                 expr_vec
             }
             Expr::AggregateFunction(AggregateFunction { args, filter, .. })
-            | Expr::AggregateUDF ( AggregateUDF{args, filter, .. }) => {
+            | Expr::AggregateUDF(AggregateUDF { args, filter, .. }) => {
                 let mut expr_vec = args.clone();
 
                 if let Some(f) = filter {
@@ -117,7 +117,7 @@ impl TreeNode for Expr {
                 expr_vec.extend(order_by.clone());
                 expr_vec
             }
-            Expr::InList { expr, list, .. } => {
+            Expr::InList(InList { expr, list, .. }) => {
                 let mut expr_vec = vec![];
                 expr_vec.push(expr.as_ref().clone());
                 expr_vec.extend(list.clone());
@@ -314,21 +314,21 @@ impl TreeNode for Expr {
                 }
             },
             Expr::AggregateUDF(AggregateUDF { args, fun, filter }) => {
-                Expr::AggregateUDF(AggregateUDF {
-                    args: transform_vec(args, &mut transform)?,
+                Expr::AggregateUDF(AggregateUDF::new(
                     fun,
-                    filter: transform_option_box(filter, &mut transform)?,
-                })
+                    transform_vec(args, &mut transform)?,
+                    transform_option_box(filter, &mut transform)?,
+                ))
             }
-            Expr::InList {
+            Expr::InList(InList {
                 expr,
                 list,
                 negated,
-            } => Expr::InList {
-                expr: transform_boxed(expr, &mut transform)?,
-                list: transform_vec(list, &mut transform)?,
+            }) => Expr::InList(InList::new(
+                transform_boxed(expr, &mut transform)?,
+                transform_vec(list, &mut transform)?,
                 negated,
-            },
+            )),
             Expr::Wildcard => Expr::Wildcard,
             Expr::QualifiedWildcard { qualifier } => {
                 Expr::QualifiedWildcard { qualifier }
diff --git a/datafusion/optimizer/src/analyzer/type_coercion.rs b/datafusion/optimizer/src/analyzer/type_coercion.rs
index 0175831c89..f42bc96dcb 100644
--- a/datafusion/optimizer/src/analyzer/type_coercion.rs
+++ b/datafusion/optimizer/src/analyzer/type_coercion.rs
@@ -25,7 +25,7 @@ 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, Like, ScalarFunction, ScalarUDF,
+    self, Between, BinaryExpr, Case, Exists, InList, Like, ScalarFunction, ScalarUDF,
     WindowFunction,
 };
 use datafusion_expr::expr_schema::cast_subquery;
@@ -332,11 +332,11 @@ impl TreeNodeRewriter for TypeCoercionRewriter {
                 ));
                 Ok(expr)
             }
-            Expr::InList {
+            Expr::InList(InList {
                 expr,
                 list,
                 negated,
-            } => {
+            }) => {
                 let expr_data_type = expr.get_type(&self.schema)?;
                 let list_data_types = list
                     .iter()
@@ -357,11 +357,11 @@ impl TreeNodeRewriter for TypeCoercionRewriter {
                                 list_expr.cast_to(&coerced_type, &self.schema)
                             })
                             .collect::<Result<Vec<_>>>()?;
-                        let expr = Expr::InList {
-                            expr: Box::new(cast_expr),
-                            list: cast_list_expr,
+                        let expr = Expr::InList(InList ::new(
+                             Box::new(cast_expr),
+                             cast_list_expr,
                             negated,
-                        };
+                        ));
                         Ok(expr)
                     }
                 }
diff --git a/datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs b/datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs
index a0c5ff6636..75055b6404 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::ScalarFunction;
+use datafusion_expr::expr::{InList, ScalarFunction};
 use datafusion_expr::{
     and, expr, lit, or, BinaryExpr, BuiltinScalarFunction, ColumnarValue, Expr, Like,
     Volatility,
@@ -391,20 +391,20 @@ impl<'a, S: SimplifyInfo> TreeNodeRewriter for Simplifier<'a, S> {
             }
             // expr IN () --> false
             // expr NOT IN () --> true
-            Expr::InList {
+            Expr::InList(InList {
                 expr,
                 list,
                 negated,
-            } if list.is_empty() && *expr != Expr::Literal(ScalarValue::Null) => {
+            }) if list.is_empty() && *expr != Expr::Literal(ScalarValue::Null) => {
                 lit(negated)
             }
 
             // expr IN ((subquery)) -> expr IN (subquery), see ##5529
-            Expr::InList {
+            Expr::InList(InList {
                 expr,
                 mut list,
                 negated,
-            } if list.len() == 1
+            }) if list.len() == 1
                 && matches!(list.first(), Some(Expr::ScalarSubquery { .. })) =>
             {
                 let Expr::ScalarSubquery(subquery) = list.remove(0) else { unreachable!() };
@@ -417,11 +417,11 @@ impl<'a, S: SimplifyInfo> TreeNodeRewriter for Simplifier<'a, S> {
 
             // if expr is a single column reference:
             // expr IN (A, B, ...) --> (expr = A) OR (expr = B) OR (expr = C)
-            Expr::InList {
+            Expr::InList(InList {
                 expr,
                 list,
                 negated,
-            } if !list.is_empty()
+            }) if !list.is_empty()
                 && (
                     // For lists with only 1 value we allow more complex expressions to be simplified
                     // e.g SUBSTR(c1, 2, 3) IN ('1') -> SUBSTR(c1, 2, 3) = '1'
diff --git a/datafusion/optimizer/src/simplify_expressions/utils.rs b/datafusion/optimizer/src/simplify_expressions/utils.rs
index 094647ca5c..9d36202485 100644
--- a/datafusion/optimizer/src/simplify_expressions/utils.rs
+++ b/datafusion/optimizer/src/simplify_expressions/utils.rs
@@ -21,7 +21,7 @@ use crate::simplify_expressions::SimplifyInfo;
 use datafusion_common::{DataFusionError, Result, ScalarValue};
 use datafusion_expr::expr::ScalarFunction;
 use datafusion_expr::{
-    expr::{Between, BinaryExpr},
+    expr::{Between, BinaryExpr, InList},
     expr_fn::{and, bitwise_and, bitwise_or, concat_ws, or},
     lit, BuiltinScalarFunction, Expr, Like, Operator,
 };
@@ -281,11 +281,11 @@ pub fn negate_clause(expr: Expr) -> Expr {
         Expr::IsNull(expr) => expr.is_not_null(),
         // not (A not in (..)) ===> A in (..)
         // not (A in (..)) ===> A not in (..)
-        Expr::InList {
+        Expr::InList(InList {
             expr,
             list,
             negated,
-        } => expr.in_list(list, !negated),
+        }) => expr.in_list(list, !negated),
         // not (A between B and C) ===> (A not between B and C)
         // not (A not between B and C) ===> (A between B and C)
         Expr::Between(between) => Expr::Between(Between::new(
diff --git a/datafusion/optimizer/src/unwrap_cast_in_comparison.rs b/datafusion/optimizer/src/unwrap_cast_in_comparison.rs
index d3f46472aa..807ce9bb0d 100644
--- a/datafusion/optimizer/src/unwrap_cast_in_comparison.rs
+++ b/datafusion/optimizer/src/unwrap_cast_in_comparison.rs
@@ -27,7 +27,7 @@ use arrow::datatypes::{
 use arrow::temporal_conversions::{MICROSECONDS, MILLISECONDS, NANOSECONDS};
 use datafusion_common::tree_node::{RewriteRecursion, TreeNodeRewriter};
 use datafusion_common::{DFSchemaRef, DataFusionError, Result, ScalarValue};
-use datafusion_expr::expr::{BinaryExpr, Cast, TryCast};
+use datafusion_expr::expr::{BinaryExpr, Cast, InList, TryCast};
 use datafusion_expr::utils::from_plan;
 use datafusion_expr::{
     binary_expr, in_list, lit, Expr, ExprSchemable, LogicalPlan, Operator,
@@ -193,11 +193,11 @@ impl TreeNodeRewriter for UnwrapCastExprRewriter {
             }
             // For case:
             // try_cast/cast(expr as left_type) in (expr1,expr2,expr3)
-            Expr::InList {
+            Expr::InList(InList {
                 expr: left_expr,
                 list,
                 negated,
-            } => {
+            }) => {
                 if let Some(
                     Expr::TryCast(TryCast {
                         expr: internal_left_expr,
diff --git a/datafusion/physical-expr/src/planner.rs b/datafusion/physical-expr/src/planner.rs
index c90313c80d..40241a459e 100644
--- a/datafusion/physical-expr/src/planner.rs
+++ b/datafusion/physical-expr/src/planner.rs
@@ -27,7 +27,7 @@ use crate::{
 };
 use arrow::datatypes::{DataType, Schema};
 use datafusion_common::{DFSchema, DataFusionError, Result, ScalarValue};
-use datafusion_expr::expr::{Cast, ScalarFunction, ScalarUDF};
+use datafusion_expr::expr::{Cast, InList, ScalarFunction, ScalarUDF};
 use datafusion_expr::{
     binary_expr, Between, BinaryExpr, Expr, GetIndexedField, Like, Operator, TryCast,
 };
@@ -448,11 +448,11 @@ pub fn create_physical_expr(
                 binary_expr
             }
         }
-        Expr::InList {
+        Expr::InList(InList {
             expr,
             list,
             negated,
-        } => match expr.as_ref() {
+        }) => match expr.as_ref() {
             Expr::Literal(ScalarValue::Utf8(None)) => {
                 Ok(expressions::lit(ScalarValue::Boolean(None)))
             }
diff --git a/datafusion/proto/src/logical_plan/from_proto.rs b/datafusion/proto/src/logical_plan/from_proto.rs
index bc1b524063..890baba757 100644
--- a/datafusion/proto/src/logical_plan/from_proto.rs
+++ b/datafusion/proto/src/logical_plan/from_proto.rs
@@ -38,7 +38,7 @@ use datafusion_expr::{
     abs, acos, acosh, array, ascii, asin, asinh, atan, atan2, atanh, bit_length, btrim,
     cbrt, ceil, character_length, chr, coalesce, concat_expr, concat_ws_expr, cos, cosh,
     date_bin, date_part, date_trunc, degrees, digest, exp,
-    expr::{self, Sort, WindowFunction},
+    expr::{self, InList, Sort, WindowFunction},
     factorial, floor, from_unixtime, gcd, lcm, left, ln, log, log10, log2,
     logical_plan::{PlanType, StringifiedPlan},
     lower, lpad, ltrim, md5, now, nullif, octet_length, pi, power, radians, random,
@@ -1121,19 +1121,19 @@ pub fn parse_expr(
         ExprType::Negative(negative) => Ok(Expr::Negative(Box::new(
             parse_required_expr(negative.expr.as_deref(), registry, "expr")?,
         ))),
-        ExprType::InList(in_list) => Ok(Expr::InList {
-            expr: Box::new(parse_required_expr(
+        ExprType::InList(in_list) => Ok(Expr::InList(InList::new(
+            Box::new(parse_required_expr(
                 in_list.expr.as_deref(),
                 registry,
                 "expr",
             )?),
-            list: in_list
+            in_list
                 .list
                 .iter()
                 .map(|expr| parse_expr(expr, registry))
                 .collect::<Result<Vec<_>, _>>()?,
-            negated: in_list.negated,
-        }),
+            in_list.negated,
+        ))),
         ExprType::Wildcard(_) => Ok(Expr::Wildcard),
         ExprType::ScalarFunction(expr) => {
             let scalar_function = protobuf::ScalarFunction::from_i32(expr.fun)
diff --git a/datafusion/proto/src/logical_plan/mod.rs b/datafusion/proto/src/logical_plan/mod.rs
index 087f621cd4..8d68a958b2 100644
--- a/datafusion/proto/src/logical_plan/mod.rs
+++ b/datafusion/proto/src/logical_plan/mod.rs
@@ -1416,7 +1416,7 @@ mod roundtrip_tests {
     use datafusion::test_util::{TestTableFactory, TestTableProvider};
     use datafusion_common::{DFSchemaRef, DataFusionError, Result, ScalarValue};
     use datafusion_expr::expr::{
-        self, Between, BinaryExpr, Case, Cast, GroupingSet, Like, ScalarFunction,
+        self, Between, BinaryExpr, Case, Cast, GroupingSet, InList, Like, ScalarFunction,
         ScalarUDF, Sort,
     };
     use datafusion_expr::logical_plan::{Extension, UserDefinedLogicalNodeCore};
@@ -2439,11 +2439,11 @@ mod roundtrip_tests {
 
     #[test]
     fn roundtrip_inlist() {
-        let test_expr = Expr::InList {
-            expr: Box::new(lit(1.0_f32)),
-            list: vec![lit(2.0_f32)],
-            negated: true,
-        };
+        let test_expr = Expr::InList(InList::new(
+            Box::new(lit(1.0_f32)),
+            vec![lit(2.0_f32)],
+            true,
+        ));
 
         let ctx = SessionContext::new();
         roundtrip_expr_test(test_expr, ctx);
diff --git a/datafusion/proto/src/logical_plan/to_proto.rs b/datafusion/proto/src/logical_plan/to_proto.rs
index 25fa4714bc..4c40931b3e 100644
--- a/datafusion/proto/src/logical_plan/to_proto.rs
+++ b/datafusion/proto/src/logical_plan/to_proto.rs
@@ -36,8 +36,8 @@ use arrow::datatypes::{
 };
 use datafusion_common::{Column, DFField, DFSchemaRef, OwnedTableReference, ScalarValue};
 use datafusion_expr::expr::{
-    self, Between, BinaryExpr, Cast, GetIndexedField, GroupingSet, Like, ScalarFunction,
-    ScalarUDF, Sort,
+    self, Between, BinaryExpr, Cast, GetIndexedField, GroupingSet, InList, Like,
+    ScalarFunction, ScalarUDF, Sort,
 };
 use datafusion_expr::{
     logical_plan::PlanType, logical_plan::StringifiedPlan, AggregateFunction,
@@ -874,11 +874,11 @@ impl TryFrom<&Expr> for protobuf::LogicalExprNode {
                     expr_type: Some(ExprType::Negative(expr)),
                 }
             }
-            Expr::InList {
+            Expr::InList(InList {
                 expr,
                 list,
                 negated,
-            } => {
+            }) => {
                 let expr = Box::new(protobuf::InListNode {
                     expr: Some(Box::new(expr.as_ref().try_into()?)),
                     list: list
diff --git a/datafusion/sql/src/expr/mod.rs b/datafusion/sql/src/expr/mod.rs
index eed4487216..89f90b89e6 100644
--- a/datafusion/sql/src/expr/mod.rs
+++ b/datafusion/sql/src/expr/mod.rs
@@ -30,6 +30,7 @@ use crate::planner::{ContextProvider, PlannerContext, SqlToRel};
 use arrow_schema::DataType;
 use datafusion_common::tree_node::{Transformed, TreeNode};
 use datafusion_common::{Column, DFSchema, DataFusionError, Result, ScalarValue};
+use datafusion_expr::expr::InList;
 use datafusion_expr::expr::ScalarFunction;
 use datafusion_expr::{
     col, expr, lit, AggregateFunction, Between, BinaryExpr, BuiltinScalarFunction, Cast,
@@ -359,15 +360,11 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
             .map(|e| self.sql_expr_to_logical_expr(e, schema, planner_context))
             .collect::<Result<Vec<_>>>()?;
 
-        Ok(Expr::InList {
-            expr: Box::new(self.sql_expr_to_logical_expr(
-                expr,
-                schema,
-                planner_context,
-            )?),
-            list: list_expr,
+        Ok(Expr::InList(InList::new(
+            Box::new(self.sql_expr_to_logical_expr(expr, schema, planner_context)?),
+            list_expr,
             negated,
-        })
+        )))
     }
 
     fn sql_like_to_expr(
diff --git a/datafusion/sql/src/utils.rs b/datafusion/sql/src/utils.rs
index 9a52df7ce9..78f25905db 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, Like, ScalarFunction, ScalarUDF, WindowFunction,
+    GroupingSet, InList, Like, ScalarFunction, ScalarUDF, WindowFunction,
 };
 use datafusion_expr::expr::{Cast, Sort};
 use datafusion_expr::utils::{expr_as_column_expr, find_column_exprs};
@@ -221,18 +221,17 @@ where
                 Box::new(clone_with_replacement(low, replacement_fn)?),
                 Box::new(clone_with_replacement(high, replacement_fn)?),
             ))),
-            Expr::InList {
+            Expr::InList(InList {
                 expr: nested_expr,
                 list,
                 negated,
-            } => Ok(Expr::InList {
-                expr: Box::new(clone_with_replacement(nested_expr, replacement_fn)?),
-                list: list
-                    .iter()
+            }) => Ok(Expr::InList(InList::new(
+                Box::new(clone_with_replacement(nested_expr, replacement_fn)?),
+                list.iter()
                     .map(|e| clone_with_replacement(e, replacement_fn))
                     .collect::<Result<Vec<Expr>>>()?,
-                negated: *negated,
-            }),
+                *negated,
+            ))),
             Expr::BinaryExpr(BinaryExpr { left, right, op }) => {
                 Ok(Expr::BinaryExpr(BinaryExpr::new(
                     Box::new(clone_with_replacement(left, replacement_fn)?),