List:Commits« Previous MessageNext Message »
From:Tatjana A Nuernberg Date:February 11 2007 10:03am
Subject:bk commit into 5.0 tree (tnurnberg:1.2392) BUG#23713
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of tnurnberg. When tnurnberg does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-02-11 10:02:57+01:00, tnurnberg@stripped +7 -0
  Bug #23713: LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
  
  modify locking so CREATE/DROP TRIGGER will work when we hold an exclusive lock
  on the table in question, or no lock.  fail gracefully for a shared lock.
  sleep while locked by other client/thread.

  mysql-test/r/rpl_trigger.result@stripped, 2007-02-11 10:02:55+01:00, tnurnberg@stripped +0
-2
    Bug #23713: LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
    
    We were throwing ER_TRG_NO_DEFINER even on DROP TRIGGER, asking the user to
    improve on code they were just throwing away anyways.

  mysql-test/r/trigger-compat.result@stripped, 2007-02-11 10:02:55+01:00, tnurnberg@stripped
+0 -2
    Bug #23713: LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
    
    We were throwing ER_TRG_NO_DEFINER even on DROP TRIGGER, asking the user to
    improve on code they were just throwing away anyways.

  mysql-test/r/trigger.result@stripped, 2007-02-11 10:02:55+01:00, tnurnberg@stripped +32 -0
    Bug #23713: LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
    
    show that CREATE/DROP TRIGGER will work when we hold an exclusive lock
    on the table in question, or no lock.  fail gracefully for a shared lock.

  mysql-test/t/trigger.test@stripped, 2007-02-11 10:02:55+01:00, tnurnberg@stripped +42 -0
    Bug #23713: LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
    
    show that CREATE/DROP TRIGGER will work when we hold an exclusive lock
    on the table in question, or no lock.  fail gracefully for a shared lock.

  sql/mysql_priv.h@stripped, 2007-02-11 10:02:55+01:00, tnurnberg@stripped +1 -0
    Bug #23713: LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
    
    Make wait_while_table_is_used() global so we can use it in sql_trigger.cc

  sql/sql_table.cc@stripped, 2007-02-11 10:02:55+01:00, tnurnberg@stripped +2 -2
    Bug #23713: LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
    
    Make wait_while_table_is_used() global so we can use it in sql_trigger.cc

  sql/sql_trigger.cc@stripped, 2007-02-11 10:02:55+01:00, tnurnberg@stripped +31 -10
    Bug #23713: LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
    
    modify locking so CREATE/DROP TRIGGER will work when we hold an exclusive lock
    on the table in question, or no lock.  fail gracefully for a shared lock.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	tnurnberg
# Host:	sin.azundris.com
# Root:	/home/tnurnberg/23713/50-23713

--- 1.429/sql/mysql_priv.h	2007-01-17 19:43:41 +01:00
+++ 1.430/sql/mysql_priv.h	2007-02-11 10:02:55 +01:00
@@ -667,6 +667,7 @@
 				   bool log_query);
 int quick_rm_table(enum db_type base,const char *db,
 		   const char *table_name);
+void wait_while_table_is_used(THD *thd, TABLE *table, enum ha_extra_function function);
 void close_cached_table(THD *thd, TABLE *table);
 bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
 bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db,

--- 1.332/sql/sql_table.cc	2007-01-20 12:10:17 +01:00
+++ 1.333/sql/sql_table.cc	2007-02-11 10:02:55 +01:00
@@ -1895,8 +1895,8 @@
     Win32 clients must also have a WRITE LOCK on the table !
 */
 
