← Back to team overview

maria-developers team mailing list archive

bzr commit into file:///home/tsk/mprog/src/5.3-mwl68/ branch (timour:2767)

 

#At file:///home/tsk/mprog/src/5.3-mwl68/ based on revid:timour@xxxxxxxxxxxx-20100309103615-dzmm6xt7ye5xfs25

 2767 timour@xxxxxxxxxxxx	2010-03-11
      MWL#68 Subquery optimization: Efficient NOT IN execution with NULLs
      
      This patch does three things:
      - It adds the possibility to force the execution of top-level [NOT] IN
        subquery predicates via the IN=>EXISTS transformation. This is done by
        setting both optimizer switches partial_match_rowid_merge and
        partial_match_table_scan to "off".
      - It adjusts all test cases where the complete optimizer_switch is
        selected because now we have two more switches.
      - For those test cases where the plan changes because of the new available
        strategies, we switch off both partial match strategies in order to
        force the "old" IN=>EXISTS strategy. This is done because most of these
        test cases specifically test bugs in this strategy.
     @ sql/opt_subselect.cc
        Adds the possibility to force the execution of top-level [NOT] IN
        subquery predicates via the IN=>EXISTS transformation. This is done by
        setting both optimizer switches partial_match_rowid_merge and
        partial_match_table_scan to "off".

    modified:
      mysql-test/include/mix1.inc
      mysql-test/r/index_merge_myisam.result
      mysql-test/r/innodb_mysql.result
      mysql-test/r/myisam_mrr.result
      mysql-test/r/ps.result
      mysql-test/r/subselect.result
      mysql-test/r/subselect3.result
      mysql-test/r/subselect3_jcl6.result
      mysql-test/r/subselect_no_mat.result
      mysql-test/r/subselect_no_opts.result
      mysql-test/r/subselect_no_semijoin.result
      mysql-test/r/subselect_sj.result
      mysql-test/r/subselect_sj_jcl6.result
      mysql-test/t/ps.test
      mysql-test/t/subselect.test
      mysql-test/t/subselect3.test
      sql/opt_subselect.cc
=== modified file 'mysql-test/include/mix1.inc'
--- a/mysql-test/include/mix1.inc	2009-09-15 06:08:54 +0000
+++ b/mysql-test/include/mix1.inc	2010-03-11 21:43:31 +0000
@@ -1177,8 +1177,11 @@ DROP TABLE t1;
 
 create table t1 (a bit(1) not null,b int) engine=myisam;
 create table t2 (c int) engine=innodb;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=off';
 explain
 select b from t1 where a not in (select b from t1,t2 group by a) group by a;
+set optimizer_switch=@save_optimizer_switch;
 DROP TABLE t1,t2;
 
 --echo End of 5.0 tests

=== modified file 'mysql-test/r/index_merge_myisam.result'
--- a/mysql-test/r/index_merge_myisam.result	2010-01-17 14:51:10 +0000
+++ b/mysql-test/r/index_merge_myisam.result	2010-03-11 21:43:31 +0000
@@ -1419,19 +1419,19 @@ drop table t1;
 #
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='index_merge=off,index_merge_union=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='index_merge_union=on';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,index_merge_sort_union=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch=4;
 ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4'
 set optimizer_switch=NULL;
@@ -1458,21 +1458,21 @@ set optimizer_switch=default;
 set optimizer_switch='index_merge=off,index_merge_union=off,default';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch=default;
 select @@global.optimizer_switch;
 @@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set @@global.optimizer_switch=default;
 select @@global.optimizer_switch;
 @@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 #
 # Check index_merge's @@optimizer_switch flags
 #
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 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, c int, filler char(100), 
@@ -1582,5 +1582,5 @@ id	select_type	table	type	possible_keys	
 set optimizer_switch=default;
 show variables like 'optimizer_switch';
 Variable_name	Value
-optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 drop table t0, t1;

