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 */
18
#include <drizzled/server_includes.h>
19
#include <drizzled/sql_select.h>
20
#include <drizzled/sql_show.h>
21
#include <mysys/my_dir.h>
22
#include <libdrizzle/gettext.h>
23
#include <drizzled/util/convert.h>
27
str_or_nil(const char *str)
29
return str ? str : "<nil>";
32
/* Match the values of enum ha_choice */
33
static const char *ha_choice_values[] = {"", "0", "1"};
35
static void store_key_options(THD *thd, String *packet, Table *table,
40
int wild_case_compare(const CHARSET_INFO * const cs, const char *str,const char *wildstr)
45
while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
47
if (*wildstr == wild_prefix && wildstr[1])
49
if (my_toupper(cs, *wildstr++) != my_toupper(cs, *str++))
54
if (*wildstr++ == wild_one)
57
return (1); /* One char; skip */
62
return(0); /* '*' as last char: OK */
63
flag=(*wildstr != wild_many && *wildstr != wild_one);
69
if ((cmp= *wildstr) == wild_prefix && wildstr[1])
71
cmp=my_toupper(cs, cmp);
72
while (*str && my_toupper(cs, *str) != cmp)
77
if (wild_case_compare(cs, str,wildstr) == 0)
83
return (*str != '\0');
86
/***************************************************************************
87
** List all table types supported
88
***************************************************************************/
90
static bool show_plugins(THD *thd, plugin_ref plugin,
93
Table *table= (Table*) arg;
94
struct st_mysql_plugin *plug= plugin_decl(plugin);
95
struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
96
const CHARSET_INFO * const cs= system_charset_info;
98
restore_record(table, s->default_values);
100
table->field[0]->store(plugin_name(plugin)->str,
101
plugin_name(plugin)->length, cs);
105
table->field[1]->store(plug->version, strlen(plug->version), cs);
106
table->field[1]->set_notnull();
109
table->field[1]->set_null();
111
switch (plugin_state(plugin)) {
112
/* case PLUGIN_IS_FREED: does not happen */
113
case PLUGIN_IS_DELETED:
114
table->field[2]->store(STRING_WITH_LEN("DELETED"), cs);
116
case PLUGIN_IS_UNINITIALIZED:
117
table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs);
119
case PLUGIN_IS_READY:
120
table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
126
table->field[3]->store(plugin_type_names[plug->type].str,
127
plugin_type_names[plug->type].length,
132
table->field[4]->store(plugin_dl->dl.str, plugin_dl->dl.length, cs);
133
table->field[4]->set_notnull();
137
table->field[4]->set_null();
142
table->field[5]->store(plug->author, strlen(plug->author), cs);
143
table->field[5]->set_notnull();
146
table->field[5]->set_null();
150
table->field[6]->store(plug->descr, strlen(plug->descr), cs);
151
table->field[6]->set_notnull();
154
table->field[6]->set_null();
156
switch (plug->license) {
157
case PLUGIN_LICENSE_GPL:
158
table->field[7]->store(PLUGIN_LICENSE_GPL_STRING,
159
strlen(PLUGIN_LICENSE_GPL_STRING), cs);
161
case PLUGIN_LICENSE_BSD:
162
table->field[7]->store(PLUGIN_LICENSE_BSD_STRING,
163
strlen(PLUGIN_LICENSE_BSD_STRING), cs);
166
table->field[7]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
167
strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
170
table->field[7]->set_notnull();
172
return schema_table_store_record(thd, table);
176
int fill_plugins(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
178
Table *table= tables->table;
180
if (plugin_foreach_with_mask(thd, show_plugins, DRIZZLE_ANY_PLUGIN,
181
~PLUGIN_IS_FREED, table))
189
find_files() - find files in a given directory.
194
files put found files in this list
195
db database name to set in TableList structure
196
path path to database
197
wild filter for found files
198
dir read databases in path if true, read .frm files in
202
FIND_FILES_OK success
203
FIND_FILES_OOM out of memory error
204
FIND_FILES_DIR no such directory, or directory can't be read
209
find_files(THD *thd, List<LEX_STRING> *files, const char *db,
210
const char *path, const char *wild, bool dir)
216
LEX_STRING *file_name= 0;
217
uint32_t file_name_len;
218
TableList table_list;
220
if (wild && !wild[0])
223
memset(&table_list, 0, sizeof(table_list));
225
if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
227
if (my_errno == ENOENT)
228
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db);
230
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
231
return(FIND_FILES_DIR);
234
for (i=0 ; i < (uint) dirp->number_off_files ; i++)
236
char uname[NAME_LEN + 1]; /* Unencoded name */
237
file=dirp->dir_entry+i;
239
{ /* Return databases */
240
if ((file->name[0] == '.' &&
241
((file->name[1] == '.' && file->name[2] == '\0') ||
242
file->name[1] == '\0')))
243
continue; /* . or .. */
246
char buff[FN_REFLEN];
247
if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym"))
249
/* Only show the sym file if it points to a directory */
251
*ext=0; /* Remove extension */
252
unpack_dirname(buff, file->name);
253
end= strchr(buff, '\0');
254
if (end != buff && end[-1] == FN_LIBCHAR)
255
end[-1]= 0; // Remove end FN_LIBCHAR
256
if (stat(buff, file->mystat))
260
if (!S_ISDIR(file->mystat->st_mode))
263
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
264
if (wild && wild_compare(uname, wild, 0))
267
thd->make_lex_string(file_name, uname, file_name_len, true)))
270
return(FIND_FILES_OOM);
275
// Return only .frm files which aren't temp files.
276
if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) ||
277
is_prefix(file->name, tmp_file_prefix))
280
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
283
if (lower_case_table_names)
285
if (wild_case_compare(files_charset_info, uname, wild))
288
else if (wild_compare(uname, wild, 0))
293
thd->make_lex_string(file_name, uname, file_name_len, true)) ||
294
files->push_back(file_name))
297
return(FIND_FILES_OOM);
302
return(FIND_FILES_OK);
307
mysqld_show_create(THD *thd, TableList *table_list)
309
Protocol *protocol= thd->protocol;
311
String buffer(buff, sizeof(buff), system_charset_info);
313
/* Only one table for now, but VIEW can involve several tables */
314
if (open_normal_and_derived_tables(thd, table_list, 0))
316
if (thd->is_error() && thd->main_da.sql_errno() != ER_VIEW_INVALID)
320
Clear all messages with 'error' level status and
321
issue a warning with 'warning' level status in
322
case of invalid view and last error is ER_VIEW_INVALID
324
drizzle_reset_errors(thd, true);
330
if (store_create_info(thd, table_list, &buffer, NULL))
333
List<Item> field_list;
335
field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
336
// 1024 is for not to confuse old clients
337
field_list.push_back(new Item_empty_string("Create Table",
338
cmax(buffer.length(),(uint32_t)1024)));
341
if (protocol->send_fields(&field_list,
342
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
344
protocol->prepare_for_resend();
346
if (table_list->schema_table)
347
protocol->store(table_list->schema_table->table_name,
348
system_charset_info);
350
protocol->store(table_list->table->alias, system_charset_info);
353
protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
355
if (protocol->write())
362
bool mysqld_show_create_db(THD *thd, char *dbname,
363
HA_CREATE_INFO *create_info)
366
String buffer(buff, sizeof(buff), system_charset_info);
367
Protocol *protocol=thd->protocol;
369
if (store_db_create_info(thd, dbname, &buffer, create_info))
372
This assumes that the only reason for which store_db_create_info()
373
can fail is incorrect database name (which is the case now).
375
my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
379
List<Item> field_list;
380
field_list.push_back(new Item_empty_string("Database",NAME_CHAR_LEN));
381
field_list.push_back(new Item_empty_string("Create Database",1024));
383
if (protocol->send_fields(&field_list,
384
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
387
protocol->prepare_for_resend();
388
protocol->store(dbname, strlen(dbname), system_charset_info);
389
protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
391
if (protocol->write())
399
/****************************************************************************
400
Return only fields for API mysql_list_fields
401
Use "show table wildcard" in mysql instead of this
402
****************************************************************************/
405
mysqld_list_fields(THD *thd, TableList *table_list, const char *wild)
409
if (open_normal_and_derived_tables(thd, table_list, 0))
411
table= table_list->table;
413
List<Item> field_list;
416
for (ptr=table->field ; (field= *ptr); ptr++)
418
if (!wild || !wild[0] ||
419
!wild_case_compare(system_charset_info, field->field_name,wild))
421
field_list.push_back(new Item_field(field));
424
restore_record(table, s->default_values); // Get empty record
425
table->use_all_columns();
426
if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
434
Go through all character combinations and ensure that sql_lex.cc can
435
parse it as an identifier.
440
name_length length of name
443
# Pointer to conflicting character
444
0 No conflicting character
447
static const char *require_quotes(const char *name, uint32_t name_length)
450
bool pure_digit= true;
451
const char *end= name + name_length;
453
for (; name < end ; name++)
455
unsigned char chr= (unsigned char) *name;
456
length= my_mbcharlen(system_charset_info, chr);
457
if (length == 1 && !system_charset_info->ident_map[chr])
459
if (length == 1 && (chr < '0' || chr > '9'))
469
Quote the given identifier if needed and append it to the target string.
470
If the given identifier is empty, it will be quoted.
476
name the identifier to be appended
477
name_length length of the appending identifier
481
append_identifier(THD *thd, String *packet, const char *name, uint32_t length)
483
const char *name_end;
485
int q= get_quote_char_for_identifier(thd, name, length);
489
packet->append(name, length, packet->charset());
494
The identifier must be quoted as it includes a quote character or
498
packet->reserve(length*2 + 2);
499
quote_char= (char) q;
500
packet->append("e_char, 1, system_charset_info);
502
for (name_end= name+length ; name < name_end ; name+= length)
504
unsigned char chr= (unsigned char) *name;
505
length= my_mbcharlen(system_charset_info, chr);
507
my_mbcharlen can return 0 on a wrong multibyte
508
sequence. It is possible when upgrading from 4.0,
509
and identifier contains some accented characters.
510
The manual says it does not work. So we'll just
511
change length to 1 not to hang in the endless loop.
515
if (length == 1 && chr == (unsigned char) quote_char)
516
packet->append("e_char, 1, system_charset_info);
517
packet->append(name, length, system_charset_info);
519
packet->append("e_char, 1, system_charset_info);
524
Get the quote character for displaying an identifier.
527
get_quote_char_for_identifier()
530
length length of name
533
Force quoting in the following cases:
534
- name is empty (for one, it is possible when we use this function for
535
quoting user and host names for DEFINER clause);
537
- name includes a special character;
538
Otherwise identifier is quoted only if the option OPTION_QUOTE_SHOW_CREATE
542
EOF No quote character is needed
546
int get_quote_char_for_identifier(THD *thd, const char *name, uint32_t length)
549
!is_keyword(name,length) &&
550
!require_quotes(name, length) &&
551
!(thd->options & OPTION_QUOTE_SHOW_CREATE))
557
/* Append directory name (if exists) to CREATE INFO */
559
static void append_directory(THD *thd __attribute__((unused)),
560
String *packet, const char *dir_type,
561
const char *filename)
565
uint32_t length= dirname_length(filename);
567
packet->append(dir_type);
568
packet->append(STRING_WITH_LEN(" DIRECTORY='"));
569
packet->append(filename, length);
570
packet->append('\'');
575
#define LIST_PROCESS_HOST_LEN 64
577
static bool get_field_default_value(THD *thd __attribute__((unused)),
578
Field *timestamp_field,
579
Field *field, String *def_value,
583
bool has_now_default;
586
We are using CURRENT_TIMESTAMP instead of NOW because it is
589
has_now_default= (timestamp_field == field &&
590
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
592
has_default= (field->type() != DRIZZLE_TYPE_BLOB &&
593
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
594
field->unireg_check != Field::NEXT_NUMBER
597
def_value->length(0);
601
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
602
else if (!field->is_null())
603
{ // Not null by default
604
char tmp[MAX_FIELD_WIDTH];
605
String type(tmp, sizeof(tmp), field->charset());
606
field->val_str(&type);
610
uint32_t dummy_errors;
611
/* convert to system_charset_info == utf8 */
612
def_val.copy(type.ptr(), type.length(), field->charset(),
613
system_charset_info, &dummy_errors);
615
append_unescaped(def_value, def_val.ptr(), def_val.length());
617
def_value->append(def_val.ptr(), def_val.length());
620
def_value->append(STRING_WITH_LEN("''"));
622
else if (field->maybe_null() && quoted)
623
def_value->append(STRING_WITH_LEN("NULL")); // Null as default
632
Build a CREATE TABLE statement for a table.
637
table_list A list containing one table to write statement
639
packet Pointer to a string where statement will be
641
create_info_arg Pointer to create information that can be used
642
to tailor the format of the statement. Can be
643
NULL, in which case only SQL_MODE is considered
644
when building the statement.
647
Currently always return 0, but might return error code in the
654
int store_create_info(THD *thd, TableList *table_list, String *packet,
655
HA_CREATE_INFO *create_info_arg)
657
List<Item> field_list;
658
char tmp[MAX_FIELD_WIDTH], *for_str, def_value_buf[MAX_FIELD_WIDTH];
661
String type(tmp, sizeof(tmp), system_charset_info);
662
String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
664
uint32_t primary_key;
666
Table *table= table_list->table;
667
handler *file= table->file;
668
TABLE_SHARE *share= table->s;
669
HA_CREATE_INFO create_info;
670
bool show_table_options= false;
671
my_bitmap_map *old_map;
673
restore_record(table, s->default_values); // Get empty record
675
if (share->tmp_table)
676
packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
678
packet->append(STRING_WITH_LEN("CREATE TABLE "));
679
if (create_info_arg &&
680
(create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
681
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
682
if (table_list->schema_table)
683
alias= table_list->schema_table->table_name;
686
if (lower_case_table_names == 2)
690
alias= share->table_name.str;
693
append_identifier(thd, packet, alias, strlen(alias));
694
packet->append(STRING_WITH_LEN(" (\n"));
696
We need this to get default values from the table
697
We have to restore the read_set if we are called from insert in case
698
of row based replication.
700
old_map= table->use_all_columns(table->read_set);
702
for (ptr=table->field ; (field= *ptr); ptr++)
704
uint32_t flags = field->flags;
706
if (ptr != table->field)
707
packet->append(STRING_WITH_LEN(",\n"));
709
packet->append(STRING_WITH_LEN(" "));
710
append_identifier(thd,packet,field->field_name, strlen(field->field_name));
712
// check for surprises from the previous call to Field::sql_type()
713
if (type.ptr() != tmp)
714
type.set(tmp, sizeof(tmp), system_charset_info);
716
type.set_charset(system_charset_info);
718
if (field->vcol_info)
720
packet->append(STRING_WITH_LEN("VIRTUAL "));
723
field->sql_type(type);
724
packet->append(type.ptr(), type.length(), system_charset_info);
726
if (field->vcol_info)
728
packet->append(STRING_WITH_LEN(" AS ("));
729
packet->append(field->vcol_info->expr_str.str,
730
field->vcol_info->expr_str.length,
731
system_charset_info);
732
packet->append(STRING_WITH_LEN(")"));
733
if (field->is_stored)
734
packet->append(STRING_WITH_LEN(" STORED"));
737
if (field->has_charset())
739
if (field->charset() != share->table_charset)
741
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
742
packet->append(field->charset()->csname);
745
For string types dump collation name only if
746
collation is not primary for the given charset
748
if (!(field->charset()->state & MY_CS_PRIMARY))
750
packet->append(STRING_WITH_LEN(" COLLATE "));
751
packet->append(field->charset()->name);
755
if (flags & NOT_NULL_FLAG)
756
packet->append(STRING_WITH_LEN(" NOT NULL"));
757
else if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
760
TIMESTAMP field require explicit NULL flag, because unlike
761
all other fields they are treated as NOT NULL by default.
763
packet->append(STRING_WITH_LEN(" NULL"));
767
Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
768
and about STORAGE (DISK or MEMORY).
770
enum column_format_type column_format= (enum column_format_type)
771
((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
774
packet->append(STRING_WITH_LEN(" /*!"));
775
packet->append(STRING_WITH_LEN(DRIZZLE_VERSION_TABLESPACE_IN_FRM_STR));
776
packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
777
if (column_format == COLUMN_FORMAT_TYPE_FIXED)
778
packet->append(STRING_WITH_LEN(" FIXED */"));
780
packet->append(STRING_WITH_LEN(" DYNAMIC */"));
783
if (!field->vcol_info &&
784
get_field_default_value(thd, table->timestamp_field,
785
field, &def_value, 1))
787
packet->append(STRING_WITH_LEN(" DEFAULT "));
788
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
791
if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
792
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
794
if (field->unireg_check == Field::NEXT_NUMBER)
795
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
797
if (field->comment.length)
799
packet->append(STRING_WITH_LEN(" COMMENT "));
800
append_unescaped(packet, field->comment.str, field->comment.length);
804
key_info= table->key_info;
805
memset(&create_info, 0, sizeof(create_info));
806
/* Allow update_create_info to update row type */
807
create_info.row_type= share->row_type;
808
file->update_create_info(&create_info);
809
primary_key= share->primary_key;
811
for (uint32_t i=0 ; i < share->keys ; i++,key_info++)
813
KEY_PART_INFO *key_part= key_info->key_part;
814
bool found_primary=0;
815
packet->append(STRING_WITH_LEN(",\n "));
817
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
821
No space at end, because a space will be added after where the
822
identifier would go, but that is not added for primary key.
824
packet->append(STRING_WITH_LEN("PRIMARY KEY"));
826
else if (key_info->flags & HA_NOSAME)
827
packet->append(STRING_WITH_LEN("UNIQUE KEY "));
829
packet->append(STRING_WITH_LEN("KEY "));
832
append_identifier(thd, packet, key_info->name, strlen(key_info->name));
834
packet->append(STRING_WITH_LEN(" ("));
836
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
842
append_identifier(thd,packet,key_part->field->field_name,
843
strlen(key_part->field->field_name));
844
if (key_part->field &&
846
table->field[key_part->fieldnr-1]->key_length()))
849
buff= to_string(buff, (int32_t) key_part->length /
850
key_part->field->charset()->mbmaxlen);
852
packet->append(buff.c_str(), buff.length());
856
store_key_options(thd, packet, table, key_info);
860
Get possible foreign key definitions stored in InnoDB and append them
861
to the CREATE TABLE statement
864
if ((for_str= file->get_foreign_key_create_info()))
866
packet->append(for_str, strlen(for_str));
867
file->free_foreign_key_create_info(for_str);
870
packet->append(STRING_WITH_LEN("\n)"));
872
show_table_options= true;
874
Get possible table space definitions and append them
875
to the CREATE TABLE statement
880
THEN add ENGINE only if it was used when creating the table
882
if (!create_info_arg ||
883
(create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
885
packet->append(STRING_WITH_LEN(" ENGINE="));
886
packet->append(file->table_type());
890
Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
891
and NEXT_ID > 1 (the default). We must not print the clause
892
for engines that do not support this as it would break the
893
import of dumps, but as of this writing, the test for whether
894
AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
895
is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
896
Because of that, we do not explicitly test for the feature,
897
but may extrapolate its existence from that of an AUTO_INCREMENT column.
900
if (create_info.auto_increment_value > 1)
902
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
903
buff= to_string(create_info.auto_increment_value);
904
packet->append(buff.c_str(), buff.length());
909
packet->append(STRING_WITH_LEN(" MIN_ROWS="));
910
buff= to_string(share->min_rows);
911
packet->append(buff.c_str(), buff.length());
914
if (share->max_rows && !table_list->schema_table)
916
packet->append(STRING_WITH_LEN(" MAX_ROWS="));
917
buff= to_string(share->max_rows);
918
packet->append(buff.c_str(), buff.length());
921
if (share->avg_row_length)
923
packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
924
buff= to_string(share->avg_row_length);
925
packet->append(buff.c_str(), buff.length());
928
if (share->db_create_options & HA_OPTION_PACK_KEYS)
929
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
930
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
931
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
932
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
933
if (share->db_create_options & HA_OPTION_CHECKSUM)
934
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
935
if (share->page_checksum != HA_CHOICE_UNDEF)
937
packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
938
packet->append(ha_choice_values[(uint) share->page_checksum], 1);
940
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
941
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
942
if (create_info.row_type != ROW_TYPE_DEFAULT)
944
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
945
packet->append(ha_row_type[(uint) create_info.row_type]);
947
if (share->transactional != HA_CHOICE_UNDEF)
949
packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
950
packet->append(ha_choice_values[(uint) share->transactional], 1);
952
if (table->s->key_block_size)
954
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
955
buff= to_string(table->s->key_block_size);
956
packet->append(buff.c_str(), buff.length());
958
if (share->block_size)
960
packet->append(STRING_WITH_LEN(" BLOCK_SIZE="));
961
buff= to_string(share->block_size);
962
packet->append(buff.c_str(), buff.length());
964
table->file->append_create_info(packet);
965
if (share->comment.length)
967
packet->append(STRING_WITH_LEN(" COMMENT="));
968
append_unescaped(packet, share->comment.str, share->comment.length);
970
if (share->connect_string.length)
972
packet->append(STRING_WITH_LEN(" CONNECTION="));
973
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
975
append_directory(thd, packet, "DATA", create_info.data_file_name);
976
append_directory(thd, packet, "INDEX", create_info.index_file_name);
978
table->restore_column_map(old_map);
983
Get a CREATE statement for a given database.
985
The database is identified by its name, passed as @c dbname parameter.
986
The name should be encoded using the system character set (UTF8 currently).
988
Resulting statement is stored in the string pointed by @c buffer. The string
989
is emptied first and its character set is set to the system character set.
991
If HA_LEX_CREATE_IF_NOT_EXISTS flag is set in @c create_info->options, then
992
the resulting CREATE statement contains "IF NOT EXISTS" clause. Other flags
993
in @c create_options are ignored.
995
@param thd The current thread instance.
996
@param dbname The name of the database.
997
@param buffer A String instance where the statement is stored.
998
@param create_info If not NULL, the options member influences the resulting
1001
@returns true if errors are detected, false otherwise.
1004
bool store_db_create_info(THD *thd, const char *dbname, String *buffer,
1005
HA_CREATE_INFO *create_info)
1007
HA_CREATE_INFO create;
1008
uint32_t create_options = create_info ? create_info->options : 0;
1010
if (!my_strcasecmp(system_charset_info, dbname,
1011
INFORMATION_SCHEMA_NAME.str))
1013
dbname= INFORMATION_SCHEMA_NAME.str;
1014
create.default_table_charset= system_charset_info;
1018
if (check_db_dir_existence(dbname))
1021
load_db_opt_by_name(thd, dbname, &create);
1026
buffer->set_charset(system_charset_info);
1027
buffer->append(STRING_WITH_LEN("CREATE DATABASE "));
1029
if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
1030
buffer->append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
1032
append_identifier(thd, buffer, dbname, strlen(dbname));
1034
if (create.default_table_charset)
1036
buffer->append(STRING_WITH_LEN(" /*!40100"));
1037
buffer->append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
1038
buffer->append(create.default_table_charset->csname);
1039
if (!(create.default_table_charset->state & MY_CS_PRIMARY))
1041
buffer->append(STRING_WITH_LEN(" COLLATE "));
1042
buffer->append(create.default_table_charset->name);
1044
buffer->append(STRING_WITH_LEN(" */"));
1050
static void store_key_options(THD *thd __attribute__((unused)),
1051
String *packet, Table *table,
1054
char *end, buff[32];
1056
if (key_info->algorithm == HA_KEY_ALG_BTREE)
1057
packet->append(STRING_WITH_LEN(" USING BTREE"));
1059
if (key_info->algorithm == HA_KEY_ALG_HASH)
1060
packet->append(STRING_WITH_LEN(" USING HASH"));
1062
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
1063
table->s->key_block_size != key_info->block_size)
1065
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
1066
end= int64_t10_to_str(key_info->block_size, buff, 10);
1067
packet->append(buff, (uint) (end - buff));
1070
assert(test(key_info->flags & HA_USES_COMMENT) ==
1071
(key_info->comment.length > 0));
1072
if (key_info->flags & HA_USES_COMMENT)
1074
packet->append(STRING_WITH_LEN(" COMMENT "));
1075
append_unescaped(packet, key_info->comment.str,
1076
key_info->comment.length);
1081
/****************************************************************************
1082
Return info about all processes
1083
returns for each thread: thread id, user, host, db, command, info
1084
****************************************************************************/
1086
class thread_info :public ilink {
1088
static void *operator new(size_t size)
1090
return (void*) sql_alloc((uint) size);
1092
static void operator delete(void *ptr __attribute__((unused)),
1093
size_t size __attribute__((unused)))
1094
{ TRASH(ptr, size); }
1099
const char *user,*host,*db,*proc_info,*state_info;
1103
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1104
template class I_List<thread_info>;
1107
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
1110
List<Item> field_list;
1111
I_List<thread_info> thread_infos;
1112
ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
1113
PROCESS_LIST_WIDTH);
1114
Protocol *protocol= thd->protocol;
1116
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1117
field_list.push_back(new Item_empty_string("User",16));
1118
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1119
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1120
field->maybe_null=1;
1121
field_list.push_back(new Item_empty_string("Command",16));
1122
field_list.push_back(new Item_return_int("Time",7, DRIZZLE_TYPE_LONG));
1123
field_list.push_back(field=new Item_empty_string("State",30));
1124
field->maybe_null=1;
1125
field_list.push_back(field=new Item_empty_string("Info",max_query_length));
1126
field->maybe_null=1;
1127
if (protocol->send_fields(&field_list,
1128
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1131
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1134
I_List_iterator<THD> it(threads);
1138
Security_context *tmp_sctx= tmp->security_ctx;
1139
struct st_my_thread_var *mysys_var;
1140
if ((tmp->vio_ok() || tmp->system_thread) && (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
1142
thread_info *thd_info= new thread_info;
1144
thd_info->thread_id=tmp->thread_id;
1145
thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
1146
(tmp->system_thread ?
1147
"system user" : "unauthenticated user"));
1148
thd_info->host= thd->strdup(tmp_sctx->ip);
1149
if ((thd_info->db=tmp->db)) // Safe test
1150
thd_info->db=thd->strdup(thd_info->db);
1151
thd_info->command=(int) tmp->command;
1152
if ((mysys_var= tmp->mysys_var))
1153
pthread_mutex_lock(&mysys_var->mutex);
1154
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
1155
thd_info->state_info= (char*) (tmp->net.reading_or_writing ?
1156
(tmp->net.reading_or_writing == 2 ?
1158
thd_info->command == COM_SLEEP ? NULL :
1159
"Reading from net") :
1160
tmp->get_proc_info() ? tmp->get_proc_info() :
1162
tmp->mysys_var->current_cond ?
1163
"Waiting on cond" : NULL);
1165
pthread_mutex_unlock(&mysys_var->mutex);
1167
thd_info->start_time= tmp->start_time;
1172
query_length is always set to 0 when we set query = NULL; see
1173
the comment in sql_class.h why this prevents crashes in possible
1174
races with query_length
1176
uint32_t length= cmin((uint32_t)max_query_length, tmp->query_length);
1177
thd_info->query=(char*) thd->strmake(tmp->query,length);
1179
thread_infos.append(thd_info);
1183
pthread_mutex_unlock(&LOCK_thread_count);
1185
thread_info *thd_info;
1186
time_t now= my_time(0);
1187
while ((thd_info=thread_infos.get()))
1189
protocol->prepare_for_resend();
1190
protocol->store((uint64_t) thd_info->thread_id);
1191
protocol->store(thd_info->user, system_charset_info);
1192
protocol->store(thd_info->host, system_charset_info);
1193
protocol->store(thd_info->db, system_charset_info);
1194
if (thd_info->proc_info)
1195
protocol->store(thd_info->proc_info, system_charset_info);
1197
protocol->store(command_name[thd_info->command].str, system_charset_info);
1198
if (thd_info->start_time)
1199
protocol->store((uint32_t) (now - thd_info->start_time));
1201
protocol->store_null();
1202
protocol->store(thd_info->state_info, system_charset_info);
1203
protocol->store(thd_info->query, system_charset_info);
1204
if (protocol->write())
1205
break; /* purecov: inspected */
1211
int fill_schema_processlist(THD* thd, TableList* tables,
1212
COND* cond __attribute__((unused)))
1214
Table *table= tables->table;
1215
const CHARSET_INFO * const cs= system_charset_info;
1217
time_t now= my_time(0);
1221
pthread_mutex_lock(&LOCK_thread_count);
1225
I_List_iterator<THD> it(threads);
1230
Security_context *tmp_sctx= tmp->security_ctx;
1231
struct st_my_thread_var *mysys_var;
1234
if ((!tmp->vio_ok() && !tmp->system_thread))
1237
restore_record(table, s->default_values);
1239
table->field[0]->store((int64_t) tmp->thread_id, true);
1241
val= tmp_sctx->user ? tmp_sctx->user :
1242
(tmp->system_thread ? "system user" : "unauthenticated user");
1243
table->field[1]->store(val, strlen(val), cs);
1245
table->field[2]->store(tmp_sctx->ip, strlen(tmp_sctx->ip), cs);
1249
table->field[3]->store(tmp->db, strlen(tmp->db), cs);
1250
table->field[3]->set_notnull();
1253
if ((mysys_var= tmp->mysys_var))
1254
pthread_mutex_lock(&mysys_var->mutex);
1256
if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
1257
table->field[4]->store(val, strlen(val), cs);
1259
table->field[4]->store(command_name[tmp->command].str,
1260
command_name[tmp->command].length, cs);
1262
table->field[5]->store((uint32_t)(tmp->start_time ?
1263
now - tmp->start_time : 0), true);
1265
val= (char*) (tmp->net.reading_or_writing ?
1266
(tmp->net.reading_or_writing == 2 ?
1268
tmp->command == COM_SLEEP ? NULL :
1269
"Reading from net") :
1270
tmp->get_proc_info() ? tmp->get_proc_info() :
1272
tmp->mysys_var->current_cond ?
1273
"Waiting on cond" : NULL);
1276
table->field[6]->store(val, strlen(val), cs);
1277
table->field[6]->set_notnull();
1281
pthread_mutex_unlock(&mysys_var->mutex);
1286
table->field[7]->store(tmp->query,
1287
cmin((uint32_t)PROCESS_LIST_INFO_WIDTH,
1288
tmp->query_length), cs);
1289
table->field[7]->set_notnull();
1292
if (schema_table_store_record(thd, table))
1294
pthread_mutex_unlock(&LOCK_thread_count);
1300
pthread_mutex_unlock(&LOCK_thread_count);
1304
/*****************************************************************************
1306
*****************************************************************************/
1308
static DYNAMIC_ARRAY all_status_vars;
1309
static bool status_vars_inited= 0;
1310
static int show_var_cmp(const void *var1, const void *var2)
1312
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1316
deletes all the SHOW_UNDEF elements from the array and calls
1317
delete_dynamic() if it's completely empty.
1319
static void shrink_var_array(DYNAMIC_ARRAY *array)
1322
SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
1324
for (a= b= 0; b < array->elements; b++)
1325
if (all[b].type != SHOW_UNDEF)
1329
memset(all+a, 0, sizeof(SHOW_VAR)); // writing NULL-element to the end
1332
else // array is completely empty - delete it
1333
delete_dynamic(array);
1337
Adds an array of SHOW_VAR entries to the output of SHOW STATUS
1340
add_status_vars(SHOW_VAR *list)
1341
list - an array of SHOW_VAR entries to add to all_status_vars
1342
the last entry must be {0,0,SHOW_UNDEF}
1345
The handling of all_status_vars[] is completely internal, it's allocated
1346
automatically when something is added to it, and deleted completely when
1347
the last entry is removed.
1349
As a special optimization, if add_status_vars() is called before
1350
init_status_vars(), it assumes "startup mode" - neither concurrent access
1351
to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
1353
The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
1355
int add_status_vars(SHOW_VAR *list)
1358
if (status_vars_inited)
1359
pthread_mutex_lock(&LOCK_status);
1360
if (!all_status_vars.buffer && // array is not allocated yet - do it now
1361
my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
1367
res|= insert_dynamic(&all_status_vars, (unsigned char*)list++);
1368
res|= insert_dynamic(&all_status_vars, (unsigned char*)list); // appending NULL-element
1369
all_status_vars.elements--; // but next insert_dynamic should overwite it
1370
if (status_vars_inited)
1371
sort_dynamic(&all_status_vars, show_var_cmp);
1373
if (status_vars_inited)
1374
pthread_mutex_unlock(&LOCK_status);
1379
Make all_status_vars[] usable for SHOW STATUS
1382
See add_status_vars(). Before init_status_vars() call, add_status_vars()
1383
works in a special fast "startup" mode. Thus init_status_vars()
1384
should be called as late as possible but before enabling multi-threading.
1386
void init_status_vars()
1388
status_vars_inited=1;
1389
sort_dynamic(&all_status_vars, show_var_cmp);
1392
void reset_status_vars()
1394
SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
1395
SHOW_VAR *last= ptr + all_status_vars.elements;
1396
for (; ptr < last; ptr++)
1398
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
1399
if (ptr->type == SHOW_LONG)
1400
*(ulong*) ptr->value= 0;
1405
catch-all cleanup function, cleans up everything no matter what
1408
This function is not strictly required if all add_to_status/
1409
remove_status_vars are properly paired, but it's a safety measure that
1410
deletes everything from the all_status_vars[] even if some
1411
remove_status_vars were forgotten
1413
void free_status_vars()
1415
delete_dynamic(&all_status_vars);
1419
Removes an array of SHOW_VAR entries from the output of SHOW STATUS
1422
remove_status_vars(SHOW_VAR *list)
1423
list - an array of SHOW_VAR entries to remove to all_status_vars
1424
the last entry must be {0,0,SHOW_UNDEF}
1427
there's lots of room for optimizing this, especially in non-sorted mode,
1428
but nobody cares - it may be called only in case of failed plugin
1429
initialization in the mysqld startup.
1432
void remove_status_vars(SHOW_VAR *list)
1434
if (status_vars_inited)
1436
pthread_mutex_lock(&LOCK_status);
1437
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1438
int a= 0, b= all_status_vars.elements, c= (a+b)/2;
1440
for (; list->name; list++)
1443
for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
1445
res= show_var_cmp(list, all+c);
1454
all[c].type= SHOW_UNDEF;
1456
shrink_var_array(&all_status_vars);
1457
pthread_mutex_unlock(&LOCK_status);
1461
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1463
for (; list->name; list++)
1465
for (i= 0; i < all_status_vars.elements; i++)
1467
if (show_var_cmp(list, all+i))
1469
all[i].type= SHOW_UNDEF;
1473
shrink_var_array(&all_status_vars);
1477
inline void make_upper(char *buf)
1480
*buf= my_toupper(system_charset_info, *buf);
1483
static bool show_status_array(THD *thd, const char *wild,
1484
SHOW_VAR *variables,
1485
enum enum_var_type value_type,
1486
struct system_status_var *status_var,
1487
const char *prefix, Table *table,
1490
MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
1491
char * const buff= (char *) &buff_data;
1493
/* the variable name should not be longer than 64 characters */
1494
char name_buffer[64];
1496
LEX_STRING null_lex_str;
1499
null_lex_str.str= 0; // For sys_var->value_ptr()
1500
null_lex_str.length= 0;
1502
prefix_end=my_stpncpy(name_buffer, prefix, sizeof(name_buffer)-1);
1505
len=name_buffer + sizeof(name_buffer) - prefix_end;
1507
for (; variables->name; variables++)
1509
my_stpncpy(prefix_end, variables->name, len);
1510
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
1512
make_upper(name_buffer);
1515
if var->type is SHOW_FUNC, call the function.
1516
Repeat as necessary, if new var is again SHOW_FUNC
1518
for (var=variables; var->type == SHOW_FUNC; var= &tmp)
1519
((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(thd, &tmp, buff);
1521
SHOW_TYPE show_type=var->type;
1522
if (show_type == SHOW_ARRAY)
1524
show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
1525
status_var, name_buffer, table, ucase_names);
1529
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
1530
name_buffer, wild)))
1532
char *value=var->value;
1533
const char *pos, *end; // We assign a lot of const's
1535
pthread_mutex_lock(&LOCK_global_system_variables);
1537
if (show_type == SHOW_SYS)
1539
show_type= ((sys_var*) value)->show_type();
1540
value= (char*) ((sys_var*) value)->value_ptr(thd, value_type,
1546
note that value may be == buff. All SHOW_xxx code below
1547
should still work in this case
1549
switch (show_type) {
1550
case SHOW_DOUBLE_STATUS:
1551
value= ((char *) status_var + (ulong) value);
1554
/* 6 is the default precision for '%f' in sprintf() */
1555
end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
1557
case SHOW_LONG_STATUS:
1558
value= ((char *) status_var + (ulong) value);
1561
case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
1562
end= int10_to_str(*(long*) value, buff, 10);
1564
case SHOW_LONGLONG_STATUS:
1565
value= ((char *) status_var + (uint64_t) value);
1568
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1571
end= int64_t10_to_str((int64_t) *(ha_rows*) value, buff, 10);
1574
end= my_stpcpy(buff, *(bool*) value ? "ON" : "OFF");
1577
end= my_stpcpy(buff, *(bool*) value ? "ON" : "OFF");
1580
end= int10_to_str((long) *(uint32_t*) value, buff, 10);
1584
SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
1585
pos= show_comp_option_name[(int) tmp];
1586
end= strchr(pos, '\0');
1593
end= strchr(pos, '\0');
1598
if (!(pos= *(char**) value))
1600
end= strchr(pos, '\0');
1603
case SHOW_KEY_CACHE_LONG:
1604
value= (char*) dflt_key_cache + (ulong)value;
1605
end= int10_to_str(*(long*) value, buff, 10);
1607
case SHOW_KEY_CACHE_LONGLONG:
1608
value= (char*) dflt_key_cache + (ulong)value;
1609
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1612
break; // Return empty string
1613
case SHOW_SYS: // Cannot happen
1618
restore_record(table, s->default_values);
1619
table->field[0]->store(name_buffer, strlen(name_buffer),
1620
system_charset_info);
1621
table->field[1]->store(pos, (uint32_t) (end - pos), system_charset_info);
1622
table->field[1]->set_notnull();
1624
pthread_mutex_unlock(&LOCK_global_system_variables);
1626
if (schema_table_store_record(thd, table))
1636
/* collect status for all running threads */
1638
void calc_sum_of_all_status(STATUS_VAR *to)
1641
/* Ensure that thread id not killed during loop */
1642
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1644
I_List_iterator<THD> it(threads);
1647
/* Get global values as base */
1648
*to= global_status_var;
1650
/* Add to this status from existing threads */
1652
add_to_status(to, &tmp->status_var);
1654
pthread_mutex_unlock(&LOCK_thread_count);
1659
/* This is only used internally, but we need it here as a forward reference */
1660
extern ST_SCHEMA_TABLE schema_tables[];
1662
typedef struct st_lookup_field_values
1664
LEX_STRING db_value, table_value;
1665
bool wild_db_value, wild_table_value;
1666
} LOOKUP_FIELD_VALUES;
1670
Store record to I_S table, convert HEAP table
1671
to MyISAM if necessary
1674
schema_table_store_record()
1676
table Information schema table to be updated
1683
bool schema_table_store_record(THD *thd, Table *table)
1686
if ((error= table->file->ha_write_row(table->record[0])))
1688
TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
1690
if (create_myisam_from_heap(thd, table, param->start_recinfo,
1691
¶m->recinfo, error, 0))
1698
int make_table_list(THD *thd, SELECT_LEX *sel,
1699
LEX_STRING *db_name, LEX_STRING *table_name)
1701
Table_ident *table_ident;
1702
table_ident= new Table_ident(thd, *db_name, *table_name, 1);
1704
if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
1711
@brief Get lookup value from the part of 'WHERE' condition
1713
@details This function gets lookup value from
1714
the part of 'WHERE' condition if it's possible and
1715
fill appropriate lookup_field_vals struct field
1718
@param[in] thd thread handler
1719
@param[in] item_func part of WHERE condition
1720
@param[in] table I_S table
1721
@param[in, out] lookup_field_vals Struct which holds lookup values
1725
1 error, there can be no matching records for the condition
1728
bool get_lookup_value(THD *thd, Item_func *item_func,
1730
LOOKUP_FIELD_VALUES *lookup_field_vals)
1732
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1733
ST_FIELD_INFO *field_info= schema_table->fields_info;
1734
const char *field_name1= schema_table->idx_field1 >= 0 ?
1735
field_info[schema_table->idx_field1].field_name : "";
1736
const char *field_name2= schema_table->idx_field2 >= 0 ?
1737
field_info[schema_table->idx_field2].field_name : "";
1739
if (item_func->functype() == Item_func::EQ_FUNC ||
1740
item_func->functype() == Item_func::EQUAL_FUNC)
1742
int idx_field, idx_val;
1743
char tmp[MAX_FIELD_WIDTH];
1744
String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
1745
Item_field *item_field;
1746
const CHARSET_INFO * const cs= system_charset_info;
1748
if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
1749
item_func->arguments()[1]->const_item())
1754
else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
1755
item_func->arguments()[0]->const_item())
1763
item_field= (Item_field*) item_func->arguments()[idx_field];
1764
if (table->table != item_field->field->table)
1766
tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
1768
/* impossible value */
1772
/* Lookup value is database name */
1773
if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1774
(unsigned char *) item_field->field_name,
1775
strlen(item_field->field_name), 0))
1777
thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
1778
tmp_str->length(), false);
1780
/* Lookup value is table name */
1781
else if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name2,
1782
strlen(field_name2),
1783
(unsigned char *) item_field->field_name,
1784
strlen(item_field->field_name), 0))
1786
thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
1787
tmp_str->length(), false);
1795
@brief Calculates lookup values from 'WHERE' condition
1797
@details This function calculates lookup value(database name, table name)
1798
from 'WHERE' condition if it's possible and
1799
fill lookup_field_vals struct fields with these values.
1801
@param[in] thd thread handler
1802
@param[in] cond WHERE condition
1803
@param[in] table I_S table
1804
@param[in, out] lookup_field_vals Struct which holds lookup values
1808
1 error, there can be no matching records for the condition
1811
bool calc_lookup_values_from_cond(THD *thd, COND *cond, TableList *table,
1812
LOOKUP_FIELD_VALUES *lookup_field_vals)
1817
if (cond->type() == Item::COND_ITEM)
1819
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1821
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1823
while ((item= li++))
1825
if (item->type() == Item::FUNC_ITEM)
1827
if (get_lookup_value(thd, (Item_func*)item, table, lookup_field_vals))
1832
if (calc_lookup_values_from_cond(thd, item, table, lookup_field_vals))
1839
else if (cond->type() == Item::FUNC_ITEM &&
1840
get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals))
1846
bool uses_only_table_name_fields(Item *item, TableList *table)
1848
if (item->type() == Item::FUNC_ITEM)
1850
Item_func *item_func= (Item_func*)item;
1851
for (uint32_t i=0; i<item_func->argument_count(); i++)
1853
if (!uses_only_table_name_fields(item_func->arguments()[i], table))
1857
else if (item->type() == Item::FIELD_ITEM)
1859
Item_field *item_field= (Item_field*)item;
1860
const CHARSET_INFO * const cs= system_charset_info;
1861
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1862
ST_FIELD_INFO *field_info= schema_table->fields_info;
1863
const char *field_name1= schema_table->idx_field1 >= 0 ?
1864
field_info[schema_table->idx_field1].field_name : "";
1865
const char *field_name2= schema_table->idx_field2 >= 0 ?
1866
field_info[schema_table->idx_field2].field_name : "";
1867
if (table->table != item_field->field->table ||
1868
(cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1869
(unsigned char *) item_field->field_name,
1870
strlen(item_field->field_name), 0) &&
1871
cs->coll->strnncollsp(cs, (unsigned char *) field_name2, strlen(field_name2),
1872
(unsigned char *) item_field->field_name,
1873
strlen(item_field->field_name), 0)))
1876
else if (item->type() == Item::REF_ITEM)
1877
return uses_only_table_name_fields(item->real_item(), table);
1879
if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
1886
static COND * make_cond_for_info_schema(COND *cond, TableList *table)
1890
if (cond->type() == Item::COND_ITEM)
1892
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1894
/* Create new top level AND item */
1895
Item_cond_and *new_cond=new Item_cond_and;
1898
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1902
Item *fix= make_cond_for_info_schema(item, table);
1904
new_cond->argument_list()->push_back(fix);
1906
switch (new_cond->argument_list()->elements) {
1910
return new_cond->argument_list()->head();
1912
new_cond->quick_fix_field();
1918
Item_cond_or *new_cond=new Item_cond_or;
1921
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1925
Item *fix=make_cond_for_info_schema(item, table);
1928
new_cond->argument_list()->push_back(fix);
1930
new_cond->quick_fix_field();
1931
new_cond->top_level_item();
1936
if (!uses_only_table_name_fields(cond, table))
1943
@brief Calculate lookup values(database name, table name)
1945
@details This function calculates lookup values(database name, table name)
1946
from 'WHERE' condition or wild values (for 'SHOW' commands only)
1947
from LEX struct and fill lookup_field_vals struct field
1950
@param[in] thd thread handler
1951
@param[in] cond WHERE condition
1952
@param[in] tables I_S table
1953
@param[in, out] lookup_field_values Struct which holds lookup values
1957
1 error, there can be no matching records for the condition
1960
bool get_lookup_field_values(THD *thd, COND *cond, TableList *tables,
1961
LOOKUP_FIELD_VALUES *lookup_field_values)
1964
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
1965
memset(lookup_field_values, 0, sizeof(LOOKUP_FIELD_VALUES));
1966
switch (lex->sql_command) {
1967
case SQLCOM_SHOW_DATABASES:
1970
lookup_field_values->db_value.str= (char*) wild;
1971
lookup_field_values->db_value.length= strlen(wild);
1972
lookup_field_values->wild_db_value= 1;
1975
case SQLCOM_SHOW_TABLES:
1976
case SQLCOM_SHOW_TABLE_STATUS:
1977
lookup_field_values->db_value.str= lex->select_lex.db;
1978
lookup_field_values->db_value.length=strlen(lex->select_lex.db);
1981
lookup_field_values->table_value.str= (char*)wild;
1982
lookup_field_values->table_value.length= strlen(wild);
1983
lookup_field_values->wild_table_value= 1;
1988
The "default" is for queries over I_S.
1989
All previous cases handle SHOW commands.
1991
return calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
1996
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
1998
return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
2003
Create db names list. Information schema name always is first in list
2008
files list of db names
2010
idx_field_vals idx_field_vals->db_name contains db name or
2012
with_i_schema returns 1 if we added 'IS' name to list
2020
int make_db_list(THD *thd, List<LEX_STRING> *files,
2021
LOOKUP_FIELD_VALUES *lookup_field_vals,
2022
bool *with_i_schema)
2024
LEX_STRING *i_s_name_copy= 0;
2025
i_s_name_copy= thd->make_lex_string(i_s_name_copy,
2026
INFORMATION_SCHEMA_NAME.str,
2027
INFORMATION_SCHEMA_NAME.length, true);
2029
if (lookup_field_vals->wild_db_value)
2032
This part of code is only for SHOW DATABASES command.
2033
idx_field_vals->db_value can be 0 when we don't use
2034
LIKE clause (see also get_index_field_values() function)
2036
if (!lookup_field_vals->db_value.str ||
2037
!wild_case_compare(system_charset_info,
2038
INFORMATION_SCHEMA_NAME.str,
2039
lookup_field_vals->db_value.str))
2042
if (files->push_back(i_s_name_copy))
2045
return (find_files(thd, files, NULL, mysql_data_home,
2046
lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
2051
If we have db lookup vaule we just add it to list and
2052
exit from the function
2054
if (lookup_field_vals->db_value.str)
2056
if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
2057
lookup_field_vals->db_value.str))
2060
if (files->push_back(i_s_name_copy))
2064
if (files->push_back(&lookup_field_vals->db_value))
2070
Create list of existing databases. It is used in case
2071
of select from information schema table
2073
if (files->push_back(i_s_name_copy))
2076
return (find_files(thd, files, NULL,
2077
mysql_data_home, NULL, 1) != FIND_FILES_OK);
2081
struct st_add_schema_table
2083
List<LEX_STRING> *files;
2088
static bool add_schema_table(THD *thd, plugin_ref plugin,
2091
LEX_STRING *file_name= 0;
2092
st_add_schema_table *data= (st_add_schema_table *)p_data;
2093
List<LEX_STRING> *file_list= data->files;
2094
const char *wild= data->wild;
2095
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
2097
if (schema_table->hidden)
2101
if (lower_case_table_names)
2103
if (wild_case_compare(files_charset_info,
2104
schema_table->table_name,
2108
else if (wild_compare(schema_table->table_name, wild, 0))
2112
if ((file_name= thd->make_lex_string(file_name, schema_table->table_name,
2113
strlen(schema_table->table_name),
2115
!file_list->push_back(file_name))
2121
int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
2123
LEX_STRING *file_name= 0;
2124
ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
2125
st_add_schema_table add_data;
2127
for (; tmp_schema_table->table_name; tmp_schema_table++)
2129
if (tmp_schema_table->hidden)
2133
if (lower_case_table_names)
2135
if (wild_case_compare(files_charset_info,
2136
tmp_schema_table->table_name,
2140
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2144
thd->make_lex_string(file_name, tmp_schema_table->table_name,
2145
strlen(tmp_schema_table->table_name), true)) &&
2146
!files->push_back(file_name))
2151
add_data.files= files;
2152
add_data.wild= wild;
2153
if (plugin_foreach(thd, add_schema_table,
2154
DRIZZLE_INFORMATION_SCHEMA_PLUGIN, &add_data))
2162
@brief Create table names list
2164
@details The function creates the list of table names in
2167
@param[in] thd thread handler
2168
@param[in] table_names List of table names in database
2169
@param[in] lex pointer to LEX struct
2170
@param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
2171
@param[in] with_i_schema true means that we add I_S tables to list
2172
@param[in] db_name database name
2174
@return Operation status
2176
@retval 1 fatal error
2177
@retval 2 Not fatal error; Safe to ignore this file list
2181
make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
2182
LOOKUP_FIELD_VALUES *lookup_field_vals,
2183
bool with_i_schema, LEX_STRING *db_name)
2185
char path[FN_REFLEN];
2186
build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
2187
if (!lookup_field_vals->wild_table_value &&
2188
lookup_field_vals->table_value.str)
2192
if (find_schema_table(thd, lookup_field_vals->table_value.str))
2194
if (table_names->push_back(&lookup_field_vals->table_value))
2200
if (table_names->push_back(&lookup_field_vals->table_value))
2207
This call will add all matching the wildcards (if specified) IS tables
2211
return (schema_tables_add(thd, table_names,
2212
lookup_field_vals->table_value.str));
2214
find_files_result res= find_files(thd, table_names, db_name->str, path,
2215
lookup_field_vals->table_value.str, 0);
2216
if (res != FIND_FILES_OK)
2219
Downgrade errors about problems with database directory to
2220
warnings if this is not a 'SHOW' command. Another thread
2221
may have dropped database, and we may still have a name
2224
if (res == FIND_FILES_DIR)
2226
if (lex->sql_command != SQLCOM_SELECT)
2238
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
2240
@param[in] thd thread handler
2241
@param[in] tables TableList for I_S table
2242
@param[in] schema_table pointer to I_S structure
2243
@param[in] open_tables_state_backup pointer to Open_tables_state object
2244
which is used to save|restore original
2245
status of variables related to
2248
@return Operation status
2254
fill_schema_show_cols_or_idxs(THD *thd, TableList *tables,
2255
ST_SCHEMA_TABLE *schema_table,
2256
Open_tables_state *open_tables_state_backup)
2260
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
2261
enum_sql_command save_sql_command= lex->sql_command;
2262
TableList *show_table_list= (TableList*) tables->schema_select_lex->
2264
Table *table= tables->table;
2267
lex->all_selects_list= tables->schema_select_lex;
2269
Restore thd->temporary_tables to be able to process
2270
temporary tables(only for 'show index' & 'show columns').
2271
This should be changed when processing of temporary tables for
2272
I_S tables will be done.
2274
thd->temporary_tables= open_tables_state_backup->temporary_tables;
2276
Let us set fake sql_command so views won't try to merge
2277
themselves into main statement. If we don't do this,
2278
SELECT * from information_schema.xxxx will cause problems.
2279
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
2281
lex->sql_command= SQLCOM_SHOW_FIELDS;
2282
res= open_normal_and_derived_tables(thd, show_table_list,
2283
DRIZZLE_LOCK_IGNORE_FLUSH);
2284
lex->sql_command= save_sql_command;
2286
get_all_tables() returns 1 on failure and 0 on success thus
2287
return only these and not the result code of ::process_table()
2289
We should use show_table_list->alias instead of
2290
show_table_list->table_name because table_name
2291
could be changed during opening of I_S tables. It's safe
2292
to use alias because alias contains original table name
2293
in this case(this part of code is used only for
2294
'show columns' & 'show statistics' commands).
2296
table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
2297
strlen(show_table_list->alias), false);
2298
db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db,
2299
show_table_list->db_length, false);
2302
error= test(schema_table->process_table(thd, show_table_list,
2303
table, res, db_name,
2305
thd->temporary_tables= 0;
2306
close_tables_for_reopen(thd, &show_table_list);
2312
@brief Fill I_S table for SHOW Table NAMES commands
2314
@param[in] thd thread handler
2315
@param[in] table Table struct for I_S table
2316
@param[in] db_name database name
2317
@param[in] table_name table name
2318
@param[in] with_i_schema I_S table if true
2320
@return Operation status
2325
static int fill_schema_table_names(THD *thd, Table *table,
2326
LEX_STRING *db_name, LEX_STRING *table_name,
2331
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
2332
system_charset_info);
2336
enum legacy_db_type not_used;
2337
char path[FN_REFLEN];
2338
(void) build_table_filename(path, sizeof(path), db_name->str,
2339
table_name->str, reg_ext, 0);
2340
if (mysql_frm_type(thd, path, ¬_used))
2342
table->field[3]->store(STRING_WITH_LEN("BASE Table"),
2343
system_charset_info);
2347
table->field[3]->store(STRING_WITH_LEN("ERROR"),
2348
system_charset_info);
2351
if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2357
if (schema_table_store_record(thd, table))
2364
@brief Get open table method
2366
@details The function calculates the method which will be used
2368
SKIP_OPEN_TABLE - do not open table
2369
OPEN_FRM_ONLY - open FRM file only
2370
OPEN_FULL_TABLE - open FRM, data, index files
2371
@param[in] tables I_S table table_list
2372
@param[in] schema_table I_S table struct
2373
@param[in] schema_table_idx I_S table index
2375
@return return a set of flags
2376
@retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
2379
static uint32_t get_table_open_method(TableList *tables,
2380
ST_SCHEMA_TABLE *schema_table,
2381
enum enum_schema_tables schema_table_idx __attribute__((unused)))
2384
determine which method will be used for table opening
2386
if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
2388
Field **ptr, *field;
2389
int table_open_method= 0, field_indx= 0;
2390
for (ptr=tables->table->field; (field= *ptr) ; ptr++)
2392
if (bitmap_is_set(tables->table->read_set, field->field_index))
2393
table_open_method|= schema_table->fields_info[field_indx].open_method;
2396
return table_open_method;
2398
/* I_S tables which use get_all_tables but can not be optimized */
2399
return (uint) OPEN_FULL_TABLE;
2404
@brief Fill I_S table with data from FRM file only
2406
@param[in] thd thread handler
2407
@param[in] table Table struct for I_S table
2408
@param[in] schema_table I_S table struct
2409
@param[in] db_name database name
2410
@param[in] table_name table name
2411
@param[in] schema_table_idx I_S table index
2413
@return Operation status
2414
@retval 0 Table is processed and we can continue
2416
@retval 1 It's view and we have to use
2417
open_tables function for this table
2420
static int fill_schema_table_from_frm(THD *thd,TableList *tables,
2421
ST_SCHEMA_TABLE *schema_table,
2422
LEX_STRING *db_name,
2423
LEX_STRING *table_name,
2424
enum enum_schema_tables schema_table_idx __attribute__((unused)))
2426
Table *table= tables->table;
2429
TableList table_list;
2432
char key[MAX_DBKEY_LENGTH];
2433
uint32_t key_length;
2435
memset(&table_list, 0, sizeof(TableList));
2436
memset(&tbl, 0, sizeof(Table));
2438
table_list.table_name= table_name->str;
2439
table_list.db= db_name->str;
2441
key_length= create_table_def_key(thd, key, &table_list, 0);
2442
pthread_mutex_lock(&LOCK_open);
2443
share= get_table_share(thd, &table_list, key,
2444
key_length, 0, &error);
2453
table_list.table= &tbl;
2454
res= schema_table->process_table(thd, &table_list, table,
2455
res, db_name, table_name);
2458
release_table_share(share, RELEASE_NORMAL);
2461
pthread_mutex_unlock(&LOCK_open);
2469
@brief Fill I_S tables whose data are retrieved
2470
from frm files and storage engine
2472
@details The information schema tables are internally represented as
2473
temporary tables that are filled at query execution time.
2474
Those I_S tables whose data are retrieved
2475
from frm files and storage engine are filled by the function
2478
@param[in] thd thread handler
2479
@param[in] tables I_S table
2480
@param[in] cond 'WHERE' condition
2482
@return Operation status
2487
int get_all_tables(THD *thd, TableList *tables, COND *cond)
2490
Table *table= tables->table;
2491
SELECT_LEX *old_all_select_lex= lex->all_selects_list;
2492
enum_sql_command save_sql_command= lex->sql_command;
2493
SELECT_LEX *lsel= tables->schema_select_lex;
2494
ST_SCHEMA_TABLE *schema_table= tables->schema_table;
2496
LOOKUP_FIELD_VALUES lookup_field_vals;
2497
LEX_STRING *db_name, *table_name;
2499
enum enum_schema_tables schema_table_idx;
2500
List<LEX_STRING> db_names;
2501
List_iterator_fast<LEX_STRING> it(db_names);
2502
COND *partial_cond= 0;
2503
uint32_t derived_tables= lex->derived_tables;
2505
Open_tables_state open_tables_state_backup;
2506
Query_tables_list query_tables_list_backup;
2507
uint32_t table_open_method;
2508
bool old_value= thd->no_warnings_for_error;
2510
lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
2513
We should not introduce deadlocks even if we already have some
2514
tables open and locked, since we won't lock tables which we will
2515
open and will ignore possible name-locks for these tables.
2517
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
2519
schema_table_idx= get_schema_table_idx(schema_table);
2520
tables->table_open_method= table_open_method=
2521
get_table_open_method(tables, schema_table, schema_table_idx);
2523
this branch processes SHOW FIELDS, SHOW INDEXES commands.
2524
see sql_parse.cc, prepare_schema_table() function where
2525
this values are initialized
2527
if (lsel && lsel->table_list.first)
2529
error= fill_schema_show_cols_or_idxs(thd, tables, schema_table,
2530
&open_tables_state_backup);
2534
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2540
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
2543
if lookup value is empty string then
2544
it's impossible table name or db name
2546
if ((lookup_field_vals.db_value.str && !lookup_field_vals.db_value.str[0]) ||
2547
(lookup_field_vals.table_value.str && !lookup_field_vals.table_value.str[0]))
2554
if (lookup_field_vals.db_value.length &&
2555
!lookup_field_vals.wild_db_value)
2556
tables->has_db_lookup_value= true;
2557
if (lookup_field_vals.table_value.length &&
2558
!lookup_field_vals.wild_table_value)
2559
tables->has_table_lookup_value= true;
2561
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
2564
partial_cond= make_cond_for_info_schema(cond, tables);
2568
/* EXPLAIN SELECT */
2573
if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
2575
it.rewind(); /* To get access to new elements in basis list */
2576
while ((db_name= it++))
2579
thd->no_warnings_for_error= 1;
2580
List<LEX_STRING> table_names;
2581
int res= make_table_name_list(thd, &table_names, lex,
2583
with_i_schema, db_name);
2584
if (res == 2) /* Not fatal error, continue */
2589
List_iterator_fast<LEX_STRING> it_files(table_names);
2590
while ((table_name= it_files++))
2592
restore_record(table, s->default_values);
2593
table->field[schema_table->idx_field1]->
2594
store(db_name->str, db_name->length, system_charset_info);
2595
table->field[schema_table->idx_field2]->
2596
store(table_name->str, table_name->length, system_charset_info);
2598
if (!partial_cond || partial_cond->val_int())
2601
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
2602
we can skip table opening and we don't have lookup value for
2603
table name or lookup value is wild string(table name list is
2604
already created by make_table_name_list() function).
2606
if (!table_open_method && schema_table_idx == SCH_TABLES &&
2607
(!lookup_field_vals.table_value.length ||
2608
lookup_field_vals.wild_table_value))
2610
if (schema_table_store_record(thd, table))
2611
goto err; /* Out of space in temporary table */
2615
/* SHOW Table NAMES command */
2616
if (schema_table_idx == SCH_TABLE_NAMES)
2618
if (fill_schema_table_names(thd, tables->table, db_name,
2619
table_name, with_i_schema))
2624
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
2627
if (!fill_schema_table_from_frm(thd, tables, schema_table, db_name,
2628
table_name, schema_table_idx))
2633
LEX_STRING tmp_lex_string, orig_db_name;
2635
Set the parent lex of 'sel' because it is needed by
2636
sel.init_query() which is called inside make_table_list.
2638
thd->no_warnings_for_error= 1;
2639
sel.parent_lex= lex;
2640
/* db_name can be changed in make_table_list() func */
2641
if (!thd->make_lex_string(&orig_db_name, db_name->str,
2642
db_name->length, false))
2644
if (make_table_list(thd, &sel, db_name, table_name))
2646
TableList *show_table_list= (TableList*) sel.table_list.first;
2647
lex->all_selects_list= &sel;
2648
lex->derived_tables= 0;
2649
lex->sql_command= SQLCOM_SHOW_FIELDS;
2650
show_table_list->i_s_requested_object=
2651
schema_table->i_s_requested_object;
2652
res= open_normal_and_derived_tables(thd, show_table_list,
2653
DRIZZLE_LOCK_IGNORE_FLUSH);
2654
lex->sql_command= save_sql_command;
2656
XXX: show_table_list has a flag i_is_requested,
2657
and when it's set, open_normal_and_derived_tables()
2658
can return an error without setting an error message
2659
in THD, which is a hack. This is why we have to
2660
check for res, then for thd->is_error() only then
2661
for thd->main_da.sql_errno().
2663
if (res && thd->is_error() &&
2664
thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2667
Hide error for not existing table.
2668
This error can occur for example when we use
2669
where condition with db name and table name and this
2670
table does not exist.
2678
We should use show_table_list->alias instead of
2679
show_table_list->table_name because table_name
2680
could be changed during opening of I_S tables. It's safe
2681
to use alias because alias contains original table name
2684
thd->make_lex_string(&tmp_lex_string, show_table_list->alias,
2685
strlen(show_table_list->alias), false);
2686
res= schema_table->process_table(thd, show_table_list, table,
2689
close_tables_for_reopen(thd, &show_table_list);
2691
assert(!lex->query_tables_own_last);
2698
If we have information schema its always the first table and only
2699
the first table. Reset for other tables.
2707
thd->restore_backup_open_tables_state(&open_tables_state_backup);
2708
lex->restore_backup_query_tables_list(&query_tables_list_backup);
2709
lex->derived_tables= derived_tables;
2710
lex->all_selects_list= old_all_select_lex;
2711
lex->sql_command= save_sql_command;
2712
thd->no_warnings_for_error= old_value;
2717
bool store_schema_shemata(THD* thd, Table *table, LEX_STRING *db_name,
2718
const CHARSET_INFO * const cs)
2720
restore_record(table, s->default_values);
2721
table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2722
table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2723
table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2724
return schema_table_store_record(thd, table);
2728
int fill_schema_schemata(THD *thd, TableList *tables, COND *cond)
2731
TODO: fill_schema_shemata() is called when new client is connected.
2732
Returning error status in this case leads to client hangup.
2735
LOOKUP_FIELD_VALUES lookup_field_vals;
2736
List<LEX_STRING> db_names;
2737
LEX_STRING *db_name;
2739
HA_CREATE_INFO create;
2740
Table *table= tables->table;
2742
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2744
if (make_db_list(thd, &db_names, &lookup_field_vals,
2749
If we have lookup db value we should check that the database exists
2751
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
2754
char path[FN_REFLEN+16];
2756
struct stat stat_info;
2757
if (!lookup_field_vals.db_value.str[0])
2759
path_len= build_table_filename(path, sizeof(path),
2760
lookup_field_vals.db_value.str, "", "", 0);
2761
path[path_len-1]= 0;
2762
if (stat(path,&stat_info))
2766
List_iterator_fast<LEX_STRING> it(db_names);
2767
while ((db_name=it++))
2769
if (with_i_schema) // information schema name is always first in list
2771
if (store_schema_shemata(thd, table, db_name,
2772
system_charset_info))
2778
load_db_opt_by_name(thd, db_name->str, &create);
2779
if (store_schema_shemata(thd, table, db_name,
2780
create.default_table_charset))
2788
static int get_schema_tables_record(THD *thd, TableList *tables,
2789
Table *table, bool res,
2790
LEX_STRING *db_name,
2791
LEX_STRING *table_name)
2793
const char *tmp_buff;
2795
const CHARSET_INFO * const cs= system_charset_info;
2797
restore_record(table, s->default_values);
2798
table->field[1]->store(db_name->str, db_name->length, cs);
2799
table->field[2]->store(table_name->str, table_name->length, cs);
2803
there was errors during opening tables
2805
const char *error= thd->is_error() ? thd->main_da.message() : "";
2806
if (tables->schema_table)
2807
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2809
table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
2810
table->field[20]->store(error, strlen(error), cs);
2815
char option_buff[400],*ptr;
2816
Table *show_table= tables->table;
2817
TABLE_SHARE *share= show_table->s;
2818
handler *file= show_table->file;
2819
handlerton *tmp_db_type= share->db_type();
2820
if (share->tmp_table == SYSTEM_TMP_TABLE)
2821
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2822
else if (share->tmp_table)
2823
table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
2825
table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
2827
for (int i= 4; i < 20; i++)
2829
if (i == 7 || (i > 12 && i < 17) || i == 18)
2831
table->field[i]->set_notnull();
2833
tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
2834
table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
2835
table->field[5]->store((int64_t) share->frm_version, true);
2838
if (share->min_rows)
2840
ptr=my_stpcpy(ptr," min_rows=");
2841
ptr=int64_t10_to_str(share->min_rows,ptr,10);
2843
if (share->max_rows)
2845
ptr=my_stpcpy(ptr," max_rows=");
2846
ptr=int64_t10_to_str(share->max_rows,ptr,10);
2848
if (share->avg_row_length)
2850
ptr=my_stpcpy(ptr," avg_row_length=");
2851
ptr=int64_t10_to_str(share->avg_row_length,ptr,10);
2853
if (share->db_create_options & HA_OPTION_PACK_KEYS)
2854
ptr=my_stpcpy(ptr," pack_keys=1");
2855
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
2856
ptr=my_stpcpy(ptr," pack_keys=0");
2857
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2858
if (share->db_create_options & HA_OPTION_CHECKSUM)
2859
ptr=my_stpcpy(ptr," checksum=1");
2860
if (share->page_checksum != HA_CHOICE_UNDEF)
2861
ptr= strxmov(ptr, " page_checksum=",
2862
ha_choice_values[(uint) share->page_checksum], NULL);
2863
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
2864
ptr=my_stpcpy(ptr," delay_key_write=1");
2865
if (share->row_type != ROW_TYPE_DEFAULT)
2866
ptr=strxmov(ptr, " row_format=",
2867
ha_row_type[(uint) share->row_type],
2869
if (share->block_size)
2871
ptr= my_stpcpy(ptr, " block_size=");
2872
ptr= int64_t10_to_str(share->block_size, ptr, 10);
2875
if (share->transactional != HA_CHOICE_UNDEF)
2877
ptr= strxmov(ptr, " TRANSACTIONAL=",
2878
(share->transactional == HA_CHOICE_YES ? "1" : "0"),
2881
if (share->transactional != HA_CHOICE_UNDEF)
2882
ptr= strxmov(ptr, " transactional=",
2883
ha_choice_values[(uint) share->transactional], NULL);
2884
table->field[19]->store(option_buff+1,
2885
(ptr == option_buff ? 0 :
2886
(uint) (ptr-option_buff)-1), cs);
2888
tmp_buff= (share->table_charset ?
2889
share->table_charset->name : "default");
2890
table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
2892
if (share->comment.str)
2893
table->field[20]->store(share->comment.str, share->comment.length, cs);
2897
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
2899
enum row_type row_type = file->get_row_type();
2901
case ROW_TYPE_NOT_USED:
2902
case ROW_TYPE_DEFAULT:
2903
tmp_buff= ((share->db_options_in_use &
2904
HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
2905
(share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
2906
"Dynamic" : "Fixed");
2908
case ROW_TYPE_FIXED:
2911
case ROW_TYPE_DYNAMIC:
2912
tmp_buff= "Dynamic";
2914
case ROW_TYPE_COMPRESSED:
2915
tmp_buff= "Compressed";
2917
case ROW_TYPE_REDUNDANT:
2918
tmp_buff= "Redundant";
2920
case ROW_TYPE_COMPACT:
2921
tmp_buff= "Compact";
2927
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
2928
if (!tables->schema_table)
2930
table->field[7]->store((int64_t) file->stats.records, true);
2931
table->field[7]->set_notnull();
2933
table->field[8]->store((int64_t) file->stats.mean_rec_length, true);
2934
table->field[9]->store((int64_t) file->stats.data_file_length, true);
2935
if (file->stats.max_data_file_length)
2937
table->field[10]->store((int64_t) file->stats.max_data_file_length,
2940
table->field[11]->store((int64_t) file->stats.index_file_length, true);
2941
table->field[12]->store((int64_t) file->stats.delete_length, true);
2942
if (show_table->found_next_number_field)
2944
table->field[13]->store((int64_t) file->stats.auto_increment_value,
2946
table->field[13]->set_notnull();
2948
if (file->stats.create_time)
2950
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2951
(my_time_t) file->stats.create_time);
2952
table->field[14]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2953
table->field[14]->set_notnull();
2955
if (file->stats.update_time)
2957
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2958
(my_time_t) file->stats.update_time);
2959
table->field[15]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2960
table->field[15]->set_notnull();
2962
if (file->stats.check_time)
2964
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2965
(my_time_t) file->stats.check_time);
2966
table->field[16]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2967
table->field[16]->set_notnull();
2969
if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
2971
table->field[18]->store((int64_t) file->checksum(), true);
2972
table->field[18]->set_notnull();
2976
return(schema_table_store_record(thd, table));
2981
@brief Store field characteristics into appropriate I_S table columns
2983
@param[in] table I_S table
2984
@param[in] field processed field
2985
@param[in] cs I_S table charset
2986
@param[in] offset offset from beginning of table
2987
to DATE_TYPE column in I_S table
2992
void store_column_type(Table *table, Field *field, const CHARSET_INFO * const cs,
2996
int decimals, field_length;
2997
const char *tmp_buff;
2998
char column_type_buff[MAX_FIELD_WIDTH];
2999
String column_type(column_type_buff, sizeof(column_type_buff), cs);
3001
field->sql_type(column_type);
3002
/* DTD_IDENTIFIER column */
3003
table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs);
3004
table->field[offset + 7]->set_notnull();
3005
tmp_buff= strchr(column_type.ptr(), '(');
3006
/* DATA_TYPE column */
3007
table->field[offset]->store(column_type.ptr(),
3008
(tmp_buff ? tmp_buff - column_type.ptr() :
3009
column_type.length()), cs);
3010
is_blob= (field->type() == DRIZZLE_TYPE_BLOB);
3011
if (field->has_charset() || is_blob ||
3012
field->real_type() == DRIZZLE_TYPE_VARCHAR) // For varbinary type
3014
uint32_t octet_max_length= field->max_display_length();
3015
if (is_blob && octet_max_length != (uint32_t) 4294967295U)
3016
octet_max_length /= field->charset()->mbmaxlen;
3017
int64_t char_max_len= is_blob ?
3018
(int64_t) octet_max_length / field->charset()->mbminlen :
3019
(int64_t) octet_max_length / field->charset()->mbmaxlen;
3020
/* CHARACTER_MAXIMUM_LENGTH column*/
3021
table->field[offset + 1]->store(char_max_len, true);
3022
table->field[offset + 1]->set_notnull();
3023
/* CHARACTER_OCTET_LENGTH column */
3024
table->field[offset + 2]->store((int64_t) octet_max_length, true);
3025
table->field[offset + 2]->set_notnull();
3029
Calculate field_length and decimals.
3030
They are set to -1 if they should not be set (we should return NULL)
3033
decimals= field->decimals();
3034
switch (field->type()) {
3035
case DRIZZLE_TYPE_NEWDECIMAL:
3036
field_length= ((Field_new_decimal*) field)->precision;
3038
case DRIZZLE_TYPE_TINY:
3039
case DRIZZLE_TYPE_LONG:
3040
case DRIZZLE_TYPE_LONGLONG:
3041
field_length= field->max_display_length() - 1;
3043
case DRIZZLE_TYPE_DOUBLE:
3044
field_length= field->field_length;
3045
if (decimals == NOT_FIXED_DEC)
3046
decimals= -1; // return NULL
3049
field_length= decimals= -1;
3053
/* NUMERIC_PRECISION column */
3054
if (field_length >= 0)
3056
table->field[offset + 3]->store((int64_t) field_length, true);
3057
table->field[offset + 3]->set_notnull();
3059
/* NUMERIC_SCALE column */
3062
table->field[offset + 4]->store((int64_t) decimals, true);
3063
table->field[offset + 4]->set_notnull();
3065
if (field->has_charset())
3067
/* CHARACTER_SET_NAME column*/
3068
tmp_buff= field->charset()->csname;
3069
table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs);
3070
table->field[offset + 5]->set_notnull();
3071
/* COLLATION_NAME column */
3072
tmp_buff= field->charset()->name;
3073
table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs);
3074
table->field[offset + 6]->set_notnull();
3079
static int get_schema_column_record(THD *thd, TableList *tables,
3080
Table *table, bool res,
3081
LEX_STRING *db_name,
3082
LEX_STRING *table_name)
3085
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3086
const CHARSET_INFO * const cs= system_charset_info;
3088
TABLE_SHARE *show_table_share;
3089
Field **ptr, *field, *timestamp_field;
3094
if (lex->sql_command != SQLCOM_SHOW_FIELDS)
3097
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
3098
rather than in SHOW COLUMNS
3100
if (thd->is_error())
3101
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3102
thd->main_da.sql_errno(), thd->main_da.message());
3109
show_table= tables->table;
3110
show_table_share= show_table->s;
3113
if (tables->schema_table)
3115
ptr= show_table->field;
3116
timestamp_field= show_table->timestamp_field;
3117
show_table->use_all_columns(); // Required for default
3121
ptr= show_table_share->field;
3122
timestamp_field= show_table_share->timestamp_field;
3124
read_set may be inited in case of
3127
if (!show_table->read_set)
3129
/* to satisfy 'field->val_str' ASSERTs */
3130
unsigned char *bitmaps;
3131
uint32_t bitmap_size= show_table_share->column_bitmap_size;
3132
if (!(bitmaps= (unsigned char*) alloc_root(thd->mem_root, bitmap_size)))
3134
bitmap_init(&show_table->def_read_set,
3135
(my_bitmap_map*) bitmaps, show_table_share->fields, false);
3136
bitmap_set_all(&show_table->def_read_set);
3137
show_table->read_set= &show_table->def_read_set;
3139
bitmap_set_all(show_table->read_set);
3142
for (; (field= *ptr) ; ptr++)
3145
char tmp[MAX_FIELD_WIDTH];
3146
String type(tmp,sizeof(tmp), system_charset_info);
3149
/* to satisfy 'field->val_str' ASSERTs */
3150
field->table= show_table;
3151
show_table->in_use= thd;
3153
if (wild && wild[0] &&
3154
wild_case_compare(system_charset_info, field->field_name,wild))
3158
/* Get default row, with all NULL fields set to NULL */
3159
restore_record(table, s->default_values);
3161
table->field[1]->store(db_name->str, db_name->length, cs);
3162
table->field[2]->store(table_name->str, table_name->length, cs);
3163
table->field[3]->store(field->field_name, strlen(field->field_name),
3165
table->field[4]->store((int64_t) count, true);
3167
if (get_field_default_value(thd, timestamp_field, field, &type, 0))
3169
table->field[5]->store(type.ptr(), type.length(), cs);
3170
table->field[5]->set_notnull();
3172
pos=(unsigned char*) ((field->flags & NOT_NULL_FLAG) ? "NO" : "YES");
3173
table->field[6]->store((const char*) pos,
3174
strlen((const char*) pos), cs);
3175
store_column_type(table, field, cs, 7);
3177
pos=(unsigned char*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
3178
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
3179
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
3180
table->field[15]->store((const char*) pos,
3181
strlen((const char*) pos), cs);
3184
if (field->unireg_check == Field::NEXT_NUMBER)
3185
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
3186
if (timestamp_field == field &&
3187
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3188
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3190
if (field->vcol_info)
3191
table->field[16]->store(STRING_WITH_LEN("VIRTUAL"), cs);
3192
table->field[18]->store(field->comment.str, field->comment.length, cs);
3194
enum column_format_type column_format= (enum column_format_type)
3195
((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
3196
pos=(unsigned char*)"Default";
3197
table->field[19]->store((const char*) pos,
3198
strlen((const char*) pos), cs);
3199
pos=(unsigned char*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
3200
column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
3202
table->field[20]->store((const char*) pos,
3203
strlen((const char*) pos), cs);
3205
if (schema_table_store_record(thd, table))
3213
int fill_schema_charsets(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3216
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NULL;
3217
Table *table= tables->table;
3218
const CHARSET_INFO * const scs= system_charset_info;
3220
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3222
const CHARSET_INFO * const tmp_cs= cs[0];
3223
if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
3224
(tmp_cs->state & MY_CS_AVAILABLE) &&
3225
!(tmp_cs->state & MY_CS_HIDDEN) &&
3226
!(wild && wild[0] &&
3227
wild_case_compare(scs, tmp_cs->csname,wild)))
3229
const char *comment;
3230
restore_record(table, s->default_values);
3231
table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3232
table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3233
comment= tmp_cs->comment ? tmp_cs->comment : "";
3234
table->field[2]->store(comment, strlen(comment), scs);
3235
table->field[3]->store((int64_t) tmp_cs->mbmaxlen, true);
3236
if (schema_table_store_record(thd, table))
3244
int fill_schema_collation(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3247
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NULL;
3248
Table *table= tables->table;
3249
const CHARSET_INFO * const scs= system_charset_info;
3250
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3253
const CHARSET_INFO *tmp_cs= cs[0];
3254
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3255
(tmp_cs->state & MY_CS_HIDDEN) ||
3256
!(tmp_cs->state & MY_CS_PRIMARY))
3258
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3260
const CHARSET_INFO *tmp_cl= cl[0];
3261
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3262
!my_charset_same(tmp_cs, tmp_cl))
3264
if (!(wild && wild[0] &&
3265
wild_case_compare(scs, tmp_cl->name,wild)))
3267
const char *tmp_buff;
3268
restore_record(table, s->default_values);
3269
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3270
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3271
table->field[2]->store((int64_t) tmp_cl->number, true);
3272
tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
3273
table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
3274
tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
3275
table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
3276
table->field[5]->store((int64_t) tmp_cl->strxfrm_multiply, true);
3277
if (schema_table_store_record(thd, table))
3286
int fill_schema_coll_charset_app(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3289
Table *table= tables->table;
3290
const CHARSET_INFO * const scs= system_charset_info;
3291
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3294
const CHARSET_INFO *tmp_cs= cs[0];
3295
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3296
!(tmp_cs->state & MY_CS_PRIMARY))
3298
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3300
const CHARSET_INFO *tmp_cl= cl[0];
3301
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3302
!my_charset_same(tmp_cs,tmp_cl))
3304
restore_record(table, s->default_values);
3305
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3306
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3307
if (schema_table_store_record(thd, table))
3315
static int get_schema_stat_record(THD *thd, TableList *tables,
3316
Table *table, bool res,
3317
LEX_STRING *db_name,
3318
LEX_STRING *table_name)
3320
const CHARSET_INFO * const cs= system_charset_info;
3323
if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
3326
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
3327
rather than in SHOW KEYS
3329
if (thd->is_error())
3330
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3331
thd->main_da.sql_errno(), thd->main_da.message());
3339
Table *show_table= tables->table;
3340
KEY *key_info=show_table->s->key_info;
3341
if (show_table->file)
3342
show_table->file->info(HA_STATUS_VARIABLE |
3345
for (uint32_t i=0 ; i < show_table->s->keys ; i++,key_info++)
3347
KEY_PART_INFO *key_part= key_info->key_part;
3349
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
3351
restore_record(table, s->default_values);
3352
table->field[1]->store(db_name->str, db_name->length, cs);
3353
table->field[2]->store(table_name->str, table_name->length, cs);
3354
table->field[3]->store((int64_t) ((key_info->flags &
3355
HA_NOSAME) ? 0 : 1), true);
3356
table->field[4]->store(db_name->str, db_name->length, cs);
3357
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
3358
table->field[6]->store((int64_t) (j+1), true);
3359
str=(key_part->field ? key_part->field->field_name :
3361
table->field[7]->store(str, strlen(str), cs);
3362
if (show_table->file)
3364
if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
3366
table->field[8]->store(((key_part->key_part_flag &
3369
table->field[8]->set_notnull();
3371
KEY *key=show_table->key_info+i;
3372
if (key->rec_per_key[j])
3374
ha_rows records=(show_table->file->stats.records /
3375
key->rec_per_key[j]);
3376
table->field[9]->store((int64_t) records, true);
3377
table->field[9]->set_notnull();
3379
str= show_table->file->index_type(i);
3380
table->field[13]->store(str, strlen(str), cs);
3382
if ((key_part->field &&
3384
show_table->s->field[key_part->fieldnr-1]->key_length()))
3386
table->field[10]->store((int64_t) key_part->length /
3387
key_part->field->charset()->mbmaxlen, true);
3388
table->field[10]->set_notnull();
3390
uint32_t flags= key_part->field ? key_part->field->flags : 0;
3391
const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3392
table->field[12]->store(pos, strlen(pos), cs);
3393
if (!show_table->s->keys_in_use.is_set(i))
3394
table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3396
table->field[14]->store("", 0, cs);
3397
table->field[14]->set_notnull();
3398
assert(test(key_info->flags & HA_USES_COMMENT) ==
3399
(key_info->comment.length > 0));
3400
if (key_info->flags & HA_USES_COMMENT)
3401
table->field[15]->store(key_info->comment.str,
3402
key_info->comment.length, cs);
3403
if (schema_table_store_record(thd, table))
3412
bool store_constraints(THD *thd, Table *table, LEX_STRING *db_name,
3413
LEX_STRING *table_name, const char *key_name,
3414
uint32_t key_len, const char *con_type, uint32_t con_len)
3416
const CHARSET_INFO * const cs= system_charset_info;
3417
restore_record(table, s->default_values);
3418
table->field[1]->store(db_name->str, db_name->length, cs);
3419
table->field[2]->store(key_name, key_len, cs);
3420
table->field[3]->store(db_name->str, db_name->length, cs);
3421
table->field[4]->store(table_name->str, table_name->length, cs);
3422
table->field[5]->store(con_type, con_len, cs);
3423
return schema_table_store_record(thd, table);
3427
static int get_schema_constraints_record(THD *thd, TableList *tables,
3428
Table *table, bool res,
3429
LEX_STRING *db_name,
3430
LEX_STRING *table_name)
3434
if (thd->is_error())
3435
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3436
thd->main_da.sql_errno(), thd->main_da.message());
3442
List<FOREIGN_KEY_INFO> f_key_list;
3443
Table *show_table= tables->table;
3444
KEY *key_info=show_table->key_info;
3445
uint32_t primary_key= show_table->s->primary_key;
3446
show_table->file->info(HA_STATUS_VARIABLE |
3449
for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3451
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3454
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
3456
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3457
strlen(key_info->name),
3458
STRING_WITH_LEN("PRIMARY KEY")))
3461
else if (key_info->flags & HA_NOSAME)
3463
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3464
strlen(key_info->name),
3465
STRING_WITH_LEN("UNIQUE")))
3470
show_table->file->get_foreign_key_list(thd, &f_key_list);
3471
FOREIGN_KEY_INFO *f_key_info;
3472
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3473
while ((f_key_info=it++))
3475
if (store_constraints(thd, table, db_name, table_name,
3476
f_key_info->forein_id->str,
3477
strlen(f_key_info->forein_id->str),
3486
void store_key_column_usage(Table *table, LEX_STRING *db_name,
3487
LEX_STRING *table_name, const char *key_name,
3488
uint32_t key_len, const char *con_type, uint32_t con_len,
3491
const CHARSET_INFO * const cs= system_charset_info;
3492
table->field[1]->store(db_name->str, db_name->length, cs);
3493
table->field[2]->store(key_name, key_len, cs);
3494
table->field[4]->store(db_name->str, db_name->length, cs);
3495
table->field[5]->store(table_name->str, table_name->length, cs);
3496
table->field[6]->store(con_type, con_len, cs);
3497
table->field[7]->store((int64_t) idx, true);
3501
static int get_schema_key_column_usage_record(THD *thd,
3503
Table *table, bool res,
3504
LEX_STRING *db_name,
3505
LEX_STRING *table_name)
3509
if (thd->is_error())
3510
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3511
thd->main_da.sql_errno(), thd->main_da.message());
3517
List<FOREIGN_KEY_INFO> f_key_list;
3518
Table *show_table= tables->table;
3519
KEY *key_info=show_table->key_info;
3520
uint32_t primary_key= show_table->s->primary_key;
3521
show_table->file->info(HA_STATUS_VARIABLE |
3524
for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3526
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3529
KEY_PART_INFO *key_part= key_info->key_part;
3530
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
3532
if (key_part->field)
3535
restore_record(table, s->default_values);
3536
store_key_column_usage(table, db_name, table_name,
3538
strlen(key_info->name),
3539
key_part->field->field_name,
3540
strlen(key_part->field->field_name),
3542
if (schema_table_store_record(thd, table))
3548
show_table->file->get_foreign_key_list(thd, &f_key_list);
3549
FOREIGN_KEY_INFO *f_key_info;
3550
List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
3551
while ((f_key_info= fkey_it++))
3555
List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
3556
it1(f_key_info->referenced_fields);
3558
while ((f_info= it++))
3562
restore_record(table, s->default_values);
3563
store_key_column_usage(table, db_name, table_name,
3564
f_key_info->forein_id->str,
3565
f_key_info->forein_id->length,
3566
f_info->str, f_info->length,
3568
table->field[8]->store((int64_t) f_idx, true);
3569
table->field[8]->set_notnull();
3570
table->field[9]->store(f_key_info->referenced_db->str,
3571
f_key_info->referenced_db->length,
3572
system_charset_info);
3573
table->field[9]->set_notnull();
3574
table->field[10]->store(f_key_info->referenced_table->str,
3575
f_key_info->referenced_table->length,
3576
system_charset_info);
3577
table->field[10]->set_notnull();
3578
table->field[11]->store(r_info->str, r_info->length,
3579
system_charset_info);
3580
table->field[11]->set_notnull();
3581
if (schema_table_store_record(thd, table))
3590
int fill_open_tables(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3592
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NULL;
3593
Table *table= tables->table;
3594
const CHARSET_INFO * const cs= system_charset_info;
3595
OPEN_TableList *open_list;
3596
if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
3597
&& thd->is_fatal_error)
3600
for (; open_list ; open_list=open_list->next)
3602
restore_record(table, s->default_values);
3603
table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3604
table->field[1]->store(open_list->table, strlen(open_list->table), cs);
3605
table->field[2]->store((int64_t) open_list->in_use, true);
3606
table->field[3]->store((int64_t) open_list->locked, true);
3607
if (schema_table_store_record(thd, table))
3614
int fill_variables(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3618
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3619
enum enum_schema_tables schema_table_idx=
3620
get_schema_table_idx(tables->schema_table);
3621
enum enum_var_type option_type= OPT_SESSION;
3622
bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
3623
bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
3625
if (lex->option_type == OPT_GLOBAL ||
3626
schema_table_idx == SCH_GLOBAL_VARIABLES)
3627
option_type= OPT_GLOBAL;
3629
rw_rdlock(&LOCK_system_variables_hash);
3630
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
3631
option_type, NULL, "", tables->table, upper_case_names);
3632
rw_unlock(&LOCK_system_variables_hash);
3637
int fill_status(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3640
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3642
STATUS_VAR *tmp1, tmp;
3643
enum enum_schema_tables schema_table_idx=
3644
get_schema_table_idx(tables->schema_table);
3645
enum enum_var_type option_type;
3646
bool upper_case_names= (schema_table_idx != SCH_STATUS);
3648
if (schema_table_idx == SCH_STATUS)
3650
option_type= lex->option_type;
3651
if (option_type == OPT_GLOBAL)
3654
tmp1= thd->initial_status_var;
3656
else if (schema_table_idx == SCH_GLOBAL_STATUS)
3658
option_type= OPT_GLOBAL;
3663
option_type= OPT_SESSION;
3664
tmp1= &thd->status_var;
3667
pthread_mutex_lock(&LOCK_status);
3668
if (option_type == OPT_GLOBAL)
3669
calc_sum_of_all_status(&tmp);
3670
res= show_status_array(thd, wild,
3671
(SHOW_VAR *)all_status_vars.buffer,
3672
option_type, tmp1, "", tables->table,
3674
pthread_mutex_unlock(&LOCK_status);
3680
Fill and store records into I_S.referential_constraints table
3683
get_referential_constraints_record()
3685
tables table list struct(processed table)
3687
res 1 means the error during opening of the processed table
3688
0 means processed table is opened without error
3690
file_name table name
3698
get_referential_constraints_record(THD *thd, TableList *tables,
3699
Table *table, bool res,
3700
LEX_STRING *db_name, LEX_STRING *table_name)
3702
const CHARSET_INFO * const cs= system_charset_info;
3706
if (thd->is_error())
3707
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3708
thd->main_da.sql_errno(), thd->main_da.message());
3714
List<FOREIGN_KEY_INFO> f_key_list;
3715
Table *show_table= tables->table;
3716
show_table->file->info(HA_STATUS_VARIABLE |
3720
show_table->file->get_foreign_key_list(thd, &f_key_list);
3721
FOREIGN_KEY_INFO *f_key_info;
3722
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3723
while ((f_key_info= it++))
3725
restore_record(table, s->default_values);
3726
table->field[1]->store(db_name->str, db_name->length, cs);
3727
table->field[9]->store(table_name->str, table_name->length, cs);
3728
table->field[2]->store(f_key_info->forein_id->str,
3729
f_key_info->forein_id->length, cs);
3730
table->field[4]->store(f_key_info->referenced_db->str,
3731
f_key_info->referenced_db->length, cs);
3732
table->field[10]->store(f_key_info->referenced_table->str,
3733
f_key_info->referenced_table->length, cs);
3734
if (f_key_info->referenced_key_name)
3736
table->field[5]->store(f_key_info->referenced_key_name->str,
3737
f_key_info->referenced_key_name->length, cs);
3738
table->field[5]->set_notnull();
3741
table->field[5]->set_null();
3742
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3743
table->field[7]->store(f_key_info->update_method->str,
3744
f_key_info->update_method->length, cs);
3745
table->field[8]->store(f_key_info->delete_method->str,
3746
f_key_info->delete_method->length, cs);
3747
if (schema_table_store_record(thd, table))
3755
struct schema_table_ref
3757
const char *table_name;
3758
ST_SCHEMA_TABLE *schema_table;
3763
Find schema_tables elment by name
3766
find_schema_table_in_plugin()
3769
table_name table name
3773
1 found the schema table
3775
static bool find_schema_table_in_plugin(THD *thd __attribute__((unused)),
3779
schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
3780
const char* table_name= p_schema_table->table_name;
3781
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
3783
if (!my_strcasecmp(system_charset_info,
3784
schema_table->table_name,
3786
p_schema_table->schema_table= schema_table;
3795
Find schema_tables elment by name
3800
table_name table name
3804
# pointer to 'schema_tables' element
3807
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
3809
schema_table_ref schema_table_a;
3810
ST_SCHEMA_TABLE *schema_table= schema_tables;
3812
for (; schema_table->table_name; schema_table++)
3814
if (!my_strcasecmp(system_charset_info,
3815
schema_table->table_name,
3817
return(schema_table);
3820
schema_table_a.table_name= table_name;
3821
if (plugin_foreach(thd, find_schema_table_in_plugin,
3822
DRIZZLE_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
3823
return(schema_table_a.schema_table);
3829
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
3831
return &schema_tables[schema_table_idx];
3836
Create information_schema table using schema_table data.
3843
@param table_list Used to pass I_S table information(fields info, tables
3844
parameters etc) and table name.
3846
@retval \# Pointer to created table
3847
@retval NULL Can't create table
3850
Table *create_schema_table(THD *thd, TableList *table_list)
3855
List<Item> field_list;
3856
ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
3857
ST_FIELD_INFO *fields_info= schema_table->fields_info;
3858
const CHARSET_INFO * const cs= system_charset_info;
3860
for (; fields_info->field_name; fields_info++)
3862
switch (fields_info->field_type) {
3863
case DRIZZLE_TYPE_TINY:
3864
case DRIZZLE_TYPE_LONG:
3865
case DRIZZLE_TYPE_LONGLONG:
3866
if (!(item= new Item_return_int(fields_info->field_name,
3867
fields_info->field_length,
3868
fields_info->field_type,
3869
fields_info->value)))
3873
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3875
case DRIZZLE_TYPE_NEWDATE:
3876
case DRIZZLE_TYPE_TIME:
3877
case DRIZZLE_TYPE_TIMESTAMP:
3878
case DRIZZLE_TYPE_DATETIME:
3879
if (!(item=new Item_return_date_time(fields_info->field_name,
3880
fields_info->field_type)))
3885
case DRIZZLE_TYPE_DOUBLE:
3886
if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
3887
fields_info->field_length)) == NULL)
3890
case DRIZZLE_TYPE_NEWDECIMAL:
3891
if (!(item= new Item_decimal((int64_t) fields_info->value, false)))
3895
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3896
item->decimals= fields_info->field_length%10;
3897
item->max_length= (fields_info->field_length/100)%100;
3898
if (item->unsigned_flag == 0)
3899
item->max_length+= 1;
3900
if (item->decimals > 0)
3901
item->max_length+= 1;
3902
item->set_name(fields_info->field_name,
3903
strlen(fields_info->field_name), cs);
3905
case DRIZZLE_TYPE_BLOB:
3906
if (!(item= new Item_blob(fields_info->field_name,
3907
fields_info->field_length)))
3913
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
3917
item->set_name(fields_info->field_name,
3918
strlen(fields_info->field_name), cs);
3921
field_list.push_back(item);
3922
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
3925
TMP_TABLE_PARAM *tmp_table_param =
3926
(TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
3927
tmp_table_param->init();
3928
tmp_table_param->table_charset= cs;
3929
tmp_table_param->field_count= field_count;
3930
tmp_table_param->schema_table= 1;
3931
SELECT_LEX *select_lex= thd->lex->current_select;
3932
if (!(table= create_tmp_table(thd, tmp_table_param,
3933
field_list, (order_st*) 0, 0, 0,
3934
(select_lex->options | thd->options |
3935
TMP_TABLE_ALL_COLUMNS),
3936
HA_POS_ERROR, table_list->alias)))
3938
my_bitmap_map* bitmaps=
3939
(my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
3940
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
3942
table->read_set= &table->def_read_set;
3943
bitmap_clear_all(table->read_set);
3944
table_list->schema_table_param= tmp_table_param;
3950
For old SHOW compatibility. It is used when
3951
old SHOW doesn't have generated column names
3952
Make list of fields for SHOW
3957
schema_table pointer to 'schema_tables' element
3964
int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
3966
ST_FIELD_INFO *field_info= schema_table->fields_info;
3967
Name_resolution_context *context= &thd->lex->select_lex.context;
3968
for (; field_info->field_name; field_info++)
3970
if (field_info->old_name)
3972
Item_field *field= new Item_field(context,
3973
NULL, NULL, field_info->field_name);
3976
field->set_name(field_info->old_name,
3977
strlen(field_info->old_name),
3978
system_charset_info);
3979
if (add_item_to_list(thd, field))
3988
int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
3992
SELECT_LEX *sel= lex->current_select;
3993
Name_resolution_context *context= &sel->context;
3995
if (!sel->item_list.elements)
3997
ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
3998
String buffer(tmp,sizeof(tmp), system_charset_info);
3999
Item_field *field= new Item_field(context,
4000
NULL, NULL, field_info->field_name);
4001
if (!field || add_item_to_list(thd, field))
4004
buffer.append(field_info->old_name);
4005
if (lex->wild && lex->wild->ptr())
4007
buffer.append(STRING_WITH_LEN(" ("));
4008
buffer.append(lex->wild->ptr());
4011
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4017
int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4020
String buffer(tmp,sizeof(tmp), thd->charset());
4022
Name_resolution_context *context= &lex->select_lex.context;
4024
ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
4026
buffer.append(field_info->old_name);
4027
buffer.append(lex->select_lex.db);
4028
if (lex->wild && lex->wild->ptr())
4030
buffer.append(STRING_WITH_LEN(" ("));
4031
buffer.append(lex->wild->ptr());
4034
Item_field *field= new Item_field(context,
4035
NULL, NULL, field_info->field_name);
4036
if (add_item_to_list(thd, field))
4038
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4039
if (thd->lex->verbose)
4041
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4042
field_info= &schema_table->fields_info[3];
4043
field= new Item_field(context, NULL, NULL, field_info->field_name);
4044
if (add_item_to_list(thd, field))
4046
field->set_name(field_info->old_name, strlen(field_info->old_name),
4047
system_charset_info);
4053
int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4055
int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
4056
int *field_num= fields_arr;
4057
ST_FIELD_INFO *field_info;
4058
Name_resolution_context *context= &thd->lex->select_lex.context;
4060
for (; *field_num >= 0; field_num++)
4062
field_info= &schema_table->fields_info[*field_num];
4063
if (!thd->lex->verbose && (*field_num == 13 ||
4067
Item_field *field= new Item_field(context,
4068
NULL, NULL, field_info->field_name);
4071
field->set_name(field_info->old_name,
4072
strlen(field_info->old_name),
4073
system_charset_info);
4074
if (add_item_to_list(thd, field))
4082
int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4084
int fields_arr[]= {0, 2, 1, 3, -1};
4085
int *field_num= fields_arr;
4086
ST_FIELD_INFO *field_info;
4087
Name_resolution_context *context= &thd->lex->select_lex.context;
4089
for (; *field_num >= 0; field_num++)
4091
field_info= &schema_table->fields_info[*field_num];
4092
Item_field *field= new Item_field(context,
4093
NULL, NULL, field_info->field_name);
4096
field->set_name(field_info->old_name,
4097
strlen(field_info->old_name),
4098
system_charset_info);
4099
if (add_item_to_list(thd, field))
4108
Create information_schema table
4111
mysql_schema_table()
4114
table_list pointer to table_list
4121
int mysql_schema_table(THD *thd, LEX *lex, TableList *table_list)
4124
if (!(table= table_list->schema_table->create_table(thd, table_list)))
4126
table->s->tmp_table= SYSTEM_TMP_TABLE;
4128
This test is necessary to make
4129
case insensitive file systems +
4130
upper case table names(information schema tables) +
4134
if (table_list->schema_table_name)
4135
table->alias_name_used= my_strcasecmp(table_alias_charset,
4136
table_list->schema_table_name,
4138
table_list->table_name= table->s->table_name.str;
4139
table_list->table_name_length= table->s->table_name.length;
4140
table_list->table= table;
4141
table->next= thd->derived_tables;
4142
thd->derived_tables= table;
4143
table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
4145
if (table_list->schema_table_reformed) // show command
4147
SELECT_LEX *sel= lex->current_select;
4149
Field_translator *transl, *org_transl;
4151
if (table_list->field_translation)
4153
Field_translator *end= table_list->field_translation_end;
4154
for (transl= table_list->field_translation; transl < end; transl++)
4156
if (!transl->item->fixed &&
4157
transl->item->fix_fields(thd, &transl->item))
4162
List_iterator_fast<Item> it(sel->item_list);
4164
(Field_translator*)(thd->alloc(sel->item_list.elements *
4165
sizeof(Field_translator)))))
4169
for (org_transl= transl; (item= it++); transl++)
4172
transl->name= item->name;
4173
if (!item->fixed && item->fix_fields(thd, &transl->item))
4178
table_list->field_translation= org_transl;
4179
table_list->field_translation_end= transl;
4187
Generate select from information_schema table
4190
make_schema_select()
4192
sel pointer to SELECT_LEX
4193
schema_table_idx index of 'schema_tables' element
4200
int make_schema_select(THD *thd, SELECT_LEX *sel,
4201
enum enum_schema_tables schema_table_idx)
4203
ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
4204
LEX_STRING db, table;
4206
We have to make non const db_name & table_name
4207
because of lower_case_table_names
4209
thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str,
4210
INFORMATION_SCHEMA_NAME.length, 0);
4211
thd->make_lex_string(&table, schema_table->table_name,
4212
strlen(schema_table->table_name), 0);
4213
if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
4214
!sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
4224
Fill temporary schema tables before SELECT
4227
get_schema_tables_result()
4228
join join which use schema tables
4229
executed_place place where I_S table processed
4236
bool get_schema_tables_result(JOIN *join,
4237
enum enum_schema_table_state executed_place)
4239
JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
4240
THD *thd= join->thd;
4244
thd->no_warnings_for_error= 1;
4245
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
4247
if (!tab->table || !tab->table->pos_in_table_list)
4250
TableList *table_list= tab->table->pos_in_table_list;
4251
if (table_list->schema_table)
4253
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
4254
lex->current_select->master_unit()->item);
4257
/* skip I_S optimizations specific to get_all_tables */
4258
if (thd->lex->describe &&
4259
(table_list->schema_table->fill_table != get_all_tables))
4263
If schema table is already processed and
4264
the statement is not a subselect then
4265
we don't need to fill this table again.
4266
If schema table is already processed and
4267
schema_table_state != executed_place then
4268
table is already processed and
4269
we should skip second data processing.
4271
if (table_list->schema_table_state &&
4272
(!is_subselect || table_list->schema_table_state != executed_place))
4276
if table is used in a subselect and
4277
table has been processed earlier with the same
4278
'executed_place' value then we should refresh the table.
4280
if (table_list->schema_table_state && is_subselect)
4282
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
4283
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
4284
table_list->table->file->ha_delete_all_rows();
4285
free_io_cache(table_list->table);
4286
filesort_free_buffers(table_list->table,1);
4287
table_list->table->null_row= 0;
4290
table_list->table->file->stats.records= 0;
4292
if (table_list->schema_table->fill_table(thd, table_list,
4297
tab->read_record.file= table_list->table->file;
4298
table_list->schema_table_state= executed_place;
4301
tab->read_record.file= table_list->table->file;
4302
table_list->schema_table_state= executed_place;
4305
thd->no_warnings_for_error= 0;
4309
ST_FIELD_INFO schema_fields_info[]=
4311
{"CATALOG_NAME", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4312
{"SCHEMA_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4314
{"DEFAULT_CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4316
{"DEFAULT_COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4317
{"SQL_PATH", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4318
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4322
ST_FIELD_INFO tables_fields_info[]=
4324
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4325
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4326
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4328
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4329
{"ENGINE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Engine", OPEN_FRM_ONLY},
4330
{"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4331
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
4332
{"ROW_FORMAT", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Row_format", OPEN_FULL_TABLE},
4333
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4334
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
4335
{"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4336
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
4337
{"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4338
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
4339
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4340
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
4341
{"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4342
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
4343
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4344
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
4345
{"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG, 0,
4346
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
4347
{"CREATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4348
{"UPDATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4349
{"CHECK_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
4350
{"TABLE_COLLATION", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4351
{"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4352
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
4353
{"CREATE_OPTIONS", 255, DRIZZLE_TYPE_VARCHAR, 0, 1, "Create_options",
4355
{"TABLE_COMMENT", TABLE_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4356
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4360
ST_FIELD_INFO columns_fields_info[]=
4362
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4363
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4364
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4365
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Field",
4367
{"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4368
MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
4369
{"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, DRIZZLE_TYPE_VARCHAR, 0,
4370
1, "Default", OPEN_FRM_ONLY},
4371
{"IS_NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4372
{"DATA_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4373
{"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4374
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4375
{"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4376
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4377
{"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4378
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4379
{"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4380
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4381
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4382
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4383
{"COLUMN_TYPE", 65535, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", OPEN_FRM_ONLY},
4384
{"COLUMN_KEY", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key", OPEN_FRM_ONLY},
4385
{"EXTRA", 27, DRIZZLE_TYPE_VARCHAR, 0, 0, "Extra", OPEN_FRM_ONLY},
4386
{"PRIVILEGES", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Privileges", OPEN_FRM_ONLY},
4387
{"COLUMN_COMMENT", COLUMN_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4388
{"STORAGE", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Storage", OPEN_FRM_ONLY},
4389
{"FORMAT", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Format", OPEN_FRM_ONLY},
4390
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4394
ST_FIELD_INFO charsets_fields_info[]=
4396
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4398
{"DEFAULT_COLLATE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default collation",
4400
{"DESCRIPTION", 60, DRIZZLE_TYPE_VARCHAR, 0, 0, "Description",
4402
{"MAXLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
4403
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4407
ST_FIELD_INFO collation_fields_info[]=
4409
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Collation", SKIP_OPEN_TABLE},
4410
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4412
{"ID", MY_INT32_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id",
4414
{"IS_DEFAULT", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default", SKIP_OPEN_TABLE},
4415
{"IS_COMPILED", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Compiled", SKIP_OPEN_TABLE},
4416
{"SORTLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
4417
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4422
ST_FIELD_INFO coll_charset_app_fields_info[]=
4424
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4425
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4426
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4430
ST_FIELD_INFO stat_fields_info[]=
4432
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4433
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4434
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", OPEN_FRM_ONLY},
4435
{"NON_UNIQUE", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
4436
{"INDEX_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4437
{"INDEX_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key_name",
4439
{"SEQ_IN_INDEX", 2, DRIZZLE_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
4440
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Column_name",
4442
{"COLLATION", 1, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4443
{"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 1,
4444
"Cardinality", OPEN_FULL_TABLE},
4445
{"SUB_PART", 3, DRIZZLE_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
4446
{"PACKED", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Packed", OPEN_FRM_ONLY},
4447
{"NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4448
{"INDEX_TYPE", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_type", OPEN_FULL_TABLE},
4449
{"COMMENT", 16, DRIZZLE_TYPE_VARCHAR, 0, 1, "Comment", OPEN_FRM_ONLY},
4450
{"INDEX_COMMENT", INDEX_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_Comment", OPEN_FRM_ONLY},
4451
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4455
ST_FIELD_INFO table_constraints_fields_info[]=
4457
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4458
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4460
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4462
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4463
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4464
{"CONSTRAINT_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4466
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4470
ST_FIELD_INFO key_column_usage_fields_info[]=
4472
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4473
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4475
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4477
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4478
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4479
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4480
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4481
{"ORDINAL_POSITION", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
4482
{"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 1, 0,
4484
{"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4486
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4488
{"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4490
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4494
ST_FIELD_INFO table_names_fields_info[]=
4496
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4497
{"TABLE_SCHEMA",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4498
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Tables_in_",
4500
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table_type",
4502
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4506
ST_FIELD_INFO open_tables_fields_info[]=
4508
{"Database", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4510
{"Table",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", SKIP_OPEN_TABLE},
4511
{"In_use", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
4512
{"Name_locked", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
4513
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4517
ST_FIELD_INFO variables_fields_info[]=
4519
{"VARIABLE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Variable_name",
4521
{"VARIABLE_VALUE", 16300, DRIZZLE_TYPE_VARCHAR, 0, 1, "Value", SKIP_OPEN_TABLE},
4522
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4526
ST_FIELD_INFO processlist_fields_info[]=
4528
{"ID", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
4529
{"USER", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "User", SKIP_OPEN_TABLE},
4530
{"HOST", LIST_PROCESS_HOST_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Host",
4532
{"DB", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Db", SKIP_OPEN_TABLE},
4533
{"COMMAND", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Command", SKIP_OPEN_TABLE},
4534
{"TIME", 7, DRIZZLE_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
4535
{"STATE", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "State", SKIP_OPEN_TABLE},
4536
{"INFO", PROCESS_LIST_INFO_WIDTH, DRIZZLE_TYPE_VARCHAR, 0, 1, "Info",
4538
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4542
ST_FIELD_INFO plugin_fields_info[]=
4544
{"PLUGIN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4546
{"PLUGIN_VERSION", 20, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4547
{"PLUGIN_STATUS", 10, DRIZZLE_TYPE_VARCHAR, 0, 0, "Status", SKIP_OPEN_TABLE},
4548
{"PLUGIN_TYPE", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", SKIP_OPEN_TABLE},
4549
{"PLUGIN_LIBRARY", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Library",
4551
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4552
{"PLUGIN_DESCRIPTION", 65535, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4553
{"PLUGIN_LICENSE", 80, DRIZZLE_TYPE_VARCHAR, 0, 1, "License", SKIP_OPEN_TABLE},
4554
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4557
ST_FIELD_INFO referential_constraints_fields_info[]=
4559
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4560
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4562
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4564
{"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4566
{"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4568
{"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0,
4569
MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
4570
{"MATCH_OPTION", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4571
{"UPDATE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4572
{"DELETE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4573
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4574
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4576
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4581
Description of ST_FIELD_INFO in table.h
4583
Make sure that the order of schema_tables and enum_schema_tables are the same.
4587
ST_SCHEMA_TABLE schema_tables[]=
4589
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
4590
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4591
{"COLLATIONS", collation_fields_info, create_schema_table,
4592
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4593
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4594
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4595
{"COLUMNS", columns_fields_info, create_schema_table,
4596
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
4597
OPTIMIZE_I_S_TABLE},
4598
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4599
fill_status, make_old_format, 0, -1, -1, 0, 0},
4600
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
4601
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4602
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
4603
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
4605
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
4606
fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
4607
{"PLUGINS", plugin_fields_info, create_schema_table,
4608
fill_plugins, make_old_format, 0, -1, -1, 0, 0},
4609
{"PROCESSLIST", processlist_fields_info, create_schema_table,
4610
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
4611
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
4612
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
4613
1, 9, 0, OPEN_TABLE_ONLY},
4614
{"SCHEMATA", schema_fields_info, create_schema_table,
4615
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
4616
{"SESSION_STATUS", variables_fields_info, create_schema_table,
4617
fill_status, make_old_format, 0, -1, -1, 0, 0},
4618
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4619
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4620
{"STATISTICS", stat_fields_info, create_schema_table,
4621
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4622
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4623
{"STATUS", variables_fields_info, create_schema_table, fill_status,
4624
make_old_format, 0, -1, -1, 1, 0},
4625
{"TABLES", tables_fields_info, create_schema_table,
4626
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4627
OPTIMIZE_I_S_TABLE},
4628
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4629
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
4630
{"TABLE_NAMES", table_names_fields_info, create_schema_table,
4631
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
4632
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
4633
make_old_format, 0, -1, -1, 1, 0},
4634
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
4638
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
4639
template class List_iterator_fast<char>;
4640
template class List<char>;
4643
int initialize_schema_table(st_plugin_int *plugin)
4645
ST_SCHEMA_TABLE *schema_table;
4647
if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
4648
MYF(MY_WME | MY_ZEROFILL))))
4650
/* Historical Requirement */
4651
plugin->data= schema_table; // shortcut for the future
4652
if (plugin->plugin->init)
4654
schema_table->create_table= create_schema_table;
4655
schema_table->old_format= make_old_format;
4656
schema_table->idx_field1= -1,
4657
schema_table->idx_field2= -1;
4659
/* Make the name available to the init() function. */
4660
schema_table->table_name= plugin->name.str;
4662
if (plugin->plugin->init(schema_table))
4664
sql_print_error(_("Plugin '%s' init function returned error."),
4669
/* Make sure the plugin name is not set inside the init() function. */
4670
schema_table->table_name= plugin->name.str;
4679
int finalize_schema_table(st_plugin_int *plugin)
4681
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
4683
if (schema_table && plugin->plugin->deinit)