List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:August 20 2010 7:34am
Subject:bzr push into mysql-5.5-bugfixing branch (jon.hauglid:3113 to 3114) Bug#55973
View as plain text  
 3114 Jon Olav Hauglid	2010-08-20
      Bug #55973 Assertion `thd->transaction.stmt.is_empty()'
                 on CREATE TABLE .. SELECT I_S.PART
      
      This assert was triggered if an InnoDB table was created using
      CREATE TABLE ... AS SELECT where the query used an I_S table, and
      a view existed in the database. It would also be triggered for
      any statement changing an InnoDB table (e.g. INSERT, UPDATE, DELETE)
      which had a subquery referencing an I_S table.
      
      The assert was triggered if open_normal_and_derived_tables() failed
      and a statement transaction had been started. This will usually not
      happen as tables are opened before a statement transaction is started.
      However, e.g. CREATE TABLE ... AS SELECT starts a transaction in order
      to insert tuples into the new table. And if the subquery references
      an I_S table, all current tables and views can be opened in order to
      fill the I_S table on the fly. If a view is discovered, open will fail
      as it is instructed to open tables only (OPEN_TABLE_ONLY). This would
      cause the assert to be triggered.
      
      The assert was added in the patch for Bug#52044 and was therefore
      not in any released versions of the server.
      
      This patch fixes the problem by adjusting the assert to take into
      consideration the possibility of tables being opened as part of
      an I_S query. This is similar to what is already done for 
      close_tables_for_reopen().
      
      Test case added to information_schema_inno.test.

    modified:
      mysql-test/r/information_schema_inno.result
      mysql-test/t/information_schema_inno.test
      sql/sql_base.cc
 3113 Jon Olav Hauglid	2010-08-19
      Bug #56085 Embedded server tests fails with assert in
                 check_if_table_exists()
      
      This assert was triggered when the server tried to load plugins
      while running in embedded server mode. In embedded server mode,
      check_if_table_exists() was used to check if mysql.plugin existed
      so that ER_NO_SUCH_TABLE could be silently ignored.
      The problem was that this check was done without acquiring a metadata
      lock on mysql.plugin first. This triggered the assert.
      
      This patch fixes the problem by removing the call to
      check_if_table_exists() from plugin_load(). Instead an error handler
      which traps ER_NO_SUCH_TABLE is installed before trying to open
      mysql.plugin when running in embedded server mode.
      
      No test coverage added since this assert was triggered by 
      existing tests running in embedded server mode.
     @ sql/sql_base.cc
        Renamed Prelock_error_handler to No_such_table_error_handler
        and moved the declaration to sql_base.h to make it usable
        in plugin_load().
     @ sql/sql_base.h
        Renamed Prelock_error_handler to No_such_table_error_handler
        and moved the declaration to sql_base.h to make it usable
        in plugin_load().
     @ sql/sql_plugin.cc
        Removed call to check_if_table_exists() used to check for mysql.plugin 
        in plugin_load() for embedded server. Instead install error handler
        which traps ER_NO_SUCH_TABLE during open_and_lock_tables().

    modified:
      sql/sql_base.cc
      sql/sql_base.h
      sql/sql_plugin.cc
=== modified file 'mysql-test/r/information_schema_inno.result'
--- a/mysql-test/r/information_schema_inno.result	2009-10-23 11:02:20 +0000
+++ b/mysql-test/r/information_schema_inno.result	2010-08-20 07:16:26 +0000
@@ -89,3 +89,15 @@ UNIQUE_CONSTRAINT_NAME
 NULL
 drop table t2;
 set foreign_key_checks = 1;
+#
+# Bug#55973 Assertion `thd->transaction.stmt.is_empty()'
+#           on CREATE TABLE .. SELECT I_S.PART
+#
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+CREATE VIEW v1 AS SELECT 1;
+CREATE TABLE t1 engine = InnoDB AS
+SELECT * FROM information_schema.partitions
+WHERE table_schema= 'test' AND table_name= 'v1';
+DROP TABLE t1;
+DROP VIEW v1;

=== modified file 'mysql-test/t/information_schema_inno.test'
--- a/mysql-test/t/information_schema_inno.test	2008-03-14 10:12:39 +0000
+++ b/mysql-test/t/information_schema_inno.test	2010-08-20 07:16:26 +0000
@@ -89,3 +89,23 @@ from information_schema.referential_cons
 where constraint_schema = schema();
 drop table t2;
 set foreign_key_checks = 1;
+
+
+--echo #
+--echo # Bug#55973 Assertion `thd->transaction.stmt.is_empty()'
+--echo #           on CREATE TABLE .. SELECT I_S.PART
+--echo #
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+--enable_warnings
+
+CREATE VIEW v1 AS SELECT 1;
+# This used to case an assert.
+CREATE TABLE t1 engine = InnoDB AS
+  SELECT * FROM information_schema.partitions
+  WHERE table_schema= 'test' AND table_name= 'v1';
+
+DROP TABLE t1;
+DROP VIEW v1;

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-08-19 09:33:37 +0000
+++ b/sql/sql_base.cc	2010-08-20 07:16:26 +0000
@@ -5411,8 +5411,14 @@ bool open_normal_and_derived_tables(THD 
 
   DBUG_RETURN(0);
 end:
-  /* No need to rollback statement transaction, it's not started. */
-  DBUG_ASSERT(thd->transaction.stmt.is_empty());
+  /*
+    No need to commit/rollback the statement transaction: it's
+    either not started or we're filling in an INFORMATION_SCHEMA
+    table on the fly, and thus mustn't manipulate with the
+    transaction of the enclosing statement.
+  */
+  DBUG_ASSERT(thd->transaction.stmt.is_empty() ||
+              (thd->state_flags & Open_tables_state::BACKUPS_AVAIL));
   close_thread_tables(thd);
   /* Don't keep locks for a failed statement. */
   thd->mdl_context.rollback_to_savepoint(mdl_savepoint);


Attachment: [text/bzr-bundle] bzr/jon.hauglid@oracle.com-20100820071626-d8ndtdj1hyztjbyf.bundle
Thread
bzr push into mysql-5.5-bugfixing branch (jon.hauglid:3113 to 3114) Bug#55973Jon Olav Hauglid20 Aug