1 # name : innodb_show_sys_tables.patch
3 # maintainer : Yasufumi
4 # (It is revived from mysql-5.5.6-rc)
6 # Any small change to this file in the main branch
7 # should be done or reviewed by the maintainer!
8 --- a/storage/innobase/dict/dict0load.c
9 +++ b/storage/innobase/dict/dict0load.c
14 -#ifdef FOREIGN_NOT_USED
15 +//#ifdef FOREIGN_NOT_USED
16 /********************************************************************//**
17 This function parses a SYS_FOREIGN record and populate a dict_foreign_t
18 structure with the information from the record. For detail information
23 -#endif /* FOREIGN_NOT_USED */
24 +//#endif /* FOREIGN_NOT_USED */
26 -#ifdef FOREIGN_NOT_USED
27 +//#ifdef FOREIGN_NOT_USED
28 /********************************************************************//**
29 This function parses a SYS_FOREIGN_COLS record and extract necessary
30 information from the record and return to caller.
35 -#endif /* FOREIGN_NOT_USED */
36 +//#endif /* FOREIGN_NOT_USED */
38 /********************************************************************//**
39 Determine the flags of a table described in SYS_TABLES.
40 --- a/storage/innobase/handler/ha_innodb.cc
41 +++ b/storage/innobase/handler/ha_innodb.cc
42 @@ -11950,7 +11950,14 @@
46 -i_s_innodb_cmpmem_reset
47 +i_s_innodb_cmpmem_reset,
48 +i_s_innodb_sys_tables,
49 +i_s_innodb_sys_tablestats,
50 +i_s_innodb_sys_indexes,
51 +i_s_innodb_sys_columns,
52 +i_s_innodb_sys_fields,
53 +i_s_innodb_sys_foreign,
54 +i_s_innodb_sys_foreign_cols
55 mysql_declare_plugin_end;
57 /** @brief Initialize the default value of innodb_commit_concurrency.
58 --- a/storage/innobase/handler/i_s.cc
59 +++ b/storage/innobase/handler/i_s.cc
61 #include <mysql/innodb_priv.h>
64 +#include "btr0pcur.h" /* for file sys_tables related info. */
65 #include "btr0types.h"
66 #include "buf0buddy.h" /* for i_s_cmpmem */
67 #include "buf0buf.h" /* for buf_pool and PAGE_ZIP_MIN_SIZE */
68 +#include "dict0load.h" /* for file sys_tables related info. */
70 #include "dict0types.h"
71 #include "ha_prototypes.h" /* for innobase_convert_name() */
72 @@ -1812,6 +1814,1703 @@
76 +/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_TABLES */
77 +static ST_FIELD_INFO innodb_sys_tables_fields_info[] =
79 +#define SYS_TABLE_ID 0
80 + {STRUCT_FLD(field_name, "TABLE_ID"),
81 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
82 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
83 + STRUCT_FLD(value, 0),
84 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
85 + STRUCT_FLD(old_name, ""),
86 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
88 +#define SYS_TABLE_SCHEMA 1
89 + {STRUCT_FLD(field_name, "SCHEMA"),
90 + STRUCT_FLD(field_length, NAME_LEN + 1),
91 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
92 + STRUCT_FLD(value, 0),
93 + STRUCT_FLD(field_flags, 0),
94 + STRUCT_FLD(old_name, ""),
95 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
97 +#define SYS_TABLE_NAME 2
98 + {STRUCT_FLD(field_name, "NAME"),
99 + STRUCT_FLD(field_length, NAME_LEN + 1),
100 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
101 + STRUCT_FLD(value, 0),
102 + STRUCT_FLD(field_flags, 0),
103 + STRUCT_FLD(old_name, ""),
104 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
106 +#define SYS_TABLE_FLAG 3
107 + {STRUCT_FLD(field_name, "FLAG"),
108 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
109 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
110 + STRUCT_FLD(value, 0),
111 + STRUCT_FLD(field_flags, 0),
112 + STRUCT_FLD(old_name, ""),
113 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
115 +#define SYS_TABLE_NUM_COLUMN 4
116 + {STRUCT_FLD(field_name, "N_COLS"),
117 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
118 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
119 + STRUCT_FLD(value, 0),
120 + STRUCT_FLD(field_flags, 0),
121 + STRUCT_FLD(old_name, ""),
122 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
124 +#define SYS_TABLE_SPACE 5
125 + {STRUCT_FLD(field_name, "SPACE"),
126 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
127 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
128 + STRUCT_FLD(value, 0),
129 + STRUCT_FLD(field_flags, 0),
130 + STRUCT_FLD(old_name, ""),
131 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
133 + END_OF_ST_FIELD_INFO
136 +/**********************************************************************//**
137 +Populate information_schema.innodb_sys_tables table with information
139 +@return 0 on success */
142 +i_s_dict_fill_sys_tables(
143 +/*=====================*/
144 + THD* thd, /*!< in: thread */
145 + dict_table_t* table, /*!< in: table */
146 + TABLE* table_to_fill) /*!< in/out: fill this table */
149 + char buf[NAME_LEN * 2 + 2];
152 + DBUG_ENTER("i_s_dict_fill_sys_tables");
154 + fields = table_to_fill->field;
156 + OK(fields[SYS_TABLE_ID]->store(longlong(table->id), TRUE));
158 + strncpy(buf, table->name, NAME_LEN * 2 + 2);
159 + ptr = strchr(buf, '/');
164 + OK(field_store_string(fields[SYS_TABLE_SCHEMA], buf));
165 + OK(field_store_string(fields[SYS_TABLE_NAME], ptr));
167 + fields[SYS_TABLE_SCHEMA]->set_null();
168 + OK(field_store_string(fields[SYS_TABLE_NAME], buf));
171 + OK(fields[SYS_TABLE_FLAG]->store(table->flags));
173 + OK(fields[SYS_TABLE_NUM_COLUMN]->store(table->n_cols));
175 + OK(fields[SYS_TABLE_SPACE]->store(table->space));
177 + OK(schema_table_store_record(thd, table_to_fill));
181 +/*******************************************************************//**
182 +Function to go through each record in SYS_TABLES table, and fill the
183 +information_schema.innodb_sys_tables table with related table information
184 +@return 0 on success */
187 +i_s_sys_tables_fill_table(
188 +/*======================*/
189 + THD* thd, /*!< in: thread */
190 + TABLE_LIST* tables, /*!< in/out: tables to fill */
191 + COND* cond) /*!< in: condition (not used) */
198 + DBUG_ENTER("i_s_sys_tables_fill_table");
200 + /* deny access to non-superusers */
201 + if (check_global_access(thd, PROCESS_ACL)) {
206 + heap = mem_heap_create(1000);
207 + mutex_enter(&(dict_sys->mutex));
210 + rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
213 + const char* err_msg;
214 + dict_table_t* table_rec;
216 + /* Create and populate a dict_table_t structure with
217 + information from SYS_TABLES row */
218 + err_msg = dict_process_sys_tables_rec(
219 + heap, rec, &table_rec, DICT_TABLE_LOAD_FROM_RECORD);
222 + mutex_exit(&dict_sys->mutex);
225 + i_s_dict_fill_sys_tables(thd, table_rec, tables->table);
227 + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
228 + ER_CANT_FIND_SYSTEM_REC,
232 + /* Since dict_process_sys_tables_rec() is called with
233 + DICT_TABLE_LOAD_FROM_RECORD, the table_rec is created in
234 + dict_process_sys_tables_rec(), we will need to free it */
236 + dict_mem_table_free(table_rec);
239 + mem_heap_empty(heap);
241 + /* Get the next record */
242 + mutex_enter(&dict_sys->mutex);
244 + rec = dict_getnext_system(&pcur, &mtr);
248 + mutex_exit(&dict_sys->mutex);
249 + mem_heap_free(heap);
254 +/*******************************************************************//**
255 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_tables
256 +@return 0 on success */
259 +innodb_sys_tables_init(
260 +/*===================*/
261 + void* p) /*!< in/out: table schema object */
263 + ST_SCHEMA_TABLE* schema;
265 + DBUG_ENTER("innodb_sys_tables_init");
267 + schema = (ST_SCHEMA_TABLE*) p;
269 + schema->fields_info = innodb_sys_tables_fields_info;
270 + schema->fill_table = i_s_sys_tables_fill_table;
275 +UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_tables =
277 + /* the plugin type (a MYSQL_XXX_PLUGIN value) */
279 + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
281 + /* pointer to type-specific plugin descriptor */
283 + STRUCT_FLD(info, &i_s_info),
287 + STRUCT_FLD(name, "INNODB_SYS_TABLES"),
289 + /* plugin author (for SHOW PLUGINS) */
291 + STRUCT_FLD(author, "Percona"),
293 + /* general descriptive text (for SHOW PLUGINS) */
295 + STRUCT_FLD(descr, "InnoDB SYS_TABLES"),
297 + /* the plugin license (PLUGIN_LICENSE_XXX) */
299 + STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
301 + /* the function to invoke when plugin is loaded */
302 + /* int (*)(void*); */
303 + STRUCT_FLD(init, innodb_sys_tables_init),
305 + /* the function to invoke when plugin is unloaded */
306 + /* int (*)(void*); */
307 + STRUCT_FLD(deinit, i_s_common_deinit),
309 + /* plugin version (for SHOW PLUGINS) */
311 + STRUCT_FLD(version, INNODB_VERSION_SHORT),
313 + /* struct st_mysql_show_var* */
314 + STRUCT_FLD(status_vars, NULL),
316 + /* struct st_mysql_sys_var** */
317 + STRUCT_FLD(system_vars, NULL),
319 + /* reserved for dependency checking */
321 + STRUCT_FLD(__reserved1, NULL),
323 + /* flags for plugin */
324 + /* unsigned long */
325 + STRUCT_FLD(flags, 0UL)
328 +/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_TABLESTATS */
329 +static ST_FIELD_INFO innodb_sys_tablestats_fields_info[] =
331 +#define SYS_TABLESTATS_ID 0
332 + {STRUCT_FLD(field_name, "TABLE_ID"),
333 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
334 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
335 + STRUCT_FLD(value, 0),
336 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
337 + STRUCT_FLD(old_name, ""),
338 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
340 +#define SYS_TABLESTATS_SCHEMA 1
341 + {STRUCT_FLD(field_name, "SCHEMA"),
342 + STRUCT_FLD(field_length, NAME_LEN + 1),
343 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
344 + STRUCT_FLD(value, 0),
345 + STRUCT_FLD(field_flags, 0),
346 + STRUCT_FLD(old_name, ""),
347 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
349 +#define SYS_TABLESTATS_NAME 2
350 + {STRUCT_FLD(field_name, "NAME"),
351 + STRUCT_FLD(field_length, NAME_LEN + 1),
352 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
353 + STRUCT_FLD(value, 0),
354 + STRUCT_FLD(field_flags, 0),
355 + STRUCT_FLD(old_name, ""),
356 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
358 +#define SYS_TABLESTATS_INIT 3
359 + {STRUCT_FLD(field_name, "STATS_INITIALIZED"),
360 + STRUCT_FLD(field_length, NAME_LEN + 1),
361 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
362 + STRUCT_FLD(value, 0),
363 + STRUCT_FLD(field_flags, 0),
364 + STRUCT_FLD(old_name, ""),
365 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
367 +#define SYS_TABLESTATS_NROW 4
368 + {STRUCT_FLD(field_name, "NUM_ROWS"),
369 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
370 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
371 + STRUCT_FLD(value, 0),
372 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
373 + STRUCT_FLD(old_name, ""),
374 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
376 +#define SYS_TABLESTATS_CLUST_SIZE 5
377 + {STRUCT_FLD(field_name, "CLUST_INDEX_SIZE"),
378 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
379 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
380 + STRUCT_FLD(value, 0),
381 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
382 + STRUCT_FLD(old_name, ""),
383 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
385 +#define SYS_TABLESTATS_INDEX_SIZE 6
386 + {STRUCT_FLD(field_name, "OTHER_INDEX_SIZE"),
387 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
388 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
389 + STRUCT_FLD(value, 0),
390 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
391 + STRUCT_FLD(old_name, ""),
392 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
394 +#define SYS_TABLESTATS_MODIFIED 7
395 + {STRUCT_FLD(field_name, "MODIFIED_COUNTER"),
396 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
397 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
398 + STRUCT_FLD(value, 0),
399 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
400 + STRUCT_FLD(old_name, ""),
401 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
403 +#define SYS_TABLESTATS_AUTONINC 8
404 + {STRUCT_FLD(field_name, "AUTOINC"),
405 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
406 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
407 + STRUCT_FLD(value, 0),
408 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
409 + STRUCT_FLD(old_name, ""),
410 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
412 +#define SYS_TABLESTATS_MYSQL_OPEN_HANDLE 9
413 + {STRUCT_FLD(field_name, "MYSQL_HANDLES_OPENED"),
414 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
415 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
416 + STRUCT_FLD(value, 0),
417 + STRUCT_FLD(field_flags, 0),
418 + STRUCT_FLD(old_name, ""),
419 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
421 + END_OF_ST_FIELD_INFO
424 +/**********************************************************************//**
425 +Populate information_schema.innodb_sys_tablestats table with information
427 +@return 0 on success */
430 +i_s_dict_fill_sys_tablestats(
431 +/*=========================*/
432 + THD* thd, /*!< in: thread */
433 + dict_table_t* table, /*!< in: table */
434 + TABLE* table_to_fill) /*!< in/out: fill this table */
437 + char buf[NAME_LEN * 2 + 2];
440 + DBUG_ENTER("i_s_dict_fill_sys_tablestats");
442 + fields = table_to_fill->field;
444 + OK(fields[SYS_TABLESTATS_ID]->store(longlong(table->id), TRUE));
446 + strncpy(buf, table->name, NAME_LEN * 2 + 2);
447 + ptr = strchr(buf, '/');
452 + OK(field_store_string(fields[SYS_TABLESTATS_SCHEMA], buf));
453 + OK(field_store_string(fields[SYS_TABLESTATS_NAME], ptr));
455 + fields[SYS_TABLESTATS_SCHEMA]->set_null();
456 + OK(field_store_string(fields[SYS_TABLESTATS_NAME], buf));
459 + if (table->stat_initialized) {
460 + OK(field_store_string(fields[SYS_TABLESTATS_INIT],
463 + OK(field_store_string(fields[SYS_TABLESTATS_INIT],
467 + OK(fields[SYS_TABLESTATS_NROW]->store(table->stat_n_rows, TRUE));
469 + OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store(
470 + table->stat_clustered_index_size));
472 + OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store(
473 + table->stat_sum_of_other_index_sizes));
475 + OK(fields[SYS_TABLESTATS_MODIFIED]->store(
476 + table->stat_modified_counter));
478 + OK(fields[SYS_TABLESTATS_AUTONINC]->store(table->autoinc, TRUE));
480 + OK(fields[SYS_TABLESTATS_MYSQL_OPEN_HANDLE]->store(
481 + table->n_mysql_handles_opened));
483 + OK(schema_table_store_record(thd, table_to_fill));
487 +/*******************************************************************//**
488 +Function to go through each record in SYS_TABLES table, and fill the
489 +information_schema.innodb_sys_tablestats table with table statistics
491 +@return 0 on success */
494 +i_s_sys_tables_fill_table_stats(
495 +/*============================*/
496 + THD* thd, /*!< in: thread */
497 + TABLE_LIST* tables, /*!< in/out: tables to fill */
498 + COND* cond) /*!< in: condition (not used) */
505 + DBUG_ENTER("i_s_sys_tables_fill_table_stats");
507 + /* deny access to non-superusers */
508 + if (check_global_access(thd, PROCESS_ACL)) {
513 + heap = mem_heap_create(1000);
514 + mutex_enter(&dict_sys->mutex);
517 + rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
520 + const char* err_msg;
521 + dict_table_t* table_rec;
523 + /* Fetch the dict_table_t structure corresponding to
524 + this SYS_TABLES record */
525 + err_msg = dict_process_sys_tables_rec(
526 + heap, rec, &table_rec, DICT_TABLE_LOAD_FROM_CACHE);
529 + mutex_exit(&dict_sys->mutex);
532 + i_s_dict_fill_sys_tablestats(thd, table_rec,
535 + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
536 + ER_CANT_FIND_SYSTEM_REC,
540 + mem_heap_empty(heap);
542 + /* Get the next record */
543 + mutex_enter(&dict_sys->mutex);
545 + rec = dict_getnext_system(&pcur, &mtr);
549 + mutex_exit(&dict_sys->mutex);
550 + mem_heap_free(heap);
555 +/*******************************************************************//**
556 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_tablestats
557 +@return 0 on success */
560 +innodb_sys_tablestats_init(
561 +/*=======================*/
562 + void* p) /*!< in/out: table schema object */
564 + ST_SCHEMA_TABLE* schema;
566 + DBUG_ENTER("innodb_sys_tablestats_init");
568 + schema = (ST_SCHEMA_TABLE*) p;
570 + schema->fields_info = innodb_sys_tablestats_fields_info;
571 + schema->fill_table = i_s_sys_tables_fill_table_stats;
576 +UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_tablestats =
578 + /* the plugin type (a MYSQL_XXX_PLUGIN value) */
580 + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
582 + /* pointer to type-specific plugin descriptor */
584 + STRUCT_FLD(info, &i_s_info),
588 + STRUCT_FLD(name, "INNODB_SYS_TABLESTATS"),
590 + /* plugin author (for SHOW PLUGINS) */
592 + STRUCT_FLD(author, "Percona"),
594 + /* general descriptive text (for SHOW PLUGINS) */
596 + STRUCT_FLD(descr, "InnoDB SYS_TABLESTATS"),
598 + /* the plugin license (PLUGIN_LICENSE_XXX) */
600 + STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
602 + /* the function to invoke when plugin is loaded */
603 + /* int (*)(void*); */
604 + STRUCT_FLD(init, innodb_sys_tablestats_init),
606 + /* the function to invoke when plugin is unloaded */
607 + /* int (*)(void*); */
608 + STRUCT_FLD(deinit, i_s_common_deinit),
610 + /* plugin version (for SHOW PLUGINS) */
612 + STRUCT_FLD(version, INNODB_VERSION_SHORT),
614 + /* struct st_mysql_show_var* */
615 + STRUCT_FLD(status_vars, NULL),
617 + /* struct st_mysql_sys_var** */
618 + STRUCT_FLD(system_vars, NULL),
620 + /* reserved for dependency checking */
622 + STRUCT_FLD(__reserved1, NULL),
624 + /* flags for plugin */
625 + /* unsigned long */
626 + STRUCT_FLD(flags, 0UL)
629 +/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_INDEXES */
630 +static ST_FIELD_INFO innodb_sysindex_fields_info[] =
632 +#define SYS_INDEX_ID 0
633 + {STRUCT_FLD(field_name, "INDEX_ID"),
634 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
635 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
636 + STRUCT_FLD(value, 0),
637 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
638 + STRUCT_FLD(old_name, ""),
639 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
641 +#define SYS_INDEX_NAME 1
642 + {STRUCT_FLD(field_name, "NAME"),
643 + STRUCT_FLD(field_length, NAME_LEN + 1),
644 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
645 + STRUCT_FLD(value, 0),
646 + STRUCT_FLD(field_flags, 0),
647 + STRUCT_FLD(old_name, ""),
648 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
650 +#define SYS_INDEX_TABLE_ID 2
651 + {STRUCT_FLD(field_name, "TABLE_ID"),
652 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
653 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
654 + STRUCT_FLD(value, 0),
655 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
656 + STRUCT_FLD(old_name, ""),
657 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
659 +#define SYS_INDEX_TYPE 3
660 + {STRUCT_FLD(field_name, "TYPE"),
661 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
662 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
663 + STRUCT_FLD(value, 0),
664 + STRUCT_FLD(field_flags, 0),
665 + STRUCT_FLD(old_name, ""),
666 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
668 +#define SYS_INDEX_NUM_FIELDS 4
669 + {STRUCT_FLD(field_name, "N_FIELDS"),
670 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
671 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
672 + STRUCT_FLD(value, 0),
673 + STRUCT_FLD(field_flags, 0),
674 + STRUCT_FLD(old_name, ""),
675 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
677 +#define SYS_INDEX_PAGE_NO 5
678 + {STRUCT_FLD(field_name, "PAGE_NO"),
679 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
680 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
681 + STRUCT_FLD(value, 0),
682 + STRUCT_FLD(field_flags, 0),
683 + STRUCT_FLD(old_name, ""),
684 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
686 +#define SYS_INDEX_SPACE 6
687 + {STRUCT_FLD(field_name, "SPACE"),
688 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
689 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
690 + STRUCT_FLD(value, 0),
691 + STRUCT_FLD(field_flags, 0),
692 + STRUCT_FLD(old_name, ""),
693 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
695 + END_OF_ST_FIELD_INFO
698 +/**********************************************************************//**
699 +Function to populate the information_schema.innodb_sys_indexes table with
700 +collected index information
701 +@return 0 on success */
704 +i_s_dict_fill_sys_indexes(
705 +/*======================*/
706 + THD* thd, /*!< in: thread */
707 + table_id_t table_id, /*!< in: table id */
708 + dict_index_t* index, /*!< in: populated dict_index_t
709 + struct with index info */
710 + TABLE* table_to_fill) /*!< in/out: fill this table */
714 + DBUG_ENTER("i_s_dict_fill_sys_indexes");
716 + fields = table_to_fill->field;
718 + OK(fields[SYS_INDEX_ID]->store(longlong(index->id), TRUE));
720 + OK(field_store_string(fields[SYS_INDEX_NAME], index->name));
722 + OK(fields[SYS_INDEX_TABLE_ID]->store(longlong(table_id), TRUE));
724 + OK(fields[SYS_INDEX_TYPE]->store(index->type));
726 + OK(fields[SYS_INDEX_NUM_FIELDS]->store(index->n_fields));
728 + OK(fields[SYS_INDEX_PAGE_NO]->store(index->page));
730 + OK(fields[SYS_INDEX_SPACE]->store(index->space));
732 + OK(schema_table_store_record(thd, table_to_fill));
736 +/*******************************************************************//**
737 +Function to go through each record in SYS_INDEXES table, and fill the
738 +information_schema.innodb_sys_indexes table with related index information
739 +@return 0 on success */
742 +i_s_sys_indexes_fill_table(
743 +/*=======================*/
744 + THD* thd, /*!< in: thread */
745 + TABLE_LIST* tables, /*!< in/out: tables to fill */
746 + COND* cond) /*!< in: condition (not used) */
753 + DBUG_ENTER("i_s_sys_indexes_fill_table");
755 + /* deny access to non-superusers */
756 + if (check_global_access(thd, PROCESS_ACL)) {
761 + heap = mem_heap_create(1000);
762 + mutex_enter(&dict_sys->mutex);
765 + /* Start scan the SYS_INDEXES table */
766 + rec = dict_startscan_system(&pcur, &mtr, SYS_INDEXES);
768 + /* Process each record in the table */
770 + const char* err_msg;;
771 + table_id_t table_id;
772 + dict_index_t index_rec;
774 + /* Populate a dict_index_t structure with information from
775 + a SYS_INDEXES row */
776 + err_msg = dict_process_sys_indexes_rec(heap, rec, &index_rec,
780 + mutex_exit(&dict_sys->mutex);
783 + i_s_dict_fill_sys_indexes(thd, table_id, &index_rec,
786 + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
787 + ER_CANT_FIND_SYSTEM_REC,
791 + mem_heap_empty(heap);
793 + /* Get the next record */
794 + mutex_enter(&dict_sys->mutex);
796 + rec = dict_getnext_system(&pcur, &mtr);
800 + mutex_exit(&dict_sys->mutex);
801 + mem_heap_free(heap);
805 +/*******************************************************************//**
806 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_indexes
807 +@return 0 on success */
810 +innodb_sys_indexes_init(
811 +/*====================*/
812 + void* p) /*!< in/out: table schema object */
814 + ST_SCHEMA_TABLE* schema;
816 + DBUG_ENTER("innodb_sys_index_init");
818 + schema = (ST_SCHEMA_TABLE*) p;
820 + schema->fields_info = innodb_sysindex_fields_info;
821 + schema->fill_table = i_s_sys_indexes_fill_table;
826 +UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_indexes =
828 + /* the plugin type (a MYSQL_XXX_PLUGIN value) */
830 + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
832 + /* pointer to type-specific plugin descriptor */
834 + STRUCT_FLD(info, &i_s_info),
838 + STRUCT_FLD(name, "INNODB_SYS_INDEXES"),
840 + /* plugin author (for SHOW PLUGINS) */
842 + STRUCT_FLD(author, "Percona"),
844 + /* general descriptive text (for SHOW PLUGINS) */
846 + STRUCT_FLD(descr, "InnoDB SYS_INDEXES"),
848 + /* the plugin license (PLUGIN_LICENSE_XXX) */
850 + STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
852 + /* the function to invoke when plugin is loaded */
853 + /* int (*)(void*); */
854 + STRUCT_FLD(init, innodb_sys_indexes_init),
856 + /* the function to invoke when plugin is unloaded */
857 + /* int (*)(void*); */
858 + STRUCT_FLD(deinit, i_s_common_deinit),
860 + /* plugin version (for SHOW PLUGINS) */
862 + STRUCT_FLD(version, INNODB_VERSION_SHORT),
864 + /* struct st_mysql_show_var* */
865 + STRUCT_FLD(status_vars, NULL),
867 + /* struct st_mysql_sys_var** */
868 + STRUCT_FLD(system_vars, NULL),
870 + /* reserved for dependency checking */
872 + STRUCT_FLD(__reserved1, NULL),
874 + /* flags for plugin */
875 + /* unsigned long */
876 + STRUCT_FLD(flags, 0UL)
879 +/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_COLUMNS */
880 +static ST_FIELD_INFO innodb_sys_columns_fields_info[] =
882 +#define SYS_COLUMN_TABLE_ID 0
883 + {STRUCT_FLD(field_name, "TABLE_ID"),
884 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
885 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
886 + STRUCT_FLD(value, 0),
887 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
888 + STRUCT_FLD(old_name, ""),
889 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
891 +#define SYS_COLUMN_NAME 1
892 + {STRUCT_FLD(field_name, "NAME"),
893 + STRUCT_FLD(field_length, NAME_LEN + 1),
894 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
895 + STRUCT_FLD(value, 0),
896 + STRUCT_FLD(field_flags, 0),
897 + STRUCT_FLD(old_name, ""),
898 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
900 +#define SYS_COLUMN_POSITION 2
901 + {STRUCT_FLD(field_name, "POS"),
902 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
903 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
904 + STRUCT_FLD(value, 0),
905 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
906 + STRUCT_FLD(old_name, ""),
907 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
909 +#define SYS_COLUMN_MTYPE 3
910 + {STRUCT_FLD(field_name, "MTYPE"),
911 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
912 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
913 + STRUCT_FLD(value, 0),
914 + STRUCT_FLD(field_flags, 0),
915 + STRUCT_FLD(old_name, ""),
916 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
918 +#define SYS_COLUMN__PRTYPE 4
919 + {STRUCT_FLD(field_name, "PRTYPE"),
920 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
921 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
922 + STRUCT_FLD(value, 0),
923 + STRUCT_FLD(field_flags, 0),
924 + STRUCT_FLD(old_name, ""),
925 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
927 +#define SYS_COLUMN_COLUMN_LEN 5
928 + {STRUCT_FLD(field_name, "LEN"),
929 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
930 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
931 + STRUCT_FLD(value, 0),
932 + STRUCT_FLD(field_flags, 0),
933 + STRUCT_FLD(old_name, ""),
934 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
936 + END_OF_ST_FIELD_INFO
939 +/**********************************************************************//**
940 +Function to populate the information_schema.innodb_sys_columns with
941 +related column information
942 +@return 0 on success */
945 +i_s_dict_fill_sys_columns(
946 +/*======================*/
947 + THD* thd, /*!< in: thread */
948 + table_id_t table_id, /*!< in: table ID */
949 + const char* col_name, /*!< in: column name */
950 + dict_col_t* column, /*!< in: dict_col_t struct holding
951 + more column information */
952 + TABLE* table_to_fill) /*!< in/out: fill this table */
956 + DBUG_ENTER("i_s_dict_fill_sys_columns");
958 + fields = table_to_fill->field;
960 + OK(fields[SYS_COLUMN_TABLE_ID]->store(longlong(table_id), TRUE));
962 + OK(field_store_string(fields[SYS_COLUMN_NAME], col_name));
964 + OK(fields[SYS_COLUMN_POSITION]->store(column->ind));
966 + OK(fields[SYS_COLUMN_MTYPE]->store(column->mtype));
968 + OK(fields[SYS_COLUMN__PRTYPE]->store(column->prtype));
970 + OK(fields[SYS_COLUMN_COLUMN_LEN]->store(column->len));
972 + OK(schema_table_store_record(thd, table_to_fill));
976 +/*******************************************************************//**
977 +Function to fill information_schema.innodb_sys_columns with information
978 +collected by scanning SYS_COLUMNS table.
979 +@return 0 on success */
982 +i_s_sys_columns_fill_table(
983 +/*=======================*/
984 + THD* thd, /*!< in: thread */
985 + TABLE_LIST* tables, /*!< in/out: tables to fill */
986 + COND* cond) /*!< in: condition (not used) */
990 + const char* col_name;
994 + DBUG_ENTER("i_s_sys_columns_fill_table");
996 + /* deny access to non-superusers */
997 + if (check_global_access(thd, PROCESS_ACL)) {
1002 + heap = mem_heap_create(1000);
1003 + mutex_enter(&dict_sys->mutex);
1006 + rec = dict_startscan_system(&pcur, &mtr, SYS_COLUMNS);
1009 + const char* err_msg;
1010 + dict_col_t column_rec;
1011 + table_id_t table_id;
1013 + /* populate a dict_col_t structure with information from
1014 + a SYS_COLUMNS row */
1015 + err_msg = dict_process_sys_columns_rec(heap, rec, &column_rec,
1016 + &table_id, &col_name);
1019 + mutex_exit(&dict_sys->mutex);
1022 + i_s_dict_fill_sys_columns(thd, table_id, col_name,
1026 + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1027 + ER_CANT_FIND_SYSTEM_REC,
1031 + mem_heap_empty(heap);
1033 + /* Get the next record */
1034 + mutex_enter(&dict_sys->mutex);
1036 + rec = dict_getnext_system(&pcur, &mtr);
1040 + mutex_exit(&dict_sys->mutex);
1041 + mem_heap_free(heap);
1045 +/*******************************************************************//**
1046 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_columns
1047 +@return 0 on success */
1050 +innodb_sys_columns_init(
1051 +/*====================*/
1052 + void* p) /*!< in/out: table schema object */
1054 + ST_SCHEMA_TABLE* schema;
1056 + DBUG_ENTER("innodb_sys_columns_init");
1058 + schema = (ST_SCHEMA_TABLE*) p;
1060 + schema->fields_info = innodb_sys_columns_fields_info;
1061 + schema->fill_table = i_s_sys_columns_fill_table;
1066 +UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_columns =
1068 + /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1070 + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1072 + /* pointer to type-specific plugin descriptor */
1074 + STRUCT_FLD(info, &i_s_info),
1078 + STRUCT_FLD(name, "INNODB_SYS_COLUMNS"),
1080 + /* plugin author (for SHOW PLUGINS) */
1082 + STRUCT_FLD(author, "Percona"),
1084 + /* general descriptive text (for SHOW PLUGINS) */
1086 + STRUCT_FLD(descr, "InnoDB SYS_COLUMNS"),
1088 + /* the plugin license (PLUGIN_LICENSE_XXX) */
1090 + STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1092 + /* the function to invoke when plugin is loaded */
1093 + /* int (*)(void*); */
1094 + STRUCT_FLD(init, innodb_sys_columns_init),
1096 + /* the function to invoke when plugin is unloaded */
1097 + /* int (*)(void*); */
1098 + STRUCT_FLD(deinit, i_s_common_deinit),
1100 + /* plugin version (for SHOW PLUGINS) */
1101 + /* unsigned int */
1102 + STRUCT_FLD(version, INNODB_VERSION_SHORT),
1104 + /* struct st_mysql_show_var* */
1105 + STRUCT_FLD(status_vars, NULL),
1107 + /* struct st_mysql_sys_var** */
1108 + STRUCT_FLD(system_vars, NULL),
1110 + /* reserved for dependency checking */
1112 + STRUCT_FLD(__reserved1, NULL),
1114 + /* flags for plugin */
1115 + /* unsigned long */
1116 + STRUCT_FLD(flags, 0UL)
1118 +/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_fields */
1119 +static ST_FIELD_INFO innodb_sys_fields_fields_info[] =
1121 +#define SYS_FIELD_INDEX_ID 0
1122 + {STRUCT_FLD(field_name, "INDEX_ID"),
1123 + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
1124 + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
1125 + STRUCT_FLD(value, 0),
1126 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1127 + STRUCT_FLD(old_name, ""),
1128 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1130 +#define SYS_FIELD_NAME 1
1131 + {STRUCT_FLD(field_name, "NAME"),
1132 + STRUCT_FLD(field_length, NAME_LEN + 1),
1133 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1134 + STRUCT_FLD(value, 0),
1135 + STRUCT_FLD(field_flags, 0),
1136 + STRUCT_FLD(old_name, ""),
1137 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1139 +#define SYS_FIELD_POS 2
1140 + {STRUCT_FLD(field_name, "POS"),
1141 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1142 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1143 + STRUCT_FLD(value, 0),
1144 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1145 + STRUCT_FLD(old_name, ""),
1146 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1148 + END_OF_ST_FIELD_INFO
1151 +/**********************************************************************//**
1152 +Function to fill information_schema.innodb_sys_fields with information
1153 +collected by scanning SYS_FIELDS table.
1154 +@return 0 on success */
1157 +i_s_dict_fill_sys_fields(
1158 +/*=====================*/
1159 + THD* thd, /*!< in: thread */
1160 + index_id_t index_id, /*!< in: index id for the field */
1161 + dict_field_t* field, /*!< in: table */
1162 + ulint pos, /*!< in: Field position */
1163 + TABLE* table_to_fill) /*!< in/out: fill this table */
1167 + DBUG_ENTER("i_s_dict_fill_sys_fields");
1169 + fields = table_to_fill->field;
1171 + OK(fields[SYS_FIELD_INDEX_ID]->store(longlong(index_id), TRUE));
1173 + OK(field_store_string(fields[SYS_FIELD_NAME], field->name));
1175 + OK(fields[SYS_FIELD_POS]->store(pos));
1177 + OK(schema_table_store_record(thd, table_to_fill));
1181 +/*******************************************************************//**
1182 +Function to go through each record in SYS_FIELDS table, and fill the
1183 +information_schema.innodb_sys_fields table with related index field
1185 +@return 0 on success */
1188 +i_s_sys_fields_fill_table(
1189 +/*======================*/
1190 + THD* thd, /*!< in: thread */
1191 + TABLE_LIST* tables, /*!< in/out: tables to fill */
1192 + COND* cond) /*!< in: condition (not used) */
1197 + index_id_t last_id;
1200 + DBUG_ENTER("i_s_sys_fields_fill_table");
1202 + /* deny access to non-superusers */
1203 + if (check_global_access(thd, PROCESS_ACL)) {
1208 + heap = mem_heap_create(1000);
1209 + mutex_enter(&dict_sys->mutex);
1212 + /* will save last index id so that we know whether we move to
1213 + the next index. This is used to calculate prefix length */
1216 + rec = dict_startscan_system(&pcur, &mtr, SYS_FIELDS);
1220 + const char* err_msg;
1221 + index_id_t index_id;
1222 + dict_field_t field_rec;
1224 + /* Populate a dict_field_t structure with information from
1225 + a SYS_FIELDS row */
1226 + err_msg = dict_process_sys_fields_rec(heap, rec, &field_rec,
1227 + &pos, &index_id, last_id);
1230 + mutex_exit(&dict_sys->mutex);
1233 + i_s_dict_fill_sys_fields(thd, index_id, &field_rec,
1234 + pos, tables->table);
1235 + last_id = index_id;
1237 + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1238 + ER_CANT_FIND_SYSTEM_REC,
1242 + mem_heap_empty(heap);
1244 + /* Get the next record */
1245 + mutex_enter(&dict_sys->mutex);
1247 + rec = dict_getnext_system(&pcur, &mtr);
1251 + mutex_exit(&dict_sys->mutex);
1252 + mem_heap_free(heap);
1256 +/*******************************************************************//**
1257 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_fields
1258 +@return 0 on success */
1261 +innodb_sys_fields_init(
1262 +/*===================*/
1263 + void* p) /*!< in/out: table schema object */
1265 + ST_SCHEMA_TABLE* schema;
1267 + DBUG_ENTER("innodb_sys_field_init");
1269 + schema = (ST_SCHEMA_TABLE*) p;
1271 + schema->fields_info = innodb_sys_fields_fields_info;
1272 + schema->fill_table = i_s_sys_fields_fill_table;
1277 +UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_fields =
1279 + /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1281 + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1283 + /* pointer to type-specific plugin descriptor */
1285 + STRUCT_FLD(info, &i_s_info),
1289 + STRUCT_FLD(name, "INNODB_SYS_FIELDS"),
1291 + /* plugin author (for SHOW PLUGINS) */
1293 + STRUCT_FLD(author, "Percona"),
1295 + /* general descriptive text (for SHOW PLUGINS) */
1297 + STRUCT_FLD(descr, "InnoDB SYS_FIELDS"),
1299 + /* the plugin license (PLUGIN_LICENSE_XXX) */
1301 + STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1303 + /* the function to invoke when plugin is loaded */
1304 + /* int (*)(void*); */
1305 + STRUCT_FLD(init, innodb_sys_fields_init),
1307 + /* the function to invoke when plugin is unloaded */
1308 + /* int (*)(void*); */
1309 + STRUCT_FLD(deinit, i_s_common_deinit),
1311 + /* plugin version (for SHOW PLUGINS) */
1312 + /* unsigned int */
1313 + STRUCT_FLD(version, INNODB_VERSION_SHORT),
1315 + /* struct st_mysql_show_var* */
1316 + STRUCT_FLD(status_vars, NULL),
1318 + /* struct st_mysql_sys_var** */
1319 + STRUCT_FLD(system_vars, NULL),
1321 + /* reserved for dependency checking */
1323 + STRUCT_FLD(__reserved1, NULL),
1325 + /* flags for plugin */
1326 + /* unsigned long */
1327 + STRUCT_FLD(flags, 0UL)
1330 +/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign */
1331 +static ST_FIELD_INFO innodb_sys_foreign_fields_info[] =
1333 +#define SYS_FOREIGN_ID 0
1334 + {STRUCT_FLD(field_name, "ID"),
1335 + STRUCT_FLD(field_length, NAME_LEN + 1),
1336 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1337 + STRUCT_FLD(value, 0),
1338 + STRUCT_FLD(field_flags, 0),
1339 + STRUCT_FLD(old_name, ""),
1340 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1342 +#define SYS_FOREIGN_FOR_NAME 1
1343 + {STRUCT_FLD(field_name, "FOR_NAME"),
1344 + STRUCT_FLD(field_length, NAME_LEN + 1),
1345 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1346 + STRUCT_FLD(value, 0),
1347 + STRUCT_FLD(field_flags, 0),
1348 + STRUCT_FLD(old_name, ""),
1349 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1351 +#define SYS_FOREIGN_REF_NAME 2
1352 + {STRUCT_FLD(field_name, "REF_NAME"),
1353 + STRUCT_FLD(field_length, NAME_LEN + 1),
1354 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1355 + STRUCT_FLD(value, 0),
1356 + STRUCT_FLD(field_flags, 0),
1357 + STRUCT_FLD(old_name, ""),
1358 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1360 +#define SYS_FOREIGN_NUM_COL 3
1361 + {STRUCT_FLD(field_name, "N_COLS"),
1362 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1363 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1364 + STRUCT_FLD(value, 0),
1365 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1366 + STRUCT_FLD(old_name, ""),
1367 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1369 +#define SYS_FOREIGN_TYPE 4
1370 + {STRUCT_FLD(field_name, "TYPE"),
1371 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1372 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1373 + STRUCT_FLD(value, 0),
1374 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1375 + STRUCT_FLD(old_name, ""),
1376 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1378 + END_OF_ST_FIELD_INFO
1381 +/**********************************************************************//**
1382 +Function to fill information_schema.innodb_sys_foreign with information
1383 +collected by scanning SYS_FOREIGN table.
1384 +@return 0 on success */
1387 +i_s_dict_fill_sys_foreign(
1388 +/*======================*/
1389 + THD* thd, /*!< in: thread */
1390 + dict_foreign_t* foreign, /*!< in: table */
1391 + TABLE* table_to_fill) /*!< in/out: fill this table */
1395 + DBUG_ENTER("i_s_dict_fill_sys_foreign");
1397 + fields = table_to_fill->field;
1399 + OK(field_store_string(fields[SYS_FOREIGN_ID], foreign->id));
1401 + OK(field_store_string(fields[SYS_FOREIGN_FOR_NAME],
1402 + foreign->foreign_table_name));
1404 + OK(field_store_string(fields[SYS_FOREIGN_REF_NAME],
1405 + foreign->referenced_table_name));
1407 + OK(fields[SYS_FOREIGN_NUM_COL]->store(foreign->n_fields));
1409 + OK(fields[SYS_FOREIGN_TYPE]->store(foreign->type));
1411 + OK(schema_table_store_record(thd, table_to_fill));
1415 +/*******************************************************************//**
1416 +Function to populate INFORMATION_SCHEMA.innodb_sys_foreign table. Loop
1417 +through each record in SYS_FOREIGN, and extract the foreign key
1419 +@return 0 on success */
1422 +i_s_sys_foreign_fill_table(
1423 +/*=======================*/
1424 + THD* thd, /*!< in: thread */
1425 + TABLE_LIST* tables, /*!< in/out: tables to fill */
1426 + COND* cond) /*!< in: condition (not used) */
1433 + DBUG_ENTER("i_s_sys_foreign_fill_table");
1435 + /* deny access to non-superusers */
1436 + if (check_global_access(thd, PROCESS_ACL)) {
1441 + heap = mem_heap_create(1000);
1442 + mutex_enter(&dict_sys->mutex);
1445 + rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN);
1448 + const char* err_msg;
1449 + dict_foreign_t foreign_rec;
1451 + /* Populate a dict_foreign_t structure with information from
1452 + a SYS_FOREIGN row */
1453 + err_msg = dict_process_sys_foreign_rec(heap, rec, &foreign_rec);
1456 + mutex_exit(&dict_sys->mutex);
1459 + i_s_dict_fill_sys_foreign(thd, &foreign_rec,
1462 + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1463 + ER_CANT_FIND_SYSTEM_REC,
1467 + mem_heap_empty(heap);
1469 + /* Get the next record */
1471 + mutex_enter(&dict_sys->mutex);
1472 + rec = dict_getnext_system(&pcur, &mtr);
1476 + mutex_exit(&dict_sys->mutex);
1477 + mem_heap_free(heap);
1481 +/*******************************************************************//**
1482 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign
1483 +@return 0 on success */
1486 +innodb_sys_foreign_init(
1487 +/*====================*/
1488 + void* p) /*!< in/out: table schema object */
1490 + ST_SCHEMA_TABLE* schema;
1492 + DBUG_ENTER("innodb_sys_foreign_init");
1494 + schema = (ST_SCHEMA_TABLE*) p;
1496 + schema->fields_info = innodb_sys_foreign_fields_info;
1497 + schema->fill_table = i_s_sys_foreign_fill_table;
1502 +UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_foreign =
1504 + /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1506 + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1508 + /* pointer to type-specific plugin descriptor */
1510 + STRUCT_FLD(info, &i_s_info),
1514 + STRUCT_FLD(name, "INNODB_SYS_FOREIGN"),
1516 + /* plugin author (for SHOW PLUGINS) */
1518 + STRUCT_FLD(author, "Percona"),
1520 + /* general descriptive text (for SHOW PLUGINS) */
1522 + STRUCT_FLD(descr, "InnoDB SYS_FOREIGN"),
1524 + /* the plugin license (PLUGIN_LICENSE_XXX) */
1526 + STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1528 + /* the function to invoke when plugin is loaded */
1529 + /* int (*)(void*); */
1530 + STRUCT_FLD(init, innodb_sys_foreign_init),
1532 + /* the function to invoke when plugin is unloaded */
1533 + /* int (*)(void*); */
1534 + STRUCT_FLD(deinit, i_s_common_deinit),
1536 + /* plugin version (for SHOW PLUGINS) */
1537 + /* unsigned int */
1538 + STRUCT_FLD(version, INNODB_VERSION_SHORT),
1540 + /* struct st_mysql_show_var* */
1541 + STRUCT_FLD(status_vars, NULL),
1543 + /* struct st_mysql_sys_var** */
1544 + STRUCT_FLD(system_vars, NULL),
1546 + /* reserved for dependency checking */
1548 + STRUCT_FLD(__reserved1, NULL),
1550 + /* flags for plugin */
1551 + /* unsigned long */
1552 + STRUCT_FLD(flags, 0UL)
1554 +/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign_cols */
1555 +static ST_FIELD_INFO innodb_sys_foreign_cols_fields_info[] =
1557 +#define SYS_FOREIGN_COL_ID 0
1558 + {STRUCT_FLD(field_name, "ID"),
1559 + STRUCT_FLD(field_length, NAME_LEN + 1),
1560 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1561 + STRUCT_FLD(value, 0),
1562 + STRUCT_FLD(field_flags, 0),
1563 + STRUCT_FLD(old_name, ""),
1564 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1566 +#define SYS_FOREIGN_COL_FOR_NAME 1
1567 + {STRUCT_FLD(field_name, "FOR_COL_NAME"),
1568 + STRUCT_FLD(field_length, NAME_LEN + 1),
1569 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1570 + STRUCT_FLD(value, 0),
1571 + STRUCT_FLD(field_flags, 0),
1572 + STRUCT_FLD(old_name, ""),
1573 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1575 +#define SYS_FOREIGN_COL_REF_NAME 2
1576 + {STRUCT_FLD(field_name, "REF_COL_NAME"),
1577 + STRUCT_FLD(field_length, NAME_LEN + 1),
1578 + STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
1579 + STRUCT_FLD(value, 0),
1580 + STRUCT_FLD(field_flags, 0),
1581 + STRUCT_FLD(old_name, ""),
1582 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1584 +#define SYS_FOREIGN_COL_POS 3
1585 + {STRUCT_FLD(field_name, "POS"),
1586 + STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
1587 + STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
1588 + STRUCT_FLD(value, 0),
1589 + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
1590 + STRUCT_FLD(old_name, ""),
1591 + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
1593 + END_OF_ST_FIELD_INFO
1596 +/**********************************************************************//**
1597 +Function to fill information_schema.innodb_sys_foreign_cols with information
1598 +collected by scanning SYS_FOREIGN_COLS table.
1599 +@return 0 on success */
1602 +i_s_dict_fill_sys_foreign_cols(
1603 +/*==========================*/
1604 + THD* thd, /*!< in: thread */
1605 + const char* name, /*!< in: foreign key constraint name */
1606 + const char* for_col_name, /*!< in: referencing column name*/
1607 + const char* ref_col_name, /*!< in: referenced column
1609 + ulint pos, /*!< in: column position */
1610 + TABLE* table_to_fill) /*!< in/out: fill this table */
1614 + DBUG_ENTER("i_s_dict_fill_sys_foreign_cols");
1616 + fields = table_to_fill->field;
1618 + OK(field_store_string(fields[SYS_FOREIGN_COL_ID], name));
1620 + OK(field_store_string(fields[SYS_FOREIGN_COL_FOR_NAME], for_col_name));
1622 + OK(field_store_string(fields[SYS_FOREIGN_COL_REF_NAME], ref_col_name));
1624 + OK(fields[SYS_FOREIGN_COL_POS]->store(pos));
1626 + OK(schema_table_store_record(thd, table_to_fill));
1630 +/*******************************************************************//**
1631 +Function to populate INFORMATION_SCHEMA.innodb_sys_foreign_cols table. Loop
1632 +through each record in SYS_FOREIGN_COLS, and extract the foreign key column
1633 +information and fill the INFORMATION_SCHEMA.innodb_sys_foreign_cols table.
1634 +@return 0 on success */
1637 +i_s_sys_foreign_cols_fill_table(
1638 +/*============================*/
1639 + THD* thd, /*!< in: thread */
1640 + TABLE_LIST* tables, /*!< in/out: tables to fill */
1641 + COND* cond) /*!< in: condition (not used) */
1648 + DBUG_ENTER("i_s_sys_foreign_cols_fill_table");
1650 + /* deny access to non-superusers */
1651 + if (check_global_access(thd, PROCESS_ACL)) {
1655 + heap = mem_heap_create(1000);
1656 + mutex_enter(&dict_sys->mutex);
1659 + rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN_COLS);
1662 + const char* err_msg;
1664 + const char* for_col_name;
1665 + const char* ref_col_name;
1668 + /* Extract necessary information from a SYS_FOREIGN_COLS row */
1669 + err_msg = dict_process_sys_foreign_col_rec(
1670 + heap, rec, &name, &for_col_name, &ref_col_name, &pos);
1673 + mutex_exit(&dict_sys->mutex);
1676 + i_s_dict_fill_sys_foreign_cols(
1677 + thd, name, for_col_name, ref_col_name, pos,
1680 + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1681 + ER_CANT_FIND_SYSTEM_REC,
1685 + mem_heap_empty(heap);
1687 + /* Get the next record */
1688 + mutex_enter(&dict_sys->mutex);
1690 + rec = dict_getnext_system(&pcur, &mtr);
1694 + mutex_exit(&dict_sys->mutex);
1695 + mem_heap_free(heap);
1699 +/*******************************************************************//**
1700 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign_cols
1701 +@return 0 on success */
1704 +innodb_sys_foreign_cols_init(
1705 +/*========================*/
1706 + void* p) /*!< in/out: table schema object */
1708 + ST_SCHEMA_TABLE* schema;
1710 + DBUG_ENTER("innodb_sys_foreign_cols_init");
1712 + schema = (ST_SCHEMA_TABLE*) p;
1714 + schema->fields_info = innodb_sys_foreign_cols_fields_info;
1715 + schema->fill_table = i_s_sys_foreign_cols_fill_table;
1720 +UNIV_INTERN struct st_mysql_plugin i_s_innodb_sys_foreign_cols =
1722 + /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1724 + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1726 + /* pointer to type-specific plugin descriptor */
1728 + STRUCT_FLD(info, &i_s_info),
1732 + STRUCT_FLD(name, "INNODB_SYS_FOREIGN_COLS"),
1734 + /* plugin author (for SHOW PLUGINS) */
1736 + STRUCT_FLD(author, "Percona"),
1738 + /* general descriptive text (for SHOW PLUGINS) */
1740 + STRUCT_FLD(descr, "InnoDB SYS_FOREIGN_COLS"),
1742 + /* the plugin license (PLUGIN_LICENSE_XXX) */
1744 + STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1746 + /* the function to invoke when plugin is loaded */
1747 + /* int (*)(void*); */
1748 + STRUCT_FLD(init, innodb_sys_foreign_cols_init),
1750 + /* the function to invoke when plugin is unloaded */
1751 + /* int (*)(void*); */
1752 + STRUCT_FLD(deinit, i_s_common_deinit),
1754 + /* plugin version (for SHOW PLUGINS) */
1755 + /* unsigned int */
1756 + STRUCT_FLD(version, INNODB_VERSION_SHORT),
1758 + /* struct st_mysql_show_var* */
1759 + STRUCT_FLD(status_vars, NULL),
1761 + /* struct st_mysql_sys_var** */
1762 + STRUCT_FLD(system_vars, NULL),
1764 + /* reserved for dependency checking */
1766 + STRUCT_FLD(__reserved1, NULL),
1768 + /* flags for plugin */
1769 + /* unsigned long */
1770 + STRUCT_FLD(flags, 0UL)
1773 /***********************************************************************
1775 static ST_FIELD_INFO i_s_innodb_rseg_fields_info[] =
1776 --- a/storage/innobase/handler/i_s.h
1777 +++ b/storage/innobase/handler/i_s.h
1779 extern struct st_mysql_plugin i_s_innodb_cmp_reset;
1780 extern struct st_mysql_plugin i_s_innodb_cmpmem;
1781 extern struct st_mysql_plugin i_s_innodb_cmpmem_reset;
1782 +extern struct st_mysql_plugin i_s_innodb_sys_tables;
1783 +extern struct st_mysql_plugin i_s_innodb_sys_tablestats;
1784 +extern struct st_mysql_plugin i_s_innodb_sys_indexes;
1785 +extern struct st_mysql_plugin i_s_innodb_sys_columns;
1786 +extern struct st_mysql_plugin i_s_innodb_sys_fields;
1787 +extern struct st_mysql_plugin i_s_innodb_sys_foreign;
1788 +extern struct st_mysql_plugin i_s_innodb_sys_foreign_cols;
1789 extern struct st_mysql_plugin i_s_innodb_rseg;