summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2019-12-30 13:34:28 +0200
committerMonty <monty@mariadb.org>2020-03-24 20:47:41 +0200
commitbff79492c5f6c9669b9dc9bf2cf0483b3b001da7 (patch)
tree7d13874ae2bf8a8c2caba079f1010d401d65dcaf
parent5f5c63e0fe6eac590549bdb76204a07cb2fe2aa1 (diff)
downloadmariadb-git-bff79492c5f6c9669b9dc9bf2cf0483b3b001da7.tar.gz
Added IF EXISTS to RENAME TABLE and ALTER TABLE
-rw-r--r--mysql-test/main/alter_table.result19
-rw-r--r--mysql-test/main/alter_table.test12
-rw-r--r--mysql-test/main/ps_1general.result8
-rw-r--r--mysql-test/main/ps_1general.test8
-rw-r--r--mysql-test/main/rename.result25
-rw-r--r--mysql-test/main/rename.test18
-rw-r--r--mysql-test/suite/engines/funcs/r/tc_rename_error.result2
-rw-r--r--mysql-test/suite/engines/funcs/t/tc_rename_error.test4
-rw-r--r--sql/handler.cc3
-rw-r--r--sql/sql_alter.cc2
-rw-r--r--sql/sql_db.cc2
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_rename.cc63
-rw-r--r--sql/sql_rename.h3
-rw-r--r--sql/sql_table.cc131
-rw-r--r--sql/sql_table.h8
-rw-r--r--sql/sql_yacc.yy8
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;
}