This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new bc2b36cf56 fix: `SELECT * EXCLUDE(...)` silently returns empty rows
when all columns are excluded (#21259)
bc2b36cf56 is described below
commit bc2b36cf56846e0c697b0f8b98619f346a72a9bf
Author: Zhen Chen <[email protected]>
AuthorDate: Wed Apr 1 14:33:06 2026 +0800
fix: `SELECT * EXCLUDE(...)` silently returns empty rows when all columns
are excluded (#21259)
## Which issue does this PR close?
- Closes #21258.
## Rationale for this change
When `SELECT * EXCLUDE(...)` or `SELECT * EXCEPT(...)` excludes every
column in the schema, DataFusion silently produces rows with zero
columns instead of failing at planning time. This is confusing and
inconsistent with DuckDB, which raises a clear `Binder Error: SELECT
list is empty after resolving * expressions!` at planning time.
## What changes are included in this PR?
- In `project_with_validation` (builder.rs), after expanding all
`Wildcard` and `QualifiedWildcard` expressions, added a check: if any
wildcard was present **and** the resulting projection list is empty,
return a `plan_err!` with the message `SELECT list is empty after
resolving * expressions, the wildcard expanded to zero columns`.
- Updated select.slt to change all existing "zero-column wildcard" test
cases (previously `statement ok`) to `statement error` asserting the new
error message. Cases updated include bare `SELECT * EXCEPT(all_cols)`,
with `LIMIT`, `WHERE`, `GROUP BY`, `JOIN`, and window functions.
## Are these changes tested?
Yes. The existing SQL logic tests in select.slt are updated to assert
the new planning error for all zero-column wildcard scenarios (`EXCLUDE`
and `EXCEPT`, with various clauses). This covers:
- `SELECT * EXCLUDE(a, b)` / `SELECT * EXCEPT(a, b, c, d)` on a plain
scan
- Combined with `LIMIT`, `WHERE`, `GROUP BY`, `JOIN`, and window
functions
- Qualified wildcards (`SELECT t.* EXCLUDE(...)`)
## Are there any user-facing changes?
Yes. Queries that previously silently returned empty-column result sets
via `SELECT * EXCLUDE(...)` or `SELECT * EXCEPT(...)` when all columns
were excluded will now fail at planning time with:
```
DataFusion error: Error during planning: SELECT list is empty after
resolving * expressions, the wildcard expanded to zero columns
```
---
datafusion/expr/src/logical_plan/builder.rs | 9 +++++++++
datafusion/sqllogictest/test_files/select.slt | 28 +++++++++++++--------------
2 files changed, 23 insertions(+), 14 deletions(-)
diff --git a/datafusion/expr/src/logical_plan/builder.rs
b/datafusion/expr/src/logical_plan/builder.rs
index 95c6010a34..e9f41670bd 100644
--- a/datafusion/expr/src/logical_plan/builder.rs
+++ b/datafusion/expr/src/logical_plan/builder.rs
@@ -1931,10 +1931,12 @@ fn project_with_validation(
expr: impl IntoIterator<Item = (impl Into<SelectExpr>, bool)>,
) -> Result<LogicalPlan> {
let mut projected_expr = vec![];
+ let mut has_wildcard = false;
for (e, validate) in expr {
let e = e.into();
match e {
SelectExpr::Wildcard(opt) => {
+ has_wildcard = true;
let expanded = expand_wildcard(plan.schema(), &plan,
Some(&opt))?;
// If there is a REPLACE statement, replace that column with
the given
@@ -1955,6 +1957,7 @@ fn project_with_validation(
}
}
SelectExpr::QualifiedWildcard(table_ref, opt) => {
+ has_wildcard = true;
let expanded =
expand_qualified_wildcard(&table_ref, plan.schema(),
Some(&opt))?;
@@ -1984,6 +1987,12 @@ fn project_with_validation(
}
}
}
+ if has_wildcard && projected_expr.is_empty() &&
!plan.schema().fields().is_empty() {
+ return plan_err!(
+ "SELECT list is empty after resolving * expressions, \
+ the wildcard expanded to zero columns"
+ );
+ }
validate_unique_names("Projections", projected_expr.iter())?;
Projection::try_new(projected_expr,
Arc::new(plan)).map(LogicalPlan::Projection)
diff --git a/datafusion/sqllogictest/test_files/select.slt
b/datafusion/sqllogictest/test_files/select.slt
index f37ec2233d..3e97dc4588 100644
--- a/datafusion/sqllogictest/test_files/select.slt
+++ b/datafusion/sqllogictest/test_files/select.slt
@@ -1318,25 +1318,25 @@ statement error
SELECT * EXCLUDE(a, a)
FROM table1
-# if EXCEPT all the columns, query should still succeed but return empty
-statement ok
+# if EXCEPT all the columns, query should return an error
+statement error DataFusion error: Error during planning: SELECT list is empty
after resolving \* expressions, the wildcard expanded to zero columns
SELECT * EXCEPT(a, b, c, d)
FROM table1
-# try zero column with LIMIT, 1 row but empty
-statement ok
+# try zero column with LIMIT, should error
+statement error DataFusion error: Error during planning: SELECT list is empty
after resolving \* expressions, the wildcard expanded to zero columns
SELECT * EXCEPT (a, b, c, d)
FROM table1
LIMIT 1
-# try zero column with GROUP BY, 2 row but empty
-statement ok
+# try zero column with GROUP BY, should error
+statement error DataFusion error: Error during planning: SELECT list is empty
after resolving \* expressions, the wildcard expanded to zero columns
SELECT * EXCEPT (a, b, c, d)
FROM table1
GROUP BY a
-# try zero column with WHERE, 1 row but empty
-statement ok
+# try zero column with WHERE, should error
+statement error DataFusion error: Error during planning: SELECT list is empty
after resolving \* expressions, the wildcard expanded to zero columns
SELECT * EXCEPT (a, b, c, d)
FROM table1
WHERE a = 1
@@ -1352,15 +1352,15 @@ CREATE TABLE table2 (
(1, 10, 100, 1000),
(2, 20, 200, 2000);
-# try zero column with inner JOIN, 2 row but empty
-statement ok
+# try zero column with inner JOIN, should error
+statement error DataFusion error: Error during planning: SELECT list is empty
after resolving \* expressions, the wildcard expanded to zero columns
WITH t1 AS (SELECT a AS t1_a FROM table1), t2 AS (SELECT a AS t2_a FROM table2)
SELECT * EXCEPT (t1_a, t2_a)
FROM t1
JOIN t2 ON (t1_a = t2_a)
-# try zero column with more JOIN, 2 row but empty
-statement ok
+# try zero column with more JOIN, should error
+statement error DataFusion error: Error during planning: SELECT list is empty
after resolving \* expressions, the wildcard expanded to zero columns
SELECT * EXCEPT (b1, b2)
FROM (
SELECT b AS b1 FROM table1
@@ -1369,8 +1369,8 @@ JOIN (
SELECT b AS b2 FROM table2
) ON b1 = b2
-# try zero column with Window, 2 row but empty
-statement ok
+# try zero column with Window, should error
+statement error DataFusion error: Error during planning: SELECT list is empty
after resolving \* expressions, the wildcard expanded to zero columns
SELECT * EXCEPT (a, b, row_num)
FROM (
SELECT
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]