summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <pem@mysql.com>2003-07-07 14:55:10 +0200
committerunknown <pem@mysql.com>2003-07-07 14:55:10 +0200
commita6b9cbd65c79289e86855472a8477e130609ada9 (patch)
treee5a52e1c7ee34232a60c8307a2ea27761f9ab1c4 /sql
parentd17a3ae1f41b00f15a06ccd6773fd602c4116932 (diff)
downloadmariadb-git-a6b9cbd65c79289e86855472a8477e130609ada9.tar.gz
Fixed the old kludge for pre-loading functions and made it more efficient
using a hash table instead (and made it work with lex pointers). Some additional code cleanup too. sql/sp.cc: Fixed the old kludge for pre-loading functions and made it more efficient using a hash table instead (and made it work with lex pointers). Some additional cleanup of comments too. sql/sp_head.h: Some additional code cleanup. sql/sql_lex.cc: Use hash table for function pre-loading (isntead of list). sql/sql_lex.h: Use hash table for function pre-loading (isntead of list).
Diffstat (limited to 'sql')
-rw-r--r--sql/sp.cc90
-rw-r--r--sql/sp_head.h2
-rw-r--r--sql/sql_lex.cc7
-rw-r--r--sql/sql_lex.h14
4 files changed, 64 insertions, 49 deletions
diff --git a/sql/sp.cc b/sql/sp.cc
index a368748e9fa..a767622057a 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -26,7 +26,7 @@
*
*/
-// *openeed=true means we opened ourselves
+// *opened=true means we opened ourselves
static int
db_find_routine_aux(THD *thd, int type, char *name, uint namelen,
enum thr_lock_type ltype, TABLE **tablep, bool *opened)
@@ -99,7 +99,6 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
char buff[65];
String str(buff, sizeof(buff), &my_charset_bin);
- // QQ Set up our own mem_root here???
ret= db_find_routine_aux(thd, type, name, namelen, TL_READ, &table, &opened);
if (ret != SP_OK)
goto done;
@@ -109,7 +108,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp)
goto done;
}
- //Get additional information
+ // Get additional information
if ((creator= get_field(&thd->mem_root, table->field[3])) == NULL)
{
ret= SP_GET_FIELD_FAILED;
@@ -377,74 +376,75 @@ sp_function_exists(THD *thd, LEX_STRING *name)
}
+byte *
+sp_lex_spfuns_key(const byte *ptr, uint *plen, my_bool first)
+{
+ LEX_STRING *lsp= (LEX_STRING *)ptr;
+ *plen= lsp->length;
+ return (byte *)lsp->str;
+}
+
void
sp_add_fun_to_lex(LEX *lex, LEX_STRING fun)
{
- List_iterator_fast<char> li(lex->spfuns);
- char *fn;
-
- while ((fn= li++))
+ if (! hash_search(&lex->spfuns, (byte *)fun.str, fun.length))
{
- uint len= strlen(fn);
+ LEX_STRING *ls= (LEX_STRING *)sql_alloc(sizeof(LEX_STRING));
+ ls->str= sql_strmake(fun.str, fun.length);
+ ls->length= fun.length;
- if (my_strnncoll(system_charset_info,
- (const uchar *)fn, len,
- (const uchar *)fun.str, fun.length) == 0)
- break;
- }
- if (! fn)
- {
- char *s= sql_strmake(fun.str, fun.length);
- lex->spfuns.push_back(s);
+ hash_insert(&lex->spfuns, (byte *)ls);
}
}
void
sp_merge_funs(LEX *dst, LEX *src)
{
- List_iterator_fast<char> li(src->spfuns);
- char *fn;
-
- while ((fn= li++))
+ for (uint i=0 ; i < src->spfuns.records ; i++)
{
- LEX_STRING lx;
+ LEX_STRING *ls= (LEX_STRING *)hash_element(&src->spfuns, i);
- lx.str= fn; lx.length= strlen(fn);
- sp_add_fun_to_lex(dst, lx);
+ if (! hash_search(&dst->spfuns, (byte *)ls->str, ls->length))
+ hash_insert(&dst->spfuns, (byte *)ls);
}
}
-/* QQ Not terribly efficient right now, but it'll do for starters.
- We should actually open the mysql.proc table just once. */
int
sp_cache_functions(THD *thd, LEX *lex)
{
- List_iterator<char> li(lex->spfuns);
- char *fn;
- enum_sql_command cmd= lex->sql_command;
+ HASH *h= &lex->spfuns;
int ret= 0;
- while ((fn= li++))
+ for (uint i=0 ; i < h->records ; i++)
{
- sp_head *sp;
- int len= strlen(fn);
-
- if (thd->sp_func_cache->lookup(fn, len))
- continue;
+ LEX_STRING *ls= (LEX_STRING *)hash_element(h, i);
- if (db_find_routine(thd, TYPE_ENUM_FUNCTION, fn, len, &sp) == SP_OK)
+ if (! thd->sp_func_cache->lookup(ls->str, ls->length))
{
- ret= sp_cache_functions(thd, thd->lex);
- if (ret)
+ sp_head *sp;
+ LEX *oldlex= thd->lex;
+ LEX *newlex= new st_lex;
+
+ thd->lex= newlex;
+ if (db_find_routine(thd, TYPE_ENUM_FUNCTION, ls->str, ls->length, &sp)
+ == SP_OK)
+ {
+ ret= sp_cache_functions(thd, newlex);
+ delete newlex;
+ thd->lex= oldlex;
+ if (ret)
+ break;
+ thd->sp_func_cache->insert(sp);
+ }
+ else
+ {
+ delete newlex;
+ thd->lex= oldlex;
+ net_printf(thd, ER_SP_DOES_NOT_EXIST, "FUNCTION", ls->str);
+ ret= 1;
break;
- thd->sp_func_cache->insert(sp);
- }
- else
- {
- send_error(thd, ER_SP_DOES_NOT_EXIST);
- ret= 1;
+ }
}
}
- lex->sql_command= cmd;
return ret;
}
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 2c37d87c7c1..bdb9e2e4eb1 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -99,7 +99,6 @@ public:
// Restores lex in 'thd' from our copy, but keeps some status from the
// one in 'thd', like ptr, tables, fields, etc.
- // If 'delete_lex' is true, we delete the current lex.
void
restore_lex(THD *thd);
@@ -162,6 +161,7 @@ private:
MEM_ROOT m_thd_root; // Temp. store for thd's mem_root
Item *m_free_list; // Where the items go
THD *m_thd; // Set if we have reset mem_root
+
LEX_STRING m_name;
LEX_STRING m_defstr;
LEX_STRING m_comment;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 2b3a6addcbd..cf94b63217c 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -126,7 +126,12 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->sql_command=SQLCOM_END;
lex->sphead= NULL;
lex->spcont= NULL;
- lex->spfuns.empty();
+
+ extern byte *sp_lex_spfuns_key(const byte *ptr, uint *plen, my_bool first);
+ hash_free(&lex->spfuns);
+ hash_init(&lex->spfuns, system_charset_info, 0, 0, 0,
+ sp_lex_spfuns_key, 0, 0);
+
return lex;
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index ffb1b2b0df7..9cb9ac0946e 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -497,9 +497,19 @@ typedef struct st_lex
sp_head *sphead;
bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */
sp_pcontext *spcont;
- List<char> spfuns; /* Called functions */
+ HASH spfuns; /* Called functions */
+
+ st_lex()
+ {
+ bzero((char *)&spfuns, sizeof(spfuns));
+ }
+
+ ~st_lex()
+ {
+ if (spfuns.array.buffer)
+ hash_free(&spfuns);
+ }
- st_lex() {}
inline void uncacheable()
{
safe_to_cache_query= 0;