Skip to content

Commit 2aab559

Browse files
zhuqi-lucasclaude
andauthored
Fix FilterExec tree render missing fetch display (#21230)
## Which issue does this PR close? Closes #21229 ## Rationale for this change When `FilterExec` has a `fetch` value (from limit pushdown), `EXPLAIN FORMAT TREE` does not show it, while `EXPLAIN` (default/verbose) correctly shows `fetch=N`. This makes the tree format output incomplete and can be confusing when debugging query plans. ## What changes are included in this PR? - Add `fetch` display to `FilterExec::fmt_as` for `TreeRender` format - Add sqllogictest to verify `fetch` appears in tree format output ## How are these changes tested? - Existing `limit` sqllogictests pass - New sqllogictest added to verify `fetch` is shown in `EXPLAIN FORMAT TREE` ## Are these changes safe? Yes — display-only change, no execution logic affected. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 51d06df commit 2aab559

File tree

3 files changed

+71
-45
lines changed

3 files changed

+71
-45
lines changed

datafusion/physical-plan/src/filter.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,9 @@ impl DisplayAs for FilterExec {
505505
)
506506
}
507507
DisplayFormatType::TreeRender => {
508+
if let Some(fetch) = self.fetch {
509+
writeln!(f, "fetch={fetch}")?;
510+
}
508511
write!(f, "predicate={}", fmt_sql(self.predicate.as_ref()))
509512
}
510513
}

datafusion/sqllogictest/test_files/explain_tree.slt

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,24 +1551,26 @@ physical_plan
15511551
09)┌─────────────┴─────────────┐
15521552
10)│ FilterExec │
15531553
11)│ -------------------- │
1554-
12)│ predicate: │
1555-
13)│ date = 2006-01-02 │
1556-
14)└─────────────┬─────────────┘
1557-
15)┌─────────────┴─────────────┐
1558-
16)│ RepartitionExec │
1559-
17)│ -------------------- │
1560-
18)│ partition_count(in->out): │
1561-
19)│ 1 -> 4 │
1562-
20)│ │
1563-
21)│ partitioning_scheme: │
1564-
22)│ RoundRobinBatch(4) │
1565-
23)└─────────────┬─────────────┘
1566-
24)┌─────────────┴─────────────┐
1567-
25)│ StreamingTableExec │
1568-
26)│ -------------------- │
1569-
27)│ infinite: true │
1570-
28)│ limit: None │
1571-
29)└───────────────────────────┘
1554+
12)│ fetch: 5 │
1555+
13)│ │
1556+
14)│ predicate: │
1557+
15)│ date = 2006-01-02 │
1558+
16)└─────────────┬─────────────┘
1559+
17)┌─────────────┴─────────────┐
1560+
18)│ RepartitionExec │
1561+
19)│ -------------------- │
1562+
20)│ partition_count(in->out): │
1563+
21)│ 1 -> 4 │
1564+
22)│ │
1565+
23)│ partitioning_scheme: │
1566+
24)│ RoundRobinBatch(4) │
1567+
25)└─────────────┬─────────────┘
1568+
26)┌─────────────┴─────────────┐
1569+
27)│ StreamingTableExec │
1570+
28)│ -------------------- │
1571+
29)│ infinite: true │
1572+
30)│ limit: None │
1573+
31)└───────────────────────────┘
15721574

15731575

15741576

@@ -1775,15 +1777,16 @@ physical_plan
17751777
40)┌─────────────┴─────────────┐
17761778
41)│ FilterExec │
17771779
42)│ -------------------- │
1778-
43)│ predicate: a > 3 │
1779-
44)└─────────────┬─────────────┘
1780-
45)┌─────────────┴─────────────┐
1781-
46)│ DataSourceExec │
1782-
47)│ -------------------- │
1783-
48)│ bytes: 160 │
1784-
49)│ format: memory │
1785-
50)│ rows: 1 │
1786-
51)└───────────────────────────┘
1780+
43)│ fetch: 9 │
1781+
44)│ predicate: a > 3 │
1782+
45)└─────────────┬─────────────┘
1783+
46)┌─────────────┴─────────────┐
1784+
47)│ DataSourceExec │
1785+
48)│ -------------------- │
1786+
49)│ bytes: 160 │
1787+
50)│ format: memory │
1788+
51)│ rows: 1 │
1789+
52)└───────────────────────────┘
17871790

