1 /* Copyright (c) 2010, 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 Foundation,
21 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22
23 /**
24 @file storage/perfschema/table_events_statements.cc
25 Table EVENTS_STATEMENTS_xxx (implementation).
26 */
27
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "table_events_statements.h"
31 #include "pfs_instr_class.h"
32 #include "pfs_instr.h"
33 #include "pfs_events_statements.h"
34 #include "pfs_timer.h"
35 #include "sp_head.h" /* TYPE_ENUM_FUNCTION, ... */
36 #include "table_helper.h"
37 #include "my_md5.h"
38 #include "pfs_buffer_container.h"
39
40 THR_LOCK table_events_statements_current::m_table_lock;
41
42 static const TABLE_FIELD_TYPE field_types[]=
43 {
44 {
45 { C_STRING_WITH_LEN("THREAD_ID") },
46 { C_STRING_WITH_LEN("bigint(20)") },
47 { NULL, 0}
48 },
49 {
50 { C_STRING_WITH_LEN("EVENT_ID") },
51 { C_STRING_WITH_LEN("bigint(20)") },
52 { NULL, 0}
53 },
54 {
55 { C_STRING_WITH_LEN("END_EVENT_ID") },
56 { C_STRING_WITH_LEN("bigint(20)") },
57 { NULL, 0}
58 },
59 {
60 { C_STRING_WITH_LEN("EVENT_NAME") },
61 { C_STRING_WITH_LEN("varchar(128)") },
62 { NULL, 0}
63 },
64 {
65 { C_STRING_WITH_LEN("SOURCE") },
66 { C_STRING_WITH_LEN("varchar(64)") },
67 { NULL, 0}
68 },
69 {
70 { C_STRING_WITH_LEN("TIMER_START") },
71 { C_STRING_WITH_LEN("bigint(20)") },
72 { NULL, 0}
73 },
74 {
75 { C_STRING_WITH_LEN("TIMER_END") },
76 { C_STRING_WITH_LEN("bigint(20)") },
77 { NULL, 0}
78 },
79 {
80 { C_STRING_WITH_LEN("TIMER_WAIT") },
81 { C_STRING_WITH_LEN("bigint(20)") },
82 { NULL, 0}
83 },
84 {
85 { C_STRING_WITH_LEN("LOCK_TIME") },
86 { C_STRING_WITH_LEN("bigint(20)") },
87 { NULL, 0}
88 },
89 {
90 { C_STRING_WITH_LEN("SQL_TEXT") },
91 { C_STRING_WITH_LEN("longtext") },
92 { NULL, 0}
93 },
94 {
95 { C_STRING_WITH_LEN("DIGEST") },
96 { C_STRING_WITH_LEN("varchar(32)") },
97 { NULL, 0}
98 },
99 {
100 { C_STRING_WITH_LEN("DIGEST_TEXT") },
101 { C_STRING_WITH_LEN("longtext") },
102 { NULL, 0}
103 },
104 {
105 { C_STRING_WITH_LEN("CURRENT_SCHEMA") },
106 { C_STRING_WITH_LEN("varchar(64)") },
107 { NULL, 0}
108 },
109 {
110 { C_STRING_WITH_LEN("OBJECT_TYPE") },
111 { C_STRING_WITH_LEN("varchar(64)") },
112 { NULL, 0}
113 },
114 {
115 { C_STRING_WITH_LEN("OBJECT_SCHEMA") },
116 { C_STRING_WITH_LEN("varchar(64)") },
117 { NULL, 0}
118 },
119 {
120 { C_STRING_WITH_LEN("OBJECT_NAME") },
121 { C_STRING_WITH_LEN("varchar(64)") },
122 { NULL, 0}
123 },
124 {
125 { C_STRING_WITH_LEN("OBJECT_INSTANCE_BEGIN") },
126 { C_STRING_WITH_LEN("bigint") },
127 { NULL, 0}
128 },
129 {
130 { C_STRING_WITH_LEN("MYSQL_ERRNO") },
131 { C_STRING_WITH_LEN("int(11)") },
132 { NULL, 0}
133 },
134 {
135 { C_STRING_WITH_LEN("RETURNED_SQLSTATE") },
136 { C_STRING_WITH_LEN("varchar(5)") },
137 { NULL, 0}
138 },
139 {
140 { C_STRING_WITH_LEN("MESSAGE_TEXT") },
141 { C_STRING_WITH_LEN("varchar(128)") },
142 { NULL, 0}
143 },
144 {
145 { C_STRING_WITH_LEN("ERRORS") },
146 { C_STRING_WITH_LEN("bigint") },
147 { NULL, 0}
148 },
149 {
150 { C_STRING_WITH_LEN("WARNINGS") },
151 { C_STRING_WITH_LEN("bigint") },
152 { NULL, 0}
153 },
154 {
155 { C_STRING_WITH_LEN("ROWS_AFFECTED") },
156 { C_STRING_WITH_LEN("bigint") },
157 { NULL, 0}
158 },
159 {
160 { C_STRING_WITH_LEN("ROWS_SENT") },
161 { C_STRING_WITH_LEN("bigint") },
162 { NULL, 0}
163 },
164 {
165 { C_STRING_WITH_LEN("ROWS_EXAMINED") },
166 { C_STRING_WITH_LEN("bigint") },
167 { NULL, 0}
168 },
169 {
170 { C_STRING_WITH_LEN("CREATED_TMP_DISK_TABLES") },
171 { C_STRING_WITH_LEN("bigint") },
172 { NULL, 0}
173 },
174 {
175 { C_STRING_WITH_LEN("CREATED_TMP_TABLES") },
176 { C_STRING_WITH_LEN("bigint") },
177 { NULL, 0}
178 },
179 {
180 { C_STRING_WITH_LEN("SELECT_FULL_JOIN") },
181 { C_STRING_WITH_LEN("bigint") },
182 { NULL, 0}
183 },
184 {
185 { C_STRING_WITH_LEN("SELECT_FULL_RANGE_JOIN") },
186 { C_STRING_WITH_LEN("bigint") },
187 { NULL, 0}
188 },
189 {
190 { C_STRING_WITH_LEN("SELECT_RANGE") },
191 { C_STRING_WITH_LEN("bigint") },
192 { NULL, 0}
193 },
194 {
195 { C_STRING_WITH_LEN("SELECT_RANGE_CHECK") },
196 { C_STRING_WITH_LEN("bigint") },
197 { NULL, 0}
198 },
199 {
200 { C_STRING_WITH_LEN("SELECT_SCAN") },
201 { C_STRING_WITH_LEN("bigint") },
202 { NULL, 0}
203 },
204 {
205 { C_STRING_WITH_LEN("SORT_MERGE_PASSES") },
206 { C_STRING_WITH_LEN("bigint") },
207 { NULL, 0}
208 },
209 {
210 { C_STRING_WITH_LEN("SORT_RANGE") },
211 { C_STRING_WITH_LEN("bigint") },
212 { NULL, 0}
213 },
214 {
215 { C_STRING_WITH_LEN("SORT_ROWS") },
216 { C_STRING_WITH_LEN("bigint") },
217 { NULL, 0}
218 },
219 {
220 { C_STRING_WITH_LEN("SORT_SCAN") },
221 { C_STRING_WITH_LEN("bigint") },
222 { NULL, 0}
223 },
224 {
225 { C_STRING_WITH_LEN("NO_INDEX_USED") },
226 { C_STRING_WITH_LEN("bigint") },
227 { NULL, 0}
228 },
229 {
230 { C_STRING_WITH_LEN("NO_GOOD_INDEX_USED") },
231 { C_STRING_WITH_LEN("bigint") },
232 { NULL, 0}
233 },
234 {
235 { C_STRING_WITH_LEN("NESTING_EVENT_ID") },
236 { C_STRING_WITH_LEN("bigint(20)") },
237 { NULL, 0}
238 },
239 {
240 { C_STRING_WITH_LEN("NESTING_EVENT_TYPE") },
241 { C_STRING_WITH_LEN("enum(\'TRANSACTION\',\'STATEMENT\',\'STAGE\',\'WAIT\'") },
242 { NULL, 0}
243 },
244 {
245 { C_STRING_WITH_LEN("NESTING_EVENT_LEVEL") },
246 { C_STRING_WITH_LEN("int(11)") },
247 { NULL, 0}
248 }
249 };
250
251 TABLE_FIELD_DEF
252 table_events_statements_current::m_field_def=
253 {41 , field_types };
254
255 PFS_engine_table_share
256 table_events_statements_current::m_share=
257 {
258 { C_STRING_WITH_LEN("events_statements_current") },
259 &pfs_truncatable_acl,
260 table_events_statements_current::create,
261 NULL, /* write_row */
262 table_events_statements_current::delete_all_rows,
263 table_events_statements_current::get_row_count,
264 sizeof(pos_events_statements_current), /* ref length */
265 &m_table_lock,
266 &m_field_def,
267 false, /* checked */
268 false /* perpetual */
269 };
270
271 THR_LOCK table_events_statements_history::m_table_lock;
272
273 PFS_engine_table_share
274 table_events_statements_history::m_share=
275 {
276 { C_STRING_WITH_LEN("events_statements_history") },
277 &pfs_truncatable_acl,
278 table_events_statements_history::create,
279 NULL, /* write_row */
280 table_events_statements_history::delete_all_rows,
281 table_events_statements_history::get_row_count,
282 sizeof(pos_events_statements_history), /* ref length */
283 &m_table_lock,
284 &table_events_statements_current::m_field_def,
285 false, /* checked */
286 false /* perpetual */
287 };
288
289 THR_LOCK table_events_statements_history_long::m_table_lock;
290
291 PFS_engine_table_share
292 table_events_statements_history_long::m_share=
293 {
294 { C_STRING_WITH_LEN("events_statements_history_long") },
295 &pfs_truncatable_acl,
296 table_events_statements_history_long::create,
297 NULL, /* write_row */
298 table_events_statements_history_long::delete_all_rows,
299 table_events_statements_history_long::get_row_count,
300 sizeof(PFS_simple_index), /* ref length */
301 &m_table_lock,
302 &table_events_statements_current::m_field_def,
303 false, /* checked */
304 false /* perpetual */
305 };
306
table_events_statements_common(const PFS_engine_table_share * share,void * pos)307 table_events_statements_common::table_events_statements_common
308 (const PFS_engine_table_share *share, void *pos)
309 : PFS_engine_table(share, pos),
310 m_row_exists(false)
311 {}
312
313 /**
314 Build a row.
315 @param statement the statement the cursor is reading
316 */
make_row_part_1(PFS_events_statements * statement,sql_digest_storage * digest)317 void table_events_statements_common::make_row_part_1(PFS_events_statements *statement,
318 sql_digest_storage *digest)
319 {
320 ulonglong timer_end;
321
322 m_row_exists= false;
323
324 PFS_statement_class *unsafe= (PFS_statement_class*) statement->m_class;
325 PFS_statement_class *klass= sanitize_statement_class(unsafe);
326 if (unlikely(klass == NULL))
327 return;
328
329 m_row.m_thread_internal_id= statement->m_thread_internal_id;
330 m_row.m_event_id= statement->m_event_id;
331 m_row.m_end_event_id= statement->m_end_event_id;
332 m_row.m_nesting_event_id= statement->m_nesting_event_id;
333 m_row.m_nesting_event_type= statement->m_nesting_event_type;
334 m_row.m_nesting_event_level= statement->m_nesting_event_level;
335
336 if (m_row.m_end_event_id == 0)
337 {
338 timer_end= get_timer_raw_value(statement_timer);
339 }
340 else
341 {
342 timer_end= statement->m_timer_end;
343 }
344
345 m_normalizer->to_pico(statement->m_timer_start, timer_end,
346 & m_row.m_timer_start, & m_row.m_timer_end, & m_row.m_timer_wait);
347 m_row.m_lock_time= statement->m_lock_time * MICROSEC_TO_PICOSEC;
348
349 m_row.m_name= klass->m_name;
350 m_row.m_name_length= klass->m_name_length;
351
352 CHARSET_INFO *cs= get_charset(statement->m_sqltext_cs_number, MYF(0));
353 size_t valid_length= statement->m_sqltext_length;
354
355 if (cs != NULL)
356 {
357 if (cs->mbmaxlen > 1)
358 {
359 int well_formed_error;
360 valid_length= cs->cset->well_formed_len(cs,
361 statement->m_sqltext,
362 statement->m_sqltext + valid_length,
363 valid_length,
364 &well_formed_error);
365 }
366 }
367
368 m_row.m_sqltext.set_charset(cs);
369 m_row.m_sqltext.length(0);
370 m_row.m_sqltext.append(statement->m_sqltext, (uint32)valid_length, cs);
371
372 /* Indicate that sqltext is truncated or not well-formed. */
373 if (statement->m_sqltext_truncated || valid_length < statement->m_sqltext_length)
374 {
375 size_t chars= m_row.m_sqltext.numchars();
376 if (chars > 3)
377 {
378 chars-= 3;
379 size_t bytes_offset= m_row.m_sqltext.charpos(chars, 0);
380 m_row.m_sqltext.length(bytes_offset);
381 m_row.m_sqltext.append("...", 3);
382 }
383 }
384
385 m_row.m_current_schema_name_length= statement->m_current_schema_name_length;
386 if (m_row.m_current_schema_name_length > 0)
387 memcpy(m_row.m_current_schema_name, statement->m_current_schema_name, m_row.m_current_schema_name_length);
388
389 m_row.m_object_type= statement->m_sp_type;
390
391 m_row.m_schema_name_length= statement->m_schema_name_length;
392 if (m_row.m_schema_name_length > 0)
393 memcpy(m_row.m_schema_name, statement->m_schema_name, m_row.m_schema_name_length);
394
395 m_row.m_object_name_length= statement->m_object_name_length;
396 if (m_row.m_object_name_length > 0)
397 memcpy(m_row.m_object_name, statement->m_object_name, m_row.m_object_name_length);
398
399 /* Disable source file and line to avoid stale __FILE__ pointers. */
400 m_row.m_source_length= 0;
401
402 memcpy(m_row.m_message_text, statement->m_message_text, sizeof(m_row.m_message_text));
403 m_row.m_sql_errno= statement->m_sql_errno;
404 memcpy(m_row.m_sqlstate, statement->m_sqlstate, SQLSTATE_LENGTH);
405 m_row.m_error_count= statement->m_error_count;
406 m_row.m_warning_count= statement->m_warning_count;
407 m_row.m_rows_affected= statement->m_rows_affected;
408
409 m_row.m_rows_sent= statement->m_rows_sent;
410 m_row.m_rows_examined= statement->m_rows_examined;
411 m_row.m_created_tmp_disk_tables= statement->m_created_tmp_disk_tables;
412 m_row.m_created_tmp_tables= statement->m_created_tmp_tables;
413 m_row.m_select_full_join= statement->m_select_full_join;
414 m_row.m_select_full_range_join= statement->m_select_full_range_join;
415 m_row.m_select_range= statement->m_select_range;
416 m_row.m_select_range_check= statement->m_select_range_check;
417 m_row.m_select_scan= statement->m_select_scan;
418 m_row.m_sort_merge_passes= statement->m_sort_merge_passes;
419 m_row.m_sort_range= statement->m_sort_range;
420 m_row.m_sort_rows= statement->m_sort_rows;
421 m_row.m_sort_scan= statement->m_sort_scan;
422 m_row.m_no_index_used= statement->m_no_index_used;
423 m_row.m_no_good_index_used= statement->m_no_good_index_used;
424
425 /*
426 Making a copy of digest storage.
427 */
428 digest->copy(& statement->m_digest_storage);
429
430 m_row_exists= true;
431 return;
432 }
433
make_row_part_2(const sql_digest_storage * digest)434 void table_events_statements_common::make_row_part_2(const sql_digest_storage *digest)
435 {
436 /*
437 Filling up statement digest information.
438 */
439 size_t safe_byte_count= digest->m_byte_count;
440 if (safe_byte_count > 0 &&
441 safe_byte_count <= pfs_max_digest_length)
442 {
443 /* Generate the DIGEST string from the MD5 digest */
444 MD5_HASH_TO_STRING(digest->m_md5,
445 m_row.m_digest.m_digest);
446 m_row.m_digest.m_digest_length= MD5_HASH_TO_STRING_LENGTH;
447
448 /* Generate the DIGEST_TEXT string from the token array */
449 compute_digest_text(digest, &m_row.m_digest.m_digest_text);
450
451 if (m_row.m_digest.m_digest_text.length() == 0)
452 m_row.m_digest.m_digest_length= 0;
453 }
454 else
455 {
456 m_row.m_digest.m_digest_length= 0;
457 m_row.m_digest.m_digest_text.length(0);
458 }
459
460 return;
461 }
462
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)463 int table_events_statements_common::read_row_values(TABLE *table,
464 unsigned char *buf,
465 Field **fields,
466 bool read_all)
467 {
468 Field *f;
469 uint len;
470
471 if (unlikely(! m_row_exists))
472 return HA_ERR_RECORD_DELETED;
473
474 /* Set the null bits */
475 assert(table->s->null_bytes == 3);
476 buf[0]= 0;
477 buf[1]= 0;
478 buf[2]= 0;
479
480 for (; (f= *fields) ; fields++)
481 {
482 if (read_all || bitmap_is_set(table->read_set, f->field_index))
483 {
484 switch(f->field_index)
485 {
486 case 0: /* THREAD_ID */
487 set_field_ulonglong(f, m_row.m_thread_internal_id);
488 break;
489 case 1: /* EVENT_ID */
490 set_field_ulonglong(f, m_row.m_event_id);
491 break;
492 case 2: /* END_EVENT_ID */
493 if (m_row.m_end_event_id > 0)
494 set_field_ulonglong(f, m_row.m_end_event_id - 1);
495 else
496 f->set_null();
497 break;
498 case 3: /* EVENT_NAME */
499 set_field_varchar_utf8(f, m_row.m_name, m_row.m_name_length);
500 break;
501 case 4: /* SOURCE */
502 set_field_varchar_utf8(f, m_row.m_source, m_row.m_source_length);
503 break;
504 case 5: /* TIMER_START */
505 if (m_row.m_timer_start != 0)
506 set_field_ulonglong(f, m_row.m_timer_start);
507 else
508 f->set_null();
509 break;
510 case 6: /* TIMER_END */
511 if (m_row.m_timer_end != 0)
512 set_field_ulonglong(f, m_row.m_timer_end);
513 else
514 f->set_null();
515 break;
516 case 7: /* TIMER_WAIT */
517 if (m_row.m_timer_wait != 0)
518 set_field_ulonglong(f, m_row.m_timer_wait);
519 else
520 f->set_null();
521 break;
522 case 8: /* LOCK_TIME */
523 if (m_row.m_lock_time != 0)
524 set_field_ulonglong(f, m_row.m_lock_time);
525 else
526 f->set_null();
527 break;
528 case 9: /* SQL_TEXT */
529 if (m_row.m_sqltext.length())
530 set_field_longtext_utf8(f, m_row.m_sqltext.ptr(), m_row.m_sqltext.length());
531 else
532 f->set_null();
533 break;
534 case 10: /* DIGEST */
535 if (m_row.m_digest.m_digest_length > 0)
536 set_field_varchar_utf8(f, m_row.m_digest.m_digest,
537 m_row.m_digest.m_digest_length);
538 else
539 f->set_null();
540 break;
541 case 11: /* DIGEST_TEXT */
542 if (m_row.m_digest.m_digest_text.length() > 0)
543 set_field_longtext_utf8(f, m_row.m_digest.m_digest_text.ptr(),
544 m_row.m_digest.m_digest_text.length());
545 else
546 f->set_null();
547 break;
548 case 12: /* CURRENT_SCHEMA */
549 if (m_row.m_current_schema_name_length)
550 set_field_varchar_utf8(f, m_row.m_current_schema_name,
551 m_row.m_current_schema_name_length);
552 else
553 f->set_null();
554 break;
555 case 13: /* OBJECT_TYPE */
556 if (m_row.m_object_name_length > 0)
557 set_field_object_type(f, m_row.m_object_type);
558 else
559 f->set_null();
560 break;
561 case 14: /* OBJECT_SCHEMA */
562 if (m_row.m_schema_name_length)
563 set_field_varchar_utf8(f, m_row.m_schema_name,
564 m_row.m_schema_name_length);
565 else
566 f->set_null();
567 break;
568 case 15: /* OBJECT_NAME */
569 if (m_row.m_object_name_length)
570 set_field_varchar_utf8(f, m_row.m_object_name,
571 m_row.m_object_name_length);
572 else
573 f->set_null();
574 break;
575 case 16: /* OBJECT_INSTANCE_BEGIN */
576 f->set_null();
577 break;
578 case 17: /* MYSQL_ERRNO */
579 set_field_ulong(f, m_row.m_sql_errno);
580 break;
581 case 18: /* RETURNED_SQLSTATE */
582 if (m_row.m_sqlstate[0] != 0)
583 set_field_varchar_utf8(f, m_row.m_sqlstate, SQLSTATE_LENGTH);
584 else
585 f->set_null();
586 break;
587 case 19: /* MESSAGE_TEXT */
588 len= strlen(m_row.m_message_text);
589 if (len)
590 set_field_varchar_utf8(f, m_row.m_message_text, len);
591 else
592 f->set_null();
593 break;
594 case 20: /* ERRORS */
595 set_field_ulonglong(f, m_row.m_error_count);
596 break;
597 case 21: /* WARNINGS */
598 set_field_ulonglong(f, m_row.m_warning_count);
599 break;
600 case 22: /* ROWS_AFFECTED */
601 set_field_ulonglong(f, m_row.m_rows_affected);
602 break;
603 case 23: /* ROWS_SENT */
604 set_field_ulonglong(f, m_row.m_rows_sent);
605 break;
606 case 24: /* ROWS_EXAMINED */
607 set_field_ulonglong(f, m_row.m_rows_examined);
608 break;
609 case 25: /* CREATED_TMP_DISK_TABLES */
610 set_field_ulonglong(f, m_row.m_created_tmp_disk_tables);
611 break;
612 case 26: /* CREATED_TMP_TABLES */
613 set_field_ulonglong(f, m_row.m_created_tmp_tables);
614 break;
615 case 27: /* SELECT_FULL_JOIN */
616 set_field_ulonglong(f, m_row.m_select_full_join);
617 break;
618 case 28: /* SELECT_FULL_RANGE_JOIN */
619 set_field_ulonglong(f, m_row.m_select_full_range_join);
620 break;
621 case 29: /* SELECT_RANGE */
622 set_field_ulonglong(f, m_row.m_select_range);
623 break;
624 case 30: /* SELECT_RANGE_CHECK */
625 set_field_ulonglong(f, m_row.m_select_range_check);
626 break;
627 case 31: /* SELECT_SCAN */
628 set_field_ulonglong(f, m_row.m_select_scan);
629 break;
630 case 32: /* SORT_MERGE_PASSES */
631 set_field_ulonglong(f, m_row.m_sort_merge_passes);
632 break;
633 case 33: /* SORT_RANGE */
634 set_field_ulonglong(f, m_row.m_sort_range);
635 break;
636 case 34: /* SORT_ROWS */
637 set_field_ulonglong(f, m_row.m_sort_rows);
638 break;
639 case 35: /* SORT_SCAN */
640 set_field_ulonglong(f, m_row.m_sort_scan);
641 break;
642 case 36: /* NO_INDEX_USED */
643 set_field_ulonglong(f, m_row.m_no_index_used);
644 break;
645 case 37: /* NO_GOOD_INDEX_USED */
646 set_field_ulonglong(f, m_row.m_no_good_index_used);
647 break;
648 case 38: /* NESTING_EVENT_ID */
649 if (m_row.m_nesting_event_id != 0)
650 set_field_ulonglong(f, m_row.m_nesting_event_id);
651 else
652 f->set_null();
653 break;
654 case 39: /* NESTING_EVENT_TYPE */
655 if (m_row.m_nesting_event_id != 0)
656 set_field_enum(f, m_row.m_nesting_event_type);
657 else
658 f->set_null();
659 break;
660 case 40: /* NESTING_EVENT_LEVEL */
661 set_field_ulong(f, m_row.m_nesting_event_level);
662 break;
663 default:
664 assert(false);
665 }
666 }
667 }
668 return 0;
669 }
670
create(void)671 PFS_engine_table* table_events_statements_current::create(void)
672 {
673 return new table_events_statements_current();
674 }
675
table_events_statements_current()676 table_events_statements_current::table_events_statements_current()
677 : table_events_statements_common(&m_share, &m_pos),
678 m_pos(), m_next_pos()
679 {}
680
reset_position(void)681 void table_events_statements_current::reset_position(void)
682 {
683 m_pos.reset();
684 m_next_pos.reset();
685 }
686
rnd_init(bool scan)687 int table_events_statements_current::rnd_init(bool scan)
688 {
689 m_normalizer= time_normalizer::get(statement_timer);
690 return 0;
691 }
692
rnd_next(void)693 int table_events_statements_current::rnd_next(void)
694 {
695 PFS_thread *pfs_thread;
696 PFS_events_statements *statement;
697 bool has_more_thread= true;
698
699 for (m_pos.set_at(&m_next_pos);
700 has_more_thread;
701 m_pos.next_thread())
702 {
703 pfs_thread= global_thread_container.get(m_pos.m_index_1, & has_more_thread);
704 if (pfs_thread != NULL)
705 {
706 uint safe_events_statements_count= pfs_thread->m_events_statements_count;
707
708 if (safe_events_statements_count == 0)
709 {
710 /* Display the last top level statement, when completed */
711 if (m_pos.m_index_2 >= 1)
712 continue;
713 }
714 else
715 {
716 /* Display all pending statements, when in progress */
717 if (m_pos.m_index_2 >= safe_events_statements_count)
718 continue;
719 }
720
721 statement= &pfs_thread->m_statement_stack[m_pos.m_index_2];
722
723 make_row(pfs_thread, statement);
724 m_next_pos.set_after(&m_pos);
725 return 0;
726 }
727 }
728
729 return HA_ERR_END_OF_FILE;
730 }
731
rnd_pos(const void * pos)732 int table_events_statements_current::rnd_pos(const void *pos)
733 {
734 PFS_thread *pfs_thread;
735 PFS_events_statements *statement;
736
737 set_position(pos);
738
739 pfs_thread= global_thread_container.get(m_pos.m_index_1);
740 if (pfs_thread != NULL)
741 {
742 uint safe_events_statements_count= pfs_thread->m_events_statements_count;
743
744 if (safe_events_statements_count == 0)
745 {
746 /* Display the last top level statement, when completed */
747 if (m_pos.m_index_2 >= 1)
748 return HA_ERR_RECORD_DELETED;
749 }
750 else
751 {
752 /* Display all pending statements, when in progress */
753 if (m_pos.m_index_2 >= safe_events_statements_count)
754 return HA_ERR_RECORD_DELETED;
755 }
756
757 assert(m_pos.m_index_2 < statement_stack_max);
758
759 statement= &pfs_thread->m_statement_stack[m_pos.m_index_2];
760
761 if (statement->m_class != NULL)
762 {
763 make_row(pfs_thread, statement);
764 return 0;
765 }
766 }
767
768 return HA_ERR_RECORD_DELETED;
769 }
770
make_row(PFS_thread * pfs_thread,PFS_events_statements * statement)771 void table_events_statements_current::make_row(PFS_thread *pfs_thread,
772 PFS_events_statements *statement)
773 {
774 sql_digest_storage digest;
775 pfs_optimistic_state lock;
776 pfs_optimistic_state stmt_lock;
777
778 digest.reset(m_token_array, MAX_DIGEST_STORAGE_SIZE);
779 /* Protect this reader against thread termination. */
780 pfs_thread->m_lock.begin_optimistic_lock(&lock);
781 /* Protect this reader against writing on statement information. */
782 pfs_thread->m_stmt_lock.begin_optimistic_lock(&stmt_lock);
783
784 table_events_statements_common::make_row_part_1(statement, &digest);
785
786 if (!pfs_thread->m_stmt_lock.end_optimistic_lock(&stmt_lock) ||
787 !pfs_thread->m_lock.end_optimistic_lock(&lock))
788 {
789 m_row_exists= false;
790 return;
791 }
792 table_events_statements_common::make_row_part_2(&digest);
793 return;
794 }
795
delete_all_rows(void)796 int table_events_statements_current::delete_all_rows(void)
797 {
798 reset_events_statements_current();
799 return 0;
800 }
801
802 ha_rows
get_row_count(void)803 table_events_statements_current::get_row_count(void)
804 {
805 return global_thread_container.get_row_count() * statement_stack_max;
806 }
807
create(void)808 PFS_engine_table* table_events_statements_history::create(void)
809 {
810 return new table_events_statements_history();
811 }
812
table_events_statements_history()813 table_events_statements_history::table_events_statements_history()
814 : table_events_statements_common(&m_share, &m_pos),
815 m_pos(), m_next_pos()
816 {}
817
reset_position(void)818 void table_events_statements_history::reset_position(void)
819 {
820 m_pos.reset();
821 m_next_pos.reset();
822 }
823
rnd_init(bool scan)824 int table_events_statements_history::rnd_init(bool scan)
825 {
826 m_normalizer= time_normalizer::get(statement_timer);
827 return 0;
828 }
829
rnd_next(void)830 int table_events_statements_history::rnd_next(void)
831 {
832 PFS_thread *pfs_thread;
833 PFS_events_statements *statement;
834 bool has_more_thread= true;
835
836 if (events_statements_history_per_thread == 0)
837 return HA_ERR_END_OF_FILE;
838
839 for (m_pos.set_at(&m_next_pos);
840 has_more_thread;
841 m_pos.next_thread())
842 {
843 pfs_thread= global_thread_container.get(m_pos.m_index_1, & has_more_thread);
844 if (pfs_thread != NULL)
845 {
846 if (m_pos.m_index_2 >= events_statements_history_per_thread)
847 {
848 /* This thread does not have more (full) history */
849 continue;
850 }
851
852 if ( ! pfs_thread->m_statements_history_full &&
853 (m_pos.m_index_2 >= pfs_thread->m_statements_history_index))
854 {
855 /* This thread does not have more (not full) history */
856 continue;
857 }
858
859 statement= &pfs_thread->m_statements_history[m_pos.m_index_2];
860
861 if (statement->m_class != NULL)
862 {
863 make_row(pfs_thread, statement);
864 /* Next iteration, look for the next history in this thread */
865 m_next_pos.set_after(&m_pos);
866 return 0;
867 }
868 }
869 }
870
871 return HA_ERR_END_OF_FILE;
872 }
873
rnd_pos(const void * pos)874 int table_events_statements_history::rnd_pos(const void *pos)
875 {
876 PFS_thread *pfs_thread;
877 PFS_events_statements *statement;
878
879 assert(events_statements_history_per_thread != 0);
880 set_position(pos);
881
882 pfs_thread= global_thread_container.get(m_pos.m_index_1);
883 if (pfs_thread != NULL)
884 {
885 assert(m_pos.m_index_2 < events_statements_history_per_thread);
886
887 if ( ! pfs_thread->m_statements_history_full &&
888 (m_pos.m_index_2 >= pfs_thread->m_statements_history_index))
889 return HA_ERR_RECORD_DELETED;
890
891 statement= &pfs_thread->m_statements_history[m_pos.m_index_2];
892 if (statement->m_class != NULL)
893 {
894 make_row(pfs_thread, statement);
895 return 0;
896 }
897 }
898
899 return HA_ERR_RECORD_DELETED;
900 }
901
make_row(PFS_thread * pfs_thread,PFS_events_statements * statement)902 void table_events_statements_history::make_row(PFS_thread *pfs_thread,
903 PFS_events_statements *statement)
904 {
905 sql_digest_storage digest;
906 pfs_optimistic_state lock;
907
908 digest.reset(m_token_array, MAX_DIGEST_STORAGE_SIZE);
909 /* Protect this reader against thread termination. */
910 pfs_thread->m_lock.begin_optimistic_lock(&lock);
911
912 table_events_statements_common::make_row_part_1(statement, &digest);
913
914 if (!pfs_thread->m_lock.end_optimistic_lock(&lock))
915 {
916 m_row_exists= false;
917 return;
918 }
919 table_events_statements_common::make_row_part_2(&digest);
920 return;
921 }
922
923
delete_all_rows(void)924 int table_events_statements_history::delete_all_rows(void)
925 {
926 reset_events_statements_history();
927 return 0;
928 }
929
930 ha_rows
get_row_count(void)931 table_events_statements_history::get_row_count(void)
932 {
933 return events_statements_history_per_thread * global_thread_container.get_row_count();
934 }
935
create(void)936 PFS_engine_table* table_events_statements_history_long::create(void)
937 {
938 return new table_events_statements_history_long();
939 }
940
table_events_statements_history_long()941 table_events_statements_history_long::table_events_statements_history_long()
942 : table_events_statements_common(&m_share, &m_pos),
943 m_pos(0), m_next_pos(0)
944 {}
945
reset_position(void)946 void table_events_statements_history_long::reset_position(void)
947 {
948 m_pos.m_index= 0;
949 m_next_pos.m_index= 0;
950 }
951
rnd_init(bool scan)952 int table_events_statements_history_long::rnd_init(bool scan)
953 {
954 m_normalizer= time_normalizer::get(statement_timer);
955 return 0;
956 }
957
rnd_next(void)958 int table_events_statements_history_long::rnd_next(void)
959 {
960 PFS_events_statements *statement;
961 uint limit;
962
963 if (events_statements_history_long_size == 0)
964 return HA_ERR_END_OF_FILE;
965
966 if (events_statements_history_long_full)
967 limit= events_statements_history_long_size;
968 else
969 limit= events_statements_history_long_index.m_u32 % events_statements_history_long_size;
970
971 for (m_pos.set_at(&m_next_pos); m_pos.m_index < limit; m_pos.next())
972 {
973 statement= &events_statements_history_long_array[m_pos.m_index];
974
975 if (statement->m_class != NULL)
976 {
977 make_row(statement);
978 /* Next iteration, look for the next entry */
979 m_next_pos.set_after(&m_pos);
980 return 0;
981 }
982 }
983
984 return HA_ERR_END_OF_FILE;
985 }
986
rnd_pos(const void * pos)987 int table_events_statements_history_long::rnd_pos(const void *pos)
988 {
989 PFS_events_statements *statement;
990 uint limit;
991
992 if (events_statements_history_long_size == 0)
993 return HA_ERR_RECORD_DELETED;
994
995 set_position(pos);
996
997 if (events_statements_history_long_full)
998 limit= events_statements_history_long_size;
999 else
1000 limit= events_statements_history_long_index.m_u32 % events_statements_history_long_size;
1001
1002 if (m_pos.m_index >= limit)
1003 return HA_ERR_RECORD_DELETED;
1004
1005 statement= &events_statements_history_long_array[m_pos.m_index];
1006
1007 if (statement->m_class == NULL)
1008 return HA_ERR_RECORD_DELETED;
1009
1010 make_row(statement);
1011 return 0;
1012 }
1013
make_row(PFS_events_statements * statement)1014 void table_events_statements_history_long::make_row(PFS_events_statements *statement)
1015 {
1016 sql_digest_storage digest;
1017
1018 digest.reset(m_token_array, MAX_DIGEST_STORAGE_SIZE);
1019 table_events_statements_common::make_row_part_1(statement, &digest);
1020
1021 table_events_statements_common::make_row_part_2(&digest);
1022 return;
1023 }
1024
delete_all_rows(void)1025 int table_events_statements_history_long::delete_all_rows(void)
1026 {
1027 reset_events_statements_history_long();
1028 return 0;
1029 }
1030
1031 ha_rows
get_row_count(void)1032 table_events_statements_history_long::get_row_count(void)
1033 {
1034 return events_statements_history_long_size;
1035 }
1036
1037