diff options
-rw-r--r-- | mysql-test/r/join_cache.result | 43 | ||||
-rwxr-xr-x | mysql-test/t/join_cache.test | 48 | ||||
-rwxr-xr-x | sql/sql_select.cc | 13 |
3 files changed, 101 insertions, 3 deletions
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index f19243961b8..975df707400 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -5173,7 +5173,6 @@ a b 2 2 set join_cache_level=default; drop table t1,t2,t3; -set @@optimizer_switch=@save_optimizer_switch; # # Bug #52394: using join buffer for 3 table join with ref access # LP #623209: and no references to the columns of the middle table @@ -5202,3 +5201,45 @@ a 27 DROP TABLE t1,t2,t3; set join_cache_level=default; +# +# Bug#51084: Batched key access crashes for SELECT with +# derived table and LEFT JOIN +# +CREATE TABLE t1 ( +carrier int, +id int PRIMARY KEY +); +INSERT INTO t1 VALUES (1,11),(1,12),(2,13); +CREATE TABLE t2 ( +scan_date int, +package_id int +); +INSERT INTO t2 VALUES (2008,21),(2008,22); +CREATE TABLE t3 ( +carrier int PRIMARY KEY, +id int +); +INSERT INTO t3 VALUES (1,31); +CREATE TABLE t4 ( +carrier_id int, +INDEX carrier_id(carrier_id) +); +INSERT INTO t4 VALUES (31),(32); +SET join_cache_level=8; +SELECT COUNT(*) +FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id) +ON t3.carrier = t1.carrier; +COUNT(*) +6 +EXPLAIN +SELECT COUNT(*) +FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id) +ON t3.carrier = t1.carrier; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.carrier 1 +1 SIMPLE t4 ref carrier_id carrier_id 5 test.t3.id 2 Using index +SET join_cache_level=default; +DROP TABLE t1,t2,t3,t4; +set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 7bc22fd4f23..f65f521f21a 100755 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -1955,8 +1955,6 @@ set join_cache_level=default; drop table t1,t2,t3; -set @@optimizer_switch=@save_optimizer_switch; - --echo # --echo # Bug #52394: using join buffer for 3 table join with ref access --echo # LP #623209: and no references to the columns of the middle table @@ -1984,3 +1982,49 @@ DROP TABLE t1,t2,t3; set join_cache_level=default; +--echo # +--echo # Bug#51084: Batched key access crashes for SELECT with +--echo # derived table and LEFT JOIN +--echo # + +CREATE TABLE t1 ( + carrier int, + id int PRIMARY KEY +); +INSERT INTO t1 VALUES (1,11),(1,12),(2,13); + +CREATE TABLE t2 ( + scan_date int, + package_id int +); +INSERT INTO t2 VALUES (2008,21),(2008,22); + +CREATE TABLE t3 ( + carrier int PRIMARY KEY, + id int +); +INSERT INTO t3 VALUES (1,31); + +CREATE TABLE t4 ( + carrier_id int, + INDEX carrier_id(carrier_id) +); +INSERT INTO t4 VALUES (31),(32); + +SET join_cache_level=8; + +SELECT COUNT(*) + FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id) + ON t3.carrier = t1.carrier; + +EXPLAIN +SELECT COUNT(*) + FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id) + ON t3.carrier = t1.carrier; + +SET join_cache_level=default; + +DROP TABLE t1,t2,t3,t4; + +# this must be the last command in the file +set @@optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7ccbd8689a9..be11e9a6c39 100755 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7202,6 +7202,19 @@ void set_join_cache_denial(JOIN_TAB *join_tab) { if (join_tab->cache) { + /* + If there is a previous cache linked to this cache through the + next_cache pointer: remove the link. + */ + if (join_tab->cache->prev_cache) + join_tab->cache->prev_cache->next_cache= 0; + /* + No need to do the same for next_cache since cache denial is done + backwards starting from the latest cache in the linked list (see + revise_cache_usage()). + */ + DBUG_ASSERT(!join_tab->cache->next_cache); + join_tab->cache->free(); join_tab->cache= 0; } |