summaryrefslogtreecommitdiff
path: root/sql/sp.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2017-07-31 23:00:02 +0400
committerAlexander Barkov <bar@mariadb.org>2017-07-31 23:00:02 +0400
commitc9218ff43989bf2385d1f62b45ed1f6229cbc5a5 (patch)
treea99c10f5e304662f3b51141871f94ee64eebaee6 /sql/sp.cc
parent4937474f862010c90f76bf879a70c1edf17e7c85 (diff)
downloadmariadb-git-c9218ff43989bf2385d1f62b45ed1f6229cbc5a5.tar.gz
MDEV-13415 Wrap the code in sp.cc into a class Sp_handler
Diffstat (limited to 'sql/sp.cc')
-rw-r--r--sql/sp.cc398
1 files changed, 192 insertions, 206 deletions
diff --git a/sql/sp.cc b/sql/sp.cc
index 2059c1ac508..8aefb8b3a34 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -20,6 +20,7 @@
#include "unireg.h"
#include "sp.h"
#include "sql_base.h" // close_thread_tables
+#include "sql_lex.h" // empty_clex_str
#include "sql_parse.h" // parse_sql
#include "key.h" // key_copy
#include "sql_show.h" // append_definer, append_identifier
@@ -34,20 +35,59 @@
#include <my_user.h>
-/* Used in error handling only */
-#define SP_TYPE_STRING(type) stored_procedure_type_to_str(type)
-
-static int
-db_load_routine(THD *thd, stored_procedure_type type, const sp_name *name,
- sp_head **sphp,
- sql_mode_t sql_mode,
- const LEX_CSTRING &params,
- const LEX_CSTRING &returns,
- const LEX_CSTRING &body,
- const st_sp_chistics &chistics,
- const AUTHID &definer,
- longlong created, longlong modified,
- Stored_program_creation_ctx *creation_ctx);
+
+sp_cache **Sp_handler_procedure::get_cache(THD *thd) const
+{
+ return &thd->sp_proc_cache;
+}
+
+sp_cache **Sp_handler_function::get_cache(THD *thd) const
+{
+ return &thd->sp_func_cache;
+}
+
+ulong Sp_handler_procedure::recursion_depth(THD *thd) const
+{
+ return thd->variables.max_sp_recursion_depth;
+}
+
+
+bool Sp_handler::add_instr_freturn(THD *thd, sp_head *sp,
+ sp_pcontext *spcont,
+ Item *item, LEX *lex) const
+{
+ my_error(ER_SP_BADRETURN, MYF(0));
+ return true;
+}
+
+
+bool Sp_handler::add_instr_preturn(THD *thd, sp_head *sp,
+ sp_pcontext *spcont) const
+{
+ thd->parse_error();
+ return true;
+}
+
+
+bool Sp_handler_function::add_instr_freturn(THD *thd, sp_head *sp,
+ sp_pcontext *spcont,
+ Item *item, LEX *lex) const
+{
+ return sp->add_instr_freturn(thd, spcont, item, lex);
+}
+
+
+bool Sp_handler_procedure::add_instr_preturn(THD *thd, sp_head *sp,
+ sp_pcontext *spcont) const
+{
+ return sp->add_instr_preturn(thd, spcont);
+}
+
+
+Sp_handler_procedure sp_handler_procedure;
+Sp_handler_function sp_handler_function;
+Sp_handler_trigger sp_handler_trigger;
+
static const
TABLE_FIELD_TYPE proc_table_fields[MYSQL_PROC_FIELD_COUNT] =
@@ -178,7 +218,7 @@ class Stored_routine_creation_ctx : public Stored_program_creation_ctx,
{
public:
static Stored_routine_creation_ctx *
- load_from_db(THD *thd, const sp_name *name, TABLE *proc_tbl);
+ load_from_db(THD *thd, const Database_qualified_name *name, TABLE *proc_tbl);
public:
virtual Stored_program_creation_ctx *clone(MEM_ROOT *mem_root)
@@ -267,8 +307,8 @@ bool load_collation(MEM_ROOT *mem_root,
Stored_routine_creation_ctx *
Stored_routine_creation_ctx::load_from_db(THD *thd,
- const sp_name *name,
- TABLE *proc_tbl)
+ const Database_qualified_name *name,
+ TABLE *proc_tbl)
{
/* Load character set/collation attributes. */
@@ -463,7 +503,6 @@ static TABLE *open_proc_table_for_update(THD *thd)
Find row in open mysql.proc table representing stored routine.
@param thd Thread context
- @param type Type of routine to find (function or procedure)
@param name Name of routine
@param table TABLE object for open mysql.proc table.
@@ -473,15 +512,16 @@ static TABLE *open_proc_table_for_update(THD *thd)
SP_KEY_NOT_FOUND No routine with given name
*/
-static int
-db_find_routine_aux(THD *thd, stored_procedure_type type,
- const Database_qualified_name *name,
- TABLE *table)
+int
+Sp_handler::db_find_routine_aux(THD *thd,
+ const Database_qualified_name *name,
+ TABLE *table) const
{
uchar key[MAX_KEY_LENGTH]; // db, name, optional key length type
DBUG_ENTER("db_find_routine_aux");
- DBUG_PRINT("enter", ("type: %d name: %.*s",
- type, (int) name->m_name.length, name->m_name.str));
+ DBUG_PRINT("enter", ("type: %s name: %.*s",
+ type_str(),
+ (int) name->m_name.length, name->m_name.str));
/*
Create key to find row. We have to use field->store() to be able to
@@ -494,7 +534,7 @@ db_find_routine_aux(THD *thd, stored_procedure_type type,
DBUG_RETURN(SP_KEY_NOT_FOUND);
table->field[0]->store(name->m_db, &my_charset_bin);
table->field[1]->store(name->m_name, &my_charset_bin);
- table->field[2]->store((longlong) type, TRUE);
+ table->field[2]->store((longlong) type(), true);
key_copy(key, table->record[0], table->key_info,
table->key_info->key_length);
@@ -568,7 +608,6 @@ bool AUTHID::read_from_mysql_proc_row(THD *thd, TABLE *table)
sp_head object for it.
@param thd Thread context
- @param type Type of routine (TYPE_ENUM_PROCEDURE/...)
@param name Name of routine
@param sphp Out parameter in which pointer to created sp_head
object is returned (0 in case of error).
@@ -583,9 +622,10 @@ bool AUTHID::read_from_mysql_proc_row(THD *thd, TABLE *table)
non-0 Error (may be one of special codes like SP_KEY_NOT_FOUND)
*/
-static int
-db_find_routine(THD *thd, stored_procedure_type type, const sp_name *name,
- sp_head **sphp)
+int
+Sp_handler::db_find_routine(THD *thd,
+ const Database_qualified_name *name,
+ sp_head **sphp) const
{
TABLE *table;
LEX_CSTRING params, returns, body;
@@ -600,8 +640,9 @@ db_find_routine(THD *thd, stored_procedure_type type, const sp_name *name,
AUTHID definer;
DBUG_ENTER("db_find_routine");
- DBUG_PRINT("enter", ("type: %d name: %.*s",
- type, (int) name->m_name.length, name->m_name.str));
+ DBUG_PRINT("enter", ("type: %s name: %.*s",
+ type_str(),
+ (int) name->m_name.length, name->m_name.str));
*sphp= 0; // In case of errors
if (!(table= open_proc_table_for_read(thd, &open_tables_state_backup)))
@@ -610,7 +651,7 @@ db_find_routine(THD *thd, stored_procedure_type type, const sp_name *name,
/* Reset sql_mode during data dictionary operations. */
thd->variables.sql_mode= 0;
- if ((ret= db_find_routine_aux(thd, type, name, table)) != SP_OK)
+ if ((ret= db_find_routine_aux(thd, name, table)) != SP_OK)
goto done;
if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
@@ -628,7 +669,7 @@ db_find_routine(THD *thd, stored_procedure_type type, const sp_name *name,
table->field[MYSQL_PROC_FIELD_PARAM_LIST]->val_str_nopad(thd->mem_root,
&params);
- if (type == TYPE_ENUM_PROCEDURE)
+ if (type() == TYPE_ENUM_PROCEDURE)
returns= empty_clex_str;
else if (table->field[MYSQL_PROC_FIELD_RETURNS]->val_str_nopad(thd->mem_root,
&returns))
@@ -654,7 +695,7 @@ db_find_routine(THD *thd, stored_procedure_type type, const sp_name *name,
close_system_tables(thd, &open_tables_state_backup);
table= 0;
- ret= db_load_routine(thd, type, name, sphp,
+ ret= db_load_routine(thd, name, sphp,
sql_mode, params, returns, body, chistics, definer,
created, modified, creation_ctx);
done:
@@ -797,17 +838,17 @@ Bad_db_error_handler::handle_condition(THD *thd,
}
-static int
-db_load_routine(THD *thd, stored_procedure_type type,
- const sp_name *name, sp_head **sphp,
- sql_mode_t sql_mode,
- const LEX_CSTRING &params,
- const LEX_CSTRING &returns,
- const LEX_CSTRING &body,
- const st_sp_chistics &chistics,
- const AUTHID &definer,
- longlong created, longlong modified,
- Stored_program_creation_ctx *creation_ctx)
+int
+Sp_handler::db_load_routine(THD *thd, const Database_qualified_name *name,
+ sp_head **sphp,
+ sql_mode_t sql_mode,
+ const LEX_CSTRING &params,
+ const LEX_CSTRING &returns,
+ const LEX_CSTRING &body,
+ const st_sp_chistics &chistics,
+ const AUTHID &definer,
+ longlong created, longlong modified,
+ Stored_program_creation_ctx *creation_ctx) const
{
LEX *old_lex= thd->lex, newlex;
String defstr;
@@ -833,10 +874,9 @@ db_load_routine(THD *thd, stored_procedure_type type,
*/
if (!show_create_sp(thd, &defstr,
- type,
- null_clex_str, name->m_name,
- params, returns, body,
- chistics, definer, sql_mode))
+ null_clex_str, name->m_name,
+ params, returns, body,
+ chistics, definer, sql_mode))
{
ret= SP_INTERNAL_ERROR;
goto end;
@@ -911,7 +951,7 @@ end:
void
-sp_returns_type(THD *thd, String &result, sp_head *sp)
+sp_returns_type(THD *thd, String &result, const sp_head *sp)
{
TABLE table;
TABLE_SHARE share;
@@ -947,7 +987,6 @@ sp_returns_type(THD *thd, String &result, sp_head *sp)
and invalidates the stored-routine cache.
@param thd Thread context.
- @param type Stored routine type (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
@param name Stored routine name.
@param table A pointer to the opened mysql.proc table
@@ -955,9 +994,10 @@ sp_returns_type(THD *thd, String &result, sp_head *sp)
@return SP_OK on success, or SP_DELETE_ROW_FAILED on error.
used to indicate about errors.
*/
-static int
-sp_drop_routine_internal(THD *thd, stored_procedure_type type,
- const Database_qualified_name *name, TABLE *table)
+int
+Sp_handler::sp_drop_routine_internal(THD *thd,
+ const Database_qualified_name *name,
+ TABLE *table) const
{
DBUG_ENTER("sp_drop_routine_internal");
@@ -974,10 +1014,9 @@ sp_drop_routine_internal(THD *thd, stored_procedure_type type,
local cache.
*/
sp_head *sp;
- sp_cache **spc= (type == TYPE_ENUM_FUNCTION ?
- &thd->sp_func_cache : &thd->sp_proc_cache);
- sp= sp_cache_lookup(spc, name);
- if (sp)
+ sp_cache **spc= get_cache(thd);
+ DBUG_ASSERT(spc);
+ if ((sp= sp_cache_lookup(spc, name)))
sp_cache_flush_obsolete(spc, &sp);
DBUG_RETURN(SP_OK);
}
@@ -990,8 +1029,6 @@ sp_drop_routine_internal(THD *thd, stored_procedure_type type,
the mysql.proc.
@param thd Thread context.
- @param type Stored routine type
- (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION).
@param sp Stored routine object to store.
@note Opens and closes the thread tables. Therefore assumes
@@ -1008,7 +1045,7 @@ sp_drop_routine_internal(THD *thd, stored_procedure_type type,
*/
bool
-sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
+Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const
{
LEX *lex= thd->lex;
bool ret= TRUE;
@@ -1016,8 +1053,6 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
char definer_buf[USER_HOST_BUFF_SIZE];
LEX_CSTRING definer;
sql_mode_t saved_mode= thd->variables.sql_mode;
- MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ?
- MDL_key::FUNCTION : MDL_key::PROCEDURE;
CHARSET_INFO *db_cs= get_default_db_collation(thd, sp->m_db.str);
@@ -1025,16 +1060,15 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
bool store_failed= FALSE;
DBUG_ENTER("sp_create_routine");
- DBUG_PRINT("enter", ("type: %d name: %.*s", (int) type,
+ DBUG_PRINT("enter", ("type: %s name: %.*s",
+ type_str(),
(int) sp->m_name.length,
sp->m_name.str));
+ MDL_key::enum_mdl_namespace mdl_type= get_mdl_type();
LEX_CSTRING returns= empty_clex_str;
String retstr(64);
retstr.set_charset(system_charset_info);
- DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
- type == TYPE_ENUM_FUNCTION);
-
/* Grab an exclusive MDL lock. */
if (lock_object_name(thd, mdl_type, sp->m_db.str, sp->m_name.str))
{
@@ -1062,17 +1096,17 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
if (!(table= open_proc_table_for_update(thd)))
{
- my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(type),sp->m_name.str);
+ my_error(ER_SP_STORE_FAILED, MYF(0), type_str(), sp->m_name.str);
goto done;
}
else
{
/* Checking if the routine already exists */
- if (db_find_routine_aux(thd, type, sp, table) == SP_OK)
+ if (db_find_routine_aux(thd, sp, table) == SP_OK)
{
if (lex->create_info.or_replace())
{
- if ((ret= sp_drop_routine_internal(thd, type, sp, table)))
+ if ((ret= sp_drop_routine_internal(thd, sp, table)))
goto done;
}
else if (lex->create_info.if_not_exists())
@@ -1080,13 +1114,12 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_SP_ALREADY_EXISTS,
ER_THD(thd, ER_SP_ALREADY_EXISTS),
- SP_TYPE_STRING(type),
- sp->m_name.str);
+ type_str(), sp->m_name.str);
ret= FALSE;
// Setting retstr as it is used for logging.
- if (sp->m_type == TYPE_ENUM_FUNCTION)
+ if (type() == TYPE_ENUM_FUNCTION)
{
sp_returns_type(thd, retstr, sp);
returns= retstr.lex_cstring();
@@ -1095,8 +1128,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
}
else
{
- my_error(ER_SP_ALREADY_EXISTS, MYF(0),
- SP_TYPE_STRING(type), sp->m_name.str);
+ my_error(ER_SP_ALREADY_EXISTS, MYF(0), type_str(), sp->m_name.str);
goto done;
}
}
@@ -1108,8 +1140,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
if (table->s->fields < MYSQL_PROC_FIELD_COUNT)
{
- my_error(ER_SP_STORE_FAILED, MYF(0),
- SP_TYPE_STRING(type), sp->m_name.str);
+ my_error(ER_SP_STORE_FAILED, MYF(0), type_str(), sp->m_name.str);
goto done;
}
@@ -1137,7 +1168,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
store_failed= store_failed ||
table->field[MYSQL_PROC_MYSQL_TYPE]->
- store((longlong)type, TRUE);
+ store((longlong) type(), true);
store_failed= store_failed ||
table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]->
@@ -1165,7 +1196,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
store(sp->m_params, system_charset_info);
- if (sp->m_type == TYPE_ENUM_FUNCTION)
+ if (type() == TYPE_ENUM_FUNCTION)
{
sp_returns_type(thd, retstr, sp);
returns= retstr.lex_cstring();
@@ -1197,7 +1228,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
store(sp->comment(), system_charset_info);
}
- if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
+ if (type() == TYPE_ENUM_FUNCTION &&
!trust_function_creators && mysql_bin_log.is_open())
{
if (!sp->detistic())
@@ -1255,8 +1286,7 @@ sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
if (table->file->ha_write_row(table->record[0]))
{
- my_error(ER_SP_ALREADY_EXISTS, MYF(0),
- SP_TYPE_STRING(type), sp->m_name.str);
+ my_error(ER_SP_ALREADY_EXISTS, MYF(0), type_str(), sp->m_name.str);
goto done;
}
/* Make change permanent and avoid 'table is marked as crashed' errors */
@@ -1274,7 +1304,6 @@ log:
log_query.set_charset(system_charset_info);
if (!show_create_sp(thd, &log_query,
- sp->m_type,
sp->m_explicit_name ? sp->m_db : null_clex_str,
sp->m_name,
sp->m_params, returns, sp->m_body,
@@ -1314,8 +1343,6 @@ done:
from the mysql.proc table and invalidates the stored-routine cache.
@param thd Thread context.
- @param type Stored routine type
- (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
@param name Stored routine name.
@return Error code. SP_OK is returned on success. Other SP_ constants are
@@ -1323,18 +1350,16 @@ done:
*/
int
-sp_drop_routine(THD *thd, stored_procedure_type type, const sp_name *name)
+Sp_handler::sp_drop_routine(THD *thd,
+ const Database_qualified_name *name) const
{
TABLE *table;
int ret;
- MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ?
- MDL_key::FUNCTION : MDL_key::PROCEDURE;
DBUG_ENTER("sp_drop_routine");
- DBUG_PRINT("enter", ("type: %d name: %.*s",
- type, (int) name->m_name.length, name->m_name.str));
-
- DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
- type == TYPE_ENUM_FUNCTION);
+ DBUG_PRINT("enter", ("type: %s name: %.*s",
+ type_str(),
+ (int) name->m_name.length, name->m_name.str));
+ MDL_key::enum_mdl_namespace mdl_type= get_mdl_type();
/* Grab an exclusive MDL lock. */
if (lock_object_name(thd, mdl_type, name->m_db.str, name->m_name.str))
@@ -1343,8 +1368,8 @@ sp_drop_routine(THD *thd, stored_procedure_type type, const sp_name *name)
if (!(table= open_proc_table_for_update(thd)))
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
- if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK)
- ret= sp_drop_routine_internal(thd, type, name, table);
+ if ((ret= db_find_routine_aux(thd, name, table)) == SP_OK)
+ ret= sp_drop_routine_internal(thd, name, table);
if (ret == SP_OK &&
write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
@@ -1367,8 +1392,6 @@ sp_drop_routine(THD *thd, stored_procedure_type type, const sp_name *name)
successful update, the cache is invalidated.
@param thd Thread context.
- @param type Stored routine type
- (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
@param name Stored routine name.
@param chistics New values of stored routine attributes to write.
@@ -1377,20 +1400,16 @@ sp_drop_routine(THD *thd, stored_procedure_type type, const sp_name *name)
*/
int
-sp_update_routine(THD *thd, stored_procedure_type type, const sp_name *name,
- const st_sp_chistics *chistics)
+Sp_handler::sp_update_routine(THD *thd, const Database_qualified_name *name,
+ const st_sp_chistics *chistics) const
{
TABLE *table;
int ret;
- MDL_key::enum_mdl_namespace mdl_type= type == TYPE_ENUM_FUNCTION ?
- MDL_key::FUNCTION : MDL_key::PROCEDURE;
DBUG_ENTER("sp_update_routine");
- DBUG_PRINT("enter", ("type: %d name: %.*s",
- (int) type,
+ DBUG_PRINT("enter", ("type: %s name: %.*s",
+ type_str(),
(int) name->m_name.length, name->m_name.str));
-
- DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
- type == TYPE_ENUM_FUNCTION);
+ MDL_key::enum_mdl_namespace mdl_type= get_mdl_type();
/* Grab an exclusive MDL lock. */
if (lock_object_name(thd, mdl_type, name->m_db.str, name->m_name.str))
@@ -1399,9 +1418,9 @@ sp_update_routine(THD *thd, stored_procedure_type type, const sp_name *name,
if (!(table= open_proc_table_for_update(thd)))
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
- if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK)
+ if ((ret= db_find_routine_aux(thd, name, table)) == SP_OK)
{
- if (type == TYPE_ENUM_FUNCTION && ! trust_function_creators &&
+ if (type() == TYPE_ENUM_FUNCTION && ! trust_function_creators &&
mysql_bin_log.is_open() &&
(chistics->daccess == SP_CONTAINS_SQL ||
chistics->daccess == SP_MODIFIES_SQL_DATA))
@@ -1650,8 +1669,6 @@ err:
calls sp_head::show_create_routine() for the object.
@param thd Thread context.
- @param type Stored routine type
- (TYPE_ENUM_PROCEDURE or TYPE_ENUM_FUNCTION)
@param name Stored routine name.
@return Error status.
@@ -1660,19 +1677,16 @@ err:
*/
bool
-sp_show_create_routine(THD *thd,
- stored_procedure_type type, const sp_name *name)
+Sp_handler::sp_show_create_routine(THD *thd,
+ const Database_qualified_name *name) const
{
sp_head *sp;
DBUG_ENTER("sp_show_create_routine");
- DBUG_PRINT("enter", ("name: %.*s",
+ DBUG_PRINT("enter", ("type: %s name: %.*s",
+ type_str(),
(int) name->m_name.length,
name->m_name.str));
-
- DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
- type == TYPE_ENUM_FUNCTION);
-
/*
@todo: Consider using prelocking for this code as well. Currently
SHOW CREATE PROCEDURE/FUNCTION is a dirty read of the data
@@ -1680,17 +1694,16 @@ sp_show_create_routine(THD *thd,
It is "safe" to do as long as it doesn't affect the results
of the binary log or the query cache, which currently it does not.
*/
- if (sp_cache_routine(thd, type, name, FALSE, &sp))
+ if (sp_cache_routine(thd, name, false, &sp))
DBUG_RETURN(TRUE);
- if (sp == NULL || sp->show_create_routine(thd, type))
+ if (sp == NULL || sp->show_create_routine(thd, this))
{
/*
If we have insufficient privileges, pretend the routine
does not exist.
*/
- my_error(ER_SP_DOES_NOT_EXIST, MYF(0), stored_procedure_type_to_str(type),
- name->m_name.str);
+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), type_str(), name->m_name.str);
DBUG_RETURN(TRUE);
}
@@ -1703,7 +1716,6 @@ sp_show_create_routine(THD *thd,
stored procedures cache and looking into mysql.proc if needed.
@param thd thread context
- @param type type of object (TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE)
@param name name of procedure
@param cp hash to look routine in
@param cache_only if true perform cache-only lookup
@@ -1716,18 +1728,16 @@ sp_show_create_routine(THD *thd,
*/
sp_head *
-sp_find_routine(THD *thd, stored_procedure_type type, const sp_name *name,
- sp_cache **cp, bool cache_only)
+Sp_handler::sp_find_routine(THD *thd, const Database_qualified_name *name,
+ bool cache_only) const
{
+ sp_cache **cp= get_cache(thd);
sp_head *sp;
- ulong depth= (type == TYPE_ENUM_PROCEDURE ?
- thd->variables.max_sp_recursion_depth :
- 0);
DBUG_ENTER("sp_find_routine");
- DBUG_PRINT("enter", ("name: %.*s.%.*s type: %d cache only %d",
+ DBUG_PRINT("enter", ("name: %.*s.%.*s type: %s cache only %d",
(int) name->m_db.length, name->m_db.str,
(int) name->m_name.length, name->m_name.str,
- type, cache_only));
+ type_str(), cache_only));
if ((sp= sp_cache_lookup(cp, name)))
{
@@ -1750,9 +1760,9 @@ sp_find_routine(THD *thd, stored_procedure_type type, const sp_name *name,
sp->m_first_free_instance->m_recursion_level,
sp->m_first_free_instance->m_flags));
DBUG_ASSERT(!(sp->m_first_free_instance->m_flags & sp_head::IS_INVOKED));
- if (sp->m_first_free_instance->m_recursion_level > depth)
+ if (sp->m_first_free_instance->m_recursion_level > recursion_depth(thd))
{
- sp->recursion_level_error(thd);
+ recursion_level_error(thd, sp);
DBUG_RETURN(0);
}
DBUG_RETURN(sp->m_first_free_instance);
@@ -1764,18 +1774,18 @@ sp_find_routine(THD *thd, stored_procedure_type type, const sp_name *name,
*/
level= sp->m_last_cached_sp->m_recursion_level + 1;
- if (level > depth)
+ if (level > recursion_depth(thd))
{
- sp->recursion_level_error(thd);
+ recursion_level_error(thd, sp);
DBUG_RETURN(0);
}
- if (type == TYPE_ENUM_FUNCTION)
+ if (type() == TYPE_ENUM_FUNCTION)
{
sp_returns_type(thd, retstr, sp);
returns= retstr.lex_cstring();
}
- if (db_load_routine(thd, type, name, &new_sp,
+ if (db_load_routine(thd, name, &new_sp,
sp->m_sql_mode, sp->m_params, returns,
sp->m_body, sp->chistics(),
sp->m_definer,
@@ -1795,7 +1805,7 @@ sp_find_routine(THD *thd, stored_procedure_type type, const sp_name *name,
}
if (!cache_only)
{
- if (db_find_routine(thd, type, name, &sp) == SP_OK)
+ if (db_find_routine(thd, name, &sp) == SP_OK)
{
sp_cache_insert(cp, sp);
DBUG_PRINT("info", ("added new: 0x%lx, level: %lu, flags %x",
@@ -1813,8 +1823,6 @@ sp_find_routine(THD *thd, stored_procedure_type type, const sp_name *name,
@param thd Thread handler
@param routines List of needles in the hay stack
- @param is_proc Indicates whether routines in the list are procedures
- or functions.
@return
@retval FALSE Found.
@@ -1822,7 +1830,7 @@ sp_find_routine(THD *thd, stored_procedure_type type, const sp_name *name,
*/
bool
-sp_exist_routines(THD *thd, TABLE_LIST *routines, bool is_proc)
+Sp_handler::sp_exist_routines(THD *thd, TABLE_LIST *routines) const
{
TABLE_LIST *routine;
bool sp_object_found;
@@ -1836,12 +1844,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool is_proc)
thd->make_lex_string(&lex_name, routine->table_name,
strlen(routine->table_name));
name= new sp_name(&lex_db, &lex_name, true);
- sp_object_found= is_proc ? sp_find_routine(thd, TYPE_ENUM_PROCEDURE,
- name, &thd->sp_proc_cache,
- FALSE) != NULL :
- sp_find_routine(thd, TYPE_ENUM_FUNCTION,
- name, &thd->sp_func_cache,
- FALSE) != NULL;
+ sp_object_found= sp_find_routine(thd, name, false) != NULL;
thd->get_stmt_da()->clear_warning_info(thd->query_id);
if (! sp_object_found)
{
@@ -1932,20 +1935,18 @@ bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
@param arena Arena in which memory for new element of the set
will be allocated
@param rt Routine name
- @param rt_type Routine type (one of TYPE_ENUM_PROCEDURE/...)
@note
Will also add element to end of 'Query_tables_list::sroutines_list' list
(and will take into account that this is an explicitly used routine).
*/
-void sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
- const sp_name *rt, enum stored_procedure_type rt_type)
+void Sp_handler::add_used_routine(Query_tables_list *prelocking_ctx,
+ Query_arena *arena,
+ const Database_qualified_name *rt) const
{
- MDL_key key((rt_type == TYPE_ENUM_FUNCTION) ? MDL_key::FUNCTION :
- MDL_key::PROCEDURE,
- rt->m_db.str, rt->m_name.str);
- (void)sp_add_used_routine(prelocking_ctx, arena, &key, 0);
+ MDL_key key(get_mdl_type(), rt->m_db.str, rt->m_name.str);
+ (void) sp_add_used_routine(prelocking_ctx, arena, &key, 0);
prelocking_ctx->sroutines_list_own_last= prelocking_ctx->sroutines_list.next;
prelocking_ctx->sroutines_list_own_elements=
prelocking_ctx->sroutines_list.elements;
@@ -2072,24 +2073,24 @@ void sp_update_stmt_used_routines(THD *thd, Query_tables_list *prelocking_ctx,
prelocking until 'sp_name' is eradicated as a class.
*/
-int sp_cache_routine(THD *thd, Sroutine_hash_entry *rt,
- bool lookup_only, sp_head **sp)
+int Sroutine_hash_entry::sp_cache_routine(THD *thd,
+ bool lookup_only,
+ sp_head **sp) const
{
char qname_buff[NAME_LEN*2+1+1];
- sp_name name(&rt->mdl_request.key, qname_buff);
- MDL_key::enum_mdl_namespace mdl_type= rt->mdl_request.key.mdl_namespace();
- stored_procedure_type type= ((mdl_type == MDL_key::FUNCTION) ?
- TYPE_ENUM_FUNCTION : TYPE_ENUM_PROCEDURE);
-
+ sp_name name(&mdl_request.key, qname_buff);
+ MDL_key::enum_mdl_namespace mdl_type= mdl_request.key.mdl_namespace();
+ const Sp_handler *sph= Sp_handler::handler(mdl_type);
+ DBUG_ASSERT(sph);
/*
Check that we have an MDL lock on this routine, unless it's a top-level
CALL. The assert below should be unambiguous: the first element
in sroutines_list has an MDL lock unless it's a top-level call, or a
trigger, but triggers can't occur here (see the preceding assert).
*/
- DBUG_ASSERT(rt->mdl_request.ticket || rt == thd->lex->sroutines_list.first);
+ DBUG_ASSERT(mdl_request.ticket || this == thd->lex->sroutines_list.first);
- return sp_cache_routine(thd, type, &name, lookup_only, sp);
+ return sph->sp_cache_routine(thd, &name, lookup_only, sp);
}
@@ -2100,7 +2101,6 @@ int sp_cache_routine(THD *thd, Sroutine_hash_entry *rt,
loading.
@param[in] thd Thread context.
- @param[in] type Type of object (TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE).
@param[in] name Name of routine.
@param[in] lookup_only Only check that the routine is in the cache.
If it's not, don't try to load. If it is present,
@@ -2113,17 +2113,17 @@ int sp_cache_routine(THD *thd, Sroutine_hash_entry *rt,
@retval non-0 Error while loading routine from mysql,proc table.
*/
-int sp_cache_routine(THD *thd, enum stored_procedure_type type,
- const sp_name *name,
- bool lookup_only, sp_head **sp)
+int Sp_handler::sp_cache_routine(THD *thd,
+ const Database_qualified_name *name,
+ bool lookup_only,
+ sp_head **sp) const
{
int ret= 0;
- sp_cache **spc= (type == TYPE_ENUM_FUNCTION ?
- &thd->sp_func_cache : &thd->sp_proc_cache);
+ sp_cache **spc= get_cache(thd);
DBUG_ENTER("sp_cache_routine");
- DBUG_ASSERT(type == TYPE_ENUM_FUNCTION || type == TYPE_ENUM_PROCEDURE);
+ DBUG_ASSERT(spc);
*sp= sp_cache_lookup(spc, name);
@@ -2137,7 +2137,7 @@ int sp_cache_routine(THD *thd, enum stored_procedure_type type,
DBUG_RETURN(SP_OK);
}
- switch ((ret= db_find_routine(thd, type, name, sp)))
+ switch ((ret= db_find_routine(thd, name, sp)))
{
case SP_OK:
sp_cache_insert(spc, *sp);
@@ -2179,16 +2179,15 @@ int sp_cache_routine(THD *thd, enum stored_procedure_type type,
Returns TRUE on success, FALSE on (alloc) failure.
*/
bool
-show_create_sp(THD *thd, String *buf,
- stored_procedure_type type,
- const LEX_CSTRING &db,
- const LEX_CSTRING &name,
- const LEX_CSTRING &params,
- const LEX_CSTRING &returns,
- const LEX_CSTRING &body,
- const st_sp_chistics &chistics,
- const AUTHID &definer,
- sql_mode_t sql_mode)
+Sp_handler::show_create_sp(THD *thd, String *buf,
+ const LEX_CSTRING &db,
+ const LEX_CSTRING &name,
+ const LEX_CSTRING &params,
+ const LEX_CSTRING &returns,
+ const LEX_CSTRING &body,
+ const st_sp_chistics &chistics,
+ const AUTHID &definer,
+ sql_mode_t sql_mode) const
{
sql_mode_t old_sql_mode= thd->variables.sql_mode;
/* Make some room to begin with */
@@ -2203,10 +2202,8 @@ show_create_sp(THD *thd, String *buf,
if (thd->lex->create_info.or_replace())
buf->append(STRING_WITH_LEN("OR REPLACE "));
append_definer(thd, buf, &definer.user, &definer.host);
- if (type == TYPE_ENUM_FUNCTION)
- buf->append(STRING_WITH_LEN("FUNCTION "));
- else
- buf->append(STRING_WITH_LEN("PROCEDURE "));
+ buf->append(type_lex_cstring());
+ buf->append(STRING_WITH_LEN(" "));
if (thd->lex->create_info.if_not_exists())
buf->append(STRING_WITH_LEN("IF NOT EXISTS "));
@@ -2219,7 +2216,7 @@ show_create_sp(THD *thd, String *buf,
buf->append('(');
buf->append(params);
buf->append(')');
- if (type == TYPE_ENUM_FUNCTION)
+ if (type() == TYPE_ENUM_FUNCTION)
{
if (sql_mode & MODE_ORACLE)
buf->append(STRING_WITH_LEN(" RETURN "));
@@ -2259,15 +2256,6 @@ show_create_sp(THD *thd, String *buf,
}
-static LEX_CSTRING empty_body_lex_cstring(stored_procedure_type type)
-{
- static LEX_CSTRING empty_body_func= {C_STRING_WITH_LEN("RETURN NULL")};
- static LEX_CSTRING empty_body_proc= {C_STRING_WITH_LEN("BEGIN END")};
- return type == TYPE_ENUM_FUNCTION ? empty_body_func :
- empty_body_proc;
-}
-
-
/**
@brief The function loads sp_head struct for information schema purposes
(used for I_S ROUTINES & PARAMETERS tables).
@@ -2289,21 +2277,19 @@ static LEX_CSTRING empty_body_lex_cstring(stored_procedure_type type)
*/
sp_head *
-sp_load_for_information_schema(THD *thd, TABLE *proc_table,
- stored_procedure_type type,
- const LEX_CSTRING &db,
- const LEX_CSTRING &name,
- const LEX_CSTRING &params,
- const LEX_CSTRING &returns,
- sql_mode_t sql_mode,
- bool *free_sp_head)
+Sp_handler::sp_load_for_information_schema(THD *thd, TABLE *proc_table,
+ const LEX_CSTRING &db,
+ const LEX_CSTRING &name,
+ const LEX_CSTRING &params,
+ const LEX_CSTRING &returns,
+ sql_mode_t sql_mode,
+ bool *free_sp_head) const
{
String defstr;
const AUTHID definer= {{STRING_WITH_LEN("")}, {STRING_WITH_LEN("")}};
sp_head *sp;
- sp_cache **spc= ((type == TYPE_ENUM_PROCEDURE) ?
- &thd->sp_proc_cache : &thd->sp_func_cache);
- sp_name sp_name_obj(&db, &name, true);
+ sp_cache **spc= get_cache(thd);
+ sp_name sp_name_obj(&db, &name, true); // This can change "name"
*free_sp_head= 0;
if ((sp= sp_cache_lookup(spc, &sp_name_obj)))
{
@@ -2314,9 +2300,9 @@ sp_load_for_information_schema(THD *thd, TABLE *proc_table,
Stored_program_creation_ctx *creation_ctx=
Stored_routine_creation_ctx::load_from_db(thd, &sp_name_obj, proc_table);
defstr.set_charset(creation_ctx->get_client_cs());
- if (!show_create_sp(thd, &defstr, type,
+ if (!show_create_sp(thd, &defstr,
sp_name_obj.m_db, sp_name_obj.m_name,
- params, returns, empty_body_lex_cstring(type),
+ params, returns, empty_body_lex_cstring(),
Sp_chistics(), definer, sql_mode))
return 0;