diff options
-rw-r--r-- | mysql-test/r/bug40113.result | 29 | ||||
-rw-r--r-- | mysql-test/r/group_min_max.result | 6 | ||||
-rw-r--r-- | mysql-test/t/bug40113-master.opt | 1 | ||||
-rw-r--r-- | mysql-test/t/bug40113.test | 46 | ||||
-rw-r--r-- | mysql-test/t/group_min_max.test | 2 | ||||
-rw-r--r-- | sql/sql_delete.cc | 10 | ||||
-rw-r--r-- | sql/sql_update.cc | 11 |
7 files changed, 97 insertions, 8 deletions
diff --git a/mysql-test/r/bug40113.result b/mysql-test/r/bug40113.result new file mode 100644 index 00000000000..289037a3f35 --- /dev/null +++ b/mysql-test/r/bug40113.result @@ -0,0 +1,29 @@ +# +# Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout +# without error +# +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB; +INSERT INTO t1 (a,b) VALUES (1070109,99); +CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB; +INSERT INTO t2 (b,a) VALUES (7,1070109); +SELECT * FROM t1; +a b +1070109 99 +BEGIN; +SELECT b FROM t2 WHERE b=7 FOR UPDATE; +b +7 +BEGIN; +SELECT b FROM t2 WHERE b=7 FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7)); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1; +a b +1070109 99 +DROP TABLE t2, t1; +End of 5.0 tests diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result index 1138a5e1d88..9acbbaac499 100644 --- a/mysql-test/r/group_min_max.result +++ b/mysql-test/r/group_min_max.result @@ -2278,12 +2278,10 @@ Handler_read_key 8 Handler_read_next 0 FLUSH STATUS; DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x -FROM t1) > 10000; -Warnings: -Error 1242 Subquery returns more than 1 row +FROM t1 WHERE a = 1 AND b = 1) > 10000; SHOW STATUS LIKE 'handler_read__e%'; Variable_name Value -Handler_read_key 8 +Handler_read_key 9 Handler_read_next 1 DROP TABLE t1,t2,t3; CREATE TABLE t1 (a int, INDEX idx(a)); diff --git a/mysql-test/t/bug40113-master.opt b/mysql-test/t/bug40113-master.opt new file mode 100644 index 00000000000..462f8fbe828 --- /dev/null +++ b/mysql-test/t/bug40113-master.opt @@ -0,0 +1 @@ +--innodb_lock_wait_timeout=1 diff --git a/mysql-test/t/bug40113.test b/mysql-test/t/bug40113.test new file mode 100644 index 00000000000..6d35d0b73d3 --- /dev/null +++ b/mysql-test/t/bug40113.test @@ -0,0 +1,46 @@ +--source include/have_innodb.inc + +--echo # +--echo # Bug #40113: Embedded SELECT inside UPDATE or DELETE can timeout +--echo # without error +--echo # + +CREATE TABLE t1 (a int, b int, PRIMARY KEY (a,b)) ENGINE=InnoDB; + +INSERT INTO t1 (a,b) VALUES (1070109,99); + +CREATE TABLE t2 (b int, a int, PRIMARY KEY (b)) ENGINE=InnoDB; + +INSERT INTO t2 (b,a) VALUES (7,1070109); + +SELECT * FROM t1; + +BEGIN; + +SELECT b FROM t2 WHERE b=7 FOR UPDATE; + +CONNECT (addconroot, localhost, root,,); +CONNECTION addconroot; + +BEGIN; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT b FROM t2 WHERE b=7 FOR UPDATE; + +--error ER_LOCK_WAIT_TIMEOUT +INSERT INTO t1 (a) VALUES ((SELECT a FROM t2 WHERE b=7)); + +--error ER_LOCK_WAIT_TIMEOUT +UPDATE t1 SET a='7000000' WHERE a=(SELECT a FROM t2 WHERE b=7); + +--error ER_LOCK_WAIT_TIMEOUT +DELETE FROM t1 WHERE a=(SELECT a FROM t2 WHERE b=7); + +SELECT * FROM t1; + +CONNECTION default; +DISCONNECT addconroot; + +DROP TABLE t2, t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test index 163c170eaa0..c81babb42e6 100644 --- a/mysql-test/t/group_min_max.test +++ b/mysql-test/t/group_min_max.test @@ -866,7 +866,7 @@ DELETE FROM t3 WHERE (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) > 10000; SHOW STATUS LIKE 'handler_read__e%'; FLUSH STATUS; DELETE FROM t3 WHERE (SELECT (SELECT MAX(b) FROM t1 GROUP BY a HAVING a < 2) x - FROM t1) > 10000; + FROM t1 WHERE a = 1 AND b = 1) > 10000; SHOW STATUS LIKE 'handler_read__e%'; DROP TABLE t1,t2,t3; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 30b14209a7c..3bf088609cd 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -144,6 +144,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, delete select; free_underlaid_joins(thd, select_lex); thd->row_count_func= 0; + /* + Error was already created by quick select evaluation (check_quick()). + TODO: Add error code output parameter to Item::val_xxx() methods. + Currently they rely on the user checking DA for + errors when unwinding the stack after calling Item::val_xxx(). + */ + if (thd->net.report_error) + DBUG_RETURN(TRUE); send_ok(thd,0L); /* @@ -407,7 +415,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) if (select_lex->inner_refs_list.elements && fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array)) - DBUG_RETURN(-1); + DBUG_RETURN(TRUE); select_lex->fix_prepare_information(thd, conds, &fake_conds); DBUG_RETURN(FALSE); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 481fe30c6e7..f95f0a22a71 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -230,7 +230,7 @@ int mysql_update(THD *thd, if (select_lex->inner_refs_list.elements && fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array)) - DBUG_RETURN(-1); + DBUG_RETURN(1); if (conds) { @@ -247,7 +247,14 @@ int mysql_update(THD *thd, { delete select; free_underlaid_joins(thd, select_lex); - if (error) + /* + There was an error or the error was already sent by + the quick select evaluation. + TODO: Add error code output parameter to Item::val_xxx() methods. + Currently they rely on the user checking DA for + errors when unwinding the stack after calling Item::val_xxx(). + */ + if (error || thd->net.report_error) { DBUG_RETURN(1); // Error in where } |