mirror of
https://github.com/MariaDB/server.git
synced 2025-09-02 09:41:40 +03:00
Merge mysql-5.1 -> mysql-5.1-innodb
(innodb_mysql.result needs to be adjusted after this commit)
This commit is contained in:
@@ -12,11 +12,11 @@ alter table t1 enable keys;;
|
||||
insert into t2 values (1);
|
||||
insert into t1 values (1, 1, 1);
|
||||
set session debug="-d,sleep_alter_enable_indexes";
|
||||
show binlog events in 'master-bin.000001' from 106;
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t2 values (1)
|
||||
master-bin.000001 # Query 1 # use `test`; alter table t1 enable keys
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t1 values (1, 1, 1)
|
||||
master-bin.000001 # Query # # use `test`; insert into t2 values (1)
|
||||
master-bin.000001 # Query # # use `test`; alter table t1 enable keys
|
||||
master-bin.000001 # Query # # use `test`; insert into t1 values (1, 1, 1)
|
||||
drop tables t1, t2;
|
||||
End of 5.0 tests
|
||||
drop table if exists t1, t2, t3;
|
||||
@@ -41,17 +41,17 @@ alter table t2 change c vc varchar(100) default 'Test2', rename to t1;;
|
||||
rename table t1 to t3;
|
||||
drop table t3;
|
||||
set session debug="-d,sleep_alter_before_main_binlog";
|
||||
show binlog events in 'master-bin.000001' from 106;
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # use `test`; alter table t1 change i c char(10) default 'Test1'
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t1 values ()
|
||||
master-bin.000001 # Query 1 # use `test`; alter table t1 change c vc varchar(100) default 'Test2'
|
||||
master-bin.000001 # Query 1 # use `test`; rename table t1 to t2
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t2
|
||||
master-bin.000001 # Query 1 # use `test`; create table t1 (i int)
|
||||
master-bin.000001 # Query 1 # use `test`; alter table t1 change i c char(10) default 'Test3', rename to t2
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t2 values ()
|
||||
master-bin.000001 # Query 1 # use `test`; alter table t2 change c vc varchar(100) default 'Test2', rename to t1
|
||||
master-bin.000001 # Query 1 # use `test`; rename table t1 to t3
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t3
|
||||
master-bin.000001 # Query # # use `test`; alter table t1 change i c char(10) default 'Test1'
|
||||
master-bin.000001 # Query # # use `test`; insert into t1 values ()
|
||||
master-bin.000001 # Query # # use `test`; alter table t1 change c vc varchar(100) default 'Test2'
|
||||
master-bin.000001 # Query # # use `test`; rename table t1 to t2
|
||||
master-bin.000001 # Query # # use `test`; drop table t2
|
||||
master-bin.000001 # Query # # use `test`; create table t1 (i int)
|
||||
master-bin.000001 # Query # # use `test`; alter table t1 change i c char(10) default 'Test3', rename to t2
|
||||
master-bin.000001 # Query # # use `test`; insert into t2 values ()
|
||||
master-bin.000001 # Query # # use `test`; alter table t2 change c vc varchar(100) default 'Test2', rename to t1
|
||||
master-bin.000001 # Query # # use `test`; rename table t1 to t3
|
||||
master-bin.000001 # Query # # use `test`; drop table t3
|
||||
End of 5.1 tests
|
||||
|
@@ -12,7 +12,7 @@ INSERT INTO t2 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),
|
||||
START TRANSACTION;
|
||||
# in thread2
|
||||
REPLACE INTO t2 VALUES (-17);
|
||||
SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d);
|
||||
SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d) LOCK IN SHARE MODE;
|
||||
d
|
||||
# in thread1
|
||||
REPLACE INTO t1(a,b) VALUES (67,20);
|
||||
@@ -21,10 +21,10 @@ COMMIT;
|
||||
START TRANSACTION;
|
||||
REPLACE INTO t1(a,b) VALUES (65,-50);
|
||||
REPLACE INTO t2 VALUES (-91);
|
||||
SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d);
|
||||
SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d) LOCK IN SHARE MODE;
|
||||
# in thread1
|
||||
# should not crash
|
||||
SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d);
|
||||
SELECT d FROM t2,t1 WHERE d=(SELECT MAX(a) FROM t1 WHERE t1.a > t2.d) LOCK IN SHARE MODE;
|
||||
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||
# in thread2
|
||||
d
|
||||
|
@@ -175,12 +175,12 @@ t2 CREATE TABLE `t2` (
|
||||
`i` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t2;
|
||||
show binlog events in 'master-bin.000001' from 106;
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t1 values (1)
|
||||
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t1
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t2
|
||||
master-bin.000001 # Query # # use `test`; insert into t1 values (1)
|
||||
master-bin.000001 # Query # # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query # # use `test`; drop table t1
|
||||
master-bin.000001 # Query # # use `test`; drop table t2
|
||||
create table t1 (i int);
|
||||
set session debug="-d,sleep_create_like_before_check_if_exists:+d,sleep_create_like_before_copy";
|
||||
create table t2 like t1;;
|
||||
@@ -197,11 +197,11 @@ reset master;
|
||||
create table t2 like t1;;
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
show binlog events in 'master-bin.000001' from 106;
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t1
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t2
|
||||
master-bin.000001 # Query # # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query # # use `test`; drop table t1
|
||||
master-bin.000001 # Query # # use `test`; drop table t2
|
||||
create table t1 (i int);
|
||||
set session debug="-d,sleep_create_like_before_copy:+d,sleep_create_like_before_ha_create";
|
||||
reset master;
|
||||
@@ -213,16 +213,16 @@ drop table t2;
|
||||
create table t2 like t1;;
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
show binlog events in 'master-bin.000001' from 106;
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t2 values (1)
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t2
|
||||
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t2
|
||||
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t1
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t2
|
||||
master-bin.000001 # Query # # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query # # use `test`; insert into t2 values (1)
|
||||
master-bin.000001 # Query # # use `test`; drop table t2
|
||||
master-bin.000001 # Query # # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query # # use `test`; drop table t2
|
||||
master-bin.000001 # Query # # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query # # use `test`; drop table t1
|
||||
master-bin.000001 # Query # # use `test`; drop table t2
|
||||
create table t1 (i int);
|
||||
set session debug="-d,sleep_create_like_before_ha_create:+d,sleep_create_like_before_binlogging";
|
||||
reset master;
|
||||
@@ -234,14 +234,14 @@ drop table t2;
|
||||
create table t2 like t1;;
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
show binlog events in 'master-bin.000001' from 106;
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t2 values (1)
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t2
|
||||
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t2
|
||||
master-bin.000001 # Query 1 # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t1
|
||||
master-bin.000001 # Query 1 # use `test`; drop table t2
|
||||
master-bin.000001 # Query # # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query # # use `test`; insert into t2 values (1)
|
||||
master-bin.000001 # Query # # use `test`; drop table t2
|
||||
master-bin.000001 # Query # # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query # # use `test`; drop table t2
|
||||
master-bin.000001 # Query # # use `test`; create table t2 like t1
|
||||
master-bin.000001 # Query # # use `test`; drop table t1
|
||||
master-bin.000001 # Query # # use `test`; drop table t2
|
||||
set session debug="-d,sleep_create_like_before_binlogging";
|
||||
|
@@ -29,20 +29,20 @@ HEX(s1) HEX(s2) d
|
||||
466F6F2773206120426172 ED40ED41ED42 47.93
|
||||
DROP PROCEDURE bug18293|
|
||||
DROP TABLE t4|
|
||||
SHOW BINLOG EVENTS FROM 370|
|
||||
show binlog events from <binlog_start>|
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 370 Query 1 536 use `test`; CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1,
|
||||
master-bin.000001 # Query # # use `test`; CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1,
|
||||
s2 CHAR(50) CHARACTER SET cp932,
|
||||
d DECIMAL(10,2))
|
||||
master-bin.000001 536 Query 1 785 use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `bug18293`(IN ins1 CHAR(50),
|
||||
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `bug18293`(IN ins1 CHAR(50),
|
||||
IN ins2 CHAR(50) CHARACTER SET cp932,
|
||||
IN ind DECIMAL(10,2))
|
||||
BEGIN
|
||||
INSERT INTO t4 VALUES (ins1, ins2, ind);
|
||||
END
|
||||
master-bin.000001 785 Query 1 1049 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172 COLLATE 'latin1_swedish_ci'), NAME_CONST('ins2',_cp932 0xED40ED41ED42 COLLATE 'cp932_japanese_ci'), NAME_CONST('ind',47.93))
|
||||
master-bin.000001 1049 Query 1 1138 use `test`; DROP PROCEDURE bug18293
|
||||
master-bin.000001 1138 Query 1 1217 use `test`; DROP TABLE t4
|
||||
master-bin.000001 # Query # # use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172 COLLATE 'latin1_swedish_ci'), NAME_CONST('ins2',_cp932 0xED40ED41ED42 COLLATE 'cp932_japanese_ci'), NAME_CONST('ind',47.93))
|
||||
master-bin.000001 # Query # # use `test`; DROP PROCEDURE bug18293
|
||||
master-bin.000001 # Query # # use `test`; DROP TABLE t4
|
||||
End of 5.0 tests
|
||||
SHOW BINLOG EVENTS FROM 365;
|
||||
ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Wrong offset or I/O error
|
||||
|
@@ -349,4 +349,13 @@ END |
|
||||
DELETE IGNORE FROM t1;
|
||||
ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug #53450: Crash/assertion
|
||||
# "virtual int ha_myisam::index_first(uchar*)") at assert.c:81
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b INT, c INT,
|
||||
INDEX(a), INDEX(b), INDEX(c));
|
||||
INSERT INTO t1 VALUES (1,2,3), (4,5,6), (7,8,9);
|
||||
DELETE FROM t1 WHERE a = 10 OR b = 20 ORDER BY c LIMIT 1;
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
|
@@ -82,5 +82,24 @@ DROP TABLE table_1;
|
||||
DROP TABLE table_2;
|
||||
DROP TABLE table_3;
|
||||
DROP TABLE table_4;
|
||||
|
||||
Bug #50087 Interval arithmetic for Event_queue_element is not portable.
|
||||
|
||||
CREATE TABLE t1(a int);
|
||||
CREATE EVENT e1 ON SCHEDULE EVERY 1 MONTH
|
||||
STARTS NOW() - INTERVAL 1 MONTH
|
||||
ENDS NOW() + INTERVAL 2 MONTH
|
||||
ON COMPLETION PRESERVE
|
||||
DO
|
||||
INSERT INTO t1 VALUES (1);
|
||||
CREATE EVENT e2 ON SCHEDULE EVERY 1 MONTH
|
||||
STARTS NOW()
|
||||
ENDS NOW() + INTERVAL 11 MONTH
|
||||
ON COMPLETION PRESERVE
|
||||
DO
|
||||
INSERT INTO t1 VALUES (1);
|
||||
DROP TABLE t1;
|
||||
DROP EVENT e1;
|
||||
DROP EVENT e2;
|
||||
DROP DATABASE events_test;
|
||||
SET GLOBAL event_scheduler=@event_scheduler;
|
||||
|
@@ -7,15 +7,13 @@ SET AUTOCOMMIT=0;
|
||||
INSERT t1 VALUES (1);
|
||||
# Switch to connection con2
|
||||
FLUSH TABLES WITH READ LOCK;
|
||||
SHOW MASTER STATUS;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 106
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
# Switch to connection con1
|
||||
COMMIT;
|
||||
# Switch to connection con2
|
||||
SHOW MASTER STATUS;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 106
|
||||
show binlog events from <binlog_start>;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
UNLOCK TABLES;
|
||||
# Switch to connection con1
|
||||
DROP TABLE t1;
|
||||
|
@@ -1790,4 +1790,24 @@ aa b COUNT( b)
|
||||
1 10 1
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug#52051: Aggregate functions incorrectly returns NULL from outer
|
||||
# join query
|
||||
#
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY);
|
||||
CREATE TABLE t2 (a INT PRIMARY KEY);
|
||||
INSERT INTO t2 VALUES (1), (2);
|
||||
EXPLAIN SELECT MIN(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
SELECT MIN(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
|
||||
MIN(t2.a)
|
||||
1
|
||||
EXPLAIN SELECT MAX(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
|
||||
SELECT MAX(t2.a) FROM t2 LEFT JOIN t1 ON t2.a = t1.a;
|
||||
MAX(t2.a)
|
||||
2
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# End of 5.1 tests
|
||||
|
601
mysql-test/r/innodb_mysql_lock2.result
Normal file
601
mysql-test/r/innodb_mysql_lock2.result
Normal file
@@ -0,0 +1,601 @@
|
||||
#
|
||||
# Test how do we handle locking in various cases when
|
||||
# we read data from InnoDB tables.
|
||||
#
|
||||
# In fact by performing this test we check two things:
|
||||
# 1) That SQL-layer correctly determine type of thr_lock.c
|
||||
# lock to be acquired/passed to InnoDB engine.
|
||||
# 2) That InnoDB engine correctly interprets this lock
|
||||
# type and takes necessary row locks or does not
|
||||
# take them if they are not necessary.
|
||||
#
|
||||
# This test makes sense only in REPEATABLE-READ mode as
|
||||
# in SERIALIZABLE mode all statements that read data take
|
||||
# shared lock on them to enforce its semantics.
|
||||
select @@session.tx_isolation;
|
||||
@@session.tx_isolation
|
||||
REPEATABLE-READ
|
||||
# Prepare playground by creating tables, views,
|
||||
# routines and triggers used in tests.
|
||||
drop table if exists t0, t1, t2, t3, t4, t5, te;
|
||||
drop view if exists v1, v2;
|
||||
drop procedure if exists p1;
|
||||
drop procedure if exists p2;
|
||||
drop function if exists f1;
|
||||
drop function if exists f2;
|
||||
drop function if exists f3;
|
||||
drop function if exists f4;
|
||||
drop function if exists f5;
|
||||
drop function if exists f6;
|
||||
drop function if exists f7;
|
||||
drop function if exists f8;
|
||||
drop function if exists f9;
|
||||
drop function if exists f10;
|
||||
drop function if exists f11;
|
||||
drop function if exists f12;
|
||||
drop function if exists f13;
|
||||
drop function if exists f14;
|
||||
drop function if exists f15;
|
||||
create table t1 (i int primary key) engine=innodb;
|
||||
insert into t1 values (1), (2), (3), (4), (5);
|
||||
create table t2 (j int primary key) engine=innodb;
|
||||
insert into t2 values (1), (2), (3), (4), (5);
|
||||
create table t3 (k int primary key) engine=innodb;
|
||||
insert into t3 values (1), (2), (3);
|
||||
create table t4 (l int primary key) engine=innodb;
|
||||
insert into t4 values (1);
|
||||
create table t5 (l int primary key) engine=innodb;
|
||||
insert into t5 values (1);
|
||||
create table te(e int primary key);
|
||||
insert into te values (1);
|
||||
create view v1 as select i from t1;
|
||||
create view v2 as select j from t2 where j in (select i from t1);
|
||||
create procedure p1(k int) insert into t2 values (k);
|
||||
create function f1() returns int
|
||||
begin
|
||||
declare j int;
|
||||
select i from t1 where i = 1 into j;
|
||||
return j;
|
||||
end|
|
||||
create function f2() returns int
|
||||
begin
|
||||
declare k int;
|
||||
select i from t1 where i = 1 into k;
|
||||
insert into t2 values (k + 5);
|
||||
return 0;
|
||||
end|
|
||||
create function f3() returns int
|
||||
begin
|
||||
return (select i from t1 where i = 3);
|
||||
end|
|
||||
create function f4() returns int
|
||||
begin
|
||||
if (select i from t1 where i = 3) then
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
end if;
|
||||
end|
|
||||
create function f5() returns int
|
||||
begin
|
||||
insert into t2 values ((select i from t1 where i = 1) + 5);
|
||||
return 0;
|
||||
end|
|
||||
create function f6() returns int
|
||||
begin
|
||||
declare k int;
|
||||
select i from v1 where i = 1 into k;
|
||||
return k;
|
||||
end|
|
||||
create function f7() returns int
|
||||
begin
|
||||
declare k int;
|
||||
select j from v2 where j = 1 into k;
|
||||
return k;
|
||||
end|
|
||||
create function f8() returns int
|
||||
begin
|
||||
declare k int;
|
||||
select i from v1 where i = 1 into k;
|
||||
insert into t2 values (k+5);
|
||||
return k;
|
||||
end|
|
||||
create function f9() returns int
|
||||
begin
|
||||
update v2 set j=j+10 where j=1;
|
||||
return 1;
|
||||
end|
|
||||
create function f10() returns int
|
||||
begin
|
||||
return f1();
|
||||
end|
|
||||
create function f11() returns int
|
||||
begin
|
||||
declare k int;
|
||||
set k= f1();
|
||||
insert into t2 values (k+5);
|
||||
return k;
|
||||
end|
|
||||
create function f12(p int) returns int
|
||||
begin
|
||||
insert into t2 values (p);
|
||||
return p;
|
||||
end|
|
||||
create function f13(p int) returns int
|
||||
begin
|
||||
return p;
|
||||
end|
|
||||
create procedure p2(inout p int)
|
||||
begin
|
||||
select i from t1 where i = 1 into p;
|
||||
end|
|
||||
create function f14() returns int
|
||||
begin
|
||||
declare k int;
|
||||
call p2(k);
|
||||
insert into t2 values (k+5);
|
||||
return k;
|
||||
end|
|
||||
create function f15() returns int
|
||||
begin
|
||||
declare k int;
|
||||
call p2(k);
|
||||
return k;
|
||||
end|
|
||||
create trigger t4_bi before insert on t4 for each row
|
||||
begin
|
||||
declare k int;
|
||||
select i from t1 where i=1 into k;
|
||||
set new.l= k+1;
|
||||
end|
|
||||
create trigger t4_bu before update on t4 for each row
|
||||
begin
|
||||
if (select i from t1 where i=1) then
|
||||
set new.l= 2;
|
||||
end if;
|
||||
end|
|
||||
# Trigger below uses insertion of duplicate key in 'te'
|
||||
# table as a way to abort delete operation.
|
||||
create trigger t4_bd before delete on t4 for each row
|
||||
begin
|
||||
if !(select i from v1 where i=1) then
|
||||
insert into te values (1);
|
||||
end if;
|
||||
end|
|
||||
create trigger t5_bi before insert on t5 for each row
|
||||
begin
|
||||
set new.l= f1()+1;
|
||||
end|
|
||||
create trigger t5_bu before update on t5 for each row
|
||||
begin
|
||||
declare j int;
|
||||
call p2(j);
|
||||
set new.l= j + 1;
|
||||
end|
|
||||
#
|
||||
# Set common variables to be used by scripts called below.
|
||||
#
|
||||
#
|
||||
# 1. Statements that read tables and do not use subqueries.
|
||||
#
|
||||
#
|
||||
# 1.1 Simple SELECT statement.
|
||||
#
|
||||
# No locks are necessary as this statement won't be written
|
||||
# to the binary log and InnoDB supports snapshots.
|
||||
Success: 'select * from t1' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 1.2 Multi-UPDATE statement.
|
||||
#
|
||||
# Has to take shared locks on rows in the table being read as this
|
||||
# statement will be written to the binary log and therefore should
|
||||
# be serialized with concurrent statements.
|
||||
Success: 'update t2, t1 set j= j - 1 where i = j' takes shared row locks on 't1'.
|
||||
#
|
||||
# 1.3 Multi-DELETE statement.
|
||||
#
|
||||
# The above is true for this statement as well.
|
||||
Success: 'delete t2 from t1, t2 where i = j' takes shared row locks on 't1'.
|
||||
#
|
||||
# 1.4 DESCRIBE statement.
|
||||
#
|
||||
# This statement does not really read data from the
|
||||
# target table and thus does not take any lock on it.
|
||||
# We check this for completeness of coverage.
|
||||
Success: 'describe t1' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 1.5 SHOW statements.
|
||||
#
|
||||
# The above is true for SHOW statements as well.
|
||||
Success: 'show create table t1' doesn't take row locks on 't1'.
|
||||
Success: 'show keys from t1' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 2. Statements which read tables through subqueries.
|
||||
#
|
||||
#
|
||||
# 2.1 CALL with a subquery.
|
||||
#
|
||||
# A strong lock is not necessary as this statement is not
|
||||
# written to the binary log as a whole (it is written
|
||||
# statement-by-statement) and thanks to MVCC we can always get
|
||||
# versions of rows prior to the update that has locked them.
|
||||
# But in practice InnoDB does locking reads for all statements
|
||||
# other than SELECT (unless it is a READ-COMITTED mode or
|
||||
# innodb_locks_unsafe_for_binlog is ON).
|
||||
Success: 'call p1((select i + 5 from t1 where i = 1))' takes shared row locks on 't1'.
|
||||
#
|
||||
# 2.2 CREATE TABLE with a subquery.
|
||||
#
|
||||
# Has to take shared locks on rows in the table being read as
|
||||
# this statement is written to the binary log and therefore
|
||||
# should be serialized with concurrent statements.
|
||||
Success: 'create table t0 engine=innodb select * from t1' takes shared row locks on 't1'.
|
||||
drop table t0;
|
||||
Success: 'create table t0 engine=innodb select j from t2 where j in (select i from t1)' takes shared row locks on 't1'.
|
||||
drop table t0;
|
||||
#
|
||||
# 2.3 DELETE with a subquery.
|
||||
#
|
||||
# The above is true for this statement as well.
|
||||
Success: 'delete from t2 where j in (select i from t1)' takes shared row locks on 't1'.
|
||||
#
|
||||
# 2.4 MULTI-DELETE with a subquery.
|
||||
#
|
||||
# Same is true for this statement as well.
|
||||
Success: 'delete t2 from t3, t2 where k = j and j in (select i from t1)' takes shared row locks on 't1'.
|
||||
#
|
||||
# 2.5 DO with a subquery.
|
||||
#
|
||||
# In theory should not take row locks as it is not logged.
|
||||
# In practice InnoDB takes shared row locks.
|
||||
Success: 'do (select i from t1 where i = 1)' takes shared row locks on 't1'.
|
||||
#
|
||||
# 2.6 INSERT with a subquery.
|
||||
#
|
||||
# Has to take shared locks on rows in the table being read as
|
||||
# this statement is written to the binary log and therefore
|
||||
# should be serialized with concurrent statements.
|
||||
Success: 'insert into t2 select i+5 from t1' takes shared row locks on 't1'.
|
||||
Success: 'insert into t2 values ((select i+5 from t1 where i = 4))' takes shared row locks on 't1'.
|
||||
#
|
||||
# 2.7 LOAD DATA with a subquery.
|
||||
#
|
||||
# The above is true for this statement as well.
|
||||
Success: 'load data infile '../../std_data/rpl_loaddata.dat' into table t2 (@a, @b) set j= @b + (select i from t1 where i = 1)' takes shared row locks on 't1'.
|
||||
#
|
||||
# 2.8 REPLACE with a subquery.
|
||||
#
|
||||
# Same is true for this statement as well.
|
||||
Success: 'replace into t2 select i+5 from t1' takes shared row locks on 't1'.
|
||||
Success: 'replace into t2 values ((select i+5 from t1 where i = 4))' takes shared row locks on 't1'.
|
||||
#
|
||||
# 2.9 SELECT with a subquery.
|
||||
#
|
||||
# Locks are not necessary as this statement is not written
|
||||
# to the binary log and thanks to MVCC we can always get
|
||||
# versions of rows prior to the update that has locked them.
|
||||
#
|
||||
# Also serves as a test case for bug #46947 "Embedded SELECT
|
||||
# without FOR UPDATE is causing a lock".
|
||||
Success: 'select * from t2 where j in (select i from t1)' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 2.10 SET with a subquery.
|
||||
#
|
||||
# In theory should not require locking as it is not written
|
||||
# to the binary log. In practice InnoDB acquires shared row
|
||||
# locks.
|
||||
Success: 'set @a:= (select i from t1 where i = 1)' takes shared row locks on 't1'.
|
||||
#
|
||||
# 2.11 SHOW with a subquery.
|
||||
#
|
||||
# Similarly to the previous case, in theory should not require locking
|
||||
# as it is not written to the binary log. In practice InnoDB
|
||||
# acquires shared row locks.
|
||||
Success: 'show tables from test where Tables_in_test = 't2' and (select i from t1 where i = 1)' takes shared row locks on 't1'.
|
||||
Success: 'show columns from t2 where (select i from t1 where i = 1)' takes shared row locks on 't1'.
|
||||
#
|
||||
# 2.12 UPDATE with a subquery.
|
||||
#
|
||||
# Has to take shared locks on rows in the table being read as
|
||||
# this statement is written to the binary log and therefore
|
||||
# should be serialized with concurrent statements.
|
||||
Success: 'update t2 set j= j-10 where j in (select i from t1)' takes shared row locks on 't1'.
|
||||
#
|
||||
# 2.13 MULTI-UPDATE with a subquery.
|
||||
#
|
||||
# Same is true for this statement as well.
|
||||
Success: 'update t2, t3 set j= j -10 where j=k and j in (select i from t1)' takes shared row locks on 't1'.
|
||||
#
|
||||
# 3. Statements which read tables through a view.
|
||||
#
|
||||
#
|
||||
# 3.1 SELECT statement which uses some table through a view.
|
||||
#
|
||||
# Since this statement is not written to the binary log
|
||||
# and old version of rows are accessible thanks to MVCC,
|
||||
# no locking is necessary.
|
||||
Success: 'select * from v1' doesn't take row locks on 't1'.
|
||||
Success: 'select * from v2' doesn't take row locks on 't1'.
|
||||
Success: 'select * from t2 where j in (select i from v1)' doesn't take row locks on 't1'.
|
||||
Success: 'select * from t3 where k in (select j from v2)' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 3.2 Statements which modify a table and use views.
|
||||
#
|
||||
# Since such statements are going to be written to the binary
|
||||
# log they need to be serialized against concurrent statements
|
||||
# and therefore should take shared row locks on data read.
|
||||
Success: 'update t2 set j= j-10 where j in (select i from v1)' takes shared row locks on 't1'.
|
||||
Success: 'update t3 set k= k-10 where k in (select j from v2)' takes shared row locks on 't1'.
|
||||
Success: 'update t2, v1 set j= j-10 where j = i' takes shared row locks on 't1'.
|
||||
Success: 'update v2 set j= j-10 where j = 3' takes shared row locks on 't1'.
|
||||
#
|
||||
# 4. Statements which read tables through stored functions.
|
||||
#
|
||||
#
|
||||
# 4.1 SELECT/SET with a stored function which does not
|
||||
# modify data and uses SELECT in its turn.
|
||||
#
|
||||
# Calls to such functions won't get into the binary log and
|
||||
# thus don't need to acquire strong locks.
|
||||
# In 5.5 due to fix for bug #53921 "Wrong locks for SELECTs
|
||||
# used stored functions may lead to broken SBR" strong locks
|
||||
# are taken (we accepted it as a trade-off for this fix).
|
||||
Success: 'select f1()' doesn't take row locks on 't1'.
|
||||
Success: 'set @a:= f1()' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 4.2 INSERT (or other statement which modifies data) with
|
||||
# a stored function which does not modify data and uses
|
||||
# SELECT.
|
||||
#
|
||||
# Since such statement is written to the binary log it should
|
||||
# be serialized with concurrent statements affecting the data
|
||||
# it uses. Therefore it should take row locks on the data
|
||||
# it reads.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken.
|
||||
Success: 'insert into t2 values (f1() + 5)' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 4.3 SELECT/SET with a stored function which
|
||||
# reads and modifies data.
|
||||
#
|
||||
# Since a call to such function is written to the binary log,
|
||||
# it should be serialized with concurrent statements affecting
|
||||
# the data it uses. Hence, row locks on the data read
|
||||
# should be taken.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken.
|
||||
Success: 'select f2()' doesn't take row locks on 't1'.
|
||||
Success: 'set @a:= f2()' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 4.4. SELECT/SET with a stored function which does not
|
||||
# modify data and reads a table through subselect
|
||||
# in a control construct.
|
||||
#
|
||||
# Again, in theory a call to this function won't get to the
|
||||
# binary log and thus no locking is needed. But in practice
|
||||
# we don't detect this fact early enough (get_lock_type_for_table())
|
||||
# to avoid taking row locks.
|
||||
Success: 'select f3()' takes shared row locks on 't1'.
|
||||
Success: 'set @a:= f3()' takes shared row locks on 't1'.
|
||||
Success: 'select f4()' takes shared row locks on 't1'.
|
||||
Success: 'set @a:= f4()' takes shared row locks on 't1'.
|
||||
#
|
||||
# 4.5. INSERT (or other statement which modifies data) with
|
||||
# a stored function which does not modify data and reads
|
||||
# the table through a subselect in one of its control
|
||||
# constructs.
|
||||
#
|
||||
# Since such statement is written to the binary log it should
|
||||
# be serialized with concurrent statements affecting data it
|
||||
# uses. Therefore it should take row locks on the data
|
||||
# it reads.
|
||||
Success: 'insert into t2 values (f3() + 5)' takes shared row locks on 't1'.
|
||||
Success: 'insert into t2 values (f4() + 6)' takes shared row locks on 't1'.
|
||||
#
|
||||
# 4.6 SELECT/SET which uses a stored function with
|
||||
# DML which reads a table via a subquery.
|
||||
#
|
||||
# Since call to such function is written to the binary log
|
||||
# it should be serialized with concurrent statements.
|
||||
# Hence reads should take row locks.
|
||||
Success: 'select f5()' takes shared row locks on 't1'.
|
||||
Success: 'set @a:= f5()' takes shared row locks on 't1'.
|
||||
#
|
||||
# 4.7 SELECT/SET which uses a stored function which
|
||||
# doesn't modify data and reads tables through
|
||||
# a view.
|
||||
#
|
||||
# Once again, in theory, calls to such functions won't
|
||||
# get into the binary log and thus don't need row
|
||||
# locks. In practice this fact is discovered
|
||||
# too late to have any effect.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken
|
||||
# in case of simple SELECT.
|
||||
Success: 'select f6()' doesn't take row locks on 't1'.
|
||||
Success: 'set @a:= f6()' doesn't take row locks on 't1'.
|
||||
Success: 'select f7()' takes shared row locks on 't1'.
|
||||
Success: 'set @a:= f7()' takes shared row locks on 't1'.
|
||||
#
|
||||
# 4.8 INSERT which uses stored function which
|
||||
# doesn't modify data and reads a table
|
||||
# through a view.
|
||||
#
|
||||
# Since such statement is written to the binary log and
|
||||
# should be serialized with concurrent statements affecting
|
||||
# the data it uses. Therefore it should take row locks on
|
||||
# the rows it reads.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken
|
||||
# in case of simple SELECT.
|
||||
Success: 'insert into t3 values (f6() + 5)' doesn't take row locks on 't1'.
|
||||
Success: 'insert into t3 values (f7() + 5)' takes shared row locks on 't1'.
|
||||
#
|
||||
# 4.9 SELECT which uses a stored function which
|
||||
# modifies data and reads tables through a view.
|
||||
#
|
||||
# Since a call to such function is written to the binary log
|
||||
# it should be serialized with concurrent statements.
|
||||
# Hence, reads should take row locks.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken
|
||||
# in case of simple SELECT.
|
||||
Success: 'select f8()' doesn't take row locks on 't1'.
|
||||
Success: 'select f9()' takes shared row locks on 't1'.
|
||||
#
|
||||
# 4.10 SELECT which uses stored function which doesn't modify
|
||||
# data and reads a table indirectly, by calling another
|
||||
# function.
|
||||
#
|
||||
# Calls to such functions won't get into the binary log and
|
||||
# thus don't need to acquire strong locks.
|
||||
# In 5.5 due to fix for bug #53921 "Wrong locks for SELECTs
|
||||
# used stored functions may lead to broken SBR" strong locks
|
||||
# are taken (we accepted it as a trade-off for this fix).
|
||||
Success: 'select f10()' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 4.11 INSERT which uses a stored function which doesn't modify
|
||||
# data and reads a table indirectly, by calling another
|
||||
# function.
|
||||
#
|
||||
# Since such statement is written to the binary log, it should
|
||||
# be serialized with concurrent statements affecting the data it
|
||||
# uses. Therefore it should take row locks on data it reads.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken.
|
||||
Success: 'insert into t2 values (f10() + 5)' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 4.12 SELECT which uses a stored function which modifies
|
||||
# data and reads a table indirectly, by calling another
|
||||
# function.
|
||||
#
|
||||
# Since a call to such function is written to the binary log
|
||||
# it should be serialized from concurrent statements.
|
||||
# Hence, reads should take row locks.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken.
|
||||
Success: 'select f11()' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 4.13 SELECT that reads a table through a subquery passed
|
||||
# as a parameter to a stored function which modifies
|
||||
# data.
|
||||
#
|
||||
# Even though a call to this function is written to the
|
||||
# binary log, values of its parameters are written as literals.
|
||||
# So there is no need to acquire row locks on rows used in
|
||||
# the subquery.
|
||||
# But due to the fact that in 5.1 for prelocked statements
|
||||
# THD::in_lock_tables is set to TRUE we acquire strong locks
|
||||
# (see also bug#44613 "SELECT statement inside FUNCTION takes
|
||||
# a shared lock" [sic!!!]).
|
||||
Success: 'select f12((select i+10 from t1 where i=1))' takes shared row locks on 't1'.
|
||||
#
|
||||
# 4.14 INSERT that reads a table via a subquery passed
|
||||
# as a parameter to a stored function which doesn't
|
||||
# modify data.
|
||||
#
|
||||
# Since this statement is written to the binary log it should
|
||||
# be serialized with concurrent statements affecting the data it
|
||||
# uses. Therefore it should take row locks on the data it reads.
|
||||
Success: 'insert into t2 values (f13((select i+10 from t1 where i=1)))' takes shared row locks on 't1'.
|
||||
#
|
||||
# 5. Statements that read tables through stored procedures.
|
||||
#
|
||||
#
|
||||
# 5.1 CALL statement which reads a table via SELECT.
|
||||
#
|
||||
# Since neither this statement nor its components are
|
||||
# written to the binary log, there is no need to take
|
||||
# row locks on the data it reads.
|
||||
Success: 'call p2(@a)' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 5.2 Function that modifies data and uses CALL,
|
||||
# which reads a table through SELECT.
|
||||
#
|
||||
# Since a call to such function is written to the binary
|
||||
# log, it should be serialized with concurrent statements.
|
||||
# Hence, in this case reads should take row locks on data.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken.
|
||||
Success: 'select f14()' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 5.3 SELECT that calls a function that doesn't modify data and
|
||||
# uses a CALL statement that reads a table via SELECT.
|
||||
#
|
||||
# Calls to such functions won't get into the binary log and
|
||||
# thus don't need to acquire strong locks.
|
||||
# In 5.5 due to fix for bug #53921 "Wrong locks for SELECTs
|
||||
# used stored functions may lead to broken SBR" strong locks
|
||||
# are taken (we accepted it as a trade-off for this fix).
|
||||
Success: 'select f15()' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 5.4 INSERT which calls function which doesn't modify data and
|
||||
# uses CALL statement which reads table through SELECT.
|
||||
#
|
||||
# Since such statement is written to the binary log it should
|
||||
# be serialized with concurrent statements affecting data it
|
||||
# uses. Therefore it should take row locks on data it reads.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken.
|
||||
Success: 'insert into t2 values (f15()+5)' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 6. Statements that use triggers.
|
||||
#
|
||||
#
|
||||
# 6.1 Statement invoking a trigger that reads table via SELECT.
|
||||
#
|
||||
# Since this statement is written to the binary log it should
|
||||
# be serialized with concurrent statements affecting the data
|
||||
# it uses. Therefore, it should take row locks on the data
|
||||
# it reads.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken.
|
||||
Success: 'insert into t4 values (2)' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 6.2 Statement invoking a trigger that reads table through
|
||||
# a subquery in a control construct.
|
||||
#
|
||||
# The above is true for this statement as well.
|
||||
Success: 'update t4 set l= 2 where l = 1' takes shared row locks on 't1'.
|
||||
#
|
||||
# 6.3 Statement invoking a trigger that reads a table through
|
||||
# a view.
|
||||
#
|
||||
# And for this statement.
|
||||
Success: 'delete from t4 where l = 1' takes shared row locks on 't1'.
|
||||
#
|
||||
# 6.4 Statement invoking a trigger that reads a table through
|
||||
# a stored function.
|
||||
#
|
||||
# And for this statement.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken.
|
||||
Success: 'insert into t5 values (2)' doesn't take row locks on 't1'.
|
||||
#
|
||||
# 6.5 Statement invoking a trigger that reads a table through
|
||||
# stored procedure.
|
||||
#
|
||||
# And for this statement.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" no lock is taken.
|
||||
Success: 'update t5 set l= 2 where l = 1' doesn't take row locks on 't1'.
|
||||
# Clean-up.
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop function f3;
|
||||
drop function f4;
|
||||
drop function f5;
|
||||
drop function f6;
|
||||
drop function f7;
|
||||
drop function f8;
|
||||
drop function f9;
|
||||
drop function f10;
|
||||
drop function f11;
|
||||
drop function f12;
|
||||
drop function f13;
|
||||
drop function f14;
|
||||
drop function f15;
|
||||
drop view v1, v2;
|
||||
drop procedure p1;
|
||||
drop procedure p2;
|
||||
drop table t1, t2, t3, t4, t5, te;
|
@@ -1308,4 +1308,93 @@ WHERE (COALESCE(t1.f1, t2.f1), f3) IN ((1, 3), (2, 2));
|
||||
f1 f2 f3 f1 f2
|
||||
1 NULL 3 NULL NULL
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug#52357: Assertion failed: join->best_read in greedy_search
|
||||
# optimizer_search_depth=0
|
||||
#
|
||||
CREATE TABLE t1( a INT );
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
SET optimizer_search_depth = 0;
|
||||
# Should not core dump on query preparation
|
||||
EXPLAIN
|
||||
SELECT 1
|
||||
FROM t1 tt3 LEFT OUTER JOIN t1 tt4 ON 1
|
||||
LEFT OUTER JOIN t1 tt5 ON 1
|
||||
LEFT OUTER JOIN t1 tt6 ON 1
|
||||
LEFT OUTER JOIN t1 tt7 ON 1
|
||||
LEFT OUTER JOIN t1 tt8 ON 1
|
||||
RIGHT OUTER JOIN t1 tt2 ON 1
|
||||
RIGHT OUTER JOIN t1 tt1 ON 1
|
||||
STRAIGHT_JOIN t1 tt9 ON 1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE tt1 ALL NULL NULL NULL NULL 2
|
||||
1 SIMPLE tt2 ALL NULL NULL NULL NULL 2
|
||||
1 SIMPLE tt3 ALL NULL NULL NULL NULL 2
|
||||
1 SIMPLE tt4 ALL NULL NULL NULL NULL 2
|
||||
1 SIMPLE tt5 ALL NULL NULL NULL NULL 2
|
||||
1 SIMPLE tt6 ALL NULL NULL NULL NULL 2
|
||||
1 SIMPLE tt7 ALL NULL NULL NULL NULL 2
|
||||
1 SIMPLE tt8 ALL NULL NULL NULL NULL 2
|
||||
1 SIMPLE tt9 ALL NULL NULL NULL NULL 2 Using join buffer
|
||||
SET optimizer_search_depth = DEFAULT;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#46091 STRAIGHT_JOIN + RIGHT JOIN returns different result
|
||||
#
|
||||
CREATE TABLE t1 (f1 INT NOT NULL);
|
||||
INSERT INTO t1 VALUES (9),(0);
|
||||
CREATE TABLE t2 (f1 INT NOT NULL);
|
||||
INSERT INTO t2 VALUES
|
||||
(5),(3),(0),(3),(1),(0),(1),(7),(1),(0),(0),(8),(4),(9),(0),(2),(0),(8),(5),(1);
|
||||
SELECT STRAIGHT_JOIN COUNT(*) FROM t1 TA1
|
||||
RIGHT JOIN t2 TA2 JOIN t2 TA3 ON TA2.f1 ON TA3.f1;
|
||||
COUNT(*)
|
||||
476
|
||||
EXPLAIN SELECT STRAIGHT_JOIN COUNT(*) FROM t1 TA1
|
||||
RIGHT JOIN t2 TA2 JOIN t2 TA3 ON TA2.f1 ON TA3.f1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE TA2 ALL NULL NULL NULL NULL 20 Using where
|
||||
1 SIMPLE TA3 ALL NULL NULL NULL NULL 20 Using join buffer
|
||||
1 SIMPLE TA1 ALL NULL NULL NULL NULL 2
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug#48971 Segfault in add_found_match_trig_cond () at sql_select.cc:5990
|
||||
#
|
||||
CREATE TABLE t1(f1 INT, PRIMARY KEY (f1));
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1
|
||||
LEFT JOIN t1 AS jt2
|
||||
RIGHT JOIN t1 AS jt3
|
||||
JOIN t1 AS jt4 ON 1
|
||||
LEFT JOIN t1 AS jt5 ON 1
|
||||
ON 1
|
||||
RIGHT JOIN t1 AS jt6 ON jt6.f1
|
||||
ON 1;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE jt1 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
1 SIMPLE jt6 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
1 SIMPLE jt3 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
1 SIMPLE jt4 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
Warnings:
|
||||
Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt1` left join (`test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1))) on(1) where 1
|
||||
EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1
|
||||
RIGHT JOIN t1 AS jt2
|
||||
RIGHT JOIN t1 AS jt3
|
||||
JOIN t1 AS jt4 ON 1
|
||||
LEFT JOIN t1 AS jt5 ON 1
|
||||
ON 1
|
||||
RIGHT JOIN t1 AS jt6 ON jt6.f1
|
||||
ON 1;
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 SIMPLE jt6 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
1 SIMPLE jt3 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
1 SIMPLE jt4 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
1 SIMPLE jt1 index NULL PRIMARY 4 NULL 2 100.00 Using index
|
||||
Warnings:
|
||||
Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1)) left join `test`.`t1` `jt1` on(1) where 1
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
|
631
mysql-test/r/lock_sync.result
Normal file
631
mysql-test/r/lock_sync.result
Normal file
@@ -0,0 +1,631 @@
|
||||
#
|
||||
# Test how we handle locking in various cases when
|
||||
# we read data from MyISAM tables.
|
||||
#
|
||||
# In this test we mostly check that the SQL-layer correctly
|
||||
# determines the type of thr_lock.c lock for a table being
|
||||
# read.
|
||||
# I.e. that it disallows concurrent inserts when the statement
|
||||
# is going to be written to the binary log and therefore
|
||||
# should be serialized, and allows concurrent inserts when
|
||||
# such serialization is not necessary (e.g. when
|
||||
# the statement is not written to binary log).
|
||||
#
|
||||
# Force concurrent inserts to be performed even if the table
|
||||
# has gaps. This allows to simplify clean up in scripts
|
||||
# used below (instead of backing up table being inserted
|
||||
# into and then restoring it from backup at the end of the
|
||||
# script we can simply delete rows which were inserted).
|
||||
set @old_concurrent_insert= @@global.concurrent_insert;
|
||||
set @@global.concurrent_insert= 2;
|
||||
select @@global.concurrent_insert;
|
||||
@@global.concurrent_insert
|
||||
2
|
||||
# Prepare playground by creating tables, views,
|
||||
# routines and triggers used in tests.
|
||||
drop table if exists t0, t1, t2, t3, t4, t5, te;
|
||||
drop view if exists v1, v2;
|
||||
drop procedure if exists p1;
|
||||
drop procedure if exists p2;
|
||||
drop function if exists f1;
|
||||
drop function if exists f2;
|
||||
drop function if exists f3;
|
||||
drop function if exists f4;
|
||||
drop function if exists f5;
|
||||
drop function if exists f6;
|
||||
drop function if exists f7;
|
||||
drop function if exists f8;
|
||||
drop function if exists f9;
|
||||
drop function if exists f10;
|
||||
drop function if exists f11;
|
||||
drop function if exists f12;
|
||||
drop function if exists f13;
|
||||
drop function if exists f14;
|
||||
drop function if exists f15;
|
||||
create table t1 (i int primary key);
|
||||
insert into t1 values (1), (2), (3), (4), (5);
|
||||
create table t2 (j int primary key);
|
||||
insert into t2 values (1), (2), (3), (4), (5);
|
||||
create table t3 (k int primary key);
|
||||
insert into t3 values (1), (2), (3);
|
||||
create table t4 (l int primary key);
|
||||
insert into t4 values (1);
|
||||
create table t5 (l int primary key);
|
||||
insert into t5 values (1);
|
||||
create table te(e int primary key);
|
||||
insert into te values (1);
|
||||
create view v1 as select i from t1;
|
||||
create view v2 as select j from t2 where j in (select i from t1);
|
||||
create procedure p1(k int) insert into t2 values (k);
|
||||
create function f1() returns int
|
||||
begin
|
||||
declare j int;
|
||||
select i from t1 where i = 1 into j;
|
||||
return j;
|
||||
end|
|
||||
create function f2() returns int
|
||||
begin
|
||||
declare k int;
|
||||
select i from t1 where i = 1 into k;
|
||||
insert into t2 values (k + 5);
|
||||
return 0;
|
||||
end|
|
||||
create function f3() returns int
|
||||
begin
|
||||
return (select i from t1 where i = 3);
|
||||
end|
|
||||
create function f4() returns int
|
||||
begin
|
||||
if (select i from t1 where i = 3) then
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
end if;
|
||||
end|
|
||||
create function f5() returns int
|
||||
begin
|
||||
insert into t2 values ((select i from t1 where i = 1) + 5);
|
||||
return 0;
|
||||
end|
|
||||
create function f6() returns int
|
||||
begin
|
||||
declare k int;
|
||||
select i from v1 where i = 1 into k;
|
||||
return k;
|
||||
end|
|
||||
create function f7() returns int
|
||||
begin
|
||||
declare k int;
|
||||
select j from v2 where j = 1 into k;
|
||||
return k;
|
||||
end|
|
||||
create function f8() returns int
|
||||
begin
|
||||
declare k int;
|
||||
select i from v1 where i = 1 into k;
|
||||
insert into t2 values (k+5);
|
||||
return k;
|
||||
end|
|
||||
create function f9() returns int
|
||||
begin
|
||||
update v2 set j=j+10 where j=1;
|
||||
return 1;
|
||||
end|
|
||||
create function f10() returns int
|
||||
begin
|
||||
return f1();
|
||||
end|
|
||||
create function f11() returns int
|
||||
begin
|
||||
declare k int;
|
||||
set k= f1();
|
||||
insert into t2 values (k+5);
|
||||
return k;
|
||||
end|
|
||||
create function f12(p int) returns int
|
||||
begin
|
||||
insert into t2 values (p);
|
||||
return p;
|
||||
end|
|
||||
create function f13(p int) returns int
|
||||
begin
|
||||
return p;
|
||||
end|
|
||||
create procedure p2(inout p int)
|
||||
begin
|
||||
select i from t1 where i = 1 into p;
|
||||
end|
|
||||
create function f14() returns int
|
||||
begin
|
||||
declare k int;
|
||||
call p2(k);
|
||||
insert into t2 values (k+5);
|
||||
return k;
|
||||
end|
|
||||
create function f15() returns int
|
||||
begin
|
||||
declare k int;
|
||||
call p2(k);
|
||||
return k;
|
||||
end|
|
||||
create trigger t4_bi before insert on t4 for each row
|
||||
begin
|
||||
declare k int;
|
||||
select i from t1 where i=1 into k;
|
||||
set new.l= k+1;
|
||||
end|
|
||||
create trigger t4_bu before update on t4 for each row
|
||||
begin
|
||||
if (select i from t1 where i=1) then
|
||||
set new.l= 2;
|
||||
end if;
|
||||
end|
|
||||
# Trigger below uses insertion of duplicate key in 'te'
|
||||
# table as a way to abort delete operation.
|
||||
create trigger t4_bd before delete on t4 for each row
|
||||
begin
|
||||
if !(select i from v1 where i=1) then
|
||||
insert into te values (1);
|
||||
end if;
|
||||
end|
|
||||
create trigger t5_bi before insert on t5 for each row
|
||||
begin
|
||||
set new.l= f1()+1;
|
||||
end|
|
||||
create trigger t5_bu before update on t5 for each row
|
||||
begin
|
||||
declare j int;
|
||||
call p2(j);
|
||||
set new.l= j + 1;
|
||||
end|
|
||||
#
|
||||
# Set common variables to be used by the scripts
|
||||
# called below.
|
||||
#
|
||||
# Switch to connection 'con1'.
|
||||
# Cache all functions used in the tests below so statements
|
||||
# calling them won't need to open and lock mysql.proc table
|
||||
# and we can assume that each statement locks its tables
|
||||
# once during its execution.
|
||||
show create procedure p1;
|
||||
show create procedure p2;
|
||||
show create function f1;
|
||||
show create function f2;
|
||||
show create function f3;
|
||||
show create function f4;
|
||||
show create function f5;
|
||||
show create function f6;
|
||||
show create function f7;
|
||||
show create function f8;
|
||||
show create function f9;
|
||||
show create function f10;
|
||||
show create function f11;
|
||||
show create function f12;
|
||||
show create function f13;
|
||||
show create function f14;
|
||||
show create function f15;
|
||||
# Switch back to connection 'default'.
|
||||
#
|
||||
# 1. Statements that read tables and do not use subqueries.
|
||||
#
|
||||
#
|
||||
# 1.1 Simple SELECT statement.
|
||||
#
|
||||
# No locks are necessary as this statement won't be written
|
||||
# to the binary log and thanks to how MyISAM works SELECT
|
||||
# will see version of the table prior to concurrent insert.
|
||||
Success: 'select * from t1' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 1.2 Multi-UPDATE statement.
|
||||
#
|
||||
# Has to take shared locks on rows in the table being read as this
|
||||
# statement will be written to the binary log and therefore should
|
||||
# be serialized with concurrent statements.
|
||||
Success: 'update t2, t1 set j= j - 1 where i = j' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 1.3 Multi-DELETE statement.
|
||||
#
|
||||
# The above is true for this statement as well.
|
||||
Success: 'delete t2 from t1, t2 where i = j' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 1.4 DESCRIBE statement.
|
||||
#
|
||||
# This statement does not really read data from the
|
||||
# target table and thus does not take any lock on it.
|
||||
# We check this for completeness of coverage.
|
||||
lock table t1 write;
|
||||
# Switching to connection 'con1'.
|
||||
# This statement should not be blocked.
|
||||
describe t1;
|
||||
# Switching to connection 'default'.
|
||||
unlock tables;
|
||||
#
|
||||
# 1.5 SHOW statements.
|
||||
#
|
||||
# The above is true for SHOW statements as well.
|
||||
lock table t1 write;
|
||||
# Switching to connection 'con1'.
|
||||
# These statements should not be blocked.
|
||||
show keys from t1;
|
||||
# Switching to connection 'default'.
|
||||
unlock tables;
|
||||
#
|
||||
# 2. Statements which read tables through subqueries.
|
||||
#
|
||||
#
|
||||
# 2.1 CALL with a subquery.
|
||||
#
|
||||
# In theory strong lock is not necessary as this statement
|
||||
# is not written to the binary log as a whole (it is written
|
||||
# statement-by-statement). But in practice in 5.1 for
|
||||
# almost everything except SELECT we take strong lock.
|
||||
Success: 'call p1((select i + 5 from t1 where i = 1))' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 2.2 CREATE TABLE with a subquery.
|
||||
#
|
||||
# Has to take a strong lock on the table being read as
|
||||
# this statement is written to the binary log and therefore
|
||||
# should be serialized with concurrent statements.
|
||||
Success: 'create table t0 select * from t1' doesn't allow concurrent inserts into 't1'.
|
||||
drop table t0;
|
||||
Success: 'create table t0 select j from t2 where j in (select i from t1)' doesn't allow concurrent inserts into 't1'.
|
||||
drop table t0;
|
||||
#
|
||||
# 2.3 DELETE with a subquery.
|
||||
#
|
||||
# The above is true for this statement as well.
|
||||
Success: 'delete from t2 where j in (select i from t1)' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 2.4 MULTI-DELETE with a subquery.
|
||||
#
|
||||
# Same is true for this statement as well.
|
||||
Success: 'delete t2 from t3, t2 where k = j and j in (select i from t1)' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 2.5 DO with a subquery.
|
||||
#
|
||||
# In theory strong lock is not necessary as it is not logged.
|
||||
# But in practice in 5.1 for almost everything except SELECT
|
||||
# we take strong lock.
|
||||
Success: 'do (select i from t1 where i = 1)' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 2.6 INSERT with a subquery.
|
||||
#
|
||||
# Has to take a strong lock on the table being read as
|
||||
# this statement is written to the binary log and therefore
|
||||
# should be serialized with concurrent inserts.
|
||||
Success: 'insert into t2 select i+5 from t1' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'insert into t2 values ((select i+5 from t1 where i = 4))' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 2.7 LOAD DATA with a subquery.
|
||||
#
|
||||
# The above is true for this statement as well.
|
||||
Success: 'load data infile '../../std_data/rpl_loaddata.dat' into table t2 (@a, @b) set j= @b + (select i from t1 where i = 1)' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 2.8 REPLACE with a subquery.
|
||||
#
|
||||
# Same is true for this statement as well.
|
||||
Success: 'replace into t2 select i+5 from t1' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'replace into t2 values ((select i+5 from t1 where i = 4))' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 2.9 SELECT with a subquery.
|
||||
#
|
||||
# Strong locks are not necessary as this statement is not written
|
||||
# to the binary log and thanks to how MyISAM works this statement
|
||||
# sees a version of the table prior to the concurrent insert.
|
||||
Success: 'select * from t2 where j in (select i from t1)' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 2.10 SET with a subquery.
|
||||
#
|
||||
# In theory the same is true for this statement as well.
|
||||
# But in practice in 5.1 we acquire strong lock in this
|
||||
# case as well.
|
||||
Success: 'set @a:= (select i from t1 where i = 1)' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 2.11 SHOW with a subquery.
|
||||
#
|
||||
# The same is true for this statement too.
|
||||
Success: 'show tables from test where Tables_in_test = 't2' and (select i from t1 where i = 1)' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'show columns from t2 where (select i from t1 where i = 1)' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 2.12 UPDATE with a subquery.
|
||||
#
|
||||
# Has to take a strong lock on the table being read as
|
||||
# this statement is written to the binary log and therefore
|
||||
# should be serialized with concurrent inserts.
|
||||
Success: 'update t2 set j= j-10 where j in (select i from t1)' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 2.13 MULTI-UPDATE with a subquery.
|
||||
#
|
||||
# Same is true for this statement as well.
|
||||
Success: 'update t2, t3 set j= j -10 where j=k and j in (select i from t1)' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 3. Statements which read tables through a view.
|
||||
#
|
||||
#
|
||||
# 3.1 SELECT statement which uses some table through a view.
|
||||
#
|
||||
# Since this statement is not written to the binary log and
|
||||
# an old version of the table is accessible thanks to how MyISAM
|
||||
# handles concurrent insert, no locking is necessary.
|
||||
Success: 'select * from v1' allows concurrent inserts into 't1'.
|
||||
Success: 'select * from v2' allows concurrent inserts into 't1'.
|
||||
Success: 'select * from t2 where j in (select i from v1)' allows concurrent inserts into 't1'.
|
||||
Success: 'select * from t3 where k in (select j from v2)' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 3.2 Statements which modify a table and use views.
|
||||
#
|
||||
# Since such statements are going to be written to the binary
|
||||
# log they need to be serialized against concurrent statements
|
||||
# and therefore should take strong locks on the data read.
|
||||
Success: 'update t2 set j= j-10 where j in (select i from v1)' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'update t3 set k= k-10 where k in (select j from v2)' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'update t2, v1 set j= j-10 where j = i' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'update v2 set j= j-10 where j = 3' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 4. Statements which read tables through stored functions.
|
||||
#
|
||||
#
|
||||
# 4.1 SELECT/SET with a stored function which does not
|
||||
# modify data and uses SELECT in its turn.
|
||||
#
|
||||
# Calls to such functions won't get into the binary log and
|
||||
# thus don't need to acquire strong locks.
|
||||
# In 5.5 due to fix for bug #53921 "Wrong locks for SELECTs
|
||||
# used stored functions may lead to broken SBR" strong locks
|
||||
# are taken (we accepted it as a trade-off for this fix).
|
||||
Success: 'select f1()' allows concurrent inserts into 't1'.
|
||||
Success: 'set @a:= f1()' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.2 INSERT (or other statement which modifies data) with
|
||||
# a stored function which does not modify data and uses
|
||||
# SELECT.
|
||||
#
|
||||
# Since such statement is written to the binary log it should
|
||||
# be serialized with concurrent statements affecting the data
|
||||
# it uses. Therefore it should take strong lock on the data
|
||||
# it reads.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken.
|
||||
Success: 'insert into t2 values (f1() + 5)' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.3 SELECT/SET with a stored function which
|
||||
# reads and modifies data.
|
||||
#
|
||||
# Since a call to such function is written to the binary log,
|
||||
# it should be serialized with concurrent statements affecting
|
||||
# the data it uses. Hence, a strong lock on the data read
|
||||
# should be taken.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken.
|
||||
Success: 'select f2()' allows concurrent inserts into 't1'.
|
||||
Success: 'set @a:= f2()' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.4. SELECT/SET with a stored function which does not
|
||||
# modify data and reads a table through subselect
|
||||
# in a control construct.
|
||||
#
|
||||
# Again, in theory a call to this function won't get to the
|
||||
# binary log and thus no strong lock is needed. But in practice
|
||||
# we don't detect this fact early enough (get_lock_type_for_table())
|
||||
# to avoid taking a strong lock.
|
||||
Success: 'select f3()' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'set @a:= f3()' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'select f4()' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'set @a:= f4()' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.5. INSERT (or other statement which modifies data) with
|
||||
# a stored function which does not modify data and reads
|
||||
# the table through a subselect in one of its control
|
||||
# constructs.
|
||||
#
|
||||
# Since such statement is written to the binary log it should
|
||||
# be serialized with concurrent statements affecting data it
|
||||
# uses. Therefore it should take a strong lock on the data
|
||||
# it reads.
|
||||
Success: 'insert into t2 values (f3() + 5)' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'insert into t2 values (f4() + 6)' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.6 SELECT/SET which uses a stored function with
|
||||
# DML which reads a table via a subquery.
|
||||
#
|
||||
# Since call to such function is written to the binary log
|
||||
# it should be serialized with concurrent statements.
|
||||
# Hence reads should take a strong lock.
|
||||
Success: 'select f5()' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'set @a:= f5()' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.7 SELECT/SET which uses a stored function which
|
||||
# doesn't modify data and reads tables through
|
||||
# a view.
|
||||
#
|
||||
# Once again, in theory, calls to such functions won't
|
||||
# get into the binary log and thus don't need strong
|
||||
# locks. In practice this fact is discovered
|
||||
# too late to have any effect.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken
|
||||
# in case when simple SELECT is used.
|
||||
Success: 'select f6()' allows concurrent inserts into 't1'.
|
||||
Success: 'set @a:= f6()' allows concurrent inserts into 't1'.
|
||||
Success: 'select f7()' doesn't allow concurrent inserts into 't1'.
|
||||
Success: 'set @a:= f7()' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.8 INSERT which uses stored function which
|
||||
# doesn't modify data and reads a table
|
||||
# through a view.
|
||||
#
|
||||
# Since such statement is written to the binary log and
|
||||
# should be serialized with concurrent statements affecting
|
||||
# the data it uses. Therefore it should take a strong lock on
|
||||
# the table it reads.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken
|
||||
# in case when simple SELECT is used.
|
||||
Success: 'insert into t3 values (f6() + 5)' allows concurrent inserts into 't1'.
|
||||
Success: 'insert into t3 values (f7() + 5)' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.9 SELECT which uses a stored function which
|
||||
# modifies data and reads tables through a view.
|
||||
#
|
||||
# Since a call to such function is written to the binary log
|
||||
# it should be serialized with concurrent statements.
|
||||
# Hence, reads should take strong locks.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken
|
||||
# in case when simple SELECT is used.
|
||||
Success: 'select f8()' allows concurrent inserts into 't1'.
|
||||
Success: 'select f9()' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.10 SELECT which uses a stored function which doesn't modify
|
||||
# data and reads a table indirectly, by calling another
|
||||
# function.
|
||||
#
|
||||
# Calls to such functions won't get into the binary log and
|
||||
# thus don't need to acquire strong locks.
|
||||
# In 5.5 due to fix for bug #53921 "Wrong locks for SELECTs
|
||||
# used stored functions may lead to broken SBR" strong locks
|
||||
# are taken (we accepted it as a trade-off for this fix).
|
||||
Success: 'select f10()' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.11 INSERT which uses a stored function which doesn't modify
|
||||
# data and reads a table indirectly, by calling another
|
||||
# function.
|
||||
#
|
||||
# Since such statement is written to the binary log, it should
|
||||
# be serialized with concurrent statements affecting the data it
|
||||
# uses. Therefore it should take strong locks on data it reads.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken.
|
||||
Success: 'insert into t2 values (f10() + 5)' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.12 SELECT which uses a stored function which modifies
|
||||
# data and reads a table indirectly, by calling another
|
||||
# function.
|
||||
#
|
||||
# Since a call to such function is written to the binary log
|
||||
# it should be serialized from concurrent statements.
|
||||
# Hence, read should take a strong lock.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken.
|
||||
Success: 'select f11()' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.13 SELECT that reads a table through a subquery passed
|
||||
# as a parameter to a stored function which modifies
|
||||
# data.
|
||||
#
|
||||
# Even though a call to this function is written to the
|
||||
# binary log, values of its parameters are written as literals.
|
||||
# So there is no need to acquire strong locks for tables used in
|
||||
# the subquery.
|
||||
Success: 'select f12((select i+10 from t1 where i=1))' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 4.14 INSERT that reads a table via a subquery passed
|
||||
# as a parameter to a stored function which doesn't
|
||||
# modify data.
|
||||
#
|
||||
# Since this statement is written to the binary log it should
|
||||
# be serialized with concurrent statements affecting the data it
|
||||
# uses. Therefore it should take strong locks on the data it reads.
|
||||
Success: 'insert into t2 values (f13((select i+10 from t1 where i=1)))' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 5. Statements that read tables through stored procedures.
|
||||
#
|
||||
#
|
||||
# 5.1 CALL statement which reads a table via SELECT.
|
||||
#
|
||||
# Since neither this statement nor its components are
|
||||
# written to the binary log, there is no need to take
|
||||
# strong locks on the data it reads.
|
||||
Success: 'call p2(@a)' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 5.2 Function that modifies data and uses CALL,
|
||||
# which reads a table through SELECT.
|
||||
#
|
||||
# Since a call to such function is written to the binary
|
||||
# log, it should be serialized with concurrent statements.
|
||||
# Hence, in this case reads should take strong locks on data.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken.
|
||||
Success: 'select f14()' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 5.3 SELECT that calls a function that doesn't modify data and
|
||||
# uses a CALL statement that reads a table via SELECT.
|
||||
#
|
||||
# Calls to such functions won't get into the binary log and
|
||||
# thus don't need to acquire strong locks.
|
||||
# In 5.5 due to fix for bug #53921 "Wrong locks for SELECTs
|
||||
# used stored functions may lead to broken SBR" strong locks
|
||||
# are taken (we accepted it as a trade-off for this fix).
|
||||
Success: 'select f15()' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 5.4 INSERT which calls function which doesn't modify data and
|
||||
# uses CALL statement which reads table through SELECT.
|
||||
#
|
||||
# Since such statement is written to the binary log it should
|
||||
# be serialized with concurrent statements affecting data it
|
||||
# uses. Therefore it should take strong locks on data it reads.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken.
|
||||
Success: 'insert into t2 values (f15()+5)' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 6. Statements that use triggers.
|
||||
#
|
||||
#
|
||||
# 6.1 Statement invoking a trigger that reads table via SELECT.
|
||||
#
|
||||
# Since this statement is written to the binary log it should
|
||||
# be serialized with concurrent statements affecting the data
|
||||
# it uses. Therefore, it should take strong locks on the data
|
||||
# it reads.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken.
|
||||
Success: 'insert into t4 values (2)' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 6.2 Statement invoking a trigger that reads table through
|
||||
# a subquery in a control construct.
|
||||
#
|
||||
# The above is true for this statement as well.
|
||||
Success: 'update t4 set l= 2 where l = 1' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 6.3 Statement invoking a trigger that reads a table through
|
||||
# a view.
|
||||
#
|
||||
# And for this statement.
|
||||
Success: 'delete from t4 where l = 1' doesn't allow concurrent inserts into 't1'.
|
||||
#
|
||||
# 6.4 Statement invoking a trigger that reads a table through
|
||||
# a stored function.
|
||||
#
|
||||
# And for this statement.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken.
|
||||
Success: 'insert into t5 values (2)' allows concurrent inserts into 't1'.
|
||||
#
|
||||
# 6.5 Statement invoking a trigger that reads a table through
|
||||
# stored procedure.
|
||||
#
|
||||
# And for this statement.
|
||||
# But due to bug #53921 "Wrong locks for SELECTs used stored
|
||||
# functions may lead to broken SBR" weak locks are taken.
|
||||
Success: 'update t5 set l= 2 where l = 1' allows concurrent inserts into 't1'.
|
||||
# Clean-up.
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop function f3;
|
||||
drop function f4;
|
||||
drop function f5;
|
||||
drop function f6;
|
||||
drop function f7;
|
||||
drop function f8;
|
||||
drop function f9;
|
||||
drop function f10;
|
||||
drop function f11;
|
||||
drop function f12;
|
||||
drop function f13;
|
||||
drop function f14;
|
||||
drop function f15;
|
||||
drop view v1, v2;
|
||||
drop procedure p1;
|
||||
drop procedure p2;
|
||||
drop table t1, t2, t3, t4, t5, te;
|
||||
set @@global.concurrent_insert= @old_concurrent_insert;
|
@@ -308,8 +308,41 @@ SET @@global.general_log = @old_general_log;
|
||||
SET @@global.general_log_file = @old_general_log_file;
|
||||
SET @@global.slow_query_log = @old_slow_query_log;
|
||||
SET @@global.slow_query_log_file = @old_slow_query_log_file;
|
||||
#
|
||||
# Bug #49756 Rows_examined is always 0 in the slow query log
|
||||
# for update statements
|
||||
#
|
||||
SET @old_log_output = @@global.log_output;
|
||||
SET GLOBAL log_output = "TABLE";
|
||||
SET GLOBAL slow_query_log = ON;
|
||||
SET GLOBAL long_query_time = 0.001;
|
||||
TRUNCATE TABLE mysql.slow_log;
|
||||
CREATE TABLE t1 (a INT);
|
||||
CREATE TABLE t2 (b INT, PRIMARY KEY (b));
|
||||
INSERT INTO t2 VALUES (3),(4);
|
||||
INSERT INTO t1 VALUES (1+sleep(.01)),(2);
|
||||
INSERT INTO t1 SELECT b+sleep(.01) from t2;
|
||||
UPDATE t1 SET a=a+sleep(.01) WHERE a>2;
|
||||
UPDATE t1 SET a=a+sleep(.01) ORDER BY a DESC;
|
||||
UPDATE t2 set b=b+sleep(.01) limit 1;
|
||||
UPDATE t1 SET a=a+sleep(.01) WHERE a in (SELECT b from t2);
|
||||
DELETE FROM t1 WHERE a=a+sleep(.01) ORDER BY a LIMIT 2;
|
||||
SELECT rows_examined,sql_text FROM mysql.slow_log;
|
||||
rows_examined sql_text
|
||||
0 INSERT INTO t1 VALUES (1+sleep(.01)),(2)
|
||||
2 INSERT INTO t1 SELECT b+sleep(.01) from t2
|
||||
4 UPDATE t1 SET a=a+sleep(.01) WHERE a>2
|
||||
8 UPDATE t1 SET a=a+sleep(.01) ORDER BY a DESC
|
||||
2 UPDATE t2 set b=b+sleep(.01) limit 1
|
||||
4 UPDATE t1 SET a=a+sleep(.01) WHERE a in (SELECT b from t2)
|
||||
6 DELETE FROM t1 WHERE a=a+sleep(.01) ORDER BY a LIMIT 2
|
||||
DROP TABLE t1,t2;
|
||||
TRUNCATE TABLE mysql.slow_log;
|
||||
# end of bug#49756
|
||||
End of 5.1 tests
|
||||
# Close connection con1
|
||||
SET GLOBAL long_query_time = DEFAULT;
|
||||
SET GLOBAL log_output = @old_log_output;
|
||||
SET global general_log = @old_general_log;
|
||||
SET global general_log_file = @old_general_log_file;
|
||||
SET global slow_query_log = @old_slow_query_log;
|
||||
|
@@ -602,9 +602,6 @@ select * from t2 /* must be (3,1), (4,4) */;
|
||||
a b
|
||||
3 1
|
||||
4 4
|
||||
show master status /* there must be the UPDATE query event */;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 206
|
||||
delete from t1;
|
||||
delete from t2;
|
||||
insert into t1 values (1,2),(3,4),(4,4);
|
||||
@@ -612,9 +609,6 @@ insert into t2 values (1,2),(3,4),(4,4);
|
||||
reset master;
|
||||
UPDATE t2,t1 SET t2.a=t2.b where t2.a=t1.a;
|
||||
ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
|
||||
show master status /* there must be the UPDATE query event */;
|
||||
File Position Binlog_Do_DB Binlog_Ignore_DB
|
||||
master-bin.000001 221
|
||||
drop table t1, t2;
|
||||
set @@session.binlog_format= @sav_binlog_format;
|
||||
drop table if exists t1, t2, t3;
|
||||
|
@@ -4561,5 +4561,20 @@ a b c
|
||||
SET NAMES default;
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug #53088: mysqldump with -T & --default-character-set set
|
||||
# truncates text/blob to 766 chars
|
||||
#
|
||||
# Also see outfile_loaddata.test
|
||||
#
|
||||
CREATE TABLE t1 (a BLOB) CHARSET latin1;
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
INSERT INTO t1 VALUES (REPEAT('.', 800));
|
||||
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/t1.txt' INTO TABLE t2 CHARACTER SET latin1;
|
||||
# should be 800
|
||||
SELECT LENGTH(a) FROM t2;
|
||||
LENGTH(a)
|
||||
800
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# End of 5.1 tests
|
||||
#
|
||||
|
@@ -239,4 +239,24 @@ a b c
|
||||
2 NULL NULL
|
||||
SET NAMES default;
|
||||
DROP TABLE t1, t2;
|
||||
#
|
||||
# Bug #53088: mysqldump with -T & --default-character-set set
|
||||
# truncates text/blob to 766 chars
|
||||
#
|
||||
# Also see mysqldump.test
|
||||
#
|
||||
CREATE TABLE t1 (a BLOB) CHARSET latin1;
|
||||
CREATE TABLE t2 LIKE t1;
|
||||
INSERT INTO t1 VALUES (REPEAT('.', 800));
|
||||
SELECT * INTO OUTFILE 'MYSQLTEST_VARDIR/tmp/bug53088.txt' CHARACTER SET latin1 FROM t1;
|
||||
# should be greater than 800
|
||||
SELECT LENGTH(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug53088.txt'));
|
||||
LENGTH(LOAD_FILE('MYSQLTEST_VARDIR/tmp/bug53088.txt'))
|
||||
801
|
||||
LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug53088.txt' INTO TABLE t2;
|
||||
# should be 800
|
||||
SELECT LENGTH(a) FROM t2;
|
||||
LENGTH(a)
|
||||
800
|
||||
DROP TABLE t1, t2;
|
||||
# End of 5.1 tests.
|
||||
|
@@ -1,5 +1,29 @@
|
||||
drop table if exists t1;
|
||||
#
|
||||
# Bug#49161: Out of memory; restart server and try again (needed 2 bytes)
|
||||
#
|
||||
CREATE TABLE t1 (a INT) PARTITION BY HASH (a);
|
||||
FLUSH TABLES;
|
||||
CHECK TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check Error Failed to read from the .par file
|
||||
test.t1 check Error Incorrect information in file: './test/t1.frm'
|
||||
test.t1 check error Corrupt
|
||||
SELECT * FROM t1;
|
||||
ERROR HY000: Failed to read from the .par file
|
||||
# Note that it is currently impossible to drop a partitioned table
|
||||
# without the .par file
|
||||
DROP TABLE t1;
|
||||
ERROR 42S02: Unknown table 't1'
|
||||
#
|
||||
# Bug#49477: Assertion `0' failed in ha_partition.cc:5530
|
||||
# with temporary table and partitions
|
||||
#
|
||||
CREATE TABLE t1 (a INT) PARTITION BY HASH(a);
|
||||
CREATE TEMPORARY TABLE tmp_t1 LIKE t1;
|
||||
ERROR HY000: Cannot create temporary table with partitions
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#50392: insert_id is not reset for partitioned tables
|
||||
# auto_increment on duplicate entry
|
||||
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY);
|
||||
|
@@ -1653,4 +1653,48 @@ a b
|
||||
0 0
|
||||
1 1
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug#50939: Loose Index Scan unduly relies on engine to remember range
|
||||
# endpoints
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY ( a, b )
|
||||
) PARTITION BY HASH (a) PARTITIONS 1;
|
||||
CREATE TABLE t2 (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY ( a, b )
|
||||
);
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
|
||||
INSERT INTO t1 SELECT a + 5, b + 5 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 10, b + 10 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 20, b + 20 FROM t1;
|
||||
INSERT INTO t1 SELECT a + 40, b + 40 FROM t1;
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
# plans should be identical
|
||||
EXPLAIN SELECT a, MAX(b) FROM t1 WHERE a IN (10,100) GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index for group-by
|
||||
EXPLAIN SELECT a, MAX(b) FROM t2 WHERE a IN (10,100) GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 range a a 5 NULL 2 Using where; Using index for group-by
|
||||
FLUSH status;
|
||||
SELECT a, MAX(b) FROM t1 WHERE a IN (10, 100) GROUP BY a;
|
||||
a MAX(b)
|
||||
10 10
|
||||
# Should be no more than 4 reads.
|
||||
SHOW status LIKE 'handler_read_key';
|
||||
Variable_name Value
|
||||
Handler_read_key 4
|
||||
FLUSH status;
|
||||
SELECT a, MAX(b) FROM t2 WHERE a IN (10, 100) GROUP BY a;
|
||||
a MAX(b)
|
||||
10 10
|
||||
# Should be no more than 4 reads.
|
||||
SHOW status LIKE 'handler_read_key';
|
||||
Variable_name Value
|
||||
Handler_read_key 4
|
||||
DROP TABLE t1, t2;
|
||||
End of 5.1 tests
|
||||
|
@@ -7,6 +7,6 @@ ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and n
|
||||
ALTER DATABASE `#mysql51#not-yet` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
|
||||
ALTER DATABASE `#mysql50#` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR HY000: Incorrect usage of ALTER DATABASE UPGRADE DATA DIRECTORY NAME and name
|
||||
ERROR 42000: Incorrect database name '#mysql50#'
|
||||
ALTER DATABASE `#mysql50#upgrade-me` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR 42000: Unknown database '#mysql50#upgrade-me'
|
||||
|
@@ -14,13 +14,13 @@ end|
|
||||
reset master|
|
||||
insert into t2 values (bug23333(),1)|
|
||||
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
||||
show binlog events from 106 /* with fixes for #23333 will show there is the query */|
|
||||
show binlog events from <binlog_start>|
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # #
|
||||
master-bin.000001 # Table_map 1 # #
|
||||
master-bin.000001 # Table_map 1 # #
|
||||
master-bin.000001 # Write_rows 1 # #
|
||||
master-bin.000001 # Query 1 # #
|
||||
master-bin.000001 # Query # # BEGIN
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t2)
|
||||
master-bin.000001 # Table_map # # table_id: # (test.t1)
|
||||
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
|
||||
master-bin.000001 # Query # # ROLLBACK
|
||||
select count(*),@a from t1 /* must be 1,1 */|
|
||||
count(*) @a
|
||||
1 1
|
||||
|
@@ -138,3 +138,13 @@ CAST(c AS TIME)
|
||||
00:00:00
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests
|
||||
#
|
||||
# Bug#53942 valgrind warnings with timestamp() function and incomplete datetime values
|
||||
#
|
||||
CREATE TABLE t1(f1 TIME);
|
||||
INSERT INTO t1 VALUES ('23:38:57');
|
||||
SELECT TIMESTAMP(f1,'1') FROM t1;
|
||||
TIMESTAMP(f1,'1')
|
||||
NULL
|
||||
DROP TABLE t1;
|
||||
End of 5.1 tests
|
||||
|
@@ -112,3 +112,31 @@ select * from `a-b-c`.v1;
|
||||
f1
|
||||
drop database `a-b-c`;
|
||||
use test;
|
||||
# End of 5.0 tests
|
||||
#
|
||||
# Bug #53804: serious flaws in the alter database .. upgrade data
|
||||
# directory name command
|
||||
#
|
||||
ALTER DATABASE `#mysql50#:` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR 42000: Unknown database '#mysql50#:'
|
||||
ALTER DATABASE `#mysql50#.` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR 42000: Incorrect database name '#mysql50#.'
|
||||
ALTER DATABASE `#mysql50#../` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR 42000: Incorrect database name '#mysql50#../'
|
||||
ALTER DATABASE `#mysql50#../..` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR 42000: Incorrect database name '#mysql50#../..'
|
||||
ALTER DATABASE `#mysql50#../../` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR 42000: Incorrect database name '#mysql50#../../'
|
||||
ALTER DATABASE `#mysql50#./blablabla` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR 42000: Incorrect database name '#mysql50#./blablabla'
|
||||
ALTER DATABASE `#mysql50#../blablabla` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR 42000: Incorrect database name '#mysql50#../blablabla'
|
||||
ALTER DATABASE `#mysql50#/` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR 42000: Incorrect database name '#mysql50#/'
|
||||
ALTER DATABASE `#mysql50#/.` UPGRADE DATA DIRECTORY NAME;
|
||||
ERROR 42000: Incorrect database name '#mysql50#/.'
|
||||
USE `#mysql50#.`;
|
||||
ERROR 42000: Incorrect database name '#mysql50#.'
|
||||
USE `#mysql50#../blablabla`;
|
||||
ERROR 42000: Incorrect database name '#mysql50#../blablabla'
|
||||
# End of 5.1 tests
|
||||
|
@@ -1,3 +1,4 @@
|
||||
SET @old_debug = @@GLOBAL.debug;
|
||||
set debug= 'T';
|
||||
select @@debug;
|
||||
@@debug
|
||||
@@ -22,4 +23,5 @@ SET GLOBAL debug='';
|
||||
SELECT @@global.debug;
|
||||
@@global.debug
|
||||
|
||||
SET GLOBAL debug=@old_debug;
|
||||
End of 5.1 tests
|
||||
|
Reference in New Issue
Block a user