mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
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.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -89,3 +89,23 @@ from information_schema.referential_constraints
|
||||
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;
|
||||
|
||||
@@ -5411,8 +5411,14 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags)
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user