← Back to team overview

maria-developers team mailing list archive

bzr commit into file:///home/tsk/mprog/src/5.3-mwl68-merge.base-mwl68/ branch (timour:2766)

 

#At file:///home/tsk/mprog/src/5.3-mwl68-merge.base-mwl68/ based on revid:timour@xxxxxxxxxxxx-20100309101406-xygkt2sgftvjvevg

 2766 timour@xxxxxxxxxxxx	2010-03-09 [merge]
      MWL#68 Subquery optimization: Efficient NOT IN execution with NULLs
      
      Automerge with 5.3-subqueries

    modified:
      mysql-test/r/join_cache.result
      mysql-test/r/subselect_sj.result
      mysql-test/r/subselect_sj2.result
      mysql-test/r/subselect_sj2_jcl6.result
      mysql-test/r/subselect_sj_jcl6.result
      mysql-test/suite/pbxt/r/group_min_max.result
      mysql-test/suite/pbxt/r/subselect.result
      mysql-test/t/join_cache.test
      mysql-test/t/subselect_sj.test
      mysql-test/t/subselect_sj2.test
      mysql-test/t/subselect_sj_jcl6.test
      sql/item.cc
      sql/opt_subselect.cc
      sql/sql_join_cache.cc
      sql/sql_select.cc
      sql/sql_select.h
=== modified file 'mysql-test/r/join_cache.result'
--- a/mysql-test/r/join_cache.result	2010-02-11 21:59:32 +0000
+++ b/mysql-test/r/join_cache.result	2010-03-06 19:14:55 +0000
@@ -4142,3 +4142,46 @@ c1	c2	c1	c2	LENGTH(t2.c1)	LENGTH(t2.c2)
 2	2	tt	uu	2	2
 set join_cache_level=default;
 DROP TABLE t1,t2;
+#
+# Bug #51092: linked join buffer is used for a 3-way cross join query 
+#             that selects only records of the first table
+#
+create table t1 (a int, b int);
+insert into t1 values (1,1),(2,2);
+create table t2 (a int, b int);
+insert into t2 values (1,1),(2,2);
+create table t3 (a int, b int);
+insert into t3 values (1,1),(2,2);
+explain select t1.* from t1,t2,t3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	Using join buffer
+1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	2	Using join buffer
+select t1.* from t1,t2,t3;
+a	b
+1	1
+2	2
+1	1
+2	2
+1	1
+2	2
+1	1
+2	2
+set join_cache_level=2;
+explain select t1.* from t1,t2,t3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	Using join buffer
+1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	2	Using join buffer
+select t1.* from t1,t2,t3;
+a	b
+1	1
+2	2
+1	1
+2	2
+1	1
+2	2
+1	1
+2	2
+set join_cache_level=default;
+drop table t1,t2,t3;

=== modified file 'mysql-test/r/subselect_sj.result'
--- a/mysql-test/r/subselect_sj.result	2010-02-21 07:53:12 +0000
+++ b/mysql-test/r/subselect_sj.result	2010-02-24 11:33:42 +0000
@@ -824,3 +824,50 @@ a
 3
 2
 drop table t1, t2, t3;
+# 
+# Bug#49198 Wrong result for second call of procedure
+#           with view in subselect.
+# 
+CREATE TABLE t1 (t1field integer, primary key (t1field));
+CREATE TABLE t2 (t2field integer, primary key (t2field));
+CREATE TABLE t3 (t3field integer, primary key (t3field));
+CREATE VIEW v2 AS SELECT * FROM t2;
+CREATE VIEW v3 AS SELECT * FROM t3;
+INSERT INTO t1 VALUES(1),(2);
+INSERT INTO t2 VALUES(1),(2);
+INSERT INTO t3 VALUES(1),(2);
+PREPARE stmt FROM
+"
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2);
+";
+EXECUTE stmt;
+t1field
+1
+2
+EXECUTE stmt;
+t1field
+1
+2
+PREPARE stmt FROM
+"
+EXPLAIN
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2)
+  AND t1field IN (SELECT * FROM v3)
+";
+EXECUTE stmt;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
+1	PRIMARY	t2	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+EXECUTE stmt;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
+1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	SIMPLE	t3	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+DROP TABLE t1, t2, t3;
+DROP VIEW v2, v3;
+# End of Bug#49198

