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#13383857 | Roy Lyseng | 14 Nov |