=== modified file 'mysql-test/r/innodb_mysql.result'
--- a/mysql-test/r/innodb_mysql.result	2009-12-15 07:16:46 +0000
+++ b/mysql-test/r/innodb_mysql.result	2010-03-11 21:43:31 +0000
@@ -1425,12 +1425,15 @@ DROP TABLE t1;
 #
 create table t1 (a bit(1) not null,b int) engine=myisam;
 create table t2 (c int) engine=innodb;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=off';
 explain
 select b from t1 where a not in (select b from t1,t2 group by a) group by a;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
 2	DEPENDENT SUBQUERY	t1	system	NULL	NULL	NULL	NULL	0	const row not found
 2	DEPENDENT SUBQUERY	t2	ALL	NULL	NULL	NULL	NULL	1	
+set optimizer_switch=@save_optimizer_switch;
 DROP TABLE t1,t2;
 End of 5.0 tests
 CREATE TABLE `t2` (

=== modified file 'mysql-test/r/myisam_mrr.result'
--- a/mysql-test/r/myisam_mrr.result	2010-01-17 14:51:10 +0000
+++ b/mysql-test/r/myisam_mrr.result	2010-03-11 21:43:31 +0000
@@ -394,7 +394,7 @@ drop table t0, t1;
 #   - engine_condition_pushdown does not affect ICP
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 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, key(a));

=== modified file 'mysql-test/r/ps.result'
--- a/mysql-test/r/ps.result	2009-05-27 15:19:44 +0000
+++ b/mysql-test/r/ps.result	2010-03-11 21:43:31 +0000
@@ -149,6 +149,8 @@ c29 longblob, c30 longtext, c31 enum('on
 c32 set('monday', 'tuesday', 'wednesday')
 ) engine = MYISAM ;
 create table t2 like t1;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
 set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
 prepare stmt1 from @stmt ;
 execute stmt1 ;
@@ -177,6 +179,7 @@ id	select_type	table	type	possible_keys	
 2	DEPENDENT SUBQUERY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
 deallocate prepare stmt1;
 drop tables t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
 set @arg00=1;
 prepare stmt1 from ' create table t1 (m int) as select 1 as m ' ;
 execute stmt1 ;

=== modified file 'mysql-test/r/subselect.result'
--- a/mysql-test/r/subselect.result	2010-02-17 21:59:41 +0000
+++ b/mysql-test/r/subselect.result	2010-03-11 21:43:31 +0000
@@ -1,4 +1,6 @@
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
 select (select 2);
 (select 2)
 2
@@ -4803,4 +4805,5 @@ SELECT 1 FROM t1 GROUP BY
 1
 1
 DROP TABLE t1;
+set @@optimizer_switch=@save_optimizer_switch;
 End of 5.1 tests.

