diff options
author | unknown <Li-Bing.Song@sun.com> | 2009-08-13 10:48:57 +0800 |
---|---|---|
committer | unknown <Li-Bing.Song@sun.com> | 2009-08-13 10:48:57 +0800 |
commit | fce4fa362c5234f1e85212060f61b842844192b7 (patch) | |
tree | 35a500b7817051b61aeb42aba97e0a4b6d6e774c /sql/sql_insert.cc | |
parent | 89260b24c9334fb7357ed5fdac62e24c278cda3d (diff) | |
download | mariadb-git-fce4fa362c5234f1e85212060f61b842844192b7.tar.gz |
BUG#45574 CREATE IF NOT EXISTS is not binlogged if the object exists
There is an inconsistency with DROP DATABASE|TABLE|EVENT IF EXISTS and
CREATE DATABASE|TABLE|EVENT IF NOT EXISTS. DROP IF EXISTS statements are
binlogged even if either the DB, TABLE or EVENT does not exist. In
contrast, Only the CREATE EVENT IF NOT EXISTS is binlogged when the EVENT
exists.
This patch fixes the following cases for all the replication formats:
CREATE DATABASE IF NOT EXISTS.
CREATE TABLE IF NOT EXISTS,
CREATE TABLE IF NOT EXISTS ... LIKE,
CREAET TABLE IF NOT EXISTS ... SELECT.
sql/sql_insert.cc:
Part of the code was moved from the create_table_from_items to select_create::prepare.
When replication is row based, CREATE TABLE IF NOT EXISTS.. SELECT is binlogged if the table exists.
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r-- | sql/sql_insert.cc | 52 |
1 files changed, 29 insertions, 23 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 7d581f8c3a9..a799cbea4c2 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3392,25 +3392,6 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, bool not_used; DBUG_ENTER("create_table_from_items"); - DBUG_EXECUTE_IF("sleep_create_select_before_check_if_exists", my_sleep(6000000);); - - if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE) && - create_table->table->db_stat) - { - /* Table already exists and was open at open_and_lock_tables() stage. */ - if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) - { - create_info->table_existed= 1; // Mark that table existed - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), - create_table->table_name); - DBUG_RETURN(create_table->table); - } - - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name); - DBUG_RETURN(0); - } - tmp_table.alias= 0; tmp_table.timestamp_field= 0; tmp_table.s= &share; @@ -3612,10 +3593,35 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) thd->binlog_start_trans_and_stmt(); } - if (!(table= create_table_from_items(thd, create_info, create_table, - alter_info, &values, - &extra_lock, hook_ptr))) - DBUG_RETURN(-1); // abort() deletes table + DBUG_EXECUTE_IF("sleep_create_select_before_check_if_exists", my_sleep(6000000);); + + if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE) && + create_table->table->db_stat) + { + /* Table already exists and was open at open_and_lock_tables() stage. */ + if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) + { + /* Mark that table existed */ + create_info->table_existed= 1; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), + create_table->table_name); + if (thd->current_stmt_binlog_row_based) + binlog_show_create_table(&(create_table->table), 1); + table= create_table->table; + } + else + { + my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_table->table_name); + DBUG_RETURN(-1); + } + } + else + if (!(table= create_table_from_items(thd, create_info, create_table, + alter_info, &values, + &extra_lock, hook_ptr))) + /* abort() deletes table */ + DBUG_RETURN(-1); if (extra_lock) { |