From ef65e32d70913dd57c206b29a1a6935aa23de210 Mon Sep 17 00:00:00 2001 From: "Bernt M. Johnsen" Date: Tue, 5 May 2009 11:07:11 +0200 Subject: [PATCH 1/2] Bug#23471 prepared for commit in 5.0 gca branch --- tests/mysql_client_test.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 9e026a27b6d..9dfacb7436d 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -3971,6 +3971,10 @@ static void test_fetch_date() myheader("test_fetch_date"); + /* Will not work if sql_mode is NO_ZERO_DATE (implicit if TRADITIONAL) /*/ + rc= mysql_query(mysql, "SET SQL_MODE=''"); + myquery(rc); + rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result"); myquery(rc); @@ -4685,6 +4689,9 @@ static void test_stmt_close() /* set AUTOCOMMIT to ON*/ mysql_autocommit(lmysql, TRUE); + rc= mysql_query(lmysql, "SET SQL_MODE = ''"); + myquery(rc); + rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_stmt_close"); myquery(rc); @@ -11855,6 +11862,9 @@ static void test_bug6058() myheader("test_bug6058"); + rc= mysql_query(mysql, "SET SQL_MODE=''"); + myquery(rc); + stmt_text= "SELECT CAST('0000-00-00' AS DATE)"; rc= mysql_real_query(mysql, stmt_text, (uint) strlen(stmt_text)); @@ -13026,6 +13036,9 @@ static void test_bug8378() if (!opt_silent) fprintf(stdout, " OK"); + rc= mysql_query(lmysql, "SET SQL_MODE=''"); + myquery(rc); + len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4); /* No escaping should have actually happened. */ @@ -16056,6 +16069,11 @@ static void test_bug31669() rc= mysql_query(mysql, query); myquery(rc); + strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'localhost' IDENTIFIED BY " + "'", buff, "' WITH GRANT OPTION", NullS); + rc= mysql_query(mysql, query); + myquery(rc); + rc= mysql_query(mysql, "FLUSH PRIVILEGES"); myquery(rc); @@ -16093,7 +16111,7 @@ static void test_bug31669() strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS); rc= mysql_query(mysql, query); myquery(rc); - DIE_UNLESS(mysql_affected_rows(mysql) == 1); + DIE_UNLESS(mysql_affected_rows(mysql) == 2); #endif DBUG_VOID_RETURN; From 609a794b15fe44408fa47582e798147d1ffe3463 Mon Sep 17 00:00:00 2001 From: Anurag Shekhar Date: Wed, 6 May 2009 13:37:10 +0530 Subject: [PATCH 2/2] Bug #39918 memory (heap) engine crashing with b-tree index and DELETE with seg fault Multiple-table DELETE from a table joined to itself may cause server crash. This was originally discovered with MEMORY engine, but may affect other engines with different symptoms. The problem was that the server violated SE API by performing parallel table scan in one handler and removing records in another (delete on the fly optimization). mysql-test/r/heap_btree.result: Updated test result after adding new test for this bug. mysql-test/t/heap_btree.test: Updated test result after adding new test for the bug report. sql/sql_delete.cc: Updated to check if the files in delete list appears in join list and disable delete while scanning, if it appears. --- mysql-test/r/heap_btree.result | 7 +++++++ mysql-test/t/heap_btree.test | 8 ++++++++ sql/sql_delete.cc | 20 +++++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result index c20dfbe80d2..65ced2bd24e 100644 --- a/mysql-test/r/heap_btree.result +++ b/mysql-test/r/heap_btree.result @@ -336,4 +336,11 @@ a b NULL NULL NULL 1 drop table t1; +# +# bug#39918 - memory (heap) engine crashing while executing self join with delete +# +CREATE TABLE t1(a INT, KEY USING BTREE (a)) ENGINE=MEMORY; +INSERT INTO t1 VALUES(1),(1); +DELETE a1 FROM t1 AS a1, t1 AS a2 WHERE a1.a=a2.a; +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test index 76c319c0bc1..710c8411751 100644 --- a/mysql-test/t/heap_btree.test +++ b/mysql-test/t/heap_btree.test @@ -253,5 +253,13 @@ insert into t1 values (1, 1), (3, 3), (2, 2), (NULL, 1), (NULL, NULL), (0, 0); select * from t1 where a is null; drop table t1; +-- echo # +-- echo # bug#39918 - memory (heap) engine crashing while executing self join with delete +-- echo # + +CREATE TABLE t1(a INT, KEY USING BTREE (a)) ENGINE=MEMORY; +INSERT INTO t1 VALUES(1),(1); +DELETE a1 FROM t1 AS a1, t1 AS a2 WHERE a1.a=a2.a; +DROP TABLE t1; --echo End of 5.0 tests diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index a757b7c28a5..5307a4426c5 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -503,6 +503,11 @@ int mysql_multi_delete_prepare(THD *thd) } } } + /* + Reset the exclude flag to false so it doesn't interfare + with further calls to unique_table + */ + lex->select_lex.exclude_from_table_unique_test= FALSE; DBUG_RETURN(FALSE); } @@ -538,11 +543,24 @@ multi_delete::initialize_tables(JOIN *join) DBUG_RETURN(1); table_map tables_to_delete_from=0; + delete_while_scanning= 1; for (walk= delete_tables; walk; walk= walk->next_local) + { tables_to_delete_from|= walk->table->map; + if (delete_while_scanning && + unique_table(thd, walk, join->tables_list, false)) + { + /* + If the table we are going to delete from appears + in join, we need to defer delete. So the delete + doesn't interfers with the scaning of results. + */ + delete_while_scanning= 0; + } + } + walk= delete_tables; - delete_while_scanning= 1; for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables; tab < end; tab++)