17881791
# clean up
17891792
statement ok
@@ -1815,23 +1818,24 @@ physical_plan
18151818
06)┌─────────────┴─────────────┐
18161819
07)│ FilterExec │
18171820
08)│ -------------------- │
1818-
09)│ predicate: c3 > 0 │
1819-
10)└─────────────┬─────────────┘
1820-
11)┌─────────────┴─────────────┐
1821-
12)│ RepartitionExec │
1822-
13)│ -------------------- │
1823-
14)│ partition_count(in->out): │
1824-
15)│ 1 -> 4 │
1825-
16)│ │
1826-
17)│ partitioning_scheme: │
1827-
18)│ RoundRobinBatch(4) │
1828-
19)└─────────────┬─────────────┘
1829-
20)┌─────────────┴─────────────┐
1830-
21)│ StreamingTableExec │
1831-
22)│ -------------------- │
1832-
23)│ infinite: true │
1833-
24)│ limit: None │
1834-
25)└───────────────────────────┘
1821+
09)│ fetch: 5 │
1822+
10)│ predicate: c3 > 0 │
1823+
11)└─────────────┬─────────────┘
1824+
12)┌─────────────┴─────────────┐
1825+
13)│ RepartitionExec │
1826+
14)│ -------------------- │
1827+
15)│ partition_count(in->out): │
1828+
16)│ 1 -> 4 │
1829+
17)│ │
1830+
18)│ partitioning_scheme: │
1831+
19)│ RoundRobinBatch(4) │
1832+
20)└─────────────┬─────────────┘
1833+
21)┌─────────────┴─────────────┐
1834+
22)│ StreamingTableExec │
1835+
23)│ -------------------- │
1836+
24)│ infinite: true │
1837+
25)│ limit: None │
1838+
26)└───────────────────────────┘
18351839

18361840
# Test explain tree for PlaceholderRowExec
18371841
query TT

datafusion/sqllogictest/test_files/limit.slt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,25 @@ SELECT COUNT(*) FROM (SELECT a FROM t1 WHERE a > 3 LIMIT 3 OFFSET 6);
385385
----
386386
1
387387

388+
# Verify that EXPLAIN FORMAT TREE shows fetch on FilterExec
389+
query TT
390+
EXPLAIN FORMAT TREE SELECT a FROM t1 WHERE a > 3 LIMIT 5;
391+
----
392+
physical_plan
393+
01)┌───────────────────────────┐
394+
02)│ FilterExec │
395+
03)│ -------------------- │
396+
04)│ fetch: 5 │
397+
05)│ predicate: a > 3 │
398+
06)└─────────────┬─────────────┘
399+
07)┌─────────────┴─────────────┐
400+
08)│ DataSourceExec │
401+
09)│ -------------------- │
402+
10)│ bytes: 160 │
403+
11)│ format: memory │
404+
12)│ rows: 1 │
405+
13)└───────────────────────────┘
406+
388407
# generate BIGINT data from 1 to 1000 in multiple partitions
389408
statement ok
390409
CREATE TABLE t1000 (i BIGINT) AS
@@ -867,7 +886,7 @@ limit 1000;
867886

868887
# Config reset
869888

870-
# The SLT runner sets `target_partitions` to 4 instead of using the default, so
889+
# The SLT runner sets `target_partitions` to 4 instead of using the default, so
871890
# reset it explicitly.
872891
statement ok
873892
set datafusion.execution.target_partitions = 4;

0 commit comments

Comments
 (0)