summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Hansson <martin.hansson@oracle.com>2010-09-07 09:58:05 +0200
committerMartin Hansson <martin.hansson@oracle.com>2010-09-07 09:58:05 +0200
commit446cc653c0ab13a6fec8ab54de9f5596389b08bc (patch)
treeb5a71beeffb63735a0ec8e19060817e72a1751b5
parentd2d4fdb23f6b38ff6718a35120043627582ee836 (diff)
downloadmariadb-git-446cc653c0ab13a6fec8ab54de9f5596389b08bc.tar.gz
Bug#54543: update ignore with incorrect subquery leads to assertion failure:
inited==INDEX When an error occurs while sending the data in a temporary table there was no cleanup performed. This caused a failed assertion in the case when different access methods were used for populating the table vs. retrieving the data from the table if IGNORE was specified and sql_safe_updates = 0. In this case execution continues, but the handler expects to continue with the access method used for row retrieval. Fixed by doing the cleanup even if errors occur.
-rw-r--r--mysql-test/r/multi_update.result20
-rw-r--r--mysql-test/t/multi_update.test21
-rw-r--r--sql/sql_select.cc18
3 files changed, 49 insertions, 10 deletions
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
index ae72f416c79..d77ad1d2953 100644
--- a/mysql-test/r/multi_update.result
+++ b/mysql-test/r/multi_update.result
@@ -639,4 +639,24 @@ SET SESSION sql_safe_updates = 1;
UPDATE IGNORE t1, t1 t1a SET t1.a = 1 WHERE t1a.a = 1;
ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
DROP TABLE t1;
+#
+# Bug#54543: update ignore with incorrect subquery leads to assertion
+# failure: inited==INDEX
+#
+SET SESSION sql_safe_updates = 0;
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 ( a INT );
+INSERT INTO t2 VALUES (1), (2);
+CREATE TABLE t3 ( a INT );
+INSERT INTO t3 VALUES (1), (2);
+# Should not crash
+UPDATE IGNORE
+( SELECT ( SELECT COUNT(*) FROM t1 GROUP BY a, @v ) a FROM t2 ) x, t3
+SET t3.a = 0;
+Warnings:
+Error 1242 Subquery returns more than 1 row
+Error 1242 Subquery returns more than 1 row
+DROP TABLE t1, t2, t3;
+SET SESSION sql_safe_updates = DEFAULT;
end of tests
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
index 559408eb90e..85d2ed19fda 100644
--- a/mysql-test/t/multi_update.test
+++ b/mysql-test/t/multi_update.test
@@ -651,5 +651,26 @@ SET SESSION sql_safe_updates = 1;
UPDATE IGNORE t1, t1 t1a SET t1.a = 1 WHERE t1a.a = 1;
DROP TABLE t1;
+--echo #
+--echo # Bug#54543: update ignore with incorrect subquery leads to assertion
+--echo # failure: inited==INDEX
+--echo #
+SET SESSION sql_safe_updates = 0;
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (1), (2);
+
+CREATE TABLE t2 ( a INT );
+INSERT INTO t2 VALUES (1), (2);
+
+CREATE TABLE t3 ( a INT );
+INSERT INTO t3 VALUES (1), (2);
+
+--echo # Should not crash
+UPDATE IGNORE
+ ( SELECT ( SELECT COUNT(*) FROM t1 GROUP BY a, @v ) a FROM t2 ) x, t3
+SET t3.a = 0;
+
+DROP TABLE t1, t2, t3;
+SET SESSION sql_safe_updates = DEFAULT;
--echo end of tests
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 4a32ca34790..f550f75c8b8 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -11157,22 +11157,20 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
if (error == NESTED_LOOP_NO_MORE_ROWS)
error= NESTED_LOOP_OK;
+ if (table == NULL) // If sending data to client
+ /*
+ The following will unlock all cursors if the command wasn't an
+ update command
+ */
+ join->join_free(); // Unlock all cursors
if (error == NESTED_LOOP_OK)
{
/*
Sic: this branch works even if rc != 0, e.g. when
send_data above returns an error.
*/
- if (!table) // If sending data to client
- {
- /*
- The following will unlock all cursors if the command wasn't an
- update command
- */
- join->join_free(); // Unlock all cursors
- if (join->result->send_eof())
- rc= 1; // Don't send error
- }
+ if (table == NULL && join->result->send_eof()) // If sending data to client
+ rc= 1; // Don't send error
DBUG_PRINT("info",("%ld records output", (long) join->send_records));
}
else