[Commits] Rev 2846: Fixed LP bug #669382. in file:///home/igor/maria/maria-5.3-mwl128-bug669382/

Igor Babaev igor at askmonty.org
Fri Nov 5 06:00:33 EET 2010


At file:///home/igor/maria/maria-5.3-mwl128-bug669382/

------------------------------------------------------------
revno: 2846
revision-id: igor at askmonty.org-20101105040033-tnqvwaskat1kqf8d
parent: igor at askmonty.org-20101103192618-17ii8dyn1h2qzdy8
committer: Igor Babaev <igor at askmonty.org>
branch nick: maria-5.3-mwl128-bug669382
timestamp: Thu 2010-11-04 21:00:33 -0700
message:
  Fixed LP bug #669382.
  When probing into the hash table of a hashed join cache is performed
  the key value should not constructed in the buffer used to build keys
  in the hash tables. The constant parts of these keys copied only once,
  so they should not be ever overwritten. Otherwise wrong results
  can be produced by queries that employ hashed join buffers.
-------------- next part --------------
=== modified file 'mysql-test/r/join_cache.result'
--- a/mysql-test/r/join_cache.result	2010-10-30 22:14:36 +0000
+++ b/mysql-test/r/join_cache.result	2010-11-05 04:00:33 +0000
@@ -5589,4 +5589,30 @@
 6
 SET SESSION join_cache_level = DEFAULT;
 DROP TABLE t1,t2;
+#
+# Bug #669382: hash join using a ref with constant key parts 
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES
+(9), (11), (7), (8), (4), (1), (12), (3), (5);
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+CREATE TABLE t2 (a int, b int, c int, INDEX idx (a,b));
+INSERT INTO t2 VALUES
+(8, 80, 800), (1, 10, 100), (1, 11, 101), (3, 30, 300),
+(1, 12, 102), (8, 81, 801), (7, 70, 700), (12, 120, 1200),
+(8, 82, 802), (1, 13, 103), (1, 14, 104), (3, 31, 301),
+(1, 15, 105), (8, 83, 803), (7, 71, 701);
+SET SESSION join_cache_level = 4;
+SET SESSION join_buffer_size = 192;
+EXPLAIN
+SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	36	Using where
+1	SIMPLE	t2	ref	idx	idx	10	test.t1.a,const	2	Using join buffer (flat, BNLH join)
+SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99;
+a	c
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+DROP TABLE t1,t2;
 set @@optimizer_switch=@save_optimizer_switch;

=== modified file 'mysql-test/t/join_cache.test'
--- a/mysql-test/t/join_cache.test	2010-10-30 22:14:36 +0000
+++ b/mysql-test/t/join_cache.test	2010-11-05 04:00:33 +0000
@@ -2286,5 +2286,34 @@
 
 DROP TABLE t1,t2;
 
+--echo #
+--echo # Bug #669382: hash join using a ref with constant key parts 
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES
+  (9), (11), (7), (8), (4), (1), (12), (3), (5);
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+
+CREATE TABLE t2 (a int, b int, c int, INDEX idx (a,b));
+INSERT INTO t2 VALUES
+  (8, 80, 800), (1, 10, 100), (1, 11, 101), (3, 30, 300),
+  (1, 12, 102), (8, 81, 801), (7, 70, 700), (12, 120, 1200),
+  (8, 82, 802), (1, 13, 103), (1, 14, 104), (3, 31, 301),
+  (1, 15, 105), (8, 83, 803), (7, 71, 701);
+
+SET SESSION join_cache_level = 4;
+SET SESSION join_buffer_size = 192;
+
+EXPLAIN
+SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99; 
+SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99; 
+
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+
+DROP TABLE t1,t2;
+
 # this must be the last command in the file
 set @@optimizer_switch=@save_optimizer_switch;

=== modified file 'sql/sql_join_cache.cc'
--- a/sql/sql_join_cache.cc	2010-11-03 19:26:18 +0000
+++ b/sql/sql_join_cache.cc	2010-11-05 04:00:33 +0000
@@ -2500,6 +2500,9 @@
   if ((rc= JOIN_CACHE::init()))
     DBUG_RETURN (rc);
 
+  if (!(key_buff= (uchar*) sql_alloc(key_length)))
+    DBUG_RETURN(1);
+
   /* Take into account a reference to the next record in the key chain */
   pack_length+= get_size_of_rec_offset(); 
   pack_length_with_blob_ptrs+= get_size_of_rec_offset();
@@ -3300,9 +3303,9 @@
   TABLE_REF *ref= &join_tab->ref;
   KEY *keyinfo= table->key_info+ref->key;
   /* Build the join key value out of the record in the record buffer */
-  key_copy(ref->key_buff, table->record[0], keyinfo, ref->key_length);
+  key_copy(key_buff, table->record[0], keyinfo, key_length);
   /* Look for this key in the join buffer */
-  if (!key_search(ref->key_buff, ref->key_length, &key_ref_ptr))
+  if (!key_search(key_buff, key_length, &key_ref_ptr))
     return 0;
   return key_ref_ptr+get_size_of_key_offset();
 }

=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h	2010-11-03 19:26:18 +0000
+++ b/sql/sql_select.h	2010-11-05 04:00:33 +0000
@@ -1134,11 +1134,6 @@
   uint size_of_key_ofs;
 
   /* 
-    Length of a key value.
-    It is assumed that all key values have the same length.
-  */
-  uint key_length;
-  /* 
     Length of the key entry in the hash table.
     A key entry either contains the key value, or it contains a reference
     to the key value if use_emb_key flag is set for the cache.
@@ -1164,6 +1159,14 @@
   
 protected:
 
+  /* 
+    Length of a key value.
+    It is assumed that all key values have the same length.
+  */
+  uint key_length;
+  /* Buffer to store key values for probing */
+  uchar *key_buff;
+
   /* Number of key entries in the hash table (number of distinct keys) */
   uint key_entries;
 



More information about the commits mailing list