summaryrefslogtreecommitdiff
path: root/mysql-test/t
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2010-01-17 17:51:10 +0300
committerSergey Petrunya <psergey@askmonty.org>2010-01-17 17:51:10 +0300
commitb83cb52e9e78a0d07c05f6515aa7811deabe434c (patch)
treeaa289e64cb57964bd08fc79d326136cb801e1da7 /mysql-test/t
parent1a490f2da492f2e5698b244341696c6dd9d8db4c (diff)
downloadmariadb-git-b83cb52e9e78a0d07c05f6515aa7811deabe434c.tar.gz
Backport of subquery optimizations to 5.3.
There are still test failures because of: - Wrong query results in outer join + semi join - EXPLAIN output differences
Diffstat (limited to 'mysql-test/t')
-rw-r--r--mysql-test/t/subselect.test721
-rw-r--r--mysql-test/t/subselect3.test440
-rw-r--r--mysql-test/t/subselect3_jcl6.test11
-rw-r--r--mysql-test/t/subselect4.test333
-rw-r--r--mysql-test/t/subselect_mat.test891
-rw-r--r--mysql-test/t/subselect_no_mat.test11
-rw-r--r--mysql-test/t/subselect_no_opts.test11
-rw-r--r--mysql-test/t/subselect_no_semijoin.test11
-rw-r--r--mysql-test/t/subselect_nulls.test94
-rw-r--r--mysql-test/t/subselect_sj.test683
-rw-r--r--mysql-test/t/subselect_sj2.test904
-rw-r--r--mysql-test/t/subselect_sj2_jcl6.test11
-rw-r--r--mysql-test/t/subselect_sj_jcl6.test11
13 files changed, 4006 insertions, 126 deletions
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index ead7c89d1c0..70fc02801a5 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1,3 +1,11 @@
+#
+# NOTE. Please do not switch connection inside this test.
+# subselect.test is included from several other test cases which set
+# explicit session properties that must be preserved throughout the test.
+# If you need to use a dedicated connection for a test case,
+# close the new connection and switch back to "default" as soon
+# as possible.
+#
# Initialise
--disable_warnings
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
@@ -811,17 +819,12 @@ create table t1 (a int, b int, index a (a,b));
create table t2 (a int, index a (a));
create table t3 (a int, b int, index a (a));
insert into t1 values (1,10), (2,20), (3,30), (4,40);
---disable_query_log
-begin;
# making table large enough
-let $1 = 10000;
-while ($1)
- {
- eval insert into t1 values (rand()*100000+200,rand()*100000);
- dec $1;
- }
-commit;
---enable_query_log
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1
+select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D;
+
insert into t2 values (2), (3), (4), (5);
insert into t3 values (10,3), (20,4), (30,5);
select * from t2 where t2.a in (select a from t1);
@@ -834,7 +837,7 @@ insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31);
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
-drop table t1, t2, t3;
+drop table t0, t1, t2, t3;
#
# alloc_group_fields() working
@@ -1494,12 +1497,13 @@ drop table t1;
#
# Subselect in non-select command just after connection
+# Disconnect new connection and switch back when test is finished
#
connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connection root;
set @got_val= (SELECT 1 FROM (SELECT 'A' as my_col) as T1 ) ;
-connection default;
disconnect root;
+connection default;
#
# primary query with temporary table and subquery with grouping
@@ -2512,33 +2516,30 @@ DROP TABLE t1, t2;
#
# Bug#14654 Cannot select from the same table twice within a UNION statement
#
-CREATE TABLE t1 (i INT);
-
-(SELECT i FROM t1) UNION (SELECT i FROM t1);
-#TODO:not supported
---error ER_PARSE_ERROR
-SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
- (
- (SELECT i FROM t1) UNION
- (SELECT i FROM t1)
- );
-
-#TODO:not supported
---error ER_PARSE_ERROR
-SELECT * FROM t1
-WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
-
-#TODO:not supported
---error ER_PARSE_ERROR
-explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
- from t1;
-
+# disabled by psergey-merge:
+#CREATE TABLE t1 (i INT);
+#
+#(SELECT i FROM t1) UNION (SELECT i FROM t1);
+#SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
+# (
+# (SELECT i FROM t1) UNION
+# (SELECT i FROM t1)
+# );
+#
#TODO:not supported
---error ER_PARSE_ERROR
-explain select * from t1 where not exists
- ((select t11.i from t1 t11) union (select t12.i from t1 t12));
-
-DROP TABLE t1;
+#--error ER_PARSE_ERROR
+#SELECT * FROM t1
+#WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
+#
+##TODO:not supported
+#--error ER_PARSE_ERROR
+#explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
+# from t1;
+#
+#explain select * from t1 where not exists
+# ((select t11.i from t1 t11) union (select t12.i from t1 t12));
+#
+#DROP TABLE t1;
#
@@ -2605,27 +2606,16 @@ DROP TABLE t1,t2;
# slow with big sort_buffer_size
#
-CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b));
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (b));
CREATE TABLE t2 (x int auto_increment, y int, z int,
PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
---disable_query_log
-begin;
-let $1=3000;
-while ($1)
-{
- eval INSERT INTO t1(a) VALUES(RAND()*1000);
- eval SELECT MAX(b) FROM t1 INTO @id;
- let $2=10;
- while ($2)
- {
- eval INSERT INTO t2(y,z) VALUES(@id,RAND()*1000);
- dec $2;
- }
- dec $1;
-}
-commit;
---enable_query_log
+insert into t1 select RAND()*1000, A.a + 10*(B.a+10*(C.a+10*D.a))
+from t3 A, t3 B, t3 C, t3 D where D.a<3;
+insert into t2(y,z) select t1.b, RAND()*1000 from t1, t3;
+enable_query_log;
SET SESSION sort_buffer_size = 32 * 1024;
SELECT SQL_NO_CACHE COUNT(*)
@@ -2637,8 +2627,7 @@ SELECT SQL_NO_CACHE COUNT(*)
FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
FROM t1) t;
-DROP TABLE t1,t2;
-
+DROP TABLE t1,t2,t3;
#
# Bug#25219 EXIST subquery with UNION over a mix of
@@ -3094,6 +3083,53 @@ SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
DROP TABLE t1, t2;
#
+# Bug31048 Many nested subqueries may cause server crash.
+#
+#create table t1(a int,b int,key(a),key(b));
+#insert into t1(a,b) values (1,2),(2,1),(2,3),(3,4),(5,4),(5,5),
+# (6,7),(7,4),(5,3);
+# TODO: enable the test after fixing 33266 in 6.0
+
+#let $nesting= 26;
+#let $should_work_nesting= 5;
+#let $start= select sum(a),a from t1 where a> ( select sum(a) from t1 ;
+#let $end= )group by a ;
+#let $start_app= where a> ( select sum(a) from t1 ;
+#let $end_pre= )group by b limit 1 ;
+
+#--disable_result_log
+#--disable_query_log
+# At least 4 level nesting should work without errors
+#while ($should_work_nesting)
+#{
+#--echo $should_work_nesting
+# eval $start $end;
+# eval explain $start $end;
+# let $start= $start
+# $start_app;
+# let $end= $end_pre
+# $end;
+# dec $should_work_nesting;
+#}
+# Other may fail with the 'stack overrun error'
+#while ($nesting)
+#{
+#--echo $nesting
+#--error 0,1436
+# eval $start $end;
+#--error 0,1436
+# eval explain $start $end;
+# let $start= $start
+# $start_app;
+# let $end= $end_pre
+# $end;
+# dec $nesting;
+#}
+#--enable_result_log
+#--enable_query_log
+#drop table t1;
+
+#
# Bug#28076 inconsistent binary/varbinary comparison
#
@@ -3195,52 +3231,45 @@ DROP TABLE t1;
#
# Bug#32036 EXISTS within a WHERE clause with a UNION crashes MySQL 5.122
#
-
-CREATE TABLE t1 (a INT);
-CREATE TABLE t2 (a INT);
-
-INSERT INTO t1 VALUES (1),(2);
-INSERT INTO t2 VALUES (1),(2);
-
-SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
-EXPLAIN EXTENDED
-SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
-
-
-#TODO:not supported
---error ER_PARSE_ERROR
-EXPLAIN EXTENDED
-SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
- (SELECT 1 FROM t2 WHERE t1.a = t2.a));
-
-DROP TABLE t1,t2;
+# disabled by psergey-merge:
+#
+#CREATE TABLE t1 (a INT);
+#CREATE TABLE t2 (a INT);
+#
+#INSERT INTO t1 VALUES (1),(2);
+#INSERT INTO t2 VALUES (1),(2);
+#
+#SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
+#EXPLAIN EXTENDED
+#SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a));
+#
+#
+#EXPLAIN EXTENDED
+#SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
+# (SELECT 1 FROM t2 WHERE t1.a = t2.a));
+#
+#DROP TABLE t1,t2;
#
# Bug#33675 Usage of an uninitialized memory by filesort in a subquery
# caused server crash.
#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1(f11 int, f12 int);
create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
insert into t1 values(1,1),(2,2), (3, 3);
-let $i=10000;
---disable_query_log
--disable_warnings
-begin;
-while ($i)
-{
- eval insert into t2 values (-1 , $i/5000 + 1, '$i');
- dec $i;
-}
-commit;
+insert into t2
+select -1 , (@a:=(A.a + 10 * (B.a + 10 * (C.a+10*D.a))))/5000 + 1, @a
+from t0 A, t0 B, t0 C, t0 D;
--enable_warnings
---enable_query_log
set session sort_buffer_size= 33*1024;
select count(*) from t1 where f12 =
(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
-drop table t1,t2;
-
+drop table t0,t1,t2;
#
# Bug#33794 "MySQL crashes executing specific query on specific dump"
@@ -3374,9 +3403,212 @@ WHERE a = 230;
DROP TABLE t1, st1, st2;
+--echo #
+--echo # Bug #48709: Assertion failed in sql_select.cc:11782:
+--echo # int join_read_key(JOIN_TAB*)
+--echo #
+
+CREATE TABLE t1 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t1 VALUES (10,1), (14,1);
+
+CREATE TABLE t2 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t2 VALUES (3,3), (5,NULL), (7,3);
+
+--echo # should have eq_ref for t1
+--replace_column 1 x 2 x 5 x 6 x 7 x 8 x 9 x 10 x
+EXPLAIN
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+
+--echo # should not crash on debug binaries
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+
+DROP TABLE t1,t2;
+
+
--echo End of 5.0 tests.
#
+# Test [NOT] IN truth table (both as top-level and general predicate).
+#
+
+create table t_out (subcase char(3),
+ a1 char(2), b1 char(2), c1 char(2));
+create table t_in (a2 char(2), b2 char(2), c2 char(2));
+
+insert into t_out values ('A.1','2a', NULL, '2a');
+#------------------------- A.2 - impossible
+insert into t_out values ('A.3', '2a', NULL, '2a');
+insert into t_out values ('A.4', '2a', NULL, 'xx');
+insert into t_out values ('B.1', '2a', '2a', '2a');
+insert into t_out values ('B.2', '2a', '2a', '2a');
+insert into t_out values ('B.3', '3a', 'xx', '3a');
+insert into t_out values ('B.4', 'xx', '3a', '3a');
+
+insert into t_in values ('1a', '1a', '1a');
+insert into t_in values ('2a', '2a', '2a');
+insert into t_in values (NULL, '2a', '2a');
+insert into t_in values ('3a', NULL, '3a');
+-- echo
+-- echo Test general IN semantics (not top-level)
+-- echo
+-- echo case A.1
+select subcase,
+ (a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'A.1';
+
+-- echo case A.2 - impossible
+
+-- echo case A.3
+select subcase,
+ (a1, b1, c1) IN (select * from t_in) pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.3';
+
+-- echo case A.4
+select subcase,
+ (a1, b1, c1) IN (select * from t_in) pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.4';
+
+-- echo case B.1
+select subcase,
+ (a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'B.1';
+
+-- echo case B.2
+select subcase,
+ (a1, b1, c1) IN (select * from t_in) pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.2';
+
+-- echo case B.3
+select subcase,
+ (a1, b1, c1) IN (select * from t_in) pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.3';
+
+-- echo case B.4
+select subcase,
+ (a1, b1, c1) IN (select * from t_in) pred_in,
+ (a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.4';
+
+-- echo
+-- echo Test IN as top-level predicate, and
+-- echo as non-top level for cases A.3, B.3 (the only cases with NULL result).
+-- echo
+-- echo case A.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.1' and
+ (a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.1' and
+ (a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.1' and
+ NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+
+-- echo case A.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.3' and
+ (a1, b1, c1) IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.3' and
+ (a1, b1, c1) NOT IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.3' and
+ NOT((a1, b1, c1) IN (select * from t_in));
+# test non-top level result indirectly
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'A.3' and
+ ((a1, b1, c1) IN (select * from t_in)) is NULL and
+ ((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+
+-- echo case A.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.4' and
+ (a1, b1, c1) IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.4' and
+ (a1, b1, c1) NOT IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.4' and
+ NOT((a1, b1, c1) IN (select * from t_in));
+
+-- echo case B.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.1' and
+ (a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.1' and
+ (a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.1' and
+ NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+
+-- echo case B.2
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.2' and
+ (a1, b1, c1) IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.2' and
+ (a1, b1, c1) NOT IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.2' and
+ NOT((a1, b1, c1) IN (select * from t_in));
+
+-- echo case B.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.3' and
+ (a1, b1, c1) IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.3' and
+ (a1, b1, c1) NOT IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.3' and
+ NOT((a1, b1, c1) IN (select * from t_in));
+# test non-top level result indirectly
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'B.3' and
+ ((a1, b1, c1) IN (select * from t_in)) is NULL and
+ ((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+
+-- echo case B.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.4' and
+ (a1, b1, c1) IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.4' and
+ (a1, b1, c1) NOT IN (select * from t_in);
+
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.4' and
+ NOT((a1, b1, c1) IN (select * from t_in));
+
+drop table t_out;
+drop table t_in;
+
+
+#
# Bug#27348 SET FUNCTION used in a subquery from WHERE condition
#
@@ -3423,6 +3655,8 @@ SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
DROP TABLE t1,t2;
+--echo End of 5.0 tests.
+
#
# Bug#38191 Server crash with subquery containing DISTINCT and ORDER BY
#
@@ -3480,44 +3714,266 @@ SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT
DROP TABLE t1,t2,t3;
-#
-# Bug#37460 Assertion failed:
-# !table->file || table->file->inited == handler::NONE
-#
-CREATE TABLE t1 (id int);
-CREATE TABLE t2 (id int, c int);
-
-INSERT INTO t1 (id) VALUES (1);
-INSERT INTO t2 (id) VALUES (1);
-INSERT INTO t1 (id) VALUES (1);
-INSERT INTO t2 (id) VALUES (1);
-
-CREATE VIEW v1 AS
-SELECT t2.c AS c FROM t1, t2
-WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
-UPDATE v1 SET c=1;
+# -- echo #
+# -- echo # Bug#33204: INTO is allowed in subselect, causing inconsistent results
+# -- echo #
+# CREATE TABLE t1( a INT );
+# INSERT INTO t1 VALUES (1),(2);
+#
+# CREATE TABLE t2( a INT, b INT );
+#
+# --error ER_PARSE_ERROR
+# SELECT *
+# FROM (SELECT a INTO @var FROM t1 WHERE a = 2) t1a;
+# --error ER_PARSE_ERROR
+# SELECT *
+# FROM (SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2) t1a;
+# --error ER_PARSE_ERROR
+# SELECT *
+# FROM (SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2) t1a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM (
+# SELECT 1 a
+# UNION
+# SELECT a INTO @var FROM t1 WHERE a = 2
+# ) t1a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM (
+# SELECT 1 a
+# UNION
+# SELECT a INTO OUTFILE 'file' FROM t1 WHERE a = 2
+# ) t1a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM (
+# SELECT 1 a
+# UNION
+# SELECT a INTO DUMPFILE 'file' FROM t1 WHERE a = 2
+# ) t1a;
+#
+# SELECT * FROM (SELECT a FROM t1 WHERE a = 2) t1a;
+#
+# SELECT * FROM (
+# SELECT a FROM t1 WHERE a = 2
+# UNION
+# SELECT a FROM t1 WHERE a = 2
+# ) t1a;
+#
+# SELECT * FROM (
+# SELECT 1 a
+# UNION
+# SELECT a FROM t1 WHERE a = 2
+# UNION
+# SELECT a FROM t1 WHERE a = 2
+# ) t1a;
+#
+# # This was not allowed previously. Possibly, it should be allowed on the future.
+# # For now, the intent is to keep the fix as non-intrusive as possible.
+# --error ER_PARSE_ERROR
+# SELECT * FROM ((SELECT 1 a) UNION SELECT 1 a);
+# SELECT * FROM (SELECT 1 a UNION (SELECT 1 a)) alias;
+# SELECT * FROM (SELECT 1 UNION SELECT 1) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM ((SELECT 1 a INTO @a)) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM ((SELECT 1 a INTO OUTFILE 'file' )) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM ((SELECT 1 a INTO DUMPFILE 'file' )) t1a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO @a)) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO DUMPFILE 'file' )) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION (SELECT 1 a INTO OUTFILE 'file' )) t1a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO @a))) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO DUMPFILE 'file' ))) t1a;
+# --error ER_PARSE_ERROR
+# SELECT * FROM (SELECT 1 a UNION ((SELECT 1 a INTO OUTFILE 'file' ))) t1a;
+#
+# SELECT * FROM (SELECT 1 a ORDER BY a) t1a;
+# SELECT * FROM (SELECT 1 a UNION SELECT 1 a ORDER BY a) t1a;
+# SELECT * FROM (SELECT 1 a UNION SELECT 1 a LIMIT 1) t1a;
+# SELECT * FROM (SELECT 1 a UNION SELECT 1 a ORDER BY a LIMIT 1) t1a;
+#
+# # Test of rule
+# # table_factor: '(' get_select_lex query_expression_body ')' opt_table_alias
+# # UNION should not be allowed inside the parentheses, nor should
+# # aliases after.
+# #
+# SELECT * FROM t1 JOIN (SELECT 1 UNION SELECT 1) alias ON 1;
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 JOIN ((SELECT 1 UNION SELECT 1)) ON 1;
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 JOIN (t1 t1a UNION SELECT 1) ON 1;
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 JOIN ((t1 t1a UNION SELECT 1)) ON 1;
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 JOIN (t1 t1a) t1a ON 1;
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 JOIN ((t1 t1a)) t1a ON 1;
+#
+# SELECT * FROM t1 JOIN (t1 t1a) ON 1;
+# SELECT * FROM t1 JOIN ((t1 t1a)) ON 1;
+#
+# SELECT * FROM (t1 t1a);
+# SELECT * FROM ((t1 t1a));
+#
+# SELECT * FROM t1 JOIN (SELECT 1 t1a) alias ON 1;
+# SELECT * FROM t1 JOIN ((SELECT 1 t1a)) alias ON 1;
+#
+# SELECT * FROM t1 JOIN (SELECT 1 a) a ON 1;
+# SELECT * FROM t1 JOIN ((SELECT 1 a)) a ON 1;
+#
+# # For the join, TABLE_LIST::select_lex == NULL
+# # Check that we handle this.
+# --error ER_PARSE_ERROR
+# SELECT * FROM (t1 JOIN (SELECT 1) t1a1 ON 1) t1a2;
+#
+# SELECT * FROM t1 WHERE a = ALL ( SELECT 1 );
+# SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION SELECT 1 );
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 3 UNION SELECT 1 );
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO @a);
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
+#
+# SELECT * FROM t1 WHERE a = ( SELECT 1 );
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 INTO @a);
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 INTO OUTFILE 'file' );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 INTO DUMPFILE 'file' );
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO @a);
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
+#
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 INTO @v );
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 INTO OUTFILE 'file' );
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 INTO DUMPFILE 'file' );
+#
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 UNION SELECT 1 INTO @v );
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 UNION SELECT 1 INTO OUTFILE 'file' );
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 UNION SELECT 1 INTO DUMPFILE 'file' );
+#
+# # Make sure context is popped when we leave the nested select
+# SELECT ( SELECT a FROM t1 WHERE a = 1 ), a FROM t1;
+# SELECT ( SELECT a FROM t1 WHERE a = 1 UNION SELECT 1 ), a FROM t1;
+#
+# # Make sure we have feature F561 (see .yy file)
+# SELECT * FROM t2 WHERE (a, b) IN (SELECT a, b FROM t2);
+#
+# # Make sure the parser does not allow nested UNIONs anywhere
+#
+# --error ER_PARSE_ERROR
+# SELECT 1 UNION ( SELECT 1 UNION SELECT 1 );
+# --error ER_PARSE_ERROR
+# ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
+#
+# --error ER_PARSE_ERROR
+# SELECT ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+# --error ER_PARSE_ERROR
+# SELECT ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1;
+# SELECT ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
+# SELECT ((SELECT 1 UNION SELECT 1 UNION SELECT 1));
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+# --error ER_PARSE_ERROR
+# SELECT * FROM ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
+# SELECT * FROM ( SELECT 1 UNION SELECT 1 UNION SELECT 1 ) a;
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION ( SELECT 1 UNION SELECT 1 ) );
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ALL ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a = ANY ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a IN ( ( SELECT 1 UNION SELECT 1 ) UNION SELECT 1 );
+#
+# SELECT * FROM t1 WHERE a = ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
+# SELECT * FROM t1 WHERE a = ALL ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
+# SELECT * FROM t1 WHERE a = ANY ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
+# SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 UNION SELECT 1 );
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE EXISTS ( SELECT 1 UNION SELECT 1 INTO @v );
+# SELECT EXISTS(SELECT 1+1);
+# --error ER_PARSE_ERROR
+# SELECT EXISTS(SELECT 1+1 INTO @test);
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a IN ( SELECT 1 UNION SELECT 1 INTO @v );
+#
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE EXISTS ( SELECT 1 INTO @v );
+# --error ER_PARSE_ERROR
+# SELECT * FROM t1 WHERE a IN ( SELECT 1 INTO @v );
+# DROP TABLE t1, t2;
-CREATE VIEW v2 (a,b) AS
-SELECT t2.id, t2.c AS c FROM t1, t2
-WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
-
---error ER_VIEW_CHECK_FAILED
-INSERT INTO v2(a,b) VALUES (2,2);
-
-# disabled for now as this refers to old content of t2
---disable_parsing
-INSERT INTO v2(a,b) VALUES (1,2);
---enable_parsing
-SELECT * FROM v1;
-
-CREATE VIEW v3 AS
-SELECT t2.c AS c FROM t2
-WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
-
-DELETE FROM v3;
+--echo #
+--echo # BUG#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+--echo #
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+ (10, 10, 10, 'l'),
+ (20, 20, 20, 'l'),
+ (40, 40, 40, 'l'),
+ (41, 40, null, 'l'),
+ (50, 50, 50, 'l'),
+ (51, 50, null, 'l'),
+ (60, 60, 60, 'l'),
+ (61, 60, null, 'l'),
+ (70, 70, 70, 'l'),
+ (90, 90, null, 'l');
+insert into t2 values
+ (10, 10, 10, 'r'),
+ (30, 30, 30, 'r'),
+ (50, 50, 50, 'r'),
+ (60, 60, 60, 'r'),
+ (61, 60, null, 'r'),
+ (70, 70, 70, 'r'),
+ (71, 70, null, 'r'),
+ (80, 80, 80, 'r'),
+ (81, 80, null, 'r'),
+ (100,100,null, 'r');
-DROP VIEW v1,v2,v3;
-DROP TABLE t1,t2;
+select *
+from t1
+where v in(select v
+ from t2
+ where t1.g=t2.g) is unknown;
+drop table t1, t2;
--echo #
--echo # Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
@@ -3554,4 +4010,19 @@ where v in(select v
where t1.g=t2.g) is unknown;
drop table t1, t2;
+#
+# Bug #31157: Crash when select+order by the avg of some field within the
+# group by
+#
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+ (SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+DROP TABLE t1;
+
--echo End of 5.1 tests.
diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test
index ee90fb9ff52..8ae73587d6e 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -1,5 +1,5 @@
--disable_warnings
-drop table if exists t0, t1, t2, t3, t4, t5;
+drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22;
--enable_warnings
#
@@ -619,6 +619,20 @@ SELECT 1 FROM t1 WHERE t1.a NOT IN (SELECT 1 FROM t1, t2 WHERE 0);
DROP TABLE t1, t2;
#
+# Bug 2198
+#
+
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "subselect.out.file.1" from t1;
+delete from t1;
+load data infile "subselect.out.file.1" into table t1;
+select * from t1;
+drop table t1;
+let $datadir=`select @@datadir`;
+--remove_file $datadir/test/subselect.out.file.1
+
+#
# Bug #37894: Assertion in init_read_record_seq in handler.h line 1444
#
@@ -692,6 +706,13 @@ DROP TABLE t1;
--echo End of 5.0 tests
+--echo #
+--echo # BUG#36896: Server crash on SELECT FROM DUAL
+--echo #
+create table t1 (a int);
+select 1 as res from dual where (1) in (select * from t1);
+drop table t1;
+
#
# BUG#36135 "void Diagnostics_area::set_eof_status(THD*): Assertion `!is_set()' failed."
#
@@ -730,3 +751,420 @@ where
from t4, t5 limit 2));
drop table t0, t1, t2, t3, t4, t5;
+
+--echo #
+--echo # BUG#48177 - SELECTs with NOT IN subqueries containing NULL
+--echo # values return too many records
+--echo #
+
+CREATE TABLE t1 (
+ i1 int DEFAULT NULL,
+ i2 int DEFAULT NULL
+) ;
+
+INSERT INTO t1 VALUES (1, NULL);
+INSERT INTO t1 VALUES (2, 3);
+INSERT INTO t1 VALUES (4, NULL);
+INSERT INTO t1 VALUES (4, 0);
+INSERT INTO t1 VALUES (NULL, NULL);
+
+CREATE TABLE t2 (
+ i1 int DEFAULT NULL,
+ i2 int DEFAULT NULL
+) ;
+
+INSERT INTO t2 VALUES (4, NULL);
+INSERT INTO t2 VALUES (5, 0);
+
+--echo
+--echo Data in t1
+SELECT i1, i2 FROM t1;
+
+--echo
+--echo Data in subquery (should be filtered out)
+SELECT i1, i2 FROM t2 ORDER BY i1;
+
+FLUSH STATUS;
+
+--echo
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+ NOT IN (SELECT i1, i2 FROM t2);
+
+--echo
+--echo # Check that the subquery only has to be evaluated once
+--echo # for all-NULL values even though there are two (NULL,NULL) records
+--echo # Baseline:
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+
+--echo
+INSERT INTO t1 VALUES (NULL, NULL);
+FLUSH STATUS;
+
+--echo
+SELECT i1, i2
+FROM t1
+WHERE (i1, i2)
+ NOT IN (SELECT i1, i2 FROM t2);
+
+--echo
+--echo # Handler_read_rnd_next should be one more than baseline
+--echo # (read record from t1, but do not read from t2)
+SHOW STATUS LIKE '%Handler_read_rnd_next';
+
+
+DROP TABLE t1,t2;
+
+--echo End of 5.1 tests
+
+#
+# Test for the problem with using sj-materialization when subquery's select
+# list element SCOL is covered by equality propagation and has preceding equal
+# column PCOL which belongs to a table within the the semi-join nest: SJM-Scan
+# process should unpack column value not to SCOL but rather to PCOL, as
+# substitute_best_equal has made all conditions to refer to PCOL.
+#
+CREATE TABLE t1 (
+ a int(11) NOT NULL,
+ b int(11) NOT NULL,
+ c datetime default NULL,
+ PRIMARY KEY (a),
+ KEY idx_bc (b,c)
+);
+
+INSERT INTO t1 VALUES
+(406989,67,'2006-02-23 17:08:46'), (150078,67,'2005-10-26 11:17:45'),
+(406993,67,'2006-02-27 11:20:57'), (245655,67,'2005-12-08 15:59:08'),
+(406994,67,'2006-02-27 11:26:46'), (256,67,NULL),
+(398341,67,'2006-02-20 04:48:44'), (254,67,NULL),(1120,67,NULL),
+(406988,67,'2006-02-23 17:07:22'), (255,67,NULL),
+(398340,67,'2006-02-20 04:38:53'),(406631,67,'2006-02-23 10:49:42'),
+(245653,67,'2005-12-08 15:59:07'),(406992,67,'2006-02-24 16:47:18'),
+(245654,67,'2005-12-08 15:59:08'),(406995,67,'2006-02-28 11:55:00'),
+(127261,67,'2005-10-13 12:17:58'),(406991,67,'2006-02-24 16:42:32'),
+(245652,67,'2005-12-08 15:58:27'),(398545,67,'2006-02-20 04:53:13'),
+(154504,67,'2005-10-28 11:53:01'),(9199,67,NULL),(1,67,'2006-02-23 15:01:35'),
+(223456,67,NULL),(4101,67,NULL),(1133,67,NULL),
+(406990,67,'2006-02-23 18:01:45'),(148815,67,'2005-10-25 15:34:17'),
+(148812,67,'2005-10-25 15:30:01'),(245651,67,'2005-12-08 15:58:27'),
+(154503,67,'2005-10-28 11:52:38');
+
+create table t11 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 asc;
+create table t12 select * from t1 where b = 67 AND (c IS NULL OR c > NOW()) order by 3 desc;
+create table t21 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 asc;
+create table t22 select * from t1 where b = 67 AND (c IS NULL OR c > '2005-12-08') order by 3 desc;
+
+update t22 set c = '2005-12-08 15:58:27' where a = 255;
+explain select t21.* from t21,t22 where t21.a = t22.a and
+t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
+select t21.* from t21,t22 where t21.a = t22.a and
+t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a;
+
+drop table t1, t11, t12, t21, t22;
+
+#
+# Test sj-materialization re-execution. The test isn't meaningful (materialized
+# table stays the same across all executions) because it's hard to create a
+# dataset that would verify correct re-execution without hitting BUG#31480
+#
+create table t1(a int);
+insert into t1 values (0),(1);
+
+set @@optimizer_switch='firstmatch=off';
+explain
+select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
+select (select max(Y.a) from t1 Y where a in (select a from t1 Z) and a < X.a) as subq from t1 X;
+set @@optimizer_switch=default;
+
+drop table t1;
+
+#
+# Test confluent duplicate weedout
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 as select * from t0;
+insert into t1 select a+10 from t0;
+set @@optimizer_switch='firstmatch=off,materialization=off';
+insert into t0 values(2);
+explain select * from t1 where 2 in (select a from t0);
+select * from t1 where 2 in (select a from t0);
+set @@optimizer_switch='default,materialization=off';
+explain select * from t1 where 2 in (select a from t0);
+select * from t1 where 2 in (select a from t0);
+set @@optimizer_switch=default;
+
+
+#
+# FirstMatch referring to a derived table
+#
+explain select * from (select a from t0) X where a in (select a from t1);
+drop table t0, t1;
+
+#
+# LooseScan: Check if we can pick it together with range access
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (kp1 int, kp2 int, c int, filler char(100), key(kp1, kp2));
+insert into t1 select A.a+10*(B.a+10*C.a), 0, 0, 'filler' from t0 A, t0 B, t0 C;
+insert into t1 select * from t1 where kp1 < 20;
+
+create table t3 (a int);
+insert into t3 select A.a + 10*B.a from t0 A, t0 B;
+
+explain select * from t3 where a in (select kp1 from t1 where kp1<20);
+
+create table t4 (pk int primary key);
+insert into t4 select a from t3;
+
+explain select * from t3 where a in (select t1.kp1 from t1,t4 where kp1<20
+and t4.pk=t1.c);
+
+drop table t1, t3, t4;
+
+#
+# Test if we handle duplicate elimination temptable overflowing to disk
+#
+create table t1 (a int) as select * from t0 where a < 5;
+
+set @save_max_heap_table_size=@@max_heap_table_size;
+set @@optimizer_switch='firstmatch=off,materialization=off';
+set @@max_heap_table_size= 16384;
+
+explain select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
+flush status;
+select count(*) from t0 A, t0 B, t0 C, t0 D where D.a in (select a from t1 E);
+show status like 'Created_tmp_disk_tables';
+set @save_max_heap_table_size=@@max_heap_table_size;
+set @@optimizer_switch=default;
+drop table t0, t1;
+
+#
+# Materialize + Scan + ref access to the subsequent table based on scanned
+# value
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2(a int);
+insert into t2 values (1),(2);
+create table t3 ( a int , filler char(100), key(a));
+insert into t3 select A.a + 10*B.a, 'filler' from t0 A, t0 B;
+explain select * from t3 where a in (select a from t2) and (a > 5 or a < 10);
+select * from t3 where a in (select a from t2);
+
+drop table t0, t2, t3;
+
+#
+# DATETIME type checks
+#
+set @@optimizer_switch='firstmatch=off,materialization=off';
+create table t1 (a date);
+insert into t1 values ('2008-01-01'),('2008-01-01'),('2008-02-01'),('2008-02-01');
+create table t2 (a int);
+insert into t2 values (1),(2);
+create table t3 (a char(10));
+insert into t3 select * from t1;
+insert into t3 values (1),(2);
+explain select * from t2 where a in (select a from t1);
+explain select * from t2 where a in (select a from t2);
+explain select * from t2 where a in (select a from t3);
+explain select * from t1 where a in (select a from t3);
+drop table t1, t2, t3;
+create table t1 (a decimal);
+insert into t1 values (1),(2);
+explain select * from t1 where a in (select a from t1);
+drop table t1;
+set @@optimizer_switch=default;
+
+#
+# SJ-Materialization-scan for non-first table
+#
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 as select * from t1;
+create table t3 (a int, b int, filler char(100), key(a));
+insert into t3 select A.a + 10*B.a, A.a + 10*B.a, 'filler' from t1 A, t1 B, t1 C;
+explain select * from t1, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30) and t1.a =3;
+
+#
+# Verify that straight_join modifier in parent or child prevents flattening
+#
+explain select straight_join * from t1 A, t1 B where A.a in (select a from t2);
+explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
+explain select * from t2 where a in (select straight_join A.a from t1 A, t1 B);
+explain select straight_join * from t2 X, t2 Y
+where X.a in (select straight_join A.a from t1 A, t1 B);
+
+#
+# SJ-Materialization scan + first table being system const table
+#
+create table t0 (a int, b int);
+insert into t0 values(1,1);
+explain select * from t0, t3 where t3.a in (select a from t2) and (t3.a < 10 or t3.a >30);
+create table t4 as select a as x, a as y from t1;
+explain select * from t0, t3 where (t3.a, t3.b) in (select x,y from t4) and (t3.a < 10 or t3.a >30);
+drop table t0,t1,t2,t3,t4;
+
+#
+# LooseScan with ref access
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, filler char(100), key(a,b));
+insert into t1 select A.a, B.a, 'filler' from t0 A, t0 B;
+create table t2 as select * from t1;
+
+explain select * from t2 where a in (select b from t1 where a=3);
+explain select * from t2 where (b,a) in (select a,b from t1 where a=3);
+
+drop table t1,t2;
+
+#
+# Multi-column sj-materialization with lookups
+#
+create table t1 (a int, b int);
+insert into t1 select a,a from t0;
+create table t2 (a int, b int);
+insert into t2 select A.a + 10*B.a, A.a + 10*B.a from t0 A, t0 B;
+
+set @@optimizer_switch='firstmatch=off';
+explain select * from t1 where (a,b) in (select a,b from t2);
+
+# A smallish test if find_best() still works for semi-join optimization:
+set @save_optimizer_search_depth=@@optimizer_search_depth;
+set @@optimizer_search_depth=63;
+explain select * from t1 where (a,b) in (select a,b from t2);
+set @@optimizer_search_depth=@save_optimizer_search_depth;
+set @@optimizer_switch=default;
+
+drop table t0, t1, t2;
+
+
+#
+# Primitive SJ-Materialization tests for DECIMAL and DATE
+#
+create table t0 (a decimal(4,2));
+insert into t0 values (10.24), (22.11);
+create table t1 as select * from t0;
+insert into t1 select * from t0;
+explain select * from t0 where a in (select a from t1);
+select * from t0 where a in (select a from t1);
+drop table t0, t1;
+
+create table t0(a date);
+insert into t0 values ('2008-01-01'),('2008-02-02');
+create table t1 as select * from t0;
+insert into t1 select * from t0;
+explain select * from t0 where a in (select a from t1);
+select * from t0 where a in (select a from t1);
+drop table t0, t1;
+
+#
+# Fix a trivial crash with SJ-Materialization lookup, multiple tables in the
+# subquery, and a condition on some of inner tables but not others
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 as select a as a, a as b, a as c from t0 where a < 3;
+create table t2 as select a as a, a as b from t0 where a < 3;
+insert into t2 select * from t2;
+
+explain select * from t1 where (a,b,c) in (select X.a, Y.a, Z.a from t2 X, t2 Y, t2 Z where X.b=33);
+
+drop table t0,t1,t2;
+
+--echo
+--echo BUG#37842: Assertion in DsMrr_impl::dsmrr_init, at handler.cc:4307
+--echo
+CREATE TABLE t1 (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `int_key` int(11) DEFAULT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `int_key` (`int_key`)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1,9),(2,3),(3,8),(4,6),(5,9),(6,5),(7,5),(8,9),(9,1),(10,10);
+SELECT `pk` FROM t1 AS OUTR WHERE `int_key` = ALL (
+ SELECT `int_key` FROM t1 AS INNR WHERE INNR . `pk` >= 9
+);
+DROP TABLE t1;
+
+--echo
+--echo BUG#40118 Crash when running Batched Key Access and requiring one match for each key
+--echo
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, key(a));
+insert into t1 select * from t0;
+alter table t1 add b int not null, add filler char(200);
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+
+set @save_join_cache_level=@@join_cache_level;
+set join_cache_level=6;
+select * from t0 where t0.a in (select t1.a from t1 where t1.b=0);
+set join_cache_level=@save_join_cache_level;
+drop table t0, t1;
+
+--echo #
+--echo # BUG#32665 Query with dependent subquery is too slow
+--echo #
+create table t1 (
+ idIndividual int primary key
+);
+insert into t1 values (1),(2);
+
+create table t2 (
+ idContact int primary key,
+ contactType int,
+ idObj int
+);
+insert into t2 values (1,1,1),(2,2,2),(3,3,3);
+
+create table t3 (
+ idAddress int primary key,
+ idContact int,
+ postalStripped varchar(100)
+);
+
+insert into t3 values (1,1, 'foo'), (2,2,'bar');
+
+--echo The following must be converted to a semi-join:
+explain extended SELECT a.idIndividual FROM t1 a
+WHERE a.idIndividual IN
+ ( SELECT c.idObj FROM t3 cona
+ INNER JOIN t2 c ON c.idContact=cona.idContact
+ WHERE cona.postalStripped='T2H3B2'
+ );
+drop table t1,t2,t3;
+
+--echo #
+--echo # BUG#47367 Crash in Name_resolution_context::process_error
+--echo #
+
+SET SESSION optimizer_switch = 'default,semijoin=off';
+CREATE TABLE t1 (f1 INTEGER);
+CREATE TABLE t2 LIKE t1;
+delimiter |;
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
+delimiter ;|
+CALL p1;
+ALTER TABLE t2 CHANGE COLUMN f1 my_column INT;
+CALL p1;
+DROP PROCEDURE p1;
+--echo # Restore the original column list of table t2:
+ALTER TABLE t2 CHANGE COLUMN my_column f1 INT;
+
+SET SESSION optimizer_switch = 'semijoin=on';
+delimiter |;
+--echo # Recreate procedure so that we eliminate any caching effects
+CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
+delimiter ;|
+CALL p1;
+ALTER TABLE t2 CHANGE COLUMN f1 my_column INT;
+--error ER_BAD_FIELD_ERROR
+CALL p1;
+DROP PROCEDURE p1;
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/subselect3_jcl6.test b/mysql-test/t/subselect3_jcl6.test
new file mode 100644
index 00000000000..9ee23288d99
--- /dev/null
+++ b/mysql-test/t/subselect3_jcl6.test
@@ -0,0 +1,11 @@
+#
+# Run subselect3.test with BKA enabled
+#
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+--source t/subselect3.test
+
+set join_cache_level=default;
+show variables like 'join_cache_level';
diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test
new file mode 100644
index 00000000000..d71ce28d2b3
--- /dev/null
+++ b/mysql-test/t/subselect4.test
@@ -0,0 +1,333 @@
+# General purpose bug fix tests go here : subselect.test too large
+
+
+--echo #
+--echo # Bug #46791: Assertion failed:(table->key_read==0),function unknown
+--echo # function,file sql_base.cc
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, KEY(a));
+INSERT INTO t1 VALUES (1,1),(2,2);
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1,1),(2,2);
+CREATE TABLE t3 LIKE t1;
+
+--echo # should have 1 impossible where and 2 dependent subqueries
+EXPLAIN
+SELECT 1 FROM t1
+WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
+ORDER BY count(*);
+
+--echo # should not crash the next statement
+SELECT 1 FROM t1
+WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE 1 = (SELECT MIN(t2.b) FROM t3))
+ORDER BY count(*);
+
+--echo # should not crash: the crash is caused by the previous statement
+SELECT 1;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #47106: Crash / segfault on adding EXPLAIN to a non-crashing
+--echo # query
+--echo #
+
+CREATE TABLE t1 (
+ a INT,
+ b INT,
+ PRIMARY KEY (a),
+ KEY b (b)
+);
+INSERT INTO t1 VALUES (1, 1), (2, 1);
+
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 SELECT * FROM t1;
+
+CREATE TABLE t3 LIKE t1;
+INSERT INTO t3 SELECT * FROM t1;
+
+--echo # Should not crash.
+--echo # Should have 1 impossible where and 2 dependent subqs.
+EXPLAIN
+SELECT
+ (SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+FROM t3 WHERE 1 = 0 GROUP BY 1;
+
+--echo # should return 0 rows
+SELECT
+ (SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
+FROM t3 WHERE 1 = 0 GROUP BY 1;
+
+DROP TABLE t1,t2,t3;
+
+--echo End of 5.0 tests.
+
+--echo #
+--echo # BUG#46743 "Azalea processing correlated, aggregate SELECT
+--echo # subqueries incorrectly"
+--echo #
+
+CREATE TABLE t1 (c int);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2 (d int , KEY (d)); # index is needed for bug
+INSERT INTO t2 VALUES (NULL),(NULL); # two rows needed for bug
+# we see that subquery returns 0 rows
+--echo 0 rows in subquery
+SELECT 1 AS RESULT FROM t2,t1 WHERE d = c;
+# so here it ends up as NULL
+--echo base query
+SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 ;
+EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 ;
+--echo first equivalent variant
+SELECT (SELECT 1 FROM t2 WHERE d = IFNULL(c,NULL)) AS RESULT FROM t1 GROUP BY c ;
+EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = IFNULL(c,NULL)) AS RESULT FROM t1 GROUP BY c;
+--echo second equivalent variant
+# used to fail with 1242: Subquery returns more than 1 row
+SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 GROUP BY c ;
+EXPLAIN EXTENDED SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 GROUP BY c ;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # BUG#45928 "Differing query results depending on MRR and
+--echo # engine_condition_pushdown settings"
+--echo #
+
+CREATE TABLE `t1` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `time_nokey` time NOT NULL,
+ `varchar_key` varchar(1) NOT NULL,
+ `varchar_nokey` varchar(1) NOT NULL,
+ PRIMARY KEY (`pk`),
+ KEY `varchar_key` (`varchar_key`)
+) AUTO_INCREMENT=12 DEFAULT CHARSET=latin1;
+INSERT INTO `t1` VALUES (10,'00:00:00','i','i'),(11,'00:00:00','','');
+
+set @old_optimizer_switch = @@session.optimizer_switch,
+ @old_optimizer_use_mrr = @@session.optimizer_use_mrr,
+ @old_engine_condition_pushdown = @@session.engine_condition_pushdown;
+
+SET SESSION OPTIMIZER_SWITCH = 'materialization=off,semijoin=off,loosescan=off,firstmatch=off';
+SET SESSION optimizer_use_mrr = 'force';
+SET SESSION engine_condition_pushdown = 1;
+
+ SELECT `time_nokey` G1 FROM t1 WHERE ( `varchar_nokey` , `varchar_key` ) IN (
+SELECT `varchar_nokey` , `varchar_nokey` ) AND `varchar_key` >= 'c' HAVING G1 ORDER
+BY `pk` ;
+
+set @@session.optimizer_switch = @old_optimizer_switch,
+ @@session.optimizer_use_mrr = @old_optimizer_use_mrr,
+ @@session.engine_condition_pushdown = @old_engine_condition_pushdown;
+
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#45863 "Assertion failed: (fixed == 0), function fix_fields(),
+--echo # file item.cc, line 4448"
+--echo #
+--disable_warnings
+DROP TABLE IF EXISTS C, BB;
+--enable_warnings
+
+CREATE TABLE C (
+ varchar_nokey varchar(1) NOT NULL
+);
+INSERT INTO C VALUES
+ ('k'),('a'),(''),('u'),('e'),('v'),('i'),
+ ('t'),('u'),('f'),('u'),('m'),('j'),('f'),
+ ('v'),('j'),('g'),('e'),('h'),('z');
+CREATE TABLE BB (
+ varchar_nokey varchar(1) NOT NULL
+);
+INSERT INTO BB VALUES ('i'),('t');
+-- error ER_OPERAND_COLUMNS
+SELECT varchar_nokey FROM C
+WHERE (varchar_nokey, OUTR) IN (SELECT varchar_nokey
+ FROM BB);
+-- error ER_BAD_FIELD_ERROR
+SELECT varchar_nokey FROM C
+WHERE (varchar_nokey, OUTR) IN (SELECT varchar_nokey, varchar_nokey
+ FROM BB);
+DROP TABLE C,BB;
+
+--echo #
+--echo # During work with BUG#45863 I had problems with a query that was
+--echo # optimized differently in regular and prepared mode.
+--echo # Because there was a bug in one of the selected strategies, I became
+--echo # aware of the problem. Adding an EXPLAIN query to catch this.
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, t3;
+--enable_warnings
+
+CREATE TABLE t1
+ (EMPNUM CHAR(3) NOT NULL,
+ EMPNAME CHAR(20),
+ GRADE DECIMAL(4),
+ CITY CHAR(15));
+
+CREATE TABLE t2
+ (PNUM CHAR(3) NOT NULL,
+ PNAME CHAR(20),
+ PTYPE CHAR(6),
+ BUDGET DECIMAL(9),
+ CITY CHAR(15));
+
+CREATE TABLE t3
+ (EMPNUM CHAR(3) NOT NULL,
+ PNUM CHAR(3) NOT NULL,
+ HOURS DECIMAL(5));
+
+INSERT INTO t1 VALUES ('E1','Alice',12,'Deale');
+INSERT INTO t1 VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO t1 VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO t1 VALUES ('E4','Don',12,'Deale');
+INSERT INTO t1 VALUES ('E5','Ed',13,'Akron');
+
+INSERT INTO t2 VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO t2 VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO t2 VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO t2 VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO t2 VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO t2 VALUES ('P6','PAYR','Design',50000,'Deale');
+
+INSERT INTO t3 VALUES ('E1','P1',40);
+INSERT INTO t3 VALUES ('E1','P2',20);
+INSERT INTO t3 VALUES ('E1','P3',80);
+INSERT INTO t3 VALUES ('E1','P4',20);
+INSERT INTO t3 VALUES ('E1','P5',12);
+INSERT INTO t3 VALUES ('E1','P6',12);
+INSERT INTO t3 VALUES ('E2','P1',40);
+INSERT INTO t3 VALUES ('E2','P2',80);
+INSERT INTO t3 VALUES ('E3','P2',20);
+INSERT INTO t3 VALUES ('E4','P2',20);
+INSERT INTO t3 VALUES ('E4','P4',40);
+INSERT INTO t3 VALUES ('E4','P5',80);
+
+SET @old_optimizer_switch = @@session.optimizer_switch;
+SET @old_join_cache_level = @@session.join_cache_level;
+SET SESSION optimizer_switch = 'firstmatch=on,loosescan=on,materialization=on,semijoin=on';
+SET SESSION join_cache_level = 1;
+
+CREATE UNIQUE INDEX t1_IDX ON t1(EMPNUM);
+
+EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'))";
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+DROP INDEX t1_IDX ON t1;
+CREATE INDEX t1_IDX ON t1(EMPNUM);
+
+EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'))";
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+DROP INDEX t1_IDX ON t1;
+
+EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+PREPARE stmt FROM "EXPLAIN SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'))";
+EXECUTE stmt;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+SET SESSION optimizer_switch = @old_optimizer_switch;
+SET SESSION join_cache_level = @old_join_cache_level;
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # BUG#45221 Query SELECT pk FROM C WHERE pk IN (SELECT int_key) failing
+--echo #
+
+CREATE TABLE t1 (
+ i1_key INT,
+ i2 INT,
+ i3 INT,
+ KEY i1_index (i1_key)
+);
+
+INSERT INTO t1 VALUES (9,1,2), (9,2,1);
+
+CREATE TABLE t2 (
+ pk INT NOT NULL,
+ i1 INT,
+ PRIMARY KEY (pk)
+);
+
+INSERT INTO t2 VALUES (9,1);
+
+--echo # Enable Index condition pushdown
+--replace_column 1 #
+SELECT @old_icp:=@@engine_condition_pushdown;
+SET SESSION engine_condition_pushdown = 'ON';
+
+--echo
+SELECT pk
+FROM t2
+WHERE
+ pk IN (
+ SELECT i1_key
+ FROM t1
+ WHERE t1.i2 < t1.i3 XOR t2.i1 > 1
+ ORDER BY t1.i2 desc);
+
+--echo # Restore old value for Index condition pushdown
+SET SESSION engine_condition_pushdown=@old_icp;
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/subselect_mat.test b/mysql-test/t/subselect_mat.test
new file mode 100644
index 00000000000..71b453057f0
--- /dev/null
+++ b/mysql-test/t/subselect_mat.test
@@ -0,0 +1,891 @@
+#
+# Hash semi-join regression tests
+# (WL#1110: Subquery optimization: materialization)
+#
+
+--disable_warnings
+drop table if exists t1, t2, t3, t1i, t2i, t3i;
+drop view if exists v1, v2, v1m, v2m;
+--enable_warnings
+
+create table t1 (a1 char(8), a2 char(8));
+create table t2 (b1 char(8), b2 char(8));
+create table t3 (c1 char(8), c2 char(8));
+
+insert into t1 values ('1 - 00', '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+insert into t1 values ('1 - 02', '2 - 02');
+
+insert into t2 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 02', '2 - 02');
+insert into t2 values ('1 - 02', '2 - 02');
+insert into t2 values ('1 - 03', '2 - 03');
+
+insert into t3 values ('1 - 01', '2 - 01');
+insert into t3 values ('1 - 02', '2 - 02');
+insert into t3 values ('1 - 03', '2 - 03');
+insert into t3 values ('1 - 04', '2 - 04');
+
+# Indexed columns
+create table t1i (a1 char(8), a2 char(8));
+create table t2i (b1 char(8), b2 char(8));
+create table t3i (c1 char(8), c2 char(8));
+create index it1i1 on t1i (a1);
+create index it1i2 on t1i (a2);
+create index it1i3 on t1i (a1, a2);
+
+create index it2i1 on t2i (b1);
+create index it2i2 on t2i (b2);
+create index it2i3 on t2i (b1, b2);
+
+create index it3i1 on t3i (c1);
+create index it3i2 on t3i (c2);
+create index it3i3 on t3i (c1, c2);
+
+insert into t1i select * from t1;
+insert into t2i select * from t2;
+insert into t3i select * from t3;
+
+# force the use of materialization
+set @@optimizer_switch='semijoin=off';
+
+/******************************************************************************
+* Simple tests.
+******************************************************************************/
+# non-indexed nullable fields
+explain extended
+select * from t1 where a1 in (select b1 from t2 where b1 > '0');
+select * from t1 where a1 in (select b1 from t2 where b1 > '0');
+
+explain extended
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
+
+explain extended
+select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
+select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
+
+explain extended
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
+
+# indexed columns
+explain extended
+select * from t1i where a1 in (select b1 from t2i where b1 > '0');
+select * from t1i where a1 in (select b1 from t2i where b1 > '0');
+
+explain extended
+select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
+
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+
+explain extended
+select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+
+# BUG#31639: Wrong plan for uncorrelated subquery when loose scan is applicable.
+explain extended
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
+
+prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
+execute st1;
+execute st1;
+prepare st2 from "select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1)";
+execute st2;
+execute st2;
+
+explain extended
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
+-- error 1235
+select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1);
+
+# test re-optimization/re-execution with different execution methods
+# prepare once, exec with different modes
+set @@optimizer_switch='default,semijoin=off';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch='default,materialization=off';
+execute st1;
+set @@optimizer_switch='default,semijoin=off';
+execute st1;
+
+set @@optimizer_switch='default,materialization=off';
+prepare st1 from
+"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
+set @@optimizer_switch='default,semijoin=off';
+execute st1;
+set @@optimizer_switch='default,materialization=off';
+execute st1;
+set @@optimizer_switch='default,semijoin=off';
+
+# materialize the result of ORDER BY
+# non-indexed fields
+explain extended
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
+# indexed fields
+explain extended
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
+
+/******************************************************************************
+* Views, UNIONs, several levels of nesting.
+******************************************************************************/
+# materialize the result of subquery over temp-table view
+
+create algorithm=merge view v1 as
+select b1, c2 from t2, t3 where b2 > c2;
+
+create algorithm=merge view v2 as
+select b1, c2 from t2, t3 group by b2, c2;
+
+create algorithm=temptable view v1m as
+select b1, c2 from t2, t3 where b2 > c2;
+
+create algorithm=temptable view v2m as
+select b1, c2 from t2, t3 group by b2, c2;
+
+select * from v1 where (c2, b1) in (select c2, b1 from v2 where b1 is not null);
+select * from v1 where (c2, b1) in (select distinct c2, b1 from v2 where b1 is not null);
+
+select * from v1m where (c2, b1) in (select c2, b1 from v2m where b1 is not null);
+select * from v1m where (c2, b1) in (select distinct c2, b1 from v2m where b1 is not null);
+
+drop view v1, v2, v1m, v2m;
+
+# nested subqueries, views
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+select * from t1
+where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+
+explain extended
+select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3i
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3i
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+ where b2 in (select c2 from t3 where c2 LIKE '%02') or
+ b2 in (select c2 from t3 where c2 LIKE '%03')) and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+ where b2 in (select c2 from t3 where c2 LIKE '%02') or
+ b2 in (select c2 from t3 where c2 LIKE '%03')) and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+
+# as above with correlated innermost subquery
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+ where b2 in (select c2 from t3 t3a where c1 = a1) or
+ b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
+ (a1, a2) in (select c1, c2 from t3 t3c
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+ where b2 in (select c2 from t3 t3a where c1 = a1) or
+ b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
+ (a1, a2) in (select c1, c2 from t3 t3c
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+
+
+# multiple levels of nesting subqueries, unions
+explain extended
+(select * from t1
+where (a1, a2) in (select b1, b2 from t2
+ where b2 in (select c2 from t3 where c2 LIKE '%02') or
+ b2 in (select c2 from t3 where c2 LIKE '%03')
+ group by b1, b2) and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0')))
+UNION
+(select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3i
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
+
+(select * from t1
+where (a1, a2) in (select b1, b2 from t2
+ where b2 in (select c2 from t3 where c2 LIKE '%02') or
+ b2 in (select c2 from t3 where c2 LIKE '%03')
+ group by b1, b2) and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0')))
+UNION
+(select * from t1i
+where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
+ (a1, a2) in (select c1, c2 from t3i
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0')));
+
+
+# UNION of subqueries as a subquery (thus it is not computed via materialization)
+explain extended
+select * from t1
+where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+select * from t1
+where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
+ (a1, a2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
+# as above, with a join conditon between the outer references
+explain extended
+select * from t1, t3
+where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
+ (c1, c2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and
+ a1 = c1;
+select * from t1, t3
+where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
+ (c1, c2) in (select c1, c2 from t3
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0')) and
+ a1 = c1;
+
+
+/******************************************************************************
+* Negative tests, where materialization should not be applied.
+******************************************************************************/
+# UNION in a subquery
+explain extended
+select * from t3
+where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
+select * from t3
+where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
+
+# correlation
+explain extended
+select * from t1
+where (a1, a2) in (select b1, b2 from t2
+ where b2 in (select c2 from t3 t3a where c1 = a1) or
+ b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
+ (a1, a2) in (select c1, c2 from t3 t3c
+ where (c1, c2) in (select b1, b2 from t2i where b2 > '0' or b2 = a2));
+
+# subquery has no tables
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
+explain extended
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
+
+
+/******************************************************************************
+* Subqueries in other uncovered clauses.
+******************************************************************************/
+
+/* SELECT clause */
+select ((a1,a2) IN (select * from t2 where b2 > '0')) IS NULL from t1;
+
+/* GROUP BY clause */
+create table columns (col int key);
+insert into columns values (1), (2);
+
+explain extended
+select * from t1 group by (select col from columns limit 1);
+select * from t1 group by (select col from columns limit 1);
+
+explain extended
+select * from t1 group by (a1 in (select col from columns));
+select * from t1 group by (a1 in (select col from columns));
+
+/* ORDER BY clause */
+explain extended
+select * from t1 order by (select col from columns limit 1);
+select * from t1 order by (select col from columns limit 1);
+
+/******************************************************************************
+* Column types/sizes that affect materialization.
+******************************************************************************/
+
+/*
+ Test that BLOBs are not materialized (except when arguments of some functions).
+*/
+# force materialization to be always considered
+set @@optimizer_switch='semijoin=off';
+set @prefix_len = 6;
+
+# BLOB == 16 (small blobs that could be stored in HEAP tables)
+set @blob_len = 16;
+set @suffix_len = @blob_len - @prefix_len;
+
+create table t1_16 (a1 blob(16), a2 blob(16));
+create table t2_16 (b1 blob(16), b2 blob(16));
+create table t3_16 (c1 blob(16), c2 blob(16));
+
+insert into t1_16 values
+ (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_16 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_16 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+
+insert into t2_16 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_16 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_16 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+
+insert into t3_16 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_16 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_16 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_16 values
+ (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+
+# single value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select b1 from t2_16 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select b1 from t2_16 where b1 > '0');
+
+# row value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_16
+where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
+
+# string function with a blob argument, the return type may be != blob
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
+
+# group_concat with a blob argument - depends on
+# the variable group_concat_max_len, and
+# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+
+set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512)
+
+explain extended select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_16
+where a1 in (select group_concat(b1) from t2_16 group by b2);
+
+# BLOB column at the second (intermediate) level of nesting
+explain extended
+select * from t1
+where concat(a1,'x') IN
+ (select left(a1,8) from t1_16
+ where (a1, a2) IN
+ (select t2_16.b1, t2_16.b2 from t2_16, t2
+ where t2.b2 = substring(t2_16.b2,1,6) and
+ t2.b1 IN (select c1 from t3 where c2 > '0')));
+
+
+drop table t1_16, t2_16, t3_16;
+
+
+# BLOB == 512 (CONVERT_IF_BIGGER_TO_BLOB == 512)
+set @blob_len = 512;
+set @suffix_len = @blob_len - @prefix_len;
+
+create table t1_512 (a1 blob(512), a2 blob(512));
+create table t2_512 (b1 blob(512), b2 blob(512));
+create table t3_512 (c1 blob(512), c2 blob(512));
+
+insert into t1_512 values
+ (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_512 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_512 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+
+insert into t2_512 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_512 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_512 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+
+insert into t3_512 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_512 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_512 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_512 values
+ (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+
+# single value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select b1 from t2_512 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select b1 from t2_512 where b1 > '0');
+
+# row value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_512
+where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
+
+# string function with a blob argument, the return type may be != blob
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
+
+# group_concat with a blob argument - depends on
+# the variable group_concat_max_len, and
+# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+
+set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 512)
+
+explain extended select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_512
+where a1 in (select group_concat(b1) from t2_512 group by b2);
+
+drop table t1_512, t2_512, t3_512;
+
+
+# BLOB == 1024 (group_concat_max_len == 1024)
+set @blob_len = 1024;
+set @suffix_len = @blob_len - @prefix_len;
+
+create table t1_1024 (a1 blob(1024), a2 blob(1024));
+create table t2_1024 (b1 blob(1024), b2 blob(1024));
+create table t3_1024 (c1 blob(1024), c2 blob(1024));
+
+insert into t1_1024 values
+ (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_1024 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_1024 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+
+insert into t2_1024 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_1024 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_1024 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+
+insert into t3_1024 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_1024 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_1024 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_1024 values
+ (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+
+# single value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select b1 from t2_1024 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select b1 from t2_1024 where b1 > '0');
+
+# row value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_1024
+where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_1024
+where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
+
+# string function with a blob argument, the return type may be != blob
+explain extended select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
+
+# group_concat with a blob argument - depends on
+# the variable group_concat_max_len, and
+# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
+explain extended select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+
+set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1024)
+
+explain extended select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_1024
+where a1 in (select group_concat(b1) from t2_1024 group by b2);
+
+drop table t1_1024, t2_1024, t3_1024;
+
+
+# BLOB == 1025
+set @blob_len = 1025;
+set @suffix_len = @blob_len - @prefix_len;
+
+create table t1_1025 (a1 blob(1025), a2 blob(1025));
+create table t2_1025 (b1 blob(1025), b2 blob(1025));
+create table t3_1025 (c1 blob(1025), c2 blob(1025));
+
+insert into t1_1025 values
+ (concat('1 - 00', repeat('x', @suffix_len)), concat('2 - 00', repeat('x', @suffix_len)));
+insert into t1_1025 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t1_1025 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+
+insert into t2_1025 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t2_1025 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t2_1025 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+
+insert into t3_1025 values
+ (concat('1 - 01', repeat('x', @suffix_len)), concat('2 - 01', repeat('x', @suffix_len)));
+insert into t3_1025 values
+ (concat('1 - 02', repeat('x', @suffix_len)), concat('2 - 02', repeat('x', @suffix_len)));
+insert into t3_1025 values
+ (concat('1 - 03', repeat('x', @suffix_len)), concat('2 - 03', repeat('x', @suffix_len)));
+insert into t3_1025 values
+ (concat('1 - 04', repeat('x', @suffix_len)), concat('2 - 04', repeat('x', @suffix_len)));
+
+# single value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select b1 from t2_1025 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select b1 from t2_1025 where b1 > '0');
+
+# row value transformer
+explain extended select left(a1,7), left(a2,7)
+from t1_1025
+where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_1025
+where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
+
+# string function with a blob argument, the return type may be != blob
+explain extended select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
+
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
+
+# group_concat with a blob argument - depends on
+# the variable group_concat_max_len, and
+# convert_blob_length == max_len*collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB
+explain extended select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+
+set @@group_concat_max_len = 256; # anything < (CONVERT_IF_BIGGER_TO_BLOB = 1025)
+
+explain extended select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+
+select left(a1,7), left(a2,7)
+from t1_1025
+where a1 in (select group_concat(b1) from t2_1025 group by b2);
+
+drop table t1_1025, t2_1025, t3_1025;
+
+# test for BIT fields
+create table t1bit (a1 bit(3), a2 bit(3));
+create table t2bit (b1 bit(3), b2 bit(3));
+
+insert into t1bit values (b'000', b'100');
+insert into t1bit values (b'001', b'101');
+insert into t1bit values (b'010', b'110');
+
+insert into t2bit values (b'001', b'101');
+insert into t2bit values (b'010', b'110');
+insert into t2bit values (b'110', b'111');
+
+set @@optimizer_switch='semijoin=off';
+
+explain extended select bin(a1), bin(a2)
+from t1bit
+where (a1, a2) in (select b1, b2 from t2bit);
+
+select bin(a1), bin(a2)
+from t1bit
+where (a1, a2) in (select b1, b2 from t2bit);
+
+drop table t1bit, t2bit;
+
+# test mixture of BIT and BLOB
+create table t1bb (a1 bit(3), a2 blob(3));
+create table t2bb (b1 bit(3), b2 blob(3));
+
+insert into t1bb values (b'000', '100');
+insert into t1bb values (b'001', '101');
+insert into t1bb values (b'010', '110');
+
+insert into t2bb values (b'001', '101');
+insert into t2bb values (b'010', '110');
+insert into t2bb values (b'110', '111');
+
+explain extended select bin(a1), a2
+from t1bb
+where (a1, a2) in (select b1, b2 from t2bb);
+
+select bin(a1), a2
+from t1bb
+where (a1, a2) in (select b1, b2 from t2bb);
+
+drop table t1bb, t2bb;
+drop table t1, t2, t3, t1i, t2i, t3i, columns;
+
+/******************************************************************************
+* Test the cache of the left operand of IN.
+******************************************************************************/
+set @@optimizer_switch='semijoin=off';
+
+# Test that default values of Cached_item are not used for comparison
+create table t1 (s1 int);
+create table t2 (s2 int);
+insert into t1 values (5),(1),(0);
+insert into t2 values (0), (1);
+select s2 from t2 where s2 in (select s1 from t1);
+drop table t1, t2;
+
+create table t1 (a int not null, b int not null);
+create table t2 (c int not null, d int not null);
+create table t3 (e int not null);
+
+# the first outer row has no matching inner row
+insert into t1 values (1,10);
+insert into t1 values (1,20);
+insert into t1 values (2,10);
+insert into t1 values (2,20);
+insert into t1 values (2,30);
+insert into t1 values (3,20);
+insert into t1 values (4,40);
+
+insert into t2 values (2,10);
+insert into t2 values (2,20);
+insert into t2 values (2,40);
+insert into t2 values (3,20);
+insert into t2 values (4,10);
+insert into t2 values (5,10);
+
+insert into t3 values (10);
+insert into t3 values (10);
+insert into t3 values (20);
+insert into t3 values (30);
+
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+select a from t1 where a in (select c from t2 where d >= 20);
+
+create index it1a on t1(a);
+
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+select a from t1 where a in (select c from t2 where d >= 20);
+
+# the first outer row has a matching inner row
+insert into t2 values (1,10);
+
+explain extended
+select a from t1 where a in (select c from t2 where d >= 20);
+select a from t1 where a in (select c from t2 where d >= 20);
+
+# cacheing for IN predicates inside a having clause - here the cached
+# items are changed to point to temporary tables.
+explain extended
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+
+# create an index that can be used for the outer query GROUP BY
+create index iab on t1(a, b);
+explain extended
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+select a from t1 group by a having a in (select c from t2 where d >= 20);
+
+explain extended
+select a from t1 group by a
+having a in (select c from t2 where d >= some(select e from t3 where max(b)=e));
+select a from t1 group by a
+having a in (select c from t2 where d >= some(select e from t3 where max(b)=e));
+explain extended
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+select a from t1
+where a in (select c from t2 where d >= some(select e from t3 where b=e));
+
+drop table t1, t2, t3;
+
+#
+# BUG#36133 "Assertion `exec_method != MATERIALIZATION || (exec_method == MATERIALIZATION &&"
+#
+create table t2 (a int, b int, key(a), key(b));
+insert into t2 values (3,3),(3,3),(3,3);
+select 1 from t2 where
+ t2.a > 1
+ or
+ t2.a = 3 and not t2.a not in (select t2.b from t2);
+drop table t2;
+
+#
+# BUG#37896 Assertion on entry of Item_in_subselect::exec on subquery with AND NOT
+#
+create table t1 (a1 int key);
+create table t2 (b1 int);
+insert into t1 values (5);
+
+# Query with group by, executed via materialization
+explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+# Query with group by, executed via IN=>EXISTS
+set @@optimizer_switch='default,materialization=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+
+# Executed with materialization
+set @@optimizer_switch='default,semijoin=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+select min(a1) from t1 where 7 in (select b1 from t2);
+# Executed with semi-join. Notice, this time we get a different result (NULL).
+# This is the only correct result of all four queries. This difference is
+# filed as BUG#40037.
+set @@optimizer_switch='default,materialization=off';
+explain select min(a1) from t1 where 7 in (select b1 from t2);
+select min(a1) from t1 where 7 in (select b1 from t2);
+drop table t1,t2;
+
+#
+# BUG#36752 "subquery materialization produces wrong results when comparing different types"
+#
+create table t1 (a char(2), b varchar(10));
+insert into t1 values ('a', 'aaa');
+insert into t1 values ('aa', 'aaaa');
+
+set @@optimizer_switch='default,semijoin=off';
+explain select a,b from t1 where b in (select a from t1);
+select a,b from t1 where b in (select a from t1);
+prepare st1 from "select a,b from t1 where b in (select a from t1)";
+execute st1;
+execute st1;
+drop table t1;
+
+#
+# Bug #44303 Assertion failures in Field_new_decimal::store_decimal
+# when executing materialized InsideOut semijoin
+#
+CREATE TABLE t1 (f1 INT, f2 DECIMAL(5,3)) ENGINE=MyISAM;
+INSERT INTO t1 (f1, f2) VALUES (1, 1.789);
+INSERT INTO t1 (f1, f2) VALUES (13, 1.454);
+INSERT INTO t1 (f1, f2) VALUES (10, 1.668);
+
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1, 1.789);
+INSERT INTO t2 VALUES (13, 1.454);
+
+SET @@optimizer_switch='default,semijoin=on,materialization=on';
+EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
+
+DROP TABLE t1, t2;
+
+#
+# BUG#46548 IN-subqueries return 0 rows with materialization=on
+#
+CREATE TABLE t1 (
+ pk int,
+ a varchar(1),
+ b varchar(4),
+ c varchar(4),
+ d varchar(4),
+ PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff');
+
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff');
+
+SET @@optimizer_switch='default,semijoin=on,materialization=on';
+EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
+SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
+DROP TABLE t1, t2;
+
diff --git a/mysql-test/t/subselect_no_mat.test b/mysql-test/t/subselect_no_mat.test
new file mode 100644
index 00000000000..6f105ed50d3
--- /dev/null
+++ b/mysql-test/t/subselect_no_mat.test
@@ -0,0 +1,11 @@
+#
+# Run subselect.test without semi-join optimization (test materialize)
+#
+show variables like 'optimizer_switch';
+set optimizer_switch='materialization=off';
+
+--source t/subselect.test
+
+set optimizer_switch=default;
+show variables like 'optimizer_switch';
+
diff --git a/mysql-test/t/subselect_no_opts.test b/mysql-test/t/subselect_no_opts.test
new file mode 100644
index 00000000000..358b843b53c
--- /dev/null
+++ b/mysql-test/t/subselect_no_opts.test
@@ -0,0 +1,11 @@
+#
+# Run subselect.test without semi-join optimization (test materialize)
+#
+show variables like 'optimizer_switch';
+set optimizer_switch='materialization=off,semijoin=off';
+
+--source t/subselect.test
+
+set optimizer_switch=default;
+show variables like 'optimizer_switch';
+
diff --git a/mysql-test/t/subselect_no_semijoin.test b/mysql-test/t/subselect_no_semijoin.test
new file mode 100644
index 00000000000..e5a6e170302
--- /dev/null
+++ b/mysql-test/t/subselect_no_semijoin.test
@@ -0,0 +1,11 @@
+#
+# Run subselect.test without semi-join optimization (test materialize)
+#
+show variables like 'optimizer_switch';
+set optimizer_switch='semijoin=off';
+
+--source t/subselect.test
+
+set optimizer_switch=default;
+show variables like 'optimizer_switch';
+
diff --git a/mysql-test/t/subselect_nulls.test b/mysql-test/t/subselect_nulls.test
new file mode 100644
index 00000000000..6de7820872c
--- /dev/null
+++ b/mysql-test/t/subselect_nulls.test
@@ -0,0 +1,94 @@
+# Initialize tables for the test
+
+--disable_warnings
+drop table if exists x1;
+drop table if exists x2;
+--enable_warnings
+
+create table x1(k int primary key, d1 int, d2 int);
+create table x2(k int primary key, d1 int, d2 int);
+
+insert into x1 values
+ (10, 10, 10),
+ (20, 20, 20),
+ (21, 20, null),
+ (30, null, 30),
+ (40, 40, 40);
+insert into x2 values
+ (10, 10, 10),
+ (20, 20, 20),
+ (21, 20, null),
+ (30, null, 30);
+
+# Test various IN and EXISTS queries with NULL values and UNKNOWN
+# Q1 T=(10, 20) U=(21,30) F=(40)
+select *
+from x1
+where (d1, d2) in (select d1, d2
+ from x2);
+select *
+from x1
+where (d1, d2) in (select d1, d2
+ from x2) is true;
+select *
+from x1
+where (d1, d2) in (select d1, d2
+ from x2) is false;
+select *
+from x1
+where (d1, d2) in (select d1, d2
+ from x2) is unknown;
+
+# Q2 T=(10, 20) U=(30) F=(21, 40)
+select *
+from x1
+where d1 in (select d1
+ from x2
+ where x1.d2=x2.d2);
+select *
+from x1
+where d1 in (select d1
+ from x2
+ where x1.d2=x2.d2) is true;
+select *
+from x1
+where d1 in (select d1
+ from x2
+ where x1.d2=x2.d2) is false;
+select *
+from x1
+where d1 in (select d1
+ from x2
+ where x1.d2=x2.d2) is unknown;
+
+# Q3 T=(10, 20) U=() F=(21, 30, 40)
+select *
+from x1
+where 1 in (select 1
+ from x2
+ where x1.d1=x2.d1 and x1.d2=x2.d2);
+select *
+from x1
+where 1 in (select 1
+ from x2
+ where x1.d1=x2.d1 and x1.d2=x2.d2) is true;
+select *
+from x1
+where 1 in (select 1
+ from x2
+ where x1.d1=x2.d1 and x1.d2=x2.d2) is false;
+select *
+from x1
+where 1 in (select 1
+ from x2
+ where x1.d1=x2.d1 and x1.d2=x2.d2) is unknown;
+
+# Q4 T=(10, 20) F=(21, 30, 40)
+select *
+from x1
+where exists (select *
+ from x2
+ where x1.d1=x2.d1 and x1.d2=x2.d2);
+
+drop table x1;
+drop table x2;
diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test
new file mode 100644
index 00000000000..4b24544320c
--- /dev/null
+++ b/mysql-test/t/subselect_sj.test
@@ -0,0 +1,683 @@
+#
+# Nested Loops semi-join subquery evaluation tests
+#
+--disable_warnings
+drop table if exists t0, t1, t2, t10, t11, t12;
+--enable_warnings
+
+#
+# 1. Subqueries that are converted into semi-joins
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1(a int, b int);
+insert into t1 values (0,0),(1,1),(2,2);
+create table t2 as select * from t1;
+
+create table t11(a int, b int);
+
+create table t10 (pk int, a int, primary key(pk));
+insert into t10 select a,a from t0;
+create table t12 like t10;
+insert into t12 select * from t10;
+
+
+--echo Flattened because of dependency, t10=func(t1)
+explain select * from t1 where a in (select pk from t10);
+select * from t1 where a in (select pk from t10);
+
+--echo A confluent case of dependency
+explain select * from t1 where a in (select a from t10 where pk=12);
+select * from t1 where a in (select a from t10 where pk=12);
+
+explain select * from t1 where a in (select a from t10 where pk=9);
+select * from t1 where a in (select a from t10 where pk=9);
+
+--echo An empty table inside
+explain select * from t1 where a in (select a from t11);
+select * from t1 where a in (select a from t11);
+
+explain select * from t1 where a in (select pk from t10) and b in (select pk from t10);
+select * from t1 where a in (select pk from t10) and b in (select pk from t10);
+
+--echo flattening a nested subquery
+explain select * from t1 where a in (select pk from t10 where t10.a in (select pk from t12));
+select * from t1 where a in (select pk from t10 where t10.a in (select pk from t12));
+
+--echo flattening subquery w/ several tables
+explain extended select * from t1 where a in (select t10.pk from t10, t12 where t12.pk=t10.a);
+
+--echo subqueries within outer joins go into ON expr.
+# TODO: psergey: check if case conversions like those are ok (it broke on windows)
+--replace_result a A b B
+explain extended
+select * from t1 left join (t2 A, t2 B) on ( A.a= t1.a and B.a in (select pk from t10));
+
+# TODO: psergey: check if case conversions like those are ok (it broke on windows)
+--echo t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
+--replace_result a A b B
+explain extended
+select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10));
+
+--echo we shouldn't flatten if we're going to get a join of > MAX_TABLES.
+explain select * from
+ t1 s00, t1 s01, t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
+ t1 s10, t1 s11, t1 s12, t1 s13, t1 s14,t1 s15,t1 s16,t1 s17,t1 s18,t1 s19,
+ t1 s20, t1 s21, t1 s22, t1 s23, t1 s24,t1 s25,t1 s26,t1 s27,t1 s28,t1 s29,
+ t1 s30, t1 s31, t1 s32, t1 s33, t1 s34,t1 s35,t1 s36,t1 s37,t1 s38,t1 s39,
+ t1 s40, t1 s41, t1 s42, t1 s43, t1 s44,t1 s45,t1 s46,t1 s47,t1 s48,t1 s49
+where
+ s00.a in (
+ select m00.a from
+ t1 m00, t1 m01, t1 m02, t1 m03, t1 m04,t1 m05,t1 m06,t1 m07,t1 m08,t1 m09,
+ t1 m10, t1 m11, t1 m12, t1 m13, t1 m14,t1 m15,t1 m16,t1 m17,t1 m18,t1 m19
+ );
+
+select * from
+ t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
+where t1.a < 5;
+
+#
+# Prepared statements
+#
+prepare s1 from
+ ' select * from
+ t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t10))
+ where t1.a < 5';
+execute s1;
+execute s1;
+
+# Try I2O orders
+insert into t1 select (A.a + 10 * B.a),1 from t0 A, t0 B;
+explain extended select * from t1 where a in (select pk from t10 where pk<3);
+
+--echo
+--echo BUG#37120 optimizer_switch allowable values not according to specification
+--echo
+
+select @@optimizer_switch;
+
+set optimizer_switch='default,materialization=off';
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off';
+select @@optimizer_switch;
+
+set optimizer_switch='default,loosescan=off';
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off,materialization=off';
+select @@optimizer_switch;
+
+set optimizer_switch='default,materialization=off,semijoin=off';
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
+select @@optimizer_switch;
+
+set optimizer_switch='default,semijoin=off,loosescan=off';
+select @@optimizer_switch;
+
+set optimizer_switch='default,materialization=off,loosescan=off';
+select @@optimizer_switch;
+set optimizer_switch=default;
+
+drop table t0, t1, t2;
+drop table t10, t11, t12;
+
+--echo
+--echo Bug#37899: Wrongly checked optimization prerequisite caused failed
+--echo assertion.
+--echo
+CREATE TABLE t1 (
+ `pk` int(11),
+ `varchar_nokey` varchar(5)
+);
+
+INSERT INTO t1 VALUES
+(1,'qk'),(2,'j'),(3,'aew');
+
+SELECT *
+FROM t1
+WHERE varchar_nokey IN (
+ SELECT
+ varchar_nokey
+ FROM
+ t1
+) XOR pk = 30;
+drop table t1;
+
+--echo #
+--echo # BUG#41842: Semi-join materialization strategy crashes when the upper query has HAVING
+--echo #
+
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ int_nokey int(11) NOT NULL,
+ time_key time NOT NULL,
+ datetime_key datetime NOT NULL,
+ datetime_nokey datetime NOT NULL,
+ varchar_key varchar(1) NOT NULL,
+ varchar_nokey varchar(1) NOT NULL,
+ PRIMARY KEY (pk),
+ KEY time_key (time_key),
+ KEY datetime_key (datetime_key),
+ KEY varchar_key (varchar_key)
+);
+INSERT INTO t1 VALUES
+(1,0, '00:16:10','2008-09-03 14:25:40','2008-09-03 14:25:40','h','h'),
+(2,7, '00:00:00','2001-01-13 00:00:00','2001-01-13 00:00:00','',''),
+(3,0, '00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','x','x'),
+(4,2, '16:29:24','2000-10-16 01:39:08','2000-10-16 01:39:08','w','w'),
+(5,1, '09:23:32','0000-00-00 00:00:00','0000-00-00 00:00:00','p','p'),
+(6,3, '00:00:00','2007-12-02 00:00:00','2007-12-02 00:00:00','o','o'),
+(7,3, '00:00:00','2008-09-11 00:00:00','2008-09-11 00:00:00','',''),
+(8,0, '13:59:04','0000-00-00 00:00:00','0000-00-00 00:00:00','s','s'),
+(9,7, '09:01:06','0000-00-00 00:00:00','0000-00-00 00:00:00','d','d'),
+(10,5,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','n','n'),
+(11,0,'21:06:46','0000-00-00 00:00:00','0000-00-00 00:00:00','o','o'),
+(12,2,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','',''),
+(13,6,'14:45:34','2003-07-28 02:34:08','2003-07-28 02:34:08','w','w'),
+(14,1,'15:04:12','0000-00-00 00:00:00','0000-00-00 00:00:00','o','o'),
+(15,0,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','x','x'),
+(16,0,'15:55:23','2004-03-17 00:32:27','2004-03-17 00:32:27','p','p'),
+(17,1,'16:30:00','2004-12-27 19:20:00','2004-12-27 19:20:00','d','d'),
+(18,0,'00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','h','h'),
+(19,0,'14:13:26','2008-11-09 05:53:48','2008-11-09 05:53:48','o','o'),
+(20,0,'00:00:00','2009-10-11 06:58:04','2009-10-11 06:58:04','k','k');
+
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ int_nokey int(11) NOT NULL,
+ time_key time NOT NULL,
+ datetime_key datetime NOT NULL,
+ datetime_nokey datetime NOT NULL,
+ varchar_key varchar(1) NOT NULL,
+ varchar_nokey varchar(1) NOT NULL,
+ PRIMARY KEY (pk),
+ KEY time_key (time_key),
+ KEY datetime_key (datetime_key),
+ KEY varchar_key (varchar_key)
+);
+INSERT INTO t2 VALUES
+(10,0,'19:39:13','0000-00-00 00:00:00','0000-00-00 00:00:00','g','g'),
+(11,8,'03:43:53','0000-00-00 00:00:00','0000-00-00 00:00:00','b','b');
+SELECT OUTR.datetime_nokey AS X FROM t1 AS OUTR
+WHERE
+ OUTR.varchar_nokey IN (SELECT
+ INNR . varchar_nokey AS Y
+ FROM t2 AS INNR
+ WHERE
+ INNR . datetime_key >= INNR . time_key OR
+ INNR . pk = INNR . int_nokey
+ )
+ AND OUTR . varchar_nokey <= 'w'
+HAVING X > '2012-12-12';
+drop table t1, t2;
+
+--echo #
+--echo # Bug#45191: Incorrectly initialized semi-join led to a wrong result.
+--echo #
+CREATE TABLE STAFF (EMPNUM CHAR(3) NOT NULL,
+ EMPNAME CHAR(20), GRADE DECIMAL(4), CITY CHAR(15));
+
+CREATE TABLE PROJ (PNUM CHAR(3) NOT NULL,
+ PNAME CHAR(20), PTYPE CHAR(6),
+ BUDGET DECIMAL(9),
+ CITY CHAR(15));
+
+CREATE TABLE WORKS (EMPNUM CHAR(3) NOT NULL,
+ PNUM CHAR(3) NOT NULL, HOURS DECIMAL(5));
+INSERT INTO STAFF VALUES ('E1','Alice',12,'Deale');
+INSERT INTO STAFF VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO STAFF VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO STAFF VALUES ('E4','Don',12,'Deale');
+INSERT INTO STAFF VALUES ('E5','Ed',13,'Akron');
+
+INSERT INTO PROJ VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO PROJ VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO PROJ VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO PROJ VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO PROJ VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO PROJ VALUES ('P6','PAYR','Design',50000,'Deale');
+
+INSERT INTO WORKS VALUES ('E1','P1',40);
+INSERT INTO WORKS VALUES ('E1','P2',20);
+INSERT INTO WORKS VALUES ('E1','P3',80);
+INSERT INTO WORKS VALUES ('E1','P4',20);
+INSERT INTO WORKS VALUES ('E1','P5',12);
+INSERT INTO WORKS VALUES ('E1','P6',12);
+INSERT INTO WORKS VALUES ('E2','P1',40);
+INSERT INTO WORKS VALUES ('E2','P2',80);
+INSERT INTO WORKS VALUES ('E3','P2',20);
+INSERT INTO WORKS VALUES ('E4','P2',20);
+INSERT INTO WORKS VALUES ('E4','P4',40);
+INSERT INTO WORKS VALUES ('E4','P5',80);
+
+set optimizer_switch='default,materialization=off';
+
+explain SELECT EMPNUM, EMPNAME
+FROM STAFF
+WHERE EMPNUM IN
+ (SELECT EMPNUM FROM WORKS
+ WHERE PNUM IN
+ (SELECT PNUM FROM PROJ));
+
+SELECT EMPNUM, EMPNAME
+FROM STAFF
+WHERE EMPNUM IN
+ (SELECT EMPNUM FROM WORKS
+ WHERE PNUM IN
+ (SELECT PNUM FROM PROJ));
+
+set optimizer_switch='default';
+
+drop table STAFF,WORKS,PROJ;
+
+--echo # End of bug#45191
+
+--echo #
+--echo # Bug#46550 Azalea returning duplicate results for some IN subqueries
+--echo # w/ semijoin=on
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t0, t1, t2;
+--enable_warnings
+
+CREATE TABLE t0 (
+ int_key int(11) DEFAULT NULL,
+ varchar_key varchar(1) DEFAULT NULL,
+ varchar_nokey varchar(1) DEFAULT NULL,
+ KEY int_key (int_key),
+ KEY varchar_key (varchar_key,int_key)
+);
+
+INSERT INTO t0 VALUES
+(1,'m','m'),
+(40,'h','h'),
+(1,'r','r'),
+(1,'h','h'),
+(9,'x','x'),
+(NULL,'q','q'),
+(NULL,'k','k'),
+(7,'l','l'),
+(182,'k','k'),
+(202,'a','a'),
+(7,'x','x'),
+(6,'j','j'),
+(119,'z','z'),
+(4,'d','d'),
+(5,'h','h'),
+(1,'u','u'),
+(3,'q','q'),
+(7,'a','a'),
+(3,'e','e'),
+(6,'l','l');
+
+CREATE TABLE t1 (
+ int_key int(11) DEFAULT NULL,
+ varchar_key varchar(1) DEFAULT NULL,
+ varchar_nokey varchar(1) DEFAULT NULL,
+ KEY int_key (int_key),
+ KEY varchar_key (varchar_key,int_key)
+);
+INSERT INTO t1 VALUES (7,NULL,NULL),(4,'x','x');
+
+CREATE TABLE t2 (
+ int_key int(11) DEFAULT NULL,
+ varchar_key varchar(1) DEFAULT NULL,
+ varchar_nokey varchar(1) DEFAULT NULL,
+ KEY int_key (int_key),
+ KEY varchar_key (varchar_key,int_key)
+);
+INSERT INTO t2 VALUES (123,NULL,NULL);
+
+SELECT int_key
+FROM t0
+WHERE varchar_nokey IN (
+ SELECT t1 .varchar_key from t1
+);
+
+SELECT t0.int_key
+FROM t0
+WHERE t0.varchar_nokey IN (
+ SELECT t1_1 .varchar_key
+ FROM t1 AS t1_1 JOIN t1 AS t1_2 ON t1_1 .int_key
+);
+
+SELECT t0.int_key
+FROM t0, t2
+WHERE t0.varchar_nokey IN (
+ SELECT t1_1 .varchar_key
+ FROM t1 AS t1_1 JOIN t1 AS t1_2 ON t1_1 .int_key
+);
+
+DROP TABLE t0, t1, t2;
+
+--echo # End of bug#46550
+
+--echo #
+--echo # Bug #46744 Crash in optimize_semijoin_nests on empty view
+--echo # with limit and procedure.
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+CREATE TABLE t1 ( f1 int );
+CREATE TABLE t2 ( f1 int );
+
+insert into t2 values (5), (7);
+
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1 LIMIT 2;
+
+create procedure p1()
+select COUNT(*)
+FROM v1 WHERE f1 IN
+(SELECT f1 FROM t2 WHERE f1 = ANY (SELECT f1 FROM v1));
+
+SET SESSION optimizer_switch = 'semijoin=on';
+CALL p1();
+SET SESSION optimizer_switch = 'semijoin=off';
+CALL p1();
+
+drop table t1, t2;
+drop view v1;
+drop procedure p1;
+
+set SESSION optimizer_switch='default';
+
+--echo # End of bug#46744
+
+--echo
+--echo Bug#46797 "Crash in fix_semijoin_strategies_for_picked_join_order
+--echo with semijoin=on"
+--echo
+CREATE TABLE t1 (
+ varchar_key varchar(1) DEFAULT NULL,
+ KEY varchar_key (varchar_key)
+);
+
+CREATE TABLE t2 (
+ varchar_key varchar(1) DEFAULT NULL,
+ KEY varchar_key (varchar_key)
+);
+INSERT INTO t2 VALUES
+ (NULL),(NULL),(NULL),(NULL),('a'),('a'),('a'),('b'),('b'),('b'),('b'),('c'),
+ ('c'),('c'),('c'),('c'),('c'),('c'),('d'),('d'),('d'),('d'),('d'),('d'),('e'),
+ ('e'),('e'),('e'),('e'),('e'),('f'),('f'),('f'),('g'),('g'),('h'),('h'),('h'),
+ ('h'),('i'),('j'),('j'),('j'),('k'),('k'),('l'),('l'),('m'),('m'),('m'),('m'),
+ ('n'),('n'),('n'),('o'),('o'),('o'),('p'),('p'),('p'),('q'),('q'),('q'),('r'),
+ ('r'),('r'),('r'),('s'),('s'),('s'),('s'),('t'),('t'),('t'),('t'),('u'),('u'),
+ ('u'),('u'),('v'),('v'),('v'),('v'),('w'),('w'),('w'),('w'),('w'),('w'),('x'),
+ ('x'),('x'),('y'),('y'),('y'),('y'),('z'),('z'),('z'),('z');
+
+CREATE TABLE t3 (
+ varchar_key varchar(1) DEFAULT NULL,
+ KEY varchar_key (varchar_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t3 VALUES
+ (NULL),('c'),('d'),('e'),('f'),('h'),('j'),('k'),('k'),('m'),('m'),('m'),
+ ('n'),('o'),('r'),('t'),('t'),('u'),('w'),('y');
+
+SELECT varchar_key FROM t3
+WHERE (SELECT varchar_key FROM t3
+ WHERE (varchar_key,varchar_key)
+ IN (SELECT t1.varchar_key, t2 .varchar_key
+ FROM t1 RIGHT JOIN t2 ON t1.varchar_key
+ )
+ );
+
+DROP TABLE t1, t2, t3;
+
+
+--echo #
+--echo # Bug#46556 Returning incorrect, empty results for some IN subqueries
+--echo # w/semijoin=on
+--echo #
+
+CREATE TABLE t0 (
+ pk INTEGER,
+ vkey VARCHAR(1),
+ vnokey VARCHAR(1),
+ PRIMARY KEY (pk),
+ KEY vkey(vkey)
+);
+
+INSERT INTO t0
+VALUES (1,'g','g'), (2,'v','v'), (3,'t','t'), (4,'u','u'), (5,'n','n');
+
+EXPLAIN EXTENDED SELECT vkey FROM t0 WHERE pk IN
+ (SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
+
+SELECT vkey FROM t0 WHERE pk IN
+ (SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
+
+DROP TABLE t0;
+
+--echo # End of bug#46556
+
+--echo
+--echo Bug #48073 Subquery on char columns from view crashes Mysql
+--echo
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+--enable_warnings
+
+CREATE TABLE t1 (
+ city VARCHAR(50) NOT NULL,
+ country_id SMALLINT UNSIGNED NOT NULL
+);
+
+INSERT INTO t1 VALUES
+('Batna',2),
+('Bchar',2),
+('Skikda',2),
+('Tafuna',3),
+('Algeria',2) ;
+
+CREATE TABLE t2 (
+ country_id SMALLINT UNSIGNED NOT NULL,
+ country VARCHAR(50) NOT NULL
+);
+
+INSERT INTO t2 VALUES
+(2,'Algeria'),
+(3,'American Samoa') ;
+
+CREATE VIEW v1 AS
+SELECT country_id, country
+FROM t2
+WHERE LEFT(country,1) = "A"
+;
+
+SELECT city, country_id
+FROM t1
+WHERE city IN (
+ SELECT country
+ FROM t2
+ WHERE LEFT(country, 1) = "A"
+);
+
+SELECT city, country_id
+FROM t1
+WHERE city IN (
+ SELECT country
+ FROM v1
+);
+
+drop table t1, t2;
+drop view v1;
+
+--echo # End of bug#48073
+
+--echo
+--echo Bug#48834: Procedure with view + subquery + semijoin=on
+--echo crashes on second call.
+--echo
+
+SET SESSION optimizer_switch ='semijoin=on';
+
+CREATE TABLE t1 ( t1field integer, primary key (t1field));
+CREATE TABLE t2 ( t2field integer, primary key (t2field));
+
+CREATE VIEW v1 AS
+ SELECT t1field as v1field
+ FROM t1 A
+ WHERE A.t1field IN (SELECT t1field FROM t2 );
+
+CREATE VIEW v2 AS
+ SELECT t2field as v2field
+ FROM t2 A
+ WHERE A.t2field IN (SELECT t2field FROM t2 );
+
+DELIMITER |;
+CREATE PROCEDURE p1 ()
+ BEGIN
+ SELECT v1field
+ FROM v1
+ WHERE v1field IN ( SELECT v2field as vf_inner FROM v2 );
+ END|
+DELIMITER ;|
+
+INSERT INTO t1 VALUES (1),(2),(3);
+INSERT INTO t2 VALUES (2),(3),(4);
+
+CALL p1;
+CALL p1;
+
+DROP TABLE t1,t2;
+DROP VIEW v1,v2;
+DROP PROCEDURE p1;
+
+set SESSION optimizer_switch='default';
+
+--echo # End of BUG#48834
+
+--echo
+--echo Bug#49097 subquery with view generates wrong result with
+--echo non-prepared statement
+--echo
+
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2;
+DROP VIEW IF EXISTS v1;
+--enable_warnings
+
+CREATE TABLE t1 (
+ city VARCHAR(50) NOT NULL,
+ country_id SMALLINT UNSIGNED NOT NULL
+);
+
+INSERT INTO t1 VALUES
+('Batna',2),
+('Bchar',2),
+('Skikda',2),
+('Tafuna',3),
+('Algeria',2) ;
+
+CREATE TABLE t2 (
+ country_id SMALLINT UNSIGNED NOT NULL,
+ country VARCHAR(50) NOT NULL
+);
+
+INSERT INTO t2 VALUES
+(2,'Algeria'),
+(3,'XAmerican Samoa') ;
+
+CREATE VIEW v1 AS
+SELECT country_id, country
+FROM t2
+WHERE LEFT(country,1) = "A"
+;
+
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+ SELECT country_id
+ FROM t2
+ WHERE LEFT(country,1) = "A"
+);
+
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+ SELECT country_id
+ FROM v1
+);
+
+PREPARE stmt FROM
+"
+SELECT city, country_id
+FROM t1
+WHERE country_id IN (
+ SELECT country_id
+ FROM v1
+);
+";
+
+execute stmt;
+
+deallocate prepare stmt;
+drop table t1, t2;
+drop view v1;
+
+--echo # End of Bug#49097
+
+--echo #
+--echo # BUG#38075: Wrong result: rows matching a subquery with outer join not returned
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS ot1, it1, it2;
+--enable_warnings
+
+CREATE TABLE it2 (
+ int_key int(11) NOT NULL,
+ datetime_key datetime NOT NULL,
+ KEY int_key (int_key),
+ KEY datetime_key (datetime_key)
+);
+INSERT INTO it2 VALUES
+ (5,'2002-04-10 14:25:30'), (0,'0000-00-00 00:00:00'),
+ (0,'2006-09-14 04:01:02'), (4,'0000-00-00 00:00:00'),
+ (8,'0000-00-00 00:00:00'), (5,'0000-00-00 00:00:00'),
+ (9,'0000-00-00 00:00:00'), (8,'2007-04-01 11:04:17'),
+ (1,'0000-00-00 00:00:00'), (7,'2009-01-12 00:00:00'),
+ (0,'2009-06-05 00:00:00'), (3,'2006-02-14 18:06:35'),
+ (5,'2006-02-21 07:08:16'), (0,'0000-00-00 00:00:00'),
+ (7,'0000-00-00 00:00:00'), (0,'0000-00-00 00:00:00'),
+ (0,'2007-02-13 00:00:00'), (1,'0000-00-00 00:00:00'),
+ (0,'0000-00-00 00:00:00'), (1,'2003-08-11 00:00:00');
+CREATE TABLE ot1 (
+ int_nokey int(11) NOT NULL,
+ int_key int(11) NOT NULL,
+ KEY int_key (int_key)
+);
+INSERT INTO ot1 VALUES
+ (5,0), (3,0), (0,2), (3,0), (1,3), (0,0), (1,7), (7,0), (1,7), (0,7),
+ (0,9), (8,2), (4,4), (9,3), (0,9), (2,5), (0,5), (8,0), (5,8), (1,5);
+CREATE TABLE it1 (
+ int_nokey int(11) NOT NULL,
+ int_key int(11) NOT NULL,
+ KEY int_key (int_key)
+);
+INSERT INTO it1 VALUES
+ (9,5), (0,4);
+SELECT int_key FROM ot1
+WHERE int_nokey IN (SELECT it2.int_key
+ FROM it1 LEFT JOIN it2 ON it2.datetime_key);
+EXPLAIN
+SELECT int_key FROM ot1
+WHERE int_nokey IN (SELECT it2.int_key
+ FROM it1 LEFT JOIN it2 ON it2.datetime_key);
+DROP TABLE ot1, it1, it2;
+
+--echo # End of BUG#38075
diff --git a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test
new file mode 100644
index 00000000000..5578015ec29
--- /dev/null
+++ b/mysql-test/t/subselect_sj2.test
@@ -0,0 +1,904 @@
+#
+# DuplicateElimination strategy test
+#
+--source include/have_innodb.inc
+--disable_warnings
+drop table if exists t0, t1, t2, t3;
+drop view if exists v1;
+--enable_warnings
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+# First test simple cases: I20 order, no join buffering.
+
+create table t1 (
+ a int,
+ b int
+);
+insert into t1 values (1,1),(1,1),(2,2);
+
+create table t2 (
+ a int,
+ b int,
+ key(b)
+);
+insert into t2 select a, a/2 from t0;
+
+select * from t1;
+select * from t2;
+explain select * from t2 where b in (select a from t1);
+select * from t2 where b in (select a from t1);
+
+# Try an InnoDB table with very long rowid
+create table t3 (
+ a int,
+ b int,
+ key(b),
+ pk1 char(200), pk2 char(200), pk3 char(200),
+ primary key(pk1, pk2, pk3)
+) engine=innodb;
+insert into t3 select a,a, a,a,a from t0;
+
+explain select * from t3 where b in (select a from t1);
+select * from t3 where b in (select a from t1);
+
+# Test overflow to MyISAM:
+set @save_max_heap_table_size= @@max_heap_table_size;
+set max_heap_table_size=16384;
+set @save_join_buffer_size = @@join_buffer_size;
+set join_buffer_size= 8000;
+
+drop table t3;
+create table t3 (
+ a int,
+ b int,
+ key(b),
+ pk1 char(200), pk2 char(200),
+ primary key(pk1, pk2)
+) engine=innodb;
+insert into t3 select
+ A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a, A.a + 10*B.a
+from t0 A, t0 B where B.a <5;
+
+explain select * from t3 where b in (select a from t0);
+# Because of BUG#40154, run the next select w/o index condition pushdown:
+set @save_ecp= @@engine_condition_pushdown;
+set engine_condition_pushdown=0;
+select * from t3 where b in (select A.a+B.a from t0 A, t0 B where B.a<5);
+set engine_condition_pushdown=@save_ecp;
+
+set join_buffer_size= @save_join_buffer_size;
+set max_heap_table_size= @save_max_heap_table_size;
+
+# O2I join orders, with shortcutting:
+explain select * from t1 where a in (select b from t2);
+select * from t1;
+select * from t1 where a in (select b from t2);
+
+drop table t1, t2, t3;
+# (no need for anything in range/index_merge/DS-MRR)
+
+#
+# Test join buffering
+#
+set @save_join_buffer_size = @@join_buffer_size;
+set join_buffer_size= 8000;
+
+create table t1 (a int, filler1 binary(200), filler2 binary(200));
+insert into t1 select a, 'filler123456', 'filler123456' from t0;
+insert into t1 select a+10, 'filler123456', 'filler123456' from t0;
+
+create table t2 as select * from t1;
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+
+insert into t1 values (2, 'duplicate ok', 'duplicate ok');
+insert into t1 values (18, 'duplicate ok', 'duplicate ok');
+
+insert into t2 values (3, 'duplicate ok', 'duplicate ok');
+insert into t2 values (19, 'duplicate ok', 'duplicate ok');
+
+explain select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+
+explain select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+
+# Now let the buffer overfill:
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+insert into t1 select a+20, 'filler123456', 'filler123456' from t0;
+
+explain select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2) as Z
+from t1 ot where a in (select a from t2 it);
+
+explain select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+select
+ a, mid(filler1, 1,10), length(filler1)=length(filler2)
+from t2 ot where a in (select a from t1 it);
+
+drop table t1, t2;
+
+# Check ref access to tables inside the OJ nest inside the SJ nest
+create table t1 (a int, b int, key(a));
+create table t2 (a int, b int, key(a));
+create table t3 (a int, b int, key(a));
+
+insert into t1 select a,a from t0;
+insert into t2 select a,a from t0;
+insert into t3 select a,a from t0;
+
+--echo t2 and t3 must be use 'ref', not 'ALL':
+explain select *
+from t0 where a in
+ (select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
+
+drop table t0, t1,t2,t3;
+
+#
+# Bug #27348: Assertion abort for a query with two subqueries to be flattened
+# Bug #35674: Range optimizer ignores conditions on inner tables in semi-join IN subqueries
+#
+CREATE TABLE t1 (
+ ID int(11) NOT NULL auto_increment,
+ Name char(35) NOT NULL default '',
+ Country char(3) NOT NULL default '',
+ Population int(11) NOT NULL default '0',
+ PRIMARY KEY (ID),
+ INDEX (Population),
+ INDEX (Country)
+);
+CREATE TABLE t2 (
+ Code char(3) NOT NULL default '',
+ Name char(52) NOT NULL default '',
+ SurfaceArea float(10,2) NOT NULL default '0.00',
+ Population int(11) NOT NULL default '0',
+ Capital int(11) default NULL,
+ PRIMARY KEY (Code),
+ UNIQUE INDEX (Name),
+ INDEX (Population)
+);
+CREATE TABLE t3 (
+ Country char(3) NOT NULL default '',
+ Language char(30) NOT NULL default '',
+ Percentage float(3,1) NOT NULL default '0.0',
+ PRIMARY KEY (Country, Language),
+ INDEX (Percentage)
+);
+
+--disable_query_log
+INSERT INTO t1 VALUES
+(1,'Kabul','AFG',1780000),(2,'Qandahar','AFG',237500),
+(3,'Herat','AFG',186800),(4,'Mazar-e-Sharif','AFG',127800),
+(5,'Amsterdam','NLD',731200),(6,'Rotterdam','NLD',593321),
+(7,'Haag','NLD',440900),(8,'Utrecht','NLD',234323),
+(9,'Eindhoven','NLD',201843),(10,'Tilburg','NLD',193238),
+(11,'Groningen','NLD',172701),(12,'Breda','NLD',160398),
+(13,'Apeldoorn','NLD',153491),(14,'Nijmegen','NLD',152463),
+(15,'Enschede','NLD',149544),(16,'Haarlem','NLD',148772),
+(17,'Almere','NLD',142465),(18,'Arnhem','NLD',138020),
+(19,'Zaanstad','NLD',135621),(20,'´s-Hertogenbosch','NLD',129170),
+(21,'Amersfoort','NLD',126270),(22,'Maastricht','NLD',122087),
+(23,'Dordrecht','NLD',119811),(24,'Leiden','NLD',117196),
+(25,'Haarlemmermeer','NLD',110722),(26,'Zoetermeer','NLD',110214),
+(27,'Emmen','NLD',105853),(28,'Zwolle','NLD',105819),
+(29,'Ede','NLD',101574),(30,'Delft','NLD',95268);
+
+INSERT INTO t2 VALUES
+('AFG','Afghanistan',652090.00,22720000,1),
+('NLD','Netherlands',41526.00,15864000,5),
+('ANT','Netherlands Antilles',800.00,217000,33),
+('ALB','Albania',28748.00,3401200,34),
+('DZA','Algeria',2381741.00,31471000,35),
+('ASM','American Samoa',199.00,68000,54),
+('AND','Andorra',468.00,78000,55),
+('AGO','Angola',1246700.00,12878000,56),
+('AIA','Anguilla',96.00,8000,62),
+('ATG','Antigua and Barbuda',442.00,68000,63),
+('ARE','United Arab Emirates',83600.00,2441000,65),
+('ARG','Argentina',2780400.00,37032000,69),
+('ARM','Armenia',29800.00,3520000,126),
+('ABW','Aruba',193.00,103000,129),
+('AUS','Australia',7741220.00,18886000,135),
+('AZE','Azerbaijan',86600.00,7734000,144);
+
+INSERT INTO t3 VALUES
+('AFG','Pashto',52.4),('NLD','Dutch',95.6),
+('ANT','Papiamento',86.2),('ALB','Albaniana',97.9),
+('DZA','Arabic',86.0),('ASM','Samoan',90.6),
+('AND','Spanish',44.6),('AGO','Ovimbundu',37.2),
+('AIA','English',0.0),('ATG','Creole English',95.7),
+('ARE','Arabic',42.0),('ARG','Spanish',96.8),
+('ARM','Armenian',93.4),('ABW','Papiamento',76.7),
+('AUS','English',81.2),('AZE','Azerbaijani',89.0),
+('BHS','Creole English',89.7),('BHR','Arabic',67.7),
+('BGD','Bengali',97.7),('BRB','Bajan',95.1),
+('BEL','Dutch',59.2),('BLZ','English',50.8);
+--enable_query_log
+
+EXPLAIN
+SELECT Name FROM t2
+ WHERE t2.Code IN (SELECT Country FROM t1 WHERE Population > 5000000)
+ AND
+ t2.Code IN (SELECT Country FROM t3
+ WHERE Language='English' AND Percentage > 10 AND
+ t2.Population > 100000);
+
+DROP TABLE t1,t2,t3;
+
+# BUG#30993:
+CREATE TABLE t1 (
+ Code char(3) NOT NULL DEFAULT '',
+ Name char(52) NOT NULL DEFAULT '',
+ Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL DEFAULT 'Asia',
+ Region char(26) NOT NULL DEFAULT '',
+ SurfaceArea float(10,2) NOT NULL DEFAULT '0.00',
+ IndepYear smallint(6) DEFAULT NULL,
+ Population int(11) NOT NULL DEFAULT '0',
+ LifeExpectancy float(3,1) DEFAULT NULL,
+ GNP float(10,2) DEFAULT NULL,
+ GNPOld float(10,2) DEFAULT NULL,
+ LocalName char(45) NOT NULL DEFAULT '',
+ GovernmentForm char(45) NOT NULL DEFAULT '',
+ HeadOfState char(60) DEFAULT NULL,
+ Capital int(11) DEFAULT NULL,
+ Code2 char(2) NOT NULL DEFAULT '',
+ PRIMARY KEY (Code)
+);
+
+CREATE TABLE t2 (
+ ID int(11) NOT NULL AUTO_INCREMENT,
+ Name char(35) NOT NULL DEFAULT '',
+ CountryCode char(3) NOT NULL DEFAULT '',
+ District char(20) NOT NULL DEFAULT '',
+ Population int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (ID),
+ KEY CountryCode (CountryCode)
+);
+
+--echo Fill the table with test data
+--disable_query_log
+insert into t2 (ID, Name, CountryCode, Population) values
+(1,'Kabul','AFG',1780000), (2,'Qandahar','AFG',237500), (3,'Herat','AFG',186800),
+(4,'Mazar-e-Sharif','AFG',127800), (33,'Willemstad','ANT',2345), (34,'Tirana','ALB',270000),
+(55,'Andorra la Vella','AND',21189), (61,'South Hill','AIA',961), (62,'The Valley','AIA',595),
+(63,'Saint John�s','ATG',24000), (64,'Dubai','ARE',669181), (65,'Abu Dhabi','ARE',398695),
+(66,'Sharja','ARE',320095), (67,'al-Ayn','ARE',225970), (68,'Ajman','ARE',114395),
+(126,'Yerevan','ARM',1248700), (127,'Gjumri','ARM',211700), (128,'Vanadzor','ARM',172700),
+(129,'Oranjestad','ABW',29034), (144,'Baku','AZE',1787800), (145,'G�nc�','AZE',299300),
+(146,'Sumqayit','AZE',283000), (147,'Ming��evir','AZE',93900), (148,'Nassau','BHS',172000),
+(149,'al-Manama','BHR',148000), (150,'Dhaka','BGD',3612850), (151,'Chittagong','BGD',1392860),
+(152,'Khulna','BGD',663340), (153,'Rajshahi','BGD',294056), (154,'Narayanganj','BGD',202134),
+(155,'Rangpur','BGD',191398), (156,'Mymensingh','BGD',188713), (157,'Barisal','BGD',170232),
+(158,'Tungi','BGD',168702), (159,'Jessore','BGD',139710), (160,'Comilla','BGD',135313),
+(161,'Nawabganj','BGD',130577), (162,'Dinajpur','BGD',127815), (163,'Bogra','BGD',120170),
+(164,'Sylhet','BGD',117396), (165,'Brahmanbaria','BGD',109032), (166,'Tangail','BGD',106004),
+(167,'Jamalpur','BGD',103556), (168,'Pabna','BGD',103277), (169,'Naogaon','BGD',101266),
+(170,'Sirajganj','BGD',99669), (171,'Narsinghdi','BGD',98342), (172,'Saidpur','BGD',96777),
+(173,'Gazipur','BGD',96717), (174,'Bridgetown','BRB',6070), (175,'Antwerpen','BEL',446525),
+(176,'Gent','BEL',224180), (177,'Charleroi','BEL',200827), (178,'Li�ge','BEL',185639),
+(179,'Bruxelles [Brussel]','BEL',133859), (180,'Brugge','BEL',116246), (181,'Schaerbeek','BEL',105692),
+(182,'Namur','BEL',105419), (183,'Mons','BEL',90935), (184,'Belize City','BLZ',55810),
+(185,'Belmopan','BLZ',7105), (190,'Saint George','BMU',1800), (191,'Hamilton','BMU',1200),
+(192,'Thimphu','BTN',22000), (201,'Sarajevo','BIH',360000), (202,'Banja Luka','BIH',143079),
+(203,'Zenica','BIH',96027), (538,'Bandar Seri Begawan','BRN',21484), (539,'Sofija','BGR',1122302),
+(540,'Plovdiv','BGR',342584), (541,'Varna','BGR',299801), (542,'Burgas','BGR',195255),
+(543,'Ruse','BGR',166467), (544,'Stara Zagora','BGR',147939), (545,'Pleven','BGR',121952),
+(546,'Sliven','BGR',105530), (547,'Dobric','BGR',100399), (548,'�umen','BGR',94686),
+(553,'George Town','CYM',19600), (584,'San Jos�','CRI',339131), (1523,'Wien','AUT',1608144),
+(1524,'Graz','AUT',240967), (1525,'Linz','AUT',188022), (1526,'Salzburg','AUT',144247),
+(1527,'Innsbruck','AUT',111752), (1528,'Klagenfurt','AUT',91141), (1810,'Montr�al','CAN',1016376),
+(1811,'Calgary','CAN',768082), (1812,'Toronto','CAN',688275), (1813,'North York','CAN',622632),
+(1814,'Winnipeg','CAN',618477), (1815,'Edmonton','CAN',616306), (1816,'Mississauga','CAN',608072),
+(1817,'Scarborough','CAN',594501), (1818,'Vancouver','CAN',514008), (1819,'Etobicoke','CAN',348845),
+(1820,'London','CAN',339917), (1821,'Hamilton','CAN',335614), (1822,'Ottawa','CAN',335277),
+(1823,'Laval','CAN',330393), (1824,'Surrey','CAN',304477), (1825,'Brampton','CAN',296711),
+(1826,'Windsor','CAN',207588), (1827,'Saskatoon','CAN',193647), (1828,'Kitchener','CAN',189959),
+(1829,'Markham','CAN',189098), (1830,'Regina','CAN',180400), (1831,'Burnaby','CAN',179209),
+(1832,'Qu�bec','CAN',167264), (1833,'York','CAN',154980), (1834,'Richmond','CAN',148867),
+(1835,'Vaughan','CAN',147889), (1836,'Burlington','CAN',145150), (1837,'Oshawa','CAN',140173),
+(1838,'Oakville','CAN',139192), (1839,'Saint Catharines','CAN',136216), (1840,'Longueuil','CAN',127977),
+(1841,'Richmond Hill','CAN',116428), (1842,'Thunder Bay','CAN',115913), (1843,'Nepean','CAN',115100),
+(1844,'Cape Breton','CAN',114733), (1845,'East York','CAN',114034), (1846,'Halifax','CAN',113910),
+(1847,'Cambridge','CAN',109186), (1848,'Gloucester','CAN',107314), (1849,'Abbotsford','CAN',105403),
+(1850,'Guelph','CAN',103593), (1851,'Saint John�s','CAN',101936), (1852,'Coquitlam','CAN',101820),
+(1853,'Saanich','CAN',101388), (1854,'Gatineau','CAN',100702), (1855,'Delta','CAN',95411),
+(1856,'Sudbury','CAN',92686), (1857,'Kelowna','CAN',89442), (1858,'Barrie','CAN',89269),
+(1890,'Shanghai','CHN',9696300), (1891,'Peking','CHN',7472000), (1892,'Chongqing','CHN',6351600),
+(1893,'Tianjin','CHN',5286800), (1894,'Wuhan','CHN',4344600), (1895,'Harbin','CHN',4289800),
+(1896,'Shenyang','CHN',4265200), (1897,'Kanton [Guangzhou]','CHN',4256300), (1898,'Chengdu','CHN',3361500),
+(1899,'Nanking [Nanjing]','CHN',2870300), (1900,'Changchun','CHN',2812000), (1901,'Xi�an','CHN',2761400),
+(1902,'Dalian','CHN',2697000), (1903,'Qingdao','CHN',2596000), (1904,'Jinan','CHN',2278100),
+(1905,'Hangzhou','CHN',2190500), (1906,'Zhengzhou','CHN',2107200), (1907,'Shijiazhuang','CHN',2041500),
+(1908,'Taiyuan','CHN',1968400), (1909,'Kunming','CHN',1829500), (1910,'Changsha','CHN',1809800),
+(1911,'Nanchang','CHN',1691600), (1912,'Fuzhou','CHN',1593800), (1913,'Lanzhou','CHN',1565800),
+(1914,'Guiyang','CHN',1465200), (1915,'Ningbo','CHN',1371200), (1916,'Hefei','CHN',1369100),
+(1917,'Urumt�i [�r�mqi]','CHN',1310100), (1918,'Anshan','CHN',1200000), (1919,'Fushun','CHN',1200000),
+(1920,'Nanning','CHN',1161800), (1921,'Zibo','CHN',1140000), (1922,'Qiqihar','CHN',1070000),
+(1923,'Jilin','CHN',1040000), (1924,'Tangshan','CHN',1040000), (1925,'Baotou','CHN',980000),
+(1926,'Shenzhen','CHN',950500), (1927,'Hohhot','CHN',916700), (1928,'Handan','CHN',840000),
+(1929,'Wuxi','CHN',830000), (1930,'Xuzhou','CHN',810000), (1931,'Datong','CHN',800000),
+(1932,'Yichun','CHN',800000), (1933,'Benxi','CHN',770000), (1934,'Luoyang','CHN',760000),
+(1935,'Suzhou','CHN',710000), (1936,'Xining','CHN',700200), (1937,'Huainan','CHN',700000),
+(1938,'Jixi','CHN',683885), (1939,'Daqing','CHN',660000), (1940,'Fuxin','CHN',640000),
+(1941,'Amoy [Xiamen]','CHN',627500), (1942,'Liuzhou','CHN',610000), (1943,'Shantou','CHN',580000),
+(1944,'Jinzhou','CHN',570000), (1945,'Mudanjiang','CHN',570000), (1946,'Yinchuan','CHN',544500),
+(1947,'Changzhou','CHN',530000), (1948,'Zhangjiakou','CHN',530000), (1949,'Dandong','CHN',520000),
+(1950,'Hegang','CHN',520000), (1951,'Kaifeng','CHN',510000), (1952,'Jiamusi','CHN',493409),
+(1953,'Liaoyang','CHN',492559), (1954,'Hengyang','CHN',487148), (1955,'Baoding','CHN',483155),
+(1956,'Hunjiang','CHN',482043), (1957,'Xinxiang','CHN',473762), (1958,'Huangshi','CHN',457601),
+(1959,'Haikou','CHN',454300), (1960,'Yantai','CHN',452127), (1961,'Bengbu','CHN',449245),
+(1962,'Xiangtan','CHN',441968), (1963,'Weifang','CHN',428522), (1964,'Wuhu','CHN',425740),
+(1965,'Pingxiang','CHN',425579), (1966,'Yingkou','CHN',421589), (1967,'Anyang','CHN',420332),
+(1968,'Panzhihua','CHN',415466), (1969,'Pingdingshan','CHN',410775), (1970,'Xiangfan','CHN',410407),
+(1971,'Zhuzhou','CHN',409924), (1972,'Jiaozuo','CHN',409100), (1973,'Wenzhou','CHN',401871),
+(1974,'Zhangjiang','CHN',400997), (1975,'Zigong','CHN',393184), (1976,'Shuangyashan','CHN',386081),
+(1977,'Zaozhuang','CHN',380846), (1978,'Yakeshi','CHN',377869), (1979,'Yichang','CHN',371601),
+(1980,'Zhenjiang','CHN',368316), (1981,'Huaibei','CHN',366549), (1982,'Qinhuangdao','CHN',364972),
+(1983,'Guilin','CHN',364130), (1984,'Liupanshui','CHN',363954), (1985,'Panjin','CHN',362773),
+(1986,'Yangquan','CHN',362268), (1987,'Jinxi','CHN',357052), (1988,'Liaoyuan','CHN',354141),
+(1989,'Lianyungang','CHN',354139), (1990,'Xianyang','CHN',352125), (1991,'Tai�an','CHN',350696),
+(1992,'Chifeng','CHN',350077), (1993,'Shaoguan','CHN',350043), (1994,'Nantong','CHN',343341),
+(1995,'Leshan','CHN',341128), (1996,'Baoji','CHN',337765), (1997,'Linyi','CHN',324720),
+(1998,'Tonghua','CHN',324600), (1999,'Siping','CHN',317223), (2000,'Changzhi','CHN',317144),
+(2001,'Tengzhou','CHN',315083), (2002,'Chaozhou','CHN',313469), (2003,'Yangzhou','CHN',312892),
+(2004,'Dongwan','CHN',308669), (2005,'Ma�anshan','CHN',305421), (2006,'Foshan','CHN',303160),
+(2007,'Yueyang','CHN',302800), (2008,'Xingtai','CHN',302789), (2009,'Changde','CHN',301276),
+(2010,'Shihezi','CHN',299676), (2011,'Yancheng','CHN',296831), (2012,'Jiujiang','CHN',291187),
+(2013,'Dongying','CHN',281728), (2014,'Shashi','CHN',281352), (2015,'Xintai','CHN',281248),
+(2016,'Jingdezhen','CHN',281183), (2017,'Tongchuan','CHN',280657), (2018,'Zhongshan','CHN',278829),
+(2019,'Shiyan','CHN',273786), (2020,'Tieli','CHN',265683), (2021,'Jining','CHN',265248),
+(2022,'Wuhai','CHN',264081), (2023,'Mianyang','CHN',262947), (2024,'Luzhou','CHN',262892),
+(2025,'Zunyi','CHN',261862), (2026,'Shizuishan','CHN',257862), (2027,'Neijiang','CHN',256012),
+(2028,'Tongliao','CHN',255129), (2029,'Tieling','CHN',254842), (2030,'Wafangdian','CHN',251733),
+(2031,'Anqing','CHN',250718), (2032,'Shaoyang','CHN',247227), (2033,'Laiwu','CHN',246833),
+(2034,'Chengde','CHN',246799), (2035,'Tianshui','CHN',244974), (2036,'Nanyang','CHN',243303),
+(2037,'Cangzhou','CHN',242708), (2038,'Yibin','CHN',241019), (2039,'Huaiyin','CHN',239675),
+(2040,'Dunhua','CHN',235100), (2041,'Yanji','CHN',230892), (2042,'Jiangmen','CHN',230587),
+(2043,'Tongling','CHN',228017), (2044,'Suihua','CHN',227881), (2045,'Gongziling','CHN',226569),
+(2046,'Xiantao','CHN',222884), (2047,'Chaoyang','CHN',222394), (2048,'Ganzhou','CHN',220129),
+(2049,'Huzhou','CHN',218071), (2050,'Baicheng','CHN',217987), (2051,'Shangzi','CHN',215373),
+(2052,'Yangjiang','CHN',215196), (2053,'Qitaihe','CHN',214957), (2054,'Gejiu','CHN',214294),
+(2055,'Jiangyin','CHN',213659), (2056,'Hebi','CHN',212976), (2057,'Jiaxing','CHN',211526),
+(2058,'Wuzhou','CHN',210452), (2059,'Meihekou','CHN',209038), (2060,'Xuchang','CHN',208815),
+(2061,'Liaocheng','CHN',207844), (2062,'Haicheng','CHN',205560), (2063,'Qianjiang','CHN',205504),
+(2064,'Baiyin','CHN',204970), (2065,'Bei�an','CHN',204899), (2066,'Yixing','CHN',200824),
+(2067,'Laizhou','CHN',198664), (2068,'Qaramay','CHN',197602), (2069,'Acheng','CHN',197595),
+(2070,'Dezhou','CHN',195485), (2071,'Nanping','CHN',195064), (2072,'Zhaoqing','CHN',194784),
+(2073,'Beipiao','CHN',194301), (2074,'Fengcheng','CHN',193784), (2075,'Fuyu','CHN',192981),
+(2076,'Xinyang','CHN',192509), (2077,'Dongtai','CHN',192247), (2078,'Yuci','CHN',191356),
+(2079,'Honghu','CHN',190772), (2080,'Ezhou','CHN',190123), (2081,'Heze','CHN',189293),
+(2082,'Daxian','CHN',188101), (2083,'Linfen','CHN',187309), (2084,'Tianmen','CHN',186332),
+(2085,'Yiyang','CHN',185818), (2086,'Quanzhou','CHN',185154), (2087,'Rizhao','CHN',185048),
+(2088,'Deyang','CHN',182488), (2089,'Guangyuan','CHN',182241), (2090,'Changshu','CHN',181805),
+(2091,'Zhangzhou','CHN',181424), (2092,'Hailar','CHN',180650), (2093,'Nanchong','CHN',180273),
+(2094,'Jiutai','CHN',180130), (2095,'Zhaodong','CHN',179976), (2096,'Shaoxing','CHN',179818),
+(2097,'Fuyang','CHN',179572), (2098,'Maoming','CHN',178683), (2099,'Qujing','CHN',178669),
+(2100,'Ghulja','CHN',177193), (2101,'Jiaohe','CHN',176367), (2102,'Puyang','CHN',175988),
+(2103,'Huadian','CHN',175873), (2104,'Jiangyou','CHN',175753), (2105,'Qashqar','CHN',174570),
+(2106,'Anshun','CHN',174142), (2107,'Fuling','CHN',173878), (2108,'Xinyu','CHN',173524),
+(2109,'Hanzhong','CHN',169930), (2110,'Danyang','CHN',169603), (2111,'Chenzhou','CHN',169400),
+(2112,'Xiaogan','CHN',166280), (2113,'Shangqiu','CHN',164880), (2114,'Zhuhai','CHN',164747),
+(2115,'Qingyuan','CHN',164641), (2116,'Aqsu','CHN',164092), (2117,'Jining','CHN',163552),
+(2118,'Xiaoshan','CHN',162930), (2119,'Zaoyang','CHN',162198), (2120,'Xinghua','CHN',161910),
+(2121,'Hami','CHN',161315), (2122,'Huizhou','CHN',161023), (2123,'Jinmen','CHN',160794),
+(2124,'Sanming','CHN',160691), (2125,'Ulanhot','CHN',159538), (2126,'Korla','CHN',159344),
+(2127,'Wanxian','CHN',156823), (2128,'Rui�an','CHN',156468), (2129,'Zhoushan','CHN',156317),
+(2130,'Liangcheng','CHN',156307), (2131,'Jiaozhou','CHN',153364), (2132,'Taizhou','CHN',152442),
+(2133,'Suzhou','CHN',151862), (2134,'Yichun','CHN',151585), (2135,'Taonan','CHN',150168),
+(2136,'Pingdu','CHN',150123), (2137,'Ji�an','CHN',148583), (2138,'Longkou','CHN',148362),
+(2139,'Langfang','CHN',148105), (2140,'Zhoukou','CHN',146288), (2141,'Suining','CHN',146086),
+(2142,'Yulin','CHN',144467), (2143,'Jinhua','CHN',144280), (2144,'Liu�an','CHN',144248),
+(2145,'Shuangcheng','CHN',142659), (2146,'Suizhou','CHN',142302), (2147,'Ankang','CHN',142170),
+(2148,'Weinan','CHN',140169), (2149,'Longjing','CHN',139417), (2150,'Da�an','CHN',138963),
+(2151,'Lengshuijiang','CHN',137994), (2152,'Laiyang','CHN',137080), (2153,'Xianning','CHN',136811),
+(2154,'Dali','CHN',136554), (2155,'Anda','CHN',136446), (2156,'Jincheng','CHN',136396),
+(2157,'Longyan','CHN',134481), (2158,'Xichang','CHN',134419), (2159,'Wendeng','CHN',133910),
+(2160,'Hailun','CHN',133565), (2161,'Binzhou','CHN',133555), (2162,'Linhe','CHN',133183),
+(2163,'Wuwei','CHN',133101), (2164,'Duyun','CHN',132971), (2165,'Mishan','CHN',132744),
+(2166,'Shangrao','CHN',132455), (2167,'Changji','CHN',132260), (2168,'Meixian','CHN',132156),
+(2169,'Yushu','CHN',131861), (2170,'Tiefa','CHN',131807), (2171,'Huai�an','CHN',131149),
+(2172,'Leiyang','CHN',130115), (2173,'Zalantun','CHN',130031), (2174,'Weihai','CHN',128888),
+(2175,'Loudi','CHN',128418), (2176,'Qingzhou','CHN',128258), (2177,'Qidong','CHN',126872),
+(2178,'Huaihua','CHN',126785), (2179,'Luohe','CHN',126438), (2180,'Chuzhou','CHN',125341),
+(2181,'Kaiyuan','CHN',124219), (2182,'Linqing','CHN',123958), (2183,'Chaohu','CHN',123676),
+(2184,'Laohekou','CHN',123366), (2185,'Dujiangyan','CHN',123357), (2186,'Zhumadian','CHN',123232),
+(2187,'Linchuan','CHN',121949), (2188,'Jiaonan','CHN',121397), (2189,'Sanmenxia','CHN',120523),
+(2190,'Heyuan','CHN',120101), (2191,'Manzhouli','CHN',120023), (2192,'Lhasa','CHN',120000),
+(2193,'Lianyuan','CHN',118858), (2194,'Kuytun','CHN',118553), (2195,'Puqi','CHN',117264),
+(2196,'Hongjiang','CHN',116188), (2197,'Qinzhou','CHN',114586), (2198,'Renqiu','CHN',114256),
+(2199,'Yuyao','CHN',114065), (2200,'Guigang','CHN',114025), (2201,'Kaili','CHN',113958),
+(2202,'Yan�an','CHN',113277), (2203,'Beihai','CHN',112673), (2204,'Xuangzhou','CHN',112673),
+(2205,'Quzhou','CHN',112373), (2206,'Yong�an','CHN',111762), (2207,'Zixing','CHN',110048),
+(2208,'Liyang','CHN',109520), (2209,'Yizheng','CHN',109268), (2210,'Yumen','CHN',109234),
+(2211,'Liling','CHN',108504), (2212,'Yuncheng','CHN',108359), (2213,'Shanwei','CHN',107847),
+(2214,'Cixi','CHN',107329), (2215,'Yuanjiang','CHN',107004), (2216,'Bozhou','CHN',106346),
+(2217,'Jinchang','CHN',105287), (2218,'Fu�an','CHN',105265), (2219,'Suqian','CHN',105021),
+(2220,'Shishou','CHN',104571), (2221,'Hengshui','CHN',104269), (2222,'Danjiangkou','CHN',103211),
+(2223,'Fujin','CHN',103104), (2224,'Sanya','CHN',102820), (2225,'Guangshui','CHN',102770),
+(2226,'Huangshan','CHN',102628), (2227,'Xingcheng','CHN',102384), (2228,'Zhucheng','CHN',102134),
+(2229,'Kunshan','CHN',102052), (2230,'Haining','CHN',100478), (2231,'Pingliang','CHN',99265),
+(2232,'Fuqing','CHN',99193), (2233,'Xinzhou','CHN',98667), (2234,'Jieyang','CHN',98531),
+(2235,'Zhangjiagang','CHN',97994), (2236,'Tong Xian','CHN',97168), (2237,'Ya�an','CHN',95900),
+(2238,'Jinzhou','CHN',95761), (2239,'Emeishan','CHN',94000), (2240,'Enshi','CHN',93056),
+(2241,'Bose','CHN',93009), (2242,'Yuzhou','CHN',92889), (2243,'Kaiyuan','CHN',91999),
+(2244,'Tumen','CHN',91471), (2245,'Putian','CHN',91030), (2246,'Linhai','CHN',90870),
+(2247,'Xilin Hot','CHN',90646), (2248,'Shaowu','CHN',90286), (2249,'Junan','CHN',90222),
+(2250,'Huaying','CHN',89400), (2251,'Pingyi','CHN',89373), (2252,'Huangyan','CHN',89288),
+(2413,'La Habana','CUB',2256000), (2414,'Santiago de Cuba','CUB',433180), (2415,'Camag�ey','CUB',298726),
+(2416,'Holgu�n','CUB',249492), (2417,'Santa Clara','CUB',207350), (2418,'Guant�namo','CUB',205078),
+(2419,'Pinar del R�o','CUB',142100), (2420,'Bayamo','CUB',141000), (2421,'Cienfuegos','CUB',132770),
+(2422,'Victoria de las Tunas','CUB',132350), (2423,'Matanzas','CUB',123273), (2424,'Manzanillo','CUB',109350),
+(2425,'Sancti-Sp�ritus','CUB',100751), (2426,'Ciego de �vila','CUB',98505), (2430,'Nicosia','CYP',195000),
+(2431,'Limassol','CYP',154400), (3245,'Z�rich','CHE',336800), (3246,'Geneve','CHE',173500),
+(3247,'Basel','CHE',166700), (3248,'Bern','CHE',122700), (3249,'Lausanne','CHE',114500),
+(3339,'Praha','CZE',1181126), (3340,'Brno','CZE',381862), (3341,'Ostrava','CZE',320041),
+(3342,'Plzen','CZE',166759), (3343,'Olomouc','CZE',102702), (3344,'Liberec','CZE',99155),
+(3345,'Cesk� Budejovice','CZE',98186), (3346,'Hradec Kr�lov�','CZE',98080), (3347,'�st� nad Labem','CZE',95491),
+(3348,'Pardubice','CZE',91309), (3520,'Minsk','BLR',1674000), (3521,'Gomel','BLR',475000),
+(3522,'Mogiljov','BLR',356000), (3523,'Vitebsk','BLR',340000), (3524,'Grodno','BLR',302000),
+(3525,'Brest','BLR',286000), (3526,'Bobruisk','BLR',221000), (3527,'Baranovit�i','BLR',167000),
+(3528,'Borisov','BLR',151000), (3529,'Pinsk','BLR',130000), (3530,'Or�a','BLR',124000),
+(3531,'Mozyr','BLR',110000), (3532,'Novopolotsk','BLR',106000), (3533,'Lida','BLR',101000),
+(3534,'Soligorsk','BLR',101000), (3535,'Molodet�no','BLR',97000);
+
+insert into t1 (Code, Name, Continent) values
+('AFG','Afghanistan','Asia'), ('ANT','Netherlands Antilles','North America'),
+('ALB','Albania','Europe'), ('AND','Andorra','Europe'),
+('AIA','Anguilla','North America'), ('ATG','Antigua and Barbuda','North America'),
+('ARE','United Arab Emirates','Asia'), ('ARM','Armenia','Asia'),
+('ABW','Aruba','North America'), ('AZE','Azerbaijan','Asia'),
+('BHS','Bahamas','North America'), ('BHR','Bahrain','Asia'),
+('BGD','Bangladesh','Asia'), ('BRB','Barbados','North America'),
+('BEL','Belgium','Europe'), ('BLZ','Belize','North America'),
+('BMU','Bermuda','North America'), ('BTN','Bhutan','Asia'),
+('BIH','Bosnia and Herzegovina','Europe'), ('BRN','Brunei','Asia'),
+('BGR','Bulgaria','Europe'), ('CYM','Cayman Islands','North America'),
+('CRI','Costa Rica','North America'), ('AUT','Austria','Europe'),
+('CAN','Canada','North America'), ('CHN','China','Asia'),
+('CUB','Cuba','North America'), ('CYP','Cyprus','Asia'),
+('CHE','Switzerland','Europe'), ('CZE','Czech Republic','Europe'),
+('BLR','Belarus','Europe');
+update t2 set population=6000000 where Name in ('Wien', 'Vancouver', 'Praha');
+--enable_query_log
+
+--echo This must not use LooseScan:
+EXPLAIN SELECT Name FROM t1
+ WHERE t1.Code IN (
+ SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
+
+SELECT Name FROM t1
+ WHERE t1.Code IN (
+ SELECT t2.CountryCode FROM t2 WHERE Population > 5000000);
+
+drop table t1, t2;
+
+#
+# Bug#33062: subquery in stored routine cause crash
+#
+
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(c INT);
+
+DELIMITER //;
+
+CREATE PROCEDURE p1(v1 int)
+BEGIN
+ SELECT 1 FROM t1 WHERE a = v1 AND a IN (SELECT c FROM t2);
+END
+//
+
+CREATE PROCEDURE p2(v1 int)
+BEGIN
+ SELECT 1 FROM t1 WHERE a IN (SELECT c FROM t2);
+END
+//
+
+CREATE PROCEDURE p3(v1 int)
+BEGIN
+ SELECT 1
+ FROM
+ t1 t01,t1 t02,t1 t03,t1 t04,t1 t05,t1 t06,t1 t07,t1 t08,
+ t1 t09,t1 t10,t1 t11,t1 t12,t1 t13,t1 t14,t1 t15,t1 t16,
+ t1 t17,t1 t18,t1 t19,t1 t20,t1 t21,t1 t22,t1 t23,t1 t24,
+ t1 t25,t1 t26,t1 t27,t1 t28,t1 t29,t1 t30,t1 t31,t1 t32,
+ t1 t33,t1 t34,t1 t35,t1 t36,t1 t37,t1 t38,t1 t39,t1 t40,
+ t1 t41,t1 t42,t1 t43,t1 t44,t1 t45,t1 t46,t1 t47,t1 t48,
+ t1 t49,t1 t50,t1 t51,t1 t52,t1 t53,t1 t54,t1 t55,t1 t56,
+ t1 t57,t1 t58,t1 t59,t1 t60
+ WHERE t01.a IN (SELECT c FROM t2);
+END
+//
+
+CREATE PROCEDURE p4(v1 int)
+BEGIN
+ SELECT 1
+ FROM
+ t1 t01,t1 t02,t1 t03,t1 t04,t1 t05,t1 t06,t1 t07,t1 t08,
+ t1 t09,t1 t10,t1 t11,t1 t12,t1 t13,t1 t14,t1 t15,t1 t16,
+ t1 t17,t1 t18,t1 t19,t1 t20,t1 t21,t1 t22,t1 t23,t1 t24,
+ t1 t25,t1 t26,t1 t27,t1 t28,t1 t29,t1 t30,t1 t31,t1 t32,
+ t1 t33,t1 t34,t1 t35,t1 t36,t1 t37,t1 t38,t1 t39,t1 t40,
+ t1 t41,t1 t42,t1 t43,t1 t44,t1 t45,t1 t46,t1 t47,t1 t48,
+ t1 t49,t1 t50,t1 t51,t1 t52,t1 t53,t1 t54,t1 t55,t1 t56,
+ t1 t57,t1 t58,t1 t59,t1 t60
+ WHERE t01.a = v1 AND t01.a IN (SELECT c FROM t2);
+END
+//
+
+DELIMITER ;//
+
+CALL p1(1);
+CALL p2(1);
+CALL p3(1);
+CALL p4(1);
+
+DROP TABLE t1, t2;
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP PROCEDURE p3;
+DROP PROCEDURE p4;
+
+
+#
+# BUG#35160 "Subquery optimization: table pullout is not reflected in EXPLAIN EXTENDED"
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4);
+
+create table t1 (a int, b int, key(a));
+insert into t1 select a,a from t0;
+
+create table t2 (a int, b int, primary key(a));
+insert into t2 select * from t1;
+
+# Table t2 should be pulled out because t2.a=t0.a equality
+--echo Table t2, unlike table t1, should be displayed as pulled out
+explain extended select * from t0
+where t0.a in ( select t1.a from t1,t2 where t2.a=t0.a and
+t1.b=t2.b);
+
+#
+# BUG#46556 "Returning incorrect, empty results for some IN subqueries
+# w/ semijoin=on"
+#
+
+# The above query did not have a valid plan before the fix of BUG#46556.
+# Add some data that would cause wrong result with the old plan.
+update t1 set a=3, b=11 where a=4;
+update t2 set b=11 where a=3;
+
+if (`select @@join_cache_level=6`)
+{
+ --echo
+ --echo # The following query gives wrong result due to Bug#49129
+}
+select * from t0 where t0.a in
+ (select t1.a from t1, t2 where t2.a=t0.a and t1.b=t2.b);
+
+drop table t0, t1, t2;
+
+#
+# BUG#35767: Processing of uncorrelated subquery with semi-join cause wrong result and crash
+#
+CREATE TABLE t1 (
+ id int(11) NOT NULL,
+ PRIMARY KEY (id));
+
+CREATE TABLE t2 (
+ id int(11) NOT NULL,
+ fid int(11) NOT NULL,
+ PRIMARY KEY (id));
+
+insert into t1 values(1);
+insert into t2 values(1,7503),(2,1);
+
+--error 1054
+explain select count(*)
+from t1
+where fid IN (select fid from t2 where (id between 7502 and 8420) order by fid );
+
+drop table t1, t2;
+
+#
+# BUG#36137 "virtual longlong Item_in_subselect::val_int(): Assertion `0' failed."
+#
+create table t1 (a int, b int, key (a), key (b));
+insert into t1 values (2,4),(2,4),(2,4);
+select t1.a from t1
+where
+ t1.a in (select 1 from t1 where t1.a in (select 1 from t1) group by t1.a);
+drop table t1;
+
+#
+# BUG#36128: not in subquery causes crash in cleanup..
+#
+create table t1(a int,b int,key(a),key(b));
+insert into t1 values (1,1),(2,2),(3,3);
+select 1 from t1
+where t1.a not in (select 1 from t1
+ where t1.a in (select 1 from t1)
+ group by t1.b);
+drop table t1;
+
+#
+# BUG#33743 "nested subqueries, unique index, wrong result"
+#
+CREATE TABLE t1
+ (EMPNUM CHAR(3) NOT NULL,
+ EMPNAME CHAR(20),
+ GRADE DECIMAL(4),
+ CITY CHAR(15));
+
+CREATE TABLE t2
+ (PNUM CHAR(3) NOT NULL,
+ PNAME CHAR(20),
+ PTYPE CHAR(6),
+ BUDGET DECIMAL(9),
+ CITY CHAR(15));
+
+CREATE TABLE t3
+ (EMPNUM CHAR(3) NOT NULL,
+ PNUM CHAR(3) NOT NULL,
+ HOURS DECIMAL(5));
+
+INSERT INTO t1 VALUES ('E1','Alice',12,'Deale');
+INSERT INTO t1 VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO t1 VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO t1 VALUES ('E4','Don',12,'Deale');
+INSERT INTO t1 VALUES ('E5','Ed',13,'Akron');
+
+INSERT INTO t2 VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO t2 VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO t2 VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO t2 VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO t2 VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO t2 VALUES ('P6','PAYR','Design',50000,'Deale');
+
+INSERT INTO t3 VALUES ('E1','P1',40);
+INSERT INTO t3 VALUES ('E1','P2',20);
+INSERT INTO t3 VALUES ('E1','P3',80);
+INSERT INTO t3 VALUES ('E1','P4',20);
+INSERT INTO t3 VALUES ('E1','P5',12);
+INSERT INTO t3 VALUES ('E1','P6',12);
+INSERT INTO t3 VALUES ('E2','P1',40);
+INSERT INTO t3 VALUES ('E2','P2',80);
+INSERT INTO t3 VALUES ('E3','P2',20);
+INSERT INTO t3 VALUES ('E4','P2',20);
+INSERT INTO t3 VALUES ('E4','P4',40);
+INSERT INTO t3 VALUES ('E4','P5',80);
+
+
+SELECT * FROM t1;
+CREATE UNIQUE INDEX t1_IDX ON t1(EMPNUM);
+--sorted_result
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+DROP INDEX t1_IDX ON t1;
+CREATE INDEX t1_IDX ON t1(EMPNUM);
+--sorted_result
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+DROP INDEX t1_IDX ON t1;
+--sorted_result
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+ (SELECT EMPNUM
+ FROM t3
+ WHERE PNUM IN
+ (SELECT PNUM
+ FROM t2
+ WHERE PTYPE = 'Design'));
+
+DROP TABLE t1, t2, t3;
+
+#
+# BUG#33245 "Crash on VIEW referencing FROM table in an IN clause"
+#
+CREATE TABLE t1 (f1 INT NOT NULL);
+CREATE VIEW v1 (a) AS SELECT f1 IN (SELECT f1 FROM t1) FROM t1;
+SELECT * FROM v1;
+drop view v1;
+drop table t1;
+
+
+#
+# BUG#35550 "Semi-join subquery in ON clause and no WHERE crashes the server"
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1(a int, b int);
+insert into t1 values (0,0),(1,1),(2,2);
+create table t2 as select * from t1;
+
+create table t3 (pk int, a int, primary key(pk));
+insert into t3 select a,a from t0;
+
+explain
+select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
+
+drop table t0, t1, t2, t3;
+
+#
+# BUG#34799: crash or/and memory overrun with dependant subquery and some joins
+#
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t2 (a char(200), b char(200), c char(200), primary key (a,b,c)) engine=innodb;
+insert into t2 select concat(a, repeat('X',198)),repeat('B',200),repeat('B',200) from t1;
+insert into t2 select concat(a, repeat('Y',198)),repeat('B',200),repeat('B',200) from t1;
+alter table t2 add filler1 int;
+
+insert into t1 select A.a + 10*(B.a + 10*C.a) from t1 A, t1 B, t1 C;
+
+set @save_join_buffer_size=@@join_buffer_size;
+--disable_warnings
+set join_buffer_size=1;
+--enable_warnings
+
+select * from t2 where filler1 in ( select a from t1);
+set join_buffer_size=default;
+
+drop table t1, t2;
+#
+# BUG#33509: Server crashes with number of recursive subqueries=61
+# (the query may or may not fail with an error so we're using it with SP
+#
+create table t1 (a int not null);
+
+--disable_warnings
+drop procedure if exists p1;
+--enable_warnings
+
+delimiter |;
+
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE EXIT HANDLER FOR SQLEXCEPTION select a from t1;
+ prepare s1 from '
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in (
+ select a from t1 where a in ( select a from t1)
+ )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))';
+ execute s1;
+END;
+|
+delimiter ;|
+
+call p1();
+drop procedure p1;
+drop table t1;
+
+#
+# BUG#35468 "Slowdown and wrong result for uncorrelated subquery w/o where"
+#
+
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int) as select A.a + 10 *(B.a + 10*C.a) as a from t0 A, t0 B, t0 C;
+create table t2 (id int, a int, primary key(id), key(a)) as select a as id, a as a from t1;
+show create table t2;
+set @a=0;
+create table t3 as select * from t2 limit 0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+insert into t3 select @a:=@a+1, t2.a from t2, t0;
+
+alter table t3 add primary key(id), add key(a);
+--echo The following must use loose index scan over t3, key a:
+explain select count(a) from t2 where a in ( SELECT a FROM t3);
+select count(a) from t2 where a in ( SELECT a FROM t3);
+
+drop table t0,t1,t2,t3;
+
+--echo
+--echo BUG#42740: crash in optimize_semijoin_nests
+--echo
+create table t1 (c6 timestamp,key (c6)) engine=innodb;
+create table t2 (c2 double) engine=innodb;
+explain select 1 from t2 where c2 = any (select log10(null) from t1 where c6 <null) ;
+drop table t1, t2;
+
+--echo #
+--echo # BUG#42742: crash in setup_sj_materialization, Copy_field::set
+--echo #
+create table t3 ( c1 year) engine=innodb;
+insert into t3 values (2135),(2142);
+create table t2 (c1 tinytext,c2 text,c6 timestamp) engine=innodb;
+-- echo # The following must not crash, EXPLAIN should show one SJ strategy, not a mix:
+explain select 1 from t2 where
+ c2 in (select 1 from t3, t2) and
+ c1 in (select convert(c6,char(1)) from t2);
+drop table t2, t3;
+
diff --git a/mysql-test/t/subselect_sj2_jcl6.test b/mysql-test/t/subselect_sj2_jcl6.test
new file mode 100644
index 00000000000..202ea139e5f
--- /dev/null
+++ b/mysql-test/t/subselect_sj2_jcl6.test
@@ -0,0 +1,11 @@
+#
+# Run subselect_sj2.test with BKA enabled
+#
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+--source t/subselect_sj2.test
+
+set join_cache_level=default;
+show variables like 'join_cache_level';
diff --git a/mysql-test/t/subselect_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test
new file mode 100644
index 00000000000..9b5309ff264
--- /dev/null
+++ b/mysql-test/t/subselect_sj_jcl6.test
@@ -0,0 +1,11 @@
+#
+# Run subselect_sj.test with BKA enabled
+#
+
+set join_cache_level=6;
+show variables like 'join_cache_level';
+
+--source t/subselect_sj.test
+
+set join_cache_level=default;
+show variables like 'join_cache_level';