Commit 1050c564 authored by Igor Babaev's avatar Igor Babaev

Back-ported the fix and test cases for bugs #59487 and #43368 from

the mysql-5.6 code line.
parent d9e5cdd1
...@@ -1240,3 +1240,52 @@ f1 MIN(f2) ...@@ -1240,3 +1240,52 @@ f1 MIN(f2)
drop table t1,t2; drop table t1,t2;
drop view v1,v2; drop view v1,v2;
End of 5.1 tests End of 5.1 tests
#
# Bug #43368: STRAIGHT_JOIN DOESN'T WORK FOR NESTED JOINS
#
create table t1(c1 int primary key, c2 char(10)) engine=myisam;
create table t2(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam;
create table t3(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam;
create table t4(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam;
insert into t1 values(1,'a');
insert into t2 values(1,'a', 1);
insert into t3 values(1,'a', 1);
insert into t3 values(2,'b',2);
insert into t4 values(1,'a', 1);
insert into t4 values(2,'a', 2);
insert into t4 values(3,'a', 3);
insert into t4 values(4,'a', 4);
insert into t1 values(2,'b');
insert into t1 values(3,'c');
EXPLAIN
SELECT *
FROM t4 JOIN
(t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1)
ON t4.ref_t1=t1.c1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 system NULL NULL NULL NULL 1
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
1 SIMPLE t4 ALL NULL NULL NULL NULL 4 Using where; Using join buffer
EXPLAIN
SELECT STRAIGHT_JOIN *
FROM t4 JOIN
(t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1)
ON t4.ref_t1=t1.c1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 4
1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 3 Using where; Using join buffer
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer
1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer
EXPLAIN
SELECT *
FROM t4 STRAIGHT_JOIN
(t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1)
ON t4.ref_t1=t1.c1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 4
1 SIMPLE t2 ALL NULL NULL NULL NULL 1 Using where; Using join buffer
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t4.ref_t1 1
drop table t1,t2,t3,t4;
End of 5.2 tests
...@@ -25,3 +25,130 @@ WHERE (t1.b NOT BETWEEN 1 AND 7 OR t1.a IS NULL AND t1.b = t2.b) AND t2.b = 4 ...@@ -25,3 +25,130 @@ WHERE (t1.b NOT BETWEEN 1 AND 7 OR t1.a IS NULL AND t1.b = t2.b) AND t2.b = 4
GROUP BY 1; GROUP BY 1;
a a
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
Bug #59487: WRONG RESULT WITH STRAIGHT_JOIN AND RIGHT JOIN
#
CREATE TABLE t1 (
pk int(11) NOT NULL,
col_varchar_10_latin1_key varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t1 VALUES (1,'1');
CREATE TABLE t2 (
pk int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t2 VALUES (1);
CREATE TABLE t3 (
pk int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t3 VALUES (1);
CREATE TABLE t4 (
pk int(11) NOT NULL,
col_int int(11) DEFAULT NULL,
col_int_key int(11) DEFAULT NULL,
col_varchar_10_latin1_key varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t4 VALUES (1,1,1,'1');
CREATE TABLE t5 (
col_int int(11) DEFAULT NULL,
col_varchar_10_utf8_key varchar(10) CHARACTER SET utf8 DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t5 VALUES (1,'1');
CREATE TABLE t6 (
col_int_key int(11) DEFAULT NULL,
col_varchar_10_latin1_key varchar(10) DEFAULT NULL,
pk int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t6 VALUES (1,'1',1);
SELECT STRAIGHT_JOIN t6a.pk, t2.pk
FROM t6 AS t6a
LEFT JOIN
(
t2
RIGHT JOIN
(
(t1 LEFT JOIN (t4 JOIN t3 ON t4.col_int) ON t4.col_int_key = t1.pk)
LEFT JOIN
(t5 JOIN t6 AS t6b
ON t5.col_varchar_10_utf8_key = t6b.col_varchar_10_latin1_key)
ON t1.pk = t5.col_int
)
ON t4.col_varchar_10_latin1_key = t1.col_varchar_10_latin1_key
AND t5.col_varchar_10_utf8_key = 0
)
ON t6a.pk IS TRUE
WHERE t6b.col_int_key IS TRUE;
pk pk
1 NULL
EXPLAIN SELECT STRAIGHT_JOIN t6a.pk, t2.pk
FROM t6 AS t6a
LEFT JOIN
(
t2
RIGHT JOIN
(
(t1 LEFT JOIN (t4 JOIN t3 ON t4.col_int) ON t4.col_int_key = t1.pk)
LEFT JOIN
(t5 JOIN t6 AS t6b
ON t5.col_varchar_10_utf8_key = t6b.col_varchar_10_latin1_key)
ON t1.pk = t5.col_int
)
ON t4.col_varchar_10_latin1_key = t1.col_varchar_10_latin1_key
AND t5.col_varchar_10_utf8_key = 0
)
ON t6a.pk IS TRUE
WHERE t6b.col_int_key IS TRUE;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t6a ALL NULL NULL NULL NULL 1 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer
1 SIMPLE t4 ALL NULL NULL NULL NULL 1
1 SIMPLE t3 ALL NULL NULL NULL NULL 1
1 SIMPLE t5 ALL NULL NULL NULL NULL 1 Using where; Using join buffer
1 SIMPLE t6b ALL NULL NULL NULL NULL 1 Using where; Using join buffer
1 SIMPLE t2 ALL NULL NULL NULL NULL 1
SELECT t6a.pk, t2.pk
FROM t6 AS t6a
LEFT JOIN
(
t2
RIGHT JOIN
(
(t1 LEFT JOIN (t4 JOIN t3 ON t4.col_int) ON t4.col_int_key = t1.pk)
LEFT JOIN
(t5 JOIN t6 AS t6b
ON t5.col_varchar_10_utf8_key = t6b.col_varchar_10_latin1_key)
ON t1.pk = t5.col_int
)
ON t4.col_varchar_10_latin1_key = t1.col_varchar_10_latin1_key
AND t5.col_varchar_10_utf8_key = 0
)
ON t6a.pk IS TRUE
WHERE t6b.col_int_key IS TRUE;
pk pk
1 NULL
EXPLAIN SELECT t6a.pk, t2.pk
FROM t6 AS t6a
LEFT JOIN
(
t2
RIGHT JOIN
(
(t1 LEFT JOIN (t4 JOIN t3 ON t4.col_int) ON t4.col_int_key = t1.pk)
LEFT JOIN
(t5 JOIN t6 AS t6b
ON t5.col_varchar_10_utf8_key = t6b.col_varchar_10_latin1_key)
ON t1.pk = t5.col_int
)
ON t4.col_varchar_10_latin1_key = t1.col_varchar_10_latin1_key
AND t5.col_varchar_10_utf8_key = 0
)
ON t6a.pk IS TRUE
WHERE t6b.col_int_key IS TRUE;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t6a ALL NULL NULL NULL NULL 1 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer
1 SIMPLE t4 ALL NULL NULL NULL NULL 1
1 SIMPLE t3 ALL NULL NULL NULL NULL 1
1 SIMPLE t5 ALL NULL NULL NULL NULL 1 Using where; Using join buffer
1 SIMPLE t2 ALL NULL NULL NULL NULL 1
1 SIMPLE t6b ALL NULL NULL NULL NULL 1 Using where; Using join buffer
drop table t1,t2,t3,t4,t5,t6;
...@@ -4817,10 +4817,10 @@ SET SESSION join_buffer_size = 9000; ...@@ -4817,10 +4817,10 @@ SET SESSION join_buffer_size = 9000;
EXPLAIN EXPLAIN
SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
1 SIMPLE t2 ALL NULL NULL NULL NULL 12 1 SIMPLE t2 ALL NULL NULL NULL NULL 12
1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer
1 SIMPLE t3 ALL NULL NULL NULL NULL 1 1 SIMPLE t3 ALL NULL NULL NULL NULL 1
1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 const 1 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 test.t1.f1 1
1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer
1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer 1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer
SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6;
......
...@@ -4817,10 +4817,10 @@ SET SESSION join_buffer_size = 9000; ...@@ -4817,10 +4817,10 @@ SET SESSION join_buffer_size = 9000;
EXPLAIN EXPLAIN
SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
1 SIMPLE t2 ALL NULL NULL NULL NULL 12 1 SIMPLE t2 ALL NULL NULL NULL NULL 12
1 SIMPLE t1 ALL NULL NULL NULL NULL 1 Using join buffer
1 SIMPLE t3 ALL NULL NULL NULL NULL 1 1 SIMPLE t3 ALL NULL NULL NULL NULL 1
1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 const 1 1 SIMPLE t4 eq_ref PRIMARY PRIMARY 4 test.t1.f1 1
1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer 1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer
1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer 1 SIMPLE t6 ALL NULL NULL NULL NULL 2 Using join buffer
SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6; SELECT STRAIGHT_JOIN * FROM t2, (t1 LEFT JOIN (t3,t4) ON t1.f1 = t4.f1), t5, t6;
......
...@@ -938,5 +938,45 @@ SELECT f1 , MIN(f2) FROM v2 GROUP BY f1; ...@@ -938,5 +938,45 @@ SELECT f1 , MIN(f2) FROM v2 GROUP BY f1;
drop table t1,t2; drop table t1,t2;
drop view v1,v2; drop view v1,v2;
--echo End of 5.1 tests --echo End of 5.1 tests
--echo #
--echo # Bug #43368: STRAIGHT_JOIN DOESN'T WORK FOR NESTED JOINS
--echo #
create table t1(c1 int primary key, c2 char(10)) engine=myisam;
create table t2(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam;
create table t3(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam;
create table t4(c1 int primary key, c2 char(10), ref_t1 int) engine=myisam;
insert into t1 values(1,'a');
insert into t2 values(1,'a', 1);
insert into t3 values(1,'a', 1);
insert into t3 values(2,'b',2);
insert into t4 values(1,'a', 1);
insert into t4 values(2,'a', 2);
insert into t4 values(3,'a', 3);
insert into t4 values(4,'a', 4);
insert into t1 values(2,'b');
insert into t1 values(3,'c');
EXPLAIN
SELECT *
FROM t4 JOIN
(t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1)
ON t4.ref_t1=t1.c1;
EXPLAIN
SELECT STRAIGHT_JOIN *
FROM t4 JOIN
(t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1)
ON t4.ref_t1=t1.c1;
EXPLAIN
SELECT *
FROM t4 STRAIGHT_JOIN
(t1 JOIN t3 ON t3.ref_t1=t1.c1 JOIN t2 ON t2.ref_t1=t1.c1)
ON t4.ref_t1=t1.c1;
drop table t1,t2,t3,t4;
--echo End of 5.2 tests
...@@ -39,3 +39,70 @@ SELECT STRAIGHT_JOIN t1.a FROM t1 RIGHT JOIN t2 ON t1.b = t2.b ...@@ -39,3 +39,70 @@ SELECT STRAIGHT_JOIN t1.a FROM t1 RIGHT JOIN t2 ON t1.b = t2.b
GROUP BY 1; GROUP BY 1;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo Bug #59487: WRONG RESULT WITH STRAIGHT_JOIN AND RIGHT JOIN
--echo #
CREATE TABLE t1 (
pk int(11) NOT NULL,
col_varchar_10_latin1_key varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t1 VALUES (1,'1');
CREATE TABLE t2 (
pk int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t2 VALUES (1);
CREATE TABLE t3 (
pk int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t3 VALUES (1);
CREATE TABLE t4 (
pk int(11) NOT NULL,
col_int int(11) DEFAULT NULL,
col_int_key int(11) DEFAULT NULL,
col_varchar_10_latin1_key varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t4 VALUES (1,1,1,'1');
CREATE TABLE t5 (
col_int int(11) DEFAULT NULL,
col_varchar_10_utf8_key varchar(10) CHARACTER SET utf8 DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t5 VALUES (1,'1');
CREATE TABLE t6 (
col_int_key int(11) DEFAULT NULL,
col_varchar_10_latin1_key varchar(10) DEFAULT NULL,
pk int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO t6 VALUES (1,'1',1);
# EXPLAIN of query above (t2 is before t5 in plan)
let $rest_of_query=t6a.pk, t2.pk
FROM t6 AS t6a
LEFT JOIN
(
t2
RIGHT JOIN
(
(t1 LEFT JOIN (t4 JOIN t3 ON t4.col_int) ON t4.col_int_key = t1.pk)
LEFT JOIN
(t5 JOIN t6 AS t6b
ON t5.col_varchar_10_utf8_key = t6b.col_varchar_10_latin1_key)
ON t1.pk = t5.col_int
)
ON t4.col_varchar_10_latin1_key = t1.col_varchar_10_latin1_key
AND t5.col_varchar_10_utf8_key = 0
)
ON t6a.pk IS TRUE
WHERE t6b.col_int_key IS TRUE;
eval SELECT STRAIGHT_JOIN $rest_of_query;
eval EXPLAIN SELECT STRAIGHT_JOIN $rest_of_query;
# right result (same query, just remove STRAIGHT_JOIN):
eval SELECT $rest_of_query;
eval EXPLAIN SELECT $rest_of_query;
drop table t1,t2,t3,t4,t5,t6;
...@@ -9067,6 +9067,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top) ...@@ -9067,6 +9067,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
if (!tbl->embedding && !tbl->on_expr && tbl->table) if (!tbl->embedding && !tbl->on_expr && tbl->table)
tbl->table->maybe_null= FALSE; tbl->table->maybe_null= FALSE;
tbl->join_list= table->join_list; tbl->join_list= table->join_list;
tbl->dep_tables|= table->dep_tables;
} }
li.replace(nested_join->join_list); li.replace(nested_join->join_list);
/* Need to update the name resolution table chain when flattening joins */ /* Need to update the name resolution table chain when flattening joins */
......
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