-static void wait_while_table_is_used(THD *thd,TABLE *table,
-				     enum ha_extra_function function)
+void wait_while_table_is_used(THD *thd,TABLE *table,
+                              enum ha_extra_function function)
 {
   DBUG_PRINT("enter",("table: %s", table->s->table_name));
   DBUG_ENTER("wait_while_table_is_used");

--- 1.4/mysql-test/r/trigger-compat.result	2006-05-12 18:58:49 +02:00
+++ 1.5/mysql-test/r/trigger-compat.result	2007-02-11 10:02:55 +01:00
@@ -37,8 +37,6 @@
 NULL	mysqltest_db1	wl2818_trg1	INSERT	NULL	mysqltest_db1	t1	0	NULL	INSERT INTO t2
VALUES(CURRENT_USER())	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL		
 NULL	mysqltest_db1	wl2818_trg2	INSERT	NULL	mysqltest_db1	t1	0	NULL	INSERT INTO t2
VALUES(CURRENT_USER())	ROW	AFTER	NULL	NULL	OLD	NEW	NULL		mysqltest_dfn@localhost
 DROP TRIGGER wl2818_trg1;
-Warnings:
-Warning	1454	No definer attribute for trigger 'mysqltest_db1'.'wl2818_trg1'. The trigger
will be activated under the authorization of the invoker, which may have insufficient
privileges. Please recreate the trigger.
 DROP TRIGGER wl2818_trg2;
 use mysqltest_db1;
 DROP TABLE t1;

--- 1.50/mysql-test/r/trigger.result	2006-11-13 23:38:34 +01:00
+++ 1.51/mysql-test/r/trigger.result	2007-02-11 10:02:55 +01:00
@@ -1278,4 +1278,36 @@
 2	b
 3	c
 drop table t1;
+create table t1 (i int);
+create trigger t1_bi before insert on t1 for each row begin end;
+create trigger t1_bi before insert on t1 for each row begin end;
+ERROR 42000: This version of MySQL doesn't yet support 'multiple triggers with the same
action time and event for one table'
+drop trigger t1_bi;
+drop trigger t1_bi;
+ERROR HY000: Trigger does not exist
+lock tables t1 read;
+create trigger t1_bi before insert on t1 for each row begin end;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+create trigger t1_bi before insert on t1 for each row begin end;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+drop trigger t1_bi;
+ERROR HY000: Trigger does not exist
+unlock tables;
+create trigger t1_bi before insert on t1 for each row begin end;
+lock tables t1 read;
+create trigger t1_bi before insert on t1 for each row begin end;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+drop trigger t1_bi;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+unlock tables;
+drop trigger t1_bi;
+lock tables t1 write;
+create trigger t1_bi before insert on t1 for each row begin end;
+create trigger t1_bi before insert on t1 for each row begin end;
+ERROR 42000: This version of MySQL doesn't yet support 'multiple triggers with the same
action time and event for one table'
+drop trigger t1_bi;
+drop trigger t1_bi;
+ERROR HY000: Trigger does not exist
+unlock tables;
+drop table if exists t1;
 End of 5.0 tests

--- 1.58/mysql-test/t/trigger.test	2007-01-11 15:43:42 +01:00
+++ 1.59/mysql-test/t/trigger.test	2007-02-11 10:02:55 +01:00
@@ -1554,4 +1554,46 @@
 
 drop table t1;
 
+#
+# Bug #23713: LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock
+#
+
+create table t1 (i int);
+
+create trigger t1_bi before insert on t1 for each row begin end;
+--error ER_NOT_SUPPORTED_YET
+create trigger t1_bi before insert on t1 for each row begin end;
+drop trigger t1_bi;
+--error ER_TRG_DOES_NOT_EXIST
+drop trigger t1_bi;
+
+lock tables t1 read;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+create trigger t1_bi before insert on t1 for each row begin end;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+create trigger t1_bi before insert on t1 for each row begin end;
+--error ER_TRG_DOES_NOT_EXIST
+drop trigger t1_bi;
+unlock tables;
+
+create trigger t1_bi before insert on t1 for each row begin end;
+lock tables t1 read;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+create trigger t1_bi before insert on t1 for each row begin end;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+drop trigger t1_bi;
+unlock tables;
+drop trigger t1_bi;
+
+lock tables t1 write;
+create trigger t1_bi before insert on t1 for each row begin end;
+--error ER_NOT_SUPPORTED_YET
+create trigger t1_bi before insert on t1 for each row begin end;
+drop trigger t1_bi;
+--error ER_TRG_DOES_NOT_EXIST
+drop trigger t1_bi;
+unlock tables;
+
+drop table if exists t1;
+
 --echo End of 5.0 tests

--- 1.61/sql/sql_trigger.cc	2006-12-23 20:04:27 +01:00
+++ 1.62/sql/sql_trigger.cc	2007-02-11 10:02:55 +01:00
@@ -136,6 +136,7 @@
   LEX_STRING *trigger_table_value;
 };
 
