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 9382add72b Improve parsing `extra_info` in tree explain (#15125)
9382add72b is described below
commit 9382add72b929c553ca4976d1423d8ebbc80889d
Author: irenjj <[email protected]>
AuthorDate: Tue Mar 11 03:11:16 2025 +0800
Improve parsing `extra_info` in tree explain (#15125)
* Improve parsing `extra_info` in tree explain
* Improve documentation and CrossJoinDisplay
---------
Co-authored-by: Andrew Lamb <[email protected]>
---
datafusion/physical-plan/src/display.rs | 24 ++--
datafusion/physical-plan/src/joins/cross_join.rs | 8 +-
datafusion/physical-plan/src/render_tree.rs | 3 +
datafusion/physical-plan/src/sorts/partial_sort.rs | 6 +-
datafusion/physical-plan/src/sorts/sort.rs | 6 +-
.../sqllogictest/test_files/explain_tree.slt | 157 ++++++++++-----------
6 files changed, 103 insertions(+), 101 deletions(-)
diff --git a/datafusion/physical-plan/src/display.rs
b/datafusion/physical-plan/src/display.rs
index 98ba3e1fd9..59d5e60ca9 100644
--- a/datafusion/physical-plan/src/display.rs
+++ b/datafusion/physical-plan/src/display.rs
@@ -52,14 +52,18 @@ pub enum DisplayFormatType {
/// information for understanding a plan. It should NOT contain the same
level
/// of detail information as the [`Self::Default`] format.
///
- /// In this mode, each line contains a key=value pair.
- /// Everything before the first `=` is treated as the key, and everything
after the
- /// first `=` is treated as the value.
+ /// In this mode, each line has one of two formats:
+ ///
+ /// 1. A string without a `=`, which is printed in its own line
+ ///
+ /// 2. A string with a `=` that is treated as a `key=value pair`.
Everything
+ /// before the first `=` is treated as the key, and everything after the
+ /// first `=` is treated as the value.
///
/// For example, if the output of `TreeRender` is this:
/// ```text
+ /// Parquet
/// partition_sizes=[1]
- /// partitions=1
/// ```
///
/// It is rendered in the center of a box in the following way:
@@ -69,7 +73,7 @@ pub enum DisplayFormatType {
/// │ DataSourceExec │
/// │ -------------------- │
/// │ partition_sizes: [1] │
- /// │ partitions: 1 │
+ /// │ Parquet │
/// └───────────────────────────┘
/// ```
TreeRender,
@@ -857,22 +861,24 @@ impl TreeRenderVisitor<'_, '_> {
let sorted_extra_info: BTreeMap<_, _> = extra_info.iter().collect();
for (key, value) in sorted_extra_info {
let mut str = Self::remove_padding(value);
- if str.is_empty() {
- continue;
- }
let mut is_inlined = false;
let available_width = Self::NODE_RENDER_WIDTH - 7;
let total_size = key.len() + str.len() + 2;
let is_multiline = str.contains('\n');
- if !is_multiline && total_size < available_width {
+
+ if str.is_empty() {
+ str = key.to_string();
+ } else if !is_multiline && total_size < available_width {
str = format!("{}: {}", key, str);
is_inlined = true;
} else {
str = format!("{}:\n{}", key, str);
}
+
if is_inlined && was_inlined {
requires_padding = false;
}
+
if requires_padding {
result.push(String::new());
}
diff --git a/datafusion/physical-plan/src/joins/cross_join.rs
b/datafusion/physical-plan/src/joins/cross_join.rs
index e0998862bd..35c8961065 100644
--- a/datafusion/physical-plan/src/joins/cross_join.rs
+++ b/datafusion/physical-plan/src/joins/cross_join.rs
@@ -237,11 +237,13 @@ impl DisplayAs for CrossJoinExec {
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
match t {
- DisplayFormatType::Default
- | DisplayFormatType::Verbose
- | DisplayFormatType::TreeRender => {
+ DisplayFormatType::Default | DisplayFormatType::Verbose => {
write!(f, "CrossJoinExec")
}
+ DisplayFormatType::TreeRender => {
+ // no extra info to display
+ Ok(())
+ }
}
}
}
diff --git a/datafusion/physical-plan/src/render_tree.rs
b/datafusion/physical-plan/src/render_tree.rs
index 5f8da76a89..f86e4c55e7 100644
--- a/datafusion/physical-plan/src/render_tree.rs
+++ b/datafusion/physical-plan/src/render_tree.rs
@@ -198,9 +198,12 @@ fn create_tree_recursive(
let mut extra_info = HashMap::new();
// Parse the key-value pairs from the formatted string.
+ // See DisplayFormatType::TreeRender for details
for line in display_info.lines() {
if let Some((key, value)) = line.split_once('=') {
extra_info.insert(key.to_string(), value.to_string());
+ } else {
+ extra_info.insert(line.to_string(), "".to_string());
}
}
diff --git a/datafusion/physical-plan/src/sorts/partial_sort.rs
b/datafusion/physical-plan/src/sorts/partial_sort.rs
index 4cff0fedfa..5277a50b85 100644
--- a/datafusion/physical-plan/src/sorts/partial_sort.rs
+++ b/datafusion/physical-plan/src/sorts/partial_sort.rs
@@ -228,11 +228,11 @@ impl DisplayAs for PartialSortExec {
}
DisplayFormatType::TreeRender => match self.fetch {
Some(fetch) => {
- writeln!(f, "limit={fetch}")?;
- writeln!(f, "sort keys={}", self.expr)
+ writeln!(f, "{}", self.expr)?;
+ writeln!(f, "limit={fetch}")
}
None => {
- writeln!(f, "sort keys={}", self.expr)
+ writeln!(f, "{}", self.expr)
}
},
}
diff --git a/datafusion/physical-plan/src/sorts/sort.rs
b/datafusion/physical-plan/src/sorts/sort.rs
index 0b62925426..3d2323eb43 100644
--- a/datafusion/physical-plan/src/sorts/sort.rs
+++ b/datafusion/physical-plan/src/sorts/sort.rs
@@ -1007,11 +1007,11 @@ impl DisplayAs for SortExec {
}
DisplayFormatType::TreeRender => match self.fetch {
Some(fetch) => {
- writeln!(f, "limit={fetch}")?;
- writeln!(f, "sort keys=[{}]", self.expr)
+ writeln!(f, "{}", self.expr)?;
+ writeln!(f, "limit={fetch}")
}
None => {
- writeln!(f, "sort keys=[{}]", self.expr)
+ writeln!(f, "{}", self.expr)
}
},
}
diff --git a/datafusion/sqllogictest/test_files/explain_tree.slt
b/datafusion/sqllogictest/test_files/explain_tree.slt
index d81d83ea42..be926c0fc9 100644
--- a/datafusion/sqllogictest/test_files/explain_tree.slt
+++ b/datafusion/sqllogictest/test_files/explain_tree.slt
@@ -674,17 +674,16 @@ physical_plan
23)┌─────────────┴─────────────┐
24)│ SortExec │
25)│ -------------------- │
-26)│ sort keys: │
-27)│ [v1@0 ASC NULLS LAST] │
-28)└─────────────┬─────────────┘
-29)┌─────────────┴─────────────┐
-30)│ ProjectionExec │
-31)│ -------------------- │
-32)│ v1: value@0 │
-33)└─────────────┬─────────────┘
-34)┌─────────────┴─────────────┐
-35)│ LazyMemoryExec │
-36)└───────────────────────────┘
+26)│ v1@0 ASC NULLS LAST │
+27)└─────────────┬─────────────┘
+28)┌─────────────┴─────────────┐
+29)│ ProjectionExec │
+30)│ -------------------- │
+31)│ v1: value@0 │
+32)└─────────────┬─────────────┘
+33)┌─────────────┴─────────────┐
+34)│ LazyMemoryExec │
+35)└───────────────────────────┘
query TT
explain select
@@ -745,16 +744,14 @@ physical_plan
01)┌───────────────────────────┐
02)│ SortExec │
03)│ -------------------- │
-04)│ sort keys: │
-05)│ [string_col@1 ASC NULLS │
-06)│ LAST] │
-07)└─────────────┬─────────────┘
-08)┌─────────────┴─────────────┐
-09)│ DataSourceExec │
-10)│ -------------------- │
-11)│ files: 1 │
-12)│ format: csv │
-13)└───────────────────────────┘
+04)│string_col@1 ASC NULLS LAST│
+05)└─────────────┬─────────────┘
+06)┌─────────────┴─────────────┐
+07)│ DataSourceExec │
+08)│ -------------------- │
+09)│ files: 1 │
+10)│ format: csv │
+11)└───────────────────────────┘
# Query for sort with limit.
query TT
@@ -769,16 +766,14 @@ physical_plan
03)│ -------------------- │
04)│ limit: 1 │
05)│ │
-06)│ sort keys: │
-07)│ [string_col@1 ASC NULLS │
-08)│ LAST] │
-09)└─────────────┬─────────────┘
-10)┌─────────────┴─────────────┐
-11)│ DataSourceExec │
-12)│ -------------------- │
-13)│ files: 1 │
-14)│ format: csv │
-15)└───────────────────────────┘
+06)│string_col@1 ASC NULLS LAST│
+07)└─────────────┬─────────────┘
+08)┌─────────────┴─────────────┐
+09)│ DataSourceExec │
+10)│ -------------------- │
+11)│ files: 1 │
+12)│ format: csv │
+13)└───────────────────────────┘
# Query with projection on csv
query TT
@@ -865,33 +860,31 @@ physical_plan
41)┌─────────────┴─────────────┐
42)│ SortExec │
43)│ -------------------- │
-44)│ sort keys: │
-45)│ [int_col@0 ASC NULLS LAST]│
-46)└─────────────┬─────────────┘
-47)┌─────────────┴─────────────┐
-48)│ BoundedWindowAggExec │
-49)│ -------------------- │
-50)│ mode: Sorted │
-51)│ │
-52)│ select_list: │
-53)│ rank() ORDER BY [table1 │
-54)│ .int_col DESC NULLS │
-55)│ FIRST] RANGE BETWEEN │
-56)│ UNBOUNDED PRECEDING AND │
-57)│ CURRENT ROW │
-58)└─────────────┬─────────────┘
-59)┌─────────────┴─────────────┐
-60)│ SortExec │
-61)│ -------------------- │
-62)│ sort keys: │
-63)│ [int_col@0 DESC] │
-64)└─────────────┬─────────────┘
-65)┌─────────────┴─────────────┐
-66)│ DataSourceExec │
-67)│ -------------------- │
-68)│ files: 1 │
-69)│ format: csv │
-70)└───────────────────────────┘
+44)│ int_col@0 ASC NULLS LAST │
+45)└─────────────┬─────────────┘
+46)┌─────────────┴─────────────┐
+47)│ BoundedWindowAggExec │
+48)│ -------------------- │
+49)│ mode: Sorted │
+50)│ │
+51)│ select_list: │
+52)│ rank() ORDER BY [table1 │
+53)│ .int_col DESC NULLS │
+54)│ FIRST] RANGE BETWEEN │
+55)│ UNBOUNDED PRECEDING AND │
+56)│ CURRENT ROW │
+57)└─────────────┬─────────────┘
+58)┌─────────────┴─────────────┐
+59)│ SortExec │
+60)│ -------------------- │
+61)│ int_col@0 DESC │
+62)└─────────────┬─────────────┘
+63)┌─────────────┴─────────────┐
+64)│ DataSourceExec │
+65)│ -------------------- │
+66)│ files: 1 │
+67)│ format: csv │
+68)└───────────────────────────┘
# Query with projection on parquet
query TT
@@ -1025,17 +1018,16 @@ physical_plan
01)┌───────────────────────────┐
02)│ PartialSortExec │
03)│ -------------------- │
-04)│ sort keys: │
-05)│ a@1 ASC NULLS LAST, b@2 │
-06)│ ASC NULLS LAST, d@4 │
-07)│ ASC NULLS LAST │
-08)└─────────────┬─────────────┘
-09)┌─────────────┴─────────────┐
-10)│ StreamingTableExec │
-11)│ -------------------- │
-12)│ infinite: true │
-13)│ limit: None │
-14)└───────────────────────────┘
+04)│ a@1 ASC NULLS LAST, b@2 │
+05)│ ASC NULLS LAST, d@4 │
+06)│ ASC NULLS LAST │
+07)└─────────────┬─────────────┘
+08)┌─────────────┴─────────────┐
+09)│ StreamingTableExec │
+10)│ -------------------- │
+11)│ infinite: true │
+12)│ limit: None │
+13)└───────────────────────────┘
query TT
EXPLAIN SELECT *
@@ -1050,19 +1042,18 @@ physical_plan
01)┌───────────────────────────┐
02)│ PartialSortExec │
03)│ -------------------- │
-04)│ limit: 50 │
-05)│ │
-06)│ sort keys: │
-07)│ a@1 ASC NULLS LAST, b@2 │
-08)│ ASC NULLS LAST, d@4 │
-09)│ ASC NULLS LAST │
-10)└─────────────┬─────────────┘
-11)┌─────────────┴─────────────┐
-12)│ StreamingTableExec │
-13)│ -------------------- │
-14)│ infinite: true │
-15)│ limit: None │
-16)└───────────────────────────┘
+04)│ a@1 ASC NULLS LAST, b@2 │
+05)│ ASC NULLS LAST, d@4 │
+06)│ ASC NULLS LAST │
+07)│ │
+08)│ limit: 50 │
+09)└─────────────┬─────────────┘
+10)┌─────────────┴─────────────┐
+11)│ StreamingTableExec │
+12)│ -------------------- │
+13)│ infinite: true │
+14)│ limit: None │
+15)└───────────────────────────┘
# Query with hash join.
query TT
@@ -1270,7 +1261,7 @@ physical_plan
06)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
07)│ SortExec ││ SortExec │
08)│ -------------------- ││ -------------------- │
-09)│ sort keys: [c1@0 ASC] ││ sort keys: [c1@0 ASC] │
+09)│ c1@0 ASC ││ c1@0 ASC │
10)└─────────────┬─────────────┘└─────────────┬─────────────┘
11)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
12)│ DataSourceExec ││ DataSourceExec │
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]