1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-09 22:24:09 +03:00

MDEV-31618: Server crashes in process_i_s_table_temporary_tables/get_all_tables after alter in rename query

Any TMP_TABLE_SHARE must always have at least one TABLE instance.
So whenever a temporary TABLE that is marked for reopen is closed,
reopen it at once if its TMP_TABLE_SHARE list of tables becomes empty.
This commit is contained in:
Anel Husakovic
2023-08-08 10:58:44 +02:00
committed by Sergei Golubchik
parent de57da733f
commit 80439e6918
3 changed files with 96 additions and 2 deletions

View File

@@ -266,3 +266,56 @@ mysqltest s1
DROP TABLE seq1; DROP TABLE seq1;
DROP TABLE mysqltest.s1; DROP TABLE mysqltest.s1;
DROP TABLE mysqltest.s2; DROP TABLE mysqltest.s2;
#
# MDEV-31618: Server crashes in
# process_i_s_table_temporary_tables/get_all_tables after alter in rename
#
CREATE table seq1 (a bigint, b int);
CREATE TEMPORARY TABLE tmp LIKE seq1;
INSERT tmp SELECT * FROM seq1;
ALTER TABLE tmp RENAME TO seq1;
ALTER TABLE seq1 CHANGE a b int ;
Got one of the listed errors
RENAME TABLE seq1 TO seq1;
ERROR 42S01: Table 'seq1' already exists
show full tables;
Tables_in_test Table_type
seq1 TEMPORARY TABLE
seq1 BASE TABLE
drop table seq1;
drop table seq1;
CREATE SEQUENCE seq2;
CREATE TEMPORARY sequence tmp;
show full tables;
Tables_in_test Table_type
tmp TEMPORARY SEQUENCE
seq2 SEQUENCE
ALTER table `tmp` RENAME TO seq1;
show full tables;
Tables_in_test Table_type
seq1 TEMPORARY SEQUENCE
seq2 SEQUENCE
ALTER TABLE `seq1` CHANGE `cache_size` cache_size int ;
ERROR HY000: Sequence 'test.seq1' table structure is invalid (cache_size)
show full tables;
Tables_in_test Table_type
seq1 TEMPORARY SEQUENCE
seq2 SEQUENCE
RENAME TABLE seq1 TO seq1;
ERROR 42S01: Table 'seq1' already exists
show full tables;
Tables_in_test Table_type
seq1 TEMPORARY SEQUENCE
seq2 SEQUENCE
RENAME TABLE seq1 TO seq3;
show full tables;
Tables_in_test Table_type
seq3 TEMPORARY SEQUENCE
seq2 SEQUENCE
drop table seq2;
show full tables;
Tables_in_test Table_type
seq3 TEMPORARY SEQUENCE
drop table seq3;
show full tables;
Tables_in_test Table_type

View File

@@ -242,3 +242,39 @@ SELECT table_schema, table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_type
DROP TABLE seq1; DROP TABLE seq1;
DROP TABLE mysqltest.s1; DROP TABLE mysqltest.s1;
DROP TABLE mysqltest.s2; DROP TABLE mysqltest.s2;
--echo #
--echo # MDEV-31618: Server crashes in
--echo # process_i_s_table_temporary_tables/get_all_tables after alter in rename
--echo #
# Check on temporary tables
CREATE table seq1 (a bigint, b int);
CREATE TEMPORARY TABLE tmp LIKE seq1;
INSERT tmp SELECT * FROM seq1;
ALTER TABLE tmp RENAME TO seq1;
--error 4086,1060
ALTER TABLE seq1 CHANGE a b int ;
--error 1050
RENAME TABLE seq1 TO seq1;
show full tables;
drop table seq1;
drop table seq1;
# Check on sequences
CREATE SEQUENCE seq2;
CREATE TEMPORARY sequence tmp;
show full tables;
ALTER table `tmp` RENAME TO seq1;
show full tables;
--error ER_SEQUENCE_INVALID_TABLE_STRUCTURE
ALTER TABLE `seq1` CHANGE `cache_size` cache_size int ;
show full tables;
--error ER_TABLE_EXISTS_ERROR
RENAME TABLE seq1 TO seq1;
show full tables;
RENAME TABLE seq1 TO seq3;
show full tables;
drop table seq2;
show full tables;
drop table seq3;
show full tables;

View File

@@ -1086,8 +1086,13 @@ TABLE *THD::find_temporary_table(const char *key, uint key_length,
{ {
share->all_tmp_tables.remove(table); share->all_tmp_tables.remove(table);
free_temporary_table(table); free_temporary_table(table);
it.rewind(); if (share->all_tmp_tables.is_empty())
continue; table= open_temporary_table(share, share->table_name.str);
else
{
it.rewind();
continue;
}
} }
result= table; result= table;
break; break;