Commit de69dbae authored by Igor Babaev's avatar Igor Babaev

Fixed LP bug #663818.

After the patch for bug 663840 had been applied the test case for
bug 663818 triggered the assert introduced by this patch.
It happened because the the patch turned out to be incomplete:
the space needed for a key entry must be taken into account
for the record written into the buffer, and, for the next record
as well, when figuring out whether the record being written is
the last for the buffer or not. 
parent ca862231
...@@ -2390,3 +2390,59 @@ SECOND(c)-@bug47453 ...@@ -2390,3 +2390,59 @@ SECOND(c)-@bug47453
0 0
DROP TABLE t1, t2; DROP TABLE t1, t2;
End of 5.1 tests End of 5.1 tests
#
# Bug #663818: wrong result when BNLH is used
#
CREATE TABLE t1(pk int NOT NULL PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(1), (2), (11), (12), (13), (14),
(15), (16), (17), (18), (19);
CREATE TABLE t2(pk int NOT NULL PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1), (10), (11), (12), (13), (14),
(15), (16), (17), (18), (19), (20), (21);
SET SESSION join_buffer_size=10000;
SET SESSION join_cache_level=3;
EXPLAIN
SELECT t1.pk FROM t1,t2
WHERE t1.pk = t2.pk AND t2.pk <> 8;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 11 Using where; Using index
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index; Using join buffer (flat, BNLH join)
SELECT t1.pk FROM t1,t2
WHERE t1.pk = t2.pk AND t2.pk <> 8;
pk
1
11
12
13
14
15
16
17
18
19
SET SESSION join_cache_level=1;
EXPLAIN
SELECT t1.pk FROM t1,t2
WHERE t1.pk = t2.pk AND t2.pk <> 8;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 11 Using where; Using index
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index
SELECT t1.pk FROM t1,t2
WHERE t1.pk = t2.pk AND t2.pk <> 8;
pk
1
11
12
13
14
15
16
17
18
19
DROP TABLE t1,t2;
SET SESSION join_cache_level=DEFAULT;
SET SESSION join_buffer_size=DEFAULT;
End of 5.3 tests
...@@ -634,3 +634,39 @@ SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a; ...@@ -634,3 +634,39 @@ SELECT SECOND(c)-@bug47453 FROM t1 JOIN t2 ON d=a;
DROP TABLE t1, t2; DROP TABLE t1, t2;
--echo End of 5.1 tests --echo End of 5.1 tests
--echo #
--echo # Bug #663818: wrong result when BNLH is used
--echo #
CREATE TABLE t1(pk int NOT NULL PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(1), (2), (11), (12), (13), (14),
(15), (16), (17), (18), (19);
CREATE TABLE t2(pk int NOT NULL PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t2 VALUES
(1), (10), (11), (12), (13), (14),
(15), (16), (17), (18), (19), (20), (21);
SET SESSION join_buffer_size=10000;
SET SESSION join_cache_level=3;
EXPLAIN
SELECT t1.pk FROM t1,t2
WHERE t1.pk = t2.pk AND t2.pk <> 8;
SELECT t1.pk FROM t1,t2
WHERE t1.pk = t2.pk AND t2.pk <> 8;
SET SESSION join_cache_level=1;
EXPLAIN
SELECT t1.pk FROM t1,t2
WHERE t1.pk = t2.pk AND t2.pk <> 8;
SELECT t1.pk FROM t1,t2
WHERE t1.pk = t2.pk AND t2.pk <> 8;
DROP TABLE t1,t2;
SET SESSION join_cache_level=DEFAULT;
SET SESSION join_buffer_size=DEFAULT;
--echo End of 5.3 tests
...@@ -1161,10 +1161,11 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full) ...@@ -1161,10 +1161,11 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
uchar *cp= pos; uchar *cp= pos;
uchar *init_pos= cp; uchar *init_pos= cp;
uchar *rec_len_ptr= 0; uchar *rec_len_ptr= 0;
uint key_extra= extra_key_length();
records++; /* Increment the counter of records in the cache */ records++; /* Increment the counter of records in the cache */
len= pack_length + extra_key_length(); len= pack_length + key_extra;
/* Make an adjustment for the size of the auxiliary buffer if there is any */ /* Make an adjustment for the size of the auxiliary buffer if there is any */
uint incr= aux_buffer_incr(records); uint incr= aux_buffer_incr(records);
...@@ -1204,7 +1205,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full) ...@@ -1204,7 +1205,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
This function is called only in the case when there is enough space left in This function is called only in the case when there is enough space left in
the cache to store at least non-blob parts of the current record. the cache to store at least non-blob parts of the current record.
*/ */
last_record= (len+pack_length_with_blob_ptrs) > rem_space(); last_record= (len+pack_length_with_blob_ptrs+key_extra) > rem_space();
/* /*
Save the position for the length of the record in the cache if it's needed. Save the position for the length of the record in the cache if it's needed.
......
...@@ -1282,7 +1282,7 @@ protected: ...@@ -1282,7 +1282,7 @@ protected:
Calculate how much space is taken by allocation of the key Calculate how much space is taken by allocation of the key
entry for a record in the join buffer entry for a record in the join buffer
*/ */
virtual uint extra_key_length() { return key_entry_length; } uint extra_key_length() { return key_entry_length; }
/* /*
Skip record from a hashed join buffer if its match flag Skip record from a hashed join buffer if its match flag
......
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