← Back to team overview

maria-developers team mailing list archive

bzr commit into Mariadb 5.2, with Maria 2.0:maria/5.2 branch (igor:2772) Bug#51092

 

#At lp:maria/5.2 based on revid:igor@xxxxxxxxxxxx-20100305185448-satt36ksg5xxkwji

 2772 Igor Babaev	2010-03-06
      Fixed bug #51092.
      The function JOIN_CACHE::read_all_record_fields could return 0
      for an incremental join cache in two cases:
      1. there were no more records in the associated join buffer
      2. there was no table fields stored in the join buffer.
      As a result the function JOIN_CACHE::get_record() could
      return prematurely and did not read all needed fields from
      join buffers into the record buffer.
      
      Now the function JOIN_CACHE::read_all_record_fields returns
      -1 if there are no more records in the associated join buffer.
      modified:
        mysql-test/r/join_cache.result
        mysql-test/t/join_cache.test
        sql/sql_join_cache.cc

=== modified file 'mysql-test/r/join_cache.result'
--- a/mysql-test/r/join_cache.result	2010-02-11 21:59:32 +0000
+++ b/mysql-test/r/join_cache.result	2010-03-06 19:14:55 +0000
@@ -4142,3 +4142,46 @@ c1	c2	c1	c2	LENGTH(t2.c1)	LENGTH(t2.c2)
 2	2	tt	uu	2	2
 set join_cache_level=default;
 DROP TABLE t1,t2;
+#
+# Bug #51092: linked join buffer is used for a 3-way cross join query 
+#             that selects only records of the first table
+#
+create table t1 (a int, b int);
+insert into t1 values (1,1),(2,2);
+create table t2 (a int, b int);
+insert into t2 values (1,1),(2,2);
+create table t3 (a int, b int);
+insert into t3 values (1,1),(2,2);
+explain select t1.* from t1,t2,t3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	Using join buffer
+1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	2	Using join buffer
+select t1.* from t1,t2,t3;
+a	b
+1	1
+2	2
+1	1
+2	2
+1	1
+2	2
+1	1
+2	2
+set join_cache_level=2;
+explain select t1.* from t1,t2,t3;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	Using join buffer
+1	SIMPLE	t3	ALL	NULL	NULL	NULL	NULL	2	Using join buffer
+select t1.* from t1,t2,t3;
+a	b
+1	1
+2	2
+1	1
+2	2
+1	1
+2	2
+1	1
+2	2
+set join_cache_level=default;
+drop table t1,t2,t3;

=== modified file 'mysql-test/t/join_cache.test'
--- a/mysql-test/t/join_cache.test	2009-12-21 02:26:15 +0000
+++ b/mysql-test/t/join_cache.test	2010-03-06 19:14:55 +0000
@@ -1823,3 +1823,27 @@ SELECT t1.*, t2.*, LENGTH(t2.c1), LENGTH
 set join_cache_level=default;
 
 DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug #51092: linked join buffer is used for a 3-way cross join query 
+--echo #             that selects only records of the first table
+--echo #
+
+create table t1 (a int, b int);
+insert into t1 values (1,1),(2,2);
+create table t2 (a int, b int);
+insert into t2 values (1,1),(2,2);
+create table t3 (a int, b int);
+insert into t3 values (1,1),(2,2);
+
+explain select t1.* from t1,t2,t3;
+select t1.* from t1,t2,t3; 
+
+set join_cache_level=2;
+
+explain select t1.* from t1,t2,t3;
+select t1.* from t1,t2,t3; 
+
+set join_cache_level=default;
+
+drop table t1,t2,t3;

=== modified file 'sql/sql_join_cache.cc'
--- a/sql/sql_join_cache.cc	2010-03-05 18:54:48 +0000
+++ b/sql/sql_join_cache.cc	2010-03-06 19:14:55 +0000
@@ -31,6 +31,8 @@
 #include "sql_select.h"
 #include "opt_subselect.h"
 
+#define NO_MORE_RECORDS_IN_BUFFER  (uint)(-1)
+
 
 /*****************************************************************************
  *  Join cache module
@@ -1237,7 +1239,7 @@ bool JOIN_CACHE::get_record()
     prev_rec_ptr= prev_cache->get_rec_ref(pos);
   }
   curr_rec_pos= pos;
-  if (!(res= read_all_record_fields() == 0))
+  if (!(res= read_all_record_fields() == NO_MORE_RECORDS_IN_BUFFER))
   {
     pos+= referenced_fields*size_of_fld_ofs;
     if (prev_cache)
@@ -1326,7 +1328,8 @@ bool JOIN_CACHE::get_match_flag_by_pos(u
     read data. 
 
   RETURN
-    length of the data read from the join buffer
+    (-1) - if there is no more records in the join buffer
+    length of the data read from the join buffer - otherwise
 */
 
 uint JOIN_CACHE::read_all_record_fields()
@@ -1334,7 +1337,7 @@ uint JOIN_CACHE::read_all_record_fields(
   uchar *init_pos= pos;
   
   if (pos > last_rec_pos || !records)
-    return 0;
+    return NO_MORE_RECORDS_IN_BUFFER;
 
   /* First match flag, read null bitmaps and null_row flag for each table */
   read_flag_fields();