📄 sp.test
字号:
create view v2 (a) as select a*10 from v1|select * from v2|select id, a from t1, v2|select * from v1, v2|# Nice example where the same view is used on# on different expression levelscreate function f8 () returns int return (select count(*) from v2)|select *, f8() from v1|# Let us test what will happen if function is missingdrop function f1|--error 1356select * from v1|# And what will happen if we have recursion which involves# views and functions ?create function f1() returns int return (select sum(data) from t1) + (select sum(data) from v1)|--error ER_SP_NO_RECURSIONselect f1()|--error ER_SP_NO_RECURSIONselect * from v1|--error ER_SP_NO_RECURSIONselect * from v2|# Back to the normal casesdrop function f1|create function f1() returns int return (select sum(data) from t1)|# Let us also test some weird cases where no real tables is usedcreate function f0() returns int return (select * from (select 100) as r)|select f0()|select *, f0() from (select 1) as t|create view v0 as select f0()|select * from v0|select *, f0() from v0|## Let us test how well prelocking works with explicit LOCK TABLES.#lock tables t1 read, t1 as t11 read|# These should work wellselect f3()|select id, f3() from t1 as t11|# Degenerate cases work too :)select f0()|select * from v0|select *, f0() from v0, (select 123) as d1|# But these should not !--error 1100select id, f3() from t1|--error 1100select f4()|unlock tables|# Let us test how LOCK TABLES which implicitly depends on functions# workslock tables v2 read, mysql.proc read|select * from v2|select * from v1|# These should not work as we have too little instances of tables locked--error 1100select * from v1, t1|--error 1100select f4()|unlock tables|# Tests for handling of temporary tables in functions.## Unlike for permanent tables we should be able to create, use# and drop such tables in functions.# # Simplest function using temporary table. It is also test case for bug # #12198 "Temporary table aliasing does not work inside stored functions"create function f9() returns intbegin declare a, b int; drop temporary table if exists t3; create temporary table t3 (id int); insert into t3 values (1), (2), (3); set a:= (select count(*) from t3); set b:= (select count(*) from t3 t3_alias); return a + b;end|# This will emit warning as t3 was not existing before.select f9()|select f9() from t1 limit 1|# Function which uses both temporary and permanent tables.create function f10() returns intbegin drop temporary table if exists t3; create temporary table t3 (id int); insert into t3 select id from t4; return (select count(*) from t3);end|# Check that we don't ignore completely tables used in function--error ER_NO_SUCH_TABLEselect f10()|create table t4 as select 1 as id|select f10()|# Practical cases which we don't handle well (yet)## Function which does not work because of well-known and documented# limitation of MySQL. We can't use the several instances of the# same temporary table in statement.create function f11() returns intbegin drop temporary table if exists t3; create temporary table t3 (id int); insert into t3 values (1), (2), (3); return (select count(*) from t3 as a, t3 as b);end|--error ER_CANT_REOPEN_TABLEselect f11()|--error ER_CANT_REOPEN_TABLEselect f11() from t1|# We don't handle temporary tables used by nested functions wellcreate function f12_1() returns intbegin drop temporary table if exists t3; create temporary table t3 (id int); insert into t3 values (1), (2), (3); return f12_2();end|create function f12_2() returns int return (select count(*) from t3)|# We need clean start to get errordrop temporary table t3|--error ER_NO_SUCH_TABLEselect f12_1()|--error ER_NO_SUCH_TABLEselect f12_1() from t1 limit 1|# Cleanupdrop function f0|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_1|drop function f12_2|drop view v0|drop view v1|drop view v2|delete from t1 |delete from t2 |drop table t4|# End of non-bug tests## Some "real" examples## fac--disable_warningsdrop table if exists fac|--enable_warningscreate table fac (n int unsigned not null primary key, f bigint unsigned)|--disable_warningsdrop procedure if exists ifac|--enable_warningscreate procedure ifac(n int unsigned)begin declare i int unsigned default 1; if n > 20 then set n = 20; # bigint overflow otherwise end if; while i <= n do begin insert into test.fac values (i, fac(i)); set i = i + 1; end; end while;end|call ifac(20)|select * from fac|drop table fac|--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'show function status like '%f%'|drop procedure ifac|drop function fac|--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'show function status like '%f%'|# primes--disable_warningsdrop table if exists primes|--enable_warningscreate table primes ( i int unsigned not null primary key, p bigint unsigned not null)|insert into primes values ( 0, 3), ( 1, 5), ( 2, 7), ( 3, 11), ( 4, 13), ( 5, 17), ( 6, 19), ( 7, 23), ( 8, 29), ( 9, 31), (10, 37), (11, 41), (12, 43), (13, 47), (14, 53), (15, 59), (16, 61), (17, 67), (18, 71), (19, 73), (20, 79), (21, 83), (22, 89), (23, 97), (24, 101), (25, 103), (26, 107), (27, 109), (28, 113), (29, 127), (30, 131), (31, 137), (32, 139), (33, 149), (34, 151), (35, 157), (36, 163), (37, 167), (38, 173), (39, 179), (40, 181), (41, 191), (42, 193), (43, 197), (44, 199)|--disable_warningsdrop procedure if exists opp|--enable_warningscreate procedure opp(n bigint unsigned, out pp bool)begin declare r double; declare b, s bigint unsigned default 0; set r = sqrt(n); again: loop if s = 45 then set b = b+200, s = 0; else begin declare p bigint unsigned; select t.p into p from test.primes t where t.i = s; if b+p > r then set pp = 1; leave again; end if; if mod(n, b+p) = 0 then set pp = 0; leave again; end if; set s = s+1; end; end if; end loop;end|--disable_warningsdrop procedure if exists ip|--enable_warningscreate procedure ip(m int unsigned)begin declare p bigint unsigned; declare i int unsigned; set i=45, p=201; while i < m do begin declare pp bool default 0; call opp(p, pp); if pp then insert into test.primes values (i, p); set i = i+1; end if; set p = p+2; end; end while;end|show create procedure opp|--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'show procedure status like '%p%'|# This isn't the fastest way in the world to compute prime numbers, so# don't be too ambitious. ;-)call ip(200)|# We don't want to select the entire table here, just pick a few# examples.# The expected result is:# i p# --- ----# 45 211# 100 557# 199 1229select * from primes where i=45 or i=100 or i=199|drop table primes|drop procedure opp|drop procedure ip|--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'show procedure status like '%p%'|# Fibonacci, for recursion test. (Yet Another Numerical series :)#--disable_warningsdrop table if exists fib|--enable_warningscreate table fib ( f bigint unsigned not null )|# We deliberately do it the awkward way, fetching the last two# values from the table, in order to exercise various statements# and table accesses at each turn.--disable_warningsdrop procedure if exists fib|--enable_warningscreate procedure fib(n int unsigned)begin if n > 1 then begin declare x, y bigint unsigned; declare c cursor for select f from fib order by f desc limit 2; open c; fetch c into y; fetch c into x; close c; insert into fib values (x+y); call fib(n-1); end; end if;end|# Enable recursionset @@max_sp_recursion_depth= 20|# Minimum test: recursion of 3 levelsinsert into fib values (0), (1)|call fib(3)|select * from fib order by f asc|delete from fib|# Original test: 20 levels (may run into memory limits!)insert into fib values (0), (1)|call fib(20)|select * from fib order by f asc|drop table fib|drop procedure fib|set @@max_sp_recursion_depth= 0|## Comment & suid#--disable_warningsdrop procedure if exists bar|--enable_warningscreate procedure bar(x char(16), y int) comment "111111111111" sql security invoker insert into test.t1 values (x, y)|--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'show procedure status like 'bar'|alter procedure bar comment "2222222222" sql security definer|alter procedure bar comment "3333333333"|alter procedure bar|show create procedure bar|--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'show procedure status like 'bar'|drop procedure bar|## rexecution#--disable_warningsdrop procedure if exists p1|--enable_warningscreate procedure p1 () select (select s1 from t3) from t3|create table t3 (s1 int)|call p1()|insert into t3 values (1)|call p1()|drop procedure p1|drop table t3|## backticks#--disable_warningsdrop function if exists foo|--enable_warningscreate function `foo` () returns int return 5|select `foo` ()|drop function `foo`|## Implicit LOCK/UNLOCK TABLES for table access in functions#--disable_warningdrop function if exists t1max|--enable_warningscreate function t1max() returns intbegin declare x int; select max(data) into x from t1; return x;end|insert into t1 values ("foo", 3), ("bar", 2), ("zip", 5), ("zap", 1)|select t1max()|drop function t1max|create table t3 ( v char(16) not null primary key, c int unsigned not null)|create function getcount(s char(16)) returns intbegin declare x int; select count(*) into x from t3 where v = s; if x = 0 then insert into t3 values (s, 1); else update t3 set c = c+1 where v = s; end if; return x;end|select * from t1 where data = getcount("bar")|select * from t3|select getcount("zip")|select getcount("zip")|select * from t3|select getcount(id) from t1 where data = 3|select getcount(id) from t1 where data = 5|select * from t3|drop table t3|drop function getcount|## Test cases for old bugs### BUG#822#--disable_warningsdrop procedure if exists bug822|--enable_warningscreate procedure bug822(a_id char(16), a_data int)begin declare n int; select count(*) into n from t1 where id = a_id and data = a_data; if n = 0 then insert into t1 (id, data) values (a_id, a_data); end if;end|delete from t1|call bug822('foo', 42)|call bug822('foo', 42)|call bug822('bar', 666)|select * from t1|delete from t1|drop procedure bug822|## BUG#1495#--disable_warningsdrop procedure if exists bug1495|--enable_warningscreate procedure bug1495()begin declare x int; select data into x from t1 order by id limit 1; if x > 10 then insert into t1 values ("less", x-10); else insert into t1 values ("more", x+10); end if;end|insert into t1 values ('foo', 12)|call bug1495()|delete from t1 where id='foo'|insert into t1 values ('bar', 7)|call bug1495()|delete from t1 where id='bar'|select * from t1|delete from t1|drop procedure bug1495|## BUG#1547#--disable_warningsdrop procedure if exists bug1547|--enable_warningscreate procedure bug1547(s char(16))begin declare x int; select data into x from t1 where s = id limit 1; if x > 10 then insert into t1 values ("less", x-10); else insert into t1 values ("more", x+10); end if;end|insert into t1 values ("foo", 12), ("bar", 7)|call bug1547("foo")|call bug1547("bar")|select * from t1|delete from t1|drop procedure bug1547|## BUG#1656#--disable_warningsdrop table if exists t70|--enable_warningscreate table t70 (s1 int,s2 int)|insert into t70 values (1,2)|--disable_warningsdrop procedure if exists bug1656|--enable_warningscreate procedure bug1656(out p1 int, out p2 int) select * into p1, p1 from t70|call bug1656(@1, @2)|select @1, @2|drop table t70|drop procedure bug1656|## BUG#1862#create table t3(a int)|--disable_warningsdrop procedure if exists bug1862|--enable_warningscreate procedure bug1862()begin insert into t3 values(2); flush tables;end|call bug1862()|# the second call caused a segmentationcall bug1862()|select * from t3|drop table t3|drop procedure bug1862|## BUG#1874#--disable_warningsdrop procedure if exists bug1874|--enable_warningscreate procedure bug1874()begin declare x int; declare y double; select max(data) into x from t1; insert into t2 values ("max", x, 0); select min(data) into x from t1; insert into t2 values ("min", x, 0); select sum(data) into x from t1; insert into t2 values ("sum", x, 0); select avg(data) into y from t1; insert into t2 values ("avg", 0, y);end|insert into t1 (data) values (3), (1), (5), (9), (4)|call bug1874()|select * from t2|delete from t1|delete from t2|drop procedure bug1874|## BUG#2260#--disable_warningsdrop procedure if exists bug2260|--enable_warningscreate procedure bug2260()begin declare v1 int; declare c1 cursor for select data from t1; declare continue handler for not found set @x2 = 1; open c1; fetch c1 into v1; set @x2 = 2; close c1;end|call bug2260()|select @x2|drop procedure bug2260|
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -