Repository navigation
Conversation
A `Projection` with no expressions (as `optimize_projections` leaves
under `count(*)` when a filter column is not otherwise needed) was
unparsed as `SELECT FROM ...` regardless of
`Dialect::supports_empty_select_list`. Only the `TableScan` path
consulted the dialect, so e.g. BigQuery received
SELECT COUNT(1) FROM (SELECT FROM `t` WHERE ...)
and rejected it with "SELECT list must not be empty".
`reconstruct_select_statement` now uses `empty_projection_fallback`
for an empty projection, the same as the table scan path: `SELECT 1`
for dialects without empty select lists, unchanged for PostgreSQL.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Which issue does this PR close?
Rationale for this change
Unparsing the optimized plan of
select count(*) from t where id > 10producesSELECT count(1) AS "count(*)" FROM (SELECT FROM t WHERE (t.id > 10)), even for dialects whosesupports_empty_select_list()isfalse. Engines that don't accept an empty select list, such as BigQuery ("SELECT list must not be empty"), reject the generated SQL.optimize_projectionsprunes the filter column above theFilter, which leaves aProjectionwith no expressions. #19221 added theSELECT 1fallback for empty projections, but only theTableScanpath uses it.What changes are included in this PR?
reconstruct_select_statementnow usesempty_projection_fallback()when theProjectionhas no expressions, the same as theTableScanpath. Dialects without empty select list support getSELECT 1 FROM .... PostgreSQL output is unchanged (SELECT FROM ...).Are these changes tested?
Yes.
datafusion/core/tests/sql/unparser.rs:optimized_count_over_filter_empty_projectionruns the real query through the optimizer and unparser. It fails without the fix.datafusion/sql/tests/cases/plan_to_sql.rs: snapshot tests for an emptyProjectionnode with the default, PostgreSQL and BigQuery dialects.Are there any user-facing changes?
Yes, generated SQL changes for dialects that don't support an empty select list: an empty
Projectionnow unparses asSELECT 1 FROM ...instead ofSELECT FROM .... There are no public API changes.🤖 Generated with Claude Code