You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by al...@apache.org on 2025/03/20 14:54:43 UTC
(datafusion) branch main updated: Simplify display format of `AggregateFunctionExpr`, add `Expr::sql_name` (#15253)
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 11838be5ef Simplify display format of `AggregateFunctionExpr`, add `Expr::sql_name` (#15253)
11838be5ef is described below
commit 11838be5efa8607f762504c198615c54575b0593
Author: irenjj <re...@gmail.com>
AuthorDate: Thu Mar 20 22:54:37 2025 +0800
Simplify display format of `AggregateFunctionExpr`, add `Expr::sql_name` (#15253)
* Simplify display format of `AggregateFunctionExpr`
* add more info for SqlDisplay
* simplify aggr expr
* add doc
* add table name
* fix issues
* Update datafusion/physical-expr/src/aggregate.rs
Co-authored-by: Andrew Lamb <an...@nerdnetworks.org>
* Update datafusion/physical-expr/src/aggregate.rs
Co-authored-by: Andrew Lamb <an...@nerdnetworks.org>
* Update datafusion/physical-plan/src/aggregates/mod.rs
Co-authored-by: Andrew Lamb <an...@nerdnetworks.org>
* Update datafusion/physical-plan/src/aggregates/mod.rs
Co-authored-by: Andrew Lamb <an...@nerdnetworks.org>
* fmt
* fix build
* improve docs
* Add documentation about sql_format
* Rename to `human_display`
---------
Co-authored-by: Andrew Lamb <an...@nerdnetworks.org>
---
datafusion/core/src/physical_planner.rs | 17 +-
datafusion/expr/src/expr.rs | 298 ++++++++++++++++++++-
datafusion/expr/src/udaf.rs | 48 +++-
datafusion/physical-expr/src/aggregate.rs | 18 ++
datafusion/physical-plan/src/aggregates/mod.rs | 37 ++-
.../sqllogictest/test_files/explain_tree.slt | 216 +++++++--------
6 files changed, 500 insertions(+), 134 deletions(-)
diff --git a/datafusion/core/src/physical_planner.rs b/datafusion/core/src/physical_planner.rs
index 135b32a0a8..bc3c1d0ac9 100644
--- a/datafusion/core/src/physical_planner.rs
+++ b/datafusion/core/src/physical_planner.rs
@@ -1588,6 +1588,7 @@ type AggregateExprWithOptionalArgs = (
pub fn create_aggregate_expr_with_name_and_maybe_filter(
e: &Expr,
name: Option<String>,
+ human_displan: String,
logical_input_schema: &DFSchema,
physical_input_schema: &Schema,
execution_props: &ExecutionProps,
@@ -1642,6 +1643,7 @@ pub fn create_aggregate_expr_with_name_and_maybe_filter(
.order_by(ordering_reqs)
.schema(Arc::new(physical_input_schema.to_owned()))
.alias(name)
+ .human_display(human_displan)
.with_ignore_nulls(ignore_nulls)
.with_distinct(*distinct)
.build()
@@ -1664,15 +1666,22 @@ pub fn create_aggregate_expr_and_maybe_filter(
execution_props: &ExecutionProps,
) -> Result<AggregateExprWithOptionalArgs> {
// unpack (nested) aliased logical expressions, e.g. "sum(col) as total"
- let (name, e) = match e {
- Expr::Alias(Alias { expr, name, .. }) => (Some(name.clone()), expr.as_ref()),
- Expr::AggregateFunction(_) => (Some(e.schema_name().to_string()), e),
- _ => (None, e),
+ let (name, human_display, e) = match e {
+ Expr::Alias(Alias { expr, name, .. }) => {
+ (Some(name.clone()), String::default(), expr.as_ref())
+ }
+ Expr::AggregateFunction(_) => (
+ Some(e.schema_name().to_string()),
+ e.human_display().to_string(),
+ e,
+ ),
+ _ => (None, String::default(), e),
};
create_aggregate_expr_with_name_and_maybe_filter(
e,
name,
+ human_display,
logical_input_schema,
physical_input_schema,
execution_props,
diff --git a/datafusion/expr/src/expr.rs b/datafusion/expr/src/expr.rs
index 6f110895a4..9f6855b698 100644
--- a/datafusion/expr/src/expr.rs
+++ b/datafusion/expr/src/expr.rs
@@ -64,6 +64,15 @@ use sqlparser::ast::{
///
/// [`ExprFunctionExt`]: crate::expr_fn::ExprFunctionExt
///
+/// # Printing Expressions
+///
+/// You can print `Expr`s using the the `Debug` trait, `Display` trait, or
+/// [`Self::human_display`]. See the [examples](#examples-displaying-exprs) below.
+///
+/// If you need SQL to pass to other systems, consider using [`Unparser`].
+///
+/// [`Unparser`]: https://docs.rs/datafusion/latest/datafusion/sql/unparser/struct.Unparser.html
+///
/// # Schema Access
///
/// See [`ExprSchemable::get_type`] to access the [`DataType`] and nullability
@@ -76,9 +85,9 @@ use sqlparser::ast::{
/// `Expr` and [`TreeNode::transform`] can be used to rewrite an expression. See
/// the examples below and [`TreeNode`] for more information.
///
-/// # Examples
+/// # Examples: Creating and Using `Expr`s
///
-/// ## Column references and literals
+/// ## Column References and Literals
///
/// [`Expr::Column`] refer to the values of columns and are often created with
/// the [`col`] function. For example to create an expression `c1` referring to
@@ -104,6 +113,7 @@ use sqlparser::ast::{
/// // All literals are strongly typed in DataFusion. To make an `i64` 42:
/// let expr = lit(42i64);
/// assert_eq!(expr, Expr::Literal(ScalarValue::Int64(Some(42))));
+/// assert_eq!(expr, Expr::Literal(ScalarValue::Int64(Some(42))));
/// // To make a (typed) NULL:
/// let expr = Expr::Literal(ScalarValue::Int64(None));
/// // to make an (untyped) NULL (the optimizer will coerce this to the correct type):
@@ -171,7 +181,51 @@ use sqlparser::ast::{
/// ]);
/// ```
///
-/// # Visiting and Rewriting `Expr`s
+/// # Examples: Displaying `Exprs`
+///
+/// There are three ways to print an `Expr` depending on the usecase.
+///
+/// ## Use `Debug` trait
+///
+/// Following Rust conventions, the `Debug` implementation prints out the
+/// internal structure of the expression, which is useful for debugging.
+///
+/// ```
+/// # use datafusion_expr::{lit, col};
+/// let expr = col("c1") + lit(42);
+/// assert_eq!(format!("{expr:?}"), "BinaryExpr(BinaryExpr { left: Column(Column { relation: None, name: \"c1\" }), op: Plus, right: Literal(Int32(42)) })");
+/// ```
+///
+/// ## Use the `Display` trait (detailed expression)
+///
+/// The `Display` implementation prints out the expression in a SQL-like form,
+/// but has additional details such as the data type of literals. This is useful
+/// for understanding the expression in more detail and is used for the low level
+/// [`ExplainFormat::Indent`] explain plan format.
+///
+/// [`ExplainFormat::Indent`]: crate::logical_plan::ExplainFormat::Indent
+///
+/// ```
+/// # use datafusion_expr::{lit, col};
+/// let expr = col("c1") + lit(42);
+/// assert_eq!(format!("{expr}"), "c1 + Int32(42)");
+/// ```
+///
+/// ## Use [`Self::human_display`] (human readable)
+///
+/// [`Self::human_display`] prints out the expression in a SQL-like form, optimized
+/// for human consumption by end users. It is used for the
+/// [`ExplainFormat::Tree`] explain plan format.
+///
+/// [`ExplainFormat::Tree`]: crate::logical_plan::ExplainFormat::Tree
+///
+///```
+/// # use datafusion_expr::{lit, col};
+/// let expr = col("c1") + lit(42);
+/// assert_eq!(format!("{}", expr.human_display()), "c1 + 42");
+/// ```
+///
+/// # Examples: Visiting and Rewriting `Expr`s
///
/// Here is an example that finds all literals in an `Expr` tree:
/// ```
@@ -1147,6 +1201,31 @@ impl Expr {
SchemaDisplay(self)
}
+ /// Human readable display formatting for this expression.
+ ///
+ /// This function is primarily used in printing the explain tree output,
+ /// (e.g. `EXPLAIN FORMAT TREE <query>`), providing a readable format to
+ /// show how expressions are used in physical and logical plans. See the
+ /// [`Expr`] for other ways to format expressions
+ ///
+ /// Note this format is intended for human consumption rather than SQL for
+ /// other systems. If you need SQL to pass to other systems, consider using
+ /// [`Unparser`].
+ ///
+ /// [`Unparser`]: https://docs.rs/datafusion/latest/datafusion/sql/unparser/struct.Unparser.html
+ ///
+ /// # Example
+ /// ```
+ /// # use datafusion_expr::{col, lit};
+ /// let expr = col("foo") + lit(42);
+ /// // For EXPLAIN output:
+ /// // "foo + 42"
+ /// println!("{}", expr.human_display());
+ /// ```
+ pub fn human_display(&self) -> impl Display + '_ {
+ SqlDisplay(self)
+ }
+
/// Returns the qualifier and the schema name of this expression.
///
/// Used when the expression forms the output field of a certain plan.
@@ -2596,6 +2675,187 @@ impl Display for SchemaDisplay<'_> {
}
}
+/// A helper struct for displaying an `Expr` as an SQL-like string.
+struct SqlDisplay<'a>(&'a Expr);
+
+impl Display for SqlDisplay<'_> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+ match self.0 {
+ Expr::Literal(scalar) => scalar.fmt(f),
+ Expr::Alias(Alias { name, .. }) => write!(f, "{name}"),
+ Expr::Between(Between {
+ expr,
+ negated,
+ low,
+ high,
+ }) => {
+ if *negated {
+ write!(
+ f,
+ "{} NOT BETWEEN {} AND {}",
+ SqlDisplay(expr),
+ SqlDisplay(low),
+ SqlDisplay(high),
+ )
+ } else {
+ write!(
+ f,
+ "{} BETWEEN {} AND {}",
+ SqlDisplay(expr),
+ SqlDisplay(low),
+ SqlDisplay(high),
+ )
+ }
+ }
+ Expr::BinaryExpr(BinaryExpr { left, op, right }) => {
+ write!(f, "{} {op} {}", SqlDisplay(left), SqlDisplay(right),)
+ }
+ Expr::Case(Case {
+ expr,
+ when_then_expr,
+ else_expr,
+ }) => {
+ write!(f, "CASE ")?;
+
+ if let Some(e) = expr {
+ write!(f, "{} ", SqlDisplay(e))?;
+ }
+
+ for (when, then) in when_then_expr {
+ write!(f, "WHEN {} THEN {} ", SqlDisplay(when), SqlDisplay(then),)?;
+ }
+
+ if let Some(e) = else_expr {
+ write!(f, "ELSE {} ", SqlDisplay(e))?;
+ }
+
+ write!(f, "END")
+ }
+ Expr::Cast(Cast { expr, .. }) | Expr::TryCast(TryCast { expr, .. }) => {
+ write!(f, "{}", SqlDisplay(expr))
+ }
+ Expr::InList(InList {
+ expr,
+ list,
+ negated,
+ }) => {
+ write!(
+ f,
+ "{}{} IN {}",
+ SqlDisplay(expr),
+ if *negated { " NOT" } else { "" },
+ ExprListDisplay::comma_separated(list.as_slice())
+ )
+ }
+ Expr::GroupingSet(GroupingSet::Cube(exprs)) => {
+ write!(
+ f,
+ "ROLLUP ({})",
+ ExprListDisplay::comma_separated(exprs.as_slice())
+ )
+ }
+ Expr::GroupingSet(GroupingSet::GroupingSets(lists_of_exprs)) => {
+ write!(f, "GROUPING SETS (")?;
+ for exprs in lists_of_exprs.iter() {
+ write!(
+ f,
+ "({})",
+ ExprListDisplay::comma_separated(exprs.as_slice())
+ )?;
+ }
+ write!(f, ")")
+ }
+ Expr::GroupingSet(GroupingSet::Rollup(exprs)) => {
+ write!(
+ f,
+ "ROLLUP ({})",
+ ExprListDisplay::comma_separated(exprs.as_slice())
+ )
+ }
+ Expr::IsNull(expr) => write!(f, "{} IS NULL", SqlDisplay(expr)),
+ Expr::IsNotNull(expr) => {
+ write!(f, "{} IS NOT NULL", SqlDisplay(expr))
+ }
+ Expr::IsUnknown(expr) => {
+ write!(f, "{} IS UNKNOWN", SqlDisplay(expr))
+ }
+ Expr::IsNotUnknown(expr) => {
+ write!(f, "{} IS NOT UNKNOWN", SqlDisplay(expr))
+ }
+ Expr::IsTrue(expr) => write!(f, "{} IS TRUE", SqlDisplay(expr)),
+ Expr::IsFalse(expr) => write!(f, "{} IS FALSE", SqlDisplay(expr)),
+ Expr::IsNotTrue(expr) => {
+ write!(f, "{} IS NOT TRUE", SqlDisplay(expr))
+ }
+ Expr::IsNotFalse(expr) => {
+ write!(f, "{} IS NOT FALSE", SqlDisplay(expr))
+ }
+ Expr::Like(Like {
+ negated,
+ expr,
+ pattern,
+ escape_char,
+ case_insensitive,
+ }) => {
+ write!(
+ f,
+ "{} {}{} {}",
+ SqlDisplay(expr),
+ if *negated { "NOT " } else { "" },
+ if *case_insensitive { "ILIKE" } else { "LIKE" },
+ SqlDisplay(pattern),
+ )?;
+
+ if let Some(char) = escape_char {
+ write!(f, " CHAR '{char}'")?;
+ }
+
+ Ok(())
+ }
+ Expr::Negative(expr) => write!(f, "(- {})", SqlDisplay(expr)),
+ Expr::Not(expr) => write!(f, "NOT {}", SqlDisplay(expr)),
+ Expr::Unnest(Unnest { expr }) => {
+ write!(f, "UNNEST({})", SqlDisplay(expr))
+ }
+ Expr::SimilarTo(Like {
+ negated,
+ expr,
+ pattern,
+ escape_char,
+ ..
+ }) => {
+ write!(
+ f,
+ "{} {} {}",
+ SqlDisplay(expr),
+ if *negated {
+ "NOT SIMILAR TO"
+ } else {
+ "SIMILAR TO"
+ },
+ SqlDisplay(pattern),
+ )?;
+ if let Some(char) = escape_char {
+ write!(f, " CHAR '{char}'")?;
+ }
+
+ Ok(())
+ }
+ Expr::AggregateFunction(AggregateFunction { func, params }) => {
+ match func.human_display(params) {
+ Ok(name) => {
+ write!(f, "{name}")
+ }
+ Err(e) => {
+ write!(f, "got error from schema_name {}", e)
+ }
+ }
+ }
+ _ => write!(f, "{}", self.0),
+ }
+ }
+}
+
/// Get schema_name for Vector of expressions
///
/// Internal usage. Please call `schema_name_from_exprs` instead
@@ -2607,6 +2867,38 @@ pub(crate) fn schema_name_from_exprs_comma_separated_without_space(
schema_name_from_exprs_inner(exprs, ",")
}
+/// Formats a list of `&Expr` with a custom separator using SQL display format
+pub struct ExprListDisplay<'a> {
+ exprs: &'a [Expr],
+ sep: &'a str,
+}
+
+impl<'a> ExprListDisplay<'a> {
+ /// Create a new display struct with the given expressions and separator
+ pub fn new(exprs: &'a [Expr], sep: &'a str) -> Self {
+ Self { exprs, sep }
+ }
+
+ /// Create a new display struct with comma-space separator
+ pub fn comma_separated(exprs: &'a [Expr]) -> Self {
+ Self::new(exprs, ", ")
+ }
+}
+
+impl Display for ExprListDisplay<'_> {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ let mut first = true;
+ for expr in self.exprs {
+ if !first {
+ write!(f, "{}", self.sep)?;
+ }
+ write!(f, "{}", SqlDisplay(expr))?;
+ first = false;
+ }
+ Ok(())
+ }
+}
+
/// Get schema_name for Vector of expressions
pub fn schema_name_from_exprs(exprs: &[Expr]) -> Result<String, fmt::Error> {
schema_name_from_exprs_inner(exprs, ", ")
diff --git a/datafusion/expr/src/udaf.rs b/datafusion/expr/src/udaf.rs
index f9039cea2e..b75e8fd3cd 100644
--- a/datafusion/expr/src/udaf.rs
+++ b/datafusion/expr/src/udaf.rs
@@ -31,7 +31,7 @@ use datafusion_physical_expr_common::physical_expr::PhysicalExpr;
use crate::expr::{
schema_name_from_exprs, schema_name_from_exprs_comma_separated_without_space,
- schema_name_from_sorts, AggregateFunction, AggregateFunctionParams,
+ schema_name_from_sorts, AggregateFunction, AggregateFunctionParams, ExprListDisplay,
WindowFunctionParams,
};
use crate::function::{
@@ -175,6 +175,13 @@ impl AggregateUDF {
self.inner.schema_name(params)
}
+ /// Returns a human readable expression.
+ ///
+ /// See [`Expr::human_display`] for details.
+ pub fn human_display(&self, params: &AggregateFunctionParams) -> Result<String> {
+ self.inner.human_display(params)
+ }
+
pub fn window_function_schema_name(
&self,
params: &WindowFunctionParams,
@@ -452,6 +459,45 @@ pub trait AggregateUDFImpl: Debug + Send + Sync {
Ok(schema_name)
}
+ /// Returns a human readable expression.
+ ///
+ /// See [`Expr::human_display`] for details.
+ fn human_display(&self, params: &AggregateFunctionParams) -> Result<String> {
+ let AggregateFunctionParams {
+ args,
+ distinct,
+ filter,
+ order_by,
+ null_treatment,
+ } = params;
+
+ let mut schema_name = String::new();
+
+ schema_name.write_fmt(format_args!(
+ "{}({}{})",
+ self.name(),
+ if *distinct { "DISTINCT " } else { "" },
+ ExprListDisplay::comma_separated(args.as_slice())
+ ))?;
+
+ if let Some(null_treatment) = null_treatment {
+ schema_name.write_fmt(format_args!(" {}", null_treatment))?;
+ }
+
+ if let Some(filter) = filter {
+ schema_name.write_fmt(format_args!(" FILTER (WHERE {filter})"))?;
+ };
+
+ if let Some(order_by) = order_by {
+ schema_name.write_fmt(format_args!(
+ " ORDER BY [{}]",
+ schema_name_from_sorts(order_by)?
+ ))?;
+ };
+
+ Ok(schema_name)
+ }
+
/// Returns the name of the column this expression would create
///
/// See [`Expr::schema_name`] for details
diff --git a/datafusion/physical-expr/src/aggregate.rs b/datafusion/physical-expr/src/aggregate.rs
index 34c4e52d51..ae3d9050fa 100644
--- a/datafusion/physical-expr/src/aggregate.rs
+++ b/datafusion/physical-expr/src/aggregate.rs
@@ -65,6 +65,8 @@ pub struct AggregateExprBuilder {
/// Physical expressions of the aggregate function
args: Vec<Arc<dyn PhysicalExpr>>,
alias: Option<String>,
+ /// A human readable name
+ human_display: String,
/// Arrow Schema for the aggregate function
schema: SchemaRef,
/// The physical order by expressions
@@ -83,6 +85,7 @@ impl AggregateExprBuilder {
fun,
args,
alias: None,
+ human_display: String::default(),
schema: Arc::new(Schema::empty()),
ordering_req: LexOrdering::default(),
ignore_nulls: false,
@@ -99,6 +102,7 @@ impl AggregateExprBuilder {
fun,
args,
alias,
+ human_display,
schema,
ordering_req,
ignore_nulls,
@@ -148,6 +152,7 @@ impl AggregateExprBuilder {
args,
data_type,
name,
+ human_display,
schema: Arc::unwrap_or_clone(schema),
ordering_req,
ignore_nulls,
@@ -164,6 +169,11 @@ impl AggregateExprBuilder {
self
}
+ pub fn human_display(mut self, name: String) -> Self {
+ self.human_display = name;
+ self
+ }
+
pub fn schema(mut self, schema: SchemaRef) -> Self {
self.schema = schema;
self
@@ -214,7 +224,10 @@ pub struct AggregateFunctionExpr {
args: Vec<Arc<dyn PhysicalExpr>>,
/// Output / return type of this aggregate
data_type: DataType,
+ /// Output column name that this expression creates
name: String,
+ /// Simplified name for `tree` explain.
+ human_display: String,
schema: Schema,
// The physical order by expressions
ordering_req: LexOrdering,
@@ -245,6 +258,11 @@ impl AggregateFunctionExpr {
&self.name
}
+ /// Simplified name for `tree` explain.
+ pub fn human_display(&self) -> &str {
+ &self.human_display
+ }
+
/// Return if the aggregation is distinct
pub fn is_distinct(&self) -> bool {
self.is_distinct
diff --git a/datafusion/physical-plan/src/aggregates/mod.rs b/datafusion/physical-plan/src/aggregates/mod.rs
index 4230eeeed0..84ba0fe3b6 100644
--- a/datafusion/physical-plan/src/aggregates/mod.rs
+++ b/datafusion/physical-plan/src/aggregates/mod.rs
@@ -48,6 +48,7 @@ use datafusion_physical_expr::{
PhysicalSortRequirement,
};
+use datafusion_physical_expr_common::physical_expr::fmt_sql;
use itertools::Itertools;
pub(crate) mod group_values;
@@ -742,17 +743,18 @@ impl DisplayAs for AggregateExec {
t: DisplayFormatType,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
- let format_expr_with_alias =
- |(e, alias): &(Arc<dyn PhysicalExpr>, String)| -> String {
- let e = e.to_string();
- if &e != alias {
- format!("{e} as {alias}")
- } else {
- e
- }
- };
match t {
DisplayFormatType::Default | DisplayFormatType::Verbose => {
+ let format_expr_with_alias =
+ |(e, alias): &(Arc<dyn PhysicalExpr>, String)| -> String {
+ let e = e.to_string();
+ if &e != alias {
+ format!("{e} as {alias}")
+ } else {
+ e
+ }
+ };
+
write!(f, "AggregateExec: mode={:?}", self.mode)?;
let g: Vec<String> = if self.group_by.is_single() {
self.group_by
@@ -801,6 +803,16 @@ impl DisplayAs for AggregateExec {
}
}
DisplayFormatType::TreeRender => {
+ let format_expr_with_alias =
+ |(e, alias): &(Arc<dyn PhysicalExpr>, String)| -> String {
+ let expr_sql = fmt_sql(e.as_ref()).to_string();
+ if &expr_sql != alias {
+ format!("{expr_sql} as {alias}")
+ } else {
+ expr_sql
+ }
+ };
+
let g: Vec<String> = if self.group_by.is_single() {
self.group_by
.expr
@@ -830,17 +842,18 @@ impl DisplayAs for AggregateExec {
})
.collect()
};
- // TODO: Implement `fmt_sql` for `AggregateFunctionExpr`.
let a: Vec<String> = self
.aggr_expr
.iter()
- .map(|agg| agg.name().to_string())
+ .map(|agg| agg.human_display().to_string())
.collect();
writeln!(f, "mode={:?}", self.mode)?;
if !g.is_empty() {
writeln!(f, "group_by={}", g.join(", "))?;
}
- writeln!(f, "aggr={}", a.join(", "))?;
+ if !a.is_empty() {
+ writeln!(f, "aggr={}", a.join(", "))?;
+ }
}
}
Ok(())
diff --git a/datafusion/sqllogictest/test_files/explain_tree.slt b/datafusion/sqllogictest/test_files/explain_tree.slt
index 22b1b46019..aaea05be76 100644
--- a/datafusion/sqllogictest/test_files/explain_tree.slt
+++ b/datafusion/sqllogictest/test_files/explain_tree.slt
@@ -204,53 +204,50 @@ physical_plan
04)│ aggr: │
05)│ sum(table1.bigint_col) │
06)│ │
-07)│ group_by: │
-08)│ string_col@0 as string_col│
-09)│ │
-10)│ mode: │
-11)│ FinalPartitioned │
-12)└─────────────┬─────────────┘
-13)┌─────────────┴─────────────┐
-14)│ CoalesceBatchesExec │
-15)│ -------------------- │
-16)│ target_batch_size: │
-17)│ 8192 │
-18)└─────────────┬─────────────┘
-19)┌─────────────┴─────────────┐
-20)│ RepartitionExec │
-21)│ -------------------- │
-22)│ output_partition_count: │
-23)│ 4 │
-24)│ │
-25)│ partitioning_scheme: │
-26)│ Hash([string_col@0], 4) │
-27)└─────────────┬─────────────┘
-28)┌─────────────┴─────────────┐
-29)│ AggregateExec │
-30)│ -------------------- │
-31)│ aggr: │
-32)│ sum(table1.bigint_col) │
-33)│ │
-34)│ group_by: │
-35)│ string_col@0 as string_col│
-36)│ │
-37)│ mode: Partial │
-38)└─────────────┬─────────────┘
-39)┌─────────────┴─────────────┐
-40)│ RepartitionExec │
-41)│ -------------------- │
-42)│ output_partition_count: │
-43)│ 1 │
-44)│ │
-45)│ partitioning_scheme: │
-46)│ RoundRobinBatch(4) │
-47)└─────────────┬─────────────┘
-48)┌─────────────┴─────────────┐
-49)│ DataSourceExec │
-50)│ -------------------- │
-51)│ files: 1 │
-52)│ format: csv │
-53)└───────────────────────────┘
+07)│ group_by: string_col │
+08)│ │
+09)│ mode: │
+10)│ FinalPartitioned │
+11)└─────────────┬─────────────┘
+12)┌─────────────┴─────────────┐
+13)│ CoalesceBatchesExec │
+14)│ -------------------- │
+15)│ target_batch_size: │
+16)│ 8192 │
+17)└─────────────┬─────────────┘
+18)┌─────────────┴─────────────┐
+19)│ RepartitionExec │
+20)│ -------------------- │
+21)│ output_partition_count: │
+22)│ 4 │
+23)│ │
+24)│ partitioning_scheme: │
+25)│ Hash([string_col@0], 4) │
+26)└─────────────┬─────────────┘
+27)┌─────────────┴─────────────┐
+28)│ AggregateExec │
+29)│ -------------------- │
+30)│ aggr: │
+31)│ sum(table1.bigint_col) │
+32)│ │
+33)│ group_by: string_col │
+34)│ mode: Partial │
+35)└─────────────┬─────────────┘
+36)┌─────────────┴─────────────┐
+37)│ RepartitionExec │
+38)│ -------------------- │
+39)│ output_partition_count: │
+40)│ 1 │
+41)│ │
+42)│ partitioning_scheme: │
+43)│ RoundRobinBatch(4) │
+44)└─────────────┬─────────────┘
+45)┌─────────────┴─────────────┐
+46)│ DataSourceExec │
+47)│ -------------------- │
+48)│ files: 1 │
+49)│ format: csv │
+50)└───────────────────────────┘
# Limit
@@ -1339,7 +1336,7 @@ physical_plan
12)-----------------------------┌─────────────┴─────────────┐
13)-----------------------------│ AggregateExec │
14)-----------------------------│ -------------------- │
-15)-----------------------------│ aggr: count(Int64(1)) │
+15)-----------------------------│ aggr: count(1) │
16)-----------------------------│ mode: Final │
17)-----------------------------└─────────────┬─────────────┘
18)-----------------------------┌─────────────┴─────────────┐
@@ -1348,7 +1345,7 @@ physical_plan
21)-----------------------------┌─────────────┴─────────────┐
22)-----------------------------│ AggregateExec │
23)-----------------------------│ -------------------- │
-24)-----------------------------│ aggr: count(Int64(1)) │
+24)-----------------------------│ aggr: count(1) │
25)-----------------------------│ mode: Partial │
26)-----------------------------└─────────────┬─────────────┘
27)-----------------------------┌─────────────┴─────────────┐
@@ -1477,69 +1474,60 @@ physical_plan
07)┌─────────────┴─────────────┐
08)│ AggregateExec │
09)│ -------------------- │
-10)│ aggr: count(Int64(1)) │
-11)│ │
-12)│ group_by: │
-13)│ name@0 as name │
-14)│ │
-15)│ mode: │
-16)│ SinglePartitioned │
-17)└─────────────┬─────────────┘
-18)┌─────────────┴─────────────┐
-19)│ InterleaveExec ├──────────────┐
-20)└─────────────┬─────────────┘ │
-21)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
-22)│ AggregateExec ││ AggregateExec │
-23)│ -------------------- ││ -------------------- │
-24)│ aggr ││ aggr │
-25)│ ││ │
-26)│ group_by: ││ group_by: │
-27)│ name@0 as name ││ name@0 as name │
-28)│ ││ │
-29)│ mode: ││ mode: │
-30)│ FinalPartitioned ││ FinalPartitioned │
-31)└─────────────┬─────────────┘└─────────────┬─────────────┘
-32)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
-33)│ CoalesceBatchesExec ││ CoalesceBatchesExec │
-34)│ -------------------- ││ -------------------- │
-35)│ target_batch_size: ││ target_batch_size: │
-36)│ 8192 ││ 8192 │
-37)└─────────────┬─────────────┘└─────────────┬─────────────┘
-38)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
-39)│ RepartitionExec ││ RepartitionExec │
-40)│ -------------------- ││ -------------------- │
-41)│ output_partition_count: ││ output_partition_count: │
-42)│ 4 ││ 4 │
-43)│ ││ │
-44)│ partitioning_scheme: ││ partitioning_scheme: │
-45)│ Hash([name@0], 4) ││ Hash([name@0], 4) │
-46)└─────────────┬─────────────┘└─────────────┬─────────────┘
-47)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
-48)│ RepartitionExec ││ RepartitionExec │
-49)│ -------------------- ││ -------------------- │
-50)│ output_partition_count: ││ output_partition_count: │
-51)│ 1 ││ 1 │
-52)│ ││ │
-53)│ partitioning_scheme: ││ partitioning_scheme: │
-54)│ RoundRobinBatch(4) ││ RoundRobinBatch(4) │
-55)└─────────────┬─────────────┘└─────────────┬─────────────┘
-56)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
-57)│ AggregateExec ││ AggregateExec │
-58)│ -------------------- ││ -------------------- │
-59)│ aggr ││ aggr │
-60)│ ││ │
-61)│ group_by: ││ group_by: │
-62)│ name@0 as name ││ name@0 as name │
-63)│ ││ │
-64)│ mode: Partial ││ mode: Partial │
-65)└─────────────┬─────────────┘└─────────────┬─────────────┘
-66)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
-67)│ DataSourceExec ││ DataSourceExec │
-68)│ -------------------- ││ -------------------- │
-69)│ bytes: 1320 ││ bytes: 1312 │
-70)│ format: memory ││ format: memory │
-71)│ rows: 1 ││ rows: 1 │
-72)└───────────────────────────┘└───────────────────────────┘
+10)│ aggr: count(1) │
+11)│ group_by: name │
+12)│ │
+13)│ mode: │
+14)│ SinglePartitioned │
+15)└─────────────┬─────────────┘
+16)┌─────────────┴─────────────┐
+17)│ InterleaveExec ├──────────────┐
+18)└─────────────┬─────────────┘ │
+19)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
+20)│ AggregateExec ││ AggregateExec │
+21)│ -------------------- ││ -------------------- │
+22)│ group_by: name ││ group_by: name │
+23)│ ││ │
+24)│ mode: ││ mode: │
+25)│ FinalPartitioned ││ FinalPartitioned │
+26)└─────────────┬─────────────┘└─────────────┬─────────────┘
+27)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
+28)│ CoalesceBatchesExec ││ CoalesceBatchesExec │
+29)│ -------------------- ││ -------------------- │
+30)│ target_batch_size: ││ target_batch_size: │
+31)│ 8192 ││ 8192 │
+32)└─────────────┬─────────────┘└─────────────┬─────────────┘
+33)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
+34)│ RepartitionExec ││ RepartitionExec │
+35)│ -------------------- ││ -------------------- │
+36)│ output_partition_count: ││ output_partition_count: │
+37)│ 4 ││ 4 │
+38)│ ││ │
+39)│ partitioning_scheme: ││ partitioning_scheme: │
+40)│ Hash([name@0], 4) ││ Hash([name@0], 4) │
+41)└─────────────┬─────────────┘└─────────────┬─────────────┘
+42)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
+43)│ RepartitionExec ││ RepartitionExec │
+44)│ -------------------- ││ -------------------- │
+45)│ output_partition_count: ││ output_partition_count: │
+46)│ 1 ││ 1 │
+47)│ ││ │
+48)│ partitioning_scheme: ││ partitioning_scheme: │
+49)│ RoundRobinBatch(4) ││ RoundRobinBatch(4) │
+50)└─────────────┬─────────────┘└─────────────┬─────────────┘
+51)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
+52)│ AggregateExec ││ AggregateExec │
+53)│ -------------------- ││ -------------------- │
+54)│ group_by: name ││ group_by: name │
+55)│ mode: Partial ││ mode: Partial │
+56)└─────────────┬─────────────┘└─────────────┬─────────────┘
+57)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
+58)│ DataSourceExec ││ DataSourceExec │
+59)│ -------------------- ││ -------------------- │
+60)│ bytes: 1320 ││ bytes: 1312 │
+61)│ format: memory ││ format: memory │
+62)│ rows: 1 ││ rows: 1 │
+63)└───────────────────────────┘└───────────────────────────┘
# Test explain tree for UnionExec
query TT
@@ -1975,7 +1963,7 @@ physical_plan
07)┌─────────────┴─────────────┐
08)│ AggregateExec │
09)│ -------------------- │
-10)│ aggr: count(Int64(1)) │
+10)│ aggr: count(1) │
11)│ mode: Final │
12)└─────────────┬─────────────┘
13)┌─────────────┴─────────────┐
@@ -1984,7 +1972,7 @@ physical_plan
16)┌─────────────┴─────────────┐
17)│ AggregateExec │
18)│ -------------------- │
-19)│ aggr: count(Int64(1)) │
+19)│ aggr: count(1) │
20)│ mode: Partial │
21)└─────────────┬─────────────┘
22)┌─────────────┴─────────────┐
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org