=== modified file 'mysql-test/r/subselect3.result'
--- a/mysql-test/r/subselect3.result	2010-02-17 10:05:27 +0000
+++ b/mysql-test/r/subselect3.result	2010-03-11 21:43:31 +0000
@@ -63,12 +63,15 @@ Handler_read_rnd_next	11
 select ' ^ This must show 11' Z;
 Z
  ^ This must show 11
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
 explain extended select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	100.00	
 2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	6	100.00	Using where; Using temporary; Using filesort
 Warnings:
 Note	1003	select <in_optimizer>(`test`.`t3`.`a`,<exists>(select max(`test`.`t1`.`ie`) AS `max(ie)` from `test`.`t1` where (`test`.`t1`.`oref` = 4) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t3`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))) AS `a in (select max(ie) from t1 where oref=4 group by grp)` from `test`.`t3`
+set @@optimizer_switch=@save_optimizer_switch;
 drop table t1, t2, t3;
 create table t1 (a int, oref int, key(a));
 insert into t1 values 
@@ -692,6 +695,8 @@ a	MAX(b)	test
 2	3	h
 3	4	i
 DROP TABLE t1, t2;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
 CREATE TABLE t1 (a int);
 CREATE TABLE t2 (b int, PRIMARY KEY(b));
 INSERT INTO t1 VALUES (1), (NULL), (4);
@@ -759,6 +764,7 @@ id	select_type	table	type	possible_keys	
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where
 2	DEPENDENT SUBQUERY	t2	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index; Using where
 DROP TABLE t1, t2;
+set @@optimizer_switch=@save_optimizer_switch;
 CREATE TABLE t1 (a INT);
 INSERT INTO t1 VALUES(1);
 CREATE TABLE t2 (placeholder CHAR(11));
@@ -960,7 +966,7 @@ i1	i2
 # Baseline:
 SHOW STATUS LIKE '%Handler_read_rnd_next';
 Variable_name	Value
-Handler_read_rnd_next	17
+Handler_read_rnd_next	18
 
 INSERT INTO t1 VALUES (NULL, NULL);
 FLUSH STATUS;
@@ -977,7 +983,7 @@ i1	i2
 # (read record from t1, but do not read from t2)
 SHOW STATUS LIKE '%Handler_read_rnd_next';
 Variable_name	Value
-Handler_read_rnd_next	18
+Handler_read_rnd_next	19
 DROP TABLE t1,t2;
 End of 5.1 tests
 CREATE TABLE t1 (

=== modified file 'mysql-test/r/subselect3_jcl6.result'
--- a/mysql-test/r/subselect3_jcl6.result	2010-02-17 10:47:55 +0000
+++ b/mysql-test/r/subselect3_jcl6.result	2010-03-11 21:43:31 +0000
@@ -67,12 +67,15 @@ Handler_read_rnd_next	11
 select ' ^ This must show 11' Z;
 Z
  ^ This must show 11
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
 explain extended select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	100.00	
 2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	6	100.00	Using where; Using temporary; Using filesort
 Warnings:
 Note	1003	select <in_optimizer>(`test`.`t3`.`a`,<exists>(select max(`test`.`t1`.`ie`) AS `max(ie)` from `test`.`t1` where (`test`.`t1`.`oref` = 4) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t3`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))) AS `a in (select max(ie) from t1 where oref=4 group by grp)` from `test`.`t3`
+set @@optimizer_switch=@save_optimizer_switch;
 drop table t1, t2, t3;
 create table t1 (a int, oref int, key(a));
 insert into t1 values 
@@ -696,6 +699,8 @@ a	MAX(b)	test
 2	3	h
 3	4	i
 DROP TABLE t1, t2;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
 CREATE TABLE t1 (a int);
 CREATE TABLE t2 (b int, PRIMARY KEY(b));
 INSERT INTO t1 VALUES (1), (NULL), (4);
@@ -763,6 +768,7 @@ id	select_type	table	type	possible_keys	
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	4	Using where
 2	DEPENDENT SUBQUERY	t2	unique_subquery	PRIMARY	PRIMARY	4	func	1	Using index; Using where
 DROP TABLE t1, t2;
+set @@optimizer_switch=@save_optimizer_switch;
 CREATE TABLE t1 (a INT);
 INSERT INTO t1 VALUES(1);
 CREATE TABLE t2 (placeholder CHAR(11));
@@ -964,7 +970,7 @@ i1	i2
 # Baseline:
 SHOW STATUS LIKE '%Handler_read_rnd_next';
 Variable_name	Value
-Handler_read_rnd_next	17
+Handler_read_rnd_next	18
 
 INSERT INTO t1 VALUES (NULL, NULL);
 FLUSH STATUS;
@@ -981,7 +987,7 @@ i1	i2
 # (read record from t1, but do not read from t2)
 SHOW STATUS LIKE '%Handler_read_rnd_next';
 Variable_name	Value
