Commit 242bb263 authored by Sergey Glukhov's avatar Sergey Glukhov

Bug#42364 SHOW ERRORS returns empty resultset after dropping non existent table

partial backport of bug43138 fix
parent 3a5b80ab
...@@ -313,4 +313,9 @@ ERROR 22001: Data too long for column 'c_tinytext' at row 1 ...@@ -313,4 +313,9 @@ ERROR 22001: Data too long for column 'c_tinytext' at row 1
insert into t2 values(@q); insert into t2 values(@q);
ERROR 22001: Data too long for column 'c_tinyblob' at row 1 ERROR 22001: Data too long for column 'c_tinyblob' at row 1
drop table t1, t2; drop table t1, t2;
DROP TABLE t1;
ERROR 42S02: Unknown table 't1'
SHOW ERRORS;
Level Code Message
Error 1051 Unknown table 't1'
End of 5.0 tests End of 5.0 tests
...@@ -225,4 +225,11 @@ insert into t2 values(@q); ...@@ -225,4 +225,11 @@ insert into t2 values(@q);
drop table t1, t2; drop table t1, t2;
#
# Bug#42364 SHOW ERRORS returns empty resultset after dropping non existent table
#
--error ER_BAD_TABLE_ERROR
DROP TABLE t1;
SHOW ERRORS;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -399,6 +399,31 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length, ...@@ -399,6 +399,31 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length,
return buffer; return buffer;
} }
/**
Implementation of Drop_table_error_handler::handle_error().
The reason in having this implementation is to silence technical low-level
warnings during DROP TABLE operation. Currently we don't want to expose
the following warnings during DROP TABLE:
- Some of table files are missed or invalid (the table is going to be
deleted anyway, so why bother that something was missed);
- A trigger associated with the table does not have DEFINER (One of the
MySQL specifics now is that triggers are loaded for the table being
dropped. So, we may have a warning that trigger does not have DEFINER
attribute during DROP TABLE operation).
@return TRUE if the condition is handled.
*/
bool Drop_table_error_handler::handle_error(uint sql_errno,
const char *message,
MYSQL_ERROR::enum_warning_level level,
THD *thd)
{
return ((sql_errno == EE_DELETE && my_errno == ENOENT) ||
sql_errno == ER_TRG_NO_DEFINER);
}
/** /**
Clear this diagnostics area. Clear this diagnostics area.
......
...@@ -1091,6 +1091,31 @@ public: ...@@ -1091,6 +1091,31 @@ public:
}; };
/**
This class is an internal error handler implementation for
DROP TABLE statements. The thing is that there may be warnings during
execution of these statements, which should not be exposed to the user.
This class is intended to silence such warnings.
*/
class Drop_table_error_handler : public Internal_error_handler
{
public:
Drop_table_error_handler(Internal_error_handler *err_handler)
:m_err_handler(err_handler)
{ }
public:
bool handle_error(uint sql_errno,
const char *message,
MYSQL_ERROR::enum_warning_level level,
THD *thd);
private:
Internal_error_handler *m_err_handler;
};
/** /**
Stores status of the currently executed statement. Stores status of the currently executed statement.
Cleared at the beginning of the statement, and then Cleared at the beginning of the statement, and then
......
...@@ -1772,6 +1772,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, ...@@ -1772,6 +1772,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
my_bool drop_temporary) my_bool drop_temporary)
{ {
bool error= FALSE, need_start_waiters= FALSE; bool error= FALSE, need_start_waiters= FALSE;
Drop_table_error_handler err_handler(thd->get_internal_handler());
DBUG_ENTER("mysql_rm_table"); DBUG_ENTER("mysql_rm_table");
/* mark for close and remove all cached entries */ /* mark for close and remove all cached entries */
...@@ -1792,7 +1793,10 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, ...@@ -1792,7 +1793,10 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
LOCK_open during wait_if_global_read_lock(), other threads could not LOCK_open during wait_if_global_read_lock(), other threads could not
close their tables. This would make a pretty deadlock. close their tables. This would make a pretty deadlock.
*/ */
thd->push_internal_handler(&err_handler);
error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0); error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
thd->pop_internal_handler();
if (need_start_waiters) if (need_start_waiters)
start_waiting_global_read_lock(thd); start_waiting_global_read_lock(thd);
...@@ -1894,9 +1898,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, ...@@ -1894,9 +1898,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
DBUG_RETURN(1); DBUG_RETURN(1);
} }
/* Don't give warnings for not found errors, as we already generate notes */
thd->no_warnings_for_error= 1;
for (table= tables; table; table= table->next_local) for (table= tables; table; table= table->next_local)
{ {
char *db=table->db; char *db=table->db;
...@@ -2145,7 +2146,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, ...@@ -2145,7 +2146,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
err_with_placeholders: err_with_placeholders:
unlock_table_names(thd, tables, (TABLE_LIST*) 0); unlock_table_names(thd, tables, (TABLE_LIST*) 0);
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
thd->no_warnings_for_error= 0;
DBUG_RETURN(error); DBUG_RETURN(error);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment