diff --git a/mysql-test/r/innodb-non-simple.result b/mysql-test/r/innodb-non-simple.result new file mode 100644 index 00000000000..8461b9d8d4d --- /dev/null +++ b/mysql-test/r/innodb-non-simple.result @@ -0,0 +1,76 @@ +drop table if exists t1, t2; +create table t1 (id integer, x integer) type=INNODB; +create table t2 (b integer, a integer) type=INNODB; +insert into t1 values(0, 0), (300, 300); +insert into t2 values(0, 10), (1, 20), (2, 30); +set autocommit=0; +select * from t2; +b a +0 10 +1 20 +2 30 +update t2 set a=100 where b=(SELECT x from t1 where id = b FOR UPDATE); +select * from t2; +b a +0 100 +1 20 +2 30 +select * from t1; +id x +0 0 +300 300 +set autocommit=0; +update t1 set x=2 where id = 0; +update t1 set x=1 where id = 0; +select * from t1; +id x +0 1 +300 300 +commit; +commit; +select * from t1; +id x +0 2 +300 300 +commit; +drop table t1, t2; +create table t1 (id integer, x integer) type=INNODB; +create table t2 (b integer, a integer) type=INNODB; +insert into t1 values(0, 0), (300, 300); +insert into t2 values(0, 0), (1, 20), (2, 30); +commit; +select a,b from t2 UNION SELECT id, x from t1 FOR UPDATE; +a b +0 0 +20 1 +30 2 +300 300 +select * from t2; +b a +0 0 +1 20 +2 30 +select * from t1; +id x +0 0 +300 300 +update t2 set a=2 where b = 0; +select * from t2; +b a +0 2 +1 20 +2 30 +update t1 set x=2 where id = 0; +update t1 set x=1 where id = 0; +select * from t1; +id x +0 1 +300 300 +commit; +commit; +select * from t1; +id x +0 2 +300 300 +commit; +drop table t1, t2; diff --git a/mysql-test/t/innodb-non-simple.test b/mysql-test/t/innodb-non-simple.test new file mode 100644 index 00000000000..1d890896d3f --- /dev/null +++ b/mysql-test/t/innodb-non-simple.test @@ -0,0 +1,76 @@ +-- source include/have_innodb.inc + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); +drop table if exists t1, t2; +# +# Testing of FOR UPDATE +# + +connection con1; +create table t1 (id integer, x integer) type=INNODB; +create table t2 (b integer, a integer) type=INNODB; +insert into t1 values(0, 0), (300, 300); +insert into t2 values(0, 10), (1, 20), (2, 30); +set autocommit=0; +select * from t2; +update t2 set a=100 where b=(SELECT x from t1 where id = b FOR UPDATE); +select * from t2; +select * from t1; + +connection con2; +set autocommit=0; + +# The following query should hang because con1 is locking the page +--send +update t1 set x=2 where id = 0; +--sleep 2; + +connection con1; +update t1 set x=1 where id = 0; +select * from t1; +commit; + +connection con2; +reap; +commit; + +connection con1; +select * from t1; +commit; + +drop table t1, t2; +create table t1 (id integer, x integer) type=INNODB; +create table t2 (b integer, a integer) type=INNODB; +insert into t1 values(0, 0), (300, 300); +insert into t2 values(0, 0), (1, 20), (2, 30); +commit; + +connection con1; +select a,b from t2 UNION SELECT id, x from t1 FOR UPDATE; +select * from t2; +select * from t1; + +connection con2; + +# The following query should hang because con1 is locking the page +update t2 set a=2 where b = 0; +select * from t2; +--send +update t1 set x=2 where id = 0; +--sleep 2; + +connection con1; +update t1 set x=1 where id = 0; +select * from t1; +commit; + +connection con2; +reap; +commit; + +connection con1; +select * from t1; +commit; + +drop table t1, t2; \ No newline at end of file diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index df343714e55..70d50559df9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1690,17 +1690,14 @@ select_lock_type: | FOR_SYM UPDATE_SYM { LEX *lex=Lex; - if (check_simple_select()) - YYABORT; - lex->lock_option= TL_WRITE; + lex->current_select->set_lock_for_tables(TL_WRITE); lex->thd->safe_to_cache_query=0; } | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM { LEX *lex=Lex; - if (check_simple_select()) - YYABORT; - lex->lock_option= TL_READ_WITH_SHARED_LOCKS; + lex->current_select-> + set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS); lex->thd->safe_to_cache_query=0; } ;