Commit ede52616 authored by unknown's avatar unknown

Fixed BUG#8408: Stored procedure crash if function contains SHOW

  We simply have to disallow any kind of result set being sent back
  from a function. Can't see any way to make that to work.


mysql-test/r/sp-error.result:
  New test case for BUG#8408.
mysql-test/t/sp-error.test:
  New test case for BUG#8408.
sql/item_func.cc:
  Disable result sets from functions but temporarily turning CLIENT_MULTI_RESULTS off.
sql/share/errmsg.txt:
  Added error message for statements not allowed in functions (detected during parsing).
sql/sql_yacc.yy:
  Don't allow result sets in functions.
parent 22311d27
......@@ -594,4 +594,52 @@ alter function bug7047;
return 0;
end|
ERROR HY000: Can't drop or alter a FUNCTION from within another stored routine
drop function if exists bug8408|
drop procedure if exists bug8408|
create function bug8408() returns int
begin
select * from t1;
return 0;
end|
ERROR 0A000: Not allowed to return a result set from a function
create function bug8408() returns int
begin
show warnings;
return 0;
end|
ERROR 0A000: Not allowed to return a result set from a function
create function bug8408(a int) returns int
begin
declare b int;
select b;
return b;
end|
ERROR 0A000: Not allowed to return a result set from a function
create function bug8408() returns int
begin
call bug8408();
return 0;
end|
create procedure bug8408()
select * from t1|
call bug8408()|
val x
select bug8408()|
ERROR 0A000: SELECT in a stored procedure must have INTO
drop procedure bug8408|
drop function bug8408|
create function bug8408() returns int
begin
declare n int default 0;
select count(*) into n from t1;
return n;
end|
insert into t1 value (2, 2.7), (3, 3.14), (7, 7.0)|
select *,bug8408() from t1|
val x bug8408()
2 2.7 3
3 3.14 3
7 7 3
drop function bug8408|
delete from t1|
drop table t1|
......@@ -831,6 +831,67 @@ begin
end|
#
# BUG#8408: Stored procedure crash if function contains SHOW
# BUG#9058: Stored Procedures: Crash if function included SELECT
#
--disable_warnings
drop function if exists bug8408|
drop procedure if exists bug8408|
--enable_warnings
# Some things are caught when parsing
--error ER_SP_NO_RETSET_IN_FUNC
create function bug8408() returns int
begin
select * from t1;
return 0;
end|
--error ER_SP_NO_RETSET_IN_FUNC
create function bug8408() returns int
begin
show warnings;
return 0;
end|
--error ER_SP_NO_RETSET_IN_FUNC
create function bug8408(a int) returns int
begin
declare b int;
select b;
return b;
end|
# Some things must be caught at invokation time
create function bug8408() returns int
begin
call bug8408();
return 0;
end|
create procedure bug8408()
select * from t1|
call bug8408()|
--error ER_SP_BADSELECT
select bug8408()|
drop procedure bug8408|
drop function bug8408|
# But this is ok
create function bug8408() returns int
begin
declare n int default 0;
select count(*) into n from t1;
return n;
end|
insert into t1 value (2, 2.7), (3, 3.14), (7, 7.0)|
select *,bug8408() from t1|
drop function bug8408|
delete from t1|
#
# BUG#NNNN: New bug synopsis
#
......
......@@ -4554,6 +4554,7 @@ Item_func_sp::execute(Item **itp)
{
DBUG_ENTER("Item_func_sp::execute");
THD *thd= current_thd;
bool clcap_mr;
int res;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
st_sp_security_context save_ctx;
......@@ -4567,6 +4568,9 @@ Item_func_sp::execute(Item **itp)
DBUG_RETURN(-1);
}
clcap_mr= (thd->client_capabilities & CLIENT_MULTI_RESULTS);
thd->client_capabilities &= ~CLIENT_MULTI_RESULTS;
#ifndef EMBEDDED_LIBRARY
my_bool nsok= thd->net.no_send_ok;
thd->net.no_send_ok= TRUE;
......@@ -4582,6 +4586,8 @@ Item_func_sp::execute(Item **itp)
m_sp->m_db.str, m_sp->m_name.str, 0))
{
sp_restore_security_context(thd, m_sp, &save_ctx);
if (clcap_mr)
thd->client_capabilities |= CLIENT_MULTI_RESULTS;
DBUG_RETURN(-1);
}
#endif
......@@ -4595,6 +4601,10 @@ Item_func_sp::execute(Item **itp)
#ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok;
#endif
if (clcap_mr)
thd->client_capabilities |= CLIENT_MULTI_RESULTS;
DBUG_RETURN(res);
}
......
......@@ -5342,3 +5342,5 @@ ER_SP_DUP_HANDLER 42000
eng "Duplicate handler declared in the same block"
ER_SP_NOT_VAR_ARG 42000
eng "OUT or INOUT argument %d for routine %s is not a variable"
ER_SP_NO_RETSET_IN_FUNC 0A000
eng "Not allowed to return a result set from a function"
......@@ -1442,6 +1442,12 @@ create_function_tail:
LEX *lex= Lex;
sp_head *sp= lex->sphead;
if (sp->m_multi_results)
{
my_message(ER_SP_NO_RETSET_IN_FUNC, ER(ER_SP_NO_RETSET_IN_FUNC),
MYF(0));
YYABORT;
}
if (sp->check_backpatch(YYTHD))
YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment