diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index b7724c316f9..0c9c98e4b59 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -4998,9 +4998,9 @@ id1 num3 text1 id4 id3 dummy 228808822 18 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0 228808822 1 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0 228808822 3 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0 -228808822 4 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0 228808822 17 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0 228808822 50 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0 +228808822 4 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 826928662 935693782 0 228808822 89 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 228808822 19 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 228808822 9 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 @@ -5009,9 +5009,9 @@ id1 num3 text1 id4 id3 dummy 228808822 1 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 228808822 10 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 228808822 26 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 +228808822 4 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 228808822 3 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 228808822 1 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 -228808822 4 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 228808822 3 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 228808822 28 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 228808822 62 CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC 2381969632 2482416112 0 @@ -5202,8 +5202,8 @@ a DROP TABLE t1,t2,t3; set join_cache_level=default; # -# Bug#51084: Batched key access crashes for SELECT with -# derived table and LEFT JOIN +# Bug #51084: Batched key access crashes for SELECT with +# derived table and LEFT JOIN # CREATE TABLE t1 ( carrier int, @@ -5243,7 +5243,7 @@ id select_type table type possible_keys key key_len ref rows Extra SET join_cache_level=default; DROP TABLE t1,t2,t3,t4; # -# BUG#52636: allowing JOINs on NULL values w/ join_cache_level = 5-8 +# Bug #52636: allowing JOINs on NULL values w/ join_cache_level = 5-8 # CREATE TABLE t1 (b int); INSERT INTO t1 VALUES (NULL),(3); @@ -5304,8 +5304,8 @@ NULL set join_cache_level = default; DROP TABLE t1,t2; # -# BUG#54359 "Extra rows with join_cache_level=7,8 and two joins -# --and multi-column index" +# Bug #54359: Extra rows with join_cache_level=7,8 and two joins +# and multi-column index" # CREATE TABLE t1 ( pk int NOT NULL, @@ -5331,7 +5331,7 @@ a set join_cache_level = default; DROP TABLE t1; # -# Bug#54235 Extra rows with join_cache_level=6,8 and two LEFT JOINs +# Bug #54235: Extra rows with join_cache_level=6,8 and two LEFT JOINs # CREATE TABLE t1 (a int); CREATE TABLE t2 (a int); @@ -5370,4 +5370,96 @@ a 1 set join_cache_level = default; DROP TABLE t1,t2,t3,t4; +# +# Bug #663840: Memory overwrite causing crash with hash join +# +SET SESSION join_cache_level=3; +SET SESSION join_buffer_size=100; +Warnings: +Warning 1292 Truncated incorrect join_buffer_size value: '100' +CREATE TABLE t3 ( +i int NOT NULL, +j int NOT NULL, +d date NOT NULL, +t time NOT NULL, +v varchar(1) NOT NULL, +u varchar(1) NOT NULL, +INDEX idx (v) +) COLLATE=latin1_bin; +INSERT INTO t3 VALUES +(3,8,'2008-12-04','00:00:00','v','v'), (3,8,'2009-03-28','00:00:00','f','f'), +(3,5,'1900-01-01','00:55:47','v','v'), (2,8,'2009-10-02','00:00:00','s','s'), +(1,8,'1900-01-01','20:51:59','a','a'), (0,6,'2008-06-04','09:47:27','p','p'), +(8,7,'2009-01-13','21:58:29','z','z'), (5,2,'1900-01-01','22:45:53','a','a'), +(9,5,'2008-01-28','14:06:48','h','h'), (5,7,'2004-09-18','22:17:16','h','h'), +(4,2,'2006-10-14','14:59:37','v','v'), (2,9,'1900-01-01','23:37:40','v','v'), +(33,142,'2000-11-28','14:14:01','b','b'), (5,3,'2008-04-04','02:54:19','y','y'), +(1,0,'2002-07-13','06:34:26','v','v'), (9,3,'2003-01-03','18:07:38','m','m'), +(1,5,'2006-04-02','13:55:23','z','z'), (3,9,'2006-10-19','20:32:28','n','n'), +(8,1,'2005-06-08','11:57:44','d','d'), (231,107,'2006-12-26','03:10:35','a','a'); +CREATE TABLE t1 SELECT * FROM t3; +DELETE FROM t1 WHERE i > 8; +CREATE TABLE t2 SELECT * FROM t3; +DELETE FROM t2 WHERE j > 10; +EXPLAIN +SELECT t1.i, t1.d, t1.v, t2.i, t2.d, t2.t, t2.v FROM t1,t2,t3 +WHERE t3.u <='a' AND t2.j < 5 AND t3.v = t2.u; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 16 +1 SIMPLE t2 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 ref idx idx 3 test.t2.u 2 Using where; Using join buffer (flat, BNLH join) +SELECT t1.i, t1.d, t1.v, t2.i, t2.d, t2.t, t2.v FROM t1,t2,t3 +WHERE t3.u <='a' AND t2.j < 5 AND t3.v = t2.u; +i d v i d t v +3 2008-12-04 v 5 1900-01-01 22:45:53 a +3 2009-03-28 f 5 1900-01-01 22:45:53 a +3 1900-01-01 v 5 1900-01-01 22:45:53 a +2 2009-10-02 s 5 1900-01-01 22:45:53 a +3 2008-12-04 v 5 1900-01-01 22:45:53 a +3 2009-03-28 f 5 1900-01-01 22:45:53 a +3 1900-01-01 v 5 1900-01-01 22:45:53 a +2 2009-10-02 s 5 1900-01-01 22:45:53 a +3 2008-12-04 v 5 1900-01-01 22:45:53 a +3 2009-03-28 f 5 1900-01-01 22:45:53 a +3 1900-01-01 v 5 1900-01-01 22:45:53 a +2 2009-10-02 s 5 1900-01-01 22:45:53 a +1 1900-01-01 a 5 1900-01-01 22:45:53 a +0 2008-06-04 p 5 1900-01-01 22:45:53 a +8 2009-01-13 z 5 1900-01-01 22:45:53 a +5 1900-01-01 a 5 1900-01-01 22:45:53 a +1 1900-01-01 a 5 1900-01-01 22:45:53 a +0 2008-06-04 p 5 1900-01-01 22:45:53 a +8 2009-01-13 z 5 1900-01-01 22:45:53 a +5 1900-01-01 a 5 1900-01-01 22:45:53 a +1 1900-01-01 a 5 1900-01-01 22:45:53 a +0 2008-06-04 p 5 1900-01-01 22:45:53 a +8 2009-01-13 z 5 1900-01-01 22:45:53 a +5 1900-01-01 a 5 1900-01-01 22:45:53 a +5 2004-09-18 h 5 1900-01-01 22:45:53 a +4 2006-10-14 v 5 1900-01-01 22:45:53 a +2 1900-01-01 v 5 1900-01-01 22:45:53 a +5 2008-04-04 y 5 1900-01-01 22:45:53 a +5 2004-09-18 h 5 1900-01-01 22:45:53 a +4 2006-10-14 v 5 1900-01-01 22:45:53 a +2 1900-01-01 v 5 1900-01-01 22:45:53 a +5 2008-04-04 y 5 1900-01-01 22:45:53 a +5 2004-09-18 h 5 1900-01-01 22:45:53 a +4 2006-10-14 v 5 1900-01-01 22:45:53 a +2 1900-01-01 v 5 1900-01-01 22:45:53 a +5 2008-04-04 y 5 1900-01-01 22:45:53 a +1 2002-07-13 v 5 1900-01-01 22:45:53 a +1 2006-04-02 z 5 1900-01-01 22:45:53 a +3 2006-10-19 n 5 1900-01-01 22:45:53 a +8 2005-06-08 d 5 1900-01-01 22:45:53 a +1 2002-07-13 v 5 1900-01-01 22:45:53 a +1 2006-04-02 z 5 1900-01-01 22:45:53 a +3 2006-10-19 n 5 1900-01-01 22:45:53 a +8 2005-06-08 d 5 1900-01-01 22:45:53 a +1 2002-07-13 v 5 1900-01-01 22:45:53 a +1 2006-04-02 z 5 1900-01-01 22:45:53 a +3 2006-10-19 n 5 1900-01-01 22:45:53 a +8 2005-06-08 d 5 1900-01-01 22:45:53 a +DROP TABLE t1,t2,t3; +SET SESSION join_cache_level=DEFAULT; +SET SESSION join_buffer_size=DEFAULT; set @@optimizer_switch=@save_optimizer_switch; diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 8ab9165457b..d83646b5e99 100755 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -1983,8 +1983,8 @@ 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 # Bug #51084: Batched key access crashes for SELECT with +--echo # derived table and LEFT JOIN --echo # CREATE TABLE t1 ( @@ -2027,7 +2027,7 @@ SET join_cache_level=default; DROP TABLE t1,t2,t3,t4; --echo # ---echo # BUG#52636: allowing JOINs on NULL values w/ join_cache_level = 5-8 +--echo # Bug #52636: allowing JOINs on NULL values w/ join_cache_level = 5-8 --echo # CREATE TABLE t1 (b int); @@ -2077,8 +2077,8 @@ set join_cache_level = default; DROP TABLE t1,t2; --echo # ---echo # BUG#54359 "Extra rows with join_cache_level=7,8 and two joins ---echo # --and multi-column index" +--echo # Bug #54359: Extra rows with join_cache_level=7,8 and two joins +--echo # and multi-column index" --echo # CREATE TABLE t1 ( @@ -2104,9 +2104,8 @@ SELECT t.a FROM t1 t, t1 s FORCE INDEX(idx) set join_cache_level = default; DROP TABLE t1; - --echo # ---echo # Bug#54235 Extra rows with join_cache_level=6,8 and two LEFT JOINs +--echo # Bug #54235: Extra rows with join_cache_level=6,8 and two LEFT JOINs --echo # CREATE TABLE t1 (a int); @@ -2136,5 +2135,51 @@ SELECT t1.a set join_cache_level = default; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # Bug #663840: Memory overwrite causing crash with hash join +--echo # + +SET SESSION join_cache_level=3; +SET SESSION join_buffer_size=100; + +CREATE TABLE t3 ( + i int NOT NULL, + j int NOT NULL, + d date NOT NULL, + t time NOT NULL, + v varchar(1) NOT NULL, + u varchar(1) NOT NULL, + INDEX idx (v) +) COLLATE=latin1_bin; + +INSERT INTO t3 VALUES + (3,8,'2008-12-04','00:00:00','v','v'), (3,8,'2009-03-28','00:00:00','f','f'), + (3,5,'1900-01-01','00:55:47','v','v'), (2,8,'2009-10-02','00:00:00','s','s'), + (1,8,'1900-01-01','20:51:59','a','a'), (0,6,'2008-06-04','09:47:27','p','p'), + (8,7,'2009-01-13','21:58:29','z','z'), (5,2,'1900-01-01','22:45:53','a','a'), + (9,5,'2008-01-28','14:06:48','h','h'), (5,7,'2004-09-18','22:17:16','h','h'), + (4,2,'2006-10-14','14:59:37','v','v'), (2,9,'1900-01-01','23:37:40','v','v'), + (33,142,'2000-11-28','14:14:01','b','b'), (5,3,'2008-04-04','02:54:19','y','y'), + (1,0,'2002-07-13','06:34:26','v','v'), (9,3,'2003-01-03','18:07:38','m','m'), + (1,5,'2006-04-02','13:55:23','z','z'), (3,9,'2006-10-19','20:32:28','n','n'), + (8,1,'2005-06-08','11:57:44','d','d'), (231,107,'2006-12-26','03:10:35','a','a'); + +CREATE TABLE t1 SELECT * FROM t3; +DELETE FROM t1 WHERE i > 8; +CREATE TABLE t2 SELECT * FROM t3; +DELETE FROM t2 WHERE j > 10; + +EXPLAIN +SELECT t1.i, t1.d, t1.v, t2.i, t2.d, t2.t, t2.v FROM t1,t2,t3 + WHERE t3.u <='a' AND t2.j < 5 AND t3.v = t2.u; + +SELECT t1.i, t1.d, t1.v, t2.i, t2.d, t2.t, t2.v FROM t1,t2,t3 + WHERE t3.u <='a' AND t2.j < 5 AND t3.v = t2.u; + +DROP TABLE t1,t2,t3; + +SET SESSION join_cache_level=DEFAULT; +SET SESSION join_buffer_size=DEFAULT; + # this must be the last command in the file set @@optimizer_switch=@save_optimizer_switch; diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index cd45145f69c..dad3abd0af4 100755 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -1164,7 +1164,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full) records++; /* Increment the counter of records in the cache */ - len= pack_length; + len= pack_length + extra_key_length(); /* Make an adjustment for the size of the auxiliary buffer if there is any */ uint incr= aux_buffer_incr(records); @@ -2723,6 +2723,7 @@ bool JOIN_CACHE_HASHED::put_record() memcpy(cp, key, key_len); } last_key_entry= cp; + DBUG_ASSERT(last_key_entry >= end_pos); /* Increment the counter of key_entries in the hash table */ key_entries++; } diff --git a/sql/sql_select.h b/sql/sql_select.h index 4279761fda3..da23a639ff4 100755 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -790,6 +790,12 @@ protected: return max(buff_size-(end_pos-buff)-aux_buff_size,0); } + /* + Shall calculate how much space is taken by allocation of the key + for a record in the join buffer + */ + virtual uint extra_key_length() { return 0; } + /* Read all flag and data fields of a record from the join buffer */ uint read_all_record_fields(); @@ -1272,6 +1278,12 @@ protected: return max(last_key_entry-end_pos-aux_buff_size,0); } + /* + Calculate how much space is taken by allocation of the key + entry for a record in the join buffer + */ + virtual uint extra_key_length() { return key_entry_length; } + /* Skip record from a hashed join buffer if its match flag is set to MATCH_FOUND