=== modified file 'mysql-test/r/subselect_sj2.result'
--- a/mysql-test/r/subselect_sj2.result	2010-02-17 10:47:55 +0000
+++ b/mysql-test/r/subselect_sj2.result	2010-03-07 15:41:45 +0000
@@ -264,8 +264,8 @@ 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);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t0	ALL	NULL	NULL	NULL	NULL	10	
-1	PRIMARY	t1	index	NULL	a	5	NULL	10	Using index; Start temporary; Using join buffer
+1	PRIMARY	t0	ALL	NULL	NULL	NULL	NULL	10	Start temporary
+1	PRIMARY	t1	index	NULL	a	5	NULL	10	Using index; Using join buffer
 1	PRIMARY	t2	ref	a	a	5	test.t1.a	1	Using index
 1	PRIMARY	t3	ref	a	a	5	test.t1.a	1	Using where; Using index; End temporary
 drop table t0, t1,t2,t3;

=== modified file 'mysql-test/r/subselect_sj2_jcl6.result'
--- a/mysql-test/r/subselect_sj2_jcl6.result	2010-02-17 10:47:55 +0000
+++ b/mysql-test/r/subselect_sj2_jcl6.result	2010-03-07 15:41:45 +0000
@@ -268,8 +268,8 @@ 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);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t0	ALL	NULL	NULL	NULL	NULL	10	
-1	PRIMARY	t1	index	NULL	a	5	NULL	10	Using index; Start temporary; Using join buffer
+1	PRIMARY	t0	ALL	NULL	NULL	NULL	NULL	10	Start temporary
+1	PRIMARY	t1	index	NULL	a	5	NULL	10	Using index; Using join buffer
 1	PRIMARY	t2	ref	a	a	5	test.t1.a	1	Using index
 1	PRIMARY	t3	ref	a	a	5	test.t1.a	1	Using where; Using index; End temporary
 drop table t0, t1,t2,t3;