-Handler_read_rnd_next	18
+Handler_read_rnd_next	19
 DROP TABLE t1,t2;
 End of 5.1 tests
 CREATE TABLE t1 (

=== modified file 'mysql-test/r/subselect_no_mat.result'
--- a/mysql-test/r/subselect_no_mat.result	2010-02-21 07:33:54 +0000
+++ b/mysql-test/r/subselect_no_mat.result	2010-03-11 21:43:31 +0000
@@ -1,8 +1,10 @@
 show variables like 'optimizer_switch';
 Variable_name	Value
-optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='materialization=off';
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
 select (select 2);
 (select 2)
 2
@@ -4807,8 +4809,9 @@ SELECT 1 FROM t1 GROUP BY
 1
 1
 DROP TABLE t1;
+set @@optimizer_switch=@save_optimizer_switch;
 End of 5.1 tests.
 set optimizer_switch=default;
 show variables like 'optimizer_switch';
 Variable_name	Value
-optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on

=== modified file 'mysql-test/r/subselect_no_opts.result'
--- a/mysql-test/r/subselect_no_opts.result	2010-02-21 07:33:54 +0000
+++ b/mysql-test/r/subselect_no_opts.result	2010-03-11 21:43:31 +0000
@@ -1,8 +1,10 @@
 show variables like 'optimizer_switch';
 Variable_name	Value
-optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='materialization=off,semijoin=off';
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
 select (select 2);
 (select 2)
 2
@@ -4807,8 +4809,9 @@ SELECT 1 FROM t1 GROUP BY
 1
 1
 DROP TABLE t1;
+set @@optimizer_switch=@save_optimizer_switch;
 End of 5.1 tests.
 set optimizer_switch=default;
 show variables like 'optimizer_switch';
 Variable_name	Value
-optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on

=== modified file 'mysql-test/r/subselect_no_semijoin.result'
--- a/mysql-test/r/subselect_no_semijoin.result	2010-02-21 07:33:54 +0000
+++ b/mysql-test/r/subselect_no_semijoin.result	2010-03-11 21:43:31 +0000
@@ -1,8 +1,10 @@
 show variables like 'optimizer_switch';
 Variable_name	Value
-optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='semijoin=off';
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
 select (select 2);
 (select 2)
 2
@@ -4807,8 +4809,9 @@ SELECT 1 FROM t1 GROUP BY
 1
 1
 DROP TABLE t1;
+set @@optimizer_switch=@save_optimizer_switch;
 End of 5.1 tests.
 set optimizer_switch=default;
 show variables like 'optimizer_switch';
 Variable_name	Value
-optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+optimizer_switch	index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on

=== modified file 'mysql-test/r/subselect_sj.result'
--- a/mysql-test/r/subselect_sj.result	2010-02-24 11:33:42 +0000
+++ b/mysql-test/r/subselect_sj.result	2010-03-11 21:43:31 +0000
@@ -202,39 +202,39 @@ BUG#37120 optimizer_switch allowable val
 
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,materialization=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,semijoin=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,loosescan=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,semijoin=off,materialization=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,materialization=off,semijoin=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,semijoin=off,loosescan=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,materialization=off,loosescan=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch=default;
 drop table t0, t1, t2;
 drop table t10, t11, t12;

=== modified file 'mysql-test/r/subselect_sj_jcl6.result'
--- a/mysql-test/r/subselect_sj_jcl6.result	2010-03-07 15:41:45 +0000
+++ b/mysql-test/r/subselect_sj_jcl6.result	2010-03-11 21:43:31 +0000
@@ -206,39 +206,39 @@ BUG#37120 optimizer_switch allowable val
 
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,materialization=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,semijoin=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,loosescan=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,semijoin=off,materialization=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,materialization=off,semijoin=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=on,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,semijoin=off,loosescan=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=off
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch='default,materialization=off,loosescan=off';
 select @@optimizer_switch;
 @@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_condition_pushdown=on,firstmatch=on,loosescan=off,materialization=off,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on
 set optimizer_switch=default;
 drop table t0, t1, t2;
 drop table t10, t11, t12;

=== modified file 'mysql-test/t/ps.test'
--- a/mysql-test/t/ps.test	2009-05-27 15:19:44 +0000
+++ b/mysql-test/t/ps.test	2010-03-11 21:43:31 +0000
@@ -163,6 +163,9 @@ create table t1 
 ) engine = MYISAM ;
 create table t2 like t1;
 
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+
 set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
 prepare stmt1 from @stmt ;
 execute stmt1 ;