+
 /*
   Create or drop trigger for table.
 
@@ -165,7 +166,7 @@
     This is a good candidate for a minor refactoring.
   */
   TABLE *table;
-  bool result= TRUE;
+  bool result= TRUE, need_unlock= FALSE;
   String stmt_query;
 
   DBUG_ENTER("mysql_create_or_drop_trigger");
@@ -223,16 +224,17 @@
     DBUG_RETURN(TRUE);
   }
 
+
   /*
     We don't want perform our operations while global read lock is held
     so we have to wait until its end and then prevent it from occurring
     again until we are done. (Acquiring LOCK_open is not enough because
     global read lock is held without holding LOCK_open).
   */
-  if (wait_if_global_read_lock(thd, 0, 1))
-    DBUG_RETURN(TRUE);
+  /* end_active_trans(thd) was called in sql_parse */
 
-  VOID(pthread_mutex_lock(&LOCK_open));
+  if (!thd->locked_tables && wait_if_global_read_lock(thd, 0, 1))
+    DBUG_RETURN(1);
 
   if (!create)
   {
@@ -259,6 +261,9 @@
     }
   }
 
+  if (tables)
+    mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL, FALSE);
+
   /* We should have only one table in table list. */
   DBUG_ASSERT(tables->next_global == 0);
 
@@ -269,19 +274,21 @@
     goto end;
   }
 
-  if (lock_table_names(thd, tables))
-    goto end;
-
   /* We also don't allow creation of triggers on views. */
   tables->required_type= FRMTYPE_TABLE;
 
-  if (reopen_name_locked_table(thd, tables))
+  if (!(tables->table= open_ltable(thd,tables,TL_WRITE_ALLOW_READ)))
   {
-    unlock_table_name(thd, tables);
     goto end;
   }
   table= tables->table;
 
+  VOID(pthread_mutex_lock(&LOCK_open));
+
+  need_unlock= TRUE;
+
+  wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+
   if (!table->triggers)
   {
     if (!create)
@@ -311,9 +318,23 @@
                             FALSE);
       mysql_bin_log.write(&qinfo);
     }
+    if (need_unlock)
+    {
+      if (!thd->locked_tables ||
+          (table &&
+           (close_data_tables(thd, table->s->db, table->s->table_name) ||
+            reopen_tables(thd, 1, 0))))
+      {						// This shouldn't happen
+        close_cached_table(thd, table);		// Remove lock for table
+      }
+    }
+  }
+
+  if (need_unlock)
+  {
+    VOID(pthread_mutex_unlock(&LOCK_open));
   }
 
-  VOID(pthread_mutex_unlock(&LOCK_open));
   start_waiting_global_read_lock(thd);
 
   if (!result)

--- 1.11/mysql-test/r/rpl_trigger.result	2006-11-13 23:38:34 +01:00
+++ 1.12/mysql-test/r/rpl_trigger.result	2007-02-11 10:02:55 +01:00
@@ -883,8 +883,6 @@
 @
 root@localhost
 DROP TRIGGER trg1;
-Warnings:
-Warning	1454	No definer attribute for trigger 'test'.'trg1'. The trigger will be
activated under the authorization of the invoker, which may have insufficient privileges.
Please recreate the trigger.
 DROP TABLE t1;
 DROP TABLE t2;
 STOP SLAVE;
Thread
bk commit into 5.0 tree (tnurnberg:1.2392) BUG#23713Tatjana A Nuernberg11 Feb