@@ -421,20 +421,23 @@ 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);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	t0	ALL	NULL	NULL	NULL	NULL	5	100.00	
-1	PRIMARY	t1	ref	a	a	5	test.t0.a	1	100.00	Start temporary; Using join buffer
+1	PRIMARY	t0	ALL	NULL	NULL	NULL	NULL	5	100.00	Start temporary
+1	PRIMARY	t1	ref	a	a	5	test.t0.a	1	100.00	Using join buffer
 1	PRIMARY	t2	eq_ref	PRIMARY	PRIMARY	4	test.t0.a	1	100.00	Using where; End temporary; Using join buffer
 Warnings:
 Note	1276	Field or reference 'test.t0.a' of SELECT #2 was resolved in SELECT #1
 Note	1003	select `test`.`t0`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) join `test`.`t0` where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t0`.`a`) and (`test`.`t2`.`a` = `test`.`t0`.`a`))
 update t1 set a=3, b=11 where a=4;
 update t2 set b=11 where a=3;
-
+# Not anymore:
 # 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);
 a
 0
+1
+2
+3
 drop table t0, t1, t2;
 CREATE TABLE t1 (
 id int(11) NOT NULL,
@@ -713,9 +716,9 @@ c2 in (select 1 from t3, t2) and
 c1 in (select convert(c6,char(1)) from t2);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	1	Using where
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	1	
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	1	Using where
-1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	FirstMatch(t2)
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	1	Using join buffer
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	1	Using where; Using join buffer
+1	PRIMARY	t3	ALL	NULL	NULL	NULL	NULL	2	FirstMatch(t2); Using join buffer
 drop table t2, t3;
 set join_cache_level=default;
 show variables like 'join_cache_level';

=== modified file 'mysql-test/r/subselect_sj_jcl6.result'
--- a/mysql-test/r/subselect_sj_jcl6.result	2010-02-21 07:53:12 +0000
+++ b/mysql-test/r/subselect_sj_jcl6.result	2010-03-07 15:41:45 +0000
@@ -374,8 +374,8 @@ WHERE PNUM IN
 (SELECT PNUM  FROM PROJ));
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	STAFF	ALL	NULL	NULL	NULL	NULL	5	
-1	PRIMARY	PROJ	ALL	NULL	NULL	NULL	NULL	6	
-1	PRIMARY	WORKS	ALL	NULL	NULL	NULL	NULL	12	Using where; FirstMatch(STAFF)
+1	PRIMARY	PROJ	ALL	NULL	NULL	NULL	NULL	6	Using join buffer
+1	PRIMARY	WORKS	ALL	NULL	NULL	NULL	NULL	12	Using where; FirstMatch(STAFF); Using join buffer
 SELECT EMPNUM, EMPNAME
 FROM STAFF
 WHERE EMPNUM IN
@@ -828,6 +828,84 @@ a
 3
 2
 drop table t1, t2, t3;
+# 
+# Bug#49198 Wrong result for second call of procedure
+#           with view in subselect.
+# 
+CREATE TABLE t1 (t1field integer, primary key (t1field));
+CREATE TABLE t2 (t2field integer, primary key (t2field));
+CREATE TABLE t3 (t3field integer, primary key (t3field));
+CREATE VIEW v2 AS SELECT * FROM t2;
+CREATE VIEW v3 AS SELECT * FROM t3;
+INSERT INTO t1 VALUES(1),(2);
+INSERT INTO t2 VALUES(1),(2);
+INSERT INTO t3 VALUES(1),(2);
+PREPARE stmt FROM
+"
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2);
+";
+EXECUTE stmt;
+t1field
+1
+2
+EXECUTE stmt;
+t1field
+1
+2
+PREPARE stmt FROM
+"
+EXPLAIN
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2)
+  AND t1field IN (SELECT * FROM v3)
+";
+EXECUTE stmt;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
+1	PRIMARY	t2	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+EXECUTE stmt;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index	PRIMARY	PRIMARY	4	NULL	2	Using index
+1	SIMPLE	t2	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+1	SIMPLE	t3	eq_ref	PRIMARY	PRIMARY	4	test.t1.t1field	1	Using index
+DROP TABLE t1, t2, t3;
+DROP VIEW v2, v3;
+# End of Bug#49198
+#
+# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
+#
+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;
+UPDATE t1 SET a=3, b=11 WHERE a=4;
+UPDATE t2 SET b=11 WHERE a=3;
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='firstmatch=off';
+The following should use a join order of t0,t1,t2, with DuplicateElimination:
+explain
+SELECT * FROM t0 WHERE t0.a IN 
+(SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t0	ALL	NULL	NULL	NULL	NULL	5	Start temporary
+1	PRIMARY	t1	ref	a	a	5	test.t0.a	1	Using join buffer
+1	PRIMARY	t2	eq_ref	PRIMARY	PRIMARY	4	test.t0.a	1	Using where; End temporary; Using join buffer
+SELECT * FROM t0 WHERE t0.a IN 
+(SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+a
+0
+1
+2
+3
+set optimizer_switch=@save_optimizer_switch;
+drop table t0, t1, t2;
+# End
 set join_cache_level=default;
 show variables like 'join_cache_level';
 Variable_name	Value

=== modified file 'mysql-test/suite/pbxt/r/group_min_max.result'
--- a/mysql-test/suite/pbxt/r/group_min_max.result	2009-08-17 15:57:58 +0000
+++ b/mysql-test/suite/pbxt/r/group_min_max.result	2010-02-23 09:22:02 +0000
@@ -2257,7 +2257,7 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer WHE
 a IN (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1_outer	index	NULL	a	10	NULL	15	Using where; Using index
-2	DEPENDENT SUBQUERY	t1	index	NULL	a	10	NULL	1	Using index
+2	SUBQUERY	t1	index	NULL	a	10	NULL	15	Using index
 EXPLAIN SELECT 1 FROM t1 AS t1_outer GROUP BY a HAVING 
 a > (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra

=== modified file 'mysql-test/suite/pbxt/r/subselect.result'
--- a/mysql-test/suite/pbxt/r/subselect.result	2009-12-16 09:28:51 +0000
+++ b/mysql-test/suite/pbxt/r/subselect.result	2010-02-23 09:22:02 +0000
@@ -1293,31 +1293,31 @@ a
 4
 explain extended select * from t2 where t2.a in (select a from t1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	t2	index	NULL	PRIMARY	4	NULL	4	100.00	Using where; Using index
-2	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	100.00	Using index
+1	PRIMARY	t2	index	PRIMARY	PRIMARY	4	NULL	4	100.00	Using index
+1	PRIMARY	t1	index	PRIMARY	PRIMARY	4	NULL	4	75.00	Using where; Using index; Using join buffer
 Warnings:
-Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY)))
+Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)
 select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
 a
 2
 4
 explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	t2	index	NULL	PRIMARY	4	NULL	4	100.00	Using where; Using index
-2	DEPENDENT SUBQUERY	t1	unique_subquery	PRIMARY	PRIMARY	4	func	1	100.00	Using where
+1	PRIMARY	t2	index	PRIMARY	PRIMARY	4	NULL	4	100.00	Using index
+1	PRIMARY	t1	ALL	PRIMARY	NULL	NULL	NULL	4	75.00	Using where; Using join buffer
 Warnings:
-Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
+Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
 select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
 a
 2
 3
 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	t2	index	NULL	PRIMARY	4	NULL	4	100.00	Using where; Using index
-2	DEPENDENT SUBQUERY	t1	eq_ref	PRIMARY	PRIMARY	4	func	1	100.00	
-2	DEPENDENT SUBQUERY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t1.b	1	100.00	Using index
+1	PRIMARY	t2	index	PRIMARY	PRIMARY	4	NULL	4	100.00	Using index
+1	PRIMARY	t1	ALL	PRIMARY	NULL	NULL	NULL	4	75.00	Using where; Using join buffer
+1	PRIMARY	t3	eq_ref	PRIMARY	PRIMARY	4	test.t1.b	1	100.00	Using index
 Warnings:
-Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select 1 AS `Not_used` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))
+Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`))
 drop table t1, t2, t3;
 create table t1 (a int, b int, index a (a,b));
 create table t2 (a int, index a (a));
