Commit 4c9d19ee authored by Igor Babaev's avatar Igor Babaev

Fixed the bug mdev-13796.

A reference to a CTE may occur not in the master of the CTE
specification. In this case if the reference to the CTE is
the first one the specification should be detached from its
master and attached to the referencing select.

Also fixed the TYPE column in the lines of the EXPLAIN output
created for CTE tables.
parent dc8ac122
......@@ -86,7 +86,7 @@ select * from t2,t where t2.c=t.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2
2 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
explain
select * from t2, (select a, count(*) from t1 where b >= 'c' group by a) as t
where t2.c=t.a;
......@@ -176,7 +176,7 @@ select * from t2 where c in (select c from t);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where
1 PRIMARY <derived2> ref key0 key0 8 test.t2.c 2 Using where; FirstMatch(t2)
2 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
explain
select * from t2
where c in (select c from (select count(*) as c from t1
......@@ -245,8 +245,8 @@ select * from t as r1, t as r2 where r1.a=r2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8 Using where
1 PRIMARY <derived3> ref key0 key0 5 r1.a 2
3 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary
2 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary
3 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary
2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary
explain
select * from (select distinct a from t1 where b >= 'c') as r1,
(select distinct a from t1 where b >= 'c') as r2
......@@ -370,7 +370,7 @@ select * from t2,t where t2.c=t.a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where
1 PRIMARY <derived2> ref key0 key0 5 test.t2.c 2
2 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where
2 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where
3 UNION t2 ALL NULL NULL NULL NULL 4 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
explain
......@@ -598,7 +598,7 @@ select * from v2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where
1 PRIMARY <derived3> ref key0 key0 5 test.t2.c 2
3 SUBQUERY t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
3 DERIVED t1 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort
# with clause in the specification of a view that whose definition
# table alias for a with table
create view v3 as
......@@ -1055,3 +1055,27 @@ deallocate prepare stmt1;
deallocate prepare stmt2;
drop view v1,v2;
drop table t1,t2;
#
# MDEV-13796: UNION of two materialized CTEs
#
CREATE TABLE t1 (id int, k int);
CREATE TABLE t2 (id int);
INSERT INTO t1 VALUES (3,5), (1,7), (4,3);
INSERT INTO t2 VALUES (4), (3), (2);
WITH d1 AS (SELECT SUM(k) FROM t1, t2 as t2 WHERE t1.id = t2.id),
d2 AS (SELECT SUM(k) FROM t1, t2 as t2 WHERE t1.id = t2.id)
SELECT * FROM d1 UNION SELECT * FROM d2;
SUM(k)
8
explain WITH d1 AS (SELECT SUM(k) FROM t1, t2 as t2 WHERE t1.id = t2.id),
d2 AS (SELECT SUM(k) FROM t1, t2 as t2 WHERE t1.id = t2.id)
SELECT * FROM d1 UNION SELECT * FROM d2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 9
2 DERIVED t1 ALL NULL NULL NULL NULL 3
2 DERIVED t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
4 UNION <derived3> ALL NULL NULL NULL NULL 9
3 DERIVED t1 ALL NULL NULL NULL NULL 3
3 DERIVED t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union1,4> ALL NULL NULL NULL NULL NULL
DROP TABLE t1,t2;
......@@ -86,7 +86,7 @@ select t2.a from t1,t2 where t1.a+1=t2.a
select * from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 30
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
2 DERIVED t2 ALL NULL NULL NULL NULL 5 Using where
3 UNION t1 ALL NULL NULL NULL NULL 5
3 UNION t2 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
......@@ -114,7 +114,7 @@ select t2.a from t1,t2 where t1.a+1=t2.a
select * from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
2 DERIVED t2 ALL NULL NULL NULL NULL 5 Using where
3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 5
3 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
......@@ -691,13 +691,13 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00 Using where
1 PRIMARY <derived3> ref key0 key0 5 c.h_id 2 100.00
1 PRIMARY <derived3> ref key0 key0 5 c.w_id 2 100.00
3 SUBQUERY folks ALL NULL NULL NULL NULL 12 100.00 Using where
3 DERIVED folks ALL NULL NULL NULL NULL 12 100.00 Using where
4 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
4 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
5 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 2 100.00
5 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union3,4,5> ALL NULL NULL NULL NULL NULL NULL
2 UNCACHEABLE SUBQUERY <derived3> ALL NULL NULL NULL NULL 12 100.00 Using where
2 DERIVED <derived3> ALL NULL NULL NULL NULL 12 100.00 Using where
Warnings:
Note 1003 with recursive ancestor_couple_ids as (select `a`.`father` AS `h_id`,`a`.`mother` AS `w_id` from `coupled_ancestors` `a` where `a`.`father` is not null and `a`.`mother` is not null), coupled_ancestors as (select `test`.`folks`.`id` AS `id`,`test`.`folks`.`name` AS `name`,`test`.`folks`.`dob` AS `dob`,`test`.`folks`.`father` AS `father`,`test`.`folks`.`mother` AS `mother` from `test`.`folks` where `test`.`folks`.`name` = 'Me' union all select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `fa` where `test`.`p`.`id` = `fa`.`h_id` union all select `test`.`p`.`id` AS `id`,`test`.`p`.`name` AS `name`,`test`.`p`.`dob` AS `dob`,`test`.`p`.`father` AS `father`,`test`.`p`.`mother` AS `mother` from `test`.`folks` `p` join `ancestor_couple_ids` `ma` where `test`.`p`.`id` = `ma`.`w_id`)select `h`.`name` AS `name`,`h`.`dob` AS `dob`,`w`.`name` AS `name`,`w`.`dob` AS `dob` from `ancestor_couple_ids` `c` join `coupled_ancestors` `h` join `coupled_ancestors` `w` where `h`.`id` = `c`.`h_id` and `w`.`id` = `c`.`w_id`
# simple mutual recursion
......@@ -877,7 +877,7 @@ where p.id = a.father or p.id = a.mother
select * from ancestors;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 12 100.00
2 SUBQUERY folks ALL NULL NULL NULL NULL 12 100.00 Using where
2 DERIVED folks ALL NULL NULL NULL NULL 12 100.00 Using where
3 RECURSIVE UNION p ALL NULL NULL NULL NULL 12 100.00
3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 12 100.00 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
......@@ -1236,7 +1236,7 @@ where p.id = ma.mother
select * from ancestors;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 12
2 SUBQUERY folks ALL NULL NULL NULL NULL 12 Using where
2 DERIVED folks ALL NULL NULL NULL NULL 12 Using where
3 RECURSIVE UNION p ALL PRIMARY NULL NULL NULL 12
3 RECURSIVE UNION <derived2> ref key0 key0 5 test.p.id 2
4 RECURSIVE UNION p ALL PRIMARY NULL NULL NULL 12
......@@ -1300,14 +1300,14 @@ from prev_gen
select ancestors.name, ancestors.dob from ancestors;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 24
4 SUBQUERY folks ALL NULL NULL NULL NULL 12 Using where
4 DERIVED folks ALL NULL NULL NULL NULL 12 Using where
6 RECURSIVE UNION <derived3> ALL NULL NULL NULL NULL 12
5 RECURSIVE UNION <derived4> ALL NULL NULL NULL NULL 24
NULL UNION RESULT <union4,6,5> ALL NULL NULL NULL NULL NULL
3 SUBQUERY folks ALL NULL NULL NULL NULL 12 Using where
3 DERIVED folks ALL NULL NULL NULL NULL 12 Using where
2 RECURSIVE UNION folks ALL PRIMARY NULL NULL NULL 12
2 RECURSIVE UNION <derived3> ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union3,2> ALL NULL NULL NULL NULL NULL
5 RECURSIVE UNION <derived4> ALL NULL NULL NULL NULL 24
NULL UNION RESULT <union4,6,5> ALL NULL NULL NULL NULL NULL
explain FORMAT=JSON
with recursive
prev_gen
......@@ -1831,7 +1831,7 @@ select t2.a from t1,t2 where t1.a+1=t2.a
select * from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
2 DERIVED t2 ALL NULL NULL NULL NULL 5 Using where
4 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 5
4 RECURSIVE UNION t2 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL
......@@ -2783,7 +2783,7 @@ SELECT c1 FROM t, cte
) SELECT COUNT(*) FROM cte;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
2 SUBQUERY t ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
2 DERIVED t ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
3 RECURSIVE UNION t ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 4 4.00 100.00 100.00 Using join buffer (flat, BNL join)
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL 0.00 NULL NULL
......@@ -2801,7 +2801,7 @@ SELECT c2 FROM t, cte
) SELECT COUNT(*) FROM cte;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
2 SUBQUERY t ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
2 DERIVED t ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
3 RECURSIVE UNION t ALL NULL NULL NULL NULL 4 4.00 100.00 100.00
3 RECURSIVE UNION <derived2> ALL NULL NULL NULL NULL 4 4.00 100.00 100.00 Using join buffer (flat, BNL join)
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL 0.00 NULL NULL
......
......@@ -724,3 +724,22 @@ deallocate prepare stmt2;
drop view v1,v2;
drop table t1,t2;
--echo #
--echo # MDEV-13796: UNION of two materialized CTEs
--echo #
CREATE TABLE t1 (id int, k int);
CREATE TABLE t2 (id int);
INSERT INTO t1 VALUES (3,5), (1,7), (4,3);
INSERT INTO t2 VALUES (4), (3), (2);
let $q=
WITH d1 AS (SELECT SUM(k) FROM t1, t2 as t2 WHERE t1.id = t2.id),
d2 AS (SELECT SUM(k) FROM t1, t2 as t2 WHERE t1.id = t2.id)
SELECT * FROM d1 UNION SELECT * FROM d2;
eval $q;
eval explain $q;
DROP TABLE t1,t2;
......@@ -991,7 +991,7 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
been done yet.
*/
if (with_elem && sl->master_unit() == with_elem->spec)
break;
break;
With_clause *with_clause=sl->get_with_clause();
if (with_clause)
{
......@@ -1039,13 +1039,21 @@ bool TABLE_LIST::set_as_with_table(THD *thd, With_element *with_elem)
}
with= with_elem;
if (!with_elem->is_referenced() || with_elem->is_recursive)
{
derived= with_elem->spec;
if (derived->get_master() != select_lex &&
!is_with_table_recursive_reference())
{
derived->move_as_slave(select_lex);
}
}
else
{
if(!(derived= with_elem->clone_parsed_spec(thd, this)))
return true;
derived->with_element= with_elem;
}
derived->first_select()->linkage= DERIVED_TABLE_TYPE;
with_elem->inc_references();
return false;
}
......
......@@ -2304,6 +2304,30 @@ st_select_lex_node *st_select_lex_node:: insert_chain_before(
return this;
}
/*
Detach the node from its master and attach it to a new master
*/
void st_select_lex_node::move_as_slave(st_select_lex_node *new_master)
{
exclude_from_tree();
if (new_master->slave)
{
st_select_lex_node *curr= new_master->slave;
for ( ; curr->next ; curr= curr->next) ;
prev= &curr->next;
}
else
{
prev= &new_master->slave;
new_master->slave= this;
}
next= 0;
master= new_master;
}
/*
Exclude a node from the tree lex structure, but leave it in the global
list of nodes.
......@@ -4404,7 +4428,8 @@ void st_select_lex::set_explain_type(bool on_the_fly)
pos_in_table_list=NULL for e.g. post-join aggregation JOIN_TABs.
*/
if (tab->table && tab->table->pos_in_table_list &&
tab->table->pos_in_table_list->with)
tab->table->pos_in_table_list->with &&
tab->table->pos_in_table_list->with->is_recursive)
{
uses_cte= true;
break;
......
......@@ -561,6 +561,7 @@ class st_select_lex_node {
}
st_select_lex_node *insert_chain_before(st_select_lex_node **ptr_pos_to_insert,
st_select_lex_node *end_chain_node);
void move_as_slave(st_select_lex_node *new_master);
friend class st_select_lex_unit;
friend bool mysql_new_select(LEX *lex, bool move_down);
friend bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table,
......
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