Skip to content

Commit

Permalink
MDEV-16726 Assertion `tab->type == JT_REF || tab->type == JT_EQ_REF' …
Browse files Browse the repository at this point in the history
…failed

Due to a legacy bug in the code of make_join_statistics() detecting
so-called constant tables could miss some of them in rare queries
that used RIGHT JOIN. As a result these queries had execution plans
different from the execution plans of the equivalent queries with
LEFT JOIN.
Besides starting from 10.2 this could trigger an assertion failure.
  • Loading branch information
igorbabaev committed Jul 19, 2018
1 parent 8c45eb3 commit 9cea4cc
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 3 deletions.
50 changes: 50 additions & 0 deletions mysql-test/r/join_outer.result
Expand Up @@ -2368,5 +2368,55 @@ id sid id
1 NULL NULL
2 NULL NULL
drop table t1, t2;
#
# MDEV-16726: SELECT with STRAGHT JOIN containing NESTED RIGHT JOIN
# converted to INNER JOIN with first constant inner table
#
CREATE TABLE t1 (
pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1), KEY v1 (v1,i1)
) engine=MyISAM;
INSERT INTO t1 VALUES
(8,3,'c','c'),(9,4,'z','z'),(10,3,'i','i'),(11,186,'x','x'),
(14,226,'m','m'),(15,133,'p','p');
CREATE TABLE t2 (
pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1)
) engine=MyISAM;
INSERT INTO t2 VALUES (10,6,'p','p');
EXPLAIN EXTENDED
SELECT STRAIGHT_JOIN t2.v2
FROM
(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2)
RIGHT JOIN
(t2,t1)
ON t1.pk = t2.pk AND t2.v2 = tb1.v1
WHERE tb1.pk = 40
ORDER BY tb1.i1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(`test`.`tb2`.`v1`, NULL)) where 0 order by NULL
EXPLAIN EXTENDED
SELECT STRAIGHT_JOIN t2.v2
FROM
(t2,t1)
LEFT JOIN
(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2)
ON t1.pk = t2.pk AND t2.v2 = tb1.v1
WHERE tb1.pk = 40
ORDER BY tb1.i1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(`test`.`tb2`.`v1`, NULL)) where 0 order by NULL
SELECT STRAIGHT_JOIN DISTINCT t2.v2
FROM
(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2)
RIGHT JOIN
(t2,t1)
ON t1.pk = t2.pk AND t2.v2 = tb1.v1
WHERE tb1.pk = 40
ORDER BY tb1.i1;
v2
DROP TABLE t1,t2;
# end of 5.5 tests
SET optimizer_switch=@save_optimizer_switch;
50 changes: 50 additions & 0 deletions mysql-test/r/join_outer_jcl6.result
Expand Up @@ -2379,6 +2379,56 @@ id sid id
1 NULL NULL
2 NULL NULL
drop table t1, t2;
#
# MDEV-16726: SELECT with STRAGHT JOIN containing NESTED RIGHT JOIN
# converted to INNER JOIN with first constant inner table
#
CREATE TABLE t1 (
pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1), KEY v1 (v1,i1)
) engine=MyISAM;
INSERT INTO t1 VALUES
(8,3,'c','c'),(9,4,'z','z'),(10,3,'i','i'),(11,186,'x','x'),
(14,226,'m','m'),(15,133,'p','p');
CREATE TABLE t2 (
pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1)
) engine=MyISAM;
INSERT INTO t2 VALUES (10,6,'p','p');
EXPLAIN EXTENDED
SELECT STRAIGHT_JOIN t2.v2
FROM
(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2)
RIGHT JOIN
(t2,t1)
ON t1.pk = t2.pk AND t2.v2 = tb1.v1
WHERE tb1.pk = 40
ORDER BY tb1.i1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(`test`.`tb2`.`v1`, NULL)) where 0 order by NULL
EXPLAIN EXTENDED
SELECT STRAIGHT_JOIN t2.v2
FROM
(t2,t1)
LEFT JOIN
(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2)
ON t1.pk = t2.pk AND t2.v2 = tb1.v1
WHERE tb1.pk = 40
ORDER BY tb1.i1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(`test`.`tb2`.`v1`, NULL)) where 0 order by NULL
SELECT STRAIGHT_JOIN DISTINCT t2.v2
FROM
(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2)
RIGHT JOIN
(t2,t1)
ON t1.pk = t2.pk AND t2.v2 = tb1.v1
WHERE tb1.pk = 40
ORDER BY tb1.i1;
v2
DROP TABLE t1,t2;
# end of 5.5 tests
SET optimizer_switch=@save_optimizer_switch;
set join_cache_level=default;
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/r/subselect_mat_cost_bugs.result
Expand Up @@ -442,7 +442,7 @@ SELECT i2 FROM t2 RIGHT JOIN t3 ON (c3 = c2) WHERE pk3 = i1
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
2 DEPENDENT SUBQUERY t3 const PRIMARY PRIMARY 4 const 1
2 DEPENDENT SUBQUERY t2 index NULL i2 11 NULL 2 Using where; Using index
2 DEPENDENT SUBQUERY t2 index i2 i2 11 NULL 2 Using where; Using index
DROP TABLE t1,t2,t3;
#
# MDEV-7599: in-to-exists chosen after min/max optimization
Expand Down
48 changes: 48 additions & 0 deletions mysql-test/t/join_outer.test
Expand Up @@ -1911,6 +1911,54 @@ select * from t1 t
on t.id=r.id ;
drop table t1, t2;

--echo #
--echo # MDEV-16726: SELECT with STRAGHT JOIN containing NESTED RIGHT JOIN
--echo # converted to INNER JOIN with first constant inner table
--echo #

CREATE TABLE t1 (
pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1), KEY v1 (v1,i1)
) engine=MyISAM;
INSERT INTO t1 VALUES
(8,3,'c','c'),(9,4,'z','z'),(10,3,'i','i'),(11,186,'x','x'),
(14,226,'m','m'),(15,133,'p','p');

CREATE TABLE t2 (
pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1)
) engine=MyISAM;
INSERT INTO t2 VALUES (10,6,'p','p');

EXPLAIN EXTENDED
SELECT STRAIGHT_JOIN t2.v2
FROM
(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2)
RIGHT JOIN
(t2,t1)
ON t1.pk = t2.pk AND t2.v2 = tb1.v1
WHERE tb1.pk = 40
ORDER BY tb1.i1;

EXPLAIN EXTENDED
SELECT STRAIGHT_JOIN t2.v2
FROM
(t2,t1)
LEFT JOIN
(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2)
ON t1.pk = t2.pk AND t2.v2 = tb1.v1
WHERE tb1.pk = 40
ORDER BY tb1.i1;

SELECT STRAIGHT_JOIN DISTINCT t2.v2
FROM
(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2)
RIGHT JOIN
(t2,t1)
ON t1.pk = t2.pk AND t2.v2 = tb1.v1
WHERE tb1.pk = 40
ORDER BY tb1.i1;

DROP TABLE t1,t2;

--echo # end of 5.5 tests

SET optimizer_switch=@save_optimizer_switch;
4 changes: 2 additions & 2 deletions sql/sql_select.cc
Expand Up @@ -3456,8 +3456,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
int ref_changed;
do
{
more_const_tables_found:
ref_changed = 0;
more_const_tables_found:
found_ref=0;

/*
Expand Down Expand Up @@ -3622,7 +3622,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
}
}
}
} while (join->const_table_map & found_ref && ref_changed);
} while (ref_changed);

join->sort_by_table= get_sort_by_table(join->order, join->group_list,
join->select_lex->leaf_tables,
Expand Down

0 comments on commit 9cea4cc

Please sign in to comment.