1
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
/* Function with list databases, tables or fields */
19
#include "mysql_priv.h"
20
#include "sql_select.h" // For select_describe
22
#include "repl_failsafe.h"
25
#include "sql_trigger.h"
27
#include "contributors.h"
28
#ifdef HAVE_EVENT_SCHEDULER
30
#include "event_data_objects.h"
34
#define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
36
#ifdef WITH_PARTITION_STORAGE_ENGINE
37
#include "ha_partition.h"
39
enum enum_i_s_events_fields
67
#ifndef NO_EMBEDDED_ACCESS_CHECKS
68
static const char *grant_names[]={
69
"select","insert","update","delete","create","drop","reload","shutdown",
70
"process","file","grant","references","index","alter"};
72
static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
77
static void store_key_options(THD *thd, String *packet, TABLE *table,
81
append_algorithm(TABLE_LIST *table, String *buff);
83
static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table);
85
/***************************************************************************
86
** List all table types supported
87
***************************************************************************/
89
static int make_version_string(char *buf, int buf_length, uint version)
91
return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
94
static my_bool show_plugins(THD *thd, plugin_ref plugin,
97
TABLE *table= (TABLE*) arg;
98
struct st_mysql_plugin *plug= plugin_decl(plugin);
99
struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
100
CHARSET_INFO *cs= system_charset_info;
101
char version_buf[20];
103
restore_record(table, s->default_values);
105
table->field[0]->store(plugin_name(plugin)->str,
106
plugin_name(plugin)->length, cs);
108
table->field[1]->store(version_buf,
109
make_version_string(version_buf, sizeof(version_buf), plug->version),
113
switch (plugin_state(plugin)) {
114
/* case PLUGIN_IS_FREED: does not happen */
115
case PLUGIN_IS_DELETED:
116
table->field[2]->store(STRING_WITH_LEN("DELETED"), cs);
118
case PLUGIN_IS_UNINITIALIZED:
119
table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs);
121
case PLUGIN_IS_READY:
122
table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
124
case PLUGIN_IS_DISABLED:
125
table->field[2]->store(STRING_WITH_LEN("DISABLED"), cs);
131
table->field[3]->store(plugin_type_names[plug->type].str,
132
plugin_type_names[plug->type].length,
134
table->field[4]->store(version_buf,
135
make_version_string(version_buf, sizeof(version_buf),
136
*(uint *)plug->info), cs);
140
table->field[5]->store(plugin_dl->dl.str, plugin_dl->dl.length, cs);
141
table->field[5]->set_notnull();
142
table->field[6]->store(version_buf,
143
make_version_string(version_buf, sizeof(version_buf),
146
table->field[6]->set_notnull();
150
table->field[5]->set_null();
151
table->field[6]->set_null();
157
table->field[7]->store(plug->author, strlen(plug->author), cs);
158
table->field[7]->set_notnull();
161
table->field[7]->set_null();
165
table->field[8]->store(plug->descr, strlen(plug->descr), cs);
166
table->field[8]->set_notnull();
169
table->field[8]->set_null();
171
switch (plug->license) {
172
case PLUGIN_LICENSE_GPL:
173
table->field[9]->store(PLUGIN_LICENSE_GPL_STRING,
174
strlen(PLUGIN_LICENSE_GPL_STRING), cs);
176
case PLUGIN_LICENSE_BSD:
177
table->field[9]->store(PLUGIN_LICENSE_BSD_STRING,
178
strlen(PLUGIN_LICENSE_BSD_STRING), cs);
181
table->field[9]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
182
strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
185
table->field[9]->set_notnull();
187
return schema_table_store_record(thd, table);
191
int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond)
193
DBUG_ENTER("fill_plugins");
194
TABLE *table= tables->table;
196
if (plugin_foreach_with_mask(thd, show_plugins, MYSQL_ANY_PLUGIN,
197
~PLUGIN_IS_FREED, table))
204
/***************************************************************************
206
** If you can update it, you get to be in it :)
207
***************************************************************************/
209
bool mysqld_show_authors(THD *thd)
211
List<Item> field_list;
212
Protocol *protocol= thd->protocol;
213
DBUG_ENTER("mysqld_show_authors");
215
field_list.push_back(new Item_empty_string("Name",40));
216
field_list.push_back(new Item_empty_string("Location",40));
217
field_list.push_back(new Item_empty_string("Comment",80));
219
if (protocol->send_fields(&field_list,
220
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
223
show_table_authors_st *authors;
224
for (authors= show_table_authors; authors->name; authors++)
226
protocol->prepare_for_resend();
227
protocol->store(authors->name, system_charset_info);
228
protocol->store(authors->location, system_charset_info);
229
protocol->store(authors->comment, system_charset_info);
230
if (protocol->write())
238
/***************************************************************************
239
** List all Contributors.
240
** Please get permission before updating
241
***************************************************************************/
243
bool mysqld_show_contributors(THD *thd)
245
List<Item> field_list;
246
Protocol *protocol= thd->protocol;
247
DBUG_ENTER("mysqld_show_contributors");
249
field_list.push_back(new Item_empty_string("Name",40));
250
field_list.push_back(new Item_empty_string("Location",40));
251
field_list.push_back(new Item_empty_string("Comment",80));
253
if (protocol->send_fields(&field_list,
254
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
257
show_table_contributors_st *contributors;
258
for (contributors= show_table_contributors; contributors->name; contributors++)
260
protocol->prepare_for_resend();
261
protocol->store(contributors->name, system_charset_info);
262
protocol->store(contributors->location, system_charset_info);
263
protocol->store(contributors->comment, system_charset_info);
264
if (protocol->write())
272
/***************************************************************************
273
List all privileges supported
274
***************************************************************************/
276
struct show_privileges_st {
277
const char *privilege;
282
static struct show_privileges_st sys_privileges[]=
284
{"Alter", "Tables", "To alter the table"},
285
{"Alter routine", "Functions,Procedures", "To alter or drop stored functions/procedures"},
286
{"Create", "Databases,Tables,Indexes", "To create new databases and tables"},
287
{"Create routine","Databases","To use CREATE FUNCTION/PROCEDURE"},
288
{"Create temporary tables","Databases","To use CREATE TEMPORARY TABLE"},
289
{"Create view", "Tables", "To create new views"},
290
{"Create user", "Server Admin", "To create new users"},
291
{"Delete", "Tables", "To delete existing rows"},
292
{"Drop", "Databases,Tables", "To drop databases, tables, and views"},
293
#ifdef HAVE_EVENT_SCHEDULER
294
{"Event","Server Admin","To create, alter, drop and execute events"},
296
{"Execute", "Functions,Procedures", "To execute stored routines"},
297
{"File", "File access on server", "To read and write files on the server"},
298
{"Grant option", "Databases,Tables,Functions,Procedures", "To give to other users those privileges you possess"},
299
{"Index", "Tables", "To create or drop indexes"},
300
{"Insert", "Tables", "To insert data into tables"},
301
{"Lock tables","Databases","To use LOCK TABLES (together with SELECT privilege)"},
302
{"Process", "Server Admin", "To view the plain text of currently executing queries"},
303
{"References", "Databases,Tables", "To have references on tables"},
304
{"Reload", "Server Admin", "To reload or refresh tables, logs and privileges"},
305
{"Replication client","Server Admin","To ask where the slave or master servers are"},
306
{"Replication slave","Server Admin","To read binary log events from the master"},
307
{"Select", "Tables", "To retrieve rows from table"},
308
{"Show databases","Server Admin","To see all databases with SHOW DATABASES"},
309
{"Show view","Tables","To see views with SHOW CREATE VIEW"},
310
{"Shutdown","Server Admin", "To shut down the server"},
311
{"Super","Server Admin","To use KILL thread, SET GLOBAL, CHANGE MASTER, etc."},
312
{"Trigger","Tables", "To use triggers"},
313
{"Update", "Tables", "To update existing rows"},
314
{"Usage","Server Admin","No privileges - allow connect only"},
315
{NullS, NullS, NullS}
318
bool mysqld_show_privileges(THD *thd)
320
List<Item> field_list;
321
Protocol *protocol= thd->protocol;
322
DBUG_ENTER("mysqld_show_privileges");
324
field_list.push_back(new Item_empty_string("Privilege",10));
325
field_list.push_back(new Item_empty_string("Context",15));
326
field_list.push_back(new Item_empty_string("Comment",NAME_CHAR_LEN));
328
if (protocol->send_fields(&field_list,
329
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
332
show_privileges_st *privilege= sys_privileges;
333
for (privilege= sys_privileges; privilege->privilege ; privilege++)
335
protocol->prepare_for_resend();
336
protocol->store(privilege->privilege, system_charset_info);
337
protocol->store(privilege->context, system_charset_info);
338
protocol->store(privilege->comment, system_charset_info);
339
if (protocol->write())
347
/***************************************************************************
348
List all column types
349
***************************************************************************/
351
struct show_column_type_st
355
const char *min_value;
356
const char *max_value;
359
const char *nullable;
360
const char *auto_increment;
361
const char *unsigned_attr;
362
const char *zerofill;
363
const char *searchable;
364
const char *case_sensitivity;
365
const char *default_value;
369
/* TODO: Add remaning types */
371
static struct show_column_type_st sys_column_types[]=
374
1, "-128", "127", 0, 0, "YES", "YES",
375
"NO", "YES", "YES", "NO", "NULL,0",
376
"A very small integer"},
378
1, "0" , "255", 0, 0, "YES", "YES",
379
"YES", "YES", "YES", "NO", "NULL,0",
380
"A very small integer"},
383
bool mysqld_show_column_types(THD *thd)
385
List<Item> field_list;
386
Protocol *protocol= thd->protocol;
387
DBUG_ENTER("mysqld_show_column_types");
389
field_list.push_back(new Item_empty_string("Type",30));
390
field_list.push_back(new Item_int("Size",(longlong) 1,
391
MY_INT64_NUM_DECIMAL_DIGITS));
392
field_list.push_back(new Item_empty_string("Min_Value",20));
393
field_list.push_back(new Item_empty_string("Max_Value",20));
394
field_list.push_back(new Item_return_int("Prec", 4, MYSQL_TYPE_SHORT));
395
field_list.push_back(new Item_return_int("Scale", 4, MYSQL_TYPE_SHORT));
396
field_list.push_back(new Item_empty_string("Nullable",4));
397
field_list.push_back(new Item_empty_string("Auto_Increment",4));
398
field_list.push_back(new Item_empty_string("Unsigned",4));
399
field_list.push_back(new Item_empty_string("Zerofill",4));
400
field_list.push_back(new Item_empty_string("Searchable",4));
401
field_list.push_back(new Item_empty_string("Case_Sensitive",4));
402
field_list.push_back(new Item_empty_string("Default",NAME_CHAR_LEN));
403
field_list.push_back(new Item_empty_string("Comment",NAME_CHAR_LEN));
405
if (protocol->send_fields(&field_list,
406
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
409
/* TODO: Change the loop to not use 'i' */
410
for (uint i=0; i < sizeof(sys_column_types)/sizeof(sys_column_types[0]); i++)
412
protocol->prepare_for_resend();
413
protocol->store(sys_column_types[i].type, system_charset_info);
414
protocol->store((ulonglong) sys_column_types[i].size);
415
protocol->store(sys_column_types[i].min_value, system_charset_info);
416
protocol->store(sys_column_types[i].max_value, system_charset_info);
417
protocol->store_short((longlong) sys_column_types[i].precision);
418
protocol->store_short((longlong) sys_column_types[i].scale);
419
protocol->store(sys_column_types[i].nullable, system_charset_info);
420
protocol->store(sys_column_types[i].auto_increment, system_charset_info);
421
protocol->store(sys_column_types[i].unsigned_attr, system_charset_info);
422
protocol->store(sys_column_types[i].zerofill, system_charset_info);
423
protocol->store(sys_column_types[i].searchable, system_charset_info);
424
protocol->store(sys_column_types[i].case_sensitivity, system_charset_info);
425
protocol->store(sys_column_types[i].default_value, system_charset_info);
426
protocol->store(sys_column_types[i].comment, system_charset_info);
427
if (protocol->write())
436
find_files() - find files in a given directory.
441
files put found files in this list
442
db database name to set in TABLE_LIST structure
443
path path to database
444
wild filter for found files
445
dir read databases in path if TRUE, read .frm files in
449
FIND_FILES_OK success
450
FIND_FILES_OOM out of memory error
451
FIND_FILES_DIR no such directory, or directory can't be read
456
find_files(THD *thd, List<LEX_STRING> *files, const char *db,
457
const char *path, const char *wild, bool dir)
463
LEX_STRING *file_name= 0;
465
#ifndef NO_EMBEDDED_ACCESS_CHECKS
466
uint col_access=thd->col_access;
469
TABLE_LIST table_list;
470
DBUG_ENTER("find_files");
477
wild_length= strlen(wild);
482
bzero((char*) &table_list,sizeof(table_list));
484
if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
486
if (my_errno == ENOENT)
487
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db);
489
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
490
DBUG_RETURN(FIND_FILES_DIR);
493
for (i=0 ; i < (uint) dirp->number_off_files ; i++)
495
char uname[NAME_LEN + 1]; /* Unencoded name */
496
file=dirp->dir_entry+i;
498
{ /* Return databases */
499
if ((file->name[0] == '.' &&
500
((file->name[1] == '.' && file->name[2] == '\0') ||
501
file->name[1] == '\0')))
502
continue; /* . or .. */
505
char buff[FN_REFLEN];
506
if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym"))
508
/* Only show the sym file if it points to a directory */
510
*ext=0; /* Remove extension */
511
unpack_dirname(buff, file->name);
513
if (end != buff && end[-1] == FN_LIBCHAR)
514
end[-1]= 0; // Remove end FN_LIBCHAR
515
if (!my_stat(buff, file->mystat, MYF(0)))
519
if (!MY_S_ISDIR(file->mystat->st_mode))
522
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
523
if (wild && wild_compare(uname, wild, 0))
526
thd->make_lex_string(file_name, uname, file_name_len, TRUE)))
529
DBUG_RETURN(FIND_FILES_OOM);
534
// Return only .frm files which aren't temp files.
535
if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) ||
536
is_prefix(file->name, tmp_file_prefix))
539
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
542
if (lower_case_table_names)
544
if (my_wildcmp(files_charset_info,
545
uname, uname + file_name_len,
546
wild, wild + wild_length,
547
wild_prefix, wild_one,wild_many))
550
else if (wild_compare(uname, wild, 0))
554
#ifndef NO_EMBEDDED_ACCESS_CHECKS
555
/* Don't show tables where we don't have any privileges */
556
if (db && !(col_access & TABLE_ACLS))
558
table_list.db= (char*) db;
559
table_list.db_length= strlen(db);
560
table_list.table_name= uname;
561
table_list.table_name_length= file_name_len;
562
table_list.grant.privilege=col_access;
563
if (check_grant(thd, TABLE_ACLS, &table_list, 1, 1, 1))
568
thd->make_lex_string(file_name, uname, file_name_len, TRUE)) ||
569
files->push_back(file_name))
572
DBUG_RETURN(FIND_FILES_OOM);
575
DBUG_PRINT("info",("found: %d files", files->elements));
578
VOID(ha_find_files(thd, db, path, wild, dir, files));
580
DBUG_RETURN(FIND_FILES_OK);
585
An Internal_error_handler that suppresses errors regarding views'
586
underlying tables that occur during privilege checking within SHOW CREATE
587
VIEW commands. This happens in the cases when
589
- A view's underlying table (e.g. referenced in its SELECT list) does not
590
exist. There should not be an error as no attempt was made to access it
593
- Access is denied for some table, column, function or stored procedure
594
such as mentioned above. This error gets raised automatically, since we
595
can't untangle its access checking from that of the view itself.
597
class Show_create_error_handler : public Internal_error_handler {
599
TABLE_LIST *m_top_view;
601
Security_context *m_sctx;
603
char m_view_access_denied_message[MYSQL_ERRMSG_SIZE];
604
char *m_view_access_denied_message_ptr;
609
Creates a new Show_create_error_handler for the particular security
612
@thd Thread context, used for security context information if needed.
613
@top_view The view. We do not verify at this point that top_view is in
614
fact a view since, alas, these things do not stay constant.
616
explicit Show_create_error_handler(THD *thd, TABLE_LIST *top_view) :
617
m_top_view(top_view), m_handling(FALSE),
618
m_view_access_denied_message_ptr(NULL)
621
m_sctx = test(m_top_view->security_ctx) ?
622
m_top_view->security_ctx : thd->security_ctx;
626
Lazy instantiation of 'view access denied' message. The purpose of the
627
Show_create_error_handler is to hide details of underlying tables for
628
which we have no privileges behind ER_VIEW_INVALID messages. But this
629
obviously does not apply if we lack privileges on the view itself.
630
Unfortunately the information about for which table privilege checking
631
failed is not available at this point. The only way for us to check is by
632
reconstructing the actual error message and see if it's the same.
634
char* get_view_access_denied_message()
636
if (!m_view_access_denied_message_ptr)
638
m_view_access_denied_message_ptr= m_view_access_denied_message;
639
my_snprintf(m_view_access_denied_message, MYSQL_ERRMSG_SIZE,
640
ER(ER_TABLEACCESS_DENIED_ERROR), "SHOW VIEW",
642
m_sctx->host_or_ip, m_top_view->get_table_name());
644
return m_view_access_denied_message_ptr;
647
bool handle_error(uint sql_errno, const char *message,
648
MYSQL_ERROR::enum_warning_level level, THD *thd) {
650
The handler does not handle the errors raised by itself.
651
At this point we know if top_view is really a view.
653
if (m_handling || !m_top_view->view)
662
case ER_TABLEACCESS_DENIED_ERROR:
663
if (!strcmp(get_view_access_denied_message(), message))
665
/* Access to top view is not granted, don't interfere. */
669
case ER_COLUMNACCESS_DENIED_ERROR:
670
case ER_VIEW_NO_EXPLAIN: /* Error was anonymized, ignore all the same. */
671
case ER_PROCACCESS_DENIED_ERROR:
675
case ER_NO_SUCH_TABLE:
676
/* Established behavior: warn if underlying tables are missing. */
677
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
680
m_top_view->get_db_name(),
681
m_top_view->get_table_name());
685
case ER_SP_DOES_NOT_EXIST:
686
/* Established behavior: warn if underlying functions are missing. */
687
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
690
m_top_view->get_db_name(),
691
m_top_view->get_table_name());
705
mysqld_show_create(THD *thd, TABLE_LIST *table_list)
707
Protocol *protocol= thd->protocol;
709
String buffer(buff, sizeof(buff), system_charset_info);
710
DBUG_ENTER("mysqld_show_create");
711
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
712
table_list->table_name));
714
/* We want to preserve the tree for views. */
715
thd->lex->view_prepare_mode= TRUE;
718
Show_create_error_handler view_error_suppressor(thd, table_list);
719
thd->push_internal_handler(&view_error_suppressor);
720
bool error= open_normal_and_derived_tables(thd, table_list, 0);
721
thd->pop_internal_handler();
722
if (error && (thd->killed || thd->main_da.is_error()))
726
/* TODO: add environment variables show when it become possible */
727
if (thd->lex->only_view && !table_list->view)
729
my_error(ER_WRONG_OBJECT, MYF(0),
730
table_list->db, table_list->table_name, "VIEW");
736
if (table_list->view)
737
buffer.set_charset(table_list->view_creation_ctx->get_client_cs());
739
if ((table_list->view ?
740
view_store_create_info(thd, table_list, &buffer) :
741
store_create_info(thd, table_list, &buffer, NULL,
742
FALSE /* show_database */)))
745
List<Item> field_list;
746
if (table_list->view)
748
field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
749
field_list.push_back(new Item_empty_string("Create View",
750
max(buffer.length(),1024)));
751
field_list.push_back(new Item_empty_string("character_set_client",
753
field_list.push_back(new Item_empty_string("collation_connection",
758
field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
759
// 1024 is for not to confuse old clients
760
field_list.push_back(new Item_empty_string("Create Table",
761
max(buffer.length(),1024)));
764
if (protocol->send_fields(&field_list,
765
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
767
protocol->prepare_for_resend();
768
if (table_list->view)
769
protocol->store(table_list->view_name.str, system_charset_info);
772
if (table_list->schema_table)
773
protocol->store(table_list->schema_table->table_name,
774
system_charset_info);
776
protocol->store(table_list->table->alias, system_charset_info);
779
if (table_list->view)
781
protocol->store(buffer.ptr(), buffer.length(),
782
table_list->view_creation_ctx->get_client_cs());
784
protocol->store(table_list->view_creation_ctx->get_client_cs()->csname,
785
system_charset_info);
787
protocol->store(table_list->view_creation_ctx->get_connection_cl()->name,
788
system_charset_info);
791
protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
793
if (protocol->write())
800
bool mysqld_show_create_db(THD *thd, char *dbname,
801
HA_CREATE_INFO *create_info)
804
String buffer(buff, sizeof(buff), system_charset_info);
805
#ifndef NO_EMBEDDED_ACCESS_CHECKS
806
Security_context *sctx= thd->security_ctx;
809
HA_CREATE_INFO create;
810
uint create_options = create_info ? create_info->options : 0;
811
Protocol *protocol=thd->protocol;
812
DBUG_ENTER("mysql_show_create_db");
814
#ifndef NO_EMBEDDED_ACCESS_CHECKS
815
if (test_all_bits(sctx->master_access, DB_ACLS))
818
db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
819
sctx->master_access);
820
if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname))
822
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
823
sctx->priv_user, sctx->host_or_ip, dbname);
824
general_log_print(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
825
sctx->priv_user, sctx->host_or_ip, dbname);
829
if (is_schema_db(dbname))
831
dbname= INFORMATION_SCHEMA_NAME.str;
832
create.default_table_charset= system_charset_info;
836
if (check_db_dir_existence(dbname))
838
my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
842
load_db_opt_by_name(thd, dbname, &create);
844
List<Item> field_list;
845
field_list.push_back(new Item_empty_string("Database",NAME_CHAR_LEN));
846
field_list.push_back(new Item_empty_string("Create Database",1024));
848
if (protocol->send_fields(&field_list,
849
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
852
protocol->prepare_for_resend();
853
protocol->store(dbname, strlen(dbname), system_charset_info);
855
buffer.append(STRING_WITH_LEN("CREATE DATABASE "));
856
if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
857
buffer.append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
858
append_identifier(thd, &buffer, dbname, strlen(dbname));
860
if (create.default_table_charset)
862
buffer.append(STRING_WITH_LEN(" /*!40100"));
863
buffer.append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
864
buffer.append(create.default_table_charset->csname);
865
if (!(create.default_table_charset->state & MY_CS_PRIMARY))
867
buffer.append(STRING_WITH_LEN(" COLLATE "));
868
buffer.append(create.default_table_charset->name);
870
buffer.append(STRING_WITH_LEN(" */"));
872
protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
874
if (protocol->write())
882
/****************************************************************************
883
Return only fields for API mysql_list_fields
884
Use "show table wildcard" in mysql instead of this
885
****************************************************************************/
888
mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
891
DBUG_ENTER("mysqld_list_fields");
892
DBUG_PRINT("enter",("table: %s",table_list->table_name));
894
if (open_normal_and_derived_tables(thd, table_list, 0))
896
table= table_list->table;
898
List<Item> field_list;
901
for (ptr=table->field ; (field= *ptr); ptr++)
903
if (!wild || !wild[0] ||
904
!wild_case_compare(system_charset_info, field->field_name,wild))
906
if (table_list->view)
907
field_list.push_back(new Item_ident_for_show(field,
908
table_list->view_db.str,
909
table_list->view_name.str));
911
field_list.push_back(new Item_field(field));
914
restore_record(table, s->default_values); // Get empty record
915
table->use_all_columns();
916
if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
924
mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd)
926
Protocol *protocol= thd->protocol;
927
String *packet= protocol->storage_packet();
928
DBUG_ENTER("mysqld_dump_create_info");
929
DBUG_PRINT("enter",("table: %s",table_list->table->s->table_name.str));
931
protocol->prepare_for_resend();
932
if (store_create_info(thd, table_list, packet, NULL,
933
FALSE /* show_database */))
938
if (protocol->write())
944
if (my_write(fd, (const uchar*) packet->ptr(), packet->length(),
952
Go through all character combinations and ensure that sql_lex.cc can
953
parse it as an identifier.
958
name_length length of name
961
# Pointer to conflicting character
962
0 No conflicting character
965
static const char *require_quotes(const char *name, uint name_length)
968
bool pure_digit= TRUE;
969
const char *end= name + name_length;
971
for (; name < end ; name++)
973
uchar chr= (uchar) *name;
974
length= my_mbcharlen(system_charset_info, chr);
975
if (length == 1 && !system_charset_info->ident_map[chr])
977
if (length == 1 && (chr < '0' || chr > '9'))
987
Quote the given identifier if needed and append it to the target string.
988
If the given identifier is empty, it will be quoted.
994
name the identifier to be appended
995
name_length length of the appending identifier
999
append_identifier(THD *thd, String *packet, const char *name, uint length)
1001
const char *name_end;
1003
int q= get_quote_char_for_identifier(thd, name, length);
1007
packet->append(name, length, packet->charset());
1012
The identifier must be quoted as it includes a quote character or
1016
VOID(packet->reserve(length*2 + 2));
1017
quote_char= (char) q;
1018
packet->append("e_char, 1, system_charset_info);
1020
for (name_end= name+length ; name < name_end ; name+= length)
1022
uchar chr= (uchar) *name;
1023
length= my_mbcharlen(system_charset_info, chr);
1025
my_mbcharlen can return 0 on a wrong multibyte
1026
sequence. It is possible when upgrading from 4.0,
1027
and identifier contains some accented characters.
1028
The manual says it does not work. So we'll just
1029
change length to 1 not to hang in the endless loop.
1033
if (length == 1 && chr == (uchar) quote_char)
1034
packet->append("e_char, 1, system_charset_info);
1035
packet->append(name, length, system_charset_info);
1037
packet->append("e_char, 1, system_charset_info);
1042
Get the quote character for displaying an identifier.
1045
get_quote_char_for_identifier()
1048
length length of name
1051
Force quoting in the following cases:
1052
- name is empty (for one, it is possible when we use this function for
1053
quoting user and host names for DEFINER clause);
1054
- name is a keyword;
1055
- name includes a special character;
1056
Otherwise identifier is quoted only if the option OPTION_QUOTE_SHOW_CREATE
1060
EOF No quote character is needed
1064
int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
1067
!is_keyword(name,length) &&
1068
!require_quotes(name, length) &&
1069
!(thd->options & OPTION_QUOTE_SHOW_CREATE))
1071
if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
1077
/* Append directory name (if exists) to CREATE INFO */
1079
static void append_directory(THD *thd, String *packet, const char *dir_type,
1080
const char *filename)
1082
if (filename && !(thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
1084
uint length= dirname_length(filename);
1085
packet->append(' ');
1086
packet->append(dir_type);
1087
packet->append(STRING_WITH_LEN(" DIRECTORY='"));
1089
/* Convert \ to / to be able to create table on unix */
1090
char *winfilename= (char*) thd->memdup(filename, length);
1092
for (pos= winfilename, end= pos+length ; pos < end ; pos++)
1097
filename= winfilename;
1099
packet->append(filename, length);
1100
packet->append('\'');
1105
#define LIST_PROCESS_HOST_LEN 64
1107
static bool get_field_default_value(THD *thd, TABLE *table,
1108
Field *field, String *def_value,
1112
bool has_now_default;
1113
enum enum_field_types field_type= field->type();
1115
We are using CURRENT_TIMESTAMP instead of NOW because it is
1118
has_now_default= table->timestamp_field == field &&
1119
field->unireg_check != Field::TIMESTAMP_UN_FIELD;
1121
has_default= (field_type != FIELD_TYPE_BLOB &&
1122
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
1123
field->unireg_check != Field::NEXT_NUMBER &&
1124
!((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
1125
&& has_now_default));
1127
def_value->length(0);
1130
if (has_now_default)
1131
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
1132
else if (!field->is_null())
1133
{ // Not null by default
1134
char tmp[MAX_FIELD_WIDTH];
1135
String type(tmp, sizeof(tmp), field->charset());
1136
if (field_type == MYSQL_TYPE_BIT)
1138
longlong dec= field->val_int();
1139
char *ptr= longlong2str(dec, tmp + 2, 2);
1140
uint32 length= (uint32) (ptr - tmp);
1144
type.length(length + 1);
1148
field->val_str(&type);
1153
/* convert to system_charset_info == utf8 */
1154
def_val.copy(type.ptr(), type.length(), field->charset(),
1155
system_charset_info, &dummy_errors);
1157
append_unescaped(def_value, def_val.ptr(), def_val.length());
1159
def_value->append(def_val.ptr(), def_val.length());
1162
def_value->append(STRING_WITH_LEN("''"));
1164
else if (field->maybe_null() && quoted)
1165
def_value->append(STRING_WITH_LEN("NULL")); // Null as default
1174
Build a CREATE TABLE statement for a table.
1179
table_list A list containing one table to write statement
1181
packet Pointer to a string where statement will be
1183
create_info_arg Pointer to create information that can be used
1184
to tailor the format of the statement. Can be
1185
NULL, in which case only SQL_MODE is considered
1186
when building the statement.
1189
Currently always return 0, but might return error code in the
1196
int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
1197
HA_CREATE_INFO *create_info_arg, bool show_database)
1199
List<Item> field_list;
1200
char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
1202
String type(tmp, sizeof(tmp), system_charset_info);
1203
String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
1207
TABLE *table= table_list->table;
1208
handler *file= table->file;
1209
TABLE_SHARE *share= table->s;
1210
HA_CREATE_INFO create_info;
1211
bool show_table_options= FALSE;
1212
bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
1218
bool limited_mysql_mode= (thd->variables.sql_mode & (MODE_NO_FIELD_OPTIONS |
1220
MODE_MYSQL40)) != 0;
1221
my_bitmap_map *old_map;
1222
DBUG_ENTER("store_create_info");
1223
DBUG_PRINT("enter",("table: %s", table->s->table_name.str));
1225
restore_record(table, s->default_values); // Get empty record
1227
if (share->tmp_table)
1228
packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
1230
packet->append(STRING_WITH_LEN("CREATE TABLE "));
1231
if (create_info_arg &&
1232
(create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
1233
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
1234
if (table_list->schema_table)
1235
alias= table_list->schema_table->table_name;
1238
if (lower_case_table_names == 2)
1239
alias= table->alias;
1242
alias= share->table_name.str;
1247
Print the database before the table name if told to do that. The
1248
database name is only printed in the event that it is different
1249
from the current database. The main reason for doing this is to
1250
avoid having to update gazillions of tests and result files, but
1251
it also saves a few bytes of the binary log.
1255
const LEX_STRING *const db=
1256
table_list->schema_table ? &INFORMATION_SCHEMA_NAME : &table->s->db;
1257
if (!thd->db || strcmp(db->str, thd->db))
1259
append_identifier(thd, packet, db->str, db->length);
1260
packet->append(STRING_WITH_LEN("."));
1264
append_identifier(thd, packet, alias, strlen(alias));
1265
packet->append(STRING_WITH_LEN(" (\n"));
1267
We need this to get default values from the table
1268
We have to restore the read_set if we are called from insert in case
1269
of row based replication.
1271
old_map= tmp_use_all_columns(table, table->read_set);
1273
for (ptr=table->field ; (field= *ptr); ptr++)
1275
uint flags = field->flags;
1277
if (ptr != table->field)
1278
packet->append(STRING_WITH_LEN(",\n"));
1280
packet->append(STRING_WITH_LEN(" "));
1281
append_identifier(thd,packet,field->field_name, strlen(field->field_name));
1282
packet->append(' ');
1283
// check for surprises from the previous call to Field::sql_type()
1284
if (type.ptr() != tmp)
1285
type.set(tmp, sizeof(tmp), system_charset_info);
1287
type.set_charset(system_charset_info);
1289
field->sql_type(type);
1290
packet->append(type.ptr(), type.length(), system_charset_info);
1292
if (field->has_charset() &&
1293
!(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)))
1295
if (field->charset() != share->table_charset)
1297
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
1298
packet->append(field->charset()->csname);
1301
For string types dump collation name only if
1302
collation is not primary for the given charset
1304
if (!(field->charset()->state & MY_CS_PRIMARY))
1306
packet->append(STRING_WITH_LEN(" COLLATE "));
1307
packet->append(field->charset()->name);
1311
if (flags & NOT_NULL_FLAG)
1312
packet->append(STRING_WITH_LEN(" NOT NULL"));
1313
else if (field->type() == MYSQL_TYPE_TIMESTAMP)
1316
TIMESTAMP field require explicit NULL flag, because unlike
1317
all other fields they are treated as NOT NULL by default.
1319
packet->append(STRING_WITH_LEN(" NULL"));
1322
if (get_field_default_value(thd, table, field, &def_value, 1))
1324
packet->append(STRING_WITH_LEN(" DEFAULT "));
1325
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
1328
if (!limited_mysql_mode && table->timestamp_field == field &&
1329
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
1330
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
1332
if (field->unireg_check == Field::NEXT_NUMBER &&
1333
!(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
1334
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
1336
if (field->comment.length)
1338
packet->append(STRING_WITH_LEN(" COMMENT "));
1339
append_unescaped(packet, field->comment.str, field->comment.length);
1343
key_info= table->key_info;
1344
bzero((char*) &create_info, sizeof(create_info));
1345
/* Allow update_create_info to update row type */
1346
create_info.row_type= share->row_type;
1347
file->update_create_info(&create_info);
1348
primary_key= share->primary_key;
1350
for (uint i=0 ; i < share->keys ; i++,key_info++)
1352
KEY_PART_INFO *key_part= key_info->key_part;
1353
bool found_primary=0;
1354
packet->append(STRING_WITH_LEN(",\n "));
1356
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
1360
No space at end, because a space will be added after where the
1361
identifier would go, but that is not added for primary key.
1363
packet->append(STRING_WITH_LEN("PRIMARY KEY"));
1365
else if (key_info->flags & HA_NOSAME)
1366
packet->append(STRING_WITH_LEN("UNIQUE KEY "));
1367
else if (key_info->flags & HA_FULLTEXT)
1368
packet->append(STRING_WITH_LEN("FULLTEXT KEY "));
1369
else if (key_info->flags & HA_SPATIAL)
1370
packet->append(STRING_WITH_LEN("SPATIAL KEY "));
1372
packet->append(STRING_WITH_LEN("KEY "));
1375
append_identifier(thd, packet, key_info->name, strlen(key_info->name));
1377
packet->append(STRING_WITH_LEN(" ("));
1379
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
1382
packet->append(',');
1384
if (key_part->field)
1385
append_identifier(thd,packet,key_part->field->field_name,
1386
strlen(key_part->field->field_name));
1387
if (key_part->field &&
1388
(key_part->length !=
1389
table->field[key_part->fieldnr-1]->key_length() &&
1390
!(key_info->flags & (HA_FULLTEXT | HA_SPATIAL))))
1394
end= int10_to_str((long) key_part->length /
1395
key_part->field->charset()->mbmaxlen,
1398
packet->append(buff,(uint) (end-buff));
1401
packet->append(')');
1402
store_key_options(thd, packet, table, key_info);
1403
if (key_info->parser)
1405
LEX_STRING *parser_name= plugin_name(key_info->parser);
1406
packet->append(STRING_WITH_LEN(" /*!50100 WITH PARSER "));
1407
append_identifier(thd, packet, parser_name->str, parser_name->length);
1408
packet->append(STRING_WITH_LEN(" */ "));
1413
Get possible foreign key definitions stored in InnoDB and append them
1414
to the CREATE TABLE statement
1417
if ((for_str= file->get_foreign_key_create_info()))
1419
packet->append(for_str, strlen(for_str));
1420
file->free_foreign_key_create_info(for_str);
1423
packet->append(STRING_WITH_LEN("\n)"));
1424
if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
1426
show_table_options= TRUE;
1428
Get possible table space definitions and append them
1429
to the CREATE TABLE statement
1432
if ((for_str= file->get_tablespace_name(thd,0,0)))
1434
packet->append(STRING_WITH_LEN(" /*!50100 TABLESPACE "));
1435
packet->append(for_str, strlen(for_str));
1436
packet->append(STRING_WITH_LEN(" STORAGE DISK */"));
1437
my_free(for_str, MYF(0));
1441
IF check_create_info
1442
THEN add ENGINE only if it was used when creating the table
1444
if (!create_info_arg ||
1445
(create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
1447
if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
1448
packet->append(STRING_WITH_LEN(" TYPE="));
1450
packet->append(STRING_WITH_LEN(" ENGINE="));
1451
#ifdef WITH_PARTITION_STORAGE_ENGINE
1452
if (table->part_info)
1453
packet->append(ha_resolve_storage_engine_name(
1454
table->part_info->default_engine_type));
1456
packet->append(file->table_type());
1458
packet->append(file->table_type());
1463
Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
1464
and NEXT_ID > 1 (the default). We must not print the clause
1465
for engines that do not support this as it would break the
1466
import of dumps, but as of this writing, the test for whether
1467
AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
1468
is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
1469
Because of that, we do not explicitly test for the feature,
1470
but may extrapolate its existence from that of an AUTO_INCREMENT column.
1473
if (create_info.auto_increment_value > 1)
1476
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
1477
end= longlong10_to_str(create_info.auto_increment_value, buff,10);
1478
packet->append(buff, (uint) (end - buff));
1482
if (share->table_charset &&
1483
!(thd->variables.sql_mode & MODE_MYSQL323) &&
1484
!(thd->variables.sql_mode & MODE_MYSQL40))
1487
IF check_create_info
1488
THEN add DEFAULT CHARSET only if it was used when creating the table
1490
if (!create_info_arg ||
1491
(create_info_arg->used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
1493
packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
1494
packet->append(share->table_charset->csname);
1495
if (!(share->table_charset->state & MY_CS_PRIMARY))
1497
packet->append(STRING_WITH_LEN(" COLLATE="));
1498
packet->append(table->s->table_charset->name);
1503
if (share->min_rows)
1506
packet->append(STRING_WITH_LEN(" MIN_ROWS="));
1507
end= longlong10_to_str(share->min_rows, buff, 10);
1508
packet->append(buff, (uint) (end- buff));
1511
if (share->max_rows && !table_list->schema_table)
1514
packet->append(STRING_WITH_LEN(" MAX_ROWS="));
1515
end= longlong10_to_str(share->max_rows, buff, 10);
1516
packet->append(buff, (uint) (end - buff));
1519
if (share->avg_row_length)
1522
packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
1523
end= longlong10_to_str(share->avg_row_length, buff,10);
1524
packet->append(buff, (uint) (end - buff));
1527
if (share->db_create_options & HA_OPTION_PACK_KEYS)
1528
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
1529
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
1530
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
1531
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
1532
if (share->db_create_options & HA_OPTION_CHECKSUM)
1533
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
1534
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
1535
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
1536
if (create_info.row_type != ROW_TYPE_DEFAULT)
1538
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
1539
packet->append(ha_row_type[(uint) create_info.row_type]);
1541
if (table->s->key_block_size)
1544
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
1545
end= longlong10_to_str(table->s->key_block_size, buff, 10);
1546
packet->append(buff, (uint) (end - buff));
1548
table->file->append_create_info(packet);
1549
if (share->comment.length)
1551
packet->append(STRING_WITH_LEN(" COMMENT="));
1552
append_unescaped(packet, share->comment.str, share->comment.length);
1554
if (share->connect_string.length)
1556
packet->append(STRING_WITH_LEN(" CONNECTION="));
1557
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
1559
append_directory(thd, packet, "DATA", create_info.data_file_name);
1560
append_directory(thd, packet, "INDEX", create_info.index_file_name);
1562
#ifdef WITH_PARTITION_STORAGE_ENGINE
1565
Partition syntax for CREATE TABLE is at the end of the syntax.
1567
uint part_syntax_len;
1569
if (table->part_info &&
1570
(!table->part_info->is_auto_partitioned) &&
1571
((part_syntax= generate_partition_syntax(table->part_info,
1574
show_table_options))))
1576
packet->append(STRING_WITH_LEN("\n/*!50100"));
1577
packet->append(part_syntax, part_syntax_len);
1578
packet->append(STRING_WITH_LEN(" */"));
1579
my_free(part_syntax, MYF(0));
1583
tmp_restore_column_map(table->read_set, old_map);
1588
static void store_key_options(THD *thd, String *packet, TABLE *table,
1591
bool limited_mysql_mode= (thd->variables.sql_mode &
1592
(MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 |
1593
MODE_MYSQL40)) != 0;
1594
bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
1600
char *end, buff[32];
1602
if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
1603
!limited_mysql_mode && !foreign_db_mode)
1606
if (key_info->algorithm == HA_KEY_ALG_BTREE)
1607
packet->append(STRING_WITH_LEN(" USING BTREE"));
1609
if (key_info->algorithm == HA_KEY_ALG_HASH)
1610
packet->append(STRING_WITH_LEN(" USING HASH"));
1612
/* send USING only in non-default case: non-spatial rtree */
1613
if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
1614
!(key_info->flags & HA_SPATIAL))
1615
packet->append(STRING_WITH_LEN(" USING RTREE"));
1617
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
1618
table->s->key_block_size != key_info->block_size)
1620
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
1621
end= longlong10_to_str(key_info->block_size, buff, 10);
1622
packet->append(buff, (uint) (end - buff));
1629
view_store_options(THD *thd, TABLE_LIST *table, String *buff)
1631
append_algorithm(table, buff);
1632
append_definer(thd, buff, &table->definer.user, &table->definer.host);
1633
if (table->view_suid)
1634
buff->append(STRING_WITH_LEN("SQL SECURITY DEFINER "));
1636
buff->append(STRING_WITH_LEN("SQL SECURITY INVOKER "));
1641
Append DEFINER clause to the given buffer.
1645
thd [in] thread handle
1646
buffer [inout] buffer to hold DEFINER clause
1647
definer_user [in] user name part of definer
1648
definer_host [in] host name part of definer
1651
static void append_algorithm(TABLE_LIST *table, String *buff)
1653
buff->append(STRING_WITH_LEN("ALGORITHM="));
1654
switch ((int8)table->algorithm) {
1655
case VIEW_ALGORITHM_UNDEFINED:
1656
buff->append(STRING_WITH_LEN("UNDEFINED "));
1658
case VIEW_ALGORITHM_TMPTABLE:
1659
buff->append(STRING_WITH_LEN("TEMPTABLE "));
1661
case VIEW_ALGORITHM_MERGE:
1662
buff->append(STRING_WITH_LEN("MERGE "));
1665
DBUG_ASSERT(0); // never should happen
1670
Append DEFINER clause to the given buffer.
1674
thd [in] thread handle
1675
buffer [inout] buffer to hold DEFINER clause
1676
definer_user [in] user name part of definer
1677
definer_host [in] host name part of definer
1680
void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
1681
const LEX_STRING *definer_host)
1683
buffer->append(STRING_WITH_LEN("DEFINER="));
1684
append_identifier(thd, buffer, definer_user->str, definer_user->length);
1685
buffer->append('@');
1686
append_identifier(thd, buffer, definer_host->str, definer_host->length);
1687
buffer->append(' ');
1692
view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
1694
my_bool compact_view_name= TRUE;
1695
my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
1702
if (!thd->db || strcmp(thd->db, table->view_db.str))
1704
print compact view name if the view belongs to the current database
1706
compact_view_name= table->compact_view_format= FALSE;
1710
Compact output format for view body can be used
1711
if this view only references table inside it's own db
1714
table->compact_view_format= TRUE;
1715
for (tbl= thd->lex->query_tables;
1717
tbl= tbl->next_global)
1719
if (strcmp(table->view_db.str, tbl->view ? tbl->view_db.str :tbl->db)!= 0)
1721
table->compact_view_format= FALSE;
1727
buff->append(STRING_WITH_LEN("CREATE "));
1728
if (!foreign_db_mode)
1730
view_store_options(thd, table, buff);
1732
buff->append(STRING_WITH_LEN("VIEW "));
1733
if (!compact_view_name)
1735
append_identifier(thd, buff, table->view_db.str, table->view_db.length);
1738
append_identifier(thd, buff, table->view_name.str, table->view_name.length);
1739
buff->append(STRING_WITH_LEN(" AS "));
1742
We can't just use table->query, because our SQL_MODE may trigger
1743
a different syntax, like when ANSI_QUOTES is defined.
1745
table->view->unit.print(buff, QT_ORDINARY);
1747
if (table->with_check != VIEW_CHECK_NONE)
1749
if (table->with_check == VIEW_CHECK_LOCAL)
1750
buff->append(STRING_WITH_LEN(" WITH LOCAL CHECK OPTION"));
1752
buff->append(STRING_WITH_LEN(" WITH CASCADED CHECK OPTION"));
1758
/****************************************************************************
1759
Return info about all processes
1760
returns for each thread: thread id, user, host, db, command, info
1761
****************************************************************************/
1763
class thread_info :public ilink {
1765
static void *operator new(size_t size)
1767
return (void*) sql_alloc((uint) size);
1769
static void operator delete(void *ptr __attribute__((unused)),
1770
size_t size __attribute__((unused)))
1771
{ TRASH(ptr, size); }
1776
const char *user,*host,*db,*proc_info,*state_info;
1780
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1781
template class I_List<thread_info>;
1784
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
1787
List<Item> field_list;
1788
I_List<thread_info> thread_infos;
1789
ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
1790
PROCESS_LIST_WIDTH);
1791
Protocol *protocol= thd->protocol;
1792
DBUG_ENTER("mysqld_list_processes");
1794
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1795
field_list.push_back(new Item_empty_string("User",16));
1796
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1797
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1798
field->maybe_null=1;
1799
field_list.push_back(new Item_empty_string("Command",16));
1800
field_list.push_back(field= new Item_return_int("Time",7, MYSQL_TYPE_LONG));
1801
field->unsigned_flag= 0;
1802
field_list.push_back(field=new Item_empty_string("State",30));
1803
field->maybe_null=1;
1804
field_list.push_back(field=new Item_empty_string("Info",max_query_length));
1805
field->maybe_null=1;
1806
if (protocol->send_fields(&field_list,
1807
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1810
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
1813
I_List_iterator<THD> it(threads);
1817
Security_context *tmp_sctx= tmp->security_ctx;
1818
struct st_my_thread_var *mysys_var;
1819
if ((tmp->vio_ok() || tmp->system_thread) &&
1820
(!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
1822
thread_info *thd_info= new thread_info;
1824
thd_info->thread_id=tmp->thread_id;
1825
thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
1826
(tmp->system_thread ?
1827
"system user" : "unauthenticated user"));
1828
if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
1829
thd->security_ctx->host_or_ip[0])
1831
if ((thd_info->host= (char*) thd->alloc(LIST_PROCESS_HOST_LEN+1)))
1832
my_snprintf((char *) thd_info->host, LIST_PROCESS_HOST_LEN,
1833
"%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
1836
thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
1837
tmp_sctx->host_or_ip :
1838
tmp_sctx->host ? tmp_sctx->host : "");
1839
if ((thd_info->db=tmp->db)) // Safe test
1840
thd_info->db=thd->strdup(thd_info->db);
1841
thd_info->command=(int) tmp->command;
1842
if ((mysys_var= tmp->mysys_var))
1843
pthread_mutex_lock(&mysys_var->mutex);
1844
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
1845
#ifndef EMBEDDED_LIBRARY
1846
thd_info->state_info= (char*) (tmp->locked ? "Locked" :
1847
tmp->net.reading_or_writing ?
1848
(tmp->net.reading_or_writing == 2 ?
1850
thd_info->command == COM_SLEEP ? "" :
1851
"Reading from net") :
1852
tmp->proc_info ? tmp->proc_info :
1854
tmp->mysys_var->current_cond ?
1855
"Waiting on cond" : NullS);
1857
thd_info->state_info= (char*)"Writing to net";
1860
pthread_mutex_unlock(&mysys_var->mutex);
1862
thd_info->start_time= tmp->start_time;
1864
/* Lock THD mutex that protects its data when looking at it. */
1865
pthread_mutex_lock(&tmp->LOCK_thd_data);
1868
uint length= min(max_query_length, tmp->query_length());
1869
thd_info->query= (char*) thd->strmake(tmp->query(),length);
1871
pthread_mutex_unlock(&tmp->LOCK_thd_data);
1872
thread_infos.append(thd_info);
1876
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1878
thread_info *thd_info;
1879
time_t now= my_time(0);
1880
while ((thd_info=thread_infos.get()))
1882
protocol->prepare_for_resend();
1883
protocol->store((ulonglong) thd_info->thread_id);
1884
protocol->store(thd_info->user, system_charset_info);
1885
protocol->store(thd_info->host, system_charset_info);
1886
protocol->store(thd_info->db, system_charset_info);
1887
if (thd_info->proc_info)
1888
protocol->store(thd_info->proc_info, system_charset_info);
1890
protocol->store(command_name[thd_info->command].str, system_charset_info);
1891
if (thd_info->start_time)
1892
protocol->store_long ((longlong) (now - thd_info->start_time));
1894
protocol->store_null();
1895
protocol->store(thd_info->state_info, system_charset_info);
1896
protocol->store(thd_info->query, system_charset_info);
1897
if (protocol->write())
1898
break; /* purecov: inspected */
1904
int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
1906
TABLE *table= tables->table;
1907
CHARSET_INFO *cs= system_charset_info;
1909
time_t now= my_time(0);
1910
DBUG_ENTER("fill_process_list");
1912
user= thd->security_ctx->master_access & PROCESS_ACL ?
1913
NullS : thd->security_ctx->priv_user;
1915
VOID(pthread_mutex_lock(&LOCK_thread_count));
1919
I_List_iterator<THD> it(threads);
1924
Security_context *tmp_sctx= tmp->security_ctx;
1925
struct st_my_thread_var *mysys_var;
1928
if ((!tmp->vio_ok() && !tmp->system_thread) ||
1929
(user && (!tmp_sctx->user || strcmp(tmp_sctx->user, user))))
1932
restore_record(table, s->default_values);
1934
table->field[0]->store((longlong) tmp->thread_id, TRUE);
1936
val= tmp_sctx->user ? tmp_sctx->user :
1937
(tmp->system_thread ? "system user" : "unauthenticated user");
1938
table->field[1]->store(val, strlen(val), cs);
1940
if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
1941
thd->security_ctx->host_or_ip[0])
1943
char host[LIST_PROCESS_HOST_LEN + 1];
1944
my_snprintf(host, LIST_PROCESS_HOST_LEN, "%s:%u",
1945
tmp_sctx->host_or_ip, tmp->peer_port);
1946
table->field[2]->store(host, strlen(host), cs);
1949
table->field[2]->store(tmp_sctx->host_or_ip,
1950
strlen(tmp_sctx->host_or_ip), cs);
1954
table->field[3]->store(tmp->db, strlen(tmp->db), cs);
1955
table->field[3]->set_notnull();
1958
if ((mysys_var= tmp->mysys_var))
1959
pthread_mutex_lock(&mysys_var->mutex);
1961
if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
1962
table->field[4]->store(val, strlen(val), cs);
1964
table->field[4]->store(command_name[tmp->command].str,
1965
command_name[tmp->command].length, cs);
1967
table->field[5]->store((longlong)(tmp->start_time ?
1968
now - tmp->start_time : 0), FALSE);
1970
#ifndef EMBEDDED_LIBRARY
1971
val= (char*) (tmp->locked ? "Locked" :
1972
tmp->net.reading_or_writing ?
1973
(tmp->net.reading_or_writing == 2 ?
1975
tmp->command == COM_SLEEP ? "" :
1976
"Reading from net") :
1977
tmp->proc_info ? tmp->proc_info :
1979
tmp->mysys_var->current_cond ?
1980
"Waiting on cond" : NullS);
1982
val= (char *) (tmp->proc_info ? tmp->proc_info : NullS);
1986
table->field[6]->store(val, strlen(val), cs);
1987
table->field[6]->set_notnull();
1991
pthread_mutex_unlock(&mysys_var->mutex);
1996
table->field[7]->store(tmp->query(),
1997
min(PROCESS_LIST_INFO_WIDTH,
1998
tmp->query_length()), cs);
1999
table->field[7]->set_notnull();
2002
if (schema_table_store_record(thd, table))
2004
VOID(pthread_mutex_unlock(&LOCK_thread_count));
2010
VOID(pthread_mutex_unlock(&LOCK_thread_count));
2014
/*****************************************************************************
2016
*****************************************************************************/
2018
static DYNAMIC_ARRAY all_status_vars;
2019
static bool status_vars_inited= 0;
2020
static int show_var_cmp(const void *var1, const void *var2)
2022
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
2026
deletes all the SHOW_UNDEF elements from the array and calls
2027
delete_dynamic() if it's completely empty.
2029
static void shrink_var_array(DYNAMIC_ARRAY *array)
2032
SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
2034
for (a= b= 0; b < array->elements; b++)
2035
if (all[b].type != SHOW_UNDEF)
2039
bzero(all+a, sizeof(SHOW_VAR)); // writing NULL-element to the end
2042
else // array is completely empty - delete it
2043
delete_dynamic(array);
2047
Adds an array of SHOW_VAR entries to the output of SHOW STATUS
2050
add_status_vars(SHOW_VAR *list)
2051
list - an array of SHOW_VAR entries to add to all_status_vars
2052
the last entry must be {0,0,SHOW_UNDEF}
2055
The handling of all_status_vars[] is completely internal, it's allocated
2056
automatically when something is added to it, and deleted completely when
2057
the last entry is removed.
2059
As a special optimization, if add_status_vars() is called before
2060
init_status_vars(), it assumes "startup mode" - neither concurrent access
2061
to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
2063
The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
2065
int add_status_vars(SHOW_VAR *list)
2068
if (status_vars_inited)
2069
pthread_mutex_lock(&LOCK_status);
2070
if (!all_status_vars.buffer && // array is not allocated yet - do it now
2071
my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
2077
res|= insert_dynamic(&all_status_vars, (uchar*)list++);
2078
res|= insert_dynamic(&all_status_vars, (uchar*)list); // appending NULL-element
2079
all_status_vars.elements--; // but next insert_dynamic should overwite it
2080
if (status_vars_inited)
2081
sort_dynamic(&all_status_vars, show_var_cmp);
2083
if (status_vars_inited)
2084
pthread_mutex_unlock(&LOCK_status);
2089
Make all_status_vars[] usable for SHOW STATUS
2092
See add_status_vars(). Before init_status_vars() call, add_status_vars()
2093
works in a special fast "startup" mode. Thus init_status_vars()
2094
should be called as late as possible but before enabling multi-threading.
2096
void init_status_vars()
2098
status_vars_inited=1;
2099
sort_dynamic(&all_status_vars, show_var_cmp);
2102
void reset_status_vars()
2104
SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
2105
SHOW_VAR *last= ptr + all_status_vars.elements;
2106
for (; ptr < last; ptr++)
2108
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
2109
if (ptr->type == SHOW_LONG)
2110
*(ulong*) ptr->value= 0;
2115
catch-all cleanup function, cleans up everything no matter what
2118
This function is not strictly required if all add_to_status/
2119
remove_status_vars are properly paired, but it's a safety measure that
2120
deletes everything from the all_status_vars[] even if some
2121
remove_status_vars were forgotten
2123
void free_status_vars()
2125
delete_dynamic(&all_status_vars);
2129
Removes an array of SHOW_VAR entries from the output of SHOW STATUS
2132
remove_status_vars(SHOW_VAR *list)
2133
list - an array of SHOW_VAR entries to remove to all_status_vars
2134
the last entry must be {0,0,SHOW_UNDEF}
2137
there's lots of room for optimizing this, especially in non-sorted mode,
2138
but nobody cares - it may be called only in case of failed plugin
2139
initialization in the mysqld startup.
2142
void remove_status_vars(SHOW_VAR *list)
2144
if (status_vars_inited)
2146
pthread_mutex_lock(&LOCK_status);
2147
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
2148
int a= 0, b= all_status_vars.elements, c= (a+b)/2;
2150
for (; list->name; list++)
2153
for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
2155
res= show_var_cmp(list, all+c);
2164
all[c].type= SHOW_UNDEF;
2166
shrink_var_array(&all_status_vars);
2167
pthread_mutex_unlock(&LOCK_status);
2171
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
2173
for (; list->name; list++)
2175
for (i= 0; i < all_status_vars.elements; i++)
2177
if (show_var_cmp(list, all+i))
2179
all[i].type= SHOW_UNDEF;
2183
shrink_var_array(&all_status_vars);
2187
inline void make_upper(char *buf)
2190
*buf= my_toupper(system_charset_info, *buf);
2193
static bool show_status_array(THD *thd, const char *wild,
2194
SHOW_VAR *variables,
2195
enum enum_var_type value_type,
2196
struct system_status_var *status_var,
2197
const char *prefix, TABLE *table,
2201
MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
2202
char * const buff= (char *) &buff_data;
2204
/* the variable name should not be longer than 64 characters */
2205
char name_buffer[64];
2207
LEX_STRING null_lex_str;
2209
COND *partial_cond= 0;
2210
enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
2212
CHARSET_INFO *charset= system_charset_info;
2213
DBUG_ENTER("show_status_array");
2215
thd->count_cuted_fields= CHECK_FIELD_WARN;
2216
null_lex_str.str= 0; // For sys_var->value_ptr()
2217
null_lex_str.length= 0;
2219
prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
2222
len=name_buffer + sizeof(name_buffer) - prefix_end;
2223
partial_cond= make_cond_for_info_schema(cond, table->pos_in_table_list);
2225
for (; variables->name; variables++)
2227
strnmov(prefix_end, variables->name, len);
2228
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
2230
make_upper(name_buffer);
2232
restore_record(table, s->default_values);
2233
table->field[0]->store(name_buffer, strlen(name_buffer),
2234
system_charset_info);
2236
if var->type is SHOW_FUNC, call the function.
2237
Repeat as necessary, if new var is again SHOW_FUNC
2239
for (var=variables; var->type == SHOW_FUNC; var= &tmp)
2240
((mysql_show_var_func)(var->value))(thd, &tmp, buff);
2242
SHOW_TYPE show_type=var->type;
2243
if (show_type == SHOW_ARRAY)
2245
show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
2246
status_var, name_buffer, table, ucase_names, partial_cond);
2250
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
2251
name_buffer, wild)) &&
2252
(!partial_cond || partial_cond->val_int()))
2254
char *value=var->value;
2255
const char *pos, *end; // We assign a lot of const's
2257
pthread_mutex_lock(&LOCK_global_system_variables);
2259
if (show_type == SHOW_SYS)
2261
sys_var *var= ((sys_var *) value);
2262
show_type= var->show_type();
2263
value= (char*) var->value_ptr(thd, value_type, &null_lex_str);
2264
charset= var->charset(thd);
2269
note that value may be == buff. All SHOW_xxx code below
2270
should still work in this case
2272
switch (show_type) {
2273
case SHOW_DOUBLE_STATUS:
2274
value= ((char *) status_var + (ulong) value);
2277
end= buff + my_sprintf(buff, (buff, "%f", *(double*) value));
2279
case SHOW_LONG_STATUS:
2280
value= ((char *) status_var + (ulong) value);
2283
case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
2284
end= int10_to_str(*(long*) value, buff, 10);
2286
case SHOW_LONGLONG_STATUS:
2287
value= ((char *) status_var + (ulonglong) value);
2290
end= longlong10_to_str(*(longlong*) value, buff, 10);
2293
end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10);
2296
end= strmov(buff, *(bool*) value ? "ON" : "OFF");
2299
end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
2302
end= int10_to_str((long) *(uint32*) value, buff, 10);
2306
SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
2307
pos= show_comp_option_name[(int) tmp];
2320
if (!(pos= *(char**) value))
2325
case SHOW_KEY_CACHE_LONG:
2326
value= (char*) dflt_key_cache + (ulong)value;
2327
end= int10_to_str(*(long*) value, buff, 10);
2329
case SHOW_KEY_CACHE_LONGLONG:
2330
value= (char*) dflt_key_cache + (ulong)value;
2331
end= longlong10_to_str(*(longlong*) value, buff, 10);
2334
break; // Return empty string
2335
case SHOW_SYS: // Cannot happen
2340
table->field[1]->store(pos, (uint32) (end - pos), charset);
2341
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
2342
table->field[1]->set_notnull();
2344
pthread_mutex_unlock(&LOCK_global_system_variables);
2346
if (schema_table_store_record(thd, table))
2355
thd->count_cuted_fields= save_count_cuted_fields;
2360
/* collect status for all running threads */
2362
void calc_sum_of_all_status(STATUS_VAR *to)
2364
DBUG_ENTER("calc_sum_of_all_status");
2366
/* Ensure that thread id not killed during loop */
2367
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
2369
I_List_iterator<THD> it(threads);
2372
/* Get global values as base */
2373
*to= global_status_var;
2375
/* Add to this status from existing threads */
2377
add_to_status(to, &tmp->status_var);
2379
VOID(pthread_mutex_unlock(&LOCK_thread_count));
2384
/* This is only used internally, but we need it here as a forward reference */
2385
extern ST_SCHEMA_TABLE schema_tables[];
2387
typedef struct st_lookup_field_values
2389
LEX_STRING db_value, table_value;
2390
bool wild_db_value, wild_table_value;
2391
} LOOKUP_FIELD_VALUES;
2395
Store record to I_S table, convert HEAP table
2396
to MyISAM if necessary
2399
schema_table_store_record()
2401
table Information schema table to be updated
2408
bool schema_table_store_record(THD *thd, TABLE *table)
2411
if ((error= table->file->ha_write_row(table->record[0])))
2413
if (create_myisam_from_heap(thd, table,
2414
table->pos_in_table_list->schema_table_param,
2422
int make_table_list(THD *thd, SELECT_LEX *sel,
2423
LEX_STRING *db_name, LEX_STRING *table_name)
2425
Table_ident *table_ident;
2426
table_ident= new Table_ident(thd, *db_name, *table_name, 1);
2428
if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
2435
@brief Get lookup value from the part of 'WHERE' condition
2437
@details This function gets lookup value from
2438
the part of 'WHERE' condition if it's possible and
2439
fill appropriate lookup_field_vals struct field
2442
@param[in] thd thread handler
2443
@param[in] item_func part of WHERE condition
2444
@param[in] table I_S table
2445
@param[in, out] lookup_field_vals Struct which holds lookup values
2449
1 error, there can be no matching records for the condition
2452
bool get_lookup_value(THD *thd, Item_func *item_func,
2454
LOOKUP_FIELD_VALUES *lookup_field_vals)
2456
ST_SCHEMA_TABLE *schema_table= table->schema_table;
2457
ST_FIELD_INFO *field_info= schema_table->fields_info;
2458
const char *field_name1= schema_table->idx_field1 >= 0 ?
2459
field_info[schema_table->idx_field1].field_name : "";
2460
const char *field_name2= schema_table->idx_field2 >= 0 ?
2461
field_info[schema_table->idx_field2].field_name : "";
2463
if (item_func->functype() == Item_func::EQ_FUNC ||
2464
item_func->functype() == Item_func::EQUAL_FUNC)
2466
int idx_field, idx_val;
2467
char tmp[MAX_FIELD_WIDTH];
2468
String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
2469
Item_field *item_field;
2470
CHARSET_INFO *cs= system_charset_info;
2472
if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
2473
item_func->arguments()[1]->const_item())
2478
else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
2479
item_func->arguments()[0]->const_item())
2487
item_field= (Item_field*) item_func->arguments()[idx_field];
2488
if (table->table != item_field->field->table)
2490
tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
2492
/* impossible value */
2496
/* Lookup value is database name */
2497
if (!cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
2498
(uchar *) item_field->field_name,
2499
strlen(item_field->field_name), 0))
2501
thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
2502
tmp_str->length(), FALSE);
2504
/* Lookup value is table name */
2505
else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2,
2506
strlen(field_name2),
2507
(uchar *) item_field->field_name,
2508
strlen(item_field->field_name), 0))
2510
thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
2511
tmp_str->length(), FALSE);
2519
@brief Calculates lookup values from 'WHERE' condition
2521
@details This function calculates lookup value(database name, table name)
2522
from 'WHERE' condition if it's possible and
2523
fill lookup_field_vals struct fields with these values.
2525
@param[in] thd thread handler
2526
@param[in] cond WHERE condition
2527
@param[in] table I_S table
2528
@param[in, out] lookup_field_vals Struct which holds lookup values
2532
1 error, there can be no matching records for the condition
2535
bool calc_lookup_values_from_cond(THD *thd, COND *cond, TABLE_LIST *table,
2536
LOOKUP_FIELD_VALUES *lookup_field_vals)
2541
if (cond->type() == Item::COND_ITEM)
2543
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
2545
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2547
while ((item= li++))
2549
if (item->type() == Item::FUNC_ITEM)
2551
if (get_lookup_value(thd, (Item_func*)item, table, lookup_field_vals))
2556
if (calc_lookup_values_from_cond(thd, item, table, lookup_field_vals))
2563
else if (cond->type() == Item::FUNC_ITEM &&
2564
get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals))
2570
bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
2572
if (item->type() == Item::FUNC_ITEM)
2574
Item_func *item_func= (Item_func*)item;
2575
for (uint i=0; i<item_func->argument_count(); i++)
2577
if (!uses_only_table_name_fields(item_func->arguments()[i], table))
2581
else if (item->type() == Item::FIELD_ITEM)
2583
Item_field *item_field= (Item_field*)item;
2584
CHARSET_INFO *cs= system_charset_info;
2585
ST_SCHEMA_TABLE *schema_table= table->schema_table;
2586
ST_FIELD_INFO *field_info= schema_table->fields_info;
2587
const char *field_name1= schema_table->idx_field1 >= 0 ?
2588
field_info[schema_table->idx_field1].field_name : "";
2589
const char *field_name2= schema_table->idx_field2 >= 0 ?
2590
field_info[schema_table->idx_field2].field_name : "";
2591
if (table->table != item_field->field->table ||
2592
(cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
2593
(uchar *) item_field->field_name,
2594
strlen(item_field->field_name), 0) &&
2595
cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2),
2596
(uchar *) item_field->field_name,
2597
strlen(item_field->field_name), 0)))
2600
else if (item->type() == Item::REF_ITEM)
2601
return uses_only_table_name_fields(item->real_item(), table);
2603
if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
2610
static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
2614
if (cond->type() == Item::COND_ITEM)
2616
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
2618
/* Create new top level AND item */
2619
Item_cond_and *new_cond=new Item_cond_and;
2622
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2626
Item *fix= make_cond_for_info_schema(item, table);
2628
new_cond->argument_list()->push_back(fix);
2630
switch (new_cond->argument_list()->elements) {
2634
return new_cond->argument_list()->head();
2636
new_cond->quick_fix_field();
2642
Item_cond_or *new_cond=new Item_cond_or;
2645
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2649
Item *fix=make_cond_for_info_schema(item, table);
2652
new_cond->argument_list()->push_back(fix);
2654
new_cond->quick_fix_field();
2655
new_cond->top_level_item();
2660
if (!uses_only_table_name_fields(cond, table))
2667
@brief Calculate lookup values(database name, table name)
2669
@details This function calculates lookup values(database name, table name)
2670
from 'WHERE' condition or wild values (for 'SHOW' commands only)
2671
from LEX struct and fill lookup_field_vals struct field
2674
@param[in] thd thread handler
2675
@param[in] cond WHERE condition
2676
@param[in] tables I_S table
2677
@param[in, out] lookup_field_values Struct which holds lookup values
2681
1 error, there can be no matching records for the condition
2684
bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables,
2685
LOOKUP_FIELD_VALUES *lookup_field_values)
2688
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
2689
bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES));
2690
switch (lex->sql_command) {
2691
case SQLCOM_SHOW_DATABASES:
2694
lookup_field_values->db_value.str= (char*) wild;
2695
lookup_field_values->db_value.length= strlen(wild);
2696
lookup_field_values->wild_db_value= 1;
2699
case SQLCOM_SHOW_TABLES:
2700
case SQLCOM_SHOW_TABLE_STATUS:
2701
case SQLCOM_SHOW_TRIGGERS:
2702
case SQLCOM_SHOW_EVENTS:
2703
lookup_field_values->db_value.str= lex->select_lex.db;
2704
lookup_field_values->db_value.length=strlen(lex->select_lex.db);
2707
lookup_field_values->table_value.str= (char*)wild;
2708
lookup_field_values->table_value.length= strlen(wild);
2709
lookup_field_values->wild_table_value= 1;
2714
The "default" is for queries over I_S.
2715
All previous cases handle SHOW commands.
2717
return calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
2722
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
2724
return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
2729
Create db names list. Information schema name always is first in list
2734
files list of db names
2736
idx_field_vals idx_field_vals->db_name contains db name or
2738
with_i_schema returns 1 if we added 'IS' name to list
2746
int make_db_list(THD *thd, List<LEX_STRING> *files,
2747
LOOKUP_FIELD_VALUES *lookup_field_vals,
2748
bool *with_i_schema)
2750
LEX_STRING *i_s_name_copy= 0;
2751
i_s_name_copy= thd->make_lex_string(i_s_name_copy,
2752
INFORMATION_SCHEMA_NAME.str,
2753
INFORMATION_SCHEMA_NAME.length, TRUE);
2755
if (lookup_field_vals->wild_db_value)
2758
This part of code is only for SHOW DATABASES command.
2759
idx_field_vals->db_value can be 0 when we don't use
2760
LIKE clause (see also get_index_field_values() function)
2762
if (!lookup_field_vals->db_value.str ||
2763
!wild_case_compare(system_charset_info,
2764
INFORMATION_SCHEMA_NAME.str,
2765
lookup_field_vals->db_value.str))
2768
if (files->push_back(i_s_name_copy))
2771
return (find_files(thd, files, NullS, mysql_data_home,
2772
lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
2777
If we have db lookup vaule we just add it to list and
2778
exit from the function
2780
if (lookup_field_vals->db_value.str)
2782
if (is_schema_db(lookup_field_vals->db_value.str,
2783
lookup_field_vals->db_value.length))
2786
if (files->push_back(i_s_name_copy))
2790
if (files->push_back(&lookup_field_vals->db_value))
2796
Create list of existing databases. It is used in case
2797
of select from information schema table
2799
if (files->push_back(i_s_name_copy))
2802
return (find_files(thd, files, NullS,
2803
mysql_data_home, NullS, 1) != FIND_FILES_OK);
2807
struct st_add_schema_table
2809
List<LEX_STRING> *files;
2814
static my_bool add_schema_table(THD *thd, plugin_ref plugin,
2817
LEX_STRING *file_name= 0;
2818
st_add_schema_table *data= (st_add_schema_table *)p_data;
2819
List<LEX_STRING> *file_list= data->files;
2820
const char *wild= data->wild;
2821
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
2822
DBUG_ENTER("add_schema_table");
2824
if (schema_table->hidden)
2828
if (lower_case_table_names)
2830
if (wild_case_compare(files_charset_info,
2831
schema_table->table_name,
2835
else if (wild_compare(schema_table->table_name, wild, 0))
2839
if ((file_name= thd->make_lex_string(file_name, schema_table->table_name,
2840
strlen(schema_table->table_name),
2842
!file_list->push_back(file_name))
2848
int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
2850
LEX_STRING *file_name= 0;
2851
ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
2852
st_add_schema_table add_data;
2853
DBUG_ENTER("schema_tables_add");
2855
for (; tmp_schema_table->table_name; tmp_schema_table++)
2857
if (tmp_schema_table->hidden)
2861
if (lower_case_table_names)
2863
if (wild_case_compare(files_charset_info,
2864
tmp_schema_table->table_name,
2868
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2872
thd->make_lex_string(file_name, tmp_schema_table->table_name,
2873
strlen(tmp_schema_table->table_name), TRUE)) &&
2874
!files->push_back(file_name))
2879
add_data.files= files;
2880
add_data.wild= wild;
2881
if (plugin_foreach(thd, add_schema_table,
2882
MYSQL_INFORMATION_SCHEMA_PLUGIN, &add_data))
2890
@brief Create table names list
2892
@details The function creates the list of table names in
2895
@param[in] thd thread handler
2896
@param[in] table_names List of table names in database
2897
@param[in] lex pointer to LEX struct
2898
@param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
2899
@param[in] with_i_schema TRUE means that we add I_S tables to list
2900
@param[in] db_name database name
2902
@return Operation status
2904
@retval 1 fatal error
2905
@retval 2 Not fatal error; Safe to ignore this file list
2909
make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
2910
LOOKUP_FIELD_VALUES *lookup_field_vals,
2911
bool with_i_schema, LEX_STRING *db_name)
2913
char path[FN_REFLEN + 1];
2914
build_table_filename(path, sizeof(path) - 1, db_name->str, "", "", 0);
2915
if (!lookup_field_vals->wild_table_value &&
2916
lookup_field_vals->table_value.str)
2920
if (find_schema_table(thd, lookup_field_vals->table_value.str))
2922
if (table_names->push_back(&lookup_field_vals->table_value))
2928
if (table_names->push_back(&lookup_field_vals->table_value))
2931
Check that table is relevant in current transaction.
2932
(used for ndb engine, see ndbcluster_find_files(), ha_ndbcluster.cc)
2934
VOID(ha_find_files(thd, db_name->str, path,
2935
lookup_field_vals->table_value.str, 0,
2942
This call will add all matching the wildcards (if specified) IS tables
2946
return (schema_tables_add(thd, table_names,
2947
lookup_field_vals->table_value.str));
2949
find_files_result res= find_files(thd, table_names, db_name->str, path,
2950
lookup_field_vals->table_value.str, 0);
2951
if (res != FIND_FILES_OK)
2954
Downgrade errors about problems with database directory to
2955
warnings if this is not a 'SHOW' command. Another thread
2956
may have dropped database, and we may still have a name
2959
if (res == FIND_FILES_DIR)
2961
if (lex->sql_command != SQLCOM_SELECT)
2973
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
2975
@param[in] thd thread handler
2976
@param[in] tables TABLE_LIST for I_S table
2977
@param[in] schema_table pointer to I_S structure
2978
@param[in] open_tables_state_backup pointer to Open_tables_state object
2979
which is used to save|restore original
2980
status of variables related to
2983
@return Operation status
2989
fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
2990
ST_SCHEMA_TABLE *schema_table,
2991
Open_tables_state *open_tables_state_backup)
2995
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
2996
enum_sql_command save_sql_command= lex->sql_command;
2997
TABLE_LIST *show_table_list= (TABLE_LIST*) tables->schema_select_lex->
2999
TABLE *table= tables->table;
3001
DBUG_ENTER("fill_schema_show");
3003
lex->all_selects_list= tables->schema_select_lex;
3005
Restore thd->temporary_tables to be able to process
3006
temporary tables(only for 'show index' & 'show columns').
3007
This should be changed when processing of temporary tables for
3008
I_S tables will be done.
3010
thd->temporary_tables= open_tables_state_backup->temporary_tables;
3012
Let us set fake sql_command so views won't try to merge
3013
themselves into main statement. If we don't do this,
3014
SELECT * from information_schema.xxxx will cause problems.
3015
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
3017
lex->sql_command= SQLCOM_SHOW_FIELDS;
3018
res= open_normal_and_derived_tables(thd, show_table_list,
3019
MYSQL_LOCK_IGNORE_FLUSH);
3020
lex->sql_command= save_sql_command;
3022
get_all_tables() returns 1 on failure and 0 on success thus
3023
return only these and not the result code of ::process_table()
3025
We should use show_table_list->alias instead of
3026
show_table_list->table_name because table_name
3027
could be changed during opening of I_S tables. It's safe
3028
to use alias because alias contains original table name
3029
in this case(this part of code is used only for
3030
'show columns' & 'show statistics' commands).
3032
table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
3033
strlen(show_table_list->alias), FALSE);
3034
if (!show_table_list->view)
3035
db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db,
3036
show_table_list->db_length, FALSE);
3038
db_name= &show_table_list->view_db;
3041
error= test(schema_table->process_table(thd, show_table_list,
3042
table, res, db_name,
3044
thd->temporary_tables= 0;
3045
close_tables_for_reopen(thd, &show_table_list);
3051
@brief Fill I_S table for SHOW TABLE NAMES commands
3053
@param[in] thd thread handler
3054
@param[in] table TABLE struct for I_S table
3055
@param[in] db_name database name
3056
@param[in] table_name table name
3057
@param[in] with_i_schema I_S table if TRUE
3059
@return Operation status
3064
static int fill_schema_table_names(THD *thd, TABLE *table,
3065
LEX_STRING *db_name, LEX_STRING *table_name,
3070
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
3071
system_charset_info);
3075
enum legacy_db_type not_used;
3076
char path[FN_REFLEN + 1];
3077
(void) build_table_filename(path, sizeof(path) - 1, db_name->str,
3078
table_name->str, reg_ext, 0);
3079
switch (mysql_frm_type(thd, path, ¬_used)) {
3081
table->field[3]->store(STRING_WITH_LEN("ERROR"),
3082
system_charset_info);
3085
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"),
3086
system_charset_info);
3089
table->field[3]->store(STRING_WITH_LEN("VIEW"),
3090
system_charset_info);
3095
if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
3101
if (schema_table_store_record(thd, table))
3108
@brief Get open table method
3110
@details The function calculates the method which will be used
3112
SKIP_OPEN_TABLE - do not open table
3113
OPEN_FRM_ONLY - open FRM file only
3114
OPEN_FULL_TABLE - open FRM, data, index files
3115
@param[in] tables I_S table table_list
3116
@param[in] schema_table I_S table struct
3117
@param[in] schema_table_idx I_S table index
3119
@return return a set of flags
3120
@retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
3123
uint get_table_open_method(TABLE_LIST *tables,
3124
ST_SCHEMA_TABLE *schema_table,
3125
enum enum_schema_tables schema_table_idx)
3128
determine which method will be used for table opening
3130
if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
3132
Field **ptr, *field;
3133
int table_open_method= 0, field_indx= 0;
3134
uint star_table_open_method= OPEN_FULL_TABLE;
3135
bool used_star= true; // true if '*' is used in select
3136
for (ptr=tables->table->field; (field= *ptr) ; ptr++)
3138
star_table_open_method=
3139
min(star_table_open_method,
3140
schema_table->fields_info[field_indx].open_method);
3141
if (bitmap_is_set(tables->table->read_set, field->field_index))
3144
table_open_method|= schema_table->fields_info[field_indx].open_method;
3149
return star_table_open_method;
3150
return table_open_method;
3152
/* I_S tables which use get_all_tables but can not be optimized */
3153
return (uint) OPEN_FULL_TABLE;
3158
@brief Fill I_S table with data from FRM file only
3160
@param[in] thd thread handler
3161
@param[in] table TABLE struct for I_S table
3162
@param[in] schema_table I_S table struct
3163
@param[in] db_name database name
3164
@param[in] table_name table name
3165
@param[in] schema_table_idx I_S table index
3167
@return Operation status
3168
@retval 0 Table is processed and we can continue
3170
@retval 1 It's view and we have to use
3171
open_tables function for this table
3174
static int fill_schema_table_from_frm(THD *thd,TABLE *table,
3175
ST_SCHEMA_TABLE *schema_table,
3176
LEX_STRING *db_name,
3177
LEX_STRING *table_name,
3178
enum enum_schema_tables schema_table_idx)
3182
TABLE_LIST table_list;
3185
char key[MAX_DBKEY_LENGTH];
3188
bzero((char*) &table_list, sizeof(TABLE_LIST));
3189
bzero((char*) &tbl, sizeof(TABLE));
3191
table_list.table_name= table_name->str;
3192
table_list.db= db_name->str;
3193
key_length= create_table_def_key(thd, key, &table_list, 0);
3194
pthread_mutex_lock(&LOCK_open);
3195
share= get_table_share(thd, &table_list, key,
3196
key_length, OPEN_VIEW, &error);
3205
if (schema_table->i_s_requested_object & OPEN_TABLE_ONLY)
3207
/* skip view processing */
3211
else if (schema_table->i_s_requested_object & OPEN_VIEW_FULL)
3214
tell get_all_tables() to fall back to
3215
open_normal_and_derived_tables()
3222
if (share->is_view ||
3223
!open_table_from_share(thd, share, table_name->str, 0,
3224
(READ_KEYINFO | COMPUTE_TYPES |
3225
EXTRA_RECORD | OPEN_FRM_FILE_ONLY),
3226
thd->open_options, &tbl, FALSE))
3229
table_list.table= &tbl;
3230
table_list.view= (st_lex*) share->is_view;
3231
res= schema_table->process_table(thd, &table_list, table,
3232
res, db_name, table_name);
3233
closefrm(&tbl, true);
3238
release_table_share(share, RELEASE_NORMAL);
3241
pthread_mutex_unlock(&LOCK_open);
3249
@brief Fill I_S tables whose data are retrieved
3250
from frm files and storage engine
3252
@details The information schema tables are internally represented as
3253
temporary tables that are filled at query execution time.
3254
Those I_S tables whose data are retrieved
3255
from frm files and storage engine are filled by the function
3258
@param[in] thd thread handler
3259
@param[in] tables I_S table
3260
@param[in] cond 'WHERE' condition
3262
@return Operation status
3267
int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
3270
TABLE *table= tables->table;
3271
SELECT_LEX *old_all_select_lex= lex->all_selects_list;
3272
enum_sql_command save_sql_command= lex->sql_command;
3273
SELECT_LEX *lsel= tables->schema_select_lex;
3274
ST_SCHEMA_TABLE *schema_table= tables->schema_table;
3276
LOOKUP_FIELD_VALUES lookup_field_vals;
3277
LEX_STRING *db_name, *table_name;
3279
enum enum_schema_tables schema_table_idx;
3280
List<LEX_STRING> db_names;
3281
List_iterator_fast<LEX_STRING> it(db_names);
3282
COND *partial_cond= 0;
3283
uint derived_tables= lex->derived_tables;
3285
Open_tables_state open_tables_state_backup;
3286
bool save_view_prepare_mode= lex->view_prepare_mode;
3287
Query_tables_list query_tables_list_backup;
3288
#ifndef NO_EMBEDDED_ACCESS_CHECKS
3289
Security_context *sctx= thd->security_ctx;
3291
uint table_open_method;
3292
DBUG_ENTER("get_all_tables");
3294
lex->view_prepare_mode= TRUE;
3295
lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
3298
We should not introduce deadlocks even if we already have some
3299
tables open and locked, since we won't lock tables which we will
3300
open and will ignore possible name-locks for these tables.
3302
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
3305
this branch processes SHOW FIELDS, SHOW INDEXES commands.
3306
see sql_parse.cc, prepare_schema_table() function where
3307
this values are initialized
3309
if (lsel && lsel->table_list.first)
3311
error= fill_schema_show_cols_or_idxs(thd, tables, schema_table,
3312
&open_tables_state_backup);
3316
schema_table_idx= get_schema_table_idx(schema_table);
3317
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
3322
DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
3323
STR_OR_NIL(lookup_field_vals.db_value.str),
3324
STR_OR_NIL(lookup_field_vals.table_value.str)));
3326
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
3329
if lookup value is empty string then
3330
it's impossible table name or db name
3332
if ((lookup_field_vals.db_value.str &&
3333
!lookup_field_vals.db_value.str[0]) ||
3334
(lookup_field_vals.table_value.str &&
3335
!lookup_field_vals.table_value.str[0]))
3342
if (lookup_field_vals.db_value.length &&
3343
!lookup_field_vals.wild_db_value)
3344
tables->has_db_lookup_value= TRUE;
3345
if (lookup_field_vals.table_value.length &&
3346
!lookup_field_vals.wild_table_value)
3347
tables->has_table_lookup_value= TRUE;
3349
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
3352
partial_cond= make_cond_for_info_schema(cond, tables);
3354
tables->table_open_method= table_open_method=
3355
get_table_open_method(tables, schema_table, schema_table_idx);
3359
/* EXPLAIN SELECT */
3364
if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
3366
it.rewind(); /* To get access to new elements in basis list */
3367
while ((db_name= it++))
3369
#ifndef NO_EMBEDDED_ACCESS_CHECKS
3370
if (!(check_access(thd,SELECT_ACL, db_name->str,
3371
&thd->col_access, 0, 1, with_i_schema) ||
3372
(!thd->col_access && check_grant_db(thd, db_name->str))) ||
3373
sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
3374
acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0))
3377
thd->no_warnings_for_error= 1;
3378
List<LEX_STRING> table_names;
3379
int res= make_table_name_list(thd, &table_names, lex,
3381
with_i_schema, db_name);
3382
if (res == 2) /* Not fatal error, continue */
3387
List_iterator_fast<LEX_STRING> it_files(table_names);
3388
while ((table_name= it_files++))
3390
restore_record(table, s->default_values);
3391
table->field[schema_table->idx_field1]->
3392
store(db_name->str, db_name->length, system_charset_info);
3393
table->field[schema_table->idx_field2]->
3394
store(table_name->str, table_name->length, system_charset_info);
3396
if (!partial_cond || partial_cond->val_int())
3399
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
3400
we can skip table opening and we don't have lookup value for
3401
table name or lookup value is wild string(table name list is
3402
already created by make_table_name_list() function).
3404
if (!table_open_method && schema_table_idx == SCH_TABLES &&
3405
(!lookup_field_vals.table_value.length ||
3406
lookup_field_vals.wild_table_value))
3408
if (schema_table_store_record(thd, table))
3409
goto err; /* Out of space in temporary table */
3413
/* SHOW TABLE NAMES command */
3414
if (schema_table_idx == SCH_TABLE_NAMES)
3416
if (fill_schema_table_names(thd, tables->table, db_name,
3417
table_name, with_i_schema))
3422
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
3425
if (!fill_schema_table_from_frm(thd, table, schema_table, db_name,
3426
table_name, schema_table_idx))
3431
LEX_STRING tmp_lex_string, orig_db_name;
3433
Set the parent lex of 'sel' because it is needed by
3434
sel.init_query() which is called inside make_table_list.
3436
thd->no_warnings_for_error= 1;
3437
sel.parent_lex= lex;
3438
/* db_name can be changed in make_table_list() func */
3439
if (!thd->make_lex_string(&orig_db_name, db_name->str,
3440
db_name->length, FALSE))
3442
if (make_table_list(thd, &sel, db_name, table_name))
3444
TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first;
3445
lex->all_selects_list= &sel;
3446
lex->derived_tables= 0;
3447
lex->sql_command= SQLCOM_SHOW_FIELDS;
3448
show_table_list->i_s_requested_object=
3449
schema_table->i_s_requested_object;
3450
res= open_normal_and_derived_tables(thd, show_table_list,
3451
MYSQL_LOCK_IGNORE_FLUSH);
3452
lex->sql_command= save_sql_command;
3454
XXX: show_table_list has a flag i_is_requested,
3455
and when it's set, open_normal_and_derived_tables()
3456
can return an error without setting an error message
3457
in THD, which is a hack. This is why we have to
3458
check for res, then for thd->is_error() only then
3459
for thd->main_da.sql_errno().
3461
if (res && thd->is_error() &&
3462
thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
3465
Hide error for not existing table.
3466
This error can occur for example when we use
3467
where condition with db name and table name and this
3468
table does not exist.
3476
We should use show_table_list->alias instead of
3477
show_table_list->table_name because table_name
3478
could be changed during opening of I_S tables. It's safe
3479
to use alias because alias contains original table name
3482
thd->make_lex_string(&tmp_lex_string, show_table_list->alias,
3483
strlen(show_table_list->alias), FALSE);
3484
res= schema_table->process_table(thd, show_table_list, table,
3487
close_tables_for_reopen(thd, &show_table_list);
3489
DBUG_ASSERT(!lex->query_tables_own_last);
3496
If we have information schema its always the first table and only
3497
the first table. Reset for other tables.
3505
thd->restore_backup_open_tables_state(&open_tables_state_backup);
3506
lex->restore_backup_query_tables_list(&query_tables_list_backup);
3507
lex->derived_tables= derived_tables;
3508
lex->all_selects_list= old_all_select_lex;
3509
lex->view_prepare_mode= save_view_prepare_mode;
3510
lex->sql_command= save_sql_command;
3515
bool store_schema_shemata(THD* thd, TABLE *table, LEX_STRING *db_name,
3518
restore_record(table, s->default_values);
3519
table->field[1]->store(db_name->str, db_name->length, system_charset_info);
3520
table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
3521
table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
3522
return schema_table_store_record(thd, table);
3526
int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
3529
TODO: fill_schema_shemata() is called when new client is connected.
3530
Returning error status in this case leads to client hangup.
3533
LOOKUP_FIELD_VALUES lookup_field_vals;
3534
List<LEX_STRING> db_names;
3535
LEX_STRING *db_name;
3537
HA_CREATE_INFO create;
3538
TABLE *table= tables->table;
3539
#ifndef NO_EMBEDDED_ACCESS_CHECKS
3540
Security_context *sctx= thd->security_ctx;
3542
DBUG_ENTER("fill_schema_shemata");
3544
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
3546
DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
3547
lookup_field_vals.db_value.str,
3548
lookup_field_vals.table_value.str));
3549
if (make_db_list(thd, &db_names, &lookup_field_vals,
3554
If we have lookup db value we should check that the database exists
3556
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
3559
char path[FN_REFLEN+16];
3562
if (!lookup_field_vals.db_value.str[0])
3564
path_len= build_table_filename(path, sizeof(path) - 1,
3565
lookup_field_vals.db_value.str, "", "", 0);
3566
path[path_len-1]= 0;
3567
if (!my_stat(path,&stat_info,MYF(0)))
3571
List_iterator_fast<LEX_STRING> it(db_names);
3572
while ((db_name=it++))
3574
if (with_i_schema) // information schema name is always first in list
3576
if (store_schema_shemata(thd, table, db_name,
3577
system_charset_info))
3582
#ifndef NO_EMBEDDED_ACCESS_CHECKS
3583
if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
3584
acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) ||
3585
!check_grant_db(thd, db_name->str))
3588
load_db_opt_by_name(thd, db_name->str, &create);
3589
if (store_schema_shemata(thd, table, db_name,
3590
create.default_table_charset))
3598
static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
3599
TABLE *table, bool res,
3600
LEX_STRING *db_name,
3601
LEX_STRING *table_name)
3603
const char *tmp_buff;
3605
CHARSET_INFO *cs= system_charset_info;
3606
DBUG_ENTER("get_schema_tables_record");
3608
restore_record(table, s->default_values);
3609
table->field[1]->store(db_name->str, db_name->length, cs);
3610
table->field[2]->store(table_name->str, table_name->length, cs);
3614
there was errors during opening tables
3616
const char *error= thd->is_error() ? thd->main_da.message() : "";
3618
table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
3619
else if (tables->schema_table)
3620
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
3622
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
3623
table->field[20]->store(error, strlen(error), cs);
3626
else if (tables->view)
3628
table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
3629
table->field[20]->store(STRING_WITH_LEN("VIEW"), cs);
3633
char option_buff[350],*ptr;
3634
TABLE *show_table= tables->table;
3635
TABLE_SHARE *share= show_table->s;
3636
handler *file= show_table->file;
3637
handlerton *tmp_db_type= share->db_type();
3638
#ifdef WITH_PARTITION_STORAGE_ENGINE
3639
bool is_partitioned= FALSE;
3641
if (share->tmp_table == SYSTEM_TMP_TABLE)
3642
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
3643
else if (share->tmp_table)
3644
table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
3646
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
3648
for (int i= 4; i < 20; i++)
3650
if (i == 7 || (i > 12 && i < 17) || i == 18)
3652
table->field[i]->set_notnull();
3654
#ifdef WITH_PARTITION_STORAGE_ENGINE
3655
if (share->db_type() == partition_hton &&
3656
share->partition_info_len)
3658
tmp_db_type= share->default_part_db_type;
3659
is_partitioned= TRUE;
3662
tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
3663
table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
3664
table->field[5]->store((longlong) share->frm_version, TRUE);
3667
if (share->min_rows)
3669
ptr=strmov(ptr," min_rows=");
3670
ptr=longlong10_to_str(share->min_rows,ptr,10);
3672
if (share->max_rows)
3674
ptr=strmov(ptr," max_rows=");
3675
ptr=longlong10_to_str(share->max_rows,ptr,10);
3677
if (share->avg_row_length)
3679
ptr=strmov(ptr," avg_row_length=");
3680
ptr=longlong10_to_str(share->avg_row_length,ptr,10);
3682
if (share->db_create_options & HA_OPTION_PACK_KEYS)
3683
ptr=strmov(ptr," pack_keys=1");
3684
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
3685
ptr=strmov(ptr," pack_keys=0");
3686
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
3687
if (share->db_create_options & HA_OPTION_CHECKSUM)
3688
ptr=strmov(ptr," checksum=1");
3689
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
3690
ptr=strmov(ptr," delay_key_write=1");
3691
if (share->row_type != ROW_TYPE_DEFAULT)
3692
ptr=strxmov(ptr, " row_format=",
3693
ha_row_type[(uint) share->row_type],
3695
if (share->key_block_size)
3697
ptr= strmov(ptr, " KEY_BLOCK_SIZE=");
3698
ptr= longlong10_to_str(share->key_block_size, ptr, 10);
3700
#ifdef WITH_PARTITION_STORAGE_ENGINE
3702
ptr= strmov(ptr, " partitioned");
3704
table->field[19]->store(option_buff+1,
3705
(ptr == option_buff ? 0 :
3706
(uint) (ptr-option_buff)-1), cs);
3708
tmp_buff= (share->table_charset ?
3709
share->table_charset->name : "default");
3710
table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
3712
if (share->comment.str)
3713
table->field[20]->store(share->comment.str, share->comment.length, cs);
3717
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO);
3718
enum row_type row_type = file->get_row_type();
3720
case ROW_TYPE_NOT_USED:
3721
case ROW_TYPE_DEFAULT:
3722
tmp_buff= ((share->db_options_in_use &
3723
HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
3724
(share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
3725
"Dynamic" : "Fixed");
3727
case ROW_TYPE_FIXED:
3730
case ROW_TYPE_DYNAMIC:
3731
tmp_buff= "Dynamic";
3733
case ROW_TYPE_COMPRESSED:
3734
tmp_buff= "Compressed";
3736
case ROW_TYPE_REDUNDANT:
3737
tmp_buff= "Redundant";
3739
case ROW_TYPE_COMPACT:
3740
tmp_buff= "Compact";
3746
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
3747
if (!tables->schema_table)
3749
table->field[7]->store((longlong) file->stats.records, TRUE);
3750
table->field[7]->set_notnull();
3752
table->field[8]->store((longlong) file->stats.mean_rec_length, TRUE);
3753
table->field[9]->store((longlong) file->stats.data_file_length, TRUE);
3754
if (file->stats.max_data_file_length)
3756
table->field[10]->store((longlong) file->stats.max_data_file_length,
3759
table->field[11]->store((longlong) file->stats.index_file_length, TRUE);
3760
table->field[12]->store((longlong) file->stats.delete_length, TRUE);
3761
if (show_table->found_next_number_field)
3763
table->field[13]->store((longlong) file->stats.auto_increment_value,
3765
table->field[13]->set_notnull();
3767
if (file->stats.create_time)
3769
thd->variables.time_zone->gmt_sec_to_TIME(&time,
3770
(my_time_t) file->stats.create_time);
3771
table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
3772
table->field[14]->set_notnull();
3774
if (file->stats.update_time)
3776
thd->variables.time_zone->gmt_sec_to_TIME(&time,
3777
(my_time_t) file->stats.update_time);
3778
table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
3779
table->field[15]->set_notnull();
3781
if (file->stats.check_time)
3783
thd->variables.time_zone->gmt_sec_to_TIME(&time,
3784
(my_time_t) file->stats.check_time);
3785
table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
3786
table->field[16]->set_notnull();
3788
if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
3790
table->field[18]->store((longlong) file->checksum(), TRUE);
3791
table->field[18]->set_notnull();
3795
DBUG_RETURN(schema_table_store_record(thd, table));
3799
static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
3800
TABLE *table, bool res,
3801
LEX_STRING *db_name,
3802
LEX_STRING *table_name)
3805
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3806
CHARSET_INFO *cs= system_charset_info;
3810
DBUG_ENTER("get_schema_column_record");
3814
if (lex->sql_command != SQLCOM_SHOW_FIELDS)
3817
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
3818
rather than in SHOW COLUMNS
3820
if (thd->is_error())
3821
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3822
thd->main_da.sql_errno(), thd->main_da.message());
3829
show_table= tables->table;
3831
restore_record(show_table, s->default_values);
3832
show_table->use_all_columns(); // Required for default
3834
for (ptr= show_table->field; (field= *ptr) ; ptr++)
3836
const char *tmp_buff;
3839
uint flags=field->flags;
3840
char tmp[MAX_FIELD_WIDTH];
3841
String type(tmp,sizeof(tmp), system_charset_info);
3843
int decimals, field_length;
3845
if (wild && wild[0] &&
3846
wild_case_compare(system_charset_info, field->field_name,wild))
3849
flags= field->flags;
3851
/* Get default row, with all NULL fields set to NULL */
3852
restore_record(table, s->default_values);
3854
#ifndef NO_EMBEDDED_ACCESS_CHECKS
3856
check_access(thd,SELECT_ACL | EXTRA_ACL, db_name->str,
3857
&tables->grant.privilege, 0, 0, test(tables->schema_table));
3858
col_access= get_column_grant(thd, &tables->grant,
3859
db_name->str, table_name->str,
3860
field->field_name) & COL_ACLS;
3861
if (!tables->schema_table && !col_access)
3864
for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
3869
end=strmov(end,grant_types.type_names[bitnr]);
3872
table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);
3875
table->field[1]->store(db_name->str, db_name->length, cs);
3876
table->field[2]->store(table_name->str, table_name->length, cs);
3877
table->field[3]->store(field->field_name, strlen(field->field_name),
3879
table->field[4]->store((longlong) count, TRUE);
3880
field->sql_type(type);
3881
table->field[14]->store(type.ptr(), type.length(), cs);
3883
MySQL column type has the following format:
3884
base_type [(dimension)] [unsigned] [zerofill].
3885
For DATA_TYPE column we extract only base type.
3887
tmp_buff= strchr(type.ptr(), '(');
3890
if there is no dimention part then check the presence of
3891
[unsigned] [zerofill] attributes and cut them of if exist.
3893
tmp_buff= strchr(type.ptr(), ' ');
3894
table->field[7]->store(type.ptr(),
3895
(tmp_buff ? tmp_buff - type.ptr() :
3896
type.length()), cs);
3898
if (get_field_default_value(thd, show_table, field, &type, 0))
3900
table->field[5]->store(type.ptr(), type.length(), cs);
3901
table->field[5]->set_notnull();
3903
pos=(uchar*) ((flags & NOT_NULL_FLAG) ? "NO" : "YES");
3904
table->field[6]->store((const char*) pos,
3905
strlen((const char*) pos), cs);
3906
is_blob= (field->type() == MYSQL_TYPE_BLOB);
3907
if (field->has_charset() || is_blob ||
3908
field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type
3909
field->real_type() == MYSQL_TYPE_STRING) // For binary type
3911
uint32 octet_max_length= field->max_display_length();
3912
if (is_blob && octet_max_length != (uint32) 4294967295U)
3913
octet_max_length /= field->charset()->mbmaxlen;
3914
longlong char_max_len= is_blob ?
3915
(longlong) octet_max_length / field->charset()->mbminlen :
3916
(longlong) octet_max_length / field->charset()->mbmaxlen;
3917
table->field[8]->store(char_max_len, TRUE);
3918
table->field[8]->set_notnull();
3919
table->field[9]->store((longlong) octet_max_length, TRUE);
3920
table->field[9]->set_notnull();
3924
Calculate field_length and decimals.
3925
They are set to -1 if they should not be set (we should return NULL)
3928
decimals= field->decimals();
3929
switch (field->type()) {
3930
case MYSQL_TYPE_NEWDECIMAL:
3931
field_length= ((Field_new_decimal*) field)->precision;
3933
case MYSQL_TYPE_DECIMAL:
3934
field_length= field->field_length - (decimals ? 2 : 1);
3936
case MYSQL_TYPE_TINY:
3937
case MYSQL_TYPE_SHORT:
3938
case MYSQL_TYPE_LONG:
3939
case MYSQL_TYPE_LONGLONG:
3940
case MYSQL_TYPE_INT24:
3941
field_length= field->max_display_length() - 1;
3943
case MYSQL_TYPE_BIT:
3944
field_length= field->max_display_length();
3945
decimals= -1; // return NULL
3947
case MYSQL_TYPE_FLOAT:
3948
case MYSQL_TYPE_DOUBLE:
3949
field_length= field->field_length;
3950
if (decimals == NOT_FIXED_DEC)
3951
decimals= -1; // return NULL
3954
field_length= decimals= -1;
3958
if (field_length >= 0)
3960
table->field[10]->store((longlong) field_length, TRUE);
3961
table->field[10]->set_notnull();
3965
table->field[11]->store((longlong) decimals, TRUE);
3966
table->field[11]->set_notnull();
3969
if (field->has_charset())
3971
pos=(uchar*) field->charset()->csname;
3972
table->field[12]->store((const char*) pos,
3973
strlen((const char*) pos), cs);
3974
table->field[12]->set_notnull();
3975
pos=(uchar*) field->charset()->name;
3976
table->field[13]->store((const char*) pos,
3977
strlen((const char*) pos), cs);
3978
table->field[13]->set_notnull();
3980
pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
3981
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
3982
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
3983
table->field[15]->store((const char*) pos,
3984
strlen((const char*) pos), cs);
3987
if (field->unireg_check == Field::NEXT_NUMBER)
3988
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
3989
if (show_table->timestamp_field == field &&
3990
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3991
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3994
table->field[18]->store(field->comment.str, field->comment.length, cs);
3995
if (schema_table_store_record(thd, table))
4003
int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
4006
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
4007
TABLE *table= tables->table;
4008
CHARSET_INFO *scs= system_charset_info;
4010
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
4012
CHARSET_INFO *tmp_cs= cs[0];
4013
if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
4014
(tmp_cs->state & MY_CS_AVAILABLE) &&
4015
!(tmp_cs->state & MY_CS_HIDDEN) &&
4016
!(wild && wild[0] &&
4017
wild_case_compare(scs, tmp_cs->csname,wild)))
4019
const char *comment;
4020
restore_record(table, s->default_values);
4021
table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
4022
table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
4023
comment= tmp_cs->comment ? tmp_cs->comment : "";
4024
table->field[2]->store(comment, strlen(comment), scs);
4025
table->field[3]->store((longlong) tmp_cs->mbmaxlen, TRUE);
4026
if (schema_table_store_record(thd, table))
4034
static my_bool iter_schema_engines(THD *thd, plugin_ref plugin,
4037
TABLE *table= (TABLE *) ptable;
4038
handlerton *hton= plugin_data(plugin, handlerton *);
4039
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
4040
CHARSET_INFO *scs= system_charset_info;
4041
handlerton *default_type= ha_default_handlerton(thd);
4042
DBUG_ENTER("iter_schema_engines");
4045
/* Disabled plugins */
4046
if (plugin_state(plugin) != PLUGIN_IS_READY)
4049
struct st_mysql_plugin *plug= plugin_decl(plugin);
4050
if (!(wild && wild[0] &&
4051
wild_case_compare(scs, plug->name,wild)))
4053
restore_record(table, s->default_values);
4054
table->field[0]->store(plug->name, strlen(plug->name), scs);
4055
table->field[1]->store(C_STRING_WITH_LEN("NO"), scs);
4056
table->field[2]->store(plug->descr, strlen(plug->descr), scs);
4057
if (schema_table_store_record(thd, table))
4063
if (!(hton->flags & HTON_HIDDEN))
4065
LEX_STRING *name= plugin_name(plugin);
4066
if (!(wild && wild[0] &&
4067
wild_case_compare(scs, name->str,wild)))
4069
LEX_STRING yesno[2]= {{ C_STRING_WITH_LEN("NO") },
4070
{ C_STRING_WITH_LEN("YES") }};
4072
const char *option_name= show_comp_option_name[(int) hton->state];
4073
restore_record(table, s->default_values);
4075
table->field[0]->store(name->str, name->length, scs);
4076
if (hton->state == SHOW_OPTION_YES && default_type == hton)
4077
option_name= "DEFAULT";
4078
table->field[1]->store(option_name, strlen(option_name), scs);
4079
table->field[2]->store(plugin_decl(plugin)->descr,
4080
strlen(plugin_decl(plugin)->descr), scs);
4081
tmp= &yesno[test(hton->commit)];
4082
table->field[3]->store(tmp->str, tmp->length, scs);
4083
table->field[3]->set_notnull();
4084
tmp= &yesno[test(hton->prepare)];
4085
table->field[4]->store(tmp->str, tmp->length, scs);
4086
table->field[4]->set_notnull();
4087
tmp= &yesno[test(hton->savepoint_set)];
4088
table->field[5]->store(tmp->str, tmp->length, scs);
4089
table->field[5]->set_notnull();
4091
if (schema_table_store_record(thd, table))
4098
int fill_schema_engines(THD *thd, TABLE_LIST *tables, COND *cond)
4100
DBUG_ENTER("fill_schema_engines");
4101
if (plugin_foreach_with_mask(thd, iter_schema_engines,
4102
MYSQL_STORAGE_ENGINE_PLUGIN,
4103
~PLUGIN_IS_FREED, tables->table))
4109
int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
4112
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
4113
TABLE *table= tables->table;
4114
CHARSET_INFO *scs= system_charset_info;
4115
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
4118
CHARSET_INFO *tmp_cs= cs[0];
4119
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
4120
(tmp_cs->state & MY_CS_HIDDEN) ||
4121
!(tmp_cs->state & MY_CS_PRIMARY))
4123
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
4125
CHARSET_INFO *tmp_cl= cl[0];
4126
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
4127
!my_charset_same(tmp_cs, tmp_cl))
4129
if (!(wild && wild[0] &&
4130
wild_case_compare(scs, tmp_cl->name,wild)))
4132
const char *tmp_buff;
4133
restore_record(table, s->default_values);
4134
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
4135
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
4136
table->field[2]->store((longlong) tmp_cl->number, TRUE);
4137
tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
4138
table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
4139
tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
4140
table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
4141
table->field[5]->store((longlong) tmp_cl->strxfrm_multiply, TRUE);
4142
if (schema_table_store_record(thd, table))
4151
int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
4154
TABLE *table= tables->table;
4155
CHARSET_INFO *scs= system_charset_info;
4156
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
4159
CHARSET_INFO *tmp_cs= cs[0];
4160
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
4161
!(tmp_cs->state & MY_CS_PRIMARY))
4163
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
4165
CHARSET_INFO *tmp_cl= cl[0];
4166
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
4167
!my_charset_same(tmp_cs,tmp_cl))
4169
restore_record(table, s->default_values);
4170
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
4171
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
4172
if (schema_table_store_record(thd, table))
4180
bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
4181
const char *wild, bool full_access, const char *sp_user)
4184
String sp_db, sp_name, definer;
4187
CHARSET_INFO *cs= system_charset_info;
4188
get_field(thd->mem_root, proc_table->field[0], &sp_db);
4189
get_field(thd->mem_root, proc_table->field[1], &sp_name);
4190
get_field(thd->mem_root, proc_table->field[11], &definer);
4192
full_access= !strcmp(sp_user, definer.ptr());
4193
if (!full_access && check_some_routine_access(thd, sp_db.ptr(),
4195
proc_table->field[2]->
4197
TYPE_ENUM_PROCEDURE))
4200
if ((lex->sql_command == SQLCOM_SHOW_STATUS_PROC &&
4201
proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE) ||
4202
(lex->sql_command == SQLCOM_SHOW_STATUS_FUNC &&
4203
proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) ||
4204
(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)
4206
restore_record(table, s->default_values);
4207
if (!wild || !wild[0] || !wild_compare(sp_name.ptr(), wild, 0))
4209
int enum_idx= (int) proc_table->field[5]->val_int();
4210
table->field[3]->store(sp_name.ptr(), sp_name.length(), cs);
4211
get_field(thd->mem_root, proc_table->field[3], &tmp_string);
4212
table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs);
4213
table->field[2]->store(sp_db.ptr(), sp_db.length(), cs);
4214
get_field(thd->mem_root, proc_table->field[2], &tmp_string);
4215
table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs);
4216
if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION)
4218
get_field(thd->mem_root, proc_table->field[9], &tmp_string);
4219
table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs);
4220
table->field[5]->set_notnull();
4224
get_field(thd->mem_root, proc_table->field[19], &tmp_string);
4225
table->field[7]->store(tmp_string.ptr(), tmp_string.length(), cs);
4226
table->field[7]->set_notnull();
4228
table->field[6]->store(STRING_WITH_LEN("SQL"), cs);
4229
table->field[10]->store(STRING_WITH_LEN("SQL"), cs);
4230
get_field(thd->mem_root, proc_table->field[6], &tmp_string);
4231
table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs);
4232
table->field[12]->store(sp_data_access_name[enum_idx].str,
4233
sp_data_access_name[enum_idx].length , cs);
4234
get_field(thd->mem_root, proc_table->field[7], &tmp_string);
4235
table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs);
4236
bzero((char *)&time, sizeof(time));
4237
((Field_timestamp *) proc_table->field[12])->get_time(&time);
4238
table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
4239
bzero((char *)&time, sizeof(time));
4240
((Field_timestamp *) proc_table->field[13])->get_time(&time);
4241
table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
4242
get_field(thd->mem_root, proc_table->field[14], &tmp_string);
4243
table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs);
4244
get_field(thd->mem_root, proc_table->field[15], &tmp_string);
4245
table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs);
4246
table->field[19]->store(definer.ptr(), definer.length(), cs);
4248
get_field(thd->mem_root, proc_table->field[16], &tmp_string);
4249
table->field[20]->store(tmp_string.ptr(), tmp_string.length(), cs);
4251
get_field(thd->mem_root, proc_table->field[17], &tmp_string);
4252
table->field[21]->store(tmp_string.ptr(), tmp_string.length(), cs);
4254
get_field(thd->mem_root, proc_table->field[18], &tmp_string);
4255
table->field[22]->store(tmp_string.ptr(), tmp_string.length(), cs);
4257
return schema_table_store_record(thd, table);
4264
int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
4267
TABLE_LIST proc_tables;
4268
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
4270
TABLE *table= tables->table;
4272
char definer[USER_HOST_BUFF_SIZE];
4273
Open_tables_state open_tables_state_backup;
4274
DBUG_ENTER("fill_schema_proc");
4276
strxmov(definer, thd->security_ctx->priv_user, "@",
4277
thd->security_ctx->priv_host, NullS);
4278
/* We use this TABLE_LIST instance only for checking of privileges. */
4279
bzero((char*) &proc_tables,sizeof(proc_tables));
4280
proc_tables.db= (char*) "mysql";
4281
proc_tables.db_length= 5;
4282
proc_tables.table_name= proc_tables.alias= (char*) "proc";
4283
proc_tables.table_name_length= 4;
4284
proc_tables.lock_type= TL_READ;
4285
full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1, TRUE);
4286
if (!(proc_table= open_proc_table_for_read(thd, &open_tables_state_backup)))
4290
proc_table->file->ha_index_init(0, 1);
4291
if ((res= proc_table->file->index_first(proc_table->record[0])))
4293
res= (res == HA_ERR_END_OF_FILE) ? 0 : 1;
4296
if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
4301
while (!proc_table->file->index_next(proc_table->record[0]))
4303
if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
4311
proc_table->file->ha_index_end();
4312
close_system_tables(thd, &open_tables_state_backup);
4317
static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
4318
TABLE *table, bool res,
4319
LEX_STRING *db_name,
4320
LEX_STRING *table_name)
4322
CHARSET_INFO *cs= system_charset_info;
4323
DBUG_ENTER("get_schema_stat_record");
4326
if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
4329
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
4330
rather than in SHOW KEYS
4332
if (thd->is_error())
4333
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
4334
thd->main_da.sql_errno(), thd->main_da.message());
4340
else if (!tables->view)
4342
TABLE *show_table= tables->table;
4343
KEY *key_info=show_table->s->key_info;
4344
if (show_table->file)
4345
show_table->file->info(HA_STATUS_VARIABLE |
4348
for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
4350
KEY_PART_INFO *key_part= key_info->key_part;
4352
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
4354
restore_record(table, s->default_values);
4355
table->field[1]->store(db_name->str, db_name->length, cs);
4356
table->field[2]->store(table_name->str, table_name->length, cs);
4357
table->field[3]->store((longlong) ((key_info->flags &
4358
HA_NOSAME) ? 0 : 1), TRUE);
4359
table->field[4]->store(db_name->str, db_name->length, cs);
4360
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
4361
table->field[6]->store((longlong) (j+1), TRUE);
4362
str=(key_part->field ? key_part->field->field_name :
4364
table->field[7]->store(str, strlen(str), cs);
4365
if (show_table->file)
4367
if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
4369
table->field[8]->store(((key_part->key_part_flag &
4372
table->field[8]->set_notnull();
4374
KEY *key=show_table->key_info+i;
4375
if (key->rec_per_key[j])
4377
ha_rows records=(show_table->file->stats.records /
4378
key->rec_per_key[j]);
4379
table->field[9]->store((longlong) records, TRUE);
4380
table->field[9]->set_notnull();
4382
str= show_table->file->index_type(i);
4383
table->field[13]->store(str, strlen(str), cs);
4385
if (!(key_info->flags & HA_FULLTEXT) &&
4388
show_table->s->field[key_part->fieldnr-1]->key_length()))
4390
table->field[10]->store((longlong) key_part->length /
4391
key_part->field->charset()->mbmaxlen, TRUE);
4392
table->field[10]->set_notnull();
4394
uint flags= key_part->field ? key_part->field->flags : 0;
4395
const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
4396
table->field[12]->store(pos, strlen(pos), cs);
4397
if (!show_table->s->keys_in_use.is_set(i))
4398
table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
4400
table->field[14]->store("", 0, cs);
4401
table->field[14]->set_notnull();
4402
if (schema_table_store_record(thd, table))
4411
static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
4412
TABLE *table, bool res,
4413
LEX_STRING *db_name,
4414
LEX_STRING *table_name)
4416
CHARSET_INFO *cs= system_charset_info;
4417
DBUG_ENTER("get_schema_views_record");
4418
LEX_STRING *tmp_db_name, *tmp_table_name;
4419
char definer[USER_HOST_BUFF_SIZE];
4421
bool updatable_view;
4423
if SELECT FROM I_S.VIEWS uses only fields
4424
which have OPEN_FRM_ONLY flag then 'tables'
4425
structure is zeroed and only tables->view is set.
4426
(see fill_schema_table_from_frm() function).
4427
So we should disable other fields filling.
4429
bool only_share= !tables->definer.user.str;
4433
Security_context *sctx= thd->security_ctx;
4434
if (!only_share && !tables->allowed_show)
4436
if (!my_strcasecmp(system_charset_info, tables->definer.user.str,
4438
!my_strcasecmp(system_charset_info, tables->definer.host.str,
4440
tables->allowed_show= TRUE;
4441
#ifndef NO_EMBEDDED_ACCESS_CHECKS
4444
if ((thd->col_access & (SHOW_VIEW_ACL|SELECT_ACL)) ==
4445
(SHOW_VIEW_ACL|SELECT_ACL))
4446
tables->allowed_show= TRUE;
4449
TABLE_LIST table_list;
4451
memset(&table_list, 0, sizeof(table_list));
4452
table_list.db= tables->view_db.str;
4453
table_list.table_name= tables->view_name.str;
4454
table_list.grant.privilege= thd->col_access;
4455
view_access= get_table_grant(thd, &table_list);
4456
if ((view_access & (SHOW_VIEW_ACL|SELECT_ACL)) ==
4457
(SHOW_VIEW_ACL|SELECT_ACL))
4458
tables->allowed_show= TRUE;
4463
restore_record(table, s->default_values);
4464
tmp_db_name= &tables->view_db;
4465
tmp_table_name= &tables->view_name;
4468
tmp_db_name= db_name;
4469
tmp_table_name= table_name;
4471
table->field[1]->store(tmp_db_name->str, tmp_db_name->length, cs);
4472
table->field[2]->store(tmp_table_name->str, tmp_table_name->length, cs);
4475
if (tables->allowed_show)
4477
table->field[3]->store(tables->view_body_utf8.str,
4478
tables->view_body_utf8.length,
4482
if (tables->with_check != VIEW_CHECK_NONE)
4484
if (tables->with_check == VIEW_CHECK_LOCAL)
4485
table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs);
4487
table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs);
4490
table->field[4]->store(STRING_WITH_LEN("NONE"), cs);
4493
if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE)
4496
We should use tables->view->select_lex.item_list here and
4497
can not use Field_iterator_view because the view always uses
4498
temporary algorithm during opening for I_S and
4499
TABLE_LIST fields 'field_translation' & 'field_translation_end'
4500
are uninitialized is this case.
4502
List<Item> *fields= &tables->view->select_lex.item_list;
4503
List_iterator<Item> it(*fields);
4507
check that at least one column in view is updatable
4509
while ((item= it++))
4511
if ((field= item->filed_for_view_update()) && field->field &&
4512
!field->field->table->pos_in_table_list->schema_table)
4518
if (updatable_view && !tables->view->can_be_merged())
4522
table->field[5]->store(STRING_WITH_LEN("YES"), cs);
4524
table->field[5]->store(STRING_WITH_LEN("NO"), cs);
4525
definer_len= (strxmov(definer, tables->definer.user.str, "@",
4526
tables->definer.host.str, NullS) - definer);
4527
table->field[6]->store(definer, definer_len, cs);
4528
if (tables->view_suid)
4529
table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);
4531
table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs);
4533
table->field[8]->store(tables->view_creation_ctx->get_client_cs()->csname,
4534
strlen(tables->view_creation_ctx->
4535
get_client_cs()->csname), cs);
4537
table->field[9]->store(tables->view_creation_ctx->
4538
get_connection_cl()->name,
4539
strlen(tables->view_creation_ctx->
4540
get_connection_cl()->name), cs);
4543
if (schema_table_store_record(thd, table))
4545
if (res && thd->is_error())
4546
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
4547
thd->main_da.sql_errno(), thd->main_da.message());
4555
bool store_constraints(THD *thd, TABLE *table, LEX_STRING *db_name,
4556
LEX_STRING *table_name, const char *key_name,
4557
uint key_len, const char *con_type, uint con_len)
4559
CHARSET_INFO *cs= system_charset_info;
4560
restore_record(table, s->default_values);
4561
table->field[1]->store(db_name->str, db_name->length, cs);
4562
table->field[2]->store(key_name, key_len, cs);
4563
table->field[3]->store(db_name->str, db_name->length, cs);
4564
table->field[4]->store(table_name->str, table_name->length, cs);
4565
table->field[5]->store(con_type, con_len, cs);
4566
return schema_table_store_record(thd, table);
4570
static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
4571
TABLE *table, bool res,
4572
LEX_STRING *db_name,
4573
LEX_STRING *table_name)
4575
DBUG_ENTER("get_schema_constraints_record");
4578
if (thd->is_error())
4579
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
4580
thd->main_da.sql_errno(), thd->main_da.message());
4584
else if (!tables->view)
4586
List<FOREIGN_KEY_INFO> f_key_list;
4587
TABLE *show_table= tables->table;
4588
KEY *key_info=show_table->key_info;
4589
uint primary_key= show_table->s->primary_key;
4590
show_table->file->info(HA_STATUS_VARIABLE |
4593
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
4595
if (i != primary_key && !(key_info->flags & HA_NOSAME))
4598
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
4600
if (store_constraints(thd, table, db_name, table_name, key_info->name,
4601
strlen(key_info->name),
4602
STRING_WITH_LEN("PRIMARY KEY")))
4605
else if (key_info->flags & HA_NOSAME)
4607
if (store_constraints(thd, table, db_name, table_name, key_info->name,
4608
strlen(key_info->name),
4609
STRING_WITH_LEN("UNIQUE")))
4614
show_table->file->get_foreign_key_list(thd, &f_key_list);
4615
FOREIGN_KEY_INFO *f_key_info;
4616
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
4617
while ((f_key_info=it++))
4619
if (store_constraints(thd, table, db_name, table_name,
4620
f_key_info->forein_id->str,
4621
strlen(f_key_info->forein_id->str),
4630
static bool store_trigger(THD *thd, TABLE *table, LEX_STRING *db_name,
4631
LEX_STRING *table_name, LEX_STRING *trigger_name,
4632
enum trg_event_type event,
4633
enum trg_action_time_type timing,
4634
LEX_STRING *trigger_stmt,
4636
LEX_STRING *definer_buffer,
4637
LEX_STRING *client_cs_name,
4638
LEX_STRING *connection_cl_name,
4639
LEX_STRING *db_cl_name)
4641
CHARSET_INFO *cs= system_charset_info;
4642
LEX_STRING sql_mode_rep;
4644
restore_record(table, s->default_values);
4645
table->field[1]->store(db_name->str, db_name->length, cs);
4646
table->field[2]->store(trigger_name->str, trigger_name->length, cs);
4647
table->field[3]->store(trg_event_type_names[event].str,
4648
trg_event_type_names[event].length, cs);
4649
table->field[5]->store(db_name->str, db_name->length, cs);
4650
table->field[6]->store(table_name->str, table_name->length, cs);
4651
table->field[9]->store(trigger_stmt->str, trigger_stmt->length, cs);
4652
table->field[10]->store(STRING_WITH_LEN("ROW"), cs);
4653
table->field[11]->store(trg_action_time_type_names[timing].str,
4654
trg_action_time_type_names[timing].length, cs);
4655
table->field[14]->store(STRING_WITH_LEN("OLD"), cs);
4656
table->field[15]->store(STRING_WITH_LEN("NEW"), cs);
4658
sys_var_thd_sql_mode::symbolic_mode_representation(thd, sql_mode,
4660
table->field[17]->store(sql_mode_rep.str, sql_mode_rep.length, cs);
4661
table->field[18]->store(definer_buffer->str, definer_buffer->length, cs);
4662
table->field[19]->store(client_cs_name->str, client_cs_name->length, cs);
4663
table->field[20]->store(connection_cl_name->str,
4664
connection_cl_name->length, cs);
4665
table->field[21]->store(db_cl_name->str, db_cl_name->length, cs);
4667
return schema_table_store_record(thd, table);
4671
static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables,
4672
TABLE *table, bool res,
4673
LEX_STRING *db_name,
4674
LEX_STRING *table_name)
4676
DBUG_ENTER("get_schema_triggers_record");
4678
res can be non zero value when processed table is a view or
4679
error happened during opening of processed table.
4683
if (thd->is_error())
4684
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
4685
thd->main_da.sql_errno(), thd->main_da.message());
4689
if (!tables->view && tables->table->triggers)
4691
Table_triggers_list *triggers= tables->table->triggers;
4694
if (check_table_access(thd, TRIGGER_ACL, tables, 1, TRUE))
4697
for (event= 0; event < (int)TRG_EVENT_MAX; event++)
4699
for (timing= 0; timing < (int)TRG_ACTION_MAX; timing++)
4701
LEX_STRING trigger_name;
4702
LEX_STRING trigger_stmt;
4704
char definer_holder[USER_HOST_BUFF_SIZE];
4705
LEX_STRING definer_buffer;
4706
LEX_STRING client_cs_name;
4707
LEX_STRING connection_cl_name;
4708
LEX_STRING db_cl_name;
4710
definer_buffer.str= definer_holder;
4711
if (triggers->get_trigger_info(thd, (enum trg_event_type) event,
4712
(enum trg_action_time_type)timing,
4713
&trigger_name, &trigger_stmt,
4717
&connection_cl_name,
4721
if (store_trigger(thd, table, db_name, table_name, &trigger_name,
4722
(enum trg_event_type) event,
4723
(enum trg_action_time_type) timing, &trigger_stmt,
4727
&connection_cl_name,
4738
void store_key_column_usage(TABLE *table, LEX_STRING *db_name,
4739
LEX_STRING *table_name, const char *key_name,
4740
uint key_len, const char *con_type, uint con_len,
4743
CHARSET_INFO *cs= system_charset_info;
4744
table->field[1]->store(db_name->str, db_name->length, cs);
4745
table->field[2]->store(key_name, key_len, cs);
4746
table->field[4]->store(db_name->str, db_name->length, cs);
4747
table->field[5]->store(table_name->str, table_name->length, cs);
4748
table->field[6]->store(con_type, con_len, cs);
4749
table->field[7]->store((longlong) idx, TRUE);
4753
static int get_schema_key_column_usage_record(THD *thd,
4755
TABLE *table, bool res,
4756
LEX_STRING *db_name,
4757
LEX_STRING *table_name)
4759
DBUG_ENTER("get_schema_key_column_usage_record");
4762
if (thd->is_error())
4763
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
4764
thd->main_da.sql_errno(), thd->main_da.message());
4768
else if (!tables->view)
4770
List<FOREIGN_KEY_INFO> f_key_list;
4771
TABLE *show_table= tables->table;
4772
KEY *key_info=show_table->key_info;
4773
uint primary_key= show_table->s->primary_key;
4774
show_table->file->info(HA_STATUS_VARIABLE |
4777
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
4779
if (i != primary_key && !(key_info->flags & HA_NOSAME))
4782
KEY_PART_INFO *key_part= key_info->key_part;
4783
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
4785
if (key_part->field)
4788
restore_record(table, s->default_values);
4789
store_key_column_usage(table, db_name, table_name,
4791
strlen(key_info->name),
4792
key_part->field->field_name,
4793
strlen(key_part->field->field_name),
4795
if (schema_table_store_record(thd, table))
4801
show_table->file->get_foreign_key_list(thd, &f_key_list);
4802
FOREIGN_KEY_INFO *f_key_info;
4803
List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
4804
while ((f_key_info= fkey_it++))
4808
List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
4809
it1(f_key_info->referenced_fields);
4811
while ((f_info= it++))
4815
restore_record(table, s->default_values);
4816
store_key_column_usage(table, db_name, table_name,
4817
f_key_info->forein_id->str,
4818
f_key_info->forein_id->length,
4819
f_info->str, f_info->length,
4821
table->field[8]->store((longlong) f_idx, TRUE);
4822
table->field[8]->set_notnull();
4823
table->field[9]->store(f_key_info->referenced_db->str,
4824
f_key_info->referenced_db->length,
4825
system_charset_info);
4826
table->field[9]->set_notnull();
4827
table->field[10]->store(f_key_info->referenced_table->str,
4828
f_key_info->referenced_table->length,
4829
system_charset_info);
4830
table->field[10]->set_notnull();
4831
table->field[11]->store(r_info->str, r_info->length,
4832
system_charset_info);
4833
table->field[11]->set_notnull();
4834
if (schema_table_store_record(thd, table))
4843
#ifdef WITH_PARTITION_STORAGE_ENGINE
4844
static void collect_partition_expr(List<char> &field_list, String *str)
4846
List_iterator<char> part_it(field_list);
4847
ulong no_fields= field_list.elements;
4848
const char *field_str;
4850
while ((field_str= part_it++))
4852
str->append(field_str);
4853
if (--no_fields != 0)
4861
static void store_schema_partitions_record(THD *thd, TABLE *schema_table,
4862
TABLE *showing_table,
4863
partition_element *part_elem,
4864
handler *file, uint part_id)
4866
TABLE* table= schema_table;
4867
CHARSET_INFO *cs= system_charset_info;
4868
PARTITION_INFO stat_info;
4870
file->get_dynamic_partition_info(&stat_info, part_id);
4871
table->field[12]->store((longlong) stat_info.records, TRUE);
4872
table->field[13]->store((longlong) stat_info.mean_rec_length, TRUE);
4873
table->field[14]->store((longlong) stat_info.data_file_length, TRUE);
4874
if (stat_info.max_data_file_length)
4876
table->field[15]->store((longlong) stat_info.max_data_file_length, TRUE);
4877
table->field[15]->set_notnull();
4879
table->field[16]->store((longlong) stat_info.index_file_length, TRUE);
4880
table->field[17]->store((longlong) stat_info.delete_length, TRUE);
4881
if (stat_info.create_time)
4883
thd->variables.time_zone->gmt_sec_to_TIME(&time,
4884
(my_time_t)stat_info.create_time);
4885
table->field[18]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
4886
table->field[18]->set_notnull();
4888
if (stat_info.update_time)
4890
thd->variables.time_zone->gmt_sec_to_TIME(&time,
4891
(my_time_t)stat_info.update_time);
4892
table->field[19]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
4893
table->field[19]->set_notnull();
4895
if (stat_info.check_time)
4897
thd->variables.time_zone->gmt_sec_to_TIME(&time,
4898
(my_time_t)stat_info.check_time);
4899
table->field[20]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
4900
table->field[20]->set_notnull();
4902
if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
4904
table->field[21]->store((longlong) stat_info.check_sum, TRUE);
4905
table->field[21]->set_notnull();
4909
if (part_elem->part_comment)
4910
table->field[22]->store(part_elem->part_comment,
4911
strlen(part_elem->part_comment), cs);
4913
table->field[22]->store(STRING_WITH_LEN(""), cs);
4914
if (part_elem->nodegroup_id != UNDEF_NODEGROUP)
4915
table->field[23]->store((longlong) part_elem->nodegroup_id, TRUE);
4917
table->field[23]->store(STRING_WITH_LEN("default"), cs);
4919
table->field[24]->set_notnull();
4920
if (part_elem->tablespace_name)
4921
table->field[24]->store(part_elem->tablespace_name,
4922
strlen(part_elem->tablespace_name), cs);
4925
char *ts= showing_table->file->get_tablespace_name(thd,0,0);
4928
table->field[24]->store(ts, strlen(ts), cs);
4929
my_free(ts, MYF(0));
4932
table->field[24]->set_null();
4939
static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
4940
TABLE *table, bool res,
4941
LEX_STRING *db_name,
4942
LEX_STRING *table_name)
4944
CHARSET_INFO *cs= system_charset_info;
4946
String tmp_res(buff, sizeof(buff), cs);
4948
TABLE *show_table= tables->table;
4950
#ifdef WITH_PARTITION_STORAGE_ENGINE
4951
partition_info *part_info;
4953
DBUG_ENTER("get_schema_partitions_record");
4957
if (thd->is_error())
4958
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
4959
thd->main_da.sql_errno(), thd->main_da.message());
4963
file= show_table->file;
4964
#ifdef WITH_PARTITION_STORAGE_ENGINE
4965
part_info= show_table->part_info;
4968
partition_element *part_elem;
4969
List_iterator<partition_element> part_it(part_info->partitions);
4970
uint part_pos= 0, part_id= 0;
4972
restore_record(table, s->default_values);
4973
table->field[1]->store(db_name->str, db_name->length, cs);
4974
table->field[2]->store(table_name->str, table_name->length, cs);
4977
/* Partition method*/
4978
switch (part_info->part_type) {
4979
case RANGE_PARTITION:
4980
table->field[7]->store(partition_keywords[PKW_RANGE].str,
4981
partition_keywords[PKW_RANGE].length, cs);
4983
case LIST_PARTITION:
4984
table->field[7]->store(partition_keywords[PKW_LIST].str,
4985
partition_keywords[PKW_LIST].length, cs);
4987
case HASH_PARTITION:
4989
if (part_info->linear_hash_ind)
4990
tmp_res.append(partition_keywords[PKW_LINEAR].str,
4991
partition_keywords[PKW_LINEAR].length);
4992
if (part_info->list_of_part_fields)
4993
tmp_res.append(partition_keywords[PKW_KEY].str,
4994
partition_keywords[PKW_KEY].length);
4996
tmp_res.append(partition_keywords[PKW_HASH].str,
4997
partition_keywords[PKW_HASH].length);
4998
table->field[7]->store(tmp_res.ptr(), tmp_res.length(), cs);
5002
my_error(ER_OUT_OF_RESOURCES, MYF(0));
5003
current_thd->fatal_error();
5006
table->field[7]->set_notnull();
5008
/* Partition expression */
5009
if (part_info->part_expr)
5011
table->field[9]->store(part_info->part_func_string,
5012
part_info->part_func_len, cs);
5014
else if (part_info->list_of_part_fields)
5016
collect_partition_expr(part_info->part_field_list, &tmp_str);
5017
table->field[9]->store(tmp_str.ptr(), tmp_str.length(), cs);
5019
table->field[9]->set_notnull();
5021
if (part_info->is_sub_partitioned())
5023
/* Subpartition method */
5025
if (part_info->linear_hash_ind)
5026
tmp_res.append(partition_keywords[PKW_LINEAR].str,
5027
partition_keywords[PKW_LINEAR].length);
5028
if (part_info->list_of_subpart_fields)
5029
tmp_res.append(partition_keywords[PKW_KEY].str,
5030
partition_keywords[PKW_KEY].length);
5032
tmp_res.append(partition_keywords[PKW_HASH].str,
5033
partition_keywords[PKW_HASH].length);
5034
table->field[8]->store(tmp_res.ptr(), tmp_res.length(), cs);
5035
table->field[8]->set_notnull();
5037
/* Subpartition expression */
5038
if (part_info->subpart_expr)
5040
table->field[10]->store(part_info->subpart_func_string,
5041
part_info->subpart_func_len, cs);
5043
else if (part_info->list_of_subpart_fields)
5045
collect_partition_expr(part_info->subpart_field_list, &tmp_str);
5046
table->field[10]->store(tmp_str.ptr(), tmp_str.length(), cs);
5048
table->field[10]->set_notnull();
5051
while ((part_elem= part_it++))
5053
table->field[3]->store(part_elem->partition_name,
5054
strlen(part_elem->partition_name), cs);
5055
table->field[3]->set_notnull();
5056
/* PARTITION_ORDINAL_POSITION */
5057
table->field[5]->store((longlong) ++part_pos, TRUE);
5058
table->field[5]->set_notnull();
5060
/* Partition description */
5061
if (part_info->part_type == RANGE_PARTITION)
5063
if (part_elem->range_value != LONGLONG_MAX)
5064
table->field[11]->store((longlong) part_elem->range_value, FALSE);
5066
table->field[11]->store(partition_keywords[PKW_MAXVALUE].str,
5067
partition_keywords[PKW_MAXVALUE].length, cs);
5068
table->field[11]->set_notnull();
5070
else if (part_info->part_type == LIST_PARTITION)
5072
List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
5073
part_elem_value *list_value;
5074
uint no_items= part_elem->list_val_list.elements;
5077
if (part_elem->has_null_value)
5079
tmp_str.append("NULL");
5081
tmp_str.append(",");
5083
while ((list_value= list_val_it++))
5085
if (!list_value->unsigned_flag)
5086
tmp_res.set(list_value->value, cs);
5088
tmp_res.set((ulonglong)list_value->value, cs);
5089
tmp_str.append(tmp_res);
5090
if (--no_items != 0)
5091
tmp_str.append(",");
5093
table->field[11]->store(tmp_str.ptr(), tmp_str.length(), cs);
5094
table->field[11]->set_notnull();
5097
if (part_elem->subpartitions.elements)
5099
List_iterator<partition_element> sub_it(part_elem->subpartitions);
5100
partition_element *subpart_elem;
5101
uint subpart_pos= 0;
5103
while ((subpart_elem= sub_it++))
5105
table->field[4]->store(subpart_elem->partition_name,
5106
strlen(subpart_elem->partition_name), cs);
5107
table->field[4]->set_notnull();
5108
/* SUBPARTITION_ORDINAL_POSITION */
5109
table->field[6]->store((longlong) ++subpart_pos, TRUE);
5110
table->field[6]->set_notnull();
5112
store_schema_partitions_record(thd, table, show_table, subpart_elem,
5115
if(schema_table_store_record(thd, table))
5121
store_schema_partitions_record(thd, table, show_table, part_elem,
5124
if(schema_table_store_record(thd, table))
5133
store_schema_partitions_record(thd, table, show_table, 0, file, 0);
5134
if(schema_table_store_record(thd, table))
5142
static interval_type get_real_interval_type(interval_type i_type)
5146
return INTERVAL_YEAR;
5148
case INTERVAL_QUARTER:
5149
case INTERVAL_YEAR_MONTH:
5150
case INTERVAL_MONTH:
5151
return INTERVAL_MONTH;
5155
return INTERVAL_DAY;
5157
case INTERVAL_DAY_HOUR:
5159
return INTERVAL_HOUR;
5161
case INTERVAL_DAY_MINUTE:
5162
case INTERVAL_HOUR_MINUTE:
5163
case INTERVAL_MINUTE:
5164
return INTERVAL_MINUTE;
5166
case INTERVAL_DAY_SECOND:
5167
case INTERVAL_HOUR_SECOND:
5168
case INTERVAL_MINUTE_SECOND:
5169
case INTERVAL_SECOND:
5170
return INTERVAL_SECOND;
5172
case INTERVAL_DAY_MICROSECOND:
5173
case INTERVAL_HOUR_MICROSECOND:
5174
case INTERVAL_MINUTE_MICROSECOND:
5175
case INTERVAL_SECOND_MICROSECOND:
5176
case INTERVAL_MICROSECOND:
5177
return INTERVAL_MICROSECOND;
5182
return INTERVAL_SECOND;
5187
#ifdef HAVE_EVENT_SCHEDULER
5189
Loads an event from mysql.event and copies it's data to a row of
5193
copy_event_to_schema_table()
5195
sch_table The schema table (information_schema.event)
5196
event_table The event table to use for loading (mysql.event).
5204
copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
5206
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
5207
CHARSET_INFO *scs= system_charset_info;
5210
DBUG_ENTER("copy_event_to_schema_table");
5212
restore_record(sch_table, s->default_values);
5214
if (et.load_from_row(thd, event_table))
5216
my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), event_table->alias);
5220
if (!(!wild || !wild[0] || !wild_compare(et.name.str, wild, 0)))
5224
Skip events in schemas one does not have access to. The check is
5225
optimized. It's guaranteed in case of SHOW EVENTS that the user
5228
if (thd->lex->sql_command != SQLCOM_SHOW_EVENTS &&
5229
check_access(thd, EVENT_ACL, et.dbname.str, 0, 0, 1,
5230
is_schema_db(et.dbname.str, et.dbname.length)))
5233
/* ->field[0] is EVENT_CATALOG and is by default NULL */
5235
sch_table->field[ISE_EVENT_SCHEMA]->
5236
store(et.dbname.str, et.dbname.length,scs);
5237
sch_table->field[ISE_EVENT_NAME]->
5238
store(et.name.str, et.name.length, scs);
5239
sch_table->field[ISE_DEFINER]->
5240
store(et.definer.str, et.definer.length, scs);
5241
const String *tz_name= et.time_zone->get_name();
5242
sch_table->field[ISE_TIME_ZONE]->
5243
store(tz_name->ptr(), tz_name->length(), scs);
5244
sch_table->field[ISE_EVENT_BODY]->
5245
store(STRING_WITH_LEN("SQL"), scs);
5246
sch_table->field[ISE_EVENT_DEFINITION]->store(
5247
et.body_utf8.str, et.body_utf8.length, scs);
5251
LEX_STRING sql_mode;
5252
sys_var_thd_sql_mode::symbolic_mode_representation(thd, et.sql_mode,
5254
sch_table->field[ISE_SQL_MODE]->
5255
store(sql_mode.str, sql_mode.length, scs);
5264
sch_table->field[ISE_EVENT_TYPE]->store(STRING_WITH_LEN("RECURRING"), scs);
5266
if (Events::reconstruct_interval_expression(&show_str, et.interval,
5270
sch_table->field[ISE_INTERVAL_VALUE]->set_notnull();
5271
sch_table->field[ISE_INTERVAL_VALUE]->
5272
store(show_str.ptr(), show_str.length(), scs);
5274
LEX_STRING *ival= &interval_type_to_name[et.interval];
5275
sch_table->field[ISE_INTERVAL_FIELD]->set_notnull();
5276
sch_table->field[ISE_INTERVAL_FIELD]->store(ival->str, ival->length, scs);
5278
/* starts & ends . STARTS is always set - see sql_yacc.yy */
5279
et.time_zone->gmt_sec_to_TIME(&time, et.starts);
5280
sch_table->field[ISE_STARTS]->set_notnull();
5281
sch_table->field[ISE_STARTS]->
5282
store_time(&time, MYSQL_TIMESTAMP_DATETIME);
5286
et.time_zone->gmt_sec_to_TIME(&time, et.ends);
5287
sch_table->field[ISE_ENDS]->set_notnull();
5288
sch_table->field[ISE_ENDS]->
5289
store_time(&time, MYSQL_TIMESTAMP_DATETIME);
5295
sch_table->field[ISE_EVENT_TYPE]->store(STRING_WITH_LEN("ONE TIME"), scs);
5297
et.time_zone->gmt_sec_to_TIME(&time, et.execute_at);
5298
sch_table->field[ISE_EXECUTE_AT]->set_notnull();
5299
sch_table->field[ISE_EXECUTE_AT]->
5300
store_time(&time, MYSQL_TIMESTAMP_DATETIME);
5307
case Event_parse_data::ENABLED:
5308
sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("ENABLED"), scs);
5310
case Event_parse_data::SLAVESIDE_DISABLED:
5311
sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("SLAVESIDE_DISABLED"),
5314
case Event_parse_data::DISABLED:
5315
sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("DISABLED"), scs);
5320
sch_table->field[ISE_ORIGINATOR]->store(et.originator, TRUE);
5323
if (et.on_completion == Event_parse_data::ON_COMPLETION_DROP)
5324
sch_table->field[ISE_ON_COMPLETION]->
5325
store(STRING_WITH_LEN("NOT PRESERVE"), scs);
5327
sch_table->field[ISE_ON_COMPLETION]->
5328
store(STRING_WITH_LEN("PRESERVE"), scs);
5330
number_to_datetime(et.created, &time, 0, ¬_used);
5331
DBUG_ASSERT(not_used==0);
5332
sch_table->field[ISE_CREATED]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
5334
number_to_datetime(et.modified, &time, 0, ¬_used);
5335
DBUG_ASSERT(not_used==0);
5336
sch_table->field[ISE_LAST_ALTERED]->
5337
store_time(&time, MYSQL_TIMESTAMP_DATETIME);
5339
if (et.last_executed)
5341
et.time_zone->gmt_sec_to_TIME(&time, et.last_executed);
5342
sch_table->field[ISE_LAST_EXECUTED]->set_notnull();
5343
sch_table->field[ISE_LAST_EXECUTED]->
5344
store_time(&time, MYSQL_TIMESTAMP_DATETIME);
5347
sch_table->field[ISE_EVENT_COMMENT]->
5348
store(et.comment.str, et.comment.length, scs);
5350
sch_table->field[ISE_CLIENT_CS]->set_notnull();
5351
sch_table->field[ISE_CLIENT_CS]->store(
5352
et.creation_ctx->get_client_cs()->csname,
5353
strlen(et.creation_ctx->get_client_cs()->csname),
5356
sch_table->field[ISE_CONNECTION_CL]->set_notnull();
5357
sch_table->field[ISE_CONNECTION_CL]->store(
5358
et.creation_ctx->get_connection_cl()->name,
5359
strlen(et.creation_ctx->get_connection_cl()->name),
5362
sch_table->field[ISE_DB_CL]->set_notnull();
5363
sch_table->field[ISE_DB_CL]->store(
5364
et.creation_ctx->get_db_cl()->name,
5365
strlen(et.creation_ctx->get_db_cl()->name),
5368
if (schema_table_store_record(thd, sch_table))
5375
int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
5377
DBUG_ENTER("fill_open_tables");
5378
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
5379
TABLE *table= tables->table;
5380
CHARSET_INFO *cs= system_charset_info;
5381
OPEN_TABLE_LIST *open_list;
5382
if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
5383
&& thd->is_fatal_error)
5386
for (; open_list ; open_list=open_list->next)
5388
restore_record(table, s->default_values);
5389
table->field[0]->store(open_list->db, strlen(open_list->db), cs);
5390
table->field[1]->store(open_list->table, strlen(open_list->table), cs);
5391
table->field[2]->store((longlong) open_list->in_use, TRUE);
5392
table->field[3]->store((longlong) open_list->locked, TRUE);
5393
if (schema_table_store_record(thd, table))
5400
int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
5402
DBUG_ENTER("fill_variables");
5405
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
5406
enum enum_schema_tables schema_table_idx=
5407
get_schema_table_idx(tables->schema_table);
5408
enum enum_var_type option_type= OPT_SESSION;
5409
bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
5410
bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
5412
if (lex->option_type == OPT_GLOBAL ||
5413
schema_table_idx == SCH_GLOBAL_VARIABLES)
5414
option_type= OPT_GLOBAL;
5416
rw_rdlock(&LOCK_system_variables_hash);
5417
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
5418
option_type, NULL, "", tables->table, upper_case_names, cond);
5419
rw_unlock(&LOCK_system_variables_hash);
5424
int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
5426
DBUG_ENTER("fill_status");
5428
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
5430
STATUS_VAR *tmp1, tmp;
5431
enum enum_schema_tables schema_table_idx=
5432
get_schema_table_idx(tables->schema_table);
5433
enum enum_var_type option_type;
5434
bool upper_case_names= (schema_table_idx != SCH_STATUS);
5436
if (schema_table_idx == SCH_STATUS)
5438
option_type= lex->option_type;
5439
if (option_type == OPT_GLOBAL)
5442
tmp1= thd->initial_status_var;
5444
else if (schema_table_idx == SCH_GLOBAL_STATUS)
5446
option_type= OPT_GLOBAL;
5451
option_type= OPT_SESSION;
5452
tmp1= &thd->status_var;
5455
pthread_mutex_lock(&LOCK_status);
5456
if (option_type == OPT_GLOBAL)
5457
calc_sum_of_all_status(&tmp);
5458
res= show_status_array(thd, wild,
5459
(SHOW_VAR *)all_status_vars.buffer,
5460
option_type, tmp1, "", tables->table,
5461
upper_case_names, cond);
5462
pthread_mutex_unlock(&LOCK_status);
5468
Fill and store records into I_S.referential_constraints table
5471
get_referential_constraints_record()
5473
tables table list struct(processed table)
5475
res 1 means the error during opening of the processed table
5476
0 means processed table is opened without error
5478
file_name table name
5486
get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
5487
TABLE *table, bool res,
5488
LEX_STRING *db_name, LEX_STRING *table_name)
5490
CHARSET_INFO *cs= system_charset_info;
5491
DBUG_ENTER("get_referential_constraints_record");
5495
if (thd->is_error())
5496
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
5497
thd->main_da.sql_errno(), thd->main_da.message());
5503
List<FOREIGN_KEY_INFO> f_key_list;
5504
TABLE *show_table= tables->table;
5505
show_table->file->info(HA_STATUS_VARIABLE |
5509
show_table->file->get_foreign_key_list(thd, &f_key_list);
5510
FOREIGN_KEY_INFO *f_key_info;
5511
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
5512
while ((f_key_info= it++))
5514
restore_record(table, s->default_values);
5515
table->field[1]->store(db_name->str, db_name->length, cs);
5516
table->field[9]->store(table_name->str, table_name->length, cs);
5517
table->field[2]->store(f_key_info->forein_id->str,
5518
f_key_info->forein_id->length, cs);
5519
table->field[4]->store(f_key_info->referenced_db->str,
5520
f_key_info->referenced_db->length, cs);
5521
table->field[10]->store(f_key_info->referenced_table->str,
5522
f_key_info->referenced_table->length, cs);
5523
if (f_key_info->referenced_key_name)
5525
table->field[5]->store(f_key_info->referenced_key_name->str,
5526
f_key_info->referenced_key_name->length, cs);
5527
table->field[5]->set_notnull();
5530
table->field[5]->set_null();
5531
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
5532
table->field[7]->store(f_key_info->update_method->str,
5533
f_key_info->update_method->length, cs);
5534
table->field[8]->store(f_key_info->delete_method->str,
5535
f_key_info->delete_method->length, cs);
5536
if (schema_table_store_record(thd, table))
5543
struct schema_table_ref
5545
const char *table_name;
5546
ST_SCHEMA_TABLE *schema_table;
5551
Find schema_tables elment by name
5554
find_schema_table_in_plugin()
5557
table_name table name
5561
1 found the schema table
5563
static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin,
5566
schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
5567
const char* table_name= p_schema_table->table_name;
5568
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
5569
DBUG_ENTER("find_schema_table_in_plugin");
5571
if (!my_strcasecmp(system_charset_info,
5572
schema_table->table_name,
5574
p_schema_table->schema_table= schema_table;
5583
Find schema_tables elment by name
5588
table_name table name
5592
# pointer to 'schema_tables' element
5595
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
5597
schema_table_ref schema_table_a;
5598
ST_SCHEMA_TABLE *schema_table= schema_tables;
5599
DBUG_ENTER("find_schema_table");
5601
for (; schema_table->table_name; schema_table++)
5603
if (!my_strcasecmp(system_charset_info,
5604
schema_table->table_name,
5606
DBUG_RETURN(schema_table);
5609
schema_table_a.table_name= table_name;
5610
if (plugin_foreach(thd, find_schema_table_in_plugin,
5611
MYSQL_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
5612
DBUG_RETURN(schema_table_a.schema_table);
5618
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
5620
return &schema_tables[schema_table_idx];
5625
Create information_schema table using schema_table data.
5628
For MYSQL_TYPE_DECIMAL fields only, the field_length member has encoded
5629
into it two numbers, based on modulus of base-10 numbers. In the ones
5630
position is the number of decimals. Tens position is unused. In the
5631
hundreds and thousands position is a two-digit decimal number representing
5632
length. Encode this value with (decimals*100)+length , where
5633
0<decimals<10 and 0<=length<100 .
5638
@param table_list Used to pass I_S table information(fields info, tables
5639
parameters etc) and table name.
5641
@retval \# Pointer to created table
5642
@retval NULL Can't create table
5645
TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
5650
List<Item> field_list;
5651
ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
5652
ST_FIELD_INFO *fields_info= schema_table->fields_info;
5653
CHARSET_INFO *cs= system_charset_info;
5654
DBUG_ENTER("create_schema_table");
5656
for (; fields_info->field_name; fields_info++)
5658
switch (fields_info->field_type) {
5659
case MYSQL_TYPE_TINY:
5660
case MYSQL_TYPE_LONG:
5661
case MYSQL_TYPE_SHORT:
5662
case MYSQL_TYPE_LONGLONG:
5663
case MYSQL_TYPE_INT24:
5664
if (!(item= new Item_return_int(fields_info->field_name,
5665
fields_info->field_length,
5666
fields_info->field_type,
5667
fields_info->value)))
5671
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
5673
case MYSQL_TYPE_DATE:
5674
case MYSQL_TYPE_TIME:
5675
case MYSQL_TYPE_TIMESTAMP:
5676
case MYSQL_TYPE_DATETIME:
5677
if (!(item=new Item_return_date_time(fields_info->field_name,
5678
fields_info->field_type)))
5683
case MYSQL_TYPE_FLOAT:
5684
case MYSQL_TYPE_DOUBLE:
5685
if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
5686
fields_info->field_length)) == NULL)
5689
case MYSQL_TYPE_DECIMAL:
5690
case MYSQL_TYPE_NEWDECIMAL:
5691
if (!(item= new Item_decimal((longlong) fields_info->value, false)))
5695
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
5696
item->decimals= fields_info->field_length%10;
5697
item->max_length= (fields_info->field_length/100)%100;
5698
if (item->unsigned_flag == 0)
5699
item->max_length+= 1;
5700
if (item->decimals > 0)
5701
item->max_length+= 1;
5702
item->set_name(fields_info->field_name,
5703
strlen(fields_info->field_name), cs);
5705
case MYSQL_TYPE_TINY_BLOB:
5706
case MYSQL_TYPE_MEDIUM_BLOB:
5707
case MYSQL_TYPE_LONG_BLOB:
5708
case MYSQL_TYPE_BLOB:
5709
if (!(item= new Item_blob(fields_info->field_name,
5710
fields_info->field_length)))
5716
/* Don't let unimplemented types pass through. Could be a grave error. */
5717
DBUG_ASSERT(fields_info->field_type == MYSQL_TYPE_STRING);
5719
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
5723
item->set_name(fields_info->field_name,
5724
strlen(fields_info->field_name), cs);
5727
field_list.push_back(item);
5728
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
5731
TMP_TABLE_PARAM *tmp_table_param =
5732
(TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
5733
tmp_table_param->init();
5734
tmp_table_param->table_charset= cs;
5735
tmp_table_param->field_count= field_count;
5736
tmp_table_param->schema_table= 1;
5737
SELECT_LEX *select_lex= thd->lex->current_select;
5738
if (!(table= create_tmp_table(thd, tmp_table_param,
5739
field_list, (ORDER*) 0, 0, 0,
5740
(select_lex->options | thd->options |
5741
TMP_TABLE_ALL_COLUMNS),
5742
HA_POS_ERROR, table_list->alias)))
5744
my_bitmap_map* bitmaps=
5745
(my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
5746
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
5748
table->read_set= &table->def_read_set;
5749
bitmap_clear_all(table->read_set);
5750
table_list->schema_table_param= tmp_table_param;
5756
For old SHOW compatibility. It is used when
5757
old SHOW doesn't have generated column names
5758
Make list of fields for SHOW
5763
schema_table pointer to 'schema_tables' element
5770
int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
5772
ST_FIELD_INFO *field_info= schema_table->fields_info;
5773
Name_resolution_context *context= &thd->lex->select_lex.context;
5774
for (; field_info->field_name; field_info++)
5776
if (field_info->old_name)
5778
Item_field *field= new Item_field(context,
5779
NullS, NullS, field_info->field_name);
5782
field->set_name(field_info->old_name,
5783
strlen(field_info->old_name),
5784
system_charset_info);
5785
if (add_item_to_list(thd, field))
5794
int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
5798
SELECT_LEX *sel= lex->current_select;
5799
Name_resolution_context *context= &sel->context;
5801
if (!sel->item_list.elements)
5803
ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
5804
String buffer(tmp,sizeof(tmp), system_charset_info);
5805
Item_field *field= new Item_field(context,
5806
NullS, NullS, field_info->field_name);
5807
if (!field || add_item_to_list(thd, field))
5810
buffer.append(field_info->old_name);
5811
if (lex->wild && lex->wild->ptr())
5813
buffer.append(STRING_WITH_LEN(" ("));
5814
buffer.append(lex->wild->ptr());
5817
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
5823
int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
5826
String buffer(tmp,sizeof(tmp), thd->charset());
5828
Name_resolution_context *context= &lex->select_lex.context;
5830
ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
5832
buffer.append(field_info->old_name);
5833
buffer.append(lex->select_lex.db);
5834
if (lex->wild && lex->wild->ptr())
5836
buffer.append(STRING_WITH_LEN(" ("));
5837
buffer.append(lex->wild->ptr());
5840
Item_field *field= new Item_field(context,
5841
NullS, NullS, field_info->field_name);
5842
if (add_item_to_list(thd, field))
5844
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
5845
if (thd->lex->verbose)
5847
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
5848
field_info= &schema_table->fields_info[3];
5849
field= new Item_field(context, NullS, NullS, field_info->field_name);
5850
if (add_item_to_list(thd, field))
5852
field->set_name(field_info->old_name, strlen(field_info->old_name),
5853
system_charset_info);
5859
int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
5861
int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
5862
int *field_num= fields_arr;
5863
ST_FIELD_INFO *field_info;
5864
Name_resolution_context *context= &thd->lex->select_lex.context;
5866
for (; *field_num >= 0; field_num++)
5868
field_info= &schema_table->fields_info[*field_num];
5869
if (!thd->lex->verbose && (*field_num == 13 ||
5873
Item_field *field= new Item_field(context,
5874
NullS, NullS, field_info->field_name);
5877
field->set_name(field_info->old_name,
5878
strlen(field_info->old_name),
5879
system_charset_info);
5880
if (add_item_to_list(thd, field))
5888
int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
5890
int fields_arr[]= {0, 2, 1, 3, -1};
5891
int *field_num= fields_arr;
5892
ST_FIELD_INFO *field_info;
5893
Name_resolution_context *context= &thd->lex->select_lex.context;
5895
for (; *field_num >= 0; field_num++)
5897
field_info= &schema_table->fields_info[*field_num];
5898
Item_field *field= new Item_field(context,
5899
NullS, NullS, field_info->field_name);
5902
field->set_name(field_info->old_name,
5903
strlen(field_info->old_name),
5904
system_charset_info);
5905
if (add_item_to_list(thd, field))
5913
int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
5915
int fields_arr[]= {2, 3, 4, 19, 16, 15, 14, 18, 20, 21, 22, -1};
5916
int *field_num= fields_arr;
5917
ST_FIELD_INFO *field_info;
5918
Name_resolution_context *context= &thd->lex->select_lex.context;
5920
for (; *field_num >= 0; field_num++)
5922
field_info= &schema_table->fields_info[*field_num];
5923
Item_field *field= new Item_field(context,
5924
NullS, NullS, field_info->field_name);
5927
field->set_name(field_info->old_name,
5928
strlen(field_info->old_name),
5929
system_charset_info);
5930
if (add_item_to_list(thd, field))
5939
Create information_schema table
5942
mysql_schema_table()
5945
table_list pointer to table_list
5952
int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
5955
DBUG_ENTER("mysql_schema_table");
5956
if (!(table= table_list->schema_table->create_table(thd, table_list)))
5958
table->s->tmp_table= SYSTEM_TMP_TABLE;
5959
table->grant.privilege= SELECT_ACL;
5961
This test is necessary to make
5962
case insensitive file systems +
5963
upper case table names(information schema tables) +
5967
if (table_list->schema_table_name)
5968
table->alias_name_used= my_strcasecmp(table_alias_charset,
5969
table_list->schema_table_name,
5971
table_list->table_name= table->s->table_name.str;
5972
table_list->table_name_length= table->s->table_name.length;
5973
table_list->table= table;
5974
table->next= thd->derived_tables;
5975
thd->derived_tables= table;
5976
table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
5977
lex->safe_to_cache_query= 0;
5979
if (table_list->schema_table_reformed) // show command
5981
SELECT_LEX *sel= lex->current_select;
5983
Field_translator *transl, *org_transl;
5985
if (table_list->field_translation)
5987
Field_translator *end= table_list->field_translation_end;
5988
for (transl= table_list->field_translation; transl < end; transl++)
5990
if (!transl->item->fixed &&
5991
transl->item->fix_fields(thd, &transl->item))
5996
List_iterator_fast<Item> it(sel->item_list);
5998
(Field_translator*)(thd->stmt_arena->
5999
alloc(sel->item_list.elements *
6000
sizeof(Field_translator)))))
6004
for (org_transl= transl; (item= it++); transl++)
6007
transl->name= item->name;
6008
if (!item->fixed && item->fix_fields(thd, &transl->item))
6013
table_list->field_translation= org_transl;
6014
table_list->field_translation_end= transl;
6022
Generate select from information_schema table
6025
make_schema_select()
6027
sel pointer to SELECT_LEX
6028
schema_table_idx index of 'schema_tables' element
6035
int make_schema_select(THD *thd, SELECT_LEX *sel,
6036
enum enum_schema_tables schema_table_idx)
6038
ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
6039
LEX_STRING db, table;
6040
DBUG_ENTER("make_schema_select");
6041
DBUG_PRINT("enter", ("mysql_schema_select: %s", schema_table->table_name));
6043
We have to make non const db_name & table_name
6044
because of lower_case_table_names
6046
thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str,
6047
INFORMATION_SCHEMA_NAME.length, 0);
6048
thd->make_lex_string(&table, schema_table->table_name,
6049
strlen(schema_table->table_name), 0);
6050
if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
6051
!sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
6061
Fill temporary schema tables before SELECT
6064
get_schema_tables_result()
6065
join join which use schema tables
6066
executed_place place where I_S table processed
6073
bool get_schema_tables_result(JOIN *join,
6074
enum enum_schema_table_state executed_place)
6076
JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
6077
THD *thd= join->thd;
6080
DBUG_ENTER("get_schema_tables_result");
6082
thd->no_warnings_for_error= 1;
6083
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
6085
if (!tab->table || !tab->table->pos_in_table_list)
6088
TABLE_LIST *table_list= tab->table->pos_in_table_list;
6089
if (table_list->schema_table && thd->fill_information_schema_tables())
6091
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
6092
lex->current_select->master_unit()->item);
6094
/* A value of 0 indicates a dummy implementation */
6095
if (table_list->schema_table->fill_table == 0)
6098
/* skip I_S optimizations specific to get_all_tables */
6099
if (thd->lex->describe &&
6100
(table_list->schema_table->fill_table != get_all_tables))
6104
If schema table is already processed and
6105
the statement is not a subselect then
6106
we don't need to fill this table again.
6107
If schema table is already processed and
6108
schema_table_state != executed_place then
6109
table is already processed and
6110
we should skip second data processing.
6112
if (table_list->schema_table_state &&
6113
(!is_subselect || table_list->schema_table_state != executed_place))
6117
if table is used in a subselect and
6118
table has been processed earlier with the same
6119
'executed_place' value then we should refresh the table.
6121
if (table_list->schema_table_state && is_subselect)
6123
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
6124
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
6125
table_list->table->file->ha_delete_all_rows();
6126
free_io_cache(table_list->table);
6127
filesort_free_buffers(table_list->table,1);
6128
table_list->table->null_row= 0;
6131
table_list->table->file->stats.records= 0;
6133
if (table_list->schema_table->fill_table(thd, table_list,
6138
tab->read_record.file= table_list->table->file;
6139
table_list->schema_table_state= executed_place;
6142
tab->read_record.file= table_list->table->file;
6143
table_list->schema_table_state= executed_place;
6146
thd->no_warnings_for_error= 0;
6147
DBUG_RETURN(result);
6150
struct run_hton_fill_schema_files_args
6156
static my_bool run_hton_fill_schema_files(THD *thd, plugin_ref plugin,
6159
struct run_hton_fill_schema_files_args *args=
6160
(run_hton_fill_schema_files_args *) arg;
6161
handlerton *hton= plugin_data(plugin, handlerton *);
6162
if(hton->fill_files_table && hton->state == SHOW_OPTION_YES)
6163
hton->fill_files_table(hton, thd, args->tables, args->cond);
6167
int fill_schema_files(THD *thd, TABLE_LIST *tables, COND *cond)
6169
DBUG_ENTER("fill_schema_files");
6171
struct run_hton_fill_schema_files_args args;
6172
args.tables= tables;
6175
plugin_foreach(thd, run_hton_fill_schema_files,
6176
MYSQL_STORAGE_ENGINE_PLUGIN, &args);
6182
ST_FIELD_INFO schema_fields_info[]=
6184
{"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6185
{"SCHEMA_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
6187
{"DEFAULT_CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
6189
{"DEFAULT_COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
6191
{"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6192
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6196
ST_FIELD_INFO tables_fields_info[]=
6198
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6199
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6200
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
6202
{"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
6203
{"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine", OPEN_FRM_ONLY},
6204
{"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
6205
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
6206
{"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", OPEN_FULL_TABLE},
6207
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
6208
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
6209
{"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
6210
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
6211
{"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
6212
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
6213
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
6214
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
6215
{"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
6216
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
6217
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
6218
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
6219
{"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0,
6220
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
6221
{"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
6222
{"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
6223
{"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
6224
{"TABLE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, "Collation",
6226
{"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
6227
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
6228
{"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options",
6230
{"TABLE_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
6231
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6235
ST_FIELD_INFO columns_fields_info[]=
6237
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
6238
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
6239
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
6240
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Field",
6242
{"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
6243
MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
6244
{"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0,
6245
1, "Default", OPEN_FRM_ONLY},
6246
{"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
6247
{"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
6248
{"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
6249
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
6250
{"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
6251
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
6252
{"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
6253
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
6254
{"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
6255
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
6256
{"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, 0,
6258
{"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, "Collation",
6260
{"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type", OPEN_FRM_ONLY},
6261
{"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key", OPEN_FRM_ONLY},
6262
{"EXTRA", 27, MYSQL_TYPE_STRING, 0, 0, "Extra", OPEN_FRM_ONLY},
6263
{"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges", OPEN_FRM_ONLY},
6264
{"COLUMN_COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
6265
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6269
ST_FIELD_INFO charsets_fields_info[]=
6271
{"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Charset",
6273
{"DEFAULT_COLLATE_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
6274
"Default collation", SKIP_OPEN_TABLE},
6275
{"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description",
6277
{"MAXLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
6278
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6282
ST_FIELD_INFO collation_fields_info[]=
6284
{"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Collation",
6286
{"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Charset",
6288
{"ID", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Id",
6290
{"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default", SKIP_OPEN_TABLE},
6291
{"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled", SKIP_OPEN_TABLE},
6292
{"SORTLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
6293
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6297
ST_FIELD_INFO engines_fields_info[]=
6299
{"ENGINE", 64, MYSQL_TYPE_STRING, 0, 0, "Engine", SKIP_OPEN_TABLE},
6300
{"SUPPORT", 8, MYSQL_TYPE_STRING, 0, 0, "Support", SKIP_OPEN_TABLE},
6301
{"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN_TABLE},
6302
{"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 1, "Transactions", SKIP_OPEN_TABLE},
6303
{"XA", 3, MYSQL_TYPE_STRING, 0, 1, "XA", SKIP_OPEN_TABLE},
6304
{"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 1, "Savepoints", SKIP_OPEN_TABLE},
6305
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6309
ST_FIELD_INFO events_fields_info[]=
6311
{"EVENT_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6312
{"EVENT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db",
6314
{"EVENT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
6316
{"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
6317
{"TIME_ZONE", 64, MYSQL_TYPE_STRING, 0, 0, "Time zone", SKIP_OPEN_TABLE},
6318
{"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6319
{"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6320
{"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
6321
{"EXECUTE_AT", 0, MYSQL_TYPE_DATETIME, 0, 1, "Execute at", SKIP_OPEN_TABLE},
6322
{"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value",
6324
{"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field",
6326
{"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6327
{"STARTS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Starts", SKIP_OPEN_TABLE},
6328
{"ENDS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Ends", SKIP_OPEN_TABLE},
6329
{"STATUS", 18, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
6330
{"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6331
{"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
6332
{"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
6333
{"LAST_EXECUTED", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
6334
{"EVENT_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6335
{"ORIGINATOR", 10, MYSQL_TYPE_LONGLONG, 0, 0, "Originator", SKIP_OPEN_TABLE},
6336
{"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
6337
"character_set_client", SKIP_OPEN_TABLE},
6338
{"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
6339
"collation_connection", SKIP_OPEN_TABLE},
6340
{"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
6341
"Database Collation", SKIP_OPEN_TABLE},
6342
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6347
ST_FIELD_INFO coll_charset_app_fields_info[]=
6349
{"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
6351
{"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
6353
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6357
ST_FIELD_INFO proc_fields_info[]=
6359
{"SPECIFIC_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6360
{"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6361
{"ROUTINE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db",
6363
{"ROUTINE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
6365
{"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
6366
{"DTD_IDENTIFIER", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6367
{"ROUTINE_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6368
{"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6369
{"EXTERNAL_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6370
{"EXTERNAL_LANGUAGE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
6372
{"PARAMETER_STYLE", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6373
{"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6374
{"SQL_DATA_ACCESS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
6376
{"SQL_PATH", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6377
{"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type",
6379
{"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Created", SKIP_OPEN_TABLE},
6380
{"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Modified", SKIP_OPEN_TABLE},
6381
{"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6382
{"ROUTINE_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment",
6384
{"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
6385
{"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
6386
"character_set_client", SKIP_OPEN_TABLE},
6387
{"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
6388
"collation_connection", SKIP_OPEN_TABLE},
6389
{"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
6390
"Database Collation", SKIP_OPEN_TABLE},
6391
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6395
ST_FIELD_INFO stat_fields_info[]=
6397
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
6398
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
6399
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", OPEN_FRM_ONLY},
6400
{"NON_UNIQUE", 1, MYSQL_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
6401
{"INDEX_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
6402
{"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name",
6404
{"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
6405
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name",
6407
{"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
6408
{"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 1,
6409
"Cardinality", OPEN_FULL_TABLE},
6410
{"SUB_PART", 3, MYSQL_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
6411
{"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed", OPEN_FRM_ONLY},
6412
{"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
6413
{"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type", OPEN_FULL_TABLE},
6414
{"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment", OPEN_FRM_ONLY},
6415
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6419
ST_FIELD_INFO view_fields_info[]=
6421
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
6422
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
6423
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
6424
{"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6425
{"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6426
{"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6427
{"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6428
{"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6429
{"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
6431
{"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
6433
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6437
ST_FIELD_INFO user_privileges_fields_info[]=
6439
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6440
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6441
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6442
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6443
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6447
ST_FIELD_INFO schema_privileges_fields_info[]=
6449
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6450
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6451
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6452
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6453
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6454
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6458
ST_FIELD_INFO table_privileges_fields_info[]=
6460
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6461
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6462
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6463
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6464
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6465
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6466
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6470
ST_FIELD_INFO column_privileges_fields_info[]=
6472
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6473
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6474
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6475
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6476
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6477
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6478
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6479
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6483
ST_FIELD_INFO table_constraints_fields_info[]=
6485
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6486
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
6488
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
6490
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6491
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6492
{"CONSTRAINT_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
6494
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6498
ST_FIELD_INFO key_column_usage_fields_info[]=
6500
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6501
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
6503
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
6505
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6506
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6507
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6508
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6509
{"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
6510
{"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONGLONG, 0, 1, 0,
6512
{"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
6514
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
6516
{"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
6518
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6522
ST_FIELD_INFO table_names_fields_info[]=
6524
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6525
{"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6526
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_",
6528
{"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type",
6530
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6534
ST_FIELD_INFO open_tables_fields_info[]=
6536
{"Database", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
6538
{"Table",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", SKIP_OPEN_TABLE},
6539
{"In_use", 1, MYSQL_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
6540
{"Name_locked", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
6541
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6545
ST_FIELD_INFO triggers_fields_info[]=
6547
{"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6548
{"TRIGGER_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6549
{"TRIGGER_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Trigger",
6551
{"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event", OPEN_FULL_TABLE},
6552
{"EVENT_OBJECT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0,
6554
{"EVENT_OBJECT_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
6556
{"EVENT_OBJECT_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table",
6558
{"ACTION_ORDER", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
6559
{"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6560
{"ACTION_STATEMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Statement",
6562
{"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6563
{"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing", OPEN_FULL_TABLE},
6564
{"ACTION_REFERENCE_OLD_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
6566
{"ACTION_REFERENCE_NEW_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
6568
{"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6569
{"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6570
{"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FULL_TABLE},
6571
{"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, "sql_mode", OPEN_FULL_TABLE},
6572
{"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FULL_TABLE},
6573
{"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
6574
"character_set_client", OPEN_FULL_TABLE},
6575
{"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
6576
"collation_connection", OPEN_FULL_TABLE},
6577
{"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
6578
"Database Collation", OPEN_FULL_TABLE},
6579
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6583
ST_FIELD_INFO partitions_fields_info[]=
6585
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6586
{"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6587
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6588
{"PARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6589
{"SUBPARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
6591
{"PARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONGLONG, 0,
6592
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
6593
{"SUBPARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONGLONG, 0,
6594
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
6595
{"PARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6596
{"SUBPARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6597
{"PARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6598
{"SUBPARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0,
6600
{"PARTITION_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6601
{"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
6603
{"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
6605
{"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
6607
{"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
6608
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
6609
{"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
6611
{"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
6613
{"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
6614
{"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
6615
{"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
6616
{"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0,
6617
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
6618
{"PARTITION_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6619
{"NODEGROUP", 12 , MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6620
{"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
6622
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6626
ST_FIELD_INFO variables_fields_info[]=
6628
{"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name",
6630
{"VARIABLE_VALUE", 1024, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE},
6631
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6635
ST_FIELD_INFO processlist_fields_info[]=
6637
{"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
6638
{"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
6639
{"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host",
6641
{"DB", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Db", SKIP_OPEN_TABLE},
6642
{"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command", SKIP_OPEN_TABLE},
6643
{"TIME", 7, MYSQL_TYPE_LONG, 0, 0, "Time", SKIP_OPEN_TABLE},
6644
{"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE},
6645
{"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info",
6647
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6651
ST_FIELD_INFO plugin_fields_info[]=
6653
{"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
6655
{"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6656
{"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
6657
{"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
6658
{"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6659
{"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library",
6661
{"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6662
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6663
{"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6664
{"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
6665
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6668
ST_FIELD_INFO files_fields_info[]=
6670
{"FILE_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
6671
{"FILE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6672
{"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6673
{"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
6675
{"TABLE_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6676
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6677
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6678
{"LOGFILE_GROUP_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
6680
{"LOGFILE_GROUP_NUMBER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
6681
{"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6682
{"FULLTEXT_KEYS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6683
{"DELETED_ROWS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
6684
{"UPDATE_COUNT", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
6685
{"FREE_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
6686
{"TOTAL_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
6687
{"EXTENT_SIZE", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
6688
{"INITIAL_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
6689
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
6690
{"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
6691
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
6692
{"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
6693
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
6694
{"CREATION_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
6695
{"LAST_UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
6696
{"LAST_ACCESS_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
6697
{"RECOVER_TIME", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
6698
{"TRANSACTION_COUNTER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
6699
{"VERSION", 21 , MYSQL_TYPE_LONGLONG, 0,
6700
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", SKIP_OPEN_TABLE},
6701
{"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", SKIP_OPEN_TABLE},
6702
{"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0,
6703
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", SKIP_OPEN_TABLE},
6704
{"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
6705
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", SKIP_OPEN_TABLE},
6706
{"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
6707
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", SKIP_OPEN_TABLE},
6708
{"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
6709
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", SKIP_OPEN_TABLE},
6710
{"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
6711
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", SKIP_OPEN_TABLE},
6712
{"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0,
6713
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", SKIP_OPEN_TABLE},
6714
{"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", SKIP_OPEN_TABLE},
6715
{"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", SKIP_OPEN_TABLE},
6716
{"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", SKIP_OPEN_TABLE},
6717
{"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0,
6718
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", SKIP_OPEN_TABLE},
6719
{"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
6720
{"EXTRA", 255, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
6721
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6724
void init_fill_schema_files_row(TABLE* table)
6727
for(i=0; files_fields_info[i].field_name!=NULL; i++)
6728
table->field[i]->set_null();
6730
table->field[IS_FILES_STATUS]->set_notnull();
6731
table->field[IS_FILES_STATUS]->store("NORMAL", 6, system_charset_info);
6734
ST_FIELD_INFO referential_constraints_fields_info[]=
6736
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
6737
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
6739
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
6741
{"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0,
6743
{"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
6745
{"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0,
6746
MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
6747
{"MATCH_OPTION", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6748
{"UPDATE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6749
{"DELETE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6750
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
6751
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
6753
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
6758
Description of ST_FIELD_INFO in table.h
6760
Make sure that the order of schema_tables and enum_schema_tables are the same.
6764
ST_SCHEMA_TABLE schema_tables[]=
6766
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
6767
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
6768
{"COLLATIONS", collation_fields_info, create_schema_table,
6769
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
6770
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
6771
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
6772
{"COLUMNS", columns_fields_info, create_schema_table,
6773
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
6774
OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL},
6775
{"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
6776
fill_schema_column_privileges, 0, 0, -1, -1, 0, 0},
6777
{"ENGINES", engines_fields_info, create_schema_table,
6778
fill_schema_engines, make_old_format, 0, -1, -1, 0, 0},
6779
#ifdef HAVE_EVENT_SCHEDULER
6780
{"EVENTS", events_fields_info, create_schema_table,
6781
Events::fill_schema_events, make_old_format, 0, -1, -1, 0, 0},
6783
{"EVENTS", events_fields_info, create_schema_table,
6784
0, make_old_format, 0, -1, -1, 0, 0},
6786
{"FILES", files_fields_info, create_schema_table,
6787
fill_schema_files, 0, 0, -1, -1, 0, 0},
6788
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
6789
fill_status, make_old_format, 0, 0, -1, 0, 0},
6790
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
6791
fill_variables, make_old_format, 0, 0, -1, 0, 0},
6792
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
6793
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
6795
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
6796
fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
6797
{"PARTITIONS", partitions_fields_info, create_schema_table,
6798
get_all_tables, 0, get_schema_partitions_record, 1, 2, 0, OPEN_TABLE_ONLY},
6799
{"PLUGINS", plugin_fields_info, create_schema_table,
6800
fill_plugins, make_old_format, 0, -1, -1, 0, 0},
6801
{"PROCESSLIST", processlist_fields_info, create_schema_table,
6802
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
6803
{"PROFILING", query_profile_statistics_info, create_schema_table,
6804
fill_query_profile_statistics_info, make_profile_table_for_show,
6805
NULL, -1, -1, false, 0},
6806
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
6807
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
6808
1, 9, 0, OPEN_TABLE_ONLY},
6809
{"ROUTINES", proc_fields_info, create_schema_table,
6810
fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0},
6811
{"SCHEMATA", schema_fields_info, create_schema_table,
6812
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
6813
{"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
6814
fill_schema_schema_privileges, 0, 0, -1, -1, 0, 0},
6815
{"SESSION_STATUS", variables_fields_info, create_schema_table,
6816
fill_status, make_old_format, 0, 0, -1, 0, 0},
6817
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
6818
fill_variables, make_old_format, 0, 0, -1, 0, 0},
6819
{"STATISTICS", stat_fields_info, create_schema_table,
6820
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
6821
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
6822
{"STATUS", variables_fields_info, create_schema_table, fill_status,
6823
make_old_format, 0, 0, -1, 1, 0},
6824
{"TABLES", tables_fields_info, create_schema_table,
6825
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
6826
OPTIMIZE_I_S_TABLE},
6827
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
6828
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
6829
{"TABLE_NAMES", table_names_fields_info, create_schema_table,
6830
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
6831
{"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
6832
fill_schema_table_privileges, 0, 0, -1, -1, 0, 0},
6833
{"TRIGGERS", triggers_fields_info, create_schema_table,
6834
get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
6836
{"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
6837
fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
6838
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
6839
make_old_format, 0, 0, -1, 1, 0},
6840
{"VIEWS", view_fields_info, create_schema_table,
6841
get_all_tables, 0, get_schema_views_record, 1, 2, 0,
6842
OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE},
6843
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
6847
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
6848
template class List_iterator_fast<char>;
6849
template class List<char>;
6852
int initialize_schema_table(st_plugin_int *plugin)
6854
ST_SCHEMA_TABLE *schema_table;
6855
DBUG_ENTER("initialize_schema_table");
6857
if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
6858
MYF(MY_WME | MY_ZEROFILL))))
6860
/* Historical Requirement */
6861
plugin->data= schema_table; // shortcut for the future
6862
if (plugin->plugin->init)
6864
schema_table->create_table= create_schema_table;
6865
schema_table->old_format= make_old_format;
6866
schema_table->idx_field1= -1,
6867
schema_table->idx_field2= -1;
6869
/* Make the name available to the init() function. */
6870
schema_table->table_name= plugin->name.str;
6872
if (plugin->plugin->init(schema_table))
6874
sql_print_error("Plugin '%s' init function returned error.",
6877
my_free(schema_table, MYF(0));
6881
/* Make sure the plugin name is not set inside the init() function. */
6882
schema_table->table_name= plugin->name.str;
6887
int finalize_schema_table(st_plugin_int *plugin)
6889
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
6890
DBUG_ENTER("finalize_schema_table");
6892
if (schema_table && plugin->plugin->deinit)
6894
DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
6895
if (plugin->plugin->deinit(NULL))
6897
DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
6900
my_free(schema_table, MYF(0));
6907
Output trigger information (SHOW CREATE TRIGGER) to the client.
6909
@param thd Thread context.
6910
@param triggers List of triggers for the table.
6911
@param trigger_idx Index of the trigger to dump.
6913
@return Operation status
6915
@retval FALSE Success.
6918
static bool show_create_trigger_impl(THD *thd,
6919
Table_triggers_list *triggers,
6924
Protocol *p= thd->protocol;
6927
LEX_STRING trg_name;
6928
ulonglong trg_sql_mode;
6929
LEX_STRING trg_sql_mode_str;
6930
LEX_STRING trg_sql_original_stmt;
6931
LEX_STRING trg_client_cs_name;
6932
LEX_STRING trg_connection_cl_name;
6933
LEX_STRING trg_db_cl_name;
6935
CHARSET_INFO *trg_client_cs;
6938
TODO: Check privileges here. This functionality will be added by
6939
implementation of the following WL items:
6940
- WL#2227: New privileges for new objects
6941
- WL#3482: Protect SHOW CREATE PROCEDURE | FUNCTION | VIEW | TRIGGER
6944
SHOW TRIGGERS and I_S.TRIGGERS will be affected too.
6947
/* Prepare trigger "object". */
6949
triggers->get_trigger_info(thd,
6953
&trg_sql_original_stmt,
6954
&trg_client_cs_name,
6955
&trg_connection_cl_name,
6958
sys_var_thd_sql_mode::symbolic_mode_representation(thd,
6962
/* Resolve trigger client character set. */
6964
if (resolve_charset(trg_client_cs_name.str, NULL, &trg_client_cs))
6969
fields.push_back(new Item_empty_string("Trigger", NAME_LEN));
6970
fields.push_back(new Item_empty_string("sql_mode", trg_sql_mode_str.length));
6974
NOTE: SQL statement field must be not less than 1024 in order not to
6975
confuse old clients.
6978
Item_empty_string *stmt_fld=
6979
new Item_empty_string("SQL Original Statement",
6980
max(trg_sql_original_stmt.length, 1024));
6982
stmt_fld->maybe_null= TRUE;
6984
fields.push_back(stmt_fld);
6987
fields.push_back(new Item_empty_string("character_set_client",
6990
fields.push_back(new Item_empty_string("collation_connection",
6993
fields.push_back(new Item_empty_string("Database Collation",
6996
if (p->send_fields(&fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
7001
p->prepare_for_resend();
7003
p->store(trg_name.str,
7005
system_charset_info);
7007
p->store(trg_sql_mode_str.str,
7008
trg_sql_mode_str.length,
7009
system_charset_info);
7011
p->store(trg_sql_original_stmt.str,
7012
trg_sql_original_stmt.length,
7015
p->store(trg_client_cs_name.str,
7016
trg_client_cs_name.length,
7017
system_charset_info);
7019
p->store(trg_connection_cl_name.str,
7020
trg_connection_cl_name.length,
7021
system_charset_info);
7023
p->store(trg_db_cl_name.str,
7024
trg_db_cl_name.length,
7025
system_charset_info);
7027
ret_code= p->write();
7032
return ret_code != 0;
7037
Read TRN and TRG files to obtain base table name for the specified
7038
trigger name and construct TABE_LIST object for the base table.
7040
@param thd Thread context.
7041
@param trg_name Trigger name.
7043
@return TABLE_LIST object corresponding to the base table.
7045
TODO: This function is a copy&paste from add_table_to_list() and
7046
sp_add_to_query_tables(). The problem is that in order to be compatible
7047
with Stored Programs (Prepared Statements), we should not touch thd->lex.
7048
The "source" functions also add created TABLE_LIST object to the
7049
thd->lex->query_tables.
7051
The plan to eliminate this copy&paste is to:
7053
- get rid of sp_add_to_query_tables() and use Lex::add_table_to_list().
7054
Only add_table_to_list() must be used to add tables from the parser
7055
into Lex::query_tables list.
7057
- do not update Lex::query_tables in add_table_to_list().
7060
static TABLE_LIST *get_trigger_table_impl(
7062
const sp_name *trg_name)
7064
char trn_path_buff[FN_REFLEN];
7066
LEX_STRING trn_path= { trn_path_buff, 0 };
7067
LEX_STRING tbl_name;
7069
build_trn_path(thd, trg_name, &trn_path);
7071
if (check_trn_exists(&trn_path))
7073
my_error(ER_TRG_DOES_NOT_EXIST, MYF(0));
7077
if (load_table_name_for_trigger(thd, trg_name, &trn_path, &tbl_name))
7080
/* We need to reset statement table list to be PS/SP friendly. */
7084
if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
7086
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(TABLE_LIST));
7090
table->db_length= trg_name->m_db.length;
7091
table->db= thd->strmake(trg_name->m_db.str, trg_name->m_db.length);
7093
table->table_name_length= tbl_name.length;
7094
table->table_name= thd->strmake(tbl_name.str, tbl_name.length);
7096
table->alias= thd->strmake(tbl_name.str, tbl_name.length);
7098
table->lock_type= TL_IGNORE;
7099
table->cacheable_table= 0;
7105
Read TRN and TRG files to obtain base table name for the specified
7106
trigger name and construct TABE_LIST object for the base table. Acquire
7107
LOCK_open when doing this.
7109
@param thd Thread context.
7110
@param trg_name Trigger name.
7112
@return TABLE_LIST object corresponding to the base table.
7115
static TABLE_LIST *get_trigger_table(THD *thd, const sp_name *trg_name)
7117
/* Acquire LOCK_open (stop the server). */
7119
pthread_mutex_lock(&LOCK_open);
7122
Load base table name from the TRN-file and create TABLE_LIST object.
7125
TABLE_LIST *lst= get_trigger_table_impl(thd, trg_name);
7127
/* Release LOCK_open (continue the server). */
7129
pthread_mutex_unlock(&LOCK_open);
7138
SHOW CREATE TRIGGER high-level implementation.
7140
@param thd Thread context.
7141
@param trg_name Trigger name.
7143
@return Operation status
7145
@retval FALSE Success.
7148
bool show_create_trigger(THD *thd, const sp_name *trg_name)
7150
TABLE_LIST *lst= get_trigger_table(thd, trg_name);
7155
if (check_table_access(thd, TRIGGER_ACL, lst, 1, TRUE))
7157
my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "TRIGGER");
7162
Open the table by name in order to load Table_triggers_list object.
7164
NOTE: there is race condition here -- the table can be dropped after
7165
LOCK_open is released. It will be fixed later by introducing
7166
acquire-shared-table-name-lock functionality.
7169
uint num_tables; /* NOTE: unused, only to pass to open_tables(). */
7171
if (open_tables(thd, &lst, &num_tables, 0))
7173
my_error(ER_TRG_CANT_OPEN_TABLE, MYF(0),
7174
(const char *) trg_name->m_db.str,
7175
(const char *) lst->table_name);
7179
/* Perform closing actions and return error status. */
7182
Table_triggers_list *triggers= lst->table->triggers;
7186
my_error(ER_TRG_DOES_NOT_EXIST, MYF(0));
7190
int trigger_idx= triggers->find_trigger_by_name(&trg_name->m_name);
7192
if (trigger_idx < 0)
7194
my_error(ER_TRG_CORRUPTED_FILE, MYF(0),
7195
(const char *) trg_name->m_db.str,
7196
(const char *) lst->table_name);
7201
return show_create_trigger_impl(thd, triggers, trigger_idx);
7204
NOTE: if show_create_trigger_impl() failed, that means we could not
7205
send data to the client. In this case we simply raise the error
7206
status and client connection will be closed.