@@ -1332,31 +1332,31 @@ a
 4
 explain extended select * from t2 where t2.a in (select a from t1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	t2	index	NULL	a	5	NULL	4	100.00	Using where; Using index
-2	DEPENDENT SUBQUERY	t1	index_subquery	a	a	5	func	1	100.00	Using index
+1	PRIMARY	t2	index	a	a	5	NULL	4	100.00	Using index
+1	PRIMARY	t1	ref	a	a	5	test.t2.a	1	100.00	Using index; FirstMatch(t2)
 Warnings:
-Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a)))
+Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`t2`.`a`)
 select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
 a
 2
 4
 explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	t2	index	NULL	a	5	NULL	4	100.00	Using where; Using index
-2	DEPENDENT SUBQUERY	t1	index_subquery	a	a	5	func	1	100.00	Using index; Using where
+1	PRIMARY	t2	index	a	a	5	NULL	4	100.00	Using index
+1	PRIMARY	t1	ref	a	a	5	test.t2.a	1	100.00	Using where; Using index; FirstMatch(t2)
 Warnings:
-Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
+Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
 select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
 a
 2
 3
 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	t2	index	NULL	a	5	NULL	4	100.00	Using where; Using index
-2	DEPENDENT SUBQUERY	t1	ref	a	a	5	func	1	100.00	Using index
-2	DEPENDENT SUBQUERY	t3	ref	a	a	5	test.t1.b	1	100.00	Using index
+1	PRIMARY	t2	index	a	a	5	NULL	4	100.00	Using index
+1	PRIMARY	t1	ref	a	a	5	test.t2.a	1	100.00	Using index
+1	PRIMARY	t3	ref	a	a	5	test.t1.b	1	100.00	Using index; FirstMatch(t2)
 Warnings:
-Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select 1 AS `Not_used` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))
+Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`))
 insert into t1 values (3,31);
 select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
 a
@@ -1369,10 +1369,10 @@ a
 4
 explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	t2	index	NULL	a	5	NULL	4	100.00	Using where; Using index
-2	DEPENDENT SUBQUERY	t1	index_subquery	a	a	5	func	1	100.00	Using index; Using where
+1	PRIMARY	t2	index	a	a	5	NULL	4	100.00	Using index
+1	PRIMARY	t1	ref	a	a	5	test.t2.a	1	100.00	Using where; Using index; FirstMatch(t2)
 Warnings:
-Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
+Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
 drop table t1, t2, t3;
 create table t1 (a int, b int);
 create table t2 (a int, b int);
@@ -2823,10 +2823,10 @@ Warnings:
 Note	1003	select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
 explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
-1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	8	100.00	Using where
-2	DEPENDENT SUBQUERY	t2	ALL	NULL	NULL	NULL	NULL	9	100.00	Using where
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	8	100.00	
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	9	100.00	Using where; FirstMatch(t1)
 Warnings:
-Note	1003	select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where ((`test`.`t2`.`flag` = 'N') and (<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) and (<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`))))
+Note	1003	select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`two` = `test`.`t1`.`two`) and (`test`.`t2`.`one` = `test`.`t1`.`one`) and (`test`.`t2`.`flag` = 'N'))
 explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	8	100.00	
