Skip to content

Commit f0b86fc

Browse files
irenjjalamb
andauthored
Implement tree explain for BoundedWindowAggExec and WindowAggExec (#15084)
* Implement `tree explain for `BoundedWindowAggExec` and `WindowAggExec` * fix clippy * add bounded win agg test * add test * remove * merge --------- Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
1 parent 55ec83b commit f0b86fc

File tree

3 files changed

+233
-4
lines changed

3 files changed

+233
-4
lines changed

datafusion/physical-plan/src/windows/bounded_window_agg_exec.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,15 @@ impl DisplayAs for BoundedWindowAggExec {
253253
write!(f, "wdw=[{}], mode=[{:?}]", g.join(", "), mode)?;
254254
}
255255
DisplayFormatType::TreeRender => {
256-
// TODO: collect info
257-
write!(f, "")?;
256+
let g: Vec<String> = self
257+
.window_expr
258+
.iter()
259+
.map(|e| e.name().to_owned().to_string())
260+
.collect();
261+
writeln!(f, "select_list={}", g.join(", "))?;
262+
263+
let mode = &self.input_order_mode;
264+
writeln!(f, "mode={:?}", mode)?;
258265
}
259266
}
260267
Ok(())

datafusion/physical-plan/src/windows/window_agg_exec.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,12 @@ impl DisplayAs for WindowAggExec {
182182
write!(f, "wdw=[{}]", g.join(", "))?;
183183
}
184184
DisplayFormatType::TreeRender => {
185-
// TODO: collect info
186-
write!(f, "")?;
185+
let g: Vec<String> = self
186+
.window_expr
187+
.iter()
188+
.map(|e| e.name().to_owned().to_string())
189+
.collect();
190+
writeln!(f, "select_list={}", g.join(", "))?;
187191
}
188192
}
189193
Ok(())

datafusion/sqllogictest/test_files/explain_tree.slt

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,142 @@ physical_plan
577577
17)│ format: arrow │
578578
18)└───────────────────────────┘
579579

580+
581+
# Query with window agg.
582+
query TT
583+
explain select count(*) over() from table1;
584+
----
585+
logical_plan
586+
01)Projection: count(Int64(1)) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING AS count(*) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
587+
02)--WindowAggr: windowExpr=[[count(Int64(1)) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING]]
588+
03)----TableScan: table1 projection=[]
589+
physical_plan
590+
01)┌───────────────────────────┐
591+
02)│ ProjectionExec │
592+
03)│ -------------------- │
593+
04)│ count(*) ROWS BETWEEN │
594+
05)│ UNBOUNDED PRECEDING │
595+
06)│ AND UNBOUNDED FOLLOWING: │
596+
07)│ count(Int64(1)) ROWS │
597+
08)│ BETWEEN UNBOUNDED │
598+
09)│ PRECEDING AND UNBOUNDED │
599+
10)│ FOLLOWING@0 │
600+
11)└─────────────┬─────────────┘
601+
12)┌─────────────┴─────────────┐
602+
13)│ WindowAggExec │
603+
14)│ -------------------- │
604+
15)│ select_list: │
605+
16)│ count(Int64(1)) ROWS │
606+
17)│ BETWEEN UNBOUNDED │
607+
18)│ PRECEDING AND UNBOUNDED │
608+
19)│ FOLLOWING │
609+
20)└─────────────┬─────────────┘
610+
21)┌─────────────┴─────────────┐
611+
22)│ DataSourceExec │
612+
23)│ -------------------- │
613+
24)│ files: 1 │
614+
25)│ format: csv │
615+
26)└───────────────────────────┘
616+
617+
# Query with bounded window agg.
618+
query TT
619+
explain SELECT
620+
v1,
621+
SUM(v1) OVER (ORDER BY v1 ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS rolling_sum
622+
FROM generate_series(1, 1000) AS t1(v1);
623+
----
624+
logical_plan
625+
01)Projection: t1.v1, sum(t1.v1) ORDER BY [t1.v1 ASC NULLS LAST] ROWS BETWEEN 1 PRECEDING AND CURRENT ROW AS rolling_sum
626+
02)--WindowAggr: windowExpr=[[sum(t1.v1) ORDER BY [t1.v1 ASC NULLS LAST] ROWS BETWEEN 1 PRECEDING AND CURRENT ROW]]
627+
03)----SubqueryAlias: t1
628+
04)------Projection: tmp_table.value AS v1
629+
05)--------TableScan: tmp_table projection=[value]
630+
physical_plan
631+
01)┌───────────────────────────┐
632+
02)│ ProjectionExec │
633+
03)│ -------------------- │
634+
04)│ rolling_sum: │
635+
05)│ sum(t1.v1) ORDER BY [t1.v1│
636+
06)│ ASC NULLS LAST] ROWS │
637+
07)│ BETWEEN 1 PRECEDING │
638+
08)│ AND CURRENT ROW@1 │
639+
09)│ │
640+
10)│ v1: v1@0 │
641+
11)└─────────────┬─────────────┘
642+
12)┌─────────────┴─────────────┐
643+
13)│ BoundedWindowAggExec │
644+
14)│ -------------------- │
645+
15)│ mode: Sorted │
646+
16)│ │
647+
17)│ select_list: │
648+
18)│ sum(t1.v1) ORDER BY [t1.v1│
649+
19)│ ASC NULLS LAST] ROWS │
650+
20)│ BETWEEN 1 PRECEDING │
651+
21)│ AND CURRENT ROW │
652+
22)└─────────────┬─────────────┘
653+
23)┌─────────────┴─────────────┐
654+
24)│ SortExec │
655+
25)│ -------------------- │
656+
26)│ sort keys: │
657+
27)│ [v1@0 ASC NULLS LAST] │
658+
28)└─────────────┬─────────────┘
659+
29)┌─────────────┴─────────────┐
660+
30)│ ProjectionExec │
661+
31)│ -------------------- │
662+
32)│ v1: value@0 │
663+
33)└─────────────┬─────────────┘
664+
34)┌─────────────┴─────────────┐
665+
35)│ LazyMemoryExec │
666+
36)└───────────────────────────┘
667+
668+
query TT
669+
explain select
670+
count(*) over(),
671+
row_number() over ()
672+
from table1
673+
----
674+
logical_plan
675+
01)Projection: count(Int64(1)) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING AS count(*) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING, row_number() ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
676+
02)--WindowAggr: windowExpr=[[count(Int64(1)) ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING, row_number() ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING]]
677+
03)----TableScan: table1 projection=[]
678+
physical_plan
679+
01)┌───────────────────────────┐
680+
02)│ ProjectionExec │
681+
03)│ -------------------- │
682+
04)│ count(*) ROWS BETWEEN │
683+
05)│ UNBOUNDED PRECEDING │
684+
06)│ AND UNBOUNDED FOLLOWING: │
685+
07)│ count(Int64(1)) ROWS │
686+
08)│ BETWEEN UNBOUNDED │
687+
09)│ PRECEDING AND UNBOUNDED │
688+
10)│ FOLLOWING@0 │
689+
11)│ │
690+
12)│ row_number() ROWS BETWEEN │
691+
13)│ UNBOUNDED PRECEDING AND │
692+
14)│ UNBOUNDED FOLLOWING: │
693+
15)│ row_number() ROWS BETWEEN │
694+
16)│ UNBOUNDED PRECEDING AND │
695+
17)│ UNBOUNDED FOLLOWING@1 │
696+
18)└─────────────┬─────────────┘
697+
19)┌─────────────┴─────────────┐
698+
20)│ WindowAggExec │
699+
21)│ -------------------- │
700+
22)│ select_list: │
701+
23)│ count(Int64(1)) ROWS │
702+
24)│ BETWEEN UNBOUNDED │
703+
25)│ PRECEDING AND UNBOUNDED │
704+
26)│ FOLLOWING, row_number() │
705+
27)│ ROWS BETWEEN UNBOUNDED │
706+
28)│ PRECEDING AND UNBOUNDED │
707+
29)│ FOLLOWING │
708+
30)└─────────────┬─────────────┘
709+
31)┌─────────────┴─────────────┐
710+
32)│ DataSourceExec │
711+
33)│ -------------------- │
712+
34)│ files: 1 │
713+
35)│ format: csv │
714+
36)└───────────────────────────┘
715+
580716
# Query for sort.
581717
query TT
582718
explain SELECT * FROM table1 ORDER BY string_col;
@@ -653,6 +789,88 @@ physical_plan
653789
20)│ format: csv │
654790
21)└───────────────────────────┘
655791

792+
query TT
793+
explain select
794+
rank() over(ORDER BY int_col DESC),
795+
row_number() over (ORDER BY int_col ASC)
796+
from table1
797+
----
798+
logical_plan
799+
01)Projection: rank() ORDER BY [table1.int_col DESC NULLS FIRST] RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, row_number() ORDER BY [table1.int_col ASC NULLS LAST] RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
800+
02)--WindowAggr: windowExpr=[[row_number() ORDER BY [table1.int_col ASC NULLS LAST] RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW]]
801+
03)----WindowAggr: windowExpr=[[rank() ORDER BY [table1.int_col DESC NULLS FIRST] RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW]]
802+
04)------TableScan: table1 projection=[int_col]
803+
physical_plan
804+
01)┌───────────────────────────┐
805+
02)│ ProjectionExec │
806+
03)│ -------------------- │
807+
04)│ rank() ORDER BY [table1 │
808+
05)│ .int_col DESC NULLS │
809+
06)│ FIRST] RANGE BETWEEN │
810+
07)│ UNBOUNDED PRECEDING AND │
811+
08)│ CURRENT ROW: │
812+
09)│ rank() ORDER BY [table1 │
813+
10)│ .int_col DESC NULLS │
814+
11)│ FIRST] RANGE BETWEEN │
815+
12)│ UNBOUNDED PRECEDING AND │
816+
13)│ CURRENT ROW@1 │
817+
14)│ │
818+
15)│ row_number() ORDER BY │
819+
16)│ [table1.int_col ASC │
820+
17)│ NULLS LAST] RANGE │
821+
18)│ BETWEEN UNBOUNDED │
822+
19)│ PRECEDING AND CURRENT │
823+
20)│ ROW: │
824+
21)│ row_number() ORDER BY │
825+
22)│ [table1.int_col ASC │
826+
23)│ NULLS LAST] RANGE │
827+
24)│ BETWEEN UNBOUNDED │
828+
25)│ PRECEDING AND CURRENT │
829+
26)│ ROW@2 │
830+
27)└─────────────┬─────────────┘
831+
28)┌─────────────┴─────────────┐
832+
29)│ BoundedWindowAggExec │
833+
30)│ -------------------- │
834+
31)│ mode: Sorted │
835+
32)│ │
836+
33)│ select_list: │
837+
34)│ row_number() ORDER BY │
838+
35)│ [table1.int_col ASC │
839+
36)│ NULLS LAST] RANGE │
840+
37)│ BETWEEN UNBOUNDED │
841+
38)│ PRECEDING AND CURRENT │
842+
39)│ ROW │
843+
40)└─────────────┬─────────────┘
844+
41)┌─────────────┴─────────────┐
845+
42)│ SortExec │
846+
43)│ -------------------- │
847+
44)│ sort keys: │
848+
45)│ [int_col@0 ASC NULLS LAST]│
849+
46)└─────────────┬─────────────┘
850+
47)┌─────────────┴─────────────┐
851+
48)│ BoundedWindowAggExec │
852+
49)│ -------------------- │
853+
50)│ mode: Sorted │
854+
51)│ │
855+
52)│ select_list: │
856+
53)│ rank() ORDER BY [table1 │
857+
54)│ .int_col DESC NULLS │
858+
55)│ FIRST] RANGE BETWEEN │
859+
56)│ UNBOUNDED PRECEDING AND │
860+
57)│ CURRENT ROW │
861+
58)└─────────────┬─────────────┘
862+
59)┌─────────────┴─────────────┐
863+
60)│ SortExec │
864+
61)│ -------------------- │
865+
62)│ sort keys: │
866+
63)│ [int_col@0 DESC] │
867+
64)└─────────────┬─────────────┘
868+
65)┌─────────────┴─────────────┐
869+
66)│ DataSourceExec │
870+
67)│ -------------------- │
871+
68)│ files: 1 │
872+
69)│ format: csv │
873+
70)└───────────────────────────┘
656874

657875
# Query with projection on parquet
658876
query TT

0 commit comments

Comments
 (0)