@@ -55,6 +55,59 @@ impl PhysicalPlan {
5555 ) -> Result < FormatTreeNode < String > > {
5656 to_format_tree ( self , & metadata, & prof_span_set)
5757 }
58+
59+ pub fn format_join ( & self , metadata : & MetadataRef ) -> Result < FormatTreeNode < String > > {
60+ match self {
61+ PhysicalPlan :: TableScan ( plan) => {
62+ if plan. table_index == DUMMY_TABLE_INDEX {
63+ return Ok ( FormatTreeNode :: with_children (
64+ format ! ( "Scan: dummy, rows: {}" , plan. source. statistics. read_rows) ,
65+ vec ! [ ] ,
66+ ) ) ;
67+ }
68+ let table = metadata. read ( ) . table ( plan. table_index ) . clone ( ) ;
69+ let table_name =
70+ format ! ( "{}.{}.{}" , table. catalog( ) , table. database( ) , table. name( ) ) ;
71+
72+ Ok ( FormatTreeNode :: with_children (
73+ format ! (
74+ "Scan: {}, rows: {}" ,
75+ table_name, plan. source. statistics. read_rows
76+ ) ,
77+ vec ! [ ] ,
78+ ) )
79+ }
80+ PhysicalPlan :: HashJoin ( plan) => {
81+ let build_child = plan. build . format_join ( metadata) ?;
82+ let probe_child = plan. probe . format_join ( metadata) ?;
83+
84+ let children = vec ! [
85+ FormatTreeNode :: with_children( "Build" . to_string( ) , vec![ build_child] ) ,
86+ FormatTreeNode :: with_children( "Probe" . to_string( ) , vec![ probe_child] ) ,
87+ ] ;
88+
89+ Ok ( FormatTreeNode :: with_children (
90+ format ! ( "HashJoin: {}" , plan. join_type) ,
91+ children,
92+ ) )
93+ }
94+ other => {
95+ let children = other
96+ . children ( )
97+ . map ( |child| child. format_join ( metadata) )
98+ . collect :: < Result < Vec < FormatTreeNode < String > > > > ( ) ?;
99+
100+ if children. len ( ) == 1 {
101+ Ok ( children[ 0 ] . clone ( ) )
102+ } else {
103+ Ok ( FormatTreeNode :: with_children (
104+ format ! ( "{:?}" , other) ,
105+ children,
106+ ) )
107+ }
108+ }
109+ }
110+ }
58111}
59112
60113fn to_format_tree (
0 commit comments