@@ -171,6 +174,8 @@ explain SELECT (SELECT SUM(c1 + c12 + 0.
 deallocate prepare stmt1;
 drop tables t1,t2;
 
+set @@optimizer_switch=@save_optimizer_switch;
+
 #
 # parameters from variables (for field creation)
 #

=== modified file 'mysql-test/t/subselect.test'
--- a/mysql-test/t/subselect.test	2010-01-17 20:52:20 +0000
+++ b/mysql-test/t/subselect.test	2010-03-11 21:43:31 +0000
@@ -11,6 +11,9 @@
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
 --enable_warnings
 
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+
 select (select 2);
 explain extended select (select 2);
 SELECT (SELECT 1) UNION SELECT (SELECT 2);
@@ -4061,4 +4064,6 @@ SELECT 1 FROM t1 GROUP BY
   (SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
 DROP TABLE t1;
 
+set @@optimizer_switch=@save_optimizer_switch;
+
 --echo End of 5.1 tests.

=== modified file 'mysql-test/t/subselect3.test'
--- a/mysql-test/t/subselect3.test	2010-01-17 14:51:10 +0000
+++ b/mysql-test/t/subselect3.test	2010-03-11 21:43:31 +0000
@@ -59,9 +59,13 @@ select a in (select max(ie) from t1 wher
 show status like 'Handler_read_rnd_next';
 select ' ^ This must show 11' Z;
 
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+
 # This must show trigcond:
 explain extended select a in (select max(ie) from t1 where oref=4 group by grp) from t3;
 
+set @@optimizer_switch=@save_optimizer_switch;
 drop table t1, t2, t3;
 
 # 
@@ -529,6 +533,9 @@ SELECT a, MAX(b),
 
 DROP TABLE t1, t2;
 
+# The next three test cases must be executed with the IN=>EXISTS strategy
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
 
 #
 # Bug #27870: crash of an equijoin query with WHERE condition containing 
@@ -588,6 +595,8 @@ EXPLAIN SELECT a FROM t1 WHERE a NOT IN 
 
 DROP TABLE t1, t2;
 
+set @@optimizer_switch=@save_optimizer_switch;
+
 #
 # Bug #34763: item_subselect.cc:1235:Item_in_subselect::row_value_transformer:
 #             Assertion failed, unexpected error message:

=== modified file 'sql/opt_subselect.cc'
--- a/sql/opt_subselect.cc	2010-03-09 10:36:15 +0000
+++ b/sql/opt_subselect.cc	2010-03-11 21:43:31 +0000
@@ -187,7 +187,11 @@ int check_and_do_in_subquery_rewrites(JO
              does not call setup_subquery_materialization(). We could make 
              SELECT ... FROM DUAL call that function but that doesn't seem
              to be the case that is worth handling.
-        4. Subquery is non-correlated
+        4. Either the subquery predicate is a top-level predicate, or at
+           least one partial match strategy is enabled. If no partial match
+           strategy is enabled, then materialization cannot be used for
+           non-top-level queries because it cannot handle NULLs correctly.
+        5. Subquery is non-correlated
            TODO:
            This is an overly restrictive condition. It can be extended to:
            (Subquery is non-correlated ||
@@ -195,13 +199,13 @@ int check_and_do_in_subquery_rewrites(JO
             (Subquery is correlated to the immediate outer query &&
              Subquery !contains {GROUP BY, ORDER BY [LIMIT],
              aggregate functions}) && subquery predicate is not under "NOT IN"))
-        5. No execution method was already chosen (by a prepared statement).
+        6. No execution method was already chosen (by a prepared statement).
 
         (*) The subquery must be part of a SELECT statement. The current
              condition also excludes multi-table update statements.
 
-        We have to determine whether we will perform subquery materialization
-        before calling the IN=>EXISTS transformation, so that we know whether to
+        Determine whether we will perform subquery materialization before
+        calling the IN=>EXISTS transformation, so that we know whether to
         perform the whole transformation or only that part of it which wraps
         Item_in_subselect in an Item_in_optimizer.
       */
@@ -211,11 +215,14 @@ int check_and_do_in_subquery_rewrites(JO
           select_lex->master_unit()->first_select()->leaf_tables &&     // 3
           thd->lex->sql_command == SQLCOM_SELECT &&                     // *
           select_lex->outer_select()->leaf_tables &&                    // 3A
-          subquery_types_allow_materialization(in_subs))
+          subquery_types_allow_materialization(in_subs) &&
+          // psergey-todo: duplicated_subselect_card_check: where it's done?
+          (in_subs->is_top_level_item() ||
+           optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) ||
+           optimizer_flag(thd, OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN)) &&//4
+          !in_subs->is_correlated &&                                  // 5
+          in_subs->exec_method == Item_in_subselect::NOT_TRANSFORMED) // 6
       {
-        // psergey-todo: duplicated_subselect_card_check: where it's done?
-        if (!in_subs->is_correlated &&                                  // 4
-            in_subs->exec_method == Item_in_subselect::NOT_TRANSFORMED) // 5
           in_subs->exec_method= Item_in_subselect::MATERIALIZATION;
       }
 

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: timour@xxxxxxxxxxxx-20100311214331-kw8ng8aiy6h60vai
# target_branch: file:///home/tsk/mprog/src/5.3-mwl68/
# testament_sha1: 4f872a00f00f0251e792c8c4e0455ea224e42d5f
# timestamp: 2010-03-11 23:43:40 +0200
# source_branch: file:///home/tsk/mprog/src/5.3-subqueries/
# base_revision_id: timour@xxxxxxxxxxxx-20100309103615-\
#   dzmm6xt7ye5xfs25
# 
# Begin bundle
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
TDogwIqn5Ul9yp1fJzwOXlFFFOaixVCixVNQE4GzoNPKVgWQohDuDnzGJRL/OX540wEwVFfcr1iW
y/G+tYooUKJlPGMJROSkPgyfi+c0Ky22Xqs8GVUKEtQVJtiudyDPITBWaHNJoIjIQECAMyK5nRNO
WgMeZXWwhfpQVN0faRuCpBTDfKW2fyKJK8FUopPzu3SIlbeJHR2zuVSFINTO2FJJtQUE0IMpXxQZ
J30lOdZHZwl8vl8tkspqlTXSQzbX3nwYXLVwkqZ62L5Nfg9XY7v776UiR9rP0JqGH11PvgiaiDJY
zWdhKPBg5yIsN/JBn+/63bHr3Mn36yteye7e8Xc6JC3Q3VSSeMcZk6FPcmtwXIls5tjE2ubi1zU5
NLLmu2OmCQs4tjZ4uKo6qR0faYSEr+8zyRFTe02kOGLo833eKrk6E1ktcYkR+dEuzukb1u9o+HBj
FjiVSDR3vJqbXh50W6a1HBQwqY1WKxJZdfNqQyWsIlzWvdeXU4P0Z3jnWJ1blupY1djZtU2tK6I6
O5zXX1qfVVkkPJnd0rhE0drgzZmZSZnaebM79vXW37XoScfwwD/F3JFOFCQ8hFZJAA==