diff options
author | unknown <pem@mysql.comhem.se> | 2004-02-17 17:36:53 +0100 |
---|---|---|
committer | unknown <pem@mysql.comhem.se> | 2004-02-17 17:36:53 +0100 |
commit | e55c4ed179c5703f7b0c4b5ea2a4f9c6c59d0b20 (patch) | |
tree | ed911cc3b55e2fc5c450953efcdddc56c730097e | |
parent | 7444a50af81b2a790376519245fb09ca9a6068ba (diff) | |
download | mariadb-git-e55c4ed179c5703f7b0c4b5ea2a4f9c6c59d0b20.tar.gz |
WL#1366: Use the schema (db) associated with an SP.
Phase 1: Introduced sp_name class, for qualified name support.
sql/item_func.cc:
Introduced sp_name class; moved some methods from item_func.h.
sql/item_func.h:
Introduced sp_name class; moved some methods to item_func.cc.
sql/sp.cc:
Introduced sp_name class, for qualified name support.
sql/sp.h:
Introduced sp_name class, for qualified name support.
sql/sp_cache.cc:
Introduced sp_name class, for qualified name support.
sql/sp_cache.h:
Introduced sp_name class, for qualified name support.
sql/sp_head.cc:
Introduced sp_name class, for qualified name support.
sql/sp_head.h:
Introduced sp_name class, for qualified name support.
sql/sql_lex.h:
Introduced sp_name class, for qualified name support.
sql/sql_parse.cc:
Introduced sp_name class, for qualified name support.
sql/sql_yacc.yy:
Introduced sp_name class, for qualified name support.
-rw-r--r-- | sql/item_func.cc | 27 | ||||
-rw-r--r-- | sql/item_func.h | 16 | ||||
-rw-r--r-- | sql/sp.cc | 124 | ||||
-rw-r--r-- | sql/sp.h | 19 | ||||
-rw-r--r-- | sql/sp_cache.cc | 8 | ||||
-rw-r--r-- | sql/sp_cache.h | 4 | ||||
-rw-r--r-- | sql/sp_head.cc | 63 | ||||
-rw-r--r-- | sql/sp_head.h | 33 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 50 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 61 |
11 files changed, 266 insertions, 141 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc index d1d03b21eed..fdb0a5e5240 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3088,6 +3088,25 @@ longlong Item_func_is_used_lock::val_int() return ull->thread_id; } + +Item_func_sp::Item_func_sp(sp_name *name) + :Item_func(), m_name(name), m_sp(NULL) +{ + m_name->init_qname(current_thd); +} + +Item_func_sp::Item_func_sp(sp_name *name, List<Item> &list) + :Item_func(list), m_name(name), m_sp(NULL) +{ + m_name->init_qname(current_thd); +} + +const char * +Item_func_sp::func_name() const +{ + return m_name->m_name.str; +} + int Item_func_sp::execute(Item **itp) { @@ -3099,7 +3118,7 @@ Item_func_sp::execute(Item **itp) #endif if (! m_sp) - m_sp= sp_find_function(thd, &m_name); + m_sp= sp_find_function(thd, m_name); if (! m_sp) DBUG_RETURN(-1); @@ -3122,7 +3141,7 @@ Item_func_sp::field_type() const DBUG_ENTER("Item_func_sp::field_type"); if (! m_sp) - m_sp= sp_find_function(current_thd, const_cast<LEX_STRING*>(&m_name)); + m_sp= sp_find_function(current_thd, m_name); if (m_sp) { DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns)); @@ -3138,7 +3157,7 @@ Item_func_sp::result_type() const DBUG_PRINT("info", ("m_sp = %p", m_sp)); if (! m_sp) - m_sp= sp_find_function(current_thd, const_cast<LEX_STRING*>(&m_name)); + m_sp= sp_find_function(current_thd, m_name); if (m_sp) { DBUG_RETURN(m_sp->result()); @@ -3152,7 +3171,7 @@ Item_func_sp::fix_length_and_dec() DBUG_ENTER("Item_func_sp::fix_length_and_dec"); if (! m_sp) - m_sp= sp_find_function(current_thd, &m_name); + m_sp= sp_find_function(current_thd, m_name); if (m_sp) { switch (m_sp->result()) { diff --git a/sql/item_func.h b/sql/item_func.h index 75c8b348347..e68826ca56e 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1072,32 +1072,26 @@ enum Cast_target */ class sp_head; +class sp_name; class Item_func_sp :public Item_func { private: - LEX_STRING m_name; + sp_name *m_name; mutable sp_head *m_sp; int execute(Item **itp); public: - Item_func_sp(LEX_STRING name) - :Item_func(), m_name(name), m_sp(NULL) - {} + Item_func_sp(sp_name *name); - Item_func_sp(LEX_STRING name, List<Item> &list) - :Item_func(list), m_name(name), m_sp(NULL) - {} + Item_func_sp(sp_name *name, List<Item> &list); virtual ~Item_func_sp() {} - const char *func_name() const - { - return m_name.str; - } + const char *func_name() const; enum enum_field_types field_type() const; diff --git a/sql/sp.cc b/sql/sp.cc index 83fbd8c5173..26f21c31fd8 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -58,21 +58,22 @@ enum /* *opened=true means we opened ourselves */ static int -db_find_routine_aux(THD *thd, int type, char *name, uint namelen, +db_find_routine_aux(THD *thd, int type, sp_name *name, enum thr_lock_type ltype, TABLE **tablep, bool *opened) { TABLE *table; byte key[64+64+1]; // db, name, type uint keylen; DBUG_ENTER("db_find_routine_aux"); - DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); + DBUG_PRINT("enter", ("type: %d name: %*s", + type, name->m_name.length, name->m_name.str)); // Put the key used to read the row together memset(key, (int)' ', 64); // QQ Empty db for now - keylen= namelen; + keylen= name->m_name.length; if (keylen > 64) keylen= 64; - memcpy(key+64, name, keylen); + memcpy(key+64, name->m_name.str, keylen); memset(key+64+keylen, (int)' ', 64-keylen); // Pad with space key[128]= type; keylen= sizeof(key); @@ -112,7 +113,7 @@ db_find_routine_aux(THD *thd, int type, char *name, uint namelen, static int -db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) +db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) { extern int yyparse(void *thd); TABLE *table; @@ -129,9 +130,10 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) String str(buff, sizeof(buff), &my_charset_bin); ulong sql_mode; DBUG_ENTER("db_find_routine"); - DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); + DBUG_PRINT("enter", ("type: %d name: %*s", + type, name->m_name.length, name->m_name.str)); - ret= db_find_routine_aux(thd, type, name, namelen, TL_READ, &table, &opened); + ret= db_find_routine_aux(thd, type, name, TL_READ, &table, &opened); if (ret != SP_OK) goto done; @@ -220,7 +222,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) if (!(defstr= create_string(thd, &deflen, type, - name, namelen, + name->m_name.str, name->m_name.length, params, strlen(params), returns, strlen(returns), body, strlen(body), @@ -289,6 +291,9 @@ db_create_routine(THD *thd, int type, sp_head *sp) ret= SP_GET_FIELD_FAILED; goto done; } +// QQ Not yet +// table->field[MYSQL_PROC_FIELD_DB]-> +// store(sp->m_db.str, sp->m_db.length, system_charset_info); table->field[MYSQL_PROC_FIELD_NAME]-> store(sp->m_name.str, sp->m_name.length, system_charset_info); table->field[MYSQL_PROC_FIELD_TYPE]-> @@ -329,15 +334,16 @@ done: static int -db_drop_routine(THD *thd, int type, char *name, uint namelen) +db_drop_routine(THD *thd, int type, sp_name *name) { TABLE *table; int ret; bool opened; DBUG_ENTER("db_drop_routine"); - DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); + DBUG_PRINT("enter", ("type: %d name: %*s", + type, name->m_name.length, name->m_name.str)); - ret= db_find_routine_aux(thd, type, name, namelen, TL_WRITE, &table, &opened); + ret= db_find_routine_aux(thd, type, name, TL_WRITE, &table, &opened); if (ret == SP_OK) { if (table->file->delete_row(table->record[0])) @@ -351,7 +357,7 @@ db_drop_routine(THD *thd, int type, char *name, uint namelen) static int -db_update_routine(THD *thd, int type, char *name, uint namelen, +db_update_routine(THD *thd, int type, sp_name *name, char *newname, uint newnamelen, st_sp_chistics *chistics) { @@ -359,9 +365,10 @@ db_update_routine(THD *thd, int type, char *name, uint namelen, int ret; bool opened; DBUG_ENTER("db_update_routine"); - DBUG_PRINT("enter", ("type: %d name: %*s", type, namelen, name)); + DBUG_PRINT("enter", ("type: %d name: %*s", + type, name->m_name.length, name->m_name.str)); - ret= db_find_routine_aux(thd, type, name, namelen, TL_WRITE, &table, &opened); + ret= db_find_routine_aux(thd, type, name, TL_WRITE, &table, &opened); if (ret == SP_OK) { store_record(table,record[1]); @@ -395,6 +402,8 @@ struct st_used_field static struct st_used_field init_fields[]= { +// QQ Not yet +// { "Db", NAME_LEN, MYSQL_TYPE_STRING, 0}, { "Name", NAME_LEN, MYSQL_TYPE_STRING, 0}, { "Type", 9, MYSQL_TYPE_STRING, 0}, { "Definer", 77, MYSQL_TYPE_STRING, 0}, @@ -550,16 +559,17 @@ done: ******************************************************************************/ sp_head * -sp_find_procedure(THD *thd, LEX_STRING *name) +sp_find_procedure(THD *thd, sp_name *name) { sp_head *sp; DBUG_ENTER("sp_find_procedure"); - DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); + DBUG_PRINT("enter", ("name: %*s.%*s", + name->m_db.length, name->m_db.str, + name->m_name.length, name->m_name.str)); - if (!(sp= sp_cache_lookup(&thd->sp_proc_cache, name->str, name->length))) + if (!(sp= sp_cache_lookup(&thd->sp_proc_cache, name))) { - if (db_find_routine(thd, TYPE_ENUM_PROCEDURE, - name->str, name->length, &sp) == SP_OK) + if (db_find_routine(thd, TYPE_ENUM_PROCEDURE, name, &sp) == SP_OK) sp_cache_insert(&thd->sp_proc_cache, sp); } @@ -580,40 +590,40 @@ sp_create_procedure(THD *thd, sp_head *sp) int -sp_drop_procedure(THD *thd, char *name, uint namelen) +sp_drop_procedure(THD *thd, sp_name *name) { int ret; DBUG_ENTER("sp_drop_procedure"); - DBUG_PRINT("enter", ("name: %*s", namelen, name)); + DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); - sp_cache_remove(&thd->sp_proc_cache, name, namelen); - ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen); + sp_cache_remove(&thd->sp_proc_cache, name); + ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name); DBUG_RETURN(ret); } int -sp_update_procedure(THD *thd, char *name, uint namelen, +sp_update_procedure(THD *thd, sp_name *name, char *newname, uint newnamelen, st_sp_chistics *chistics) { int ret; DBUG_ENTER("sp_update_procedure"); - DBUG_PRINT("enter", ("name: %*s", namelen, name)); + DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); - sp_cache_remove(&thd->sp_proc_cache, name, namelen); - ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, namelen, + sp_cache_remove(&thd->sp_proc_cache, name); + ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, newname, newnamelen, chistics); DBUG_RETURN(ret); } int -sp_show_create_procedure(THD *thd, LEX_STRING *name) +sp_show_create_procedure(THD *thd, sp_name *name) { sp_head *sp; DBUG_ENTER("sp_show_create_procedure"); - DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); + DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); if ((sp= sp_find_procedure(thd, name))) { @@ -642,16 +652,15 @@ sp_show_status_procedure(THD *thd, const char *wild) ******************************************************************************/ sp_head * -sp_find_function(THD *thd, LEX_STRING *name) +sp_find_function(THD *thd, sp_name *name) { sp_head *sp; DBUG_ENTER("sp_find_function"); - DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); + DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); - if (!(sp= sp_cache_lookup(&thd->sp_func_cache, name->str, name->length))) + if (!(sp= sp_cache_lookup(&thd->sp_func_cache, name))) { - if (db_find_routine(thd, TYPE_ENUM_FUNCTION, - name->str, name->length, &sp) != SP_OK) + if (db_find_routine(thd, TYPE_ENUM_FUNCTION, name, &sp) != SP_OK) sp= NULL; else sp_cache_insert(&thd->sp_func_cache, sp); @@ -673,40 +682,40 @@ sp_create_function(THD *thd, sp_head *sp) int -sp_drop_function(THD *thd, char *name, uint namelen) +sp_drop_function(THD *thd, sp_name *name) { int ret; DBUG_ENTER("sp_drop_function"); - DBUG_PRINT("enter", ("name: %*s", namelen, name)); + DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); - sp_cache_remove(&thd->sp_func_cache, name, namelen); - ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name, namelen); + sp_cache_remove(&thd->sp_func_cache, name); + ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name); DBUG_RETURN(ret); } int -sp_update_function(THD *thd, char *name, uint namelen, +sp_update_function(THD *thd, sp_name *name, char *newname, uint newnamelen, st_sp_chistics *chistics) { int ret; DBUG_ENTER("sp_update_procedure"); - DBUG_PRINT("enter", ("name: %*s", namelen, name)); + DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); - sp_cache_remove(&thd->sp_func_cache, name, namelen); - ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, namelen, + sp_cache_remove(&thd->sp_func_cache, name); + ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, newname, newnamelen, chistics); DBUG_RETURN(ret); } int -sp_show_create_function(THD *thd, LEX_STRING *name) +sp_show_create_function(THD *thd, sp_name *name) { sp_head *sp; DBUG_ENTER("sp_show_create_function"); - DBUG_PRINT("enter", ("name: %*s", name->length, name->str)); + DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); if ((sp= sp_find_function(thd, name))) { @@ -728,18 +737,18 @@ sp_show_status_function(THD *thd, const char *wild) } -// QQ Temporary until the function call detection in sql_lex has been reworked. bool sp_function_exists(THD *thd, LEX_STRING *name) { TABLE *table; bool ret= FALSE; bool opened= FALSE; + sp_name n(*name); DBUG_ENTER("sp_function_exists"); - if (sp_cache_lookup(&thd->sp_func_cache, name->str, name->length) || + if (sp_cache_lookup(&thd->sp_func_cache, &n) || db_find_routine_aux(thd, TYPE_ENUM_FUNCTION, - name->str, name->length, TL_READ, + &n, TL_READ, &table, &opened) == SP_OK) ret= TRUE; if (opened) @@ -758,13 +767,14 @@ sp_lex_spfuns_key(const byte *ptr, uint *plen, my_bool first) void -sp_add_fun_to_lex(LEX *lex, LEX_STRING fun) +sp_add_fun_to_lex(LEX *lex, sp_name *fun) { - if (! hash_search(&lex->spfuns, (byte *)fun.str, fun.length)) + if (! hash_search(&lex->spfuns, + (byte *)fun->m_name.str, fun->m_name.length)) { LEX_STRING *ls= (LEX_STRING *)sql_alloc(sizeof(LEX_STRING)); - ls->str= sql_strmake(fun.str, fun.length); - ls->length= fun.length; + ls->str= sql_strmake(fun->m_name.str, fun->m_name.length); + ls->length= fun->m_name.length; my_hash_insert(&lex->spfuns, (byte *)ls); } @@ -793,15 +803,17 @@ sp_cache_functions(THD *thd, LEX *lex) for (uint i=0 ; i < h->records ; i++) { LEX_STRING *ls= (LEX_STRING *)hash_element(h, i); + sp_name name(*ls); - if (! sp_cache_lookup(&thd->sp_func_cache, ls->str, ls->length)) + if (! sp_cache_lookup(&thd->sp_func_cache, &name)) { 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) + if (db_find_routine(thd, TYPE_ENUM_FUNCTION, &name, &sp) + == SP_OK) { ret= sp_cache_functions(thd, newlex); delete newlex; @@ -836,11 +848,13 @@ create_string(THD *thd, ulong *lenp, char *buf, *ptr; ulong buflen; - buflen= 100 + namelen + paramslen + returnslen + bodylen + chistics->comment.length; + buflen= 100 + namelen + paramslen + returnslen + bodylen + + chistics->comment.length; if (!(buf= thd->alloc(buflen))) return 0; - ptr= strxmov(buf, "CREATE ", (type == TYPE_ENUM_FUNCTION) ? "FUNCTION" : "PROCEDURE", + ptr= strxmov(buf, "CREATE ", + (type == TYPE_ENUM_FUNCTION) ? "FUNCTION" : "PROCEDURE", " `", name, "`(", params, ")", NullS); if (type == TYPE_ENUM_FUNCTION) @@ -29,47 +29,46 @@ #define SP_INTERNAL_ERROR -7 sp_head * -sp_find_procedure(THD *thd, LEX_STRING *name); +sp_find_procedure(THD *thd, sp_name *name); int sp_create_procedure(THD *thd, sp_head *sp); int -sp_drop_procedure(THD *thd, char *name, uint namelen); +sp_drop_procedure(THD *thd, sp_name *name); int -sp_update_procedure(THD *thd, char *name, uint namelen, +sp_update_procedure(THD *thd, sp_name *name, char *newname, uint newnamelen, st_sp_chistics *chistics); int -sp_show_create_procedure(THD *thd, LEX_STRING *name); +sp_show_create_procedure(THD *thd, sp_name *name); int sp_show_status_procedure(THD *thd, const char *wild); sp_head * -sp_find_function(THD *thd, LEX_STRING *name); +sp_find_function(THD *thd, sp_name *name); int sp_create_function(THD *thd, sp_head *sp); int -sp_drop_function(THD *thd, char *name, uint namelen); +sp_drop_function(THD *thd, sp_name *name); int -sp_update_function(THD *thd, char *name, uint namelen, +sp_update_function(THD *thd, sp_name *name, char *newname, uint newnamelen, st_sp_chistics *chistics); int -sp_show_create_function(THD *thd, LEX_STRING *name); +sp_show_create_function(THD *thd, sp_name *name); int sp_show_status_function(THD *thd, const char *wild); -// QQ Temporary until the function call detection in sql_lex has been reworked. bool sp_function_exists(THD *thd, LEX_STRING *name); @@ -77,7 +76,7 @@ sp_function_exists(THD *thd, LEX_STRING *name); // 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); +sp_add_fun_to_lex(LEX *lex, sp_name *fun); void sp_merge_funs(LEX *dst, LEX *src); int diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index 657a96ec33d..93f51938000 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -71,7 +71,7 @@ sp_cache_insert(sp_cache **cp, sp_head *sp) } sp_head * -sp_cache_lookup(sp_cache **cp, char *name, uint namelen) +sp_cache_lookup(sp_cache **cp, sp_name *name) { ulong v; sp_cache *c= *cp; @@ -89,11 +89,11 @@ sp_cache_lookup(sp_cache **cp, char *name, uint namelen) c->version= v; return NULL; } - return c->lookup(name, namelen); + return c->lookup(name->m_name.str, name->m_name.length); } bool -sp_cache_remove(sp_cache **cp, char *name, uint namelen) +sp_cache_remove(sp_cache **cp, sp_name *name) { sp_cache *c= *cp; bool found= FALSE; @@ -109,7 +109,7 @@ sp_cache_remove(sp_cache **cp, char *name, uint namelen) if (c->version < v) c->remove_all(); else - found= c->remove(name, namelen); + found= c->remove(name->m_name.str, name->m_name.length); c->version= v+1; } return found; diff --git a/sql/sp_cache.h b/sql/sp_cache.h index da25227303b..253e9b11588 100644 --- a/sql/sp_cache.h +++ b/sql/sp_cache.h @@ -35,10 +35,10 @@ void sp_cache_clear(sp_cache **cp); 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); +sp_head *sp_cache_lookup(sp_cache **cp, sp_name *name); /* Remove an SP from cache. Returns true if something was removed */ -bool sp_cache_remove(sp_cache **cp, char *name, uint namelen); +bool sp_cache_remove(sp_cache **cp, sp_name *name); /* diff --git a/sql/sp_head.cc b/sql/sp_head.cc index a68118cecd1..d43ac54e57d 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -130,6 +130,32 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) DBUG_RETURN(it); } + +/* + * + * sp_name + * + */ + +void +sp_name::init_qname(THD *thd) +{ + m_qname.length= m_db.length+m_name.length+1; + m_qname.str= alloc_root(&thd->mem_root, m_qname.length+1); + sprintf(m_qname.str, "%*s.%*s", + m_db.length, (m_db.length ? m_db.str : ""), + m_name.length, m_name.str); +} + +/* ------------------------------------------------------------------ */ + + +/* + * + * sp_head + * + */ + void * sp_head::operator new(size_t size) { @@ -178,22 +204,42 @@ sp_head::init(LEX *lex) lex->spcont= m_pcont= new sp_pcontext(); my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); m_param_begin= m_param_end= m_returns_begin= m_returns_end= m_body_begin= 0; - m_name.str= m_params.str= m_retstr.str= m_body.str= m_defstr.str= 0; - m_name.length= m_params.length= m_retstr.length= m_body.length= - m_defstr.length= 0; + m_qname.str= m_db.str= m_name.str= m_params.str= m_retstr.str= + m_body.str= m_defstr.str= 0; + m_qname.length= m_db.length= m_name.length= m_params.length= + m_retstr.length= m_body.length= m_defstr.length= 0; DBUG_VOID_RETURN; } void -sp_head::init_strings(THD *thd, LEX *lex, LEX_STRING *name) +sp_head::init_strings(THD *thd, LEX *lex, sp_name *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(root, name->str, name->length); + DBUG_PRINT("info", ("name: %*.s%*s", + name->m_db.length, name->m_db.str, + name->m_name.length, name->m_name.str)); + /* We have to copy strings to get them into the right memroot */ + if (name->m_db.length == 0) + { + m_db.length= strlen(thd->db); + m_db.str= strmake_root(root, thd->db, m_db.length); + } + else + { + m_db.length= name->m_db.length; + m_db.str= strmake_root(root, name->m_db.str, name->m_db.length); + } + m_name.length= name->m_name.length; + m_name.str= strmake_root(root, name->m_name.str, name->m_name.length); + + if (name->m_qname.length == 0) + name->init_qname(thd); + m_qname.length= name->m_qname.length; + m_qname.str= strmake_root(root, name->m_qname.str, m_qname.length); + m_params.length= m_param_end- m_param_begin; m_params.str= strmake_root(root, (char *)m_param_begin, m_params.length); @@ -1089,10 +1135,13 @@ sp_instr_cfetch::execute(THD *thd, uint *nextp) DBUG_RETURN(res); } +/* ------------------------------------------------------------------ */ + // // Security context swapping // + #ifndef NO_EMBEDDED_ACCESS_CHECKS void sp_change_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp) diff --git a/sql/sp_head.h b/sql/sp_head.h index b2dee5204bb..b35b4c37501 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -37,6 +37,35 @@ class sp_instr; struct sp_cond_type; struct sp_pvar; +class sp_name : public Sql_alloc +{ +public: + + LEX_STRING m_db; + LEX_STRING m_name; + LEX_STRING m_qname; + + sp_name(LEX_STRING name) + : m_name(name) + { + m_db.str= m_qname.str= 0; + m_db.length= m_qname.length= 0; + } + + sp_name(LEX_STRING db, LEX_STRING name) + : m_db(db), m_name(name) + { + m_qname.str= 0; + m_qname.length= 0; + } + + // Init. the qualified name from the db and name. + void init_qname(THD *thd); // thd for memroot allocation + + ~sp_name() + {} +}; + class sp_head : public Sql_alloc { sp_head(const sp_head &); /* Prevent use of these */ @@ -56,6 +85,8 @@ public: List<char *> m_calls; // Called procedures. List<char *> m_tables; // Used tables. #endif + LEX_STRING m_qname; // db.name + LEX_STRING m_db; LEX_STRING m_name; LEX_STRING m_params; LEX_STRING m_retstr; // For FUNCTIONs only @@ -83,7 +114,7 @@ public: // Initialize strings after parsing header void - init_strings(THD *thd, LEX *lex, LEX_STRING *name); + init_strings(THD *thd, LEX *lex, sp_name *name); int create(THD *thd); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 50b8f322731..221f864db81 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -22,6 +22,7 @@ class Table_ident; class sql_exchange; class LEX_COLUMN; class sp_head; +class sp_name; class sp_instr; class sp_pcontext; @@ -604,6 +605,7 @@ typedef struct st_lex bool derived_tables; bool safe_to_cache_query; sp_head *sphead; + sp_name *spname; bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */ sp_pcontext *spcont; HASH spfuns; /* Called functions */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ae507c34272..9de3247496c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3101,9 +3101,9 @@ mysql_execute_command(THD *thd) if (check_access(thd,INSERT_ACL,"mysql",0,1,0)) break; #ifdef HAVE_DLOPEN - if ((sph= sp_find_function(thd, &lex->udf.name))) + if ((sph= sp_find_function(thd, lex->spname))) { - net_printf(thd, ER_UDF_EXISTS, lex->udf.name.str); + net_printf(thd, ER_UDF_EXISTS, lex->spname->m_name.str); goto error; } if (!(res = mysql_create_function(thd,&lex->udf))) @@ -3441,9 +3441,10 @@ mysql_execute_command(THD *thd) { sp_head *sp; - if (!(sp= sp_find_procedure(thd, &lex->udf.name))) + if (!(sp= sp_find_procedure(thd, lex->spname))) { - net_printf(thd, ER_SP_DOES_NOT_EXIST, "PROCEDURE", lex->udf.name); + net_printf(thd, ER_SP_DOES_NOT_EXIST, "PROCEDURE", + lex->spname->m_name.str); goto error; } else @@ -3521,10 +3522,10 @@ mysql_execute_command(THD *thd) goto error; } if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) - res= sp_update_procedure(thd, lex->udf.name.str, lex->udf.name.length, + res= sp_update_procedure(thd, lex->spname, lex->name, newname_len, &lex->sp_chistics); else - res= sp_update_function(thd, lex->udf.name.str, lex->udf.name.length, + res= sp_update_function(thd, lex->spname, lex->name, newname_len, &lex->sp_chistics); switch (res) { @@ -3532,10 +3533,12 @@ mysql_execute_command(THD *thd) send_ok(thd); break; case SP_KEY_NOT_FOUND: - net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex),lex->udf.name); + net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex), + lex->spname->m_name.str); goto error; default: - net_printf(thd, ER_SP_CANT_ALTER, SP_COM_STRING(lex),lex->udf.name); + net_printf(thd, ER_SP_CANT_ALTER, SP_COM_STRING(lex), + lex->spname->m_name.str); goto error; } break; @@ -3544,19 +3547,20 @@ mysql_execute_command(THD *thd) case SQLCOM_DROP_FUNCTION: { if (lex->sql_command == SQLCOM_DROP_PROCEDURE) - res= sp_drop_procedure(thd, lex->udf.name.str, lex->udf.name.length); + res= sp_drop_procedure(thd, lex->spname); else { - res= sp_drop_function(thd, lex->udf.name.str, lex->udf.name.length); + res= sp_drop_function(thd, lex->spname); #ifdef HAVE_DLOPEN if (res == SP_KEY_NOT_FOUND) { - udf_func *udf = find_udf(lex->udf.name.str, lex->udf.name.length); + udf_func *udf = find_udf(lex->spname->m_name.str, + lex->spname->m_name.length); if (udf) { if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0)) goto error; - if (!(res = mysql_drop_function(thd,&lex->udf.name))) + if (!(res = mysql_drop_function(thd,&lex->spname->m_name))) { send_ok(thd); break; @@ -3575,17 +3579,17 @@ mysql_execute_command(THD *thd) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), - SP_COM_STRING(lex), lex->udf.name.str); + SP_COM_STRING(lex), lex->spname->m_name.str); res= 0; send_ok(thd); break; } net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex), - lex->udf.name.str); + lex->spname->m_name.str); goto error; default: net_printf(thd, ER_SP_DROP_FAILED, SP_COM_STRING(lex), - lex->udf.name.str); + lex->spname->m_name.str); goto error; } break; @@ -3593,16 +3597,16 @@ mysql_execute_command(THD *thd) case SQLCOM_SHOW_CREATE_PROC: { res= -1; - if (lex->udf.name.length > NAME_LEN) + if (lex->spname->m_name.length > NAME_LEN) { - net_printf(thd, ER_TOO_LONG_IDENT, lex->udf.name.str); + net_printf(thd, ER_TOO_LONG_IDENT, lex->spname->m_name.str); goto error; } - res= sp_show_create_procedure(thd, &lex->udf.name); + res= sp_show_create_procedure(thd, lex->spname); if (res != SP_OK) { /* We don't distinguish between errors for now */ net_printf(thd, ER_SP_DOES_NOT_EXIST, - SP_COM_STRING(lex), lex->udf.name.str); + SP_COM_STRING(lex), lex->spname->m_name.str); res= 0; goto error; } @@ -3610,16 +3614,16 @@ mysql_execute_command(THD *thd) } case SQLCOM_SHOW_CREATE_FUNC: { - if (lex->udf.name.length > NAME_LEN) + if (lex->spname->m_name.length > NAME_LEN) { - net_printf(thd, ER_TOO_LONG_IDENT, lex->udf.name.str); + net_printf(thd, ER_TOO_LONG_IDENT, lex->spname->m_name.str); goto error; } - res= sp_show_create_function(thd, &lex->udf.name); + res= sp_show_create_function(thd, lex->spname); if (res != SP_OK) { /* We don't distinguish between errors for now */ net_printf(thd, ER_SP_DOES_NOT_EXIST, - SP_COM_STRING(lex), lex->udf.name.str); + SP_COM_STRING(lex), lex->spname->m_name.str); res= 0; goto error; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 27937999004..4224971fd47 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -92,6 +92,7 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B) chooser_compare_func_creator boolfunc2creator; struct sp_cond_type *spcondtype; struct { int vars, conds, hndlrs, curs; } spblock; + sp_name *spname; struct st_lex *lex; } @@ -771,6 +772,7 @@ END_OF_INPUT %type <spcondtype> sp_cond sp_hcond %type <spblock> sp_decls sp_decl %type <lex> sp_cursor_stmt +%type <spname> sp_name %type <NONE> '-' '+' '*' '/' '%' '(' ')' @@ -1019,15 +1021,15 @@ create: lex->name=$4.str; lex->create_info.options=$3; } - | CREATE udf_func_type FUNCTION_SYM IDENT_sys + | CREATE udf_func_type FUNCTION_SYM sp_name { LEX *lex=Lex; - lex->udf.name = $4; + lex->spname= $4; lex->udf.type= $2; } create_function_tail {} - | CREATE PROCEDURE ident + | CREATE PROCEDURE sp_name { LEX *lex= Lex; sp_head *sp; @@ -1078,7 +1080,7 @@ create: { LEX *lex= Lex; - lex->sphead->init_strings(YYTHD, lex, &$3); + 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) @@ -1087,11 +1089,17 @@ create: } ; +sp_name: + IDENT_sys '.' IDENT_sys { $$= new sp_name($1, $3); } + | IDENT_sys { $$= new sp_name($1); } + ; + create_function_tail: RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING_sys { LEX *lex=Lex; lex->sql_command = SQLCOM_CREATE_FUNCTION; + lex->udf.name = lex->spname->m_name; lex->udf.returns=(Item_result) $2; lex->udf.dl=$4.str; } @@ -1153,7 +1161,7 @@ create_function_tail: sp_head *sp= lex->sphead; lex->sql_command= SQLCOM_CREATE_SPFUNCTION; - sp->init_strings(YYTHD, lex, &lex->udf.name); + sp->init_strings(YYTHD, lex, lex->spname); /* Restore flag if it was cleared above */ if (sp->m_old_cmq) YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; @@ -1203,12 +1211,12 @@ sp_suid: ; call: - CALL_SYM IDENT_sys + CALL_SYM sp_name { LEX *lex = Lex; lex->sql_command= SQLCOM_CALL; - lex->udf.name= $2; + lex->spname= $2; lex->value_list.empty(); } '(' sp_cparam_list ')' {} @@ -2723,7 +2731,7 @@ alter: lex->sql_command=SQLCOM_ALTER_DB; lex->name=$3.str; } - | ALTER PROCEDURE ident + | ALTER PROCEDURE sp_name { LEX *lex= Lex; @@ -2736,9 +2744,9 @@ alter: LEX *lex=Lex; lex->sql_command= SQLCOM_ALTER_PROCEDURE; - lex->udf.name= $3; + lex->spname= $3; } - | ALTER FUNCTION_SYM ident + | ALTER FUNCTION_SYM sp_name { LEX *lex= Lex; @@ -2751,7 +2759,7 @@ alter: LEX *lex=Lex; lex->sql_command= SQLCOM_ALTER_FUNCTION; - lex->udf.name= $3; + lex->spname= $3; } ; @@ -3908,12 +3916,13 @@ simple_expr: if (sp_function_exists(YYTHD, &$1)) { LEX *lex= Lex; + sp_name *name= new sp_name($1); - sp_add_fun_to_lex(lex, $1); + sp_add_fun_to_lex(lex, name); if ($3) - $$= new Item_func_sp($1, *$3); + $$= new Item_func_sp(name, *$3); else - $$= new Item_func_sp($1); + $$= new Item_func_sp(name); } else { @@ -4830,19 +4839,19 @@ drop: lex->drop_if_exists=$3; lex->name=$4.str; } - | DROP FUNCTION_SYM if_exists IDENT_sys opt_restrict + | DROP FUNCTION_SYM if_exists sp_name opt_restrict { LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_FUNCTION; lex->drop_if_exists= $3; - lex->udf.name= $4; + lex->spname= $4; } - | DROP PROCEDURE if_exists IDENT_sys opt_restrict + | DROP PROCEDURE if_exists sp_name opt_restrict { LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_PROCEDURE; lex->drop_if_exists= $3; - lex->udf.name= $4; + lex->spname= $4; } | DROP USER { @@ -5321,15 +5330,19 @@ show_param: { Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; } - | CREATE PROCEDURE ident + | CREATE PROCEDURE sp_name { - Lex->sql_command = SQLCOM_SHOW_CREATE_PROC; - Lex->udf.name= $3; + LEX *lex= Lex; + + lex->sql_command = SQLCOM_SHOW_CREATE_PROC; + lex->spname= $3; } - | CREATE FUNCTION_SYM ident + | CREATE FUNCTION_SYM sp_name { - Lex->sql_command = SQLCOM_SHOW_CREATE_FUNC; - Lex->udf.name= $3; + LEX *lex= Lex; + + lex->sql_command = SQLCOM_SHOW_CREATE_FUNC; + lex->spname= $3; } | PROCEDURE STATUS_SYM wild { |