Commit 07c30f91 authored by Davi Arnaut's avatar Davi Arnaut

Bug#50624: crash in check_table_access during call procedure

This bug is just one facet of stored routines not being able to
detect changes in meta-data (WL#4179). This particular problem
can be triggered within a single session due to the improper
management of the pre-locking list if the view is expanded after
the pre-locking list is calculated.

Since the overall solution for the meta-data detection issue is
planned for a later release, for now a workaround is used to
fix this particular aspect that only involves a single session.
The workaround is to flush the thread-local stored routine cache
every time a view is created or modified, causing locally cached
routines to be re-evaluated upon invocation.

mysql-test/r/sp-bugs.result:
  Add test case result for Bug#50624.
mysql-test/t/sp-bugs.test:
  Add test case for Bug#50624.
sql/sp_cache.cc:
  Update function description.
sql/sql_view.cc:
  Invalidate the SP cache if a view is being created or modified.
parent d6ab925c
...@@ -59,4 +59,18 @@ CALL p1 (); ...@@ -59,4 +59,18 @@ CALL p1 ();
ERROR HY000: Trigger does not exist ERROR HY000: Trigger does not exist
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE p1; DROP PROCEDURE p1;
#
# Bug#50423: Crash on second call of a procedure dropping a trigger
#
DROP TABLE IF EXISTS t1;
DROP TRIGGER IF EXISTS tr1;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1 (f1 INTEGER);
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET @aux = 1;
CREATE PROCEDURE p1 () DROP TRIGGER tr1;
CALL p1 ();
CALL p1 ();
ERROR HY000: Trigger does not exist
DROP TABLE t1;
DROP PROCEDURE p1;
End of 5.1 tests End of 5.1 tests
...@@ -80,4 +80,25 @@ CALL p1 (); ...@@ -80,4 +80,25 @@ CALL p1 ();
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE p1; DROP PROCEDURE p1;
--echo #
--echo # Bug#50423: Crash on second call of a procedure dropping a trigger
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TRIGGER IF EXISTS tr1;
DROP PROCEDURE IF EXISTS p1;
--enable_warnings
CREATE TABLE t1 (f1 INTEGER);
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET @aux = 1;
CREATE PROCEDURE p1 () DROP TRIGGER tr1;
CALL p1 ();
--error ER_TRG_DOES_NOT_EXIST
CALL p1 ();
DROP TABLE t1;
DROP PROCEDURE p1;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -175,8 +175,9 @@ sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name) ...@@ -175,8 +175,9 @@ sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name)
sp_cache_invalidate() sp_cache_invalidate()
NOTE NOTE
This is called when a VIEW definition is modifed. We can't destroy sp_head This is called when a VIEW definition is created or modified (and in some
objects here as one may modify VIEW definitions from prelocking-free SPs. other contexts). We can't destroy sp_head objects here as one may modify
VIEW definitions from prelocking-free SPs.
*/ */
void sp_cache_invalidate() void sp_cache_invalidate()
......
...@@ -400,17 +400,14 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, ...@@ -400,17 +400,14 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
DBUG_ASSERT(!lex->proc_list.first && !lex->result && DBUG_ASSERT(!lex->proc_list.first && !lex->result &&
!lex->param_list.elements); !lex->param_list.elements);
if (mode != VIEW_CREATE_NEW) if (mode == VIEW_ALTER && fill_defined_view_parts(thd, view))
{ {
if (mode == VIEW_ALTER && res= TRUE;
fill_defined_view_parts(thd, view)) goto err;
{
res= TRUE;
goto err;
}
sp_cache_invalidate();
} }
sp_cache_invalidate();
if (!lex->definer) if (!lex->definer)
{ {
/* /*
......
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