#At file:///home/svoj/devel/bzr-mysql/mysql-6.0-falcon-team-bug34892/
2842 Sergey Vojtovich 2008-09-29
BUG#34892 - Transaction handling in select_create::abort let's Falcon fail
CREATE ... SELECT that fails (e.g. due to duplicate key) with
Falcon storage engine prevents to create or drop a table with
the same name in future.
Added missing call to trans_rollback_stmt(), which was likely
lost during merge.
renamed:
mysql-test/suite/falcon_team/r/falcon_bug_23945.result => mysql-test/suite/falcon/r/falcon_bug_23945.result
mysql-test/suite/falcon_team/t/falcon_bug_23945.test => mysql-test/suite/falcon/t/falcon_bug_23945.test
modified:
mysql-test/suite/falcon_team/t/disabled.def
sql/sql_insert.cc
mysql-test/suite/falcon/r/falcon_bug_23945.result
mysql-test/suite/falcon/t/falcon_bug_23945.test
per-file messages:
mysql-test/suite/falcon/r/falcon_bug_23945.result
Re-enabled a test case.
mysql-test/suite/falcon/t/falcon_bug_23945.test
Re-enabled a test case.
mysql-test/suite/falcon_team/t/disabled.def
Removed an entry for falcon_bug_23945. This test is re-enabled and
moved back to the falcon suite.
sql/sql_insert.cc
Fixed wrongly merged code:
- modified_non_trans_table must be set to false before calling
select_insert::abort(). This instructs binlog_rollback() to
truncate transaction cache as it is stated in a comment around
select_create::abort().
- added missing call to trans_rollback_stmt(). We must rollback
transaction before unlocking a table, otherwise transactional
engine may release savepoint earlier than needed.
- fixed assertion, so it takes into account select_create::abort()
logic.
=== renamed file 'mysql-test/suite/falcon_team/r/falcon_bug_23945.result' => 'mysql-test/suite/falcon/r/falcon_bug_23945.result'
--- a/mysql-test/suite/falcon_team/r/falcon_bug_23945.result 2008-09-09 08:30:18 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_23945.result 2008-09-29 18:35:51 +0000
@@ -15,3 +15,5 @@ SELECT * FROM t1;
ERROR 42S02: Table 'test.t1' doesn't exist
DROP TABLE t1;
ERROR 42S02: Unknown table 't1'
+CREATE TABLE t1(a INT);
+DROP TABLE t1;
=== renamed file 'mysql-test/suite/falcon_team/t/falcon_bug_23945.test' => 'mysql-test/suite/falcon/t/falcon_bug_23945.test'
--- a/mysql-test/suite/falcon_team/t/falcon_bug_23945.test 2008-09-09 08:30:18 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_23945.test 2008-09-29 18:35:51 +0000
@@ -36,6 +36,9 @@ SELECT * FROM t1;
--error ER_BAD_TABLE_ERROR
DROP TABLE t1;
+CREATE TABLE t1(a INT);
+DROP TABLE t1;
+
# ----------------------------------------------------- #
# --- Check --- #
# ----------------------------------------------------- #
=== modified file 'mysql-test/suite/falcon_team/t/disabled.def'
--- a/mysql-test/suite/falcon_team/t/disabled.def 2008-09-10 22:35:51 +0000
+++ b/mysql-test/suite/falcon_team/t/disabled.def 2008-09-29 18:35:51 +0000
@@ -17,4 +17,3 @@
# which should probably be attached to a bug report instead.
# Also please keep the list sorted.
-falcon_bug_23945 : Bug#34892 2008-09-10 hky Test failure brings Falcon's data dictionary out of sync
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc 2008-09-16 17:58:49 +0000
+++ b/sql/sql_insert.cc 2008-09-29 18:35:51 +0000
@@ -3306,10 +3306,19 @@ void select_insert::abort() {
if (changed)
query_cache_invalidate3(thd, table, 1);
}
+ /*
+ CREATE ... SELECT pretends that it was transactional table
+ by setting modified_non_trans_table to false. This may cause
+ assertion failure if we're in fact updating non-transactional
+ table. In this case we also check can_rollback_data(), which
+ is true only for CREATE ... SELECT.
+ */
DBUG_ASSERT(transactional_table || !changed ||
- thd->transaction.stmt.modified_non_trans_table);
+ thd->transaction.stmt.modified_non_trans_table ||
+ can_rollback_data());
table->file->ha_release_auto_increment();
}
+ trans_rollback_stmt(thd);
DBUG_VOID_RETURN;
}
@@ -3803,8 +3812,8 @@ void select_create::abort()
log state.
*/
tmp_disable_binlog(thd);
- select_insert::abort();
thd->transaction.stmt.modified_non_trans_table= FALSE;
+ select_insert::abort();
reenable_binlog(thd);
thd->binlog_flush_pending_rows_event(TRUE);