Commit 10cdb0e1 authored by unknown's avatar unknown

Fixed BUG#2267: Lost connect if stored procedure has SHOW FUNCTION STATUS.

(This might not be enough, could be more statements that must be detected...)


mysql-test/r/sp.result:
  Test case for BUG#2267
mysql-test/t/sp.test:
  Test case for BUG#2267
sql/sp.cc:
  Code clean-up: Get the correct order of print-outs in debug trace.
sql/sql_yacc.yy:
  Detect "select-like" statements so that the multi result flag is set correctly.
parent 1f24d2f4
...@@ -908,6 +908,52 @@ select @x2| ...@@ -908,6 +908,52 @@ select @x2|
@x2 @x2
2 2
drop procedure bug2260| drop procedure bug2260|
create procedure bug2267_1()
begin
show procedure status;
end|
create procedure bug2267_2()
begin
show function status;
end|
create procedure bug2267_3()
begin
show create procedure bug2267_1;
end|
create procedure bug2267_4()
begin
show create function fac;
end|
call bug2267_1()|
Name Type Definer Modified Created Security_type Comment
bug2267_1 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
bug2267_2 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
bug2267_3 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
bug2267_4 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
call bug2267_2()|
Name Type Definer Modified Created Security_type Comment
fac FUNCTION root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
call bug2267_3()|
Procedure Create Procedure
bug2267_1 CREATE PROCEDURE `bug2267_1`()
begin
show procedure status;
end
call bug2267_4()|
Function Create Function
fac CREATE FUNCTION `fac`(n int unsigned) RETURNS bigint unsigned
begin
declare f bigint unsigned default 1;
while n > 1 do
set f = f * n;
set n = n - 1;
end while;
return f;
end
drop procedure bug2267_1|
drop procedure bug2267_2|
drop procedure bug2267_3|
drop procedure bug2267_4|
drop table if exists fac| drop table if exists fac|
create table fac (n int unsigned not null primary key, f bigint unsigned)| create table fac (n int unsigned not null primary key, f bigint unsigned)|
create procedure ifac(n int unsigned) create procedure ifac(n int unsigned)
......
...@@ -1055,6 +1055,41 @@ call bug2260()| ...@@ -1055,6 +1055,41 @@ call bug2260()|
select @x2| select @x2|
drop procedure bug2260| drop procedure bug2260|
#
# BUG#2267
#
create procedure bug2267_1()
begin
show procedure status;
end|
create procedure bug2267_2()
begin
show function status;
end|
create procedure bug2267_3()
begin
show create procedure bug2267_1;
end|
create procedure bug2267_4()
begin
show create function fac;
end|
--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00'
call bug2267_1()|
--replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00'
call bug2267_2()|
call bug2267_3()|
call bug2267_4()|
drop procedure bug2267_1|
drop procedure bug2267_2|
drop procedure bug2267_3|
drop procedure bug2267_4|
# #
# Some "real" examples # Some "real" examples
......
...@@ -570,20 +570,25 @@ sp_find_procedure(THD *thd, LEX_STRING *name) ...@@ -570,20 +570,25 @@ sp_find_procedure(THD *thd, LEX_STRING *name)
int int
sp_create_procedure(THD *thd, sp_head *sp) sp_create_procedure(THD *thd, sp_head *sp)
{ {
int ret;
DBUG_ENTER("sp_create_procedure"); DBUG_ENTER("sp_create_procedure");
DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str)); DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str));
DBUG_RETURN(db_create_routine(thd, TYPE_ENUM_PROCEDURE, sp));
ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, sp);
DBUG_RETURN(ret);
} }
int int
sp_drop_procedure(THD *thd, char *name, uint namelen) sp_drop_procedure(THD *thd, char *name, uint namelen)
{ {
int ret;
DBUG_ENTER("sp_drop_procedure"); DBUG_ENTER("sp_drop_procedure");
DBUG_PRINT("enter", ("name: %*s", namelen, name)); DBUG_PRINT("enter", ("name: %*s", namelen, name));
sp_cache_remove(&thd->sp_proc_cache, name, namelen); sp_cache_remove(&thd->sp_proc_cache, name, namelen);
DBUG_RETURN(db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen)); ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen);
DBUG_RETURN(ret);
} }
...@@ -592,12 +597,14 @@ sp_update_procedure(THD *thd, char *name, uint namelen, ...@@ -592,12 +597,14 @@ sp_update_procedure(THD *thd, char *name, uint namelen,
char *newname, uint newnamelen, char *newname, uint newnamelen,
st_sp_chistics *chistics) st_sp_chistics *chistics)
{ {
int ret;
DBUG_ENTER("sp_update_procedure"); DBUG_ENTER("sp_update_procedure");
DBUG_PRINT("enter", ("name: %*s", namelen, name)); DBUG_PRINT("enter", ("name: %*s", namelen, name));
sp_cache_remove(&thd->sp_proc_cache, name, namelen); sp_cache_remove(&thd->sp_proc_cache, name, namelen);
DBUG_RETURN(db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen, ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen,
newname, newnamelen, chistics)); newname, newnamelen, chistics);
DBUG_RETURN(ret);
} }
...@@ -609,7 +616,11 @@ sp_show_create_procedure(THD *thd, LEX_STRING *name) ...@@ -609,7 +616,11 @@ sp_show_create_procedure(THD *thd, LEX_STRING *name)
DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); DBUG_PRINT("enter", ("name: %*s", name->length, name->str));
if ((sp= sp_find_procedure(thd, name))) if ((sp= sp_find_procedure(thd, name)))
DBUG_RETURN(sp->show_create_procedure(thd)); {
int ret= sp->show_create_procedure(thd);
DBUG_RETURN(ret);
}
DBUG_RETURN(SP_KEY_NOT_FOUND); DBUG_RETURN(SP_KEY_NOT_FOUND);
} }
...@@ -618,8 +629,11 @@ sp_show_create_procedure(THD *thd, LEX_STRING *name) ...@@ -618,8 +629,11 @@ sp_show_create_procedure(THD *thd, LEX_STRING *name)
int int
sp_show_status_procedure(THD *thd, const char *wild) sp_show_status_procedure(THD *thd, const char *wild)
{ {
int ret;
DBUG_ENTER("sp_show_status_procedure"); DBUG_ENTER("sp_show_status_procedure");
DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_PROCEDURE, wild));
ret= db_show_routine_status(thd, TYPE_ENUM_PROCEDURE, wild);
DBUG_RETURN(ret);
} }
...@@ -649,21 +663,25 @@ sp_find_function(THD *thd, LEX_STRING *name) ...@@ -649,21 +663,25 @@ sp_find_function(THD *thd, LEX_STRING *name)
int int
sp_create_function(THD *thd, sp_head *sp) sp_create_function(THD *thd, sp_head *sp)
{ {
int ret;
DBUG_ENTER("sp_create_function"); DBUG_ENTER("sp_create_function");
DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str)); DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str));
DBUG_RETURN(db_create_routine(thd, TYPE_ENUM_FUNCTION, sp)); ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, sp);
DBUG_RETURN(ret);
} }
int int
sp_drop_function(THD *thd, char *name, uint namelen) sp_drop_function(THD *thd, char *name, uint namelen)
{ {
int ret;
DBUG_ENTER("sp_drop_function"); DBUG_ENTER("sp_drop_function");
DBUG_PRINT("enter", ("name: %*s", namelen, name)); DBUG_PRINT("enter", ("name: %*s", namelen, name));
sp_cache_remove(&thd->sp_func_cache, name, namelen); sp_cache_remove(&thd->sp_func_cache, name, namelen);
DBUG_RETURN(db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen)); ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen);
DBUG_RETURN(ret);
} }
...@@ -672,12 +690,14 @@ sp_update_function(THD *thd, char *name, uint namelen, ...@@ -672,12 +690,14 @@ sp_update_function(THD *thd, char *name, uint namelen,
char *newname, uint newnamelen, char *newname, uint newnamelen,
st_sp_chistics *chistics) st_sp_chistics *chistics)
{ {
int ret;
DBUG_ENTER("sp_update_procedure"); DBUG_ENTER("sp_update_procedure");
DBUG_PRINT("enter", ("name: %*s", namelen, name)); DBUG_PRINT("enter", ("name: %*s", namelen, name));
sp_cache_remove(&thd->sp_func_cache, name, namelen); sp_cache_remove(&thd->sp_func_cache, name, namelen);
DBUG_RETURN(db_update_routine(thd, TYPE_ENUM_FUNCTION, name, namelen, ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, namelen,
newname, newnamelen, chistics)); newname, newnamelen, chistics);
DBUG_RETURN(ret);
} }
...@@ -689,7 +709,11 @@ sp_show_create_function(THD *thd, LEX_STRING *name) ...@@ -689,7 +709,11 @@ sp_show_create_function(THD *thd, LEX_STRING *name)
DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); DBUG_PRINT("enter", ("name: %*s", name->length, name->str));
if ((sp= sp_find_function(thd, name))) if ((sp= sp_find_function(thd, name)))
DBUG_RETURN(sp->show_create_function(thd)); {
int ret= sp->show_create_function(thd);
DBUG_RETURN(ret);
}
DBUG_RETURN(SP_KEY_NOT_FOUND); DBUG_RETURN(SP_KEY_NOT_FOUND);
} }
...@@ -697,8 +721,10 @@ sp_show_create_function(THD *thd, LEX_STRING *name) ...@@ -697,8 +721,10 @@ sp_show_create_function(THD *thd, LEX_STRING *name)
int int
sp_show_status_function(THD *thd, const char *wild) sp_show_status_function(THD *thd, const char *wild)
{ {
int ret;
DBUG_ENTER("sp_show_status_function"); DBUG_ENTER("sp_show_status_function");
DBUG_RETURN(db_show_routine_status(thd, TYPE_ENUM_FUNCTION, wild)); ret= db_show_routine_status(thd, TYPE_ENUM_FUNCTION, wild);
DBUG_RETURN(ret);
} }
......
...@@ -1572,7 +1572,13 @@ sp_proc_stmt: ...@@ -1572,7 +1572,13 @@ sp_proc_stmt:
{ {
LEX *lex= Lex; LEX *lex= Lex;
if (lex->sql_command == SQLCOM_SELECT && !lex->result) /* QQ What else? This doesn't seem to be a practical way,
but at the moment we can't think of anything better... */
if ((lex->sql_command == SQLCOM_SELECT && !lex->result) ||
lex->sql_command == SQLCOM_SHOW_CREATE_PROC ||
lex->sql_command == SQLCOM_SHOW_CREATE_FUNC ||
lex->sql_command == SQLCOM_SHOW_STATUS_PROC ||
lex->sql_command == SQLCOM_SHOW_STATUS_FUNC)
{ {
/* We maybe have one or more SELECT without INTO */ /* We maybe have one or more SELECT without INTO */
lex->sphead->m_multi_results= TRUE; lex->sphead->m_multi_results= TRUE;
......
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