summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/innodb.result55
-rw-r--r--mysql-test/t/innodb.test57
-rw-r--r--sql/ha_berkeley.cc2
-rw-r--r--sql/ha_berkeley.h2
-rw-r--r--sql/ha_innodb.cc5
-rw-r--r--sql/ha_innodb.h2
-rw-r--r--sql/ha_ndbcluster.cc2
-rw-r--r--sql/ha_ndbcluster.h2
-rw-r--r--sql/handler.h2
-rw-r--r--sql/sql_base.cc2
10 files changed, 91 insertions, 40 deletions
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 3fcdccceed6..f634d0fc98b 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -2616,31 +2616,50 @@ SET FOREIGN_KEY_CHECKS=1;
INSERT INTO t2 VALUES(3);
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
DROP TABLE t2;
-create table test_checksum(a int not null) engine=innodb DEFAULT CHARSET=latin1;
-insert into test_checksum values (1),(2);
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
set autocommit=0;
-checksum table test_checksum;
+checksum table t1;
Table Checksum
-test.test_checksum 1531596814
-insert into test_checksum values(3);
-checksum table test_checksum;
+test.t1 1531596814
+insert into t1 values(3);
+checksum table t1;
Table Checksum
-test.test_checksum 2605035534
+test.t1 2605035534
commit;
-checksum table test_checksum;
+checksum table t1;
Table Checksum
-test.test_checksum 127268899
+test.t1 127268899
commit;
-drop table test_checksum;
-create table test_checksum(a int not null) engine=innodb DEFAULT CHARSET=latin1;
-insert into test_checksum values (1),(2);
+drop table t1;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
set autocommit=1;
-checksum table test_checksum;
+checksum table t1;
Table Checksum
-test.test_checksum 1531596814
+test.t1 1531596814
set autocommit=1;
-insert into test_checksum values(3);
-checksum table test_checksum;
+insert into t1 values(3);
+checksum table t1;
Table Checksum
-test.test_checksum 127268899
-drop table test_checksum;
+test.t1 127268899
+drop table t1;
+create table t1 (col1 integer primary key, col2 integer) engine=innodb;
+insert t1 values (1,100);
+create function f1 () returns integer begin
+declare var1 int;
+select col2 into var1 from t1 where col1=1 for update;
+return var1;
+end|
+start transaction;
+select f1();
+f1()
+100
+ update t1 set col2=0 where col1=1;
+select * from t1;
+col1 col2
+1 100
+rollback;
+rollback;
+drop table t1;
+drop function f1;
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 7d4e15163ef..5a45b3524ac 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -1571,36 +1571,67 @@ DROP TABLE t2;
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
-create table test_checksum(a int not null) engine=innodb DEFAULT CHARSET=latin1;
-insert into test_checksum values (1),(2);
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
set autocommit=0;
-checksum table test_checksum;
+checksum table t1;
connection b;
-insert into test_checksum values(3);
+insert into t1 values(3);
connection a;
#
# Here checksum should not see insert
#
-checksum table test_checksum;
+checksum table t1;
connection a;
commit;
-checksum table test_checksum;
+checksum table t1;
commit;
-drop table test_checksum;
+drop table t1;
#
# autocommit = 1
#
connection a;
-create table test_checksum(a int not null) engine=innodb DEFAULT CHARSET=latin1;
-insert into test_checksum values (1),(2);
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
set autocommit=1;
-checksum table test_checksum;
+checksum table t1;
connection b;
set autocommit=1;
-insert into test_checksum values(3);
+insert into t1 values(3);
connection a;
#
# Here checksum sees insert
#
-checksum table test_checksum;
-drop table test_checksum;
+checksum table t1;
+drop table t1;
+
+#
+# BUG#11238 - in prelocking mode SELECT .. FOR UPDATE is changed to
+# non-blocking SELECT
+#
+create table t1 (col1 integer primary key, col2 integer) engine=innodb;
+insert t1 values (1,100);
+delimiter |;
+create function f1 () returns integer begin
+declare var1 int;
+select col2 into var1 from t1 where col1=1 for update;
+return var1;
+end|
+delimiter ;|
+start transaction;
+select f1();
+connection b;
+send update t1 set col2=0 where col1=1;
+connection default;
+select * from t1;
+connection a;
+rollback;
+connection b;
+reap;
+rollback;
+connection default;
+drop table t1;
+drop function f1;
+disconnect a;
+disconnect b;
+
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 2f47b03de9d..a4c91c72368 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -1894,7 +1894,7 @@ int ha_berkeley::external_lock(THD *thd, int lock_type)
Under LOCK TABLES, each used tables will force a call to start_stmt.
*/
-int ha_berkeley::start_stmt(THD *thd)
+int ha_berkeley::start_stmt(THD *thd, thr_lock_type lock_type)
{
int error=0;
DBUG_ENTER("ha_berkeley::start_stmt");
diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h
index 282641e3f25..f291fd7a668 100644
--- a/sql/ha_berkeley.h
+++ b/sql/ha_berkeley.h
@@ -124,7 +124,7 @@ class ha_berkeley: public handler
int extra(enum ha_extra_function operation);
int reset(void);
int external_lock(THD *thd, int lock_type);
- int start_stmt(THD *thd);
+ int start_stmt(THD *thd, thr_lock_type lock_type);
void position(byte *record);
int analyze(THD* thd,HA_CHECK_OPT* check_opt);
int optimize(THD* thd, HA_CHECK_OPT* check_opt);
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index de458785534..b6737b3a991 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -6000,7 +6000,8 @@ int
ha_innobase::start_stmt(
/*====================*/
/* out: 0 or error code */
- THD* thd) /* in: handle to the user thread */
+ THD* thd, /* in: handle to the user thread */
+ thr_lock_type lock_type)
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
trx_t* trx;
@@ -6041,7 +6042,7 @@ ha_innobase::start_stmt(
} else {
if (trx->isolation_level != TRX_ISO_SERIALIZABLE
&& thd->lex->sql_command == SQLCOM_SELECT
- && thd->lex->lock_option == TL_READ) {
+ && lock_type == TL_READ) {
/* For other than temporary tables, we obtain
no lock for consistent read (plain SELECT). */
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index d3c7af432a0..0c2b6d0f71a 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -150,7 +150,7 @@ class ha_innobase: public handler
int extra(enum ha_extra_function operation);
int external_lock(THD *thd, int lock_type);
int transactional_table_lock(THD *thd, int lock_type);
- int start_stmt(THD *thd);
+ int start_stmt(THD *thd, thr_lock_type lock_type);
void position(byte *record);
ha_rows records_in_range(uint inx, key_range *min_key, key_range
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 709a7ed14e0..e22f0ecfbc2 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -3400,7 +3400,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
startTransaction for each transaction/statement.
*/
-int ha_ndbcluster::start_stmt(THD *thd)
+int ha_ndbcluster::start_stmt(THD *thd, thr_lock_type lock_type)
{
int error=0;
DBUG_ENTER("start_stmt");
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 2a1d51724d4..4bda78cf234 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -501,7 +501,7 @@ class ha_ndbcluster: public handler
int extra(enum ha_extra_function operation);
int extra_opt(enum ha_extra_function operation, ulong cache_size);
int external_lock(THD *thd, int lock_type);
- int start_stmt(THD *thd);
+ int start_stmt(THD *thd, thr_lock_type lock_type);
const char * table_type() const;
const char ** bas_ext() const;
ulong table_flags(void) const;
diff --git a/sql/handler.h b/sql/handler.h
index f4f6a8592bb..c3a61d696f7 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -647,7 +647,7 @@ public:
virtual int reset() { return extra(HA_EXTRA_RESET); }
virtual int external_lock(THD *thd, int lock_type) { return 0; }
virtual void unlock_row() {}
- virtual int start_stmt(THD *thd) {return 0;}
+ virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
/*
This is called to delete all rows in a table
If the handler don't support this, then this function will
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index bb14d22e493..7352940ee69 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2148,7 +2148,7 @@ static bool check_lock_and_start_stmt(THD *thd, TABLE *table,
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0),table->alias);
DBUG_RETURN(1);
}
- if ((error=table->file->start_stmt(thd)))
+ if ((error=table->file->start_stmt(thd, lock_type)))
{
table->file->print_error(error,MYF(0));
DBUG_RETURN(1);