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 ...@@ -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.
# #
......
...@@ -291,3 +291,6 @@ test.t1 repair status OK ...@@ -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;
...@@ -70,6 +70,20 @@ Level Code Message ...@@ -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);
......
...@@ -87,16 +87,16 @@ create temporary table t1(a int not null primary key, b int, key(b)) engine=inno ...@@ -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;
# #
......
...@@ -319,3 +319,7 @@ INSERT INTO t3 VALUES (101), (102), (103); ...@@ -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;
...@@ -508,6 +508,7 @@ void init_update_queries(void) ...@@ -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;
......
...@@ -212,6 +212,28 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list) ...@@ -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, ...@@ -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) ...@@ -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);
......
...@@ -2710,14 +2710,15 @@ bool log_drop_table(THD *thd, const char *db_name, size_t db_name_length, ...@@ -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 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -9220,7 +9221,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
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
......
...@@ -247,7 +247,8 @@ bool log_drop_table(THD *thd, const char *db_name, size_t db_name_length, ...@@ -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,
......
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