Commit c451ace9 authored by Igor Babaev's avatar Igor Babaev

Fixed LP bug #663840.

When adding a new record into the join buffer that is employed by
BNLH join algorithm the writing procedure JOIN_CACHE::write_record_data 
checks whether there is enough space for the record in the buffer.
When doing this it must take into account a possible new key entry
added to the buffer. It might happen, as it has been demonstrated by
the bug test case, that there is enough remaining space in the buffer
for the record, but not for the additional key entry for this record.
In this case the key entry overwrites the end of the record that might
cause a crash or wrong results.
Fixed by taking into account a possible addition of new key entry when
estimating the remaining free space in the buffer.
parent e2e110f4
......@@ -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;
......@@ -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;
......@@ -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++;
}
......
......@@ -790,6 +790,12 @@ class JOIN_CACHE :public Sql_alloc
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 @@ class JOIN_CACHE_HASHED: public JOIN_CACHE
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
......
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