mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Merge
This commit is contained in:
@@ -1594,4 +1594,24 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
1 SIMPLE t1 index_merge a,b,c a,c 5,5 NULL 54 Using sort_union(a,c); Using where
|
1 SIMPLE t1 index_merge a,b,c a,c 5,5 NULL 54 Using sort_union(a,c); Using where
|
||||||
set optimizer_switch=default;
|
set optimizer_switch=default;
|
||||||
drop table t0, t1;
|
drop table t0, t1;
|
||||||
|
#
|
||||||
|
# BUG#834514 Assertion `!table || (!table->read_set || bitmap_is_set(...' with aggregates
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 ( a int , b int, c int, KEY (b), PRIMARY KEY (a)) ;
|
||||||
|
INSERT INTO t1 VALUES (1,4,0),(5,0,0),(6,7,0),(7,7,0),(8,1,0),(9,7,0),(10,1,0);
|
||||||
|
CREATE TABLE t2 ( b int, c int, KEY (c,b)) ;
|
||||||
|
INSERT INTO t2 VALUES (7,0),(1,0),(7,0),(1,0);
|
||||||
|
CREATE TABLE t3 ( a int ) ;
|
||||||
|
SELECT COUNT(DISTINCT t2.b), CONCAT(t1.c)
|
||||||
|
FROM t1, t2
|
||||||
|
WHERE (t2.c = t1.c)
|
||||||
|
AND (
|
||||||
|
t1.b IN ( 4 )
|
||||||
|
OR t1.a = 137
|
||||||
|
AND EXISTS ( SELECT a FROM t3 )
|
||||||
|
)
|
||||||
|
GROUP BY 2;
|
||||||
|
COUNT(DISTINCT t2.b) CONCAT(t1.c)
|
||||||
|
2 0
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
set optimizer_switch= @optimizer_switch_save;
|
set optimizer_switch= @optimizer_switch_save;
|
||||||
|
@@ -3,7 +3,7 @@ set @subselect_sj_mat_tmp= @@optimizer_switch;
|
|||||||
set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on');
|
set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on');
|
||||||
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
|
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
|
||||||
set @optimizer_switch_local_default= @@optimizer_switch;
|
set @optimizer_switch_local_default= @@optimizer_switch;
|
||||||
drop table if exists t1, t2, t3, t1i, t2i, t3i;
|
drop table if exists t1, t2, t3, t4, t5, t1i, t2i, t3i;
|
||||||
drop table if exists columns;
|
drop table if exists columns;
|
||||||
drop table if exists t1_16, t2_16, t3_16;
|
drop table if exists t1_16, t2_16, t3_16;
|
||||||
drop view if exists v1, v2, v1m, v2m;
|
drop view if exists v1, v2, v1m, v2m;
|
||||||
@@ -1579,6 +1579,83 @@ GROUP BY 1 , 2;
|
|||||||
a c
|
a c
|
||||||
1 2
|
1 2
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
|
#
|
||||||
|
# BUG#836523: Crash in JOIN::get_partial_cost_and_fanout with semijoin+materialization
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a varchar(1));
|
||||||
|
INSERT INTO t1 VALUES ('a'),('a');
|
||||||
|
CREATE TABLE t2 (a varchar(1));
|
||||||
|
CREATE TABLE t3 (a int);
|
||||||
|
INSERT INTO t3 VALUES (1),(2);
|
||||||
|
CREATE TABLE t4 (a varchar(1));
|
||||||
|
INSERT INTO t4 VALUES ('a'),('a');
|
||||||
|
SELECT t1.a
|
||||||
|
FROM t1
|
||||||
|
WHERE t1.a IN (
|
||||||
|
SELECT t2.a
|
||||||
|
FROM t2, t3
|
||||||
|
)
|
||||||
|
HAVING a IN (
|
||||||
|
SELECT a
|
||||||
|
FROM t4
|
||||||
|
);
|
||||||
|
a
|
||||||
|
DROP TABLE t1, t2, t3, t4;
|
||||||
|
#
|
||||||
|
# BUG#836507: Crash in setup_sj_materialization_part1() with semijoin+materialization
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a int) ;
|
||||||
|
INSERT IGNORE INTO t1 VALUES (1),(1);
|
||||||
|
CREATE TABLE t2 (a int);
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
CREATE TABLE t3 (a int);
|
||||||
|
CREATE TABLE t4 (a int);
|
||||||
|
INSERT INTO t4 VALUES (2),(2);
|
||||||
|
CREATE TABLE t5 (a int);
|
||||||
|
INSERT INTO t5 VALUES (1);
|
||||||
|
SELECT * FROM t1
|
||||||
|
WHERE (a) IN (
|
||||||
|
SELECT t5.a
|
||||||
|
FROM (
|
||||||
|
t2
|
||||||
|
LEFT JOIN ( t3 , t4 )
|
||||||
|
ON 1 = 1
|
||||||
|
)
|
||||||
|
JOIN t5
|
||||||
|
);
|
||||||
|
a
|
||||||
|
1
|
||||||
|
1
|
||||||
|
DROP TABLE t1,t2,t3,t4,t5;
|
||||||
|
#
|
||||||
|
# BUG#836532: Crash in Item_equal_fields_iterator::get_curr_field with semijoin+materialization
|
||||||
|
#
|
||||||
|
CREATE TABLE t2 (a int);
|
||||||
|
INSERT INTO t2 VALUES ('a'),('a');
|
||||||
|
Warnings:
|
||||||
|
Warning 1366 Incorrect integer value: 'a' for column 'a' at row 1
|
||||||
|
Warning 1366 Incorrect integer value: 'a' for column 'a' at row 2
|
||||||
|
CREATE TABLE t4 (a varchar(1));
|
||||||
|
INSERT INTO t4 VALUES ('m'),('o');
|
||||||
|
CREATE TABLE t3 (a varchar(1) , b varchar(1) ) ;
|
||||||
|
INSERT INTO t3 VALUES ('b','b');
|
||||||
|
CREATE TABLE t5 (a varchar(1), KEY (a)) ;
|
||||||
|
INSERT INTO t5 VALUES ('d'),('e');
|
||||||
|
SELECT *
|
||||||
|
FROM t2
|
||||||
|
WHERE t2.a = ALL (
|
||||||
|
SELECT t4.a
|
||||||
|
FROM t4
|
||||||
|
WHERE t4.a IN (
|
||||||
|
SELECT t3.a
|
||||||
|
FROM t3 , t5
|
||||||
|
WHERE ( t5.a = t3.b )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
a
|
||||||
|
0
|
||||||
|
0
|
||||||
|
DROP TABLE t2,t3,t4,t5;
|
||||||
set optimizer_switch=@subselect_sj_mat_tmp;
|
set optimizer_switch=@subselect_sj_mat_tmp;
|
||||||
set @subselect_mat_test_optimizer_switch_value=null;
|
set @subselect_mat_test_optimizer_switch_value=null;
|
||||||
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
|
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
drop table if exists t0, t1, t2, t3, t4, t10, t11, t12;
|
drop table if exists t0, t1, t2, t3, t4, t5, t10, t11, t12;
|
||||||
drop view if exists v1, v2, v3, v4;
|
drop view if exists v1, v2, v3, v4;
|
||||||
drop procedure if exists p1;
|
drop procedure if exists p1;
|
||||||
set @subselect_sj_tmp= @@optimizer_switch;
|
set @subselect_sj_tmp= @@optimizer_switch;
|
||||||
@@ -1749,4 +1749,66 @@ FROM t2
|
|||||||
);
|
);
|
||||||
a
|
a
|
||||||
drop table t1, t2,t3;
|
drop table t1, t2,t3;
|
||||||
|
#
|
||||||
|
# BUG#834758: Wrong result with innner join, LooseScan, two-column IN() predicate
|
||||||
|
#
|
||||||
|
set @tmp835758=@@optimizer_switch;
|
||||||
|
set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
|
||||||
|
CREATE TABLE t1 (b int) ;
|
||||||
|
INSERT INTO t1 VALUES (1),(5);
|
||||||
|
CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
|
||||||
|
INSERT INTO t2 VALUES (6),(10);
|
||||||
|
CREATE TABLE t3 (a int, b int, KEY (b)) ;
|
||||||
|
INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5);
|
||||||
|
# This used to incorrectly pick a join order of (t1, LooseScan(t3), t2):
|
||||||
|
explain
|
||||||
|
SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
|
||||||
|
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 index PRIMARY PRIMARY 4 NULL 2 Using index; Using join buffer (flat, BNL join)
|
||||||
|
1 PRIMARY t3 ALL b NULL NULL NULL 5 Using where; End temporary; Using join buffer (flat, BNL join)
|
||||||
|
SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
|
||||||
|
b a
|
||||||
|
5 6
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
set @@optimizer_switch= @tmp835758;
|
||||||
|
#
|
||||||
|
# BUG#834739: Wrong result with 3-way inner join, LooseScan,multipart keys
|
||||||
|
#
|
||||||
|
set @tmp834739=@@optimizer_switch;
|
||||||
|
set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
|
||||||
|
CREATE TABLE t2 ( b int, c int, KEY (b)) ;
|
||||||
|
INSERT INTO t2 VALUES (1,0),(1,0),(9,0),(1,0),(5,0);
|
||||||
|
CREATE TABLE t3 ( a int);
|
||||||
|
INSERT INTO t3 VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
|
||||||
|
CREATE TABLE t4 ( a int);
|
||||||
|
INSERT INTO t4 VALUES (0),(0),(0);
|
||||||
|
CREATE TABLE t5 ( b int, a int , KEY (a,b)) ;
|
||||||
|
INSERT INTO t5 VALUES (7,0),(9,0);
|
||||||
|
explain
|
||||||
|
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; LooseScan
|
||||||
|
1 PRIMARY t4 ALL NULL NULL NULL NULL 3
|
||||||
|
1 PRIMARY t2 ref b b 5 test.t5.b 2 Using where; FirstMatch(t5)
|
||||||
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join)
|
||||||
|
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
|
||||||
|
a
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
DROP TABLE t2, t3, t4, t5;
|
||||||
|
set @@optimizer_switch=@tmp834739;
|
||||||
set optimizer_switch=@subselect_sj_tmp;
|
set optimizer_switch=@subselect_sj_tmp;
|
||||||
|
@@ -9,7 +9,7 @@ set join_cache_level=6;
|
|||||||
show variables like 'join_cache_level';
|
show variables like 'join_cache_level';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
join_cache_level 6
|
join_cache_level 6
|
||||||
drop table if exists t0, t1, t2, t3, t4, t10, t11, t12;
|
drop table if exists t0, t1, t2, t3, t4, t5, t10, t11, t12;
|
||||||
drop view if exists v1, v2, v3, v4;
|
drop view if exists v1, v2, v3, v4;
|
||||||
drop procedure if exists p1;
|
drop procedure if exists p1;
|
||||||
set @subselect_sj_tmp= @@optimizer_switch;
|
set @subselect_sj_tmp= @@optimizer_switch;
|
||||||
@@ -1760,6 +1760,68 @@ FROM t2
|
|||||||
);
|
);
|
||||||
a
|
a
|
||||||
drop table t1, t2,t3;
|
drop table t1, t2,t3;
|
||||||
|
#
|
||||||
|
# BUG#834758: Wrong result with innner join, LooseScan, two-column IN() predicate
|
||||||
|
#
|
||||||
|
set @tmp835758=@@optimizer_switch;
|
||||||
|
set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
|
||||||
|
CREATE TABLE t1 (b int) ;
|
||||||
|
INSERT INTO t1 VALUES (1),(5);
|
||||||
|
CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
|
||||||
|
INSERT INTO t2 VALUES (6),(10);
|
||||||
|
CREATE TABLE t3 (a int, b int, KEY (b)) ;
|
||||||
|
INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5);
|
||||||
|
# This used to incorrectly pick a join order of (t1, LooseScan(t3), t2):
|
||||||
|
explain
|
||||||
|
SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
|
||||||
|
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 index PRIMARY PRIMARY 4 NULL 2 Using index; Using join buffer (flat, BNL join)
|
||||||
|
1 PRIMARY t3 ALL b NULL NULL NULL 5 Using where; End temporary; Using join buffer (incremental, BNL join)
|
||||||
|
SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
|
||||||
|
b a
|
||||||
|
5 6
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
set @@optimizer_switch= @tmp835758;
|
||||||
|
#
|
||||||
|
# BUG#834739: Wrong result with 3-way inner join, LooseScan,multipart keys
|
||||||
|
#
|
||||||
|
set @tmp834739=@@optimizer_switch;
|
||||||
|
set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
|
||||||
|
CREATE TABLE t2 ( b int, c int, KEY (b)) ;
|
||||||
|
INSERT INTO t2 VALUES (1,0),(1,0),(9,0),(1,0),(5,0);
|
||||||
|
CREATE TABLE t3 ( a int);
|
||||||
|
INSERT INTO t3 VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
|
||||||
|
CREATE TABLE t4 ( a int);
|
||||||
|
INSERT INTO t4 VALUES (0),(0),(0);
|
||||||
|
CREATE TABLE t5 ( b int, a int , KEY (a,b)) ;
|
||||||
|
INSERT INTO t5 VALUES (7,0),(9,0);
|
||||||
|
explain
|
||||||
|
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; LooseScan
|
||||||
|
1 PRIMARY t4 ALL NULL NULL NULL NULL 3
|
||||||
|
1 PRIMARY t2 ref b b 5 test.t5.b 2 Using where; FirstMatch(t5)
|
||||||
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join)
|
||||||
|
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
|
||||||
|
a
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
DROP TABLE t2, t3, t4, t5;
|
||||||
|
set @@optimizer_switch=@tmp834739;
|
||||||
set optimizer_switch=@subselect_sj_tmp;
|
set optimizer_switch=@subselect_sj_tmp;
|
||||||
#
|
#
|
||||||
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
|
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
|
||||||
|
@@ -2,7 +2,7 @@ set @subselect_sj_mat_tmp= @@optimizer_switch;
|
|||||||
set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on');
|
set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on');
|
||||||
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
|
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
|
||||||
set @optimizer_switch_local_default= @@optimizer_switch;
|
set @optimizer_switch_local_default= @@optimizer_switch;
|
||||||
drop table if exists t1, t2, t3, t1i, t2i, t3i;
|
drop table if exists t1, t2, t3, t4, t5, t1i, t2i, t3i;
|
||||||
drop table if exists columns;
|
drop table if exists columns;
|
||||||
drop table if exists t1_16, t2_16, t3_16;
|
drop table if exists t1_16, t2_16, t3_16;
|
||||||
drop view if exists v1, v2, v1m, v2m;
|
drop view if exists v1, v2, v1m, v2m;
|
||||||
@@ -856,15 +856,16 @@ explain extended select left(a1,7), left(a2,7)
|
|||||||
from t1_1024
|
from t1_1024
|
||||||
where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
|
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
|
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 t1_1024 ALL NULL NULL NULL NULL 3 100.00 Start temporary
|
||||||
1 PRIMARY <subquery2> eq_ref NULL distinct_key 15 func,func 1 100.00
|
1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
|
||||||
2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
|
|
||||||
Warnings:
|
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)))
|
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)))
|
||||||
select left(a1,7), left(a2,7)
|
select left(a1,7), left(a2,7)
|
||||||
from t1_1024
|
from t1_1024
|
||||||
where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
|
where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
|
||||||
left(a1,7) left(a2,7)
|
left(a1,7) left(a2,7)
|
||||||
|
1 - 01x 2 - 01x
|
||||||
|
1 - 02x 2 - 02x
|
||||||
explain extended select left(a1,7), left(a2,7)
|
explain extended select left(a1,7), left(a2,7)
|
||||||
from t1_1024
|
from t1_1024
|
||||||
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
where a1 in (select group_concat(b1) from t2_1024 group by b2);
|
||||||
@@ -950,15 +951,16 @@ explain extended select left(a1,7), left(a2,7)
|
|||||||
from t1_1025
|
from t1_1025
|
||||||
where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
|
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
|
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 t1_1025 ALL NULL NULL NULL NULL 3 100.00 Start temporary
|
||||||
1 PRIMARY <subquery2> eq_ref NULL distinct_key 15 func,func 1 100.00
|
1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
|
||||||
2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
|
|
||||||
Warnings:
|
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)))
|
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)))
|
||||||
select left(a1,7), left(a2,7)
|
select left(a1,7), left(a2,7)
|
||||||
from t1_1025
|
from t1_1025
|
||||||
where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
|
where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
|
||||||
left(a1,7) left(a2,7)
|
left(a1,7) left(a2,7)
|
||||||
|
1 - 01x 2 - 01x
|
||||||
|
1 - 02x 2 - 02x
|
||||||
explain extended select left(a1,7), left(a2,7)
|
explain extended select left(a1,7), left(a2,7)
|
||||||
from t1_1025
|
from t1_1025
|
||||||
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
where a1 in (select group_concat(b1) from t2_1025 group by b2);
|
||||||
@@ -1617,4 +1619,81 @@ GROUP BY 1 , 2;
|
|||||||
a c
|
a c
|
||||||
1 2
|
1 2
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
|
#
|
||||||
|
# BUG#836523: Crash in JOIN::get_partial_cost_and_fanout with semijoin+materialization
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a varchar(1));
|
||||||
|
INSERT INTO t1 VALUES ('a'),('a');
|
||||||
|
CREATE TABLE t2 (a varchar(1));
|
||||||
|
CREATE TABLE t3 (a int);
|
||||||
|
INSERT INTO t3 VALUES (1),(2);
|
||||||
|
CREATE TABLE t4 (a varchar(1));
|
||||||
|
INSERT INTO t4 VALUES ('a'),('a');
|
||||||
|
SELECT t1.a
|
||||||
|
FROM t1
|
||||||
|
WHERE t1.a IN (
|
||||||
|
SELECT t2.a
|
||||||
|
FROM t2, t3
|
||||||
|
)
|
||||||
|
HAVING a IN (
|
||||||
|
SELECT a
|
||||||
|
FROM t4
|
||||||
|
);
|
||||||
|
a
|
||||||
|
DROP TABLE t1, t2, t3, t4;
|
||||||
|
#
|
||||||
|
# BUG#836507: Crash in setup_sj_materialization_part1() with semijoin+materialization
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a int) ;
|
||||||
|
INSERT IGNORE INTO t1 VALUES (1),(1);
|
||||||
|
CREATE TABLE t2 (a int);
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
CREATE TABLE t3 (a int);
|
||||||
|
CREATE TABLE t4 (a int);
|
||||||
|
INSERT INTO t4 VALUES (2),(2);
|
||||||
|
CREATE TABLE t5 (a int);
|
||||||
|
INSERT INTO t5 VALUES (1);
|
||||||
|
SELECT * FROM t1
|
||||||
|
WHERE (a) IN (
|
||||||
|
SELECT t5.a
|
||||||
|
FROM (
|
||||||
|
t2
|
||||||
|
LEFT JOIN ( t3 , t4 )
|
||||||
|
ON 1 = 1
|
||||||
|
)
|
||||||
|
JOIN t5
|
||||||
|
);
|
||||||
|
a
|
||||||
|
1
|
||||||
|
1
|
||||||
|
DROP TABLE t1,t2,t3,t4,t5;
|
||||||
|
#
|
||||||
|
# BUG#836532: Crash in Item_equal_fields_iterator::get_curr_field with semijoin+materialization
|
||||||
|
#
|
||||||
|
CREATE TABLE t2 (a int);
|
||||||
|
INSERT INTO t2 VALUES ('a'),('a');
|
||||||
|
Warnings:
|
||||||
|
Warning 1366 Incorrect integer value: 'a' for column 'a' at row 1
|
||||||
|
Warning 1366 Incorrect integer value: 'a' for column 'a' at row 2
|
||||||
|
CREATE TABLE t4 (a varchar(1));
|
||||||
|
INSERT INTO t4 VALUES ('m'),('o');
|
||||||
|
CREATE TABLE t3 (a varchar(1) , b varchar(1) ) ;
|
||||||
|
INSERT INTO t3 VALUES ('b','b');
|
||||||
|
CREATE TABLE t5 (a varchar(1), KEY (a)) ;
|
||||||
|
INSERT INTO t5 VALUES ('d'),('e');
|
||||||
|
SELECT *
|
||||||
|
FROM t2
|
||||||
|
WHERE t2.a = ALL (
|
||||||
|
SELECT t4.a
|
||||||
|
FROM t4
|
||||||
|
WHERE t4.a IN (
|
||||||
|
SELECT t3.a
|
||||||
|
FROM t3 , t5
|
||||||
|
WHERE ( t5.a = t3.b )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
a
|
||||||
|
0
|
||||||
|
0
|
||||||
|
DROP TABLE t2,t3,t4,t5;
|
||||||
set optimizer_switch=@subselect_sj_mat_tmp;
|
set optimizer_switch=@subselect_sj_mat_tmp;
|
||||||
|
@@ -125,5 +125,29 @@ set optimizer_switch=default;
|
|||||||
|
|
||||||
drop table t0, t1;
|
drop table t0, t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG#834514 Assertion `!table || (!table->read_set || bitmap_is_set(...' with aggregates
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 ( a int , b int, c int, KEY (b), PRIMARY KEY (a)) ;
|
||||||
|
INSERT INTO t1 VALUES (1,4,0),(5,0,0),(6,7,0),(7,7,0),(8,1,0),(9,7,0),(10,1,0);
|
||||||
|
|
||||||
|
CREATE TABLE t2 ( b int, c int, KEY (c,b)) ;
|
||||||
|
INSERT INTO t2 VALUES (7,0),(1,0),(7,0),(1,0);
|
||||||
|
|
||||||
|
CREATE TABLE t3 ( a int ) ;
|
||||||
|
|
||||||
|
SELECT COUNT(DISTINCT t2.b), CONCAT(t1.c)
|
||||||
|
FROM t1, t2
|
||||||
|
WHERE (t2.c = t1.c)
|
||||||
|
AND (
|
||||||
|
t1.b IN ( 4 )
|
||||||
|
OR t1.a = 137
|
||||||
|
AND EXISTS ( SELECT a FROM t3 )
|
||||||
|
)
|
||||||
|
GROUP BY 2;
|
||||||
|
|
||||||
|
DROP TABLE t1,t2,t3;
|
||||||
|
|
||||||
set optimizer_switch= @optimizer_switch_save;
|
set optimizer_switch= @optimizer_switch_save;
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
# Nested Loops semi-join subquery evaluation tests
|
# Nested Loops semi-join subquery evaluation tests
|
||||||
#
|
#
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t0, t1, t2, t3, t4, t10, t11, t12;
|
drop table if exists t0, t1, t2, t3, t4, t5, t10, t11, t12;
|
||||||
drop view if exists v1, v2, v3, v4;
|
drop view if exists v1, v2, v3, v4;
|
||||||
drop procedure if exists p1;
|
drop procedure if exists p1;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
@@ -1594,5 +1594,53 @@ WHERE (t3.a) IN (
|
|||||||
);
|
);
|
||||||
drop table t1, t2,t3;
|
drop table t1, t2,t3;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG#834758: Wrong result with innner join, LooseScan, two-column IN() predicate
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
set @tmp835758=@@optimizer_switch;
|
||||||
|
set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
|
||||||
|
|
||||||
|
CREATE TABLE t1 (b int) ;
|
||||||
|
INSERT INTO t1 VALUES (1),(5);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
|
||||||
|
INSERT INTO t2 VALUES (6),(10);
|
||||||
|
|
||||||
|
CREATE TABLE t3 (a int, b int, KEY (b)) ;
|
||||||
|
INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5);
|
||||||
|
|
||||||
|
--echo # This used to incorrectly pick a join order of (t1, LooseScan(t3), t2):
|
||||||
|
explain
|
||||||
|
SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
|
||||||
|
SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
|
||||||
|
|
||||||
|
DROP TABLE t1, t2, t3;
|
||||||
|
set @@optimizer_switch= @tmp835758;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG#834739: Wrong result with 3-way inner join, LooseScan,multipart keys
|
||||||
|
--echo #
|
||||||
|
set @tmp834739=@@optimizer_switch;
|
||||||
|
set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
|
||||||
|
CREATE TABLE t2 ( b int, c int, KEY (b)) ;
|
||||||
|
INSERT INTO t2 VALUES (1,0),(1,0),(9,0),(1,0),(5,0);
|
||||||
|
|
||||||
|
CREATE TABLE t3 ( a int);
|
||||||
|
INSERT INTO t3 VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
|
||||||
|
|
||||||
|
CREATE TABLE t4 ( a int);
|
||||||
|
INSERT INTO t4 VALUES (0),(0),(0);
|
||||||
|
|
||||||
|
CREATE TABLE t5 ( b int, a int , KEY (a,b)) ;
|
||||||
|
INSERT INTO t5 VALUES (7,0),(9,0);
|
||||||
|
|
||||||
|
explain
|
||||||
|
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
|
||||||
|
SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
|
||||||
|
|
||||||
|
DROP TABLE t2, t3, t4, t5;
|
||||||
|
set @@optimizer_switch=@tmp834739;
|
||||||
|
|
||||||
# The following command must be the last one the file
|
# The following command must be the last one the file
|
||||||
set optimizer_switch=@subselect_sj_tmp;
|
set optimizer_switch=@subselect_sj_tmp;
|
||||||
|
@@ -9,7 +9,7 @@ set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
|
|||||||
set @optimizer_switch_local_default= @@optimizer_switch;
|
set @optimizer_switch_local_default= @@optimizer_switch;
|
||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t1, t2, t3, t1i, t2i, t3i;
|
drop table if exists t1, t2, t3, t4, t5, t1i, t2i, t3i;
|
||||||
drop table if exists columns;
|
drop table if exists columns;
|
||||||
drop table if exists t1_16, t2_16, t3_16;
|
drop table if exists t1_16, t2_16, t3_16;
|
||||||
drop view if exists v1, v2, v1m, v2m;
|
drop view if exists v1, v2, v1m, v2m;
|
||||||
@@ -1263,5 +1263,91 @@ GROUP BY 1 , 2;
|
|||||||
|
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG#836523: Crash in JOIN::get_partial_cost_and_fanout with semijoin+materialization
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (a varchar(1));
|
||||||
|
INSERT INTO t1 VALUES ('a'),('a');
|
||||||
|
|
||||||
|
CREATE TABLE t2 (a varchar(1));
|
||||||
|
|
||||||
|
CREATE TABLE t3 (a int);
|
||||||
|
INSERT INTO t3 VALUES (1),(2);
|
||||||
|
|
||||||
|
CREATE TABLE t4 (a varchar(1));
|
||||||
|
INSERT INTO t4 VALUES ('a'),('a');
|
||||||
|
|
||||||
|
SELECT t1.a
|
||||||
|
FROM t1
|
||||||
|
WHERE t1.a IN (
|
||||||
|
SELECT t2.a
|
||||||
|
FROM t2, t3
|
||||||
|
)
|
||||||
|
HAVING a IN (
|
||||||
|
SELECT a
|
||||||
|
FROM t4
|
||||||
|
);
|
||||||
|
DROP TABLE t1, t2, t3, t4;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG#836507: Crash in setup_sj_materialization_part1() with semijoin+materialization
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (a int) ;
|
||||||
|
INSERT IGNORE INTO t1 VALUES (1),(1);
|
||||||
|
|
||||||
|
CREATE TABLE t2 (a int);
|
||||||
|
INSERT INTO t2 VALUES (1);
|
||||||
|
|
||||||
|
CREATE TABLE t3 (a int);
|
||||||
|
|
||||||
|
CREATE TABLE t4 (a int);
|
||||||
|
INSERT INTO t4 VALUES (2),(2);
|
||||||
|
|
||||||
|
CREATE TABLE t5 (a int);
|
||||||
|
INSERT INTO t5 VALUES (1);
|
||||||
|
|
||||||
|
SELECT * FROM t1
|
||||||
|
WHERE (a) IN (
|
||||||
|
SELECT t5.a
|
||||||
|
FROM (
|
||||||
|
t2
|
||||||
|
LEFT JOIN ( t3 , t4 )
|
||||||
|
ON 1 = 1
|
||||||
|
)
|
||||||
|
JOIN t5
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TABLE t1,t2,t3,t4,t5;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # BUG#836532: Crash in Item_equal_fields_iterator::get_curr_field with semijoin+materialization
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t2 (a int);
|
||||||
|
INSERT INTO t2 VALUES ('a'),('a');
|
||||||
|
|
||||||
|
CREATE TABLE t4 (a varchar(1));
|
||||||
|
INSERT INTO t4 VALUES ('m'),('o');
|
||||||
|
|
||||||
|
CREATE TABLE t3 (a varchar(1) , b varchar(1) ) ;
|
||||||
|
INSERT INTO t3 VALUES ('b','b');
|
||||||
|
|
||||||
|
CREATE TABLE t5 (a varchar(1), KEY (a)) ;
|
||||||
|
INSERT INTO t5 VALUES ('d'),('e');
|
||||||
|
|
||||||
|
SELECT *
|
||||||
|
FROM t2
|
||||||
|
WHERE t2.a = ALL (
|
||||||
|
SELECT t4.a
|
||||||
|
FROM t4
|
||||||
|
WHERE t4.a IN (
|
||||||
|
SELECT t3.a
|
||||||
|
FROM t3 , t5
|
||||||
|
WHERE ( t5.a = t3.b )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
DROP TABLE t2,t3,t4,t5;
|
||||||
|
|
||||||
set optimizer_switch=@subselect_sj_mat_tmp;
|
set optimizer_switch=@subselect_sj_mat_tmp;
|
||||||
|
|
||||||
|
@@ -624,15 +624,21 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
|
|||||||
SQL_SELECT::skip_record evaluates this condition. it may include a
|
SQL_SELECT::skip_record evaluates this condition. it may include a
|
||||||
correlated subquery predicate, such that some field in the subquery
|
correlated subquery predicate, such that some field in the subquery
|
||||||
refers to 'sort_form'.
|
refers to 'sort_form'.
|
||||||
|
|
||||||
|
PSergey-todo: discuss the above with Timour.
|
||||||
*/
|
*/
|
||||||
|
MY_BITMAP *tmp_read_set= sort_form->read_set;
|
||||||
|
MY_BITMAP *tmp_write_set= sort_form->write_set;
|
||||||
|
MY_BITMAP *tmp_vcol_set= sort_form->vcol_set;
|
||||||
|
|
||||||
if (select->cond->with_subselect)
|
if (select->cond->with_subselect)
|
||||||
sort_form->column_bitmaps_set(save_read_set, save_write_set,
|
sort_form->column_bitmaps_set(save_read_set, save_write_set,
|
||||||
save_vcol_set);
|
save_vcol_set);
|
||||||
write_record= (select->skip_record(thd) > 0);
|
write_record= (select->skip_record(thd) > 0);
|
||||||
if (select->cond->with_subselect)
|
if (select->cond->with_subselect)
|
||||||
sort_form->column_bitmaps_set(&sort_form->tmp_set,
|
sort_form->column_bitmaps_set(tmp_read_set,
|
||||||
&sort_form->tmp_set,
|
tmp_write_set,
|
||||||
&sort_form->tmp_set);
|
tmp_vcol_set);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
write_record= true;
|
write_record= true;
|
||||||
|
@@ -5191,6 +5191,10 @@ Field *Item::make_string_field(TABLE *table)
|
|||||||
{
|
{
|
||||||
Field *field;
|
Field *field;
|
||||||
DBUG_ASSERT(collation.collation);
|
DBUG_ASSERT(collation.collation);
|
||||||
|
/*
|
||||||
|
Note: the following check is repeated in
|
||||||
|
subquery_types_allow_materialization():
|
||||||
|
*/
|
||||||
if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
|
if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
|
||||||
field= new Field_blob(max_length, maybe_null, name,
|
field= new Field_blob(max_length, maybe_null, name,
|
||||||
collation.collation);
|
collation.collation);
|
||||||
|
@@ -2264,7 +2264,12 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
|
|||||||
{
|
{
|
||||||
/* The argument list of the top-level AND may change after fix fields. */
|
/* The argument list of the top-level AND may change after fix fields. */
|
||||||
and_args= ((Item_cond*) join_arg->conds)->argument_list();
|
and_args= ((Item_cond*) join_arg->conds)->argument_list();
|
||||||
and_args->concat((List<Item> *) &join_arg->cond_equal->current_level);
|
List_iterator<Item_equal> li(join_arg->cond_equal->current_level);
|
||||||
|
Item_equal *elem;
|
||||||
|
while ((elem= li++))
|
||||||
|
{
|
||||||
|
and_args->push_back(elem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -559,6 +559,16 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs)
|
|||||||
if (inner->field_type() == MYSQL_TYPE_BLOB ||
|
if (inner->field_type() == MYSQL_TYPE_BLOB ||
|
||||||
inner->field_type() == MYSQL_TYPE_GEOMETRY)
|
inner->field_type() == MYSQL_TYPE_GEOMETRY)
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
|
/*
|
||||||
|
Materialization also is unable to work when create_tmp_table() will
|
||||||
|
create a blob column because item->max_length is too big.
|
||||||
|
The following check is copied from Item::make_string_field():
|
||||||
|
*/
|
||||||
|
if (inner->max_length / inner->collation.collation->mbmaxlen >
|
||||||
|
CONVERT_IF_BIGGER_TO_BLOB)
|
||||||
|
{
|
||||||
|
DBUG_RETURN(FALSE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TIME_RESULT:
|
case TIME_RESULT:
|
||||||
if (mysql_type_to_time_type(outer->field_type()) !=
|
if (mysql_type_to_time_type(outer->field_type()) !=
|
||||||
@@ -2639,6 +2649,7 @@ ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest,
|
|||||||
{
|
{
|
||||||
res |= 1ULL << i;
|
res |= 1ULL << i;
|
||||||
}
|
}
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -2935,6 +2946,11 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
|
|||||||
DBUG_ENTER("setup_sj_materialization");
|
DBUG_ENTER("setup_sj_materialization");
|
||||||
JOIN_TAB *tab= sjm_tab->bush_children->start;
|
JOIN_TAB *tab= sjm_tab->bush_children->start;
|
||||||
TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
|
TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
|
||||||
|
|
||||||
|
/* Walk out of outer join nests until we reach the semi-join nest we're in */
|
||||||
|
while (!emb_sj_nest->sj_mat_info)
|
||||||
|
emb_sj_nest= emb_sj_nest->embedding;
|
||||||
|
|
||||||
SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
|
SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
|
||||||
THD *thd= tab->join->thd;
|
THD *thd= tab->join->thd;
|
||||||
/* First the calls come to the materialization function */
|
/* First the calls come to the materialization function */
|
||||||
@@ -2983,6 +2999,9 @@ bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab)
|
|||||||
DBUG_ENTER("setup_sj_materialization_part2");
|
DBUG_ENTER("setup_sj_materialization_part2");
|
||||||
JOIN_TAB *tab= sjm_tab->bush_children->start;
|
JOIN_TAB *tab= sjm_tab->bush_children->start;
|
||||||
TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
|
TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
|
||||||
|
/* Walk out of outer join nests until we reach the semi-join nest we're in */
|
||||||
|
while (!emb_sj_nest->sj_mat_info)
|
||||||
|
emb_sj_nest= emb_sj_nest->embedding;
|
||||||
SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
|
SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
|
||||||
THD *thd= tab->join->thd;
|
THD *thd= tab->join->thd;
|
||||||
uint i;
|
uint i;
|
||||||
@@ -3818,6 +3837,8 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
|
|||||||
{
|
{
|
||||||
/* We jump from the last table to the first one */
|
/* We jump from the last table to the first one */
|
||||||
tab->loosescan_match_tab= tab + pos->n_sj_tables - 1;
|
tab->loosescan_match_tab= tab + pos->n_sj_tables - 1;
|
||||||
|
for (uint j= i; j < pos->n_sj_tables; j++)
|
||||||
|
join->join_tab[j].inside_loosescan_range= TRUE;
|
||||||
|
|
||||||
/* Calculate key length */
|
/* Calculate key length */
|
||||||
keylen= 0;
|
keylen= 0;
|
||||||
@@ -4478,20 +4499,6 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
|
|||||||
outer_join= unit->outer_select() ? unit->outer_select()->join : NULL;
|
outer_join= unit->outer_select() ? unit->outer_select()->join : NULL;
|
||||||
if (outer_join && outer_join->table_count > 0)
|
if (outer_join && outer_join->table_count > 0)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
The index of the last JOIN_TAB in the outer JOIN where in_subs is
|
|
||||||
attached (pushed to).
|
|
||||||
*/
|
|
||||||
uint max_outer_join_tab_idx;
|
|
||||||
/*
|
|
||||||
Make_cond_for_table is called for predicates only in the WHERE/ON
|
|
||||||
clauses. In all other cases, predicates are not pushed to any
|
|
||||||
JOIN_TAB, and their join_tab_idx remains MAX_TABLES. Such predicates
|
|
||||||
are evaluated for each complete row of the outer join.
|
|
||||||
*/
|
|
||||||
max_outer_join_tab_idx= (in_subs->get_join_tab_idx() == MAX_TABLES) ?
|
|
||||||
outer_join->table_count - 1:
|
|
||||||
in_subs->get_join_tab_idx();
|
|
||||||
/*
|
/*
|
||||||
TODO:
|
TODO:
|
||||||
Currently outer_lookup_keys is computed as the number of rows in
|
Currently outer_lookup_keys is computed as the number of rows in
|
||||||
@@ -4504,7 +4511,7 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
|
|||||||
If the join order: t1, t2, the number of unique lookup keys is ~ to
|
If the join order: t1, t2, the number of unique lookup keys is ~ to
|
||||||
the number of unique values t2.c2 in the partial join t1 join t2.
|
the number of unique values t2.c2 in the partial join t1 join t2.
|
||||||
*/
|
*/
|
||||||
outer_join->get_partial_cost_and_fanout(max_outer_join_tab_idx,
|
outer_join->get_partial_cost_and_fanout(in_subs->get_join_tab_idx(),
|
||||||
table_map(-1),
|
table_map(-1),
|
||||||
&dummy,
|
&dummy,
|
||||||
&outer_lookup_keys);
|
&outer_lookup_keys);
|
||||||
|
@@ -310,6 +310,26 @@ public:
|
|||||||
friend class error_list;
|
friend class error_list;
|
||||||
friend class error_list_iterator;
|
friend class error_list_iterator;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Debugging help: return N-th element in the list, or NULL if the list has
|
||||||
|
less than N elements.
|
||||||
|
*/
|
||||||
|
inline void *nth_element(int n)
|
||||||
|
{
|
||||||
|
list_node *node= first;
|
||||||
|
void *data= NULL;
|
||||||
|
for (int i=0; i <= n; i++)
|
||||||
|
{
|
||||||
|
if (node == &end_of_list)
|
||||||
|
{
|
||||||
|
data= NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data= node->info;
|
||||||
|
node= node->next;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
#ifdef LIST_EXTRA_DEBUG
|
#ifdef LIST_EXTRA_DEBUG
|
||||||
/*
|
/*
|
||||||
Check list invariants and print results into trace. Invariants are:
|
Check list invariants and print results into trace. Invariants are:
|
||||||
@@ -488,6 +508,7 @@ public:
|
|||||||
}
|
}
|
||||||
empty();
|
empty();
|
||||||
}
|
}
|
||||||
|
inline T *nth_element(int n) { return (T*)base_list::nth_element(n); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -175,14 +175,14 @@ int join_read_always_key_or_null(JOIN_TAB *tab);
|
|||||||
int join_read_next_same_or_null(READ_RECORD *info);
|
int join_read_next_same_or_null(READ_RECORD *info);
|
||||||
static COND *make_cond_for_table(THD *thd, Item *cond,table_map table,
|
static COND *make_cond_for_table(THD *thd, Item *cond,table_map table,
|
||||||
table_map used_table,
|
table_map used_table,
|
||||||
uint join_tab_idx_arg,
|
int join_tab_idx_arg,
|
||||||
bool exclude_expensive_cond,
|
bool exclude_expensive_cond,
|
||||||
bool retain_ref_cond);
|
bool retain_ref_cond);
|
||||||
static COND *make_cond_for_table_from_pred(THD *thd, Item *root_cond,
|
static COND *make_cond_for_table_from_pred(THD *thd, Item *root_cond,
|
||||||
Item *cond,
|
Item *cond,
|
||||||
table_map tables,
|
table_map tables,
|
||||||
table_map used_table,
|
table_map used_table,
|
||||||
uint join_tab_idx_arg,
|
int join_tab_idx_arg,
|
||||||
bool exclude_expensive_cond,
|
bool exclude_expensive_cond,
|
||||||
bool retain_ref_cond);
|
bool retain_ref_cond);
|
||||||
|
|
||||||
@@ -1088,7 +1088,7 @@ JOIN::optimize()
|
|||||||
if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
|
if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
|
||||||
{
|
{
|
||||||
COND *table_independent_conds=
|
COND *table_independent_conds=
|
||||||
make_cond_for_table(thd, conds, PSEUDO_TABLE_BITS, 0, MAX_TABLES,
|
make_cond_for_table(thd, conds, PSEUDO_TABLE_BITS, 0, -1,
|
||||||
FALSE, FALSE);
|
FALSE, FALSE);
|
||||||
DBUG_EXECUTE("where",
|
DBUG_EXECUTE("where",
|
||||||
print_where(table_independent_conds,
|
print_where(table_independent_conds,
|
||||||
@@ -2535,7 +2535,7 @@ JOIN::exec()
|
|||||||
|
|
||||||
Item* sort_table_cond= make_cond_for_table(thd, curr_join->tmp_having,
|
Item* sort_table_cond= make_cond_for_table(thd, curr_join->tmp_having,
|
||||||
used_tables,
|
used_tables,
|
||||||
(table_map)0, MAX_TABLES,
|
(table_map)0, -1,
|
||||||
FALSE, FALSE);
|
FALSE, FALSE);
|
||||||
if (sort_table_cond)
|
if (sort_table_cond)
|
||||||
{
|
{
|
||||||
@@ -2573,7 +2573,7 @@ JOIN::exec()
|
|||||||
QT_ORDINARY););
|
QT_ORDINARY););
|
||||||
curr_join->tmp_having= make_cond_for_table(thd, curr_join->tmp_having,
|
curr_join->tmp_having= make_cond_for_table(thd, curr_join->tmp_having,
|
||||||
~ (table_map) 0,
|
~ (table_map) 0,
|
||||||
~used_tables, MAX_TABLES,
|
~used_tables, -1,
|
||||||
FALSE, FALSE);
|
FALSE, FALSE);
|
||||||
DBUG_EXECUTE("where",print_where(curr_join->tmp_having,
|
DBUG_EXECUTE("where",print_where(curr_join->tmp_having,
|
||||||
"having after sort",
|
"having after sort",
|
||||||
@@ -6047,7 +6047,7 @@ greedy_search(JOIN *join,
|
|||||||
read_time_arg and record_count_arg contain the computed cost and fanout
|
read_time_arg and record_count_arg contain the computed cost and fanout
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
|
void JOIN::get_partial_cost_and_fanout(int end_tab_idx,
|
||||||
table_map filter_map,
|
table_map filter_map,
|
||||||
double *read_time_arg,
|
double *read_time_arg,
|
||||||
double *record_count_arg)
|
double *record_count_arg)
|
||||||
@@ -6057,14 +6057,14 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
|
|||||||
double sj_inner_fanout= 1.0;
|
double sj_inner_fanout= 1.0;
|
||||||
JOIN_TAB *end_tab= NULL;
|
JOIN_TAB *end_tab= NULL;
|
||||||
JOIN_TAB *tab;
|
JOIN_TAB *tab;
|
||||||
uint i;
|
int i;
|
||||||
uint last_sj_table= MAX_TABLES;
|
int last_sj_table= MAX_TABLES;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Handle a special case where the join is degenerate, and produces no
|
Handle a special case where the join is degenerate, and produces no
|
||||||
records
|
records
|
||||||
*/
|
*/
|
||||||
if (table_count == 0)
|
if (table_count == const_tables)
|
||||||
{
|
{
|
||||||
*read_time_arg= 0.0;
|
*read_time_arg= 0.0;
|
||||||
/*
|
/*
|
||||||
@@ -6074,6 +6074,7 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
|
|||||||
calculations.
|
calculations.
|
||||||
*/
|
*/
|
||||||
*record_count_arg=1.0;
|
*record_count_arg=1.0;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (tab= first_depth_first_tab(this), i= const_tables;
|
for (tab= first_depth_first_tab(this), i= const_tables;
|
||||||
@@ -6086,19 +6087,17 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (tab= first_depth_first_tab(this), i= const_tables;
|
for (tab= first_depth_first_tab(this), i= const_tables;
|
||||||
(i <= end_tab_idx && tab);
|
;
|
||||||
tab= next_depth_first_tab(this, tab), i++)
|
tab= next_depth_first_tab(this, tab), i++)
|
||||||
|
{
|
||||||
|
if (end_tab->bush_root_tab && end_tab->bush_root_tab == tab)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We've entered the SJM nest that contains the end_tab. The caller is
|
We've entered the SJM nest that contains the end_tab. The caller is
|
||||||
actually
|
|
||||||
- interested in fanout inside the nest (because that's how many times
|
- interested in fanout inside the nest (because that's how many times
|
||||||
we'll invoke the attached WHERE conditions)
|
we'll invoke the attached WHERE conditions)
|
||||||
- not interested in cost
|
- not interested in cost
|
||||||
*/
|
*/
|
||||||
if (end_tab->bush_root_tab && end_tab->bush_root_tab == tab)
|
|
||||||
{
|
|
||||||
/* Ok, end_tab is inside SJM nest and we're entering that nest now */
|
|
||||||
record_count= 1.0;
|
record_count= 1.0;
|
||||||
read_time= 0.0;
|
read_time= 0.0;
|
||||||
}
|
}
|
||||||
@@ -6113,7 +6112,17 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
|
|||||||
last_sj_table= i + tab->n_sj_tables;
|
last_sj_table= i + tab->n_sj_tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tab->records_read && (tab->table->map & filter_map))
|
table_map cur_table_map;
|
||||||
|
if (tab->table)
|
||||||
|
cur_table_map= tab->table->map;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is a SJ-Materialization nest. Check all of its tables */
|
||||||
|
TABLE *first_child= tab->bush_children->start->table;
|
||||||
|
TABLE_LIST *sjm_nest= first_child->pos_in_table_list->embedding;
|
||||||
|
cur_table_map= sjm_nest->nested_join->used_tables;
|
||||||
|
}
|
||||||
|
if (tab->records_read && (cur_table_map & filter_map))
|
||||||
{
|
{
|
||||||
record_count *= tab->records_read;
|
record_count *= tab->records_read;
|
||||||
read_time += tab->read_time;
|
read_time += tab->read_time;
|
||||||
@@ -6127,6 +6136,9 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
|
|||||||
sj_inner_fanout= 1.0;
|
sj_inner_fanout= 1.0;
|
||||||
last_sj_table= MAX_TABLES;
|
last_sj_table= MAX_TABLES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tab == end_tab)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
*read_time_arg= read_time;// + record_count / TIME_FOR_COMPARE;
|
*read_time_arg= read_time;// + record_count / TIME_FOR_COMPARE;
|
||||||
*record_count_arg= record_count;
|
*record_count_arg= record_count;
|
||||||
@@ -6615,7 +6627,7 @@ int JOIN_TAB::make_scan_filter()
|
|||||||
if (cond &&
|
if (cond &&
|
||||||
(tmp= make_cond_for_table(join->thd, cond,
|
(tmp= make_cond_for_table(join->thd, cond,
|
||||||
join->const_table_map | table->map,
|
join->const_table_map | table->map,
|
||||||
table->map, MAX_TABLES, FALSE, TRUE)))
|
table->map, -1, FALSE, TRUE)))
|
||||||
{
|
{
|
||||||
DBUG_EXECUTE("where",print_where(tmp,"cache", QT_ORDINARY););
|
DBUG_EXECUTE("where",print_where(tmp,"cache", QT_ORDINARY););
|
||||||
if (!(cache_select=
|
if (!(cache_select=
|
||||||
@@ -7087,6 +7099,7 @@ get_best_combination(JOIN *join)
|
|||||||
goto loop_end; // Handled in make_join_stat..
|
goto loop_end; // Handled in make_join_stat..
|
||||||
|
|
||||||
j->loosescan_match_tab= NULL; //non-nulls will be set later
|
j->loosescan_match_tab= NULL; //non-nulls will be set later
|
||||||
|
j->inside_loosescan_range= FALSE;
|
||||||
j->ref.key = -1;
|
j->ref.key = -1;
|
||||||
j->ref.key_parts=0;
|
j->ref.key_parts=0;
|
||||||
|
|
||||||
@@ -7901,7 +7914,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
join->exec_const_cond=
|
join->exec_const_cond=
|
||||||
make_cond_for_table(thd, cond,
|
make_cond_for_table(thd, cond,
|
||||||
join->const_table_map,
|
join->const_table_map,
|
||||||
(table_map) 0, MAX_TABLES, FALSE, FALSE);
|
(table_map) 0, -1, FALSE, FALSE);
|
||||||
/* Add conditions added by add_not_null_conds(). */
|
/* Add conditions added by add_not_null_conds(). */
|
||||||
for (uint i= 0 ; i < join->const_tables ; i++)
|
for (uint i= 0 ; i < join->const_tables ; i++)
|
||||||
add_cond_and_fix(thd, &join->exec_const_cond,
|
add_cond_and_fix(thd, &join->exec_const_cond,
|
||||||
@@ -7920,7 +7933,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
COND *outer_ref_cond= make_cond_for_table(thd, cond,
|
COND *outer_ref_cond= make_cond_for_table(thd, cond,
|
||||||
OUTER_REF_TABLE_BIT,
|
OUTER_REF_TABLE_BIT,
|
||||||
OUTER_REF_TABLE_BIT,
|
OUTER_REF_TABLE_BIT,
|
||||||
MAX_TABLES, FALSE, FALSE);
|
-1, FALSE, FALSE);
|
||||||
if (outer_ref_cond)
|
if (outer_ref_cond)
|
||||||
{
|
{
|
||||||
add_cond_and_fix(thd, &outer_ref_cond, join->outer_ref_cond);
|
add_cond_and_fix(thd, &outer_ref_cond, join->outer_ref_cond);
|
||||||
@@ -8090,7 +8103,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
{
|
{
|
||||||
COND *push_cond=
|
COND *push_cond=
|
||||||
make_cond_for_table(thd, tmp, current_map, current_map,
|
make_cond_for_table(thd, tmp, current_map, current_map,
|
||||||
MAX_TABLES, FALSE, FALSE);
|
-1, FALSE, FALSE);
|
||||||
if (push_cond)
|
if (push_cond)
|
||||||
{
|
{
|
||||||
/* Push condition to handler */
|
/* Push condition to handler */
|
||||||
@@ -8262,7 +8275,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
JOIN_TAB *cond_tab= join_tab->first_inner;
|
JOIN_TAB *cond_tab= join_tab->first_inner;
|
||||||
COND *tmp= make_cond_for_table(thd, *join_tab->on_expr_ref,
|
COND *tmp= make_cond_for_table(thd, *join_tab->on_expr_ref,
|
||||||
join->const_table_map,
|
join->const_table_map,
|
||||||
(table_map) 0, MAX_TABLES, FALSE, FALSE);
|
(table_map) 0, -1, FALSE, FALSE);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
continue;
|
continue;
|
||||||
tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
|
tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
|
||||||
@@ -8308,10 +8321,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||||||
current_map= tab->table->map;
|
current_map= tab->table->map;
|
||||||
used_tables2|= current_map;
|
used_tables2|= current_map;
|
||||||
/*
|
/*
|
||||||
psergey: have put the MAX_TABLES below. It's bad, will need to fix it.
|
psergey: have put the -1 below. It's bad, will need to fix it.
|
||||||
*/
|
*/
|
||||||
COND *tmp_cond= make_cond_for_table(thd, on_expr, used_tables2,
|
COND *tmp_cond= make_cond_for_table(thd, on_expr, used_tables2,
|
||||||
current_map, /*(tab - first_tab)*/ MAX_TABLES,
|
current_map, /*(tab - first_tab)*/ -1,
|
||||||
FALSE, FALSE);
|
FALSE, FALSE);
|
||||||
if (tab == first_inner_tab && tab->on_precond)
|
if (tab == first_inner_tab && tab->on_precond)
|
||||||
add_cond_and_fix(thd, &tmp_cond, tab->on_precond);
|
add_cond_and_fix(thd, &tmp_cond, tab->on_precond);
|
||||||
@@ -8972,6 +8985,15 @@ uint check_join_cache_usage(JOIN_TAB *tab,
|
|||||||
if (tab->use_quick == 2)
|
if (tab->use_quick == 2)
|
||||||
goto no_join_cache;
|
goto no_join_cache;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Don't use join cache if we're inside a join tab range covered by LooseScan
|
||||||
|
strategy (TODO: LooseScan is very similar to FirstMatch so theoretically it
|
||||||
|
should be possible to use join buffering in the same way we're using it for
|
||||||
|
multi-table firstmatch ranges).
|
||||||
|
*/
|
||||||
|
if (tab->inside_loosescan_range)
|
||||||
|
goto no_join_cache;
|
||||||
|
|
||||||
if (tab->is_inner_table_of_semi_join_with_first_match() &&
|
if (tab->is_inner_table_of_semi_join_with_first_match() &&
|
||||||
!join->allowed_semijoin_with_cache)
|
!join->allowed_semijoin_with_cache)
|
||||||
goto no_join_cache;
|
goto no_join_cache;
|
||||||
@@ -16684,7 +16706,7 @@ bool test_if_ref(Item *root_cond, Item_field *left_item,Item *right_item)
|
|||||||
static Item *
|
static Item *
|
||||||
make_cond_for_table(THD *thd, Item *cond, table_map tables,
|
make_cond_for_table(THD *thd, Item *cond, table_map tables,
|
||||||
table_map used_table,
|
table_map used_table,
|
||||||
uint join_tab_idx_arg,
|
int join_tab_idx_arg,
|
||||||
bool exclude_expensive_cond __attribute__((unused)),
|
bool exclude_expensive_cond __attribute__((unused)),
|
||||||
bool retain_ref_cond)
|
bool retain_ref_cond)
|
||||||
{
|
{
|
||||||
@@ -16698,7 +16720,7 @@ make_cond_for_table(THD *thd, Item *cond, table_map tables,
|
|||||||
static Item *
|
static Item *
|
||||||
make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
|
make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
|
||||||
table_map tables, table_map used_table,
|
table_map tables, table_map used_table,
|
||||||
uint join_tab_idx_arg,
|
int join_tab_idx_arg,
|
||||||
bool exclude_expensive_cond __attribute__
|
bool exclude_expensive_cond __attribute__
|
||||||
((unused)),
|
((unused)),
|
||||||
bool retain_ref_cond)
|
bool retain_ref_cond)
|
||||||
|
@@ -348,6 +348,9 @@ typedef struct st_join_table {
|
|||||||
*/
|
*/
|
||||||
struct st_join_table *loosescan_match_tab;
|
struct st_join_table *loosescan_match_tab;
|
||||||
|
|
||||||
|
/* TRUE <=> we are inside LooseScan range */
|
||||||
|
bool inside_loosescan_range;
|
||||||
|
|
||||||
/* Buffer to save index tuple to be able to skip duplicates */
|
/* Buffer to save index tuple to be able to skip duplicates */
|
||||||
uchar *loosescan_buf;
|
uchar *loosescan_buf;
|
||||||
|
|
||||||
@@ -1154,7 +1157,7 @@ public:
|
|||||||
max_allowed_join_cache_level > JOIN_CACHE_HASHED_BIT;
|
max_allowed_join_cache_level > JOIN_CACHE_HASHED_BIT;
|
||||||
}
|
}
|
||||||
bool choose_subquery_plan(table_map join_tables);
|
bool choose_subquery_plan(table_map join_tables);
|
||||||
void get_partial_cost_and_fanout(uint end_tab_idx,
|
void get_partial_cost_and_fanout(int end_tab_idx,
|
||||||
table_map filter_map,
|
table_map filter_map,
|
||||||
double *read_time_arg,
|
double *read_time_arg,
|
||||||
double *record_count_arg);
|
double *record_count_arg);
|
||||||
|
Reference in New Issue
Block a user