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