summaryrefslogtreecommitdiffstats
path: root/sql/sql_cte.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_cte.cc')
-rw-r--r--sql/sql_cte.cc42
1 files changed, 28 insertions, 14 deletions
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index ad385128..5b3db9bc 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -106,6 +106,7 @@ bool LEX::check_dependencies_in_with_clauses()
@param tables Points to the beginning of the sub-chain
@param tables_last Points to the address with the sub-chain barrier
+ @param excl_spec Ignore the definition with this spec
@details
The method resolves tables references to CTE from the chain of
@@ -147,7 +148,8 @@ bool LEX::check_dependencies_in_with_clauses()
*/
bool LEX::resolve_references_to_cte(TABLE_LIST *tables,
- TABLE_LIST **tables_last)
+ TABLE_LIST **tables_last,
+ st_select_lex_unit *excl_spec)
{
With_element *with_elem= 0;
@@ -156,7 +158,8 @@ bool LEX::resolve_references_to_cte(TABLE_LIST *tables,
if (tbl->derived)
continue;
if (!tbl->db.str && !tbl->with)
- tbl->with= tbl->select_lex->find_table_def_in_with_clauses(tbl);
+ tbl->with= tbl->select_lex->find_table_def_in_with_clauses(tbl,
+ excl_spec);
if (!tbl->with) // no CTE matches table reference tbl
{
if (only_cte_resolution)
@@ -244,7 +247,7 @@ LEX::check_cte_dependencies_and_resolve_references()
return true;
if (!with_cte_resolution)
return false;
- if (resolve_references_to_cte(query_tables, query_tables_last))
+ if (resolve_references_to_cte(query_tables, query_tables_last, NULL))
return true;
return false;
}
@@ -388,6 +391,7 @@ bool With_element::check_dependencies_in_spec()
@param table The reference to the table that is looked for
@param barrier The barrier with element for the search
+ @param excl_spec Ignore the definition with this spec
@details
The function looks through the elements of this with clause trying to find
@@ -401,12 +405,15 @@ bool With_element::check_dependencies_in_spec()
*/
With_element *With_clause::find_table_def(TABLE_LIST *table,
- With_element *barrier)
+ With_element *barrier,
+ st_select_lex_unit *excl_spec)
{
for (With_element *with_elem= with_list.first;
with_elem != barrier;
with_elem= with_elem->next)
{
+ if (excl_spec && with_elem->spec == excl_spec)
+ continue;
if (my_strcasecmp(system_charset_info, with_elem->get_name_str(),
table->table_name.str) == 0 &&
!table->is_fqtn)
@@ -466,7 +473,7 @@ With_element *find_table_def_in_with_clauses(TABLE_LIST *tbl,
top_unit->with_element &&
top_unit->with_element->get_owner() == with_clause)
barrier= top_unit->with_element;
- found= with_clause->find_table_def(tbl, barrier);
+ found= with_clause->find_table_def(tbl, barrier, NULL);
if (found)
break;
}
@@ -521,10 +528,11 @@ void With_element::check_dependencies_in_select(st_select_lex *sl,
{
With_clause *with_clause= sl->master_unit()->with_clause;
if (with_clause)
- tbl->with= with_clause->find_table_def(tbl, NULL);
+ tbl->with= with_clause->find_table_def(tbl, NULL, NULL);
if (!tbl->with)
tbl->with= owner->find_table_def(tbl,
- owner->with_recursive ? NULL : this);
+ owner->with_recursive ? NULL : this,
+ NULL);
}
if (!tbl->with)
tbl->with= find_table_def_in_with_clauses(tbl, ctxt);
@@ -643,6 +651,8 @@ void With_element::check_dependencies_in_unit(st_select_lex_unit *unit,
{
check_dependencies_in_select(sl, &unit_ctxt_elem, in_subq, dep_map);
}
+ if ((sl= unit->fake_select_lex))
+ check_dependencies_in_select(sl, &unit_ctxt_elem, in_subq, dep_map);
}
@@ -1099,7 +1109,8 @@ st_select_lex_unit *With_element::clone_parsed_spec(LEX *old_lex,
*/
lex->only_cte_resolution= old_lex->only_cte_resolution;
if (lex->resolve_references_to_cte(lex->query_tables,
- lex->query_tables_last))
+ lex->query_tables_last,
+ spec))
{
res= NULL;
goto err;
@@ -1199,7 +1210,7 @@ With_element::process_columns_of_derived_unit(THD *thd,
/* Rename the columns of the first select in the unit */
while ((item= it++, name= nm++))
{
- item->set_name(thd, *name);
+ lex_string_set(&item->name, name->str);
item->base_flags|= item_base_t::IS_EXPLICIT_NAME;
}
@@ -1279,14 +1290,14 @@ bool With_element::prepare_unreferenced(THD *thd)
sl= sl->next_select())
sl->context.outer_context= 0;
+ uint8 save_context_analysys_only= thd->lex->context_analysis_only;
thd->lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED;
if (!spec->prepared &&
(spec->prepare(spec->derived, 0, 0) ||
process_columns_of_derived_unit(thd, spec) ||
check_duplicate_names(thd, first_sl->item_list, 1)))
rc= true;
-
- thd->lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_DERIVED;
+ thd->lex->context_analysis_only= save_context_analysys_only;
return rc;
}
@@ -1302,6 +1313,7 @@ bool With_element::is_anchor(st_select_lex *sel)
Search for the definition of the given table referred in this select node
@param table reference to the table whose definition is searched for
+ @param excl_spec ignore the definition with this spec
@details
The method looks for the definition of the table whose reference is occurred
@@ -1314,7 +1326,8 @@ bool With_element::is_anchor(st_select_lex *sel)
NULL - otherwise
*/
-With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
+With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table,
+ st_select_lex_unit *excl_spec)
{
With_element *found= NULL;
With_clause *containing_with_clause= NULL;
@@ -1331,7 +1344,7 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
With_clause *attached_with_clause= sl->get_with_clause();
if (attached_with_clause &&
attached_with_clause != containing_with_clause &&
- (found= attached_with_clause->find_table_def(table, NULL)))
+ (found= attached_with_clause->find_table_def(table, NULL, excl_spec)))
break;
master_unit= sl->master_unit();
outer_sl= master_unit->outer_select();
@@ -1341,7 +1354,8 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
containing_with_clause= with_elem->get_owner();
With_element *barrier= containing_with_clause->with_recursive ?
NULL : with_elem;
- if ((found= containing_with_clause->find_table_def(table, barrier)))
+ if ((found= containing_with_clause->find_table_def(table, barrier,
+ excl_spec)))
break;
if (outer_sl && !outer_sl->get_with_element())
break;