List:Commits« Previous MessageNext Message »
From:Konstantin Osipov Date:December 11 2009 12:13pm
Subject:bzr commit into mysql-5.6-next-mr branch (kostja:3032) Bug#20667
View as plain text  
#At file:///opt/local/work/next-4284/ based on revid:kostja@stripped

 3032 Konstantin Osipov	2009-12-11
      Backport:
      ------------------------------------------------------------
       2599.161.3 Ingo Struewing      2009-07-21
       Bug#20667 - Truncate table fails for a write locked table
      
       TRUNCATE TABLE was not allowed under LOCK TABLES.
      
       The patch removes this restriction. mysql_truncate()
       does now handle that case.
     @ mysql-test/r/merge.result
        Bug#20667 - Truncate table fails for a write locked table
        Updated test result.
     @ mysql-test/r/truncate.result
        Bug#20667 - Truncate table fails for a write locked table
        Updated test result.
     @ mysql-test/r/truncate_coverage.result
        Bug#20667 - Truncate table fails for a write locked table
        New test result.
     @ mysql-test/t/merge.test
        Bug#20667 - Truncate table fails for a write locked table
        Updated test case due to now working TRUNCATE under LOCK TABLES.
        Added some SELECTs to show that child tables are truncated.
     @ mysql-test/t/truncate.test
        Bug#20667 - Truncate table fails for a write locked table
        Added test cases for TRUNCATE under LOCK TABLE.
     @ mysql-test/t/truncate_coverage.test
        Bug#20667 - Truncate table fails for a write locked table
        New test file. Coverage tests for TRUNCATE.
     @ sql/sql_delete.cc
        Bug#20667 - Truncate table fails for a write locked table
        Added branches for thd->locked_tables_mode.
     @ sql/sql_parse.cc
        Bug#20667 - Truncate table fails for a write locked table
        Deleted rejection of TRUNCATE in case of LOCK TABLES.

    added:
      mysql-test/r/truncate_coverage.result
      mysql-test/t/truncate_coverage.test
    modified:
      mysql-test/r/merge.result
      mysql-test/r/truncate.result
      mysql-test/t/merge.test
      mysql-test/t/truncate.test
      sql/sql_delete.cc
      sql/sql_parse.cc
=== modified file 'mysql-test/r/merge.result'
--- a/mysql-test/r/merge.result	2009-12-10 10:53:20 +0000
+++ b/mysql-test/r/merge.result	2009-12-11 12:13:37 +0000
@@ -1046,18 +1046,21 @@ c1
 LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
 INSERT INTO t1 VALUES (1);
 TRUNCATE TABLE t3;
-ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 SELECT * FROM t3;
 c1
-1
-2
+UNLOCK TABLES;
+SELECT * FROM t1;
+c1
+SELECT * FROM t2;
+c1
 #
 # Truncate child table under locked tables.
+LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
 TRUNCATE TABLE t1;
-ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 SELECT * FROM t3;
 c1
-1
 2
 UNLOCK TABLES;
 DROP TABLE t1, t2, t3;
@@ -1089,18 +1092,24 @@ INSERT INTO t1 VALUES (1);
 CREATE TABLE t4 (c1 INT, INDEX(c1));
 LOCK TABLE t4 WRITE;
 TRUNCATE TABLE t3;
-ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 SELECT * FROM t3;
 c1
-1
-2
+SELECT * FROM t1;
+c1
+SELECT * FROM t2;
+c1
 #
 # Truncate temporary child table under locked tables.
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
 TRUNCATE TABLE t1;
-ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
 SELECT * FROM t3;
 c1
-1
+2
+SELECT * FROM t1;
+c1
+SELECT * FROM t2;
+c1
 2
 UNLOCK TABLES;
 DROP TABLE t1, t2, t3, t4;

