mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/dlenev/src/mysql-5.0-bg11394 mysql-test/r/sp.result: Auto merged mysql-test/t/sp.test: Auto merged sql/sp_head.cc: Auto merged sql/sp_head.h: Auto merged mysql-test/r/sp-error.result: Manual merge. mysql-test/t/sp-error.test: Manual merge. sql/share/errmsg.txt: Manual merge.
This commit is contained in:
@ -665,3 +665,43 @@ TEMP_SUM
|
||||
0
|
||||
drop procedure SP001;
|
||||
drop table t1, t2;
|
||||
drop function if exists bug11394|
|
||||
drop function if exists bug11394_1|
|
||||
drop function if exists bug11394_2|
|
||||
drop procedure if exists bug11394|
|
||||
create function bug11394(i int) returns int
|
||||
begin
|
||||
if i <= 0 then
|
||||
return 0;
|
||||
else
|
||||
return (i in (100, 200, bug11394(i-1), 400));
|
||||
end if;
|
||||
end|
|
||||
select bug11394(2)|
|
||||
ERROR HY000: Recursive stored routines are not allowed.
|
||||
drop function bug11394|
|
||||
create function bug11394_1(i int) returns int
|
||||
begin
|
||||
if i <= 0 then
|
||||
return 0;
|
||||
else
|
||||
return (select bug11394_1(i-1));
|
||||
end if;
|
||||
end|
|
||||
select bug11394_1(2)|
|
||||
ERROR HY000: Recursive stored routines are not allowed.
|
||||
drop function bug11394_1|
|
||||
create function bug11394_2(i int) returns int return i|
|
||||
select bug11394_2(bug11394_2(10))|
|
||||
bug11394_2(bug11394_2(10))
|
||||
10
|
||||
drop function bug11394_2|
|
||||
create procedure bug11394(i int, j int)
|
||||
begin
|
||||
if i > 0 then
|
||||
call bug11394(i - 1,(select 1));
|
||||
end if;
|
||||
end|
|
||||
call bug11394(2, 1)|
|
||||
ERROR HY000: Recursive stored routines are not allowed.
|
||||
drop procedure bug11394|
|
||||
|
@ -1257,60 +1257,6 @@ drop procedure opp|
|
||||
drop procedure ip|
|
||||
show procedure status like '%p%'|
|
||||
Db Name Type Definer Modified Created Security_type Comment
|
||||
drop table if exists fib|
|
||||
create table fib ( f bigint unsigned not null )|
|
||||
drop procedure if exists fib|
|
||||
create 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|
|
||||
insert into fib values (0), (1)|
|
||||
call fib(3)|
|
||||
select * from fib order by f asc|
|
||||
f
|
||||
0
|
||||
1
|
||||
1
|
||||
2
|
||||
delete from fib|
|
||||
insert into fib values (0), (1)|
|
||||
call fib(20)|
|
||||
select * from fib order by f asc|
|
||||
f
|
||||
0
|
||||
1
|
||||
1
|
||||
2
|
||||
3
|
||||
5
|
||||
8
|
||||
13
|
||||
21
|
||||
34
|
||||
55
|
||||
89
|
||||
144
|
||||
233
|
||||
377
|
||||
610
|
||||
987
|
||||
1597
|
||||
2584
|
||||
4181
|
||||
6765
|
||||
drop table fib|
|
||||
drop procedure fib|
|
||||
drop procedure if exists bar|
|
||||
create procedure bar(x char(16), y int)
|
||||
comment "111111111111" sql security invoker
|
||||
@ -2367,20 +2313,6 @@ s1
|
||||
1
|
||||
drop procedure bug4905|
|
||||
drop table t3|
|
||||
drop function if exists bug6022|
|
||||
drop function if exists bug6022|
|
||||
create function bug6022(x int) returns int
|
||||
begin
|
||||
if x < 0 then
|
||||
return 0;
|
||||
else
|
||||
return bug6022(x-1);
|
||||
end if;
|
||||
end|
|
||||
select bug6022(5)|
|
||||
bug6022(5)
|
||||
0
|
||||
drop function bug6022|
|
||||
drop procedure if exists bug6029|
|
||||
drop procedure if exists bug6029|
|
||||
create procedure bug6029()
|
||||
|
@ -971,3 +971,58 @@ delimiter ;|
|
||||
call SP001();
|
||||
drop procedure SP001;
|
||||
drop table t1, t2;
|
||||
|
||||
# Bug #11394 "Recursion in SP crash server" and bug #11600 "Stored
|
||||
# procedures: crash with function calling itself".
|
||||
# We have to disable recursion since in many cases LEX and many
|
||||
# Item's can't be used in reentrant way nowdays.
|
||||
delimiter |;
|
||||
--disable_warnings
|
||||
drop function if exists bug11394|
|
||||
drop function if exists bug11394_1|
|
||||
drop function if exists bug11394_2|
|
||||
drop procedure if exists bug11394|
|
||||
--enable_warnings
|
||||
create function bug11394(i int) returns int
|
||||
begin
|
||||
if i <= 0 then
|
||||
return 0;
|
||||
else
|
||||
return (i in (100, 200, bug11394(i-1), 400));
|
||||
end if;
|
||||
end|
|
||||
# If we allow recursive functions without additional modifications
|
||||
# this will crash server since Item for "IN" is not reenterable.
|
||||
--error 1423
|
||||
select bug11394(2)|
|
||||
drop function bug11394|
|
||||
create function bug11394_1(i int) returns int
|
||||
begin
|
||||
if i <= 0 then
|
||||
return 0;
|
||||
else
|
||||
return (select bug11394_1(i-1));
|
||||
end if;
|
||||
end|
|
||||
# The following statement will crash because some LEX members responsible
|
||||
# for selects cannot be used in reentrant fashion.
|
||||
--error 1423
|
||||
select bug11394_1(2)|
|
||||
drop function bug11394_1|
|
||||
# Note that the following should be allowed since it does not contains
|
||||
# recursion
|
||||
create function bug11394_2(i int) returns int return i|
|
||||
select bug11394_2(bug11394_2(10))|
|
||||
drop function bug11394_2|
|
||||
create procedure bug11394(i int, j int)
|
||||
begin
|
||||
if i > 0 then
|
||||
call bug11394(i - 1,(select 1));
|
||||
end if;
|
||||
end|
|
||||
# Again if we allow recursion for stored procedures (without
|
||||
# additional efforts) the following statement will crash the server.
|
||||
--error 1423
|
||||
call bug11394(2, 1)|
|
||||
drop procedure bug11394|
|
||||
delimiter |;
|
||||
|
@ -1498,54 +1498,56 @@ show procedure status like '%p%'|
|
||||
|
||||
|
||||
# Fibonacci, for recursion test. (Yet Another Numerical series :)
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists fib|
|
||||
--enable_warnings
|
||||
create 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_warnings
|
||||
drop procedure if exists fib|
|
||||
--enable_warnings
|
||||
create 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|
|
||||
|
||||
# Minimum test: recursion of 3 levels
|
||||
|
||||
insert 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|
|
||||
#
|
||||
# This part of test is disabled until we implement support for
|
||||
# recursive stored procedures.
|
||||
#--disable_warnings
|
||||
#drop table if exists fib|
|
||||
#--enable_warnings
|
||||
#create 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_warnings
|
||||
#drop procedure if exists fib|
|
||||
#--enable_warnings
|
||||
#create 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|
|
||||
#
|
||||
## Minimum test: recursion of 3 levels
|
||||
#
|
||||
#insert 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|
|
||||
|
||||
|
||||
#
|
||||
@ -2879,24 +2881,26 @@ drop table t3|
|
||||
#
|
||||
# BUG#6022: Stored procedure shutdown problem with self-calling function.
|
||||
#
|
||||
--disable_warnings
|
||||
drop function if exists bug6022|
|
||||
--enable_warnings
|
||||
|
||||
--disable_warnings
|
||||
drop function if exists bug6022|
|
||||
--enable_warnings
|
||||
create function bug6022(x int) returns int
|
||||
begin
|
||||
if x < 0 then
|
||||
return 0;
|
||||
else
|
||||
return bug6022(x-1);
|
||||
end if;
|
||||
end|
|
||||
|
||||
select bug6022(5)|
|
||||
drop function bug6022|
|
||||
# This part of test is disabled until we implement support for
|
||||
# recursive stored functions.
|
||||
#--disable_warnings
|
||||
#drop function if exists bug6022|
|
||||
#--enable_warnings
|
||||
#
|
||||
#--disable_warnings
|
||||
#drop function if exists bug6022|
|
||||
#--enable_warnings
|
||||
#create function bug6022(x int) returns int
|
||||
#begin
|
||||
# if x < 0 then
|
||||
# return 0;
|
||||
# else
|
||||
# return bug6022(x-1);
|
||||
# end if;
|
||||
#end|
|
||||
#
|
||||
#select bug6022(5)|
|
||||
#drop function bug6022|
|
||||
|
||||
#
|
||||
# BUG#6029: Stored procedure specific handlers should have priority
|
||||
|
@ -5360,3 +5360,5 @@ ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
|
||||
eng "Explicit or implicit commit is not allowed in stored function or trigger."
|
||||
ER_NO_DEFAULT_FOR_VIEW_FIELD
|
||||
eng "Field of view '%-.64s.%-.64s' underlying table doesn't have a default value"
|
||||
ER_SP_NO_RECURSION
|
||||
eng "Recursive stored routines are not allowed."
|
||||
|
@ -312,7 +312,8 @@ sp_head::operator delete(void *ptr, size_t size)
|
||||
sp_head::sp_head()
|
||||
:Query_arena(&main_mem_root, INITIALIZED_FOR_SP),
|
||||
m_returns_cs(NULL), m_has_return(FALSE),
|
||||
m_simple_case(FALSE), m_multi_results(FALSE), m_in_handler(FALSE)
|
||||
m_simple_case(FALSE), m_multi_results(FALSE), m_in_handler(FALSE),
|
||||
m_is_invoked(FALSE)
|
||||
{
|
||||
extern byte *
|
||||
sp_table_key(const byte *ptr, uint *plen, my_bool first);
|
||||
@ -587,6 +588,28 @@ sp_head::execute(THD *thd)
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
if (m_is_invoked)
|
||||
{
|
||||
/*
|
||||
We have to disable recursion for stored routines since in
|
||||
many cases LEX structure and many Item's can't be used in
|
||||
reentrant way now.
|
||||
|
||||
TODO: We can circumvent this problem by using separate
|
||||
sp_head instances for each recursive invocation.
|
||||
|
||||
NOTE: Theoretically arguments of procedure can be evaluated
|
||||
before its invocation so there should be no problem with
|
||||
recursion. But since we perform cleanup for CALL statement
|
||||
as for any other statement only after its execution, its LEX
|
||||
structure is not reusable for recursive calls. Thus we have
|
||||
to prohibit recursion for stored procedures too.
|
||||
*/
|
||||
my_error(ER_SP_NO_RECURSION, MYF(0));
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
m_is_invoked= TRUE;
|
||||
|
||||
dbchanged= FALSE;
|
||||
if (m_db.length &&
|
||||
(ret= sp_use_new_db(thd, m_db.str, olddb, sizeof(olddb), 0, &dbchanged)))
|
||||
@ -710,6 +733,7 @@ sp_head::execute(THD *thd)
|
||||
if (! thd->killed)
|
||||
ret= sp_change_db(thd, olddb, 0);
|
||||
}
|
||||
m_is_invoked= FALSE;
|
||||
DBUG_RETURN(ret);
|
||||
}
|
||||
|
||||
|
@ -259,6 +259,9 @@ private:
|
||||
*/
|
||||
HASH m_sptabs;
|
||||
|
||||
/* Used for tracking of routine invocations and preventing recursion. */
|
||||
bool m_is_invoked;
|
||||
|
||||
int
|
||||
execute(THD *thd);
|
||||
|
||||
|
Reference in New Issue
Block a user