Commit bee76b78 authored by konstantin@mysql.com's avatar konstantin@mysql.com

A fix and a test case for Bug#13587 "Server crash when SP is created

without database"
parent 867e790d
...@@ -872,3 +872,14 @@ names ...@@ -872,3 +872,14 @@ names
foo4 foo4
drop procedure bug13510_3| drop procedure bug13510_3|
drop procedure bug13510_4| drop procedure bug13510_4|
create database mysqltest1;
use mysqltest1;
drop database mysqltest1;
create function f1() returns int return 1;
ERROR 3D000: No database selected
create procedure p1(out param1 int)
begin
select count(*) into param1 from t3;
end|
ERROR 3D000: No database selected
use test;
...@@ -1266,6 +1266,24 @@ drop procedure bug13510_4| ...@@ -1266,6 +1266,24 @@ drop procedure bug13510_4|
delimiter ;| delimiter ;|
# #
# Bug#13514 "server crash when create a stored procedure before choose a
# database" and
# Bug#13587 "Server crash when SP is created without database
# selected"
#
create database mysqltest1;
use mysqltest1;
drop database mysqltest1;
--error ER_NO_DB_ERROR
create function f1() returns int return 1;
delimiter |;
--error ER_NO_DB_ERROR
create procedure p1(out param1 int)
begin
select count(*) into param1 from t3;
end|
delimiter ;|
use test;
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #
#--disable_warnings #--disable_warnings
......
...@@ -4068,6 +4068,19 @@ end_with_restore_list: ...@@ -4068,6 +4068,19 @@ end_with_restore_list:
DBUG_ASSERT(lex->sphead != 0); DBUG_ASSERT(lex->sphead != 0);
if (!lex->sphead->m_db.str || !lex->sphead->m_db.str[0])
{
if (! thd->db)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
delete lex->sphead;
lex->sphead= 0;
goto error;
}
lex->sphead->m_db.length= strlen(thd->db);
lex->sphead->m_db.str= thd->db;
}
if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0, if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0,
is_schema_db(lex->sphead->m_db.str))) is_schema_db(lex->sphead->m_db.str)))
{ {
...@@ -4077,13 +4090,10 @@ end_with_restore_list: ...@@ -4077,13 +4090,10 @@ end_with_restore_list:
} }
if (end_active_trans(thd)) if (end_active_trans(thd))
goto error;
if (!lex->sphead->m_db.str || !lex->sphead->m_db.str[0])
{ {
lex->sphead->m_db.length= strlen(thd->db); delete lex->sphead;
lex->sphead->m_db.str= strmake_root(thd->mem_root, thd->db, lex->sphead= 0;
lex->sphead->m_db.length); goto error;
} }
name= lex->sphead->name(&namelen); name= lex->sphead->name(&namelen);
...@@ -4110,11 +4120,23 @@ end_with_restore_list: ...@@ -4110,11 +4120,23 @@ end_with_restore_list:
goto error; goto error;
} }
/*
We need to copy name and db in order to use them for
check_routine_access which is called after lex->sphead has
been deleted.
*/
name= thd->strdup(name); name= thd->strdup(name);
db= thd->strmake(lex->sphead->m_db.str, lex->sphead->m_db.length); lex->sphead->m_db.str= db= thd->strmake(lex->sphead->m_db.str,
lex->sphead->m_db.length);
res= (result= lex->sphead->create(thd)); res= (result= lex->sphead->create(thd));
if (result == SP_OK) if (result == SP_OK)
{ {
/*
We must cleanup the unit and the lex here because
sp_grant_privileges calls (indirectly) db_find_routine,
which in turn may call yyparse with THD::lex.
TODO: fix db_find_routine to use a temporary lex.
*/
lex->unit.cleanup(); lex->unit.cleanup();
delete lex->sphead; delete lex->sphead;
lex->sphead= 0; lex->sphead= 0;
......
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