Commit 176cd143 authored by unknown's avatar unknown
Browse files

Fixed BUG#18344: DROP DATABASE does not drop associated routines

  We must use the db key length in sp_drop_db_routines (and not the
  number of characters), or long db names will be truncated in the key.


mysql-test/r/sp.result:
  Updated results for new test case (BUG#18344)
mysql-test/t/sp.test:
  Added new test case for BUG#18344.
sql/sp.cc:
  In sp_drop_db_routines(), give the key field's ("db") key length
  instead of the number of characters to index_read(), or the key
  packing will truncate long db names.
parent 750bc269
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -4858,4 +4858,33 @@ call bug18787()|
no_such_function()
NULL
drop procedure bug18787|
create database bug18344_012345678901|
use bug18344_012345678901|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|
create database bug18344_0123456789012|
use bug18344_0123456789012|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|
use test|
select schema_name from information_schema.schemata where 
schema_name like 'bug18344%'|
schema_name
bug18344_012345678901
bug18344_0123456789012
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
routine_name	routine_schema
bug18344	bug18344_012345678901
bug18344_2	bug18344_012345678901
bug18344	bug18344_0123456789012
bug18344_2	bug18344_0123456789012
drop database bug18344_012345678901|
drop database bug18344_0123456789012|
select schema_name from information_schema.schemata where 
schema_name like 'bug18344%'|
schema_name
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
routine_name	routine_schema
drop table t1,t2;
+32 −0
Original line number Diff line number Diff line
@@ -5716,6 +5716,38 @@ call bug18787()|
drop procedure bug18787|


#
# BUG#18344: DROP DATABASE does not drop associated routines
# (... if the database name is longer than 21 characters)
#
#               1234567890123456789012
create database bug18344_012345678901| 
use bug18344_012345678901|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|

create database bug18344_0123456789012| 
use bug18344_0123456789012|
create procedure bug18344() begin end|
create procedure bug18344_2() begin end|

use test|

select schema_name from information_schema.schemata where 
  schema_name like 'bug18344%'|
select routine_name,routine_schema from information_schema.routines where
  routine_schema like 'bug18344%'|

drop database bug18344_012345678901| 
drop database bug18344_0123456789012| 

# Should be nothing left.
select schema_name from information_schema.schemata where 
  schema_name like 'bug18344%'|
select routine_name,routine_schema from information_schema.routines where
  routine_schema like 'bug18344%'|


#
# BUG#NNNN: New bug synopsis
#
+8 −12
Original line number Diff line number Diff line
@@ -886,28 +886,23 @@ int
sp_drop_db_routines(THD *thd, char *db)
{
  TABLE *table;
  byte key[64];			// db
  uint keylen;
  int ret;
  uint key_len;
  DBUG_ENTER("sp_drop_db_routines");
  DBUG_PRINT("enter", ("db: %s", db));

  // Put the key used to read the row together
  keylen= strlen(db);
  if (keylen > 64)
    keylen= 64;
  memcpy(key, db, keylen);
  memset(key+keylen, (int)' ', 64-keylen); // Pad with space
  keylen= sizeof(key);

  ret= SP_OPEN_TABLE_FAILED;
  if (!(table= open_proc_table_for_update(thd)))
    goto err;

  table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info);
  key_len= table->key_info->key_part[0].store_length;

  ret= SP_OK;
  table->file->ha_index_init(0);
  if (! table->file->index_read(table->record[0],
				key, keylen, HA_READ_KEY_EXACT))
                                table->field[MYSQL_PROC_FIELD_DB]->ptr,
				key_len, HA_READ_KEY_EXACT))
  {
    int nxtres;
    bool deleted= FALSE;
@@ -923,7 +918,8 @@ sp_drop_db_routines(THD *thd, char *db)
	break;
      }
    } while (! (nxtres= table->file->index_next_same(table->record[0],
						     key, keylen)));
                                        table->field[MYSQL_PROC_FIELD_DB]->ptr,
						     key_len)));
    if (nxtres != HA_ERR_END_OF_FILE)
      ret= SP_KEY_NOT_FOUND;
    if (deleted)