summaryrefslogtreecommitdiff
path: root/sql/sql_cte.h
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2017-04-28 21:58:04 -0700
committerIgor Babaev <igor@askmonty.org>2017-04-28 21:59:11 -0700
commit7a29ca277698ffac757b2bd17c0977fb02b78557 (patch)
treee23dc1653e46c095d4488f614cbc26ed18dbb7d6 /sql/sql_cte.h
parent4b24467ff37d6db82500e736e832d0a53842ac9b (diff)
downloadmariadb-git-7a29ca277698ffac757b2bd17c0977fb02b78557.tar.gz
Fixed the bug mdev-12563.
The bug happened when the specification of a recursive CTE had no recursive references at the top level of the specification. In this case the regular processing of derived table references of the select containing a non-recursive reference to this recursive CTE misses handling the specification unit. At the preparation stage any non-recursive reference to a recursive CTE must be handled after the preparation of the specification unit for this CTE. So we have to force this preparation when regular handling of derived tables does not do it.
Diffstat (limited to 'sql/sql_cte.h')
-rw-r--r--sql/sql_cte.h20
1 files changed, 19 insertions, 1 deletions
diff --git a/sql/sql_cte.h b/sql/sql_cte.h
index 1cb77af8099..64b2f1cb1c8 100644
--- a/sql/sql_cte.h
+++ b/sql/sql_cte.h
@@ -46,6 +46,16 @@ private:
/* Dependency map of with elements mutually recursive with this with element */
table_map mutually_recursive;
/*
+ Dependency map built only for the top level references i.e. for those that
+ are encountered in from lists of the selects of the specification unit
+ */
+ table_map top_level_dep_map;
+ /*
+ Points to a recursive reference in subqueries.
+ Used only for specifications without recursive references on the top level.
+ */
+ TABLE_LIST *sq_rec_ref;
+ /*
The next with element from the circular chain of the with elements
mutually recursive with this with element.
(If This element is simply recursive than next_mutually_recursive contains
@@ -118,7 +128,7 @@ public:
stage and is used at the execution stage.
*/
select_union_recursive *rec_result;
-
+
/* List of Item_subselects containing recursive references to this CTE */
SQL_I_List<Item_subselect> sq_with_rec_ref;
@@ -127,6 +137,7 @@ public:
st_select_lex_unit *unit)
: next(NULL), base_dep_map(0), derived_dep_map(0),
sq_dep_map(0), work_dep_map(0), mutually_recursive(0),
+ top_level_dep_map(0), sq_rec_ref(NULL),
next_mutually_recursive(NULL), references(0),
query_name(name), column_list(list), spec(unit),
is_recursive(false), with_anchor(false),
@@ -154,6 +165,8 @@ public:
bool check_dependency_on(With_element *with_elem)
{ return base_dep_map & with_elem->get_elem_map(); }
+ TABLE_LIST *find_first_sq_rec_ref_in_select(st_select_lex *sel);
+
bool set_unparsed_spec(THD *thd, char *spec_start, char *spec_end);
st_select_lex_unit *clone_parsed_spec(THD *thd, TABLE_LIST *with_table);
@@ -177,11 +190,16 @@ public:
bool contains_sq_with_recursive_reference()
{ return sq_dep_map & mutually_recursive; }
+ bool no_rec_ref_on_top_level()
+ { return !(top_level_dep_map & mutually_recursive); }
+
table_map get_mutually_recursive() { return mutually_recursive; }
With_element *get_next_mutually_recursive()
{ return next_mutually_recursive; }
+ TABLE_LIST *get_sq_rec_ref() { return sq_rec_ref; }
+
bool is_anchor(st_select_lex *sel);
void move_anchors_ahead();