diff options
-rw-r--r-- | sql/sp.cc | 20 | ||||
-rw-r--r-- | sql/sp_cache.cc | 18 | ||||
-rw-r--r-- | sql/sp_cache.h | 11 | ||||
-rw-r--r-- | sql/sp_head.cc | 15 | ||||
-rw-r--r-- | sql/sp_head.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 6 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 4 |
7 files changed, 42 insertions, 34 deletions
diff --git a/sql/sp.cc b/sql/sp.cc index 10eb9c0c6f0..4bb629b3dbe 100644 --- a/sql/sp.cc +++ b/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); diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index 7e9d5f92ef0..4fee49c2d81 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -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; } diff --git a/sql/sp_cache.h b/sql/sp_cache.h index 3d38d6f1d1f..da25227303b 100644 --- a/sql/sp_cache.h +++ b/sql/sp_cache.h @@ -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 diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 66c811c1e19..e40d56d4ef9 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -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; } diff --git a/sql/sp_head.h b/sql/sp_head.h index bf3dc012a08..2c0a5e18bad 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -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); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f5f07a651bd..89a81498ef2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -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; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a4832e1d913..b08cbef3a57 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -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; |