From 635b5ce355473167af64e116e403a51bfaed184b Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 16 Apr 2021 09:53:16 -0700 Subject: MDEV-25362 Incorrect name resolution for subqueries in ON expressions This patch sets the proper name resolution context for outer references used in a subquery from an ON clause. Usually this context is more narrow than the name resolution context of the parent select that were used before this fix. This fix revealed another problem that concerned ON expressions used in from clauses of specifications of derived tables / views / CTEs. The name resolution outer context for such ON expression must be set to NULL to prevent name resolution beyond the derived table where it is used. The solution to resolve this problem applied in sql_derived.cc was provided by Sergei Petrunia . The change in sql_parse.cc is not good for 10.4+. A corresponding diff for 10.4+ will be provided in JIRA entry for this bug. Approved by Oleksandr Byelkin --- sql/sql_derived.cc | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'sql/sql_derived.cc') diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index be5905da683..5a85b7ea7e3 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -562,6 +562,32 @@ bool mysql_derived_init(THD *thd, LEX *lex, TABLE_LIST *derived) } +/* + @brief + Prevent name resolution out of context of ON expressions in derived tables + + @param + join_list list of tables used in from list of a derived + + @details + The function sets the Name_resolution_context::outer_context to NULL + for all ON expressions contexts in the given join list. It does this + recursively for all nested joins the list contains. +*/ + +static void nullify_outer_context_for_on_clauses(List& join_list) +{ + List_iterator li(join_list); + while (TABLE_LIST *table= li++) + { + if (table->on_context) + table->on_context->outer_context= NULL; + if (table->nested_join) + nullify_outer_context_for_on_clauses(table->nested_join->join_list); + } +} + + /* Create temporary table structure (but do not fill it) @@ -695,7 +721,12 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) /* prevent name resolving out of derived table */ for (SELECT_LEX *sl= first_select; sl; sl= sl->next_select()) { + // Prevent it for the WHERE clause sl->context.outer_context= 0; + + // And for ON clauses, if there are any + nullify_outer_context_for_on_clauses(*sl->join_list); + if (!derived->is_with_table_recursive_reference() || (!derived->with->with_anchor && !derived->with->is_with_prepared_anchor())) -- cgit v1.2.1