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

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


The following commit(s) were added to refs/heads/main by this push:
     new 0e77fb2aa5 Simpler to see expressions in explain `tree` mode (#15163)
0e77fb2aa5 is described below

commit 0e77fb2aa54a3ea53c47a90ae870ee0adef3279f
Author: irenjj <[email protected]>
AuthorDate: Sat Mar 15 20:11:13 2025 +0800

    Simpler to see expressions in explain `tree` mode (#15163)
    
    * Simpler to see expressions in tree explain mode
    
    * add more
    
    * add cast
    
    * rename
    
    * fmt
    
    * add sql_formatter
    
    * add license
    
    * fix test
    
    * fix doc
    
    * Update datafusion/physical-expr-common/src/physical_expr.rs
    
    Co-authored-by: Andrew Lamb <[email protected]>
    
    * add example
    
    * fix
    
    * simplify col
    
    * fix
    
    * Update plan
    
    * Rename sql_formatter, add doc and examples
    
    ---------
    
    Co-authored-by: Andrew Lamb <[email protected]>
---
 .../physical-expr-common/src/physical_expr.rs      | 69 +++++++++++++++-
 datafusion/physical-expr-common/src/sort_expr.rs   |  3 +-
 datafusion/physical-expr/src/expressions/binary.rs | 95 ++++++++++++++++++++++
 datafusion/physical-expr/src/expressions/case.rs   | 55 +++++++++++++
 datafusion/physical-expr/src/expressions/cast.rs   | 31 +++++++
 datafusion/physical-expr/src/expressions/column.rs |  4 +
 .../physical-expr/src/expressions/in_list.rs       | 57 +++++++++++++
 .../physical-expr/src/expressions/is_not_null.rs   | 31 +++++++
 .../physical-expr/src/expressions/is_null.rs       | 20 +++++
 datafusion/physical-expr/src/expressions/like.rs   | 33 ++++++++
 .../physical-expr/src/expressions/literal.rs       | 17 ++++
 .../physical-expr/src/expressions/negative.rs      | 18 ++++
 datafusion/physical-expr/src/expressions/no_op.rs  |  4 +
 datafusion/physical-expr/src/expressions/not.rs    | 21 +++++
 .../physical-expr/src/expressions/try_cast.rs      | 29 +++++++
 .../src/expressions/unknown_column.rs              |  4 +
 datafusion/physical-expr/src/scalar_function.rs    | 11 +++
 datafusion/physical-plan/src/projection.rs         | 10 ++-
 .../proto/tests/cases/roundtrip_physical_plan.rs   |  6 +-
 .../sqllogictest/test_files/explain_tree.slt       | 80 +++++++++---------
 20 files changed, 551 insertions(+), 47 deletions(-)

diff --git a/datafusion/physical-expr-common/src/physical_expr.rs 
b/datafusion/physical-expr-common/src/physical_expr.rs
index cc2ff2f247..43f214607f 100644
--- a/datafusion/physical-expr-common/src/physical_expr.rs
+++ b/datafusion/physical-expr-common/src/physical_expr.rs
@@ -16,6 +16,7 @@
 // under the License.
 
 use std::any::Any;
+use std::fmt;
 use std::fmt::{Debug, Display, Formatter};
 use std::hash::{Hash, Hasher};
 use std::sync::Arc;
@@ -53,6 +54,12 @@ pub type PhysicalExprRef = Arc<dyn PhysicalExpr>;
 /// * [`SessionContext::create_physical_expr`]: A high level API
 /// * [`create_physical_expr`]: A low level API
 ///
+/// # Formatting `PhysicalExpr` as strings
+/// There are three ways to format `PhysicalExpr` as a string:
+/// * [`Debug`]: Standard Rust debugging format (e.g. `Constant { value: ... 
}`)
+/// * [`Display`]: Detailed SQL-like format that shows expression structure 
(e.g. (`Utf8 ("foobar")`). This is often used for debugging and tests
+/// * [`Self::fmt_sql`]: SQL-like human readable format (e.g. ('foobar')`), 
See also [`sql_fmt`]
+///
 /// [`SessionContext::create_physical_expr`]: 
https://docs.rs/datafusion/latest/datafusion/execution/context/struct.SessionContext.html#method.create_physical_expr
 /// [`PhysicalPlanner`]: 
https://docs.rs/datafusion/latest/datafusion/physical_planner/trait.PhysicalPlanner.html
 /// [`Expr`]: 