=== modified file 'mysql-test/r/truncate.result'
--- a/mysql-test/r/truncate.result	2009-12-09 09:29:36 +0000
+++ b/mysql-test/r/truncate.result	2009-12-11 12:13:37 +0000
@@ -1,4 +1,4 @@
-drop table if exists t1;
+drop table if exists t1, t2;
 create table t1 (a integer, b integer,c1 CHAR(10));
 insert into t1 (a) values (1),(2);
 truncate table t1;
@@ -61,6 +61,91 @@ ERROR 42S02: Table 'test.v1' doesn't exi
 drop view v1;
 drop table t1;
 #
+# Bug#20667 - Truncate table fails for a write locked table
+#
+CREATE TABLE t1 (c1 INT);
+LOCK TABLE t1 WRITE;
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+c1
+1
+TRUNCATE TABLE t1;
+SELECT * FROM t1;
+c1
+UNLOCK TABLES;
+LOCK TABLE t1 READ;
+TRUNCATE TABLE t1;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+UNLOCK TABLES;
+CREATE TABLE t2 (c1 INT);
+LOCK TABLE t2 WRITE;
+TRUNCATE TABLE t1;
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
+UNLOCK TABLES;
+CREATE VIEW v1 AS SELECT t1.c1 FROM t1,t2 WHERE t1.c1 = t2.c1;
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (1), (3), (4);
+SELECT * FROM v1;
+c1
+1
+3
+TRUNCATE v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+SELECT * FROM v1;
+c1
+1
+3
+LOCK TABLE t1 WRITE;
+SELECT * FROM v1;
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
+TRUNCATE v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+SELECT * FROM v1;
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
+UNLOCK TABLES;
+LOCK TABLE t1 WRITE, t2 WRITE;
+SELECT * FROM v1;
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
+TRUNCATE v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+SELECT * FROM v1;
+ERROR HY000: Table 'v1' was not locked with LOCK TABLES
+UNLOCK TABLES;
+LOCK TABLE v1 WRITE;
+SELECT * FROM v1;
+c1
+1
+3
+TRUNCATE v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+SELECT * FROM v1;
+c1
+1
+3
+UNLOCK TABLES;
+LOCK TABLE t1 WRITE, t2 WRITE, v1 WRITE;
+SELECT * FROM v1;
+c1
+1
+3
+TRUNCATE v1;
+ERROR 42S02: Table 'test.v1' doesn't exist
+SELECT * FROM v1;
+c1
+1
+3
+UNLOCK TABLES;
+DROP VIEW v1;
+DROP TABLE t1, t2;
+CREATE PROCEDURE p1() SET @a = 5;
+TRUNCATE p1;
+ERROR 42S02: Table 'test.p1' doesn't exist
+SHOW CREATE PROCEDURE p1;
+Procedure	sql_mode	Create Procedure	character_set_client	collation_connection	Database Collation
+p1		CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
+SET @a = 5	latin1	latin1_swedish_ci	latin1_swedish_ci
+DROP PROCEDURE p1;
+#
 # Bug#46452 Crash in MDL, HANDLER OPEN + TRUNCATE TABLE
 #
 DROP TABLE IF EXISTS t1;

=== added file 'mysql-test/r/truncate_coverage.result'
--- a/mysql-test/r/truncate_coverage.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/truncate_coverage.result	2009-12-11 12:13:37 +0000
@@ -0,0 +1,70 @@
+SET DEBUG_SYNC='RESET';
+DROP TABLE IF EXISTS t1;
+#
+# Bug#20667 - Truncate table fails for a write locked table
+#
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# connection con1
+START TRANSACTION;
+INSERT INTO t1 VALUES (2);
+#
+# connection default
+LOCK TABLE t1 WRITE;
+SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
+TRUNCATE TABLE t1;
+#
+# connection con1
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+KILL QUERY @id;
+COMMIT;
+#
+# connection default
+ERROR 70100: Query execution was interrupted
+UNLOCK TABLES;
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# connection con1
+START TRANSACTION;
+INSERT INTO t1 VALUES (2);
+#
+# connection default
+LOCK TABLE t1 WRITE;
+SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
+TRUNCATE TABLE t1;
+#
+# connection con1
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+COMMIT;
+#
+# connection default
+ERROR 42S02: Table 'test.t1' doesn't exist
+UNLOCK TABLES;
+DROP TABLE t1;
+ERROR 42S02: Unknown table 't1'
+SET DEBUG_SYNC='RESET';
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# connection con1
+START TRANSACTION;
+INSERT INTO t1 VALUES (2);
+#
+# connection default
+SET DEBUG_SYNC='mdl_acquire_exclusive_locks_wait SIGNAL waiting';
+TRUNCATE TABLE t1;
+#
+# connection con1
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+KILL QUERY @id;
+COMMIT;
+#
+# connection default
+ERROR 70100: Query execution was interrupted
+UNLOCK TABLES;
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';

