1/* Copyright (C) 2013 Kentoku Shiba
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
15
16#define MYSQL_SERVER 1
17#include <my_global.h>
18#include "mysql_version.h"
19#include "mysql/plugin.h"
20#include "sql_class.h"
21#include "sql_show.h"
22
23static const LEX_STRING metadata_lock_info_lock_name[] = {
24 { C_STRING_WITH_LEN("Global read lock") },
25 { C_STRING_WITH_LEN("Schema metadata lock") },
26 { C_STRING_WITH_LEN("Table metadata lock") },
27 { C_STRING_WITH_LEN("Stored function metadata lock") },
28 { C_STRING_WITH_LEN("Stored procedure metadata lock") },
29 { C_STRING_WITH_LEN("Stored package body metadata lock") },
30 { C_STRING_WITH_LEN("Trigger metadata lock") },
31 { C_STRING_WITH_LEN("Event metadata lock") },
32 { C_STRING_WITH_LEN("Commit lock") },
33 { C_STRING_WITH_LEN("User lock") },
34};
35
36static const LEX_STRING metadata_lock_info_lock_mode[] = {
37 { C_STRING_WITH_LEN("MDL_INTENTION_EXCLUSIVE") },
38 { C_STRING_WITH_LEN("MDL_SHARED") },
39 { C_STRING_WITH_LEN("MDL_SHARED_HIGH_PRIO") },
40 { C_STRING_WITH_LEN("MDL_SHARED_READ") },
41 { C_STRING_WITH_LEN("MDL_SHARED_WRITE") },
42 { C_STRING_WITH_LEN("MDL_SHARED_UPGRADABLE") },
43 { C_STRING_WITH_LEN("MDL_SHARED_READ_ONLY") },
44 { C_STRING_WITH_LEN("MDL_SHARED_NO_WRITE") },
45 { C_STRING_WITH_LEN("MDL_SHARED_NO_READ_WRITE") },
46 { C_STRING_WITH_LEN("MDL_EXCLUSIVE") },
47};
48
49static ST_FIELD_INFO i_s_metadata_lock_info_fields_info[] =
50{
51 {"THREAD_ID", 20, MYSQL_TYPE_LONGLONG, 0,
52 MY_I_S_UNSIGNED, "thread_id", SKIP_OPEN_TABLE},
53 {"LOCK_MODE", 24, MYSQL_TYPE_STRING, 0,
54 MY_I_S_MAYBE_NULL, "lock_mode", SKIP_OPEN_TABLE},
55 {"LOCK_DURATION", 30, MYSQL_TYPE_STRING, 0,
56 MY_I_S_MAYBE_NULL, "lock_duration", SKIP_OPEN_TABLE},
57 {"LOCK_TYPE", 33, MYSQL_TYPE_STRING, 0,
58 MY_I_S_MAYBE_NULL, "lock_type", SKIP_OPEN_TABLE},
59 {"TABLE_SCHEMA", 64, MYSQL_TYPE_STRING, 0,
60 MY_I_S_MAYBE_NULL, "table_schema", SKIP_OPEN_TABLE},
61 {"TABLE_NAME", 64, MYSQL_TYPE_STRING, 0,
62 MY_I_S_MAYBE_NULL, "table_name", SKIP_OPEN_TABLE},
63 {NULL, 0, MYSQL_TYPE_STRING, 0, 0, NULL, 0}
64};
65
66struct st_i_s_metadata_param
67{
68 THD *thd;
69 TABLE *table;
70};
71
72int i_s_metadata_lock_info_fill_row(
73 MDL_ticket *mdl_ticket,
74 void *arg
75) {
76 st_i_s_metadata_param *param = (st_i_s_metadata_param *) arg;
77 THD *thd = param->thd;
78 TABLE *table = param->table;
79 DBUG_ENTER("i_s_metadata_lock_info_fill_row");
80 MDL_context *mdl_ctx = mdl_ticket->get_ctx();
81 enum_mdl_type mdl_ticket_type = mdl_ticket->get_type();
82 MDL_key *mdl_key = mdl_ticket->get_key();
83 MDL_key::enum_mdl_namespace mdl_namespace = mdl_key->mdl_namespace();
84 table->field[0]->store((longlong) mdl_ctx->get_thread_id(), TRUE);
85 table->field[1]->set_notnull();
86 table->field[1]->store(
87 metadata_lock_info_lock_mode[(int) mdl_ticket_type].str,
88 metadata_lock_info_lock_mode[(int) mdl_ticket_type].length,
89 system_charset_info);
90 table->field[2]->set_null();
91 table->field[3]->set_notnull();
92 table->field[3]->store(
93 metadata_lock_info_lock_name[(int) mdl_namespace].str,
94 metadata_lock_info_lock_name[(int) mdl_namespace].length,
95 system_charset_info);
96 table->field[4]->set_notnull();
97 table->field[4]->store(mdl_key->db_name(),
98 mdl_key->db_name_length(), system_charset_info);
99 table->field[5]->set_notnull();
100 table->field[5]->store(mdl_key->name(),
101 mdl_key->name_length(), system_charset_info);
102 if (schema_table_store_record(thd, table))
103 DBUG_RETURN(1);
104 DBUG_RETURN(0);
105}
106
107int i_s_metadata_lock_info_fill_table(
108 THD *thd,
109 TABLE_LIST *tables,
110 COND *cond
111) {
112 st_i_s_metadata_param param;
113 DBUG_ENTER("i_s_metadata_lock_info_fill_table");
114 param.table = tables->table;
115 param.thd = thd;
116 DBUG_RETURN(mdl_iterate(i_s_metadata_lock_info_fill_row, &param));
117}
118
119static int i_s_metadata_lock_info_init(
120 void *p
121) {
122
123 compile_time_assert(sizeof(metadata_lock_info_lock_name)/sizeof(LEX_STRING)
124 == MDL_key::NAMESPACE_END);
125 compile_time_assert(sizeof(metadata_lock_info_lock_mode)/sizeof(LEX_STRING)
126 == MDL_TYPE_END);
127
128 ST_SCHEMA_TABLE *schema = (ST_SCHEMA_TABLE *) p;
129 DBUG_ENTER("i_s_metadata_lock_info_init");
130 schema->fields_info = i_s_metadata_lock_info_fields_info;
131 schema->fill_table = i_s_metadata_lock_info_fill_table;
132 schema->idx_field1 = 0;
133 DBUG_RETURN(0);
134}
135
136static int i_s_metadata_lock_info_deinit(
137 void *p
138) {
139 DBUG_ENTER("i_s_metadata_lock_info_deinit");
140 DBUG_RETURN(0);
141}
142
143static struct st_mysql_information_schema i_s_metadata_lock_info_plugin =
144{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
145
146#ifdef MARIADB_BASE_VERSION
147maria_declare_plugin(metadata_lock_info)
148{
149 MYSQL_INFORMATION_SCHEMA_PLUGIN,
150 &i_s_metadata_lock_info_plugin,
151 "METADATA_LOCK_INFO",
152 "Kentoku Shiba",
153 "Metadata locking viewer",
154 PLUGIN_LICENSE_GPL,
155 i_s_metadata_lock_info_init,
156 i_s_metadata_lock_info_deinit,
157 0x0001,
158 NULL,
159 NULL,
160 NULL,
161 MariaDB_PLUGIN_MATURITY_STABLE
162}
163maria_declare_plugin_end;
164#else
165mysql_declare_plugin(metadata_lock_info)
166{
167 MYSQL_INFORMATION_SCHEMA_PLUGIN,
168 &i_s_metadata_lock_info_plugin,
169 "METADATA_LOCK_INFO",
170 "Kentoku Shiba",
171 "Metadata locking viewer",
172 PLUGIN_LICENSE_GPL,
173 i_s_metadata_lock_info_init,
174 i_s_metadata_lock_info_deinit,
175 0x0001,
176 NULL,
177 NULL,
178 NULL,
179#if MYSQL_VERSION_ID >= 50600
180 0,
181#endif
182}
183mysql_declare_plugin_end;
184#endif
185