https://docs.rs/datafusion/latest/datafusion/logical_expr/enum.Expr.html
@@ -266,6 +273,16 @@ pub trait PhysicalExpr: Send + Sync + Display + Debug + 
DynEq + DynHash {
     fn get_properties(&self, _children: &[ExprProperties]) -> 
Result<ExprProperties> {
         Ok(ExprProperties::new_unknown())
     }
+
+    /// Format this `PhysicalExpr` in nice human readable "SQL" format
+    ///
+    /// Specifically, this format is designed to be readable by humans, at the
+    /// expense of details. Use `Display` or `Debug` for more detailed
+    /// representation.
+    ///
+    /// See the [`fmt_sql`] function for an example of printing 
`PhysicalExpr`s as SQL.
+    ///
+    fn fmt_sql(&self, f: &mut Formatter<'_>) -> fmt::Result;
 }
 
 /// [`PhysicalExpr`] can't be constrained by [`Eq`] directly because it must 
remain object
@@ -363,7 +380,7 @@ where
         I: Iterator + Clone,
         I::Item: Display,
     {
-        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
             let mut iter = self.0.clone();
             write!(f, "[")?;
             if let Some(expr) = iter.next() {
@@ -379,3 +396,53 @@ where
 
     DisplayWrapper(exprs.into_iter())
 }
+
+/// Prints a [`PhysicalExpr`] in a SQL-like format
+///
+/// # Example
+/// ```
+/// # // The boiler plate needed to create a `PhysicalExpr` for the example
+/// # use std::any::Any;
+/// # use std::fmt::Formatter;
+/// # use std::sync::Arc;
+/// # use arrow::array::RecordBatch;
+/// # use arrow::datatypes::{DataType, Schema};
+/// # use datafusion_common::Result;
+/// # use datafusion_expr_common::columnar_value::ColumnarValue;
+/// # use datafusion_physical_expr_common::physical_expr::{fmt_sql, DynEq, 
PhysicalExpr};
+/// # #[derive(Debug, Hash, PartialOrd, PartialEq)]
+/// # struct MyExpr {};
+/// # impl PhysicalExpr for MyExpr {fn as_any(&self) -> &dyn Any { 
unimplemented!() }
+/// # fn data_type(&self, input_schema: &Schema) -> Result<DataType> { 
unimplemented!() }
+/// # fn nullable(&self, input_schema: &Schema) -> Result<bool> { 
unimplemented!() }
+/// # fn evaluate(&self, batch: &RecordBatch) -> Result<ColumnarValue> { 
unimplemented!() }
+/// # fn children(&self) -> Vec<&Arc<dyn PhysicalExpr>>{ unimplemented!() }
+/// # fn with_new_children(self: Arc<Self>, children: Vec<Arc<dyn 
PhysicalExpr>>) -> Result<Arc<dyn PhysicalExpr>> { unimplemented!() }
+/// # fn fmt_sql(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, 
"CASE a > b THEN 1 ELSE 0 END") }
+/// # }
+/// # impl std::fmt::Display for MyExpr {fn fmt(&self, f: &mut Formatter<'_>) 
-> std::fmt::Result { unimplemented!() } }
+/// # impl DynEq for MyExpr {fn dyn_eq(&self, other: &dyn Any) -> bool { 
unimplemented!() } }
+/// # fn make_physical_expr() -> Arc<dyn PhysicalExpr> { Arc::new(MyExpr{}) }
+/// let expr: Arc<dyn PhysicalExpr> = make_physical_expr();
+/// // wrap the expression in `sql_fmt` which can be used with
+/// // `format!`, `to_string()`, etc
+/// let expr_as_sql = fmt_sql(expr.as_ref());
+/// assert_eq!(
+///   "The SQL: CASE a > b THEN 1 ELSE 0 END",
+///   format!("The SQL: {expr_as_sql}")
+/// );
+/// ```
+pub fn fmt_sql(expr: &dyn PhysicalExpr) -> impl Display + '_ {
+    struct Wrapper<'a> {
+        expr: &'a dyn PhysicalExpr,
+    }
+
+    impl Display for Wrapper<'_> {
+        fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+            self.expr.fmt_sql(f)?;
+            Ok(())
+        }
+    }
+
+    Wrapper { expr }
+}
diff --git a/datafusion/physical-expr-common/src/sort_expr.rs 
b/datafusion/physical-expr-common/src/sort_expr.rs
index 38b820edc5..fe5c2ecfdf 100644
--- a/datafusion/physical-expr-common/src/sort_expr.rs
+++ b/datafusion/physical-expr-common/src/sort_expr.rs
@@ -37,7 +37,7 @@ use itertools::Itertools;
 /// Example:
 /// ```
 /// # use std::any::Any;
-/// # use std::fmt::Display;
+/// # use std::fmt::{Display, Formatter};
 /// # use std::hash::Hasher;
 /// # use std::sync::Arc;
 /// # use arrow::array::RecordBatch;
@@ -58,6 +58,7 @@ use itertools::Itertools;
 /// #  fn evaluate(&self, batch: &RecordBatch) -> Result<ColumnarValue> 
{todo!() }
 /// #  fn children(&self) -> Vec<&Arc<dyn PhysicalExpr>> {todo!()}
 /// #  fn with_new_children(self: Arc<Self>, children: Vec<Arc<dyn 
PhysicalExpr>>) -> Result<Arc<dyn PhysicalExpr>> {todo!()}
+/// # fn fmt_sql(&self, f: &mut Formatter<'_>) -> std::fmt::Result { todo!() }
 /// # }
 /// # impl Display for MyPhysicalExpr {
 /// #    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 
write!(f, "a") }
diff --git a/datafusion/physical-expr/src/expressions/binary.rs 
b/datafusion/physical-expr/src/expressions/binary.rs
index 1f16c5471e..872773b06f 100644
--- a/datafusion/physical-expr/src/expressions/binary.rs
+++ b/datafusion/physical-expr/src/expressions/binary.rs
@@ -571,6 +571,32 @@ impl PhysicalExpr for BinaryExpr {
             _ => Ok(ExprProperties::new_unknown()),
         }
     }
+
+    fn fmt_sql(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        fn write_child(
+            f: &mut std::fmt::Formatter,
+            expr: &dyn PhysicalExpr,
+            precedence: u8,
+        ) -> std::fmt::Result {
+            if let Some(child) = expr.as_any().downcast_ref::<BinaryExpr>() {
+                let p = child.op.precedence();
+                if p == 0 || p < precedence {
+                    write!(f, "(")?;
+                    child.fmt_sql(f)?;
+                    write!(f, ")")
+                } else {
+                    child.fmt_sql(f)
+                }
+            } else {
+                expr.fmt_sql(f)
+            }
+        }
+
+        let precedence = self.op.precedence();
+        write_child(f, self.left.as_ref(), precedence)?;
+        write!(f, " {} ", self.op)?;
+        write_child(f, self.right.as_ref(), precedence)
+    }
 }
 
 /// Casts dictionary array to result type for binary numerical operators. Such 
