Hello Jon Olav!
* Jon Olav Hauglid <jon.hauglid@stripped> [10/08/19 19:20]:
> #At file:///export/home/x/mysql-5.5-runtime-bug55973/ based on
> 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.
Maybe it makes sense to mention that this bug can show up if
one performs any statement changing InnoDB table (e.g. INSERT/
UPDATE/DELETE) which has subquery referencing 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, 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
> Test case added to information_schema_inno.test.
> === 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 #
> +DROP TABLE IF EXISTS t1;
> +DROP VIEW IF EXISTS v1;
> +CREATE VIEW v1 AS SELECT 1;
> +# This used to case an assert.
> +CREATE TABLE t1 engine = InnoDB AS SELECT * FROM information_schema.partitions;
Please consider using subquery with WHERE clause to make test faster
(e.g. something like 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-19 14:25:47 +0000
> @@ -5411,8 +5411,14 @@ bool open_normal_and_derived_tables(THD
> - /* 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));
> /* Don't keep locks for a failed statement. */
Otherwise I am OK with your patch.
Thank you for working on this issue!
Dmitry Lenev, Software Developer
Oracle Development SPB/MySQL, www.mysql.com
Are you MySQL certified? http://www.mysql.com/certification