Commit bef74a23 authored by Georgi Kodinov's avatar Georgi Kodinov

Merge of the fix for bug #40113 to 5.1.

parents 68228070 410e1a72
#
# 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
--innodb_lock_wait_timeout=1
--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
...@@ -187,6 +187,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -187,6 +187,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
delete select; delete select;
free_underlaid_joins(thd, select_lex); free_underlaid_joins(thd, select_lex);
thd->row_count_func= 0; 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->is_error())
DBUG_RETURN(TRUE);
my_ok(thd, (ha_rows) thd->row_count_func); my_ok(thd, (ha_rows) thd->row_count_func);
/* /*
We don't need to call reset_auto_increment in this case, because We don't need to call reset_auto_increment in this case, because
...@@ -490,7 +498,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds) ...@@ -490,7 +498,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
if (select_lex->inner_refs_list.elements && if (select_lex->inner_refs_list.elements &&
fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array)) 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); select_lex->fix_prepare_information(thd, conds, &fake_conds);
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
......
...@@ -292,7 +292,7 @@ int mysql_update(THD *thd, ...@@ -292,7 +292,7 @@ int mysql_update(THD *thd,
if (select_lex->inner_refs_list.elements && if (select_lex->inner_refs_list.elements &&
fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array)) fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
DBUG_RETURN(-1); DBUG_RETURN(1);
if (conds) if (conds)
{ {
...@@ -332,7 +332,14 @@ int mysql_update(THD *thd, ...@@ -332,7 +332,14 @@ int mysql_update(THD *thd,
{ {
delete select; delete select;
free_underlaid_joins(thd, select_lex); 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->is_error())
{ {
DBUG_RETURN(1); // Error in where DBUG_RETURN(1); // Error in where
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment