1
/* Copyright (C) 2000-2004 MySQL AB
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
#define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
27
/* Match the values of enum ha_choice */
28
static const char *ha_choice_values[] = {"", "0", "1"};
30
static void store_key_options(THD *thd, String *packet, TABLE *table,
35
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr)
38
DBUG_ENTER("wild_case_compare");
39
DBUG_PRINT("enter",("str: '%s' wildstr: '%s'",str,wildstr));
42
while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
44
if (*wildstr == wild_prefix && wildstr[1])
46
if (my_toupper(cs, *wildstr++) !=
47
my_toupper(cs, *str++)) DBUG_RETURN(1);
49
if (! *wildstr ) DBUG_RETURN (*str != 0);
50
if (*wildstr++ == wild_one)
52
if (! *str++) DBUG_RETURN (1); /* One char; skip */
56
if (!*wildstr) DBUG_RETURN(0); /* '*' as last char: OK */
57
flag=(*wildstr != wild_many && *wildstr != wild_one);
63
if ((cmp= *wildstr) == wild_prefix && wildstr[1])
65
cmp=my_toupper(cs, cmp);
66
while (*str && my_toupper(cs, *str) != cmp)
68
if (!*str) DBUG_RETURN (1);
70
if (wild_case_compare(cs, str,wildstr) == 0) DBUG_RETURN (0);
75
DBUG_RETURN (*str != '\0');
78
/***************************************************************************
79
** List all table types supported
80
***************************************************************************/
82
static int make_version_string(char *buf, int buf_length, uint version)
84
return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
87
static my_bool show_plugins(THD *thd, plugin_ref plugin,
90
TABLE *table= (TABLE*) arg;
91
struct st_mysql_plugin *plug= plugin_decl(plugin);
92
struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
93
CHARSET_INFO *cs= system_charset_info;
96
restore_record(table, s->default_values);
98
table->field[0]->store(plugin_name(plugin)->str,
99
plugin_name(plugin)->length, cs);
101
table->field[1]->store(version_buf,
102
make_version_string(version_buf, sizeof(version_buf), plug->version),
106
switch (plugin_state(plugin)) {
107
/* case PLUGIN_IS_FREED: does not happen */
108
case PLUGIN_IS_DELETED:
109
table->field[2]->store(STRING_WITH_LEN("DELETED"), cs);
111
case PLUGIN_IS_UNINITIALIZED:
112
table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs);
114
case PLUGIN_IS_READY:
115
table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
121
table->field[3]->store(plugin_type_names[plug->type].str,
122
plugin_type_names[plug->type].length,
124
table->field[4]->store(version_buf,
125
make_version_string(version_buf, sizeof(version_buf),
126
*(uint *)plug->info), cs);
130
table->field[5]->store(plugin_dl->dl.str, plugin_dl->dl.length, cs);
131
table->field[5]->set_notnull();
132
table->field[6]->store(version_buf,
133
make_version_string(version_buf, sizeof(version_buf),
136
table->field[6]->set_notnull();
140
table->field[5]->set_null();
141
table->field[6]->set_null();
147
table->field[7]->store(plug->author, strlen(plug->author), cs);
148
table->field[7]->set_notnull();
151
table->field[7]->set_null();
155
table->field[8]->store(plug->descr, strlen(plug->descr), cs);
156
table->field[8]->set_notnull();
159
table->field[8]->set_null();
161
switch (plug->license) {
162
case PLUGIN_LICENSE_GPL:
163
table->field[9]->store(PLUGIN_LICENSE_GPL_STRING,
164
strlen(PLUGIN_LICENSE_GPL_STRING), cs);
166
case PLUGIN_LICENSE_BSD:
167
table->field[9]->store(PLUGIN_LICENSE_BSD_STRING,
168
strlen(PLUGIN_LICENSE_BSD_STRING), cs);
171
table->field[9]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
172
strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
175
table->field[9]->set_notnull();
177
return schema_table_store_record(thd, table);
181
int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond)
183
DBUG_ENTER("fill_plugins");
184
TABLE *table= tables->table;
186
if (plugin_foreach_with_mask(thd, show_plugins, MYSQL_ANY_PLUGIN,
187
~PLUGIN_IS_FREED, table))
195
find_files() - find files in a given directory.
200
files put found files in this list
201
db database name to set in TABLE_LIST structure
202
path path to database
203
wild filter for found files
204
dir read databases in path if TRUE, read .frm files in
208
FIND_FILES_OK success
209
FIND_FILES_OOM out of memory error
210
FIND_FILES_DIR no such directory, or directory can't be read
215
find_files(THD *thd, List<LEX_STRING> *files, const char *db,
216
const char *path, const char *wild, bool dir)
222
LEX_STRING *file_name= 0;
224
TABLE_LIST table_list;
225
DBUG_ENTER("find_files");
227
if (wild && !wild[0])
230
bzero((char*) &table_list,sizeof(table_list));
232
if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
234
if (my_errno == ENOENT)
235
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db);
237
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
238
DBUG_RETURN(FIND_FILES_DIR);
241
for (i=0 ; i < (uint) dirp->number_off_files ; i++)
243
char uname[NAME_LEN + 1]; /* Unencoded name */
244
file=dirp->dir_entry+i;
246
{ /* Return databases */
247
if ((file->name[0] == '.' &&
248
((file->name[1] == '.' && file->name[2] == '\0') ||
249
file->name[1] == '\0')))
250
continue; /* . or .. */
253
char buff[FN_REFLEN];
254
if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym"))
256
/* Only show the sym file if it points to a directory */
258
*ext=0; /* Remove extension */
259
unpack_dirname(buff, file->name);
261
if (end != buff && end[-1] == FN_LIBCHAR)
262
end[-1]= 0; // Remove end FN_LIBCHAR
263
if (!my_stat(buff, file->mystat, MYF(0)))
267
if (!MY_S_ISDIR(file->mystat->st_mode))
270
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
271
if (wild && wild_compare(uname, wild, 0))
274
thd->make_lex_string(file_name, uname, file_name_len, TRUE)))
277
DBUG_RETURN(FIND_FILES_OOM);
282
// Return only .frm files which aren't temp files.
283
if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) ||
284
is_prefix(file->name, tmp_file_prefix))
287
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
290
if (lower_case_table_names)
292
if (wild_case_compare(files_charset_info, uname, wild))
295
else if (wild_compare(uname, wild, 0))
300
thd->make_lex_string(file_name, uname, file_name_len, TRUE)) ||
301
files->push_back(file_name))
304
DBUG_RETURN(FIND_FILES_OOM);
307
DBUG_PRINT("info",("found: %d files", files->elements));
310
DBUG_RETURN(FIND_FILES_OK);
315
mysqld_show_create(THD *thd, TABLE_LIST *table_list)
317
Protocol *protocol= thd->protocol;
319
String buffer(buff, sizeof(buff), system_charset_info);
320
DBUG_ENTER("mysqld_show_create");
321
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
322
table_list->table_name));
324
/* Only one table for now, but VIEW can involve several tables */
325
if (open_normal_and_derived_tables(thd, table_list, 0))
327
if (thd->is_error() && thd->main_da.sql_errno() != ER_VIEW_INVALID)
331
Clear all messages with 'error' level status and
332
issue a warning with 'warning' level status in
333
case of invalid view and last error is ER_VIEW_INVALID
335
mysql_reset_errors(thd, true);
341
if (store_create_info(thd, table_list, &buffer, NULL))
344
List<Item> field_list;
346
field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
347
// 1024 is for not to confuse old clients
348
field_list.push_back(new Item_empty_string("Create Table",
349
max(buffer.length(),1024)));
352
if (protocol->send_fields(&field_list,
353
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
355
protocol->prepare_for_resend();
357
if (table_list->schema_table)
358
protocol->store(table_list->schema_table->table_name,
359
system_charset_info);
361
protocol->store(table_list->table->alias, system_charset_info);
364
protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
366
if (protocol->write())
373
bool mysqld_show_create_db(THD *thd, char *dbname,
374
HA_CREATE_INFO *create_info)
377
String buffer(buff, sizeof(buff), system_charset_info);
378
Protocol *protocol=thd->protocol;
379
DBUG_ENTER("mysql_show_create_db");
381
if (store_db_create_info(thd, dbname, &buffer, create_info))
384
This assumes that the only reason for which store_db_create_info()
385
can fail is incorrect database name (which is the case now).
387
my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
391
List<Item> field_list;
392
field_list.push_back(new Item_empty_string("Database",NAME_CHAR_LEN));
393
field_list.push_back(new Item_empty_string("Create Database",1024));
395
if (protocol->send_fields(&field_list,
396
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
399
protocol->prepare_for_resend();
400
protocol->store(dbname, strlen(dbname), system_charset_info);
401
protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
403
if (protocol->write())
411
/****************************************************************************
412
Return only fields for API mysql_list_fields
413
Use "show table wildcard" in mysql instead of this
414
****************************************************************************/
417
mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
420
DBUG_ENTER("mysqld_list_fields");
421
DBUG_PRINT("enter",("table: %s",table_list->table_name));
423
if (open_normal_and_derived_tables(thd, table_list, 0))
425
table= table_list->table;
427
List<Item> field_list;
430
for (ptr=table->field ; (field= *ptr); ptr++)
432
if (!wild || !wild[0] ||
433
!wild_case_compare(system_charset_info, field->field_name,wild))
435
field_list.push_back(new Item_field(field));
438
restore_record(table, s->default_values); // Get empty record
439
table->use_all_columns();
440
if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
448
Go through all character combinations and ensure that sql_lex.cc can
449
parse it as an identifier.
454
name_length length of name
457
# Pointer to conflicting character
458
0 No conflicting character
461
static const char *require_quotes(const char *name, uint name_length)
464
bool pure_digit= TRUE;
465
const char *end= name + name_length;
467
for (; name < end ; name++)
469
uchar chr= (uchar) *name;
470
length= my_mbcharlen(system_charset_info, chr);
471
if (length == 1 && !system_charset_info->ident_map[chr])
473
if (length == 1 && (chr < '0' || chr > '9'))
483
Quote the given identifier if needed and append it to the target string.
484
If the given identifier is empty, it will be quoted.
490
name the identifier to be appended
491
name_length length of the appending identifier
495
append_identifier(THD *thd, String *packet, const char *name, uint length)
497
const char *name_end;
499
int q= get_quote_char_for_identifier(thd, name, length);
503
packet->append(name, length, packet->charset());
508
The identifier must be quoted as it includes a quote character or
512
VOID(packet->reserve(length*2 + 2));
513
quote_char= (char) q;
514
packet->append("e_char, 1, system_charset_info);
516
for (name_end= name+length ; name < name_end ; name+= length)
518
uchar chr= (uchar) *name;
519
length= my_mbcharlen(system_charset_info, chr);
521
my_mbcharlen can return 0 on a wrong multibyte
522
sequence. It is possible when upgrading from 4.0,
523
and identifier contains some accented characters.
524
The manual says it does not work. So we'll just
525
change length to 1 not to hang in the endless loop.
529
if (length == 1 && chr == (uchar) quote_char)
530
packet->append("e_char, 1, system_charset_info);
531
packet->append(name, length, system_charset_info);
533
packet->append("e_char, 1, system_charset_info);
538
Get the quote character for displaying an identifier.
541
get_quote_char_for_identifier()
544
length length of name
547
Force quoting in the following cases:
548
- name is empty (for one, it is possible when we use this function for
549
quoting user and host names for DEFINER clause);
551
- name includes a special character;
552
Otherwise identifier is quoted only if the option OPTION_QUOTE_SHOW_CREATE
556
EOF No quote character is needed
560
int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
563
!is_keyword(name,length) &&
564
!require_quotes(name, length) &&
565
!(thd->options & OPTION_QUOTE_SHOW_CREATE))
571
/* Append directory name (if exists) to CREATE INFO */
573
static void append_directory(THD *thd, String *packet, const char *dir_type,
574
const char *filename)
578
uint length= dirname_length(filename);
580
packet->append(dir_type);
581
packet->append(STRING_WITH_LEN(" DIRECTORY='"));
582
packet->append(filename, length);
583
packet->append('\'');
588
#define LIST_PROCESS_HOST_LEN 64
590
static bool get_field_default_value(THD *thd, Field *timestamp_field,
591
Field *field, String *def_value,
595
bool has_now_default;
598
We are using CURRENT_TIMESTAMP instead of NOW because it is
601
has_now_default= (timestamp_field == field &&
602
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
604
has_default= (field->type() != FIELD_TYPE_BLOB &&
605
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
606
field->unireg_check != Field::NEXT_NUMBER
609
def_value->length(0);
613
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
614
else if (!field->is_null())
615
{ // Not null by default
616
char tmp[MAX_FIELD_WIDTH];
617
String type(tmp, sizeof(tmp), field->charset());
618
field->val_str(&type);
623
/* convert to system_charset_info == utf8 */
624
def_val.copy(type.ptr(), type.length(), field->charset(),
625
system_charset_info, &dummy_errors);
627
append_unescaped(def_value, def_val.ptr(), def_val.length());
629
def_value->append(def_val.ptr(), def_val.length());
632
def_value->append(STRING_WITH_LEN("''"));
634
else if (field->maybe_null() && quoted)
635
def_value->append(STRING_WITH_LEN("NULL")); // Null as default
644
Build a CREATE TABLE statement for a table.
649
table_list A list containing one table to write statement
651
packet Pointer to a string where statement will be
653
create_info_arg Pointer to create information that can be used
654
to tailor the format of the statement. Can be
655
NULL, in which case only SQL_MODE is considered
656
when building the statement.
659
Currently always return 0, but might return error code in the
666
int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
667
HA_CREATE_INFO *create_info_arg)
669
List<Item> field_list;
670
char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
672
String type(tmp, sizeof(tmp), system_charset_info);
673
String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
677
TABLE *table= table_list->table;
678
handler *file= table->file;
679
TABLE_SHARE *share= table->s;
680
HA_CREATE_INFO create_info;
681
bool show_table_options= FALSE;
682
my_bitmap_map *old_map;
683
DBUG_ENTER("store_create_info");
684
DBUG_PRINT("enter",("table: %s", table->s->table_name.str));
686
restore_record(table, s->default_values); // Get empty record
688
if (share->tmp_table)
689
packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
691
packet->append(STRING_WITH_LEN("CREATE TABLE "));
692
if (create_info_arg &&
693
(create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
694
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
695
if (table_list->schema_table)
696
alias= table_list->schema_table->table_name;
699
if (lower_case_table_names == 2)
703
alias= share->table_name.str;
706
append_identifier(thd, packet, alias, strlen(alias));
707
packet->append(STRING_WITH_LEN(" (\n"));
709
We need this to get default values from the table
710
We have to restore the read_set if we are called from insert in case
711
of row based replication.
713
old_map= tmp_use_all_columns(table, table->read_set);
715
for (ptr=table->field ; (field= *ptr); ptr++)
717
uint flags = field->flags;
719
if (ptr != table->field)
720
packet->append(STRING_WITH_LEN(",\n"));
722
packet->append(STRING_WITH_LEN(" "));
723
append_identifier(thd,packet,field->field_name, strlen(field->field_name));
725
// check for surprises from the previous call to Field::sql_type()
726
if (type.ptr() != tmp)
727
type.set(tmp, sizeof(tmp), system_charset_info);
729
type.set_charset(system_charset_info);
731
field->sql_type(type);
732
packet->append(type.ptr(), type.length(), system_charset_info);
734
if (field->has_charset())
736
if (field->charset() != share->table_charset)
738
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
739
packet->append(field->charset()->csname);
742
For string types dump collation name only if
743
collation is not primary for the given charset
745
if (!(field->charset()->state & MY_CS_PRIMARY))
747
packet->append(STRING_WITH_LEN(" COLLATE "));
748
packet->append(field->charset()->name);
752
if (flags & NOT_NULL_FLAG)
753
packet->append(STRING_WITH_LEN(" NOT NULL"));
754
else if (field->type() == MYSQL_TYPE_TIMESTAMP)
757
TIMESTAMP field require explicit NULL flag, because unlike
758
all other fields they are treated as NOT NULL by default.
760
packet->append(STRING_WITH_LEN(" NULL"));
764
Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
765
and about STORAGE (DISK or MEMORY).
767
enum ha_storage_media storage_type= (enum ha_storage_media)
768
((flags >> FIELD_STORAGE_FLAGS) & STORAGE_TYPE_MASK);
769
enum column_format_type column_format= (enum column_format_type)
770
((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
773
packet->append(STRING_WITH_LEN(" /*!"));
774
packet->append(STRING_WITH_LEN(MYSQL_VERSION_TABLESPACE_IN_FRM_STR));
775
packet->append(STRING_WITH_LEN(" STORAGE"));
776
if (storage_type == HA_SM_DISK)
777
packet->append(STRING_WITH_LEN(" DISK */"));
779
packet->append(STRING_WITH_LEN(" MEMORY */"));
783
packet->append(STRING_WITH_LEN(" /*!"));
784
packet->append(STRING_WITH_LEN(MYSQL_VERSION_TABLESPACE_IN_FRM_STR));
785
packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
786
if (column_format == COLUMN_FORMAT_TYPE_FIXED)
787
packet->append(STRING_WITH_LEN(" FIXED */"));
789
packet->append(STRING_WITH_LEN(" DYNAMIC */"));
792
if (get_field_default_value(thd, table->timestamp_field,
793
field, &def_value, 1))
795
packet->append(STRING_WITH_LEN(" DEFAULT "));
796
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
799
if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
800
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
802
if (field->unireg_check == Field::NEXT_NUMBER)
803
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
805
if (field->comment.length)
807
packet->append(STRING_WITH_LEN(" COMMENT "));
808
append_unescaped(packet, field->comment.str, field->comment.length);
812
key_info= table->key_info;
813
bzero((char*) &create_info, sizeof(create_info));
814
/* Allow update_create_info to update row type */
815
create_info.row_type= share->row_type;
816
file->update_create_info(&create_info);
817
primary_key= share->primary_key;
819
for (uint i=0 ; i < share->keys ; i++,key_info++)
821
KEY_PART_INFO *key_part= key_info->key_part;
822
bool found_primary=0;
823
packet->append(STRING_WITH_LEN(",\n "));
825
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
829
No space at end, because a space will be added after where the
830
identifier would go, but that is not added for primary key.
832
packet->append(STRING_WITH_LEN("PRIMARY KEY"));
834
else if (key_info->flags & HA_NOSAME)
835
packet->append(STRING_WITH_LEN("UNIQUE KEY "));
837
packet->append(STRING_WITH_LEN("KEY "));
840
append_identifier(thd, packet, key_info->name, strlen(key_info->name));
842
packet->append(STRING_WITH_LEN(" ("));
844
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
850
append_identifier(thd,packet,key_part->field->field_name,
851
strlen(key_part->field->field_name));
852
if (key_part->field &&
854
table->field[key_part->fieldnr-1]->key_length()))
858
end= int10_to_str((long) key_part->length /
859
key_part->field->charset()->mbmaxlen,
862
packet->append(buff,(uint) (end-buff));
866
store_key_options(thd, packet, table, key_info);
870
Get possible foreign key definitions stored in InnoDB and append them
871
to the CREATE TABLE statement
874
if ((for_str= file->get_foreign_key_create_info()))
876
packet->append(for_str, strlen(for_str));
877
file->free_foreign_key_create_info(for_str);
880
packet->append(STRING_WITH_LEN("\n)"));
882
show_table_options= TRUE;
884
Get possible table space definitions and append them
885
to the CREATE TABLE statement
888
switch (table->s->default_storage_media) {
890
if ((for_str= (char *)file->get_tablespace_name()))
892
packet->append(STRING_WITH_LEN(" /*!50100 TABLESPACE "));
893
append_identifier(thd, packet, for_str, strlen(for_str));
894
packet->append(STRING_WITH_LEN(" */"));
898
packet->append(STRING_WITH_LEN(" /*!50100"));
899
if ((for_str= (char *)file->get_tablespace_name()))
901
packet->append(STRING_WITH_LEN(" TABLESPACE "));
902
append_identifier(thd, packet, for_str, strlen(for_str));
904
packet->append(STRING_WITH_LEN(" STORAGE DISK */"));
907
packet->append(STRING_WITH_LEN(" /*!50100"));
908
if ((for_str= (char *)file->get_tablespace_name()))
910
packet->append(STRING_WITH_LEN(" TABLESPACE "));
911
append_identifier(thd, packet, for_str, strlen(for_str));
913
packet->append(STRING_WITH_LEN(" STORAGE MEMORY */"));
919
THEN add ENGINE only if it was used when creating the table
921
if (!create_info_arg ||
922
(create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
924
packet->append(STRING_WITH_LEN(" ENGINE="));
925
packet->append(file->table_type());
929
Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
930
and NEXT_ID > 1 (the default). We must not print the clause
931
for engines that do not support this as it would break the
932
import of dumps, but as of this writing, the test for whether
933
AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
934
is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
935
Because of that, we do not explicitly test for the feature,
936
but may extrapolate its existence from that of an AUTO_INCREMENT column.
939
if (create_info.auto_increment_value > 1)
942
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
943
end= longlong10_to_str(create_info.auto_increment_value, buff,10);
944
packet->append(buff, (uint) (end - buff));
948
if (share->table_charset)
952
THEN add DEFAULT CHARSET only if it was used when creating the table
954
if (!create_info_arg ||
955
(create_info_arg->used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
957
packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
958
packet->append(share->table_charset->csname);
959
if (!(share->table_charset->state & MY_CS_PRIMARY))
961
packet->append(STRING_WITH_LEN(" COLLATE="));
962
packet->append(table->s->table_charset->name);
970
packet->append(STRING_WITH_LEN(" MIN_ROWS="));
971
end= longlong10_to_str(share->min_rows, buff, 10);
972
packet->append(buff, (uint) (end- buff));
975
if (share->max_rows && !table_list->schema_table)
978
packet->append(STRING_WITH_LEN(" MAX_ROWS="));
979
end= longlong10_to_str(share->max_rows, buff, 10);
980
packet->append(buff, (uint) (end - buff));
983
if (share->avg_row_length)
986
packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
987
end= longlong10_to_str(share->avg_row_length, buff,10);
988
packet->append(buff, (uint) (end - buff));
991
if (share->db_create_options & HA_OPTION_PACK_KEYS)
992
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
993
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
994
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
995
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
996
if (share->db_create_options & HA_OPTION_CHECKSUM)
997
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
998
if (share->page_checksum != HA_CHOICE_UNDEF)
1000
packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
1001
packet->append(ha_choice_values[(uint) share->page_checksum], 1);
1003
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
1004
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
1005
if (create_info.row_type != ROW_TYPE_DEFAULT)
1007
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
1008
packet->append(ha_row_type[(uint) create_info.row_type]);
1010
if (share->transactional != HA_CHOICE_UNDEF)
1012
packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
1013
packet->append(ha_choice_values[(uint) share->transactional], 1);
1015
if (table->s->key_block_size)
1018
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
1019
end= longlong10_to_str(table->s->key_block_size, buff, 10);
1020
packet->append(buff, (uint) (end - buff));
1022
table->file->append_create_info(packet);
1023
if (share->comment.length)
1025
packet->append(STRING_WITH_LEN(" COMMENT="));
1026
append_unescaped(packet, share->comment.str, share->comment.length);
1028
if (share->connect_string.length)
1030
packet->append(STRING_WITH_LEN(" CONNECTION="));
1031
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
1033
append_directory(thd, packet, "DATA", create_info.data_file_name);
1034
append_directory(thd, packet, "INDEX", create_info.index_file_name);
1036
tmp_restore_column_map(table->read_set, old_map);
1041
Get a CREATE statement for a given database.
1043
The database is identified by its name, passed as @c dbname parameter.
1044
The name should be encoded using the system character set (UTF8 currently).
1046
Resulting statement is stored in the string pointed by @c buffer. The string
1047
is emptied first and its character set is set to the system character set.
1049
If HA_LEX_CREATE_IF_NOT_EXISTS flag is set in @c create_info->options, then
1050
the resulting CREATE statement contains "IF NOT EXISTS" clause. Other flags
1051
in @c create_options are ignored.
1053
@param thd The current thread instance.
1054
@param dbname The name of the database.
1055
@param buffer A String instance where the statement is stored.
1056
@param create_info If not NULL, the options member influences the resulting
1059
@returns TRUE if errors are detected, FALSE otherwise.
1062
bool store_db_create_info(THD *thd, const char *dbname, String *buffer,
1063
HA_CREATE_INFO *create_info)
1065
HA_CREATE_INFO create;
1066
uint create_options = create_info ? create_info->options : 0;
1067
DBUG_ENTER("store_db_create_info");
1069
if (!my_strcasecmp(system_charset_info, dbname,
1070
INFORMATION_SCHEMA_NAME.str))
1072
dbname= INFORMATION_SCHEMA_NAME.str;
1073
create.default_table_charset= system_charset_info;
1077
if (check_db_dir_existence(dbname))
1080
load_db_opt_by_name(thd, dbname, &create);
1085
buffer->set_charset(system_charset_info);
1086
buffer->append(STRING_WITH_LEN("CREATE DATABASE "));
1088
if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
1089
buffer->append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
1091
append_identifier(thd, buffer, dbname, strlen(dbname));
1093
if (create.default_table_charset)
1095
buffer->append(STRING_WITH_LEN(" /*!40100"));
1096
buffer->append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
1097
buffer->append(create.default_table_charset->csname);
1098
if (!(create.default_table_charset->state & MY_CS_PRIMARY))
1100
buffer->append(STRING_WITH_LEN(" COLLATE "));
1101
buffer->append(create.default_table_charset->name);
1103
buffer->append(STRING_WITH_LEN(" */"));
1109
static void store_key_options(THD *thd, String *packet, TABLE *table,
1112
char *end, buff[32];
1114
if (key_info->algorithm == HA_KEY_ALG_BTREE)
1115
packet->append(STRING_WITH_LEN(" USING BTREE"));
1117
if (key_info->algorithm == HA_KEY_ALG_HASH)
1118
packet->append(STRING_WITH_LEN(" USING HASH"));
1120
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
1121
table->s->key_block_size != key_info->block_size)
1123
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
1124
end= longlong10_to_str(key_info->block_size, buff, 10);
1125
packet->append(buff, (uint) (end - buff));
1128
DBUG_ASSERT(test(key_info->flags & HA_USES_COMMENT) ==
1129
(key_info->comment.length > 0));
1130
if (key_info->flags & HA_USES_COMMENT)
1132
packet->append(STRING_WITH_LEN(" COMMENT "));
1133
append_unescaped(packet, key_info->comment.str,
1134
key_info->comment.length);
1139
/****************************************************************************
1140
Return info about all processes
1141
returns for each thread: thread id, user, host, db, command, info
1142
****************************************************************************/
1144
class thread_info :public ilink {
1146
static void *operator new(size_t size)
1148
return (void*) sql_alloc((uint) size);
1150
static void operator delete(void *ptr __attribute__((unused)),
1151
size_t size __attribute__((unused)))
1152
{ TRASH(ptr, size); }
1157
const char *user,*host,*db,*proc_info,*state_info;
1161
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1162
template class I_List<thread_info>;
1165
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
1168
List<Item> field_list;
1169
I_List<thread_info> thread_infos;
1170
ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
1171
PROCESS_LIST_WIDTH);
1172
Protocol *protocol= thd->protocol;
1173
DBUG_ENTER("mysqld_list_processes");
1175
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1176
field_list.push_back(new Item_empty_string("User",16));
1177
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1178
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1179
field->maybe_null=1;
1180
field_list.push_back(new Item_empty_string("Command",16));
1181
field_list.push_back(new Item_return_int("Time",7, MYSQL_TYPE_LONG));
1182
field_list.push_back(field=new Item_empty_string("State",30));
1183
field->maybe_null=1;
1184
field_list.push_back(field=new Item_empty_string("Info",max_query_length));
1185
field->maybe_null=1;
1186
if (protocol->send_fields(&field_list,
1187
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1190
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
1193
I_List_iterator<THD> it(threads);
1197
Security_context *tmp_sctx= tmp->security_ctx;
1198
struct st_my_thread_var *mysys_var;
1199
if ((tmp->vio_ok() || tmp->system_thread) && (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
1201
thread_info *thd_info= new thread_info;
1203
thd_info->thread_id=tmp->thread_id;
1204
thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
1205
(tmp->system_thread ?
1206
"system user" : "unauthenticated user"));
1207
thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
1208
tmp_sctx->host_or_ip :
1209
tmp_sctx->host ? tmp_sctx->host : "");
1210
if ((thd_info->db=tmp->db)) // Safe test
1211
thd_info->db=thd->strdup(thd_info->db);
1212
thd_info->command=(int) tmp->command;
1213
if ((mysys_var= tmp->mysys_var))
1214
pthread_mutex_lock(&mysys_var->mutex);
1215
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
1216
thd_info->state_info= (char*) (tmp->net.reading_or_writing ?
1217
(tmp->net.reading_or_writing == 2 ?
1219
thd_info->command == COM_SLEEP ? NullS :
1220
"Reading from net") :
1221
tmp->proc_info ? tmp->proc_info :
1223
tmp->mysys_var->current_cond ?
1224
"Waiting on cond" : NullS);
1226
pthread_mutex_unlock(&mysys_var->mutex);
1228
thd_info->start_time= tmp->start_time;
1233
query_length is always set to 0 when we set query = NULL; see
1234
the comment in sql_class.h why this prevents crashes in possible
1235
races with query_length
1237
uint length= min(max_query_length, tmp->query_length);
1238
thd_info->query=(char*) thd->strmake(tmp->query,length);
1240
thread_infos.append(thd_info);
1244
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1246
thread_info *thd_info;
1247
time_t now= my_time(0);
1248
while ((thd_info=thread_infos.get()))
1250
protocol->prepare_for_resend();
1251
protocol->store((ulonglong) thd_info->thread_id);
1252
protocol->store(thd_info->user, system_charset_info);
1253
protocol->store(thd_info->host, system_charset_info);
1254
protocol->store(thd_info->db, system_charset_info);
1255
if (thd_info->proc_info)
1256
protocol->store(thd_info->proc_info, system_charset_info);
1258
protocol->store(command_name[thd_info->command].str, system_charset_info);
1259
if (thd_info->start_time)
1260
protocol->store((uint32) (now - thd_info->start_time));
1262
protocol->store_null();
1263
protocol->store(thd_info->state_info, system_charset_info);
1264
protocol->store(thd_info->query, system_charset_info);
1265
if (protocol->write())
1266
break; /* purecov: inspected */
1272
int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
1274
TABLE *table= tables->table;
1275
CHARSET_INFO *cs= system_charset_info;
1277
time_t now= my_time(0);
1278
DBUG_ENTER("fill_process_list");
1282
VOID(pthread_mutex_lock(&LOCK_thread_count));
1286
I_List_iterator<THD> it(threads);
1291
Security_context *tmp_sctx= tmp->security_ctx;
1292
struct st_my_thread_var *mysys_var;
1295
if ((!tmp->vio_ok() && !tmp->system_thread))
1298
restore_record(table, s->default_values);
1300
table->field[0]->store((longlong) tmp->thread_id, TRUE);
1302
val= tmp_sctx->user ? tmp_sctx->user :
1303
(tmp->system_thread ? "system user" : "unauthenticated user");
1304
table->field[1]->store(val, strlen(val), cs);
1306
table->field[2]->store(tmp_sctx->host_or_ip,
1307
strlen(tmp_sctx->host_or_ip), cs);
1311
table->field[3]->store(tmp->db, strlen(tmp->db), cs);
1312
table->field[3]->set_notnull();
1315
if ((mysys_var= tmp->mysys_var))
1316
pthread_mutex_lock(&mysys_var->mutex);
1318
if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
1319
table->field[4]->store(val, strlen(val), cs);
1321
table->field[4]->store(command_name[tmp->command].str,
1322
command_name[tmp->command].length, cs);
1324
table->field[5]->store((uint32)(tmp->start_time ?
1325
now - tmp->start_time : 0), TRUE);
1327
val= (char*) (tmp->net.reading_or_writing ?
1328
(tmp->net.reading_or_writing == 2 ?
1330
tmp->command == COM_SLEEP ? NullS :
1331
"Reading from net") :
1332
tmp->proc_info ? tmp->proc_info :
1334
tmp->mysys_var->current_cond ?
1335
"Waiting on cond" : NullS);
1338
table->field[6]->store(val, strlen(val), cs);
1339
table->field[6]->set_notnull();
1343
pthread_mutex_unlock(&mysys_var->mutex);
1348
table->field[7]->store(tmp->query,
1349
min(PROCESS_LIST_INFO_WIDTH,
1350
tmp->query_length), cs);
1351
table->field[7]->set_notnull();
1354
if (schema_table_store_record(thd, table))
1356
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1362
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1366
/*****************************************************************************
1368
*****************************************************************************/
1370
static DYNAMIC_ARRAY all_status_vars;
1371
static bool status_vars_inited= 0;
1372
static int show_var_cmp(const void *var1, const void *var2)
1374
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1378
deletes all the SHOW_UNDEF elements from the array and calls
1379
delete_dynamic() if it's completely empty.
1381
static void shrink_var_array(DYNAMIC_ARRAY *array)
1384
SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
1386
for (a= b= 0; b < array->elements; b++)
1387
if (all[b].type != SHOW_UNDEF)
1391
bzero(all+a, sizeof(SHOW_VAR)); // writing NULL-element to the end
1394
else // array is completely empty - delete it
1395
delete_dynamic(array);
1399
Adds an array of SHOW_VAR entries to the output of SHOW STATUS
1402
add_status_vars(SHOW_VAR *list)
1403
list - an array of SHOW_VAR entries to add to all_status_vars
1404
the last entry must be {0,0,SHOW_UNDEF}
1407
The handling of all_status_vars[] is completely internal, it's allocated
1408
automatically when something is added to it, and deleted completely when
1409
the last entry is removed.
1411
As a special optimization, if add_status_vars() is called before
1412
init_status_vars(), it assumes "startup mode" - neither concurrent access
1413
to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
1415
The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
1417
int add_status_vars(SHOW_VAR *list)
1420
if (status_vars_inited)
1421
pthread_mutex_lock(&LOCK_status);
1422
if (!all_status_vars.buffer && // array is not allocated yet - do it now
1423
my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
1429
res|= insert_dynamic(&all_status_vars, (uchar*)list++);
1430
res|= insert_dynamic(&all_status_vars, (uchar*)list); // appending NULL-element
1431
all_status_vars.elements--; // but next insert_dynamic should overwite it
1432
if (status_vars_inited)
1433
sort_dynamic(&all_status_vars, show_var_cmp);
1435
if (status_vars_inited)
1436
pthread_mutex_unlock(&LOCK_status);
1441
Make all_status_vars[] usable for SHOW STATUS
1444
See add_status_vars(). Before init_status_vars() call, add_status_vars()
1445
works in a special fast "startup" mode. Thus init_status_vars()
1446
should be called as late as possible but before enabling multi-threading.
1448
void init_status_vars()
1450
status_vars_inited=1;
1451
sort_dynamic(&all_status_vars, show_var_cmp);
1454
void reset_status_vars()
1456
SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
1457
SHOW_VAR *last= ptr + all_status_vars.elements;
1458
for (; ptr < last; ptr++)
1460
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
1461
if (ptr->type == SHOW_LONG)
1462
*(ulong*) ptr->value= 0;
1467
catch-all cleanup function, cleans up everything no matter what
1470
This function is not strictly required if all add_to_status/
1471
remove_status_vars are properly paired, but it's a safety measure that
1472
deletes everything from the all_status_vars[] even if some
1473
remove_status_vars were forgotten
1475
void free_status_vars()
1477
delete_dynamic(&all_status_vars);
1481
Removes an array of SHOW_VAR entries from the output of SHOW STATUS
1484
remove_status_vars(SHOW_VAR *list)
1485
list - an array of SHOW_VAR entries to remove to all_status_vars
1486
the last entry must be {0,0,SHOW_UNDEF}
1489
there's lots of room for optimizing this, especially in non-sorted mode,
1490
but nobody cares - it may be called only in case of failed plugin
1491
initialization in the mysqld startup.
1494
void remove_status_vars(SHOW_VAR *list)
1496
if (status_vars_inited)
1498
pthread_mutex_lock(&LOCK_status);
1499
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1500
int a= 0, b= all_status_vars.elements, c= (a+b)/2;
1502
for (; list->name; list++)
1505
for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
1507
res= show_var_cmp(list, all+c);
1516
all[c].type= SHOW_UNDEF;
1518
shrink_var_array(&all_status_vars);
1519
pthread_mutex_unlock(&LOCK_status);
1523
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1525
for (; list->name; list++)
1527
for (i= 0; i < all_status_vars.elements; i++)
1529
if (show_var_cmp(list, all+i))
1531
all[i].type= SHOW_UNDEF;
1535
shrink_var_array(&all_status_vars);
1539
inline void make_upper(char *buf)
1542
*buf= my_toupper(system_charset_info, *buf);
1545
static bool show_status_array(THD *thd, const char *wild,
1546
SHOW_VAR *variables,
1547
enum enum_var_type value_type,
1548
struct system_status_var *status_var,
1549
const char *prefix, TABLE *table,
1552
MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
1553
char * const buff= (char *) &buff_data;
1555
/* the variable name should not be longer than 64 characters */
1556
char name_buffer[64];
1558
LEX_STRING null_lex_str;
1560
DBUG_ENTER("show_status_array");
1562
null_lex_str.str= 0; // For sys_var->value_ptr()
1563
null_lex_str.length= 0;
1565
prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
1568
len=name_buffer + sizeof(name_buffer) - prefix_end;
1570
for (; variables->name; variables++)
1572
strnmov(prefix_end, variables->name, len);
1573
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
1575
make_upper(name_buffer);
1578
if var->type is SHOW_FUNC, call the function.
1579
Repeat as necessary, if new var is again SHOW_FUNC
1581
for (var=variables; var->type == SHOW_FUNC; var= &tmp)
1582
((mysql_show_var_func)(var->value))(thd, &tmp, buff);
1584
SHOW_TYPE show_type=var->type;
1585
if (show_type == SHOW_ARRAY)
1587
show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
1588
status_var, name_buffer, table, ucase_names);
1592
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
1593
name_buffer, wild)))
1595
char *value=var->value;
1596
const char *pos, *end; // We assign a lot of const's
1598
pthread_mutex_lock(&LOCK_global_system_variables);
1600
if (show_type == SHOW_SYS)
1602
show_type= ((sys_var*) value)->show_type();
1603
value= (char*) ((sys_var*) value)->value_ptr(thd, value_type,
1609
note that value may be == buff. All SHOW_xxx code below
1610
should still work in this case
1612
switch (show_type) {
1613
case SHOW_DOUBLE_STATUS:
1614
value= ((char *) status_var + (ulong) value);
1617
/* 6 is the default precision for '%f' in sprintf() */
1618
end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
1620
case SHOW_LONG_STATUS:
1621
value= ((char *) status_var + (ulong) value);
1624
case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
1625
end= int10_to_str(*(long*) value, buff, 10);
1627
case SHOW_LONGLONG_STATUS:
1628
value= ((char *) status_var + (ulonglong) value);
1631
end= longlong10_to_str(*(longlong*) value, buff, 10);
1634
end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10);
1637
end= strmov(buff, *(bool*) value ? "ON" : "OFF");
1640
end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
1643
end= int10_to_str((long) *(uint32*) value, buff, 10);
1647
SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
1648
pos= show_comp_option_name[(int) tmp];
1661
if (!(pos= *(char**) value))
1666
case SHOW_KEY_CACHE_LONG:
1667
value= (char*) dflt_key_cache + (ulong)value;
1668
end= int10_to_str(*(long*) value, buff, 10);
1670
case SHOW_KEY_CACHE_LONGLONG:
1671
value= (char*) dflt_key_cache + (ulong)value;
1672
end= longlong10_to_str(*(longlong*) value, buff, 10);
1675
break; // Return empty string
1676
case SHOW_SYS: // Cannot happen
1681
restore_record(table, s->default_values);
1682
table->field[0]->store(name_buffer, strlen(name_buffer),
1683
system_charset_info);
1684
table->field[1]->store(pos, (uint32) (end - pos), system_charset_info);
1685
table->field[1]->set_notnull();
1687
pthread_mutex_unlock(&LOCK_global_system_variables);
1689
if (schema_table_store_record(thd, table))
1699
/* collect status for all running threads */
1701
void calc_sum_of_all_status(STATUS_VAR *to)
1703
DBUG_ENTER("calc_sum_of_all_status");
1705
/* Ensure that thread id not killed during loop */
1706
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
1708
I_List_iterator<THD> it(threads);
1711
/* Get global values as base */
1712
*to= global_status_var;
1714
/* Add to this status from existing threads */
1716
add_to_status(to, &tmp->status_var);
1718
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1723
/* This is only used internally, but we need it here as a forward reference */
1724
extern ST_SCHEMA_TABLE schema_tables[];
1726
typedef struct st_lookup_field_values
1728
LEX_STRING db_value, table_value;
1729
bool wild_db_value, wild_table_value;
1730
} LOOKUP_FIELD_VALUES;
1734
Store record to I_S table, convert HEAP table
1735
to MyISAM if necessary
1738
schema_table_store_record()
1740
table Information schema table to be updated
1747
bool schema_table_store_record(THD *thd, TABLE *table)
1750
if ((error= table->file->ha_write_row(table->record[0])))
1752
TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
1754
if (create_myisam_from_heap(thd, table, param->start_recinfo,
1755
¶m->recinfo, error, 0))
1762
int make_table_list(THD *thd, SELECT_LEX *sel,
1763
LEX_STRING *db_name, LEX_STRING *table_name)
1765
Table_ident *table_ident;
1766
table_ident= new Table_ident(thd, *db_name, *table_name, 1);
1768
if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
1775
@brief Get lookup value from the part of 'WHERE' condition
1777
@details This function gets lookup value from
1778
the part of 'WHERE' condition if it's possible and
1779
fill appropriate lookup_field_vals struct field
1782
@param[in] thd thread handler
1783
@param[in] item_func part of WHERE condition
1784
@param[in] table I_S table
1785
@param[in, out] lookup_field_vals Struct which holds lookup values
1789
1 error, there can be no matching records for the condition
1792
bool get_lookup_value(THD *thd, Item_func *item_func,
1794
LOOKUP_FIELD_VALUES *lookup_field_vals)
1796
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1797
ST_FIELD_INFO *field_info= schema_table->fields_info;
1798
const char *field_name1= schema_table->idx_field1 >= 0 ?
1799
field_info[schema_table->idx_field1].field_name : "";
1800
const char *field_name2= schema_table->idx_field2 >= 0 ?
1801
field_info[schema_table->idx_field2].field_name : "";
1803
if (item_func->functype() == Item_func::EQ_FUNC ||
1804
item_func->functype() == Item_func::EQUAL_FUNC)
1806
int idx_field, idx_val;
1807
char tmp[MAX_FIELD_WIDTH];
1808
String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
1809
Item_field *item_field;
1810
CHARSET_INFO *cs= system_charset_info;
1812
if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
1813
item_func->arguments()[1]->const_item())
1818
else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
1819
item_func->arguments()[0]->const_item())
1827
item_field= (Item_field*) item_func->arguments()[idx_field];
1828
if (table->table != item_field->field->table)
1830
tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
1832
/* impossible value */
1836
/* Lookup value is database name */
1837
if (!cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
1838
(uchar *) item_field->field_name,
1839
strlen(item_field->field_name), 0))
1841
thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
1842
tmp_str->length(), FALSE);
1844
/* Lookup value is table name */
1845
else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2,
1846
strlen(field_name2),
1847
(uchar *) item_field->field_name,
1848
strlen(item_field->field_name), 0))
1850
thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
1851
tmp_str->length(), FALSE);
1859
@brief Calculates lookup values from 'WHERE' condition
1861
@details This function calculates lookup value(database name, table name)
1862
from 'WHERE' condition if it's possible and
1863
fill lookup_field_vals struct fields with these values.
1865
@param[in] thd thread handler
1866
@param[in] cond WHERE condition
1867
@param[in] table I_S table
1868
@param[in, out] lookup_field_vals Struct which holds lookup values
1872
1 error, there can be no matching records for the condition
1875
bool calc_lookup_values_from_cond(THD *thd, COND *cond, TABLE_LIST *table,
1876
LOOKUP_FIELD_VALUES *lookup_field_vals)
1881
if (cond->type() == Item::COND_ITEM)
1883
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1885
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1887
while ((item= li++))
1889
if (item->type() == Item::FUNC_ITEM)
1891
if (get_lookup_value(thd, (Item_func*)item, table, lookup_field_vals))
1896
if (calc_lookup_values_from_cond(thd, item, table, lookup_field_vals))
1903
else if (cond->type() == Item::FUNC_ITEM &&
1904
get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals))
1910
bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
1912
if (item->type() == Item::FUNC_ITEM)
1914
Item_func *item_func= (Item_func*)item;
1915
for (uint i=0; i<item_func->argument_count(); i++)
1917
if (!uses_only_table_name_fields(item_func->arguments()[i], table))
1921
else if (item->type() == Item::FIELD_ITEM)
1923
Item_field *item_field= (Item_field*)item;
1924
CHARSET_INFO *cs= system_charset_info;
1925
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1926
ST_FIELD_INFO *field_info= schema_table->fields_info;
1927
const char *field_name1= schema_table->idx_field1 >= 0 ?
1928
field_info[schema_table->idx_field1].field_name : "";
1929
const char *field_name2= schema_table->idx_field2 >= 0 ?
1930
field_info[schema_table->idx_field2].field_name : "";
1931
if (table->table != item_field->field->table ||
1932
(cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
1933
(uchar *) item_field->field_name,
1934
strlen(item_field->field_name), 0) &&
1935
cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2),
1936
(uchar *) item_field->field_name,
1937
strlen(item_field->field_name), 0)))
1940
else if (item->type() == Item::REF_ITEM)
1941
return uses_only_table_name_fields(item->real_item(), table);
1943
if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
1950
static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
1954
if (cond->type() == Item::COND_ITEM)
1956
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1958
/* Create new top level AND item */
1959
Item_cond_and *new_cond=new Item_cond_and;
1962
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1966
Item *fix= make_cond_for_info_schema(item, table);
1968
new_cond->argument_list()->push_back(fix);
1970
switch (new_cond->argument_list()->elements) {
1974
return new_cond->argument_list()->head();
1976
new_cond->quick_fix_field();
1982
Item_cond_or *new_cond=new Item_cond_or;
1985
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1989
Item *fix=make_cond_for_info_schema(item, table);
1992
new_cond->argument_list()->push_back(fix);
1994
new_cond->quick_fix_field();
1995
new_cond->top_level_item();
2000
if (!uses_only_table_name_fields(cond, table))
2007
@brief Calculate lookup values(database name, table name)
2009
@details This function calculates lookup values(database name, table name)
2010
from 'WHERE' condition or wild values (for 'SHOW' commands only)
2011
from LEX struct and fill lookup_field_vals struct field
2014
@param[in] thd thread handler
2015
@param[in] cond WHERE condition
2016
@param[in] tables I_S table
2017
@param[in, out] lookup_field_values Struct which holds lookup values
2021
1 error, there can be no matching records for the condition
2024
bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables,
2025
LOOKUP_FIELD_VALUES *lookup_field_values)
2028
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
2029
bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES));
2030
switch (lex->sql_command) {
2031
case SQLCOM_SHOW_DATABASES:
2034
lookup_field_values->db_value.str= (char*) wild;
2035
lookup_field_values->db_value.length= strlen(wild);
2036
lookup_field_values->wild_db_value= 1;
2039
case SQLCOM_SHOW_TABLES:
2040
case SQLCOM_SHOW_TABLE_STATUS:
2041
lookup_field_values->db_value.str= lex->select_lex.db;
2042
lookup_field_values->db_value.length=strlen(lex->select_lex.db);
2045
lookup_field_values->table_value.str= (char*)wild;
2046
lookup_field_values->table_value.length= strlen(wild);
2047
lookup_field_values->wild_table_value= 1;
2052
The "default" is for queries over I_S.
2053
All previous cases handle SHOW commands.
2055
return calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
2060
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
2062
return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
2067
Create db names list. Information schema name always is first in list
2072
files list of db names
2074
idx_field_vals idx_field_vals->db_name contains db name or
2076
with_i_schema returns 1 if we added 'IS' name to list
2084
int make_db_list(THD *thd, List<LEX_STRING> *files,
2085
LOOKUP_FIELD_VALUES *lookup_field_vals,
2086
bool *with_i_schema)
2088
LEX_STRING *i_s_name_copy= 0;
2089
i_s_name_copy= thd->make_lex_string(i_s_name_copy,
2090
INFORMATION_SCHEMA_NAME.str,
2091
INFORMATION_SCHEMA_NAME.length, TRUE);
2093
if (lookup_field_vals->wild_db_value)
2096
This part of code is only for SHOW DATABASES command.
2097
idx_field_vals->db_value can be 0 when we don't use
2098
LIKE clause (see also get_index_field_values() function)
2100
if (!lookup_field_vals->db_value.str ||
2101
!wild_case_compare(system_charset_info,
2102
INFORMATION_SCHEMA_NAME.str,
2103
lookup_field_vals->db_value.str))
2106
if (files->push_back(i_s_name_copy))
2109
return (find_files(thd, files, NullS, mysql_data_home,
2110
lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
2115
If we have db lookup vaule we just add it to list and
2116
exit from the function
2118
if (lookup_field_vals->db_value.str)
2120
if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
2121
lookup_field_vals->db_value.str))
2124
if (files->push_back(i_s_name_copy))
2128
if (files->push_back(&lookup_field_vals->db_value))
2134
Create list of existing databases. It is used in case
2135
of select from information schema table
2137
if (files->push_back(i_s_name_copy))
2140
return (find_files(thd, files, NullS,
2141
mysql_data_home, NullS, 1) != FIND_FILES_OK);
2145
struct st_add_schema_table
2147
List<LEX_STRING> *files;
2152
static my_bool add_schema_table(THD *thd, plugin_ref plugin,
2155
LEX_STRING *file_name= 0;
2156
st_add_schema_table *data= (st_add_schema_table *)p_data;
2157
List<LEX_STRING> *file_list= data->files;
2158
const char *wild= data->wild;
2159
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
2160
DBUG_ENTER("add_schema_table");
2162
if (schema_table->hidden)
2166
if (lower_case_table_names)
2168
if (wild_case_compare(files_charset_info,
2169
schema_table->table_name,
2173
else if (wild_compare(schema_table->table_name, wild, 0))
2177
if ((file_name= thd->make_lex_string(file_name, schema_table->table_name,
2178
strlen(schema_table->table_name),
2180
!file_list->push_back(file_name))
2186
int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
2188
LEX_STRING *file_name= 0;
2189
ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
2190
st_add_schema_table add_data;
2191
DBUG_ENTER("schema_tables_add");
2193
for (; tmp_schema_table->table_name; tmp_schema_table++)
2195
if (tmp_schema_table->hidden)
2199
if (lower_case_table_names)
2201
if (wild_case_compare(files_charset_info,
2202
tmp_schema_table->table_name,
2206
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2210
thd->make_lex_string(file_name, tmp_schema_table->table_name,
2211
strlen(tmp_schema_table->table_name), TRUE)) &&
2212
!files->push_back(file_name))
2217
add_data.files= files;
2218
add_data.wild= wild;
2219
if (plugin_foreach(thd, add_schema_table,
2220
MYSQL_INFORMATION_SCHEMA_PLUGIN, &add_data))
2228
@brief Create table names list
2230
@details The function creates the list of table names in
2233
@param[in] thd thread handler
2234
@param[in] table_names List of table names in database
2235
@param[in] lex pointer to LEX struct
2236
@param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
2237
@param[in] with_i_schema TRUE means that we add I_S tables to list
2238
@param[in] db_name database name
2240
@return Operation status
2242
@retval 1 fatal error
2243
@retval 2 Not fatal error; Safe to ignore this file list
2247
make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
2248
LOOKUP_FIELD_VALUES *lookup_field_vals,
2249
bool with_i_schema, LEX_STRING *db_name)
2251
char path[FN_REFLEN];
2252
build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
2253
if (!lookup_field_vals->wild_table_value &&
2254
lookup_field_vals->table_value.str)
2258
if (find_schema_table(thd, lookup_field_vals->table_value.str))
2260
if (table_names->push_back(&lookup_field_vals->table_value))
2266
if (table_names->push_back(&lookup_field_vals->table_value))
2273
This call will add all matching the wildcards (if specified) IS tables
2277
return (schema_tables_add(thd, table_names,
2278
lookup_field_vals->table_value.str));
2280
find_files_result res= find_files(thd, table_names, db_name->str, path,
2281
lookup_field_vals->table_value.str, 0);
2282
if (res != FIND_FILES_OK)
2285
Downgrade errors about problems with database directory to
2286
warnings if this is not a 'SHOW' command. Another thread
2287
may have dropped database, and we may still have a name
2290
if (res == FIND_FILES_DIR)
2292
if (lex->sql_command != SQLCOM_SELECT)
2304
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
2306
@param[in] thd thread handler
2307
@param[in] tables TABLE_LIST for I_S table
2308
@param[in] schema_table pointer to I_S structure
2309
@param[in] open_tables_state_backup pointer to Open_tables_state object
2310
which is used to save|restore original
2311
status of variables related to
2314
@return Operation status
2320
fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
2321
ST_SCHEMA_TABLE *schema_table,
2322
Open_tables_state *open_tables_state_backup)
2326
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
2327
enum_sql_command save_sql_command= lex->sql_command;
2328
TABLE_LIST *show_table_list= (TABLE_LIST*) tables->schema_select_lex->
2330
TABLE *table= tables->table;
2332
DBUG_ENTER("fill_schema_show");
2334
lex->all_selects_list= tables->schema_select_lex;
2336
Restore thd->temporary_tables to be able to process
2337
temporary tables(only for 'show index' & 'show columns').
2338
This should be changed when processing of temporary tables for
2339
I_S tables will be done.
2341
thd->temporary_tables= open_tables_state_backup->temporary_tables;
2343
Let us set fake sql_command so views won't try to merge
2344
themselves into main statement. If we don't do this,
2345
SELECT * from information_schema.xxxx will cause problems.
2346
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
2348
lex->sql_command= SQLCOM_SHOW_FIELDS;
2349
res= open_normal_and_derived_tables(thd, show_table_list,
2350
MYSQL_LOCK_IGNORE_FLUSH);
2351
lex->sql_command= save_sql_command;
2353
get_all_tables() returns 1 on failure and 0 on success thus
2354
return only these and not the result code of ::process_table()
2356
We should use show_table_list->alias instead of
2357
show_table_list->table_name because table_name
2358
could be changed during opening of I_S tables. It's safe
2359
to use alias because alias contains original table name
2360
in this case(this part of code is used only for
2361
'show columns' & 'show statistics' commands).
2363
table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
2364
strlen(show_table_list->alias), FALSE);
2365
db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db,
2366
show_table_list->db_length, FALSE);
2369
error= test(schema_table->process_table(thd, show_table_list,
2370
table, res, db_name,
2372
thd->temporary_tables= 0;
2373
close_tables_for_reopen(thd, &show_table_list);
2379
@brief Fill I_S table for SHOW TABLE NAMES commands
2381
@param[in] thd thread handler
2382
@param[in] table TABLE struct for I_S table
2383
@param[in] db_name database name
2384
@param[in] table_name table name
2385
@param[in] with_i_schema I_S table if TRUE
2387
@return Operation status
2392
static int fill_schema_table_names(THD *thd, TABLE *table,
2393
LEX_STRING *db_name, LEX_STRING *table_name,
2398
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
2399
system_charset_info);
2403
enum legacy_db_type not_used;
2404
char path[FN_REFLEN];
2405
(void) build_table_filename(path, sizeof(path), db_name->str,
2406
table_name->str, reg_ext, 0);
2407
switch (mysql_frm_type(thd, path, ¬_used)) {
2409
table->field[3]->store(STRING_WITH_LEN("ERROR"),
2410
system_charset_info);
2413
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"),
2414
system_charset_info);
2419
if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2425
if (schema_table_store_record(thd, table))
2432
@brief Get open table method
2434
@details The function calculates the method which will be used
2436
SKIP_OPEN_TABLE - do not open table
2437
OPEN_FRM_ONLY - open FRM file only
2438
OPEN_FULL_TABLE - open FRM, data, index files
2439
@param[in] tables I_S table table_list
2440
@param[in] schema_table I_S table struct
2441
@param[in] schema_table_idx I_S table index
2443
@return return a set of flags
2444
@retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
2447
static uint get_table_open_method(TABLE_LIST *tables,
2448
ST_SCHEMA_TABLE *schema_table,
2449
enum enum_schema_tables schema_table_idx)
2452
determine which method will be used for table opening
2454
if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
2456
Field **ptr, *field;
2457
int table_open_method= 0, field_indx= 0;
2458
for (ptr=tables->table->field; (field= *ptr) ; ptr++)
2460
if (bitmap_is_set(tables->table->read_set, field->field_index))
2461
table_open_method|= schema_table->fields_info[field_indx].open_method;
2464
return table_open_method;
2466
/* I_S tables which use get_all_tables but can not be optimized */
2467
return (uint) OPEN_FULL_TABLE;
2472
@brief Fill I_S table with data from FRM file only
2474
@param[in] thd thread handler
2475
@param[in] table TABLE struct for I_S table
2476
@param[in] schema_table I_S table struct
2477
@param[in] db_name database name
2478
@param[in] table_name table name
2479
@param[in] schema_table_idx I_S table index
2481
@return Operation status
2482
@retval 0 Table is processed and we can continue
2484
@retval 1 It's view and we have to use
2485
open_tables function for this table
2488
static int fill_schema_table_from_frm(THD *thd,TABLE_LIST *tables,
2489
ST_SCHEMA_TABLE *schema_table,
2490
LEX_STRING *db_name,
2491
LEX_STRING *table_name,
2492
enum enum_schema_tables schema_table_idx)
2494
TABLE *table= tables->table;
2497
TABLE_LIST table_list;
2500
char key[MAX_DBKEY_LENGTH];
2503
bzero((char*) &table_list, sizeof(TABLE_LIST));
2504
bzero((char*) &tbl, sizeof(TABLE));
2506
table_list.table_name= table_name->str;
2507
table_list.db= db_name->str;
2509
key_length= create_table_def_key(thd, key, &table_list, 0);
2510
pthread_mutex_lock(&LOCK_open);
2511
share= get_table_share(thd, &table_list, key,
2512
key_length, OPEN_VIEW, &error);
2521
table_list.table= &tbl;
2522
res= schema_table->process_table(thd, &table_list, table,
2523
res, db_name, table_name);
2526
release_table_share(share, RELEASE_NORMAL);
2529
pthread_mutex_unlock(&LOCK_open);
2537
@brief Fill I_S tables whose data are retrieved
2538
from frm files and storage engine
2540
@details The information schema tables are internally represented as
2541
temporary tables that are filled at query execution time.
2542
Those I_S tables whose data are retrieved
2543
from frm files and storage engine are filled by the function
2546
@param[in] thd thread handler
2547
@param[in] tables I_S table
2548
@param[in] cond 'WHERE' condition
2550
@return Operation status
2555
int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
2558
TABLE *table= tables->table;
2559
SELECT_LEX *old_all_select_lex= lex->all_selects_list;
2560
enum_sql_command save_sql_command= lex->sql_command;
2561
SELECT_LEX *lsel= tables->schema_select_lex;
2562
ST_SCHEMA_TABLE *schema_table= tables->schema_table;
2564
LOOKUP_FIELD_VALUES lookup_field_vals;
2565
LEX_STRING *db_name, *table_name;
2567
enum enum_schema_tables schema_table_idx;
2568
List<LEX_STRING> db_names;
2569
List_iterator_fast<LEX_STRING> it(db_names);
2570
COND *partial_cond= 0;
2571
uint derived_tables= lex->derived_tables;
2573
Open_tables_state open_tables_state_backup;
2574
Query_tables_list query_tables_list_backup;
2575
uint table_open_method;
2576
bool old_value= thd->no_warnings_for_error;
2577
DBUG_ENTER("get_all_tables");
2579
lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
2582
We should not introduce deadlocks even if we already have some
2583
tables open and locked, since we won't lock tables which we will
2584
open and will ignore possible name-locks for these tables.
2586
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
2588
schema_table_idx= get_schema_table_idx(schema_table);
2589
tables->table_open_method= table_open_method=
2590
get_table_open_method(tables, schema_table, schema_table_idx);
2591
DBUG_PRINT("open_method", ("%d", tables->table_open_method));
2593
this branch processes SHOW FIELDS, SHOW INDEXES commands.
2594
see sql_parse.cc, prepare_schema_table() function where
2595
this values are initialized
2597
if (lsel && lsel->table_list.first)
2599
error= fill_schema_show_cols_or_idxs(thd, tables, schema_table,
2600
&open_tables_state_backup);
2604
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2609
DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
2610
STR_OR_NIL(lookup_field_vals.db_value.str),
2611
STR_OR_NIL(lookup_field_vals.table_value.str)));
2613
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
2616
if lookup value is empty string then
2617
it's impossible table name or db name
2619
if (lookup_field_vals.db_value.str &&
2620
!lookup_field_vals.db_value.str[0] ||
2621
lookup_field_vals.table_value.str &&
2622
!lookup_field_vals.table_value.str[0])
2629
if (lookup_field_vals.db_value.length &&
2630
!lookup_field_vals.wild_db_value)
2631
tables->has_db_lookup_value= TRUE;
2632
if (lookup_field_vals.table_value.length &&
2633
!lookup_field_vals.wild_table_value)
2634
tables->has_table_lookup_value= TRUE;
2636
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
2639
partial_cond= make_cond_for_info_schema(cond, tables);
2643
/* EXPLAIN SELECT */
2648
if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
2650
it.rewind(); /* To get access to new elements in basis list */
2651
while ((db_name= it++))
2654
thd->no_warnings_for_error= 1;
2655
List<LEX_STRING> table_names;
2656
int res= make_table_name_list(thd, &table_names, lex,
2658
with_i_schema, db_name);
2659
if (res == 2) /* Not fatal error, continue */
2664
List_iterator_fast<LEX_STRING> it_files(table_names);
2665
while ((table_name= it_files++))
2667
restore_record(table, s->default_values);
2668
table->field[schema_table->idx_field1]->
2669
store(db_name->str, db_name->length, system_charset_info);
2670
table->field[schema_table->idx_field2]->
2671
store(table_name->str, table_name->length, system_charset_info);
2673
if (!partial_cond || partial_cond->val_int())
2676
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
2677
we can skip table opening and we don't have lookup value for
2678
table name or lookup value is wild string(table name list is
2679
already created by make_table_name_list() function).
2681
if (!table_open_method && schema_table_idx == SCH_TABLES &&
2682
(!lookup_field_vals.table_value.length ||
2683
lookup_field_vals.wild_table_value))
2685
if (schema_table_store_record(thd, table))
2686
goto err; /* Out of space in temporary table */
2690
/* SHOW TABLE NAMES command */
2691
if (schema_table_idx == SCH_TABLE_NAMES)
2693
if (fill_schema_table_names(thd, tables->table, db_name,
2694
table_name, with_i_schema))
2699
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
2702
if (!fill_schema_table_from_frm(thd, tables, schema_table, db_name,
2703
table_name, schema_table_idx))
2708
LEX_STRING tmp_lex_string, orig_db_name;
2710
Set the parent lex of 'sel' because it is needed by
2711
sel.init_query() which is called inside make_table_list.
2713
thd->no_warnings_for_error= 1;
2714
sel.parent_lex= lex;
2715
/* db_name can be changed in make_table_list() func */
2716
if (!thd->make_lex_string(&orig_db_name, db_name->str,
2717
db_name->length, FALSE))
2719
if (make_table_list(thd, &sel, db_name, table_name))
2721
TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first;
2722
lex->all_selects_list= &sel;
2723
lex->derived_tables= 0;
2724
lex->sql_command= SQLCOM_SHOW_FIELDS;
2725
show_table_list->i_s_requested_object=
2726
schema_table->i_s_requested_object;
2727
res= open_normal_and_derived_tables(thd, show_table_list,
2728
MYSQL_LOCK_IGNORE_FLUSH);
2729
lex->sql_command= save_sql_command;
2731
XXX: show_table_list has a flag i_is_requested,
2732
and when it's set, open_normal_and_derived_tables()
2733
can return an error without setting an error message
2734
in THD, which is a hack. This is why we have to
2735
check for res, then for thd->is_error() only then
2736
for thd->main_da.sql_errno().
2738
if (res && thd->is_error() &&
2739
thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2742
Hide error for not existing table.
2743
This error can occur for example when we use
2744
where condition with db name and table name and this
2745
table does not exist.
2753
We should use show_table_list->alias instead of
2754
show_table_list->table_name because table_name
2755
could be changed during opening of I_S tables. It's safe
2756
to use alias because alias contains original table name
2759
thd->make_lex_string(&tmp_lex_string, show_table_list->alias,
2760
strlen(show_table_list->alias), FALSE);
2761
res= schema_table->process_table(thd, show_table_list, table,
2764
close_tables_for_reopen(thd, &show_table_list);
2766
DBUG_ASSERT(!lex->query_tables_own_last);
2773
If we have information schema its always the first table and only
2774
the first table. Reset for other tables.
2782
thd->restore_backup_open_tables_state(&open_tables_state_backup);
2783
lex->restore_backup_query_tables_list(&query_tables_list_backup);
2784
lex->derived_tables= derived_tables;
2785
lex->all_selects_list= old_all_select_lex;
2786
lex->sql_command= save_sql_command;
2787
thd->no_warnings_for_error= old_value;
2792
bool store_schema_shemata(THD* thd, TABLE *table, LEX_STRING *db_name,
2795
restore_record(table, s->default_values);
2796
table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2797
table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2798
table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2799
return schema_table_store_record(thd, table);
2803
int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
2806
TODO: fill_schema_shemata() is called when new client is connected.
2807
Returning error status in this case leads to client hangup.
2810
LOOKUP_FIELD_VALUES lookup_field_vals;
2811
List<LEX_STRING> db_names;
2812
LEX_STRING *db_name;
2814
HA_CREATE_INFO create;
2815
TABLE *table= tables->table;
2816
DBUG_ENTER("fill_schema_shemata");
2818
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2820
DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
2821
lookup_field_vals.db_value.str,
2822
lookup_field_vals.table_value.str));
2823
if (make_db_list(thd, &db_names, &lookup_field_vals,
2828
If we have lookup db value we should check that the database exists
2830
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
2833
char path[FN_REFLEN+16];
2836
if (!lookup_field_vals.db_value.str[0])
2838
path_len= build_table_filename(path, sizeof(path),
2839
lookup_field_vals.db_value.str, "", "", 0);
2840
path[path_len-1]= 0;
2841
if (!my_stat(path,&stat_info,MYF(0)))
2845
List_iterator_fast<LEX_STRING> it(db_names);
2846
while ((db_name=it++))
2848
if (with_i_schema) // information schema name is always first in list
2850
if (store_schema_shemata(thd, table, db_name,
2851
system_charset_info))
2857
load_db_opt_by_name(thd, db_name->str, &create);
2858
if (store_schema_shemata(thd, table, db_name,
2859
create.default_table_charset))
2867
static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
2868
TABLE *table, bool res,
2869
LEX_STRING *db_name,
2870
LEX_STRING *table_name)
2872
const char *tmp_buff;
2874
CHARSET_INFO *cs= system_charset_info;
2875
DBUG_ENTER("get_schema_tables_record");
2877
restore_record(table, s->default_values);
2878
table->field[1]->store(db_name->str, db_name->length, cs);
2879
table->field[2]->store(table_name->str, table_name->length, cs);
2883
there was errors during opening tables
2885
const char *error= thd->is_error() ? thd->main_da.message() : "";
2886
if (tables->schema_table)
2887
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2889
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
2890
table->field[20]->store(error, strlen(error), cs);
2895
char option_buff[350],*ptr;
2896
TABLE *show_table= tables->table;
2897
TABLE_SHARE *share= show_table->s;
2898
handler *file= show_table->file;
2899
handlerton *tmp_db_type= share->db_type();
2900
if (share->tmp_table == SYSTEM_TMP_TABLE)
2901
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2902
else if (share->tmp_table)
2903
table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
2905
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
2907
for (int i= 4; i < 20; i++)
2909
if (i == 7 || (i > 12 && i < 17) || i == 18)
2911
table->field[i]->set_notnull();
2913
tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
2914
table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
2915
table->field[5]->store((longlong) share->frm_version, TRUE);
2918
if (share->min_rows)
2920
ptr=strmov(ptr," min_rows=");
2921
ptr=longlong10_to_str(share->min_rows,ptr,10);
2923
if (share->max_rows)
2925
ptr=strmov(ptr," max_rows=");
2926
ptr=longlong10_to_str(share->max_rows,ptr,10);
2928
if (share->avg_row_length)
2930
ptr=strmov(ptr," avg_row_length=");
2931
ptr=longlong10_to_str(share->avg_row_length,ptr,10);
2933
if (share->db_create_options & HA_OPTION_PACK_KEYS)
2934
ptr=strmov(ptr," pack_keys=1");
2935
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
2936
ptr=strmov(ptr," pack_keys=0");
2937
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2938
if (share->db_create_options & HA_OPTION_CHECKSUM)
2939
ptr=strmov(ptr," checksum=1");
2940
if (share->page_checksum != HA_CHOICE_UNDEF)
2941
ptr= strxmov(ptr, " page_checksum=",
2942
ha_choice_values[(uint) share->page_checksum], NullS);
2943
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
2944
ptr=strmov(ptr," delay_key_write=1");
2945
if (share->row_type != ROW_TYPE_DEFAULT)
2946
ptr=strxmov(ptr, " row_format=",
2947
ha_row_type[(uint) share->row_type],
2949
if (share->transactional != HA_CHOICE_UNDEF)
2951
ptr= strxmov(ptr, " TRANSACTIONAL=",
2952
(share->transactional == HA_CHOICE_YES ? "1" : "0"),
2955
if (share->transactional != HA_CHOICE_UNDEF)
2956
ptr= strxmov(ptr, " transactional=",
2957
ha_choice_values[(uint) share->transactional], NullS);
2958
table->field[19]->store(option_buff+1,
2959
(ptr == option_buff ? 0 :
2960
(uint) (ptr-option_buff)-1), cs);
2962
tmp_buff= (share->table_charset ?
2963
share->table_charset->name : "default");
2964
table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
2966
if (share->comment.str)
2967
table->field[20]->store(share->comment.str, share->comment.length, cs);
2971
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
2973
enum row_type row_type = file->get_row_type();
2975
case ROW_TYPE_NOT_USED:
2976
case ROW_TYPE_DEFAULT:
2977
tmp_buff= ((share->db_options_in_use &
2978
HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
2979
(share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
2980
"Dynamic" : "Fixed");
2982
case ROW_TYPE_FIXED:
2985
case ROW_TYPE_DYNAMIC:
2986
tmp_buff= "Dynamic";
2988
case ROW_TYPE_COMPRESSED:
2989
tmp_buff= "Compressed";
2991
case ROW_TYPE_REDUNDANT:
2992
tmp_buff= "Redundant";
2994
case ROW_TYPE_COMPACT:
2995
tmp_buff= "Compact";
3001
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
3002
if (!tables->schema_table)
3004
table->field[7]->store((longlong) file->stats.records, TRUE);
3005
table->field[7]->set_notnull();
3007
table->field[8]->store((longlong) file->stats.mean_rec_length, TRUE);
3008
table->field[9]->store((longlong) file->stats.data_file_length, TRUE);
3009
if (file->stats.max_data_file_length)
3011
table->field[10]->store((longlong) file->stats.max_data_file_length,
3014
table->field[11]->store((longlong) file->stats.index_file_length, TRUE);
3015
table->field[12]->store((longlong) file->stats.delete_length, TRUE);
3016
if (show_table->found_next_number_field)
3018
table->field[13]->store((longlong) file->stats.auto_increment_value,
3020
table->field[13]->set_notnull();
3022
if (file->stats.create_time)
3024
thd->variables.time_zone->gmt_sec_to_TIME(&time,
3025
(my_time_t) file->stats.create_time);
3026
table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
3027
table->field[14]->set_notnull();
3029
if (file->stats.update_time)
3031
thd->variables.time_zone->gmt_sec_to_TIME(&time,
3032
(my_time_t) file->stats.update_time);
3033
table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
3034
table->field[15]->set_notnull();
3036
if (file->stats.check_time)
3038
thd->variables.time_zone->gmt_sec_to_TIME(&time,
3039
(my_time_t) file->stats.check_time);
3040
table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
3041
table->field[16]->set_notnull();
3043
if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
3045
table->field[18]->store((longlong) file->checksum(), TRUE);
3046
table->field[18]->set_notnull();
3050
DBUG_RETURN(schema_table_store_record(thd, table));
3055
@brief Store field characteristics into appropriate I_S table columns
3057
@param[in] table I_S table
3058
@param[in] field processed field
3059
@param[in] cs I_S table charset
3060
@param[in] offset offset from beginning of table
3061
to DATE_TYPE column in I_S table
3066
void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs,
3070
int decimals, field_length;
3071
const char *tmp_buff;
3072
char column_type_buff[MAX_FIELD_WIDTH];
3073
String column_type(column_type_buff, sizeof(column_type_buff), cs);
3075
field->sql_type(column_type);
3076
/* DTD_IDENTIFIER column */
3077
table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs);
3078
table->field[offset + 7]->set_notnull();
3079
tmp_buff= strchr(column_type.ptr(), '(');
3080
/* DATA_TYPE column */
3081
table->field[offset]->store(column_type.ptr(),
3082
(tmp_buff ? tmp_buff - column_type.ptr() :
3083
column_type.length()), cs);
3084
is_blob= (field->type() == MYSQL_TYPE_BLOB);
3085
if (field->has_charset() || is_blob ||
3086
field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type
3087
field->real_type() == MYSQL_TYPE_STRING) // For binary type
3089
uint32 octet_max_length= field->max_display_length();
3090
if (is_blob && octet_max_length != (uint32) 4294967295U)
3091
octet_max_length /= field->charset()->mbmaxlen;
3092
longlong char_max_len= is_blob ?
3093
(longlong) octet_max_length / field->charset()->mbminlen :
3094
(longlong) octet_max_length / field->charset()->mbmaxlen;
3095
/* CHARACTER_MAXIMUM_LENGTH column*/
3096
table->field[offset + 1]->store(char_max_len, TRUE);
3097
table->field[offset + 1]->set_notnull();
3098
/* CHARACTER_OCTET_LENGTH column */
3099
table->field[offset + 2]->store((longlong) octet_max_length, TRUE);
3100
table->field[offset + 2]->set_notnull();
3104
Calculate field_length and decimals.
3105
They are set to -1 if they should not be set (we should return NULL)
3108
decimals= field->decimals();
3109
switch (field->type()) {
3110
case MYSQL_TYPE_NEWDECIMAL:
3111
field_length= ((Field_new_decimal*) field)->precision;
3113
case MYSQL_TYPE_DECIMAL:
3114
field_length= field->field_length - (decimals ? 2 : 1);
3116
case MYSQL_TYPE_TINY:
3117
case MYSQL_TYPE_SHORT:
3118
case MYSQL_TYPE_LONG:
3119
case MYSQL_TYPE_LONGLONG:
3120
case MYSQL_TYPE_INT24:
3121
field_length= field->max_display_length() - 1;
3123
case MYSQL_TYPE_BIT:
3124
field_length= field->max_display_length();
3125
decimals= -1; // return NULL
3127
case MYSQL_TYPE_FLOAT:
3128
case MYSQL_TYPE_DOUBLE:
3129
field_length= field->field_length;
3130
if (decimals == NOT_FIXED_DEC)
3131
decimals= -1; // return NULL
3134
field_length= decimals= -1;
3138
/* NUMERIC_PRECISION column */
3139
if (field_length >= 0)
3141
table->field[offset + 3]->store((longlong) field_length, TRUE);
3142
table->field[offset + 3]->set_notnull();
3144
/* NUMERIC_SCALE column */
3147
table->field[offset + 4]->store((longlong) decimals, TRUE);
3148
table->field[offset + 4]->set_notnull();
3150
if (field->has_charset())
3152
/* CHARACTER_SET_NAME column*/
3153
tmp_buff= field->charset()->csname;
3154
table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs);
3155
table->field[offset + 5]->set_notnull();
3156
/* COLLATION_NAME column */
3157
tmp_buff= field->charset()->name;
3158
table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs);
3159
table->field[offset + 6]->set_notnull();
3164
static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
3165
TABLE *table, bool res,
3166
LEX_STRING *db_name,
3167
LEX_STRING *table_name)
3170
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3171
CHARSET_INFO *cs= system_charset_info;
3173
TABLE_SHARE *show_table_share;
3174
Field **ptr, *field, *timestamp_field;
3176
DBUG_ENTER("get_schema_column_record");
3180
if (lex->sql_command != SQLCOM_SHOW_FIELDS)
3183
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
3184
rather than in SHOW COLUMNS
3186
if (thd->is_error())
3187
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3188
thd->main_da.sql_errno(), thd->main_da.message());
3195
show_table= tables->table;
3196
show_table_share= show_table->s;
3199
if (tables->schema_table)
3201
ptr= show_table->field;
3202
timestamp_field= show_table->timestamp_field;
3203
show_table->use_all_columns(); // Required for default
3207
ptr= show_table_share->field;
3208
timestamp_field= show_table_share->timestamp_field;
3210
read_set may be inited in case of
3213
if (!show_table->read_set)
3215
/* to satisfy 'field->val_str' ASSERTs */
3217
uint bitmap_size= show_table_share->column_bitmap_size;
3218
if (!(bitmaps= (uchar*) alloc_root(thd->mem_root, bitmap_size)))
3220
bitmap_init(&show_table->def_read_set,
3221
(my_bitmap_map*) bitmaps, show_table_share->fields, FALSE);
3222
bitmap_set_all(&show_table->def_read_set);
3223
show_table->read_set= &show_table->def_read_set;
3225
bitmap_set_all(show_table->read_set);
3228
for (; (field= *ptr) ; ptr++)
3231
char tmp[MAX_FIELD_WIDTH];
3232
String type(tmp,sizeof(tmp), system_charset_info);
3235
/* to satisfy 'field->val_str' ASSERTs */
3236
field->table= show_table;
3237
show_table->in_use= thd;
3239
if (wild && wild[0] &&
3240
wild_case_compare(system_charset_info, field->field_name,wild))
3244
/* Get default row, with all NULL fields set to NULL */
3245
restore_record(table, s->default_values);
3247
table->field[1]->store(db_name->str, db_name->length, cs);
3248
table->field[2]->store(table_name->str, table_name->length, cs);
3249
table->field[3]->store(field->field_name, strlen(field->field_name),
3251
table->field[4]->store((longlong) count, TRUE);
3253
if (get_field_default_value(thd, timestamp_field, field, &type, 0))
3255
table->field[5]->store(type.ptr(), type.length(), cs);
3256
table->field[5]->set_notnull();
3258
pos=(uchar*) ((field->flags & NOT_NULL_FLAG) ? "NO" : "YES");
3259
table->field[6]->store((const char*) pos,
3260
strlen((const char*) pos), cs);
3261
store_column_type(table, field, cs, 7);
3263
pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
3264
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
3265
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
3266
table->field[15]->store((const char*) pos,
3267
strlen((const char*) pos), cs);
3270
if (field->unireg_check == Field::NEXT_NUMBER)
3271
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
3272
if (timestamp_field == field &&
3273
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3274
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3277
table->field[18]->store(field->comment.str, field->comment.length, cs);
3279
enum ha_storage_media storage_type= (enum ha_storage_media)
3280
((field->flags >> FIELD_STORAGE_FLAGS) & STORAGE_TYPE_MASK);
3281
enum column_format_type column_format= (enum column_format_type)
3282
((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
3283
pos=(uchar*)(storage_type == HA_SM_DEFAULT ? "Default" :
3284
storage_type == HA_SM_DISK ? "Disk" : "Memory");
3285
table->field[19]->store((const char*) pos,
3286
strlen((const char*) pos), cs);
3287
pos=(uchar*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
3288
column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
3290
table->field[20]->store((const char*) pos,
3291
strlen((const char*) pos), cs);
3293
if (schema_table_store_record(thd, table))
3301
int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
3304
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3305
TABLE *table= tables->table;
3306
CHARSET_INFO *scs= system_charset_info;
3308
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3310
CHARSET_INFO *tmp_cs= cs[0];
3311
if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
3312
(tmp_cs->state & MY_CS_AVAILABLE) &&
3313
!(tmp_cs->state & MY_CS_HIDDEN) &&
3314
!(wild && wild[0] &&
3315
wild_case_compare(scs, tmp_cs->csname,wild)))
3317
const char *comment;
3318
restore_record(table, s->default_values);
3319
table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3320
table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3321
comment= tmp_cs->comment ? tmp_cs->comment : "";
3322
table->field[2]->store(comment, strlen(comment), scs);
3323
table->field[3]->store((longlong) tmp_cs->mbmaxlen, TRUE);
3324
if (schema_table_store_record(thd, table))
3332
int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
3335
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3336
TABLE *table= tables->table;
3337
CHARSET_INFO *scs= system_charset_info;
3338
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3341
CHARSET_INFO *tmp_cs= cs[0];
3342
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3343
(tmp_cs->state & MY_CS_HIDDEN) ||
3344
!(tmp_cs->state & MY_CS_PRIMARY))
3346
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3348
CHARSET_INFO *tmp_cl= cl[0];
3349
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3350
!my_charset_same(tmp_cs, tmp_cl))
3352
if (!(wild && wild[0] &&
3353
wild_case_compare(scs, tmp_cl->name,wild)))
3355
const char *tmp_buff;
3356
restore_record(table, s->default_values);
3357
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3358
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3359
table->field[2]->store((longlong) tmp_cl->number, TRUE);
3360
tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
3361
table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
3362
tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
3363
table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
3364
table->field[5]->store((longlong) tmp_cl->strxfrm_multiply, TRUE);
3365
if (schema_table_store_record(thd, table))
3374
int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
3377
TABLE *table= tables->table;
3378
CHARSET_INFO *scs= system_charset_info;
3379
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3382
CHARSET_INFO *tmp_cs= cs[0];
3383
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3384
!(tmp_cs->state & MY_CS_PRIMARY))
3386
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3388
CHARSET_INFO *tmp_cl= cl[0];
3389
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3390
!my_charset_same(tmp_cs,tmp_cl))
3392
restore_record(table, s->default_values);
3393
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3394
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3395
if (schema_table_store_record(thd, table))
3403
static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
3404
TABLE *table, bool res,
3405
LEX_STRING *db_name,
3406
LEX_STRING *table_name)
3408
CHARSET_INFO *cs= system_charset_info;
3409
DBUG_ENTER("get_schema_stat_record");
3412
if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
3415
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
3416
rather than in SHOW KEYS
3418
if (thd->is_error())
3419
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3420
thd->main_da.sql_errno(), thd->main_da.message());
3428
TABLE *show_table= tables->table;
3429
KEY *key_info=show_table->s->key_info;
3430
if (show_table->file)
3431
show_table->file->info(HA_STATUS_VARIABLE |
3434
for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
3436
KEY_PART_INFO *key_part= key_info->key_part;
3438
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3440
restore_record(table, s->default_values);
3441
table->field[1]->store(db_name->str, db_name->length, cs);
3442
table->field[2]->store(table_name->str, table_name->length, cs);
3443
table->field[3]->store((longlong) ((key_info->flags &
3444
HA_NOSAME) ? 0 : 1), TRUE);
3445
table->field[4]->store(db_name->str, db_name->length, cs);
3446
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
3447
table->field[6]->store((longlong) (j+1), TRUE);
3448
str=(key_part->field ? key_part->field->field_name :
3450
table->field[7]->store(str, strlen(str), cs);
3451
if (show_table->file)
3453
if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
3455
table->field[8]->store(((key_part->key_part_flag &
3458
table->field[8]->set_notnull();
3460
KEY *key=show_table->key_info+i;
3461
if (key->rec_per_key[j])
3463
ha_rows records=(show_table->file->stats.records /
3464
key->rec_per_key[j]);
3465
table->field[9]->store((longlong) records, TRUE);
3466
table->field[9]->set_notnull();
3468
str= show_table->file->index_type(i);
3469
table->field[13]->store(str, strlen(str), cs);
3471
if ((key_part->field &&
3473
show_table->s->field[key_part->fieldnr-1]->key_length()))
3475
table->field[10]->store((longlong) key_part->length /
3476
key_part->field->charset()->mbmaxlen, TRUE);
3477
table->field[10]->set_notnull();
3479
uint flags= key_part->field ? key_part->field->flags : 0;
3480
const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3481
table->field[12]->store(pos, strlen(pos), cs);
3482
if (!show_table->s->keys_in_use.is_set(i))
3483
table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3485
table->field[14]->store("", 0, cs);
3486
table->field[14]->set_notnull();
3487
DBUG_ASSERT(test(key_info->flags & HA_USES_COMMENT) ==
3488
(key_info->comment.length > 0));
3489
if (key_info->flags & HA_USES_COMMENT)
3490
table->field[15]->store(key_info->comment.str,
3491
key_info->comment.length, cs);
3492
if (schema_table_store_record(thd, table))
3501
bool store_constraints(THD *thd, TABLE *table, LEX_STRING *db_name,
3502
LEX_STRING *table_name, const char *key_name,
3503
uint key_len, const char *con_type, uint con_len)
3505
CHARSET_INFO *cs= system_charset_info;
3506
restore_record(table, s->default_values);
3507
table->field[1]->store(db_name->str, db_name->length, cs);
3508
table->field[2]->store(key_name, key_len, cs);
3509
table->field[3]->store(db_name->str, db_name->length, cs);
3510
table->field[4]->store(table_name->str, table_name->length, cs);
3511
table->field[5]->store(con_type, con_len, cs);
3512
return schema_table_store_record(thd, table);
3516
static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
3517
TABLE *table, bool res,
3518
LEX_STRING *db_name,
3519
LEX_STRING *table_name)
3521
DBUG_ENTER("get_schema_constraints_record");
3524
if (thd->is_error())
3525
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3526
thd->main_da.sql_errno(), thd->main_da.message());
3532
List<FOREIGN_KEY_INFO> f_key_list;
3533
TABLE *show_table= tables->table;
3534
KEY *key_info=show_table->key_info;
3535
uint primary_key= show_table->s->primary_key;
3536
show_table->file->info(HA_STATUS_VARIABLE |
3539
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3541
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3544
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
3546
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3547
strlen(key_info->name),
3548
STRING_WITH_LEN("PRIMARY KEY")))
3551
else if (key_info->flags & HA_NOSAME)
3553
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3554
strlen(key_info->name),
3555
STRING_WITH_LEN("UNIQUE")))
3560
show_table->file->get_foreign_key_list(thd, &f_key_list);
3561
FOREIGN_KEY_INFO *f_key_info;
3562
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3563
while ((f_key_info=it++))
3565
if (store_constraints(thd, table, db_name, table_name,
3566
f_key_info->forein_id->str,
3567
strlen(f_key_info->forein_id->str),
3576
void store_key_column_usage(TABLE *table, LEX_STRING *db_name,
3577
LEX_STRING *table_name, const char *key_name,
3578
uint key_len, const char *con_type, uint con_len,
3581
CHARSET_INFO *cs= system_charset_info;
3582
table->field[1]->store(db_name->str, db_name->length, cs);
3583
table->field[2]->store(key_name, key_len, cs);
3584
table->field[4]->store(db_name->str, db_name->length, cs);
3585
table->field[5]->store(table_name->str, table_name->length, cs);
3586
table->field[6]->store(con_type, con_len, cs);
3587
table->field[7]->store((longlong) idx, TRUE);
3591
static int get_schema_key_column_usage_record(THD *thd,
3593
TABLE *table, bool res,
3594
LEX_STRING *db_name,
3595
LEX_STRING *table_name)
3597
DBUG_ENTER("get_schema_key_column_usage_record");
3600
if (thd->is_error())
3601
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3602
thd->main_da.sql_errno(), thd->main_da.message());
3608
List<FOREIGN_KEY_INFO> f_key_list;
3609
TABLE *show_table= tables->table;
3610
KEY *key_info=show_table->key_info;
3611
uint primary_key= show_table->s->primary_key;
3612
show_table->file->info(HA_STATUS_VARIABLE |
3615
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3617
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3620
KEY_PART_INFO *key_part= key_info->key_part;
3621
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3623
if (key_part->field)
3626
restore_record(table, s->default_values);
3627
store_key_column_usage(table, db_name, table_name,
3629
strlen(key_info->name),
3630
key_part->field->field_name,
3631
strlen(key_part->field->field_name),
3633
if (schema_table_store_record(thd, table))
3639
show_table->file->get_foreign_key_list(thd, &f_key_list);
3640
FOREIGN_KEY_INFO *f_key_info;
3641
List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
3642
while ((f_key_info= fkey_it++))
3646
List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
3647
it1(f_key_info->referenced_fields);
3649
while ((f_info= it++))
3653
restore_record(table, s->default_values);
3654
store_key_column_usage(table, db_name, table_name,
3655
f_key_info->forein_id->str,
3656
f_key_info->forein_id->length,
3657
f_info->str, f_info->length,
3659
table->field[8]->store((longlong) f_idx, TRUE);
3660
table->field[8]->set_notnull();
3661
table->field[9]->store(f_key_info->referenced_db->str,
3662
f_key_info->referenced_db->length,
3663
system_charset_info);
3664
table->field[9]->set_notnull();
3665
table->field[10]->store(f_key_info->referenced_table->str,
3666
f_key_info->referenced_table->length,
3667
system_charset_info);
3668
table->field[10]->set_notnull();
3669
table->field[11]->store(r_info->str, r_info->length,
3670
system_charset_info);
3671
table->field[11]->set_notnull();
3672
if (schema_table_store_record(thd, table))
3681
int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
3683
DBUG_ENTER("fill_open_tables");
3684
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3685
TABLE *table= tables->table;
3686
CHARSET_INFO *cs= system_charset_info;
3687
OPEN_TABLE_LIST *open_list;
3688
if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
3689
&& thd->is_fatal_error)
3692
for (; open_list ; open_list=open_list->next)
3694
restore_record(table, s->default_values);
3695
table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3696
table->field[1]->store(open_list->table, strlen(open_list->table), cs);
3697
table->field[2]->store((longlong) open_list->in_use, TRUE);
3698
table->field[3]->store((longlong) open_list->locked, TRUE);
3699
if (schema_table_store_record(thd, table))
3706
int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
3708
DBUG_ENTER("fill_variables");
3711
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3712
enum enum_schema_tables schema_table_idx=
3713
get_schema_table_idx(tables->schema_table);
3714
enum enum_var_type option_type= OPT_SESSION;
3715
bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
3716
bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
3718
if (lex->option_type == OPT_GLOBAL ||
3719
schema_table_idx == SCH_GLOBAL_VARIABLES)
3720
option_type= OPT_GLOBAL;
3722
rw_rdlock(&LOCK_system_variables_hash);
3723
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
3724
option_type, NULL, "", tables->table, upper_case_names);
3725
rw_unlock(&LOCK_system_variables_hash);
3730
int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
3732
DBUG_ENTER("fill_status");
3734
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3736
STATUS_VAR *tmp1, tmp;
3737
enum enum_schema_tables schema_table_idx=
3738
get_schema_table_idx(tables->schema_table);
3739
enum enum_var_type option_type;
3740
bool upper_case_names= (schema_table_idx != SCH_STATUS);
3742
if (schema_table_idx == SCH_STATUS)
3744
option_type= lex->option_type;
3745
if (option_type == OPT_GLOBAL)
3748
tmp1= thd->initial_status_var;
3750
else if (schema_table_idx == SCH_GLOBAL_STATUS)
3752
option_type= OPT_GLOBAL;
3757
option_type= OPT_SESSION;
3758
tmp1= &thd->status_var;
3761
pthread_mutex_lock(&LOCK_status);
3762
if (option_type == OPT_GLOBAL)
3763
calc_sum_of_all_status(&tmp);
3764
res= show_status_array(thd, wild,
3765
(SHOW_VAR *)all_status_vars.buffer,
3766
option_type, tmp1, "", tables->table,
3768
pthread_mutex_unlock(&LOCK_status);
3774
Fill and store records into I_S.referential_constraints table
3777
get_referential_constraints_record()
3779
tables table list struct(processed table)
3781
res 1 means the error during opening of the processed table
3782
0 means processed table is opened without error
3784
file_name table name
3792
get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
3793
TABLE *table, bool res,
3794
LEX_STRING *db_name, LEX_STRING *table_name)
3796
CHARSET_INFO *cs= system_charset_info;
3797
DBUG_ENTER("get_referential_constraints_record");
3801
if (thd->is_error())
3802
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3803
thd->main_da.sql_errno(), thd->main_da.message());
3809
List<FOREIGN_KEY_INFO> f_key_list;
3810
TABLE *show_table= tables->table;
3811
show_table->file->info(HA_STATUS_VARIABLE |
3815
show_table->file->get_foreign_key_list(thd, &f_key_list);
3816
FOREIGN_KEY_INFO *f_key_info;
3817
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3818
while ((f_key_info= it++))
3820
restore_record(table, s->default_values);
3821
table->field[1]->store(db_name->str, db_name->length, cs);
3822
table->field[9]->store(table_name->str, table_name->length, cs);
3823
table->field[2]->store(f_key_info->forein_id->str,
3824
f_key_info->forein_id->length, cs);
3825
table->field[4]->store(f_key_info->referenced_db->str,
3826
f_key_info->referenced_db->length, cs);
3827
table->field[10]->store(f_key_info->referenced_table->str,
3828
f_key_info->referenced_table->length, cs);
3829
if (f_key_info->referenced_key_name)
3831
table->field[5]->store(f_key_info->referenced_key_name->str,
3832
f_key_info->referenced_key_name->length, cs);
3833
table->field[5]->set_notnull();
3836
table->field[5]->set_null();
3837
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3838
table->field[7]->store(f_key_info->update_method->str,
3839
f_key_info->update_method->length, cs);
3840
table->field[8]->store(f_key_info->delete_method->str,
3841
f_key_info->delete_method->length, cs);
3842
if (schema_table_store_record(thd, table))
3850
struct schema_table_ref
3852
const char *table_name;
3853
ST_SCHEMA_TABLE *schema_table;
3858
Find schema_tables elment by name
3861
find_schema_table_in_plugin()
3864
table_name table name
3868
1 found the schema table
3870
static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin,
3873
schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
3874
const char* table_name= p_schema_table->table_name;
3875
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
3876
DBUG_ENTER("find_schema_table_in_plugin");
3878
if (!my_strcasecmp(system_charset_info,
3879
schema_table->table_name,
3881
p_schema_table->schema_table= schema_table;
3890
Find schema_tables elment by name
3895
table_name table name
3899
# pointer to 'schema_tables' element
3902
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
3904
schema_table_ref schema_table_a;
3905
ST_SCHEMA_TABLE *schema_table= schema_tables;
3906
DBUG_ENTER("find_schema_table");
3908
for (; schema_table->table_name; schema_table++)
3910
if (!my_strcasecmp(system_charset_info,
3911
schema_table->table_name,
3913
DBUG_RETURN(schema_table);
3916
schema_table_a.table_name= table_name;
3917
if (plugin_foreach(thd, find_schema_table_in_plugin,
3918
MYSQL_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
3919
DBUG_RETURN(schema_table_a.schema_table);
3925
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
3927
return &schema_tables[schema_table_idx];
3932
Create information_schema table using schema_table data.
3935
For MYSQL_TYPE_DECIMAL fields only, the field_length member has encoded
3936
into it two numbers, based on modulus of base-10 numbers. In the ones
3937
position is the number of decimals. Tens position is unused. In the
3938
hundreds and thousands position is a two-digit decimal number representing
3939
length. Encode this value with (decimals*100)+length , where
3940
0<decimals<10 and 0<=length<100 .
3945
@param table_list Used to pass I_S table information(fields info, tables
3946
parameters etc) and table name.
3948
@retval \# Pointer to created table
3949
@retval NULL Can't create table
3952
TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
3957
List<Item> field_list;
3958
ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
3959
ST_FIELD_INFO *fields_info= schema_table->fields_info;
3960
CHARSET_INFO *cs= system_charset_info;
3961
DBUG_ENTER("create_schema_table");
3963
for (; fields_info->field_name; fields_info++)
3965
switch (fields_info->field_type) {
3966
case MYSQL_TYPE_TINY:
3967
case MYSQL_TYPE_LONG:
3968
case MYSQL_TYPE_SHORT:
3969
case MYSQL_TYPE_LONGLONG:
3970
case MYSQL_TYPE_INT24:
3971
if (!(item= new Item_return_int(fields_info->field_name,
3972
fields_info->field_length,
3973
fields_info->field_type,
3974
fields_info->value)))
3978
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3980
case MYSQL_TYPE_DATE:
3981
case MYSQL_TYPE_TIME:
3982
case MYSQL_TYPE_TIMESTAMP:
3983
case MYSQL_TYPE_DATETIME:
3984
if (!(item=new Item_return_date_time(fields_info->field_name,
3985
fields_info->field_type)))
3990
case MYSQL_TYPE_FLOAT:
3991
case MYSQL_TYPE_DOUBLE:
3992
if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
3993
fields_info->field_length)) == NULL)
3996
case MYSQL_TYPE_DECIMAL:
3997
case MYSQL_TYPE_NEWDECIMAL:
3998
if (!(item= new Item_decimal((longlong) fields_info->value, false)))
4002
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
4003
item->decimals= fields_info->field_length%10;
4004
item->max_length= (fields_info->field_length/100)%100;
4005
if (item->unsigned_flag == 0)
4006
item->max_length+= 1;
4007
if (item->decimals > 0)
4008
item->max_length+= 1;
4009
item->set_name(fields_info->field_name,
4010
strlen(fields_info->field_name), cs);
4012
case MYSQL_TYPE_TINY_BLOB:
4013
case MYSQL_TYPE_MEDIUM_BLOB:
4014
case MYSQL_TYPE_LONG_BLOB:
4015
case MYSQL_TYPE_BLOB:
4016
if (!(item= new Item_blob(fields_info->field_name,
4017
fields_info->field_length)))
4023
/* Don't let unimplemented types pass through. Could be a grave error. */
4024
DBUG_ASSERT(fields_info->field_type == MYSQL_TYPE_STRING);
4026
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
4030
item->set_name(fields_info->field_name,
4031
strlen(fields_info->field_name), cs);
4034
field_list.push_back(item);
4035
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
4038
TMP_TABLE_PARAM *tmp_table_param =
4039
(TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
4040
tmp_table_param->init();
4041
tmp_table_param->table_charset= cs;
4042
tmp_table_param->field_count= field_count;
4043
tmp_table_param->schema_table= 1;
4044
SELECT_LEX *select_lex= thd->lex->current_select;
4045
if (!(table= create_tmp_table(thd, tmp_table_param,
4046
field_list, (ORDER*) 0, 0, 0,
4047
(select_lex->options | thd->options |
4048
TMP_TABLE_ALL_COLUMNS),
4049
HA_POS_ERROR, table_list->alias)))
4051
my_bitmap_map* bitmaps=
4052
(my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
4053
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
4055
table->read_set= &table->def_read_set;
4056
bitmap_clear_all(table->read_set);
4057
table_list->schema_table_param= tmp_table_param;
4063
For old SHOW compatibility. It is used when
4064
old SHOW doesn't have generated column names
4065
Make list of fields for SHOW
4070
schema_table pointer to 'schema_tables' element
4077
int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4079
ST_FIELD_INFO *field_info= schema_table->fields_info;
4080
Name_resolution_context *context= &thd->lex->select_lex.context;
4081
for (; field_info->field_name; field_info++)
4083
if (field_info->old_name)
4085
Item_field *field= new Item_field(context,
4086
NullS, NullS, field_info->field_name);
4089
field->set_name(field_info->old_name,
4090
strlen(field_info->old_name),
4091
system_charset_info);
4092
if (add_item_to_list(thd, field))
4101
int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4105
SELECT_LEX *sel= lex->current_select;
4106
Name_resolution_context *context= &sel->context;
4108
if (!sel->item_list.elements)
4110
ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
4111
String buffer(tmp,sizeof(tmp), system_charset_info);
4112
Item_field *field= new Item_field(context,
4113
NullS, NullS, field_info->field_name);
4114
if (!field || add_item_to_list(thd, field))
4117
buffer.append(field_info->old_name);
4118
if (lex->wild && lex->wild->ptr())
4120
buffer.append(STRING_WITH_LEN(" ("));
4121
buffer.append(lex->wild->ptr());
4124
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4130
int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4133
String buffer(tmp,sizeof(tmp), thd->charset());
4135
Name_resolution_context *context= &lex->select_lex.context;
4137
ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
4139
buffer.append(field_info->old_name);
4140
buffer.append(lex->select_lex.db);
4141
if (lex->wild && lex->wild->ptr())
4143
buffer.append(STRING_WITH_LEN(" ("));
4144
buffer.append(lex->wild->ptr());
4147
Item_field *field= new Item_field(context,
4148
NullS, NullS, field_info->field_name);
4149
if (add_item_to_list(thd, field))
4151
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4152
if (thd->lex->verbose)
4154
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4155
field_info= &schema_table->fields_info[3];
4156
field= new Item_field(context, NullS, NullS, field_info->field_name);
4157
if (add_item_to_list(thd, field))
4159
field->set_name(field_info->old_name, strlen(field_info->old_name),
4160
system_charset_info);
4166
int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4168
int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
4169
int *field_num= fields_arr;
4170
ST_FIELD_INFO *field_info;
4171
Name_resolution_context *context= &thd->lex->select_lex.context;
4173
for (; *field_num >= 0; field_num++)
4175
field_info= &schema_table->fields_info[*field_num];
4176
if (!thd->lex->verbose && (*field_num == 13 ||
4180
Item_field *field= new Item_field(context,
4181
NullS, NullS, field_info->field_name);
4184
field->set_name(field_info->old_name,
4185
strlen(field_info->old_name),
4186
system_charset_info);
4187
if (add_item_to_list(thd, field))
4195
int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4197
int fields_arr[]= {0, 2, 1, 3, -1};
4198
int *field_num= fields_arr;
4199
ST_FIELD_INFO *field_info;
4200
Name_resolution_context *context= &thd->lex->select_lex.context;
4202
for (; *field_num >= 0; field_num++)
4204
field_info= &schema_table->fields_info[*field_num];
4205
Item_field *field= new Item_field(context,
4206
NullS, NullS, field_info->field_name);
4209
field->set_name(field_info->old_name,
4210
strlen(field_info->old_name),
4211
system_charset_info);
4212
if (add_item_to_list(thd, field))
4221
Create information_schema table
4224
mysql_schema_table()
4227
table_list pointer to table_list
4234
int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
4237
DBUG_ENTER("mysql_schema_table");
4238
if (!(table= table_list->schema_table->create_table(thd, table_list)))
4240
table->s->tmp_table= SYSTEM_TMP_TABLE;
4242
This test is necessary to make
4243
case insensitive file systems +
4244
upper case table names(information schema tables) +
4248
if (table_list->schema_table_name)
4249
table->alias_name_used= my_strcasecmp(table_alias_charset,
4250
table_list->schema_table_name,
4252
table_list->table_name= table->s->table_name.str;
4253
table_list->table_name_length= table->s->table_name.length;
4254
table_list->table= table;
4255
table->next= thd->derived_tables;
4256
thd->derived_tables= table;
4257
table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
4259
if (table_list->schema_table_reformed) // show command
4261
SELECT_LEX *sel= lex->current_select;
4263
Field_translator *transl, *org_transl;
4265
if (table_list->field_translation)
4267
Field_translator *end= table_list->field_translation_end;
4268
for (transl= table_list->field_translation; transl < end; transl++)
4270
if (!transl->item->fixed &&
4271
transl->item->fix_fields(thd, &transl->item))
4276
List_iterator_fast<Item> it(sel->item_list);
4278
(Field_translator*)(thd->stmt_arena->
4279
alloc(sel->item_list.elements *
4280
sizeof(Field_translator)))))
4284
for (org_transl= transl; (item= it++); transl++)
4287
transl->name= item->name;
4288
if (!item->fixed && item->fix_fields(thd, &transl->item))
4293
table_list->field_translation= org_transl;
4294
table_list->field_translation_end= transl;
4302
Generate select from information_schema table
4305
make_schema_select()
4307
sel pointer to SELECT_LEX
4308
schema_table_idx index of 'schema_tables' element
4315
int make_schema_select(THD *thd, SELECT_LEX *sel,
4316
enum enum_schema_tables schema_table_idx)
4318
ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
4319
LEX_STRING db, table;
4320
DBUG_ENTER("make_schema_select");
4321
DBUG_PRINT("enter", ("mysql_schema_select: %s", schema_table->table_name));
4323
We have to make non const db_name & table_name
4324
because of lower_case_table_names
4326
thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str,
4327
INFORMATION_SCHEMA_NAME.length, 0);
4328
thd->make_lex_string(&table, schema_table->table_name,
4329
strlen(schema_table->table_name), 0);
4330
if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
4331
!sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
4341
Fill temporary schema tables before SELECT
4344
get_schema_tables_result()
4345
join join which use schema tables
4346
executed_place place where I_S table processed
4353
bool get_schema_tables_result(JOIN *join,
4354
enum enum_schema_table_state executed_place)
4356
JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
4357
THD *thd= join->thd;
4360
DBUG_ENTER("get_schema_tables_result");
4362
thd->no_warnings_for_error= 1;
4363
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
4365
if (!tab->table || !tab->table->pos_in_table_list)
4368
TABLE_LIST *table_list= tab->table->pos_in_table_list;
4369
if (table_list->schema_table)
4371
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
4372
lex->current_select->master_unit()->item);
4375
/* skip I_S optimizations specific to get_all_tables */
4376
if (thd->lex->describe &&
4377
(table_list->schema_table->fill_table != get_all_tables))
4381
If schema table is already processed and
4382
the statement is not a subselect then
4383
we don't need to fill this table again.
4384
If schema table is already processed and
4385
schema_table_state != executed_place then
4386
table is already processed and
4387
we should skip second data processing.
4389
if (table_list->schema_table_state &&
4390
(!is_subselect || table_list->schema_table_state != executed_place))
4394
if table is used in a subselect and
4395
table has been processed earlier with the same
4396
'executed_place' value then we should refresh the table.
4398
if (table_list->schema_table_state && is_subselect)
4400
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
4401
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
4402
table_list->table->file->ha_delete_all_rows();
4403
free_io_cache(table_list->table);
4404
filesort_free_buffers(table_list->table,1);
4405
table_list->table->null_row= 0;
4408
table_list->table->file->stats.records= 0;
4410
if (table_list->schema_table->fill_table(thd, table_list,
4415
tab->read_record.file= table_list->table->file;
4416
table_list->schema_table_state= executed_place;
4419
tab->read_record.file= table_list->table->file;
4420
table_list->schema_table_state= executed_place;
4423
thd->no_warnings_for_error= 0;
4424
DBUG_RETURN(result);
4427
ST_FIELD_INFO schema_fields_info[]=
4429
{"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4430
{"SCHEMA_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
4432
{"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0,
4434
{"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4435
{"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4436
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4440
ST_FIELD_INFO tables_fields_info[]=
4442
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4443
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4444
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
4446
{"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4447
{"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine", OPEN_FRM_ONLY},
4448
{"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4449
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
4450
{"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", OPEN_FULL_TABLE},
4451
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4452
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
4453
{"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4454
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
4455
{"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4456
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
4457
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4458
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
4459
{"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4460
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
4461
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4462
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
4463
{"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0,
4464
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
4465
{"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4466
{"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4467
{"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
4468
{"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
4469
{"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4470
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
4471
{"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options",
4473
{"TABLE_COMMENT", TABLE_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
4474
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4478
ST_FIELD_INFO columns_fields_info[]=
4480
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
4481
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4482
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4483
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Field",
4485
{"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4486
MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
4487
{"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0,
4488
1, "Default", OPEN_FRM_ONLY},
4489
{"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
4490
{"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4491
{"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
4492
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4493
{"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
4494
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4495
{"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
4496
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4497
{"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
4498
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4499
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
4500
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
4501
{"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type", OPEN_FRM_ONLY},
4502
{"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key", OPEN_FRM_ONLY},
4503
{"EXTRA", 27, MYSQL_TYPE_STRING, 0, 0, "Extra", OPEN_FRM_ONLY},
4504
{"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges", OPEN_FRM_ONLY},
4505
{"COLUMN_COMMENT", COLUMN_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
4506
{"STORAGE", 8, MYSQL_TYPE_STRING, 0, 0, "Storage", OPEN_FRM_ONLY},
4507
{"FORMAT", 8, MYSQL_TYPE_STRING, 0, 0, "Format", OPEN_FRM_ONLY},
4508
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4512
ST_FIELD_INFO charsets_fields_info[]=
4514
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset",
4516
{"DEFAULT_COLLATE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Default collation",
4518
{"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description",
4520
{"MAXLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
4521
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4525
ST_FIELD_INFO collation_fields_info[]=
4527
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Collation", SKIP_OPEN_TABLE},
4528
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset",
4530
{"ID", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Id",
4532
{"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default", SKIP_OPEN_TABLE},
4533
{"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled", SKIP_OPEN_TABLE},
4534
{"SORTLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
4535
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4539
ST_FIELD_INFO events_fields_info[]=
4541
{"EVENT_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4542
{"EVENT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db",
4544
{"EVENT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
4546
{"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
4547
{"TIME_ZONE", 64, MYSQL_TYPE_STRING, 0, 0, "Time zone", SKIP_OPEN_TABLE},
4548
{"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4549
{"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4550
{"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
4551
{"EXECUTE_AT", 0, MYSQL_TYPE_DATETIME, 0, 1, "Execute at", SKIP_OPEN_TABLE},
4552
{"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value",
4554
{"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field",
4556
{"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4557
{"STARTS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Starts", SKIP_OPEN_TABLE},
4558
{"ENDS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Ends", SKIP_OPEN_TABLE},
4559
{"STATUS", 18, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
4560
{"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4561
{"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
4562
{"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
4563
{"LAST_EXECUTED", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
4564
{"EVENT_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4565
{"ORIGINATOR", 10, MYSQL_TYPE_LONGLONG, 0, 0, "Originator", SKIP_OPEN_TABLE},
4566
{"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
4567
"character_set_client", SKIP_OPEN_TABLE},
4568
{"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
4569
"collation_connection", SKIP_OPEN_TABLE},
4570
{"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
4571
"Database Collation", SKIP_OPEN_TABLE},
4572
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4577
ST_FIELD_INFO coll_charset_app_fields_info[]=
4579
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4580
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4581
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4585
ST_FIELD_INFO stat_fields_info[]=
4587
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
4588
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4589
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", OPEN_FRM_ONLY},
4590
{"NON_UNIQUE", 1, MYSQL_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
4591
{"INDEX_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4592
{"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name",
4594
{"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
4595
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name",
4597
{"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
4598
{"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 1,
4599
"Cardinality", OPEN_FULL_TABLE},
4600
{"SUB_PART", 3, MYSQL_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
4601
{"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed", OPEN_FRM_ONLY},
4602
{"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
4603
{"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type", OPEN_FULL_TABLE},
4604
{"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment", OPEN_FRM_ONLY},
4605
{"INDEX_COMMENT", INDEX_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0, "Index_Comment", OPEN_FRM_ONLY},
4606
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4610
ST_FIELD_INFO user_privileges_fields_info[]=
4612
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4613
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4614
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4615
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4616
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4620
ST_FIELD_INFO schema_privileges_fields_info[]=
4622
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4623
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4624
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4625
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4626
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4627
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4631
ST_FIELD_INFO table_privileges_fields_info[]=
4633
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4634
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4635
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4636
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4637
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4638
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4639
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4643
ST_FIELD_INFO column_privileges_fields_info[]=
4645
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4646
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4647
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4648
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4649
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4650
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4651
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4652
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4656
ST_FIELD_INFO table_constraints_fields_info[]=
4658
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4659
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4661
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4663
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4664
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4665
{"CONSTRAINT_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4667
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4671
ST_FIELD_INFO key_column_usage_fields_info[]=
4673
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4674
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4676
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4678
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4679
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4680
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4681
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4682
{"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
4683
{"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONGLONG, 0, 1, 0,
4685
{"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
4687
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
4689
{"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
4691
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4695
ST_FIELD_INFO table_names_fields_info[]=
4697
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4698
{"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4699
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_",
4701
{"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type",
4703
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4707
ST_FIELD_INFO open_tables_fields_info[]=
4709
{"Database", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
4711
{"Table",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", SKIP_OPEN_TABLE},
4712
{"In_use", 1, MYSQL_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
4713
{"Name_locked", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
4714
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4718
ST_FIELD_INFO variables_fields_info[]=
4720
{"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name",
4722
{"VARIABLE_VALUE", 16300, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE},
4723
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4727
ST_FIELD_INFO processlist_fields_info[]=
4729
{"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
4730
{"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
4731
{"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host",
4733
{"DB", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Db", SKIP_OPEN_TABLE},
4734
{"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command", SKIP_OPEN_TABLE},
4735
{"TIME", 7, MYSQL_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
4736
{"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE},
4737
{"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info",
4739
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4743
ST_FIELD_INFO plugin_fields_info[]=
4745
{"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
4747
{"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4748
{"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
4749
{"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
4750
{"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4751
{"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library",
4753
{"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4754
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4755
{"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4756
{"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
4757
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4760
ST_FIELD_INFO referential_constraints_fields_info[]=
4762
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4763
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4765
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4767
{"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0,
4769
{"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4771
{"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0,
4772
MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
4773
{"MATCH_OPTION", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4774
{"UPDATE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4775
{"DELETE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4776
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4777
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4779
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4783
ST_FIELD_INFO parameters_fields_info[]=
4785
{"SPECIFIC_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4786
{"SPECIFIC_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4787
{"SPECIFIC_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4788
{"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FULL_TABLE},
4789
{"PARAMETER_MODE", 5, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4790
{"PARAMETER_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4791
{"DATA_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4792
{"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4793
{"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4794
{"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4795
{"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4796
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4797
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4798
{"DTD_IDENTIFIER", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4799
{"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4800
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}
4805
Description of ST_FIELD_INFO in table.h
4807
Make sure that the order of schema_tables and enum_schema_tables are the same.
4811
ST_SCHEMA_TABLE schema_tables[]=
4813
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
4814
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4815
{"COLLATIONS", collation_fields_info, create_schema_table,
4816
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4817
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4818
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4819
{"COLUMNS", columns_fields_info, create_schema_table,
4820
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
4821
OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL},
4822
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4823
fill_status, make_old_format, 0, -1, -1, 0, 0},
4824
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
4825
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4826
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
4827
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
4829
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
4830
fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
4831
{"PLUGINS", plugin_fields_info, create_schema_table,
4832
fill_plugins, make_old_format, 0, -1, -1, 0, 0},
4833
{"PROCESSLIST", processlist_fields_info, create_schema_table,
4834
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
4835
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
4836
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
4837
1, 9, 0, OPEN_TABLE_ONLY},
4838
{"SCHEMATA", schema_fields_info, create_schema_table,
4839
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
4840
{"SESSION_STATUS", variables_fields_info, create_schema_table,
4841
fill_status, make_old_format, 0, -1, -1, 0, 0},
4842
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4843
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4844
{"STATISTICS", stat_fields_info, create_schema_table,
4845
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4846
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4847
{"STATUS", variables_fields_info, create_schema_table, fill_status,
4848
make_old_format, 0, -1, -1, 1, 0},
4849
{"TABLES", tables_fields_info, create_schema_table,
4850
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4851
OPTIMIZE_I_S_TABLE},
4852
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4853
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
4854
{"TABLE_NAMES", table_names_fields_info, create_schema_table,
4855
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
4856
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
4857
make_old_format, 0, -1, -1, 1, 0},
4858
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
4862
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
4863
template class List_iterator_fast<char>;
4864
template class List<char>;
4867
int initialize_schema_table(st_plugin_int *plugin)
4869
ST_SCHEMA_TABLE *schema_table;
4870
DBUG_ENTER("initialize_schema_table");
4872
if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
4873
MYF(MY_WME | MY_ZEROFILL))))
4875
/* Historical Requirement */
4876
plugin->data= schema_table; // shortcut for the future
4877
if (plugin->plugin->init)
4879
schema_table->create_table= create_schema_table;
4880
schema_table->old_format= make_old_format;
4881
schema_table->idx_field1= -1,
4882
schema_table->idx_field2= -1;
4884
/* Make the name available to the init() function. */
4885
schema_table->table_name= plugin->name.str;
4887
if (plugin->plugin->init(schema_table))
4889
sql_print_error("Plugin '%s' init function returned error.",
4894
/* Make sure the plugin name is not set inside the init() function. */
4895
schema_table->table_name= plugin->name.str;
4900
my_free(schema_table, MYF(0));
4904
int finalize_schema_table(st_plugin_int *plugin)
4906
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
4907
DBUG_ENTER("finalize_schema_table");
4909
if (schema_table && plugin->plugin->deinit)
4911
DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
4912
if (plugin->plugin->deinit(NULL))
4914
DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
4917
my_free(schema_table, MYF(0));