summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/join_cache.result43
-rwxr-xr-xmysql-test/t/join_cache.test48
-rwxr-xr-xsql/sql_select.cc13
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;
}