Commit 533e1d28 authored by Sergey Petrunya's avatar Sergey Petrunya

MDEV-273: SHOW EXPLAIN: server crashes in JOIN::print_explain on a query with impossible WHERE

- It turns out, there is a case where the join is degenerate, but 
  join->table_count!= && join->tables_list!=NULL. Need to also check 
  if join->zero_result_cause!=NULL, too.

- There is a slight problem: The code sets
    zero_result_cause= "no matching row in const table"
  when NOT running EXPLAIN. The result is that SHOW EXPLAIN will show this line while 
  regular EXPLAIN will not.
parent 382e81ca
drop table if exists t0, t1, t2;
drop table if exists t0, t1, t2, t3, t4;
drop view if exists v1;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
......@@ -407,8 +407,7 @@ set debug='d,show_explain_probe_join_exec_end';
select * from t0,t3 where t3.a=112233;
show explain for $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t3 const PRIMARY PRIMARY 4 0 unique row not found
1 SIMPLE t0 ALL NULL NULL NULL NULL 10
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL no matching row in const table
Warnings:
Note 1003 select * from t0,t3 where t3.a=112233
a a
......@@ -453,4 +452,55 @@ pk a
9 7
set debug='';
drop table t2;
#
# MDEV-273: SHOW EXPLAIN: server crashes in JOIN::print_explain on a query with impossible WHERE
#
CREATE TABLE t2 (a1 INT, KEY(a1)) ENGINE=MyISAM;
INSERT INTO t2 VALUES
(4),(6),(7),(1),(0),(7),(7),(1),(7),(1),
(5),(2),(0),(1),(8),(1),(1),(9),(1),(5);
CREATE TABLE t3 (b1 INT) ENGINE=MyISAM;
INSERT INTO t3 VALUES
(4),(5),(8),(4),(8),(2),(9),(6),(4),(8),
(3),(5),(9),(6),(8),(3),(2),(6),(3),(1),
(4),(3),(1),(7),(0),(0),(9),(5),(9),(0),
(2),(2),(5),(9),(1),(4),(8),(6),(5),(5),
(1),(7),(2),(8),(9),(3),(2),(6),(6),(5),
(4),(3),(2),(7),(4),(6),(0),(8),(5),(8),
(2),(9),(7),(5),(7),(0),(4),(3),(1),(0),
(6),(2),(8),(3),(7),(3),(5),(5),(1),(2),
(1),(7),(1),(9),(9),(8),(3);
CREATE TABLE t4 (c1 INT) ENGINE=MyISAM;
EXPLAIN
SELECT count(*) FROM t2, t3
WHERE a1 < ALL (
SELECT a1 FROM t2
WHERE a1 IN ( SELECT a1 FROM t2, t4 )
);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index NULL a1 5 NULL 20 Using where; Using index
1 PRIMARY t3 ALL NULL NULL NULL NULL 87 Using join buffer (flat, BNL join)
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
set @show_explain_probe_select_id=1;
set debug='d,show_explain_probe_do_select';
SELECT count(*) FROM t2, t3
WHERE a1 < ALL (
SELECT a1 FROM t2
WHERE a1 IN ( SELECT a1 FROM t2, t4 )
);
show explain for $thr2;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index NULL a1 5 NULL 20 Using where; Using index
1 PRIMARY t3 ALL NULL NULL NULL NULL 87 Using join buffer (flat, BNL join)
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
Warnings:
Note 1003 SELECT count(*) FROM t2, t3
WHERE a1 < ALL (
SELECT a1 FROM t2
WHERE a1 IN ( SELECT a1 FROM t2, t4 )
)
count(*)
1740
set debug='';
drop table t2, t3, t4;
drop table t0,t1;
......@@ -4,7 +4,7 @@
--source include/have_debug.inc
--disable_warnings
drop table if exists t0, t1, t2;
drop table if exists t0, t1, t2, t3, t4;
drop view if exists v1;
--enable_warnings
......@@ -444,9 +444,50 @@ set debug='';
drop table t2;
--echo #
--echo # MDEV-273: SHOW EXPLAIN: server crashes in JOIN::print_explain on a query with impossible WHERE
--echo #
CREATE TABLE t2 (a1 INT, KEY(a1)) ENGINE=MyISAM;
INSERT INTO t2 VALUES
(4),(6),(7),(1),(0),(7),(7),(1),(7),(1),
(5),(2),(0),(1),(8),(1),(1),(9),(1),(5);
CREATE TABLE t3 (b1 INT) ENGINE=MyISAM;
INSERT INTO t3 VALUES
(4),(5),(8),(4),(8),(2),(9),(6),(4),(8),
(3),(5),(9),(6),(8),(3),(2),(6),(3),(1),
(4),(3),(1),(7),(0),(0),(9),(5),(9),(0),
(2),(2),(5),(9),(1),(4),(8),(6),(5),(5),
(1),(7),(2),(8),(9),(3),(2),(6),(6),(5),
(4),(3),(2),(7),(4),(6),(0),(8),(5),(8),
(2),(9),(7),(5),(7),(0),(4),(3),(1),(0),
(6),(2),(8),(3),(7),(3),(5),(5),(1),(2),
(1),(7),(1),(9),(9),(8),(3);
CREATE TABLE t4 (c1 INT) ENGINE=MyISAM;
EXPLAIN
SELECT count(*) FROM t2, t3
WHERE a1 < ALL (
SELECT a1 FROM t2
WHERE a1 IN ( SELECT a1 FROM t2, t4 )
);
set @show_explain_probe_select_id=1;
set debug='d,show_explain_probe_do_select';
send
SELECT count(*) FROM t2, t3
WHERE a1 < ALL (
SELECT a1 FROM t2
WHERE a1 IN ( SELECT a1 FROM t2, t4 )
);
connection default;
--source include/wait_condition.inc
evalp show explain for $thr2;
connection con1;
reap;
set debug='';
drop table t2, t3, t4;
## TODO: Test this: have several SHOW EXPLAIN requests be queued up for a
## thread and served together.
......
......@@ -3752,7 +3752,11 @@ int st_select_lex::print_explain(select_result_sink *output,
int res;
if (join && join->optimized == JOIN::OPTIMIZATION_DONE)
{
if (!join->table_count || !join->tables_list)
/*
There is a number of reasons join can be marked as degenerate, so all
three conditions below can happen simultaneously, or individually:
*/
if (!join->table_count || !join->tables_list || join->zero_result_cause)
{
/* It's a degenerate join */
const char *cause= join->zero_result_cause ? join-> zero_result_cause :
......
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