MDEV-39522 Query with UNION fails in Oracle sql_mode with ER_BAD_FIELD_ERROR/ER_UNKNOWN_TABLE - #5461
Merged
Conversation
Contributor
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
…D_ERROR/ER_UNKNOWN_TABLE MDEV-37325 unconditionally wrapped union subqueries in derived tables, breaking name resolution of outer-scope/correlated references inside the unions (producing ER_UNKNOWN_TABLE errors). Delay the wrap until a following operator has a different linkage. In Oracle mode all set operators share one priority and bind left-to-right, so wrapping the accumulated prefix on each operator change enforces it. This also corrects the row multiplicity of mixed set operations toward left-to-right order. create_priority_nest(): when the nest covers the whole prefix, point the wrapper's first_nested at itself. Cut the prefix with cut_next() before wrapping and re-register it on the outer unit; Aleksey Midenkov: In Oracle mode optimize_bag_operation() returns early, so union_distinct is never recomputed and the stale value reaches execution. Register the wrapper first, then run fix_distinct(): reset_distinct() now scans the new outer chain (the wrapper alone) and correctly leaves union_distinct NULL; a following DISTINCT operand re-establishes it.
forkfun
force-pushed
the
10.11-MDEV-39522
branch
from
July 27, 2026 10:57
545b90a to
9d8ed0c
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes set-operator parsing/rewriting in Oracle sql_mode to avoid incorrect derived-table wrapping that breaks correlated name resolution in UNION subqueries (e.g., ER_UNKNOWN_TABLE) and to ensure union_distinct is recomputed correctly after wrapping so execution doesn’t incorrectly de-duplicate results.
Changes:
- Adjusts
LEX::parsed_select_expr_*()logic to delay/condition wrapping in Oracle mode and to re-register the wrapped prefix before recalculating DISTINCT state. - Tweaks
LEX::create_priority_nest()handling offirst_nestedwhen wrapping a whole prefix. - Updates/extends Oracle-mode MTR coverage and refreshes multiple expected-result files to match the new query plan/rendering behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| sql/sql_lex.cc | Updates Oracle-mode set-operator wrapping and DISTINCT tracking to preserve correlated name resolution and correct execution semantics. |
| mysql-test/suite/compat/oracle/r/table_value_constr.result | Refreshes expected EXPLAIN/SHOW output for TVC + set-operator cases after wrapping changes. |
| mysql-test/suite/compat/oracle/r/empty_string_literal.result | Updates expected SHOW CREATE VIEW output (no longer wrapped into derived tables). |
| mysql-test/main/set_operation_oracle.test | Adds a regression test for MDEV-39522 plus Oracle-vs-non-Oracle precedence checks and a recursive CTE case. |
| mysql-test/main/set_operation_oracle.result | Updates expected output for set-operator Oracle-mode behavior (including new test output). |
| mysql-test/main/intersect_all.result | Refreshes expected EXPLAIN/SHOW output for Oracle-mode intersect/union combinations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+106
to
+109
| set sql_mode='oracle'; | ||
| create table t1 (id varchar(10)); | ||
| select 1 from t1 where exists (select 1 from dual union select 1 from dual where t1.id=1); | ||
| drop table t1; |
midenok
approved these changes
Jul 27, 2026
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.
MDEV-37325 unconditionally wrapped union subqueries in derived tables,
breaking name resolution of outer-scope/correlated references inside
the unions (producing ER_UNKNOWN_TABLE errors).
Delay the wrap until a following operator has a different linkage.
In Oracle mode all set operators share one priority and bind
left-to-right, so wrapping the accumulated prefix on each operator
change enforces it. This also corrects the row multiplicity of mixed
set operations toward left-to-right order.
create_priority_nest(): when the nest covers the whole prefix, point
the wrapper's first_nested at itself. Cut the prefix with
cut_next() before wrapping and re-register it on the outer unit;
Aleksey Midenkov:
In Oracle mode optimize_bag_operation() returns early, so union_distinct is
never recomputed and the stale value reaches execution.
Register the wrapper first, then run fix_distinct(): reset_distinct() now
scans the new outer chain (the wrapper alone) and correctly leaves
union_distinct NULL; a following DISTINCT operand re-establishes it.