From 8164bd24a611ee2682ff0ba922fd0da526f75f14 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 21 May 2019 14:22:49 +0400 Subject: [PATCH] MDEV-19535 sql_mode=ORACLE: 'SELECT INTO @var FOR UPDATE' does not lock the table --- .../compat/oracle/r/update_innodb.result | 26 +++++++++++++++++ .../suite/compat/oracle/t/update_innodb.test | 28 +++++++++++++++++++ sql/sql_lex.cc | 6 ++++ sql/sql_lex.h | 1 + sql/sql_yacc.yy | 8 ++---- sql/sql_yacc_ora.yy | 4 +-- 6 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 mysql-test/suite/compat/oracle/r/update_innodb.result create mode 100644 mysql-test/suite/compat/oracle/t/update_innodb.test diff --git a/mysql-test/suite/compat/oracle/r/update_innodb.result b/mysql-test/suite/compat/oracle/r/update_innodb.result new file mode 100644 index 00000000000..1dae643eeff --- /dev/null +++ b/mysql-test/suite/compat/oracle/r/update_innodb.result @@ -0,0 +1,26 @@ +# +# MDEV-19535 sql_mode=ORACLE: 'SELECT INTO @var FOR UPDATE' does not lock the table +# +SET sql_mode='ORACLE'; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) engine=innodb; +INSERT INTO t1 VALUES (1); +START TRANSACTION; +SELECT a AS a_con1 FROM t1 INTO @a FOR UPDATE; +Warnings: +Warning 1287 ' INTO FROM...' instead +connect con2,localhost,root,,; +SET sql_mode='ORACLE'; +START TRANSACTION; +SELECT a AS a_con2 FROM t1 INTO @a FOR UPDATE;; +connection default; +UPDATE t1 SET a=a+100; +COMMIT; +connection con2; +Warnings: +Warning 1287 ' INTO FROM...' instead +SELECT a AS con2 FROM t1; +con2 +101 +COMMIT; +connection default; +DROP TABLE t1; diff --git a/mysql-test/suite/compat/oracle/t/update_innodb.test b/mysql-test/suite/compat/oracle/t/update_innodb.test new file mode 100644 index 00000000000..8af219584d6 --- /dev/null +++ b/mysql-test/suite/compat/oracle/t/update_innodb.test @@ -0,0 +1,28 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-19535 sql_mode=ORACLE: 'SELECT INTO @var FOR UPDATE' does not lock the table +--echo # + +SET sql_mode='ORACLE'; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY) engine=innodb; +INSERT INTO t1 VALUES (1); +START TRANSACTION; +SELECT a AS a_con1 FROM t1 INTO @a FOR UPDATE; + +--connect(con2,localhost,root,,) +SET sql_mode='ORACLE'; +START TRANSACTION; +--send SELECT a AS a_con2 FROM t1 INTO @a FOR UPDATE; + +--connection default +UPDATE t1 SET a=a+100; +COMMIT; + +--connection con2 +--reap +SELECT a AS con2 FROM t1; +COMMIT; + +--connection default +DROP TABLE t1; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index adc9c6c752b..67bc8b31a98 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -9470,6 +9470,12 @@ bool LEX::select_finalize(st_select_lex_unit *expr) } +bool LEX::select_finalize(st_select_lex_unit *expr, Lex_select_lock l) +{ + return expr->set_lock_to_the_last_select(l) || + select_finalize(expr); +} + /* "IN" and "EXISTS" subselect can appear in two statement types: diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 7a56ce55297..b205207f64d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -4452,6 +4452,7 @@ public: LEX_CSTRING *alias); bool parsed_create_view(SELECT_LEX_UNIT *unit, int check); bool select_finalize(st_select_lex_unit *expr); + bool select_finalize(st_select_lex_unit *expr, Lex_select_lock l); void relink_hack(st_select_lex *select_lex); bool stmt_install_plugin(const DDL_options_st &opt, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 08f9c4b4117..54ec7e95906 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -9122,9 +9122,7 @@ select: opt_procedure_or_into { Lex->pop_select(); - if ($1->set_lock_to_the_last_select($3)) - MYSQL_YYABORT; - if (Lex->select_finalize($1)) + if (Lex->select_finalize($1, $3)) MYSQL_YYABORT; } | with_clause query_expression_body @@ -9139,9 +9137,7 @@ select: Lex->pop_select(); $2->set_with_clause($1); $1->attach_to($2->first_select()); - if ($2->set_lock_to_the_last_select($4)) - MYSQL_YYABORT; - if (Lex->select_finalize($2)) + if (Lex->select_finalize($2, $4)) MYSQL_YYABORT; } ; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 1537adaaaf3..89538884d2b 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -9239,7 +9239,7 @@ select: opt_procedure_or_into { Lex->pop_select(); - if (Lex->select_finalize($1)) + if (Lex->select_finalize($1, $3)) MYSQL_YYABORT; } | with_clause query_expression_body @@ -9254,7 +9254,7 @@ select: Lex->pop_select(); $2->set_with_clause($1); $1->attach_to($2->first_select()); - if (Lex->select_finalize($2)) + if (Lex->select_finalize($2, $4)) MYSQL_YYABORT; } ;