Commit 1aede4d1 authored by Sergey Petrunya's avatar Sergey Petrunya

Merge

parents a853c7dd ff960f43
......@@ -123,14 +123,14 @@ DOCID DOCNAME DOCTYPEID FOLDERID AUTHOR CREATED TITLE SUBTITLE DOCABSTRACT PUBLI
c373e9f5ad07993f3859444553544200 Last Discussion c373e9f5ad079174ff17444553544200 c373e9f5ad0796c0eca4444553544200 Goldilocks 2003-06-09 11:21:06 Title: Last Discussion NULL Setting new abstract and keeping doc checked out 2003-06-09 10:51:26 2003-06-09 10:51:26 NULL NULL NULL 03eea05112b845949f3fd03278b5fe43 2003-06-09 11:21:06 admin 0 NULL Discussion NULL NULL
EXPLAIN SELECT t2.*, t4.DOCTYPENAME, t1.CONTENTSIZE,t1.MIMETYPE FROM t2 INNER JOIN t4 ON t2.DOCTYPEID = t4.DOCTYPEID LEFT OUTER JOIN t1 ON t2.DOCID = t1.DOCID WHERE t2.FOLDERID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t3.FOLDERNAME = 'Level1') AND t3.FOLDERNAME = 'Level2') AND t3.FOLDERNAME = 'Level3') AND t3.FOLDERNAME = 'CopiedFolder') AND t3.FOLDERNAME = 'Movie Reviews') AND t2.DOCNAME = 'Last Discussion';
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL DDOCTYPEID_IDX NULL NULL NULL 9 Using where
1 PRIMARY t3 ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX CMFLDRPARNT_IDX 35 const 6 Using index condition; Using where
1 PRIMARY t3 ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX CMFLDRPARNT_IDX 35 test.t3.FOLDERID 1 Using where
1 PRIMARY t3 ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX CMFLDRPARNT_IDX 35 test.t3.FOLDERID 1 Using where
1 PRIMARY t3 ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX CMFLDRPARNT_IDX 35 test.t3.FOLDERID 1 Using where
1 PRIMARY t3 ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX CMFLDRPARNT_IDX 35 test.t3.FOLDERID 1 Using where
1 PRIMARY t2 ALL DDOCTYPEID_IDX,DFOLDERID_IDX NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 34 test.t2.DOCID 1
1 PRIMARY t4 eq_ref PRIMARY PRIMARY 34 test.t2.DOCTYPEID 1
2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 func 1 Using where
2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
drop table t1, t2, t3, t4;
CREATE TABLE t1 (a int(10) , PRIMARY KEY (a)) Engine=InnoDB;
INSERT INTO t1 VALUES (1),(2);
......
......@@ -1200,33 +1200,33 @@ EXPLAIN
SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1)
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
c1 c1
EXPLAIN
SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1)
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
c1 c1
EXPLAIN
SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1)
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2);
c1 c1 c1
EXPLAIN
SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t4 index NULL PRIMARY 3 NULL 2 Using index
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch
1 PRIMARY t4 index NULL PRIMARY 3 NULL 2 Using index; Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2);
c1 c1
drop table t1, t2, t3, t4;
......
......@@ -1277,9 +1277,9 @@ CREATE VIEW v1 AS SELECT 1;
EXPLAIN
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived3> system NULL NULL NULL NULL 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
a a
......@@ -1358,4 +1358,161 @@ f10 f11
0 0
set optimizer_switch=@tmp_751484;
drop table t1, t3;
#
# BUG#795530 Wrong result with subquery semijoin materialization and outer join
# Simplified testcase that uses DuplicateElimination
#
create table t1 (a int);
create table t2 (a int, b char(10));
insert into t1 values (1),(2);
insert into t2 values (1, 'one'), (3, 'three');
create table t3 (b char(10));
insert into t3 values('three'),( 'four');
insert into t3 values('three'),( 'four');
insert into t3 values('three'),( 'four');
insert into t3 values('three'),( 'four');
explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where; End temporary; Using join buffer (flat, BNL join)
select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
b
drop table t1, t2, t3;
#
# BUG#600958 RQG: Crash in optimize_semijoin_nests
#
CREATE TABLE t1 (
pk int(11) NOT NULL AUTO_INCREMENT,
col_int_key int(11) DEFAULT NULL,
col_date_key date DEFAULT NULL,
col_varchar_key varchar(1) DEFAULT NULL,
PRIMARY KEY (pk),
KEY col_int_key (col_int_key),
KEY col_date_key (col_date_key),
KEY col_varchar_key (col_varchar_key,col_int_key)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
INSERT INTO t1 VALUES (10,8,'2002-02-21',NULL);
CREATE TABLE t2 (
pk int(11) NOT NULL AUTO_INCREMENT,
col_int_key int(11) DEFAULT NULL,
col_date_key date DEFAULT NULL,
col_varchar_key varchar(1) DEFAULT NULL,
PRIMARY KEY (pk),
KEY col_int_key (col_int_key),
KEY col_date_key (col_date_key),
KEY col_varchar_key (col_varchar_key,col_int_key)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
INSERT INTO t2 VALUES (1,7,'1900-01-01','f');
SELECT col_date_key FROM t1
WHERE 5 IN (
SELECT SUBQUERY3_t1 .col_int_key
FROM t2 SUBQUERY3_t1
LEFT JOIN t1 SUBQUERY3_t2 ON SUBQUERY3_t1 .col_varchar_key
);
col_date_key
drop table t2, t1;
#
# No BUG#: Duplicate weedout check is not done for outer joins
#
create table t1 (a int);
create table t2 (a int);
insert into t1 values (1),(1),(2),(2);
insert into t2 values (1);
create table t0 (a int);
insert into t0 values (1),(2);
set @tmp_20110622= @@optimizer_switch;
set optimizer_switch='firstmatch=off,loosescan=off,materialization=off';
# Check DuplicateWeedout + join buffer
explain
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
a
1
2
# Check DuplicateWeedout without join buffer
set @tmp_jcl_20110622= @@join_cache_level;
set join_cache_level= 0;
explain
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
a
1
2
# Check FirstMatch without join buffer:
set optimizer_switch='firstmatch=on';
explain
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; FirstMatch(t0)
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
a
1
2
#
# Now, check the same for multiple inner tables:
alter table t2 add b int;
update t2 set b=a;
create table t3 as select * from t2;
set optimizer_switch='firstmatch=off';
set join_cache_level= 0;
# DuplicateWeedout without join buffer
explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
a
1
2
set @@join_cache_level=@tmp_jcl_20110622;
# DuplicateWeedout + join buffer
explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
a
1
2
# Now, let the inner join side have a 'partial' match
select * from t3;
a b
1 1
insert into t3 values(2,2);
explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 1
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
a
1
2
set @@optimizer_switch=@tmp_20110622;
drop table t0, t1, t2, t3;
set @@optimizer_switch=@save_optimizer_switch;
......@@ -1285,9 +1285,9 @@ CREATE VIEW v1 AS SELECT 1;
EXPLAIN
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived3> system NULL NULL NULL NULL 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 2 Using where
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
a a
......@@ -1366,6 +1366,163 @@ f10 f11
0 0
set optimizer_switch=@tmp_751484;
drop table t1, t3;
#
# BUG#795530 Wrong result with subquery semijoin materialization and outer join
# Simplified testcase that uses DuplicateElimination
#
create table t1 (a int);
create table t2 (a int, b char(10));
insert into t1 values (1),(2);
insert into t2 values (1, 'one'), (3, 'three');
create table t3 (b char(10));
insert into t3 values('three'),( 'four');
insert into t3 values('three'),( 'four');
insert into t3 values('three'),( 'four');
insert into t3 values('three'),( 'four');
explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where; End temporary; Using join buffer (incremental, BNL join)
select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
b
drop table t1, t2, t3;
#
# BUG#600958 RQG: Crash in optimize_semijoin_nests
#
CREATE TABLE t1 (
pk int(11) NOT NULL AUTO_INCREMENT,
col_int_key int(11) DEFAULT NULL,
col_date_key date DEFAULT NULL,
col_varchar_key varchar(1) DEFAULT NULL,
PRIMARY KEY (pk),
KEY col_int_key (col_int_key),
KEY col_date_key (col_date_key),
KEY col_varchar_key (col_varchar_key,col_int_key)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
INSERT INTO t1 VALUES (10,8,'2002-02-21',NULL);
CREATE TABLE t2 (
pk int(11) NOT NULL AUTO_INCREMENT,
col_int_key int(11) DEFAULT NULL,
col_date_key date DEFAULT NULL,
col_varchar_key varchar(1) DEFAULT NULL,
PRIMARY KEY (pk),
KEY col_int_key (col_int_key),
KEY col_date_key (col_date_key),
KEY col_varchar_key (col_varchar_key,col_int_key)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
INSERT INTO t2 VALUES (1,7,'1900-01-01','f');
SELECT col_date_key FROM t1
WHERE 5 IN (
SELECT SUBQUERY3_t1 .col_int_key
FROM t2 SUBQUERY3_t1
LEFT JOIN t1 SUBQUERY3_t2 ON SUBQUERY3_t1 .col_varchar_key
);
col_date_key
drop table t2, t1;
#
# No BUG#: Duplicate weedout check is not done for outer joins
#
create table t1 (a int);
create table t2 (a int);
insert into t1 values (1),(1),(2),(2);
insert into t2 values (1);
create table t0 (a int);
insert into t0 values (1),(2);
set @tmp_20110622= @@optimizer_switch;
set optimizer_switch='firstmatch=off,loosescan=off,materialization=off';
# Check DuplicateWeedout + join buffer
explain
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary; Using join buffer (incremental, BNL join)
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
a
1
2
# Check DuplicateWeedout without join buffer
set @tmp_jcl_20110622= @@join_cache_level;
set join_cache_level= 0;
explain
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
a
1
2
# Check FirstMatch without join buffer:
set optimizer_switch='firstmatch=on';
explain
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; FirstMatch(t0)
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
a
1
2
#
# Now, check the same for multiple inner tables:
alter table t2 add b int;
update t2 set b=a;
create table t3 as select * from t2;
set optimizer_switch='firstmatch=off';
set join_cache_level= 0;
# DuplicateWeedout without join buffer
explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
a
1
2
set @@join_cache_level=@tmp_jcl_20110622;
# DuplicateWeedout + join buffer
explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary; Using join buffer (incremental, BNL join)
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
a
1
2
# Now, let the inner join side have a 'partial' match
select * from t3;
a b
1 1
insert into t3 values(2,2);
explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using join buffer (incremental, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (incremental, BNL join)
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
a
1
2
set @@optimizer_switch=@tmp_20110622;
drop table t0, t1, t2, t3;
set @@optimizer_switch=@save_optimizer_switch;
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
......
......@@ -365,7 +365,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b2` = `test`.`t3c`.`c2`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b1` = `test`.`t3c`.`c1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3c`.`c2` > '0'))
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b2` = `test`.`t3c`.`c2`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b1` = `test`.`t3c`.`c1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t1`.`a1` = `test`.`t3a`.`c1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3c`.`c2` > '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
......@@ -504,7 +504,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
Note 1276 Field or reference 'test.t1.a2' of SELECT #6 was resolved in SELECT #1
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t3c`.`c2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t3c`.`c1` = `test`.`t1`.`a1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))))
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t3c`.`c2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t3c`.`c1` = `test`.`t1`.`a1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t1`.`a1` = `test`.`t3a`.`c1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))))
explain extended
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
id select_type table type possible_keys key key_len ref rows filtered Extra
......@@ -636,7 +636,7 @@ from t1_16
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 20 func 1 100.00 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 20 func 1 100.00
2 SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where ((`test`.`t2_16`.`b1` > '0') and (`test`.`t1_16`.`a1` = substr(`test`.`t2_16`.`b1`,1,16)))
......@@ -751,7 +751,7 @@ from t1_512
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 517 func 1 100.00 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 517 func 1 100.00
2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where ((`test`.`t2_512`.`b1` > '0') and (`test`.`t1_512`.`a1` = substr(`test`.`t2_512`.`b1`,1,512)))
......@@ -847,7 +847,7 @@ from t1_1024
where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00
1 PRIMARY <subquery2> eq_ref NULL distinct_key 15 func,func 1 100.00 Using where
1 PRIMARY <subquery2> eq_ref NULL distinct_key 15 func,func 1 100.00
2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where ((`test`.`t2_1024`.`b1` > '0') and (`test`.`t1_1024`.`a1` = substr(`test`.`t2_1024`.`b1`,1,1024)))
......@@ -941,7 +941,7 @@ from t1_1025
where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00
1 PRIMARY <subquery2> eq_ref NULL distinct_key 15 func,func 1 100.00 Using where
1 PRIMARY <subquery2> eq_ref NULL distinct_key 15 func,func 1 100.00
2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where ((`test`.`t2_1025`.`b1` > '0') and (`test`.`t1_1025`.`a1` = substr(`test`.`t2_1025`.`b1`,1,1025)))
......@@ -1219,7 +1219,7 @@ insert into t1 values ('aa', 'aaaa');
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
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
select a,b from t1 where b in (select a from t1);
a b
......
......@@ -1242,5 +1242,133 @@ WHERE f11 IN (
set optimizer_switch=@tmp_751484;
drop table t1, t3;
#
--echo # BUG#795530 Wrong result with subquery semijoin materialization and outer join
--echo # Simplified testcase that uses DuplicateElimination
--echo #
create table t1 (a int);
create table t2 (a int, b char(10));
insert into t1 values (1),(2);
insert into t2 values (1, 'one'), (3, 'three');
create table t3 (b char(10));
insert into t3 values('three'),( 'four');
insert into t3 values('three'),( 'four');
insert into t3 values('three'),( 'four');
insert into t3 values('three'),( 'four');
explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
drop table t1, t2, t3;
--echo #
--echo # BUG#600958 RQG: Crash in optimize_semijoin_nests
--echo #
CREATE TABLE t1 (
pk int(11) NOT NULL AUTO_INCREMENT,
col_int_key int(11) DEFAULT NULL,
col_date_key date DEFAULT NULL,
col_varchar_key varchar(1) DEFAULT NULL,
PRIMARY KEY (pk),
KEY col_int_key (col_int_key),
KEY col_date_key (col_date_key),
KEY col_varchar_key (col_varchar_key,col_int_key)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
INSERT INTO t1 VALUES (10,8,'2002-02-21',NULL);
CREATE TABLE t2 (
pk int(11) NOT NULL AUTO_INCREMENT,
col_int_key int(11) DEFAULT NULL,
col_date_key date DEFAULT NULL,
col_varchar_key varchar(1) DEFAULT NULL,
PRIMARY KEY (pk),
KEY col_int_key (col_int_key),
KEY col_date_key (col_date_key),
KEY col_varchar_key (col_varchar_key,col_int_key)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
INSERT INTO t2 VALUES (1,7,'1900-01-01','f');
SELECT col_date_key FROM t1
WHERE 5 IN (
SELECT SUBQUERY3_t1 .col_int_key
FROM t2 SUBQUERY3_t1
LEFT JOIN t1 SUBQUERY3_t2 ON SUBQUERY3_t1 .col_varchar_key
);
drop table t2, t1;
--echo #
--echo # No BUG#: Duplicate weedout check is not done for outer joins
--echo #
create table t1 (a int);
create table t2 (a int);
insert into t1 values (1),(1),(2),(2);
insert into t2 values (1);
create table t0 (a int);
insert into t0 values (1),(2);
set @tmp_20110622= @@optimizer_switch;
set optimizer_switch='firstmatch=off,loosescan=off,materialization=off';
--echo # Check DuplicateWeedout + join buffer
explain
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
--echo # Check DuplicateWeedout without join buffer
set @tmp_jcl_20110622= @@join_cache_level;
set join_cache_level= 0;
explain
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
--echo # Check FirstMatch without join buffer:
set optimizer_switch='firstmatch=on';
explain
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
--echo #
--echo # Now, check the same for multiple inner tables:
alter table t2 add b int;
update t2 set b=a;
create table t3 as select * from t2;
set optimizer_switch='firstmatch=off';
set join_cache_level= 0;
--echo # DuplicateWeedout without join buffer
explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
set @@join_cache_level=@tmp_jcl_20110622;
--echo # DuplicateWeedout + join buffer
explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
--echo # Now, let the inner join side have a 'partial' match
select * from t3;
insert into t3 values(2,2);
explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
set @@optimizer_switch=@tmp_20110622;
drop table t0, t1, t2, t3;
# The following command must be the last one the file
set @@optimizer_switch=@save_optimizer_switch;
......@@ -1688,7 +1688,8 @@ class Item_equal: public Item_bool_func
friend class Item_equal_fields_iterator;
friend Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
Item_equal *item_equal);
friend bool setup_sj_materialization(struct st_join_table *tab);
friend bool setup_sj_materialization_part1(struct st_join_table *tab);
friend bool setup_sj_materialization_part2(struct st_join_table *tab);
};
class COND_EQUAL: public Sql_alloc
......
......@@ -476,12 +476,10 @@ void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
upper->item->walk(&Item::enumerate_field_refs_processor, FALSE,
(uchar*)&fixer);
used_tables_cache |= fixer.used_tables;
/*
if (after_pullout)
upper->item->fix_after_pullout(new_parent, &(upper->item));
upper->item->update_used_tables();
used_tables_cache |= upper->item->used_tables();
*/
}
}
}
......
......@@ -774,18 +774,20 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
if (convert_join_subqueries_to_semijoins(child_join))
DBUG_RETURN(TRUE);
(*in_subq)->sj_convert_priority=
test((*in_subq)->emb_on_expr_nest != NO_JOIN_NEST) * MAX_TABLES * 2 +
(*in_subq)->is_correlated * MAX_TABLES + child_join->outer_tables;
}
// Temporary measure: disable semi-joins when they are together with outer
// joins.
#if 0
if (check_for_outer_joins(join->join_list))
{
in_subq= join->sj_subselects.front();
arena= thd->activate_stmt_arena_if_needed(&backup);
goto skip_conversion;
}
#endif
//dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables);
/*
2. Pick which subqueries to convert:
......@@ -803,6 +805,11 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
in_subq++)
{
bool remove_item= TRUE;
/* Stop processing if we've reached a subquery that's attached to the ON clause */
if ((*in_subq)->emb_on_expr_nest != NO_JOIN_NEST)
break;
if ((*in_subq)->is_flattenable_semijoin)
{
if (join->table_count +
......@@ -828,7 +835,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
DBUG_RETURN(TRUE); /* purecov: inspected */
}
}
skip_conversion:
//skip_conversion:
/*
3. Finalize (perform IN->EXISTS rewrite) the subqueries that we didn't
convert:
......@@ -861,6 +868,11 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
do_fix_fields))
DBUG_RETURN(TRUE);
(*in_subq)->substitution= NULL;
#if 0
/*
Don't do the following, because the simplify_join() call is after this
call, and that call will save to prep_wher/prep_on_expr.
*/
/*
If this is a prepared statement, repeat the above operation for
......@@ -877,6 +889,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
FALSE))
DBUG_RETURN(TRUE);
}
#endif
/*
Revert to the IN->EXISTS strategy in the rare case when the subquery could
not be flattened.
......@@ -2840,9 +2853,8 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
TRUE Error
*/
bool setup_sj_materialization(JOIN_TAB *sjm_tab)
bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
{
uint i;
DBUG_ENTER("setup_sj_materialization");
JOIN_TAB *tab= sjm_tab->bush_children->start;
TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
......@@ -2851,6 +2863,7 @@ bool setup_sj_materialization(JOIN_TAB *sjm_tab)
/* First the calls come to the materialization function */
List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
DBUG_ASSERT(sjm->is_used);
/*
Set up the table to write to, do as select_union::create_result_table does
*/
......@@ -2878,6 +2891,22 @@ bool setup_sj_materialization(JOIN_TAB *sjm_tab)
sjm->materialized= FALSE;
sjm_tab->table= sjm->table;
sjm->table->pos_in_table_list= emb_sj_nest;
DBUG_RETURN(FALSE);
}
bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab)
{
DBUG_ENTER("setup_sj_materialization_part2");
JOIN_TAB *tab= sjm_tab->bush_children->start;
TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
THD *thd= tab->join->thd;
uint i;
List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
List_iterator<Item> it(item_list);
if (!sjm->is_sj_scan)
{
......@@ -2992,7 +3021,7 @@ bool setup_sj_materialization(JOIN_TAB *sjm_tab)
in the record buffers for the source tables.
*/
sjm->copy_field= new Copy_field[sjm->sjm_table_cols.elements];
it.rewind();
//it.rewind();
for (uint i=0; i < sjm->sjm_table_cols.elements; i++)
{
bool dummy;
......
......@@ -285,7 +285,9 @@ void restore_prev_sj_state(const table_map remaining_tables,
const JOIN_TAB *tab, uint idx);
void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
bool setup_sj_materialization(JOIN_TAB *tab);
bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab);
bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab);
TABLE *create_duplicate_weedout_tmp_table(THD *thd, uint uniq_tuple_length_arg,
SJ_TMP_TABLE *sjtbl);
......
......@@ -90,7 +90,7 @@ static store_key *get_store_key(THD *thd,
KEYUSE *keyuse, table_map used_tables,
KEY_PART_INFO *key_part, uchar *key_buff,
uint maybe_null);
static void make_outerjoin_info(JOIN *join);
static bool make_outerjoin_info(JOIN *join);
static Item*
make_cond_after_sjm(Item *root_cond, Item *cond, table_map tables, table_map sjm_tables);
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
......@@ -1165,7 +1165,10 @@ JOIN::optimize()
}
reset_nj_counters(this, join_list);
make_outerjoin_info(this);
if (make_outerjoin_info(this))
{
DBUG_RETURN(1);
}
/*
Among the equal fields belonging to the same multiple equality
......@@ -7625,6 +7628,12 @@ static void add_not_null_conds(JOIN *join)
nested outer join and so on until it reaches root_tab
(root_tab can be 0).
In other words:
add_found_match_trig_cond(tab->first_inner_tab, y, 0) is the way one should
wrap parts of WHERE. The idea is that the part of WHERE should be only
evaluated after we've finished figuring out whether outer joins.
^^^ is the above correct?
@param tab the first inner table for most nested outer join
@param cond the predicate to be guarded (must be set)
@param root_tab the first inner table to stop
......@@ -7652,6 +7661,12 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
}
bool TABLE_LIST::is_active_sjm()
{
return sj_mat_info && sj_mat_info->is_used;
}
/**
Fill in outer join related info for the execution plan structure.
......@@ -7669,6 +7684,12 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
corresponding first inner table through the field t0->on_expr_ref.
Here ti are structures of the JOIN_TAB type.
In other words, for each join tab, set
- first_inner
- last_inner
- first_upper
- on_expr_ref, cond_equal
EXAMPLE. For the query:
@code
SELECT * FROM t1
......@@ -7694,20 +7715,33 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
has been chosen.
*/
static void
static bool
make_outerjoin_info(JOIN *join)
{
DBUG_ENTER("make_outerjoin_info");
for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab;
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
{
TABLE *table=tab->table;
/*
psergey: The following is probably incorrect, fix it when we get
semi+outer joins processing to work:
Create temp. tables for merged SJ-Materialization nests. We need to do
this now, because further code relies on tab->table and
tab->table->pos_in_table_list being set.
*/
if (!table)
continue;
JOIN_TAB *tab;
for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
if (tab->bush_children)
{
if (setup_sj_materialization_part1(tab))
DBUG_RETURN(TRUE);
tab->table->reginfo.join_tab= tab;
}
}
for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab;
tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
TABLE *table= tab->table;
TABLE_LIST *tbl= table->pos_in_table_list;
TABLE_LIST *embedding= tbl->embedding;
......@@ -7721,11 +7755,16 @@ make_outerjoin_info(JOIN *join)
tab->last_inner= tab->first_inner= tab;
tab->on_expr_ref= &tbl->on_expr;
tab->cond_equal= tbl->cond_equal;
if (embedding)
if (embedding && !embedding->is_active_sjm())
tab->first_upper= embedding->nested_join->first_nested;
}
for ( ; embedding ; embedding= embedding->embedding)
{
if (embedding->is_active_sjm())
{
/* We're trying to walk out of an SJ-Materialization nest. Don't do this. */
break;
}
/* Ignore sj-nests: */
if (!(embedding->on_expr && embedding->outer_join))
continue;
......@@ -7757,7 +7796,7 @@ make_outerjoin_info(JOIN *join)
}
}
}
DBUG_VOID_RETURN;
DBUG_RETURN(FALSE);
}
......@@ -8132,10 +8171,25 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
the null complemented row.
*/
/* First push down constant conditions from on expressions */
for (JOIN_TAB *join_tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
join_tab;
join_tab= next_linear_tab(join, join_tab, WITH_BUSH_ROOTS))
/*
First push down constant conditions from ON expressions.
- Each pushed-down condition is wrapped into trigger which is
enabled only for non-NULL-complemented record
- The condition is attached to the first_inner_table.
With regards to join nests:
- if we start at top level, don't walk into nests
- if we start inside a nest, stay within that nest.
*/
JOIN_TAB *start_from= tab->bush_root_tab?
tab->bush_root_tab->bush_children->start :
join->join_tab + join->const_tables;
JOIN_TAB *end_with= tab->bush_root_tab?
tab->bush_root_tab->bush_children->end :
join->join_tab + join->top_join_tab_count;
for (JOIN_TAB *join_tab= start_from;
join_tab != end_with;
join_tab++)
{
if (*join_tab->on_expr_ref)
{
......@@ -8160,9 +8214,14 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
}
}
/* Push down non-constant conditions from ON expressions */
//JOIN_TAB *first_tab= join->join_tab+join->const_tables;
JOIN_TAB *last_tab= tab;
/*
while we're inside of an outer join and last_tab is
the last of its tables ...
*/
while (first_inner_tab && first_inner_tab->last_inner == last_tab)
{
/*
......@@ -8173,19 +8232,13 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
table_map used_tables2= (join->const_table_map |
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
tab;
tab= (tab == last_tab)? NULL: next_linear_tab(join, tab,
WITH_BUSH_ROOTS))
{
if (!tab->table)
start_from= tab->bush_root_tab?
tab->bush_root_tab->bush_children->start :
join->join_tab + join->const_tables;
for (JOIN_TAB *tab= start_from; tab <= last_tab; tab++)
{
/*
psergey-todo: this is probably incorrect, fix this when we get
correct processing for outer joins + semi joins
*/
continue;
}
DBUG_ASSERT(tab->table);
current_map= tab->table->map;
used_tables2|= current_map;
/*
......@@ -9136,7 +9189,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
{
if (tab->bush_children)
{
if (setup_sj_materialization(tab))
if (setup_sj_materialization_part2(tab))
return TRUE;
}
......@@ -15188,6 +15241,26 @@ evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
/*
The row complemented by nulls satisfies all conditions
attached to inner tables.
*/
if (join_tab->check_weed_out_table)
{
int res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table);
if (res == -1)
return NESTED_LOOP_ERROR;
else if (res == 1)
return NESTED_LOOP_OK;
}
else if (join_tab->do_firstmatch)
{
/*
We should return to the join_tab->do_firstmatch after we have
enumerated all the suffixes for current prefix row combination
*/
if (join_tab->do_firstmatch < join->return_tab)
join->return_tab= join_tab->do_firstmatch;
}
/*
Send the row complemented by nulls to be joined with the
remaining tables.
*/
......@@ -20568,8 +20641,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
examined_rows= tab->limit;
else
{
if (!tab->table->pos_in_table_list ||
tab->table->is_filled_at_execution()) // temporary, is_filled_at_execution
if (tab->table->is_filled_at_execution())
{
examined_rows= tab->records;
}
......
......@@ -204,7 +204,13 @@ typedef struct st_join_table {
NULL means no index condition pushdown was performed.
*/
Item *pre_idx_push_select_cond;
Item **on_expr_ref; /**< pointer to the associated on expression */
/*
Pointer to the associated ON expression. on_expr_ref=!NULL except for
degenerate joins.
*on_expr_ref!=NULL for tables that are first inner tables within an outer
join.
*/
Item **on_expr_ref;
COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */
st_join_table *first_inner; /**< first inner table for including outerjoin */
bool found; /**< true after all matches or null complement */
......@@ -478,6 +484,8 @@ typedef struct st_join_table {
}
double scan_time();
bool preread_init();
bool is_sjm_nest() { return test(bush_children); }
} JOIN_TAB;
......
......@@ -5410,9 +5410,11 @@ bool st_table::is_children_attached(void)
bool st_table::is_filled_at_execution()
{
return test(pos_in_table_list->jtbm_subselect);
return test(pos_in_table_list->jtbm_subselect ||
pos_in_table_list->is_active_sjm());
}
/*
Cleanup this table for re-execution.
......
......@@ -1765,6 +1765,7 @@ struct TABLE_LIST
respectively.
*/
char *get_table_name() { return view != NULL ? view_name.str : table_name; }
bool is_active_sjm();
st_select_lex_unit *get_unit();
st_select_lex *get_single_select();
void wrap_into_nested_join(List<TABLE_LIST> &join_list);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment