1919
2020use std:: borrow:: Cow ;
2121use std:: collections:: HashMap ;
22- use std:: str:: FromStr ;
2322use std:: sync:: Arc ;
2423
2524use crate :: datasource:: file_format:: file_type_to_format;
@@ -78,8 +77,8 @@ use datafusion_expr::expr::{
7877use datafusion_expr:: expr_rewriter:: unnormalize_cols;
7978use datafusion_expr:: logical_plan:: builder:: wrap_projection_for_join_if_necessary;
8079use datafusion_expr:: {
81- Analyze , DescribeTable , DmlStatement , Explain , Extension , FetchType , Filter ,
82- JoinType , RecursiveQuery , SkipType , SortExpr , StringifiedPlan , WindowFrame ,
80+ Analyze , DescribeTable , DmlStatement , Explain , ExplainFormat , Extension , FetchType ,
81+ Filter , JoinType , RecursiveQuery , SkipType , SortExpr , StringifiedPlan , WindowFrame ,
8382 WindowFrameBound , WriteOp ,
8483} ;
8584use datafusion_physical_expr:: aggregate:: { AggregateExprBuilder , AggregateFunctionExpr } ;
@@ -89,7 +88,6 @@ use datafusion_physical_optimizer::PhysicalOptimizerRule;
8988use datafusion_physical_plan:: execution_plan:: InvariantLevel ;
9089use datafusion_physical_plan:: placeholder_row:: PlaceholderRowExec ;
9190use datafusion_physical_plan:: unnest:: ListUnnest ;
92- use datafusion_physical_plan:: DisplayFormatType ;
9391
9492use crate :: schema_equivalence:: schema_satisfied_by;
9593use async_trait:: async_trait;
@@ -1742,12 +1740,54 @@ impl DefaultPhysicalPlanner {
17421740 let mut stringified_plans = vec ! [ ] ;
17431741
17441742 let config = & session_state. config_options ( ) . explain ;
1745- let explain_format = DisplayFormatType :: from_str ( & config. format ) ?;
1743+ let explain_format = & e. explain_format ;
1744+
1745+ match explain_format {
1746+ ExplainFormat :: Indent => { /* fall through */ }
1747+ ExplainFormat :: Tree => {
1748+ // Tree render does not try to explain errors,
1749+ let physical_plan = self
1750+ . create_initial_plan ( e. plan . as_ref ( ) , session_state)
1751+ . await ?;
1752+
1753+ let optimized_plan = self . optimize_physical_plan (
1754+ physical_plan,
1755+ session_state,
1756+ |_plan, _optimizer| { } ,
1757+ ) ?;
1758+
1759+ stringified_plans. push ( StringifiedPlan :: new (
1760+ FinalPhysicalPlan ,
1761+ displayable ( optimized_plan. as_ref ( ) )
1762+ . tree_render ( )
1763+ . to_string ( ) ,
1764+ ) ) ;
1765+ }
1766+ ExplainFormat :: PostgresJSON => {
1767+ stringified_plans. push ( StringifiedPlan :: new (
1768+ FinalLogicalPlan ,
1769+ e. plan . display_pg_json ( ) . to_string ( ) ,
1770+ ) ) ;
1771+ }
1772+ ExplainFormat :: Graphviz => {
1773+ stringified_plans. push ( StringifiedPlan :: new (
1774+ FinalLogicalPlan ,
1775+ e. plan . display_graphviz ( ) . to_string ( ) ,
1776+ ) ) ;
1777+ }
1778+ } ;
17461779
1747- let skip_logical_plan =
1748- config. physical_plan_only || explain_format == DisplayFormatType :: TreeRender ;
1780+ if !stringified_plans. is_empty ( ) {
1781+ return Ok ( Arc :: new ( ExplainExec :: new (
1782+ Arc :: clone ( e. schema . inner ( ) ) ,
1783+ stringified_plans,
1784+ e. verbose ,
1785+ ) ) ) ;
1786+ }
17491787
1750- if !skip_logical_plan {
1788+ // The indent mode is quite sophisticated, and handles quite a few
1789+ // different cases / options for displaying the plan.
1790+ if !config. physical_plan_only {
17511791 stringified_plans. clone_from ( & e. stringified_plans ) ;
17521792 if e. logical_optimization_succeeded {
17531793 stringified_plans. push ( e. plan . to_stringified ( FinalLogicalPlan ) ) ;
@@ -1761,41 +1801,35 @@ impl DefaultPhysicalPlanner {
17611801 {
17621802 Ok ( input) => {
17631803 // Include statistics / schema if enabled
1764- stringified_plans. push (
1804+ stringified_plans. push ( StringifiedPlan :: new (
1805+ InitialPhysicalPlan ,
17651806 displayable ( input. as_ref ( ) )
17661807 . set_show_statistics ( config. show_statistics )
17671808 . set_show_schema ( config. show_schema )
1768- . to_stringified (
1769- e. verbose ,
1770- InitialPhysicalPlan ,
1771- explain_format,
1772- ) ,
1773- ) ;
1809+ . indent ( e. verbose )
1810+ . to_string ( ) ,
1811+ ) ) ;
17741812
17751813 // Show statistics + schema in verbose output even if not
17761814 // explicitly requested
17771815 if e. verbose {
17781816 if !config. show_statistics {
1779- stringified_plans. push (
1817+ stringified_plans. push ( StringifiedPlan :: new (
1818+ InitialPhysicalPlanWithStats ,
17801819 displayable ( input. as_ref ( ) )
17811820 . set_show_statistics ( true )
1782- . to_stringified (
1783- e. verbose ,
1784- InitialPhysicalPlanWithStats ,
1785- explain_format,
1786- ) ,
1787- ) ;
1821+ . indent ( e. verbose )
1822+ . to_string ( ) ,
1823+ ) ) ;
17881824 }
17891825 if !config. show_schema {
1790- stringified_plans. push (
1826+ stringified_plans. push ( StringifiedPlan :: new (
1827+ InitialPhysicalPlanWithSchema ,
17911828 displayable ( input. as_ref ( ) )
17921829 . set_show_schema ( true )
1793- . to_stringified (
1794- e. verbose ,
1795- InitialPhysicalPlanWithSchema ,
1796- explain_format,
1797- ) ,
1798- ) ;
1830+ . indent ( e. verbose )
1831+ . to_string ( ) ,
1832+ ) ) ;
17991833 }
18001834 }
18011835
@@ -1805,52 +1839,50 @@ impl DefaultPhysicalPlanner {
18051839 |plan, optimizer| {
18061840 let optimizer_name = optimizer. name ( ) . to_string ( ) ;
18071841 let plan_type = OptimizedPhysicalPlan { optimizer_name } ;
1808- stringified_plans. push (
1842+ stringified_plans. push ( StringifiedPlan :: new (
1843+ plan_type,
18091844 displayable ( plan)
18101845 . set_show_statistics ( config. show_statistics )
18111846 . set_show_schema ( config. show_schema )
1812- . to_stringified ( e. verbose , plan_type, explain_format) ,
1813- ) ;
1847+ . indent ( e. verbose )
1848+ . to_string ( ) ,
1849+ ) ) ;
18141850 } ,
18151851 ) ;
18161852 match optimized_plan {
18171853 Ok ( input) => {
18181854 // This plan will includes statistics if show_statistics is on
1819- stringified_plans. push (
1855+ stringified_plans. push ( StringifiedPlan :: new (
1856+ FinalPhysicalPlan ,
18201857 displayable ( input. as_ref ( ) )
18211858 . set_show_statistics ( config. show_statistics )
18221859 . set_show_schema ( config. show_schema )
1823- . to_stringified (
1824- e. verbose ,
1825- FinalPhysicalPlan ,
1826- explain_format,
1827- ) ,
1828- ) ;
1860+ . indent ( e. verbose )
1861+ . to_string ( ) ,
1862+ ) ) ;
18291863
18301864 // Show statistics + schema in verbose output even if not
18311865 // explicitly requested
18321866 if e. verbose {
18331867 if !config. show_statistics {
1834- stringified_plans. push (
1868+ stringified_plans. push ( StringifiedPlan :: new (
1869+ FinalPhysicalPlanWithStats ,
18351870 displayable ( input. as_ref ( ) )
18361871 . set_show_statistics ( true )
1837- . to_stringified (
1838- e. verbose ,
1839- FinalPhysicalPlanWithStats ,
1840- explain_format,
1841- ) ,
1842- ) ;
1872+ . indent ( e. verbose )
1873+ . to_string ( ) ,
1874+ ) ) ;
18431875 }
18441876 if !config. show_schema {
1845- stringified_plans. push (
1877+ stringified_plans. push ( StringifiedPlan :: new (
1878+ FinalPhysicalPlanWithSchema ,
1879+ // This will include schema if show_schema is on
1880+ // and will be set to true if verbose is on
18461881 displayable ( input. as_ref ( ) )
18471882 . set_show_schema ( true )
1848- . to_stringified (
1849- e. verbose ,
1850- FinalPhysicalPlanWithSchema ,
1851- explain_format,
1852- ) ,
1853- ) ;
1883+ . indent ( e. verbose )
1884+ . to_string ( ) ,
1885+ ) ) ;
18541886 }
18551887 }
18561888 }
0 commit comments