MDEV-8569 build_table_filename() doesn't support temporary tables.

Temporary tables support added for RENAME and ALTER TABLE.
This commit is contained in:
Alexey Botchkov 2016-07-18 11:50:08 +04:00
parent c6fdb92ca8
commit bf2e31500c
9 changed files with 70 additions and 18 deletions

View File

@ -708,7 +708,7 @@ mysqltest_db1.t3 preload_keys status OK
# RENAME (doesn't work for temporary tables, thus should fail). # RENAME (doesn't work for temporary tables, thus should fail).
# #
RENAME TABLE t3 TO t3_1; RENAME TABLE t3 TO t3_1;
ERROR 42000: DROP, ALTER command denied to user 'mysqltest_u1'@'localhost' for table 't3' ERROR 42000: INSERT, CREATE command denied to user 'mysqltest_u1'@'localhost' for table 't3_1'
# #
# HANDLER OPEN/READ/CLOSE. # HANDLER OPEN/READ/CLOSE.
# #

View File

@ -291,3 +291,6 @@ test.t1 repair status OK
test.t2 repair status OK test.t2 repair status OK
test.t3 repair status OK test.t3 repair status OK
DROP TABLES t1, t2, t3; DROP TABLES t1, t2, t3;
CREATE TEMPORARY TABLE t1 (a int);
RENAME TABLE t1 TO t2;
DROP TABLE t2;

View File

@ -70,6 +70,20 @@ Level Code Message
Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary close to foreign key(b) references t1(a). Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary close to foreign key(b) references t1(a).
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint Warning 1215 Cannot add foreign key constraint
create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb;
ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Create table `mysqld.1`.`t2` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary near 'foreign key(a) references t1(a)) engine=innodb'.
Error 1005 Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
alter table t1 add foreign key(b) references t1(a);
ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
show warnings;
Level Code Message
Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary near 'foreign key(b) references t1(a)'.
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
Warning 1215 Cannot add foreign key constraint
drop table t1; drop table t1;
create table t1(a int not null primary key, b int, key(b)) engine=innodb; create table t1(a int not null primary key, b int, key(b)) engine=innodb;
alter table t1 add foreign key(a,b) references t1(a); alter table t1 add foreign key(a,b) references t1(a);

View File

@ -87,16 +87,16 @@ create temporary table t1(a int not null primary key, b int, key(b)) engine=inno
--echo Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary close to foreign key(b) references t1(a). --echo Warning 150 Alter table `mysqld.1`.`t1` with foreign key constraint failed. Referenced table `mysqld.1`.`t1` not found in the data dictionary close to foreign key(b) references t1(a).
--echo Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") --echo Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
--echo Warning 1215 Cannot add foreign key constraint --echo Warning 1215 Cannot add foreign key constraint
#--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
#--error 1005 --error 1005
#create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb; create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb;
#--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
#show warnings; show warnings;
#--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
#--error 1005 --error 1005
#alter table t1 add foreign key(b) references t1(a); alter table t1 add foreign key(b) references t1(a);
#--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/ --replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
#show warnings; show warnings;
drop table t1; drop table t1;
# #

View File

@ -319,3 +319,7 @@ INSERT INTO t3 VALUES (101), (102), (103);
REPAIR TABLE t1, t2, t3; REPAIR TABLE t1, t2, t3;
DROP TABLES t1, t2, t3; DROP TABLES t1, t2, t3;
CREATE TEMPORARY TABLE t1 (a int);
RENAME TABLE t1 TO t2;
DROP TABLE t2;

View File

@ -508,6 +508,7 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_INSERT_SELECT]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_INSERT_SELECT]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_DELETE]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_DELETE]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_DELETE_MULTI]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_DELETE_MULTI]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_RENAME_TABLE]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_REPLACE_SELECT]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_REPLACE_SELECT]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_SELECT]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_SELECT]|= CF_PREOPEN_TMP_TABLES;
sql_command_flags[SQLCOM_SET_OPTION]|= CF_PREOPEN_TMP_TABLES; sql_command_flags[SQLCOM_SET_OPTION]|= CF_PREOPEN_TMP_TABLES;

View File

