mirror of
https://github.com/MariaDB/server.git
synced 2026-05-05 22:55:32 +02:00
Fixed various memory leaks.
sql/sp.cc: Fixed memory leaks. Deletion of sps now in sp_cache. sql/sp_cache.cc: Fixed memory leaks. Use implicit delete of objects to make sure they're always freed. sql/sp_cache.h: Fixed memory leaks. Use implicit delete of objects to make sure they're always freed. sql/sp_head.cc: Fixed memory leaks. Make sure we use the right mem_root during parsing. sql/sp_head.h: Fixed memory leaks. Make sure we use the right mem_root during parsing. sql/sql_parse.cc: Fixed memory leaks. Don't forget to free the temporary object created at definition. sql/sql_yacc.yy: Fixed memory leaks. Make sure we use the right mem_root during parsing.
This commit is contained in:
parent
a6f85eeac1
commit
1d77c0412e
7 changed files with 42 additions and 34 deletions
20
sql/sp.cc
20
sql/sp.cc
|
|
@ -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 @@ public:
|
|||
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 @@ public:
|
|||
|
||||
// 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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue