Skip to content

Commit 2fbdb97

Browse files
Standing-Manalamb
andauthored
feat: implement tree explain for ProjectionExec (#15082)
* feat: implement tree explain for ProjectionExec Signed-off-by: Alan Tang <[email protected]> * feat(test): support more tests Signed-off-by: Alan Tang <[email protected]> * chore(explain): Reduce redundant output Signed-off-by: Alan Tang <[email protected]> * Propose a different projection formatting * feat: add project exec tree rendering for hash join --------- Signed-off-by: Alan Tang <[email protected]> Co-authored-by: Andrew Lamb <[email protected]>
1 parent 618880e commit 2fbdb97

File tree

2 files changed

+215
-28
lines changed

2 files changed

+215
-28
lines changed

datafusion/physical-plan/src/projection.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,15 @@ impl DisplayAs for ProjectionExec {
168168
write!(f, "ProjectionExec: expr=[{}]", expr.join(", "))
169169
}
170170
DisplayFormatType::TreeRender => {
171-
// TODO: collect info
172-
write!(f, "")
171+
for (i, (e, alias)) in self.expr().iter().enumerate() {
172+
let e = e.to_string();
173+
if &e == alias {
174+
writeln!(f, "expr{i}={e}")?;
175+
} else {
176+
writeln!(f, "{alias}={e}")?;
177+
}
178+
}
179+
Ok(())
173180
}
174181
}
175182
}

datafusion/sqllogictest/test_files/explain_tree.slt

+206-26
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,158 @@ physical_plan
539539
17)│ format: arrow │
540540
18)└───────────────────────────┘
541541

