#At file:///data0/martin/bzr/5.1-5.1.29-rc-fix-bug38499/
2690 Martin Hansson 2008-09-20
Bug#38499: flush tables and multitable table update with
derived table cause crash
When a multi-UPDATE command fails to lock some table, and
subsequently succeeds, the tables need to be reopened if
they were altered. But the reopening procedure failed for
derived tables.
Fixed by resetting the 'prepared' flag on derived tables
during the mentioned procedure, which causes them to be
reopened.
modified:
mysql-test/r/lock_multi.result
mysql-test/t/lock_multi.test
sql/sql_update.cc
sql/table.cc
sql/table.h
per-file messages:
mysql-test/r/lock_multi.result
Bug#38499: Test result
mysql-test/t/lock_multi.test
Bug#38499: Test case
sql/sql_update.cc
Bug#38499: The fix.
sql/table.cc
Bug#38499: Definition of helper method for the fix.
sql/table.h
Bug#38499: Declaration of helper method for the fix.
=== modified file 'mysql-test/r/lock_multi.result'
--- a/mysql-test/r/lock_multi.result 2008-02-06 11:40:59 +0000
+++ b/mysql-test/r/lock_multi.result 2008-09-20 09:23:48 +0000
@@ -153,4 +153,10 @@ drop table t1;
select @tlwa < @tlwb;
@tlwa < @tlwb
1
+CREATE TABLE t1( a INT );
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+LOCK TABLES t1 WRITE;
+UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
+ALTER TABLE t1 ADD b INT;
+UNLOCK TABLES;
End of 5.1 tests
=== modified file 'mysql-test/t/lock_multi.test'
--- a/mysql-test/t/lock_multi.test 2008-02-22 12:35:08 +0000
+++ b/mysql-test/t/lock_multi.test 2008-09-20 09:23:48 +0000
@@ -472,4 +472,35 @@ eval SET @tlwb= SUBSTRING_INDEX('$tlwb',
--enable_query_log
select @tlwa < @tlwb;
+#
+# Bug#38499: flush tables and multitable table update with derived table cause
+# crash
+#
+CREATE TABLE t1( a INT );
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+--connect (conn1, localhost, root,,)
+LOCK TABLES t1 WRITE;
+--connect (conn2, localhost, root,,)
+--send
+UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
+
+--connection conn1
+
+let $wait_condition=
+ SELECT *
+ FROM information_schema.processlist
+ WHERE STATE = "Locked" AND
+ info = "UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0";
+--source include/wait_condition.inc
+
+ALTER TABLE t1 ADD b INT;
+UNLOCK TABLES;
+
+--disconnect conn1
+--connection conn2
+# When the bug is present, we get a server crash during this command.
+--reap
+--disconnect conn2
+--connection default
+
--echo End of 5.1 tests
=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc 2008-08-26 10:01:49 +0000
+++ b/sql/sql_update.cc 2008-09-20 09:23:48 +0000
@@ -1094,7 +1094,10 @@ reopen_tables:
/* We have to cleanup translation tables of views. */
for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
+ {
+ tbl->cleanup_select_lex();
tbl->cleanup_items();
+ }
close_tables_for_reopen(thd, &table_list);
goto reopen_tables;
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2008-09-03 14:45:40 +0000
+++ b/sql/table.cc 2008-09-20 09:23:48 +0000
@@ -3124,6 +3124,21 @@ bool TABLE_LIST::setup_underlying(THD *t
DBUG_RETURN(FALSE);
}
+/**
+ @brief Clean up AST structure (st_select_lex_unit) in order to cause a
+ table to be reopened.
+
+ @details For derived tables, you normally do not want to reopen the tables.
+ This is needed, however, if the table definition has changed. This method
+ marks the AST structure so that a reopen will take place when calling
+ st_select_lex_unit::prepare()
+ */
+void TABLE_LIST::cleanup_select_lex()
+{
+ if (derived)
+ derived->prepared= FALSE;
+}
+
/*
Prepare where expression of view
=== modified file 'sql/table.h'
--- a/sql/table.h 2008-09-03 14:45:40 +0000
+++ b/sql/table.h 2008-09-20 09:23:48 +0000
@@ -1357,6 +1357,7 @@ struct TABLE_LIST
int view_check_option(THD *thd, bool ignore_failure);
bool setup_underlying(THD *thd);
void cleanup_items();
+ void cleanup_select_lex();
bool placeholder()
{
return derived || view || schema_table || create && !table->db_stat ||
| Thread |
|---|
| • bzr commit into mysql-5.1 branch (mhansson:2690) Bug#38499 | Martin Hansson | 20 Sep |