MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Gleb Shchepa Date:October 8 2008 6:08pm
Subject:bzr commit into mysql-5.0-bugteam branch (gshchepa:2690) Bug#38499
View as plain text  
#At file:///work/bzr/5.0-5.1.29-rc-38499/

 2690 Gleb Shchepa	2008-10-08
      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.
      
      Extra cleanup has been added.
modified:
  mysql-test/r/lock_multi.result
  mysql-test/t/lock_multi.test
  sql/sql_union.cc
  sql/sql_update.cc

per-file messages:
  mysql-test/r/lock_multi.result
    Added test case for bug #38499.
  mysql-test/t/lock_multi.test
    Added test case for bug #38499.
  sql/sql_union.cc
    Bug#38499: flush tables and multitable table update with
               derived table cause crash
    
    Obsolete assertion has been removed.
  sql/sql_update.cc
    Bug#38499: flush tables and multitable table update with
               derived table cause crash
    
    Extra cleanup has been added:
    1) unit.cleanup(),
    2) reinit_stmt_before_use() for UNIONs.
=== modified file 'mysql-test/r/lock_multi.result'
--- a/mysql-test/r/lock_multi.result	2008-10-07 21:34:00 +0000
+++ b/mysql-test/r/lock_multi.result	2008-10-08 18:08:38 +0000
@@ -115,3 +115,21 @@ CREATE TABLE t3 SELECT * FROM t1;
 # normal mode
 # PS mode
 DROP TABLE t1, t2, t3;
+CREATE TABLE t1( a INT, b INT );
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
+# 1. test regular tables
+# 1.1. test altering of columns that multiupdate doesn't use
+# 1.1.1. normal mode
+# 1.1.2. PS mode
+# 1.2. test altering of columns that multiupdate uses
+# 1.2.1. normal mode
+# 1.2.2. PS mode
+ALTER TABLE t1 ADD COLUMN a INT;
+# 2. test UNIONs
+# 2.1. test altering of columns that multiupdate doesn't use
+# 2.1.1. normal mode
+# 2.1.2. PS mode
+# 2.2. test altering of columns that multiupdate uses
+# 2.2.1. normal mode
+# 2.2.2. PS mode
+DROP TABLE t1;

