mariadb/mysql-test/t/func_misc.test
Alexey Botchkov 1a600125ff MDEV-3917 multiple use locks (GET_LOCK) in one connection.
The patch contributed by Konstantin Osipov applied.
    Native comments:
      Implement multiple user-level locks per connection.

      GET_LOCK() function in MySQL allows a connection  to hold at most
      one user level lock. Taking a new lock automatically releases the
      old lock, if any.

      The limit of one lock per session existed since  early versions
      of MySQL didn't have a deadlock detector for SQL locks.
      MDL patches in MySQL 5.5 added a deadlock detector,
      so starting from 5.5 it became possible to take multiple locks
      in any order -- a deadlock, should it occur, would be detected
      and an error returned to the client which closed the wait chain.

      This is exactly what is done in this patch: ULLs are moved
      to use MDL subsystem.
2013-04-12 18:06:51 +05:00

554 lines
14 KiB
Text

#
# Testing of misc functions
#
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
select format(1.5555,0),format(123.5555,1),format(1234.5555,2),format(12345.55555,3),format(123456.5555,4),format(1234567.5555,5),format("12345.2399",2);
select inet_ntoa(inet_aton("255.255.255.255.255.255.255.255"));
select inet_aton("255.255.255.255.255"),inet_aton("255.255.1.255"),inet_aton("0.1.255");
select inet_ntoa(1099511627775),inet_ntoa(4294902271),inet_ntoa(511);
select hex(inet_aton('127'));
select hex(inet_aton('127.1'));
select hex(inet_aton('127.1.1'));
select length(uuid()), charset(uuid()), length(unhex(replace(uuid(),_utf8'-',_utf8'')));
# As we can assume we are the only user for the mysqld server, the difference
# between two calls should be -1
set @a= uuid_short();
set @b= uuid_short();
select @b - @a;
#
# Test for core dump with nan
#
select length(format('nan', 2)) > 0;
#
# Test for bug #628
#
select concat("$",format(2500,2));
# Test for BUG#7716
create table t1 ( a timestamp );
insert into t1 values ( '2004-01-06 12:34' );
select a from t1 where left(a+0,6) in ( left(20040106,6) );
select a from t1 where left(a+0,6) = ( left(20040106,6) );
select a from t1 where right(a+0,6) in ( right(20040106123400,6) );
select a from t1 where right(a+0,6) = ( right(20040106123400,6) );
select a from t1 where mid(a+0,6,3) in ( mid(20040106123400,6,3) );
select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) );
drop table t1;
#
# Bug#16501: IS_USED_LOCK does not appear to work
#
CREATE TABLE t1 (conn CHAR(7), connection_id INT);
INSERT INTO t1 VALUES ('default', CONNECTION_ID());
SELECT GET_LOCK('bug16501',600);
connect (con1,localhost,root,,);
INSERT INTO t1 VALUES ('con1', CONNECTION_ID());
SELECT IS_USED_LOCK('bug16501') = connection_id
FROM t1
WHERE conn = 'default';
send SELECT GET_LOCK('bug16501',600);
connection default;
SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID();
SELECT RELEASE_LOCK('bug16501');
connection con1;
reap;
connection default;
SELECT IS_USED_LOCK('bug16501') = connection_id
FROM t1
WHERE conn = 'con1';
connection con1;
SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID();
SELECT RELEASE_LOCK('bug16501');
SELECT IS_USED_LOCK('bug16501');
disconnect con1;
connection default;
DROP TABLE t1;
#
# Bug #21531: EXPORT_SET() doesn't accept args with coercible character sets
#
select export_set(3, _latin1'foo', _utf8'bar', ',', 4);
--echo End of 4.1 tests
#
# Test for BUG#9535
#
--disable_warnings
create table t1 as select uuid(), length(uuid());
--enable_warnings
show create table t1;
drop table t1;
#
# Bug #21466: INET_ATON() returns signed, not unsigned
#
create table t1 select INET_ATON('255.255.0.1') as `a`;
show create table t1;
drop table t1;
#
# Bug#26093 (SELECT BENCHMARK() for SELECT statements does not produce
# valid results)
#
--disable_warnings
drop table if exists table_26093;
drop function if exists func_26093_a;
drop function if exists func_26093_b;
--enable_warnings
create table table_26093(a int);
insert into table_26093 values
(1), (2), (3), (4), (5),
(6), (7), (8), (9), (10);
delimiter //;
create function func_26093_a(x int) returns int
begin
set @invoked := @invoked + 1;
return x;
end//
create function func_26093_b(x int, y int) returns int
begin
set @invoked := @invoked + 1;
return x;
end//
delimiter ;//
select avg(a) from table_26093;
select benchmark(100, (select avg(a) from table_26093));
set @invoked := 0;
select benchmark(100, (select avg(func_26093_a(a)) from table_26093));
# Returns only 10, since intermediate results are cached.
select @invoked;
set @invoked := 0;
select benchmark(100, (select avg(func_26093_b(a, rand())) from table_26093));
# Returns 1000, due to rand() preventing caching.
select @invoked;
--error ER_SUBQUERY_NO_1_ROW
select benchmark(100, (select (a) from table_26093));
--error ER_OPERAND_COLUMNS
select benchmark(100, (select 1, 1));
drop table table_26093;
drop function func_26093_a;
drop function func_26093_b;
#
# Bug #30832: Assertion + crash with select name_const('test',now());
#
--error ER_WRONG_ARGUMENTS
SELECT NAME_CONST('test', NOW());
--error ER_WRONG_ARGUMENTS
SELECT NAME_CONST('test', UPPER('test'));
SELECT NAME_CONST('test', NULL);
SELECT NAME_CONST('test', 1);
SELECT NAME_CONST('test', -1);
SELECT NAME_CONST('test', 1.0);
SELECT NAME_CONST('test', -1.0);
SELECT NAME_CONST('test', 'test');
#
# Bug #34749: Server crash when using NAME_CONST() with an aggregate function
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1),(2),(3);
# NAME_CONST() + aggregate.
SELECT NAME_CONST('flag',1) * MAX(a) FROM t1;
SELECT NAME_CONST('flag',1.5) * MAX(a) FROM t1;
# Now, wrap the INT_ITEM in Item_func_neg and watch the pretty explosions
SELECT NAME_CONST('flag',-1) * MAX(a) FROM t1;
SELECT NAME_CONST('flag',-1.5) * MAX(a) FROM t1;
--error ER_WRONG_ARGUMENTS
SELECT NAME_CONST('flag', SQRT(4)) * MAX(a) FROM t1;
--error ER_WRONG_ARGUMENTS
SELECT NAME_CONST('flag',-SQRT(4)) * MAX(a) FROM t1;
DROP TABLE t1;
#
# Bug #27545: erroneous usage of NAME_CONST with a name as the first parameter
# resolved against a column name of a derived table hangs the client
#
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (5), (2);
--error ER_WRONG_ARGUMENTS
SELECT NAME_CONST(x,2) FROM (SELECT a x FROM t1) t;
DROP TABLE t1;
#
# Bug #32559: connection hangs on query with name_const
#
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (), (), ();
--error ER_WRONG_ARGUMENTS
SELECT NAME_CONST(a, '1') FROM t1;
--error ER_WRONG_ARGUMENTS
SET INSERT_ID= NAME_CONST(a, a);
DROP TABLE t1;
#
# Bug #31349: ERROR 1062 (23000): Duplicate entry '' for key 'group_key'
#
create table t1 (a int not null);
insert into t1 values (-1), (-2);
select min(a) from t1 group by inet_ntoa(a);
drop table t1;
#
# BUG#34289 - Incorrect NAME_CONST substitution in stored procedures breaks
# replication
#
SELECT NAME_CONST('var', 'value') COLLATE latin1_general_cs;
#
# Bug #35848: UUID() returns UUIDs with the wrong time
#
select @@session.time_zone into @save_tz;
# make sure all times are UTC so the DayNr won't differ
set @@session.time_zone='UTC';
select uuid() into @my_uuid;
# if version nibble isn't 1, the following calculations will be rubbish
select mid(@my_uuid,15,1);
select 24 * 60 * 60 * 1000 * 1000 * 10 into @my_uuid_one_day;
select concat('0',mid(@my_uuid,16,3),mid(@my_uuid,10,4),left(@my_uuid,8)) into @my_uuidate;
select floor(conv(@my_uuidate,16,10)/@my_uuid_one_day) into @my_uuid_date;
select 141427 + datediff(curdate(),'1970-01-01') into @my_uuid_synthetic;
# these should be identical; date part of UUID should be current date
select @my_uuid_date - @my_uuid_synthetic;
set @@session.time_zone=@save_tz;
#
# Bug#42014: Crash, name_const with collate
#
CREATE TABLE t1 (a DATE);
SELECT * FROM t1 WHERE a = NAME_CONST('reportDate',
_binary'2009-01-09' COLLATE 'binary');
DROP TABLE t1;
#
# Bug#35515: Aliases of variables in binary log are ignored with NAME_CONST
#
select NAME_CONST('_id',1234) as id;
--echo End of 5.0 tests
#
# Bug #30389: connection_id() always return 0 in embedded server
#
select connection_id() > 0;
--echo #
--echo # Bug #54461: crash with longblob and union or update with subquery
--echo #
CREATE TABLE t1 (a INT, b LONGBLOB);
INSERT INTO t1 VALUES (1, '2'), (2, '3'), (3, '2');
SELECT DISTINCT LEAST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
SELECT DISTINCT GREATEST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
DROP TABLE t1;
#
# Bug #57283: inet_ntoa() crashes
#
SELECT INET_NTOA(0);
SELECT '1' IN ('1', INET_NTOA(0));
--echo #
--echo # Bug #52165: Assertion failed: file .\dtoa.c, line 465
--echo #
CREATE TABLE t1 (a SET('a'), b INT);
INSERT INTO t1 VALUES ('', 0);
SELECT COALESCE(a) = COALESCE(b) FROM t1;
DROP TABLE t1;
--echo #
--echo # Bug #54461: crash with longblob and union or update with subquery
--echo #
CREATE TABLE t1 (a INT, b LONGBLOB);
INSERT INTO t1 VALUES (1, '2'), (2, '3'), (3, '2');
SELECT DISTINCT LEAST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
SELECT DISTINCT GREATEST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1;
DROP TABLE t1;
#
# Bug #57283: inet_ntoa() crashes
#
SELECT INET_NTOA(0);
SELECT '1' IN ('1', INET_NTOA(0));
--echo #
--echo # End of 5.1 tests
--echo #
--echo #
--echo # Bug #58199: name_const in the having clause crashes
--echo #
CREATE TABLE t1 (a INT);
# NAME_CONST() would seg.fault when used wrongly in a HAVING clause
--error ER_WRONG_ARGUMENTS
SELECT 1 from t1 HAVING NAME_CONST('', a);
DROP TABLE t1;
--echo #
--echo # Test or correct maybe_null of last_value
--echo #
CREATE TABLE t1 (a char(2) not null );
INSERT INTO t1 VALUES (4),(7),(1);
set @optimizer_switch_save= @@optimizer_switch;
set optimizer_switch='materialization=off';
CREATE TABLE tv (e char(2) not null ) engine=mysql;
INSERT INTO tv VALUES (1);
CREATE ALGORITHM=MERGE VIEW v_merge AS SELECT * FROM tv;
CREATE ALGORITHM=MERGE VIEW vm AS SELECT * FROM tv;
explain extended
select a from t1 left join v_merge on (a=e) where last_value(NULL,e) not in (select last_value(NULL,e) from vm);
explain extended
select a from t1 left join v_merge on (a=e) where e not in (select last_value(NULL,e) from vm);
set optimizer_switch=@optimizer_switch_save;
drop view v_merge, vm;
drop table t1,tv;
--echo #
--echo # GET_LOCK, RELEASE_LOCK, IS_USED_LOCK functions test
--echo #
--echo # IS_USED_LOCK, IS_FREE_LOCK: the lock is not acquired
--echo # Note: IS_USED_LOCK returns NULL if the lock is unused
select is_used_lock('test');
select is_free_lock('test');
--echo # GET_LOCK returns 1 if it manages to acquire a lock
select get_lock('test', 0);
--echo # IS_USED_LOCK, IS_FREE_LOCK: the lock is acquired
select is_free_lock('test');
select is_used_lock('test') = connection_id();
connect (con1,localhost,root,,);
--echo # -> Switching to connection 'con1'
connection con1;
--echo # IS_USED_LOCK, IS_FREE_LOCK: the lock is acquired in another
--echo # connection
select is_used_lock('test') = connection_id();
select is_free_lock('test');
--echo # GET_LOCK returns 0 if it can't acquire a lock (wait timeout)
select get_lock('test', 0);
--echo # RELEASE_LOCK returns 0 if the lock belongs to another connection
select release_lock('test');
--echo # -> Switching to connection 'default'
connection default;
--echo # RELEASE_LOCK returns 1 if it successfully releases a lock
select release_lock('test');
--echo # RELEASE_LOCK returns NULL if it doesn't release a lock and there is no such lock
select release_lock('test');
--echo # Test that get_lock() returns NULL if error.
select get_lock('test', 0);
--echo # -> Switching to connection 'con1'
connection con1;
create table t1 select connection_id() as id;
send select get_lock('test', 7200);
--echo # -> Switching to connection 'default'
connection default;
let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE info LIKE 'select%' AND state='User lock';
source include/wait_condition.inc;
select (@id := id) - id from t1;
kill query @id;
--echo # -> Switching to connection 'con1'
connection con1;
reap;
--echo # -> Switching to connection 'default'
connection default;
--echo # GET_LOCK() works recursively
select get_lock('test', 0);
select get_lock('test', 0);
select get_lock('test', 0);
--echo # RELEASE_LOCK() needs to be called recursively then, too
select release_lock('test');
select release_lock('test');
select release_lock('test');
--echo # Once the last instance of the lock is released,
--echo # the next call returns NULL
select release_lock('test');
--echo # Multiple locks in the same session are OK
select get_lock('test1', 0);
select get_lock('test2', 0);
select get_lock('test3', 0);
select release_lock('test1');
select release_lock('test2');
select release_lock('test3');
--echo # Deadlocks are detected e.g. in case of a mutual wait
select get_lock('test1', 0);
--echo # -> Switching to connection 'con1'
connection con1;
select get_lock('test2', 0);
send select get_lock('test1', 7200);
--echo # -> Switching to connection 'default'
connection default;
let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE info LIKE 'select%' AND state='User lock';
source include/wait_condition.inc;
--error ER_LOCK_DEADLOCK
select get_lock('test2', 7200);
select release_lock('test1');
--echo # -> Switching to connection 'con1'
connection con1;
reap;
select release_lock('test2');
select release_lock('test1');
--echo # -> Switching to connection 'default'
connection default;
--echo # LOCK/UNLOCK TABLES works fine with a user lock.
lock table t1 write;
select get_lock('test', 0);
unlock tables;
commit;
select release_lock('test');
--echo # GLOBAL READ LOCK works with fine with user locks
select get_lock('test1', 0);
flush tables with read lock;
select get_lock('test2', 0);
unlock tables;
commit;
select release_lock('test1');
select release_lock('test2');
--echo # BEGIN/COMMIT/ROLLBACK don't unlock user locks.
begin;
select get_lock('test1', 0);
select get_lock('test2', 0);
select count(*) from t1;
rollback;
select release_lock('test1');
select release_lock('test2');
--echo # Deadlocks between user locks and LOCK TABLES locks
--echo # are detected OK.
select get_lock('test', 0);
--echo # -> Switching to connection 'con1'
connection con1;
lock table t1 write;
send select get_lock('test', 7200);
--echo # -> Switching to connection 'default'
connection default;
let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE info LIKE 'select%' AND state = 'User lock';
source include/wait_condition.inc;
--error ER_LOCK_DEADLOCK
lock table t1 read;
select release_lock('test');
--echo # -> Switching to connection 'con1'
connection con1;
reap;
select release_lock('test');
unlock tables;
--echo # cleanup
disconnect con1;
connection default;
drop table t1;
--echo # check too long identifier names
select get_lock(repeat('a', 192), 0);
select is_used_lock(repeat('a', 192)) = connection_id();
select is_free_lock(repeat('a', 192));
select release_lock(repeat('a', 192));
--error ER_TOO_LONG_IDENT
select get_lock(repeat('a', 193), 0);
--error ER_TOO_LONG_IDENT
select is_used_lock(repeat('a', 193));
--error ER_TOO_LONG_IDENT
select is_free_lock(repeat('a', 193));
--error ER_TOO_LONG_IDENT
select release_lock(repeat('a', 193));
--echo #
--echo # End of 5.5 tests
--echo #
--echo #
--echo # End of tests
--echo #