542+
# Query with projection on csv
543+
query TT
544+
explain SELECT int_col, bigint_col, int_col+bigint_col AS sum_col FROM table1;
545+
----
546+
logical_plan
547+
01)Projection: table1.int_col, table1.bigint_col, CAST(table1.int_col AS Int64) + table1.bigint_col AS sum_col
548+
02)--TableScan: table1 projection=[int_col, bigint_col]
549+
physical_plan
550+
01)┌───────────────────────────┐
551+
02)│ ProjectionExec │
552+
03)│ -------------------- │
553+
04)│ bigint_col: │
554+
05)│ bigint_col@1 │
555+
06)│ │
556+
07)│ int_col: int_col@0 │
557+
08)│ │
558+
09)│ sum_col: │
559+
10)│ CAST(int_col@0 AS Int64) +│
560+
11)│ bigint_col@1 │
561+
12)└─────────────┬─────────────┘
562+
13)┌─────────────┴─────────────┐
563+
14)│ RepartitionExec │
564+
15)└─────────────┬─────────────┘
565+
16)┌─────────────┴─────────────┐
566+
17)│ DataSourceExec │
567+
18)│ -------------------- │
568+
19)│ files: 1 │
569+
20)│ format: csv │
570+
21)└───────────────────────────┘
571+
572+
573+
# Query with projection on parquet
574+
query TT
575+
explain SELECT int_col, bigint_col, int_col+bigint_col AS sum_col FROM table2;
576+
----
577+
logical_plan
578+
01)Projection: table2.int_col, table2.bigint_col, CAST(table2.int_col AS Int64) + table2.bigint_col AS sum_col
579+
02)--TableScan: table2 projection=[int_col, bigint_col]
580+
physical_plan
581+
01)┌───────────────────────────┐
582+
02)│ ProjectionExec │
583+
03)│ -------------------- │
584+
04)│ bigint_col: │
585+
05)│ bigint_col@1 │
586+
06)│ │
587+
07)│ int_col: int_col@0 │
588+
08)│ │
589+
09)│ sum_col: │
590+
10)│ CAST(int_col@0 AS Int64) +│
591+
11)│ bigint_col@1 │
592+
12)└─────────────┬─────────────┘
593+
13)┌─────────────┴─────────────┐
594+
14)│ RepartitionExec │
595+
15)└─────────────┬─────────────┘
596+
16)┌─────────────┴─────────────┐
597+
17)│ DataSourceExec │
598+
18)│ -------------------- │
599+
19)│ files: 1 │
600+
20)│ format: parquet │
601+
21)└───────────────────────────┘
602+
603+
604+
# Query with projection on memory
605+
query TT
606+
explain SELECT int_col, bigint_col, int_col+bigint_col AS sum_col FROM table3;
607+
----
608+
logical_plan
609+
01)Projection: table3.int_col, table3.bigint_col, CAST(table3.int_col AS Int64) + table3.bigint_col AS sum_col
610+
02)--TableScan: table3 projection=[int_col, bigint_col]
611+
physical_plan
612+
01)┌───────────────────────────┐
613+
02)│ ProjectionExec │
614+
03)│ -------------------- │
615+
04)│ bigint_col: │
616+
05)│ bigint_col@1 │
617+
06)│ │
618+
07)│ int_col: int_col@0 │
619+
08)│ │
620+
09)│ sum_col: │
621+
10)│ CAST(int_col@0 AS Int64) +│
622+
11)│ bigint_col@1 │
623+
12)└─────────────┬─────────────┘
624+
13)┌─────────────┴─────────────┐
625+
14)│ DataSourceExec │
626+
15)│ -------------------- │
627+
16)│ bytes: 1560 │
628+
17)│ format: memory │
629+
18)│ rows: 1 │
630+
19)└───────────────────────────┘
631+
632+
633+
634+
# Query with projection on json
635+
query TT
636+
explain SELECT int_col, bigint_col, int_col+bigint_col AS sum_col FROM table4;
637+
----
638+
logical_plan
639+
01)Projection: table4.int_col, table4.bigint_col, table4.int_col + table4.bigint_col AS sum_col
640+
02)--TableScan: table4 projection=[bigint_col, int_col]
641+
physical_plan
642+
01)┌───────────────────────────┐
643+
02)│ ProjectionExec │
644+
03)│ -------------------- │
645+
04)│ bigint_col: │
646+
05)│ bigint_col@0 │
647+
06)│ │
648+
07)│ int_col: int_col@1 │
649+
08)│ │
650+
09)│ sum_col: │
651+
10)│ int_col@1 + bigint_col@0 │
652+
11)└─────────────┬─────────────┘
653+
12)┌─────────────┴─────────────┐
654+
13)│ RepartitionExec │
655+
14)└─────────────┬─────────────┘
656+
15)┌─────────────┴─────────────┐
657+
16)│ DataSourceExec │
658+
17)│ -------------------- │
659+
18)│ files: 1 │
660+
19)│ format: json │
661+
20)└───────────────────────────┘
662+
663+
664+
# Query with projection on arrow
665+
query TT
666+
explain SELECT int_col, bigint_col, int_col+bigint_col AS sum_col FROM table5;
667+
----
668+
logical_plan
669+
01)Projection: table5.int_col, table5.bigint_col, CAST(table5.int_col AS Int64) + table5.bigint_col AS sum_col
670+
02)--TableScan: table5 projection=[int_col, bigint_col]
671+
physical_plan
672+
01)┌───────────────────────────┐
673+
02)│ ProjectionExec │
674+
03)│ -------------------- │
675+
04)│ bigint_col: │
676+
05)│ bigint_col@1 │
677+
06)│ │
678+
07)│ int_col: int_col@0 │
679+
08)│ │
680+
09)│ sum_col: │
681+
10)│ CAST(int_col@0 AS Int64) +│
682+
11)│ bigint_col@1 │
683+
12)└─────────────┬─────────────┘
684+
13)┌─────────────┴─────────────┐
685+
14)│ RepartitionExec │
686+
15)└─────────────┬─────────────┘
687+
16)┌─────────────┴─────────────┐
688+
17)│ DataSourceExec │
689+
18)│ -------------------- │
690+
19)│ files: 1 │
691+
20)│ format: arrow │
692+
21)└───────────────────────────┘
693+
542694
# Query with PartialSortExec.
543695
query TT
544696
EXPLAIN SELECT *
@@ -614,19 +766,33 @@ physical_plan
614766
18)└─────────────┬─────────────┘└─────────────┬─────────────┘
615767
19)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
616768
20)│ ProjectionExec ││ RepartitionExec │
617-
21)└─────────────┬─────────────┘└─────────────┬─────────────┘
618-
22)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
619-
23)│ RepartitionExec ││ DataSourceExec │
620-
24)│ ││ -------------------- │
621-
25)│ ││ files: 1 │
622-
26)│ ││ format: parquet │
623-
27)└─────────────┬─────────────┘└───────────────────────────┘
624-
28)┌─────────────┴─────────────┐
625-
29)│ DataSourceExec │
626-
30)│ -------------------- │
627-
31)│ files: 1 │
628-
32)│ format: csv │
629-
33)└───────────────────────────┘
769+
21)│ -------------------- ││ │
770+
22)│ CAST(table1.string_col AS ││ │
771+
23)│ Utf8View): ││ │
772+
24)│ CAST(string_col@1 AS ││ │
773+
25)│ Utf8View) ││ │
774+
26)│ ││ │
775+
27)│ bigint_col: ││ │
776+
28)│ bigint_col@2 ││ │
777+
29)│ ││ │
778+
30)│ date_col: date_col@3 ││ │
779+
31)│ int_col: int_col@0 ││ │
780+
32)│ ││ │
781+
33)│ string_col: ││ │
782+
34)│ string_col@1 ││ │
783+
35)└─────────────┬─────────────┘└─────────────┬─────────────┘
784+
36)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
785+
37)│ RepartitionExec ││ DataSourceExec │
786+
38)│ ││ -------------------- │
787+
39)│ ││ files: 1 │
788+
40)│ ││ format: parquet │
789+
41)└─────────────┬─────────────┘└───────────────────────────┘
790+
42)┌─────────────┴─────────────┐
791+
43)│ DataSourceExec │
792+
44)│ -------------------- │
793+
45)│ files: 1 │
794+
46)│ format: csv │
795+
47)└───────────────────────────┘
630796

