1 /* Copyright (c) 2008, 2015, 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/pfs_engine_table.cc
25   Performance schema tables (implementation).
26 */
27 
28 #include "my_global.h"
29 #include "my_pthread.h"
30 #include "hostname.h" /* For Host_entry */
31 #include "pfs_engine_table.h"
32 
33 #include "table_events_waits.h"
34 #include "table_setup_actors.h"
35 #include "table_setup_consumers.h"
36 #include "table_setup_instruments.h"
37 #include "table_setup_objects.h"
38 #include "table_setup_timers.h"
39 #include "table_performance_timers.h"
40 #include "table_events_waits_summary.h"
41 #include "table_ews_by_thread_by_event_name.h"
42 #include "table_ews_global_by_event_name.h"
43 #include "table_host_cache.h"
44 #include "table_os_global_by_type.h"
45 #include "table_sync_instances.h"
46 #include "table_file_instances.h"
47 #include "table_file_summary_by_instance.h"
48 #include "table_file_summary_by_event_name.h"
49 #include "table_threads.h"
50 
51 #include "table_ews_by_host_by_event_name.h"
52 #include "table_ews_by_user_by_event_name.h"
53 #include "table_ews_by_account_by_event_name.h"
54 #include "table_tiws_by_index_usage.h"
55 #include "table_tiws_by_table.h"
56 #include "table_tlws_by_table.h"
57 
58 #include "table_events_stages.h"
59 #include "table_esgs_by_thread_by_event_name.h"
60 #include "table_esgs_by_host_by_event_name.h"
61 #include "table_esgs_by_user_by_event_name.h"
62 #include "table_esgs_by_account_by_event_name.h"
63 #include "table_esgs_global_by_event_name.h"
64 
65 #include "table_events_statements.h"
66 #include "table_esms_by_thread_by_event_name.h"
67 #include "table_esms_by_host_by_event_name.h"
68 #include "table_esms_by_user_by_event_name.h"
69 #include "table_esms_by_account_by_event_name.h"
70 #include "table_esms_global_by_event_name.h"
71 #include "table_esms_by_digest.h"
72 
73 #include "table_users.h"
74 #include "table_accounts.h"
75 #include "table_hosts.h"
76 
77 #include "table_socket_instances.h"
78 #include "table_socket_summary_by_instance.h"
79 #include "table_socket_summary_by_event_name.h"
80 #include "table_session_connect_attrs.h"
81 #include "table_session_account_connect_attrs.h"
82 
83 /* For show status */
84 #include "pfs_column_values.h"
85 #include "pfs_instr_class.h"
86 #include "pfs_instr.h"
87 #include "pfs_setup_actor.h"
88 #include "pfs_setup_object.h"
89 #include "pfs_global.h"
90 #include "pfs_digest.h"
91 
92 #include "sql_base.h"                           // close_thread_tables
93 #include "lock.h"                               // MYSQL_LOCK_IGNORE_TIMEOUT
94 
95 /**
96   @addtogroup Performance_schema_engine
97   @{
98 */
99 
100 static PFS_engine_table_share *all_shares[]=
101 {
102   &table_cond_instances::m_share,
103   &table_events_waits_current::m_share,
104   &table_events_waits_history::m_share,
105   &table_events_waits_history_long::m_share,
106   &table_ews_by_host_by_event_name::m_share,
107   &table_events_waits_summary_by_instance::m_share,
108   &table_ews_by_thread_by_event_name::m_share,
109   &table_ews_by_user_by_event_name::m_share,
110   &table_ews_by_account_by_event_name::m_share,
111   &table_ews_global_by_event_name::m_share,
112   &table_file_instances::m_share,
113   &table_file_summary_by_event_name::m_share,
114   &table_file_summary_by_instance::m_share,
115   &table_host_cache::m_share,
116   &table_mutex_instances::m_share,
117   &table_os_global_by_type::m_share,
118   &table_performance_timers::m_share,
119   &table_rwlock_instances::m_share,
120   &table_setup_actors::m_share,
121   &table_setup_consumers::m_share,
122   &table_setup_instruments::m_share,
123   &table_setup_objects::m_share,
124   &table_setup_timers::m_share,
125   &table_tiws_by_index_usage::m_share,
126   &table_tiws_by_table::m_share,
127   &table_tlws_by_table::m_share,
128   &table_threads::m_share,
129 
130   &table_events_stages_current::m_share,
131   &table_events_stages_history::m_share,
132   &table_events_stages_history_long::m_share,
133   &table_esgs_by_thread_by_event_name::m_share,
134   &table_esgs_by_account_by_event_name::m_share,
135   &table_esgs_by_user_by_event_name::m_share,
136   &table_esgs_by_host_by_event_name::m_share,
137   &table_esgs_global_by_event_name::m_share,
138 
139   &table_events_statements_current::m_share,
140   &table_events_statements_history::m_share,
141   &table_events_statements_history_long::m_share,
142   &table_esms_by_thread_by_event_name::m_share,
143   &table_esms_by_account_by_event_name::m_share,
144   &table_esms_by_user_by_event_name::m_share,
145   &table_esms_by_host_by_event_name::m_share,
146   &table_esms_global_by_event_name::m_share,
147   &table_esms_by_digest::m_share,
148 
149   &table_users::m_share,
150   &table_accounts::m_share,
151   &table_hosts::m_share,
152 
153   &table_socket_instances::m_share,
154   &table_socket_summary_by_instance::m_share,
155   &table_socket_summary_by_event_name::m_share,
156   &table_session_connect_attrs::m_share,
157   &table_session_account_connect_attrs::m_share,
158   NULL
159 };
160 
161 /**
162   Check all the tables structure.
163   @param thd              current thread
164 */
check_all_tables(THD * thd)165 void PFS_engine_table_share::check_all_tables(THD *thd)
166 {
167   PFS_engine_table_share **current;
168 
169   DBUG_EXECUTE_IF("tampered_perfschema_table1",
170                   {
171                     /* Hack SETUP_INSTRUMENT, incompatible change. */
172                     all_shares[20]->m_field_def->count++;
173                   });
174 
175   for (current= &all_shares[0]; (*current) != NULL; current++)
176     (*current)->check_one_table(thd);
177 }
178 
179 /** Error reporting for schema integrity checks. */
180 class PFS_check_intact : public Table_check_intact
181 {
182 protected:
183   virtual void report_error(uint code, const char *fmt, ...);
184 
185 public:
PFS_check_intact()186   PFS_check_intact()
187   {}
188 
~PFS_check_intact()189   ~PFS_check_intact()
190   {}
191 };
192 
report_error(uint code,const char * fmt,...)193 void PFS_check_intact::report_error(uint code, const char *fmt, ...)
194 {
195   va_list args;
196   char buff[MYSQL_ERRMSG_SIZE];
197 
198   va_start(args, fmt);
199   my_vsnprintf(buff, sizeof(buff), fmt, args);
200   va_end(args);
201 
202   /*
203     This is an install/upgrade issue:
204     - do not report it in the user connection, there is none in main(),
205     - report it in the server error log.
206   */
207   sql_print_error("%s", buff);
208 }
209 
210 /**
211   Check integrity of the actual table schema.
212   The actual table schema (.frm) is compared to the expected schema.
213   @param thd              current thread
214 */
check_one_table(THD * thd)215 void PFS_engine_table_share::check_one_table(THD *thd)
216 {
217   TABLE_LIST tables;
218 
219   tables.init_one_table(PERFORMANCE_SCHEMA_str.str,
220                         PERFORMANCE_SCHEMA_str.length,
221                         m_name.str, m_name.length,
222                         m_name.str, TL_READ);
223 
224   /* Work around until Bug#32115 is backported. */
225   LEX dummy_lex;
226   LEX *old_lex= thd->lex;
227   thd->lex= &dummy_lex;
228   lex_start(thd);
229 
230   if (! open_and_lock_tables(thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
231   {
232     PFS_check_intact checker;
233 
234     if (!checker.check(tables.table, m_field_def))
235       m_checked= true;
236     close_thread_tables(thd);
237   }
238   else
239     sql_print_error(ER(ER_WRONG_NATIVE_TABLE_STRUCTURE),
240                     PERFORMANCE_SCHEMA_str.str, m_name.str);
241 
242   lex_end(&dummy_lex);
243   thd->lex= old_lex;
244 }
245 
246 /** Initialize all the table share locks. */
init_all_locks(void)247 void PFS_engine_table_share::init_all_locks(void)
248 {
249   PFS_engine_table_share **current;
250 
251   for (current= &all_shares[0]; (*current) != NULL; current++)
252     thr_lock_init((*current)->m_thr_lock_ptr);
253 }
254 
255 /** Delete all the table share locks. */
delete_all_locks(void)256 void PFS_engine_table_share::delete_all_locks(void)
257 {
258   PFS_engine_table_share **current;
259 
260   for (current= &all_shares[0]; (*current) != NULL; current++)
261     thr_lock_delete((*current)->m_thr_lock_ptr);
262 }
263 
get_row_count(void) const264 ha_rows PFS_engine_table_share::get_row_count(void) const
265 {
266   /* If available, count the exact number or records */
267   if (m_get_row_count)
268     return m_get_row_count();
269   /* Otherwise, return an estimate */
270   return m_records;
271 }
272 
write_row(TABLE * table,unsigned char * buf,Field ** fields) const273 int PFS_engine_table_share::write_row(TABLE *table, unsigned char *buf,
274                                       Field **fields) const
275 {
276   my_bitmap_map *org_bitmap;
277 
278   /*
279     Make sure the table structure is as expected before mapping
280     hard wired columns in m_write_row.
281   */
282   if (! m_checked)
283   {
284     return HA_ERR_TABLE_NEEDS_UPGRADE;
285   }
286 
287   if (m_write_row == NULL)
288   {
289     return HA_ERR_WRONG_COMMAND;
290   }
291 
292   /* We internally read from Fields to support the write interface */
293   org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
294   int result= m_write_row(table, buf, fields);
295   dbug_tmp_restore_column_map(table->read_set, org_bitmap);
296 
297   return result;
298 }
299 
compare_table_names(const char * name1,const char * name2)300 static int compare_table_names(const char *name1, const char *name2)
301 {
302   /*
303     The performance schema is implemented as a storage engine, in memory.
304     The current storage engine interface exposed by the server,
305     and in particular handlerton::discover, uses 'FRM' files to describe a
306     table structure, which are later stored on disk, by the server,
307     in ha_create_table_from_engine().
308     Because the table metadata is stored on disk, the table naming rules
309     used by the performance schema then have to comply with the constraints
310     imposed by the disk storage, and in particular with lower_case_table_names.
311     Once the server is changed to be able to discover a table in a storage engine
312     and then open the table without storing a FRM file on disk, this constraint
313     on the performance schema will be lifted, and the naming logic can be relaxed
314     to be simply my_strcasecmp(system_charset_info, name1, name2).
315   */
316   if (lower_case_table_names)
317     return strcasecmp(name1, name2);
318   return strcmp(name1, name2);
319 }
320 
321 /**
322   Find a table share by name.
323   @param name             The table name
324   @return table share
325 */
326 const PFS_engine_table_share*
find_engine_table_share(const char * name)327 PFS_engine_table::find_engine_table_share(const char *name)
328 {
329   DBUG_ENTER("PFS_engine_table::find_table_share");
330 
331   PFS_engine_table_share **current;
332 
333   for (current= &all_shares[0]; (*current) != NULL; current++)
334   {
335     if (compare_table_names(name, (*current)->m_name.str) == 0)
336       DBUG_RETURN(*current);
337   }
338 
339   DBUG_RETURN(NULL);
340 }
341 
342 /**
343   Read a table row.
344   @param table            Table handle
345   @param buf              Row buffer
346   @param fields           Table fields
347   @return 0 on success
348 */
read_row(TABLE * table,unsigned char * buf,Field ** fields)349 int PFS_engine_table::read_row(TABLE *table,
350                                unsigned char *buf,
351                                Field **fields)
352 {
353   my_bitmap_map *org_bitmap;
354   Field *f;
355   Field **fields_reset;
356 
357   /*
358     Make sure the table structure is as expected before mapping
359     hard wired columns in read_row_values.
360   */
361   if (! m_share_ptr->m_checked)
362   {
363     return HA_ERR_TABLE_NEEDS_UPGRADE;
364   }
365 
366   /* We must read all columns in case a table is opened for update */
367   bool read_all= !bitmap_is_clear_all(table->write_set);
368 
369   /* We internally write to Fields to support the read interface */
370   org_bitmap= dbug_tmp_use_all_columns(table, table->write_set);
371 
372   /*
373     Some callers of the storage engine interface do not honor the
374     f->is_null() flag, and will attempt to read the data itself.
375     A known offender is mysql_checksum_table().
376     For robustness, reset every field.
377   */
378   for (fields_reset= fields; (f= *fields_reset) ; fields_reset++)
379     f->reset();
380 
381   int result= read_row_values(table, buf, fields, read_all);
382   dbug_tmp_restore_column_map(table->write_set, org_bitmap);
383 
384   return result;
385 }
386 
387 /**
388   Update a table row.
389   @param table            Table handle
390   @param old_buf          old row buffer
391   @param new_buf          new row buffer
392   @param fields           Table fields
393   @return 0 on success
394 */
update_row(TABLE * table,const unsigned char * old_buf,unsigned char * new_buf,Field ** fields)395 int PFS_engine_table::update_row(TABLE *table,
396                                  const unsigned char *old_buf,
397                                  unsigned char *new_buf,
398                                  Field **fields)
399 {
400   my_bitmap_map *org_bitmap;
401 
402   /*
403     Make sure the table structure is as expected before mapping
404     hard wired columns in update_row_values.
405   */
406   if (! m_share_ptr->m_checked)
407   {
408     return HA_ERR_TABLE_NEEDS_UPGRADE;
409   }
410 
411   /* We internally read from Fields to support the write interface */
412   org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
413   int result= update_row_values(table, old_buf, new_buf, fields);
414   dbug_tmp_restore_column_map(table->read_set, org_bitmap);
415 
416   return result;
417 }
418 
delete_row(TABLE * table,const unsigned char * buf,Field ** fields)419 int PFS_engine_table::delete_row(TABLE *table,
420                                  const unsigned char *buf,
421                                  Field **fields)
422 {
423   my_bitmap_map *org_bitmap;
424 
425   /*
426     Make sure the table structure is as expected before mapping
427     hard wired columns in delete_row_values.
428   */
429   if (! m_share_ptr->m_checked)
430   {
431     return HA_ERR_TABLE_NEEDS_UPGRADE;
432   }
433 
434   /* We internally read from Fields to support the delete interface */
435   org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
436   int result= delete_row_values(table, buf, fields);
437   dbug_tmp_restore_column_map(table->read_set, org_bitmap);
438 
439   return result;
440 }
441 
delete_row_values(TABLE *,const unsigned char *,Field **)442 int PFS_engine_table::delete_row_values(TABLE *,
443                                         const unsigned char *,
444                                         Field **)
445 {
446   return HA_ERR_WRONG_COMMAND;
447 }
448 
449 /**
450   Get the position of the current row.
451   @param [out] ref        position
452 */
get_position(void * ref)453 void PFS_engine_table::get_position(void *ref)
454 {
455   memcpy(ref, m_pos_ptr, m_share_ptr->m_ref_length);
456 }
457 
458 /**
459   Set the table cursor at a given position.
460   @param [in] ref         position
461 */
set_position(const void * ref)462 void PFS_engine_table::set_position(const void *ref)
463 {
464   memcpy(m_pos_ptr, ref, m_share_ptr->m_ref_length);
465 }
466 
467 /**
468   Get the timer normalizer and class type for the current row.
469   @param [in] instr_class    class
470 */
get_normalizer(PFS_instr_class * instr_class)471 void PFS_engine_table::get_normalizer(PFS_instr_class *instr_class)
472 {
473   if (instr_class->m_type != m_class_type)
474   {
475     m_normalizer= time_normalizer::get(*instr_class->m_timer);
476     m_class_type= instr_class->m_type;
477   }
478 }
479 
set_field_ulong(Field * f,ulong value)480 void PFS_engine_table::set_field_ulong(Field *f, ulong value)
481 {
482   DBUG_ASSERT(f->real_type() == MYSQL_TYPE_LONG);
483   Field_long *f2= (Field_long*) f;
484   f2->store(value, true);
485 }
486 
set_field_ulonglong(Field * f,ulonglong value)487 void PFS_engine_table::set_field_ulonglong(Field *f, ulonglong value)
488 {
489   DBUG_ASSERT(f->real_type() == MYSQL_TYPE_LONGLONG);
490   Field_longlong *f2= (Field_longlong*) f;
491   f2->store(value, true);
492 }
493 
set_field_char_utf8(Field * f,const char * str,uint len)494 void PFS_engine_table::set_field_char_utf8(Field *f, const char* str,
495                                            uint len)
496 {
497   DBUG_ASSERT(f->real_type() == MYSQL_TYPE_STRING);
498   Field_string *f2= (Field_string*) f;
499   f2->store(str, len, &my_charset_utf8_bin);
500 }
501 
set_field_varchar_utf8(Field * f,const char * str,uint len)502 void PFS_engine_table::set_field_varchar_utf8(Field *f, const char* str,
503                                               uint len)
504 {
505   DBUG_ASSERT(f->real_type() == MYSQL_TYPE_VARCHAR);
506   Field_varstring *f2= (Field_varstring*) f;
507   f2->store(str, len, &my_charset_utf8_bin);
508 }
509 
set_field_longtext_utf8(Field * f,const char * str,uint len)510 void PFS_engine_table::set_field_longtext_utf8(Field *f, const char* str,
511                                                uint len)
512 {
513   DBUG_ASSERT(f->real_type() == MYSQL_TYPE_BLOB);
514   Field_blob *f2= (Field_blob*) f;
515   f2->store(str, len, &my_charset_utf8_bin);
516 }
517 
set_field_enum(Field * f,ulonglong value)518 void PFS_engine_table::set_field_enum(Field *f, ulonglong value)
519 {
520   DBUG_ASSERT(f->real_type() == MYSQL_TYPE_ENUM);
521   Field_enum *f2= (Field_enum*) f;
522   f2->store_type(value);
523 }
524 
set_field_timestamp(Field * f,ulonglong value)525 void PFS_engine_table::set_field_timestamp(Field *f, ulonglong value)
526 {
527   struct timeval tm;
528   tm.tv_sec= (long)(value / 1000000);
529   tm.tv_usec= (long)(value % 1000000);
530   DBUG_ASSERT(f->real_type() == MYSQL_TYPE_TIMESTAMP2);
531   Field_timestampf *f2= (Field_timestampf*) f;
532   f2->store_timestamp(& tm);
533 }
534 
get_field_enum(Field * f)535 ulonglong PFS_engine_table::get_field_enum(Field *f)
536 {
537   DBUG_ASSERT(f->real_type() == MYSQL_TYPE_ENUM);
538   Field_enum *f2= (Field_enum*) f;
539   return f2->val_int();
540 }
541 
542 String*
get_field_char_utf8(Field * f,String * val)543 PFS_engine_table::get_field_char_utf8(Field *f, String *val)
544 {
545   DBUG_ASSERT(f->real_type() == MYSQL_TYPE_STRING);
546   Field_string *f2= (Field_string*) f;
547   val= f2->val_str(NULL, val);
548   return val;
549 }
550 
551 String*
get_field_varchar_utf8(Field * f,String * val)552 PFS_engine_table::get_field_varchar_utf8(Field *f, String *val)
553 {
554   DBUG_ASSERT(f->real_type() == MYSQL_TYPE_VARCHAR);
555   Field_varstring *f2= (Field_varstring*) f;
556   val= f2->val_str(NULL, val);
557   return val;
558 }
559 
update_row_values(TABLE *,const unsigned char *,unsigned char *,Field **)560 int PFS_engine_table::update_row_values(TABLE *,
561                                         const unsigned char *,
562                                         unsigned char *,
563                                         Field **)
564 {
565   return HA_ERR_WRONG_COMMAND;
566 }
567 
568 /** Implementation of internal ACL checks, for the performance schema. */
569 class PFS_internal_schema_access : public ACL_internal_schema_access
570 {
571 public:
PFS_internal_schema_access()572   PFS_internal_schema_access()
573   {}
574 
~PFS_internal_schema_access()575   ~PFS_internal_schema_access()
576   {}
577 
578   ACL_internal_access_result check(ulong want_access,
579                                    ulong *save_priv) const;
580 
581   const ACL_internal_table_access *lookup(const char *name) const;
582 };
583 
584 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const585 PFS_internal_schema_access::check(ulong want_access,
586                                   ulong *save_priv)  const
587 {
588   const ulong always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL
589     | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | EXECUTE_ACL
590     | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | ALTER_PROC_ACL
591     | EVENT_ACL | TRIGGER_ACL ;
592 
593   if (unlikely(want_access & always_forbidden))
594     return ACL_INTERNAL_ACCESS_DENIED;
595 
596   /*
597     Proceed with regular grant tables,
598     to give administrative control to the DBA.
599   */
600   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
601 }
602 
603 const ACL_internal_table_access *
lookup(const char * name) const604 PFS_internal_schema_access::lookup(const char *name) const
605 {
606   const PFS_engine_table_share* share;
607   share= PFS_engine_table::find_engine_table_share(name);
608   if (share)
609     return share->m_acl;
610   /*
611     Do not return NULL, it would mean we are not interested
612     in privilege checks for unknown tables.
613     Instead, return an object that denies every actions,
614     to prevent users for creating their own tables in the
615     performance_schema database schema.
616   */
617   return &pfs_unknown_acl;
618 }
619 
620 PFS_internal_schema_access pfs_internal_access;
621 
initialize_performance_schema_acl(bool bootstrap)622 void initialize_performance_schema_acl(bool bootstrap)
623 {
624   /*
625     ACL is always enforced, even if the performance schema
626     is not enabled (the tables are still visible).
627   */
628   if (! bootstrap)
629   {
630     ACL_internal_schema_registry::register_schema(&PERFORMANCE_SCHEMA_str,
631                                                   &pfs_internal_access);
632   }
633 }
634 
635 PFS_readonly_acl pfs_readonly_acl;
636 
637 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const638 PFS_readonly_acl::check(ulong want_access, ulong *save_priv) const
639 {
640   const ulong always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL
641     | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
642     | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL;
643 
644   if (unlikely(want_access & always_forbidden))
645     return ACL_INTERNAL_ACCESS_DENIED;
646 
647   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
648 }
649 
650 PFS_truncatable_acl pfs_truncatable_acl;
651 
652 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const653 PFS_truncatable_acl::check(ulong want_access, ulong *save_priv) const
654 {
655   const ulong always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL
656     | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
657     | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL;
658 
659   if (unlikely(want_access & always_forbidden))
660     return ACL_INTERNAL_ACCESS_DENIED;
661 
662   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
663 }
664 
665 PFS_updatable_acl pfs_updatable_acl;
666 
667 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const668 PFS_updatable_acl::check(ulong want_access, ulong *save_priv) const
669 {
670   const ulong always_forbidden= INSERT_ACL | DELETE_ACL
671     | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
672     | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL;
673 
674   if (unlikely(want_access & always_forbidden))
675     return ACL_INTERNAL_ACCESS_DENIED;
676 
677   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
678 }
679 
680 PFS_editable_acl pfs_editable_acl;
681 
682 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const683 PFS_editable_acl::check(ulong want_access, ulong *save_priv) const
684 {
685   const ulong always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL
686     | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL;
687 
688   if (unlikely(want_access & always_forbidden))
689     return ACL_INTERNAL_ACCESS_DENIED;
690 
691   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
692 }
693 
694 PFS_unknown_acl pfs_unknown_acl;
695 
696 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const697 PFS_unknown_acl::check(ulong want_access, ulong *save_priv) const
698 {
699   const ulong always_forbidden= CREATE_ACL
700     | REFERENCES_ACL | INDEX_ACL | ALTER_ACL
701     | CREATE_VIEW_ACL | TRIGGER_ACL;
702 
703   if (unlikely(want_access & always_forbidden))
704     return ACL_INTERNAL_ACCESS_DENIED;
705 
706   /*
707     There is no point in hiding (by enforcing ACCESS_DENIED for SELECT_ACL
708     on performance_schema.*) tables that do not exist anyway.
709     When SELECT_ACL is granted on performance_schema.* or *.*,
710     SELECT * from performance_schema.wrong_table
711     will fail with a more understandable ER_NO_SUCH_TABLE error,
712     instead of ER_TABLEACCESS_DENIED_ERROR.
713     The same goes for other DML (INSERT_ACL | UPDATE_ACL | DELETE_ACL),
714     for ease of use: error messages will be less surprising.
715   */
716   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
717 }
718 
719 /**
720   SHOW ENGINE PERFORMANCE_SCHEMA STATUS.
721   @param hton               Storage engine handler
722   @param thd                Current thread
723   @param print              Print function
724   @param stat               status to show
725 */
pfs_show_status(handlerton * hton,THD * thd,stat_print_fn * print,enum ha_stat_type stat)726 bool pfs_show_status(handlerton *hton, THD *thd,
727                      stat_print_fn *print, enum ha_stat_type stat)
728 {
729   char buf[1024];
730   uint buflen;
731   const char *name;
732   int i;
733   size_t size;
734 
735   DBUG_ENTER("pfs_show_status");
736 
737   /*
738     Note about naming conventions:
739     - Internal buffers exposed as a table in the performance schema are named
740     after the table, as in 'events_waits_current'
741     - Internal buffers not exposed by a table are named with parenthesis,
742     as in '(pfs_mutex_class)'.
743   */
744   if (stat != HA_ENGINE_STATUS)
745     DBUG_RETURN(false);
746 
747   size_t total_memory= 0;
748 
749   for (i=0; /* empty */; i++)
750   {
751     switch (i){
752     case 0:
753       name= "events_waits_current.row_size";
754       size= sizeof(PFS_events_waits);
755       break;
756     case 1:
757       name= "events_waits_current.row_count";
758       size= WAIT_STACK_SIZE * thread_max;
759       break;
760     case 2:
761       name= "events_waits_history.row_size";
762       size= sizeof(PFS_events_waits);
763       break;
764     case 3:
765       name= "events_waits_history.row_count";
766       size= events_waits_history_per_thread * thread_max;
767       break;
768     case 4:
769       name= "events_waits_history.memory";
770       size= events_waits_history_per_thread * thread_max
771         * sizeof(PFS_events_waits);
772       total_memory+= size;
773       break;
774     case 5:
775       name= "events_waits_history_long.row_size";
776       size= sizeof(PFS_events_waits);
777       break;
778     case 6:
779       name= "events_waits_history_long.row_count";
780       size= events_waits_history_long_size;
781       break;
782     case 7:
783       name= "events_waits_history_long.memory";
784       size= events_waits_history_long_size * sizeof(PFS_events_waits);
785       total_memory+= size;
786       break;
787     case 8:
788       name= "(pfs_mutex_class).row_size";
789       size= sizeof(PFS_mutex_class);
790       break;
791     case 9:
792       name= "(pfs_mutex_class).row_count";
793       size= mutex_class_max;
794       break;
795     case 10:
796       name= "(pfs_mutex_class).memory";
797       size= mutex_class_max * sizeof(PFS_mutex_class);
798       total_memory+= size;
799       break;
800     case 11:
801       name= "(pfs_rwlock_class).row_size";
802       size= sizeof(PFS_rwlock_class);
803       break;
804     case 12:
805       name= "(pfs_rwlock_class).row_count";
806       size= rwlock_class_max;
807       break;
808     case 13:
809       name= "(pfs_rwlock_class).memory";
810       size= rwlock_class_max * sizeof(PFS_rwlock_class);
811       total_memory+= size;
812       break;
813     case 14:
814       name= "(pfs_cond_class).row_size";
815       size= sizeof(PFS_cond_class);
816       break;
817     case 15:
818       name= "(pfs_cond_class).row_count";
819       size= cond_class_max;
820       break;
821     case 16:
822       name= "(pfs_cond_class).memory";
823       size= cond_class_max * sizeof(PFS_cond_class);
824       total_memory+= size;
825       break;
826     case 17:
827       name= "(pfs_thread_class).row_size";
828       size= sizeof(PFS_thread_class);
829       break;
830     case 18:
831       name= "(pfs_thread_class).row_count";
832       size= thread_class_max;
833       break;
834     case 19:
835       name= "(pfs_thread_class).memory";
836       size= thread_class_max * sizeof(PFS_thread_class);
837       total_memory+= size;
838       break;
839     case 20:
840       name= "(pfs_file_class).row_size";
841       size= sizeof(PFS_file_class);
842       break;
843     case 21:
844       name= "(pfs_file_class).row_count";
845       size= file_class_max;
846       break;
847     case 22:
848       name= "(pfs_file_class).memory";
849       size= file_class_max * sizeof(PFS_file_class);
850       total_memory+= size;
851       break;
852     case 23:
853       name= "mutex_instances.row_size";
854       size= sizeof(PFS_mutex);
855       break;
856     case 24:
857       name= "mutex_instances.row_count";
858       size= mutex_max;
859       break;
860     case 25:
861       name= "mutex_instances.memory";
862       size= mutex_max * sizeof(PFS_mutex);
863       total_memory+= size;
864       break;
865     case 26:
866       name= "rwlock_instances.row_size";
867       size= sizeof(PFS_rwlock);
868       break;
869     case 27:
870       name= "rwlock_instances.row_count";
871       size= rwlock_max;
872       break;
873     case 28:
874       name= "rwlock_instances.memory";
875       size= rwlock_max * sizeof(PFS_rwlock);
876       total_memory+= size;
877       break;
878     case 29:
879       name= "cond_instances.row_size";
880       size= sizeof(PFS_cond);
881       break;
882     case 30:
883       name= "cond_instances.row_count";
884       size= cond_max;
885       break;
886     case 31:
887       name= "cond_instances.memory";
888       size= cond_max * sizeof(PFS_cond);
889       total_memory+= size;
890       break;
891     case 32:
892       name= "threads.row_size";
893       size= sizeof(PFS_thread);
894       break;
895     case 33:
896       name= "threads.row_count";
897       size= thread_max;
898       break;
899     case 34:
900       name= "threads.memory";
901       size= thread_max * sizeof(PFS_thread);
902       total_memory+= size;
903       break;
904     case 35:
905       name= "file_instances.row_size";
906       size= sizeof(PFS_file);
907       break;
908     case 36:
909       name= "file_instances.row_count";
910       size= file_max;
911       break;
912     case 37:
913       name= "file_instances.memory";
914       size= file_max * sizeof(PFS_file);
915       total_memory+= size;
916       break;
917     case 38:
918       name= "(pfs_file_handle).row_size";
919       size= sizeof(PFS_file*);
920       break;
921     case 39:
922       name= "(pfs_file_handle).row_count";
923       size= file_handle_max;
924       break;
925     case 40:
926       name= "(pfs_file_handle).memory";
927       size= file_handle_max * sizeof(PFS_file*);
928       total_memory+= size;
929       break;
930     case 41:
931       name= "events_waits_summary_by_thread_by_event_name.row_size";
932       size= sizeof(PFS_single_stat);
933       break;
934     case 42:
935       name= "events_waits_summary_by_thread_by_event_name.row_count";
936       size= thread_max * wait_class_max;
937       break;
938     case 43:
939       name= "events_waits_summary_by_thread_by_event_name.memory";
940       size= thread_max * wait_class_max * sizeof(PFS_single_stat);
941       total_memory+= size;
942       break;
943     case 44:
944       name= "(pfs_table_share).row_size";
945       size= sizeof(PFS_table_share);
946       break;
947     case 45:
948       name= "(pfs_table_share).row_count";
949       size= table_share_max;
950       break;
951     case 46:
952       name= "(pfs_table_share).memory";
953       size= table_share_max * sizeof(PFS_table_share);
954       total_memory+= size;
955       break;
956     case 47:
957       name= "(pfs_table).row_size";
958       size= sizeof(PFS_table);
959       break;
960     case 48:
961       name= "(pfs_table).row_count";
962       size= table_max;
963       break;
964     case 49:
965       name= "(pfs_table).memory";
966       size= table_max * sizeof(PFS_table);
967       total_memory+= size;
968       break;
969     case 50:
970       name= "setup_actors.row_size";
971       size= sizeof(PFS_setup_actor);
972       break;
973     case 51:
974       name= "setup_actors.row_count";
975       size= setup_actor_max;
976       break;
977     case 52:
978       name= "setup_actors.memory";
979       size= setup_actor_max * sizeof(PFS_setup_actor);
980       total_memory+= size;
981       break;
982     case 53:
983       name= "setup_objects.row_size";
984       size= sizeof(PFS_setup_object);
985       break;
986     case 54:
987       name= "setup_objects.row_count";
988       size= setup_object_max;
989       break;
990     case 55:
991       name= "setup_objects.memory";
992       size= setup_object_max * sizeof(PFS_setup_object);
993       total_memory+= size;
994       break;
995     case 56:
996       name= "(pfs_account).row_size";
997       size= sizeof(PFS_account);
998       break;
999     case 57:
1000       name= "(pfs_account).row_count";
1001       size= account_max;
1002       break;
1003     case 58:
1004       name= "(pfs_account).memory";
1005       size= account_max * sizeof(PFS_account);
1006       total_memory+= size;
1007       break;
1008     case 59:
1009       name= "events_waits_summary_by_account_by_event_name.row_size";
1010       size= sizeof(PFS_single_stat);
1011       break;
1012     case 60:
1013       name= "events_waits_summary_by_account_by_event_name.row_count";
1014       size= account_max * wait_class_max;
1015       break;
1016     case 61:
1017       name= "events_waits_summary_by_account_by_event_name.memory";
1018       size= account_max * wait_class_max * sizeof(PFS_single_stat);
1019       total_memory+= size;
1020       break;
1021     case 62:
1022       name= "events_waits_summary_by_user_by_event_name.row_size";
1023       size= sizeof(PFS_single_stat);
1024       break;
1025     case 63:
1026       name= "events_waits_summary_by_user_by_event_name.row_count";
1027       size= user_max * wait_class_max;
1028       break;
1029     case 64:
1030       name= "events_waits_summary_by_user_by_event_name.memory";
1031       size= user_max * wait_class_max * sizeof(PFS_single_stat);
1032       total_memory+= size;
1033       break;
1034     case 65:
1035       name= "events_waits_summary_by_host_by_event_name.row_size";
1036       size= sizeof(PFS_single_stat);
1037       break;
1038     case 66:
1039       name= "events_waits_summary_by_host_by_event_name.row_count";
1040       size= host_max * wait_class_max;
1041       break;
1042     case 67:
1043       name= "events_waits_summary_by_host_by_event_name.memory";
1044       size= host_max * wait_class_max * sizeof(PFS_single_stat);
1045       total_memory+= size;
1046       break;
1047     case 68:
1048       name= "(pfs_user).row_size";
1049       size= sizeof(PFS_user);
1050       break;
1051     case 69:
1052       name= "(pfs_user).row_count";
1053       size= user_max;
1054       break;
1055     case 70:
1056       name= "(pfs_user).memory";
1057       size= user_max * sizeof(PFS_user);
1058       total_memory+= size;
1059       break;
1060     case 71:
1061       name= "(pfs_host).row_size";
1062       size= sizeof(PFS_host);
1063       break;
1064     case 72:
1065       name= "(pfs_host).row_count";
1066       size= host_max;
1067       break;
1068     case 73:
1069       name= "(pfs_host).memory";
1070       size= host_max * sizeof(PFS_host);
1071       total_memory+= size;
1072       break;
1073     case 74:
1074       name= "(pfs_stage_class).row_size";
1075       size= sizeof(PFS_stage_class);
1076       break;
1077     case 75:
1078       name= "(pfs_stage_class).row_count";
1079       size= stage_class_max;
1080       break;
1081     case 76:
1082       name= "(pfs_stage_class).memory";
1083       size= stage_class_max * sizeof(PFS_stage_class);
1084       total_memory+= size;
1085       break;
1086     case 77:
1087       name= "events_stages_history.row_size";
1088       size= sizeof(PFS_events_stages);
1089       break;
1090     case 78:
1091       name= "events_stages_history.row_count";
1092       size= events_stages_history_per_thread * thread_max;
1093       break;
1094     case 79:
1095       name= "events_stages_history.memory";
1096       size= events_stages_history_per_thread * thread_max
1097         * sizeof(PFS_events_stages);
1098       total_memory+= size;
1099       break;
1100     case 80:
1101       name= "events_stages_history_long.row_size";
1102       size= sizeof(PFS_events_stages);
1103       break;
1104     case 81:
1105       name= "events_stages_history_long.row_count";
1106       size= events_stages_history_long_size;
1107       break;
1108     case 82:
1109       name= "events_stages_history_long.memory";
1110       size= events_stages_history_long_size * sizeof(PFS_events_stages);
1111       total_memory+= size;
1112       break;
1113     case 83:
1114       name= "events_stages_summary_by_thread_by_event_name.row_size";
1115       size= sizeof(PFS_stage_stat);
1116       break;
1117     case 84:
1118       name= "events_stages_summary_by_thread_by_event_name.row_count";
1119       size= thread_max * stage_class_max;
1120       break;
1121     case 85:
1122       name= "events_stages_summary_by_thread_by_event_name.memory";
1123       size= thread_max * stage_class_max * sizeof(PFS_stage_stat);
1124       total_memory+= size;
1125       break;
1126     case 86:
1127       name= "events_stages_summary_global_by_event_name.row_size";
1128       size= sizeof(PFS_stage_stat);
1129       break;
1130     case 87:
1131       name= "events_stages_summary_global_by_event_name.row_count";
1132       size= stage_class_max;
1133       break;
1134     case 88:
1135       name= "events_stages_summary_global_by_event_name.memory";
1136       size= stage_class_max * sizeof(PFS_stage_stat);
1137       total_memory+= size;
1138       break;
1139     case 89:
1140       name= "events_stages_summary_by_account_by_event_name.row_size";
1141       size= sizeof(PFS_stage_stat);
1142       break;
1143     case 90:
1144       name= "events_stages_summary_by_account_by_event_name.row_count";
1145       size= account_max * stage_class_max;
1146       break;
1147     case 91:
1148       name= "events_stages_summary_by_account_by_event_name.memory";
1149       size= account_max * stage_class_max * sizeof(PFS_stage_stat);
1150       total_memory+= size;
1151       break;
1152     case 92:
1153       name= "events_stages_summary_by_user_by_event_name.row_size";
1154       size= sizeof(PFS_stage_stat);
1155       break;
1156     case 93:
1157       name= "events_stages_summary_by_user_by_event_name.row_count";
1158       size= user_max * stage_class_max;
1159       break;
1160     case 94:
1161       name= "events_stages_summary_by_user_by_event_name.memory";
1162       size= user_max * stage_class_max * sizeof(PFS_stage_stat);
1163       total_memory+= size;
1164       break;
1165     case 95:
1166       name= "events_stages_summary_by_host_by_event_name.row_size";
1167       size= sizeof(PFS_stage_stat);
1168       break;
1169     case 96:
1170       name= "events_stages_summary_by_host_by_event_name.row_count";
1171       size= host_max * stage_class_max;
1172       break;
1173     case 97:
1174       name= "events_stages_summary_by_host_by_event_name.memory";
1175       size= host_max * stage_class_max * sizeof(PFS_stage_stat);
1176       total_memory+= size;
1177       break;
1178     case 98:
1179       name= "(pfs_statement_class).row_size";
1180       size= sizeof(PFS_statement_class);
1181       break;
1182     case 99:
1183       name= "(pfs_statement_class).row_count";
1184       size= statement_class_max;
1185       break;
1186     case 100:
1187       name= "(pfs_statement_class).memory";
1188       size= statement_class_max * sizeof(PFS_statement_class);
1189       total_memory+= size;
1190       break;
1191     case 101:
1192       name= "events_statements_history.row_size";
1193       size= sizeof(PFS_events_statements);
1194       break;
1195     case 102:
1196       name= "events_statements_history.row_count";
1197       size= events_statements_history_per_thread * thread_max;
1198       break;
1199     case 103:
1200       name= "events_statements_history.memory";
1201       size= events_statements_history_per_thread * thread_max
1202         * sizeof(PFS_events_statements);
1203       total_memory+= size;
1204       break;
1205     case 104:
1206       name= "events_statements_history_long.row_size";
1207       size= sizeof(PFS_events_statements);
1208       break;
1209     case 105:
1210       name= "events_statements_history_long.row_count";
1211       size= events_statements_history_long_size;
1212       break;
1213     case 106:
1214       name= "events_statements_history_long.memory";
1215       size= events_statements_history_long_size * sizeof(PFS_events_statements);
1216       total_memory+= size;
1217       break;
1218     case 107:
1219       name= "events_statements_summary_by_thread_by_event_name.row_size";
1220       size= sizeof(PFS_statement_stat);
1221       break;
1222     case 108:
1223       name= "events_statements_summary_by_thread_by_event_name.row_count";
1224       size= thread_max * statement_class_max;
1225       break;
1226     case 109:
1227       name= "events_statements_summary_by_thread_by_event_name.memory";
1228       size= thread_max * statement_class_max * sizeof(PFS_statement_stat);
1229       total_memory+= size;
1230       break;
1231     case 110:
1232       name= "events_statements_summary_global_by_event_name.row_size";
1233       size= sizeof(PFS_statement_stat);
1234       break;
1235     case 111:
1236       name= "events_statements_summary_global_by_event_name.row_count";
1237       size= statement_class_max;
1238       break;
1239     case 112:
1240       name= "events_statements_summary_global_by_event_name.memory";
1241       size= statement_class_max * sizeof(PFS_statement_stat);
1242       total_memory+= size;
1243       break;
1244     case 113:
1245       name= "events_statements_summary_by_account_by_event_name.row_size";
1246       size= sizeof(PFS_statement_stat);
1247       break;
1248     case 114:
1249       name= "events_statements_summary_by_account_by_event_name.row_count";
1250       size= account_max * statement_class_max;
1251       break;
1252     case 115:
1253       name= "events_statements_summary_by_account_by_event_name.memory";
1254       size= account_max * statement_class_max * sizeof(PFS_statement_stat);
1255       total_memory+= size;
1256       break;
1257     case 116:
1258       name= "events_statements_summary_by_user_by_event_name.row_size";
1259       size= sizeof(PFS_statement_stat);
1260       break;
1261     case 117:
1262       name= "events_statements_summary_by_user_by_event_name.row_count";
1263       size= user_max * statement_class_max;
1264       break;
1265     case 118:
1266       name= "events_statements_summary_by_user_by_event_name.memory";
1267       size= user_max * statement_class_max * sizeof(PFS_statement_stat);
1268       total_memory+= size;
1269       break;
1270     case 119:
1271       name= "events_statements_summary_by_host_by_event_name.row_size";
1272       size= sizeof(PFS_statement_stat);
1273       break;
1274     case 120:
1275       name= "events_statements_summary_by_host_by_event_name.row_count";
1276       size= host_max * statement_class_max;
1277       break;
1278     case 121:
1279       name= "events_statements_summary_by_host_by_event_name.memory";
1280       size= host_max * statement_class_max * sizeof(PFS_statement_stat);
1281       total_memory+= size;
1282       break;
1283     case 122:
1284       name= "events_statements_current.row_size";
1285       size= sizeof(PFS_events_statements);
1286       break;
1287     case 123:
1288       name= "events_statements_current.row_count";
1289       size= thread_max * statement_stack_max;
1290       break;
1291     case 124:
1292       name= "events_statements_current.memory";
1293       size= thread_max * statement_stack_max * sizeof(PFS_events_statements);
1294       total_memory+= size;
1295       break;
1296     case 125:
1297       name= "(pfs_socket_class).row_size";
1298       size= sizeof(PFS_socket_class);
1299       break;
1300     case 126:
1301       name= "(pfs_socket_class).row_count";
1302       size= socket_class_max;
1303       break;
1304     case 127:
1305       name= "(pfs_socket_class).memory";
1306       size= socket_class_max * sizeof(PFS_socket_class);
1307       total_memory+= size;
1308       break;
1309     case 128:
1310       name= "socket_instances.row_size";
1311       size= sizeof(PFS_socket);
1312       break;
1313     case 129:
1314       name= "socket_instances.row_count";
1315       size= socket_max;
1316       break;
1317     case 130:
1318       name= "socket_instances.memory";
1319       size= socket_max * sizeof(PFS_socket);
1320       total_memory+= size;
1321       break;
1322     case 131:
1323       name= "events_statements_summary_by_digest.row_size";
1324       size= sizeof(PFS_statements_digest_stat);
1325       break;
1326     case 132:
1327       name= "events_statements_summary_by_digest.row_count";
1328       size= digest_max;
1329       break;
1330     case 133:
1331       name= "events_statements_summary_by_digest.memory";
1332       size= digest_max * sizeof(PFS_statements_digest_stat);
1333       total_memory+= size;
1334       break;
1335     case 134:
1336       name= "session_connect_attrs.row_size";
1337       size= thread_max;
1338       break;
1339     case 135:
1340       name= "session_connect_attrs.row_count";
1341       size= session_connect_attrs_size_per_thread;
1342       break;
1343     case 136:
1344       name= "session_connect_attrs.memory";
1345       size= thread_max * session_connect_attrs_size_per_thread;
1346       total_memory+= size;
1347       break;
1348 
1349     case 137:
1350       name= "(account_hash).count";
1351       size= account_hash.count;
1352       break;
1353     case 138:
1354       name= "(account_hash).size";
1355       size= account_hash.size;
1356       break;
1357     case 139:
1358       name= "(digest_hash).count";
1359       size= digest_hash.count;
1360       break;
1361     case 140:
1362       name= "(digest_hash).size";
1363       size= digest_hash.size;
1364       break;
1365     case 141:
1366       name= "(filename_hash).count";
1367       size= filename_hash.count;
1368       break;
1369     case 142:
1370       name= "(filename_hash).size";
1371       size= filename_hash.size;
1372       break;
1373     case 143:
1374       name= "(host_hash).count";
1375       size= host_hash.count;
1376       break;
1377     case 144:
1378       name= "(host_hash).size";
1379       size= host_hash.size;
1380       break;
1381     case 145:
1382       name= "(setup_actor_hash).count";
1383       size= setup_actor_hash.count;
1384       break;
1385     case 146:
1386       name= "(setup_actor_hash).size";
1387       size= setup_actor_hash.size;
1388       break;
1389     case 147:
1390       name= "(setup_object_hash).count";
1391       size= setup_object_hash.count;
1392       break;
1393     case 148:
1394       name= "(setup_object_hash).size";
1395       size= setup_object_hash.size;
1396       break;
1397     case 149:
1398       name= "(table_share_hash).count";
1399       size= table_share_hash.count;
1400       break;
1401     case 150:
1402       name= "(table_share_hash).size";
1403       size= table_share_hash.size;
1404       break;
1405     case 151:
1406       name= "(user_hash).count";
1407       size= user_hash.count;
1408       break;
1409     case 152:
1410       name= "(user_hash).size";
1411       size= user_hash.size;
1412       break;
1413     case 153:
1414       /*
1415         This is not a performance_schema buffer,
1416         the data is maintained in the server,
1417         in hostname_cache.
1418         Print the size only, there are:
1419         - no host_cache.count
1420         - no host_cache.memory
1421       */
1422       name= "host_cache.size";
1423       size= sizeof(Host_entry);
1424       break;
1425     case 154:
1426       name= "(history_long_statements_digest_token_array).row_count";
1427       size= events_statements_history_long_size;
1428       break;
1429     case 155:
1430       name= "(history_long_statements_digest_token_array).row_size";
1431       size= pfs_max_digest_length;
1432       break;
1433     case 156:
1434       name= "(history_long_statements_digest_token_array).memory";
1435       size= events_statements_history_long_size * pfs_max_digest_length;
1436       total_memory+= size;
1437       break;
1438     case 157:
1439       name= "(history_statements_digest_token_array).row_count";
1440       size= thread_max * events_statements_history_per_thread;
1441       break;
1442     case 158:
1443       name= "(history_statements_digest_token_array).row_size";
1444       size= pfs_max_digest_length;
1445       break;
1446     case 159:
1447       name= "(history_statements_digest_token_array).memory";
1448       size= thread_max * events_statements_history_per_thread * pfs_max_digest_length;
1449       total_memory+= size;
1450       break;
1451     case 160:
1452       name= "(current_statements_digest_token_array).row_count";
1453       size= thread_max * statement_stack_max;
1454       break;
1455     case 161:
1456       name= "(current_statements_digest_token_array).row_size";
1457       size= pfs_max_digest_length;
1458       break;
1459     case 162:
1460       name= "(current_statements_digest_token_array).memory";
1461       size= thread_max * statement_stack_max * pfs_max_digest_length;
1462       total_memory+= size;
1463       break;
1464     case 163:
1465       name= "(statements_digest_token_array).row_count";
1466       size= digest_max;
1467       break;
1468     case 164:
1469       name= "(statements_digest_token_array).row_size";
1470       size= pfs_max_digest_length;
1471       break;
1472     case 165:
1473       name= "(statements_digest_token_array).memory";
1474       size= digest_max * pfs_max_digest_length;
1475       total_memory+= size;
1476       break;
1477 
1478     /*
1479       This case must be last,
1480       for aggregation in total_memory.
1481     */
1482     case 166:
1483       name= "performance_schema.memory";
1484       size= total_memory;
1485       /* This will fail if something is not advertised here */
1486       DBUG_ASSERT(size == pfs_allocated_memory);
1487       break;
1488     default:
1489       goto end;
1490       break;
1491     }
1492 
1493     buflen= longlong10_to_str(size, buf, 10) - buf;
1494     if (print(thd,
1495               PERFORMANCE_SCHEMA_str.str, PERFORMANCE_SCHEMA_str.length,
1496               name, strlen(name),
1497               buf, buflen))
1498       DBUG_RETURN(true);
1499   }
1500 
1501 end:
1502   DBUG_RETURN(false);
1503 }
1504 
1505 /** @} */
1506 
1507