summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/sp.cc95
-rw-r--r--sql/sp.h6
-rw-r--r--sql/sql_class.cc19
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_parse.cc19
5 files changed, 69 insertions, 72 deletions
diff --git a/sql/sp.cc b/sql/sp.cc
index 79beb78e3e5..ecbe0ff3955 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -22,6 +22,9 @@
static sp_head *
sp_find_cached_function(THD *thd, char *name, uint namelen);
+static sp_head *
+sp_find_cached_procedure(THD *thd, char *name, uint namelen);
+
/*
*
* DB storage of Stored PROCEDUREs and FUNCTIONs
@@ -254,9 +257,17 @@ sp_find_procedure(THD *thd, LEX_STRING *name)
DBUG_PRINT("enter", ("name: %*s", name->length, name->str));
- if (db_find_routine(thd, TYPE_ENUM_PROCEDURE,
- name->str, name->length, &sp) != SP_OK)
- sp= NULL;
+ sp= sp_find_cached_procedure(thd, name->str, name->length);
+ if (! sp)
+ {
+ if (db_find_routine(thd, TYPE_ENUM_PROCEDURE,
+ name->str, name->length, &sp) == SP_OK)
+ {
+ HASH *phash= thd->sp_hash+TYPE_ENUM_PROCEDURE-1;
+
+ hash_insert(phash, (const byte*)sp);
+ }
+ }
DBUG_RETURN(sp);
}
@@ -280,8 +291,17 @@ 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_find_cached_procedure(thd, name, namelen);
+ if (sp)
+ {
+ HASH *phash= thd->sp_hash+TYPE_ENUM_PROCEDURE-1;
+
+ hash_delete(phash, (byte*)sp);
+ delete sp;
+ }
ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen);
DBUG_RETURN(ret);
@@ -331,8 +351,17 @@ 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_find_cached_function(thd, name, namelen);
+ if (sp)
+ {
+ HASH *fhash= thd->sp_hash+TYPE_ENUM_FUNCTION-1;
+
+ hash_delete(fhash, (byte*)sp);
+ delete sp;
+ }
ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen);
DBUG_RETURN(ret);
@@ -344,9 +373,10 @@ sp_function_exists(THD *thd, LEX_STRING *name)
{
TABLE *table;
bool ret= FALSE;
- bool opened;
+ bool opened= FALSE;
- if (db_find_routine_aux(thd, TYPE_ENUM_FUNCTION,
+ if (sp_find_cached_function(thd, name->str, name->length) ||
+ db_find_routine_aux(thd, TYPE_ENUM_FUNCTION,
name->str, name->length, TL_READ,
&table, &opened) == SP_OK)
{
@@ -358,13 +388,6 @@ sp_function_exists(THD *thd, LEX_STRING *name)
}
-/*
- *
- * The temporary FUNCTION cache. (QQ This will be rehacked later, but
- * it's needed now to make functions work at all.)
- *
- */
-
void
sp_add_fun_to_lex(LEX *lex, LEX_STRING fun)
{
@@ -411,25 +434,22 @@ sp_cache_functions(THD *thd, LEX *lex)
char *fn;
enum_sql_command cmd= lex->sql_command;
int ret= 0;
+ HASH *fhash= thd->sp_hash+TYPE_ENUM_FUNCTION-1;
while ((fn= li++))
{
- List_iterator_fast<sp_head> lisp(thd->spfuns);
sp_head *sp;
+ int len= strlen(fn);
- while ((sp= lisp++))
- {
- if (my_strcasecmp(system_charset_info, fn, sp->name()) == 0)
- break;
- }
- if (sp)
+ if (hash_search(fhash,(const byte*)fn,len))
continue;
- if (db_find_routine(thd, TYPE_ENUM_FUNCTION, fn, strlen(fn), &sp) == SP_OK)
+
+ if (db_find_routine(thd, TYPE_ENUM_FUNCTION, fn, len, &sp) == SP_OK)
{
ret= sp_cache_functions(thd, thd->lex);
if (ret)
break;
- thd->spfuns.push_back(sp);
+ hash_insert(fhash,(const byte*)sp);
}
else
{
@@ -441,32 +461,23 @@ sp_cache_functions(THD *thd, LEX *lex)
return ret;
}
-void
-sp_clear_function_cache(THD *thd)
+byte *
+hash_get_key_for_sp_head(const byte *ptr, uint *plen,
+ my_bool first)
{
- List_iterator_fast<sp_head> li(thd->spfuns);
- sp_head *sp;
-
- while ((sp= li++))
- delete sp;
- thd->spfuns.empty();
+ return ((sp_head*)ptr)->name(plen);
}
static sp_head *
sp_find_cached_function(THD *thd, char *name, uint namelen)
{
- List_iterator_fast<sp_head> li(thd->spfuns);
- sp_head *sp;
-
- while ((sp= li++))
- {
- uint len;
- const uchar *n= (const uchar *)sp->name(&len);
+ return (sp_head*)hash_search(thd->sp_hash+TYPE_ENUM_FUNCTION-1,
+ (const byte*)name,namelen);
+}
- if (my_strnncoll(system_charset_info,
- (const uchar *)name, namelen,
- n, len) == 0)
- break;
- }
- return sp;
+static sp_head *
+sp_find_cached_procedure(THD *thd, char *name, uint namelen)
+{
+ return (sp_head*)hash_search(thd->sp_hash+TYPE_ENUM_PROCEDURE-1,
+ (const byte*)name,namelen);
}
diff --git a/sql/sp.h b/sql/sp.h
index 3a021288907..bbf8832d55d 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -53,15 +53,13 @@ bool
sp_function_exists(THD *thd, LEX_STRING *name);
-// QQ More temporary stuff until the real cache is implemented. This is
-// needed since we have to read the functions before we do anything else.
+// This is needed since we have to read the functions before we
+// do anything else.
void
sp_add_fun_to_lex(LEX *lex, LEX_STRING fun);
void
sp_merge_funs(LEX *dst, LEX *src);
int
sp_cache_functions(THD *thd, LEX *lex);
-void
-sp_clear_function_cache(THD *thd);
#endif /* _SP_H_ */
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index c64bb7ff8fa..5ab096b91e4 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -38,6 +38,8 @@
#include <sp_rcontext.h>
+byte *hash_get_key_for_sp_head(const byte*,uint*,my_bool);
+
/*
The following is used to initialise Table_ident with a internal
table name
@@ -155,6 +157,11 @@ THD::THD():user_time(0), is_fatal_error(0),
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key,
(hash_free_key) free_user_var, 0);
+
+ hash_init(sp_hash,system_charset_info,0,0,0,
+ hash_get_key_for_sp_head,0,0);
+ hash_init(sp_hash+1,system_charset_info,0,0,0,
+ hash_get_key_for_sp_head,0,0);
/* For user vars replication*/
if (opt_bin_log)
@@ -200,9 +207,6 @@ THD::THD():user_time(0), is_fatal_error(0),
pthread_mutex_unlock(&LOCK_thread_count);
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id);
}
-
- /* QQ init the temporary function cache */
- spfuns.empty();
}
@@ -261,6 +265,10 @@ void THD::change_user(void)
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key,
(hash_free_key) free_user_var, 0);
+ hash_init(sp_hash,system_charset_info,0,0,0,
+ hash_get_key_for_sp_head,0,0);
+ hash_init(sp_hash+1,system_charset_info,0,0,0,
+ hash_get_key_for_sp_head,0,0);
}
@@ -284,6 +292,8 @@ void THD::cleanup(void)
close_temporary_tables(this);
delete_dynamic(&user_var_events);
hash_free(&user_vars);
+ hash_free(sp_hash);
+ hash_free(sp_hash+1);
if (global_read_lock)
unlock_global_read_lock(this);
if (ull)
@@ -294,9 +304,6 @@ void THD::cleanup(void)
ull= 0;
}
- // extern void sp_clear_function_cache(THD *);
- // sp_clear_function_cache(this);
-
cleanup_done=1;
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 3bb0f348024..cebcdf68391 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -551,7 +551,7 @@ public:
bool prepare_command;
bool tmp_table_used;
sp_rcontext *spcont; // SP runtime context
- List<sp_head> spfuns; // SP FUNCTIONs
+ HASH sp_hash[2]; // hash for SP PROCEDURES and FUNCTIONS
/*
If we do a purge of binary logs, log index info of the threads
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index b29e1734302..6a02383e984 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1527,13 +1527,6 @@ restore_user:
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
- /*
- Clear the SP function cache after each statement (QQ this is a temporary
- solution; caching will be rehacked later).
- Note: Must do this before we free_root.
- */
- sp_clear_function_cache(thd);
-
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
DBUG_RETURN(error);
}
@@ -2829,7 +2822,6 @@ mysql_execute_command(THD *thd)
sp_head *sph= sp_find_function(thd, &lex->udf.name);
if (sph)
{
- delete sph; // QQ Free memory. Remove this when caching!!!
net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str);
goto error;
}
@@ -3033,18 +3025,12 @@ mysql_execute_command(THD *thd)
{
case SP_OK:
send_ok(thd);
- delete lex->sphead; // QQ Free memory. Remove this when caching!!!
- lex->sphead= NULL;
break;
case SP_WRITE_ROW_FAILED:
net_printf(thd, ER_SP_ALREADY_EXISTS, SP_TYPE_STRING(lex), name);
- delete lex->sphead; // QQ Free memory. Remove this when caching!!!
- lex->sphead= NULL;
goto error;
default:
net_printf(thd, ER_SP_STORE_FAILED, SP_TYPE_STRING(lex), name);
- delete lex->sphead; // QQ Free memory. Remove this when caching!!!
- lex->sphead= NULL;
goto error;
}
break;
@@ -3068,7 +3054,6 @@ mysql_execute_command(THD *thd)
if (tables && ((res= check_table_access(thd, SELECT_ACL, tables)) ||
(res= open_and_lock_tables(thd, tables))))
{
- delete sp; // Free memory. Remove this when caching!!!
break;
}
fix_tables_pointers(lex->all_selects_list);
@@ -3087,7 +3072,6 @@ mysql_execute_command(THD *thd)
#ifndef EMBEDDED_LIBRARY
thd->net.no_send_ok= nsok;
#endif
- delete sp; // QQ Free memory. Remove this when caching!!!
goto error;
}
smrx= thd->server_status & SERVER_MORE_RESULTS_EXISTS;
@@ -3105,8 +3089,6 @@ mysql_execute_command(THD *thd)
thd->server_status &= ~SERVER_MORE_RESULTS_EXISTS;
}
- delete sp; // QQ Free memory. Remove this when caching!!!
-
if (res == 0)
send_ok(thd);
else
@@ -3132,7 +3114,6 @@ mysql_execute_command(THD *thd)
{
/* QQ This is an no-op right now, since we haven't
put the characteristics in yet. */
- delete sp; // QQ Free memory. Remove this when caching!!!
send_ok(thd);
}
break;