perfschema sp instrumentation related changes

This commit is contained in:
Sergei Golubchik 2020-02-14 16:29:16 +01:00
parent d5a0069702
commit 70e7b5095d
16 changed files with 410 additions and 83 deletions

View File

@ -32,6 +32,7 @@
#include "event_db_repository.h" #include "event_db_repository.h"
#include "sp_head.h" #include "sp_head.h"
#include "sql_show.h" // append_definer, append_identifier #include "sql_show.h" // append_definer, append_identifier
#include "mysql/psi/mysql_sp.h"
#ifdef WITH_WSREP #ifdef WITH_WSREP
#include "wsrep_trans_observer.h" #include "wsrep_trans_observer.h"
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
@ -1456,6 +1457,9 @@ Event_job_data::execute(THD *thd, bool drop)
sphead->set_creation_ctx(creation_ctx); sphead->set_creation_ctx(creation_ctx);
sphead->optimize(); 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); ret= sphead->execute_procedure(thd, &empty_item_list);
/* /*
There is no pre-locking and therefore there should be no There is no pre-locking and therefore there should be no

View File

@ -24,6 +24,7 @@
#include "tztime.h" // my_tz_find, my_tz_OFFSET0, struct Time_zone #include "tztime.h" // my_tz_find, my_tz_OFFSET0, struct Time_zone
#include "log.h" // sql_print_error #include "log.h" // sql_print_error
#include "sql_class.h" // struct THD #include "sql_class.h" // struct THD
#include "mysql/psi/mysql_sp.h"
/** /**
@addtogroup Event_Scheduler @addtogroup Event_Scheduler
@ -351,6 +352,9 @@ Event_queue::drop_matching_events(THD *thd, const LEX_CSTRING *pattern,
is ok. is ok.
*/ */
queue_remove(&queue, i); 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; delete et;
} }
else else

View File

@ -34,6 +34,7 @@
#include "sp_head.h" // for Stored_program_creation_ctx #include "sp_head.h" // for Stored_program_creation_ctx
#include "set_var.h" #include "set_var.h"
#include "lock.h" // lock_object_name #include "lock.h" // lock_object_name
#include "mysql/psi/mysql_sp.h"
/** /**
@addtogroup Event_Scheduler @addtogroup Event_Scheduler
@ -620,6 +621,9 @@ Events::drop_event(THD *thd, const LEX_CSTRING *dbname,
/* Binlog the drop event. */ /* Binlog the drop event. */
DBUG_ASSERT(thd->query() && thd->query_length()); DBUG_ASSERT(thd->query() && thd->query_length());
ret= write_bin_log(thd, TRUE, 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); thd->restore_stmt_binlog_format(save_binlog_format);

View File

@ -113,6 +113,7 @@
#include "sp_rcontext.h" #include "sp_rcontext.h"
#include "sp_cache.h" #include "sp_cache.h"
#include "sql_reload.h" // reload_acl_and_cache #include "sql_reload.h" // reload_acl_and_cache
#include "sp_head.h" // init_sp_psi_keys
#ifdef HAVE_POLL_H #ifdef HAVE_POLL_H
#include <poll.h> #include <poll.h>
@ -9698,6 +9699,8 @@ void init_server_psi_keys(void)
count= array_elements(sql_statement_info); count= array_elements(sql_statement_info);
mysql_statement_register(category, sql_statement_info, count); mysql_statement_register(category, sql_statement_info, count);
init_sp_psi_keys();
category= "com"; category= "com";
init_com_statement_info(); init_com_statement_info();

View File

