Commit 8c6a9aa3 authored by Igor Babaev's avatar Igor Babaev

Added a proper check for acceptable mutually recursive CTE.

parent 22c37c1f
......@@ -4,6 +4,21 @@ insert into t1 values
insert into t1 values
(3,'eee'), (7,'bb'), (1,'fff'), (4,'ggg');
with recursive
t as
(
select * from t1 where t1.b >= 'c'
union
select * from r
),
r as
(
select * from t
union
select t1.* from t1,r where r.a+1 = t1.a
)
select * from r;
ERROR HY000: Unacceptable mutual recursion with anchored table 't'
with recursive
a1(a,b) as
(select * from t1 where t1.a>3
union
......@@ -19,7 +34,7 @@ c1(a,b) as
union
select * from b1 where b1.b > 'auu')
select * from c1;
ERROR HY000: No anchors for recursive WITH element 'b1'
ERROR HY000: Unacceptable mutual recursion with anchored table 'a1'
drop table t1;
# WITH RECURSIVE vs just WITH
create table t1 (a int);
......
......@@ -1996,7 +1996,7 @@ NUMERIC_MAX_VALUE 4294967295
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
READ_ONLY NO
+COMMAND_LINE_ARGUMENT OPTIONAL
COMMAND_LINE_ARGUMENT OPTIONAL
VARIABLE_NAME MAX_SEEKS_FOR_KEY
SESSION_VALUE 4294967295
GLOBAL_VALUE 4294967295
......
......@@ -4,7 +4,24 @@ insert into t1 values
insert into t1 values
(3,'eee'), (7,'bb'), (1,'fff'), (4,'ggg');
--ERROR ER_RECURSIVE_WITHOUT_ANCHORS
--ERROR ER_UNACCEPTABLE_MUTUAL_RECURSION
with recursive
t as
(
select * from t1 where t1.b >= 'c'
union
select * from r
),
r as
(
select * from t
union
select t1.* from t1,r where r.a+1 = t1.a
)
select * from r;
--ERROR ER_UNACCEPTABLE_MUTUAL_RECURSION
with recursive
a1(a,b) as
(select * from t1 where t1.a>3
......
......@@ -7154,6 +7154,8 @@ ER_DUP_QUERY_NAME
eng "Duplicate query name in WITH clause"
ER_RECURSIVE_WITHOUT_ANCHORS
eng "No anchors for recursive WITH element '%s'"
ER_UNACCEPTABLE_MUTUAL_RECURSION
eng "Unacceptable mutual recursion with anchored table '%s'"
ER_REF_TO_RECURSIVE_WITH_TABLE_IN_DERIVED
eng "Reference to recursive WITH table '%s' in materiazed derived"
ER_NOT_STANDARDS_COMPLIANT_RECURSIVE
......
......@@ -292,43 +292,50 @@ bool With_clause::check_anchors()
with_elem != NULL;
with_elem= with_elem->next_elem)
{
if (!with_elem->is_recursive || with_elem->with_anchor)
if (!with_elem->is_recursive)
continue;
table_map anchored= 0;
for (With_element *elem= with_elem;
elem != NULL;
elem= elem->next_elem)
{
if (elem->mutually_recursive && elem->with_anchor)
anchored |= elem->get_elem_map();
}
table_map non_anchored= with_elem->mutually_recursive & ~anchored;
with_elem->work_dep_map= non_anchored & with_elem->base_dep_map;
}
/*Building transitive clousure on work_dep_map*/
for (With_element *with_elem= first_elem;
with_elem != NULL;
with_elem= with_elem->next_elem)
{
table_map with_elem_map= with_elem->get_elem_map();
for (With_element *elem= first_elem; elem != NULL; elem= elem->next_elem)
if (!with_elem->with_anchor)
{
if (elem->work_dep_map & with_elem_map)
elem->work_dep_map|= with_elem->work_dep_map;
With_element *elem= with_elem;
while ((elem= elem->get_next_mutually_recursive()) != with_elem)
{
if (elem->with_anchor)
break;
}
if (elem == with_elem)
{
my_error(ER_RECURSIVE_WITHOUT_ANCHORS, MYF(0),
with_elem->query_name->str);
return true;
}
}
}
for (With_element *with_elem= first_elem;
with_elem != NULL;
with_elem= with_elem->next_elem)
{
if (with_elem->work_dep_map & with_elem->get_elem_map())
else
{
my_error(ER_RECURSIVE_WITHOUT_ANCHORS, MYF(0),
with_elem->query_name->str);
return true;
With_element *elem= with_elem;
while ((elem= elem->get_next_mutually_recursive()) != with_elem)
elem->work_dep_map= elem->base_dep_map & elem->mutually_recursive;
elem= with_elem;
while ((elem= elem->get_next_mutually_recursive()) != with_elem)
{
table_map elem_map= elem->get_elem_map();
With_element *el= with_elem;
while ((el= el->get_next_mutually_recursive()) != with_elem)
{
if (el->work_dep_map & elem_map)
el->work_dep_map|= elem->work_dep_map;
}
}
elem= with_elem;
while ((elem= elem->get_next_mutually_recursive()) != with_elem)
{
if (elem->work_dep_map & elem->get_elem_map())
{
my_error(ER_UNACCEPTABLE_MUTUAL_RECURSION, MYF(0),
with_elem->query_name->str);
return true;
}
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment