Commit 5e9d6511 authored by Igor Babaev's avatar Igor Babaev

Fixed the bug mdev-12788.

In some rare cases queries with UNION ALL
using a derived table specified by
a grouping select with a subquery in WHERE and
impossible HAVING detected after constant row
substitution could hang.
The cause was not a proper return from the
function subselect_single_select_engine::exec()
in the case when the subquery was not optimized
beforehand and the optimization performed
in this function requested for a change of the
subquery engine. This was fixed.
Also a change was applied that avoided execution
of a subquery if impossible having was detected
for the main query at the optimization stage.
parent 4807df6f
......@@ -2156,3 +2156,34 @@ WHERE t1_2.b NOT IN ( SELECT 4 UNION ALL SELECT 5 );
a b a b
1 1 1 1
DROP TABLE t1;
#
# Bug mdev-12788: UNION ALL + impossible having for derived
# with IN subquery in WHERE
#
CREATE TABLE t1 (i int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (pk int PRIMARY KEY) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1),(2);
SELECT 1, 2
UNION ALL
SELECT i, COUNT(*) FROM (
SELECT * FROM t1 WHERE i IN ( SELECT pk FROM t2 )
) AS sq
GROUP BY i
HAVING i = 10;
1 2
1 2
EXPLAIN EXTENDED SELECT 1, 2
UNION ALL
SELECT i, COUNT(*) FROM (
SELECT * FROM t1 WHERE i IN ( SELECT pk FROM t2 )
) AS sq
GROUP BY i
HAVING i = 10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
2 UNION NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING noticed after reading const tables
4 DEPENDENT SUBQUERY t2 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
Warnings:
Note 1003 select 1 AS `1`,2 AS `2` union all select 1 AS `i`,count(0) AS `COUNT(*)` from dual where <in_optimizer>(1,<exists>(<primary_index_lookup>(<cache>(1) in t2 on PRIMARY))) group by 1 having 0
DROP TABLE t1,t2;
......@@ -1507,3 +1507,28 @@ SELECT * FROM t1 t1_1 LEFT JOIN t1 t1_2 ON ( t1_2.b = t1_1.a )
WHERE t1_2.b NOT IN ( SELECT 4 UNION ALL SELECT 5 );
DROP TABLE t1;
--echo #
--echo # Bug mdev-12788: UNION ALL + impossible having for derived
--echo # with IN subquery in WHERE
--echo #
CREATE TABLE t1 (i int) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1);
CREATE TABLE t2 (pk int PRIMARY KEY) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1),(2);
let $q=
SELECT 1, 2
UNION ALL
SELECT i, COUNT(*) FROM (
SELECT * FROM t1 WHERE i IN ( SELECT pk FROM t2 )
) AS sq
GROUP BY i
HAVING i = 10;
eval $q;
eval EXPLAIN EXTENDED $q;
DROP TABLE t1,t2;
......@@ -3776,7 +3776,10 @@ int subselect_single_select_engine::exec()
}
}
if (item->engine_changed(this))
{
thd->lex->current_select= save_select;
DBUG_RETURN(1);
}
}
if (select_lex->uncacheable &&
select_lex->uncacheable != UNCACHEABLE_EXPLAIN
......
......@@ -1984,7 +1984,8 @@ JOIN::optimize_inner()
having= new (thd->mem_root) Item_int(thd, (longlong) 0,1);
zero_result_cause= "Impossible HAVING noticed after reading const tables";
error= 0;
DBUG_RETURN(0);
select_lex->mark_const_derived(zero_result_cause);
goto setup_subq_exit;
}
}
......@@ -3377,7 +3378,8 @@ void JOIN::exec_inner()
condtions may be arbitrarily costly, and because the optimize phase
might not have produced a complete executable plan for EXPLAINs.
*/
if (exec_const_cond && !(select_options & SELECT_DESCRIBE) &&
if (!zero_result_cause &&
exec_const_cond && !(select_options & SELECT_DESCRIBE) &&
!exec_const_cond->val_int())
zero_result_cause= "Impossible WHERE noticed after reading const tables";
......
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