diff options
-rw-r--r-- | sql/event_data_objects.cc | 4 | ||||
-rw-r--r-- | sql/event_queue.cc | 4 | ||||
-rw-r--r-- | sql/events.cc | 4 | ||||
-rw-r--r-- | sql/mysqld.cc | 3 | ||||
-rw-r--r-- | sql/sp.cc | 58 | ||||
-rw-r--r-- | sql/sp.h | 45 | ||||
-rw-r--r-- | sql/sp_head.cc | 175 | ||||
-rw-r--r-- | sql/sp_head.h | 136 | ||||
-rw-r--r-- | sql/sql_acl.cc | 15 | ||||
-rw-r--r-- | sql/sql_const.h | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 4 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 11 | ||||
-rw-r--r-- | sql/sql_show.cc | 14 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 14 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 2 |
16 files changed, 410 insertions, 83 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 39f1889142e..564cf53a154 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -32,6 +32,7 @@ #include "event_db_repository.h" #include "sp_head.h" #include "sql_show.h" // append_definer, append_identifier +#include "mysql/psi/mysql_sp.h" #ifdef WITH_WSREP #include "wsrep_trans_observer.h" #endif /* WITH_WSREP */ @@ -1456,6 +1457,9 @@ Event_job_data::execute(THD *thd, bool drop) sphead->set_creation_ctx(creation_ctx); sphead->optimize(); + sphead->m_sp_share= MYSQL_GET_SP_SHARE(SP_TYPE_EVENT, + dbname.str, dbname.length, + name.str, name.length); ret= sphead->execute_procedure(thd, &empty_item_list); /* There is no pre-locking and therefore there should be no diff --git a/sql/event_queue.cc b/sql/event_queue.cc index 89bd672671f..1530c4e7f0d 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -24,6 +24,7 @@ #include "tztime.h" // my_tz_find, my_tz_OFFSET0, struct Time_zone #include "log.h" // sql_print_error #include "sql_class.h" // struct THD +#include "mysql/psi/mysql_sp.h" /** @addtogroup Event_Scheduler @@ -351,6 +352,9 @@ Event_queue::drop_matching_events(THD *thd, const LEX_CSTRING *pattern, is ok. */ queue_remove(&queue, i); + /* Drop statistics for this stored program from performance schema. */ + MYSQL_DROP_SP(SP_TYPE_EVENT, et->dbname.str, et->dbname.length, + et->name.str, et->name.length); delete et; } else diff --git a/sql/events.cc b/sql/events.cc index 0014ce42d28..1a97d377376 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -34,6 +34,7 @@ #include "sp_head.h" // for Stored_program_creation_ctx #include "set_var.h" #include "lock.h" // lock_object_name +#include "mysql/psi/mysql_sp.h" /** @addtogroup Event_Scheduler @@ -620,6 +621,9 @@ Events::drop_event(THD *thd, const LEX_CSTRING *dbname, /* Binlog the drop event. */ DBUG_ASSERT(thd->query() && thd->query_length()); ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + /* Drop statistics for this stored program from performance schema. */ + MYSQL_DROP_SP(SP_TYPE_EVENT, + dbname->str, dbname->length, name->str, name->length); } thd->restore_stmt_binlog_format(save_binlog_format); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a47782788a7..40255830a0a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -113,6 +113,7 @@ #include "sp_rcontext.h" #include "sp_cache.h" #include "sql_reload.h" // reload_acl_and_cache +#include "sp_head.h" // init_sp_psi_keys #ifdef HAVE_POLL_H #include <poll.h> @@ -9698,6 +9699,8 @@ void init_server_psi_keys(void) count= array_elements(sql_statement_info); mysql_statement_register(category, sql_statement_info, count); + init_sp_psi_keys(); + category= "com"; init_com_statement_info(); diff --git a/sql/sp.cc b/sql/sp.cc index 103f72b3089..67b6b6a1887 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -34,6 +34,7 @@ #include "lock.h" // lock_object_name #include <my_user.h> +#include "mysql/psi/mysql_sp.h" sp_cache **Sp_handler_procedure::get_cache(THD *thd) const { @@ -718,7 +719,7 @@ Sp_handler::db_find_routine(THD *thd, table->field[MYSQL_PROC_FIELD_PARAM_LIST]->val_str_nopad(thd->mem_root, ¶ms); - if (type() != TYPE_ENUM_FUNCTION) + if (type() != SP_TYPE_FUNCTION) returns= empty_clex_str; else if (table->field[MYSQL_PROC_FIELD_RETURNS]->val_str_nopad(thd->mem_root, &returns)) @@ -866,6 +867,8 @@ static sp_head *sp_compile(THD *thd, String *defstr, sql_mode_t sql_mode, thd->spcont= old_spcont; thd->variables.sql_mode= old_sql_mode; thd->variables.select_limit= old_select_limit; + if (sp != NULL) + sp->init_psi_share(); return sp; } @@ -1001,7 +1004,7 @@ Sp_handler::db_load_routine(THD *thd, const Database_qualified_name *name, (*sphp)->set_creation_ctx(creation_ctx); (*sphp)->optimize(); - if (type() == TYPE_ENUM_PACKAGE_BODY) + if (type() == SP_TYPE_PACKAGE_BODY) { sp_package *package= (*sphp)->get_package(); List_iterator<LEX> it(package->m_routine_implementations); @@ -1104,6 +1107,9 @@ Sp_handler::sp_drop_routine_internal(THD *thd, DBUG_ASSERT(spc); if ((sp= sp_cache_lookup(spc, name))) sp_cache_flush_obsolete(spc, &sp); + /* Drop statistics for this stored program from performance schema. */ + MYSQL_DROP_SP(type(), name->m_db.str, name->m_db.length, + name->m_name.str, name->m_name.length); DBUG_RETURN(SP_OK); } @@ -1231,16 +1237,17 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const if (lex->create_info.or_replace()) { switch (type()) { - case TYPE_ENUM_PACKAGE: + case SP_TYPE_PACKAGE: // Drop together with its PACKAGE BODY mysql.proc record ret= sp_handler_package_spec.sp_find_and_drop_routine(thd, table, sp); break; - case TYPE_ENUM_PACKAGE_BODY: - case TYPE_ENUM_FUNCTION: - case TYPE_ENUM_PROCEDURE: + case SP_TYPE_PACKAGE_BODY: + case SP_TYPE_FUNCTION: + case SP_TYPE_PROCEDURE: ret= sp_drop_routine_internal(thd, sp, table); break; - case TYPE_ENUM_TRIGGER: + case SP_TYPE_TRIGGER: + case SP_TYPE_EVENT: DBUG_ASSERT(0); ret= SP_OK; } @@ -1257,7 +1264,7 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const ret= FALSE; // Setting retstr as it is used for logging. - if (type() == TYPE_ENUM_FUNCTION) + if (type() == SP_TYPE_FUNCTION) { sp_returns_type(thd, retstr, sp); returns= retstr.lex_cstring(); @@ -1340,7 +1347,7 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const table->field[MYSQL_PROC_FIELD_PARAM_LIST]-> store(sp->m_params, system_charset_info); - if (type() == TYPE_ENUM_FUNCTION) + if (type() == SP_TYPE_FUNCTION) { sp_returns_type(thd, retstr, sp); returns= retstr.lex_cstring(); @@ -1372,7 +1379,7 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const store(sp->comment(), system_charset_info); } - if (type() == TYPE_ENUM_FUNCTION && + if (type() == SP_TYPE_FUNCTION && !trust_function_creators && mysql_bin_log.is_open()) { if (!sp->detistic()) @@ -1624,7 +1631,7 @@ Sp_handler::sp_update_routine(THD *thd, const Database_qualified_name *name, if ((ret= db_find_routine_aux(thd, name, table)) == SP_OK) { - if (type() == TYPE_ENUM_FUNCTION && ! trust_function_creators && + if (type() == SP_TYPE_FUNCTION && ! trust_function_creators && mysql_bin_log.is_open() && (chistics->daccess == SP_CONTAINS_SQL || chistics->daccess == SP_MODIFIES_SQL_DATA)) @@ -1770,7 +1777,7 @@ bool lock_db_routines(THD *thd, const char *db) longlong sp_type= table->field[MYSQL_PROC_MYSQL_TYPE]->val_int(); MDL_request *mdl_request= new (thd->mem_root) MDL_request; - const Sp_handler *sph= Sp_handler::handler((stored_procedure_type) + const Sp_handler *sph= Sp_handler::handler((enum_sp_type) sp_type); if (!sph) sph= &sp_handler_procedure; @@ -1813,6 +1820,8 @@ sp_drop_db_routines(THD *thd, const char *db) uint key_len; MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); uchar keybuf[MAX_KEY_LENGTH]; + size_t db_length= strlen(db); + Sql_mode_instant_remove smir(thd, MODE_PAD_CHAR_TO_FULL_LENGTH); // see below DBUG_ENTER("sp_drop_db_routines"); DBUG_PRINT("enter", ("db: %s", db)); @@ -1820,7 +1829,7 @@ sp_drop_db_routines(THD *thd, const char *db) if (!(table= open_proc_table_for_update(thd))) goto err; - table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info); + table->field[MYSQL_PROC_FIELD_DB]->store(db, db_length, system_charset_info); key_len= table->key_info->key_part[0].store_length; table->field[MYSQL_PROC_FIELD_DB]->get_key_image(keybuf, key_len, Field::itRAW); @@ -1839,7 +1848,18 @@ sp_drop_db_routines(THD *thd, const char *db) do { if (! table->file->ha_delete_row(table->record[0])) + { deleted= TRUE; /* We deleted something */ +#ifdef HAVE_PSI_SP_INTERFACE + String buf; + // the following assumes MODE_PAD_CHAR_TO_FULL_LENGTH being *unset* + String *name= table->field[MYSQL_PROC_FIELD_NAME]->val_str(&buf); + + enum_sp_type sp_type= (enum_sp_type) table->field[MYSQL_PROC_MYSQL_TYPE]->ptr[0]; + /* Drop statistics for this stored program from performance schema. */ + MYSQL_DROP_SP(sp_type, db, db_length, name->ptr(), name->length()); +#endif + } else { ret= SP_DELETE_ROW_FAILED; @@ -2013,7 +2033,7 @@ Sp_handler::sp_clone_and_link_routine(THD *thd, DBUG_RETURN(0); } - if (type() == TYPE_ENUM_FUNCTION) + if (type() == SP_TYPE_FUNCTION) { sp_returns_type(thd, retstr, sp); returns= retstr.lex_cstring(); @@ -2361,7 +2381,7 @@ is_package_public_routine(THD *thd, const LEX_CSTRING &db, const LEX_CSTRING &package, const LEX_CSTRING &routine, - stored_procedure_type type) + enum_sp_type type) { sp_head *sp= NULL; Database_qualified_name tmp(db, package); @@ -2395,7 +2415,7 @@ is_package_public_routine_quick(THD *thd, const LEX_CSTRING &db, const LEX_CSTRING &pkgname, const LEX_CSTRING &name, - stored_procedure_type type) + enum_sp_type type) { Database_qualified_name tmp(db, pkgname); sp_head *sp= sp_cache_lookup(&thd->sp_package_spec_cache, &tmp); @@ -2414,7 +2434,7 @@ static bool is_package_body_routine(THD *thd, sp_package *pkg, const LEX_CSTRING &name1, const LEX_CSTRING &name2, - stored_procedure_type type) + enum_sp_type type) { return Sp_handler::eq_routine_name(pkg->m_name, name1) && (pkg->m_routine_declarations.find(name2, type) || @@ -2842,7 +2862,7 @@ Sp_handler::sp_cache_package_routine(THD *thd, bool lookup_only, sp_head **sp) const { DBUG_ENTER("sp_cache_package_routine"); - DBUG_ASSERT(type() == TYPE_ENUM_FUNCTION || type() == TYPE_ENUM_PROCEDURE); + DBUG_ASSERT(type() == SP_TYPE_FUNCTION || type() == SP_TYPE_PROCEDURE); sp_name pkgname(&name->m_db, &pkgname_cstr, false); sp_head *ph= NULL; int ret= sp_handler_package_body.sp_cache_routine(thd, &pkgname, @@ -2941,7 +2961,7 @@ Sp_handler::show_create_sp(THD *thd, String *buf, buf->append('('); buf->append(¶ms); buf->append(')'); - if (type() == TYPE_ENUM_FUNCTION) + if (type() == SP_TYPE_FUNCTION) { if (sql_mode & MODE_ORACLE) buf->append(STRING_WITH_LEN(" RETURN ")); @@ -47,17 +47,18 @@ template <typename T> class SQL_I_List; /* Values for the type enum. This reflects the order of the enum declaration in the CREATE TABLE command. + See also storage/perfschema/my_thread.h */ -enum stored_procedure_type +enum enum_sp_type { - TYPE_ENUM_FUNCTION=1, - TYPE_ENUM_PROCEDURE=2, - TYPE_ENUM_PACKAGE=3, - TYPE_ENUM_PACKAGE_BODY=4, - TYPE_ENUM_TRIGGER=5 + SP_TYPE_FUNCTION=1, + SP_TYPE_PROCEDURE=2, + SP_TYPE_PACKAGE=3, + SP_TYPE_PACKAGE_BODY=4, + SP_TYPE_TRIGGER=5, + SP_TYPE_EVENT=6, }; - class Sp_handler { bool sp_resolve_package_routine_explicit(THD *thd, @@ -120,13 +121,13 @@ public: // TODO: make it private or protected public: virtual ~Sp_handler() {} static const Sp_handler *handler(enum enum_sql_command cmd); - static const Sp_handler *handler(stored_procedure_type type); + static const Sp_handler *handler(enum_sp_type type); static const Sp_handler *handler(MDL_key::enum_mdl_namespace ns); /* Return a handler only those SP objects that store definitions in the mysql.proc system table */ - static const Sp_handler *handler_mysql_proc(stored_procedure_type type) + static const Sp_handler *handler_mysql_proc(enum_sp_type type) { const Sp_handler *sph= handler(type); return sph ? sph->sp_handler_mysql_proc() : NULL; @@ -153,7 +154,7 @@ public: { return this; } - virtual stored_procedure_type type() const= 0; + virtual enum_sp_type type() const= 0; virtual LEX_CSTRING type_lex_cstring() const= 0; virtual LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const { @@ -248,7 +249,7 @@ public: class Sp_handler_procedure: public Sp_handler { public: - stored_procedure_type type() const { return TYPE_ENUM_PROCEDURE; } + enum_sp_type type() const { return SP_TYPE_PROCEDURE; } LEX_CSTRING type_lex_cstring() const { static LEX_CSTRING m_type_str= { STRING_WITH_LEN("PROCEDURE")}; @@ -298,7 +299,7 @@ public: class Sp_handler_function: public Sp_handler { public: - stored_procedure_type type() const { return TYPE_ENUM_FUNCTION; } + enum_sp_type type() const { return SP_TYPE_FUNCTION; } LEX_CSTRING type_lex_cstring() const { static LEX_CSTRING m_type_str= { STRING_WITH_LEN("FUNCTION")}; @@ -367,7 +368,7 @@ public: // TODO: make it private or protected const Database_qualified_name *name) const; public: - stored_procedure_type type() const { return TYPE_ENUM_PACKAGE; } + enum_sp_type type() const { return SP_TYPE_PACKAGE; } LEX_CSTRING type_lex_cstring() const { static LEX_CSTRING m_type_str= {STRING_WITH_LEN("PACKAGE")}; @@ -400,7 +401,7 @@ public: class Sp_handler_package_body: public Sp_handler_package { public: - stored_procedure_type type() const { return TYPE_ENUM_PACKAGE_BODY; } + enum_sp_type type() const { return SP_TYPE_PACKAGE_BODY; } LEX_CSTRING type_lex_cstring() const { static LEX_CSTRING m_type_str= {STRING_WITH_LEN("PACKAGE BODY")}; @@ -433,7 +434,7 @@ public: class Sp_handler_trigger: public Sp_handler { public: - stored_procedure_type type() const { return TYPE_ENUM_TRIGGER; } + enum_sp_type type() const { return SP_TYPE_TRIGGER; } LEX_CSTRING type_lex_cstring() const { static LEX_CSTRING m_type_str= { STRING_WITH_LEN("TRIGGER")}; @@ -492,19 +493,21 @@ inline const Sp_handler *Sp_handler::handler(enum_sql_command cmd) } -inline const Sp_handler *Sp_handler::handler(stored_procedure_type type) +inline const Sp_handler *Sp_handler::handler(enum_sp_type type) { switch (type) { - case TYPE_ENUM_PROCEDURE: + case SP_TYPE_PROCEDURE: return &sp_handler_procedure; - case TYPE_ENUM_FUNCTION: + case SP_TYPE_FUNCTION: return &sp_handler_function; - case TYPE_ENUM_PACKAGE: + case SP_TYPE_PACKAGE: return &sp_handler_package_spec; - case TYPE_ENUM_PACKAGE_BODY: + case SP_TYPE_PACKAGE_BODY: return &sp_handler_package_body; - case TYPE_ENUM_TRIGGER: + case SP_TYPE_TRIGGER: return &sp_handler_trigger; + case SP_TYPE_EVENT: + break; } return NULL; } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fb99ad11552..53e4029d82d 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -56,8 +56,39 @@ #define SP_INSTR_UINT_MAXLEN 8 #define SP_STMT_PRINT_MAXLEN 40 - #include <my_user.h> +#include "mysql/psi/mysql_statement.h" +#include "mysql/psi/mysql_sp.h" + +#ifdef HAVE_PSI_INTERFACE +void init_sp_psi_keys() +{ + const char *category= "sp"; + const int num __attribute__((unused)) = __LINE__ + 3; + + PSI_server->register_statement(category, & sp_instr_stmt::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_set::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_set_trigger_field::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_jump::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_jump_if_not::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_freturn::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_preturn::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_hpush_jump::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_hpop::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_hreturn::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_cpush::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_cpop::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_copen::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_cclose::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_cfetch::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_agg_cfetch::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_cursor_copy_struct::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_error::psi_info, 1); + PSI_server->register_statement(category, & sp_instr_set_case_expr::psi_info, 1); + + DBUG_ASSERT(SP_PSI_STATEMENT_INFO_COUNT == __LINE__ - num); +} +#endif extern "C" uchar *sp_table_key(const uchar *ptr, size_t *plen, my_bool first); @@ -605,7 +636,7 @@ bool sp_head::eq_routine_spec(const sp_head *sp) const bool sp_package::validate_after_parser(THD *thd) { - if (m_handler->type() != TYPE_ENUM_PACKAGE_BODY) + if (m_handler->type() != SP_TYPE_PACKAGE_BODY) return false; sp_head *sp= sp_cache_lookup(&thd->sp_package_spec_cache, this); sp_package *spec= sp ? sp->get_package() : NULL; @@ -684,7 +715,7 @@ bool sp_package::validate_private_routines(THD *thd) LEX *sp_package::LexList::find(const LEX_CSTRING &name, - stored_procedure_type type) + enum_sp_type type) { List_iterator<LEX> it(*this); for (LEX *lex; (lex= it++); ) @@ -707,7 +738,7 @@ LEX *sp_package::LexList::find(const LEX_CSTRING &name, LEX *sp_package::LexList::find_qualified(const LEX_CSTRING &name, - stored_procedure_type type) + enum_sp_type type) { List_iterator<LEX> it(*this); for (LEX *lex; (lex= it++); ) @@ -721,6 +752,17 @@ LEX *sp_package::LexList::find_qualified(const LEX_CSTRING &name, } +void sp_package::init_psi_share() +{ + List_iterator<LEX> it(m_routine_implementations); + for (LEX *lex; (lex= it++); ) + { + DBUG_ASSERT(lex->sphead); + lex->sphead->init_psi_share(); + } + sp_head::init_psi_share(); +} + void sp_head::init(LEX *lex) { @@ -756,6 +798,13 @@ sp_head::init_sp_name(const sp_name *spname) DBUG_VOID_RETURN; } +void +sp_head::init_psi_share() +{ + m_sp_share= MYSQL_GET_SP_SHARE(m_handler->type(), m_db.str, m_db.length, + m_name.str, m_name.length); +} + void sp_head::set_body_start(THD *thd, const char *begin_ptr) @@ -1358,8 +1407,24 @@ sp_head::execute(THD *thd, bool merge_da_on_success) WSREP_DEBUG("assigned new next trx ID for SP, trx id: %" PRIu64, thd->wsrep_next_trx_id()); } #endif /* WITH_WSREP */ + +#ifdef HAVE_PSI_STATEMENT_INTERFACE + PSI_statement_locker_state state; + PSI_statement_locker *parent_locker; + PSI_statement_info *psi_info = i->get_psi_info(); + + parent_locker= thd->m_statement_psi; + thd->m_statement_psi= MYSQL_START_STATEMENT(& state, psi_info->m_key, + thd->db.str, thd->db.length, thd->charset(), m_sp_share); +#endif + err_status= i->execute(thd, &ip); +#ifdef HAVE_PSI_STATEMENT_INTERFACE + MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da()); + thd->m_statement_psi= parent_locker; +#endif + #ifdef WITH_WSREP if (WSREP(thd)) { @@ -1830,7 +1895,12 @@ sp_head::execute_trigger(THD *thd, thd->spcont= nctx; - err_status= execute(thd, FALSE); + { + PSI_sp_locker_state psi_state; + PSI_sp_locker *locker= MYSQL_START_SP(&psi_state, m_sp_share); + err_status= execute(thd, FALSE); + MYSQL_END_SP(locker); + } err_with_cleanup: thd->restore_active_arena(&call_arena, &backup_arena); @@ -2080,7 +2150,12 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, */ thd->set_n_backup_active_arena(call_arena, &backup_arena); - err_status= execute(thd, TRUE); + { + PSI_sp_locker_state psi_state; + PSI_sp_locker *locker= MYSQL_START_SP(&psi_state, m_sp_share); + err_status= execute(thd, TRUE); + MYSQL_END_SP(locker); + } thd->restore_active_arena(call_arena, &backup_arena); @@ -2361,11 +2436,12 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) #endif opt_trace_disable_if_no_stored_proc_func_access(thd, this); + + PSI_sp_locker_state psi_state; + PSI_sp_locker *locker= MYSQL_START_SP(&psi_state, m_sp_share); if (!err_status) - { err_status= execute(thd, TRUE); - DBUG_PRINT("info", ("execute returned %d", (int) err_status)); - } + MYSQL_END_SP(locker); if (save_log_general) thd->variables.option_bits &= ~OPTION_LOG_OFF; @@ -3554,6 +3630,9 @@ int sp_instr::exec_core(THD *thd, uint *nextp) sp_instr_stmt class functions */ +PSI_statement_info sp_instr_stmt::psi_info= +{ 0, "stmt", 0}; + int sp_instr_stmt::execute(THD *thd, uint *nextp) { @@ -3564,6 +3643,8 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) DBUG_ENTER("sp_instr_stmt::execute"); DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command())); + MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, m_query.str, m_query.length); + #if defined(ENABLED_PROFILING) /* This s-p instr is profilable and will be captured. */ thd->profiling.set_query_source(m_query.str, m_query.length); @@ -3690,6 +3771,9 @@ sp_instr_stmt::exec_core(THD *thd, uint *nextp) sp_instr_set class functions */ +PSI_statement_info sp_instr_set::psi_info= +{ 0, "set", 0}; + int sp_instr_set::execute(THD *thd, uint *nextp) { @@ -3840,6 +3924,9 @@ sp_instr_set_row_field_by_name::print(String *str) sp_instr_set_trigger_field class functions */ +PSI_statement_info sp_instr_set_trigger_field::psi_info= +{ 0, "set_trigger_field", 0}; + int sp_instr_set_trigger_field::execute(THD *thd, uint *nextp) { @@ -3883,6 +3970,9 @@ uint sp_instr_opt_meta::get_cont_dest() const sp_instr_jump class functions */ +PSI_statement_info sp_instr_jump::psi_info= +{ 0, "jump", 0}; + int sp_instr_jump::execute(THD *thd, uint *nextp) { @@ -3948,6 +4038,9 @@ sp_instr_jump::opt_move(uint dst, List<sp_instr> *bp) sp_instr_jump_if_not class functions */ +PSI_statement_info sp_instr_jump_if_not::psi_info= +{ 0, "jump_if_not", 0}; + int sp_instr_jump_if_not::execute(THD *thd, uint *nextp) { @@ -4043,6 +4136,9 @@ sp_instr_jump_if_not::opt_move(uint dst, List<sp_instr> *bp) sp_instr_freturn class functions */ +PSI_statement_info sp_instr_freturn::psi_info= +{ 0, "freturn", 0}; + int sp_instr_freturn::execute(THD *thd, uint *nextp) { @@ -4107,9 +4203,33 @@ sp_instr_freturn::print(String *str) } /* + sp_instr_preturn class functions +*/ + +PSI_statement_info sp_instr_preturn::psi_info= +{ 0, "preturn", 0}; + +int +sp_instr_preturn::execute(THD *thd, uint *nextp) +{ + DBUG_ENTER("sp_instr_preturn::execute"); + *nextp= UINT_MAX; + DBUG_RETURN(0); +} + +void +sp_instr_preturn::print(String *str) +{ + str->append(STRING_WITH_LEN("preturn")); +} + +/* sp_instr_hpush_jump class functions */ +PSI_statement_info sp_instr_hpush_jump::psi_info= +{ 0, "hpush_jump", 0}; + int sp_instr_hpush_jump::execute(THD *thd, uint *nextp) { @@ -4186,6 +4306,9 @@ sp_instr_hpush_jump::opt_mark(sp_head *sp, List<sp_instr> *leads) sp_instr_hpop class functions */ +PSI_statement_info sp_instr_hpop::psi_info= +{ 0, "hpop", 0}; + int sp_instr_hpop::execute(THD *thd, uint *nextp) { @@ -4210,6 +4333,9 @@ sp_instr_hpop::print(String *str) sp_instr_hreturn class functions */ +PSI_statement_info sp_instr_hreturn::psi_info= +{ 0, "hreturn", 0}; + int sp_instr_hreturn::execute(THD *thd, uint *nextp) { @@ -4269,6 +4395,9 @@ sp_instr_hreturn::opt_mark(sp_head *sp, List<sp_instr> *leads) sp_instr_cpush class functions */ +PSI_statement_info sp_instr_cpush::psi_info= +{ 0, "cpush", 0}; + int sp_instr_cpush::execute(THD *thd, uint *nextp) { @@ -4310,6 +4439,9 @@ sp_instr_cpush::print(String *str) sp_instr_cpop class functions */ +PSI_statement_info sp_instr_cpop::psi_info= +{ 0, "cpop", 0}; + int sp_instr_cpop::execute(THD *thd, uint *nextp) { @@ -4340,6 +4472,9 @@ sp_instr_cpop::print(String *str) Assert that we either have an error or a cursor */ +PSI_statement_info sp_instr_copen::psi_info= +{ 0, "copen", 0}; + int sp_instr_copen::execute(THD *thd, uint *nextp) { @@ -4398,6 +4533,9 @@ sp_instr_copen::print(String *str) sp_instr_cclose class functions */ +PSI_statement_info sp_instr_cclose::psi_info= +{ 0, "cclose", 0}; + int sp_instr_cclose::execute(THD *thd, uint *nextp) { @@ -4440,6 +4578,9 @@ sp_instr_cclose::print(String *str) sp_instr_cfetch class functions */ +PSI_statement_info sp_instr_cfetch::psi_info= +{ 0, "cfetch", 0}; + int sp_instr_cfetch::execute(THD *thd, uint *nextp) { @@ -4487,6 +4628,13 @@ sp_instr_cfetch::print(String *str) } } +/* + sp_instr_agg_cfetch class functions +*/ + +PSI_statement_info sp_instr_agg_cfetch::psi_info= +{ 0, "agg_cfetch", 0}; + int sp_instr_agg_cfetch::execute(THD *thd, uint *nextp) { @@ -4539,6 +4687,9 @@ sp_instr_agg_cfetch::print(String *str) - copies the cursor structure to the associated %ROWTYPE variable. */ +PSI_statement_info sp_instr_cursor_copy_struct::psi_info= +{ 0, "cursor_copy_struct", 0}; + int sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp) { @@ -4611,6 +4762,9 @@ sp_instr_cursor_copy_struct::print(String *str) sp_instr_error class functions */ +PSI_statement_info sp_instr_error::psi_info= +{ 0, "error", 0}; + int sp_instr_error::execute(THD *thd, uint *nextp) { @@ -4637,6 +4791,9 @@ sp_instr_error::print(String *str) sp_instr_set_case_expr class implementation **************************************************************************/ +PSI_statement_info sp_instr_set_case_expr::psi_info= +{ 0, "set_case_expr", 0}; + int sp_instr_set_case_expr::execute(THD *thd, uint *nextp) { diff --git a/sql/sp_head.h b/sql/sp_head.h index 6cf4610c466..fb490e40375 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -47,6 +47,14 @@ class sp_instr; class sp_instr_opt_meta; class sp_instr_jump_if_not; +/** + Number of PSI_statement_info instruments + for internal stored programs statements. +*/ +#ifdef HAVE_PSI_INTERFACE +void init_sp_psi_keys(void); +#endif + /*************************************************************************/ /** @@ -174,6 +182,11 @@ public: const Sp_handler *m_handler; uint m_flags; // Boolean attributes of a stored routine + /** + Instrumentation interface for SP. + */ + PSI_sp_share *m_sp_share; + Column_definition m_return_field_def; /**< This is used for FUNCTIONs only. */ const char *m_tmp_query; ///< Temporary pointer to sub query string @@ -856,6 +869,8 @@ public: return NULL; } + virtual void init_psi_share(); + protected: MEM_ROOT *m_thd_root; ///< Temp. store for thd's mem_root @@ -931,9 +946,9 @@ public: public: LexList() { elements= 0; } // Find a package routine by a non qualified name - LEX *find(const LEX_CSTRING &name, stored_procedure_type type); + LEX *find(const LEX_CSTRING &name, enum_sp_type type); // Find a package routine by a package-qualified name, e.g. 'pkg.proc' - LEX *find_qualified(const LEX_CSTRING &name, stored_procedure_type type); + LEX *find_qualified(const LEX_CSTRING &name, enum_sp_type type); // Check if a routine with the given qualified name already exists bool check_dup_qualified(const LEX_CSTRING &name, const Sp_handler *sph) { @@ -990,6 +1005,7 @@ public: m_routine_implementations.push_back(lex, &main_mem_root); } sp_package *get_package() { return this; } + void init_psi_share(); bool is_invoked() const { /* @@ -1156,6 +1172,7 @@ public: { m_ip= dst; } + virtual PSI_statement_info* get_psi_info() = 0; }; // class sp_instr : public Sql_alloc @@ -1282,6 +1299,12 @@ private: sp_lex_keeper m_lex_keeper; +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif + }; // class sp_instr_stmt : public sp_instr @@ -1316,6 +1339,12 @@ protected: uint m_offset; ///< Frame offset Item *m_value; sp_lex_keeper m_lex_keeper; + +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_set : public sp_instr @@ -1424,6 +1453,12 @@ private: Item_trigger_field *trigger_field; Item *value; sp_lex_keeper m_lex_keeper; + +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_trigger_field : public sp_instr @@ -1510,6 +1545,11 @@ public: m_dest= new_dest; } +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_jump : public sp_instr_opt_meta @@ -1561,6 +1601,11 @@ private: Item *m_expr; ///< The condition sp_lex_keeper m_lex_keeper; +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_jump_if_not : public sp_instr_jump @@ -1578,17 +1623,9 @@ public: virtual ~sp_instr_preturn() {} - virtual int execute(THD *thd, uint *nextp) - { - DBUG_ENTER("sp_instr_preturn::execute"); - *nextp= UINT_MAX; - DBUG_RETURN(0); - } + virtual int execute(THD *thd, uint *nextp); - virtual void print(String *str) - { - str->append(STRING_WITH_LEN("preturn")); - } + virtual void print(String *str); virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads) { @@ -1596,6 +1633,11 @@ public: return UINT_MAX; } +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_preturn : public sp_instr @@ -1633,6 +1675,11 @@ protected: const Type_handler *m_type_handler; sp_lex_keeper m_lex_keeper; +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_freturn : public sp_instr @@ -1698,6 +1745,11 @@ private: // debug version only). It's used in print(). uint m_frame; +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_hpush_jump : public sp_instr_jump @@ -1728,6 +1780,11 @@ private: uint m_count; +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_hpop : public sp_instr @@ -1762,12 +1819,16 @@ private: uint m_frame; +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_hreturn : public sp_instr_jump /** This is DECLARE CURSOR */ -class sp_instr_cpush : public sp_instr, - public sp_cursor +class sp_instr_cpush : public sp_instr, public sp_cursor { sp_instr_cpush(const sp_instr_cpush &); /**< Prevent use of these */ void operator=(sp_instr_cpush &); @@ -1796,6 +1857,11 @@ private: sp_lex_keeper m_lex_keeper; uint m_cursor; /**< Frame offset (for debugging) */ +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_cpush : public sp_instr @@ -1826,6 +1892,11 @@ private: uint m_count; +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_cpop : public sp_instr @@ -1853,6 +1924,11 @@ private: uint m_cursor; ///< Stack index +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_copen : public sp_instr_stmt @@ -1880,6 +1956,12 @@ public: virtual int execute(THD *thd, uint *nextp); virtual int exec_core(THD *thd, uint *nextp); virtual void print(String *str); + +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; @@ -1905,6 +1987,11 @@ private: uint m_cursor; +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_cclose : public sp_instr @@ -1939,6 +2026,11 @@ private: List<sp_variable> m_varlist; bool m_error_on_no_data; +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_cfetch : public sp_instr /* @@ -1963,6 +2055,12 @@ public: virtual int execute(THD *thd, uint *nextp); virtual void print(String *str); + +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_agg_cfetch : public sp_instr @@ -1996,6 +2094,11 @@ private: int m_errcode; +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_error : public sp_instr @@ -2035,6 +2138,11 @@ private: Item *m_case_expr; sp_lex_keeper m_lex_keeper; +#ifdef HAVE_PSI_INTERFACE +public: + virtual PSI_statement_info* get_psi_info() { return & psi_info; } + static PSI_statement_info psi_info; +#endif }; // class sp_instr_set_case_expr : public sp_instr_opt_meta bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index fbb80a2361e..827d983a134 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -5886,18 +5886,19 @@ struct PRIVS_TO_MERGE }; -static enum PRIVS_TO_MERGE::what sp_privs_to_merge(stored_procedure_type type) +static enum PRIVS_TO_MERGE::what sp_privs_to_merge(enum_sp_type type) { switch (type) { - case TYPE_ENUM_FUNCTION: + case SP_TYPE_FUNCTION: return PRIVS_TO_MERGE::FUNC; - case TYPE_ENUM_PROCEDURE: + case SP_TYPE_PROCEDURE: return PRIVS_TO_MERGE::PROC; - case TYPE_ENUM_PACKAGE: + case SP_TYPE_PACKAGE: return PRIVS_TO_MERGE::PACKAGE_SPEC; - case TYPE_ENUM_PACKAGE_BODY: + case SP_TYPE_PACKAGE_BODY: return PRIVS_TO_MERGE::PACKAGE_BODY; - case TYPE_ENUM_TRIGGER: + case SP_TYPE_EVENT: + case SP_TYPE_TRIGGER: break; } DBUG_ASSERT(0); @@ -7748,7 +7749,7 @@ static bool grant_load(THD *thd, continue; } } - stored_procedure_type type= (stored_procedure_type)procs_priv.routine_type()->val_int(); + enum_sp_type type= (enum_sp_type)procs_priv.routine_type()->val_int(); const Sp_handler *sph= Sp_handler::handler(type); if (!sph || !(hash= sph->get_priv_hash())) { diff --git a/sql/sql_const.h b/sql/sql_const.h index f7c820c727b..a3f0e35ac47 100644 --- a/sql/sql_const.h +++ b/sql/sql_const.h @@ -309,4 +309,6 @@ #define QUERY_PRIOR 6 #endif /* __WIN92__ */ +#define SP_PSI_STATEMENT_INFO_COUNT 19 + #endif /* SQL_CONST_INCLUDED */ diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ae8f0afa18c..0420e449ed0 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -6257,7 +6257,7 @@ static bool is_old(const char *str) bool LEX::is_trigger_new_or_old_reference(const LEX_CSTRING *name) const { // "name" is not necessarily NULL-terminated! - return sphead && sphead->m_handler->type() == TYPE_ENUM_TRIGGER && + return sphead && sphead->m_handler->type() == SP_TYPE_TRIGGER && name->length == 3 && (is_new(name->str) || is_old(name->str)); } @@ -9010,7 +9010,7 @@ sp_package *LEX::create_package_start(THD *thd, } if (unlikely(set_command_with_check(command, options))) return NULL; - if (sph->type() == TYPE_ENUM_PACKAGE_BODY) + if (sph->type() == SP_TYPE_PACKAGE_BODY) { /* If we start parsing a "CREATE PACKAGE BODY", we need to load diff --git a/sql/sql_lex.h b/sql/sql_lex.h index fefcdf99e12..f5611cb6cb0 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -30,7 +30,7 @@ #include "sql_alter.h" // Alter_info #include "sql_window.h" #include "sql_trigger.h" -#include "sp.h" // enum stored_procedure_type +#include "sp.h" // enum enum_sp_type #include "sql_tvc.h" #include "item.h" #include "sql_limit.h" // Select_limit_counters diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 03116a03d22..a7cd8d3cdca 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -101,6 +101,7 @@ #include "sql_bootstrap.h" #include "sql_sequence.h" #include "opt_trace.h" +#include "mysql/psi/mysql_sp.h" #include "my_json_writer.h" @@ -3063,7 +3064,7 @@ mysql_create_routine(THD *thd, LEX *lex) const LEX_CSTRING *name= lex->sphead->name(); #ifdef HAVE_DLOPEN - if (lex->sphead->m_handler->type() == TYPE_ENUM_FUNCTION) + if (lex->sphead->m_handler->type() == SP_TYPE_FUNCTION) { udf_func *udf = find_udf(name->str, name->length); @@ -5617,12 +5618,18 @@ mysql_execute_command(THD *thd) break; /* break super switch */ } /* end case group bracket */ case SQLCOM_COMPOUND: + { + sp_head *sp= lex->sphead; DBUG_ASSERT(all_tables == 0); DBUG_ASSERT(thd->in_sub_stmt == 0); - lex->sphead->m_sql_mode= thd->variables.sql_mode; + sp->m_sql_mode= thd->variables.sql_mode; + sp->m_sp_share= MYSQL_GET_SP_SHARE(sp->m_handler->type(), + sp->m_db.str, sp->m_db.length, + sp->m_name.str, sp->m_name.length); if (do_execute_sp(thd, lex->sphead)) goto error; break; + } case SQLCOM_ALTER_PROCEDURE: case SQLCOM_ALTER_FUNCTION: diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 90b3efe3655..b7b0bdc8dd7 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -6232,11 +6232,11 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, proc_table->field[MYSQL_PROC_FIELD_NAME]->val_str_nopad(thd->mem_root, &name); proc_table->field[MYSQL_PROC_FIELD_DEFINER]->val_str_nopad(thd->mem_root, &definer); sql_mode= (sql_mode_t) proc_table->field[MYSQL_PROC_FIELD_SQL_MODE]->val_int(); - sph= Sp_handler::handler_mysql_proc((stored_procedure_type) + sph= Sp_handler::handler_mysql_proc((enum_sp_type) proc_table->field[MYSQL_PROC_MYSQL_TYPE]-> val_int()); - if (!sph || sph->type() == TYPE_ENUM_PACKAGE || - sph->type() == TYPE_ENUM_PACKAGE_BODY) + if (!sph || sph->type() == SP_TYPE_PACKAGE || + sph->type() == SP_TYPE_PACKAGE_BODY) DBUG_RETURN(0); if (!full_access) @@ -6247,7 +6247,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, proc_table->field[MYSQL_PROC_FIELD_PARAM_LIST]->val_str_nopad(thd->mem_root, ¶ms); - if (sph->type() == TYPE_ENUM_FUNCTION) + if (sph->type() == SP_TYPE_FUNCTION) proc_table->field[MYSQL_PROC_FIELD_RETURNS]->val_str_nopad(thd->mem_root, &returns); sp= sph->sp_load_for_information_schema(thd, proc_table, db, name, @@ -6260,7 +6260,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table, Sql_mode_save sql_mode_backup(thd); thd->variables.sql_mode= sql_mode; - if (sph->type() == TYPE_ENUM_FUNCTION) + if (sph->type() == SP_TYPE_FUNCTION) { restore_record(table, s->default_values); table->field[0]->store(STRING_WITH_LEN("def"), cs); @@ -6344,7 +6344,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, proc_table->field[MYSQL_PROC_FIELD_DB]->val_str_nopad(thd->mem_root, &db); proc_table->field[MYSQL_PROC_FIELD_NAME]->val_str_nopad(thd->mem_root, &name); proc_table->field[MYSQL_PROC_FIELD_DEFINER]->val_str_nopad(thd->mem_root, &definer); - sph= Sp_handler::handler_mysql_proc((stored_procedure_type) + sph= Sp_handler::handler_mysql_proc((enum_sp_type) proc_table->field[MYSQL_PROC_MYSQL_TYPE]-> val_int()); if (!sph) @@ -6373,7 +6373,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, copy_field_as_string(table->field[4], proc_table->field[MYSQL_PROC_MYSQL_TYPE]); - if (sph->type() == TYPE_ENUM_FUNCTION) + if (sph->type() == SP_TYPE_FUNCTION) { sp_head *sp; bool free_sp_head; diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index d683bdc7055..27d89b630e3 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -35,6 +35,7 @@ #include "sp_cache.h" // sp_invalidate_cache #include <mysys_err.h> #include "debug_sync.h" +#include "mysql/psi/mysql_sp.h" /*************************************************************************/ @@ -624,7 +625,13 @@ end: thd->lex->restore_backup_query_tables_list(&backup); if (!result) + { my_ok(thd); + /* Drop statistics for this stored program from performance schema. */ + MYSQL_DROP_SP(SP_TYPE_TRIGGER, + thd->lex->spname->m_db.str, thd->lex->spname->m_db.length, + thd->lex->spname->m_name.str, thd->lex->spname->m_name.length); + } DBUG_RETURN(result); #ifdef WITH_WSREP @@ -1554,6 +1561,10 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, trigger->definer= *trg_definer; } + sp->m_sp_share= MYSQL_GET_SP_SHARE(SP_TYPE_TRIGGER, + sp->m_db.str, sp->m_db.length, + sp->m_name.str, sp->m_name.length); + #ifndef DBUG_OFF /* Let us check that we correctly update trigger definitions when we @@ -1846,6 +1857,9 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, const LEX_CSTRING *db, */ result= 1; } + /* Drop statistics for this stored program from performance schema. */ + MYSQL_DROP_SP(SP_TYPE_TRIGGER, db->str, db->length, + trigger->name.str, trigger->name.length); } } } diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index e170037956b..99e8f0a52ec 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1916,7 +1916,7 @@ static int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len) log_query.set_charset(system_charset_info); - if (sp->m_handler->type() == TYPE_ENUM_FUNCTION) + if (sp->m_handler->type() == SP_TYPE_FUNCTION) { sp_returns_type(thd, retstr, sp); returns= retstr.lex_cstring(); |