diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-11-19 13:16:25 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-11-19 13:16:25 +0100 |
commit | fa3f8a18b247d5d7d86d60d016681cc188522f80 (patch) | |
tree | 180232f5e13c81e22ae9374b41be168ed9578932 /sql/sql_table.cc | |
parent | efab095c7f8f044525ce7d2313fad5f86032baab (diff) | |
parent | 543b6e02246db25d8a61574fc709b28e7720d1a0 (diff) | |
download | mariadb-git-fa3f8a18b247d5d7d86d60d016681cc188522f80.tar.gz |
mysql-5.5.34 merge
(some patches reverted, test case added)
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r-- | sql/sql_table.cc | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc index d7102c0e3f6..eda178fcc64 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2046,6 +2046,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, bool non_tmp_error= 0; bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0; bool non_tmp_table_deleted= 0; + bool is_drop_tmp_if_exists_added= 0; String built_query; String built_trans_tmp_query, built_non_trans_tmp_query; DBUG_ENTER("mysql_rm_table_no_locks"); @@ -2074,6 +2075,15 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, table stems from the fact that such drop does not commit an ongoing transaction and changes to non-transactional tables must be written ahead of the transaction in some circumstances. + + 6- Slave SQL thread ignores all replicate-* filter rules + for temporary tables with 'IF EXISTS' clause. (See sql/sql_parse.cc: + mysql_execute_command() for details). These commands will be binlogged + as they are, even if the default database (from USE `db`) is not present + on the Slave. This can cause point in time recovery failures later + when user uses the slave's binlog to re-apply. Hence at the time of binary + logging, these commands will be written with fully qualified table names + and use `db` will be suppressed. */ if (!dont_log_query) { @@ -2097,6 +2107,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, if (thd->is_current_stmt_binlog_format_row() || if_exists) { + is_drop_tmp_if_exists_added= true; built_trans_tmp_query.set_charset(system_charset_info); built_trans_tmp_query.append("DROP TEMPORARY TABLE IF EXISTS "); built_non_trans_tmp_query.set_charset(system_charset_info); @@ -2174,10 +2185,12 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, String *built_ptr_query= (is_trans ? &built_trans_tmp_query : &built_non_trans_tmp_query); /* - Don't write the database name if it is the current one (or if - thd->db is NULL). + Write the database name if it is not the current one or if + thd->db is NULL or 'IF EXISTS' clause is present in 'DROP TEMPORARY' + query. */ - if (thd->db == NULL || strcmp(db,thd->db) != 0) + if (thd->db == NULL || strcmp(db,thd->db) != 0 + || is_drop_tmp_if_exists_added ) { append_identifier(thd, built_ptr_query, db, db_length); built_ptr_query->append("."); @@ -2373,7 +2386,9 @@ err: error |= thd->binlog_query(THD::STMT_QUERY_TYPE, built_non_trans_tmp_query.ptr(), built_non_trans_tmp_query.length(), - FALSE, FALSE, FALSE, 0); + FALSE, FALSE, + is_drop_tmp_if_exists_added, + 0); } if (trans_tmp_table_deleted) { @@ -2383,7 +2398,9 @@ err: error |= thd->binlog_query(THD::STMT_QUERY_TYPE, built_trans_tmp_query.ptr(), built_trans_tmp_query.length(), - TRUE, FALSE, FALSE, 0); + TRUE, FALSE, + is_drop_tmp_if_exists_added, + 0); } if (non_tmp_table_deleted) { @@ -4967,7 +4984,6 @@ mysql_discard_or_import_tablespace(THD *thd, error= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); err: - trans_rollback_stmt(thd); thd->tablespace_op=FALSE; if (error == 0) @@ -7648,6 +7664,12 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, Protocol *protocol= thd->protocol; DBUG_ENTER("mysql_checksum_table"); + /* + CHECKSUM TABLE returns results and rollbacks statement transaction, + so it should not be used in stored function or trigger. + */ + DBUG_ASSERT(! thd->in_sub_stmt); + field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2)); item->maybe_null= 1; field_list.push_back(item= new Item_int("Checksum", (longlong) 1, @@ -7666,7 +7688,6 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, strxmov(table_name, table->db ,".", table->table_name, NullS); t= table->table= open_n_lock_single_table(thd, table, TL_READ, 0); - thd->clear_error(); // these errors shouldn't get client protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); @@ -7675,7 +7696,6 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, { /* Table didn't exist */ protocol->store_null(); - thd->clear_error(); } else { @@ -7763,9 +7783,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, t->file->ha_rnd_end(); } } - thd->clear_error(); - if (! thd->in_sub_stmt) - trans_rollback_stmt(thd); + trans_rollback_stmt(thd); close_thread_tables(thd); /* Don't release metadata locks, this will be done at @@ -7773,6 +7791,21 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, */ table->table=0; // For query cache } + + if (thd->transaction_rollback_request) + { + /* + If transaction rollback was requested we honor it. To do this we + abort statement and return error as not only CHECKSUM TABLE is + rolled back but the whole transaction in which it was used. + */ + thd->protocol->remove_last_row(); + goto err; + } + + /* Hide errors from client. Return NULL for problematic tables instead. */ + thd->clear_error(); + if (protocol->write()) goto err; } |