fix: unnest_subqueries produces invalid column references when subquery contains a UNION#7667
Merged
georgesittas merged 6 commits intoMay 22, 2026
Conversation
added 5 commits
May 22, 2026 08:15
…ry contains a UNION When a NOT IN subquery is a SetOperation (UNION/UNION ALL), the wrapper SELECT was built by copying inner qualified column references verbatim (e.g. child_table.col_a). But the FROM source is the new subquery alias, so those table-qualified references are invalid in that scope. Fix by building proper column references using the derived alias: exp.column(s.alias_or_name, inner_alias) Fixes tobymao#7666
Contributor
Author
|
dear team, there was a but in the old test. could you please have a careful look? thanks |
Contributor
Author
|
tbh, that test in optimizer.sql seems redundant and/or misplaced (and does not have a title) but I just corrected it. your call what to do with it |
geooo109
approved these changes
May 22, 2026
Collaborator
There was a problem hiding this comment.
LGTM
A note here (future work):
CREATE TABLE x AS SELECT * FROM (VALUES (1),(2),(3),(4)) AS t(a);
CREATE TABLE y AS SELECT * FROM (VALUES (1),(NULL)) AS t(a);
CREATE TABLE z AS SELECT * FROM (VALUES (2),(3)) AS t(a);
SELECT * FROM x WHERE x.a NOT IN (SELECT y.a AS a FROM y UNION ALL SELECT z.a AS a FROM z);
For this case ^ in duckdb the optimized query doesn't match the semantics of the input.
georgesittas
approved these changes
May 22, 2026
Comment on lines
-1454
to
+1457
| "cascade"."tag_input" AS "tagname" | ||
| "_u_0"."tagname" AS "tagname" | ||
| FROM "_u_0" AS "_u_0" | ||
| GROUP BY | ||
| "cascade"."tag_input" | ||
| "_u_0"."tagname" |
Collaborator
There was a problem hiding this comment.
This is embarassing, seems like I didn't notice this at all when I added the test...
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.
Fixes #7666
Problem
When
unnest_subqueriesencounters aSetOperation(UNION/UNION ALL) subquery, it wraps it in a derived table:select.selectsreturns the fully-qualified column expressions from the left branch of the UNION (e.g.child_table.col_a AS col_a). These are copied verbatim into the outer wrapper SELECT, but the FROM source is the new subquery alias_u_0, making the column references invalid in that scope.Fix
Build column references that point to the derived alias instead of copying the inner expressions:
Reproducer
Before:
child_table.col_areferenced inside a scope where only_u_0exists.After:
_u_0.col_a— correctly qualified against the derived alias.