List:Commits« Previous MessageNext Message »
From:Roy Lyseng Date:November 14 2011 11:09am
Subject:bzr push into mysql-trunk branch (roy.lyseng:3488 to 3489) Bug#13383857
View as plain text  
 3489 Roy Lyseng	2011-11-14
      Bug#13383857: Another crash in memcpy from join_cache::write_record_data
      
      This is a similar case as bug#13106350, except that the derived table
      here has join buffering enabled. When materializing the table in this
      case, setting up buffers for copying of current rowid was omitted.
      
      The fix moves materialization check from join_matching_records()
      to sub_select_cache() and adds setup of buffers for copying of
      current rowid.
      
      mysql-test/t/derived.test
        Added test case for bug#13383857.
      
      mysql-test/r/derived.result
        Added test case results for bug#13383857.
      
      sql/join_cache.cc
        materialization of derived tables is moved into sub_select_cache().
      
      sql/sql_select.cc
        In sub_select_cache(), materialize derived table when needed
        and set up buffers for copying of current rowid.

    modified:
      mysql-test/r/derived.result
      mysql-test/t/derived.test
      sql/sql_join_cache.cc
      sql/sql_select.cc
 3488 Jorgen Loland	2011-11-14
      Previous merge missed Sergey Glukhov's fix for func_analyse.test.
      Manually fixing test.

    modified:
      mysql-test/r/func_analyse.result
      mysql-test/t/func_analyse.test
=== modified file 'mysql-test/r/derived.result'
--- a/mysql-test/r/derived.result	2011-11-11 12:49:36 +0000
+++ b/mysql-test/r/derived.result	2011-11-14 10:48:09 +0000
@@ -1732,3 +1732,106 @@ id	select_type	table	type	possible_keys	
 SET @@max_heap_table_size= @save_heap_size;
 DROP TABLE t1,t2;
 #