operators
@@ -770,6 +796,7 @@ mod tests {
     use crate::expressions::{col, lit, try_cast, Column, Literal};
 
     use datafusion_common::plan_datafusion_err;
+    use datafusion_physical_expr_common::physical_expr::fmt_sql;
 
     /// Performs a binary operation, applying any type coercion necessary
     fn binary_op(
@@ -4672,4 +4699,72 @@ mod tests {
 
         Ok(())
     }
+
+    #[test]
+    fn test_fmt_sql() -> Result<()> {
+        let schema = Schema::new(vec![
+            Field::new("a", DataType::Int32, false),
+            Field::new("b", DataType::Int32, false),
+        ]);
+
+        // Test basic binary expressions
+        let simple_expr = binary_expr(
+            col("a", &schema)?,
+            Operator::Plus,
+            col("b", &schema)?,
+            &schema,
+        )?;
+        let display_string = simple_expr.to_string();
+        assert_eq!(display_string, "a@0 + b@1");
+        let sql_string = fmt_sql(&simple_expr).to_string();
+        assert_eq!(sql_string, "a + b");
+
+        // Test nested expressions with different operator precedence
+        let nested_expr = binary_expr(
+            Arc::new(binary_expr(
+                col("a", &schema)?,
+                Operator::Plus,
+                col("b", &schema)?,
+                &schema,
+            )?),
+            Operator::Multiply,
+            col("b", &schema)?,
+            &schema,
+        )?;
+        let display_string = nested_expr.to_string();
+        assert_eq!(display_string, "(a@0 + b@1) * b@1");
+        let sql_string = fmt_sql(&nested_expr).to_string();
+        assert_eq!(sql_string, "(a + b) * b");
+
+        // Test nested expressions with same operator precedence
+        let nested_same_prec = binary_expr(
+            Arc::new(binary_expr(
+                col("a", &schema)?,
+                Operator::Plus,
+                col("b", &schema)?,
+                &schema,
+            )?),
+            Operator::Plus,
+            col("b", &schema)?,
+            &schema,
+        )?;
+        let display_string = nested_same_prec.to_string();
+        assert_eq!(display_string, "a@0 + b@1 + b@1");
+        let sql_string = fmt_sql(&nested_same_prec).to_string();
+        assert_eq!(sql_string, "a + b + b");
+
+        // Test with literals
+        let lit_expr = binary_expr(
+            col("a", &schema)?,
+            Operator::Eq,
+            lit(ScalarValue::Int32(Some(42))),
+            &schema,
+        )?;
+        let display_string = lit_expr.to_string();
+        assert_eq!(display_string, "a@0 = 42");
+        let sql_string = fmt_sql(&lit_expr).to_string();
+        assert_eq!(sql_string, "a = 42");
+
+        Ok(())
+    }
 }
diff --git a/datafusion/physical-expr/src/expressions/case.rs 
b/datafusion/physical-expr/src/expressions/case.rs
index 78606f05ae..67fab3912c 100644
--- a/datafusion/physical-expr/src/expressions/case.rs
+++ b/datafusion/physical-expr/src/expressions/case.rs
@@ -559,6 +559,29 @@ impl PhysicalExpr for CaseExpr {
             )?))
         }
     }
+
+    fn fmt_sql(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "CASE ")?;
+        if let Some(e) = &self.expr {
+            e.fmt_sql(f)?;
+            write!(f, " ")?;
+        }
+
+        for (w, t) in &self.when_then_expr {
+            write!(f, "WHEN ")?;
+            w.fmt_sql(f)?;
+            write!(f, " THEN ")?;
+            t.fmt_sql(f)?;
+            write!(f, " ")?;
+        }
+
+        if let Some(e) = &self.else_expr {
+            write!(f, "ELSE ")?;
+            e.fmt_sql(f)?;
+            write!(f, " ")?;
+        }
+        write!(f, "END")
+    }
 }
 
 /// Create a CASE expression
@@ -583,6 +606,7 @@ mod tests {
     use datafusion_common::tree_node::{Transformed, TransformedResult, 
TreeNode};
     use datafusion_expr::type_coercion::binary::comparison_coercion;
     use datafusion_expr::Operator;
+    use datafusion_physical_expr_common::physical_expr::fmt_sql;
 
     #[test]
     fn case_with_expr() -> Result<()> {
@@ -1378,4 +1402,35 @@ mod tests {
                 comparison_coercion(&left_type, right_type)
             })
     }
+
+    #[test]
+    fn test_fmt_sql() -> Result<()> {
+        let schema = Schema::new(vec![Field::new("a", DataType::Utf8, true)]);
+
+        // CASE WHEN a = 'foo' THEN 123.3 ELSE 999 END
+        let when = binary(col("a", &schema)?, Operator::Eq, lit("foo"), 
&schema)?;
+        let then = lit(123.3f64);
+        let else_value = lit(999i32);
+
+        let expr = generate_case_when_with_type_coercion(
+            None,
+            vec![(when, then)],
+            Some(else_value),
+            &schema,
+        )?;
+
+        let display_string = expr.to_string();
+        assert_eq!(
+            display_string,
+            "CASE WHEN a@0 = foo THEN 123.3 ELSE TRY_CAST(999 AS Float64) END"
+        );
+
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        assert_eq!(
+            sql_string,
+            "CASE WHEN a = foo THEN 123.3 ELSE TRY_CAST(999 AS Float64) END"
+        );
+
+        Ok(())
+    }
 }
diff --git a/datafusion/physical-expr/src/expressions/cast.rs 
b/datafusion/physical-expr/src/expressions/cast.rs
index 8a093e0ae9..a6766687a8 100644
--- a/datafusion/physical-expr/src/expressions/cast.rs
+++ b/datafusion/physical-expr/src/expressions/cast.rs
@@ -194,6 +194,14 @@ impl PhysicalExpr for CastExpr {
             Ok(ExprProperties::new_unknown().with_range(unbounded))
         }
     }
+
+    fn fmt_sql(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "CAST(")?;
+        self.expr.fmt_sql(f)?;
+        write!(f, " AS {:?}", self.cast_type)?;
+
+        write!(f, ")")
+    }
 }
 
 /// Return a PhysicalExpression representing `expr` casted to
@@ -243,6 +251,7 @@ mod tests {
         datatypes::*,
     };
     use datafusion_common::assert_contains;
+    use datafusion_physical_expr_common::physical_expr::fmt_sql;
 
     // runs an end-to-end test of physical type cast
     // 1. construct a record batch with a column "a" of type A
@@ -766,4 +775,26 @@ mod tests {
         expression.evaluate(&batch)?;
         Ok(())
     }
+
+    #[test]
+    fn test_fmt_sql() -> Result<()> {
+        let schema = Schema::new(vec![Field::new("a", Int32, true)]);
+
+        // Test numeric casting
+        let expr = cast(col("a", &schema)?, &schema, Int64)?;
+        let display_string = expr.to_string();
+        assert_eq!(display_string, "CAST(a@0 AS Int64)");
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        assert_eq!(sql_string, "CAST(a AS Int64)");
+
+        // Test string casting
+        let schema = Schema::new(vec![Field::new("b", Utf8, true)]);
+        let expr = cast(col("b", &schema)?, &schema, Int32)?;
+        let display_string = expr.to_string();
+        assert_eq!(display_string, "CAST(b@0 AS Int32)");
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        assert_eq!(sql_string, "CAST(b AS Int32)");
+
+        Ok(())
+    }
 }
