]> git.pld-linux.org Git - packages/mysql.git/blob - innodb_show_sys_tables.patch
5ad8bebecb870f94b83299a8fbe044c76f890e60
[packages/mysql.git] / innodb_show_sys_tables.patch
1 # name       : innodb_show_sys_tables.patch
2 # introduced : 13?
3 # maintainer : Yasufumi
4 # (It is revived from mysql-5.5.6-rc)
5 #!!! notice !!!
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
10 @@ -442,7 +442,7 @@
11  
12  }
13  
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
19 @@ -518,9 +518,9 @@
20  
21         return(NULL);
22  }
23 -#endif  /* FOREIGN_NOT_USED */
24 +//#endif  /* FOREIGN_NOT_USED */
25  
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.
31 @@ -584,7 +584,7 @@
32  
33         return(NULL);
34  }
35 -#endif  /* FOREIGN_NOT_USED */
36 +//#endif  /* FOREIGN_NOT_USED */
37  
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 @@
43  i_s_innodb_cmp,
44  i_s_innodb_cmp_reset,
45  i_s_innodb_cmpmem,
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;
56  
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
60 @@ -36,9 +36,11 @@
61  #include <mysql/innodb_priv.h>
62  
63  extern "C" {
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. */
69  #include "dict0mem.h"
70  #include "dict0types.h"
71  #include "ha_prototypes.h" /* for innobase_convert_name() */
72 @@ -1812,6 +1814,1703 @@
73         DBUG_RETURN(0);
74  }
75  
76 +/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_TABLES */
77 +static ST_FIELD_INFO    innodb_sys_tables_fields_info[] =
78 +{
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)},
87 +
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)},
96 +
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)},
105 +
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)},
114 +
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)},
123 +
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)},
132 +
133 +       END_OF_ST_FIELD_INFO
134 +};
135 +
136 +/**********************************************************************//**
137 +Populate information_schema.innodb_sys_tables table with information
138 +from SYS_TABLES.
139 +@return        0 on success */
140 +static
141 +int
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 */
147 +{
148 +       Field**         fields;
149 +       char            buf[NAME_LEN * 2 + 2];
150 +       char*           ptr;
151 +
152 +       DBUG_ENTER("i_s_dict_fill_sys_tables");
153 +
154 +       fields = table_to_fill->field;
155 +
156 +       OK(fields[SYS_TABLE_ID]->store(longlong(table->id), TRUE));
157 +
158 +       strncpy(buf, table->name, NAME_LEN * 2 + 2);
159 +       ptr = strchr(buf, '/');
160 +       if (ptr) {
161 +               *ptr = '\0';
162 +               ++ptr;
163 +
164 +               OK(field_store_string(fields[SYS_TABLE_SCHEMA], buf));
165 +               OK(field_store_string(fields[SYS_TABLE_NAME], ptr));
166 +       } else {
167 +               fields[SYS_TABLE_SCHEMA]->set_null();
168 +               OK(field_store_string(fields[SYS_TABLE_NAME], buf));
169 +       }
170 +
171 +       OK(fields[SYS_TABLE_FLAG]->store(table->flags));
172 +
173 +       OK(fields[SYS_TABLE_NUM_COLUMN]->store(table->n_cols));
174 +
175 +       OK(fields[SYS_TABLE_SPACE]->store(table->space));
176 +
177 +       OK(schema_table_store_record(thd, table_to_fill));
178 +
179 +       DBUG_RETURN(0);
180 +}
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 */
185 +static
186 +int
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) */
192 +{
193 +        btr_pcur_t     pcur;
194 +       const rec_t*    rec;
195 +       mem_heap_t*     heap;
196 +       mtr_t           mtr;
197 +
198 +       DBUG_ENTER("i_s_sys_tables_fill_table");
199 +
200 +       /* deny access to non-superusers */
201 +       if (check_global_access(thd, PROCESS_ACL)) {
202 +
203 +                DBUG_RETURN(0);
204 +       }
205 +
206 +        heap = mem_heap_create(1000);
207 +        mutex_enter(&(dict_sys->mutex));
208 +        mtr_start(&mtr);
209 +
210 +       rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
211 +
212 +       while (rec) {
213 +               const char*     err_msg;
214 +               dict_table_t*   table_rec;
215 +
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);
220 +
221 +               mtr_commit(&mtr);
222 +               mutex_exit(&dict_sys->mutex);
223 +
224 +               if (!err_msg) {
225 +                       i_s_dict_fill_sys_tables(thd, table_rec, tables->table);
226 +               } else {
227 +                       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
228 +                                           ER_CANT_FIND_SYSTEM_REC,
229 +                                           err_msg);
230 +               }
231 +
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 */
235 +               if (table_rec) {
236 +                       dict_mem_table_free(table_rec);
237 +               }
238 +
239 +               mem_heap_empty(heap);
240 +
241 +               /* Get the next record */
242 +               mutex_enter(&dict_sys->mutex);
243 +               mtr_start(&mtr);
244 +               rec = dict_getnext_system(&pcur, &mtr);
245 +       }
246 +
247 +       mtr_commit(&mtr);
248 +       mutex_exit(&dict_sys->mutex);
249 +       mem_heap_free(heap);
250 +
251 +       DBUG_RETURN(0);
252 +}
253 +
254 +/*******************************************************************//**
255 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_tables
256 +@return 0 on success */
257 +static
258 +int
259 +innodb_sys_tables_init(
260 +/*===================*/
261 +        void*   p)      /*!< in/out: table schema object */
262 +{
263 +        ST_SCHEMA_TABLE*        schema;
264 +
265 +        DBUG_ENTER("innodb_sys_tables_init");
266 +
267 +        schema = (ST_SCHEMA_TABLE*) p;
268 +
269 +        schema->fields_info = innodb_sys_tables_fields_info;
270 +        schema->fill_table = i_s_sys_tables_fill_table;
271 +
272 +        DBUG_RETURN(0);
273 +}
274 +
275 +UNIV_INTERN struct st_mysql_plugin     i_s_innodb_sys_tables =
276 +{
277 +       /* the plugin type (a MYSQL_XXX_PLUGIN value) */
278 +       /* int */
279 +       STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
280 +
281 +       /* pointer to type-specific plugin descriptor */
282 +       /* void* */
283 +       STRUCT_FLD(info, &i_s_info),
284 +
285 +       /* plugin name */
286 +       /* const char* */
287 +       STRUCT_FLD(name, "INNODB_SYS_TABLES"),
288 +
289 +       /* plugin author (for SHOW PLUGINS) */
290 +       /* const char* */
291 +       STRUCT_FLD(author, "Percona"),
292 +
293 +       /* general descriptive text (for SHOW PLUGINS) */
294 +       /* const char* */
295 +       STRUCT_FLD(descr, "InnoDB SYS_TABLES"),
296 +
297 +       /* the plugin license (PLUGIN_LICENSE_XXX) */
298 +       /* int */
299 +       STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
300 +
301 +       /* the function to invoke when plugin is loaded */
302 +       /* int (*)(void*); */
303 +       STRUCT_FLD(init, innodb_sys_tables_init),
304 +
305 +       /* the function to invoke when plugin is unloaded */
306 +       /* int (*)(void*); */
307 +       STRUCT_FLD(deinit, i_s_common_deinit),
308 +
309 +       /* plugin version (for SHOW PLUGINS) */
310 +       /* unsigned int */
311 +       STRUCT_FLD(version, INNODB_VERSION_SHORT),
312 +
313 +       /* struct st_mysql_show_var* */
314 +       STRUCT_FLD(status_vars, NULL),
315 +
316 +       /* struct st_mysql_sys_var** */
317 +       STRUCT_FLD(system_vars, NULL),
318 +
319 +       /* reserved for dependency checking */
320 +       /* void* */
321 +       STRUCT_FLD(__reserved1, NULL),
322 +
323 +       /* flags for plugin */
324 +       /* unsigned long */
325 +       STRUCT_FLD(flags, 0UL)
326 +};
327 +
328 +/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_TABLESTATS */
329 +static ST_FIELD_INFO    innodb_sys_tablestats_fields_info[] =
330 +{
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)},
339 +
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)},
348 +
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)},
357 +
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)},
366 +
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)},
375 +
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)},
384 +
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)},
393 +
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)},
402 +
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)},
411 +
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)},
420 +
421 +       END_OF_ST_FIELD_INFO
422 +};
423 +
424 +/**********************************************************************//**
425 +Populate information_schema.innodb_sys_tablestats table with information
426 +from SYS_TABLES.
427 +@return        0 on success */
428 +static
429 +int
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 */
435 +{
436 +       Field**         fields;
437 +       char            buf[NAME_LEN * 2 + 2];
438 +       char*           ptr;
439 +
440 +       DBUG_ENTER("i_s_dict_fill_sys_tablestats");
441 +
442 +       fields = table_to_fill->field;
443 +
444 +       OK(fields[SYS_TABLESTATS_ID]->store(longlong(table->id), TRUE));
445 +
446 +       strncpy(buf, table->name, NAME_LEN * 2 + 2);
447 +       ptr = strchr(buf, '/');
448 +       if (ptr) {
449 +               *ptr = '\0';
450 +               ++ptr;
451 +
452 +               OK(field_store_string(fields[SYS_TABLESTATS_SCHEMA], buf));
453 +               OK(field_store_string(fields[SYS_TABLESTATS_NAME], ptr));
454 +       } else {
455 +               fields[SYS_TABLESTATS_SCHEMA]->set_null();
456 +               OK(field_store_string(fields[SYS_TABLESTATS_NAME], buf));
457 +       }
458 +
459 +       if (table->stat_initialized) {
460 +               OK(field_store_string(fields[SYS_TABLESTATS_INIT],
461 +                                     "Initialized"));
462 +       } else {
463 +               OK(field_store_string(fields[SYS_TABLESTATS_INIT],
464 +                                     "Uninitialized"));
465 +       }
466 +
467 +       OK(fields[SYS_TABLESTATS_NROW]->store(table->stat_n_rows, TRUE));
468 +
469 +       OK(fields[SYS_TABLESTATS_CLUST_SIZE]->store(
470 +               table->stat_clustered_index_size));
471 +
472 +       OK(fields[SYS_TABLESTATS_INDEX_SIZE]->store(
473 +               table->stat_sum_of_other_index_sizes));
474 +
475 +       OK(fields[SYS_TABLESTATS_MODIFIED]->store(
476 +               table->stat_modified_counter));
477 +
478 +       OK(fields[SYS_TABLESTATS_AUTONINC]->store(table->autoinc, TRUE));
479 +
480 +       OK(fields[SYS_TABLESTATS_MYSQL_OPEN_HANDLE]->store(
481 +               table->n_mysql_handles_opened));
482 +
483 +       OK(schema_table_store_record(thd, table_to_fill));
484 +
485 +       DBUG_RETURN(0);
486 +}
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
490 +related information
491 +@return 0 on success */
492 +static
493 +int
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) */
499 +{
500 +        btr_pcur_t     pcur;
501 +       const rec_t*    rec;
502 +       mem_heap_t*     heap;
503 +       mtr_t           mtr;
504 +
505 +       DBUG_ENTER("i_s_sys_tables_fill_table_stats");
506 +
507 +       /* deny access to non-superusers */
508 +       if (check_global_access(thd, PROCESS_ACL)) {
509 +
510 +                DBUG_RETURN(0);
511 +       }
512 +
513 +        heap = mem_heap_create(1000);
514 +        mutex_enter(&dict_sys->mutex);
515 +        mtr_start(&mtr);
516 +
517 +       rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
518 +
519 +       while (rec) {
520 +               const char*     err_msg;
521 +               dict_table_t*   table_rec;
522 +
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);
527 +
528 +               mtr_commit(&mtr);
529 +               mutex_exit(&dict_sys->mutex);
530 +
531 +               if (!err_msg) {
532 +                       i_s_dict_fill_sys_tablestats(thd, table_rec,
533 +                                                    tables->table);
534 +               } else {
535 +                       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
536 +                                           ER_CANT_FIND_SYSTEM_REC,
537 +                                           err_msg);
538 +               }
539 +
540 +               mem_heap_empty(heap);
541 +
542 +               /* Get the next record */
543 +               mutex_enter(&dict_sys->mutex);
544 +               mtr_start(&mtr);
545 +               rec = dict_getnext_system(&pcur, &mtr);
546 +       }
547 +
548 +       mtr_commit(&mtr);
549 +       mutex_exit(&dict_sys->mutex);
550 +       mem_heap_free(heap);
551 +
552 +       DBUG_RETURN(0);
553 +}
554 +
555 +/*******************************************************************//**
556 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_tablestats
557 +@return 0 on success */
558 +static
559 +int
560 +innodb_sys_tablestats_init(
561 +/*=======================*/
562 +        void*   p)      /*!< in/out: table schema object */
563 +{
564 +        ST_SCHEMA_TABLE*        schema;
565 +
566 +        DBUG_ENTER("innodb_sys_tablestats_init");
567 +
568 +        schema = (ST_SCHEMA_TABLE*) p;
569 +
570 +        schema->fields_info = innodb_sys_tablestats_fields_info;
571 +        schema->fill_table = i_s_sys_tables_fill_table_stats;
572 +
573 +        DBUG_RETURN(0);
574 +}
575 +
576 +UNIV_INTERN struct st_mysql_plugin     i_s_innodb_sys_tablestats =
577 +{
578 +       /* the plugin type (a MYSQL_XXX_PLUGIN value) */
579 +       /* int */
580 +       STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
581 +
582 +       /* pointer to type-specific plugin descriptor */
583 +       /* void* */
584 +       STRUCT_FLD(info, &i_s_info),
585 +
586 +       /* plugin name */
587 +       /* const char* */
588 +       STRUCT_FLD(name, "INNODB_SYS_TABLESTATS"),
589 +
590 +       /* plugin author (for SHOW PLUGINS) */
591 +       /* const char* */
592 +       STRUCT_FLD(author, "Percona"),
593 +
594 +       /* general descriptive text (for SHOW PLUGINS) */
595 +       /* const char* */
596 +       STRUCT_FLD(descr, "InnoDB SYS_TABLESTATS"),
597 +
598 +       /* the plugin license (PLUGIN_LICENSE_XXX) */
599 +       /* int */
600 +       STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
601 +
602 +       /* the function to invoke when plugin is loaded */
603 +       /* int (*)(void*); */
604 +       STRUCT_FLD(init, innodb_sys_tablestats_init),
605 +
606 +       /* the function to invoke when plugin is unloaded */
607 +       /* int (*)(void*); */
608 +       STRUCT_FLD(deinit, i_s_common_deinit),
609 +
610 +       /* plugin version (for SHOW PLUGINS) */
611 +       /* unsigned int */
612 +       STRUCT_FLD(version, INNODB_VERSION_SHORT),
613 +
614 +       /* struct st_mysql_show_var* */
615 +       STRUCT_FLD(status_vars, NULL),
616 +
617 +       /* struct st_mysql_sys_var** */
618 +       STRUCT_FLD(system_vars, NULL),
619 +
620 +       /* reserved for dependency checking */
621 +       /* void* */
622 +       STRUCT_FLD(__reserved1, NULL),
623 +
624 +       /* flags for plugin */
625 +       /* unsigned long */
626 +       STRUCT_FLD(flags, 0UL)
627 +};
628 +
629 +/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_INDEXES */
630 +static ST_FIELD_INFO    innodb_sysindex_fields_info[] =
631 +{
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)},
640 +
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)},
649 +
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)},
658 +
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)},
667 +
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)},
676 +
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)},
685 +
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)},
694 +
695 +       END_OF_ST_FIELD_INFO
696 +};
697 +
698 +/**********************************************************************//**
699 +Function to populate the information_schema.innodb_sys_indexes table with
700 +collected index information
701 +@return 0 on success */
702 +static
703 +int
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 */
711 +{
712 +       Field**         fields;
713 +
714 +       DBUG_ENTER("i_s_dict_fill_sys_indexes");
715 +
716 +       fields = table_to_fill->field;
717 +
718 +       OK(fields[SYS_INDEX_ID]->store(longlong(index->id), TRUE));
719 +
720 +       OK(field_store_string(fields[SYS_INDEX_NAME], index->name));
721 +
722 +       OK(fields[SYS_INDEX_TABLE_ID]->store(longlong(table_id), TRUE));
723 +
724 +       OK(fields[SYS_INDEX_TYPE]->store(index->type));
725 +
726 +       OK(fields[SYS_INDEX_NUM_FIELDS]->store(index->n_fields));
727 +
728 +       OK(fields[SYS_INDEX_PAGE_NO]->store(index->page));
729 +
730 +       OK(fields[SYS_INDEX_SPACE]->store(index->space));
731 +
732 +       OK(schema_table_store_record(thd, table_to_fill));
733 +
734 +       DBUG_RETURN(0);
735 +}
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 */
740 +static
741 +int
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) */
747 +{
748 +        btr_pcur_t             pcur;
749 +       const rec_t*            rec;
750 +       mem_heap_t*             heap;
751 +       mtr_t                   mtr;
752 +
753 +       DBUG_ENTER("i_s_sys_indexes_fill_table");
754 +
755 +       /* deny access to non-superusers */
756 +       if (check_global_access(thd, PROCESS_ACL)) {
757 +
758 +                DBUG_RETURN(0);
759 +       }
760 +
761 +        heap = mem_heap_create(1000);
762 +        mutex_enter(&dict_sys->mutex);
763 +        mtr_start(&mtr);
764 +
765 +       /* Start scan the SYS_INDEXES table */
766 +       rec = dict_startscan_system(&pcur, &mtr, SYS_INDEXES);
767 +
768 +       /* Process each record in the table */
769 +       while (rec) {
770 +               const char*     err_msg;;
771 +               table_id_t      table_id;
772 +               dict_index_t    index_rec;
773 +
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,
777 +                                                      &table_id);
778 +
779 +               mtr_commit(&mtr);
780 +               mutex_exit(&dict_sys->mutex);
781 +
782 +               if (!err_msg) {
783 +                       i_s_dict_fill_sys_indexes(thd, table_id, &index_rec,
784 +                                                tables->table);
785 +               } else {
786 +                       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
787 +                                           ER_CANT_FIND_SYSTEM_REC,
788 +                                           err_msg);
789 +               }
790 +
791 +               mem_heap_empty(heap);
792 +
793 +               /* Get the next record */
794 +               mutex_enter(&dict_sys->mutex);
795 +               mtr_start(&mtr);
796 +               rec = dict_getnext_system(&pcur, &mtr);
797 +       }
798 +
799 +       mtr_commit(&mtr);
800 +       mutex_exit(&dict_sys->mutex);
801 +       mem_heap_free(heap);
802 +
803 +       DBUG_RETURN(0);
804 +}
805 +/*******************************************************************//**
806 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_indexes
807 +@return 0 on success */
808 +static
809 +int
810 +innodb_sys_indexes_init(
811 +/*====================*/
812 +        void*   p)      /*!< in/out: table schema object */
813 +{
814 +        ST_SCHEMA_TABLE*        schema;
815 +
816 +        DBUG_ENTER("innodb_sys_index_init");
817 +
818 +        schema = (ST_SCHEMA_TABLE*) p;
819 +
820 +        schema->fields_info = innodb_sysindex_fields_info;
821 +        schema->fill_table = i_s_sys_indexes_fill_table;
822 +
823 +        DBUG_RETURN(0);
824 +}
825 +
826 +UNIV_INTERN struct st_mysql_plugin     i_s_innodb_sys_indexes =
827 +{
828 +       /* the plugin type (a MYSQL_XXX_PLUGIN value) */
829 +       /* int */
830 +       STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
831 +
832 +       /* pointer to type-specific plugin descriptor */
833 +       /* void* */
834 +       STRUCT_FLD(info, &i_s_info),
835 +
836 +       /* plugin name */
837 +       /* const char* */
838 +       STRUCT_FLD(name, "INNODB_SYS_INDEXES"),
839 +
840 +       /* plugin author (for SHOW PLUGINS) */
841 +       /* const char* */
842 +       STRUCT_FLD(author, "Percona"),
843 +
844 +       /* general descriptive text (for SHOW PLUGINS) */
845 +       /* const char* */
846 +       STRUCT_FLD(descr, "InnoDB SYS_INDEXES"),
847 +
848 +       /* the plugin license (PLUGIN_LICENSE_XXX) */
849 +       /* int */
850 +       STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
851 +
852 +       /* the function to invoke when plugin is loaded */
853 +       /* int (*)(void*); */
854 +       STRUCT_FLD(init, innodb_sys_indexes_init),
855 +
856 +       /* the function to invoke when plugin is unloaded */
857 +       /* int (*)(void*); */
858 +       STRUCT_FLD(deinit, i_s_common_deinit),
859 +
860 +       /* plugin version (for SHOW PLUGINS) */
861 +       /* unsigned int */
862 +       STRUCT_FLD(version, INNODB_VERSION_SHORT),
863 +
864 +       /* struct st_mysql_show_var* */
865 +       STRUCT_FLD(status_vars, NULL),
866 +
867 +       /* struct st_mysql_sys_var** */
868 +       STRUCT_FLD(system_vars, NULL),
869 +
870 +       /* reserved for dependency checking */
871 +       /* void* */
872 +       STRUCT_FLD(__reserved1, NULL),
873 +
874 +       /* flags for plugin */
875 +       /* unsigned long */
876 +       STRUCT_FLD(flags, 0UL)
877 +};
878 +
879 +/* Fields of the dynamic table INFORMATION_SCHEMA.SYS_COLUMNS */
880 +static ST_FIELD_INFO    innodb_sys_columns_fields_info[] =
881 +{
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)},
890 +
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)},
899 +
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)},
908 +
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)},
917 +
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)},
926 +
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)},
935 +
936 +       END_OF_ST_FIELD_INFO
937 +};
938 +
939 +/**********************************************************************//**
940 +Function to populate the information_schema.innodb_sys_columns with
941 +related column information
942 +@return 0 on success */
943 +static
944 +int
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 */
953 +{
954 +       Field**         fields;
955 +
956 +       DBUG_ENTER("i_s_dict_fill_sys_columns");
957 +
958 +       fields = table_to_fill->field;
959 +
960 +       OK(fields[SYS_COLUMN_TABLE_ID]->store(longlong(table_id), TRUE));
961 +
962 +       OK(field_store_string(fields[SYS_COLUMN_NAME], col_name));
963 +
964 +       OK(fields[SYS_COLUMN_POSITION]->store(column->ind));
965 +
966 +       OK(fields[SYS_COLUMN_MTYPE]->store(column->mtype));
967 +
968 +       OK(fields[SYS_COLUMN__PRTYPE]->store(column->prtype));
969 +
970 +       OK(fields[SYS_COLUMN_COLUMN_LEN]->store(column->len));
971 +
972 +       OK(schema_table_store_record(thd, table_to_fill));
973 +
974 +       DBUG_RETURN(0);
975 +}
976 +/*******************************************************************//**
977 +Function to fill information_schema.innodb_sys_columns with information
978 +collected by scanning SYS_COLUMNS table.
979 +@return 0 on success */
980 +static
981 +int
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) */
987 +{
988 +        btr_pcur_t     pcur;
989 +       const rec_t*    rec;
990 +       const char*     col_name;
991 +       mem_heap_t*     heap;
992 +       mtr_t           mtr;
993 +
994 +       DBUG_ENTER("i_s_sys_columns_fill_table");
995 +
996 +       /* deny access to non-superusers */
997 +       if (check_global_access(thd, PROCESS_ACL)) {
998 +
999 +                DBUG_RETURN(0);
1000 +       }
1001 +
1002 +        heap = mem_heap_create(1000);
1003 +        mutex_enter(&dict_sys->mutex);
1004 +        mtr_start(&mtr);
1005 +
1006 +       rec = dict_startscan_system(&pcur, &mtr, SYS_COLUMNS);
1007 +
1008 +       while (rec) {
1009 +               const char*     err_msg;
1010 +               dict_col_t      column_rec;
1011 +               table_id_t      table_id;
1012 +
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);
1017 +
1018 +               mtr_commit(&mtr);
1019 +               mutex_exit(&dict_sys->mutex);
1020 +
1021 +               if (!err_msg) {
1022 +                       i_s_dict_fill_sys_columns(thd, table_id, col_name,
1023 +                                                &column_rec,
1024 +                                                tables->table);
1025 +               } else {
1026 +                       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1027 +                                           ER_CANT_FIND_SYSTEM_REC,
1028 +                                           err_msg);
1029 +               }
1030 +
1031 +               mem_heap_empty(heap);
1032 +
1033 +               /* Get the next record */
1034 +               mutex_enter(&dict_sys->mutex);
1035 +               mtr_start(&mtr);
1036 +               rec = dict_getnext_system(&pcur, &mtr);
1037 +       }
1038 +
1039 +       mtr_commit(&mtr);
1040 +       mutex_exit(&dict_sys->mutex);
1041 +       mem_heap_free(heap);
1042 +
1043 +       DBUG_RETURN(0);
1044 +}
1045 +/*******************************************************************//**
1046 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_columns
1047 +@return 0 on success */
1048 +static
1049 +int
1050 +innodb_sys_columns_init(
1051 +/*====================*/
1052 +        void*   p)      /*!< in/out: table schema object */
1053 +{
1054 +        ST_SCHEMA_TABLE*        schema;
1055 +
1056 +        DBUG_ENTER("innodb_sys_columns_init");
1057 +
1058 +        schema = (ST_SCHEMA_TABLE*) p;
1059 +
1060 +        schema->fields_info = innodb_sys_columns_fields_info;
1061 +        schema->fill_table = i_s_sys_columns_fill_table;
1062 +
1063 +        DBUG_RETURN(0);
1064 +}
1065 +
1066 +UNIV_INTERN struct st_mysql_plugin     i_s_innodb_sys_columns =
1067 +{
1068 +       /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1069 +       /* int */
1070 +       STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1071 +
1072 +       /* pointer to type-specific plugin descriptor */
1073 +       /* void* */
1074 +       STRUCT_FLD(info, &i_s_info),
1075 +
1076 +       /* plugin name */
1077 +       /* const char* */
1078 +       STRUCT_FLD(name, "INNODB_SYS_COLUMNS"),
1079 +
1080 +       /* plugin author (for SHOW PLUGINS) */
1081 +       /* const char* */
1082 +       STRUCT_FLD(author, "Percona"),
1083 +
1084 +       /* general descriptive text (for SHOW PLUGINS) */
1085 +       /* const char* */
1086 +       STRUCT_FLD(descr, "InnoDB SYS_COLUMNS"),
1087 +
1088 +       /* the plugin license (PLUGIN_LICENSE_XXX) */
1089 +       /* int */
1090 +       STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1091 +
1092 +       /* the function to invoke when plugin is loaded */
1093 +       /* int (*)(void*); */
1094 +       STRUCT_FLD(init, innodb_sys_columns_init),
1095 +
1096 +       /* the function to invoke when plugin is unloaded */
1097 +       /* int (*)(void*); */
1098 +       STRUCT_FLD(deinit, i_s_common_deinit),
1099 +
1100 +       /* plugin version (for SHOW PLUGINS) */
1101 +       /* unsigned int */
1102 +       STRUCT_FLD(version, INNODB_VERSION_SHORT),
1103 +
1104 +       /* struct st_mysql_show_var* */
1105 +       STRUCT_FLD(status_vars, NULL),
1106 +
1107 +       /* struct st_mysql_sys_var** */
1108 +       STRUCT_FLD(system_vars, NULL),
1109 +
1110 +       /* reserved for dependency checking */
1111 +       /* void* */
1112 +       STRUCT_FLD(__reserved1, NULL),
1113 +
1114 +       /* flags for plugin */
1115 +       /* unsigned long */
1116 +       STRUCT_FLD(flags, 0UL)
1117 +};
1118 +/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_fields */
1119 +static ST_FIELD_INFO    innodb_sys_fields_fields_info[] =
1120 +{
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)},
1129 +
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)},
1138 +
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)},
1147 +
1148 +       END_OF_ST_FIELD_INFO
1149 +};
1150 +
1151 +/**********************************************************************//**
1152 +Function to fill information_schema.innodb_sys_fields with information
1153 +collected by scanning SYS_FIELDS table.
1154 +@return 0 on success */
1155 +static
1156 +int
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 */
1164 +{
1165 +       Field**         fields;
1166 +
1167 +       DBUG_ENTER("i_s_dict_fill_sys_fields");
1168 +
1169 +       fields = table_to_fill->field;
1170 +
1171 +       OK(fields[SYS_FIELD_INDEX_ID]->store(longlong(index_id), TRUE));
1172 +
1173 +       OK(field_store_string(fields[SYS_FIELD_NAME], field->name));
1174 +
1175 +       OK(fields[SYS_FIELD_POS]->store(pos));
1176 +
1177 +       OK(schema_table_store_record(thd, table_to_fill));
1178 +
1179 +       DBUG_RETURN(0);
1180 +}
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
1184 +information
1185 +@return 0 on success */
1186 +static
1187 +int
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) */
1193 +{
1194 +        btr_pcur_t     pcur;
1195 +       const rec_t*    rec;
1196 +       mem_heap_t*     heap;
1197 +       index_id_t      last_id;
1198 +       mtr_t           mtr;
1199 +
1200 +       DBUG_ENTER("i_s_sys_fields_fill_table");
1201 +
1202 +       /* deny access to non-superusers */
1203 +       if (check_global_access(thd, PROCESS_ACL)) {
1204 +
1205 +                DBUG_RETURN(0);
1206 +       }
1207 +
1208 +        heap = mem_heap_create(1000);
1209 +        mutex_enter(&dict_sys->mutex);
1210 +        mtr_start(&mtr);
1211 +
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 */
1214 +       last_id = 0;
1215 +
1216 +       rec = dict_startscan_system(&pcur, &mtr, SYS_FIELDS);
1217 +
1218 +       while (rec) {
1219 +               ulint           pos;
1220 +               const char*     err_msg;
1221 +               index_id_t      index_id;
1222 +               dict_field_t    field_rec;
1223 +
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);
1228 +
1229 +               mtr_commit(&mtr);
1230 +               mutex_exit(&dict_sys->mutex);
1231 +
1232 +               if (!err_msg) {
1233 +                       i_s_dict_fill_sys_fields(thd, index_id, &field_rec,
1234 +                                                pos, tables->table);
1235 +                       last_id = index_id;
1236 +               } else {
1237 +                       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1238 +                                           ER_CANT_FIND_SYSTEM_REC,
1239 +                                           err_msg);
1240 +               }
1241 +
1242 +               mem_heap_empty(heap);
1243 +
1244 +               /* Get the next record */
1245 +               mutex_enter(&dict_sys->mutex);
1246 +               mtr_start(&mtr);
1247 +               rec = dict_getnext_system(&pcur, &mtr);
1248 +       }
1249 +
1250 +       mtr_commit(&mtr);
1251 +       mutex_exit(&dict_sys->mutex);
1252 +       mem_heap_free(heap);
1253 +
1254 +       DBUG_RETURN(0);
1255 +}
1256 +/*******************************************************************//**
1257 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_fields
1258 +@return 0 on success */
1259 +static
1260 +int
1261 +innodb_sys_fields_init(
1262 +/*===================*/
1263 +        void*   p)      /*!< in/out: table schema object */
1264 +{
1265 +        ST_SCHEMA_TABLE*        schema;
1266 +
1267 +        DBUG_ENTER("innodb_sys_field_init");
1268 +
1269 +        schema = (ST_SCHEMA_TABLE*) p;
1270 +
1271 +        schema->fields_info = innodb_sys_fields_fields_info;
1272 +        schema->fill_table = i_s_sys_fields_fill_table;
1273 +
1274 +        DBUG_RETURN(0);
1275 +}
1276 +
1277 +UNIV_INTERN struct st_mysql_plugin     i_s_innodb_sys_fields =
1278 +{
1279 +       /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1280 +       /* int */
1281 +       STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1282 +
1283 +       /* pointer to type-specific plugin descriptor */
1284 +       /* void* */
1285 +       STRUCT_FLD(info, &i_s_info),
1286 +
1287 +       /* plugin name */
1288 +       /* const char* */
1289 +       STRUCT_FLD(name, "INNODB_SYS_FIELDS"),
1290 +
1291 +       /* plugin author (for SHOW PLUGINS) */
1292 +       /* const char* */
1293 +       STRUCT_FLD(author, "Percona"),
1294 +
1295 +       /* general descriptive text (for SHOW PLUGINS) */
1296 +       /* const char* */
1297 +       STRUCT_FLD(descr, "InnoDB SYS_FIELDS"),
1298 +
1299 +       /* the plugin license (PLUGIN_LICENSE_XXX) */
1300 +       /* int */
1301 +       STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1302 +
1303 +       /* the function to invoke when plugin is loaded */
1304 +       /* int (*)(void*); */
1305 +       STRUCT_FLD(init, innodb_sys_fields_init),
1306 +
1307 +       /* the function to invoke when plugin is unloaded */
1308 +       /* int (*)(void*); */
1309 +       STRUCT_FLD(deinit, i_s_common_deinit),
1310 +
1311 +       /* plugin version (for SHOW PLUGINS) */
1312 +       /* unsigned int */
1313 +       STRUCT_FLD(version, INNODB_VERSION_SHORT),
1314 +
1315 +       /* struct st_mysql_show_var* */
1316 +       STRUCT_FLD(status_vars, NULL),
1317 +
1318 +       /* struct st_mysql_sys_var** */
1319 +       STRUCT_FLD(system_vars, NULL),
1320 +
1321 +       /* reserved for dependency checking */
1322 +       /* void* */
1323 +       STRUCT_FLD(__reserved1, NULL),
1324 +
1325 +       /* flags for plugin */
1326 +       /* unsigned long */
1327 +       STRUCT_FLD(flags, 0UL)
1328 +};
1329 +
1330 +/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign */
1331 +static ST_FIELD_INFO    innodb_sys_foreign_fields_info[] =
1332 +{
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)},
1341 +
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)},
1350 +
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)},
1359 +
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)},
1368 +
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)},
1377 +
1378 +       END_OF_ST_FIELD_INFO
1379 +};
1380 +
1381 +/**********************************************************************//**
1382 +Function to fill information_schema.innodb_sys_foreign with information
1383 +collected by scanning SYS_FOREIGN table.
1384 +@return 0 on success */
1385 +static
1386 +int
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 */
1392 +{
1393 +       Field**         fields;
1394 +
1395 +       DBUG_ENTER("i_s_dict_fill_sys_foreign");
1396 +
1397 +       fields = table_to_fill->field;
1398 +
1399 +       OK(field_store_string(fields[SYS_FOREIGN_ID], foreign->id));
1400 +
1401 +       OK(field_store_string(fields[SYS_FOREIGN_FOR_NAME],
1402 +                             foreign->foreign_table_name));
1403 +
1404 +       OK(field_store_string(fields[SYS_FOREIGN_REF_NAME],
1405 +                             foreign->referenced_table_name));
1406 +
1407 +       OK(fields[SYS_FOREIGN_NUM_COL]->store(foreign->n_fields));
1408 +
1409 +       OK(fields[SYS_FOREIGN_TYPE]->store(foreign->type));
1410 +
1411 +       OK(schema_table_store_record(thd, table_to_fill));
1412 +
1413 +       DBUG_RETURN(0);
1414 +}
1415 +/*******************************************************************//**
1416 +Function to populate INFORMATION_SCHEMA.innodb_sys_foreign table. Loop
1417 +through each record in SYS_FOREIGN, and extract the foreign key
1418 +information.
1419 +@return 0 on success */
1420 +static
1421 +int
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) */
1427 +{
1428 +        btr_pcur_t     pcur;
1429 +       const rec_t*    rec;
1430 +       mem_heap_t*     heap;
1431 +       mtr_t           mtr;
1432 +
1433 +       DBUG_ENTER("i_s_sys_foreign_fill_table");
1434 +
1435 +       /* deny access to non-superusers */
1436 +       if (check_global_access(thd, PROCESS_ACL)) {
1437 +
1438 +                DBUG_RETURN(0);
1439 +       }
1440 +
1441 +        heap = mem_heap_create(1000);
1442 +        mutex_enter(&dict_sys->mutex);
1443 +        mtr_start(&mtr);
1444 +
1445 +       rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN);
1446 +
1447 +       while (rec) {
1448 +               const char*     err_msg;
1449 +               dict_foreign_t  foreign_rec;
1450 +
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);
1454 +
1455 +               mtr_commit(&mtr);
1456 +               mutex_exit(&dict_sys->mutex);
1457 +
1458 +               if (!err_msg) {
1459 +                       i_s_dict_fill_sys_foreign(thd, &foreign_rec,
1460 +                                                tables->table);
1461 +               } else {
1462 +                       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1463 +                                           ER_CANT_FIND_SYSTEM_REC,
1464 +                                           err_msg);
1465 +               }
1466 +
1467 +               mem_heap_empty(heap);
1468 +
1469 +               /* Get the next record */
1470 +               mtr_start(&mtr);
1471 +               mutex_enter(&dict_sys->mutex);
1472 +               rec = dict_getnext_system(&pcur, &mtr);
1473 +       }
1474 +
1475 +       mtr_commit(&mtr);
1476 +       mutex_exit(&dict_sys->mutex);
1477 +       mem_heap_free(heap);
1478 +
1479 +       DBUG_RETURN(0);
1480 +}
1481 +/*******************************************************************//**
1482 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign
1483 +@return 0 on success */
1484 +static
1485 +int
1486 +innodb_sys_foreign_init(
1487 +/*====================*/
1488 +        void*   p)      /*!< in/out: table schema object */
1489 +{
1490 +        ST_SCHEMA_TABLE*        schema;
1491 +
1492 +        DBUG_ENTER("innodb_sys_foreign_init");
1493 +
1494 +        schema = (ST_SCHEMA_TABLE*) p;
1495 +
1496 +        schema->fields_info = innodb_sys_foreign_fields_info;
1497 +        schema->fill_table = i_s_sys_foreign_fill_table;
1498 +
1499 +        DBUG_RETURN(0);
1500 +}
1501 +
1502 +UNIV_INTERN struct st_mysql_plugin     i_s_innodb_sys_foreign =
1503 +{
1504 +       /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1505 +       /* int */
1506 +       STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1507 +
1508 +       /* pointer to type-specific plugin descriptor */
1509 +       /* void* */
1510 +       STRUCT_FLD(info, &i_s_info),
1511 +
1512 +       /* plugin name */
1513 +       /* const char* */
1514 +       STRUCT_FLD(name, "INNODB_SYS_FOREIGN"),
1515 +
1516 +       /* plugin author (for SHOW PLUGINS) */
1517 +       /* const char* */
1518 +       STRUCT_FLD(author, "Percona"),
1519 +
1520 +       /* general descriptive text (for SHOW PLUGINS) */
1521 +       /* const char* */
1522 +       STRUCT_FLD(descr, "InnoDB SYS_FOREIGN"),
1523 +
1524 +       /* the plugin license (PLUGIN_LICENSE_XXX) */
1525 +       /* int */
1526 +       STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1527 +
1528 +       /* the function to invoke when plugin is loaded */
1529 +       /* int (*)(void*); */
1530 +       STRUCT_FLD(init, innodb_sys_foreign_init),
1531 +
1532 +       /* the function to invoke when plugin is unloaded */
1533 +       /* int (*)(void*); */
1534 +       STRUCT_FLD(deinit, i_s_common_deinit),
1535 +
1536 +       /* plugin version (for SHOW PLUGINS) */
1537 +       /* unsigned int */
1538 +       STRUCT_FLD(version, INNODB_VERSION_SHORT),
1539 +
1540 +       /* struct st_mysql_show_var* */
1541 +       STRUCT_FLD(status_vars, NULL),
1542 +
1543 +       /* struct st_mysql_sys_var** */
1544 +       STRUCT_FLD(system_vars, NULL),
1545 +
1546 +       /* reserved for dependency checking */
1547 +       /* void* */
1548 +       STRUCT_FLD(__reserved1, NULL),
1549 +
1550 +       /* flags for plugin */
1551 +       /* unsigned long */
1552 +       STRUCT_FLD(flags, 0UL)
1553 +};
1554 +/* Fields of the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign_cols */
1555 +static ST_FIELD_INFO    innodb_sys_foreign_cols_fields_info[] =
1556 +{
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)},
1565 +
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)},
1574 +
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)},
1583 +
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)},
1592 +
1593 +       END_OF_ST_FIELD_INFO
1594 +};
1595 +
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 */
1600 +static
1601 +int
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
1608 +                                       name */
1609 +       ulint           pos,            /*!< in: column position */
1610 +       TABLE*          table_to_fill)  /*!< in/out: fill this table */
1611 +{
1612 +       Field**         fields;
1613 +
1614 +       DBUG_ENTER("i_s_dict_fill_sys_foreign_cols");
1615 +
1616 +       fields = table_to_fill->field;
1617 +
1618 +       OK(field_store_string(fields[SYS_FOREIGN_COL_ID], name));
1619 +
1620 +       OK(field_store_string(fields[SYS_FOREIGN_COL_FOR_NAME], for_col_name));
1621 +
1622 +       OK(field_store_string(fields[SYS_FOREIGN_COL_REF_NAME], ref_col_name));
1623 +
1624 +       OK(fields[SYS_FOREIGN_COL_POS]->store(pos));
1625 +
1626 +       OK(schema_table_store_record(thd, table_to_fill));
1627 +
1628 +       DBUG_RETURN(0);
1629 +}
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 */
1635 +static
1636 +int
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) */
1642 +{
1643 +        btr_pcur_t     pcur;
1644 +       const rec_t*    rec;
1645 +       mem_heap_t*     heap;
1646 +       mtr_t           mtr;
1647 +
1648 +       DBUG_ENTER("i_s_sys_foreign_cols_fill_table");
1649 +
1650 +       /* deny access to non-superusers */
1651 +       if (check_global_access(thd, PROCESS_ACL)) {
1652 +                DBUG_RETURN(0);
1653 +       }
1654 +
1655 +        heap = mem_heap_create(1000);
1656 +        mutex_enter(&dict_sys->mutex);
1657 +        mtr_start(&mtr);
1658 +
1659 +       rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN_COLS);
1660 +
1661 +       while (rec) {
1662 +               const char*     err_msg;
1663 +               const char*     name;
1664 +               const char*     for_col_name;
1665 +               const char*     ref_col_name;
1666 +               ulint           pos;
1667 +
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);
1671 +
1672 +               mtr_commit(&mtr);
1673 +               mutex_exit(&dict_sys->mutex);
1674 +
1675 +               if (!err_msg) {
1676 +                       i_s_dict_fill_sys_foreign_cols(
1677 +                               thd, name, for_col_name, ref_col_name, pos,
1678 +                               tables->table);
1679 +               } else {
1680 +                       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
1681 +                                           ER_CANT_FIND_SYSTEM_REC,
1682 +                                           err_msg);
1683 +               }
1684 +
1685 +               mem_heap_empty(heap);
1686 +
1687 +               /* Get the next record */
1688 +               mutex_enter(&dict_sys->mutex);
1689 +               mtr_start(&mtr);
1690 +               rec = dict_getnext_system(&pcur, &mtr);
1691 +       }
1692 +
1693 +       mtr_commit(&mtr);
1694 +       mutex_exit(&dict_sys->mutex);
1695 +       mem_heap_free(heap);
1696 +
1697 +       DBUG_RETURN(0);
1698 +}
1699 +/*******************************************************************//**
1700 +Bind the dynamic table INFORMATION_SCHEMA.innodb_sys_foreign_cols
1701 +@return 0 on success */
1702 +static
1703 +int
1704 +innodb_sys_foreign_cols_init(
1705 +/*========================*/
1706 +        void*   p)      /*!< in/out: table schema object */
1707 +{
1708 +        ST_SCHEMA_TABLE*        schema;
1709 +
1710 +        DBUG_ENTER("innodb_sys_foreign_cols_init");
1711 +
1712 +        schema = (ST_SCHEMA_TABLE*) p;
1713 +
1714 +        schema->fields_info = innodb_sys_foreign_cols_fields_info;
1715 +        schema->fill_table = i_s_sys_foreign_cols_fill_table;
1716 +
1717 +        DBUG_RETURN(0);
1718 +}
1719 +
1720 +UNIV_INTERN struct st_mysql_plugin     i_s_innodb_sys_foreign_cols =
1721 +{
1722 +       /* the plugin type (a MYSQL_XXX_PLUGIN value) */
1723 +       /* int */
1724 +       STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
1725 +
1726 +       /* pointer to type-specific plugin descriptor */
1727 +       /* void* */
1728 +       STRUCT_FLD(info, &i_s_info),
1729 +
1730 +       /* plugin name */
1731 +       /* const char* */
1732 +       STRUCT_FLD(name, "INNODB_SYS_FOREIGN_COLS"),
1733 +
1734 +       /* plugin author (for SHOW PLUGINS) */
1735 +       /* const char* */
1736 +       STRUCT_FLD(author, "Percona"),
1737 +
1738 +       /* general descriptive text (for SHOW PLUGINS) */
1739 +       /* const char* */
1740 +       STRUCT_FLD(descr, "InnoDB SYS_FOREIGN_COLS"),
1741 +
1742 +       /* the plugin license (PLUGIN_LICENSE_XXX) */
1743 +       /* int */
1744 +       STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
1745 +
1746 +       /* the function to invoke when plugin is loaded */
1747 +       /* int (*)(void*); */
1748 +       STRUCT_FLD(init, innodb_sys_foreign_cols_init),
1749 +
1750 +       /* the function to invoke when plugin is unloaded */
1751 +       /* int (*)(void*); */
1752 +       STRUCT_FLD(deinit, i_s_common_deinit),
1753 +
1754 +       /* plugin version (for SHOW PLUGINS) */
1755 +       /* unsigned int */
1756 +       STRUCT_FLD(version, INNODB_VERSION_SHORT),
1757 +
1758 +       /* struct st_mysql_show_var* */
1759 +       STRUCT_FLD(status_vars, NULL),
1760 +
1761 +       /* struct st_mysql_sys_var** */
1762 +       STRUCT_FLD(system_vars, NULL),
1763 +
1764 +       /* reserved for dependency checking */
1765 +       /* void* */
1766 +       STRUCT_FLD(__reserved1, NULL),
1767 +
1768 +       /* flags for plugin */
1769 +       /* unsigned long */
1770 +       STRUCT_FLD(flags, 0UL)
1771 +};
1772 +
1773  /***********************************************************************
1774  */
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
1778 @@ -35,6 +35,13 @@
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;
1790  
1791  #endif /* i_s_h */
This page took 1.634831 seconds and 2 git commands to generate.