=== modified file 'mysql-test/t/merge.test'
--- a/mysql-test/t/merge.test	2009-12-10 10:53:20 +0000
+++ b/mysql-test/t/merge.test	2009-12-11 12:13:37 +0000
@@ -675,12 +675,16 @@ SELECT * FROM t3;
 --echo # Truncate MERGE table under locked tables.
 LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
 INSERT INTO t1 VALUES (1);
---error ER_LOCK_OR_ACTIVE_TRANSACTION
 TRUNCATE TABLE t3;
 SELECT * FROM t3;
+UNLOCK TABLES;
+SELECT * FROM t1;
+SELECT * FROM t2;
 --echo #
 --echo # Truncate child table under locked tables.
---error ER_LOCK_OR_ACTIVE_TRANSACTION
+LOCK TABLE t1 WRITE, t2 WRITE, t3 WRITE;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
 TRUNCATE TABLE t1;
 SELECT * FROM t3;
 UNLOCK TABLES;
@@ -706,14 +710,18 @@ SELECT * FROM t3;
 INSERT INTO t1 VALUES (1);
 CREATE TABLE t4 (c1 INT, INDEX(c1));
 LOCK TABLE t4 WRITE;
---error ER_LOCK_OR_ACTIVE_TRANSACTION
 TRUNCATE TABLE t3;
 SELECT * FROM t3;
+SELECT * FROM t1;
+SELECT * FROM t2;
 --echo #
 --echo # Truncate temporary child table under locked tables.
---error ER_LOCK_OR_ACTIVE_TRANSACTION
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (2);
 TRUNCATE TABLE t1;
 SELECT * FROM t3;
+SELECT * FROM t1;
+SELECT * FROM t2;
 UNLOCK TABLES;
 DROP TABLE t1, t2, t3, t4;
 

=== modified file 'mysql-test/t/truncate.test'
--- a/mysql-test/t/truncate.test	2009-12-09 09:29:36 +0000
+++ b/mysql-test/t/truncate.test	2009-12-11 12:13:37 +0000
@@ -2,7 +2,7 @@
 # Test of truncate
 #
 --disable_warnings
-drop table if exists t1;
+drop table if exists t1, t2;
 --enable_warnings
 
 create table t1 (a integer, b integer,c1 CHAR(10));
@@ -70,6 +70,77 @@ drop table t1;
 # End of 5.0 tests
 
 --echo #