+#
+# Bug#13383857: Another crash in memcpy from
+#               join_cache::write_record_data with semijoin
+#
+CREATE TABLE t1 (
+col_int_key INT DEFAULT NULL,
+col_time_nokey TIME DEFAULT NULL,
+col_varchar_key VARCHAR(1) DEFAULT NULL,
+col_varchar_nokey VARCHAR(1) DEFAULT NULL,
+KEY col_int_key (col_int_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+INSERT INTO t1 VALUES
+(8,'22:55:23','x','x'),
+(7,'10:19:31','d','d'),
+(1,'14:40:36','r','r'),
+(7,'04:37:47','f','f'),
+(9,'19:34:06','y','y'),
+(NULL,'20:35:33','u','u'),
+(1,NULL,'m','m'),
+(9,'14:43:37',NULL,NULL),
+(2,'02:23:09','o','o'),
+(9,'01:22:45','w','w'),
+(2,'00:00:00','m','m'),
+(4,'00:13:25','q','q'),
+(0,'03:47:16',NULL,NULL),
+(4,'01:41:48','d','d'),
+(8,'00:00:00','g','g'),
+(NULL,'22:32:04','x','x'),
+(NULL,'16:44:14','f','f'),
+(0,'17:38:37','p','p'),
+(NULL,'08:46:48','j','j'),
+(8,'14:11:27','c','c');
+CREATE TABLE t2 (
+col_int_key INT DEFAULT NULL,
+col_time_nokey TIME DEFAULT NULL,
+col_varchar_key VARCHAR(1) DEFAULT NULL,
+col_varchar_nokey VARCHAR(1) DEFAULT NULL,
+KEY col_int_key (col_int_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+INSERT INTO t2 VALUES
+(4,'22:34:09','v','v'),
+(62,'14:26:02','v','v'),
+(7,'14:03:03','c','c'),
+(1,'01:46:09',NULL,NULL),
+(0,'16:21:18','x','x'),
+(7,'18:56:33','i','i'),
+(7,NULL,'e','e'),
+(1,'09:29:08','p','p'),
+(7,'19:11:10','s','s'),
+(1,'11:57:26','j','j'),
+(5,'00:39:46','z','z'),
+(2,'03:28:15','c','c'),
+(0,'06:44:18','a','a'),
+(1,'14:36:39','q','q'),
+(8,'18:42:45','y','y'),
+(1,'02:57:29',NULL,NULL),
+(1,'16:46:13','r','r'),
+(9,'19:39:02','v','v'),
+(1,NULL,NULL,NULL),
+(5,'20:58:33','r','r');
+CREATE TABLE t3 (
+col_int_key INT DEFAULT NULL,
+col_time_nokey TIME DEFAULT NULL,
+col_varchar_key VARCHAR(1) DEFAULT NULL,
+col_varchar_nokey VARCHAR(1) DEFAULT NULL,
+KEY col_int_key (col_int_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+INSERT INTO t3 VALUES (8,'04:07:22','g','g');
+explain SELECT col_time_nokey AS x
+FROM (SELECT * FROM t2) AS outr
+WHERE col_varchar_nokey IN (
+SELECT innr.col_varchar_key
+FROM (SELECT * FROM t3) AS innr2
+LEFT JOIN (SELECT * FROM t1) AS innr
+ON innr2.col_varchar_key >= innr.col_varchar_key
+WHERE outr.col_varchar_nokey = 'e'
+  )
+AND outr.col_varchar_key <> 'r'
+;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	<derived4>	ALL	NULL	NULL	NULL	NULL	1	Start temporary
+1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	20	Using where; Using join buffer (Block Nested Loop)
+1	PRIMARY	<derived5>	ALL	NULL	NULL	NULL	NULL	20	Using where; End temporary; Using join buffer (Block Nested Loop)
+5	DERIVED	t1	ALL	NULL	NULL	NULL	NULL	20	
+4	DERIVED	t3	system	NULL	NULL	NULL	NULL	1	
+2	DERIVED	t2	ALL	NULL	NULL	NULL	NULL	20	
+SELECT col_time_nokey AS x
+FROM (SELECT * FROM t2) AS outr
+WHERE col_varchar_nokey IN (
+SELECT innr.col_varchar_key
+FROM (SELECT * FROM t3) AS innr2
+LEFT JOIN (SELECT * FROM t1) AS innr
+ON innr2.col_varchar_key >= innr.col_varchar_key
+WHERE outr.col_varchar_nokey = 'e'
+  )
+AND outr.col_varchar_key <> 'r'
+;
+x
+DROP TABLE t1, t2, t3;
+#

=== modified file 'mysql-test/t/derived.test'
--- a/mysql-test/t/derived.test	2011-11-10 13:01:02 +0000
+++ b/mysql-test/t/derived.test	2011-11-14 10:48:09 +0000
@@ -1111,3 +1111,99 @@ SET @@max_heap_table_size= @save_heap_si
 DROP TABLE t1,t2;
 --echo #
 
+--echo #
+--echo # Bug#13383857: Another crash in memcpy from
+--echo #               join_cache::write_record_data with semijoin
+--echo #
+
+CREATE TABLE t1 (
+  col_int_key INT DEFAULT NULL,
+  col_time_nokey TIME DEFAULT NULL,
+  col_varchar_key VARCHAR(1) DEFAULT NULL,
+  col_varchar_nokey VARCHAR(1) DEFAULT NULL,
+  KEY col_int_key (col_int_key),
+  KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+
+INSERT INTO t1 VALUES
+ (8,'22:55:23','x','x'),
+ (7,'10:19:31','d','d'),
+ (1,'14:40:36','r','r'),
+ (7,'04:37:47','f','f'),
+ (9,'19:34:06','y','y'),
+ (NULL,'20:35:33','u','u'),
+ (1,NULL,'m','m'),
+ (9,'14:43:37',NULL,NULL),
+ (2,'02:23:09','o','o'),
+ (9,'01:22:45','w','w'),
+ (2,'00:00:00','m','m'),
+ (4,'00:13:25','q','q'),
+ (0,'03:47:16',NULL,NULL),
+ (4,'01:41:48','d','d'),
+ (8,'00:00:00','g','g'),
+ (NULL,'22:32:04','x','x'),
+ (NULL,'16:44:14','f','f'),
+ (0,'17:38:37','p','p'),
+ (NULL,'08:46:48','j','j'),
+ (8,'14:11:27','c','c');
+
+CREATE TABLE t2 (
+  col_int_key INT DEFAULT NULL,
+  col_time_nokey TIME DEFAULT NULL,
+  col_varchar_key VARCHAR(1) DEFAULT NULL,
+  col_varchar_nokey VARCHAR(1) DEFAULT NULL,
+  KEY col_int_key (col_int_key),
+  KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+
+INSERT INTO t2 VALUES
+ (4,'22:34:09','v','v'),
+ (62,'14:26:02','v','v'),
+ (7,'14:03:03','c','c'),
+ (1,'01:46:09',NULL,NULL),
+ (0,'16:21:18','x','x'),
+ (7,'18:56:33','i','i'),
+ (7,NULL,'e','e'),
+ (1,'09:29:08','p','p'),
+ (7,'19:11:10','s','s'),
+ (1,'11:57:26','j','j'),
+ (5,'00:39:46','z','z'),
+ (2,'03:28:15','c','c'),
+ (0,'06:44:18','a','a'),
+ (1,'14:36:39','q','q'),
+ (8,'18:42:45','y','y'),
+ (1,'02:57:29',NULL,NULL),
+ (1,'16:46:13','r','r'),
+ (9,'19:39:02','v','v'),
+ (1,NULL,NULL,NULL),
+ (5,'20:58:33','r','r');
+
+CREATE TABLE t3 (
+  col_int_key INT DEFAULT NULL,
+  col_time_nokey TIME DEFAULT NULL,
+  col_varchar_key VARCHAR(1) DEFAULT NULL,
+  col_varchar_nokey VARCHAR(1) DEFAULT NULL,
+  KEY col_int_key (col_int_key),
+  KEY col_varchar_key (col_varchar_key,col_int_key)
+);
+
+INSERT INTO t3 VALUES (8,'04:07:22','g','g');
+
+let $query=
+SELECT col_time_nokey AS x
+FROM (SELECT * FROM t2) AS outr
+WHERE col_varchar_nokey IN (
+  SELECT innr.col_varchar_key
+  FROM (SELECT * FROM t3) AS innr2
+    LEFT JOIN (SELECT * FROM t1) AS innr
+    ON innr2.col_varchar_key >= innr.col_varchar_key
+  WHERE outr.col_varchar_nokey = 'e'
+  )
+  AND outr.col_varchar_key <> 'r'
+;
+eval explain $query;
+eval $query;
+
+DROP TABLE t1, t2, t3;
+
+--echo #

=== modified file 'sql/sql_join_cache.cc'
--- a/sql/sql_join_cache.cc	2011-11-03 16:03:34 +0000
+++ b/sql/sql_join_cache.cc	2011-11-14 10:48:09 +0000
@@ -1789,12 +1789,6 @@ enum_nested_loop_state JOIN_CACHE_BNL::j
     /* A dynamic range access was used last. Clean up after it */
     join_tab->select->set_quick(NULL);
 
-  /* Materialize table prior reading it */
-  if (join_tab->materialize_table &&
-      !join_tab->table->pos_in_table_list->materialized &&
-      (error= (*join_tab->materialize_table)(join_tab)))
-    return NESTED_LOOP_ERROR;
-
   /* Start retrieving all records of the joined table */
   if ((error= (*join_tab->read_first_record)(join_tab))) 
     return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
@@ -2287,12 +2281,6 @@ enum_nested_loop_state JOIN_CACHE_BKA::j
   /* Return at once if there are no records in the join buffer */
   if (!records)
     return NESTED_LOOP_OK;  
-                   
-  /* Materialize table prior reading it */
-  if (join_tab->materialize_table &&
-      !join_tab->table->pos_in_table_list->materialized &&
-      (error= (*join_tab->materialize_table)(join_tab)))
-    return NESTED_LOOP_ERROR;
 
   rc= init_join_matching_records(&seq_funcs, records);
   if (rc != NESTED_LOOP_OK)

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2011-11-11 12:49:36 +0000
+++ b/sql/sql_select.cc	2011-11-14 10:48:09 +0000
@@ -19282,6 +19282,16 @@ sub_select_cache(JOIN *join, JOIN_TAB *j
     join->thd->send_kill_message();
     DBUG_RETURN(NESTED_LOOP_KILLED);
   }
+  /* Materialize table prior to reading it */
+  if (join_tab->materialize_table &&
+      !join_tab->table->pos_in_table_list->materialized)
+  {
+    if ((*join_tab->materialize_table)(join_tab))
+      DBUG_RETURN(NESTED_LOOP_ERROR);
+    // Bind to the rowid buffer managed by the TABLE object.
+    if (join_tab->copy_current_rowid)
+      join_tab->copy_current_rowid->bind_buffer(join_tab->table->file->ref);
+  }
   if (!test_if_use_dynamic_range_scan(join_tab))
   {
     if (!cache->put_record())

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (roy.lyseng:3488 to 3489) Bug#13383857Roy Lyseng14 Nov