diff --git a/datafusion/physical-plan/src/display.rs b/datafusion/physical-plan/src/display.rs index 26e0a822f588..096b51540745 100644 --- a/datafusion/physical-plan/src/display.rs +++ b/datafusion/physical-plan/src/display.rs @@ -37,10 +37,41 @@ use super::{accept, ExecutionPlan, ExecutionPlanVisitor}; #[derive(Debug, Clone, Copy)] pub enum DisplayFormatType { /// Default, compact format. Example: `FilterExec: c12 < 10.0` + /// + /// This format is designed to provide a detailed textual description + /// of all rele Default, - /// Verbose, showing all available details + /// Verbose, showing all available details. + /// + /// This form is even more detailed than [`Self::Default`] Verbose, - /// TreeRender, display plan like a tree. + /// TreeRender, displayed in the `tree` explain type. + /// + /// This format is inspired by DuckDB's explain plans. The information + /// presented should be "user friendly", and contain only the most relevant + /// 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. + /// + /// For example, if the output of `TreeRender` is this: + /// ```text + /// partition_sizes=[1] + /// partitions=1 + /// ``` + /// + /// It is rendered in the center of a box in the following way: + /// + /// ```text + /// ┌───────────────────────────┐ + /// │ DataSourceExec │ + /// │ -------------------- │ + /// │ partition_sizes: [1] │ + /// │ partitions: 1 │ + /// └───────────────────────────┘ + /// ``` TreeRender, } diff --git a/datafusion/physical-plan/src/filter.rs b/datafusion/physical-plan/src/filter.rs index 524da586f52e..ffcda1d888b0 100644 --- a/datafusion/physical-plan/src/filter.rs +++ b/datafusion/physical-plan/src/filter.rs @@ -330,8 +330,7 @@ impl DisplayAs for FilterExec { write!(f, "FilterExec: {}{}", self.predicate, display_projections) } DisplayFormatType::TreeRender => { - // TODO: collect info - write!(f, "") + write!(f, "predicate={}", self.predicate) } } } diff --git a/datafusion/sqllogictest/test_files/explain_tree.slt b/datafusion/sqllogictest/test_files/explain_tree.slt index 5f0785782008..18de2c6a617f 100644 --- a/datafusion/sqllogictest/test_files/explain_tree.slt +++ b/datafusion/sqllogictest/test_files/explain_tree.slt @@ -74,13 +74,16 @@ physical_plan 03)└─────────────┬─────────────┘ 04)┌─────────────┴─────────────┐ 05)│ FilterExec │ -06)└─────────────┬─────────────┘ -07)┌─────────────┴─────────────┐ -08)│ RepartitionExec │ +06)│ -------------------- │ +07)│ predicate: │ +08)│ string_col@1 != foo │ 09)└─────────────┬─────────────┘ 10)┌─────────────┴─────────────┐ -11)│ DataSourceExec │ -12)└───────────────────────────┘ +11)│ RepartitionExec │ +12)└─────────────┬─────────────┘ +13)┌─────────────┴─────────────┐ +14)│ DataSourceExec │ +15)└───────────────────────────┘ # Aggregate query TT @@ -185,6 +188,32 @@ physical_plan 26)│ DataSourceExec ││ DataSourceExec │ 27)└───────────────────────────┘└───────────────────────────┘ +# Long Filter (demonstrate what happens with wrapping) +query TT +explain SELECT int_col FROM table1 +WHERE string_col != 'foo' AND string_col != 'bar' AND string_col != 'a really long string constant' +; +---- +logical_plan +01)Projection: table1.int_col +02)--Filter: table1.string_col != Utf8("foo") AND table1.string_col != Utf8("bar") AND table1.string_col != Utf8("a really long string constant") +03)----TableScan: table1 projection=[int_col, string_col], partial_filters=[table1.string_col != Utf8("foo"), table1.string_col != Utf8("bar"), table1.string_col != Utf8("a really long string constant")] +physical_plan +01)┌───────────────────────────┐ +02)│ CoalesceBatchesExec │ +03)└─────────────┬─────────────┘ +04)┌─────────────┴─────────────┐ +05)│ FilterExec │ +06)│ -------------------- │ +07)│ predicate: │ +08)│string_col@1 != foo AND ...│ +09)└─────────────┬─────────────┘ +10)┌─────────────┴─────────────┐ +11)│ RepartitionExec │ +12)└─────────────┬─────────────┘ +13)┌─────────────┴─────────────┐ +14)│ DataSourceExec │ +15)└───────────────────────────┘ # cleanup