2121use std:: fmt;
2222use std:: fmt:: Formatter ;
2323
24- use super :: { accept, ExecutionPlan , ExecutionPlanVisitor } ;
25-
2624use arrow_schema:: SchemaRef ;
25+
2726use datafusion_common:: display:: { GraphvizBuilder , PlanType , StringifiedPlan } ;
27+ use datafusion_expr:: display_schema;
2828use datafusion_physical_expr:: { LexOrdering , PhysicalSortExpr } ;
2929
30+ use super :: { accept, ExecutionPlan , ExecutionPlanVisitor } ;
31+
3032/// Options for controlling how each [`ExecutionPlan`] should format itself
3133#[ derive( Debug , Clone , Copy ) ]
3234pub enum DisplayFormatType {
@@ -37,12 +39,15 @@ pub enum DisplayFormatType {
3739}
3840
3941/// Wraps an `ExecutionPlan` with various ways to display this plan
42+ #[ derive( Debug , Clone ) ]
4043pub struct DisplayableExecutionPlan < ' a > {
4144 inner : & ' a dyn ExecutionPlan ,
4245 /// How to show metrics
4346 show_metrics : ShowMetrics ,
4447 /// If statistics should be displayed
4548 show_statistics : bool ,
49+ /// If schema should be displayed. See [`Self::set_show_schema`]
50+ show_schema : bool ,
4651}
4752
4853impl < ' a > DisplayableExecutionPlan < ' a > {
@@ -53,6 +58,7 @@ impl<'a> DisplayableExecutionPlan<'a> {
5358 inner,
5459 show_metrics : ShowMetrics :: None ,
5560 show_statistics : false ,
61+ show_schema : false ,
5662 }
5763 }
5864
@@ -64,6 +70,7 @@ impl<'a> DisplayableExecutionPlan<'a> {
6470 inner,
6571 show_metrics : ShowMetrics :: Aggregated ,
6672 show_statistics : false ,
73+ show_schema : false ,
6774 }
6875 }
6976
@@ -75,9 +82,19 @@ impl<'a> DisplayableExecutionPlan<'a> {
7582 inner,
7683 show_metrics : ShowMetrics :: Full ,
7784 show_statistics : false ,
85+ show_schema : false ,
7886 }
7987 }
8088
89+ /// Enable display of schema
90+ ///
91+ /// If true, plans will be displayed with schema information at the end
92+ /// of each line. The format is `schema=[[a:Int32;N, b:Int32;N, c:Int32;N]]`
93+ pub fn set_show_schema ( mut self , show_schema : bool ) -> Self {
94+ self . show_schema = show_schema;
95+ self
96+ }
97+
8198 /// Enable display of statistics
8299 pub fn set_show_statistics ( mut self , show_statistics : bool ) -> Self {
83100 self . show_statistics = show_statistics;
@@ -105,6 +122,7 @@ impl<'a> DisplayableExecutionPlan<'a> {
105122 plan : & ' a dyn ExecutionPlan ,
106123 show_metrics : ShowMetrics ,
107124 show_statistics : bool ,
125+ show_schema : bool ,
108126 }
109127 impl < ' a > fmt:: Display for Wrapper < ' a > {
110128 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
@@ -114,6 +132,7 @@ impl<'a> DisplayableExecutionPlan<'a> {
114132 indent : 0 ,
115133 show_metrics : self . show_metrics ,
116134 show_statistics : self . show_statistics ,
135+ show_schema : self . show_schema ,
117136 } ;
118137 accept ( self . plan , & mut visitor)
119138 }
@@ -123,6 +142,7 @@ impl<'a> DisplayableExecutionPlan<'a> {
123142 plan : self . inner ,
124143 show_metrics : self . show_metrics ,
125144 show_statistics : self . show_statistics ,
145+ show_schema : self . show_schema ,
126146 }
127147 }
128148
@@ -179,6 +199,7 @@ impl<'a> DisplayableExecutionPlan<'a> {
179199 plan : & ' a dyn ExecutionPlan ,
180200 show_metrics : ShowMetrics ,
181201 show_statistics : bool ,
202+ show_schema : bool ,
182203 }
183204
184205 impl < ' a > fmt:: Display for Wrapper < ' a > {
@@ -189,6 +210,7 @@ impl<'a> DisplayableExecutionPlan<'a> {
189210 indent : 0 ,
190211 show_metrics : self . show_metrics ,
191212 show_statistics : self . show_statistics ,
213+ show_schema : self . show_schema ,
192214 } ;
193215 visitor. pre_visit ( self . plan ) ?;
194216 Ok ( ( ) )
@@ -199,6 +221,7 @@ impl<'a> DisplayableExecutionPlan<'a> {
199221 plan : self . inner ,
200222 show_metrics : self . show_metrics ,
201223 show_statistics : self . show_statistics ,
224+ show_schema : self . show_schema ,
202225 }
203226 }
204227
@@ -221,6 +244,14 @@ enum ShowMetrics {
221244}
222245
223246/// Formats plans with a single line per node.
247+ ///
248+ /// # Example
249+ ///
250+ /// ```text
251+ /// ProjectionExec: expr=[column1@0 + 2 as column1 + Int64(2)]
252+ /// FilterExec: column1@0 = 5
253+ /// ValuesExec
254+ /// ```
224255struct IndentVisitor < ' a , ' b > {
225256 /// How to format each node
226257 t : DisplayFormatType ,
@@ -232,6 +263,8 @@ struct IndentVisitor<'a, 'b> {
232263 show_metrics : ShowMetrics ,
233264 /// If statistics should be displayed
234265 show_statistics : bool ,
266+ /// If schema should be displayed
267+ show_schema : bool ,
235268}
236269
237270impl < ' a , ' b > ExecutionPlanVisitor for IndentVisitor < ' a , ' b > {
@@ -265,6 +298,13 @@ impl<'a, 'b> ExecutionPlanVisitor for IndentVisitor<'a, 'b> {
265298 let stats = plan. statistics ( ) . map_err ( |_e| fmt:: Error ) ?;
266299 write ! ( self . f, ", statistics=[{}]" , stats) ?;
267300 }
301+ if self . show_schema {
302+ write ! (
303+ self . f,
304+ ", schema={}" ,
305+ display_schema( plan. schema( ) . as_ref( ) )
306+ ) ?;
307+ }
268308 writeln ! ( self . f) ?;
269309 self . indent += 1 ;
270310 Ok ( true )
@@ -465,12 +505,13 @@ mod tests {
465505 use std:: fmt:: Write ;
466506 use std:: sync:: Arc ;
467507
468- use super :: DisplayableExecutionPlan ;
469- use crate :: { DisplayAs , ExecutionPlan , PlanProperties } ;
470-
471508 use datafusion_common:: { DataFusionError , Result , Statistics } ;
472509 use datafusion_execution:: { SendableRecordBatchStream , TaskContext } ;
473510
511+ use crate :: { DisplayAs , ExecutionPlan , PlanProperties } ;
512+
513+ use super :: DisplayableExecutionPlan ;
514+
474515 #[ derive( Debug , Clone , Copy ) ]
475516 enum TestStatsExecPlan {
476517 Panic ,
0 commit comments