From 6ca3f69bc108485bbfdff360480949949569fe81 Mon Sep 17 00:00:00 2001 From: Charles-Antoine Leger Date: Thu, 23 Apr 2026 11:40:46 +0200 Subject: [PATCH] feat(datafusion): show pushed-down limit in IcebergTableScan EXPLAIN output (#2360) ## Which issue does this PR close? - Closes #2359. ## What changes are included in this PR? Emit ` limit:[N]` in `IcebergTableScan`'s `DisplayAs` output when a `LIMIT` is pushed down to the scan. When no limit is pushed down, the output is unchanged. - Before (unchanged): `IcebergTableScan projection:[id,name] predicate:[...]` - After (new, only when a limit reaches the scan): `IcebergTableScan projection:[...] predicate:[] limit:[3]` ## Are these changes tested? Yes: new `EXPLAIN ... LIMIT 3` assertion in `crates/sqllogictest/testdata/slts/df_test/basic_queries.slt`. Existing snapshots are unchanged, which confirms the additive-only behavior. (cherry picked from commit c82c42eb20f4bb2b33bec7c53d52742404ac0b55) --- .../datafusion/src/physical_plan/scan.rs | 6 +++++- .../testdata/slts/df_test/basic_queries.slt | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/crates/integrations/datafusion/src/physical_plan/scan.rs b/crates/integrations/datafusion/src/physical_plan/scan.rs index 234ab26470..36539ae503 100644 --- a/crates/integrations/datafusion/src/physical_plan/scan.rs +++ b/crates/integrations/datafusion/src/physical_plan/scan.rs @@ -196,7 +196,11 @@ impl DisplayAs for IcebergTableScan { self.predicates .clone() .map_or(String::from(""), |p| format!("{p}")) - ) + )?; + if let Some(limit) = self.limit { + write!(f, " limit:[{limit}]")?; + } + Ok(()) } } diff --git a/crates/sqllogictest/testdata/slts/df_test/basic_queries.slt b/crates/sqllogictest/testdata/slts/df_test/basic_queries.slt index 5d8889f158..a5ca4de46a 100644 --- a/crates/sqllogictest/testdata/slts/df_test/basic_queries.slt +++ b/crates/sqllogictest/testdata/slts/df_test/basic_queries.slt @@ -43,6 +43,18 @@ INSERT INTO default.default.query_test_table VALUES ---- 10 +# Verify EXPLAIN shows limit is pushed down to IcebergTableScan +query TT +EXPLAIN SELECT * FROM default.default.query_test_table LIMIT 3 +---- +logical_plan +01)Limit: skip=0, fetch=3 +02)--TableScan: default.default.query_test_table projection=[id, name, score, category], fetch=3 +physical_plan +01)GlobalLimitExec: skip=0, fetch=3 +02)--CooperativeExec +03)----IcebergTableScan projection:[id,name,score,category] predicate:[] limit:[3] + # Test SELECT * with ORDER BY and LIMIT query ITRT SELECT * FROM default.default.query_test_table ORDER BY id LIMIT 3