@@ -3412,7 +3412,7 @@ EXPLAIN
 SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	9	Using where
-2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	9	Using temporary; Using filesort
+2	SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	9	Using temporary; Using filesort
 ALTER TABLE t1 ADD INDEX(a);
 SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
 a	b
@@ -3423,7 +3423,7 @@ EXPLAIN
 SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	9	Using where
-2	DEPENDENT SUBQUERY	t1	index	NULL	a	8	NULL	1	Using filesort
+2	SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	9	Using temporary; Using filesort
 DROP TABLE t1;
 create table t1( f1 int,f2 int);
 insert into t1 values (1,1),(2,2);
@@ -4213,8 +4213,8 @@ CREATE INDEX I1 ON t1 (a);
 CREATE INDEX I2 ON t1 (b);
 EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	2	Using where
-2	DEPENDENT SUBQUERY	t1	index_subquery	I1	I1	2	func	1	Using index; Using where
+1	PRIMARY	t1	index	I1	I1	2	NULL	2	Using index; LooseScan
+1	PRIMARY	t1	ref	I2	I2	13	test.t1.a	1	Using where
 SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
 a	b
 CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
@@ -4223,15 +4223,15 @@ CREATE INDEX I1 ON t2 (a);
 CREATE INDEX I2 ON t2 (b);
 EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	2	Using where
-2	DEPENDENT SUBQUERY	t2	index_subquery	I1	I1	4	func	1	Using index; Using where
+1	PRIMARY	t2	index	I1	I1	4	NULL	2	Using index; LooseScan
+1	PRIMARY	t2	ref	I2	I2	13	test.t2.a	1	Using where
 SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
 a	b
 EXPLAIN
 SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	2	Using where
-2	DEPENDENT SUBQUERY	t1	index_subquery	I1	I1	2	func	1	Using index; Using where
+1	PRIMARY	t1	index	I1	I1	2	NULL	2	Using where; Using index; LooseScan
+1	PRIMARY	t1	ref	I2	I2	13	test.t1.a	1	Using where
 SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
 a	b
 DROP TABLE t1,t2;

=== modified file 'mysql-test/t/join_cache.test'
--- a/mysql-test/t/join_cache.test	2009-12-21 02:26:15 +0000
+++ b/mysql-test/t/join_cache.test	2010-03-06 19:14:55 +0000
@@ -1823,3 +1823,27 @@ SELECT t1.*, t2.*, LENGTH(t2.c1), LENGTH
 set join_cache_level=default;
 
 DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #51092: linked join buffer is used for a 3-way cross join query 
+--echo #             that selects only records of the first table
+--echo #
+
+create table t1 (a int, b int);
+insert into t1 values (1,1),(2,2);
+create table t2 (a int, b int);
+insert into t2 values (1,1),(2,2);
+create table t3 (a int, b int);
+insert into t3 values (1,1),(2,2);
+
+explain select t1.* from t1,t2,t3;
+select t1.* from t1,t2,t3; 
+
+set join_cache_level=2;
+
+explain select t1.* from t1,t2,t3;
+select t1.* from t1,t2,t3; 
+
+set join_cache_level=default;
+
+drop table t1,t2,t3;

