MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Davi Arnaut Date:January 28 2010 2:41pm
Subject:bzr commit into mysql-5.1-bugteam branch (davi:3338) Bug#50423
View as plain text  
# At a local mysql-5.1-bugteam repository of davi

 3338 Davi Arnaut	2010-01-28
      Bug#50423: Crash on second call of a procedure dropping a trigger
      
      The problem was that a DROP TRIGGER statement inside a stored
      procedure could cause a crash in subsequent invocations. This
      was due to the addition, on the first execution, of a temporary
      table reference to the stored procedure query table list. In
      a subsequent invocation, there would be a attempt to reinitialize
      the temporary table reference, which by then was already gone.
      
      The solution is to backup and reset the query table list each
      time a trigger needs to be dropped. This ensures that any temp
      changes to the query table list are discarded. It is safe to
      do so at this time as drop trigger is restricted from more
      complicated scenarios (ie, not allowed within stored functions,
      etc).
     @ mysql-test/r/sp-bugs.result
        Add test case result for Bug#50423
     @ mysql-test/t/sp-bugs.test
        Add test case for Bug#50423
     @ sql/sql_trigger.cc
        Backup and reset the query table list.
        Remove now unnecessary manual reset of the query table list.

    modified:
      mysql-test/r/sp-bugs.result
      mysql-test/t/sp-bugs.test
      sql/sql_trigger.cc
=== modified file 'mysql-test/r/sp-bugs.result'
--- a/mysql-test/r/sp-bugs.result	2009-10-26 09:55:57 +0000
+++ b/mysql-test/r/sp-bugs.result	2010-01-28 14:41:14 +0000
@@ -44,4 +44,19 @@ SELECT f2 ();
 f2 ()
 NULL
 DROP SCHEMA testdb;
+USE test;
+#
+# 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

=== modified file 'mysql-test/t/sp-bugs.test'
--- a/mysql-test/t/sp-bugs.test	2009-10-26 09:55:57 +0000
+++ b/mysql-test/t/sp-bugs.test	2010-01-28 14:41:14 +0000
@@ -57,5 +57,27 @@ SELECT f2 ();
 
 DROP SCHEMA testdb;
 
+USE test;
+
+--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

=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc	2010-01-24 07:03:23 +0000
+++ b/sql/sql_trigger.cc	2010-01-28 14:41:14 +0000
@@ -327,6 +327,7 @@ bool mysql_create_or_drop_trigger(THD *t
   TABLE *table;
   bool result= TRUE;
   String stmt_query;
+  Query_tables_list backup;
   bool need_start_waiting= FALSE;
 
   DBUG_ENTER("mysql_create_or_drop_trigger");
@@ -393,6 +394,12 @@ bool mysql_create_or_drop_trigger(THD *t
   {
     bool if_exists= thd->lex->drop_if_exists;
 
+    /*
+      Protect the query table list from the temporary and potentially
+      destructive changes necessary to open the trigger's table.
+    */
+    thd->lex->reset_n_backup_query_tables_list(&backup);
+
     if (add_table_for_trigger(thd, thd->lex->spname, if_exists, & tables))
       goto end;
 
@@ -512,6 +519,10 @@ end:
 
   VOID(pthread_mutex_unlock(&LOCK_open));
 
+  /* Restore the query table list. Used only for drop trigger. */
+  if (!create)
+    thd->lex->restore_backup_query_tables_list(&backup);
+
   if (need_start_waiting)
     start_waiting_global_read_lock(thd);
 
@@ -1625,10 +1636,6 @@ bool add_table_for_trigger(THD *thd,
   if (load_table_name_for_trigger(thd, trg_name, &trn_path, &tbl_name))
     DBUG_RETURN(TRUE);
 
-  /* We need to reset statement table list to be PS/SP friendly. */
-  lex->query_tables= 0;
-  lex->query_tables_last= &lex->query_tables;
-
   *table= sp_add_to_query_tables(thd, lex, trg_name->m_db.str,
                                  tbl_name.str, TL_IGNORE);
 


Attachment: [text/bzr-bundle] bzr/davi.arnaut@sun.com-20100128144114-s68xdj56uoygyibk.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (davi:3338) Bug#50423Davi Arnaut28 Jan
  • Re: bzr commit into mysql-5.1-bugteam branch (davi:3338) Bug#50423Konstantin Osipov12 Feb