diff --git a/datafusion/physical-expr/src/expressions/column.rs 
b/datafusion/physical-expr/src/expressions/column.rs
index 0ec985887c..ab5b359847 100644
--- a/datafusion/physical-expr/src/expressions/column.rs
+++ b/datafusion/physical-expr/src/expressions/column.rs
@@ -137,6 +137,10 @@ impl PhysicalExpr for Column {
     ) -> Result<Arc<dyn PhysicalExpr>> {
         Ok(self)
     }
+
+    fn fmt_sql(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.name)
+    }
 }
 
 impl Column {
diff --git a/datafusion/physical-expr/src/expressions/in_list.rs 
b/datafusion/physical-expr/src/expressions/in_list.rs
index dfe9a905df..469f7bbee3 100644
--- a/datafusion/physical-expr/src/expressions/in_list.rs
+++ b/datafusion/physical-expr/src/expressions/in_list.rs
@@ -398,6 +398,22 @@ impl PhysicalExpr for InListExpr {
             self.static_filter.clone(),
         )))
     }
+
+    fn fmt_sql(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.expr.fmt_sql(f)?;
+        if self.negated {
+            write!(f, " NOT")?;
+        }
+
+        write!(f, " IN (")?;
+        for (i, expr) in self.list.iter().enumerate() {
+            if i > 0 {
+                write!(f, ", ")?;
+            }
+            expr.fmt_sql(f)?;
+        }
+        write!(f, ")")
+    }
 }
 
 impl PartialEq for InListExpr {
@@ -453,6 +469,7 @@ mod tests {
     use crate::expressions::{col, lit, try_cast};
     use datafusion_common::plan_err;
     use datafusion_expr::type_coercion::binary::comparison_coercion;
+    use datafusion_physical_expr_common::physical_expr::fmt_sql;
 
     type InListCastResult = (Arc<dyn PhysicalExpr>, Vec<Arc<dyn 
PhysicalExpr>>);
 
@@ -1422,4 +1439,44 @@ mod tests {
 
         Ok(())
     }
+
+    #[test]
+    fn test_fmt_sql() -> Result<()> {
+        let schema = Schema::new(vec![Field::new("a", DataType::Utf8, true)]);
+        let col_a = col("a", &schema)?;
+
+        // Test: a IN ('a', 'b')
+        let list = vec![lit("a"), lit("b")];
+        let expr = in_list(Arc::clone(&col_a), list, &false, &schema)?;
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        let display_string = expr.to_string();
+        assert_eq!(sql_string, "a IN (a, b)");
+        assert_eq!(display_string, "Use a@0 IN (SET) ([Literal { value: 
Utf8(\"a\") }, Literal { value: Utf8(\"b\") }])");
+
+        // Test: a NOT IN ('a', 'b')
+        let list = vec![lit("a"), lit("b")];
+        let expr = in_list(Arc::clone(&col_a), list, &true, &schema)?;
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        let display_string = expr.to_string();
+        assert_eq!(sql_string, "a NOT IN (a, b)");
+        assert_eq!(display_string, "a@0 NOT IN (SET) ([Literal { value: 
Utf8(\"a\") }, Literal { value: Utf8(\"b\") }])");
+
+        // Test: a IN ('a', 'b', NULL)
+        let list = vec![lit("a"), lit("b"), lit(ScalarValue::Utf8(None))];
+        let expr = in_list(Arc::clone(&col_a), list, &false, &schema)?;
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        let display_string = expr.to_string();
+        assert_eq!(sql_string, "a IN (a, b, NULL)");
+        assert_eq!(display_string, "Use a@0 IN (SET) ([Literal { value: 
Utf8(\"a\") }, Literal { value: Utf8(\"b\") }, Literal { value: Utf8(NULL) 
}])");
+
+        // Test: a NOT IN ('a', 'b', NULL)
+        let list = vec![lit("a"), lit("b"), lit(ScalarValue::Utf8(None))];
+        let expr = in_list(Arc::clone(&col_a), list, &true, &schema)?;
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        let display_string = expr.to_string();
+        assert_eq!(sql_string, "a NOT IN (a, b, NULL)");
+        assert_eq!(display_string, "a@0 NOT IN (SET) ([Literal { value: 
Utf8(\"a\") }, Literal { value: Utf8(\"b\") }, Literal { value: Utf8(NULL) 
}])");
+
+        Ok(())
+    }
 }
diff --git a/datafusion/physical-expr/src/expressions/is_not_null.rs 
b/datafusion/physical-expr/src/expressions/is_not_null.rs
index 47dc53d125..0619e72488 100644
--- a/datafusion/physical-expr/src/expressions/is_not_null.rs
+++ b/datafusion/physical-expr/src/expressions/is_not_null.rs
@@ -104,6 +104,11 @@ impl PhysicalExpr for IsNotNullExpr {
     ) -> Result<Arc<dyn PhysicalExpr>> {
         Ok(Arc::new(IsNotNullExpr::new(Arc::clone(&children[0]))))
     }
+
+    fn fmt_sql(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.arg.fmt_sql(f)?;
+        write!(f, " IS NOT NULL")
+    }
 }
 
 /// Create an IS NOT NULL expression
