Skip to content

Commit 30185c9

Browse files
committed
MDEV-23207 Assertion `tl->table == __null' failed in THD::open_temporary_table
Assertion fails because table is opened by admin_recreate_table(): 71 result_code= (thd->open_temporary_tables(table_list) || 72 mysql_recreate_table(thd, table_list, recreate_info, false)); And that is called because t2 is failed with HA_ADMIN_NOT_IMPLEMENTED: 1093 if (result_code == HA_ADMIN_NOT_IMPLEMENTED && need_repair_or_alter) 1094 { 1095 /* 1096 repair was not implemented and we need to upgrade the table 1097 to a new version so we recreate the table with ALTER TABLE 1098 */ 1099 result_code= admin_recreate_table(thd, table, &recreate_info); 1100 } Actually 'table' is t2 but open_temporary_tables() opens whole list, i.e. t2 and everything what follows it before first_not_own_table(). Therefore t3 is also opened for t2 processing what is wrong. The fix opens exactly one specific table for HA_ADMIN_NOT_IMPLEMENTED.
1 parent fc46559 commit 30185c9

File tree

5 files changed

+37
-1
lines changed

5 files changed

+37
-1
lines changed

mysql-test/main/repair.result

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,4 +261,16 @@ REPAIR TABLE t;
261261
Table Op Msg_type Msg_text
262262
test.t repair status OK
263263
DELETE FROM t;
264+
#
265+
# MDEV-23207 Assertion `tl->table == __null' failed in THD::open_temporary_table
266+
#
267+
create table t1 (pk int primary key) engine=innodb partition by hash(pk) partitions 10;
268+
create table t2 (c int) engine=innodb;
269+
create temporary table t3 (c int);
270+
repair table t1, t2, t3;
271+
Table Op Msg_type Msg_text
272+
test.t1 repair status OK
273+
test.t2 repair status OK
274+
test.t3 repair status OK
275+
drop tables t1, t2;
264276
# End of 10.11 tests

mysql-test/main/repair.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
--source include/have_sequence.inc
66
--source include/default_charset.inc
7+
--source include/have_innodb.inc
8+
--source include/have_partition.inc
79

810
call mtr.add_suppression("character set is multi-byte");
911

@@ -279,4 +281,14 @@ INSERT INTO t VALUES(1);
279281
REPAIR TABLE t;
280282
DELETE FROM t;
281283

284+
--echo #
285+
--echo # MDEV-23207 Assertion `tl->table == __null' failed in THD::open_temporary_table
286+
--echo #
287+
create table t1 (pk int primary key) engine=innodb partition by hash(pk) partitions 10;
288+
create table t2 (c int) engine=innodb;
289+
create temporary table t3 (c int);
290+
repair table t1, t2, t3;
291+
drop tables t1, t2;
292+
282293
--echo # End of 10.11 tests
294+

sql/sql_admin.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ static bool admin_recreate_table(THD *thd, TABLE_LIST *table_list,
6868

6969
DEBUG_SYNC(thd, "ha_admin_try_alter");
7070
tmp_disable_binlog(thd); // binlogging is done by caller if wanted
71-
result_code= (thd->open_temporary_tables(table_list) ||
71+
result_code= (thd->check_and_open_tmp_table(table_list) ||
7272
mysql_recreate_table(thd, table_list, recreate_info, false));
7373
reenable_binlog(thd);
7474
/*

sql/sql_class.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5452,6 +5452,7 @@ class THD: public THD_count, /* this must be first */
54525452
TMP_TABLE_SHARE *find_tmp_table_share(const char *key, size_t key_length);
54535453

54545454
bool open_temporary_table(TABLE_LIST *tl);
5455+
bool check_and_open_tmp_table(TABLE_LIST *tl);
54555456
bool open_temporary_tables(TABLE_LIST *tl);
54565457

54575458
bool close_temporary_tables();

sql/temporary_tables.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,17 @@ bool THD::open_temporary_table(TABLE_LIST *tl)
441441
}
442442

443443

444+
bool THD::check_and_open_tmp_table(TABLE_LIST *tl)
445+
{
446+
if (!has_temporary_tables() ||
447+
tl == lex->first_not_own_table() ||
448+
tl->derived || tl->schema_table)
449+
return false;
450+
451+
return open_temporary_table(tl);
452+
}
453+
454+
444455
/**
445456
Pre-open temporary tables corresponding to table list elements.
446457

0 commit comments

Comments
 (0)