diff options
author | unknown <pem@mysql.com> | 2003-07-07 14:55:10 +0200 |
---|---|---|
committer | unknown <pem@mysql.com> | 2003-07-07 14:55:10 +0200 |
commit | a6b9cbd65c79289e86855472a8477e130609ada9 (patch) | |
tree | e5a52e1c7ee34232a60c8307a2ea27761f9ab1c4 /sql | |
parent | d17a3ae1f41b00f15a06ccd6773fd602c4116932 (diff) | |
download | mariadb-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.cc | 90 | ||||
-rw-r--r-- | sql/sp_head.h | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 7 | ||||
-rw-r--r-- | sql/sql_lex.h | 14 |
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; |