Skip to content

Commit

Permalink
Fixed bug mdev-10881
Browse files Browse the repository at this point in the history
The server missed to call check_dependencies_in_with_clauses()
when processing PREPARE ... FROM CREATE ... SELECT / INSERT ... SELECT
with WITH clause before SELECT.
  • Loading branch information
igorbabaev committed Sep 25, 2016
1 parent 61ab733 commit 54efb08
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
60 changes: 60 additions & 0 deletions mysql-test/r/cte_recursive.result
Original file line number Diff line number Diff line change
Expand Up @@ -1633,6 +1633,66 @@ id name dob father mother
8 Grandpa Ben 1940-10-21 NULL NULL
6 Grandgrandma Martha 1923-05-17 NULL NULL
deallocate prepare stmt;
#
# MDEV-10881: execution of prepared statement from
# CREATE ... SELECT, INSERT ... SELECT
#
prepare stmt from"
create table my_ancestors
with recursive
ancestor_ids (id)
as
(
select father from folks where name = 'Me'
union
select mother from folks where name = 'Me'
union
select father from folks, ancestor_ids a where folks.id = a.id
union
select mother from folks, ancestor_ids a where folks.id = a.id
)
select p.* from folks as p, ancestor_ids as a where p.id = a.id;
";
execute stmt;
deallocate prepare stmt;
select * from my_ancestors;
id name dob father mother
20 Dad 1970-02-02 10 9
30 Mom 1975-03-03 8 7
10 Grandpa Bill 1940-04-05 NULL NULL
9 Grandma Ann 1941-10-15 NULL NULL
7 Grandma Sally 1943-08-23 NULL 6
8 Grandpa Ben 1940-10-21 NULL NULL
6 Grandgrandma Martha 1923-05-17 NULL NULL
delete from my_ancestors;
prepare stmt from"
insert into my_ancestors
with recursive
ancestor_ids (id)
as
(
select father from folks where name = 'Me'
union
select mother from folks where name = 'Me'
union
select father from folks, ancestor_ids a where folks.id = a.id
union
select mother from folks, ancestor_ids a where folks.id = a.id
)
select p.* from folks as p, ancestor_ids as a where p.id = a.id;
";
execute stmt;
deallocate prepare stmt;
select * from my_ancestors;
id name dob father mother
20 Dad 1970-02-02 10 9
30 Mom 1975-03-03 8 7
10 Grandpa Bill 1940-04-05 NULL NULL
9 Grandma Ann 1941-10-15 NULL NULL
7 Grandma Sally 1943-08-23 NULL 6
8 Grandpa Ben 1940-10-21 NULL NULL
6 Grandgrandma Martha 1923-05-17 NULL NULL
drop table my_ancestors;
drop table folks;
#
# MDEV-10372: [bb-10.2-mdev9864 tree] EXPLAIN with recursive CTE enters endless recursion
Expand Down
48 changes: 48 additions & 0 deletions mysql-test/t/cte_recursive.test
Original file line number Diff line number Diff line change
Expand Up @@ -1223,6 +1223,54 @@ select p.* from folks as p, ancestor_ids as a where p.id = a.id;
execute stmt;
deallocate prepare stmt;

--echo #
--echo # MDEV-10881: execution of prepared statement from
--echo # CREATE ... SELECT, INSERT ... SELECT
--echo #

prepare stmt from"
create table my_ancestors
with recursive
ancestor_ids (id)
as
(
select father from folks where name = 'Me'
union
select mother from folks where name = 'Me'
union
select father from folks, ancestor_ids a where folks.id = a.id
union
select mother from folks, ancestor_ids a where folks.id = a.id
)
select p.* from folks as p, ancestor_ids as a where p.id = a.id;
";
execute stmt;
deallocate prepare stmt;
select * from my_ancestors;

delete from my_ancestors;

prepare stmt from"
insert into my_ancestors
with recursive
ancestor_ids (id)
as
(
select father from folks where name = 'Me'
union
select mother from folks where name = 'Me'
union
select father from folks, ancestor_ids a where folks.id = a.id
union
select mother from folks, ancestor_ids a where folks.id = a.id
)
select p.* from folks as p, ancestor_ids as a where p.id = a.id;
";
execute stmt;
deallocate prepare stmt;
select * from my_ancestors;

drop table my_ancestors;

drop table folks;

Expand Down
6 changes: 6 additions & 0 deletions sql/sql_prepare.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1777,6 +1777,9 @@ static bool mysql_test_create_table(Prepared_statement *stmt)
if (create_table_precheck(thd, tables, create_table))
DBUG_RETURN(TRUE);

if (check_dependencies_in_with_clauses(lex->with_clauses_list))
DBUG_RETURN(TRUE);

if (select_lex->item_list.elements)
{
/* Base table and temporary table are not in the same name space. */
Expand Down Expand Up @@ -2167,6 +2170,9 @@ static bool mysql_test_insert_select(Prepared_statement *stmt,
if (insert_precheck(stmt->thd, tables))
return 1;

if (check_dependencies_in_with_clauses(lex->with_clauses_list))
return 1;

/* store it, because mysql_insert_select_prepare_tester change it */
first_local_table= lex->select_lex.table_list.first;
DBUG_ASSERT(first_local_table != 0);
Expand Down

0 comments on commit 54efb08

Please sign in to comment.