summaryrefslogtreecommitdiff
path: root/sql/sql_partition_admin.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_partition_admin.cc')
-rw-r--r--sql/sql_partition_admin.cc92
1 files changed, 81 insertions, 11 deletions
diff --git a/sql/sql_partition_admin.cc b/sql/sql_partition_admin.cc
index 54484846609..7822cab5ff0 100644
--- a/sql/sql_partition_admin.cc
+++ b/sql/sql_partition_admin.cc
@@ -46,6 +46,16 @@ bool Sql_cmd_partition_unsupported::execute(THD *)
#else
+static bool return_with_logging(THD *thd)
+{
+ if (thd->slave_thread &&
+ write_bin_log_with_if_exists(thd, true, false, true))
+ return(true);
+ my_ok(thd);
+ return(false);
+}
+
+
bool Sql_cmd_alter_table_exchange_partition::execute(THD *thd)
{
/* Moved from mysql_execute_command */
@@ -63,7 +73,7 @@ bool Sql_cmd_alter_table_exchange_partition::execute(THD *thd)
*/
IF_DBUG(HA_CREATE_INFO create_info(lex->create_info);,)
Alter_info alter_info(lex->alter_info, thd->mem_root);
- ulong priv_needed= ALTER_ACL | DROP_ACL | INSERT_ACL | CREATE_ACL;
+ privilege_t priv_needed(ALTER_ACL | DROP_ACL | INSERT_ACL | CREATE_ACL);
DBUG_ENTER("Sql_cmd_alter_table_exchange_partition::execute");
@@ -501,7 +511,8 @@ bool Sql_cmd_alter_table_exchange_partition::
MDL_ticket *swap_table_mdl_ticket= NULL;
MDL_ticket *part_table_mdl_ticket= NULL;
uint table_counter;
- bool error= TRUE;
+ bool error= TRUE, force_if_exists= 0;
+ ulonglong save_option_bits= thd->variables.option_bits;
DBUG_ENTER("mysql_exchange_partition");
DBUG_ASSERT(alter_info->partition_flags & ALTER_PARTITION_EXCHANGE);
@@ -529,14 +540,40 @@ bool Sql_cmd_alter_table_exchange_partition::
table_list->mdl_request.set_type(MDL_SHARED_NO_WRITE);
if (unlikely(open_tables(thd, &table_list, &table_counter, 0,
&alter_prelocking_strategy)))
+ {
+ if (thd->lex->if_exists() &&
+ thd->get_stmt_da()->sql_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(false);
+ }
DBUG_RETURN(true);
+ }
part_table= table_list->table;
swap_table= swap_table_list->table;
+ if (part_table->file->check_if_updates_are_ignored("ALTER"))
+ DBUG_RETURN(return_with_logging(thd));
+
if (unlikely(check_exchange_partition(swap_table, part_table)))
DBUG_RETURN(TRUE);
+ /* Add IF EXISTS to binlog if shared table */
+ if (part_table->file->partition_ht()->flags &
+ HTON_TABLE_MAY_NOT_EXIST_ON_SLAVE)
+ force_if_exists= 1;
+
/* set lock pruning on first table */
partition_name= alter_info->partition_names.head();
if (unlikely(table_list->table->part_info->
@@ -563,8 +600,8 @@ bool Sql_cmd_alter_table_exchange_partition::
swap_table_list->db.str,
swap_table_list->table_name.str,
"", 0);
- /* create a unique temp name #sqlx-nnnn_nnnn, x for eXchange */
- my_snprintf(temp_name, sizeof(temp_name), "%sx-%lx_%llx",
+ /* create a unique temp name */
+ my_snprintf(temp_name, sizeof(temp_name), "%s-exchange-%lx-%llx",
tmp_file_prefix, current_pid, thd->thread_id);
if (lower_case_table_names)
my_casedn_str(files_charset_info, temp_name);
@@ -638,6 +675,9 @@ bool Sql_cmd_alter_table_exchange_partition::
*/
(void) thd->locked_tables_list.reopen_tables(thd, false);
+ if (force_if_exists)
+ thd->variables.option_bits|= OPTION_IF_EXISTS;
+
if (unlikely((error= write_bin_log(thd, TRUE, thd->query(),
thd->query_length()))))
{
@@ -648,6 +688,7 @@ bool Sql_cmd_alter_table_exchange_partition::
(void) exchange_name_with_ddl_log(thd, part_file_name, swap_file_name,
temp_file_name, table_hton);
}
+ thd->variables.option_bits= save_option_bits;
err:
if (thd->locked_tables_mode)
@@ -746,7 +787,7 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
Alter_info *alter_info= &thd->lex->alter_info;
uint table_counter, i;
List<String> partition_names_list;
- bool binlog_stmt;
+ bool binlog_stmt, force_if_exists= 0;
DBUG_ENTER("Sql_cmd_alter_table_truncate_partition::execute");
/*
@@ -784,16 +825,41 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
#endif /* WITH_WSREP */
if (open_tables(thd, &first_table, &table_counter, 0))
- DBUG_RETURN(true);
+ {
+ if (thd->lex->if_exists() &&
+ thd->get_stmt_da()->sql_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();
+ DBUG_RETURN(return_with_logging(thd));
+ }
+ DBUG_RETURN(TRUE);
+ }
- if (!first_table->table || first_table->view ||
- first_table->table->s->db_type() != partition_hton)
+ if (!first_table->table || first_table->view)
{
my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
DBUG_RETURN(TRUE);
}
-
+ if (first_table->table->file->check_if_updates_are_ignored("ALTER"))
+ DBUG_RETURN(return_with_logging(thd));
+
+ if (first_table->table->s->db_type() != partition_hton)
+ {
+ my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
+
+ if (first_table->table->file->partition_ht()->flags &
+ HTON_TABLE_MAY_NOT_EXIST_ON_SLAVE)
+ force_if_exists= 1;
+
/*
Prune all, but named partitions,
to avoid excessive calls to external_lock().
@@ -825,8 +891,7 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
if (thd->mdl_context.upgrade_shared_lock(ticket, MDL_EXCLUSIVE, timeout))
DBUG_RETURN(TRUE);
- tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN, first_table->db.str,
- first_table->table_name.str, FALSE);
+ first_table->table->s->tdc->flush(thd, true);
partition= (ha_partition*) first_table->table->file;
/* Invoke the handler method responsible for truncating the partition. */
@@ -846,9 +911,14 @@ bool Sql_cmd_alter_table_truncate_partition::execute(THD *thd)
*/
if (likely(error != HA_ERR_WRONG_COMMAND))
{
+ ulonglong save_option_bits= thd->variables.option_bits;
+ if (force_if_exists)
+ thd->variables.option_bits|= OPTION_IF_EXISTS;
+
query_cache_invalidate3(thd, first_table, FALSE);
if (binlog_stmt)
error|= write_bin_log(thd, !error, thd->query(), thd->query_length());
+ thd->variables.option_bits= save_option_bits;
}
/*