+--echo # Bug#20667 - Truncate table fails for a write locked table
+--echo #
+CREATE TABLE t1 (c1 INT);
+LOCK TABLE t1 WRITE;
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+TRUNCATE TABLE t1;
+SELECT * FROM t1;
+UNLOCK TABLES;
+#
+LOCK TABLE t1 READ;
+--error ER_TABLE_NOT_LOCKED_FOR_WRITE
+TRUNCATE TABLE t1;
+UNLOCK TABLES;
+#
+CREATE TABLE t2 (c1 INT);
+LOCK TABLE t2 WRITE;
+--error ER_TABLE_NOT_LOCKED
+TRUNCATE TABLE t1;
+UNLOCK TABLES;
+#
+CREATE VIEW v1 AS SELECT t1.c1 FROM t1,t2 WHERE t1.c1 = t2.c1;
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (1), (3), (4);
+SELECT * FROM v1;
+--error ER_NO_SUCH_TABLE
+TRUNCATE v1;
+SELECT * FROM v1;
+#
+LOCK TABLE t1 WRITE;
+--error ER_TABLE_NOT_LOCKED
+SELECT * FROM v1;
+--error ER_NO_SUCH_TABLE
+TRUNCATE v1;
+--error ER_TABLE_NOT_LOCKED
+SELECT * FROM v1;
+UNLOCK TABLES;
+#
+LOCK TABLE t1 WRITE, t2 WRITE;
+--error ER_TABLE_NOT_LOCKED
+SELECT * FROM v1;
+--error ER_NO_SUCH_TABLE
+TRUNCATE v1;
+--error ER_TABLE_NOT_LOCKED
+SELECT * FROM v1;
+UNLOCK TABLES;
+#
+LOCK TABLE v1 WRITE;
+SELECT * FROM v1;
+--error ER_NO_SUCH_TABLE
+TRUNCATE v1;
+SELECT * FROM v1;
+UNLOCK TABLES;
+#
+LOCK TABLE t1 WRITE, t2 WRITE, v1 WRITE;
+SELECT * FROM v1;
+--error ER_NO_SUCH_TABLE
+TRUNCATE v1;
+SELECT * FROM v1;
+UNLOCK TABLES;
+#
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+CREATE PROCEDURE p1() SET @a = 5;
+--error ER_NO_SUCH_TABLE
+TRUNCATE p1;
+SHOW CREATE PROCEDURE p1;
+DROP PROCEDURE p1;
+
+--echo #
 --echo # Bug#46452 Crash in MDL, HANDLER OPEN + TRUNCATE TABLE
 --echo #
 --disable_warnings

