Commit 45e58963 authored by pem@mysql.comhem.se's avatar pem@mysql.comhem.se

Fixed various memory leaks.

parent 07541b6a
......@@ -583,12 +583,9 @@ sp_drop_procedure(THD *thd, char *name, uint namelen)
{
DBUG_ENTER("sp_drop_procedure");
DBUG_PRINT("enter", ("name: %*s", namelen, name));
sp_head *sp;
int ret;
sp= sp_cache_remove(&thd->sp_proc_cache, name, namelen);
if (sp)
delete sp;
sp_cache_remove(&thd->sp_proc_cache, name, namelen);
ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen);
DBUG_RETURN(ret);
......@@ -601,12 +598,9 @@ sp_update_procedure(THD *thd, char *name, uint namelen,
{
DBUG_ENTER("sp_update_procedure");
DBUG_PRINT("enter", ("name: %*s", namelen, name));
sp_head *sp;
int ret;
sp= sp_cache_remove(&thd->sp_proc_cache, name, namelen);
if (sp)
delete sp;
sp_cache_remove(&thd->sp_proc_cache, name, namelen);
ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen,
newname, newnamelen,
chistics);
......@@ -676,12 +670,9 @@ sp_drop_function(THD *thd, char *name, uint namelen)
{
DBUG_ENTER("sp_drop_function");
DBUG_PRINT("enter", ("name: %*s", namelen, name));
sp_head *sp;
int ret;
sp= sp_cache_remove(&thd->sp_func_cache, name, namelen);
if (sp)
delete sp;
sp_cache_remove(&thd->sp_func_cache, name, namelen);
ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen);
DBUG_RETURN(ret);
......@@ -694,12 +685,9 @@ sp_update_function(THD *thd, char *name, uint namelen,
{
DBUG_ENTER("sp_update_procedure");
DBUG_PRINT("enter", ("name: %*s", namelen, name));
sp_head *sp;
int ret;
sp= sp_cache_remove(&thd->sp_func_cache, name, namelen);
if (sp)
delete sp;
sp_cache_remove(&thd->sp_func_cache, name, namelen);
ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, namelen,
newname, newnamelen,
chistics);
......
......@@ -92,11 +92,11 @@ sp_cache_lookup(sp_cache **cp, char *name, uint namelen)
return c->lookup(name, namelen);
}
sp_head *
bool
sp_cache_remove(sp_cache **cp, char *name, uint namelen)
{
sp_cache *c= *cp;
sp_head *sp= NULL;
bool found= FALSE;
if (c)
{
......@@ -109,10 +109,10 @@ sp_cache_remove(sp_cache **cp, char *name, uint namelen)
if (c->version < v)
c->remove_all();
else
sp= c->remove(name, namelen);
found= c->remove(name, namelen);
c->version= v+1;
}
return sp;
return found;
}
......@@ -123,6 +123,14 @@ hash_get_key_for_sp_head(const byte *ptr, uint *plen,
return ((sp_head*)ptr)->name(plen);
}
static void
hash_free_sp_head(void *p)
{
sp_head *sp= (sp_head *)p;
delete sp;
}
sp_cache::sp_cache()
{
init();
......@@ -137,7 +145,7 @@ void
sp_cache::init()
{
hash_init(&m_hashtable, system_charset_info, 0, 0, 0,
hash_get_key_for_sp_head, 0, 0);
hash_get_key_for_sp_head, hash_free_sp_head, 0);
version= 0;
}
......
......@@ -37,8 +37,8 @@ void sp_cache_insert(sp_cache **cp, sp_head *sp);
/* Lookup an SP in cache */
sp_head *sp_cache_lookup(sp_cache **cp, char *name, uint namelen);
/* Remove an SP from cache */
sp_head *sp_cache_remove(sp_cache **cp, char *name, uint namelen);
/* Remove an SP from cache. Returns true if something was removed */
bool sp_cache_remove(sp_cache **cp, char *name, uint namelen);
/*
......@@ -75,14 +75,17 @@ class sp_cache
return (sp_head *)hash_search(&m_hashtable, (const byte *)name, namelen);
}
inline sp_head *
inline bool
remove(char *name, uint namelen)
{
sp_head *sp= lookup(name, namelen);
if (sp)
{
hash_delete(&m_hashtable, (byte *)sp);
return sp;
return TRUE;
}
return FALSE;
}
inline void
......
......@@ -146,6 +146,7 @@ sp_head::operator delete(void *ptr, size_t size)
MEM_ROOT own_root;
sp_head *sp= (sp_head *)ptr;
DBUG_PRINT("info", ("root: %lx", &sp->m_mem_root));
memcpy(&own_root, (const void *)&sp->m_mem_root, sizeof(MEM_ROOT));
free_root(&own_root, MYF(0));
......@@ -178,15 +179,17 @@ sp_head::init(LEX *lex)
}
void
sp_head::init_strings(LEX_STRING *name, LEX *lex)
sp_head::init_strings(THD *thd, LEX *lex, LEX_STRING *name)
{
DBUG_ENTER("sp_head::init_strings");
/* During parsing, we must use thd->mem_root */
MEM_ROOT *root= &thd->mem_root;
DBUG_PRINT("info", ("name: %*s", name->length, name->str));
m_name.length= name->length;
m_name.str= strmake_root(&m_mem_root, name->str, name->length);
m_name.str= strmake_root(root, name->str, name->length);
m_params.length= m_param_end- m_param_begin;
m_params.str= strmake_root(&m_mem_root,
m_params.str= strmake_root(root,
(char *)m_param_begin, m_params.length);
if (m_returns_begin && m_returns_end)
{
......@@ -204,13 +207,13 @@ sp_head::init_strings(LEX_STRING *name, LEX *lex)
p-= 1;
m_returns_end= (uchar *)p+1;
m_retstr.length= m_returns_end - m_returns_begin;
m_retstr.str= strmake_root(&m_mem_root,
m_retstr.str= strmake_root(root,
(char *)m_returns_begin, m_retstr.length);
}
m_body.length= lex->end_of_query - m_body_begin;
m_body.str= strmake_root(&m_mem_root, (char *)m_body_begin, m_body.length);
m_body.str= strmake_root(root, (char *)m_body_begin, m_body.length);
m_defstr.length= lex->end_of_query - lex->buf;
m_defstr.str= strmake_root(&m_mem_root, (char *)lex->buf, m_defstr.length);
m_defstr.str= strmake_root(root, (char *)lex->buf, m_defstr.length);
DBUG_VOID_RETURN;
}
......
......@@ -83,7 +83,7 @@ class sp_head : public Sql_alloc
// Initialize strings after parsing header
void
init_strings(LEX_STRING *name, LEX *lex);
init_strings(THD *thd, LEX *lex, LEX_STRING *name);
int
create(THD *thd);
......
......@@ -3473,12 +3473,18 @@ mysql_execute_command(THD *thd)
{
case SP_OK:
send_ok(thd);
delete lex->sphead;
lex->sphead= 0;
break;
case SP_WRITE_ROW_FAILED:
net_printf(thd, ER_SP_ALREADY_EXISTS, SP_TYPE_STRING(lex), name);
delete lex->sphead;
lex->sphead= 0;
goto error;
default:
net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name);
delete lex->sphead;
lex->sphead= 0;
goto error;
}
break;
......
......@@ -1078,7 +1078,7 @@ create:
{
LEX *lex= Lex;
lex->sphead->init_strings(&$3, lex);
lex->sphead->init_strings(YYTHD, lex, &$3);
lex->sql_command= SQLCOM_CREATE_PROCEDURE;
/* Restore flag if it was cleared above */
if (lex->sphead->m_old_cmq)
......@@ -1158,7 +1158,7 @@ create_function_tail:
sp_head *sp= lex->sphead;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->init_strings(&lex->udf.name, lex);
sp->init_strings(YYTHD, lex, &lex->udf.name);
/* Restore flag if it was cleared above */
if (sp->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
......
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