@@ -1712,6 +1712,14 @@ impl DefaultPhysicalPlanner {
17121712 let config = & session_state. config_options ( ) . explain ;
17131713 let explain_format = & e. explain_format ;
17141714
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+
17151723 match explain_format {
17161724 ExplainFormat :: Indent => { /* fall through */ }
17171725 ExplainFormat :: Tree => {
@@ -2190,7 +2198,9 @@ mod tests {
21902198 use arrow:: array:: { ArrayRef , DictionaryArray , Int32Array } ;
21912199 use arrow:: datatypes:: { DataType , Field , Int32Type } ;
21922200 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+ } ;
21942204 use datafusion_execution:: runtime_env:: RuntimeEnv ;
21952205 use datafusion_execution:: TaskContext ;
21962206 use datafusion_expr:: { col, lit, LogicalPlanBuilder , UserDefinedLogicalNodeCore } ;
@@ -2687,6 +2697,54 @@ mod tests {
26872697 }
26882698 }
26892699
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+
26902748 #[ tokio:: test]
26912749 async fn test_maybe_fix_colon_in_physical_name ( ) {
26922750 // The physical schema has a field name with a colon
0 commit comments