=== added file 'mysql-test/t/truncate_coverage.test'
--- a/mysql-test/t/truncate_coverage.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/truncate_coverage.test	2009-12-11 12:13:37 +0000
@@ -0,0 +1,155 @@
+#
+# Code coverage testing of TRUNCATE TABLE.
+#
+# Ingo Struewing, 2009-07-20
+#
+
+--source include/have_debug_sync.inc
+SET DEBUG_SYNC='RESET';
+
+--let $MYSQLD_DATADIR= `SELECT @@datadir`
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo #
+--echo # Bug#20667 - Truncate table fails for a write locked table
+--echo #
+########
+# Attack wait_while_table_is_used(). Kill query while trying to
+# upgrade MDL.
+#
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# Start a transaction and execute a DML in it. Since 5.4.4 this leaves
+# a shared meta data lock (MDL) behind. TRUNCATE shall block on it.
+#
+--echo #
+--echo # connection con1
+--connect (con1, localhost, root,,)
+START TRANSACTION;
+INSERT INTO t1 VALUES (2);
+#
+# Get connection id of default connection.
+# Lock the table and start TRUNCATE, which will block on MDL upgrade.
+#
+--echo #
+--echo # connection default
+--connection default
+let $ID= `SELECT @id := CONNECTION_ID()`;
+LOCK TABLE t1 WRITE;
+SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
+send TRUNCATE TABLE t1;
+#
+# Get the default connection ID into a variable in an invisible statement.
+# Kill the TRUNCATE query. This shall result in an error return
+# from wait_while_table_is_used().
+#
+--echo #
+--echo # connection con1
+--connection con1
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+let $invisible_assignment_in_select = `SELECT @id := $ID`;
+KILL QUERY @id;
+COMMIT;
+--disconnect con1
+--echo #
+--echo # connection default
+--connection default
+--error ER_QUERY_INTERRUPTED
+reap;
+UNLOCK TABLES;
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';
+########
+# Attack reopen_tables(). Remove form file.
+#
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# Start a transaction and execute a DML in it. Since 5.4.4 this leaves
+# a shared meta data lock (MDL) behind. TRUNCATE shall block on it.
+#
+--echo #
+--echo # connection con1
+--connect (con1, localhost, root,,)
+START TRANSACTION;
+INSERT INTO t1 VALUES (2);
+#
+# Lock the table and start TRUNCATE, which will block on MDL upgrade.
+#
+--echo #
+--echo # connection default
+--connection default
+LOCK TABLE t1 WRITE;
+SET DEBUG_SYNC='mdl_upgrade_shared_lock_to_exclusive SIGNAL waiting';
+send TRUNCATE TABLE t1;
+#
+# Remove datafile.
+# Commit to let TRUNCATE continue.
+#
+--echo #
+--echo # connection con1
+--connection con1
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+--remove_file $MYSQLD_DATADIR/test/t1.frm
+COMMIT;
+--disconnect con1
+--echo #
+--echo # connection default
+--connection default
+--error ER_NO_SUCH_TABLE
+reap;
+UNLOCK TABLES;
+--error ER_BAD_TABLE_ERROR
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';
+########
+# Attack acquire_exclusive_locks(). Hold a global read lock.
+# Non-LOCK TABLE case.
+#
+CREATE TABLE t1 (c1 INT);
+INSERT INTO t1 VALUES (1);
+#
+# Start a transaction and execute a DML in it. Since 5.4.4 this leaves
+# a shared meta data lock (MDL) behind. TRUNCATE shall block on it.
+#
+--echo #
+--echo # connection con1
+--connect (con1, localhost, root,,)
+START TRANSACTION;
+INSERT INTO t1 VALUES (2);
+#
+# Get connection id of default connection.
+# Start TRUNCATE, which will block on acquire_exclusive_locks().
+#
+--echo #
+--echo # connection default
+--connection default
+let $ID= `SELECT @id := CONNECTION_ID()`;
+SET DEBUG_SYNC='mdl_acquire_exclusive_locks_wait SIGNAL waiting';
+send TRUNCATE TABLE t1;
+#
+# Get the default connection ID into a variable in an invisible statement.
+# Kill the TRUNCATE query. This shall result in an error return
+# from wait_while_table_is_used().
+#
+--echo #
+--echo # connection con1
+--connection con1
+SET DEBUG_SYNC='now WAIT_FOR waiting';
+let $invisible_assignment_in_select = `SELECT @id := $ID`;
+KILL QUERY @id;
+COMMIT;
+--disconnect con1
+--echo #
+--echo # connection default
+--connection default
+--error ER_QUERY_INTERRUPTED
+reap;
+UNLOCK TABLES;
+DROP TABLE t1;
+SET DEBUG_SYNC='RESET';
+

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2009-12-10 08:21:38 +0000
+++ b/sql/sql_delete.cc	2009-12-11 12:13:37 +0000
@@ -1098,9 +1098,15 @@ bool mysql_truncate(THD *thd, TABLE_LIST
   HA_CREATE_INFO create_info;
   char path[FN_REFLEN + 1];
   TABLE *table;
-  bool error;
+  bool error= TRUE;
   uint path_length;
   MDL_request mdl_request;
+  /*
+    Is set if we're under LOCK TABLES, and used
+    to downgrade the exclusive lock after the
+    table was truncated.
+  */
+  MDL_ticket *mdl_ticket= NULL;
   bool has_mdl_lock= FALSE;
   DBUG_ENTER("mysql_truncate");
 
@@ -1119,7 +1125,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST
       goto trunc_by_del;
 
     table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK);
-    
+
     close_temporary_table(thd, table, 0, 0);    // Don't free share
     ha_create_table(thd, share->normalized_path.str,
                     share->db.str, share->table_name.str, &create_info, 1);
@@ -1177,21 +1183,47 @@ bool mysql_truncate(THD *thd, TABLE_LIST
         thd->lex->alter_info.flags & ALTER_ADMIN_PARTITION)
       goto trunc_by_del;
 
