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