mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext
This commit is contained in:
@ -141,7 +141,7 @@ bool With_clause::check_dependencies()
|
||||
|
||||
/*
|
||||
Mark those elements where tables are defined with direct or indirect
|
||||
make recursion.
|
||||
recursion.
|
||||
*/
|
||||
for (With_element *with_elem= with_list.first;
|
||||
with_elem;
|
||||
@ -342,6 +342,8 @@ void With_element::check_dependencies_in_select(st_select_lex *sl,
|
||||
tbl->with_internal_reference_map= get_elem_map();
|
||||
if (in_subq)
|
||||
sq_dep_map|= tbl->with->get_elem_map();
|
||||
else
|
||||
top_level_dep_map|= tbl->with->get_elem_map();
|
||||
}
|
||||
}
|
||||
/* Now look for the dependencies in the subqueries of sl */
|
||||
@ -351,6 +353,53 @@ void With_element::check_dependencies_in_select(st_select_lex *sl,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Find a recursive reference to this with element in subqueries of a select
|
||||
|
||||
@param sel The select in whose subqueries the reference
|
||||
to be looked for
|
||||
|
||||
@details
|
||||
The function looks for a recursive reference to this with element in
|
||||
subqueries of select sl. When the first such reference is found
|
||||
it is returned as the result.
|
||||
The function assumes that the identification of all CTE references
|
||||
has been performed earlier.
|
||||
|
||||
@retval
|
||||
Pointer to the found recursive reference if the search succeeded
|
||||
NULL - otherwise
|
||||
*/
|
||||
|
||||
TABLE_LIST *With_element::find_first_sq_rec_ref_in_select(st_select_lex *sel)
|
||||
{
|
||||
TABLE_LIST *rec_ref= NULL;
|
||||
st_select_lex_unit *inner_unit= sel->first_inner_unit();
|
||||
for (; inner_unit; inner_unit= inner_unit->next_unit())
|
||||
{
|
||||
st_select_lex *sl= inner_unit->first_select();
|
||||
for (; sl; sl= sl->next_select())
|
||||
{
|
||||
for (TABLE_LIST *tbl= sl->table_list.first; tbl; tbl= tbl->next_local)
|
||||
{
|
||||
if (tbl->derived || tbl->nested_join)
|
||||
continue;
|
||||
if (tbl->with && tbl->with->owner== this->owner &&
|
||||
(tbl->with_internal_reference_map & mutually_recursive))
|
||||
{
|
||||
rec_ref= tbl;
|
||||
return rec_ref;
|
||||
}
|
||||
}
|
||||
if ((rec_ref= find_first_sq_rec_ref_in_select(sl)))
|
||||
return rec_ref;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief
|
||||
Find the dependencies of this element on its siblings in a unit
|
||||
@ -602,6 +651,10 @@ void With_clause::move_anchors_ahead()
|
||||
@details
|
||||
If the specification of this with element contains anchors the method
|
||||
moves them at the very beginning of the specification.
|
||||
Additionally for the other selects of the specification if none of them
|
||||
contains a recursive reference to this with element or a mutually recursive
|
||||
one the method looks for the first such reference in the first recursive
|
||||
select and set a pointer to it in this->sq_rec_ref.
|
||||
*/
|
||||
|
||||
void With_element::move_anchors_ahead()
|
||||
@ -618,6 +671,11 @@ void With_element::move_anchors_ahead()
|
||||
sl->move_node(new_pos);
|
||||
new_pos= sl->next_select();
|
||||
}
|
||||
else if (!sq_rec_ref && no_rec_ref_on_top_level())
|
||||
{
|
||||
sq_rec_ref= find_first_sq_rec_ref_in_select(sl);
|
||||
DBUG_ASSERT(sq_rec_ref != NULL);
|
||||
}
|
||||
last_sl= sl;
|
||||
}
|
||||
if (spec->union_distinct)
|
||||
@ -967,6 +1025,17 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
|
||||
|
||||
bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
|
||||
{
|
||||
if (table)
|
||||
{
|
||||
/*
|
||||
This table was prematurely identified as a temporary table.
|
||||
We correct it here, but it's not a nice solution in the case
|
||||
when the temporary table with this name is not used anywhere
|
||||
else in the query.
|
||||
*/
|
||||
thd->mark_tmp_table_as_free_for_reuse(table);
|
||||
table= 0;
|
||||
}
|
||||
with= with_elem;
|
||||
if (!with_elem->is_referenced() || with_elem->is_recursive)
|
||||
derived= with_elem->spec;
|
||||
@ -1228,6 +1297,7 @@ bool st_select_lex::check_subqueries_with_recursive_references()
|
||||
continue;
|
||||
Item_subselect *subq= (Item_subselect *) sl_master->item;
|
||||
subq->with_recursive_reference= true;
|
||||
subq->register_as_with_rec_ref(tbl->with);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
Reference in New Issue
Block a user