Commit e1c92a6c authored by Igor Babaev's avatar Igor Babaev

Fixed a problem with unreferenced CTE:

explain for the query containing WITH clause
with an unreferenced CTE caused a crash.
Added a test covered this case.

Also added a test for usage CTE in different parts of union.
parent 247632e6
......@@ -309,6 +309,41 @@ c c
1 1
4 4
4 4
# t two references of t used in different parts of a union
with t as (select a from t1 where b >= 'c')
select * from t where a < 2
union
select * from t where a >= 4;
a
1
4
select * from (select a from t1 where b >= 'c') as t
where t.a < 2
union
select * from (select a from t1 where b >= 'c') as t
where t.a >= 4;
a
1
4
explain
with t as (select a from t1 where b >= 'c')
select * from t where a < 2
union
select * from t where a >= 4;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
3 UNION t1 ALL NULL NULL NULL NULL 8 Using where
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL
explain
select * from (select a from t1 where b >= 'c') as t
where t.a < 2
union
select * from (select a from t1 where b >= 'c') as t
where t.a >= 4;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
3 UNION t1 ALL NULL NULL NULL NULL 8 Using where
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL
# specification of t contains union
with t as (select a from t1 where b >= 'f'
union
......@@ -749,6 +784,19 @@ ERROR HY000: WITH column list and SELECT field list have different column counts
with t(f1,f1) as (select * from t1 where b >= 'c')
select t1.b from t2,t1 where t1.a = t2.c;
ERROR 42S21: Duplicate column name 'f1'
# explain for query with unreferenced with table
explain
with t as (select a from t1 where b >= 'c')
select t1.b from t2,t1 where t1.a = t2.c;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
explain
with t as (select a, count(*) from t1 where b >= 'c' group by a)
select t1.b from t2,t1 where t1.a = t2.c;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 4
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
drop table t1,t2;
#
# Bug mdev-9937: View used in the specification of with table
......
......@@ -152,6 +152,28 @@ select * from (select * from t1 where b >= 'c') as r1,
with t(c) as (select a from t1 where b >= 'c')
select * from t r1, t r2 where r1.c=r2.c;
--echo # t two references of t used in different parts of a union
with t as (select a from t1 where b >= 'c')
select * from t where a < 2
union
select * from t where a >= 4;
select * from (select a from t1 where b >= 'c') as t
where t.a < 2
union
select * from (select a from t1 where b >= 'c') as t
where t.a >= 4;
explain
with t as (select a from t1 where b >= 'c')
select * from t where a < 2
union
select * from t where a >= 4;
explain
select * from (select a from t1 where b >= 'c') as t
where t.a < 2
union
select * from (select a from t1 where b >= 'c') as t
where t.a >= 4;
--echo # specification of t contains union
with t as (select a from t1 where b >= 'f'
union
......@@ -437,6 +459,16 @@ with t(f) as (select * from t1 where b >= 'c')
with t(f1,f1) as (select * from t1 where b >= 'c')
select t1.b from t2,t1 where t1.a = t2.c;
--echo # explain for query with unreferenced with table
explain
with t as (select a from t1 where b >= 'c')
select t1.b from t2,t1 where t1.a = t2.c;
explain
with t as (select a, count(*) from t1 where b >= 'c' group by a)
select t1.b from t2,t1 where t1.a = t2.c;
drop table t1,t2;
--echo #
......
......@@ -24402,11 +24402,14 @@ int JOIN::save_explain_data_intern(Explain_query *output,
(1) they are not parts of ON clauses that were eliminated by table
elimination.
(2) they are not merged derived tables
(3) they are not unreferenced CTE
*/
if (!(tmp_unit->item && tmp_unit->item->eliminated) && // (1)
(!tmp_unit->derived ||
tmp_unit->derived->is_materialized_derived())) // (2)
{
tmp_unit->derived->is_materialized_derived()) && // (2)
!(tmp_unit->with_element &&
!tmp_unit->with_element->is_referenced())) // (3)
{
explain->add_child(tmp_unit->first_select()->select_number);
}
}
......@@ -24466,9 +24469,11 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
Save plans for child subqueries, when
(1) they are not parts of eliminated WHERE/ON clauses.
(2) they are not VIEWs that were "merged for INSERT".
(3) they are not unreferenced CTE.
*/
if (!(unit->item && unit->item->eliminated) && // (1)
!(unit->derived && unit->derived->merged_for_insert)) // (2)
if (!(unit->item && unit->item->eliminated) && // (1)
!(unit->derived && unit->derived->merged_for_insert) && // (2)
!(unit->with_element && !unit->with_element->is_referenced())) // (3)
{
if (mysql_explain_union(thd, unit, result))
DBUG_VOID_RETURN;
......
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