=== modified file 'mysql-test/t/subselect_sj.test'
--- a/mysql-test/t/subselect_sj.test	2010-02-21 07:53:12 +0000
+++ b/mysql-test/t/subselect_sj.test	2010-02-24 11:33:42 +0000
@@ -728,3 +728,45 @@ where a in (select c from t2 where d >= 
 
 drop table t1, t2, t3;
 
+--echo # 
+--echo # Bug#49198 Wrong result for second call of procedure
+--echo #           with view in subselect.
+--echo # 
+
+CREATE TABLE t1 (t1field integer, primary key (t1field));
+CREATE TABLE t2 (t2field integer, primary key (t2field));
+CREATE TABLE t3 (t3field integer, primary key (t3field));
+
+CREATE VIEW v2 AS SELECT * FROM t2;
+CREATE VIEW v3 AS SELECT * FROM t3;
+
+INSERT INTO t1 VALUES(1),(2);
+INSERT INTO t2 VALUES(1),(2);
+INSERT INTO t3 VALUES(1),(2);
+
+PREPARE stmt FROM
+"
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2);
+";
+
+EXECUTE stmt;
+EXECUTE stmt;
+
+PREPARE stmt FROM
+"
+EXPLAIN
+SELECT t1field
+FROM t1
+WHERE t1field IN (SELECT * FROM v2)
+  AND t1field IN (SELECT * FROM v3)
+";
+
+EXECUTE stmt;
+EXECUTE stmt;
+
+DROP TABLE t1, t2, t3;
+DROP VIEW v2, v3;
+
+--echo # End of Bug#49198

=== modified file 'mysql-test/t/subselect_sj2.test'
--- a/mysql-test/t/subselect_sj2.test	2010-01-17 14:51:10 +0000
+++ b/mysql-test/t/subselect_sj2.test	2010-03-07 15:41:45 +0000
@@ -583,7 +583,7 @@ update t2 set b=11 where a=3;
 
 if (`select @@join_cache_level=6`)
 {
-  --echo 
+  --echo # Not anymore:
   --echo # The following query gives wrong result due to Bug#49129
 }
 select * from t0 where t0.a in 

=== modified file 'mysql-test/t/subselect_sj_jcl6.test'
--- a/mysql-test/t/subselect_sj_jcl6.test	2010-01-17 14:51:10 +0000
+++ b/mysql-test/t/subselect_sj_jcl6.test	2010-03-07 15:41:45 +0000
@@ -7,5 +7,33 @@ show variables like 'join_cache_level';
 
 --source t/subselect_sj.test
 
