mariadb/plugin/metadata_lock_info/metadata_lock_info.cc
Alexander Barkov 583eb96c24 MDEV-11952 Oracle-style packages: stage#5
- CREATE PACKAGE [BODY] statements are now
  entirely written to mysql.proc with type='PACKAGE' and type='PACKAGE BODY'.
- CREATE PACKAGE BODY now supports IF NOT EXISTS
- DROP PACKAGE BODY now supports IF EXISTS
- CREATE OR REPLACE PACKAGE [BODY] is now supported
- CREATE PACKAGE [BODY] now support the DEFINER clause:

    CREATE DEFINER user@host PACKAGE pkg ... END;
    CREATE DEFINER user@host PACKAGE BODY pkg ... END;

- CREATE PACKAGE [BODY] now supports SQL SECURITY and COMMENT clauses, e.g.:

    CREATE PACKAGE p1 SQL SECURITY INVOKER COMMENT "comment" AS ... END;

- Package routines are now created from the package CREATE PACKAGE BODY
  statement and don't produce individual records in mysql.proc.

- CREATE PACKAGE BODY now supports package-wide variables.
  Package variables can be read and set inside package routines.
  Package variables are stored in a separate sp_rcontext,
  which is cached in THD on the first packate routine call.

- CREATE PACKAGE BODY now supports the initialization section.

- All public routines (i.e. declared in CREATE PACKAGE)
  must have implementations in CREATE PACKAGE BODY

- Only public package routines are available outside of the package

- {CREATE|DROP} PACKAGE [BODY] now respects CREATE ROUTINE and ALTER ROUTINE
  privileges

- "GRANT EXECUTE ON PACKAGE BODY pkg" is now supported

- SHOW CREATE PACKAGE [BODY] is now supported

- SHOW PACKAGE [BODY] STATUS is now supported

- CREATE and DROP for PACKAGE [BODY] now works for non-current databases

- mysqldump now supports packages

- "SHOW {PROCEDURE|FUNCTION) CODE pkg.routine" now works for package routines

- "SHOW PACKAGE BODY CODE pkg" now works (the package initialization section)

- A new package body level MDL was added

- Recursive calls for package procedures are now possible

- Routine forward declarations in CREATE PACKATE BODY are now supported.

- Package body variables now work as SP OUT parameters

- Package body variables now work as SELECT INTO targets

- Package body variables now support ROW, %ROWTYPE, %TYPE
2018-02-25 21:08:19 +04:00

184 lines
5.8 KiB
C++

