1 /* Copyright (c) 2014, 2021, Oracle and/or its affiliates.
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, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22
23 /**
24 @file storage/perfschema/table_prepared_stmt_instances.cc
25 Table PREPARED_STATEMENTS_INSTANCES (implementation).
26 */
27
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "pfs_instr_class.h"
31 #include "pfs_column_types.h"
32 #include "pfs_column_values.h"
33 #include "pfs_global.h"
34 #include "pfs_instr.h"
35 #include "pfs_timer.h"
36 #include "pfs_visitor.h"
37 #include "pfs_prepared_stmt.h"
38 #include "table_prepared_stmt_instances.h"
39 #include "pfs_buffer_container.h"
40 #include "field.h"
41
42 THR_LOCK table_prepared_stmt_instances::m_table_lock;
43
44 static const TABLE_FIELD_TYPE field_types[]=
45 {
46 {
47 { C_STRING_WITH_LEN("OBJECT_INSTANCE_BEGIN") },
48 { C_STRING_WITH_LEN("bigint(20)") },
49 { NULL, 0}
50 },
51 {
52 { C_STRING_WITH_LEN("STATEMENT_ID") },
53 { C_STRING_WITH_LEN("bigint(20)") },
54 { NULL, 0}
55 },
56 {
57 { C_STRING_WITH_LEN("STATEMENT_NAME") },
58 { C_STRING_WITH_LEN("varchar(64)") },
59 { NULL, 0}
60 },
61 {
62 { C_STRING_WITH_LEN("SQL_TEXT") },
63 { C_STRING_WITH_LEN("longtext") },
64 { NULL, 0}
65 },
66 {
67 { C_STRING_WITH_LEN("OWNER_THREAD_ID") },
68 { C_STRING_WITH_LEN("bigint(20)") },
69 { NULL, 0}
70 },
71 {
72 { C_STRING_WITH_LEN("OWNER_EVENT_ID") },
73 { C_STRING_WITH_LEN("bigint(20)") },
74 { NULL, 0}
75 },
76 {
77 { C_STRING_WITH_LEN("OWNER_OBJECT_TYPE") },
78 { C_STRING_WITH_LEN("enum(\'EVENT\',\'FUNCTION\',\'PROCEDURE\',\'TABLE\',\'TRIGGER\')") },
79 { NULL, 0}
80 },
81 {
82 { C_STRING_WITH_LEN("OWNER_OBJECT_SCHEMA") },
83 { C_STRING_WITH_LEN("varchar(64)") },
84 { NULL, 0}
85 },
86 {
87 { C_STRING_WITH_LEN("OWNER_OBJECT_NAME") },
88 { C_STRING_WITH_LEN("varchar(64)") },
89 { NULL, 0}
90 },
91 {
92 { C_STRING_WITH_LEN("TIMER_PREPARE") },
93 { C_STRING_WITH_LEN("bigint(20)") },
94 { NULL, 0}
95 },
96 {
97 { C_STRING_WITH_LEN("COUNT_REPREPARE") },
98 { C_STRING_WITH_LEN("bigint(20)") },
99 { NULL, 0}
100 },
101 {
102 { C_STRING_WITH_LEN("COUNT_EXECUTE") },
103 { C_STRING_WITH_LEN("bigint(20)") },
104 { NULL, 0}
105 },
106 {
107 { C_STRING_WITH_LEN("SUM_TIMER_EXECUTE") },
108 { C_STRING_WITH_LEN("bigint(20)") },
109 { NULL, 0}
110 },
111 {
112 { C_STRING_WITH_LEN("MIN_TIMER_EXECUTE") },
113 { C_STRING_WITH_LEN("bigint(20)") },
114 { NULL, 0}
115 },
116 {
117 { C_STRING_WITH_LEN("AVG_TIMER_EXECUTE") },
118 { C_STRING_WITH_LEN("bigint(20)") },
119 { NULL, 0}
120 },
121 {
122 { C_STRING_WITH_LEN("MAX_TIMER_EXECUTE") },
123 { C_STRING_WITH_LEN("bigint(20)") },
124 { NULL, 0}
125 },
126 {
127 { C_STRING_WITH_LEN("SUM_LOCK_TIME") },
128 { C_STRING_WITH_LEN("bigint(20)") },
129 { NULL, 0}
130 },
131 {
132 { C_STRING_WITH_LEN("SUM_ERRORS") },
133 { C_STRING_WITH_LEN("bigint(20)") },
134 { NULL, 0}
135 },
136 {
137 { C_STRING_WITH_LEN("SUM_WARNINGS") },
138 { C_STRING_WITH_LEN("bigint(20)") },
139 { NULL, 0}
140 },
141 {
142 { C_STRING_WITH_LEN("SUM_ROWS_AFFECTED") },
143 { C_STRING_WITH_LEN("bigint(20)") },
144 { NULL, 0}
145 },
146 {
147 { C_STRING_WITH_LEN("SUM_ROWS_SENT") },
148 { C_STRING_WITH_LEN("bigint(20)") },
149 { NULL, 0}
150 },
151 {
152 { C_STRING_WITH_LEN("SUM_ROWS_EXAMINED") },
153 { C_STRING_WITH_LEN("bigint(20)") },
154 { NULL, 0}
155 },
156 {
157 { C_STRING_WITH_LEN("SUM_CREATED_TMP_DISK_TABLES") },
158 { C_STRING_WITH_LEN("bigint(20)") },
159 { NULL, 0}
160 },
161 {
162 { C_STRING_WITH_LEN("SUM_CREATED_TMP_TABLES") },
163 { C_STRING_WITH_LEN("bigint(20)") },
164 { NULL, 0}
165 },
166 {
167 { C_STRING_WITH_LEN("SUM_SELECT_FULL_JOIN") },
168 { C_STRING_WITH_LEN("bigint(20)") },
169 { NULL, 0}
170 },
171 {
172 { C_STRING_WITH_LEN("SUM_SELECT_FULL_RANGE_JOIN") },
173 { C_STRING_WITH_LEN("bigint(20)") },
174 { NULL, 0}
175 },
176 {
177 { C_STRING_WITH_LEN("SUM_SELECT_RANGE") },
178 { C_STRING_WITH_LEN("bigint(20)") },
179 { NULL, 0}
180 },
181 {
182 { C_STRING_WITH_LEN("SUM_SELECT_RANGE_CHECK") },
183 { C_STRING_WITH_LEN("bigint(20)") },
184 { NULL, 0}
185 },
186 {
187 { C_STRING_WITH_LEN("SUM_SELECT_SCAN") },
188 { C_STRING_WITH_LEN("bigint(20)") },
189 { NULL, 0}
190 },
191 {
192 { C_STRING_WITH_LEN("SUM_SORT_MERGE_PASSES") },
193 { C_STRING_WITH_LEN("bigint(20)") },
194 { NULL, 0}
195 },
196 {
197 { C_STRING_WITH_LEN("SUM_SORT_RANGE") },
198 { C_STRING_WITH_LEN("bigint(20)") },
199 { NULL, 0}
200 },
201 {
202 { C_STRING_WITH_LEN("SUM_SORT_ROWS") },
203 { C_STRING_WITH_LEN("bigint(20)") },
204 { NULL, 0}
205 },
206 {
207 { C_STRING_WITH_LEN("SUM_SORT_SCAN") },
208 { C_STRING_WITH_LEN("bigint(20)") },
209 { NULL, 0}
210 },
211 {
212 { C_STRING_WITH_LEN("SUM_NO_INDEX_USED") },
213 { C_STRING_WITH_LEN("bigint(20)") },
214 { NULL, 0}
215 },
216 {
217 { C_STRING_WITH_LEN("SUM_NO_GOOD_INDEX_USED") },
218 { C_STRING_WITH_LEN("bigint(20)") },
219 { NULL, 0}
220 },
221 };
222
223 TABLE_FIELD_DEF
224 table_prepared_stmt_instances::m_field_def=
225 { 35, field_types };
226
227 PFS_engine_table_share
228 table_prepared_stmt_instances::m_share=
229 {
230 { C_STRING_WITH_LEN("prepared_statements_instances") },
231 &pfs_truncatable_acl,
232 table_prepared_stmt_instances::create,
233 NULL, /* write_row */
234 table_prepared_stmt_instances::delete_all_rows,
235 table_prepared_stmt_instances::get_row_count,
236 sizeof(PFS_simple_index),
237 &m_table_lock,
238 &m_field_def,
239 false, /* checked */
240 false /* perpetual */
241 };
242
243 PFS_engine_table*
create(void)244 table_prepared_stmt_instances::create(void)
245 {
246 return new table_prepared_stmt_instances();
247 }
248
249 int
delete_all_rows(void)250 table_prepared_stmt_instances::delete_all_rows(void)
251 {
252 reset_prepared_stmt_instances();
253 return 0;
254 }
255
256 ha_rows
get_row_count(void)257 table_prepared_stmt_instances::get_row_count(void)
258 {
259 return global_prepared_stmt_container.get_row_count();
260 }
261
table_prepared_stmt_instances()262 table_prepared_stmt_instances::table_prepared_stmt_instances()
263 : PFS_engine_table(&m_share, &m_pos),
264 m_row_exists(false), m_pos(0), m_next_pos(0)
265 {}
266
reset_position(void)267 void table_prepared_stmt_instances::reset_position(void)
268 {
269 m_pos= 0;
270 m_next_pos= 0;
271 }
272
rnd_next(void)273 int table_prepared_stmt_instances::rnd_next(void)
274 {
275 PFS_prepared_stmt* pfs;
276
277 m_pos.set_at(&m_next_pos);
278 PFS_prepared_stmt_iterator it= global_prepared_stmt_container.iterate(m_pos.m_index);
279 pfs= it.scan_next(& m_pos.m_index);
280 if (pfs != NULL)
281 {
282 make_row(pfs);
283 m_next_pos.set_after(&m_pos);
284 return 0;
285 }
286
287 return HA_ERR_END_OF_FILE;
288 }
289
290 int
rnd_pos(const void * pos)291 table_prepared_stmt_instances::rnd_pos(const void *pos)
292 {
293 PFS_prepared_stmt* pfs;
294
295 set_position(pos);
296
297 pfs= global_prepared_stmt_container.get(m_pos.m_index);
298 if (pfs != NULL)
299 {
300 make_row(pfs);
301 return 0;
302 }
303
304 return HA_ERR_RECORD_DELETED;
305 }
306
307
make_row(PFS_prepared_stmt * prepared_stmt)308 void table_prepared_stmt_instances::make_row(PFS_prepared_stmt* prepared_stmt)
309 {
310 pfs_optimistic_state lock;
311 m_row_exists= false;
312
313 prepared_stmt->m_lock.begin_optimistic_lock(&lock);
314
315 m_row.m_identity= prepared_stmt->m_identity;
316
317 m_row.m_stmt_id= prepared_stmt->m_stmt_id;
318
319 m_row.m_owner_thread_id= prepared_stmt->m_owner_thread_id;
320 m_row.m_owner_event_id= prepared_stmt->m_owner_event_id;
321
322 m_row.m_stmt_name_length= prepared_stmt->m_stmt_name_length;
323 if(m_row.m_stmt_name_length > 0)
324 memcpy(m_row.m_stmt_name, prepared_stmt->m_stmt_name,
325 m_row.m_stmt_name_length);
326
327 m_row.m_sql_text_length= prepared_stmt->m_sqltext_length;
328 if(m_row.m_sql_text_length > 0)
329 memcpy(m_row.m_sql_text, prepared_stmt->m_sqltext,
330 m_row.m_sql_text_length);
331
332 m_row.m_owner_object_type= prepared_stmt->m_owner_object_type;
333
334 m_row.m_owner_object_name_length= prepared_stmt->m_owner_object_name_length;
335 if(m_row.m_owner_object_name_length > 0)
336 memcpy(m_row.m_owner_object_name, prepared_stmt->m_owner_object_name,
337 m_row.m_owner_object_name_length);
338
339 m_row.m_owner_object_schema_length= prepared_stmt->m_owner_object_schema_length;
340 if(m_row.m_owner_object_schema_length > 0)
341 memcpy(m_row.m_owner_object_schema, prepared_stmt->m_owner_object_schema,
342 m_row.m_owner_object_schema_length);
343
344 time_normalizer *normalizer= time_normalizer::get(statement_timer);
345 /* Get prepared statement prepare stats. */
346 m_row.m_prepare_stat.set(normalizer, & prepared_stmt->m_prepare_stat);
347 /* Get prepared statement reprepare stats. */
348 m_row.m_reprepare_stat.set(normalizer, & prepared_stmt->m_reprepare_stat);
349 /* Get prepared statement execute stats. */
350 m_row.m_execute_stat.set(normalizer, & prepared_stmt->m_execute_stat);
351
352 if (! prepared_stmt->m_lock.end_optimistic_lock(&lock))
353 return;
354
355 m_row_exists= true;
356 }
357
358 int table_prepared_stmt_instances
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)359 ::read_row_values(TABLE *table, unsigned char *buf, Field **fields,
360 bool read_all)
361 {
362 Field *f;
363
364 if (unlikely(! m_row_exists))
365 return HA_ERR_RECORD_DELETED;
366
367 /*
368 Set the null bits.
369 */
370 assert(table->s->null_bytes == 1);
371 buf[0]= 0;
372
373 for (; (f= *fields) ; fields++)
374 {
375 if (read_all || bitmap_is_set(table->read_set, f->field_index))
376 {
377 switch(f->field_index)
378 {
379 case 0: /* OBJECT_INSTANCE_BEGIN */
380 set_field_ulonglong(f, (intptr)m_row.m_identity);
381 break;
382 case 1: /* STATEMENT_ID */
383 set_field_ulonglong(f, m_row.m_stmt_id);
384 break;
385 case 2: /* STATEMENT_NAME */
386 if(m_row.m_stmt_name_length > 0)
387 set_field_varchar_utf8(f, m_row.m_stmt_name,
388 m_row.m_stmt_name_length);
389 else
390 f->set_null();
391 break;
392 case 3: /* SQL_TEXT */
393 if(m_row.m_sql_text_length > 0)
394 set_field_longtext_utf8(f, m_row.m_sql_text,
395 m_row.m_sql_text_length);
396 else
397 f->set_null();
398 break;
399 case 4: /* OWNER_THREAD_ID */
400 set_field_ulonglong(f, m_row.m_owner_thread_id);
401 break;
402 case 5: /* OWNER_EVENT_ID */
403 if(m_row.m_owner_event_id > 0)
404 set_field_ulonglong(f, m_row.m_owner_event_id);
405 else
406 f->set_null();
407 break;
408 case 6: /* OWNER_OBJECT_TYPE */
409 if(m_row.m_owner_object_type != 0)
410 set_field_enum(f, m_row.m_owner_object_type);
411 else
412 f->set_null();
413 break;
414 case 7: /* OWNER_OBJECT_SCHEMA */
415 if(m_row.m_owner_object_schema_length > 0)
416 set_field_varchar_utf8(f, m_row.m_owner_object_schema,
417 m_row.m_owner_object_schema_length);
418 else
419 f->set_null();
420 break;
421 case 8: /* OWNER_OBJECT_NAME */
422 if(m_row.m_owner_object_name_length > 0)
423 set_field_varchar_utf8(f, m_row.m_owner_object_name,
424 m_row.m_owner_object_name_length);
425 else
426 f->set_null();
427 break;
428 case 9: /* TIMER_PREPARE */
429 m_row.m_prepare_stat.set_field(1, f);
430 break;
431 case 10: /* COUNT_REPREPARE */
432 m_row.m_reprepare_stat.set_field(0, f);
433 break;
434 default: /* 14, ... COUNT/SUM/MIN/AVG/MAX */
435 m_row.m_execute_stat.set_field(f->field_index - 11, f);
436 break;
437 }
438 }
439 }
440
441 return 0;
442 }
443
444