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