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/06/30 07:49:08 UTC

[arrow-datafusion] branch main updated: refactor: encapsulate Alias as a struct (#6795)

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 e77b93a513 refactor: encapsulate Alias as a struct (#6795)
e77b93a513 is described below

commit e77b93a513563241a4c0da42df4c8b4f67fc1285
Author: jakevin <ja...@gmail.com>
AuthorDate: Fri Jun 30 15:49:03 2023 +0800

    refactor: encapsulate Alias as a struct (#6795)
---
 datafusion/core/src/datasource/listing/helpers.rs  |  2 +-
 datafusion/core/src/physical_planner.rs            | 12 ++++----
 datafusion/expr/src/expr.rs                        | 26 +++++++++++++----
 datafusion/expr/src/expr_rewriter/mod.rs           |  9 +++---
 datafusion/expr/src/expr_rewriter/order_by.rs      | 10 +++----
 datafusion/expr/src/expr_schema.rs                 |  6 ++--
 datafusion/expr/src/logical_plan/builder.rs        |  5 ++--
 datafusion/expr/src/logical_plan/plan.rs           |  6 ++--
 datafusion/expr/src/tree_node/expr.rs              | 12 ++++----
 datafusion/expr/src/utils.rs                       | 10 +++----
 .../optimizer/src/analyzer/count_wildcard_rule.rs  | 18 ++++++------
 .../optimizer/src/common_subexpr_eliminate.rs      |  3 +-
 datafusion/optimizer/src/decorrelate.rs            |  9 +++---
 datafusion/optimizer/src/push_down_filter.rs       |  5 ++--
 datafusion/optimizer/src/push_down_projection.rs   |  4 +--
 datafusion/optimizer/src/utils.rs                  | 10 ++++---
 datafusion/physical-expr/src/planner.rs            |  4 +--
 datafusion/proto/src/logical_plan/from_proto.rs    | 12 +++-----
 datafusion/proto/src/logical_plan/to_proto.rs      |  6 ++--
 datafusion/sql/src/select.rs                       |  4 +--
 datafusion/sql/src/utils.rs                        | 33 +++++++++-------------
 datafusion/substrait/src/logical_plan/producer.rs  |  6 ++--
 22 files changed, 114 insertions(+), 98 deletions(-)

diff --git a/datafusion/core/src/datasource/listing/helpers.rs b/datafusion/core/src/datasource/listing/helpers.rs
index efe1f7b59a..370bc43319 100644
--- a/datafusion/core/src/datasource/listing/helpers.rs
+++ b/datafusion/core/src/datasource/listing/helpers.rs
@@ -63,7 +63,7 @@ pub fn expr_applicable_for_cols(col_names: &[String], expr: &Expr) -> bool {
                 }
             }
             Expr::Literal(_)
-            | Expr::Alias(_, _)
+            | Expr::Alias(_)
             | Expr::OuterReferenceColumn(_, _)
             | Expr::ScalarVariable(_, _)
             | Expr::Not(_)
diff --git a/datafusion/core/src/physical_planner.rs b/datafusion/core/src/physical_planner.rs
index da2f396e8e..a4aab95635 100644
--- a/datafusion/core/src/physical_planner.rs
+++ b/datafusion/core/src/physical_planner.rs
@@ -64,8 +64,8 @@ use arrow::datatypes::{Schema, SchemaRef};
 use async_trait::async_trait;
 use datafusion_common::{DFSchema, ScalarValue};
 use datafusion_expr::expr::{
-    self, AggregateFunction, AggregateUDF, Between, BinaryExpr, Cast, GetIndexedField,
-    GroupingSet, InList, Like, ScalarUDF, TryCast, WindowFunction,
+    self, AggregateFunction, AggregateUDF, Alias, Between, BinaryExpr, Cast,
+    GetIndexedField, GroupingSet, InList, Like, ScalarUDF, TryCast, WindowFunction,
 };
 use datafusion_expr::expr_rewriter::{unalias, unnormalize_cols};
 use datafusion_expr::logical_plan::builder::wrap_projection_for_join_if_necessary;
@@ -111,7 +111,7 @@ fn create_physical_name(e: &Expr, is_first_expr: bool) -> Result<String> {
                 Ok(c.flat_name())
             }
         }
-        Expr::Alias(_, name) => Ok(name.clone()),
+        Expr::Alias(Alias { name, .. }) => Ok(name.clone()),
         Expr::ScalarVariable(_, variable_names) => Ok(variable_names.join(".")),
         Expr::Literal(value) => Ok(format!("{value:?}")),
         Expr::BinaryExpr(BinaryExpr { left, op, right }) => {
@@ -629,7 +629,7 @@ impl DefaultPhysicalPlanner {
                             ref order_by,
                             ..
                         }) => generate_sort_key(partition_by, order_by),
-                        Expr::Alias(expr, _) => {
+                        Expr::Alias(Alias{expr,..}) => {
                             // Convert &Box<T> to &T
                             match &**expr {
                                 Expr::WindowFunction(WindowFunction{
@@ -1596,7 +1596,7 @@ pub fn create_window_expr(
 ) -> Result<Arc<dyn WindowExpr>> {
     // unpack aliased logical expressions, e.g. "sum(col) over () as total"
     let (name, e) = match e {
-        Expr::Alias(sub_expr, alias) => (alias.clone(), sub_expr.as_ref()),
+        Expr::Alias(Alias { expr, name, .. }) => (name.clone(), expr.as_ref()),
         _ => (physical_name(e)?, e),
     };
     create_window_expr_with_name(
@@ -1740,7 +1740,7 @@ pub fn create_aggregate_expr_and_maybe_filter(
 ) -> Result<AggregateExprWithOptionalArgs> {
     // unpack (nested) aliased logical expressions, e.g. "sum(col) as total"
     let (name, e) = match e {
-        Expr::Alias(sub_expr, alias) => (alias.clone(), sub_expr.as_ref()),
+        Expr::Alias(Alias { expr, name, .. }) => (name.clone(), expr.as_ref()),
         _ => (physical_name(e)?, e),
     };
 
diff --git a/datafusion/expr/src/expr.rs b/datafusion/expr/src/expr.rs
index 9c3b53906a..9e1a0aae4c 100644
--- a/datafusion/expr/src/expr.rs
+++ b/datafusion/expr/src/expr.rs
@@ -82,7 +82,7 @@ use std::sync::Arc;
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub enum Expr {
     /// An expression with a specific name.
-    Alias(Box<Expr>, String),
+    Alias(Alias),
     /// A named reference to a qualified filed in a schema.
     Column(Column),
     /// A named reference to a variable in a registry.
@@ -180,6 +180,22 @@ pub enum Expr {
     OuterReferenceColumn(DataType, Column),
 }
 
+/// Alias expression
+#[derive(Clone, PartialEq, Eq, Hash, Debug)]
+pub struct Alias {
+    pub expr: Box<Expr>,
+    pub name: String,
+}
+
+impl Alias {
+    pub fn new(expr: Expr, name: impl Into<String>) -> Self {
+        Self {
+            expr: Box::new(expr),
+            name: name.into(),
+        }
+    }
+}
+
 /// Binary expression
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct BinaryExpr {
@@ -789,14 +805,14 @@ impl Expr {
                 asc,
                 nulls_first,
             }) => Expr::Sort(Sort::new(Box::new(expr.alias(name)), asc, nulls_first)),
-            _ => Expr::Alias(Box::new(self), name.into()),
+            _ => Expr::Alias(Alias::new(self, name.into())),
         }
     }
 
     /// Remove an alias from an expression if one exists.
     pub fn unalias(self) -> Expr {
         match self {
-            Expr::Alias(expr, _) => expr.as_ref().clone(),
+            Expr::Alias(alias) => alias.expr.as_ref().clone(),
             _ => self,
         }
     }
@@ -914,7 +930,7 @@ macro_rules! expr_vec_fmt {
 impl fmt::Display for Expr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
-            Expr::Alias(expr, alias) => write!(f, "{expr} AS {alias}"),
+            Expr::Alias(Alias { expr, name, .. }) => write!(f, "{expr} AS {name}"),
             Expr::Column(c) => write!(f, "{c}"),
             Expr::OuterReferenceColumn(_, c) => write!(f, "outer_ref({c})"),
             Expr::ScalarVariable(_, var_names) => write!(f, "{}", var_names.join(".")),
@@ -1180,7 +1196,7 @@ fn create_function_name(fun: &str, distinct: bool, args: &[Expr]) -> Result<Stri
 /// This function recursively transverses the expression for names such as "CAST(a > 2)".
 fn create_name(e: &Expr) -> Result<String> {
     match e {
-        Expr::Alias(_, name) => Ok(name.clone()),
+        Expr::Alias(Alias { name, .. }) => Ok(name.clone()),
         Expr::Column(c) => Ok(c.flat_name()),
         Expr::OuterReferenceColumn(_, c) => Ok(format!("outer_ref({})", c.flat_name())),
         Expr::ScalarVariable(_, variable_names) => Ok(variable_names.join(".")),
diff --git a/datafusion/expr/src/expr_rewriter/mod.rs b/datafusion/expr/src/expr_rewriter/mod.rs
index cbd336d934..acb8d23c0d 100644
--- a/datafusion/expr/src/expr_rewriter/mod.rs
+++ b/datafusion/expr/src/expr_rewriter/mod.rs
@@ -17,6 +17,7 @@
 
 //! Expression rewriter
 
+use crate::expr::Alias;
 use crate::logical_plan::Projection;
 use crate::{Expr, ExprSchemable, LogicalPlan, LogicalPlanBuilder};
 use datafusion_common::tree_node::{Transformed, TreeNode, TreeNodeRewriter};
@@ -143,7 +144,7 @@ pub fn create_col_from_scalar_expr(
     subqry_alias: String,
 ) -> Result<Column> {
     match scalar_expr {
-        Expr::Alias(_, alias) => Ok(Column::new(Some(subqry_alias), alias)),
+        Expr::Alias(Alias { name, .. }) => Ok(Column::new(Some(subqry_alias), name)),
         Expr::Column(Column { relation: _, name }) => {
             Ok(Column::new(Some(subqry_alias), name))
         }
@@ -221,8 +222,8 @@ fn coerce_exprs_for_schema(
             let new_type = dst_schema.field(idx).data_type();
             if new_type != &expr.get_type(src_schema)? {
                 match expr {
-                    Expr::Alias(e, alias) => {
-                        Ok(e.cast_to(new_type, src_schema)?.alias(alias))
+                    Expr::Alias(Alias { expr, name, .. }) => {
+                        Ok(expr.cast_to(new_type, src_schema)?.alias(name))
                     }
                     _ => expr.cast_to(new_type, src_schema),
                 }
@@ -237,7 +238,7 @@ fn coerce_exprs_for_schema(
 #[inline]
 pub fn unalias(expr: Expr) -> Expr {
     match expr {
-        Expr::Alias(sub_expr, _) => unalias(*sub_expr),
+        Expr::Alias(Alias { expr, .. }) => unalias(*expr),
         _ => expr,
     }
 }
diff --git a/datafusion/expr/src/expr_rewriter/order_by.rs b/datafusion/expr/src/expr_rewriter/order_by.rs
index ce832d11fd..c87a724d56 100644
--- a/datafusion/expr/src/expr_rewriter/order_by.rs
+++ b/datafusion/expr/src/expr_rewriter/order_by.rs
@@ -17,7 +17,7 @@
 
 //! Rewrite for order by expressions
 
-use crate::expr::Sort;
+use crate::expr::{Alias, Sort};
 use crate::expr_rewriter::normalize_col;
 use crate::{Cast, Expr, ExprSchemable, LogicalPlan, TryCast};
 use datafusion_common::tree_node::{Transformed, TreeNode};
@@ -137,12 +137,12 @@ fn rewrite_in_terms_of_projection(
 
 /// Does the underlying expr match e?
 /// so avg(c) as average will match avgc
-fn expr_match(needle: &Expr, haystack: &Expr) -> bool {
+fn expr_match(needle: &Expr, expr: &Expr) -> bool {
     // check inside aliases
-    if let Expr::Alias(haystack, _) = &haystack {
-        haystack.as_ref() == needle
+    if let Expr::Alias(Alias { expr, .. }) = &expr {
+        expr.as_ref() == needle
     } else {
-        haystack == needle
+        expr == needle
     }
 }
 
diff --git a/datafusion/expr/src/expr_schema.rs b/datafusion/expr/src/expr_schema.rs
index 5c57a8acef..83ccc8c596 100644
--- a/datafusion/expr/src/expr_schema.rs
+++ b/datafusion/expr/src/expr_schema.rs
@@ -17,7 +17,7 @@
 
 use super::{Between, Expr, Like};
 use crate::expr::{
-    AggregateFunction, AggregateUDF, BinaryExpr, Cast, GetIndexedField, InList,
+    AggregateFunction, AggregateUDF, Alias, BinaryExpr, Cast, GetIndexedField, InList,
     InSubquery, Placeholder, ScalarFunction, ScalarUDF, Sort, TryCast, WindowFunction,
 };
 use crate::field_util::get_indexed_field;
@@ -58,7 +58,7 @@ impl ExprSchemable for Expr {
     /// (e.g. `[utf8] + [bool]`).
     fn get_type<S: ExprSchema>(&self, schema: &S) -> Result<DataType> {
         match self {
-            Expr::Alias(expr, name) => match &**expr {
+            Expr::Alias(Alias { expr, name, .. }) => match &**expr {
                 Expr::Placeholder(Placeholder { data_type, .. }) => match &data_type {
                     None => schema.data_type(&Column::from_name(name)).cloned(),
                     Some(dt) => Ok(dt.clone()),
@@ -170,7 +170,7 @@ impl ExprSchemable for Expr {
     /// column that does not exist in the schema.
     fn nullable<S: ExprSchema>(&self, input_schema: &S) -> Result<bool> {
         match self {
-            Expr::Alias(expr, _)
+            Expr::Alias(Alias { expr, .. })
             | Expr::Not(expr)
             | Expr::Negative(expr)
             | Expr::Sort(Sort { expr, .. })
diff --git a/datafusion/expr/src/logical_plan/builder.rs b/datafusion/expr/src/logical_plan/builder.rs
index 3d34c087ac..61d540049c 100644
--- a/datafusion/expr/src/logical_plan/builder.rs
+++ b/datafusion/expr/src/logical_plan/builder.rs
@@ -17,6 +17,7 @@
 
 //! This module provides a builder for creating LogicalPlans
 
+use crate::expr::Alias;
 use crate::expr_rewriter::{
     coerce_plan_expr_for_schema, normalize_col,
     normalize_col_with_schemas_and_ambiguity_check, normalize_cols,
@@ -476,7 +477,7 @@ impl LogicalPlanBuilder {
         // As described in https://github.com/apache/arrow-datafusion/issues/5293
         let all_aliases = missing_exprs.iter().all(|e| {
             projection_exprs.iter().any(|proj_expr| {
-                if let Expr::Alias(expr, _) = proj_expr {
+                if let Expr::Alias(Alias { expr, .. }) = proj_expr {
                     e == expr.as_ref()
                 } else {
                     false
@@ -1131,7 +1132,7 @@ pub fn project_with_column_index(
         .into_iter()
         .enumerate()
         .map(|(i, e)| match e {
-            Expr::Alias(_, ref name) if name != schema.field(i).name() => {
+            Expr::Alias(Alias { ref name, .. }) if name != schema.field(i).name() => {
                 e.unalias().alias(schema.field(i).name())
             }
             Expr::Column(Column {
diff --git a/datafusion/expr/src/logical_plan/plan.rs b/datafusion/expr/src/logical_plan/plan.rs
index ab45047acf..cf94052252 100644
--- a/datafusion/expr/src/logical_plan/plan.rs
+++ b/datafusion/expr/src/logical_plan/plan.rs
@@ -17,7 +17,7 @@
 
 //! Logical plan types
 
-use crate::expr::{Exists, InSubquery, Placeholder};
+use crate::expr::{Alias, Exists, InSubquery, Placeholder};
 use crate::expr_rewriter::create_col_from_scalar_expr;
 use crate::expr_vec_fmt;
 use crate::logical_plan::display::{GraphvizVisitor, IndentVisitor};
@@ -1370,10 +1370,10 @@ impl Filter {
         }
 
         // filter predicates should not be aliased
-        if let Expr::Alias(expr, alias) = predicate {
+        if let Expr::Alias(Alias { expr, name, .. }) = predicate {
             return Err(DataFusionError::Plan(format!(
                 "Attempted to create Filter predicate with \
-                expression `{expr}` aliased as '{alias}'. Filter predicates should not be \
+                expression `{expr}` aliased as '{name}'. Filter predicates should not be \
                 aliased."
             )));
         }
diff --git a/datafusion/expr/src/tree_node/expr.rs b/datafusion/expr/src/tree_node/expr.rs
index 3ecf54c9ce..095a0f4e27 100644
--- a/datafusion/expr/src/tree_node/expr.rs
+++ b/datafusion/expr/src/tree_node/expr.rs
@@ -18,9 +18,9 @@
 //! Tree node implementation for logical expr
 
 use crate::expr::{
-    AggregateFunction, AggregateUDF, Between, BinaryExpr, Case, Cast, GetIndexedField,
-    GroupingSet, InList, InSubquery, Like, Placeholder, ScalarFunction, ScalarUDF, Sort,
-    TryCast, WindowFunction,
+    AggregateFunction, AggregateUDF, Alias, Between, BinaryExpr, Case, Cast,
+    GetIndexedField, GroupingSet, InList, InSubquery, Like, Placeholder, ScalarFunction,
+    ScalarUDF, Sort, TryCast, WindowFunction,
 };
 use crate::Expr;
 use datafusion_common::tree_node::VisitRecursion;
@@ -32,7 +32,7 @@ impl TreeNode for Expr {
         F: FnMut(&Self) -> Result<VisitRecursion>,
     {
         let children = match self {
-            Expr::Alias(expr, _)
+            Expr::Alias(Alias{expr,..})
             | Expr::Not(expr)
             | Expr::IsNotNull(expr)
             | Expr::IsTrue(expr)
@@ -147,8 +147,8 @@ impl TreeNode for Expr {
         let mut transform = transform;
 
         Ok(match self {
-            Expr::Alias(expr, name) => {
-                Expr::Alias(transform_boxed(expr, &mut transform)?, name)
+            Expr::Alias(Alias { expr, name, .. }) => {
+                Expr::Alias(Alias::new(transform(*expr)?, name))
             }
             Expr::Column(_) => self,
             Expr::OuterReferenceColumn(_, _) => self,
diff --git a/datafusion/expr/src/utils.rs b/datafusion/expr/src/utils.rs
index 2b6fc5793a..61b0db53fb 100644
--- a/datafusion/expr/src/utils.rs
+++ b/datafusion/expr/src/utils.rs
@@ -17,7 +17,7 @@
 
 //! Expression utilities
 
-use crate::expr::{Sort, WindowFunction};
+use crate::expr::{Alias, Sort, WindowFunction};
 use crate::logical_plan::builder::build_join_schema;
 use crate::logical_plan::{
     Aggregate, Analyze, Distinct, Extension, Filter, Join, Limit, Partitioning, Prepare,
@@ -275,7 +275,7 @@ pub fn expr_to_columns(expr: &Expr, accum: &mut HashSet<Column>) -> Result<()> {
             // implementation, so that in the future if someone adds
             // new Expr types, they will check here as well
             Expr::ScalarVariable(_, _)
-            | Expr::Alias(_, _)
+            | Expr::Alias(_)
             | Expr::Literal(_)
             | Expr::BinaryExpr { .. }
             | Expr::Like { .. }
@@ -781,7 +781,7 @@ pub fn from_plan(
                             // subqueries could contain aliases so we don't recurse into those
                             Ok(RewriteRecursion::Stop)
                         }
-                        Expr::Alias(_, _) => Ok(RewriteRecursion::Mutate),
+                        Expr::Alias(_) => Ok(RewriteRecursion::Mutate),
                         _ => Ok(RewriteRecursion::Continue),
                     }
                 }
@@ -1103,8 +1103,8 @@ pub fn columnize_expr(e: Expr, input_schema: &DFSchema) -> Expr {
     match e {
         Expr::Column(_) => e,
         Expr::OuterReferenceColumn(_, _) => e,
-        Expr::Alias(inner_expr, name) => {
-            columnize_expr(*inner_expr, input_schema).alias(name)
+        Expr::Alias(Alias { expr, name, .. }) => {
+            columnize_expr(*expr, input_schema).alias(name)
         }
         Expr::Cast(Cast { expr, data_type }) => Expr::Cast(Cast {
             expr: Box::new(columnize_expr(*expr, input_schema)),
diff --git a/datafusion/optimizer/src/analyzer/count_wildcard_rule.rs b/datafusion/optimizer/src/analyzer/count_wildcard_rule.rs
index 51354cb666..f4a5147813 100644
--- a/datafusion/optimizer/src/analyzer/count_wildcard_rule.rs
+++ b/datafusion/optimizer/src/analyzer/count_wildcard_rule.rs
@@ -18,7 +18,7 @@
 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, InSubquery};
+use datafusion_expr::expr::{AggregateFunction, Alias, InSubquery};
 use datafusion_expr::utils::COUNT_STAR_EXPANSION;
 use datafusion_expr::Expr::ScalarSubquery;
 use datafusion_expr::{
@@ -132,13 +132,15 @@ impl TreeNodeRewriter for CountWildcardRewriter {
 
     fn mutate(&mut self, old_expr: Expr) -> Result<Expr> {
         let new_expr = match old_expr.clone() {
-            Expr::Alias(expr, alias) if alias.contains(COUNT_STAR) => Expr::Alias(
-                expr,
-                alias.replace(
-                    COUNT_STAR,
-                    count(lit(COUNT_STAR_EXPANSION)).to_string().as_str(),
-                ),
-            ),
+            Expr::Alias(Alias { expr, name, .. }) if name.contains(COUNT_STAR) => {
+                Expr::Alias(Alias::new(
+                    *expr,
+                    name.replace(
+                        COUNT_STAR,
+                        count(lit(COUNT_STAR_EXPANSION)).to_string().as_str(),
+                    ),
+                ))
+            }
             Expr::Column(Column { name, relation }) if name.contains(COUNT_STAR) => {
                 Expr::Column(Column {
                     name: name.replace(
diff --git a/datafusion/optimizer/src/common_subexpr_eliminate.rs b/datafusion/optimizer/src/common_subexpr_eliminate.rs
index c0b47fbb02..74c4b1d36f 100644
--- a/datafusion/optimizer/src/common_subexpr_eliminate.rs
+++ b/datafusion/optimizer/src/common_subexpr_eliminate.rs
@@ -27,6 +27,7 @@ use datafusion_common::tree_node::{
 use datafusion_common::{
     Column, DFField, DFSchema, DFSchemaRef, DataFusionError, Result,
 };
+use datafusion_expr::expr::Alias;
 use datafusion_expr::{
     col,
     logical_plan::{Aggregate, Filter, LogicalPlan, Projection, Sort, Window},
@@ -277,7 +278,7 @@ impl CommonSubexprEliminate {
             }
             for (expr_rewritten, expr_orig) in rewritten.into_iter().zip(new_aggr_expr) {
                 if expr_rewritten == expr_orig {
-                    if let Expr::Alias(expr, name) = expr_rewritten {
+                    if let Expr::Alias(Alias { expr, name, .. }) = expr_rewritten {
                         agg_exprs.push(expr.alias(&name));
                         proj_exprs.push(Expr::Column(Column::from_name(name)));
                     } else {
diff --git a/datafusion/optimizer/src/decorrelate.rs b/datafusion/optimizer/src/decorrelate.rs
index fa96ede3c8..f335592eb3 100644
--- a/datafusion/optimizer/src/decorrelate.rs
+++ b/datafusion/optimizer/src/decorrelate.rs
@@ -24,6 +24,7 @@ use datafusion_common::tree_node::{
 };
 use datafusion_common::Result;
 use datafusion_common::{Column, DFSchemaRef, DataFusionError, ScalarValue};
+use datafusion_expr::expr::Alias;
 use datafusion_expr::{expr, EmptyRelation, Expr, LogicalPlan, LogicalPlanBuilder};
 use datafusion_physical_expr::execution_props::ExecutionProps;
 use std::collections::{BTreeSet, HashMap};
@@ -228,10 +229,10 @@ impl TreeNodeRewriter for PullUpCorrelatedExpr {
                     )?;
                     if !expr_result_map_for_count_bug.is_empty() {
                         // has count bug
-                        let un_matched_row = Expr::Alias(
-                            Box::new(Expr::Literal(ScalarValue::Boolean(Some(true)))),
+                        let un_matched_row = Expr::Alias(Alias::new(
+                            Expr::Literal(ScalarValue::Boolean(Some(true))),
                             UN_MATCHED_ROW_INDICATOR.to_string(),
-                        );
+                        ));
                         // add the unmatched rows indicator to the Aggregation's group expressions
                         missing_exprs.push(un_matched_row);
                     }
@@ -428,7 +429,7 @@ fn proj_exprs_evaluation_result_on_empty_batch(
             let simplifier = ExprSimplifier::new(info);
             let result_expr = simplifier.simplify(result_expr)?;
             let expr_name = match expr {
-                Expr::Alias(_, alias) => alias.to_string(),
+                Expr::Alias(Alias { name, .. }) => name.to_string(),
                 Expr::Column(Column { relation: _, name }) => name.to_string(),
                 _ => expr.display_name()?,
             };
diff --git a/datafusion/optimizer/src/push_down_filter.rs b/datafusion/optimizer/src/push_down_filter.rs
index 6492b95f36..92fa2d895b 100644
--- a/datafusion/optimizer/src/push_down_filter.rs
+++ b/datafusion/optimizer/src/push_down_filter.rs
@@ -19,6 +19,7 @@ use crate::utils::{conjunction, split_conjunction};
 use crate::{utils, OptimizerConfig, OptimizerRule};
 use datafusion_common::tree_node::{Transformed, TreeNode, VisitRecursion};
 use datafusion_common::{Column, DFSchema, DataFusionError, Result};
+use datafusion_expr::expr::Alias;
 use datafusion_expr::{
     and,
     expr_rewriter::replace_col,
@@ -164,7 +165,7 @@ fn can_evaluate_as_join_condition(predicate: &Expr) -> Result<bool> {
             is_evaluate = false;
             Ok(VisitRecursion::Stop)
         }
-        Expr::Alias(_, _)
+        Expr::Alias(_)
         | Expr::BinaryExpr(_)
         | Expr::Like(_)
         | Expr::ILike(_)
@@ -668,7 +669,7 @@ impl OptimizerRule for PushDownFilter {
                     .map(|(i, field)| {
                         // strip alias, as they should not be part of filters
                         let expr = match &projection.expr[i] {
-                            Expr::Alias(expr, _) => expr.as_ref().clone(),
+                            Expr::Alias(Alias { expr, .. }) => expr.as_ref().clone(),
                             expr => expr.clone(),
                         };
 
diff --git a/datafusion/optimizer/src/push_down_projection.rs b/datafusion/optimizer/src/push_down_projection.rs
index 4773a944f4..eb9ae3c981 100644
--- a/datafusion/optimizer/src/push_down_projection.rs
+++ b/datafusion/optimizer/src/push_down_projection.rs
@@ -28,7 +28,7 @@ use datafusion_common::ScalarValue::UInt8;
 use datafusion_common::{
     Column, DFField, DFSchema, DFSchemaRef, DataFusionError, Result, ToDFSchema,
 };
-use datafusion_expr::expr::AggregateFunction;
+use datafusion_expr::expr::{AggregateFunction, Alias};
 use datafusion_expr::utils::exprlist_to_fields;
 use datafusion_expr::{
     logical_plan::{Aggregate, LogicalPlan, Projection, TableScan, Union},
@@ -414,7 +414,7 @@ pub fn collect_projection_expr(projection: &Projection) -> HashMap<String, Expr>
         .flat_map(|(i, field)| {
             // strip alias, as they should not be part of filters
             let expr = match &projection.expr[i] {
-                Expr::Alias(expr, _) => expr.as_ref().clone(),
+                Expr::Alias(Alias { expr, .. }) => expr.as_ref().clone(),
                 expr => expr.clone(),
             };
 
diff --git a/datafusion/optimizer/src/utils.rs b/datafusion/optimizer/src/utils.rs
index bdef56f61b..adb3bf6302 100644
--- a/datafusion/optimizer/src/utils.rs
+++ b/datafusion/optimizer/src/utils.rs
@@ -20,7 +20,7 @@
 use crate::{OptimizerConfig, OptimizerRule};
 use datafusion_common::{plan_err, Column, DFSchemaRef};
 use datafusion_common::{DFSchema, Result};
-use datafusion_expr::expr::BinaryExpr;
+use datafusion_expr::expr::{Alias, BinaryExpr};
 use datafusion_expr::expr_rewriter::{replace_col, strip_outer_reference};
 use datafusion_expr::{
     and,
@@ -74,7 +74,7 @@ fn split_conjunction_impl<'a>(expr: &'a Expr, mut exprs: Vec<&'a Expr>) -> Vec<&
             let exprs = split_conjunction_impl(left, exprs);
             split_conjunction_impl(right, exprs)
         }
-        Expr::Alias(expr, _) => split_conjunction_impl(expr, exprs),
+        Expr::Alias(Alias { expr, .. }) => split_conjunction_impl(expr, exprs),
         other => {
             exprs.push(other);
             exprs
@@ -143,7 +143,9 @@ fn split_binary_owned_impl(
             let exprs = split_binary_owned_impl(*left, operator, exprs);
             split_binary_owned_impl(*right, operator, exprs)
         }
-        Expr::Alias(expr, _) => split_binary_owned_impl(*expr, operator, exprs),
+        Expr::Alias(Alias { expr, .. }) => {
+            split_binary_owned_impl(*expr, operator, exprs)
+        }
         other => {
             exprs.push(other);
             exprs
@@ -168,7 +170,7 @@ fn split_binary_impl<'a>(
             let exprs = split_binary_impl(left, operator, exprs);
             split_binary_impl(right, operator, exprs)
         }
-        Expr::Alias(expr, _) => split_binary_impl(expr, operator, exprs),
+        Expr::Alias(Alias { expr, .. }) => split_binary_impl(expr, operator, exprs),
         other => {
             exprs.push(other);
             exprs
diff --git a/datafusion/physical-expr/src/planner.rs b/datafusion/physical-expr/src/planner.rs
index 40241a459e..d3eb6d1db9 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, InList, ScalarFunction, ScalarUDF};
+use datafusion_expr::expr::{Alias, Cast, InList, ScalarFunction, ScalarUDF};
 use datafusion_expr::{
     binary_expr, Between, BinaryExpr, Expr, GetIndexedField, Like, Operator, TryCast,
 };
@@ -57,7 +57,7 @@ pub fn create_physical_expr(
         )));
     }
     match e {
-        Expr::Alias(expr, ..) => Ok(create_physical_expr(
+        Expr::Alias(Alias { expr, .. }) => Ok(create_physical_expr(
             expr,
             input_dfschema,
             input_schema,
diff --git a/datafusion/proto/src/logical_plan/from_proto.rs b/datafusion/proto/src/logical_plan/from_proto.rs
index 5fabf17e32..785f18d07f 100644
--- a/datafusion/proto/src/logical_plan/from_proto.rs
+++ b/datafusion/proto/src/logical_plan/from_proto.rs
@@ -34,7 +34,7 @@ use datafusion_common::{
     Column, DFField, DFSchema, DFSchemaRef, DataFusionError, OwnedTableReference, Result,
     ScalarValue,
 };
-use datafusion_expr::expr::Placeholder;
+use datafusion_expr::expr::{Alias, Placeholder};
 use datafusion_expr::{
     abs, acos, acosh, array, array_append, array_concat, array_contains, array_dims,
     array_fill, array_length, array_ndims, array_position, array_positions,
@@ -1014,14 +1014,10 @@ pub fn parse_expr(
                 parse_vec_expr(&expr.order_by, registry)?,
             )))
         }
-        ExprType::Alias(alias) => Ok(Expr::Alias(
-            Box::new(parse_required_expr(
-                alias.expr.as_deref(),
-                registry,
-                "expr",
-            )?),
+        ExprType::Alias(alias) => Ok(Expr::Alias(Alias::new(
+            parse_required_expr(alias.expr.as_deref(), registry, "expr")?,
             alias.alias.clone(),
-        )),
+        ))),
         ExprType::IsNullExpr(is_null) => Ok(Expr::IsNull(Box::new(parse_required_expr(
             is_null.expr.as_deref(),
             registry,
diff --git a/datafusion/proto/src/logical_plan/to_proto.rs b/datafusion/proto/src/logical_plan/to_proto.rs
index bf233c229f..c832faa5f7 100644
--- a/datafusion/proto/src/logical_plan/to_proto.rs
+++ b/datafusion/proto/src/logical_plan/to_proto.rs
@@ -36,7 +36,7 @@ use arrow::datatypes::{
 };
 use datafusion_common::{Column, DFField, DFSchemaRef, OwnedTableReference, ScalarValue};
 use datafusion_expr::expr::{
-    self, Between, BinaryExpr, Cast, GetIndexedField, GroupingSet, InList, Like,
+    self, Alias, Between, BinaryExpr, Cast, GetIndexedField, GroupingSet, InList, Like,
     Placeholder, ScalarFunction, ScalarUDF, Sort,
 };
 use datafusion_expr::{
@@ -468,10 +468,10 @@ impl TryFrom<&Expr> for protobuf::LogicalExprNode {
             Expr::Column(c) => Self {
                 expr_type: Some(ExprType::Column(c.into())),
             },
-            Expr::Alias(expr, alias) => {
+            Expr::Alias(Alias { expr, name, .. }) => {
                 let alias = Box::new(protobuf::AliasNode {
                     expr: Some(Box::new(expr.as_ref().try_into()?)),
-                    alias: alias.to_owned(),
+                    alias: name.to_owned(),
                 });
                 Self {
                     expr_type: Some(ExprType::Alias(alias)),
diff --git a/datafusion/sql/src/select.rs b/datafusion/sql/src/select.rs
index f12830df42..7841858bac 100644
--- a/datafusion/sql/src/select.rs
+++ b/datafusion/sql/src/select.rs
@@ -29,11 +29,11 @@ use datafusion_expr::utils::{
     expand_qualified_wildcard, expand_wildcard, expr_as_column_expr, expr_to_columns,
     find_aggregate_exprs, find_window_exprs,
 };
-use datafusion_expr::Expr::Alias;
 use datafusion_expr::{
     Expr, Filter, GroupingSet, LogicalPlan, LogicalPlanBuilder, Partitioning,
 };
 
+use datafusion_expr::expr::Alias;
 use sqlparser::ast::{Distinct, Expr as SQLExpr, WildcardAdditionalOptions, WindowType};
 use sqlparser::ast::{NamedWindowDefinition, Select, SelectItem, TableWithJoins};
 use std::collections::HashSet;
@@ -348,7 +348,7 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
                     &[&[plan.schema()]],
                     &plan.using_columns()?,
                 )?;
-                let expr = Alias(Box::new(col), self.normalizer.normalize(alias));
+                let expr = Expr::Alias(Alias::new(col, self.normalizer.normalize(alias)));
                 Ok(vec![expr])
             }
             SelectItem::Wildcard(options) => {
diff --git a/datafusion/sql/src/utils.rs b/datafusion/sql/src/utils.rs
index e37830d0ba..1cf4138773 100644
--- a/datafusion/sql/src/utils.rs
+++ b/datafusion/sql/src/utils.rs
@@ -22,7 +22,7 @@ use sqlparser::ast::Ident;
 
 use datafusion_common::{DataFusionError, Result, ScalarValue};
 use datafusion_expr::expr::{
-    AggregateFunction, AggregateUDF, Between, BinaryExpr, Case, GetIndexedField,
+    AggregateFunction, AggregateUDF, Alias, Between, BinaryExpr, Case, GetIndexedField,
     GroupingSet, InList, InSubquery, Like, Placeholder, ScalarFunction, ScalarUDF,
     WindowFunction,
 };
@@ -210,10 +210,10 @@ where
                 filter.clone(),
                 order_by.clone(),
             ))),
-            Expr::Alias(nested_expr, alias_name) => Ok(Expr::Alias(
-                Box::new(clone_with_replacement(nested_expr, replacement_fn)?),
-                alias_name.clone(),
-            )),
+            Expr::Alias(Alias { expr, name, .. }) => Ok(Expr::Alias(Alias::new(
+                clone_with_replacement(expr, replacement_fn)?,
+                name.clone(),
+            ))),
             Expr::Between(Between {
                 expr,
                 negated,
@@ -430,9 +430,7 @@ pub(crate) fn extract_aliases(exprs: &[Expr]) -> HashMap<String, Expr> {
     exprs
         .iter()
         .filter_map(|expr| match expr {
-            Expr::Alias(nested_expr, alias_name) => {
-                Some((alias_name.clone(), *nested_expr.clone()))
-            }
+            Expr::Alias(Alias { expr, name, .. }) => Some((name.clone(), *expr.clone())),
             _ => None,
         })
         .collect::<HashMap<String, Expr>>()
@@ -454,7 +452,7 @@ pub(crate) fn resolve_positions_to_exprs(
             let index = (position - 1) as usize;
             let select_expr = &select_exprs[index];
             Some(match select_expr {
-                Expr::Alias(nested_expr, _alias_name) => *nested_expr.clone(),
+                Expr::Alias(Alias { expr, .. }) => *expr.clone(),
                 _ => select_expr.clone(),
             })
         }
@@ -487,17 +485,14 @@ pub fn window_expr_common_partition_keys(window_exprs: &[Expr]) -> Result<&[Expr
         .iter()
         .map(|expr| match expr {
             Expr::WindowFunction(WindowFunction { partition_by, .. }) => Ok(partition_by),
-            Expr::Alias(expr, _) => {
-                // convert &Box<T> to &T
-                match &**expr {
-                    Expr::WindowFunction(WindowFunction { partition_by, .. }) => {
-                        Ok(partition_by)
-                    }
-                    expr => Err(DataFusionError::Execution(format!(
-                        "Impossibly got non-window expr {expr:?}"
-                    ))),
+            Expr::Alias(Alias { expr, .. }) => match expr.as_ref() {
+                Expr::WindowFunction(WindowFunction { partition_by, .. }) => {
+                    Ok(partition_by)
                 }
-            }
+                expr => Err(DataFusionError::Execution(format!(
+                    "Impossibly got non-window expr {expr:?}"
+                ))),
+            },
             expr => Err(DataFusionError::Execution(format!(
                 "Impossibly got non-window expr {expr:?}"
             ))),
diff --git a/datafusion/substrait/src/logical_plan/producer.rs b/datafusion/substrait/src/logical_plan/producer.rs
index c3d169aaab..6cc9eec75b 100644
--- a/datafusion/substrait/src/logical_plan/producer.rs
+++ b/datafusion/substrait/src/logical_plan/producer.rs
@@ -30,7 +30,7 @@ use datafusion::common::DFSchemaRef;
 #[allow(unused_imports)]
 use datafusion::logical_expr::aggregate_function;
 use datafusion::logical_expr::expr::{
-    BinaryExpr, Case, Cast, InList, ScalarFunction as DFScalarFunction, Sort,
+    Alias, BinaryExpr, Case, Cast, InList, ScalarFunction as DFScalarFunction, Sort,
     WindowFunction,
 };
 use datafusion::logical_expr::{expr, Between, JoinConstraint, LogicalPlan, Operator};
@@ -504,7 +504,7 @@ pub fn to_substrait_agg_measure(
                 }
             })
         }
-        Expr::Alias(expr, _name) => {
+        Expr::Alias(Alias{expr,..})=> {
             to_substrait_agg_measure(expr, schema, extension_info)
         }
         _ => Err(DataFusionError::Internal(format!(
@@ -858,7 +858,7 @@ pub fn to_substrait_rex(
             })
         }
         Expr::Literal(value) => to_substrait_literal(value),
-        Expr::Alias(expr, _alias) => {
+        Expr::Alias(Alias { expr, .. }) => {
             to_substrait_rex(expr, schema, col_ref_offset, extension_info)
         }
         Expr::WindowFunction(WindowFunction {