/* Copyright (C) 2013 Kentoku Shiba
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
#define MYSQL_SERVER 1
#include <my_global.h>
#include "mysql_version.h"
#include "mysql/plugin.h"
#include "sql_class.h"
#include "sql_show.h"
static const LEX_STRING metadata_lock_info_lock_name[] = {
{ C_STRING_WITH_LEN("Global read lock") },
{ C_STRING_WITH_LEN("Schema metadata lock") },
{ C_STRING_WITH_LEN("Table metadata lock") },
{ C_STRING_WITH_LEN("Stored function metadata lock") },
{ C_STRING_WITH_LEN("Stored procedure metadata lock") },
{ C_STRING_WITH_LEN("Stored package body metadata lock") },
{ C_STRING_WITH_LEN("Trigger metadata lock") },
{ C_STRING_WITH_LEN("Event metadata lock") },
{ C_STRING_WITH_LEN("Commit lock") },
{ C_STRING_WITH_LEN("User lock") },
};
static const LEX_STRING metadata_lock_info_lock_mode[] = {
{ C_STRING_WITH_LEN("MDL_INTENTION_EXCLUSIVE") },
{ C_STRING_WITH_LEN("MDL_SHARED") },
{ C_STRING_WITH_LEN("MDL_SHARED_HIGH_PRIO") },
{ C_STRING_WITH_LEN("MDL_SHARED_READ") },
{ C_STRING_WITH_LEN("MDL_SHARED_WRITE") },
{ C_STRING_WITH_LEN("MDL_SHARED_UPGRADABLE") },
{ C_STRING_WITH_LEN("MDL_SHARED_READ_ONLY") },
{ C_STRING_WITH_LEN("MDL_SHARED_NO_WRITE") },
{ C_STRING_WITH_LEN("MDL_SHARED_NO_READ_WRITE") },
{ C_STRING_WITH_LEN("MDL_EXCLUSIVE") },
};
static ST_FIELD_INFO i_s_metadata_lock_info_fields_info[] =
{
{"THREAD_ID", 20, MYSQL_TYPE_LONGLONG, 0,
MY_I_S_UNSIGNED, "thread_id", SKIP_OPEN_TABLE},
{"LOCK_MODE", 24, MYSQL_TYPE_STRING, 0,
MY_I_S_MAYBE_NULL, "lock_mode", SKIP_OPEN_TABLE},
{"LOCK_DURATION", 30, MYSQL_TYPE_STRING, 0,
MY_I_S_MAYBE_NULL, "lock_duration", SKIP_OPEN_TABLE},
{"LOCK_TYPE", 33, MYSQL_TYPE_STRING, 0,
MY_I_S_MAYBE_NULL, "lock_type", SKIP_OPEN_TABLE},
{"TABLE_SCHEMA", 64, MYSQL_TYPE_STRING, 0,
MY_I_S_MAYBE_NULL, "table_schema", SKIP_OPEN_TABLE},
{"TABLE_NAME", 64, MYSQL_TYPE_STRING, 0,
MY_I_S_MAYBE_NULL, "table_name", SKIP_OPEN_TABLE},
{NULL, 0, MYSQL_TYPE_STRING, 0, 0, NULL, 0}
};
struct st_i_s_metadata_param
{
THD *thd;
TABLE *table;
};
int i_s_metadata_lock_info_fill_row(
MDL_ticket *mdl_ticket,
void *arg
) {
st_i_s_metadata_param *param = (st_i_s_metadata_param *) arg;
THD *thd = param->thd;
TABLE *table = param->table;
DBUG_ENTER("i_s_metadata_lock_info_fill_row");
MDL_context *mdl_ctx = mdl_ticket->get_ctx();
enum_mdl_type mdl_ticket_type = mdl_ticket->get_type();
MDL_key *mdl_key = mdl_ticket->get_key();
MDL_key::enum_mdl_namespace mdl_namespace = mdl_key->mdl_namespace();
table->field[0]->store((longlong) mdl_ctx->get_thread_id(), TRUE);
table->field[1]->set_notnull();
table->field[1]->store(
metadata_lock_info_lock_mode[(int) mdl_ticket_type].str,
metadata_lock_info_lock_mode[(int) mdl_ticket_type].length,
system_charset_info);
table->field[2]->set_null();
table->field[3]->set_notnull();
table->field[3]->store(
metadata_lock_info_lock_name[(int) mdl_namespace].str,
metadata_lock_info_lock_name[(int) mdl_namespace].length,
system_charset_info);
table->field[4]->set_notnull();
table->field[4]->store(mdl_key->db_name(),
mdl_key->db_name_length(), system_charset_info);
table->field[5]->set_notnull();
table->field[5]->store(mdl_key->name(),
mdl_key->name_length(), system_charset_info);
if (schema_table_store_record(thd, table))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
int i_s_metadata_lock_info_fill_table(
THD *thd,
TABLE_LIST *tables,
COND *cond
) {
st_i_s_metadata_param param;
DBUG_ENTER("i_s_metadata_lock_info_fill_table");
param.table = tables->table;
param.thd = thd;
DBUG_RETURN(mdl_iterate(i_s_metadata_lock_info_fill_row, &param));
}
static int i_s_metadata_lock_info_init(
void *p
) {
compile_time_assert(sizeof(metadata_lock_info_lock_name)/sizeof(LEX_STRING)
== MDL_key::NAMESPACE_END);
compile_time_assert(sizeof(metadata_lock_info_lock_mode)/sizeof(LEX_STRING)
== MDL_TYPE_END);
ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *) p;
DBUG_ENTER("i_s_metadata_lock_info_init");
schema->fields_info = i_s_metadata_lock_info_fields_info;
schema->fill_table = i_s_metadata_lock_info_fill_table;
schema->idx_field1 = 0;
DBUG_RETURN(0);
}
static int i_s_metadata_lock_info_deinit(
void *p
) {
DBUG_ENTER("i_s_metadata_lock_info_deinit");
DBUG_RETURN(0);
}
static struct st_mysql_information_schema i_s_metadata_lock_info_plugin =
{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
#ifdef MARIADB_BASE_VERSION
maria_declare_plugin(metadata_lock_info)
{
MYSQL_INFORMATION_SCHEMA_PLUGIN,
&i_s_metadata_lock_info_plugin,
"METADATA_LOCK_INFO",
"Kentoku Shiba",
"Metadata locking viewer",
PLUGIN_LICENSE_GPL,
i_s_metadata_lock_info_init,
i_s_metadata_lock_info_deinit,
0x0001,
NULL,
NULL,
NULL,
MariaDB_PLUGIN_MATURITY_STABLE
}
maria_declare_plugin_end;
#else
mysql_declare_plugin(metadata_lock_info)
{
MYSQL_INFORMATION_SCHEMA_PLUGIN,
&i_s_metadata_lock_info_plugin,
"METADATA_LOCK_INFO",
"Kentoku Shiba",
"Metadata locking viewer",
PLUGIN_LICENSE_GPL,
i_s_metadata_lock_info_init,
i_s_metadata_lock_info_deinit,
0x0001,
NULL,
NULL,
NULL,
#if MYSQL_VERSION_ID >= 50600
0,
#endif
}
mysql_declare_plugin_end;
#endif