summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/sp.cc20
-rw-r--r--sql/sp_cache.cc18
-rw-r--r--sql/sp_cache.h11
-rw-r--r--sql/sp_head.cc15
-rw-r--r--sql/sp_head.h2
-rw-r--r--sql/sql_parse.cc6
-rw-r--r--sql/sql_yacc.yy4
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;