@@ -121,6 +126,7 @@ mod tests {
     use arrow::buffer::ScalarBuffer;
     use arrow::datatypes::*;
     use datafusion_common::cast::as_boolean_array;
+    use datafusion_physical_expr_common::physical_expr::fmt_sql;
 
     #[test]
     fn is_not_null_op() -> Result<()> {
@@ -187,4 +193,29 @@ mod tests {
 
         assert_eq!(expected, actual);
     }
+
+    #[test]
+    fn test_fmt_sql() -> Result<()> {
+        let union_fields: UnionFields = [
+            (0, Arc::new(Field::new("A", DataType::Int32, true))),
+            (1, Arc::new(Field::new("B", DataType::Float64, true))),
+        ]
+        .into_iter()
+        .collect();
+
+        let field = Field::new(
+            "my_union",
+            DataType::Union(union_fields, UnionMode::Sparse),
+            true,
+        );
+
+        let schema = Schema::new(vec![field]);
+        let expr = is_not_null(col("my_union", &schema).unwrap()).unwrap();
+        let display_string = expr.to_string();
+        assert_eq!(display_string, "my_union@0 IS NOT NULL");
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        assert_eq!(sql_string, "my_union IS NOT NULL");
+
+        Ok(())
+    }
 }
diff --git a/datafusion/physical-expr/src/expressions/is_null.rs 
b/datafusion/physical-expr/src/expressions/is_null.rs
index 5e883dff99..4c6081f35c 100644
--- a/datafusion/physical-expr/src/expressions/is_null.rs
+++ b/datafusion/physical-expr/src/expressions/is_null.rs
@@ -103,6 +103,11 @@ impl PhysicalExpr for IsNullExpr {
     ) -> Result<Arc<dyn PhysicalExpr>> {
         Ok(Arc::new(IsNullExpr::new(Arc::clone(&children[0]))))
     }
+
+    fn fmt_sql(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.arg.fmt_sql(f)?;
+        write!(f, " IS NULL")
+    }
 }
 
 /// Create an IS NULL expression
@@ -120,6 +125,7 @@ mod tests {
     use arrow::buffer::ScalarBuffer;
     use arrow::datatypes::*;
     use datafusion_common::cast::as_boolean_array;
+    use datafusion_physical_expr_common::physical_expr::fmt_sql;
 
     #[test]
     fn is_null_op() -> Result<()> {
@@ -209,4 +215,18 @@ mod tests {
         let expected = &BooleanArray::from(vec![false, true, false, true, 
false, true]);
         assert_eq!(expected, &result);
     }
+
+    #[test]
+    fn test_fmt_sql() -> Result<()> {
+        let schema = Schema::new(vec![Field::new("a", DataType::Utf8, true)]);
+
+        // expression: "a is null"
+        let expr = is_null(col("a", &schema)?).unwrap();
+        let display_string = expr.to_string();
+        assert_eq!(display_string, "a@0 IS NULL");
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        assert_eq!(sql_string, "a IS NULL");
+
+        Ok(())
+    }
 }
diff --git a/datafusion/physical-expr/src/expressions/like.rs 
b/datafusion/physical-expr/src/expressions/like.rs
index b26927b77f..ebf9882665 100644
--- a/datafusion/physical-expr/src/expressions/like.rs
+++ b/datafusion/physical-expr/src/expressions/like.rs
@@ -145,6 +145,12 @@ impl PhysicalExpr for LikeExpr {
             Arc::clone(&children[1]),
         )))
     }
+
+    fn fmt_sql(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        self.expr.fmt_sql(f)?;
+        write!(f, " {} ", self.op_name())?;
+        self.pattern.fmt_sql(f)
+    }
 }
 
 /// used for optimize Dictionary like
@@ -185,6 +191,7 @@ mod test {
     use arrow::array::*;
     use arrow::datatypes::Field;
     use datafusion_common::cast::as_boolean_array;
+    use datafusion_physical_expr_common::physical_expr::fmt_sql;
 
     macro_rules! test_like {
         ($A_VEC:expr, $B_VEC:expr, $VEC:expr, $NULLABLE: expr, $NEGATED:expr, 
$CASE_INSENSITIVE:expr,) => {{
@@ -256,4 +263,30 @@ mod test {
 
         Ok(())
     }
+
+    #[test]
+    fn test_fmt_sql() -> Result<()> {
+        let schema = Schema::new(vec![
+            Field::new("a", DataType::Utf8, false),
+            Field::new("b", DataType::Utf8, false),
+        ]);
+
+        let expr = like(
+            false,
+            false,
+            col("a", &schema)?,
+            col("b", &schema)?,
+            &schema,
+        )?;
+
+        // Display format
+        let display_string = expr.to_string();
+        assert_eq!(display_string, "a@0 LIKE b@1");
+
+        // fmt_sql format
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        assert_eq!(sql_string, "a LIKE b");
+
+        Ok(())
+    }
 }
diff --git a/datafusion/physical-expr/src/expressions/literal.rs 
b/datafusion/physical-expr/src/expressions/literal.rs
index 232f9769b0..0d0c0ecc62 100644
--- a/datafusion/physical-expr/src/expressions/literal.rs
+++ b/datafusion/physical-expr/src/expressions/literal.rs
@@ -93,6 +93,10 @@ impl PhysicalExpr for Literal {
             preserves_lex_ordering: true,
         })
     }
+
+    fn fmt_sql(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self, f)
+    }
 }
 
 /// Create a literal expression
@@ -110,6 +114,7 @@ mod tests {
     use arrow::array::Int32Array;
     use arrow::datatypes::*;
     use datafusion_common::cast::as_int32_array;
+    use datafusion_physical_expr_common::physical_expr::fmt_sql;
 
     #[test]
     fn literal_i32() -> Result<()> {
@@ -136,4 +141,16 @@ mod tests {
 
         Ok(())
     }
+
+    #[test]
+    fn test_fmt_sql() -> Result<()> {
+        // create and evaluate a literal expression
+        let expr = lit(42i32);
+        let display_string = expr.to_string();
+        assert_eq!(display_string, "42");
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        assert_eq!(sql_string, "42");
+
+        Ok(())
+    }
 }
diff --git a/datafusion/physical-expr/src/expressions/negative.rs 
b/datafusion/physical-expr/src/expressions/negative.rs
index 8795545274..33a1bae14d 100644
--- a/datafusion/physical-expr/src/expressions/negative.rs
+++ b/datafusion/physical-expr/src/expressions/negative.rs
@@ -167,6 +167,12 @@ impl PhysicalExpr for NegativeExpr {
             preserves_lex_ordering: false,
         })
     }
+
+    fn fmt_sql(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "(- ")?;
+        self.arg.fmt_sql(f)?;
+        write!(f, ")")
+    }
 }
 
 /// Creates a unary expression NEGATIVE
