From 392df76bc3a40a5dd1956b12628dd6489a37be36 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Thu, 23 Jul 2015 12:50:58 +0400 Subject: [PATCH] MDEV-4017 - GET_LOCK() with negative timeouts has strange behavior GET_LOCK() silently accepted negative values and NULL for timeout. Fixed GET_LOCK() to issue a warning and return NULL in such cases. --- .../binlog_tests/mix_innodb_myisam_binlog.test | 2 +- mysql-test/r/func_misc.result | 13 +++++++++++++ .../r/binlog_row_mix_innodb_myisam.result | 2 +- .../r/binlog_stm_mix_innodb_myisam.result | 4 ++-- mysql-test/t/func_misc.test | 5 +++++ sql/item_func.cc | 18 ++++++++++++++++++ 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test index b41bfeaba7467..336b11113ec3c 100644 --- a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test +++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test @@ -228,7 +228,7 @@ rollback; create table t0 (n int); insert t0 select * from t1; set autocommit=1; -insert into t0 select GET_LOCK("lock1",null); +insert into t0 select GET_LOCK("lock1",0); set autocommit=0; create table t2 (n int) engine=innodb; insert into t2 values (3); diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index d5db28f04b8c6..d654dbccb0e2b 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -361,5 +361,18 @@ set optimizer_switch=@optimizer_switch_save; drop view v_merge, vm; drop table t1,tv; # +# MDEV-4017 - GET_LOCK() with negative timeouts has strange behavior +# +SELECT GET_LOCK('ul1', NULL); +GET_LOCK('ul1', NULL) +NULL +Warnings: +Warning 1411 Incorrect timeout value: 'NULL' for function get_lock +SELECT GET_LOCK('ul1', -1); +GET_LOCK('ul1', -1) +NULL +Warnings: +Warning 1411 Incorrect timeout value: '-1' for function get_lock +# # End of 5.5 tests # diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result index ac36412c360fd..ed6e711af6b7b 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result @@ -258,7 +258,7 @@ Warning 1196 Some non-transactional changed tables couldn't be rolled back create table t0 (n int); insert t0 select * from t1; set autocommit=1; -insert into t0 select GET_LOCK("lock1",null); +insert into t0 select GET_LOCK("lock1",0); set autocommit=0; create table t2 (n int) engine=innodb; insert into t2 values (3); diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result index c10aa7abd0500..7309c611d298c 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result @@ -242,7 +242,7 @@ Warning 1196 Some non-transactional changed tables couldn't be rolled back create table t0 (n int); insert t0 select * from t1; set autocommit=1; -insert into t0 select GET_LOCK("lock1",null); +insert into t0 select GET_LOCK("lock1",0); Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave. set autocommit=0; @@ -288,7 +288,7 @@ master-bin.000001 # Query # # BEGIN master-bin.000001 # Query # # use `test`; insert t0 select * from t1 master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `test`; insert into t0 select GET_LOCK("lock1",null) +master-bin.000001 # Query # # use `test`; insert into t0 select GET_LOCK("lock1",0) master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; create table t2 (n int) engine=innodb master-bin.000001 # Query # # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `t1`,`ti` diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 24fe1ef79844f..25d8cc1067ac6 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -391,6 +391,11 @@ set optimizer_switch=@optimizer_switch_save; drop view v_merge, vm; drop table t1,tv; +--echo # +--echo # MDEV-4017 - GET_LOCK() with negative timeouts has strange behavior +--echo # +SELECT GET_LOCK('ul1', NULL); +SELECT GET_LOCK('ul1', -1); --echo # --echo # End of 5.5 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index ed08555133f6d..2f5130886e69a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4184,7 +4184,25 @@ longlong Item_func_get_lock::val_int() it's not guaranteed to be same as on master. */ if (thd->slave_thread) + { + null_value= 0; DBUG_RETURN(1); + } + + if (args[1]->null_value || + (!args[1]->unsigned_flag && ((longlong) timeout < 0))) + { + char buf[22]; + if (args[1]->null_value) + strmov(buf, "NULL"); + else + llstr(((longlong) timeout), buf); + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE), + "timeout", buf, "get_lock"); + null_value= 1; + DBUG_RETURN(0); + } mysql_mutex_lock(&LOCK_user_locks);