#At file:///export/home/x/mysql-5.5-runtime-bug55973/ based on revid:jon.hauglid@stripped
3114 Jon Olav Hauglid 2010-08-19
Bug #55973 Assertion `thd->transaction.stmt.is_empty()'
on CREATE TABLE .. SELECT I_S.PART
This assert could be 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.
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, CREATE TABLE ... AS SELECT starts a transaction in order
to insert tuples into the new table. And if the SELECT is an I_S query,
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 then
trigger the assert.
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
=== 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-19 14:25:47 +0000
@@ -89,3 +89,13 @@ 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;
+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-19 14:25:47 +0000
@@ -89,3 +89,21 @@ 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;
+
+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-19 14:25:47 +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-20100819142547-x17lf2yoo8dpcmw6.bundle