@@ -202,6 +208,7 @@ mod tests {
     use datafusion_common::cast::as_primitive_array;
     use datafusion_common::{DataFusionError, ScalarValue};
 
+    use datafusion_physical_expr_common::physical_expr::fmt_sql;
     use paste::paste;
 
     macro_rules! test_array_negative_op {
@@ -379,4 +386,15 @@ mod tests {
         matches!(expr, DataFusionError::Plan(_));
         Ok(())
     }
+
+    #[test]
+    fn test_fmt_sql() -> Result<()> {
+        let expr = NegativeExpr::new(Arc::new(Column::new("a", 0)));
+        let display_string = expr.to_string();
+        assert_eq!(display_string, "(- a@0)");
+        let sql_string = fmt_sql(&expr).to_string();
+        assert_eq!(sql_string, "(- a)");
+
+        Ok(())
+    }
 }
diff --git a/datafusion/physical-expr/src/expressions/no_op.rs 
b/datafusion/physical-expr/src/expressions/no_op.rs
index c17b52f5cd..24d2f4d9e0 100644
--- a/datafusion/physical-expr/src/expressions/no_op.rs
+++ b/datafusion/physical-expr/src/expressions/no_op.rs
@@ -77,4 +77,8 @@ impl PhysicalExpr for NoOp {
     ) -> Result<Arc<dyn PhysicalExpr>> {
         Ok(self)
     }
+
+    fn fmt_sql(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self, f)
+    }
 }
diff --git a/datafusion/physical-expr/src/expressions/not.rs 
b/datafusion/physical-expr/src/expressions/not.rs
index ddf7c739b6..8a3348b43d 100644
--- a/datafusion/physical-expr/src/expressions/not.rs
+++ b/datafusion/physical-expr/src/expressions/not.rs
@@ -175,6 +175,11 @@ impl PhysicalExpr for NotExpr {
             _ => internal_err!("NotExpr can only operate on Boolean 
datatypes"),
         }
     }
+
+    fn fmt_sql(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "NOT ")?;
+        self.arg.fmt_sql(f)
+    }
 }
 
 /// Creates a unary expression NOT
@@ -190,6 +195,7 @@ mod tests {
     use crate::expressions::{col, Column};
 
     use arrow::{array::BooleanArray, datatypes::*};
+    use datafusion_physical_expr_common::physical_expr::fmt_sql;
 
     #[test]
     fn neg_op() -> Result<()> {
@@ -322,6 +328,21 @@ mod tests {
         Ok(())
     }
 
+    #[test]
+    fn test_fmt_sql() -> Result<()> {
+        let schema = schema();
+
+        let expr = not(col("a", &schema)?)?;
+
+        let display_string = expr.to_string();
+        assert_eq!(display_string, "NOT a@0");
+
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        assert_eq!(sql_string, "NOT a");
+
+        Ok(())
+    }
+
     fn schema() -> SchemaRef {
         static SCHEMA: LazyLock<SchemaRef> = LazyLock::new(|| {
             Arc::new(Schema::new(vec![Field::new("a", DataType::Boolean, 
true)]))
diff --git a/datafusion/physical-expr/src/expressions/try_cast.rs 
b/datafusion/physical-expr/src/expressions/try_cast.rs
index 06f4e92999..e49815cd8b 100644
--- a/datafusion/physical-expr/src/expressions/try_cast.rs
+++ b/datafusion/physical-expr/src/expressions/try_cast.rs
@@ -123,6 +123,12 @@ impl PhysicalExpr for TryCastExpr {
             self.cast_type.clone(),
         )))
     }
+
+    fn fmt_sql(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "TRY_CAST(")?;
+        self.expr.fmt_sql(f)?;
+        write!(f, " AS {:?})", self.cast_type)
+    }
 }
 
 /// Return a PhysicalExpression representing `expr` casted to
@@ -158,6 +164,7 @@ mod tests {
         },
         datatypes::*,
     };
+    use datafusion_physical_expr_common::physical_expr::fmt_sql;
 
     // runs an end-to-end test of physical type cast
     // 1. construct a record batch with a column "a" of type A
@@ -573,4 +580,26 @@ mod tests {
             .with_precision_and_scale(precision, scale)
             .unwrap()
     }
+
+    #[test]
+    fn test_fmt_sql() -> Result<()> {
+        let schema = Schema::new(vec![Field::new("a", DataType::Int32, true)]);
+
+        // Test numeric casting
+        let expr = try_cast(col("a", &schema)?, &schema, DataType::Int64)?;
+        let display_string = expr.to_string();
+        assert_eq!(display_string, "TRY_CAST(a@0 AS Int64)");
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        assert_eq!(sql_string, "TRY_CAST(a AS Int64)");
+
+        // Test string casting
+        let schema = Schema::new(vec![Field::new("b", DataType::Utf8, true)]);
+        let expr = try_cast(col("b", &schema)?, &schema, DataType::Int32)?;
+        let display_string = expr.to_string();
+        assert_eq!(display_string, "TRY_CAST(b@0 AS Int32)");
+        let sql_string = fmt_sql(expr.as_ref()).to_string();
+        assert_eq!(sql_string, "TRY_CAST(b AS Int32)");
+
+        Ok(())
+    }
 }
diff --git a/datafusion/physical-expr/src/expressions/unknown_column.rs 
b/datafusion/physical-expr/src/expressions/unknown_column.rs
index a63caf7e13..2face4eb6b 100644
--- a/datafusion/physical-expr/src/expressions/unknown_column.rs
+++ b/datafusion/physical-expr/src/expressions/unknown_column.rs
@@ -86,6 +86,10 @@ impl PhysicalExpr for UnKnownColumn {
     ) -> Result<Arc<dyn PhysicalExpr>> {
         Ok(self)
     }
+
+    fn fmt_sql(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self, f)
+    }
 }
 
 impl Hash for UnKnownColumn {
diff --git a/datafusion/physical-expr/src/scalar_function.rs 
b/datafusion/physical-expr/src/scalar_function.rs
index cf8cc6e00c..44bbcc4928 100644
--- a/datafusion/physical-expr/src/scalar_function.rs
+++ b/datafusion/physical-expr/src/scalar_function.rs
@@ -260,4 +260,15 @@ impl PhysicalExpr for ScalarFunctionExpr {
             preserves_lex_ordering,
         })
     }
+
+    fn fmt_sql(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        write!(f, "{}(", self.name)?;
+        for (i, expr) in self.args.iter().enumerate() {
+            if i > 0 {
+                write!(f, ", ")?;
+            }
+            expr.fmt_sql(f)?;
+        }
+        write!(f, ")")
+    }
 }
