diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-07-31 23:00:02 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-07-31 23:00:02 +0400 |
commit | c9218ff43989bf2385d1f62b45ed1f6229cbc5a5 (patch) | |
tree | a99c10f5e304662f3b51141871f94ee64eebaee6 /sql/sp.cc | |
parent | 4937474f862010c90f76bf879a70c1edf17e7c85 (diff) | |
download | mariadb-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.cc | 398 |
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 ¶ms, - 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, ¶ms); - 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 ¶ms, - 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 ¶ms, + 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 ¶ms, - 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 ¶ms, + 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 ¶ms, - 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 ¶ms, + 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; |