Commit 5653a71d authored by Alexander Nozdrin's avatar Alexander Nozdrin

Patch for Bug#11765684 (58674: SP-cache does not detect changes in

pre-locking list caused by triggers).

The thing is that CREATE TRIGGER / DROP TRIGGER may actually
change pre-locking list of (some) stored routines.

The SP-cache does not detect such changes. Thus if sp_head-instance
is cached in SP-cache, subsequent executions of the cached
sp_head will use inaccurate pre-locking list.

The patch is to invalidate SP-cache on CREATE TRIGGER / DROP TRIGGER.
parent 0b7e6f81
...@@ -7452,4 +7452,34 @@ c1 ...@@ -7452,4 +7452,34 @@ c1
# Cleanup # Cleanup
drop table t1; drop table t1;
drop procedure p1; drop procedure p1;
# --
# -- Bug 11765684 - 58674: SP-cache does not detect changes in
# -- pre-locking list caused by triggers
# ---
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;
DROP PROCEDURE IF EXISTS p1;
CREATE TABLE t1(a INT);
CREATE TABLE t2(a INT);
CREATE TABLE t3(a INT);
CREATE PROCEDURE p1()
INSERT INTO t1(a) VALUES (1);
CREATE TRIGGER t1_ai AFTER INSERT ON t1
FOR EACH ROW
INSERT INTO t2(a) VALUES (new.a);
CALL p1();
CREATE TRIGGER t1_bi BEFORE INSERT ON t1
FOR EACH ROW
INSERT INTO t3(a) VALUES (new.a);
CALL p1();
DROP TABLE t1, t2, t3;
DROP PROCEDURE p1;
# End of 5.5 test # End of 5.5 test
...@@ -821,7 +821,6 @@ drop trigger t1_bi; ...@@ -821,7 +821,6 @@ drop trigger t1_bi;
create trigger t1_bi after insert on t1 for each row insert into t3 values (new.id); create trigger t1_bi after insert on t1 for each row insert into t3 values (new.id);
execute stmt1; execute stmt1;
call p1(); call p1();
ERROR 42S02: Table 'test.t3' doesn't exist
deallocate prepare stmt1; deallocate prepare stmt1;
drop procedure p1; drop procedure p1;
drop table t1, t2, t3; drop table t1, t2, t3;
......
...@@ -8713,4 +8713,45 @@ call p1(3, 2); ...@@ -8713,4 +8713,45 @@ call p1(3, 2);
drop table t1; drop table t1;
drop procedure p1; drop procedure p1;
--echo
--echo # --
--echo # -- Bug 11765684 - 58674: SP-cache does not detect changes in
--echo # -- pre-locking list caused by triggers
--echo # ---
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
DROP TABLE IF EXISTS t3;
DROP PROCEDURE IF EXISTS p1;
--enable_warnings
CREATE TABLE t1(a INT);
CREATE TABLE t2(a INT);
CREATE TABLE t3(a INT);
CREATE PROCEDURE p1()
INSERT INTO t1(a) VALUES (1);
--echo
CREATE TRIGGER t1_ai AFTER INSERT ON t1
FOR EACH ROW
INSERT INTO t2(a) VALUES (new.a);
--echo
CALL p1();
--echo
CREATE TRIGGER t1_bi BEFORE INSERT ON t1
FOR EACH ROW
INSERT INTO t3(a) VALUES (new.a);
--echo
CALL p1();
--echo
DROP TABLE t1, t2, t3;
DROP PROCEDURE p1;
--echo
--echo # End of 5.5 test --echo # End of 5.5 test
...@@ -998,10 +998,6 @@ call p1(); ...@@ -998,10 +998,6 @@ call p1();
drop trigger t1_bi; drop trigger t1_bi;
create trigger t1_bi after insert on t1 for each row insert into t3 values (new.id); create trigger t1_bi after insert on t1 for each row insert into t3 values (new.id);
execute stmt1; execute stmt1;
# Until we implement proper mechanism for invalidation of SP statements
# invoked whenever a table used in SP changes, this statement will fail with
# 'Table ... does not exist' error.
--error ER_NO_SUCH_TABLE
call p1(); call p1();
deallocate prepare stmt1; deallocate prepare stmt1;
drop procedure p1; drop procedure p1;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "sql_db.h" // get_default_db_collation #include "sql_db.h" // get_default_db_collation
#include "sql_acl.h" // *_ACL, is_acl_user #include "sql_acl.h" // *_ACL, is_acl_user
#include "sql_handler.h" // mysql_ha_rm_tables #include "sql_handler.h" // mysql_ha_rm_tables
#include "sp_cache.h" // sp_invalidate_cache
/*************************************************************************/ /*************************************************************************/
...@@ -517,6 +518,12 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) ...@@ -517,6 +518,12 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
*/ */
thd->locked_tables_list.reopen_tables(thd); thd->locked_tables_list.reopen_tables(thd);
/*
Invalidate SP-cache. That's needed because triggers may change list of
pre-locking tables.
*/
sp_cache_invalidate();
end: end:
if (!result) if (!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