diff options
-rw-r--r-- | mysql-test/r/warnings.result | 5 | ||||
-rw-r--r-- | mysql-test/t/warnings.test | 7 | ||||
-rw-r--r-- | sql/sql_class.cc | 25 | ||||
-rw-r--r-- | sql/sql_class.h | 25 | ||||
-rw-r--r-- | sql/sql_table.cc | 8 |
5 files changed, 66 insertions, 4 deletions
diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 2e393aea9e4..8a87852d582 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -313,4 +313,9 @@ ERROR 22001: Data too long for column 'c_tinytext' at row 1 insert into t2 values(@q); ERROR 22001: Data too long for column 'c_tinyblob' at row 1 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 diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test index 12421170eba..176f320e390 100644 --- a/mysql-test/t/warnings.test +++ b/mysql-test/t/warnings.test @@ -225,4 +225,11 @@ insert into t2 values(@q); 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 diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 3f568566c89..daef5a26742 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -399,6 +399,31 @@ char *thd_security_context(THD *thd, char *buffer, unsigned int length, 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. diff --git a/sql/sql_class.h b/sql/sql_class.h index f52d5fae76f..c38eb17f191 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1092,6 +1092,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. Cleared at the beginning of the statement, and then can hold either OK, ERROR, or EOF status. diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 89a84ebc1fe..41e76211dd8 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1772,6 +1772,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, my_bool drop_temporary) { bool error= FALSE, need_start_waiters= FALSE; + Drop_table_error_handler err_handler(thd->get_internal_handler()); DBUG_ENTER("mysql_rm_table"); /* 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, LOCK_open during wait_if_global_read_lock(), other threads could not 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); + thd->pop_internal_handler(); + if (need_start_waiters) start_waiting_global_read_lock(thd); @@ -1894,9 +1898,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, 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) { char *db=table->db; @@ -2145,7 +2146,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, err_with_placeholders: unlock_table_names(thd, tables, (TABLE_LIST*) 0); pthread_mutex_unlock(&LOCK_open); - thd->no_warnings_for_error= 0; DBUG_RETURN(error); } |