summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/timeout.result67
-rw-r--r--mysql-test/suite/innodb/r/innodb-timeout.result60
-rw-r--r--mysql-test/suite/innodb/t/innodb-timeout.test83
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result4
-rw-r--r--mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result16
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_innodb.result2
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded.result2
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result2
-rw-r--r--mysql-test/t/timeout.test60
-rw-r--r--sql/lex.h1
-rw-r--r--sql/mdl.cc8
-rw-r--r--sql/sql_lex.cc30
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_plugin.cc3
-rw-r--r--sql/sql_prepare.cc2
-rw-r--r--sql/sql_yacc.yy47
-rw-r--r--sql/sys_vars.cc2
-rw-r--r--sql/table.h3
-rw-r--r--storage/innobase/handler/ha_innodb.cc2
-rw-r--r--storage/innobase/include/lock0lock.h26
-rw-r--r--storage/innobase/lock/lock0lock.cc15
-rw-r--r--storage/innobase/srv/srv0srv.cc5
22 files changed, 369 insertions, 73 deletions
diff --git a/mysql-test/r/timeout.result b/mysql-test/r/timeout.result
new file mode 100644
index 00000000000..8d1ca137043
--- /dev/null
+++ b/mysql-test/r/timeout.result
@@ -0,0 +1,67 @@
+#
+# MDEV-11379 - AliSQL: [Feature] Issue#8: SELECT FOR UPDATE WAIT
+# MDEV-11388 - AliSQL: [Feature] Issue#15 DDL FAST FAIL
+#
+CREATE TABLE t1(a INT, b TEXT, c MULTIPOLYGON NOT NULL);
+CREATE INDEX i1 ON t1(a) WAIT 1;
+CREATE FULLTEXT INDEX i2 ON t1(b) WAIT 1;
+CREATE SPATIAL INDEX i3 ON t1(c) WAIT 1;
+ALTER TABLE t1 WAIT 1 COMMENT='test';
+OPTIMIZE TABLE t1 WAIT 1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+DROP INDEX i1 ON t1 WAIT 1;
+TRUNCATE TABLE t1 WAIT 1;
+RENAME TABLE t1 WAIT 1 TO t2;
+RENAME TABLE t2 NOWAIT TO t1;
+connect con1, localhost, root,,;
+LOCK TABLE t1 WRITE WAIT 31536001;
+Warnings:
+Warning 1292 Truncated incorrect lock_wait_timeout value: '31536001'
+connection default;
+CREATE INDEX i1 ON t1(a) WAIT 0;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+CREATE INDEX i1 ON t1(a) NOWAIT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+CREATE FULLTEXT INDEX i2 ON t1(b) WAIT 0;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+CREATE FULLTEXT INDEX i2 ON t1(b) NOWAIT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+CREATE SPATIAL INDEX i3 ON t1(c) WAIT 0;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+CREATE SPATIAL INDEX i3 ON t1(c) NOWAIT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ALTER TABLE t1 WAIT 0 COMMENT='test';
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ALTER TABLE t1 NOWAIT COMMENT='test';
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+OPTIMIZE TABLE t1 WAIT 0;
+Table Op Msg_type Msg_text
+test.t1 optimize Error Lock wait timeout exceeded; try restarting transaction
+test.t1 optimize status Operation failed
+OPTIMIZE TABLE t1 NOWAIT;
+Table Op Msg_type Msg_text
+test.t1 optimize Error Lock wait timeout exceeded; try restarting transaction
+test.t1 optimize status Operation failed
+DROP INDEX i1 ON t1 WAIT 0;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+DROP INDEX i1 ON t1 NOWAIT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+TRUNCATE TABLE t1 WAIT 0;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+TRUNCATE TABLE t1 NOWAIT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+RENAME TABLE t1 WAIT 0 TO t2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+RENAME TABLE t1 NOWAIT TO t2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+DROP TABLE t1 WAIT 0;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+DROP TABLE t1 NOWAIT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+LOCK TABLE t1 WRITE WAIT 0;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+LOCK TABLE t1 WRITE NOWAIT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+disconnect con1;
+DROP TABLE t1 WAIT 1;
diff --git a/mysql-test/suite/innodb/r/innodb-timeout.result b/mysql-test/suite/innodb/r/innodb-timeout.result
index f252ebac314..52ed1a6f9b4 100644
--- a/mysql-test/suite/innodb/r/innodb-timeout.result
+++ b/mysql-test/suite/innodb/r/innodb-timeout.result
@@ -57,3 +57,63 @@ disconnect a;
connection default;
drop table t1;
set global innodb_lock_wait_timeout=<initial_timeout>;
+#
+# MDEV-11379 - AliSQL: [Feature] Issue#8: SELECT FOR UPDATE WAIT
+#
+CREATE TABLE t1 (c1 INT, c2 INT) ENGINE=InnoDB;
+INSERT INTO t1 (c1,c2) values (1,1),(2,2),(3,3),(4,4);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT;
+ERROR HY000: View's SELECT contains a '[NO]WAIT' clause
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0;
+ERROR HY000: View's SELECT contains a '[NO]WAIT' clause
+CREATE PROCEDURE p1() SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT;
+ERROR 0A000: [NO]WAIT is not allowed in stored procedures
+CREATE PROCEDURE p1() SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0;
+ERROR 0A000: [NO]WAIT is not allowed in stored procedures
+connect con1,localhost,root,,;
+LOCK TABLE t1 WRITE;
+connect con2,localhost,root,,;
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+PREPARE stmt FROM 'SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT';
+EXECUTE stmt;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+DEALLOCATE PREPARE stmt;
+PREPARE stmt FROM 'SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0';
+EXECUTE stmt;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+DEALLOCATE PREPARE stmt;
+connection con1;
+INSERT INTO t1 VALUES(5,5);
+UNLOCK TABLES;
+set AUTOCOMMIT=0;
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE;
+connection con2;
+set AUTOCOMMIT=0;
+SET INNODB_LOCK_WAIT_TIMEOUT=1;
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection con1;
+UPDATE t1 SET c2=5 WHERE c1=4;
+COMMIT;
+set AUTOCOMMIT=0;
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE;
+c1 c2
+4 5
+connection con2;
+set AUTOCOMMIT=0;
+SET INNODB_LOCK_WAIT_TIMEOUT=1;
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 10;
+connection con1;
+COMMIT;
+connection con2;
+disconnect con1;
+disconnect con2;
+connection default;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb-timeout.test b/mysql-test/suite/innodb/t/innodb-timeout.test
index 0beeea8f39e..0f8bbbec559 100644
--- a/mysql-test/suite/innodb/t/innodb-timeout.test
+++ b/mysql-test/suite/innodb/t/innodb-timeout.test
@@ -1,3 +1,5 @@
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
--source include/have_innodb.inc
let $initial_timeout=`select @@innodb_lock_wait_timeout`;
@@ -115,3 +117,84 @@ connection default;
drop table t1;
--replace_result $initial_timeout <initial_timeout>
eval set global innodb_lock_wait_timeout=$initial_timeout;
+
+--echo #
+--echo # MDEV-11379 - AliSQL: [Feature] Issue#8: SELECT FOR UPDATE WAIT
+--echo #
+CREATE TABLE t1 (c1 INT, c2 INT) ENGINE=InnoDB;
+INSERT INTO t1 (c1,c2) values (1,1),(2,2),(3,3),(4,4);
+
+# Not supported in view/sp
+--error ER_VIEW_SELECT_CLAUSE
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT;
+--error ER_VIEW_SELECT_CLAUSE
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0;
+--error ER_SP_BADSTATEMENT
+CREATE PROCEDURE p1() SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT;
+--error ER_SP_BADSTATEMENT
+CREATE PROCEDURE p1() SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0;
+
+connect(con1,localhost,root,,);
+LOCK TABLE t1 WRITE;
+
+connect(con2,localhost,root,,);
+# The following statement should hang because con1 is locking the table
+--error ER_LOCK_WAIT_TIMEOUT
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT;
+--error ER_LOCK_WAIT_TIMEOUT
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0;
+PREPARE stmt FROM 'SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT';
+--error ER_LOCK_WAIT_TIMEOUT
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+PREPARE stmt FROM 'SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0';
+--error ER_LOCK_WAIT_TIMEOUT
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+connection con1;
+INSERT INTO t1 VALUES(5,5);
+UNLOCK TABLES;
+set AUTOCOMMIT=0;
+--disable_result_log
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE;
+--enable_result_log
+
+connection con2;
+set AUTOCOMMIT=0;
+SET INNODB_LOCK_WAIT_TIMEOUT=1;
+--error ER_LOCK_WAIT_TIMEOUT
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE;
+--error ER_LOCK_WAIT_TIMEOUT
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE NOWAIT;
+--error ER_LOCK_WAIT_TIMEOUT
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 0;
+
+connection con1;
+UPDATE t1 SET c2=5 WHERE c1=4;
+COMMIT;
+set AUTOCOMMIT=0;
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE;
+
+connection con2;
+set AUTOCOMMIT=0;
+SET INNODB_LOCK_WAIT_TIMEOUT=1;
+--send
+--disable_result_log
+SELECT * FROM t1 WHERE c1=4 FOR UPDATE WAIT 10;
+
+connection con1;
+COMMIT;
+
+connection con2;
+--reap
+
+
+disconnect con1;
+disconnect con2;
+
+# clear
+connection default;
+DROP TABLE t1;
+
+--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result b/mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result
index 74b1d21d475..3218c096c2b 100644
--- a/mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_lock_wait_timeout_basic.result
@@ -99,7 +99,7 @@ Warnings:
Warning 1292 Truncated incorrect innodb_lock_wait_timeout value: '-1024'
SELECT @@global.innodb_lock_wait_timeout;
@@global.innodb_lock_wait_timeout
-1
+0
SET @@global.innodb_lock_wait_timeout=1073741825;
Warnings:
Warning 1292 Truncated incorrect innodb_lock_wait_timeout value: '1073741825'
@@ -131,7 +131,7 @@ Warnings:
Warning 1292 Truncated incorrect innodb_lock_wait_timeout value: '-1024'
SELECT @@session.innodb_lock_wait_timeout;
@@session.innodb_lock_wait_timeout
-1
+0
SET @@session.innodb_lock_wait_timeout=1073999999;
Warnings:
Warning 1292 Truncated incorrect innodb_lock_wait_timeout value: '1073999999'
diff --git a/mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result b/mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result
index bc127bf339a..f5d66b7c561 100644
--- a/mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result
+++ b/mysql-test/suite/sys_vars/r/lock_wait_timeout_basic.result
@@ -54,17 +54,15 @@ SELECT @@session.lock_wait_timeout;
65535
'#------------------FN_DYNVARS_002_05-----------------------#'
SET @@global.lock_wait_timeout = 0;
-Warnings:
-Warning 1292 Truncated incorrect lock_wait_timeout value: '0'
SELECT @@global.lock_wait_timeout;
@@global.lock_wait_timeout
-1
+0
SET @@global.lock_wait_timeout = -1024;
Warnings:
Warning 1292 Truncated incorrect lock_wait_timeout value: '-1024'
SELECT @@global.lock_wait_timeout;
@@global.lock_wait_timeout
-1
+0
SET @@global.lock_wait_timeout = 31536001;
Warnings:
Warning 1292 Truncated incorrect lock_wait_timeout value: '31536001'
@@ -87,17 +85,15 @@ SELECT @@global.lock_wait_timeout;
@@global.lock_wait_timeout
31536000
SET @@session.lock_wait_timeout = 0;
-Warnings:
-Warning 1292 Truncated incorrect lock_wait_timeout value: '0'
SELECT @@session.lock_wait_timeout;
@@session.lock_wait_timeout
-1
+0
SET @@session.lock_wait_timeout = -2;
Warnings:
Warning 1292 Truncated incorrect lock_wait_timeout value: '-2'
SELECT @@session.lock_wait_timeout;
@@session.lock_wait_timeout
-1
+0
SET @@session.lock_wait_timeout = 31537000;
Warnings:
Warning 1292 Truncated incorrect lock_wait_timeout value: '31537000'
@@ -137,11 +133,9 @@ SELECT @@global.lock_wait_timeout;
@@global.lock_wait_timeout
1
SET @@global.lock_wait_timeout = FALSE;
-Warnings:
-Warning 1292 Truncated incorrect lock_wait_timeout value: '0'
SELECT @@global.lock_wait_timeout;
@@global.lock_wait_timeout
-1
+0
'#---------------------FN_DYNVARS_001_09----------------------#'
SET @@global.lock_wait_timeout = 10;
SET @@session.lock_wait_timeout = 11;
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index 74ceb7e631c..48d39ed2a87 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -1386,7 +1386,7 @@ DEFAULT_VALUE 50
VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.
-NUMERIC_MIN_VALUE 1
+NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 1073741824
NUMERIC_BLOCK_SIZE 0
ENUM_VALUE_LIST NULL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
index 89a6d8448fc..7813391ad98 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -1599,7 +1599,7 @@ DEFAULT_VALUE 86400
VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Timeout in seconds to wait for a lock before returning an error.
-NUMERIC_MIN_VALUE 1
+NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 31536000
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index c4018b39a8f..a999112ab41 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -1725,7 +1725,7 @@ DEFAULT_VALUE 86400
VARIABLE_SCOPE SESSION
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Timeout in seconds to wait for a lock before returning an error.
-NUMERIC_MIN_VALUE 1
+NUMERIC_MIN_VALUE 0
NUMERIC_MAX_VALUE 31536000
NUMERIC_BLOCK_SIZE 1
ENUM_VALUE_LIST NULL
diff --git a/mysql-test/t/timeout.test b/mysql-test/t/timeout.test
new file mode 100644
index 00000000000..9f6e692b148
--- /dev/null
+++ b/mysql-test/t/timeout.test
@@ -0,0 +1,60 @@
+--echo #
+--echo # MDEV-11379 - AliSQL: [Feature] Issue#8: SELECT FOR UPDATE WAIT
+--echo # MDEV-11388 - AliSQL: [Feature] Issue#15 DDL FAST FAIL
+--echo #
+CREATE TABLE t1(a INT, b TEXT, c MULTIPOLYGON NOT NULL);
+CREATE INDEX i1 ON t1(a) WAIT 1;
+CREATE FULLTEXT INDEX i2 ON t1(b) WAIT 1;
+CREATE SPATIAL INDEX i3 ON t1(c) WAIT 1;
+ALTER TABLE t1 WAIT 1 COMMENT='test';
+OPTIMIZE TABLE t1 WAIT 1;
+DROP INDEX i1 ON t1 WAIT 1;
+TRUNCATE TABLE t1 WAIT 1;
+RENAME TABLE t1 WAIT 1 TO t2;
+RENAME TABLE t2 NOWAIT TO t1;
+
+connect(con1, localhost, root,,);
+LOCK TABLE t1 WRITE WAIT 31536001;
+
+connection default;
+--error ER_LOCK_WAIT_TIMEOUT
+CREATE INDEX i1 ON t1(a) WAIT 0;
+--error ER_LOCK_WAIT_TIMEOUT
+CREATE INDEX i1 ON t1(a) NOWAIT;
+--error ER_LOCK_WAIT_TIMEOUT
+CREATE FULLTEXT INDEX i2 ON t1(b) WAIT 0;
+--error ER_LOCK_WAIT_TIMEOUT
+CREATE FULLTEXT INDEX i2 ON t1(b) NOWAIT;
+--error ER_LOCK_WAIT_TIMEOUT
+CREATE SPATIAL INDEX i3 ON t1(c) WAIT 0;
+--error ER_LOCK_WAIT_TIMEOUT
+CREATE SPATIAL INDEX i3 ON t1(c) NOWAIT;
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 WAIT 0 COMMENT='test';
+--error ER_LOCK_WAIT_TIMEOUT
+ALTER TABLE t1 NOWAIT COMMENT='test';
+OPTIMIZE TABLE t1 WAIT 0;
+OPTIMIZE TABLE t1 NOWAIT;
+--error ER_LOCK_WAIT_TIMEOUT
+DROP INDEX i1 ON t1 WAIT 0;
+--error ER_LOCK_WAIT_TIMEOUT
+DROP INDEX i1 ON t1 NOWAIT;
+--error ER_LOCK_WAIT_TIMEOUT
+TRUNCATE TABLE t1 WAIT 0;
+--error ER_LOCK_WAIT_TIMEOUT
+TRUNCATE TABLE t1 NOWAIT;
+--error ER_LOCK_WAIT_TIMEOUT
+RENAME TABLE t1 WAIT 0 TO t2;
+--error ER_LOCK_WAIT_TIMEOUT
+RENAME TABLE t1 NOWAIT TO t2;
+--error ER_LOCK_WAIT_TIMEOUT
+DROP TABLE t1 WAIT 0;
+--error ER_LOCK_WAIT_TIMEOUT
+DROP TABLE t1 NOWAIT;
+--error ER_LOCK_WAIT_TIMEOUT
+LOCK TABLE t1 WRITE WAIT 0;
+--error ER_LOCK_WAIT_TIMEOUT
+LOCK TABLE t1 WRITE NOWAIT;
+
+disconnect con1;
+DROP TABLE t1 WAIT 1;
diff --git a/sql/lex.h b/sql/lex.h
index 35c9e33d7d9..2e105eb89ec 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -409,6 +409,7 @@ static SYMBOL symbols[] = {
{ "NEXT", SYM(NEXT_SYM)},
{ "NO", SYM(NO_SYM)},
{ "NO_WAIT", SYM(NO_WAIT_SYM)},
+ { "NOWAIT", SYM(NOWAIT_SYM)},
{ "NODEGROUP", SYM(NODEGROUP_SYM)},
{ "NONE", SYM(NONE_SYM)},
{ "NOT", SYM(NOT_SYM)},
diff --git a/sql/mdl.cc b/sql/mdl.cc
index c05fdc0157b..e453ad956eb 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -2086,6 +2086,14 @@ MDL_context::acquire_lock(MDL_request *mdl_request, double lock_wait_timeout)
*/
lock= ticket->m_lock;
+ if (lock_wait_timeout == 0)
+ {
+ mysql_prlock_unlock(&lock->m_rwlock);
+ MDL_ticket::destroy(ticket);
+ my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
+ DBUG_RETURN(TRUE);
+ }
+
lock->m_waiting.add_ticket(ticket);
/*
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 24c08f1985a..0df25e5ec27 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -5334,3 +5334,33 @@ Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond,
}
return 0;
}
+
+
+int set_statement_var_if_exists(THD *thd, const char *var_name,
+ size_t var_name_length, ulonglong value)
+{
+ sys_var *sysvar;
+ if (thd->lex->sql_command == SQLCOM_CREATE_VIEW)
+ {
+ my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "[NO]WAIT");
+ return 1;
+ }
+ if (thd->lex->sphead)
+ {
+ my_error(ER_SP_BADSTATEMENT, MYF(0), "[NO]WAIT");
+ return 1;
+ }
+ if ((sysvar= find_sys_var_ex(thd, var_name, var_name_length, true, false)))
+ {
+ Item *item= new (thd->mem_root) Item_uint(thd, value);
+ set_var *var= new (thd->mem_root) set_var(thd, OPT_SESSION, sysvar,
+ &null_lex_str, item);
+
+ if (!item || !var || thd->lex->stmt_var_list.push_back(var, thd->mem_root))
+ {
+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
+ return 1;
+ }
+ }
+ return 0;
+}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index e2c6f4aaaaf..0f52b84bffd 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -3351,6 +3351,8 @@ extern bool is_lex_native_function(const LEX_STRING *name);
void my_missing_function_error(const LEX_STRING &token, const char *name);
bool is_keyword(const char *name, uint len);
+int set_statement_var_if_exists(THD *thd, const char *var_name,
+ size_t var_name_length, ulonglong value);
#endif /* MYSQL_SERVER */
#endif /* SQL_LEX_INCLUDED */
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index aea83f41527..438834284e6 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -2813,7 +2813,8 @@ sys_var *find_sys_var_ex(THD *thd, const char *str, size_t length,
mysql_mutex_unlock(&LOCK_plugin);
if (!throw_error && !var)
- my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (int)length, (char*) str);
+ my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0),
+ (int) (length ? length : strlen(str)), (char*) str);
DBUG_RETURN(var);
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 303460a5fb4..e99cf15f447 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -3701,7 +3701,7 @@ void Prepared_statement::cleanup_stmt()
{
DBUG_ENTER("Prepared_statement::cleanup_stmt");
DBUG_PRINT("enter",("stmt: 0x%lx", (long) this));
- thd->restore_set_statement_var();
+ lex->restore_set_statement_var();
cleanup_items(free_list);
thd->cleanup_after_query();
thd->rollback_item_tree_changes();
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index e0739ea848e..56ec7139c9d 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1407,6 +1407,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token NOW_SYM
%token NO_SYM /* SQL-2003-R */
%token NO_WAIT_SYM
+%token NOWAIT_SYM
%token NO_WRITE_TO_BINLOG
%token NTILE_SYM
%token NULL_SYM /* SQL-2003-R */
@@ -1982,7 +1983,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
parse_vcol_expr vcol_opt_specifier vcol_opt_attribute
vcol_opt_attribute_list vcol_attribute
opt_serial_attribute opt_serial_attribute_list serial_attribute
- explainable_command
+ explainable_command opt_lock_wait_timeout
END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@@ -2565,7 +2566,7 @@ create:
if (Lex->add_create_index($2, $5, $6, $1 | $4))
MYSQL_YYABORT;
}
- '(' key_list ')' normal_key_options
+ '(' key_list ')' opt_lock_wait_timeout normal_key_options
opt_index_lock_algorithm { }
| create_or_replace fulltext INDEX_SYM opt_if_not_exists ident
ON table_ident
@@ -2575,7 +2576,7 @@ create:
if (Lex->add_create_index($2, $5, HA_KEY_ALG_UNDEF, $1 | $4))
MYSQL_YYABORT;
}
- '(' key_list ')' fulltext_key_options
+ '(' key_list ')' opt_lock_wait_timeout fulltext_key_options
opt_index_lock_algorithm { }
| create_or_replace spatial INDEX_SYM opt_if_not_exists ident
ON table_ident
@@ -2585,7 +2586,7 @@ create:
if (Lex->add_create_index($2, $5, HA_KEY_ALG_UNDEF, $1 | $4))
MYSQL_YYABORT;
}
- '(' key_list ')' spatial_key_options
+ '(' key_list ')' opt_lock_wait_timeout spatial_key_options
opt_index_lock_algorithm { }
| create_or_replace DATABASE opt_if_not_exists ident
{
@@ -7131,7 +7132,7 @@ alter:
Lex->create_info.storage_media= HA_SM_DEFAULT;
DBUG_ASSERT(!Lex->m_sql_cmd);
}
- alter_options TABLE_SYM table_ident
+ alter_options TABLE_SYM table_ident opt_lock_wait_timeout
{
if (!Lex->select_lex.add_table_to_list(thd, $5, NULL,
TL_OPTION_UPDATING,
@@ -8221,7 +8222,7 @@ optimize:
/* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
}
- table_list
+ table_list opt_lock_wait_timeout
{
LEX* lex= thd->lex;
DBUG_ASSERT(!lex->m_sql_cmd);
@@ -8271,13 +8272,13 @@ table_to_table_list:
;
table_to_table:
- table_ident TO_SYM table_ident
+ table_ident opt_lock_wait_timeout TO_SYM table_ident
{
LEX *lex=Lex;
SELECT_LEX *sl= lex->current_select;
if (!sl->add_table_to_list(thd, $1,NULL,TL_OPTION_UPDATING,
TL_IGNORE, MDL_EXCLUSIVE) ||
- !sl->add_table_to_list(thd, $3,NULL,TL_OPTION_UPDATING,
+ !sl->add_table_to_list(thd, $4, NULL, TL_OPTION_UPDATING,
TL_IGNORE, MDL_EXCLUSIVE))
MYSQL_YYABORT;
}
@@ -8684,14 +8685,14 @@ select_option:
opt_select_lock_type:
/* empty */
- | FOR_SYM UPDATE_SYM
+ | FOR_SYM UPDATE_SYM opt_lock_wait_timeout
{
LEX *lex=Lex;
lex->current_select->lock_type= TL_WRITE;
lex->current_select->set_lock_for_tables(TL_WRITE);
lex->safe_to_cache_query=0;
}
- | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
+ | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM opt_lock_wait_timeout
{
LEX *lex=Lex;
lex->current_select->lock_type= TL_READ_WITH_SHARED_LOCKS;
@@ -12118,9 +12119,9 @@ drop:
YYPS->m_lock_type= TL_UNLOCK;
YYPS->m_mdl_type= MDL_EXCLUSIVE;
}
- table_list opt_restrict
+ table_list opt_lock_wait_timeout opt_restrict
{}
- | DROP INDEX_SYM opt_if_exists_table_element ident ON table_ident {}
+ | DROP INDEX_SYM opt_if_exists_table_element ident ON table_ident opt_lock_wait_timeout
{
LEX *lex=Lex;
Alter_drop *ad= (new (thd->mem_root)
@@ -12686,7 +12687,7 @@ truncate:
YYPS->m_lock_type= TL_WRITE;
YYPS->m_mdl_type= MDL_EXCLUSIVE;
}
- table_name
+ table_name opt_lock_wait_timeout
{
LEX* lex= thd->lex;
DBUG_ASSERT(!lex->m_sql_cmd);
@@ -14794,6 +14795,7 @@ keyword_sp:
| NEXT_SYM {}
| NEW_SYM {}
| NO_WAIT_SYM {}
+ | NOWAIT_SYM {}
| NODEGROUP_SYM {}
| NONE_SYM {}
| NUMBER_SYM {}
@@ -15444,10 +15446,27 @@ lock:
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "LOCK"));
lex->sql_command= SQLCOM_LOCK_TABLES;
}
- table_lock_list
+ table_lock_list opt_lock_wait_timeout
{}
;
+opt_lock_wait_timeout:
+ /* empty */
+ {}
+ | WAIT_SYM ulong_num
+ {
+ if (set_statement_var_if_exists(thd, C_STRING_WITH_LEN("lock_wait_timeout"), $2) ||
+ set_statement_var_if_exists(thd, C_STRING_WITH_LEN("innodb_lock_wait_timeout"), $2))
+ MYSQL_YYABORT;
+ }
+ | NOWAIT_SYM
+ {
+ if (set_statement_var_if_exists(thd, C_STRING_WITH_LEN("lock_wait_timeout"), 0) ||
+ set_statement_var_if_exists(thd, C_STRING_WITH_LEN("innodb_lock_wait_timeout"), 0))
+ MYSQL_YYABORT;
+ }
+ ;
+
table_or_tables:
TABLE_SYM { }
| TABLES { }
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 9a9e920c6dd..2608b665ae6 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1145,7 +1145,7 @@ static Sys_var_ulong Sys_lock_wait_timeout(
"lock_wait_timeout",
"Timeout in seconds to wait for a lock before returning an error.",
SESSION_VAR(lock_wait_timeout), CMD_LINE(REQUIRED_ARG),
- VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(24 * 60 * 60), BLOCK_SIZE(1));
+ VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(24 * 60 * 60), BLOCK_SIZE(1));
#ifdef HAVE_MLOCKALL
static Sys_var_mybool Sys_locked_in_memory(
diff --git a/sql/table.h b/sql/table.h
index a94fcef2316..655177e703a 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -2078,9 +2078,6 @@ struct TABLE_LIST
/* Don't associate a table share. */
OPEN_STUB
} open_strategy;
- /* For transactional locking. */
- int lock_timeout; /* NOWAIT or WAIT [X] */
- bool lock_transactional; /* If transactional lock requested. */
/** TRUE if an alias for this table was specified in the SQL. */
bool is_alias;
/** TRUE if the table is referred to in the statement using a fully
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 4a3cdb8af6b..7385de8a0d7 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -905,7 +905,7 @@ static MYSQL_THDVAR_BOOL(ft_enable_stopword, PLUGIN_VAR_OPCMDARG,
static MYSQL_THDVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
"Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back. Values above 100000000 disable the timeout.",
- NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
+ NULL, NULL, 50, 0, 1024 * 1024 * 1024, 0);
static MYSQL_THDVAR_STR(ft_user_stopword_table,
PLUGIN_VAR_OPCMDARG|PLUGIN_VAR_MEMALLOC,
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index b211b24d7ff..f3f1f39d1a6 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -299,32 +299,6 @@ lock_rec_insert_check_and_lock(
record */
MY_ATTRIBUTE((warn_unused_result));
-/*********************************************************************//**
-Enqueues a waiting request for a lock which cannot be granted immediately.
-Checks for deadlocks.
-@return DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED, or
-DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that
-there was a deadlock, but another transaction was chosen as a victim,
-and we got the lock immediately: no need to wait then */
-dberr_t
-lock_rec_enqueue_waiting(
-/*=====================*/
- ulint type_mode,/*!< in: lock mode this
- transaction is requesting:
- LOCK_S or LOCK_X, possibly
- ORed with LOCK_GAP or
- LOCK_REC_NOT_GAP, ORed with
- LOCK_INSERT_INTENTION if this
- waiting lock request is set
- when performing an insert of
- an index record */
- const buf_block_t* block, /*!< in: buffer block containing
- the record */
- ulint heap_no,/*!< in: heap number of the record */
- dict_index_t* index, /*!< in: index of record */
- que_thr_t* thr, /*!< in: query thread */
- lock_prdt_t* prdt); /*!< in: Minimum Bounding Box */
-
/*************************************************************//**
Removes a record lock request, waiting or granted, from the queue and
grants locks to other transactions in the queue if they now are entitled
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 11c1bedd39a..7e70e9a846b 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -2232,11 +2232,11 @@ queue is itself waiting roll it back, also do a deadlock check and resolve.
@param[in, out] wait_for The lock that the joining transaction is
waiting for
@param[in] prdt Predicate [optional]
-@return DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED, or
- DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that
- there was a deadlock, but another transaction was chosen
- as a victim, and we got the lock immediately: no need to
- wait then */
+@return DB_LOCK_WAIT, DB_LOCK_WAIT_TIMEOUT, DB_DEADLOCK, or
+ DB_QUE_THR_SUSPENDED, or DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC
+ means that there was a deadlock, but another transaction was chosen
+ as a victim, and we got the lock immediately: no need to wait then;
+ DB_LOCK_WAIT_TIMEOUT means no need to wait */
dberr_t
RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt)
{
@@ -2244,6 +2244,11 @@ RecLock::add_to_waitq(const lock_t* wait_for, const lock_prdt_t* prdt)
ut_ad(m_trx == thr_get_trx(m_thr));
ut_ad(trx_mutex_own(m_trx));
+ if (m_trx->mysql_thd && thd_lock_wait_timeout(m_trx->mysql_thd) == 0) {
+ m_trx->error_state = DB_LOCK_WAIT_TIMEOUT;
+ return(DB_LOCK_WAIT_TIMEOUT);
+ }
+
DEBUG_SYNC_C("rec_lock_add_to_waitq");
m_mode |= LOCK_WAIT;
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 9794146460b..d8de29a909d 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -536,11 +536,6 @@ UNIV_INTERN ulong srv_buf_dump_status_frequency = 0;
mutex_exit(&srv_sys->mutex); \
} while (0)
-#define fetch_lock_wait_timeout(trx) \
- ((trx)->lock.allowed_to_wait \
- ? thd_lock_wait_timeout((trx)->mysql_thd) \
- : 0)
-
/*
IMPLEMENTATION OF THE SERVER MAIN PROGRAM
=========================================