diff options
author | Monty <monty@mariadb.org> | 2019-12-30 13:34:28 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2020-03-24 20:47:41 +0200 |
commit | bff79492c5f6c9669b9dc9bf2cf0483b3b001da7 (patch) | |
tree | 7d13874ae2bf8a8c2caba079f1010d401d65dcaf | |
parent | 5f5c63e0fe6eac590549bdb76204a07cb2fe2aa1 (diff) | |
download | mariadb-git-bff79492c5f6c9669b9dc9bf2cf0483b3b001da7.tar.gz |
Added IF EXISTS to RENAME TABLE and ALTER TABLE
-rw-r--r-- | mysql-test/main/alter_table.result | 19 | ||||
-rw-r--r-- | mysql-test/main/alter_table.test | 12 | ||||
-rw-r--r-- | mysql-test/main/ps_1general.result | 8 | ||||
-rw-r--r-- | mysql-test/main/ps_1general.test | 8 | ||||
-rw-r--r-- | mysql-test/main/rename.result | 25 | ||||
-rw-r--r-- | mysql-test/main/rename.test | 18 | ||||
-rw-r--r-- | mysql-test/suite/engines/funcs/r/tc_rename_error.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/engines/funcs/t/tc_rename_error.test | 4 | ||||
-rw-r--r-- | sql/handler.cc | 3 | ||||
-rw-r--r-- | sql/sql_alter.cc | 2 | ||||
-rw-r--r-- | sql/sql_db.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 4 | ||||
-rw-r--r-- | sql/sql_rename.cc | 63 | ||||
-rw-r--r-- | sql/sql_rename.h | 3 | ||||
-rw-r--r-- | sql/sql_table.cc | 131 | ||||
-rw-r--r-- | sql/sql_table.h | 8 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 8 |
17 files changed, 219 insertions, 101 deletions
diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index c2c5813a100..36fb35f05b4 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -3244,3 +3244,22 @@ drop table t1; # # End of 10.5 tests # +# +# ALTER TABLE IF EXISTS +# +create table t1 (a int); +alter table if exists t1 add column b int; +alter table if exists t2 add column c int; +Warnings: +Error 1146 Table 'test.t2' doesn't exist +alter table if exists t9 rename t1; +Warnings: +Error 1146 Table 'test.t9' doesn't exist +alter table if exists t1 rename t2; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t2; diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test index 19f9777d803..b1bdd94ad8e 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -2456,3 +2456,15 @@ drop table t1; --echo # --echo # End of 10.5 tests --echo # + +--echo # +--echo # ALTER TABLE IF EXISTS +--echo # + +create table t1 (a int); +alter table if exists t1 add column b int; +alter table if exists t2 add column c int; +alter table if exists t9 rename t1; +alter table if exists t1 rename t2; +show create table t2; +drop table t2; diff --git a/mysql-test/main/ps_1general.result b/mysql-test/main/ps_1general.result index 2ef5571cdca..83060437de1 100644 --- a/mysql-test/main/ps_1general.result +++ b/mysql-test/main/ps_1general.result @@ -528,9 +528,11 @@ drop table if exists new_t2; prepare stmt3 from ' rename table t2 to new_t2 '; execute stmt3; execute stmt3; +ERROR 42S02: Table 'test.t2' doesn't exist +create table t2 like new_t2; +execute stmt3; ERROR 42S01: Table 'new_t2' already exists -rename table new_t2 to t2; -drop table t2; +drop table new_t2,t2; prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ; create table t5 (a int) ; execute stmt1 ; @@ -538,7 +540,7 @@ ERROR 42S02: Table 'test.t7' doesn't exist create table t7 (a int) ; execute stmt1 ; execute stmt1 ; -ERROR 42S01: Table 't6' already exists +ERROR 42S02: Table 'test.t5' doesn't exist rename table t6 to t5, t8 to t7 ; execute stmt1 ; drop table t6, t8 ; diff --git a/mysql-test/main/ps_1general.test b/mysql-test/main/ps_1general.test index 01a0164722d..0df1b3cabe9 100644 --- a/mysql-test/main/ps_1general.test +++ b/mysql-test/main/ps_1general.test @@ -576,10 +576,12 @@ drop table if exists new_t2; --enable_warnings prepare stmt3 from ' rename table t2 to new_t2 '; execute stmt3; +--error ER_NO_SUCH_TABLE +execute stmt3; +create table t2 like new_t2; --error ER_TABLE_EXISTS_ERROR execute stmt3; -rename table new_t2 to t2; -drop table t2; +drop table new_t2,t2; ## RENAME more than on TABLE within one statement # cases derived from client_test.c: test_rename() prepare stmt1 from ' rename table t5 to t6, t7 to t8 ' ; @@ -590,7 +592,7 @@ create table t7 (a int) ; # rename, t5 -> t6 and t7 -> t8 execute stmt1 ; # rename must fail, t5 and t7 does not exist t6 and t8 already exist ---error ER_TABLE_EXISTS_ERROR +--error ER_NO_SUCH_TABLE execute stmt1 ; rename table t6 to t5, t8 to t7 ; # rename, t5 -> t6 and t7 -> t8 diff --git a/mysql-test/main/rename.result b/mysql-test/main/rename.result index da9e4b62ecd..15c744e158c 100644 --- a/mysql-test/main/rename.result +++ b/mysql-test/main/rename.result @@ -148,3 +148,28 @@ create table t1 (a int) engine=memory; rename table t1 to non_existent.t2; ERROR 42000: Unknown database 'non_existent' drop table t1; +# +# Test rename IF EXISTS +# +rename table if exists t1 to t2; +Warnings: +Note 1146 Table 'test.t1' doesn't exist +alter table if exists t1 rename to t2; +Warnings: +Error 1146 Table 'test.t1' doesn't exist +create table t2 (a int); +alter table if exists t1 rename to t2; +Warnings: +Error 1146 Table 'test.t1' doesn't exist +rename table if exists t1 to t2; +Warnings: +Note 1146 Table 'test.t1' doesn't exist +create table t1 (a int); +rename table if exists t1 to t2; +ERROR 42S01: Table 't2' already exists +alter table if exists t1 rename to t2; +ERROR 42S01: Table 't2' already exists +drop table t2; +rename table if exists t1 to t2; +alter table if exists t2 rename to t1; +drop table t1; diff --git a/mysql-test/main/rename.test b/mysql-test/main/rename.test index 215ecbcbb18..a0b9f38ae2e 100644 --- a/mysql-test/main/rename.test +++ b/mysql-test/main/rename.test @@ -148,3 +148,21 @@ create table t1 (a int) engine=memory; --error ER_BAD_DB_ERROR rename table t1 to non_existent.t2; drop table t1; + +--echo # +--echo # Test rename IF EXISTS +--echo # +rename table if exists t1 to t2; +alter table if exists t1 rename to t2; +create table t2 (a int); +alter table if exists t1 rename to t2; +rename table if exists t1 to t2; +create table t1 (a int); +--error ER_TABLE_EXISTS_ERROR +rename table if exists t1 to t2; +--error ER_TABLE_EXISTS_ERROR +alter table if exists t1 rename to t2; +drop table t2; +rename table if exists t1 to t2; +alter table if exists t2 rename to t1; +drop table t1; diff --git a/mysql-test/suite/engines/funcs/r/tc_rename_error.result b/mysql-test/suite/engines/funcs/r/tc_rename_error.result index cd5108107fb..3cd5c3f2843 100644 --- a/mysql-test/suite/engines/funcs/r/tc_rename_error.result +++ b/mysql-test/suite/engines/funcs/r/tc_rename_error.result @@ -13,7 +13,7 @@ t1 CREATE TABLE `t1` ( RENAME TABLE t2 TO t1; ERROR 42S01: Table 't1' already exists RENAME TABLE t3 TO t1; -ERROR 42S01: Table 't1' already exists +ERROR 42S02: Table 'test.t3' doesn't exist RENAME TABLE t3 TO doesnotexist.t1; ERROR 42S02: Table 'test.t3' doesn't exist SHOW TABLES; diff --git a/mysql-test/suite/engines/funcs/t/tc_rename_error.test b/mysql-test/suite/engines/funcs/t/tc_rename_error.test index 6b56b1e6ca4..c119b3bf43a 100644 --- a/mysql-test/suite/engines/funcs/t/tc_rename_error.test +++ b/mysql-test/suite/engines/funcs/t/tc_rename_error.test @@ -7,9 +7,9 @@ SHOW TABLES; let $ENGINE=`select variable_value from information_schema.global_variables where variable_name='STORAGE_ENGINE'`; --replace_result $ENGINE ENGINE " PAGE_CHECKSUM=0" "" " PAGE_CHECKSUM=1" "" SHOW CREATE TABLE t1; ---error 1050 +--error ER_TABLE_EXISTS_ERROR RENAME TABLE t2 TO t1; ---error 1050 +--error ER_NO_SUCH_TABLE RENAME TABLE t3 TO t1; --error 1146 RENAME TABLE t3 TO doesnotexist.t1; diff --git a/sql/handler.cc b/sql/handler.cc index eb7b5b82c34..63800ce202e 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5624,7 +5624,8 @@ private: *hton will be NULL. */ -bool ha_table_exists(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_name, +bool ha_table_exists(THD *thd, const LEX_CSTRING *db, + const LEX_CSTRING *table_name, handlerton **hton, bool *is_sequence) { handlerton *dummy; diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 23e2e3e097f..131f74c2753 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -522,7 +522,7 @@ bool Sql_cmd_alter_table::execute(THD *thd) &alter_info, select_lex->order_list.elements, select_lex->order_list.first, - lex->ignore); + lex->ignore, lex->if_exists()); DBUG_RETURN(result); #ifdef WITH_WSREP diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 3ad7bea5661..3447032f193 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1805,7 +1805,7 @@ bool mysql_upgrade_db(THD *thd, const LEX_CSTRING *old_db) } if ((table_list= thd->lex->query_tables) && - (error= mysql_rename_tables(thd, table_list, 1))) + (error= mysql_rename_tables(thd, table_list, 1, 0))) { /* Failed to move all tables from the old database to the new one. diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index cb0d210b12c..0c863a8c02d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4160,7 +4160,7 @@ mysql_execute_command(THD *thd) res= mysql_alter_table(thd, &first_table->db, &first_table->table_name, &create_info, first_table, &alter_info, - 0, (ORDER*) 0, 0); + 0, (ORDER*) 0, 0, lex->if_exists()); break; } #ifdef HAVE_REPLICATION @@ -4272,7 +4272,7 @@ mysql_execute_command(THD *thd) WSREP_TO_ISOLATION_BEGIN(0, 0, first_table); - if (mysql_rename_tables(thd, first_table, 0)) + if (mysql_rename_tables(thd, first_table, 0, lex->if_exists())) goto error; break; } diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 8f818e321dd..f6a0c53a022 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -32,10 +32,13 @@ #include "sql_statistics.h" static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list, - bool skip_error); -static bool do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db, - const LEX_CSTRING *new_table_name, const LEX_CSTRING *new_table_alias, - bool skip_error); + bool skip_error, bool if_exits, + bool *force_if_exists); +static bool do_rename(THD *thd, TABLE_LIST *ren_table, + const LEX_CSTRING *new_db, + const LEX_CSTRING *new_table_name, + const LEX_CSTRING *new_table_alias, + bool skip_error, bool if_exists, bool *force_if_exists); static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list); @@ -44,10 +47,11 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list); the new name. */ -bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) +bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent, + bool if_exists) { bool error= 1; - bool binlog_error= 0; + bool binlog_error= 0, force_if_exists; TABLE_LIST *ren_table= 0; int to_table; const char *rename_log_table[2]= {NULL, NULL}; @@ -151,7 +155,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) An exclusive lock on table names is satisfactory to ensure no other thread accesses this table. */ - if ((ren_table=rename_tables(thd,table_list,0))) + if ((ren_table= rename_tables(thd, table_list, 0, if_exists, + &force_if_exists))) { /* Rename didn't succeed; rename back the tables in reverse order */ TABLE_LIST *table; @@ -165,7 +170,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) table= table->next_local->next_local) ; table= table->next_local->next_local; // Skip error table /* Revert to old names */ - rename_tables(thd, table, 1); + rename_tables(thd, table, 1, if_exists, &force_if_exists); /* Revert the table list (for prepared statements) */ table_list= reverse_table_list(table_list); @@ -246,6 +251,9 @@ do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table, new_table_name The new table/view name new_table_alias The new table/view alias skip_error Whether to skip error + if_exists Skip error, but only if the table didn't exists + force_if_exists Set to 1 if we have to log the query with 'IF EXISTS' + Otherwise don't touch the value DESCRIPTION Rename a single table or a view. @@ -257,13 +265,16 @@ do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table, static bool do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db, - const LEX_CSTRING *new_table_name, const LEX_CSTRING *new_table_alias, - bool skip_error) + const LEX_CSTRING *new_table_name, + const LEX_CSTRING *new_table_alias, + bool skip_error, bool if_exists, bool *force_if_exists) { int rc= 1; - handlerton *hton; + handlerton *hton, *new_hton; LEX_CSTRING old_alias, new_alias; DBUG_ENTER("do_rename"); + DBUG_PRINT("enter", ("skip_error: %d if_exists: %d", (int) skip_error, + (int) if_exists)); if (lower_case_table_names == 2) { @@ -277,13 +288,19 @@ do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db, } DBUG_ASSERT(new_alias.str); - if (ha_table_exists(thd, new_db, &new_alias)) + if (!ha_table_exists(thd, &ren_table->db, &old_alias, &hton) || !hton) + { + my_error(ER_NO_SUCH_TABLE, MYF((skip_error | if_exists) ? ME_NOTE : 0), + ren_table->db.str, old_alias.str); + DBUG_RETURN(skip_error || if_exists ? 0 : 1); + } + + if (ha_table_exists(thd, new_db, &new_alias, &new_hton)) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias.str); DBUG_RETURN(1); // This can't be skipped } - if (ha_table_exists(thd, &ren_table->db, &old_alias, &hton) && hton) { DBUG_ASSERT(!thd->locked_tables_mode); @@ -335,14 +352,7 @@ do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db, rc= mysql_rename_view(thd, new_db, &new_alias, ren_table); } } - else - { - my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db.str, old_alias.str); - } - if (unlikely(rc && !skip_error)) - DBUG_RETURN(1); - - DBUG_RETURN(0); + DBUG_RETURN(rc && !skip_error ? 1 : 0); } @@ -359,6 +369,9 @@ do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db, thd Thread handle table_list List of tables to rename skip_error Whether to skip errors + if_exists Don't give an error if table doesn't exists + force_if_exists Set to 1 if we have to log the query with 'IF EXISTS' + Otherwise set it to 0 DESCRIPTION Take a table/view name from and odd list element and rename it to a @@ -371,12 +384,14 @@ do_rename(THD *thd, TABLE_LIST *ren_table, const LEX_CSTRING *new_db, */ static TABLE_LIST * -rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) +rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error, + bool if_exists, bool *force_if_exists) { TABLE_LIST *ren_table, *new_table; - DBUG_ENTER("rename_tables"); + *force_if_exists= 0; + for (ren_table= table_list; ren_table; ren_table= new_table->next_local) { new_table= ren_table->next_local; @@ -384,7 +399,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool 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)) + &new_table->alias, skip_error, if_exists, force_if_exists)) DBUG_RETURN(ren_table); } DBUG_RETURN(0); diff --git a/sql/sql_rename.h b/sql/sql_rename.h index 1b9fcfb12bc..1f5f94b0f5c 100644 --- a/sql/sql_rename.h +++ b/sql/sql_rename.h @@ -19,6 +19,7 @@ class THD; struct TABLE_LIST; -bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent); +bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent, + bool if_exists); #endif /* SQL_RENAME_INCLUDED */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2d4ff71d0c1..ed1f6fe7cbd 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2777,7 +2777,7 @@ bool quick_rm_table(THD *thd, handlerton *base, const LEX_CSTRING *db, delete file; } if (!(flags & (FRM_ONLY|NO_HA_TABLE))) - error|= ha_delete_table(current_thd, base, path, db, table_name, 0); + error|= ha_delete_table(thd, base, path, db, table_name, 0); if (likely(error == 0)) { @@ -4392,8 +4392,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, /** check comment length of table, column, index and partition - If comment lenght is more than the standard length - truncate it and store the comment lenght upto the standard + If comment length is more than the standard length + truncate it and store the comment length upto the standard comment length size @param thd Thread handle @@ -9467,9 +9467,40 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, HA_CREATE_INFO *create_info, TABLE_LIST *table_list, Alter_info *alter_info, - uint order_num, ORDER *order, bool ignore) + uint order_num, ORDER *order, bool ignore, + bool if_exists) { - bool engine_changed; + bool engine_changed, error; + bool no_ha_table= true; /* We have not created table in storage engine yet */ + TABLE *table, *new_table; +#ifdef WITH_PARTITION_STORAGE_ENGINE + bool partition_changed= false; + bool fast_alter_partition= false; +#endif + /* + Create .FRM for new version of table with a temporary name. + We don't log the statement, it will be logged later. + + Keep information about keys in newly created table as it + will be used later to construct Alter_inplace_info object + and by fill_alter_inplace_info() call. + */ + KEY *key_info; + uint key_count; + /* + Remember if the new definition has new VARCHAR column; + create_info->varchar will be reset in create_table_impl()/ + mysql_prepare_create_table(). + */ + bool varchar= create_info->varchar, table_creation_was_logged= 0; + uint tables_opened; + handlerton *new_db_type, *old_db_type; + ha_rows copied=0, deleted=0; + LEX_CUSTRING frm= {0,0}; + char index_file[FN_REFLEN], data_file[FN_REFLEN]; + MDL_request target_mdl_request; + MDL_ticket *mdl_ticket= 0; + Alter_table_prelocking_strategy alter_prelocking_strategy; DBUG_ENTER("mysql_alter_table"); /* @@ -9517,17 +9548,38 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, */ table_list->required_type= TABLE_TYPE_NORMAL; - Alter_table_prelocking_strategy alter_prelocking_strategy; - DEBUG_SYNC(thd, "alter_table_before_open_tables"); - uint tables_opened; thd->open_options|= HA_OPEN_FOR_ALTER; thd->mdl_backup_ticket= 0; - bool error= open_tables(thd, &table_list, &tables_opened, 0, - &alter_prelocking_strategy); + error= open_tables(thd, &table_list, &tables_opened, 0, + &alter_prelocking_strategy); thd->open_options&= ~HA_OPEN_FOR_ALTER; + if (unlikely(error)) + { + if (if_exists) + { + int tmp_errno= thd->get_stmt_da()->sql_errno(); + if (tmp_errno == ER_NO_SUCH_TABLE) + { + /* + ALTER TABLE IF EXISTS was used on not existing table + We have to log the query on a slave as the table may be a shared one + from the master and we need to ensure that the next slave can see + the statement as this slave may not have the table shared + */ + thd->clear_error(); + if (thd->slave_thread && + write_bin_log(thd, true, thd->query(), thd->query_length())) + DBUG_RETURN(true); + my_ok(thd); + DBUG_RETURN(0); + } + } + DBUG_RETURN(true); + } + #ifdef WITH_WSREP if (WSREP(thd) && (thd->lex->sql_command == SQLCOM_ALTER_TABLE || @@ -9539,10 +9591,8 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, DEBUG_SYNC(thd, "alter_table_after_open_tables"); - TABLE *table= table_list->table; - bool versioned= table && table->versioned(); - - if (versioned) + table= table_list->table; + if (table->versioned()) { if (handlerton *hton1= create_info->db_type) { @@ -9577,11 +9627,12 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, };); #endif // WITH_WSREP - if (unlikely(error)) - DBUG_RETURN(true); + Alter_table_ctx alter_ctx(thd, table_list, tables_opened, new_db, new_name); + mdl_ticket= table->mdl_ticket; + + table_creation_was_logged= table->s->table_creation_was_logged; table->use_all_columns(); - MDL_ticket *mdl_ticket= table->mdl_ticket; /* Prohibit changing of the UNION list of a non-temporary MERGE table @@ -9598,10 +9649,6 @@ bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, DBUG_RETURN(true); } - Alter_table_ctx alter_ctx(thd, table_list, tables_opened, new_db, new_name); - - MDL_request target_mdl_request; - /* Check that we are not trying to rename to an existing table */ if (alter_ctx.is_table_renamed()) { @@ -9833,8 +9880,7 @@ do_continue:; my_ok(thd, 0L, 0L, alter_ctx.tmp_buff); /* We don't replicate alter table statement on temporary tables */ - if (table->s->tmp_table == NO_TMP_TABLE || - !thd->is_current_stmt_binlog_format_row()) + if (table_creation_was_logged) { if (write_bin_log(thd, true, thd->query(), thd->query_length())) DBUG_RETURN(true); @@ -9880,8 +9926,6 @@ do_continue:; /* We have to do full alter table. */ #ifdef WITH_PARTITION_STORAGE_ENGINE - bool partition_changed= false; - bool fast_alter_partition= false; { if (prep_alter_part_table(thd, table, alter_info, create_info, &partition_changed, &fast_alter_partition)) @@ -10000,10 +10044,9 @@ do_continue:; It's therefore important that the assignment below is done after prep_alter_part_table. */ - handlerton *new_db_type= create_info->db_type; - handlerton *old_db_type= table->s->db_type(); - TABLE *new_table= NULL; - ha_rows copied=0,deleted=0; + new_db_type= create_info->db_type; + old_db_type= table->s->db_type(); + new_table= NULL; /* Handling of symlinked tables: @@ -10029,8 +10072,6 @@ do_continue:; Copy data. Remove old table and symlinks. */ - char index_file[FN_REFLEN], data_file[FN_REFLEN]; - if (!alter_ctx.is_database_changed()) { if (create_info->index_file_name) @@ -10058,24 +10099,6 @@ do_continue:; DEBUG_SYNC(thd, "alter_table_before_create_table_no_lock"); - /* - Create .FRM for new version of table with a temporary name. - We don't log the statement, it will be logged later. - - Keep information about keys in newly created table as it - will be used later to construct Alter_inplace_info object - and by fill_alter_inplace_info() call. - */ - KEY *key_info; - uint key_count; - /* - Remember if the new definition has new VARCHAR column; - create_info->varchar will be reset in create_table_impl()/ - mysql_prepare_create_table(). - */ - bool varchar= create_info->varchar; - LEX_CUSTRING frm= {0,0}; - tmp_disable_binlog(thd); create_info->options|=HA_CREATE_TMP_ALTER; error= create_table_impl(thd, alter_ctx.db, alter_ctx.table_name, @@ -10091,9 +10114,6 @@ do_continue:; DBUG_RETURN(true); } - /* Remember that we have not created table in storage engine yet. */ - bool no_ha_table= true; - if (alter_info->requested_algorithm != Alter_info::ALTER_TABLE_ALGORITHM_COPY) { Alter_inplace_info ha_alter_info(create_info, alter_info, @@ -10313,9 +10333,7 @@ do_continue:; order_num, order, &copied, &deleted, alter_info->keys_onoff, &alter_ctx)) - { goto err_new_table_cleanup; - } } else { @@ -11088,8 +11106,8 @@ bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list, bool table_copy) alter_info.requested_algorithm= Alter_info::ALTER_TABLE_ALGORITHM_COPY; bool res= mysql_alter_table(thd, &null_clex_str, &null_clex_str, &create_info, - table_list, &alter_info, 0, - (ORDER *) 0, 0); + table_list, &alter_info, 0, + (ORDER *) 0, 0, 0); table_list->next_global= next_table; DBUG_RETURN(res); } @@ -11241,6 +11259,7 @@ err: @retval true Engine not available/supported, error has been reported. @retval false Engine available/supported. */ + bool check_engine(THD *thd, const char *db_name, const char *table_name, HA_CREATE_INFO *create_info) { diff --git a/sql/sql_table.h b/sql/sql_table.h index ae05fe05c5d..debd55e7ab9 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -217,11 +217,13 @@ bool mysql_prepare_alter_table(THD *thd, TABLE *table, Alter_table_ctx *alter_ctx); bool mysql_trans_prepare_alter_copy_data(THD *thd); bool mysql_trans_commit_alter_copy_data(THD *thd); -bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, const LEX_CSTRING *new_name, +bool mysql_alter_table(THD *thd, const LEX_CSTRING *new_db, + const LEX_CSTRING *new_name, HA_CREATE_INFO *create_info, TABLE_LIST *table_list, Alter_info *alter_info, - uint order_num, ORDER *order, bool ignore); + uint order_num, ORDER *order, bool ignore, + bool if_exists); bool mysql_compare_tables(TABLE *table, Alter_info *alter_info, HA_CREATE_INFO *create_info, @@ -244,7 +246,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, bool if_exists, int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, bool drop_temporary, bool drop_view, bool drop_sequence, - bool log_query, bool dont_free_locks); + bool dont_log_query, bool dont_free_locks); bool log_drop_table(THD *thd, const LEX_CSTRING *db_name, const LEX_CSTRING *table_name, bool temporary_table); bool quick_rm_table(THD *thd, handlerton *base, const LEX_CSTRING *db, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index cf9d11efe08..1bc5be2bab9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7098,10 +7098,11 @@ alter: MYSQL_YYABORT; DBUG_ASSERT(!Lex->m_sql_cmd); } - alter_options TABLE_SYM table_ident opt_lock_wait_timeout + alter_options TABLE_SYM opt_if_exists table_ident opt_lock_wait_timeout { + Lex->create_info.set($5); if (!Lex->first_select_lex()-> - add_table_to_list(thd, $5, NULL, TL_OPTION_UPDATING, + add_table_to_list(thd, $6, NULL, TL_OPTION_UPDATING, TL_READ_NO_INSERT, MDL_SHARED_UPGRADABLE)) MYSQL_YYABORT; Lex->first_select_lex()->db= @@ -8298,9 +8299,10 @@ opt_no_write_to_binlog: ; rename: - RENAME table_or_tables + RENAME table_or_tables opt_if_exists { Lex->sql_command= SQLCOM_RENAME_TABLE; + Lex->create_info.set($3); if (Lex->main_select_push()) MYSQL_YYABORT; } |