Commit 51793af9 authored by Jon Olav Hauglid's avatar Jon Olav Hauglid

Bug #51376 Assert `! is_set()' failed in

           Diagnostics_area::set_ok_status on DROP FUNCTION

This assert tests that the server is not trying to send "ok" to
the client if an error has occured during statement processing.

In this case, the assert was triggered by lock timeout errors when
accessing system tables to do an implicit REVOKE after executing
DROP FUNCTION/PROCEDURE. In practice, this was only likely to
happen with very low values for "lock_wait_timeout" (in the bug report
1 second was used). These errors were ignored and the server tried
to send "ok" to the client, triggering the assert.

The patch for Bug#45225 introduced lock timeouts for metadata locks.
This made it possible to get timeouts when accessing system tables.
Note that a followup patch for Bug#45225 pushed after this
bug was reported, changed accessing of system tables such
that the user-supplied timeout value is ignored and the maximum
timeout value is used instead. This exact bug was therefore
only noticeable in the period between the initial Bug#45225 patch
and the followup patch.

However, the same problem could occur for any errors during revoking
of privileges - not just timeouts. This patch fixes the problem by
making sure that any errors during revoking of privileges are
reported to the client. 

Test case added to sp-destruct.test. Since the original bug is not
reproducable now that system tables are accessed using a a long
timeout value, this test instead calls DROP FUNCTION with a grant
system table missing.
parent 4d7a3daa
......@@ -116,3 +116,21 @@ ERROR HY000: Cannot load from mysql.proc. The table is probably corrupted
DROP TABLE mysql.proc;
RENAME TABLE proc_backup TO mysql.proc;
FLUSH TABLE mysql.proc;
#
# Bug#51376 Assert `! is_set()' failed in
# Diagnostics_area::set_ok_status on DROP FUNCTION
#
DROP FUNCTION IF EXISTS f1;
CREATE FUNCTION f1() RETURNS INT RETURN 1;
# Backup the procs_priv table
RENAME TABLE mysql.procs_priv TO procs_priv_backup;
FLUSH TABLE mysql.procs_priv;
DROP FUNCTION f1;
ERROR 42S02: Table 'mysql.procs_priv' doesn't exist
SHOW WARNINGS;
Level Code Message
Error 1146 Table 'mysql.procs_priv' doesn't exist
Warning 1405 Failed to revoke all privileges to dropped routine
# Restore the procs_priv table
RENAME TABLE procs_priv_backup TO mysql.procs_priv;
FLUSH TABLE mysql.procs_priv;
......@@ -197,3 +197,28 @@ SHOW PROCEDURE STATUS;
DROP TABLE mysql.proc;
RENAME TABLE proc_backup TO mysql.proc;
FLUSH TABLE mysql.proc;
--echo #
--echo # Bug#51376 Assert `! is_set()' failed in
--echo # Diagnostics_area::set_ok_status on DROP FUNCTION
--echo #
--disable_warnings
DROP FUNCTION IF EXISTS f1;
--enable_warnings
CREATE FUNCTION f1() RETURNS INT RETURN 1;
--echo # Backup the procs_priv table
RENAME TABLE mysql.procs_priv TO procs_priv_backup;
FLUSH TABLE mysql.procs_priv;
# DROP FUNCTION used to cause an assert.
--error ER_NO_SUCH_TABLE
DROP FUNCTION f1;
SHOW WARNINGS;
--echo # Restore the procs_priv table
RENAME TABLE procs_priv_backup TO mysql.procs_priv;
FLUSH TABLE mysql.procs_priv;
......@@ -4326,14 +4326,16 @@ case SQLCOM_PREPARE:
close_thread_tables(thd);
thd->mdl_context.release_transactional_locks();
if (sp_automatic_privileges && !opt_noacl &&
sp_revoke_privileges(thd, db, name,
if (sp_automatic_privileges && !opt_noacl &&
sp_revoke_privileges(thd, db, name,
lex->sql_command == SQLCOM_DROP_PROCEDURE))
{
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_PROC_AUTO_REVOKE_FAIL,
ER(ER_PROC_AUTO_REVOKE_FAIL));
}
{
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_PROC_AUTO_REVOKE_FAIL,
ER(ER_PROC_AUTO_REVOKE_FAIL));
/* If this happens, an error should have been reported. */
goto error;
}
#endif
}
res= sp_result;
......
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