From 0f265b825136ef5a51913ce7f18255c6c432eb96 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Fri, 25 Feb 2011 21:43:57 +0300 Subject: [PATCH] BUG#723822: Crash in get_constant_key_infix with EXISTS ( SELECT .. DISTINCT ) - Make get_constant_key_infix() take into account that there may be SEL_TREEs with type=SEL_ARG::MAYBE_KEY, which it cannot process, because they are not real ranges but rather indications that we might have been able to construct a range if we had values for some other tables' fields. (check_quick_select() already has such check) --- mysql-test/r/subselect4.result | 18 ++++++++++++++++++ mysql-test/t/subselect4.test | 21 +++++++++++++++++++++ sql/opt_range.cc | 3 ++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index e188eb5a30c..9571f3fad84 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -689,3 +689,21 @@ id select_type table type possible_keys key key_len ref rows Extra 2 DEPENDENT SUBQUERY X ALL NULL NULL NULL NULL 10 2 DEPENDENT SUBQUERY B ALL a,b NULL NULL NULL 1000 Range checked for each record (index map: 0x3) drop table t1, t2; +# +# BUG#723822: Crash in get_constant_key_infix with EXISTS ( SELECT .. DISTINCT ) +# +CREATE TABLE t1 ( f1 int(11), f3 varchar(1)) ; +INSERT INTO t1 VALUES ('8','c'),('5','f'); +ALTER TABLE t1 ADD KEY (f3,f1); +CREATE TABLE t2 ( f4 varchar(1)) ; +INSERT INTO t2 VALUES ('f'),('d'); +SELECT * FROM t2 +WHERE EXISTS ( +SELECT DISTINCT f3 +FROM t1 +WHERE f3 <= t2.f4 +); +f4 +f +d +drop table t1,t2; diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index 0b8d291158f..db50ab6233b 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -619,3 +619,24 @@ select a, from t1 A; drop table t1, t2; + +--echo # +--echo # BUG#723822: Crash in get_constant_key_infix with EXISTS ( SELECT .. DISTINCT ) +--echo # +CREATE TABLE t1 ( f1 int(11), f3 varchar(1)) ; +INSERT INTO t1 VALUES ('8','c'),('5','f'); + +ALTER TABLE t1 ADD KEY (f3,f1); + +CREATE TABLE t2 ( f4 varchar(1)) ; +INSERT INTO t2 VALUES ('f'),('d'); + +SELECT * FROM t2 +WHERE EXISTS ( + SELECT DISTINCT f3 + FROM t1 + WHERE f3 <= t2.f4 +); + +drop table t1,t2; + diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 633fb3d571c..e6ff36f1307 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -11857,7 +11857,8 @@ get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree, Find the range tree for the current keypart. We assume that index_range_tree points to the leftmost keypart in the index. */ - for (cur_range= index_range_tree; cur_range; + for (cur_range= index_range_tree; + cur_range && cur_range->type == SEL_ARG::KEY_RANGE; cur_range= cur_range->next_key_part) { if (cur_range->field->eq(cur_part->field))