summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc66
1 files changed, 51 insertions, 15 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index df499797797..ff389a96a8d 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1818,7 +1818,8 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
&syntax_len,
TRUE, TRUE,
lpt->create_info,
- lpt->alter_info)))
+ lpt->alter_info,
+ NULL)))
{
DBUG_RETURN(TRUE);
}
@@ -1921,7 +1922,8 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
&syntax_len,
TRUE, TRUE,
lpt->create_info,
- lpt->alter_info)))
+ lpt->alter_info,
+ NULL)))
{
error= 1;
goto err;
@@ -2205,6 +2207,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");
@@ -2234,6 +2237,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)
{
@@ -2257,6 +2269,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);
@@ -2333,10 +2346,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(".");
@@ -2551,7 +2566,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)
{
@@ -2561,7 +2578,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)
{
@@ -4367,7 +4386,8 @@ handler *mysql_create_frm_image(THD *thd,
&syntax_len,
TRUE, TRUE,
create_info,
- alter_info)))
+ alter_info,
+ NULL)))
goto err;
part_info->part_info_string= part_syntax_buf;
part_info->part_info_len= syntax_len;
@@ -5260,7 +5280,6 @@ int 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)
@@ -7909,7 +7928,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
Table maybe does not exist, but we got an exclusive lock
on the name, now we can safely try to find out for sure.
*/
- if (!access(alter_ctx.get_new_filename(), F_OK))
+ if (ha_table_exists(thd, alter_ctx.new_db, alter_ctx.new_name, 0))
{
/* Table will be closed in do_command() */
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias);
@@ -9128,6 +9147,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",
@@ -9166,7 +9191,6 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
open_and_lock_tables(thd, table, FALSE, 0))
{
t= NULL;
- thd->clear_error(); // these errors shouldn't get client
}
else
t= table->table;
@@ -9180,7 +9204,6 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
{
/* Table didn't exist */
protocol->store_null();
- thd->clear_error();
}
else
{
@@ -9268,11 +9291,24 @@ 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);
}
+
+ 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;
}