diff --git a/datafusion/physical-plan/src/projection.rs 
b/datafusion/physical-plan/src/projection.rs
index 3f901311a0..1d3e23ea90 100644
--- a/datafusion/physical-plan/src/projection.rs
+++ b/datafusion/physical-plan/src/projection.rs
@@ -48,6 +48,7 @@ use datafusion_physical_expr::equivalence::ProjectionMapping;
 use datafusion_physical_expr::utils::collect_columns;
 use datafusion_physical_expr::PhysicalExprRef;
 
+use datafusion_physical_expr_common::physical_expr::fmt_sql;
 use futures::stream::{Stream, StreamExt};
 use itertools::Itertools;
 use log::trace;
@@ -169,13 +170,14 @@ impl DisplayAs for ProjectionExec {
             }
             DisplayFormatType::TreeRender => {
                 for (i, (e, alias)) in self.expr().iter().enumerate() {
-                    let e = e.to_string();
-                    if &e == alias {
-                        writeln!(f, "expr{i}={e}")?;
+                    let expr_sql = fmt_sql(e.as_ref());
+                    if &e.to_string() == alias {
+                        writeln!(f, "expr{i}={expr_sql}")?;
                     } else {
-                        writeln!(f, "{alias}={e}")?;
+                        writeln!(f, "{alias}={expr_sql}")?;
                     }
                 }
+
                 Ok(())
             }
         }
diff --git a/datafusion/proto/tests/cases/roundtrip_physical_plan.rs 
b/datafusion/proto/tests/cases/roundtrip_physical_plan.rs
index 21622390c6..3361bec664 100644
--- a/datafusion/proto/tests/cases/roundtrip_physical_plan.rs
+++ b/datafusion/proto/tests/cases/roundtrip_physical_plan.rs
@@ -16,7 +16,7 @@
 // under the License.
 
 use std::any::Any;
-use std::fmt::Display;
+use std::fmt::{Display, Formatter};
 use std::ops::Deref;
 use std::sync::Arc;
 use std::vec;
@@ -860,6 +860,10 @@ fn roundtrip_parquet_exec_with_custom_predicate_expr() -> 
Result<()> {
         ) -> Result<Arc<dyn PhysicalExpr>> {
             todo!()
         }
+
+        fn fmt_sql(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+            std::fmt::Display::fmt(self, f)
+        }
     }
 
     #[derive(Debug)]
diff --git a/datafusion/sqllogictest/test_files/explain_tree.slt 
b/datafusion/sqllogictest/test_files/explain_tree.slt
index 8d7e0f30ab..4e416c52a4 100644
--- a/datafusion/sqllogictest/test_files/explain_tree.slt
+++ b/datafusion/sqllogictest/test_files/explain_tree.slt
@@ -752,7 +752,7 @@ physical_plan
 07)│    count(Int64(1)) ROWS   │
 08)│      BETWEEN UNBOUNDED    │
 09)│   PRECEDING AND UNBOUNDED │
-10)│         FOLLOWING@0       │
+10)│          FOLLOWING        │
 11)└─────────────┬─────────────┘
 12)┌─────────────┴─────────────┐
 13)│       WindowAggExec       │
@@ -785,9 +785,9 @@ physical_plan
 05)│ sum(t1.v1) ORDER BY [t1.v1│
 06)│    ASC NULLS LAST] ROWS   │
 07)│     BETWEEN 1 PRECEDING   │
-08)│      AND CURRENT ROW@1    │
+08)│       AND CURRENT ROW     │
 09)│                           │
-10)│          v1: v1@0         │
+10)│           v1: v1          │
 11)└─────────────┬─────────────┘
 12)┌─────────────┴─────────────┐
 13)│    BoundedWindowAggExec   │
@@ -808,7 +808,7 @@ physical_plan
 28)┌─────────────┴─────────────┐
 29)│       ProjectionExec      │
 30)│    --------------------   │
-31)│        v1: value@0        │
+31)│         v1: value         │
 32)└─────────────┬─────────────┘
 33)┌─────────────┴─────────────┐
 34)│       LazyMemoryExec      │
@@ -835,14 +835,14 @@ physical_plan
 07)│    count(Int64(1)) ROWS   │
 08)│      BETWEEN UNBOUNDED    │
 09)│   PRECEDING AND UNBOUNDED │
-10)│         FOLLOWING@0       │
+10)│          FOLLOWING        │
 11)│                           │
 12)│ row_number() ROWS BETWEEN │
 13)│   UNBOUNDED PRECEDING AND │
 14)│    UNBOUNDED FOLLOWING:   │
 15)│ row_number() ROWS BETWEEN │
 16)│   UNBOUNDED PRECEDING AND │
-17)│    UNBOUNDED FOLLOWING@1  │
+17)│     UNBOUNDED FOLLOWING   │
 18)└─────────────┬─────────────┘
 19)┌─────────────┴─────────────┐
 20)│       WindowAggExec       │
@@ -908,13 +908,13 @@ physical_plan
 02)│       ProjectionExec      │
 03)│    --------------------   │
 04)│        bigint_col:        │
-05)│        bigint_col@1       │
+05)│         bigint_col        │
 06)│                           │
-07)│     int_col: int_col@0    │
+07)│      int_col: int_col     │
 08)│                           │
 09)│          sum_col:         │
-10)│ CAST(int_col@0 AS Int64) +│
-11)│        bigint_col@1       │
+10)│  CAST(int_col AS Int64) + │
+11)│         bigint_col        │
 12)└─────────────┬─────────────┘
 13)┌─────────────┴─────────────┐
 14)│      RepartitionExec      │
@@ -951,7 +951,7 @@ physical_plan
 10)│    .int_col DESC NULLS    │
 11)│    FIRST] RANGE BETWEEN   │
 12)│   UNBOUNDED PRECEDING AND │
-13)│        CURRENT ROW@1      │
+13)│         CURRENT ROW       │
 14)│                           │
 15)│   row_number() ORDER BY   │
 16)│    [table1.int_col ASC    │
@@ -964,7 +964,7 @@ physical_plan
 23)│      NULLS LAST] RANGE    │
 24)│      BETWEEN UNBOUNDED    │
 25)│    PRECEDING AND CURRENT  │
-26)│            ROW@2          │
+26)│             ROW           │
 27)└─────────────┬─────────────┘
 28)┌─────────────┴─────────────┐
 29)│    BoundedWindowAggExec   │
