@@ -1712,6 +1712,14 @@ impl DefaultPhysicalPlanner {
1712
1712
let config = & session_state. config_options ( ) . explain ;
1713
1713
let explain_format = & e. explain_format ;
1714
1714
1715
+ if !e. logical_optimization_succeeded {
1716
+ return Ok ( Arc :: new ( ExplainExec :: new (
1717
+ Arc :: clone ( e. schema . inner ( ) ) ,
1718
+ e. stringified_plans . clone ( ) ,
1719
+ true ,
1720
+ ) ) ) ;
1721
+ }
1722
+
1715
1723
match explain_format {
1716
1724
ExplainFormat :: Indent => { /* fall through */ }
1717
1725
ExplainFormat :: Tree => {
@@ -2190,7 +2198,9 @@ mod tests {
2190
2198
use arrow:: array:: { ArrayRef , DictionaryArray , Int32Array } ;
2191
2199
use arrow:: datatypes:: { DataType , Field , Int32Type } ;
2192
2200
use datafusion_common:: config:: ConfigOptions ;
2193
- use datafusion_common:: { assert_contains, DFSchemaRef , TableReference } ;
2201
+ use datafusion_common:: {
2202
+ assert_contains, DFSchemaRef , TableReference , ToDFSchema as _,
2203
+ } ;
2194
2204
use datafusion_execution:: runtime_env:: RuntimeEnv ;
2195
2205
use datafusion_execution:: TaskContext ;
2196
2206
use datafusion_expr:: { col, lit, LogicalPlanBuilder , UserDefinedLogicalNodeCore } ;
@@ -2687,6 +2697,54 @@ mod tests {
2687
2697
}
2688
2698
}
2689
2699
2700
+ #[ tokio:: test]
2701
+ async fn test_explain_indent_err ( ) {
2702
+ let planner = DefaultPhysicalPlanner :: default ( ) ;
2703
+ let ctx = SessionContext :: new ( ) ;
2704
+ let schema = Schema :: new ( vec ! [ Field :: new( "id" , DataType :: Int32 , false ) ] ) ;
2705
+ let plan = Arc :: new (
2706
+ scan_empty ( Some ( "employee" ) , & schema, None )
2707
+ . unwrap ( )
2708
+ . explain ( true , false )
2709
+ . unwrap ( )
2710
+ . build ( )
2711
+ . unwrap ( ) ,
2712
+ ) ;
2713
+
2714
+ // Create a schema
2715
+ let schema = Arc :: new ( Schema :: new ( vec ! [
2716
+ Field :: new( "plan_type" , DataType :: Utf8 , false ) ,
2717
+ Field :: new( "plan" , DataType :: Utf8 , false ) ,
2718
+ ] ) ) ;
2719
+
2720
+ // Create invalid indentation in the plan
2721
+ let stringified_plans =
2722
+ vec ! [ StringifiedPlan :: new( PlanType :: FinalLogicalPlan , "Test Err" ) ] ;
2723
+
2724
+ let explain = Explain {
2725
+ verbose : false ,
2726
+ explain_format : ExplainFormat :: Indent ,
2727
+ plan,
2728
+ stringified_plans,
2729
+ schema : schema. to_dfschema_ref ( ) . unwrap ( ) ,
2730
+ logical_optimization_succeeded : false ,
2731
+ } ;
2732
+ let plan = planner
2733
+ . handle_explain ( & explain, & ctx. state ( ) )
2734
+ . await
2735
+ . unwrap ( ) ;
2736
+ if let Some ( plan) = plan. as_any ( ) . downcast_ref :: < ExplainExec > ( ) {
2737
+ let stringified_plans = plan. stringified_plans ( ) ;
2738
+ assert_eq ! ( stringified_plans. len( ) , 1 ) ;
2739
+ assert_eq ! ( stringified_plans[ 0 ] . plan. as_str( ) , "Test Err" ) ;
2740
+ } else {
2741
+ panic ! (
2742
+ "Plan was not an explain plan: {}" ,
2743
+ displayable( plan. as_ref( ) ) . indent( true )
2744
+ ) ;
2745
+ }
2746
+ }
2747
+
2690
2748
#[ tokio:: test]
2691
2749
async fn test_maybe_fix_colon_in_physical_name ( ) {
2692
2750
// The physical schema has a field name with a colon
0 commit comments