summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2015-01-14 12:10:13 +0100
committerSergei Golubchik <sergii@pisem.net>2015-01-14 12:10:13 +0100
commit5900333aa5683bf0ef0698ccc911c6c07004ee3a (patch)
treecc002734b62e9bdf2cbc85c052429c3ed8dee6b0
parentf20598b27d481f0f54817dfc163007f6d56269ec (diff)
downloadmariadb-git-5900333aa5683bf0ef0698ccc911c6c07004ee3a.tar.gz
MDEV-7404 REPAIR multiple tables crash in MDL_ticket::has_stronger_or_equal_type
mysql_alter_table() that is used in mysql_recreate_table() doesn't expect many tables in the TABLE_LIST.
-rw-r--r--mysql-test/suite/innodb/r/multi_repair-7404.result21
-rw-r--r--mysql-test/suite/innodb/t/multi_repair-7404.test18
-rw-r--r--sql/sql_table.cc14
3 files changed, 48 insertions, 5 deletions
diff --git a/mysql-test/suite/innodb/r/multi_repair-7404.result b/mysql-test/suite/innodb/r/multi_repair-7404.result
new file mode 100644
index 00000000000..b3db5755b87
--- /dev/null
+++ b/mysql-test/suite/innodb/r/multi_repair-7404.result
@@ -0,0 +1,21 @@
+create table `t1`(`a` int) engine=innodb partition by key (`a`);
+create table `t2`(`b` int) engine=innodb;
+create table `t3`(`c` int) engine=innodb;
+insert t1 values (1);
+insert t2 values (2);
+insert t3 values (3);
+repair table `t1`,`t2`,`t3`;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+test.t2 repair status OK
+test.t3 repair status OK
+select * from t1;
+a
+1
+select * from t2;
+b
+2
+select * from t3;
+c
+3
+drop table t1, t2, t3;
diff --git a/mysql-test/suite/innodb/t/multi_repair-7404.test b/mysql-test/suite/innodb/t/multi_repair-7404.test
new file mode 100644
index 00000000000..0775cd8b200
--- /dev/null
+++ b/mysql-test/suite/innodb/t/multi_repair-7404.test
@@ -0,0 +1,18 @@
+#
+# MDEV-7404 REPAIR multiple tables crash in MDL_ticket::has_stronger_or_equal_type
+#
+
+--source include/have_partition.inc
+--source include/have_innodb.inc
+create table `t1`(`a` int) engine=innodb partition by key (`a`);
+create table `t2`(`b` int) engine=innodb;
+create table `t3`(`c` int) engine=innodb;
+insert t1 values (1);
+insert t2 values (2);
+insert t3 values (3);
+repair table `t1`,`t2`,`t3`;
+select * from t1;
+select * from t2;
+select * from t3;
+drop table t1, t2, t3;
+
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 77dbc765809..477ecf4a350 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -7644,12 +7644,12 @@ err:
/*
- Recreates tables by calling mysql_alter_table().
+ Recreates one table by calling mysql_alter_table().
SYNOPSIS
mysql_recreate_table()
thd Thread handler
- tables Tables to recreate
+ table_list Table to recreate
RETURN
Like mysql_alter_table().
@@ -7658,9 +7658,9 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
{
HA_CREATE_INFO create_info;
Alter_info alter_info;
+ TABLE_LIST *next_table= table_list->next_global;
DBUG_ENTER("mysql_recreate_table");
- DBUG_ASSERT(!table_list->next_global);
/*
table_list->table has been closed and freed. Do not reference
uninitialized data. open_tables() could fail.
@@ -7672,15 +7672,19 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
table_list->lock_type= TL_READ_NO_INSERT;
/* Same applies to MDL request. */
table_list->mdl_request.set_type(MDL_SHARED_NO_WRITE);
+ /* hide following tables from open_tables() */
+ table_list->next_global= NULL;
bzero((char*) &create_info, sizeof(create_info));
create_info.row_type=ROW_TYPE_NOT_USED;
create_info.default_table_charset=default_charset_info;
/* Force alter table to recreate table */
alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
- DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
+ bool res= mysql_alter_table(thd, NullS, NullS, &create_info,
table_list, &alter_info, 0,
- (ORDER *) 0, 0, 0));
+ (ORDER *) 0, 0, 0);
+ table_list->next_global= next_table;
+ DBUG_RETURN(res);
}