=== modified file 'mysql-test/t/lock_multi.test'
--- a/mysql-test/t/lock_multi.test	2008-10-07 21:34:00 +0000
+++ b/mysql-test/t/lock_multi.test	2008-10-08 18:08:38 +0000
@@ -400,4 +400,206 @@ while ($i) {
 --connection default
 DROP TABLE t1, t2, t3;
 
+#
+# Bug#38499: flush tables and multitable table update with derived table cause 
+#            crash
+#
+
+CREATE TABLE t1( a INT, b INT );
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4);
+
+--echo # 1. test regular tables
+--echo # 1.1. test altering of columns that multiupdate doesn't use
+--echo # 1.1.1. normal mode
+
+--disable_query_log
+let $i = 100;
+while ($i) {
+--dec $i
+
+--connection writer
+  send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
+
+--connection locker
+  ALTER TABLE t1 ADD COLUMN (c INT);
+  ALTER TABLE t1 DROP COLUMN c;
+
+--connection writer
+--reap
+}
+
+--echo # 1.1.2. PS mode
+
+--connection writer
+PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0';
+
+let $i = 100;
+while ($i) {
+--dec $i
+
+--connection writer
+--send EXECUTE stmt
+
+--connection locker
+  ALTER TABLE t1 ADD COLUMN (c INT);
+  ALTER TABLE t1 DROP COLUMN c;
+
+--connection writer
+--reap
+}
+--enable_query_log
+
+--echo # 1.2. test altering of columns that multiupdate uses
+--echo # 1.2.1. normal mode
+
+--connection default
+
+--disable_query_log
+let $i = 100;
+while ($i) {
+  dec $i;
+
+--connection locker
+--error 0,1060
+  ALTER TABLE t1 ADD COLUMN a int(11) unsigned default NULL;
+  UPDATE t1 SET a=b;
+
+--connection writer
+--send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0;
+
+--connection locker
+--error 0,1091
+  ALTER TABLE t1 DROP COLUMN a;
+
+--connection writer
+--error 0,1054 # unknown column error
+--reap
+}
+--enable_query_log
+
+--echo # 1.2.2. PS mode
+
+--disable_query_log
+let $i = 100;
+while ($i) {
+  dec $i;
+
+--connection locker
+--error 0,1060
+  ALTER TABLE t1 ADD COLUMN a INT;
+  UPDATE t1 SET a=b;
+
+--connection writer
+  PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0';
+--send EXECUTE stmt
+
+--connection locker
+--error 0,1091
+  ALTER TABLE t1 DROP COLUMN a;
+
+--connection writer
+--error 0,1054 # Unknown column 'a' in 'field list'
+--reap
+}
+--enable_query_log
+--connection default
+ALTER TABLE t1 ADD COLUMN a INT;
+
+--echo # 2. test UNIONs
+--echo # 2.1. test altering of columns that multiupdate doesn't use
+--echo # 2.1.1. normal mode
+
+--disable_query_log
+let $i = 100;
+while ($i) {
+--dec $i
+
+--connection writer
+  send UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0;
+
+--connection locker
+  ALTER TABLE t1 ADD COLUMN (c INT);
+  ALTER TABLE t1 DROP COLUMN c;
+
+--connection writer
+--reap
+}
+
+--echo # 2.1.2. PS mode
+
+--connection writer
+PREPARE stmt FROM 'UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0';
+
+let $i = 100;
+while ($i) {
+--dec $i
+
+--connection writer
+--send EXECUTE stmt
+
+--connection locker
+  ALTER TABLE t1 ADD COLUMN (c INT);
+  ALTER TABLE t1 DROP COLUMN c;
+
+--connection writer
+--reap
+}
+--enable_query_log
+
+--echo # 2.2. test altering of columns that multiupdate uses
+--echo # 2.2.1. normal mode
+
+--connection default
+
+--disable_query_log
+let $i = 100;
+while ($i) {
+  dec $i;
+
+--connection locker
+--error 0,1060
+  ALTER TABLE t1 ADD COLUMN a int(11) unsigned default NULL;
+  UPDATE t1 SET a=b;
+
+--connection writer
+--send UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0;
+
+--connection locker
+--error 0,1091
+  ALTER TABLE t1 DROP COLUMN a;
+
+--connection writer
+--error 0,1054 # Unknown column 'a' in 'field list'
+--reap
+}
+--enable_query_log
+
+--echo # 2.2.2. PS mode
+
+--disable_query_log
+let $i = 100;
+while ($i) {
+  dec $i;
+
+--connection locker
+--error 0,1060
+  ALTER TABLE t1 ADD COLUMN a INT;
+  UPDATE t1 SET a=b;
+
+--connection writer
+  PREPARE stmt FROM 'UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0';
+--send EXECUTE stmt
+
+--connection locker
+--error 0,1091
+  ALTER TABLE t1 DROP COLUMN a;
+
+--connection writer
+--error 0,1054 # Unknown column 'a' in 'field list'
+--reap
+}
+--enable_query_log
+--connection default
+DROP TABLE t1;
+
 # End of 5.0 tests

=== modified file 'sql/sql_union.cc'
--- a/sql/sql_union.cc	2008-03-29 14:12:23 +0000
+++ b/sql/sql_union.cc	2008-10-08 18:08:38 +0000
@@ -399,7 +399,6 @@ bool st_select_lex_unit::prepare(THD *th
     }
     else
     {
-      DBUG_ASSERT(!thd->stmt_arena->is_conventional());
       /*
         We're in execution of a prepared statement or stored procedure:
         reset field items to point at fields from the created temporary table.

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2008-10-07 21:34:00 +0000
+++ b/sql/sql_update.cc	2008-10-08 18:08:38 +0000
@@ -875,6 +875,12 @@ reopen_tables:
     for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
       tbl->cleanup_items();
 
+    lex->unit.cleanup();
+
+    /* Reinit lex for UNION execution in mysql_derived_filling below */
+    if (thd->fill_derived_tables())
+      reinit_stmt_before_use(thd, lex);
+
     /*
       Also we need to cleanup Natural_join_column::table_field items.
       To not to traverse a join tree we will cleanup whole

Thread
bzr commit into mysql-5.0-bugteam branch (gshchepa:2690) Bug#38499Gleb Shchepa8 Oct