@ -34,6 +34,7 @@
#include "lock.h" // lock_object_name #include "lock.h" // lock_object_name
#include <my_user.h> #include <my_user.h>
#include "mysql/psi/mysql_sp.h"
sp_cache **Sp_handler_procedure::get_cache(THD *thd) const 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, table->field[MYSQL_PROC_FIELD_PARAM_LIST]->val_str_nopad(thd->mem_root,
&params); &params);
if (type() != TYPE_ENUM_FUNCTION) if (type() != SP_TYPE_FUNCTION)
returns= empty_clex_str; returns= empty_clex_str;
else if (table->field[MYSQL_PROC_FIELD_RETURNS]->val_str_nopad(thd->mem_root, else if (table->field[MYSQL_PROC_FIELD_RETURNS]->val_str_nopad(thd->mem_root,
&returns)) &returns))
@ -866,6 +867,8 @@ static sp_head *sp_compile(THD *thd, String *defstr, sql_mode_t sql_mode,
thd->spcont= old_spcont; thd->spcont= old_spcont;
thd->variables.sql_mode= old_sql_mode; thd->variables.sql_mode= old_sql_mode;
thd->variables.select_limit= old_select_limit; thd->variables.select_limit= old_select_limit;
if (sp != NULL)
sp->init_psi_share();
return sp; 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)->set_creation_ctx(creation_ctx);
(*sphp)->optimize(); (*sphp)->optimize();
if (type() == TYPE_ENUM_PACKAGE_BODY) if (type() == SP_TYPE_PACKAGE_BODY)
{ {
sp_package *package= (*sphp)->get_package(); sp_package *package= (*sphp)->get_package();
List_iterator<LEX> it(package->m_routine_implementations); List_iterator<LEX> it(package->m_routine_implementations);
@ -1104,6 +1107,9 @@ Sp_handler::sp_drop_routine_internal(THD *thd,
DBUG_ASSERT(spc); DBUG_ASSERT(spc);
if ((sp= sp_cache_lookup(spc, name))) if ((sp= sp_cache_lookup(spc, name)))
sp_cache_flush_obsolete(spc, &sp); 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); 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()) if (lex->create_info.or_replace())
{ {
switch (type()) { switch (type()) {
case TYPE_ENUM_PACKAGE: case SP_TYPE_PACKAGE:
// Drop together with its PACKAGE BODY mysql.proc record // Drop together with its PACKAGE BODY mysql.proc record
ret= sp_handler_package_spec.sp_find_and_drop_routine(thd, table, sp); ret= sp_handler_package_spec.sp_find_and_drop_routine(thd, table, sp);
break; break;
case TYPE_ENUM_PACKAGE_BODY: case SP_TYPE_PACKAGE_BODY:
case TYPE_ENUM_FUNCTION: case SP_TYPE_FUNCTION:
case TYPE_ENUM_PROCEDURE: case SP_TYPE_PROCEDURE:
ret= sp_drop_routine_internal(thd, sp, table); ret= sp_drop_routine_internal(thd, sp, table);
break; break;
case TYPE_ENUM_TRIGGER: case SP_TYPE_TRIGGER:
case SP_TYPE_EVENT:
DBUG_ASSERT(0); DBUG_ASSERT(0);
ret= SP_OK; ret= SP_OK;
} }
@ -1257,7 +1264,7 @@ Sp_handler::sp_create_routine(THD *thd, const sp_head *sp) const
ret= FALSE; ret= FALSE;
// Setting retstr as it is used for logging. // Setting retstr as it is used for logging.
if (type() == TYPE_ENUM_FUNCTION) if (type() == SP_TYPE_FUNCTION)
{ {
sp_returns_type(thd, retstr, sp); sp_returns_type(thd, retstr, sp);
returns= retstr.lex_cstring(); 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]-> table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
store(sp->m_params, system_charset_info); store(sp->m_params, system_charset_info);
if (type() == TYPE_ENUM_FUNCTION) if (type() == SP_TYPE_FUNCTION)
{ {
sp_returns_type(thd, retstr, sp); sp_returns_type(thd, retstr, sp);
returns= retstr.lex_cstring(); 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); store(sp->comment(), system_charset_info);
} }
if (type() == TYPE_ENUM_FUNCTION && if (type() == SP_TYPE_FUNCTION &&
!trust_function_creators && mysql_bin_log.is_open()) !trust_function_creators && mysql_bin_log.is_open())
{ {
if (!sp->detistic()) 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 ((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() && mysql_bin_log.is_open() &&
(chistics->daccess == SP_CONTAINS_SQL || (chistics->daccess == SP_CONTAINS_SQL ||
chistics->daccess == SP_MODIFIES_SQL_DATA)) 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(); longlong sp_type= table->field[MYSQL_PROC_MYSQL_TYPE]->val_int();
MDL_request *mdl_request= new (thd->mem_root) MDL_request; 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); sp_type);
if (!sph) if (!sph)
sph= &sp_handler_procedure; sph= &sp_handler_procedure;
@ -1813,6 +1820,8 @@ sp_drop_db_routines(THD *thd, const char *db)
uint key_len; uint key_len;
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
uchar keybuf[MAX_KEY_LENGTH]; 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_ENTER("sp_drop_db_routines");
DBUG_PRINT("enter", ("db: %s", db)); 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))) if (!(table= open_proc_table_for_update(thd)))
goto err; 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; key_len= table->key_info->key_part[0].store_length;
table->field[MYSQL_PROC_FIELD_DB]->get_key_image(keybuf, key_len, Field::itRAW); 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 do
{ {
if (! table->file->ha_delete_row(table->record[0])) if (! table->file->ha_delete_row(table->record[0]))
{
deleted= TRUE; /* We deleted something */ 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 else
{ {
ret= SP_DELETE_ROW_FAILED; ret= SP_DELETE_ROW_FAILED;
@ -2013,7 +2033,7 @@ Sp_handler::sp_clone_and_link_routine(THD *thd,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (type() == TYPE_ENUM_FUNCTION) if (type() == SP_TYPE_FUNCTION)
{ {
sp_returns_type(thd, retstr, sp); sp_returns_type(thd, retstr, sp);
returns= retstr.lex_cstring(); returns= retstr.lex_cstring();
@ -2361,7 +2381,7 @@ is_package_public_routine(THD *thd,
const LEX_CSTRING &db, const LEX_CSTRING &db,
const LEX_CSTRING &package, const LEX_CSTRING &package,
const LEX_CSTRING &routine, const LEX_CSTRING &routine,
stored_procedure_type type) enum_sp_type type)
{ {
sp_head *sp= NULL; sp_head *sp= NULL;
Database_qualified_name tmp(db, package); Database_qualified_name tmp(db, package);
@ -2395,7 +2415,7 @@ is_package_public_routine_quick(THD *thd,
const LEX_CSTRING &db, const LEX_CSTRING &db,
const LEX_CSTRING &pkgname, const LEX_CSTRING &pkgname,
const LEX_CSTRING &name, const LEX_CSTRING &name,
stored_procedure_type type) enum_sp_type type)
{ {
Database_qualified_name tmp(db, pkgname); Database_qualified_name tmp(db, pkgname);
sp_head *sp= sp_cache_lookup(&thd->sp_package_spec_cache, &tmp); 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, is_package_body_routine(THD *thd, sp_package *pkg,
const LEX_CSTRING &name1, const LEX_CSTRING &name1,
const LEX_CSTRING &name2, const LEX_CSTRING &name2,
stored_procedure_type type) enum_sp_type type)
{ {
return Sp_handler::eq_routine_name(pkg->m_name, name1) && return Sp_handler::eq_routine_name(pkg->m_name, name1) &&
(pkg->m_routine_declarations.find(name2, type) || (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 bool lookup_only, sp_head **sp) const
{ {
DBUG_ENTER("sp_cache_package_routine"); 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_name pkgname(&name->m_db, &pkgname_cstr, false);
sp_head *ph= NULL; sp_head *ph= NULL;
int ret= sp_handler_package_body.sp_cache_routine(thd, &pkgname, 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('(');
buf->append(&params); buf->append(&params);
buf->append(')'); buf->append(')');
if (type() == TYPE_ENUM_FUNCTION) if (type() == SP_TYPE_FUNCTION)
{ {
if (sql_mode & MODE_ORACLE) if (sql_mode & MODE_ORACLE)
buf->append(STRING_WITH_LEN(" RETURN ")); buf->append(STRING_WITH_LEN(" RETURN "));

View File

@ -47,17 +47,18 @@ template <typename T> class SQL_I_List;
/* /*
Values for the type enum. This reflects the order of the enum declaration Values for the type enum. This reflects the order of the enum declaration
in the CREATE TABLE command. in the CREATE TABLE command.
See also storage/perfschema/my_thread.h
*/ */
enum stored_procedure_type enum enum_sp_type
{ {
TYPE_ENUM_FUNCTION=1, SP_TYPE_FUNCTION=1,
TYPE_ENUM_PROCEDURE=2, SP_TYPE_PROCEDURE=2,
TYPE_ENUM_PACKAGE=3, SP_TYPE_PACKAGE=3,
TYPE_ENUM_PACKAGE_BODY=4, SP_TYPE_PACKAGE_BODY=4,
TYPE_ENUM_TRIGGER=5 SP_TYPE_TRIGGER=5,
SP_TYPE_EVENT=6,
}; };
class Sp_handler class Sp_handler
{ {
bool sp_resolve_package_routine_explicit(THD *thd, bool sp_resolve_package_routine_explicit(THD *thd,
@ -120,13 +121,13 @@ public: // TODO: make it private or protected
public: public:
virtual ~Sp_handler() {} virtual ~Sp_handler() {}
static const Sp_handler *handler(enum enum_sql_command cmd); 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); static const Sp_handler *handler(MDL_key::enum_mdl_namespace ns);
/* /*
Return a handler only those SP objects that store Return a handler only those SP objects that store
definitions in the mysql.proc system table 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); const Sp_handler *sph= handler(type);
return sph ? sph->sp_handler_mysql_proc() : NULL; return sph ? sph->sp_handler_mysql_proc() : NULL;
@ -153,7 +154,7 @@ public:
{ {
return this; 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 type_lex_cstring() const= 0;
virtual LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const virtual LEX_CSTRING empty_body_lex_cstring(sql_mode_t mode) const
{ {
@ -248,7 +249,7 @@ public:
class Sp_handler_procedure: public Sp_handler class Sp_handler_procedure: public Sp_handler
{ {
public: 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 LEX_CSTRING type_lex_cstring() const
{ {
static LEX_CSTRING m_type_str= { STRING_WITH_LEN("PROCEDURE")}; static LEX_CSTRING m_type_str= { STRING_WITH_LEN("PROCEDURE")};
@ -298,7 +299,7 @@ public:
class Sp_handler_function: public Sp_handler class Sp_handler_function: public Sp_handler
{ {
public: 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 LEX_CSTRING type_lex_cstring() const
{ {
static LEX_CSTRING m_type_str= { STRING_WITH_LEN("FUNCTION")}; 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 Database_qualified_name *name)
const; const;
public: 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 LEX_CSTRING type_lex_cstring() const
{ {
static LEX_CSTRING m_type_str= {STRING_WITH_LEN("PACKAGE")}; static LEX_CSTRING m_type_str= {STRING_WITH_LEN("PACKAGE")};
@ -400,7 +401,7 @@ public:
class Sp_handler_package_body: public Sp_handler_package class Sp_handler_package_body: public Sp_handler_package
{ {
public: 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 LEX_CSTRING type_lex_cstring() const
{ {
static LEX_CSTRING m_type_str= {STRING_WITH_LEN("PACKAGE BODY")}; static LEX_CSTRING m_type_str= {STRING_WITH_LEN("PACKAGE BODY")};
@ -433,7 +434,7 @@ public:
class Sp_handler_trigger: public Sp_handler class Sp_handler_trigger: public Sp_handler
{ {
public: 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 LEX_CSTRING type_lex_cstring() const
{ {
static LEX_CSTRING m_type_str= { STRING_WITH_LEN("TRIGGER")}; 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) { switch (type) {
case TYPE_ENUM_PROCEDURE: case SP_TYPE_PROCEDURE:
return &sp_handler_procedure; return &sp_handler_procedure;
case TYPE_ENUM_FUNCTION: case SP_TYPE_FUNCTION:
return &sp_handler_function; return &sp_handler_function;
case TYPE_ENUM_PACKAGE: case SP_TYPE_PACKAGE:
return &sp_handler_package_spec; return &sp_handler_package_spec;
case TYPE_ENUM_PACKAGE_BODY: case SP_TYPE_PACKAGE_BODY:
return &sp_handler_package_body; return &sp_handler_package_body;
case TYPE_ENUM_TRIGGER: case SP_TYPE_TRIGGER:
return &sp_handler_trigger; return &sp_handler_trigger;
case SP_TYPE_EVENT:
break;
} }
return NULL; return NULL;
} }

View File

@ -56,8 +56,39 @@
#define SP_INSTR_UINT_MAXLEN 8 #define SP_INSTR_UINT_MAXLEN 8
#define SP_STMT_PRINT_MAXLEN 40 #define SP_STMT_PRINT_MAXLEN 40
#include <my_user.h> #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); 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) 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; return false;
sp_head *sp= sp_cache_lookup(&thd->sp_package_spec_cache, this); sp_head *sp= sp_cache_lookup(&thd->sp_package_spec_cache, this);
sp_package *spec= sp ? sp->get_package() : NULL; 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, LEX *sp_package::LexList::find(const LEX_CSTRING &name,
stored_procedure_type type) enum_sp_type type)
{ {
List_iterator<LEX> it(*this); List_iterator<LEX> it(*this);
for (LEX *lex; (lex= it++); ) 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, LEX *sp_package::LexList::find_qualified(const LEX_CSTRING &name,
stored_procedure_type type) enum_sp_type type)
{ {
List_iterator<LEX> it(*this); List_iterator<LEX> it(*this);
for (LEX *lex; (lex= it++); ) 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 void
sp_head::init(LEX *lex) sp_head::init(LEX *lex)
{ {
@ -756,6 +798,13 @@ sp_head::init_sp_name(const sp_name *spname)
DBUG_VOID_RETURN; 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 void
sp_head::set_body_start(THD *thd, const char *begin_ptr) 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()); WSREP_DEBUG("assigned new next trx ID for SP, trx id: %" PRIu64, thd->wsrep_next_trx_id());
} }
#endif /* WITH_WSREP */ #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); 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 #ifdef WITH_WSREP
if (WSREP(thd)) if (WSREP(thd))
{ {
@ -1830,7 +1895,12 @@ sp_head::execute_trigger(THD *thd,
thd->spcont= nctx; 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: err_with_cleanup:
thd->restore_active_arena(&call_arena, &backup_arena); 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); 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); thd->restore_active_arena(call_arena, &backup_arena);
@ -2361,11 +2436,12 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
#endif #endif
opt_trace_disable_if_no_stored_proc_func_access(thd, this); 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) if (!err_status)
{
err_status= execute(thd, TRUE); err_status= execute(thd, TRUE);
DBUG_PRINT("info", ("execute returned %d", (int) err_status)); MYSQL_END_SP(locker);
}
if (save_log_general) if (save_log_general)
thd->variables.option_bits &= ~OPTION_LOG_OFF; 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 sp_instr_stmt class functions
*/ */
PSI_statement_info sp_instr_stmt::psi_info=
{ 0, "stmt", 0};
int int
sp_instr_stmt::execute(THD *thd, uint *nextp) 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_ENTER("sp_instr_stmt::execute");
DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command())); 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) #if defined(ENABLED_PROFILING)
/* This s-p instr is profilable and will be captured. */ /* This s-p instr is profilable and will be captured. */
thd->profiling.set_query_source(m_query.str, m_query.length); 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 sp_instr_set class functions
*/ */
PSI_statement_info sp_instr_set::psi_info=
{ 0, "set", 0};
int int
sp_instr_set::execute(THD *thd, uint *nextp) 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 sp_instr_set_trigger_field class functions
*/ */
PSI_statement_info sp_instr_set_trigger_field::psi_info=
{ 0, "set_trigger_field", 0};
int int
sp_instr_set_trigger_field::execute(THD *thd, uint *nextp) 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 sp_instr_jump class functions
*/ */
PSI_statement_info sp_instr_jump::psi_info=
{ 0, "jump", 0};
int int
sp_instr_jump::execute(THD *thd, uint *nextp) 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 sp_instr_jump_if_not class functions
*/ */
PSI_statement_info sp_instr_jump_if_not::psi_info=
{ 0, "jump_if_not", 0};
int int
sp_instr_jump_if_not::execute(THD *thd, uint *nextp) 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 sp_instr_freturn class functions
*/ */
PSI_statement_info sp_instr_freturn::psi_info=
{ 0, "freturn", 0};
int int
sp_instr_freturn::execute(THD *thd, uint *nextp) sp_instr_freturn::execute(THD *thd, uint *nextp)
{ {
@ -4106,10 +4202,34 @@ sp_instr_freturn::print(String *str)
QT_ITEM_ORIGINAL_FUNC_NULLIF)); QT_ITEM_ORIGINAL_FUNC_NULLIF));
} }
/*
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 sp_instr_hpush_jump class functions
*/ */
PSI_statement_info sp_instr_hpush_jump::psi_info=
{ 0, "hpush_jump", 0};
int int
sp_instr_hpush_jump::execute(THD *thd, uint *nextp) 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 sp_instr_hpop class functions
*/ */
PSI_statement_info sp_instr_hpop::psi_info=
{ 0, "hpop", 0};
int int
sp_instr_hpop::execute(THD *thd, uint *nextp) sp_instr_hpop::execute(THD *thd, uint *nextp)
{ {
@ -4210,6 +4333,9 @@ sp_instr_hpop::print(String *str)
sp_instr_hreturn class functions sp_instr_hreturn class functions
*/ */
PSI_statement_info sp_instr_hreturn::psi_info=
{ 0, "hreturn", 0};
int int
sp_instr_hreturn::execute(THD *thd, uint *nextp) 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 sp_instr_cpush class functions
*/ */
PSI_statement_info sp_instr_cpush::psi_info=
{ 0, "cpush", 0};
int int
sp_instr_cpush::execute(THD *thd, uint *nextp) sp_instr_cpush::execute(THD *thd, uint *nextp)
{ {
@ -4310,6 +4439,9 @@ sp_instr_cpush::print(String *str)
sp_instr_cpop class functions sp_instr_cpop class functions
*/ */
PSI_statement_info sp_instr_cpop::psi_info=
{ 0, "cpop", 0};
int int
sp_instr_cpop::execute(THD *thd, uint *nextp) 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 Assert that we either have an error or a cursor
*/ */
PSI_statement_info sp_instr_copen::psi_info=
{ 0, "copen", 0};
int int
sp_instr_copen::execute(THD *thd, uint *nextp) sp_instr_copen::execute(THD *thd, uint *nextp)
{ {
@ -4398,6 +4533,9 @@ sp_instr_copen::print(String *str)
sp_instr_cclose class functions sp_instr_cclose class functions
*/ */
PSI_statement_info sp_instr_cclose::psi_info=
{ 0, "cclose", 0};
int int
sp_instr_cclose::execute(THD *thd, uint *nextp) sp_instr_cclose::execute(THD *thd, uint *nextp)
{ {
@ -4440,6 +4578,9 @@ sp_instr_cclose::print(String *str)
sp_instr_cfetch class functions sp_instr_cfetch class functions
*/ */
PSI_statement_info sp_instr_cfetch::psi_info=
{ 0, "cfetch", 0};
int int
sp_instr_cfetch::execute(THD *thd, uint *nextp) 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 int
sp_instr_agg_cfetch::execute(THD *thd, uint *nextp) 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. - 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 int
sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp) 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 sp_instr_error class functions
*/ */
PSI_statement_info sp_instr_error::psi_info=
{ 0, "error", 0};
int int
sp_instr_error::execute(THD *thd, uint *nextp) 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 sp_instr_set_case_expr class implementation
**************************************************************************/ **************************************************************************/
PSI_statement_info sp_instr_set_case_expr::psi_info=
{ 0, "set_case_expr", 0};
int int
sp_instr_set_case_expr::execute(THD *thd, uint *nextp) sp_instr_set_case_expr::execute(THD *thd, uint *nextp)
{ {

View File

@ -47,6 +47,14 @@ class sp_instr;
class sp_instr_opt_meta; class sp_instr_opt_meta;
class sp_instr_jump_if_not; 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; const Sp_handler *m_handler;
uint m_flags; // Boolean attributes of a stored routine 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. */ Column_definition m_return_field_def; /**< This is used for FUNCTIONs only. */
const char *m_tmp_query; ///< Temporary pointer to sub query string const char *m_tmp_query; ///< Temporary pointer to sub query string
@ -856,6 +869,8 @@ public:
return NULL; return NULL;
} }
virtual void init_psi_share();
protected: protected:
MEM_ROOT *m_thd_root; ///< Temp. store for thd's mem_root MEM_ROOT *m_thd_root; ///< Temp. store for thd's mem_root
@ -931,9 +946,9 @@ public:
public: public:
LexList() { elements= 0; } LexList() { elements= 0; }
// Find a package routine by a non qualified name // 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' // 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 // Check if a routine with the given qualified name already exists
bool check_dup_qualified(const LEX_CSTRING &name, const Sp_handler *sph) 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); m_routine_implementations.push_back(lex, &main_mem_root);
} }
sp_package *get_package() { return this; } sp_package *get_package() { return this; }
void init_psi_share();
bool is_invoked() const bool is_invoked() const
{ {
/* /*
@ -1156,6 +1172,7 @@ public:
{ {
m_ip= dst; m_ip= dst;
} }
virtual PSI_statement_info* get_psi_info() = 0;
}; // class sp_instr : public Sql_alloc }; // class sp_instr : public Sql_alloc
@ -1282,6 +1299,12 @@ private:
sp_lex_keeper m_lex_keeper; 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 }; // class sp_instr_stmt : public sp_instr
@ -1316,6 +1339,12 @@ protected:
uint m_offset; ///< Frame offset uint m_offset; ///< Frame offset
Item *m_value; Item *m_value;
sp_lex_keeper m_lex_keeper; 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 }; // class sp_instr_set : public sp_instr
@ -1424,6 +1453,12 @@ private:
Item_trigger_field *trigger_field; Item_trigger_field *trigger_field;
Item *value; Item *value;
sp_lex_keeper m_lex_keeper; 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 }; // class sp_instr_trigger_field : public sp_instr
@ -1510,6 +1545,11 @@ public:
m_dest= new_dest; 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 }; // class sp_instr_jump : public sp_instr_opt_meta
@ -1561,6 +1601,11 @@ private:
Item *m_expr; ///< The condition Item *m_expr; ///< The condition
sp_lex_keeper m_lex_keeper; 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 }; // class sp_instr_jump_if_not : public sp_instr_jump
@ -1578,17 +1623,9 @@ public:
virtual ~sp_instr_preturn() virtual ~sp_instr_preturn()
{} {}
virtual int execute(THD *thd, uint *nextp) virtual int execute(THD *thd, uint *nextp);
{
DBUG_ENTER("sp_instr_preturn::execute");
*nextp= UINT_MAX;
DBUG_RETURN(0);
}
virtual void print(String *str) virtual void print(String *str);
{
str->append(STRING_WITH_LEN("preturn"));
}
virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads) virtual uint opt_mark(sp_head *sp, List<sp_instr> *leads)
{ {
@ -1596,6 +1633,11 @@ public:
return UINT_MAX; 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 }; // class sp_instr_preturn : public sp_instr
@ -1633,6 +1675,11 @@ protected:
const Type_handler *m_type_handler; const Type_handler *m_type_handler;
sp_lex_keeper m_lex_keeper; 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 }; // class sp_instr_freturn : public sp_instr
@ -1698,6 +1745,11 @@ private:
// debug version only). It's used in print(). // debug version only). It's used in print().
uint m_frame; 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 }; // class sp_instr_hpush_jump : public sp_instr_jump
@ -1728,6 +1780,11 @@ private:
uint m_count; 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 }; // class sp_instr_hpop : public sp_instr
@ -1762,12 +1819,16 @@ private:
uint m_frame; 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 }; // class sp_instr_hreturn : public sp_instr_jump
/** This is DECLARE CURSOR */ /** This is DECLARE CURSOR */
class sp_instr_cpush : public sp_instr, class sp_instr_cpush : public sp_instr, public sp_cursor
public sp_cursor
{ {
sp_instr_cpush(const sp_instr_cpush &); /**< Prevent use of these */ sp_instr_cpush(const sp_instr_cpush &); /**< Prevent use of these */
void operator=(sp_instr_cpush &); void operator=(sp_instr_cpush &);
@ -1796,6 +1857,11 @@ private:
sp_lex_keeper m_lex_keeper; sp_lex_keeper m_lex_keeper;
uint m_cursor; /**< Frame offset (for debugging) */ 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 }; // class sp_instr_cpush : public sp_instr
@ -1826,6 +1892,11 @@ private:
uint m_count; 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 }; // class sp_instr_cpop : public sp_instr
@ -1853,6 +1924,11 @@ private:
uint m_cursor; ///< Stack index 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 }; // class sp_instr_copen : public sp_instr_stmt
@ -1880,6 +1956,12 @@ public:
virtual int execute(THD *thd, uint *nextp); virtual int execute(THD *thd, uint *nextp);
virtual int exec_core(THD *thd, uint *nextp); virtual int exec_core(THD *thd, uint *nextp);
virtual void print(String *str); 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; 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 }; // class sp_instr_cclose : public sp_instr
@ -1939,6 +2026,11 @@ private:
List<sp_variable> m_varlist; List<sp_variable> m_varlist;
bool m_error_on_no_data; 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 }; // class sp_instr_cfetch : public sp_instr
/* /*
@ -1963,6 +2055,12 @@ public:
virtual int execute(THD *thd, uint *nextp); virtual int execute(THD *thd, uint *nextp);
virtual void print(String *str); 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 }; // class sp_instr_agg_cfetch : public sp_instr
@ -1996,6 +2094,11 @@ private:
int m_errcode; 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 }; // class sp_instr_error : public sp_instr
@ -2035,6 +2138,11 @@ private:
Item *m_case_expr; Item *m_case_expr;
sp_lex_keeper m_lex_keeper; 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 }; // class sp_instr_set_case_expr : public sp_instr_opt_meta
bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access); bool check_show_routine_access(THD *thd, sp_head *sp, bool *full_access);

View File

@ -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) { switch (type) {
case TYPE_ENUM_FUNCTION: case SP_TYPE_FUNCTION:
return PRIVS_TO_MERGE::FUNC; return PRIVS_TO_MERGE::FUNC;
case TYPE_ENUM_PROCEDURE: case SP_TYPE_PROCEDURE:
return PRIVS_TO_MERGE::PROC; return PRIVS_TO_MERGE::PROC;
case TYPE_ENUM_PACKAGE: case SP_TYPE_PACKAGE:
return PRIVS_TO_MERGE::PACKAGE_SPEC; return PRIVS_TO_MERGE::PACKAGE_SPEC;
case TYPE_ENUM_PACKAGE_BODY: case SP_TYPE_PACKAGE_BODY:
return PRIVS_TO_MERGE::PACKAGE_BODY; return PRIVS_TO_MERGE::PACKAGE_BODY;
case TYPE_ENUM_TRIGGER: case SP_TYPE_EVENT:
case SP_TYPE_TRIGGER:
break; break;
} }
DBUG_ASSERT(0); DBUG_ASSERT(0);
@ -7748,7 +7749,7 @@ static bool grant_load(THD *thd,
continue; 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); const Sp_handler *sph= Sp_handler::handler(type);
if (!sph || !(hash= sph->get_priv_hash())) if (!sph || !(hash= sph->get_priv_hash()))
{ {

View File

@ -309,4 +309,6 @@
#define QUERY_PRIOR 6 #define QUERY_PRIOR 6
#endif /* __WIN92__ */ #endif /* __WIN92__ */
#define SP_PSI_STATEMENT_INFO_COUNT 19
#endif /* SQL_CONST_INCLUDED */ #endif /* SQL_CONST_INCLUDED */

View File

@ -6257,7 +6257,7 @@ static bool is_old(const char *str)
bool LEX::is_trigger_new_or_old_reference(const LEX_CSTRING *name) const bool LEX::is_trigger_new_or_old_reference(const LEX_CSTRING *name) const
{ {
// "name" is not necessarily NULL-terminated! // "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)); 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))) if (unlikely(set_command_with_check(command, options)))
return NULL; 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 If we start parsing a "CREATE PACKAGE BODY", we need to load

View File

@ -30,7 +30,7 @@
#include "sql_alter.h" // Alter_info #include "sql_alter.h" // Alter_info
#include "sql_window.h" #include "sql_window.h"
#include "sql_trigger.h" #include "sql_trigger.h"
#include "sp.h" // enum stored_procedure_type #include "sp.h" // enum enum_sp_type
#include "sql_tvc.h" #include "sql_tvc.h"
#include "item.h" #include "item.h"
#include "sql_limit.h" // Select_limit_counters #include "sql_limit.h" // Select_limit_counters

View File

@ -101,6 +101,7 @@
#include "sql_bootstrap.h" #include "sql_bootstrap.h"
#include "sql_sequence.h" #include "sql_sequence.h"
#include "opt_trace.h" #include "opt_trace.h"
#include "mysql/psi/mysql_sp.h"
#include "my_json_writer.h" #include "my_json_writer.h"
@ -3063,7 +3064,7 @@ mysql_create_routine(THD *thd, LEX *lex)
const LEX_CSTRING *name= lex->sphead->name(); const LEX_CSTRING *name= lex->sphead->name();
#ifdef HAVE_DLOPEN #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); udf_func *udf = find_udf(name->str, name->length);
@ -5617,12 +5618,18 @@ mysql_execute_command(THD *thd)
break; /* break super switch */ break; /* break super switch */
} /* end case group bracket */ } /* end case group bracket */
case SQLCOM_COMPOUND: case SQLCOM_COMPOUND:
{
sp_head *sp= lex->sphead;
DBUG_ASSERT(all_tables == 0); DBUG_ASSERT(all_tables == 0);
DBUG_ASSERT(thd->in_sub_stmt == 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)) if (do_execute_sp(thd, lex->sphead))
goto error; goto error;
break; break;
}
case SQLCOM_ALTER_PROCEDURE: case SQLCOM_ALTER_PROCEDURE:
case SQLCOM_ALTER_FUNCTION: case SQLCOM_ALTER_FUNCTION:

View File

@ -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_NAME]->val_str_nopad(thd->mem_root, &name);
proc_table->field[MYSQL_PROC_FIELD_DEFINER]->val_str_nopad(thd->mem_root, &definer); 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(); 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]-> proc_table->field[MYSQL_PROC_MYSQL_TYPE]->
val_int()); val_int());
if (!sph || sph->type() == TYPE_ENUM_PACKAGE || if (!sph || sph->type() == SP_TYPE_PACKAGE ||
sph->type() == TYPE_ENUM_PACKAGE_BODY) sph->type() == SP_TYPE_PACKAGE_BODY)
DBUG_RETURN(0); DBUG_RETURN(0);
if (!full_access) 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, proc_table->field[MYSQL_PROC_FIELD_PARAM_LIST]->val_str_nopad(thd->mem_root,
&params); &params);
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, proc_table->field[MYSQL_PROC_FIELD_RETURNS]->val_str_nopad(thd->mem_root,
&returns); &returns);
sp= sph->sp_load_for_information_schema(thd, proc_table, db, name, 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); Sql_mode_save sql_mode_backup(thd);
thd->variables.sql_mode= sql_mode; thd->variables.sql_mode= sql_mode;
if (sph->type() == TYPE_ENUM_FUNCTION) if (sph->type() == SP_TYPE_FUNCTION)
{ {
restore_record(table, s->default_values); restore_record(table, s->default_values);
table->field[0]->store(STRING_WITH_LEN("def"), cs); 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_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_NAME]->val_str_nopad(thd->mem_root, &name);
proc_table->field[MYSQL_PROC_FIELD_DEFINER]->val_str_nopad(thd->mem_root, &definer); 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]-> proc_table->field[MYSQL_PROC_MYSQL_TYPE]->
val_int()); val_int());
if (!sph) if (!sph)
@ -6373,7 +6373,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
copy_field_as_string(table->field[4], copy_field_as_string(table->field[4],
proc_table->field[MYSQL_PROC_MYSQL_TYPE]); proc_table->field[MYSQL_PROC_MYSQL_TYPE]);
if (sph->type() == TYPE_ENUM_FUNCTION) if (sph->type() == SP_TYPE_FUNCTION)
{ {
sp_head *sp; sp_head *sp;
bool free_sp_head; bool free_sp_head;

View File

@ -35,6 +35,7 @@
#include "sp_cache.h" // sp_invalidate_cache #include "sp_cache.h" // sp_invalidate_cache
#include <mysys_err.h> #include <mysys_err.h>
#include "debug_sync.h" #include "debug_sync.h"
#include "mysql/psi/mysql_sp.h"
/*************************************************************************/ /*************************************************************************/
@ -624,7 +625,13 @@ end:
thd->lex->restore_backup_query_tables_list(&backup); thd->lex->restore_backup_query_tables_list(&backup);
if (!result) if (!result)
{
my_ok(thd); 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); DBUG_RETURN(result);
#ifdef WITH_WSREP #ifdef WITH_WSREP
@ -1554,6 +1561,10 @@ bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db,
trigger->definer= *trg_definer; 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 #ifndef DBUG_OFF
/* /*
Let us check that we correctly update trigger definitions when we 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; 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);
} }
} }
} }

View File

@ -1916,7 +1916,7 @@ static int wsrep_create_sp(THD *thd, uchar** buf, size_t* buf_len)
log_query.set_charset(system_charset_info); 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); sp_returns_type(thd, retstr, sp);
returns= retstr.lex_cstring(); returns= retstr.lex_cstring();