summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_in.result43
-rw-r--r--mysql-test/t/func_in.test36
-rw-r--r--sql/item_cmpfunc.h6
3 files changed, 84 insertions, 1 deletions
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index a172d04d880..98e39917f04 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -351,4 +351,47 @@ some_id
1
2
drop table t1;
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (a));
+INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1),(5,1),(6,1);
+CREATE TABLE t2 (a int, b int, PRIMARY KEY (a));
+INSERT INTO t2 VALUES (3,2),(4,2);
+CREATE TABLE t3 (a int PRIMARY KEY);
+INSERT INTO t3 VALUES (1),(2),(3),(4);
+CREATE TABLE t4 (a int PRIMARY KEY);
+INSERT INTO t4 VALUES (1),(2);
+EXPLAIN SELECT STRAIGHT_JOIN * FROM t3
+JOIN t1 ON t3.a=t1.a
+JOIN t2 ON t3.a=t2.a
+JOIN t4 WHERE t4.a IN (t1.b, t2.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 index PRIMARY PRIMARY 4 NULL 4 Using index
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t3.a 1
+1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
+SELECT STRAIGHT_JOIN * FROM t3
+JOIN t1 ON t3.a=t1.a
+JOIN t2 ON t3.a=t2.a
+JOIN t4 WHERE t4.a IN (t1.b, t2.b);
+a a b a b a
+3 3 1 3 2 1
+3 3 1 3 2 2
+4 4 1 4 2 1
+4 4 1 4 2 2
+EXPLAIN SELECT STRAIGHT_JOIN
+(SELECT SUM(t4.a) FROM t4 WHERE t4.a IN (t1.b, t2.b))
+FROM t3, t1, t2
+WHERE t3.a=t1.a AND t3.a=t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 index PRIMARY PRIMARY 4 NULL 4 Using index
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t3.a 1
+2 DEPENDENT SUBQUERY t4 index NULL PRIMARY 4 NULL 2 Using where; Using index
+SELECT STRAIGHT_JOIN
+(SELECT SUM(t4.a) FROM t4 WHERE t4.a IN (t1.b, t2.b))
+FROM t3, t1, t2
+WHERE t3.a=t1.a AND t3.a=t2.a;
+(SELECT SUM(t4.a) FROM t4 WHERE t4.a IN (t1.b, t2.b))
+3
+3
+DROP TABLE t1,t2,t3,t4;
End of 5.0 tests
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index d48606ac6e6..8c89aa1e729 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -254,5 +254,41 @@ select some_id from t1 where some_id not in(-4,-1,-4);
select some_id from t1 where some_id not in(-4,-1,3423534,2342342);
drop table t1;
+#
+# BUG#20420: optimizer reports wrong keys on left join with IN
+#
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (a));
+INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1),(5,1),(6,1);
+
+CREATE TABLE t2 (a int, b int, PRIMARY KEY (a));
+INSERT INTO t2 VALUES (3,2),(4,2);
+
+CREATE TABLE t3 (a int PRIMARY KEY);
+INSERT INTO t3 VALUES (1),(2),(3),(4);
+
+CREATE TABLE t4 (a int PRIMARY KEY);
+INSERT INTO t4 VALUES (1),(2);
+
+EXPLAIN SELECT STRAIGHT_JOIN * FROM t3
+ JOIN t1 ON t3.a=t1.a
+ JOIN t2 ON t3.a=t2.a
+ JOIN t4 WHERE t4.a IN (t1.b, t2.b);
+
+SELECT STRAIGHT_JOIN * FROM t3
+ JOIN t1 ON t3.a=t1.a
+ JOIN t2 ON t3.a=t2.a
+ JOIN t4 WHERE t4.a IN (t1.b, t2.b);
+
+EXPLAIN SELECT STRAIGHT_JOIN
+ (SELECT SUM(t4.a) FROM t4 WHERE t4.a IN (t1.b, t2.b))
+ FROM t3, t1, t2
+ WHERE t3.a=t1.a AND t3.a=t2.a;
+
+SELECT STRAIGHT_JOIN
+ (SELECT SUM(t4.a) FROM t4 WHERE t4.a IN (t1.b, t2.b))
+ FROM t3, t1, t2
+ WHERE t3.a=t1.a AND t3.a=t2.a;
+
+DROP TABLE t1,t2,t3,t4;
--echo End of 5.0 tests
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 454aed01aff..5149ab4cfbe 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -965,6 +965,10 @@ class Item_func_in :public Item_func_opt_neg
{
public:
Item_result cmp_type;
+ /*
+ an array of values when the right hand arguments of IN
+ are all SQL constant and there are no nulls
+ */
in_vector *array;
cmp_item *in_item;
bool have_null;
@@ -990,7 +994,7 @@ public:
DBUG_VOID_RETURN;
}
optimize_type select_optimize() const
- { return array ? OPTIMIZE_KEY : OPTIMIZE_NONE; }
+ { return OPTIMIZE_KEY; }
void print(String *str);
enum Functype functype() const { return IN_FUNC; }
const char *func_name() const { return " IN "; }