-    mdl_request.init(MDL_key::TABLE, table_list->db, table_list->table_name, MDL_EXCLUSIVE);
-    if (thd->mdl_context.acquire_exclusive_lock(&mdl_request))
-      DBUG_RETURN(TRUE);
 
-    has_mdl_lock= TRUE;
-
-    pthread_mutex_lock(&LOCK_open);
-    tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db,
-                     table_list->table_name);
-    pthread_mutex_unlock(&LOCK_open);
+    if (thd->locked_tables_mode)
+    {
+      if (!(table= find_write_locked_table(thd->open_tables, table_list->db,
+                                           table_list->table_name)))
+        DBUG_RETURN(TRUE);
+      mdl_ticket= table->mdl_ticket;
+      if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
+        goto end;
+      close_all_tables_for_name(thd, table->s, FALSE);
+    }
+    else
+    {
+      /*
+        Even though we could use the previous execution branch
+        here just as well, we must not try to open the table: 
+        MySQL manual documents that TRUNCATE can be used to 
+        repair a damaged table, i.e. a table that can not be
+        fully "opened". In particular MySQL manual says:
+
+        As long as the table format file tbl_name.frm  is valid,
+        the table can be re-created as an empty table with TRUNCATE
+        TABLE, even if the data or index files have become corrupted.
+      */
+      mdl_request.init(MDL_key::TABLE, table_list->db, table_list->table_name,
+                       MDL_EXCLUSIVE);
+      if (thd->mdl_context.acquire_exclusive_lock(&mdl_request))
+        DBUG_RETURN(TRUE);
+      has_mdl_lock= TRUE;
+      pthread_mutex_lock(&LOCK_open);
+      tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db,
+                       table_list->table_name);
+      pthread_mutex_unlock(&LOCK_open);
+    }
   }
 
-  // Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
-  // crashes, replacement works.  *(path + path_length - reg_ext_length)=
-  // '\0';
+  /*
+    Remove the .frm extension AIX 5.2 64-bit compiler bug (BUG#16155): this
+    crashes, replacement works.  *(path + path_length - reg_ext_length)=
+     '\0';
+  */
   path[path_length - reg_ext_length] = 0;
   pthread_mutex_lock(&LOCK_open);
   error= ha_create_table(thd, path, table_list->db, table_list->table_name,
@@ -1202,6 +1234,12 @@ bool mysql_truncate(THD *thd, TABLE_LIST
 end:
   if (!dont_send_ok)
   {
+    if (thd->locked_tables_mode && thd->locked_tables_list.reopen_tables(thd))
+      thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
+    /*
+      Even if we failed to reopen some tables,
+      the operation itself succeeded, write the binlog.
+    */
     if (!error)
     {
       /*
@@ -1213,12 +1251,11 @@ end:
     }
     if (has_mdl_lock)
       thd->mdl_context.release_lock(mdl_request.ticket);
+    if (mdl_ticket)
+      mdl_ticket->downgrade_exclusive_lock();
   }
-  else if (error)
-  {
-    if (has_mdl_lock)
-      thd->mdl_context.release_lock(mdl_request.ticket);
-  }
+
+  DBUG_PRINT("exit", ("error: %d", error));
   DBUG_RETURN(error);
 
 trunc_by_del:

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2009-12-10 14:09:00 +0000
+++ b/sql/sql_parse.cc	2009-12-11 12:13:37 +0000
@@ -3078,7 +3078,7 @@ end_with_restore_list:
       Don't allow this within a transaction because we want to use
       re-generate table
     */
-    if (thd->locked_tables_mode || thd->active_transaction())
+    if (thd->active_transaction())
     {
       my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
                  ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));


Attachment: [text/bzr-bundle] bzr/kostja@sun.com-20091211121337-4po257u415iy5oyw.bundle
Thread
bzr commit into mysql-5.6-next-mr branch (kostja:3032) Bug#20667Konstantin Osipov11 Dec