@@ -1017,13 +1017,13 @@ physical_plan
 02)│       ProjectionExec      │
 03)│    --------------------   │
 04)│        bigint_col:        │
-05)│        bigint_col@1       │
+05)│         bigint_col        │
 06)│                           │
-07)│     int_col: int_col@0    │
+07)│      int_col: int_col     │
 08)│                           │
 09)│          sum_col:         │
-10)│ CAST(int_col@0 AS Int64) +│
-11)│        bigint_col@1       │
+10)│  CAST(int_col AS Int64) + │
+11)│         bigint_col        │
 12)└─────────────┬─────────────┘
 13)┌─────────────┴─────────────┐
 14)│      RepartitionExec      │
@@ -1051,13 +1051,13 @@ physical_plan
 02)│       ProjectionExec      │
 03)│    --------------------   │
 04)│        bigint_col:        │
-05)│        bigint_col@1       │
+05)│         bigint_col        │
 06)│                           │
-07)│     int_col: int_col@0    │
+07)│      int_col: int_col     │
 08)│                           │
 09)│          sum_col:         │
-10)│ CAST(int_col@0 AS Int64) +│
-11)│        bigint_col@1       │
+10)│  CAST(int_col AS Int64) + │
+11)│         bigint_col        │
 12)└─────────────┬─────────────┘
 13)┌─────────────┴─────────────┐
 14)│       DataSourceExec      │
@@ -1076,12 +1076,12 @@ physical_plan
 02)│       ProjectionExec      │
 03)│    --------------------   │
 04)│        bigint_col:        │
-05)│        bigint_col@0       │
+05)│         bigint_col        │
 06)│                           │
-07)│     int_col: int_col@1    │
+07)│      int_col: int_col     │
 08)│                           │
 09)│          sum_col:         │
-10)│  int_col@1 + bigint_col@0 │
+10)│    int_col + bigint_col   │
 11)└─────────────┬─────────────┘
 12)┌─────────────┴─────────────┐
 13)│      RepartitionExec      │
@@ -1109,13 +1109,13 @@ physical_plan
 02)│       ProjectionExec      │
 03)│    --------------------   │
 04)│        bigint_col:        │
-05)│        bigint_col@1       │
+05)│         bigint_col        │
 06)│                           │
-07)│     int_col: int_col@0    │
+07)│      int_col: int_col     │
 08)│                           │
 09)│          sum_col:         │
-10)│ CAST(int_col@0 AS Int64) +│
-11)│        bigint_col@1       │
+10)│  CAST(int_col AS Int64) + │
+11)│         bigint_col        │
 12)└─────────────┬─────────────┘
 13)┌─────────────┴─────────────┐
 14)│      RepartitionExec      │
@@ -1219,17 +1219,17 @@ physical_plan
 35)│    --------------------   ││    --------------------   │
 36)│ CAST(table1.string_col AS ││  output_partition_count:  │
 37)│         Utf8View):        ││             1             │
-38)│    CAST(string_col@1 AS   ││                           │
+38)│     CAST(string_col AS    ││                           │
 39)│          Utf8View)        ││    partitioning_scheme:   │
 40)│                           ││     RoundRobinBatch(4)    │
 41)│        bigint_col:        ││                           │
-42)│        bigint_col@2       ││                           │
+42)│         bigint_col        ││                           │
 43)│                           ││                           │
-44)│    date_col: date_col@3   ││                           │
-45)│     int_col: int_col@0    ││                           │
+44)│     date_col: date_col    ││                           │
+45)│      int_col: int_col     ││                           │
 46)│                           ││                           │
 47)│        string_col:        ││                           │
-48)│        string_col@1       ││                           │
+48)│         string_col        ││                           │
 49)└─────────────┬─────────────┘└─────────────┬─────────────┘
 50)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
 51)│      RepartitionExec      ││       DataSourceExec      │
@@ -1291,17 +1291,17 @@ physical_plan
 37)│    --------------------   ││    --------------------   │
 38)│ CAST(table1.string_col AS ││  output_partition_count:  │
 39)│         Utf8View):        ││             1             │
-40)│    CAST(string_col@1 AS   ││                           │
+40)│     CAST(string_col AS    ││                           │
 41)│          Utf8View)        ││    partitioning_scheme:   │
 42)│                           ││     RoundRobinBatch(4)    │
 43)│        bigint_col:        ││                           │
-44)│        bigint_col@2       ││                           │
+44)│         bigint_col        ││                           │
 45)│                           ││                           │
-46)│    date_col: date_col@3   ││                           │
-47)│     int_col: int_col@0    ││                           │
+46)│     date_col: date_col    ││                           │
+47)│      int_col: int_col     ││                           │
 48)│                           ││                           │
 49)│        string_col:        ││                           │
-50)│        string_col@1       ││                           │
+50)│         string_col        ││                           │
 51)└─────────────┬─────────────┘└─────────────┬─────────────┘
 52)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
 53)│      RepartitionExec      ││       DataSourceExec      │
@@ -1471,7 +1471,7 @@ physical_plan
 02)│       ProjectionExec      │
 03)│    --------------------   │
 04)│         count(*):         │
-05)│     count(Int64(1))@1     │
+05)│      count(Int64(1))      │
 06)└─────────────┬─────────────┘
 07)┌─────────────┴─────────────┐
 08)│       AggregateExec       │
@@ -1834,7 +1834,7 @@ physical_plan
 09)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
 10)│     PlaceholderRowExec    ││       ProjectionExec      │
 11)│                           ││    --------------------   │
-12)│                           ││        id: id@0 + 1       │
+12)│                           ││         id: id + 1        │
 13)└───────────────────────────┘└─────────────┬─────────────┘
 14)-----------------------------┌─────────────┴─────────────┐
 15)-----------------------------│    CoalesceBatchesExec    │
@@ -1944,7 +1944,7 @@ physical_plan
 02)│       ProjectionExec      │
 03)│    --------------------   │
 04)│         count(*):         │
-05)│     count(Int64(1))@0     │
+05)│      count(Int64(1))      │
 06)└─────────────┬─────────────┘
 07)┌─────────────┴─────────────┐
 08)│       AggregateExec       │


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


Reply via email to