@ -212,6 +212,28 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list)
} }
static bool
do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table,
bool skip_error)
{
const char *new_alias;
DBUG_ENTER("do_rename_temporary");
new_alias= (lower_case_table_names == 2) ? new_table->alias :
new_table->table_name;
if (is_temporary_table(new_table))
{
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
DBUG_RETURN(1); // This can't be skipped
}
DBUG_RETURN(rename_temporary_table(thd, ren_table->table,
new_table->db, new_alias));
}
/* /*
Rename a single table or a view Rename a single table or a view
@ -317,6 +339,8 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/* /*
Rename all tables in list; Return pointer to wrong entry if something goes Rename all tables in list; Return pointer to wrong entry if something goes
wrong. Note that the table_list may be empty! wrong. Note that the table_list may be empty!
@ -351,8 +375,11 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
for (ren_table= table_list; ren_table; ren_table= new_table->next_local) for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
{ {
new_table= ren_table->next_local; new_table= ren_table->next_local;
if (do_rename(thd, ren_table, new_table->db, new_table->table_name,
new_table->alias, skip_error)) if (is_temporary_table(ren_table) ?
do_rename_temporary(thd, ren_table, new_table, skip_error) :
do_rename(thd, ren_table, new_table->db, new_table->table_name,
new_table->alias, skip_error))
DBUG_RETURN(ren_table); DBUG_RETURN(ren_table);
} }
DBUG_RETURN(0); DBUG_RETURN(0);

View File

@ -2710,14 +2710,15 @@ bool log_drop_table(THD *thd, const char *db_name, size_t db_name_length,
*/ */
bool quick_rm_table(THD *thd, handlerton *base, const char *db, bool quick_rm_table(THD *thd, handlerton *base, const char *db,
const char *table_name, uint flags) const char *table_name, uint flags, const char *table_path)
{ {
char path[FN_REFLEN + 1]; char path[FN_REFLEN + 1];
bool error= 0; bool error= 0;
DBUG_ENTER("quick_rm_table"); DBUG_ENTER("quick_rm_table");
uint path_length= build_table_filename(path, sizeof(path) - 1, uint path_length= table_path ?
db, table_name, reg_ext, flags); (strxnmov(path, sizeof(path) - 1, table_path, reg_ext, NullS) - path) :
build_table_filename(path, sizeof(path)-1, db, table_name, reg_ext, flags);
if (mysql_file_delete(key_file_frm, path, MYF(0))) if (mysql_file_delete(key_file_frm, path, MYF(0)))
error= 1; /* purecov: inspected */ error= 1; /* purecov: inspected */
path[path_length - reg_ext_length]= '\0'; // Remove reg_ext path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
@ -9220,7 +9221,8 @@ err_new_table_cleanup:
else else
(void) quick_rm_table(thd, new_db_type, (void) quick_rm_table(thd, new_db_type,
alter_ctx.new_db, alter_ctx.tmp_name, alter_ctx.new_db, alter_ctx.tmp_name,
(FN_IS_TMP | (no_ha_table ? NO_HA_TABLE : 0))); (FN_IS_TMP | (no_ha_table ? NO_HA_TABLE : 0)),
alter_ctx.get_tmp_path());
/* /*
No default value was provided for a DATE/DATETIME field, the No default value was provided for a DATE/DATETIME field, the

View File

@ -247,7 +247,8 @@ bool log_drop_table(THD *thd, const char *db_name, size_t db_name_length,
const char *table_name, size_t table_name_length, const char *table_name, size_t table_name_length,
bool temporary_table); bool temporary_table);
bool quick_rm_table(THD *thd, handlerton *base, const char *db, bool quick_rm_table(THD *thd, handlerton *base, const char *db,
const char *table_name, uint flags); const char *table_name, uint flags,
const char *table_path=0);
void close_cached_table(THD *thd, TABLE *table); void close_cached_table(THD *thd, TABLE *table);
void sp_prepare_create_field(THD *thd, Create_field *sql_field); void sp_prepare_create_field(THD *thd, Create_field *sql_field);
int prepare_create_field(Create_field *sql_field, int prepare_create_field(Create_field *sql_field,