Skip to content

Commit bc2b36c

Browse files
authored
fix: SELECT * EXCLUDE(...) silently returns empty rows when all columns are excluded (apache#21259)
## Which issue does this PR close? - Closes apache#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 ```
1 parent f3e8291 commit bc2b36c

2 files changed

Lines changed: 23 additions & 14 deletions

File tree

datafusion/expr/src/logical_plan/builder.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,10 +1931,12 @@ fn project_with_validation(
19311931
expr: impl IntoIterator<Item = (impl Into<SelectExpr>, bool)>,
19321932
) -> Result<LogicalPlan> {
19331933
let mut projected_expr = vec![];
1934+
let mut has_wildcard = false;
19341935
for (e, validate) in expr {
19351936
let e = e.into();
19361937
match e {
19371938
SelectExpr::Wildcard(opt) => {
1939+
has_wildcard = true;
19381940
let expanded = expand_wildcard(plan.schema(), &plan, Some(&opt))?;
19391941

19401942
// If there is a REPLACE statement, replace that column with the given
@@ -1955,6 +1957,7 @@ fn project_with_validation(
19551957
}
19561958
}
19571959
SelectExpr::QualifiedWildcard(table_ref, opt) => {
1960+
has_wildcard = true;
19581961
let expanded =
19591962
expand_qualified_wildcard(&table_ref, plan.schema(), Some(&opt))?;
19601963

@@ -1984,6 +1987,12 @@ fn project_with_validation(
19841987
}
19851988
}
19861989
}
1990+
if has_wildcard && projected_expr.is_empty() && !plan.schema().fields().is_empty() {
1991+
return plan_err!(
1992+
"SELECT list is empty after resolving * expressions, \
1993+
the wildcard expanded to zero columns"
1994+
);
1995+
}
19871996
validate_unique_names("Projections", projected_expr.iter())?;
19881997

19891998
Projection::try_new(projected_expr, Arc::new(plan)).map(LogicalPlan::Projection)

datafusion/sqllogictest/test_files/select.slt

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,25 +1318,25 @@ statement error
13181318
SELECT * EXCLUDE(a, a)
13191319
FROM table1
13201320

1321-
# if EXCEPT all the columns, query should still succeed but return empty
1322-
statement ok
1321+
# if EXCEPT all the columns, query should return an error
1322+
statement error DataFusion error: Error during planning: SELECT list is empty after resolving \* expressions, the wildcard expanded to zero columns
13231323
SELECT * EXCEPT(a, b, c, d)
13241324
FROM table1
13251325

1326-
# try zero column with LIMIT, 1 row but empty
1327-
statement ok
1326+
# try zero column with LIMIT, should error
1327+
statement error DataFusion error: Error during planning: SELECT list is empty after resolving \* expressions, the wildcard expanded to zero columns
13281328
SELECT * EXCEPT (a, b, c, d)
13291329
FROM table1
13301330
LIMIT 1
13311331

1332-
# try zero column with GROUP BY, 2 row but empty
1333-
statement ok
1332+
# try zero column with GROUP BY, should error
1333+
statement error DataFusion error: Error during planning: SELECT list is empty after resolving \* expressions, the wildcard expanded to zero columns
13341334
SELECT * EXCEPT (a, b, c, d)
13351335
FROM table1
13361336
GROUP BY a
13371337

1338-
# try zero column with WHERE, 1 row but empty
1339-
statement ok
1338+
# try zero column with WHERE, should error
1339+
statement error DataFusion error: Error during planning: SELECT list is empty after resolving \* expressions, the wildcard expanded to zero columns
13401340
SELECT * EXCEPT (a, b, c, d)
13411341
FROM table1
13421342
WHERE a = 1
@@ -1352,15 +1352,15 @@ CREATE TABLE table2 (
13521352
(1, 10, 100, 1000),
13531353
(2, 20, 200, 2000);
13541354

1355-
# try zero column with inner JOIN, 2 row but empty
1356-
statement ok
1355+
# try zero column with inner JOIN, should error
1356+
statement error DataFusion error: Error during planning: SELECT list is empty after resolving \* expressions, the wildcard expanded to zero columns
13571357
WITH t1 AS (SELECT a AS t1_a FROM table1), t2 AS (SELECT a AS t2_a FROM table2)
13581358
SELECT * EXCEPT (t1_a, t2_a)
13591359
FROM t1
13601360
JOIN t2 ON (t1_a = t2_a)
13611361

1362-
# try zero column with more JOIN, 2 row but empty
1363-
statement ok
1362+
# try zero column with more JOIN, should error
1363+
statement error DataFusion error: Error during planning: SELECT list is empty after resolving \* expressions, the wildcard expanded to zero columns
13641364
SELECT * EXCEPT (b1, b2)
13651365
FROM (
13661366
SELECT b AS b1 FROM table1
@@ -1369,8 +1369,8 @@ JOIN (
13691369
SELECT b AS b2 FROM table2
13701370
) ON b1 = b2
13711371

1372-
# try zero column with Window, 2 row but empty
1373-
statement ok
1372+
# try zero column with Window, should error
1373+
statement error DataFusion error: Error during planning: SELECT list is empty after resolving \* expressions, the wildcard expanded to zero columns
13741374
SELECT * EXCEPT (a, b, row_num)
13751375
FROM (
13761376
SELECT

0 commit comments

Comments
 (0)