diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2016-07-18 11:50:08 +0400 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2016-07-18 11:50:08 +0400 |
commit | bf2e31500c9a0a7fcdccfb724e9447347a3ab684 (patch) | |
tree | 241096e790cb73d15daea32ed6054982f49acfb6 | |
parent | c6fdb92ca829fed893d9e7324e80b1450de16087 (diff) | |
download | mariadb-git-bf2e31500c9a0a7fcdccfb724e9447347a3ab684.tar.gz |
MDEV-8569 build_table_filename() doesn't support temporary tables.
Temporary tables support added for RENAME and ALTER TABLE.
-rw-r--r-- | mysql-test/r/grant2.result | 2 | ||||
-rw-r--r-- | mysql-test/r/temp_table.result | 3 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/innodb-fk-warnings.result | 14 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb-fk-warnings.test | 20 | ||||
-rw-r--r-- | mysql-test/t/temp_table.test | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 1 | ||||
-rw-r--r-- | sql/sql_rename.cc | 31 | ||||
-rw-r--r-- | sql/sql_table.cc | 10 | ||||
-rw-r--r-- | sql/sql_table.h | 3 |
9 files changed, 70 insertions, 18 deletions
diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 3df9a5480d3..9e9b3ffc4e5 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -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. # diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result index 0a1701be0d7..dd8bab31d75 100644 --- a/mysql-test/r/temp_table.result +++ b/mysql-test/r/temp_table.result @@ -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; diff --git a/mysql-test/suite/innodb/r/innodb-fk-warnings.result b/mysql-test/suite/innodb/r/innodb-fk-warnings.result index eddedfc3620..d7c7acfb424 100644 --- a/mysql-test/suite/innodb/r/innodb-fk-warnings.result +++ b/mysql-test/suite/innodb/r/innodb-fk-warnings.result @@ -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); diff --git a/mysql-test/suite/innodb/t/innodb-fk-warnings.test b/mysql-test/suite/innodb/t/innodb-fk-warnings.test index a95a7f55a40..f45ae00d788 100644 --- a/mysql-test/suite/innodb/t/innodb-fk-warnings.test +++ b/mysql-test/suite/innodb/t/innodb-fk-warnings.test @@ -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; # diff --git a/mysql-test/t/temp_table.test b/mysql-test/t/temp_table.test index f594f0c6c48..1de0f086a5e 100644 --- a/mysql-test/t/temp_table.test +++ b/mysql-test/t/temp_table.test @@ -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; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index fdaf3323366..118602c5127 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -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; diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index e0fd7005cd5..1a9cb842e6a 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -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); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7bf008870b9..7cf31ee4fe8 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -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 diff --git a/sql/sql_table.h b/sql/sql_table.h index 2b383623873..6c74586b2f5 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -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, |