+--echo #
+--echo # BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
+--echo #
+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;
+UPDATE t1 SET a=3, b=11 WHERE a=4;
+UPDATE t2 SET b=11 WHERE a=3;
+
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='firstmatch=off';
+
+--echo The following should use a join order of t0,t1,t2, with DuplicateElimination:
+explain
+SELECT * FROM t0 WHERE t0.a IN 
+  (SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+
+SELECT * FROM t0 WHERE t0.a IN 
+  (SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
+
+set optimizer_switch=@save_optimizer_switch;
+drop table t0, t1, t2;
+
+--echo # End
+
 set join_cache_level=default;
 show variables like 'join_cache_level';

=== modified file 'sql/item.cc'
--- a/sql/item.cc	2010-02-21 06:32:23 +0000
+++ b/sql/item.cc	2010-02-24 11:33:42 +0000
@@ -6491,11 +6491,9 @@ void Item_outer_ref::fix_after_pullout(s
 
 void Item_ref::fix_after_pullout(st_select_lex *new_parent, Item **refptr)
 {
+  (*ref)->fix_after_pullout(new_parent, ref);
   if (depended_from == new_parent)
-  {
-    (*ref)->fix_after_pullout(new_parent, ref);
     depended_from= NULL;
-  }
 }
 
 

=== modified file 'sql/opt_subselect.cc'
--- a/sql/opt_subselect.cc	2010-02-19 21:55:57 +0000
+++ b/sql/opt_subselect.cc	2010-03-09 10:36:15 +0000
@@ -531,7 +531,6 @@ static bool replace_where_subcondition(J
     *expr= new_cond;
     if (do_fix_fields)
       new_cond->fix_fields(join->thd, expr);
-    join->select_lex->where= *expr;
     return FALSE;
   }
   
@@ -3031,10 +3030,24 @@ int setup_semijoin_dups_elimination(JOIN
           forwards, but do not destroy other duplicate elimination methods.
         */
         uint first_table= i;
+        uint join_cache_level= join->thd->variables.join_cache_level;
         for (uint j= i; j < i + pos->n_sj_tables; j++)
         {
-          if (join->best_positions[j].use_join_buffer && j <= no_jbuf_after)
+          /*
+            When we'll properly take join buffering into account during
+            join optimization, the below check should be changed to 
+            "if (join->best_positions[j].use_join_buffer && 
+                 j <= no_jbuf_after)".
+            For now, use a rough criteria:
+          */
+          JOIN_TAB *js_tab=join->join_tab + j; 
+          if (j != join->const_tables && js_tab->use_quick != 2 &&
+              j <= no_jbuf_after &&
+              ((js_tab->type == JT_ALL && join_cache_level != 0) ||
+               (join_cache_level > 4 && (tab->type == JT_REF || 
+                                         tab->type == JT_EQ_REF))))
           {
+            /* Looks like we'll be using join buffer */
             first_table= join->const_tables;
             break;
           }
@@ -3112,7 +3125,12 @@ int setup_semijoin_dups_elimination(JOIN
         JOIN_TAB *j, *jump_to= tab-1;
         for (j= tab; j != tab + pos->n_sj_tables; j++)
         {
-          if (!tab->emb_sj_nest)
+          /*
+            NOTE: this loop probably doesn't do the right thing for the case 
+            where FirstMatch's duplicate-generating range is interleaved with
+            "unrelated" tables (as specified in WL#3750, section 2.2).
+          */
+          if (!j->emb_sj_nest)
             jump_to= tab;
           else
           {

=== modified file 'sql/sql_join_cache.cc'
--- a/sql/sql_join_cache.cc	2010-02-15 21:53:06 +0000
+++ b/sql/sql_join_cache.cc	2010-03-07 15:41:45 +0000
@@ -31,6 +31,8 @@
 #include "sql_select.h"
 #include "opt_subselect.h"
 
+#define NO_MORE_RECORDS_IN_BUFFER  (uint)(-1)
+
 
 /*****************************************************************************
  *  Join cache module
@@ -407,8 +409,10 @@ void JOIN_CACHE::set_constants()
     However at this moment we don't know whether we have referenced fields for
     the cache or not. Later when a referenced field is registered for the cache
     we adjust the value of the flag 'with_length'.
-  */        
-  with_length= is_key_access() || with_match_flag;
+  */ 
+  with_length= is_key_access() || 
+               join_tab->is_inner_table_of_semi_join_with_first_match() ||
+               join_tab->is_inner_table_of_outer_join();
   /* 
      At this moment we don't know yet the value of 'referenced_fields',
      but in any case it can't be greater than the value of 'fields'.
@@ -604,7 +608,12 @@ int JOIN_CACHE_BKA::init()
       copy_end= cache->field_descr+cache->fields;
       for (copy= cache->field_descr+cache->flag_fields; copy < copy_end; copy++)
       {
-        if (copy->field->table == tab->table &&
+        /*
+          (1) - when we store rowids for DuplicateWeedout, they have
+                copy->field==NULL
+        */
+        if (copy->field &&  // (1)
+            copy->field->table == tab->table &&
             bitmap_is_set(key_read_set, copy->field->field_index))
         {
           *copy_ptr++= copy; 
@@ -1235,7 +1244,7 @@ bool JOIN_CACHE::get_record()
     prev_rec_ptr= prev_cache->get_rec_ref(pos);
   }
   curr_rec_pos= pos;
-  if (!(res= read_all_record_fields() == 0))
+  if (!(res= read_all_record_fields() == NO_MORE_RECORDS_IN_BUFFER))
   {
     pos+= referenced_fields*size_of_fld_ofs;
     if (prev_cache)
@@ -1304,7 +1313,7 @@ bool JOIN_CACHE::get_match_flag_by_pos(u
     uchar *prev_rec_ptr= prev_cache->get_rec_ref(rec_ptr);
     return prev_cache->get_match_flag_by_pos(prev_rec_ptr);
   } 
-  DBUG_ASSERT(1);
+  DBUG_ASSERT(0);
   return FALSE;
 }
 
@@ -1324,7 +1333,8 @@ bool JOIN_CACHE::get_match_flag_by_pos(u
     read data. 
 
   RETURN
-    length of the data read from the join buffer
+    (-1) - if there is no more records in the join buffer
+    length of the data read from the join buffer - otherwise
 */
 
 uint JOIN_CACHE::read_all_record_fields()
@@ -1332,7 +1342,7 @@ uint JOIN_CACHE::read_all_record_fields(
   uchar *init_pos= pos;
   
   if (pos > last_rec_pos || !records)
-    return 0;
+    return NO_MORE_RECORDS_IN_BUFFER;
 
   /* First match flag, read null bitmaps and null_row flag for each table */
   read_flag_fields();
@@ -1538,12 +1548,12 @@ bool JOIN_CACHE::read_referenced_field(C
 
 bool JOIN_CACHE::skip_record_if_match()
 {
-  DBUG_ASSERT(with_match_flag && with_length);
+  DBUG_ASSERT(with_length);
   uint offset= size_of_rec_len;
   if (prev_cache)
     offset+= prev_cache->get_size_of_rec_offset();
   /* Check whether the match flag is on */
-  if (test(*(pos+offset)))
+  if (get_match_flag_by_pos(pos+offset))
   {
     pos+= size_of_rec_len + get_rec_length(pos);
     return TRUE;

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2010-02-19 21:55:57 +0000
+++ b/sql/sql_select.cc	2010-03-09 10:36:15 +0000
@@ -5635,7 +5635,11 @@ void calc_used_field_length(THD *thd, JO
     uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
 			     (join_tab->table->s->reclength-rec_length));
     rec_length+=(uint) max(4,blob_length);
-  }
+  }  
+  /*
+    psergey-todo: why we don't count here rowid that we might need to store
+    when using DuplicateElimination?
+  */
   join_tab->used_fields=fields;
   join_tab->used_fieldlength=rec_length;
   join_tab->used_blobs=blobs;
@@ -6355,10 +6359,17 @@ make_outerjoin_info(JOIN *join)
       }
       if (!tab->first_inner)  
         tab->first_inner= nested_join->first_nested;
+      if (tab->table->reginfo.not_exists_optimize)
+        tab->first_inner->table->reginfo.not_exists_optimize= 1;         
       if (++nested_join->counter < nested_join->n_tables)
         break;
       /* Table tab is the last inner table for nested join. */
       nested_join->first_nested->last_inner= tab;
+      if (tab->first_inner->table->reginfo.not_exists_optimize)
+      {
+        for (JOIN_TAB *join_tab= tab->first_inner; join_tab <= tab; join_tab++)
+          join_tab->table->reginfo.not_exists_optimize= 1;
+      } 
     }
   }
   DBUG_VOID_RETURN;
@@ -7112,18 +7123,14 @@ uint check_join_cache_usage(JOIN_TAB *ta
   if (tab->use_quick == 2)
     goto no_join_cache;
   /*
-    Use join cache with FirstMatch semi-join strategy only when semi-join
-    contains only one table.
-  */
-  if (tab->is_inner_table_of_semi_join_with_first_match() &&
-      !tab->is_single_inner_of_semi_join_with_first_match())
-    goto no_join_cache;
-  /*
     Non-linked join buffers can't guarantee one match
   */
-  if (force_unlinked_cache && 
-      (tab->is_inner_table_of_outer_join() &&
-       !tab->is_single_inner_of_outer_join()))
+   if (force_unlinked_cache && 
+       (!tab->type == JT_ALL || cache_level <= 4) && 
+       ((tab->is_inner_table_of_semi_join_with_first_match() &&
+         !tab->is_single_inner_of_semi_join_with_first_match()) ||
+        (tab->is_inner_table_of_outer_join() &&
+         !tab->is_single_inner_of_outer_join())))
     goto no_join_cache;
 
   /*

=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h	2010-02-15 21:53:06 +0000
+++ b/sql/sql_select.h	2010-03-05 18:54:48 +0000
@@ -321,8 +321,8 @@ typedef struct st_join_table {
   }
   bool check_only_first_match()
   {
-    return  last_sj_inner_tab == this ||
-           (first_inner && first_inner->last_inner == this &&
+    return is_inner_table_of_semi_join_with_first_match() ||
+           (is_inner_table_of_outer_join() &&
             table->reginfo.not_exists_optimize);
   }
   bool is_last_inner_table()

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: timour@xxxxxxxxxxxx-20100309103615-dzmm6xt7ye5xfs25
# target_branch: file:///home/tsk/mprog/src/5.3-mwl68-merge.base-\
#   mwl68/
# testament_sha1: 0f4ddb7e490a4ea925fe2a336498bdf3beb76a71
# timestamp: 2010-03-09 12:36:23 +0200
# source_branch: file:///home/tsk/mprog/src/5.3-subqueries/
# base_revision_id: timour@xxxxxxxxxxxx-20100309101406-\
#   xygkt2sgftvjvevg
# 
# Begin bundle
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