1 /* Copyright (c) 2008, 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/pfs_engine_table.cc
25   Performance schema tables (implementation).
26 */
27 
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "hostname.h" /* For Host_entry */
31 #include "pfs_engine_table.h"
32 #include "pfs_buffer_container.h"
33 
34 #include "table_events_waits.h"
35 #include "table_setup_actors.h"
36 #include "table_setup_consumers.h"
37 #include "table_setup_instruments.h"
38 #include "table_setup_objects.h"
39 #include "table_setup_timers.h"
40 #include "table_performance_timers.h"
41 #include "table_events_waits_summary.h"
42 #include "table_ews_by_thread_by_event_name.h"
43 #include "table_ews_global_by_event_name.h"
44 #include "table_host_cache.h"
45 #include "table_os_global_by_type.h"
46 #include "table_sync_instances.h"
47 #include "table_file_instances.h"
48 #include "table_file_summary_by_instance.h"
49 #include "table_file_summary_by_event_name.h"
50 #include "table_threads.h"
51 
52 #include "table_ews_by_host_by_event_name.h"
53 #include "table_ews_by_user_by_event_name.h"
54 #include "table_ews_by_account_by_event_name.h"
55 #include "table_tiws_by_index_usage.h"
56 #include "table_tiws_by_table.h"
57 #include "table_tlws_by_table.h"
58 
59 #include "table_events_stages.h"
60 #include "table_esgs_by_thread_by_event_name.h"
61 #include "table_esgs_by_host_by_event_name.h"
62 #include "table_esgs_by_user_by_event_name.h"
63 #include "table_esgs_by_account_by_event_name.h"
64 #include "table_esgs_global_by_event_name.h"
65 
66 #include "table_events_statements.h"
67 #include "table_esms_by_thread_by_event_name.h"
68 #include "table_esms_by_host_by_event_name.h"
69 #include "table_esms_by_user_by_event_name.h"
70 #include "table_esms_by_account_by_event_name.h"
71 #include "table_esms_global_by_event_name.h"
72 #include "table_esms_by_digest.h"
73 #include "table_esms_by_program.h"
74 
75 #include "table_events_transactions.h"
76 #include "table_ets_by_thread_by_event_name.h"
77 #include "table_ets_by_host_by_event_name.h"
78 #include "table_ets_by_user_by_event_name.h"
79 #include "table_ets_by_account_by_event_name.h"
80 #include "table_ets_global_by_event_name.h"
81 
82 #include "table_users.h"
83 #include "table_accounts.h"
84 #include "table_hosts.h"
85 
86 #include "table_socket_instances.h"
87 #include "table_socket_summary_by_instance.h"
88 #include "table_socket_summary_by_event_name.h"
89 #include "table_session_connect_attrs.h"
90 #include "table_session_account_connect_attrs.h"
91 #include "table_mems_global_by_event_name.h"
92 #include "table_mems_by_account_by_event_name.h"
93 #include "table_mems_by_host_by_event_name.h"
94 #include "table_mems_by_thread_by_event_name.h"
95 #include "table_mems_by_user_by_event_name.h"
96 
97 /* For replication related perfschema tables. */
98 #include "table_replication_connection_configuration.h"
99 #include "table_replication_group_members.h"
100 #include "table_replication_connection_status.h"
101 #include "table_replication_applier_configuration.h"
102 #include "table_replication_applier_status.h"
103 #include "table_replication_applier_status_by_coordinator.h"
104 #include "table_replication_applier_status_by_worker.h"
105 #include "table_replication_group_member_stats.h"
106 
107 #include "table_prepared_stmt_instances.h"
108 
109 #include "table_md_locks.h"
110 #include "table_table_handles.h"
111 
112 #include "table_uvar_by_thread.h"
113 
114 #include "table_status_by_account.h"
115 #include "table_status_by_host.h"
116 #include "table_status_by_thread.h"
117 #include "table_status_by_user.h"
118 #include "table_global_status.h"
119 #include "table_session_status.h"
120 
121 #include "table_variables_by_thread.h"
122 #include "table_global_variables.h"
123 #include "table_session_variables.h"
124 
125 /* For show status */
126 #include "pfs_column_values.h"
127 #include "pfs_instr_class.h"
128 #include "pfs_instr.h"
129 #include "pfs_setup_actor.h"
130 #include "pfs_setup_object.h"
131 #include "pfs_global.h"
132 #include "pfs_digest.h"
133 
134 #include "sql_base.h"                           // close_thread_tables
135 #include "lock.h"                               // MYSQL_LOCK_IGNORE_TIMEOUT
136 #include "log.h"
137 
138 /**
139   @addtogroup Performance_schema_engine
140   @{
141 */
142 
initialize(void)143 bool PFS_table_context::initialize(void)
144 {
145   if (m_restore)
146   {
147     /* Restore context from TLS. */
148     PFS_table_context *context= static_cast<PFS_table_context *>(my_get_thread_local(m_thr_key));
149     assert(context != NULL);
150 
151     if(context)
152     {
153       m_last_version= context->m_current_version;
154       m_map= context->m_map;
155       assert(m_map_size == context->m_map_size);
156       m_map_size= context->m_map_size;
157       m_word_size= context->m_word_size;
158     }
159   }
160   else
161   {
162     /* Check that TLS is not in use. */
163     PFS_table_context *context= static_cast<PFS_table_context *>(my_get_thread_local(m_thr_key));
164     //assert(context == NULL);
165 
166     context= this;
167 
168     /* Initialize a new context, store in TLS. */
169     m_last_version= m_current_version;
170     m_map= NULL;
171     m_word_size= sizeof(ulong) * 8;
172 
173     /* Allocate a bitmap to record which threads are materialized. */
174     if (m_map_size > 0)
175     {
176       THD *thd= current_thd;
177       ulong words= m_map_size / m_word_size + (m_map_size % m_word_size > 0);
178       m_map= (ulong *)thd->mem_calloc(words * m_word_size);
179     }
180 
181     /* Write to TLS. */
182     my_set_thread_local(m_thr_key, static_cast<void *>(context));
183   }
184 
185   m_initialized= (m_map_size > 0) ? (m_map != NULL) : true;
186 
187   return m_initialized;
188 }
189 
190 /* Constructor for global or single thread tables, map size = 0.  */
PFS_table_context(ulonglong current_version,bool restore,thread_local_key_t key)191 PFS_table_context::PFS_table_context(ulonglong current_version, bool restore, thread_local_key_t key) :
192                    m_thr_key(key), m_current_version(current_version), m_last_version(0),
193                    m_map(NULL), m_map_size(0), m_word_size(sizeof(ulong)),
194                    m_restore(restore), m_initialized(false), m_last_item(0)
195 {
196   initialize();
197 }
198 
199 /* Constructor for by-thread or aggregate tables, map size = max thread/user/host/account. */
PFS_table_context(ulonglong current_version,ulong map_size,bool restore,thread_local_key_t key)200 PFS_table_context::PFS_table_context(ulonglong current_version, ulong map_size, bool restore, thread_local_key_t key) :
201                    m_thr_key(key), m_current_version(current_version), m_last_version(0),
202                    m_map(NULL), m_map_size(map_size), m_word_size(sizeof(ulong)),
203                    m_restore(restore), m_initialized(false), m_last_item(0)
204 {
205   initialize();
206 }
207 
~PFS_table_context(void)208 PFS_table_context::~PFS_table_context(void)
209 {
210   /* Clear TLS after final use. */ // TODO: How is that determined?
211 //  if (m_restore)
212 //  {
213 //    my_set_thread_local(m_thr_key, NULL);
214 //  }
215 }
216 
set_item(ulong n)217 void PFS_table_context::set_item(ulong n)
218 {
219   if (n == m_last_item)
220     return;
221   ulong word= n / m_word_size;
222   ulong bit= n % m_word_size;
223   m_map[word] |= (1 << bit);
224   m_last_item= n;
225 }
226 
is_item_set(ulong n)227 bool PFS_table_context::is_item_set(ulong n)
228 {
229   ulong word= n / m_word_size;
230   ulong bit= n % m_word_size;
231   return (m_map[word] & (1 << bit));
232 }
233 
234 
235 static PFS_engine_table_share *all_shares[]=
236 {
237   &table_cond_instances::m_share,
238   &table_events_waits_current::m_share,
239   &table_events_waits_history::m_share,
240   &table_events_waits_history_long::m_share,
241   &table_ews_by_host_by_event_name::m_share,
242   &table_events_waits_summary_by_instance::m_share,
243   &table_ews_by_thread_by_event_name::m_share,
244   &table_ews_by_user_by_event_name::m_share,
245   &table_ews_by_account_by_event_name::m_share,
246   &table_ews_global_by_event_name::m_share,
247   &table_file_instances::m_share,
248   &table_file_summary_by_event_name::m_share,
249   &table_file_summary_by_instance::m_share,
250   &table_host_cache::m_share,
251   &table_mutex_instances::m_share,
252   &table_os_global_by_type::m_share,
253   &table_performance_timers::m_share,
254   &table_rwlock_instances::m_share,
255   &table_setup_actors::m_share,
256   &table_setup_consumers::m_share,
257   &table_setup_instruments::m_share,
258   &table_setup_objects::m_share,
259   &table_setup_timers::m_share,
260   &table_tiws_by_index_usage::m_share,
261   &table_tiws_by_table::m_share,
262   &table_tlws_by_table::m_share,
263   &table_threads::m_share,
264 
265   &table_events_stages_current::m_share,
266   &table_events_stages_history::m_share,
267   &table_events_stages_history_long::m_share,
268   &table_esgs_by_thread_by_event_name::m_share,
269   &table_esgs_by_account_by_event_name::m_share,
270   &table_esgs_by_user_by_event_name::m_share,
271   &table_esgs_by_host_by_event_name::m_share,
272   &table_esgs_global_by_event_name::m_share,
273 
274   &table_events_statements_current::m_share,
275   &table_events_statements_history::m_share,
276   &table_events_statements_history_long::m_share,
277   &table_esms_by_thread_by_event_name::m_share,
278   &table_esms_by_account_by_event_name::m_share,
279   &table_esms_by_user_by_event_name::m_share,
280   &table_esms_by_host_by_event_name::m_share,
281   &table_esms_global_by_event_name::m_share,
282   &table_esms_by_digest::m_share,
283   &table_esms_by_program::m_share,
284 
285   &table_events_transactions_current::m_share,
286   &table_events_transactions_history::m_share,
287   &table_events_transactions_history_long::m_share,
288   &table_ets_by_thread_by_event_name::m_share,
289   &table_ets_by_account_by_event_name::m_share,
290   &table_ets_by_user_by_event_name::m_share,
291   &table_ets_by_host_by_event_name::m_share,
292   &table_ets_global_by_event_name::m_share,
293 
294   &table_users::m_share,
295   &table_accounts::m_share,
296   &table_hosts::m_share,
297 
298   &table_socket_instances::m_share,
299   &table_socket_summary_by_instance::m_share,
300   &table_socket_summary_by_event_name::m_share,
301 
302   &table_session_connect_attrs::m_share,
303   &table_session_account_connect_attrs::m_share,
304 
305   &table_mems_global_by_event_name::m_share,
306   &table_mems_by_account_by_event_name::m_share,
307   &table_mems_by_host_by_event_name::m_share,
308   &table_mems_by_thread_by_event_name::m_share,
309   &table_mems_by_user_by_event_name::m_share,
310   &table_table_handles::m_share,
311   &table_metadata_locks::m_share,
312 
313   &table_replication_connection_configuration::m_share,
314   &table_replication_group_members::m_share,
315   &table_replication_connection_status::m_share,
316   &table_replication_applier_configuration::m_share,
317   &table_replication_applier_status::m_share,
318   &table_replication_applier_status_by_coordinator::m_share,
319   &table_replication_applier_status_by_worker::m_share,
320   &table_replication_group_member_stats::m_share,
321 
322   &table_prepared_stmt_instances::m_share,
323 
324   &table_uvar_by_thread::m_share,
325   &table_status_by_account::m_share,
326   &table_status_by_host::m_share,
327   &table_status_by_thread::m_share,
328   &table_status_by_user::m_share,
329   &table_global_status::m_share,
330   &table_session_status::m_share,
331 
332   &table_variables_by_thread::m_share,
333   &table_global_variables::m_share,
334   &table_session_variables::m_share,
335 
336   NULL
337 };
338 
339 /**
340   Check all the tables structure.
341   @param thd              current thread
342 */
check_all_tables(THD * thd)343 void PFS_engine_table_share::check_all_tables(THD *thd)
344 {
345   PFS_engine_table_share **current;
346 
347   DBUG_EXECUTE_IF("tampered_perfschema_table1",
348                   {
349                     /* Hack SETUP_INSTRUMENT, incompatible change. */
350                     all_shares[20]->m_field_def->count++;
351                   });
352 
353   for (current= &all_shares[0]; (*current) != NULL; current++)
354     (*current)->check_one_table(thd);
355 }
356 
357 /** Error reporting for schema integrity checks. */
358 class PFS_check_intact : public Table_check_intact
359 {
360 protected:
361   virtual void report_error(uint code, const char *fmt, ...);
362 
363 public:
PFS_check_intact()364   PFS_check_intact()
365   {}
366 
~PFS_check_intact()367   ~PFS_check_intact()
368   {}
369 };
370 
report_error(uint code,const char * fmt,...)371 void PFS_check_intact::report_error(uint code, const char *fmt, ...)
372 {
373   va_list args;
374   char buff[MYSQL_ERRMSG_SIZE];
375 
376   va_start(args, fmt);
377   my_vsnprintf(buff, sizeof(buff), fmt, args);
378   va_end(args);
379 
380   /*
381     This is an install/upgrade issue:
382     - do not report it in the user connection, there is none in main(),
383     - report it in the server error log.
384   */
385   sql_print_error("%s", buff);
386 }
387 
388 /**
389   Check integrity of the actual table schema.
390   The actual table schema (.frm) is compared to the expected schema.
391   @param thd              current thread
392 */
check_one_table(THD * thd)393 void PFS_engine_table_share::check_one_table(THD *thd)
394 {
395   TABLE_LIST tables;
396 
397   tables.init_one_table(PERFORMANCE_SCHEMA_str.str,
398                         PERFORMANCE_SCHEMA_str.length,
399                         m_name.str, m_name.length,
400                         m_name.str, TL_READ);
401 
402   /* Work around until Bug#32115 is backported. */
403   LEX dummy_lex;
404   LEX *old_lex= thd->lex;
405   thd->lex= &dummy_lex;
406   lex_start(thd);
407 
408   if (! open_and_lock_tables(thd, &tables, MYSQL_LOCK_IGNORE_TIMEOUT))
409   {
410     PFS_check_intact checker;
411 
412     if (!checker.check(tables.table, m_field_def))
413       m_checked= true;
414     close_thread_tables(thd);
415   }
416   else
417     sql_print_error(ER(ER_WRONG_NATIVE_TABLE_STRUCTURE),
418                     PERFORMANCE_SCHEMA_str.str, m_name.str);
419 
420   lex_end(&dummy_lex);
421   thd->lex= old_lex;
422 }
423 
424 /** Initialize all the table share locks. */
init_all_locks(void)425 void PFS_engine_table_share::init_all_locks(void)
426 {
427   PFS_engine_table_share **current;
428 
429   for (current= &all_shares[0]; (*current) != NULL; current++)
430     thr_lock_init((*current)->m_thr_lock_ptr);
431 }
432 
433 /** Delete all the table share locks. */
delete_all_locks(void)434 void PFS_engine_table_share::delete_all_locks(void)
435 {
436   PFS_engine_table_share **current;
437 
438   for (current= &all_shares[0]; (*current) != NULL; current++)
439     thr_lock_delete((*current)->m_thr_lock_ptr);
440 }
441 
get_row_count(void) const442 ha_rows PFS_engine_table_share::get_row_count(void) const
443 {
444   return m_get_row_count();
445 }
446 
write_row(TABLE * table,unsigned char * buf,Field ** fields) const447 int PFS_engine_table_share::write_row(TABLE *table, unsigned char *buf,
448                                       Field **fields) const
449 {
450   my_bitmap_map *org_bitmap;
451 
452   /*
453     Make sure the table structure is as expected before mapping
454     hard wired columns in m_write_row.
455   */
456   if (! m_checked)
457   {
458     return HA_ERR_TABLE_NEEDS_UPGRADE;
459   }
460 
461   if (m_write_row == NULL)
462   {
463     return HA_ERR_WRONG_COMMAND;
464   }
465 
466   /* We internally read from Fields to support the write interface */
467   org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
468   int result= m_write_row(table, buf, fields);
469   dbug_tmp_restore_column_map(table->read_set, org_bitmap);
470 
471   return result;
472 }
473 
compare_table_names(const char * name1,const char * name2)474 static int compare_table_names(const char *name1, const char *name2)
475 {
476   /*
477     The performance schema is implemented as a storage engine, in memory.
478     The current storage engine interface exposed by the server,
479     and in particular handlerton::discover, uses 'FRM' files to describe a
480     table structure, which are later stored on disk, by the server,
481     in ha_create_table_from_engine().
482     Because the table metadata is stored on disk, the table naming rules
483     used by the performance schema then have to comply with the constraints
484     imposed by the disk storage, and in particular with lower_case_table_names.
485     Once the server is changed to be able to discover a table in a storage engine
486     and then open the table without storing a FRM file on disk, this constraint
487     on the performance schema will be lifted, and the naming logic can be relaxed
488     to be simply my_strcasecmp(system_charset_info, name1, name2).
489   */
490   if (lower_case_table_names)
491     return native_strcasecmp(name1, name2);
492   return strcmp(name1, name2);
493 }
494 
495 /**
496   Find a table share by name.
497   @param name             The table name
498   @return table share
499 */
500 const PFS_engine_table_share*
find_engine_table_share(const char * name)501 PFS_engine_table::find_engine_table_share(const char *name)
502 {
503   DBUG_ENTER("PFS_engine_table::find_table_share");
504 
505   PFS_engine_table_share **current;
506 
507   for (current= &all_shares[0]; (*current) != NULL; current++)
508   {
509     if (compare_table_names(name, (*current)->m_name.str) == 0)
510       DBUG_RETURN(*current);
511   }
512 
513   DBUG_RETURN(NULL);
514 }
515 
516 /**
517   Read a table row.
518   @param table            Table handle
519   @param buf              Row buffer
520   @param fields           Table fields
521   @return 0 on success
522 */
read_row(TABLE * table,unsigned char * buf,Field ** fields)523 int PFS_engine_table::read_row(TABLE *table,
524                                unsigned char *buf,
525                                Field **fields)
526 {
527   my_bitmap_map *org_bitmap;
528   Field *f;
529   Field **fields_reset;
530 
531   /*
532     Make sure the table structure is as expected before mapping
533     hard wired columns in read_row_values.
534   */
535   if (! m_share_ptr->m_checked)
536   {
537     return HA_ERR_TABLE_NEEDS_UPGRADE;
538   }
539 
540   /* We must read all columns in case a table is opened for update */
541   bool read_all= !bitmap_is_clear_all(table->write_set);
542 
543   /* We internally write to Fields to support the read interface */
544   org_bitmap= dbug_tmp_use_all_columns(table, table->write_set);
545 
546   /*
547     Some callers of the storage engine interface do not honor the
548     f->is_null() flag, and will attempt to read the data itself.
549     A known offender is mysql_checksum_table().
550     For robustness, reset every field.
551   */
552   for (fields_reset= fields; (f= *fields_reset) ; fields_reset++)
553     f->reset();
554 
555   int result= read_row_values(table, buf, fields, read_all);
556   dbug_tmp_restore_column_map(table->write_set, org_bitmap);
557 
558   return result;
559 }
560 
561 /**
562   Update a table row.
563   @param table            Table handle
564   @param old_buf          old row buffer
565   @param new_buf          new row buffer
566   @param fields           Table fields
567   @return 0 on success
568 */
update_row(TABLE * table,const unsigned char * old_buf,unsigned char * new_buf,Field ** fields)569 int PFS_engine_table::update_row(TABLE *table,
570                                  const unsigned char *old_buf,
571                                  unsigned char *new_buf,
572                                  Field **fields)
573 {
574   my_bitmap_map *org_bitmap;
575 
576   /*
577     Make sure the table structure is as expected before mapping
578     hard wired columns in update_row_values.
579   */
580   if (! m_share_ptr->m_checked)
581   {
582     return HA_ERR_TABLE_NEEDS_UPGRADE;
583   }
584 
585   /* We internally read from Fields to support the write interface */
586   org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
587   int result= update_row_values(table, old_buf, new_buf, fields);
588   dbug_tmp_restore_column_map(table->read_set, org_bitmap);
589 
590   return result;
591 }
592 
delete_row(TABLE * table,const unsigned char * buf,Field ** fields)593 int PFS_engine_table::delete_row(TABLE *table,
594                                  const unsigned char *buf,
595                                  Field **fields)
596 {
597   my_bitmap_map *org_bitmap;
598 
599   /*
600     Make sure the table structure is as expected before mapping
601     hard wired columns in delete_row_values.
602   */
603   if (! m_share_ptr->m_checked)
604   {
605     return HA_ERR_TABLE_NEEDS_UPGRADE;
606   }
607 
608   /* We internally read from Fields to support the delete interface */
609   org_bitmap= dbug_tmp_use_all_columns(table, table->read_set);
610   int result= delete_row_values(table, buf, fields);
611   dbug_tmp_restore_column_map(table->read_set, org_bitmap);
612 
613   return result;
614 }
615 
delete_row_values(TABLE *,const unsigned char *,Field **)616 int PFS_engine_table::delete_row_values(TABLE *,
617                                         const unsigned char *,
618                                         Field **)
619 {
620   return HA_ERR_WRONG_COMMAND;
621 }
622 
623 /**
624   Get the position of the current row.
625   @param [out] ref        position
626 */
get_position(void * ref)627 void PFS_engine_table::get_position(void *ref)
628 {
629   memcpy(ref, m_pos_ptr, m_share_ptr->m_ref_length);
630 }
631 
632 /**
633   Set the table cursor at a given position.
634   @param [in] ref         position
635 */
set_position(const void * ref)636 void PFS_engine_table::set_position(const void *ref)
637 {
638   memcpy(m_pos_ptr, ref, m_share_ptr->m_ref_length);
639 }
640 
641 /**
642   Get the timer normalizer and class type for the current row.
643   @param [in] instr_class    class
644 */
get_normalizer(PFS_instr_class * instr_class)645 void PFS_engine_table::get_normalizer(PFS_instr_class *instr_class)
646 {
647   if (instr_class->m_type != m_class_type)
648   {
649     m_normalizer= time_normalizer::get(*instr_class->m_timer);
650     m_class_type= instr_class->m_type;
651   }
652 }
653 
set_field_long(Field * f,long value)654 void PFS_engine_table::set_field_long(Field *f, long value)
655 {
656   assert(f->real_type() == MYSQL_TYPE_LONG);
657   Field_long *f2= (Field_long*) f;
658   f2->store(value, false);
659 }
660 
set_field_ulong(Field * f,ulong value)661 void PFS_engine_table::set_field_ulong(Field *f, ulong value)
662 {
663   assert(f->real_type() == MYSQL_TYPE_LONG);
664   Field_long *f2= (Field_long*) f;
665   f2->store(value, true);
666 }
667 
set_field_longlong(Field * f,longlong value)668 void PFS_engine_table::set_field_longlong(Field *f, longlong value)
669 {
670   assert(f->real_type() == MYSQL_TYPE_LONGLONG);
671   Field_longlong *f2= (Field_longlong*) f;
672   f2->store(value, false);
673 }
674 
set_field_ulonglong(Field * f,ulonglong value)675 void PFS_engine_table::set_field_ulonglong(Field *f, ulonglong value)
676 {
677   assert(f->real_type() == MYSQL_TYPE_LONGLONG);
678   Field_longlong *f2= (Field_longlong*) f;
679   f2->store(value, true);
680 }
681 
set_field_char_utf8(Field * f,const char * str,uint len)682 void PFS_engine_table::set_field_char_utf8(Field *f, const char* str,
683                                            uint len)
684 {
685   assert(f->real_type() == MYSQL_TYPE_STRING);
686   Field_string *f2= (Field_string*) f;
687   f2->store(str, len, &my_charset_utf8_bin);
688 }
689 
set_field_varchar(Field * f,const CHARSET_INFO * cs,const char * str,uint len)690 void PFS_engine_table::set_field_varchar(Field *f,
691                                          const CHARSET_INFO *cs,
692                                          const char* str,
693                                          uint len)
694 {
695   assert(f->real_type() == MYSQL_TYPE_VARCHAR);
696   Field_varstring *f2= (Field_varstring*) f;
697   f2->store(str, len, cs);
698 }
699 
set_field_varchar_utf8(Field * f,const char * str,uint len)700 void PFS_engine_table::set_field_varchar_utf8(Field *f, const char* str,
701                                               uint len)
702 {
703   assert(f->real_type() == MYSQL_TYPE_VARCHAR);
704   Field_varstring *f2= (Field_varstring*) f;
705   f2->store(str, len, &my_charset_utf8_bin);
706 }
707 
set_field_longtext_utf8(Field * f,const char * str,uint len)708 void PFS_engine_table::set_field_longtext_utf8(Field *f, const char* str,
709                                                uint len)
710 {
711   assert(f->real_type() == MYSQL_TYPE_BLOB);
712   Field_blob *f2= (Field_blob*) f;
713   f2->store(str, len, &my_charset_utf8_bin);
714 }
715 
set_field_blob(Field * f,const char * val,uint len)716 void PFS_engine_table::set_field_blob(Field *f, const char* val,
717                                       uint len)
718 {
719   assert(f->real_type() == MYSQL_TYPE_BLOB);
720   Field_blob *f2= (Field_blob*) f;
721   f2->store(val, len, &my_charset_utf8_bin);
722 }
723 
set_field_enum(Field * f,ulonglong value)724 void PFS_engine_table::set_field_enum(Field *f, ulonglong value)
725 {
726   assert(f->real_type() == MYSQL_TYPE_ENUM);
727   Field_enum *f2= (Field_enum*) f;
728   f2->store_type(value);
729 }
730 
set_field_timestamp(Field * f,ulonglong value)731 void PFS_engine_table::set_field_timestamp(Field *f, ulonglong value)
732 {
733   struct timeval tm;
734   tm.tv_sec= (long)(value / 1000000);
735   tm.tv_usec= (long)(value % 1000000);
736   assert(f->real_type() == MYSQL_TYPE_TIMESTAMP2);
737   Field_timestampf *f2= (Field_timestampf*) f;
738   f2->store_timestamp(& tm);
739 }
740 
set_field_double(Field * f,double value)741 void PFS_engine_table::set_field_double(Field *f, double value)
742 {
743   assert(f->real_type() == MYSQL_TYPE_DOUBLE);
744   Field_double *f2= (Field_double*) f;
745   f2->store(value);
746 }
747 
get_field_enum(Field * f)748 ulonglong PFS_engine_table::get_field_enum(Field *f)
749 {
750   assert(f->real_type() == MYSQL_TYPE_ENUM);
751   Field_enum *f2= (Field_enum*) f;
752   return f2->val_int();
753 }
754 
755 String*
get_field_char_utf8(Field * f,String * val)756 PFS_engine_table::get_field_char_utf8(Field *f, String *val)
757 {
758   assert(f->real_type() == MYSQL_TYPE_STRING);
759   Field_string *f2= (Field_string*) f;
760   val= f2->val_str(NULL, val);
761   return val;
762 }
763 
764 String*
get_field_varchar_utf8(Field * f,String * val)765 PFS_engine_table::get_field_varchar_utf8(Field *f, String *val)
766 {
767   assert(f->real_type() == MYSQL_TYPE_VARCHAR);
768   Field_varstring *f2= (Field_varstring*) f;
769   val= f2->val_str(NULL, val);
770   return val;
771 }
772 
update_row_values(TABLE *,const unsigned char *,unsigned char *,Field **)773 int PFS_engine_table::update_row_values(TABLE *,
774                                         const unsigned char *,
775                                         unsigned char *,
776                                         Field **)
777 {
778   return HA_ERR_WRONG_COMMAND;
779 }
780 
781 /** Implementation of internal ACL checks, for the performance schema. */
782 class PFS_internal_schema_access : public ACL_internal_schema_access
783 {
784 public:
PFS_internal_schema_access()785   PFS_internal_schema_access()
786   {}
787 
~PFS_internal_schema_access()788   ~PFS_internal_schema_access()
789   {}
790 
791   ACL_internal_access_result check(ulong want_access,
792                                    ulong *save_priv) const;
793 
794   const ACL_internal_table_access *lookup(const char *name) const;
795 };
796 
797 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const798 PFS_internal_schema_access::check(ulong want_access,
799                                   ulong *save_priv)  const
800 {
801   const ulong always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL
802     | INDEX_ACL | ALTER_ACL | CREATE_TMP_ACL | EXECUTE_ACL
803     | CREATE_VIEW_ACL | SHOW_VIEW_ACL | CREATE_PROC_ACL | ALTER_PROC_ACL
804     | EVENT_ACL | TRIGGER_ACL ;
805 
806   if (unlikely(want_access & always_forbidden))
807     return ACL_INTERNAL_ACCESS_DENIED;
808 
809   /*
810     Proceed with regular grant tables,
811     to give administrative control to the DBA.
812   */
813   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
814 }
815 
816 const ACL_internal_table_access *
lookup(const char * name) const817 PFS_internal_schema_access::lookup(const char *name) const
818 {
819   const PFS_engine_table_share* share;
820   share= PFS_engine_table::find_engine_table_share(name);
821   if (share)
822     return share->m_acl;
823   /*
824     Do not return NULL, it would mean we are not interested
825     in privilege checks for unknown tables.
826     Instead, return an object that denies every actions,
827     to prevent users for creating their own tables in the
828     performance_schema database schema.
829   */
830   return &pfs_unknown_acl;
831 }
832 
833 PFS_internal_schema_access pfs_internal_access;
834 
initialize_performance_schema_acl(bool bootstrap)835 void initialize_performance_schema_acl(bool bootstrap)
836 {
837   /*
838     ACL is always enforced, even if the performance schema
839     is not enabled (the tables are still visible).
840   */
841   if (! bootstrap)
842   {
843     ACL_internal_schema_registry::register_schema(PERFORMANCE_SCHEMA_str,
844                                                   &pfs_internal_access);
845   }
846 }
847 
allow_drop_table_privilege()848 static bool allow_drop_table_privilege() {
849   /*
850     The same DROP_ACL privilege is used for different statements,
851     in particular:
852     - TRUNCATE TABLE
853     - DROP TABLE
854     - ALTER TABLE
855     Here, we want to prevent DROP / ALTER  while allowing TRUNCATE.
856     Note that we must also allow GRANT to transfer the truncate privilege.
857   */
858   THD *thd= current_thd;
859   if (thd == NULL) {
860     return false;
861   }
862 
863   assert(thd->lex != NULL);
864   if ((thd->lex->sql_command != SQLCOM_TRUNCATE) &&
865       (thd->lex->sql_command != SQLCOM_GRANT)) {
866     return false;
867   }
868 
869   return true;
870 }
871 
872 
873 PFS_readonly_acl pfs_readonly_acl;
874 
875 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const876 PFS_readonly_acl::check(ulong want_access, ulong *save_priv) const
877 {
878   const ulong always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL
879     | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
880     | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL;
881 
882   if (unlikely(want_access & always_forbidden))
883     return ACL_INTERNAL_ACCESS_DENIED;
884 
885   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
886 }
887 
888 
889 PFS_readonly_world_acl pfs_readonly_world_acl;
890 
891 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const892 PFS_readonly_world_acl::check(ulong want_access, ulong *save_priv) const
893 {
894   ACL_internal_access_result res= PFS_readonly_acl::check(want_access, save_priv);
895   if (res == ACL_INTERNAL_ACCESS_CHECK_GRANT)
896   {
897     if (want_access == SELECT_ACL)
898       res= ACL_INTERNAL_ACCESS_GRANTED;
899   }
900   return res;
901 }
902 
903 
904 PFS_truncatable_acl pfs_truncatable_acl;
905 
906 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const907 PFS_truncatable_acl::check(ulong want_access, ulong *save_priv) const
908 {
909   const ulong always_forbidden= INSERT_ACL | UPDATE_ACL | DELETE_ACL
910     | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
911     | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL | LOCK_TABLES_ACL;
912 
913   if (unlikely(want_access & always_forbidden))
914     return ACL_INTERNAL_ACCESS_DENIED;
915 
916   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
917 }
918 
919 
920 PFS_truncatable_world_acl pfs_truncatable_world_acl;
921 
922 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const923 PFS_truncatable_world_acl::check(ulong want_access, ulong *save_priv) const
924 {
925   ACL_internal_access_result res= PFS_truncatable_acl::check(want_access, save_priv);
926   if (res == ACL_INTERNAL_ACCESS_CHECK_GRANT)
927   {
928     if (want_access == DROP_ACL)
929     {
930       if (allow_drop_table_privilege())
931         res= ACL_INTERNAL_ACCESS_GRANTED;
932     }
933     else if (want_access == SELECT_ACL)
934       res= ACL_INTERNAL_ACCESS_GRANTED;
935   }
936   return res;
937 }
938 
939 
940 PFS_updatable_acl pfs_updatable_acl;
941 
942 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const943 PFS_updatable_acl::check(ulong want_access, ulong *save_priv) const
944 {
945   const ulong always_forbidden= INSERT_ACL | DELETE_ACL
946     | /* CREATE_ACL | */ REFERENCES_ACL | INDEX_ACL | ALTER_ACL
947     | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL;
948 
949   if (unlikely(want_access & always_forbidden))
950     return ACL_INTERNAL_ACCESS_DENIED;
951 
952   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
953 }
954 
955 PFS_editable_acl pfs_editable_acl;
956 
957 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const958 PFS_editable_acl::check(ulong want_access, ulong *save_priv) const
959 {
960   const ulong always_forbidden= /* CREATE_ACL | */ REFERENCES_ACL
961     | INDEX_ACL | ALTER_ACL | CREATE_VIEW_ACL | SHOW_VIEW_ACL | TRIGGER_ACL;
962 
963   if (unlikely(want_access & always_forbidden))
964     return ACL_INTERNAL_ACCESS_DENIED;
965 
966   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
967 }
968 
969 PFS_unknown_acl pfs_unknown_acl;
970 
971 ACL_internal_access_result
check(ulong want_access,ulong * save_priv) const972 PFS_unknown_acl::check(ulong want_access, ulong *save_priv) const
973 {
974   const ulong always_forbidden= CREATE_ACL
975     | REFERENCES_ACL | INDEX_ACL | ALTER_ACL
976     | CREATE_VIEW_ACL | TRIGGER_ACL;
977 
978   if (unlikely(want_access & always_forbidden))
979     return ACL_INTERNAL_ACCESS_DENIED;
980 
981   /*
982     There is no point in hiding (by enforcing ACCESS_DENIED for SELECT_ACL
983     on performance_schema.*) tables that do not exist anyway.
984     When SELECT_ACL is granted on performance_schema.* or *.*,
985     SELECT * from performance_schema.wrong_table
986     will fail with a more understandable ER_NO_SUCH_TABLE error,
987     instead of ER_TABLEACCESS_DENIED_ERROR.
988     The same goes for other DML (INSERT_ACL | UPDATE_ACL | DELETE_ACL),
989     for ease of use: error messages will be less surprising.
990   */
991   return ACL_INTERNAL_ACCESS_CHECK_GRANT;
992 }
993 
994 /**
995   SHOW ENGINE PERFORMANCE_SCHEMA STATUS.
996   @param hton               Storage engine handler
997   @param thd                Current thread
998   @param print              Print function
999   @param stat               status to show
1000 */
pfs_show_status(handlerton * hton,THD * thd,stat_print_fn * print,enum ha_stat_type stat)1001 bool pfs_show_status(handlerton *hton, THD *thd,
1002                      stat_print_fn *print, enum ha_stat_type stat)
1003 {
1004   char buf[1024];
1005   uint buflen;
1006   const char *name;
1007   int i;
1008   size_t size;
1009 
1010   DBUG_ENTER("pfs_show_status");
1011 
1012   /*
1013     Note about naming conventions:
1014     - Internal buffers exposed as a table in the performance schema are named
1015     after the table, as in 'events_waits_current'
1016     - Internal buffers not exposed by a table are named with parenthesis,
1017     as in '(pfs_mutex_class)'.
1018   */
1019   if (stat != HA_ENGINE_STATUS)
1020     DBUG_RETURN(false);
1021 
1022   size_t total_memory= 0;
1023 
1024   for (i=0; /* empty */; i++)
1025   {
1026     switch (i){
1027     case 0:
1028       name= "events_waits_current.size";
1029       size= sizeof(PFS_events_waits);
1030       break;
1031     case 1:
1032       name= "events_waits_current.count";
1033       size= WAIT_STACK_SIZE * global_thread_container.get_row_count();
1034       break;
1035     case 2:
1036       name= "events_waits_history.size";
1037       size= sizeof(PFS_events_waits);
1038       break;
1039     case 3:
1040       name= "events_waits_history.count";
1041       size= events_waits_history_per_thread * global_thread_container.get_row_count();
1042       break;
1043     case 4:
1044       name= "events_waits_history.memory";
1045       size= events_waits_history_per_thread * global_thread_container.get_row_count()
1046         * sizeof(PFS_events_waits);
1047       total_memory+= size;
1048       break;
1049     case 5:
1050       name= "events_waits_history_long.size";
1051       size= sizeof(PFS_events_waits);
1052       break;
1053     case 6:
1054       name= "events_waits_history_long.count";
1055       size= events_waits_history_long_size;
1056       break;
1057     case 7:
1058       name= "events_waits_history_long.memory";
1059       size= events_waits_history_long_size * sizeof(PFS_events_waits);
1060       total_memory+= size;
1061       break;
1062     case 8:
1063       name= "(pfs_mutex_class).size";
1064       size= sizeof(PFS_mutex_class);
1065       break;
1066     case 9:
1067       name= "(pfs_mutex_class).count";
1068       size= mutex_class_max;
1069       break;
1070     case 10:
1071       name= "(pfs_mutex_class).memory";
1072       size= mutex_class_max * sizeof(PFS_mutex_class);
1073       total_memory+= size;
1074       break;
1075     case 11:
1076       name= "(pfs_rwlock_class).size";
1077       size= sizeof(PFS_rwlock_class);
1078       break;
1079     case 12:
1080       name= "(pfs_rwlock_class).count";
1081       size= rwlock_class_max;
1082       break;
1083     case 13:
1084       name= "(pfs_rwlock_class).memory";
1085       size= rwlock_class_max * sizeof(PFS_rwlock_class);
1086       total_memory+= size;
1087       break;
1088     case 14:
1089       name= "(pfs_cond_class).size";
1090       size= sizeof(PFS_cond_class);
1091       break;
1092     case 15:
1093       name= "(pfs_cond_class).count";
1094       size= cond_class_max;
1095       break;
1096     case 16:
1097       name= "(pfs_cond_class).memory";
1098       size= cond_class_max * sizeof(PFS_cond_class);
1099       total_memory+= size;
1100       break;
1101     case 17:
1102       name= "(pfs_thread_class).size";
1103       size= sizeof(PFS_thread_class);
1104       break;
1105     case 18:
1106       name= "(pfs_thread_class).count";
1107       size= thread_class_max;
1108       break;
1109     case 19:
1110       name= "(pfs_thread_class).memory";
1111       size= thread_class_max * sizeof(PFS_thread_class);
1112       total_memory+= size;
1113       break;
1114     case 20:
1115       name= "(pfs_file_class).size";
1116       size= sizeof(PFS_file_class);
1117       break;
1118     case 21:
1119       name= "(pfs_file_class).count";
1120       size= file_class_max;
1121       break;
1122     case 22:
1123       name= "(pfs_file_class).memory";
1124       size= file_class_max * sizeof(PFS_file_class);
1125       total_memory+= size;
1126       break;
1127     case 23:
1128       name= "mutex_instances.size";
1129       size= global_mutex_container.get_row_size();
1130       break;
1131     case 24:
1132       name= "mutex_instances.count";
1133       size= global_mutex_container.get_row_count();
1134       break;
1135     case 25:
1136       name= "mutex_instances.memory";
1137       size= global_mutex_container.get_memory();
1138       total_memory+= size;
1139       break;
1140     case 26:
1141       name= "rwlock_instances.size";
1142       size= global_rwlock_container.get_row_size();
1143       break;
1144     case 27:
1145       name= "rwlock_instances.count";
1146       size= global_rwlock_container.get_row_count();
1147       break;
1148     case 28:
1149       name= "rwlock_instances.memory";
1150       size= global_rwlock_container.get_memory();
1151       total_memory+= size;
1152       break;
1153     case 29:
1154       name= "cond_instances.size";
1155       size= global_cond_container.get_row_size();
1156       break;
1157     case 30:
1158       name= "cond_instances.count";
1159       size= global_cond_container.get_row_count();
1160       break;
1161     case 31:
1162       name= "cond_instances.memory";
1163       size= global_cond_container.get_memory();
1164       total_memory+= size;
1165       break;
1166     case 32:
1167       name= "threads.size";
1168       size= global_thread_container.get_row_size();
1169       break;
1170     case 33:
1171       name= "threads.count";
1172       size= global_thread_container.get_row_count();
1173       break;
1174     case 34:
1175       name= "threads.memory";
1176       size= global_thread_container.get_memory();
1177       total_memory+= size;
1178       break;
1179     case 35:
1180       name= "file_instances.size";
1181       size= global_file_container.get_row_size();
1182       break;
1183     case 36:
1184       name= "file_instances.count";
1185       size= global_file_container.get_row_count();
1186       break;
1187     case 37:
1188       name= "file_instances.memory";
1189       size= global_file_container.get_memory();
1190       total_memory+= size;
1191       break;
1192     case 38:
1193       name= "(pfs_file_handle).size";
1194       size= sizeof(PFS_file*);
1195       break;
1196     case 39:
1197       name= "(pfs_file_handle).count";
1198       size= file_handle_max;
1199       break;
1200     case 40:
1201       name= "(pfs_file_handle).memory";
1202       size= file_handle_max * sizeof(PFS_file*);
1203       total_memory+= size;
1204       break;
1205     case 41:
1206       name= "events_waits_summary_by_thread_by_event_name.size";
1207       size= sizeof(PFS_single_stat);
1208       break;
1209     case 42:
1210       name= "events_waits_summary_by_thread_by_event_name.count";
1211       size= global_thread_container.get_row_count() * wait_class_max;
1212       break;
1213     case 43:
1214       name= "events_waits_summary_by_thread_by_event_name.memory";
1215       size= global_thread_container.get_row_count() * wait_class_max * sizeof(PFS_single_stat);
1216       total_memory+= size;
1217       break;
1218     case 44:
1219       name= "(pfs_table_share).size";
1220       size= global_table_share_container.get_row_size();
1221       break;
1222     case 45:
1223       name= "(pfs_table_share).count";
1224       size= global_table_share_container.get_row_count();
1225       break;
1226     case 46:
1227       name= "(pfs_table_share).memory";
1228       size= global_table_share_container.get_memory();
1229       total_memory+= size;
1230       break;
1231     case 47:
1232       name= "(pfs_table).size";
1233       size= global_table_container.get_row_size();
1234       break;
1235     case 48:
1236       name= "(pfs_table).count";
1237       size= global_table_container.get_row_count();
1238       break;
1239     case 49:
1240       name= "(pfs_table).memory";
1241       size= global_table_container.get_memory();
1242       total_memory+= size;
1243       break;
1244     case 50:
1245       name= "setup_actors.size";
1246       size= global_setup_actor_container.get_row_size();
1247       break;
1248     case 51:
1249       name= "setup_actors.count";
1250       size= global_setup_actor_container.get_row_count();
1251       break;
1252     case 52:
1253       name= "setup_actors.memory";
1254       size= global_setup_actor_container.get_memory();
1255       total_memory+= size;
1256       break;
1257     case 53:
1258       name= "setup_objects.size";
1259       size= global_setup_object_container.get_row_size();
1260       break;
1261     case 54:
1262       name= "setup_objects.count";
1263       size= global_setup_object_container.get_row_count();
1264       break;
1265     case 55:
1266       name= "setup_objects.memory";
1267       size= global_setup_object_container.get_memory();
1268       total_memory+= size;
1269       break;
1270     case 56:
1271       name= "(pfs_account).size";
1272       size= global_account_container.get_row_size();
1273       break;
1274     case 57:
1275       name= "(pfs_account).count";
1276       size= global_account_container.get_row_count();
1277       break;
1278     case 58:
1279       name= "(pfs_account).memory";
1280       size= global_account_container.get_memory();
1281       total_memory+= size;
1282       break;
1283     case 59:
1284       name= "events_waits_summary_by_account_by_event_name.size";
1285       size= sizeof(PFS_single_stat);
1286       break;
1287     case 60:
1288       name= "events_waits_summary_by_account_by_event_name.count";
1289       size= global_account_container.get_row_count() * wait_class_max;
1290       break;
1291     case 61:
1292       name= "events_waits_summary_by_account_by_event_name.memory";
1293       size= global_account_container.get_row_count() * wait_class_max * sizeof(PFS_single_stat);
1294       total_memory+= size;
1295       break;
1296     case 62:
1297       name= "events_waits_summary_by_user_by_event_name.size";
1298       size= sizeof(PFS_single_stat);
1299       break;
1300     case 63:
1301       name= "events_waits_summary_by_user_by_event_name.count";
1302       size= global_user_container.get_row_count() * wait_class_max;
1303       break;
1304     case 64:
1305       name= "events_waits_summary_by_user_by_event_name.memory";
1306       size= global_user_container.get_row_count() * wait_class_max * sizeof(PFS_single_stat);
1307       total_memory+= size;
1308       break;
1309     case 65:
1310       name= "events_waits_summary_by_host_by_event_name.size";
1311       size= sizeof(PFS_single_stat);
1312       break;
1313     case 66:
1314       name= "events_waits_summary_by_host_by_event_name.count";
1315       size= global_host_container.get_row_count() * wait_class_max;
1316       break;
1317     case 67:
1318       name= "events_waits_summary_by_host_by_event_name.memory";
1319       size= global_host_container.get_row_count() * wait_class_max * sizeof(PFS_single_stat);
1320       total_memory+= size;
1321       break;
1322     case 68:
1323       name= "(pfs_user).size";
1324       size= global_user_container.get_row_size();
1325       break;
1326     case 69:
1327       name= "(pfs_user).count";
1328       size= global_user_container.get_row_count();
1329       break;
1330     case 70:
1331       name= "(pfs_user).memory";
1332       size= global_user_container.get_memory();
1333       total_memory+= size;
1334       break;
1335     case 71:
1336       name= "(pfs_host).size";
1337       size= global_host_container.get_row_size();
1338       break;
1339     case 72:
1340       name= "(pfs_host).count";
1341       size= global_host_container.get_row_count();
1342       break;
1343     case 73:
1344       name= "(pfs_host).memory";
1345       size= global_host_container.get_memory();
1346       total_memory+= size;
1347       break;
1348     case 74:
1349       name= "(pfs_stage_class).size";
1350       size= sizeof(PFS_stage_class);
1351       break;
1352     case 75:
1353       name= "(pfs_stage_class).count";
1354       size= stage_class_max;
1355       break;
1356     case 76:
1357       name= "(pfs_stage_class).memory";
1358       size= stage_class_max * sizeof(PFS_stage_class);
1359       total_memory+= size;
1360       break;
1361     case 77:
1362       name= "events_stages_history.size";
1363       size= sizeof(PFS_events_stages);
1364       break;
1365     case 78:
1366       name= "events_stages_history.count";
1367       size= events_stages_history_per_thread * global_thread_container.get_row_count();
1368       break;
1369     case 79:
1370       name= "events_stages_history.memory";
1371       size= events_stages_history_per_thread * global_thread_container.get_row_count()
1372         * sizeof(PFS_events_stages);
1373       total_memory+= size;
1374       break;
1375     case 80:
1376       name= "events_stages_history_long.size";
1377       size= sizeof(PFS_events_stages);
1378       break;
1379     case 81:
1380       name= "events_stages_history_long.count";
1381       size= events_stages_history_long_size;
1382       break;
1383     case 82:
1384       name= "events_stages_history_long.memory";
1385       size= events_stages_history_long_size * sizeof(PFS_events_stages);
1386       total_memory+= size;
1387       break;
1388     case 83:
1389       name= "events_stages_summary_by_thread_by_event_name.size";
1390       size= sizeof(PFS_stage_stat);
1391       break;
1392     case 84:
1393       name= "events_stages_summary_by_thread_by_event_name.count";
1394       size= global_thread_container.get_row_count() * stage_class_max;
1395       break;
1396     case 85:
1397       name= "events_stages_summary_by_thread_by_event_name.memory";
1398       size= global_thread_container.get_row_count() * stage_class_max * sizeof(PFS_stage_stat);
1399       total_memory+= size;
1400       break;
1401     case 86:
1402       name= "events_stages_summary_global_by_event_name.size";
1403       size= sizeof(PFS_stage_stat);
1404       break;
1405     case 87:
1406       name= "events_stages_summary_global_by_event_name.count";
1407       size= stage_class_max;
1408       break;
1409     case 88:
1410       name= "events_stages_summary_global_by_event_name.memory";
1411       size= stage_class_max * sizeof(PFS_stage_stat);
1412       total_memory+= size;
1413       break;
1414     case 89:
1415       name= "events_stages_summary_by_account_by_event_name.size";
1416       size= sizeof(PFS_stage_stat);
1417       break;
1418     case 90:
1419       name= "events_stages_summary_by_account_by_event_name.count";
1420       size= global_account_container.get_row_count() * stage_class_max;
1421       break;
1422     case 91:
1423       name= "events_stages_summary_by_account_by_event_name.memory";
1424       size= global_account_container.get_row_count() * stage_class_max * sizeof(PFS_stage_stat);
1425       total_memory+= size;
1426       break;
1427     case 92:
1428       name= "events_stages_summary_by_user_by_event_name.size";
1429       size= sizeof(PFS_stage_stat);
1430       break;
1431     case 93:
1432       name= "events_stages_summary_by_user_by_event_name.count";
1433       size= global_user_container.get_row_count() * stage_class_max;
1434       break;
1435     case 94:
1436       name= "events_stages_summary_by_user_by_event_name.memory";
1437       size= global_user_container.get_row_count() * stage_class_max * sizeof(PFS_stage_stat);
1438       total_memory+= size;
1439       break;
1440     case 95:
1441       name= "events_stages_summary_by_host_by_event_name.size";
1442       size= sizeof(PFS_stage_stat);
1443       break;
1444     case 96:
1445       name= "events_stages_summary_by_host_by_event_name.count";
1446       size= global_host_container.get_row_count() * stage_class_max;
1447       break;
1448     case 97:
1449       name= "events_stages_summary_by_host_by_event_name.memory";
1450       size= global_host_container.get_row_count() * stage_class_max * sizeof(PFS_stage_stat);
1451       total_memory+= size;
1452       break;
1453     case 98:
1454       name= "(pfs_statement_class).size";
1455       size= sizeof(PFS_statement_class);
1456       break;
1457     case 99:
1458       name= "(pfs_statement_class).count";
1459       size= statement_class_max;
1460       break;
1461     case 100:
1462       name= "(pfs_statement_class).memory";
1463       size= statement_class_max * sizeof(PFS_statement_class);
1464       total_memory+= size;
1465       break;
1466     case 101:
1467       name= "events_statements_history.size";
1468       size= sizeof(PFS_events_statements);
1469       break;
1470     case 102:
1471       name= "events_statements_history.count";
1472       size= events_statements_history_per_thread * global_thread_container.get_row_count();
1473       break;
1474     case 103:
1475       name= "events_statements_history.memory";
1476       size= events_statements_history_per_thread * global_thread_container.get_row_count()
1477         * sizeof(PFS_events_statements);
1478       total_memory+= size;
1479       break;
1480     case 104:
1481       name= "events_statements_history_long.size";
1482       size= sizeof(PFS_events_statements);
1483       break;
1484     case 105:
1485       name= "events_statements_history_long.count";
1486       size= events_statements_history_long_size;
1487       break;
1488     case 106:
1489       name= "events_statements_history_long.memory";
1490       size= events_statements_history_long_size * (sizeof(PFS_events_statements));
1491       total_memory+= size;
1492       break;
1493     case 107:
1494       name= "events_statements_summary_by_thread_by_event_name.size";
1495       size= sizeof(PFS_statement_stat);
1496       break;
1497     case 108:
1498       name= "events_statements_summary_by_thread_by_event_name.count";
1499       size= global_thread_container.get_row_count() * statement_class_max;
1500       break;
1501     case 109:
1502       name= "events_statements_summary_by_thread_by_event_name.memory";
1503       size= global_thread_container.get_row_count() * statement_class_max * sizeof(PFS_statement_stat);
1504       total_memory+= size;
1505       break;
1506     case 110:
1507       name= "events_statements_summary_global_by_event_name.size";
1508       size= sizeof(PFS_statement_stat);
1509       break;
1510     case 111:
1511       name= "events_statements_summary_global_by_event_name.count";
1512       size= statement_class_max;
1513       break;
1514     case 112:
1515       name= "events_statements_summary_global_by_event_name.memory";
1516       size= statement_class_max * sizeof(PFS_statement_stat);
1517       total_memory+= size;
1518       break;
1519     case 113:
1520       name= "events_statements_summary_by_account_by_event_name.size";
1521       size= sizeof(PFS_statement_stat);
1522       break;
1523     case 114:
1524       name= "events_statements_summary_by_account_by_event_name.count";
1525       size= global_account_container.get_row_count() * statement_class_max;
1526       break;
1527     case 115:
1528       name= "events_statements_summary_by_account_by_event_name.memory";
1529       size= global_account_container.get_row_count() * statement_class_max * sizeof(PFS_statement_stat);
1530       total_memory+= size;
1531       break;
1532     case 116:
1533       name= "events_statements_summary_by_user_by_event_name.size";
1534       size= sizeof(PFS_statement_stat);
1535       break;
1536     case 117:
1537       name= "events_statements_summary_by_user_by_event_name.count";
1538       size= global_user_container.get_row_count() * statement_class_max;
1539       break;
1540     case 118:
1541       name= "events_statements_summary_by_user_by_event_name.memory";
1542       size= global_user_container.get_row_count() * statement_class_max * sizeof(PFS_statement_stat);
1543       total_memory+= size;
1544       break;
1545     case 119:
1546       name= "events_statements_summary_by_host_by_event_name.size";
1547       size= sizeof(PFS_statement_stat);
1548       break;
1549     case 120:
1550       name= "events_statements_summary_by_host_by_event_name.count";
1551       size= global_host_container.get_row_count() * statement_class_max;
1552       break;
1553     case 121:
1554       name= "events_statements_summary_by_host_by_event_name.memory";
1555       size= global_host_container.get_row_count() * statement_class_max * sizeof(PFS_statement_stat);
1556       total_memory+= size;
1557       break;
1558     case 122:
1559       name= "events_statements_current.size";
1560       size= sizeof(PFS_events_statements);
1561       break;
1562     case 123:
1563       name= "events_statements_current.count";
1564       size= global_thread_container.get_row_count() * statement_stack_max;
1565       break;
1566     case 124:
1567       name= "events_statements_current.memory";
1568       size= global_thread_container.get_row_count() * statement_stack_max * sizeof(PFS_events_statements);
1569       total_memory+= size;
1570       break;
1571     case 125:
1572       name= "(pfs_socket_class).size";
1573       size= sizeof(PFS_socket_class);
1574       break;
1575     case 126:
1576       name= "(pfs_socket_class).count";
1577       size= socket_class_max;
1578       break;
1579     case 127:
1580       name= "(pfs_socket_class).memory";
1581       size= socket_class_max * sizeof(PFS_socket_class);
1582       total_memory+= size;
1583       break;
1584     case 128:
1585       name= "socket_instances.size";
1586       size= global_socket_container.get_row_size();
1587       break;
1588     case 129:
1589       name= "socket_instances.count";
1590       size= global_socket_container.get_row_count();
1591       break;
1592     case 130:
1593       name= "socket_instances.memory";
1594       size= global_socket_container.get_memory();
1595       total_memory+= size;
1596       break;
1597     case 131:
1598       name= "events_statements_summary_by_digest.size";
1599       size= sizeof(PFS_statements_digest_stat);
1600       break;
1601     case 132:
1602       name= "events_statements_summary_by_digest.count";
1603       size= digest_max;
1604       break;
1605     case 133:
1606       name= "events_statements_summary_by_digest.memory";
1607       size= digest_max * (sizeof(PFS_statements_digest_stat));
1608       total_memory+= size;
1609       break;
1610     case 134:
1611       name= "events_statements_summary_by_program.size";
1612       size= global_program_container.get_row_size();
1613       break;
1614     case 135:
1615       name= "events_statements_summary_by_program.count";
1616       size= global_program_container.get_row_count();
1617       break;
1618     case 136:
1619       name= "events_statements_summary_by_program.memory";
1620       size= global_program_container.get_memory();
1621       total_memory+= size;
1622       break;
1623     case 137:
1624       name= "session_connect_attrs.size";
1625       size= global_thread_container.get_row_count();
1626       break;
1627     case 138:
1628       name= "session_connect_attrs.count";
1629       size= session_connect_attrs_size_per_thread;
1630       break;
1631     case 139:
1632       name= "session_connect_attrs.memory";
1633       size= global_thread_container.get_row_count() * session_connect_attrs_size_per_thread;
1634       total_memory+= size;
1635       break;
1636     case 140:
1637       name= "prepared_statements_instances.size";
1638       size= global_prepared_stmt_container.get_row_size();
1639       break;
1640     case 141:
1641       name= "prepared_statements_instances.count";
1642       size= global_prepared_stmt_container.get_row_count();
1643       break;
1644     case 142:
1645       name= "prepared_statements_instances.memory";
1646       size= global_prepared_stmt_container.get_memory();
1647       total_memory+= size;
1648       break;
1649 
1650     case 143:
1651       name= "(account_hash).count";
1652       size= account_hash.count;
1653       break;
1654     case 144:
1655       name= "(account_hash).size";
1656       size= account_hash.size;
1657       break;
1658     case 145:
1659       name= "(digest_hash).count";
1660       size= digest_hash.count;
1661       break;
1662     case 146:
1663       name= "(digest_hash).size";
1664       size= digest_hash.size;
1665       break;
1666     case 147:
1667       name= "(filename_hash).count";
1668       size= filename_hash.count;
1669       break;
1670     case 148:
1671       name= "(filename_hash).size";
1672       size= filename_hash.size;
1673       break;
1674     case 149:
1675       name= "(host_hash).count";
1676       size= host_hash.count;
1677       break;
1678     case 150:
1679       name= "(host_hash).size";
1680       size= host_hash.size;
1681       break;
1682     case 151:
1683       name= "(setup_actor_hash).count";
1684       size= setup_actor_hash.count;
1685       break;
1686     case 152:
1687       name= "(setup_actor_hash).size";
1688       size= setup_actor_hash.size;
1689       break;
1690     case 153:
1691       name= "(setup_object_hash).count";
1692       size= setup_object_hash.count;
1693       break;
1694     case 154:
1695       name= "(setup_object_hash).size";
1696       size= setup_object_hash.size;
1697       break;
1698     case 155:
1699       name= "(table_share_hash).count";
1700       size= table_share_hash.count;
1701       break;
1702     case 156:
1703       name= "(table_share_hash).size";
1704       size= table_share_hash.size;
1705       break;
1706     case 157:
1707       name= "(user_hash).count";
1708       size= user_hash.count;
1709       break;
1710     case 158:
1711       name= "(user_hash).size";
1712       size= user_hash.size;
1713       break;
1714     case 159:
1715       name= "(program_hash).count";
1716       size= program_hash.count;
1717       break;
1718     case 160:
1719       name= "(program_hash).size";
1720       size= program_hash.size;
1721       break;
1722     case 161:
1723       /*
1724         This is not a performance_schema buffer,
1725         the data is maintained in the server,
1726         in hostname_cache.
1727         Print the size only, there are:
1728         - no host_cache.count
1729         - no host_cache.memory
1730       */
1731       name= "host_cache.size";
1732       size= sizeof(Host_entry);
1733       break;
1734 
1735     case 162:
1736       name= "(pfs_memory_class).row_size";
1737       size= sizeof(PFS_memory_class);
1738       break;
1739     case 163:
1740       name= "(pfs_memory_class).row_count";
1741       size= memory_class_max;
1742       break;
1743     case 164:
1744       name= "(pfs_memory_class).memory";
1745       size= memory_class_max * sizeof(PFS_memory_class);
1746       total_memory+= size;
1747       break;
1748 
1749     case 165:
1750       name= "memory_summary_by_thread_by_event_name.row_size";
1751       size= sizeof(PFS_memory_stat);
1752       break;
1753     case 166:
1754       name= "memory_summary_by_thread_by_event_name.row_count";
1755       size= global_thread_container.get_row_count() * memory_class_max;
1756       break;
1757     case 167:
1758       name= "memory_summary_by_thread_by_event_name.memory";
1759       size= global_thread_container.get_row_count() * memory_class_max * sizeof(PFS_memory_stat);
1760       total_memory+= size;
1761       break;
1762     case 168:
1763       name= "memory_summary_global_by_event_name.row_size";
1764       size= sizeof(PFS_memory_stat);
1765       break;
1766     case 169:
1767       name= "memory_summary_global_by_event_name.row_count";
1768       size= memory_class_max;
1769       break;
1770     case 170:
1771       name= "memory_summary_global_by_event_name.memory";
1772       size= memory_class_max * sizeof(PFS_memory_stat);
1773       total_memory+= size;
1774       break;
1775     case 171:
1776       name= "memory_summary_by_account_by_event_name.row_size";
1777       size= sizeof(PFS_memory_stat);
1778       break;
1779     case 172:
1780       name= "memory_summary_by_account_by_event_name.row_count";
1781       size= global_account_container.get_row_count() * memory_class_max;
1782       break;
1783     case 173:
1784       name= "memory_summary_by_account_by_event_name.memory";
1785       size= global_account_container.get_row_count() * memory_class_max * sizeof(PFS_memory_stat);
1786       total_memory+= size;
1787       break;
1788     case 174:
1789       name= "memory_summary_by_user_by_event_name.row_size";
1790       size= sizeof(PFS_memory_stat);
1791       break;
1792     case 175:
1793       name= "memory_summary_by_user_by_event_name.row_count";
1794       size= global_user_container.get_row_count() * memory_class_max;
1795       break;
1796     case 176:
1797       name= "memory_summary_by_user_by_event_name.memory";
1798       size= global_user_container.get_row_count() * memory_class_max * sizeof(PFS_memory_stat);
1799       total_memory+= size;
1800       break;
1801     case 177:
1802       name= "memory_summary_by_host_by_event_name.row_size";
1803       size= sizeof(PFS_memory_stat);
1804       break;
1805     case 178:
1806       name= "memory_summary_by_host_by_event_name.row_count";
1807       size= global_host_container.get_row_count() * memory_class_max;
1808       break;
1809     case 179:
1810       name= "memory_summary_by_host_by_event_name.memory";
1811       size= global_host_container.get_row_count() * memory_class_max * sizeof(PFS_memory_stat);
1812       total_memory+= size;
1813       break;
1814     case 180:
1815       name= "metadata_locks.row_size";
1816       size= global_mdl_container.get_row_size();
1817       break;
1818     case 181:
1819       name= "metadata_locks.row_count";
1820       size= global_mdl_container.get_row_count();
1821       break;
1822     case 182:
1823       name= "metadata_locks.memory";
1824       size= global_mdl_container.get_memory();
1825       total_memory+= size;
1826       break;
1827     case 183:
1828       name= "events_transactions_history.size";
1829       size= sizeof(PFS_events_transactions);
1830       break;
1831     case 184:
1832       name= "events_transactions_history.count";
1833       size= events_transactions_history_per_thread * global_thread_container.get_row_count();
1834       break;
1835     case 185:
1836       name= "events_transactions_history.memory";
1837       size= events_transactions_history_per_thread * global_thread_container.get_row_count()
1838         * sizeof(PFS_events_transactions);
1839       total_memory+= size;
1840       break;
1841     case 186:
1842       name= "events_transactions_history_long.size";
1843       size= sizeof(PFS_events_transactions);
1844       break;
1845     case 187:
1846       name= "events_transactions_history_long.count";
1847       size= events_transactions_history_long_size;
1848       break;
1849     case 188:
1850       name= "events_transactions_history_long.memory";
1851       size= events_transactions_history_long_size * sizeof(PFS_events_transactions);
1852       total_memory+= size;
1853       break;
1854     case 189:
1855       name= "events_transactions_summary_by_thread_by_event_name.size";
1856       size= sizeof(PFS_transaction_stat);
1857       break;
1858     case 190:
1859       name= "events_transactions_summary_by_thread_by_event_name.count";
1860       size= global_thread_container.get_row_count() * transaction_class_max;
1861       break;
1862     case 191:
1863       name= "events_transactions_summary_by_thread_by_event_name.memory";
1864       size= global_thread_container.get_row_count() * transaction_class_max * sizeof(PFS_transaction_stat);
1865       total_memory+= size;
1866       break;
1867     case 192:
1868       name= "events_transactions_summary_by_account_by_event_name.size";
1869       size= sizeof(PFS_transaction_stat);
1870       break;
1871     case 193:
1872       name= "events_transactions_summary_by_account_by_event_name.count";
1873       size= global_account_container.get_row_count() * transaction_class_max;
1874       break;
1875     case 194:
1876       name= "events_transactions_summary_by_account_by_event_name.memory";
1877       size= global_account_container.get_row_count() * transaction_class_max * sizeof(PFS_transaction_stat);
1878       total_memory+= size;
1879       break;
1880     case 195:
1881       name= "events_transactions_summary_by_user_by_event_name.size";
1882       size= sizeof(PFS_transaction_stat);
1883       break;
1884     case 196:
1885       name= "events_transactions_summary_by_user_by_event_name.count";
1886       size= global_user_container.get_row_count() * transaction_class_max;
1887       break;
1888     case 197:
1889       name= "events_transactions_summary_by_user_by_event_name.memory";
1890       size= global_user_container.get_row_count() * transaction_class_max * sizeof(PFS_transaction_stat);
1891       total_memory+= size;
1892       break;
1893     case 198:
1894       name= "events_transactions_summary_by_host_by_event_name.size";
1895       size= sizeof(PFS_transaction_stat);
1896       break;
1897     case 199:
1898       name= "events_transactions_summary_by_host_by_event_name.count";
1899       size= global_host_container.get_row_count() * transaction_class_max;
1900       break;
1901     case 200:
1902       name= "events_transactions_summary_by_host_by_event_name.memory";
1903       size= global_host_container.get_row_count() * transaction_class_max * sizeof(PFS_transaction_stat);
1904       total_memory+= size;
1905       break;
1906     case 201:
1907       name= "table_lock_waits_summary_by_table.size";
1908       size= global_table_share_lock_container.get_row_size();
1909       break;
1910     case 202:
1911       name= "table_lock_waits_summary_by_table.count";
1912       size= global_table_share_lock_container.get_row_count();
1913       break;
1914     case 203:
1915       name= "table_lock_waits_summary_by_table.memory";
1916       size= global_table_share_lock_container.get_memory();
1917       total_memory+= size;
1918       break;
1919     case 204:
1920       name= "table_io_waits_summary_by_index_usage.size";
1921       size= global_table_share_index_container.get_row_size();
1922       break;
1923     case 205:
1924       name= "table_io_waits_summary_by_index_usage.count";
1925       size= global_table_share_index_container.get_row_count();
1926       break;
1927     case 206:
1928       name= "table_io_waits_summary_by_index_usage.memory";
1929       size= global_table_share_index_container.get_memory();
1930       total_memory+= size;
1931       break;
1932     case 207:
1933       name= "(history_long_statements_digest_token_array).count";
1934       size= events_statements_history_long_size;
1935       break;
1936     case 208:
1937       name= "(history_long_statements_digest_token_array).size";
1938       size= pfs_max_digest_length;
1939       break;
1940     case 209:
1941       name= "(history_long_statements_digest_token_array).memory";
1942       size= events_statements_history_long_size * pfs_max_digest_length;
1943       total_memory+= size;
1944       break;
1945     case 210:
1946       name= "(history_statements_digest_token_array).count";
1947       size= global_thread_container.get_row_count() * events_statements_history_per_thread;
1948       break;
1949     case 211:
1950       name= "(history_statements_digest_token_array).size";
1951       size= pfs_max_digest_length;
1952       break;
1953     case 212:
1954       name= "(history_statements_digest_token_array).memory";
1955       size= global_thread_container.get_row_count() * events_statements_history_per_thread * pfs_max_digest_length;
1956       total_memory+= size;
1957       break;
1958     case 213:
1959       name= "(current_statements_digest_token_array).count";
1960       size= global_thread_container.get_row_count() * statement_stack_max;
1961       break;
1962     case 214:
1963       name= "(current_statements_digest_token_array).size";
1964       size= pfs_max_digest_length;
1965       break;
1966     case 215:
1967       name= "(current_statements_digest_token_array).memory";
1968       size= global_thread_container.get_row_count() * statement_stack_max * pfs_max_digest_length;
1969       total_memory+= size;
1970       break;
1971     case 216:
1972       name= "(history_long_statements_text_array).count";
1973       size= events_statements_history_long_size;
1974       break;
1975     case 217:
1976       name= "(history_long_statements_text_array).size";
1977       size= pfs_max_sqltext;
1978       break;
1979     case 218:
1980       name= "(history_long_statements_text_array).memory";
1981       size= events_statements_history_long_size * pfs_max_sqltext;
1982       total_memory+= size;
1983       break;
1984     case 219:
1985       name= "(history_statements_text_array).count";
1986       size= global_thread_container.get_row_count() * events_statements_history_per_thread;
1987       break;
1988     case 220:
1989       name= "(history_statements_text_array).size";
1990       size= pfs_max_sqltext;
1991       break;
1992     case 221:
1993       name= "(history_statements_text_array).memory";
1994       size= global_thread_container.get_row_count() * events_statements_history_per_thread * pfs_max_sqltext;
1995       total_memory+= size;
1996       break;
1997     case 222:
1998       name= "(current_statements_text_array).count";
1999       size= global_thread_container.get_row_count() * statement_stack_max;
2000       break;
2001     case 223:
2002       name= "(current_statements_text_array).size";
2003       size= pfs_max_sqltext;
2004       break;
2005     case 224:
2006       name= "(current_statements_text_array).memory";
2007       size= global_thread_container.get_row_count() * statement_stack_max * pfs_max_sqltext;
2008       total_memory+= size;
2009       break;
2010     case 225:
2011       name= "(statements_digest_token_array).count";
2012       size= digest_max;
2013       break;
2014     case 226:
2015       name= "(statements_digest_token_array).size";
2016       size= pfs_max_digest_length;
2017       break;
2018     case 227:
2019       name= "(statements_digest_token_array).memory";
2020       size= digest_max * pfs_max_digest_length;
2021       total_memory+= size;
2022       break;
2023     /*
2024       This case must be last,
2025       for aggregation in total_memory.
2026     */
2027     case 228:
2028       name= "performance_schema.memory";
2029       size= total_memory;
2030       break;
2031     default:
2032       goto end;
2033       break;
2034     }
2035 
2036     buflen= (uint)(longlong10_to_str(size, buf, 10) - buf);
2037     if (print(thd,
2038               PERFORMANCE_SCHEMA_str.str, PERFORMANCE_SCHEMA_str.length,
2039               name, strlen(name),
2040               buf, buflen))
2041       DBUG_RETURN(true);
2042   }
2043 
2044 end:
2045   DBUG_RETURN(false);
2046 }
2047 
2048 /** @} */
2049 
2050