631797
# Query with outer hash join.
632798
query TT
@@ -659,19 +825,33 @@ physical_plan
659825
20)└─────────────┬─────────────┘└─────────────┬─────────────┘
660826
21)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
661827
22)│ ProjectionExec ││ RepartitionExec │
662-
23)└─────────────┬─────────────┘└─────────────┬─────────────┘
663-
24)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
664-
25)│ RepartitionExec ││ DataSourceExec │
665-
26)│ ││ -------------------- │
666-
27)│ ││ files: 1 │
667-
28)│ ││ format: parquet │
668-
29)└─────────────┬─────────────┘└───────────────────────────┘
669-
30)┌─────────────┴─────────────┐
670-
31)│ DataSourceExec │
671-
32)│ -------------------- │
672-
33)│ files: 1 │
673-
34)│ format: csv │
674-
35)└───────────────────────────┘
828+
23)│ -------------------- ││ │
829+
24)│ CAST(table1.string_col AS ││ │
830+
25)│ Utf8View): ││ │
831+
26)│ CAST(string_col@1 AS ││ │
832+
27)│ Utf8View) ││ │
833+
28)│ ││ │
834+
29)│ bigint_col: ││ │
835+
30)│ bigint_col@2 ││ │
836+
31)│ ││ │
837+
32)│ date_col: date_col@3 ││ │
838+
33)│ int_col: int_col@0 ││ │
839+
34)│ ││ │
840+
35)│ string_col: ││ │
841+
36)│ string_col@1 ││ │
842+
37)└─────────────┬─────────────┘└─────────────┬─────────────┘
843+
38)┌─────────────┴─────────────┐┌─────────────┴─────────────┐
844+
39)│ RepartitionExec ││ DataSourceExec │
845+
40)│ ││ -------------------- │
846+
41)│ ││ files: 1 │
847+
42)│ ││ format: parquet │
848+
43)└─────────────┬─────────────┘└───────────────────────────┘
849+
44)┌─────────────┴─────────────┐
850+
45)│ DataSourceExec │
851+
46)│ -------------------- │
852+
47)│ files: 1 │
853+
48)│ format: csv │
854+
49)└───────────────────────────┘
675855

676856
# cleanup
677857
statement ok

0 commit comments

Comments
 (0)