Commit 33c972e4 authored by unknown's avatar unknown
Browse files

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

without database"


mysql-test/r/sp-error.result:
  Test results fixed (a test case for Bug#13587)
mysql-test/t/sp-error.test:
  A test case for Bug#13587 "Server crash when SP is created without 
  database"
sql/sql_parse.cc:
  - move initialization of lex->sphead->m_db before it's used.
  - cleanup; comment why right now can't be cleaned any more
parent 1e7531ea
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -872,3 +872,14 @@ names
foo4
drop procedure bug13510_3|
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;
+18 −0
Original line number Diff line number Diff line
@@ -1266,6 +1266,24 @@ drop procedure bug13510_4|
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
#
#--disable_warnings
+29 −7
Original line number Diff line number Diff line
@@ -4068,6 +4068,19 @@ mysql_execute_command(THD *thd)

    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,
                     is_schema_db(lex->sphead->m_db.str)))
    {
@@ -4077,13 +4090,10 @@ mysql_execute_command(THD *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);
      lex->sphead->m_db.str= strmake_root(thd->mem_root, thd->db,
                                           lex->sphead->m_db.length);
      delete lex->sphead;
      lex->sphead= 0;
      goto error;
    }

    name= lex->sphead->name(&namelen);
@@ -4110,11 +4120,23 @@ mysql_execute_command(THD *thd)
      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); 
    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));
    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();
      delete lex->sphead;
      lex->sphead= 0;