diff --git a/mysql-test/r/rename.result b/mysql-test/r/rename.result index 1257a668ccefcae69d1463fd72c0fbae1b401c27..edf05d0c5d3c035c7179c2d485271550f0abfc8b 100644 --- a/mysql-test/r/rename.result +++ b/mysql-test/r/rename.result @@ -55,14 +55,15 @@ t2 t4 drop table t2, t4; End of 4.1 tests +# +# Bug#14959: "ALTER TABLE isn't able to rename a view" +# Bug#53976: "ALTER TABLE RENAME is allowed on views +# (not documented, broken)" +# create table t1(f1 int); create view v1 as select * from t1; alter table v1 rename to v2; -alter table v1 rename to v2; -ERROR 42S02: Table 'test.v1' doesn't exist -rename table v2 to v1; -rename table v2 to v1; -ERROR 42S01: Table 'v1' already exists +ERROR HY000: 'test.v1' is not BASE TABLE drop view v1; drop table t1; End of 5.0 tests diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index b7660dbcbd8082a492a646fedf55e74640008a3d..487ce54203dee835e6601faea17133cb878884cc 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3954,6 +3954,7 @@ drop procedure p; CREATE TABLE t1 (a INT); CREATE VIEW v1 AS SELECT a FROM t1; ALTER TABLE v1; +ERROR HY000: 'test.v1' is not BASE TABLE DROP VIEW v1; DROP TABLE t1; # diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test index 5aa1a51a90f4d3be8556581dbba8248f20df2780..bb90cbafd74a03e62571502f9ab90f49572999a7 100644 --- a/mysql-test/t/rename.test +++ b/mysql-test/t/rename.test @@ -79,17 +79,15 @@ connection default; --echo End of 4.1 tests -# -# Bug#14959: ALTER TABLE isn't able to rename a view -# +--echo # +--echo # Bug#14959: "ALTER TABLE isn't able to rename a view" +--echo # Bug#53976: "ALTER TABLE RENAME is allowed on views +--echo # (not documented, broken)" +--echo # create table t1(f1 int); create view v1 as select * from t1; +--error ER_WRONG_OBJECT alter table v1 rename to v2; ---error ER_NO_SUCH_TABLE -alter table v1 rename to v2; -rename table v2 to v1; ---error ER_TABLE_EXISTS_ERROR -rename table v2 to v1; drop view v1; drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index d1a4d78e58fa2949c9afdf0d0a00a8fb93b17ac0..360bbc1552d45b96ff48c4a67cbfdef2bd214bb2 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3902,6 +3902,7 @@ drop procedure p; --echo # CREATE TABLE t1 (a INT); CREATE VIEW v1 AS SELECT a FROM t1; +--error ER_WRONG_OBJECT ALTER TABLE v1; DROP VIEW v1; DROP TABLE t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c27ebce744fccc0d4ec940c93e4ae2053e47355a..113da3fe71909e73616967c987d7d26c978f3bfc 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6454,8 +6454,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, char reg_path[FN_REFLEN+1]; ha_rows copied,deleted; handlerton *old_db_type, *new_db_type, *save_old_db_type; - legacy_db_type table_type; - frm_type_enum frm_type; enum_alter_table_change_level need_copy_table= ALTER_TABLE_METADATA_ONLY; #ifdef WITH_PARTITION_STORAGE_ENGINE uint fast_alter_partition= 0; @@ -6535,91 +6533,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, /* Conditionally writes to binlog. */ DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, alter_info->tablespace_op)); - strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db, - "/", table_name, reg_ext, NullS); - (void) unpack_filename(new_name_buff, new_name_buff); - /* - If this is just a rename of a view, short cut to the - following scenario: 1) lock LOCK_open 2) do a RENAME - 2) unlock LOCK_open. - This is a copy-paste added to make sure - ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled - as an independent branch in mysql_execute_command. The need - for a copy-paste arose because the main code flow of ALTER TABLE - ... RENAME tries to use open_ltable, which does not work for views - (open_ltable was never modified to merge table lists of child tables - into the main table list, like open_tables does). - This code is wrong and will be removed, please do not copy. - */ - frm_type= dd_frm_type(thd, new_name_buff, &table_type); - /* Rename a view */ - /* Sic: there is a race here */ - if (frm_type == FRMTYPE_VIEW && !(alter_info->flags & ~ALTER_RENAME)) - { - /* - The following branch handles "ALTER VIEW v1 /no arguments/;" - This feature is not documented one. - However, before "OPTIMIZE TABLE t1;" was implemented, - ALTER TABLE with no alter_specifications was used to force-rebuild - the table. That's why this grammar is allowed. That's why we ignore - it for views. So just do nothing in such a case. - */ - if (!new_name) - { - my_ok(thd); - DBUG_RETURN(FALSE); - } - - /* - Avoid problems with a rename on a table that we have locked or - if the user is trying to to do this in a transcation context - */ - - if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction()) - { - my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, - ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); - DBUG_RETURN(TRUE); - } - - if (thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, TRUE)) - DBUG_RETURN(TRUE); - - /* - TODO/FIXME: Get rid of this code branch if possible. To add insult - to injury it breaks locking protocol. - */ - table_list->mdl_request.set_type(MDL_EXCLUSIVE); - if (lock_table_names(thd, table_list)) - { - error= 1; - goto view_err; - } - - mysql_mutex_lock(&LOCK_open); - - if (!do_rename(thd, table_list, new_db, new_name, new_name, 1)) - { - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query(), thd->query_length(), - FALSE, TRUE, FALSE, 0); - if ((error= mysql_bin_log.write(&qinfo))) - goto view_err_unlock; - } - my_ok(thd); - } - -view_err_unlock: - mysql_mutex_unlock(&LOCK_open); - unlock_table_names(thd); - -view_err: - thd->global_read_lock.start_waiting_global_read_lock(thd); - DBUG_RETURN(error); - } - /* Code below can handle only base tables so ensure that we won't open a view.