Commit b2057599 authored by pem@mysql.comhem.se's avatar pem@mysql.comhem.se

WL#1366: Use the schema (db) associated with an SP.

Phase 1: Introduced sp_name class, for qualified name support.
parent 786e19e5
...@@ -3088,6 +3088,25 @@ longlong Item_func_is_used_lock::val_int() ...@@ -3088,6 +3088,25 @@ longlong Item_func_is_used_lock::val_int()
return ull->thread_id; 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 int
Item_func_sp::execute(Item **itp) Item_func_sp::execute(Item **itp)
{ {
...@@ -3099,7 +3118,7 @@ Item_func_sp::execute(Item **itp) ...@@ -3099,7 +3118,7 @@ Item_func_sp::execute(Item **itp)
#endif #endif
if (! m_sp) if (! m_sp)
m_sp= sp_find_function(thd, &m_name); m_sp= sp_find_function(thd, m_name);
if (! m_sp) if (! m_sp)
DBUG_RETURN(-1); DBUG_RETURN(-1);
...@@ -3122,7 +3141,7 @@ Item_func_sp::field_type() const ...@@ -3122,7 +3141,7 @@ Item_func_sp::field_type() const
DBUG_ENTER("Item_func_sp::field_type"); DBUG_ENTER("Item_func_sp::field_type");
if (! 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) if (m_sp)
{ {
DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns)); DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns));
...@@ -3138,7 +3157,7 @@ Item_func_sp::result_type() const ...@@ -3138,7 +3157,7 @@ Item_func_sp::result_type() const
DBUG_PRINT("info", ("m_sp = %p", m_sp)); DBUG_PRINT("info", ("m_sp = %p", m_sp));
if (! 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) if (m_sp)
{ {
DBUG_RETURN(m_sp->result()); DBUG_RETURN(m_sp->result());
...@@ -3152,7 +3171,7 @@ Item_func_sp::fix_length_and_dec() ...@@ -3152,7 +3171,7 @@ Item_func_sp::fix_length_and_dec()
DBUG_ENTER("Item_func_sp::fix_length_and_dec"); DBUG_ENTER("Item_func_sp::fix_length_and_dec");
if (! m_sp) if (! m_sp)
m_sp= sp_find_function(current_thd, &m_name); m_sp= sp_find_function(current_thd, m_name);
if (m_sp) if (m_sp)
{ {
switch (m_sp->result()) { switch (m_sp->result()) {
......
...@@ -1072,32 +1072,26 @@ enum Cast_target ...@@ -1072,32 +1072,26 @@ enum Cast_target
*/ */
class sp_head; class sp_head;
class sp_name;
class Item_func_sp :public Item_func class Item_func_sp :public Item_func
{ {
private: private:
LEX_STRING m_name; sp_name *m_name;
mutable sp_head *m_sp; mutable sp_head *m_sp;
int execute(Item **itp); int execute(Item **itp);
public: public:
Item_func_sp(LEX_STRING name) Item_func_sp(sp_name *name);
:Item_func(), m_name(name), m_sp(NULL)
{}
Item_func_sp(LEX_STRING name, List<Item> &list) Item_func_sp(sp_name *name, List<Item> &list);
:Item_func(list), m_name(name), m_sp(NULL)
{}
virtual ~Item_func_sp() virtual ~Item_func_sp()
{} {}
const char *func_name() const const char *func_name() const;
{
return m_name.str;
}
enum enum_field_types field_type() const; enum enum_field_types field_type() const;
......
This diff is collapsed.
...@@ -29,47 +29,46 @@ ...@@ -29,47 +29,46 @@
#define SP_INTERNAL_ERROR -7 #define SP_INTERNAL_ERROR -7
sp_head * sp_head *
sp_find_procedure(THD *thd, LEX_STRING *name); sp_find_procedure(THD *thd, sp_name *name);
int int
sp_create_procedure(THD *thd, sp_head *sp); sp_create_procedure(THD *thd, sp_head *sp);
int int
sp_drop_procedure(THD *thd, char *name, uint namelen); sp_drop_procedure(THD *thd, sp_name *name);
int int
sp_update_procedure(THD *thd, char *name, uint namelen, sp_update_procedure(THD *thd, sp_name *name,
char *newname, uint newnamelen, char *newname, uint newnamelen,
st_sp_chistics *chistics); st_sp_chistics *chistics);
int int
sp_show_create_procedure(THD *thd, LEX_STRING *name); sp_show_create_procedure(THD *thd, sp_name *name);
int int
sp_show_status_procedure(THD *thd, const char *wild); sp_show_status_procedure(THD *thd, const char *wild);
sp_head * sp_head *
sp_find_function(THD *thd, LEX_STRING *name); sp_find_function(THD *thd, sp_name *name);
int int
sp_create_function(THD *thd, sp_head *sp); sp_create_function(THD *thd, sp_head *sp);
int int
sp_drop_function(THD *thd, char *name, uint namelen); sp_drop_function(THD *thd, sp_name *name);
int int
sp_update_function(THD *thd, char *name, uint namelen, sp_update_function(THD *thd, sp_name *name,
char *newname, uint newnamelen, char *newname, uint newnamelen,
st_sp_chistics *chistics); st_sp_chistics *chistics);
int int
sp_show_create_function(THD *thd, LEX_STRING *name); sp_show_create_function(THD *thd, sp_name *name);
int int
sp_show_status_function(THD *thd, const char *wild); sp_show_status_function(THD *thd, const char *wild);
// QQ Temporary until the function call detection in sql_lex has been reworked.
bool bool
sp_function_exists(THD *thd, LEX_STRING *name); sp_function_exists(THD *thd, LEX_STRING *name);
...@@ -77,7 +76,7 @@ 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 // This is needed since we have to read the functions before we
// do anything else. // do anything else.
void void
sp_add_fun_to_lex(LEX *lex, LEX_STRING fun); sp_add_fun_to_lex(LEX *lex, sp_name *fun);
void void
sp_merge_funs(LEX *dst, LEX *src); sp_merge_funs(LEX *dst, LEX *src);
int int
......
...@@ -71,7 +71,7 @@ sp_cache_insert(sp_cache **cp, sp_head *sp) ...@@ -71,7 +71,7 @@ sp_cache_insert(sp_cache **cp, sp_head *sp)
} }
sp_head * sp_head *
sp_cache_lookup(sp_cache **cp, char *name, uint namelen) sp_cache_lookup(sp_cache **cp, sp_name *name)
{ {
ulong v; ulong v;
sp_cache *c= *cp; sp_cache *c= *cp;
...@@ -89,11 +89,11 @@ sp_cache_lookup(sp_cache **cp, char *name, uint namelen) ...@@ -89,11 +89,11 @@ sp_cache_lookup(sp_cache **cp, char *name, uint namelen)
c->version= v; c->version= v;
return NULL; return NULL;
} }
return c->lookup(name, namelen); return c->lookup(name->m_name.str, name->m_name.length);
} }
bool bool
sp_cache_remove(sp_cache **cp, char *name, uint namelen) sp_cache_remove(sp_cache **cp, sp_name *name)
{ {
sp_cache *c= *cp; sp_cache *c= *cp;
bool found= FALSE; bool found= FALSE;
...@@ -109,7 +109,7 @@ sp_cache_remove(sp_cache **cp, char *name, uint namelen) ...@@ -109,7 +109,7 @@ sp_cache_remove(sp_cache **cp, char *name, uint namelen)
if (c->version < v) if (c->version < v)
c->remove_all(); c->remove_all();
else else
found= c->remove(name, namelen); found= c->remove(name->m_name.str, name->m_name.length);
c->version= v+1; c->version= v+1;
} }
return found; return found;
......
...@@ -35,10 +35,10 @@ void sp_cache_clear(sp_cache **cp); ...@@ -35,10 +35,10 @@ void sp_cache_clear(sp_cache **cp);
void sp_cache_insert(sp_cache **cp, sp_head *sp); void sp_cache_insert(sp_cache **cp, sp_head *sp);
/* Lookup an SP in cache */ /* 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 */ /* 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);
/* /*
......
...@@ -130,6 +130,32 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type) ...@@ -130,6 +130,32 @@ sp_eval_func_item(THD *thd, Item *it, enum enum_field_types type)
DBUG_RETURN(it); 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 * void *
sp_head::operator new(size_t size) sp_head::operator new(size_t size)
{ {
...@@ -178,22 +204,42 @@ sp_head::init(LEX *lex) ...@@ -178,22 +204,42 @@ sp_head::init(LEX *lex)
lex->spcont= m_pcont= new sp_pcontext(); lex->spcont= m_pcont= new sp_pcontext();
my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); 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_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_qname.str= m_db.str= m_name.str= m_params.str= m_retstr.str=
m_name.length= m_params.length= m_retstr.length= m_body.length= m_body.str= m_defstr.str= 0;
m_defstr.length= 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; DBUG_VOID_RETURN;
} }
void 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"); DBUG_ENTER("sp_head::init_strings");
/* During parsing, we must use thd->mem_root */ /* During parsing, we must use thd->mem_root */
MEM_ROOT *root= &thd->mem_root; MEM_ROOT *root= &thd->mem_root;
DBUG_PRINT("info", ("name: %*s", name->length, name->str)); DBUG_PRINT("info", ("name: %*.s%*s",
m_name.length= name->length; name->m_db.length, name->m_db.str,
m_name.str= strmake_root(root, name->str, name->length); 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.length= m_param_end- m_param_begin;
m_params.str= strmake_root(root, m_params.str= strmake_root(root,
(char *)m_param_begin, m_params.length); (char *)m_param_begin, m_params.length);
...@@ -1089,10 +1135,13 @@ sp_instr_cfetch::execute(THD *thd, uint *nextp) ...@@ -1089,10 +1135,13 @@ sp_instr_cfetch::execute(THD *thd, uint *nextp)
DBUG_RETURN(res); DBUG_RETURN(res);
} }
/* ------------------------------------------------------------------ */
// //
// Security context swapping // Security context swapping
// //
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
void void
sp_change_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp) sp_change_security_context(THD *thd, sp_head *sp, st_sp_security_context *ctxp)
......
...@@ -37,6 +37,35 @@ class sp_instr; ...@@ -37,6 +37,35 @@ class sp_instr;
struct sp_cond_type; struct sp_cond_type;
struct sp_pvar; 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 class sp_head : public Sql_alloc
{ {
sp_head(const sp_head &); /* Prevent use of these */ sp_head(const sp_head &); /* Prevent use of these */
...@@ -56,6 +85,8 @@ class sp_head : public Sql_alloc ...@@ -56,6 +85,8 @@ class sp_head : public Sql_alloc
List<char *> m_calls; // Called procedures. List<char *> m_calls; // Called procedures.
List<char *> m_tables; // Used tables. List<char *> m_tables; // Used tables.
#endif #endif
LEX_STRING m_qname; // db.name
LEX_STRING m_db;
LEX_STRING m_name; LEX_STRING m_name;
LEX_STRING m_params; LEX_STRING m_params;
LEX_STRING m_retstr; // For FUNCTIONs only LEX_STRING m_retstr; // For FUNCTIONs only
...@@ -83,7 +114,7 @@ class sp_head : public Sql_alloc ...@@ -83,7 +114,7 @@ class sp_head : public Sql_alloc
// Initialize strings after parsing header // Initialize strings after parsing header
void void
init_strings(THD *thd, LEX *lex, LEX_STRING *name); init_strings(THD *thd, LEX *lex, sp_name *name);
int int
create(THD *thd); create(THD *thd);
......
...@@ -22,6 +22,7 @@ class Table_ident; ...@@ -22,6 +22,7 @@ class Table_ident;
class sql_exchange; class sql_exchange;
class LEX_COLUMN; class LEX_COLUMN;
class sp_head; class sp_head;
class sp_name;
class sp_instr; class sp_instr;
class sp_pcontext; class sp_pcontext;
...@@ -604,6 +605,7 @@ typedef struct st_lex ...@@ -604,6 +605,7 @@ typedef struct st_lex
bool derived_tables; bool derived_tables;
bool safe_to_cache_query; bool safe_to_cache_query;
sp_head *sphead; sp_head *sphead;
sp_name *spname;
bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */ bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */
sp_pcontext *spcont; sp_pcontext *spcont;
HASH spfuns; /* Called functions */ HASH spfuns; /* Called functions */
......
...@@ -3101,9 +3101,9 @@ mysql_execute_command(THD *thd) ...@@ -3101,9 +3101,9 @@ mysql_execute_command(THD *thd)
if (check_access(thd,INSERT_ACL,"mysql",0,1,0)) if (check_access(thd,INSERT_ACL,"mysql",0,1,0))
break; break;
#ifdef HAVE_DLOPEN #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; goto error;
} }
if (!(res = mysql_create_function(thd,&lex->udf))) if (!(res = mysql_create_function(thd,&lex->udf)))
...@@ -3441,9 +3441,10 @@ mysql_execute_command(THD *thd) ...@@ -3441,9 +3441,10 @@ mysql_execute_command(THD *thd)
{ {
sp_head *sp; 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; goto error;
} }
else else
...@@ -3521,10 +3522,10 @@ mysql_execute_command(THD *thd) ...@@ -3521,10 +3522,10 @@ mysql_execute_command(THD *thd)
goto error; goto error;
} }
if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) 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); lex->name, newname_len, &lex->sp_chistics);
else 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); lex->name, newname_len, &lex->sp_chistics);
switch (res) switch (res)
{ {
...@@ -3532,10 +3533,12 @@ mysql_execute_command(THD *thd) ...@@ -3532,10 +3533,12 @@ mysql_execute_command(THD *thd)
send_ok(thd); send_ok(thd);
break; break;
case SP_KEY_NOT_FOUND: 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; goto error;
default: 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; goto error;
} }
break; break;
...@@ -3544,19 +3547,20 @@ mysql_execute_command(THD *thd) ...@@ -3544,19 +3547,20 @@ mysql_execute_command(THD *thd)
case SQLCOM_DROP_FUNCTION: case SQLCOM_DROP_FUNCTION:
{ {
if (lex->sql_command == SQLCOM_DROP_PROCEDURE) 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 else
{ {
res= sp_drop_function(thd, lex->udf.name.str, lex->udf.name.length); res= sp_drop_function(thd, lex->spname);
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
if (res == SP_KEY_NOT_FOUND) 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 (udf)
{ {
if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0)) if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0))
goto error; goto error;
if (!(res = mysql_drop_function(thd,&lex->udf.name))) if (!(res = mysql_drop_function(thd,&lex->spname->m_name)))
{ {
send_ok(thd); send_ok(thd);
break; break;
...@@ -3575,17 +3579,17 @@ mysql_execute_command(THD *thd) ...@@ -3575,17 +3579,17 @@ mysql_execute_command(THD *thd)
{ {
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), 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; res= 0;
send_ok(thd); send_ok(thd);
break; break;
} }
net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex), net_printf(thd, ER_SP_DOES_NOT_EXIST, SP_COM_STRING(lex),
lex->udf.name.str); lex->spname->m_name.str);
goto error; goto error;
default: default:
net_printf(thd, ER_SP_DROP_FAILED, SP_COM_STRING(lex), net_printf(thd, ER_SP_DROP_FAILED, SP_COM_STRING(lex),
lex->udf.name.str); lex->spname->m_name.str);
goto error; goto error;
} }
break; break;
...@@ -3593,16 +3597,16 @@ mysql_execute_command(THD *thd) ...@@ -3593,16 +3597,16 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_CREATE_PROC: case SQLCOM_SHOW_CREATE_PROC:
{ {
res= -1; 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; goto error;
} }
res= sp_show_create_procedure(thd, &lex->udf.name); res= sp_show_create_procedure(thd, lex->spname);
if (res != SP_OK) if (res != SP_OK)
{ /* We don't distinguish between errors for now */ { /* We don't distinguish between errors for now */
net_printf(thd, ER_SP_DOES_NOT_EXIST, 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; res= 0;
goto error; goto error;
} }
...@@ -3610,16 +3614,16 @@ mysql_execute_command(THD *thd) ...@@ -3610,16 +3614,16 @@ mysql_execute_command(THD *thd)
} }
case SQLCOM_SHOW_CREATE_FUNC: 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; goto error;
} }
res= sp_show_create_function(thd, &lex->udf.name); res= sp_show_create_function(thd, lex->spname);
if (res != SP_OK) if (res != SP_OK)
{ /* We don't distinguish between errors for now */ { /* We don't distinguish between errors for now */
net_printf(thd, ER_SP_DOES_NOT_EXIST, 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; res= 0;
goto error; goto error;
} }
......
...@@ -92,6 +92,7 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B) ...@@ -92,6 +92,7 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B)
chooser_compare_func_creator boolfunc2creator; chooser_compare_func_creator boolfunc2creator;
struct sp_cond_type *spcondtype; struct sp_cond_type *spcondtype;
struct { int vars, conds, hndlrs, curs; } spblock; struct { int vars, conds, hndlrs, curs; } spblock;
sp_name *spname;
struct st_lex *lex; struct st_lex *lex;
} }
...@@ -771,6 +772,7 @@ END_OF_INPUT ...@@ -771,6 +772,7 @@ END_OF_INPUT
%type <spcondtype> sp_cond sp_hcond %type <spcondtype> sp_cond sp_hcond
%type <spblock> sp_decls sp_decl %type <spblock> sp_decls sp_decl
%type <lex> sp_cursor_stmt %type <lex> sp_cursor_stmt
%type <spname> sp_name
%type <NONE> %type <NONE>
'-' '+' '*' '/' '%' '(' ')' '-' '+' '*' '/' '%' '(' ')'
...@@ -1019,15 +1021,15 @@ create: ...@@ -1019,15 +1021,15 @@ create:
lex->name=$4.str; lex->name=$4.str;
lex->create_info.options=$3; 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 *lex=Lex;
lex->udf.name = $4; lex->spname= $4;
lex->udf.type= $2; lex->udf.type= $2;
} }
create_function_tail create_function_tail
{} {}
| CREATE PROCEDURE ident | CREATE PROCEDURE sp_name
{ {
LEX *lex= Lex; LEX *lex= Lex;
sp_head *sp; sp_head *sp;
...@@ -1078,7 +1080,7 @@ create: ...@@ -1078,7 +1080,7 @@ create:
{ {
LEX *lex= Lex; LEX *lex= Lex;
lex->sphead->init_strings(YYTHD, lex, &$3); lex->sphead->init_strings(YYTHD, lex, $3);
lex->sql_command= SQLCOM_CREATE_PROCEDURE; lex->sql_command= SQLCOM_CREATE_PROCEDURE;
/* Restore flag if it was cleared above */ /* Restore flag if it was cleared above */
if (lex->sphead->m_old_cmq) if (lex->sphead->m_old_cmq)
...@@ -1087,11 +1089,17 @@ create: ...@@ -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: create_function_tail:
RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING_sys RETURNS_SYM udf_type UDF_SONAME_SYM TEXT_STRING_sys
{ {
LEX *lex=Lex; LEX *lex=Lex;
lex->sql_command = SQLCOM_CREATE_FUNCTION; lex->sql_command = SQLCOM_CREATE_FUNCTION;
lex->udf.name = lex->spname->m_name;
lex->udf.returns=(Item_result) $2; lex->udf.returns=(Item_result) $2;
lex->udf.dl=$4.str; lex->udf.dl=$4.str;
} }
...@@ -1153,7 +1161,7 @@ create_function_tail: ...@@ -1153,7 +1161,7 @@ create_function_tail:
sp_head *sp= lex->sphead; sp_head *sp= lex->sphead;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION; 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 */ /* Restore flag if it was cleared above */
if (sp->m_old_cmq) if (sp->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES; YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
...@@ -1203,12 +1211,12 @@ sp_suid: ...@@ -1203,12 +1211,12 @@ sp_suid:
; ;
call: call:
CALL_SYM IDENT_sys CALL_SYM sp_name
{ {
LEX *lex = Lex; LEX *lex = Lex;
lex->sql_command= SQLCOM_CALL; lex->sql_command= SQLCOM_CALL;
lex->udf.name= $2; lex->spname= $2;
lex->value_list.empty(); lex->value_list.empty();
} }
'(' sp_cparam_list ')' {} '(' sp_cparam_list ')' {}
...@@ -2723,7 +2731,7 @@ alter: ...@@ -2723,7 +2731,7 @@ alter:
lex->sql_command=SQLCOM_ALTER_DB; lex->sql_command=SQLCOM_ALTER_DB;
lex->name=$3.str; lex->name=$3.str;
} }
| ALTER PROCEDURE ident | ALTER PROCEDURE sp_name
{ {
LEX *lex= Lex; LEX *lex= Lex;
...@@ -2736,9 +2744,9 @@ alter: ...@@ -2736,9 +2744,9 @@ alter:
LEX *lex=Lex; LEX *lex=Lex;
lex->sql_command= SQLCOM_ALTER_PROCEDURE; 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; LEX *lex= Lex;
...@@ -2751,7 +2759,7 @@ alter: ...@@ -2751,7 +2759,7 @@ alter:
LEX *lex=Lex; LEX *lex=Lex;
lex->sql_command= SQLCOM_ALTER_FUNCTION; lex->sql_command= SQLCOM_ALTER_FUNCTION;
lex->udf.name= $3; lex->spname= $3;
} }
; ;
...@@ -3908,12 +3916,13 @@ simple_expr: ...@@ -3908,12 +3916,13 @@ simple_expr:
if (sp_function_exists(YYTHD, &$1)) if (sp_function_exists(YYTHD, &$1))
{ {
LEX *lex= Lex; 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) if ($3)
$$= new Item_func_sp($1, *$3); $$= new Item_func_sp(name, *$3);
else else
$$= new Item_func_sp($1); $$= new Item_func_sp(name);
} }
else else
{ {
...@@ -4830,19 +4839,19 @@ drop: ...@@ -4830,19 +4839,19 @@ drop:
lex->drop_if_exists=$3; lex->drop_if_exists=$3;
lex->name=$4.str; 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 *lex=Lex;
lex->sql_command = SQLCOM_DROP_FUNCTION; lex->sql_command = SQLCOM_DROP_FUNCTION;
lex->drop_if_exists= $3; 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 *lex=Lex;
lex->sql_command = SQLCOM_DROP_PROCEDURE; lex->sql_command = SQLCOM_DROP_PROCEDURE;
lex->drop_if_exists= $3; lex->drop_if_exists= $3;
lex->udf.name= $4; lex->spname= $4;
} }
| DROP USER | DROP USER
{ {
...@@ -5321,15 +5330,19 @@ show_param: ...@@ -5321,15 +5330,19 @@ show_param:
{ {
Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
} }
| CREATE PROCEDURE ident | CREATE PROCEDURE sp_name
{ {
Lex->sql_command = SQLCOM_SHOW_CREATE_PROC; LEX *lex= Lex;
Lex->udf.name= $3;
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 *lex= Lex;
Lex->udf.name= $3;
lex->sql_command = SQLCOM_SHOW_CREATE_FUNC;
lex->spname= $3;
} }
| PROCEDURE STATUS_SYM wild | PROCEDURE STATUS_SYM wild
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment