Commit bf2e3150 authored by Alexey Botchkov's avatar Alexey Botchkov

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

        Temporary tables support added for RENAME and ALTER TABLE.
parent c6fdb92c
......@@ -708,7 +708,7 @@ mysqltest_db1.t3 preload_keys status OK
# RENAME (doesn't work for temporary tables, thus should fail).
#
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.
#
......
......@@ -291,3 +291,6 @@ test.t1 repair status OK
test.t2 repair status OK
test.t3 repair status OK
DROP TABLES t1, t2, t3;
CREATE TEMPORARY TABLE t1 (a int);
RENAME TABLE t1 TO t2;
DROP TABLE t2;
......@@ -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).
Error 1005 Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed")
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;
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);
......
......@@ -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 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
#--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
#--error 1005
#create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb;
#--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
#show warnings;
#--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
#--error 1005
#alter table t1 add foreign key(b) references t1(a);
#--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
#show warnings;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error 1005
create temporary table t2(a int, foreign key(a) references t1(a)) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
--error 1005
alter table t1 add foreign key(b) references t1(a);
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
show warnings;
drop table t1;
#
......
......@@ -319,3 +319,7 @@ INSERT INTO t3 VALUES (101), (102), (103);
REPAIR TABLE t1, t2, t3;
DROP TABLES t1, t2, t3;
CREATE TEMPORARY TABLE t1 (a int);
RENAME TABLE t1 TO t2;
DROP TABLE t2;
......@@ -508,6 +508,7 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_INSERT_SELECT]|= 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_RENAME_TABLE]|= 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_SET_OPTION]|= CF_PREOPEN_TMP_TABLES;
......
......@@ -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
......@@ -317,6 +339,8 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
DBUG_RETURN(0);
}
/*
Rename all tables in list; Return pointer to wrong entry if something goes
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)
{
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(0);
......
......@@ -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,
const char *table_name, uint flags)
const char *table_name, uint flags, const char *table_path)
{
char path[FN_REFLEN + 1];
bool error= 0;
DBUG_ENTER("quick_rm_table");
uint path_length= build_table_filename(path, sizeof(path) - 1,
db, table_name, reg_ext, flags);
uint path_length= table_path ?
(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)))
error= 1; /* purecov: inspected */
path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
......@@ -9220,7 +9221,8 @@ err_new_table_cleanup:
else
(void) quick_rm_table(thd, new_db_type,
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
......
......@@ -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,
bool temporary_table);
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 sp_prepare_create_field(THD *thd, Create_field *sql_field);
int prepare_create_field(Create_field *sql_field,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment