122
538
# Quote character
125
int get_quote_char_for_identifier()
132
bool buildScemas(Session *session)
134
session->getLex()->sql_command= SQLCOM_SELECT;
135
session->getLex()->statement= new statement::Show(session);
137
std::string column_name= "Database";
138
if (session->getLex()->wild)
140
column_name.append(" (");
141
column_name.append(session->getLex()->wild->ptr());
142
column_name.append(")");
145
if (session->getLex()->current_select->where)
147
if (prepare_new_schema_table(session, session->getLex(), "SCHEMAS"))
152
if (prepare_new_schema_table(session, session->getLex(), "SHOW_SCHEMAS"))
156
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "SCHEMA_NAME");
157
my_field->is_autogenerated_name= false;
158
my_field->set_name(column_name.c_str(), column_name.length(), system_charset_info);
160
if (session->add_item_to_list(my_field))
163
if (session->add_order_to_list(my_field, true))
169
bool buildTables(Session *session, const char *ident)
171
session->getLex()->sql_command= SQLCOM_SELECT;
173
drizzled::statement::Show *select= new statement::Show(session);
174
session->getLex()->statement= select;
176
std::string column_name= "Tables_in_";
178
util::string::const_shared_ptr schema(session->schema());
181
identifier::Schema identifier(ident);
182
column_name.append(ident);
183
session->getLex()->select_lex.db= const_cast<char *>(ident);
184
if (not plugin::StorageEngine::doesSchemaExist(identifier))
186
my_error(ER_BAD_DB_ERROR, MYF(0), ident);
188
select->setShowPredicate(ident, "");
190
else if (schema and not schema->empty())
192
column_name.append(*schema);
193
select->setShowPredicate(*schema, "");
197
my_error(ER_NO_DB_ERROR, MYF(0));
202
if (session->getLex()->wild)
204
column_name.append(" (");
205
column_name.append(session->getLex()->wild->ptr());
206
column_name.append(")");
209
if (prepare_new_schema_table(session, session->getLex(), "SHOW_TABLES"))
212
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "TABLE_NAME");
213
my_field->is_autogenerated_name= false;
214
my_field->set_name(column_name.c_str(), column_name.length(), system_charset_info);
216
if (session->add_item_to_list(my_field))
219
if (session->add_order_to_list(my_field, true))
225
bool buildTemporaryTables(Session *session)
227
session->getLex()->sql_command= SQLCOM_SELECT;
229
session->getLex()->statement= new statement::Show(session);
232
if (prepare_new_schema_table(session, session->getLex(), "SHOW_TEMPORARY_TABLES"))
235
if (session->add_item_to_list( new Item_field(&session->lex->current_select->context, NULL, NULL, "*")))
238
(session->lex->current_select->with_wild)++;
243
bool buildTableStatus(Session *session, const char *ident)
245
session->getLex()->sql_command= SQLCOM_SELECT;
246
drizzled::statement::Show *select= new statement::Show(session);
247
session->getLex()->statement= select;
249
std::string column_name= "Tables_in_";
251
util::string::const_shared_ptr schema(session->schema());
254
session->getLex()->select_lex.db= const_cast<char *>(ident);
256
identifier::Schema identifier(ident);
257
if (not plugin::StorageEngine::doesSchemaExist(identifier))
259
my_error(ER_BAD_DB_ERROR, MYF(0), ident);
262
select->setShowPredicate(ident, "");
266
select->setShowPredicate(*schema, "");
270
my_error(ER_NO_DB_ERROR, MYF(0));
274
if (prepare_new_schema_table(session, session->getLex(), "SHOW_TABLE_STATUS"))
277
if (session->add_item_to_list( new Item_field(&session->lex->current_select->
282
(session->lex->current_select->with_wild)++;
287
bool buildEngineStatus(Session *session, LEX_STRING)
289
session->getLex()->sql_command= SQLCOM_SELECT;
290
drizzled::statement::Show *select= new statement::Show(session);
291
session->getLex()->statement= select;
293
my_error(ER_USE_DATA_DICTIONARY);
297
bool buildColumns(Session *session, const char *schema_ident, Table_ident *table_ident)
299
session->getLex()->sql_command= SQLCOM_SELECT;
301
drizzled::statement::Show *select= new statement::Show(session);
302
session->getLex()->statement= select;
304
util::string::const_shared_ptr schema(session->schema());
307
select->setShowPredicate(schema_ident, table_ident->table.str);
309
else if (table_ident->db.str)
311
select->setShowPredicate(table_ident->db.str, table_ident->table.str);
315
select->setShowPredicate(*schema, table_ident->table.str);
319
my_error(ER_NO_DB_ERROR, MYF(0));
324
drizzled::identifier::Table identifier(select->getShowSchema().c_str(), table_ident->table.str);
325
if (not plugin::StorageEngine::doesTableExist(*session, identifier))
327
my_error(ER_TABLE_UNKNOWN, identifier);
331
if (prepare_new_schema_table(session, session->getLex(), "SHOW_COLUMNS"))
334
if (session->add_item_to_list( new Item_field(&session->lex->current_select->context, NULL, NULL, "*")))
337
(session->lex->current_select->with_wild)++;
342
void buildSelectWarning(Session *session)
344
(void) create_select_for_variable(session, "warning_count");
345
session->getLex()->statement= new statement::Show(session);
348
void buildSelectError(Session *session)
350
(void) create_select_for_variable(session, "error_count");
351
session->getLex()->statement= new statement::Show(session);
354
void buildWarnings(Session *session)
356
session->getLex()->statement= new statement::ShowWarnings(session);
359
void buildErrors(Session *session)
361
session->getLex()->statement= new statement::ShowErrors(session);
364
bool buildIndex(Session *session, const char *schema_ident, Table_ident *table_ident)
366
session->getLex()->sql_command= SQLCOM_SELECT;
367
drizzled::statement::Show *select= new statement::Show(session);
368
session->getLex()->statement= select;
370
util::string::const_shared_ptr schema(session->schema());
373
select->setShowPredicate(schema_ident, table_ident->table.str);
375
else if (table_ident->db.str)
377
select->setShowPredicate(table_ident->db.str, table_ident->table.str);
381
select->setShowPredicate(*schema, table_ident->table.str);
385
my_error(ER_NO_DB_ERROR, MYF(0));
390
drizzled::identifier::Table identifier(select->getShowSchema().c_str(), table_ident->table.str);
391
if (not plugin::StorageEngine::doesTableExist(*session, identifier))
393
my_error(ER_TABLE_UNKNOWN, identifier);
397
if (prepare_new_schema_table(session, session->getLex(), "SHOW_INDEXES"))
400
if (session->add_item_to_list( new Item_field(&session->lex->current_select->context, NULL, NULL, "*")))
403
(session->lex->current_select->with_wild)++;
408
bool buildStatus(Session *session, const drizzled::sql_var_t is_global)
410
session->getLex()->sql_command= SQLCOM_SELECT;
411
session->getLex()->statement= new statement::Show(session);
413
if (is_global == OPT_GLOBAL)
415
if (prepare_new_schema_table(session, session->getLex(), "GLOBAL_STATUS"))
420
if (prepare_new_schema_table(session, session->getLex(), "SESSION_STATUS"))
424
std::string key("Variable_name");
425
std::string value("Value");
427
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "VARIABLE_NAME");
428
my_field->is_autogenerated_name= false;
429
my_field->set_name(key.c_str(), key.length(), system_charset_info);
431
if (session->add_item_to_list(my_field))
434
my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "VARIABLE_VALUE");
435
my_field->is_autogenerated_name= false;
436
my_field->set_name(value.c_str(), value.length(), system_charset_info);
438
if (session->add_item_to_list(my_field))
444
bool buildCreateTable(Session *session, Table_ident *ident)
446
session->getLex()->sql_command= SQLCOM_SELECT;
447
statement::Show *select= new statement::Show(session);
448
session->getLex()->statement= select;
450
if (session->getLex()->statement == NULL)
453
if (prepare_new_schema_table(session, session->getLex(), "TABLE_SQL_DEFINITION"))
456
util::string::const_shared_ptr schema(session->schema());
459
select->setShowPredicate(ident->db.str, ident->table.str);
463
select->setShowPredicate(*schema, ident->table.str);
467
my_error(ER_NO_DB_ERROR, MYF(0));
471
std::string key("Table");
472
std::string value("Create Table");
474
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "TABLE_NAME");
475
my_field->is_autogenerated_name= false;
476
my_field->set_name(key.c_str(), key.length(), system_charset_info);
478
if (session->add_item_to_list(my_field))
481
my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "TABLE_SQL_DEFINITION");
482
my_field->is_autogenerated_name= false;
483
my_field->set_name(value.c_str(), value.length(), system_charset_info);
485
if (session->add_item_to_list(my_field))
491
bool buildProcesslist(Session *session)
493
session->getLex()->sql_command= SQLCOM_SELECT;
494
session->getLex()->statement= new statement::Show(session);
496
if (prepare_new_schema_table(session, session->getLex(), "PROCESSLIST"))
499
if (session->add_item_to_list( new Item_field(&session->lex->current_select->context, NULL, NULL, "*")))
502
(session->lex->current_select->with_wild)++;
507
bool buildVariables(Session *session, const drizzled::sql_var_t is_global)
509
session->getLex()->sql_command= SQLCOM_SELECT;
510
session->getLex()->statement= new statement::Show(session);
512
if (is_global == OPT_GLOBAL)
514
if (prepare_new_schema_table(session, session->getLex(), "GLOBAL_VARIABLES"))
519
if (prepare_new_schema_table(session, session->getLex(), "SESSION_VARIABLES"))
523
std::string key("Variable_name");
524
std::string value("Value");
526
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "VARIABLE_NAME");
527
my_field->is_autogenerated_name= false;
528
my_field->set_name(key.c_str(), key.length(), system_charset_info);
530
if (session->add_item_to_list(my_field))
533
my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "VARIABLE_VALUE");
534
my_field->is_autogenerated_name= false;
535
my_field->set_name(value.c_str(), value.length(), system_charset_info);
537
if (session->add_item_to_list(my_field))
543
bool buildCreateSchema(Session *session, LEX_STRING &ident)
545
session->getLex()->sql_command= SQLCOM_SELECT;
546
drizzled::statement::Show *select= new statement::Show(session);
547
session->getLex()->statement= select;
549
if (prepare_new_schema_table(session, session->getLex(), "SCHEMA_SQL_DEFINITION"))
552
util::string::const_shared_ptr schema(session->schema());
555
select->setShowPredicate(ident.str);
559
select->setShowPredicate(*schema);
563
my_error(ER_NO_DB_ERROR, MYF(0));
567
std::string key("Database");
568
std::string value("Create Database");
570
Item_field *my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "SCHEMA_NAME");
571
my_field->is_autogenerated_name= false;
572
my_field->set_name(key.c_str(), key.length(), system_charset_info);
574
if (session->add_item_to_list(my_field))
577
my_field= new Item_field(&session->lex->current_select->context, NULL, NULL, "SCHEMA_SQL_DEFINITION");
578
my_field->is_autogenerated_name= false;
579
my_field->set_name(value.c_str(), value.length(), system_charset_info);
581
if (session->add_item_to_list(my_field))
587
bool buildDescribe(Session *session, Table_ident *ident)
589
session->getLex()->lock_option= TL_READ;
590
init_select(session->getLex());
591
session->getLex()->current_select->parsing_place= SELECT_LIST;
592
session->getLex()->sql_command= SQLCOM_SELECT;
593
drizzled::statement::Show *select= new statement::Show(session);
594
session->getLex()->statement= select;
595
session->getLex()->select_lex.db= 0;
597
util::string::const_shared_ptr schema(session->schema());
600
select->setShowPredicate(ident->db.str, ident->table.str);
604
select->setShowPredicate(*schema, ident->table.str);
608
my_error(ER_NO_DB_ERROR, MYF(0));
613
drizzled::identifier::Table identifier(select->getShowSchema().c_str(), ident->table.str);
614
if (not plugin::StorageEngine::doesTableExist(*session, identifier))
616
my_error(ER_TABLE_UNKNOWN, identifier);
620
if (prepare_new_schema_table(session, session->getLex(), "SHOW_COLUMNS"))
625
if (session->add_item_to_list( new Item_field(&session->lex->current_select->
632
(session->lex->current_select->with_wild)++;
637
} /* namespace drizzled */
639
} /* namespace drizzled */
541
int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
544
!is_keyword(name,length) &&
545
!require_quotes(name, length) &&
546
!(thd->options & OPTION_QUOTE_SHOW_CREATE))
552
/* Append directory name (if exists) to CREATE INFO */
554
static void append_directory(THD *thd __attribute__((__unused__)),
555
String *packet, const char *dir_type,
556
const char *filename)
560
uint length= dirname_length(filename);
562
packet->append(dir_type);
563
packet->append(STRING_WITH_LEN(" DIRECTORY='"));
564
packet->append(filename, length);
565
packet->append('\'');
570
#define LIST_PROCESS_HOST_LEN 64
572
static bool get_field_default_value(THD *thd __attribute__((__unused__)),
573
Field *timestamp_field,
574
Field *field, String *def_value,
578
bool has_now_default;
581
We are using CURRENT_TIMESTAMP instead of NOW because it is
584
has_now_default= (timestamp_field == field &&
585
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
587
has_default= (field->type() != FIELD_TYPE_BLOB &&
588
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
589
field->unireg_check != Field::NEXT_NUMBER
592
def_value->length(0);
596
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
597
else if (!field->is_null())
598
{ // Not null by default
599
char tmp[MAX_FIELD_WIDTH];
600
String type(tmp, sizeof(tmp), field->charset());
601
field->val_str(&type);
606
/* convert to system_charset_info == utf8 */
607
def_val.copy(type.ptr(), type.length(), field->charset(),
608
system_charset_info, &dummy_errors);
610
append_unescaped(def_value, def_val.ptr(), def_val.length());
612
def_value->append(def_val.ptr(), def_val.length());
615
def_value->append(STRING_WITH_LEN("''"));
617
else if (field->maybe_null() && quoted)
618
def_value->append(STRING_WITH_LEN("NULL")); // Null as default
627
Build a CREATE TABLE statement for a table.
632
table_list A list containing one table to write statement
634
packet Pointer to a string where statement will be
636
create_info_arg Pointer to create information that can be used
637
to tailor the format of the statement. Can be
638
NULL, in which case only SQL_MODE is considered
639
when building the statement.
642
Currently always return 0, but might return error code in the
649
int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
650
HA_CREATE_INFO *create_info_arg)
652
List<Item> field_list;
653
char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
655
String type(tmp, sizeof(tmp), system_charset_info);
656
String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
660
TABLE *table= table_list->table;
661
handler *file= table->file;
662
TABLE_SHARE *share= table->s;
663
HA_CREATE_INFO create_info;
664
bool show_table_options= false;
665
my_bitmap_map *old_map;
667
restore_record(table, s->default_values); // Get empty record
669
if (share->tmp_table)
670
packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
672
packet->append(STRING_WITH_LEN("CREATE TABLE "));
673
if (create_info_arg &&
674
(create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
675
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
676
if (table_list->schema_table)
677
alias= table_list->schema_table->table_name;
680
if (lower_case_table_names == 2)
684
alias= share->table_name.str;
687
append_identifier(thd, packet, alias, strlen(alias));
688
packet->append(STRING_WITH_LEN(" (\n"));
690
We need this to get default values from the table
691
We have to restore the read_set if we are called from insert in case
692
of row based replication.
694
old_map= tmp_use_all_columns(table, table->read_set);
696
for (ptr=table->field ; (field= *ptr); ptr++)
698
uint flags = field->flags;
700
if (ptr != table->field)
701
packet->append(STRING_WITH_LEN(",\n"));
703
packet->append(STRING_WITH_LEN(" "));
704
append_identifier(thd,packet,field->field_name, strlen(field->field_name));
706
// check for surprises from the previous call to Field::sql_type()
707
if (type.ptr() != tmp)
708
type.set(tmp, sizeof(tmp), system_charset_info);
710
type.set_charset(system_charset_info);
712
field->sql_type(type);
713
packet->append(type.ptr(), type.length(), system_charset_info);
715
if (field->has_charset())
717
if (field->charset() != share->table_charset)
719
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
720
packet->append(field->charset()->csname);
723
For string types dump collation name only if
724
collation is not primary for the given charset
726
if (!(field->charset()->state & MY_CS_PRIMARY))
728
packet->append(STRING_WITH_LEN(" COLLATE "));
729
packet->append(field->charset()->name);
733
if (flags & NOT_NULL_FLAG)
734
packet->append(STRING_WITH_LEN(" NOT NULL"));
735
else if (field->type() == MYSQL_TYPE_TIMESTAMP)
738
TIMESTAMP field require explicit NULL flag, because unlike
739
all other fields they are treated as NOT NULL by default.
741
packet->append(STRING_WITH_LEN(" NULL"));
745
Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
746
and about STORAGE (DISK or MEMORY).
748
enum column_format_type column_format= (enum column_format_type)
749
((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
752
packet->append(STRING_WITH_LEN(" /*!"));
753
packet->append(STRING_WITH_LEN(MYSQL_VERSION_TABLESPACE_IN_FRM_STR));
754
packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
755
if (column_format == COLUMN_FORMAT_TYPE_FIXED)
756
packet->append(STRING_WITH_LEN(" FIXED */"));
758
packet->append(STRING_WITH_LEN(" DYNAMIC */"));
761
if (get_field_default_value(thd, table->timestamp_field,
762
field, &def_value, 1))
764
packet->append(STRING_WITH_LEN(" DEFAULT "));
765
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
768
if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
769
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
771
if (field->unireg_check == Field::NEXT_NUMBER)
772
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
774
if (field->comment.length)
776
packet->append(STRING_WITH_LEN(" COMMENT "));
777
append_unescaped(packet, field->comment.str, field->comment.length);
781
key_info= table->key_info;
782
bzero((char*) &create_info, sizeof(create_info));
783
/* Allow update_create_info to update row type */
784
create_info.row_type= share->row_type;
785
file->update_create_info(&create_info);
786
primary_key= share->primary_key;
788
for (uint i=0 ; i < share->keys ; i++,key_info++)
790
KEY_PART_INFO *key_part= key_info->key_part;
791
bool found_primary=0;
792
packet->append(STRING_WITH_LEN(",\n "));
794
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
798
No space at end, because a space will be added after where the
799
identifier would go, but that is not added for primary key.
801
packet->append(STRING_WITH_LEN("PRIMARY KEY"));
803
else if (key_info->flags & HA_NOSAME)
804
packet->append(STRING_WITH_LEN("UNIQUE KEY "));
806
packet->append(STRING_WITH_LEN("KEY "));
809
append_identifier(thd, packet, key_info->name, strlen(key_info->name));
811
packet->append(STRING_WITH_LEN(" ("));
813
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
819
append_identifier(thd,packet,key_part->field->field_name,
820
strlen(key_part->field->field_name));
821
if (key_part->field &&
823
table->field[key_part->fieldnr-1]->key_length()))
827
end= int10_to_str((long) key_part->length /
828
key_part->field->charset()->mbmaxlen,
831
packet->append(buff,(uint) (end-buff));
835
store_key_options(thd, packet, table, key_info);
839
Get possible foreign key definitions stored in InnoDB and append them
840
to the CREATE TABLE statement
843
if ((for_str= file->get_foreign_key_create_info()))
845
packet->append(for_str, strlen(for_str));
846
file->free_foreign_key_create_info(for_str);
849
packet->append(STRING_WITH_LEN("\n)"));
851
show_table_options= true;
853
Get possible table space definitions and append them
854
to the CREATE TABLE statement
859
THEN add ENGINE only if it was used when creating the table
861
if (!create_info_arg ||
862
(create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
864
packet->append(STRING_WITH_LEN(" ENGINE="));
865
packet->append(file->table_type());
869
Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
870
and NEXT_ID > 1 (the default). We must not print the clause
871
for engines that do not support this as it would break the
872
import of dumps, but as of this writing, the test for whether
873
AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
874
is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
875
Because of that, we do not explicitly test for the feature,
876
but may extrapolate its existence from that of an AUTO_INCREMENT column.
879
if (create_info.auto_increment_value > 1)
882
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
883
end= int64_t10_to_str(create_info.auto_increment_value, buff,10);
884
packet->append(buff, (uint) (end - buff));
888
if (share->table_charset)
892
THEN add DEFAULT CHARSET only if it was used when creating the table
894
if (!create_info_arg ||
895
(create_info_arg->used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
897
packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
898
packet->append(share->table_charset->csname);
899
if (!(share->table_charset->state & MY_CS_PRIMARY))
901
packet->append(STRING_WITH_LEN(" COLLATE="));
902
packet->append(table->s->table_charset->name);
910
packet->append(STRING_WITH_LEN(" MIN_ROWS="));
911
end= int64_t10_to_str(share->min_rows, buff, 10);
912
packet->append(buff, (uint) (end- buff));
915
if (share->max_rows && !table_list->schema_table)
918
packet->append(STRING_WITH_LEN(" MAX_ROWS="));
919
end= int64_t10_to_str(share->max_rows, buff, 10);
920
packet->append(buff, (uint) (end - buff));
923
if (share->avg_row_length)
926
packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
927
end= int64_t10_to_str(share->avg_row_length, buff,10);
928
packet->append(buff, (uint) (end - buff));
931
if (share->db_create_options & HA_OPTION_PACK_KEYS)
932
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
933
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
934
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
935
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
936
if (share->db_create_options & HA_OPTION_CHECKSUM)
937
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
938
if (share->page_checksum != HA_CHOICE_UNDEF)
940
packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
941
packet->append(ha_choice_values[(uint) share->page_checksum], 1);
943
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
944
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
945
if (create_info.row_type != ROW_TYPE_DEFAULT)
947
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
948
packet->append(ha_row_type[(uint) create_info.row_type]);
950
if (share->transactional != HA_CHOICE_UNDEF)
952
packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
953
packet->append(ha_choice_values[(uint) share->transactional], 1);
955
if (table->s->key_block_size)
958
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
959
end= int64_t10_to_str(table->s->key_block_size, buff, 10);
960
packet->append(buff, (uint) (end - buff));
962
table->file->append_create_info(packet);
963
if (share->comment.length)
965
packet->append(STRING_WITH_LEN(" COMMENT="));
966
append_unescaped(packet, share->comment.str, share->comment.length);
968
if (share->connect_string.length)
970
packet->append(STRING_WITH_LEN(" CONNECTION="));
971
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
973
append_directory(thd, packet, "DATA", create_info.data_file_name);
974
append_directory(thd, packet, "INDEX", create_info.index_file_name);
976
tmp_restore_column_map(table->read_set, old_map);
981
Get a CREATE statement for a given database.
983
The database is identified by its name, passed as @c dbname parameter.
984
The name should be encoded using the system character set (UTF8 currently).
986
Resulting statement is stored in the string pointed by @c buffer. The string
987
is emptied first and its character set is set to the system character set.
989
If HA_LEX_CREATE_IF_NOT_EXISTS flag is set in @c create_info->options, then
990
the resulting CREATE statement contains "IF NOT EXISTS" clause. Other flags
991
in @c create_options are ignored.
993
@param thd The current thread instance.
994
@param dbname The name of the database.
995
@param buffer A String instance where the statement is stored.
996
@param create_info If not NULL, the options member influences the resulting
999
@returns true if errors are detected, false otherwise.
1002
bool store_db_create_info(THD *thd, const char *dbname, String *buffer,
1003
HA_CREATE_INFO *create_info)
1005
HA_CREATE_INFO create;
1006
uint create_options = create_info ? create_info->options : 0;
1008
if (!my_strcasecmp(system_charset_info, dbname,
1009
INFORMATION_SCHEMA_NAME.str))
1011
dbname= INFORMATION_SCHEMA_NAME.str;
1012
create.default_table_charset= system_charset_info;
1016
if (check_db_dir_existence(dbname))
1019
load_db_opt_by_name(thd, dbname, &create);
1024
buffer->set_charset(system_charset_info);
1025
buffer->append(STRING_WITH_LEN("CREATE DATABASE "));
1027
if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
1028
buffer->append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
1030
append_identifier(thd, buffer, dbname, strlen(dbname));
1032
if (create.default_table_charset)
1034
buffer->append(STRING_WITH_LEN(" /*!40100"));
1035
buffer->append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
1036
buffer->append(create.default_table_charset->csname);
1037
if (!(create.default_table_charset->state & MY_CS_PRIMARY))
1039
buffer->append(STRING_WITH_LEN(" COLLATE "));
1040
buffer->append(create.default_table_charset->name);
1042
buffer->append(STRING_WITH_LEN(" */"));
1048
static void store_key_options(THD *thd __attribute__((__unused__)),
1049
String *packet, TABLE *table,
1052
char *end, buff[32];
1054
if (key_info->algorithm == HA_KEY_ALG_BTREE)
1055
packet->append(STRING_WITH_LEN(" USING BTREE"));
1057
if (key_info->algorithm == HA_KEY_ALG_HASH)
1058
packet->append(STRING_WITH_LEN(" USING HASH"));
1060
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
1061
table->s->key_block_size != key_info->block_size)
1063
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
1064
end= int64_t10_to_str(key_info->block_size, buff, 10);
1065
packet->append(buff, (uint) (end - buff));
1068
assert(test(key_info->flags & HA_USES_COMMENT) ==
1069
(key_info->comment.length > 0));
1070
if (key_info->flags & HA_USES_COMMENT)
1072
packet->append(STRING_WITH_LEN(" COMMENT "));
1073
append_unescaped(packet, key_info->comment.str,
1074
key_info->comment.length);
1079
/****************************************************************************
1080
Return info about all processes
1081
returns for each thread: thread id, user, host, db, command, info
1082
****************************************************************************/
1084
class thread_info :public ilink {
1086
static void *operator new(size_t size)
1088
return (void*) sql_alloc((uint) size);
1090
static void operator delete(void *ptr __attribute__((unused)),
1091
size_t size __attribute__((unused)))
1092
{ TRASH(ptr, size); }
1097
const char *user,*host,*db,*proc_info,*state_info;
1101
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1102
template class I_List<thread_info>;
1105
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
1108
List<Item> field_list;
1109
I_List<thread_info> thread_infos;
1110
ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
1111
PROCESS_LIST_WIDTH);
1112
Protocol *protocol= thd->protocol;
1114
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1115
field_list.push_back(new Item_empty_string("User",16));
1116
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1117
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1118
field->maybe_null=1;
1119
field_list.push_back(new Item_empty_string("Command",16));
1120
field_list.push_back(new Item_return_int("Time",7, MYSQL_TYPE_LONG));
1121
field_list.push_back(field=new Item_empty_string("State",30));
1122
field->maybe_null=1;
1123
field_list.push_back(field=new Item_empty_string("Info",max_query_length));
1124
field->maybe_null=1;
1125
if (protocol->send_fields(&field_list,
1126
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1129
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
1132
I_List_iterator<THD> it(threads);
1136
Security_context *tmp_sctx= tmp->security_ctx;
1137
struct st_my_thread_var *mysys_var;
1138
if ((tmp->vio_ok() || tmp->system_thread) && (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
1140
thread_info *thd_info= new thread_info;
1142
thd_info->thread_id=tmp->thread_id;
1143
thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
1144
(tmp->system_thread ?
1145
"system user" : "unauthenticated user"));
1146
thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
1147
tmp_sctx->host_or_ip :
1148
tmp_sctx->host ? tmp_sctx->host : "");
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 ? NullS :
1159
"Reading from net") :
1160
tmp->proc_info ? tmp->proc_info :
1162
tmp->mysys_var->current_cond ?
1163
"Waiting on cond" : NullS);
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
uint length= min(max_query_length, tmp->query_length);
1177
thd_info->query=(char*) thd->strmake(tmp->query,length);
1179
thread_infos.append(thd_info);
1183
VOID(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, TABLE_LIST* tables,
1212
COND* cond __attribute__((__unused__)))
1214
TABLE *table= tables->table;
1215
CHARSET_INFO *cs= system_charset_info;
1217
time_t now= my_time(0);
1221
VOID(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->host_or_ip,
1246
strlen(tmp_sctx->host_or_ip), cs);
1250
table->field[3]->store(tmp->db, strlen(tmp->db), cs);
1251
table->field[3]->set_notnull();
1254
if ((mysys_var= tmp->mysys_var))
1255
pthread_mutex_lock(&mysys_var->mutex);
1257
if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
1258
table->field[4]->store(val, strlen(val), cs);
1260
table->field[4]->store(command_name[tmp->command].str,
1261
command_name[tmp->command].length, cs);
1263
table->field[5]->store((uint32_t)(tmp->start_time ?
1264
now - tmp->start_time : 0), true);
1266
val= (char*) (tmp->net.reading_or_writing ?
1267
(tmp->net.reading_or_writing == 2 ?
1269
tmp->command == COM_SLEEP ? NullS :
1270
"Reading from net") :
1271
tmp->proc_info ? tmp->proc_info :
1273
tmp->mysys_var->current_cond ?
1274
"Waiting on cond" : NullS);
1277
table->field[6]->store(val, strlen(val), cs);
1278
table->field[6]->set_notnull();
1282
pthread_mutex_unlock(&mysys_var->mutex);
1287
table->field[7]->store(tmp->query,
1288
min(PROCESS_LIST_INFO_WIDTH,
1289
tmp->query_length), cs);
1290
table->field[7]->set_notnull();
1293
if (schema_table_store_record(thd, table))
1295
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1301
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1305
/*****************************************************************************
1307
*****************************************************************************/
1309
static DYNAMIC_ARRAY all_status_vars;
1310
static bool status_vars_inited= 0;
1311
static int show_var_cmp(const void *var1, const void *var2)
1313
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1317
deletes all the SHOW_UNDEF elements from the array and calls
1318
delete_dynamic() if it's completely empty.
1320
static void shrink_var_array(DYNAMIC_ARRAY *array)
1323
SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
1325
for (a= b= 0; b < array->elements; b++)
1326
if (all[b].type != SHOW_UNDEF)
1330
bzero(all+a, sizeof(SHOW_VAR)); // writing NULL-element to the end
1333
else // array is completely empty - delete it
1334
delete_dynamic(array);
1338
Adds an array of SHOW_VAR entries to the output of SHOW STATUS
1341
add_status_vars(SHOW_VAR *list)
1342
list - an array of SHOW_VAR entries to add to all_status_vars
1343
the last entry must be {0,0,SHOW_UNDEF}
1346
The handling of all_status_vars[] is completely internal, it's allocated
1347
automatically when something is added to it, and deleted completely when
1348
the last entry is removed.
1350
As a special optimization, if add_status_vars() is called before
1351
init_status_vars(), it assumes "startup mode" - neither concurrent access
1352
to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
1354
The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
1356
int add_status_vars(SHOW_VAR *list)
1359
if (status_vars_inited)
1360
pthread_mutex_lock(&LOCK_status);
1361
if (!all_status_vars.buffer && // array is not allocated yet - do it now
1362
my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
1368
res|= insert_dynamic(&all_status_vars, (uchar*)list++);
1369
res|= insert_dynamic(&all_status_vars, (uchar*)list); // appending NULL-element
1370
all_status_vars.elements--; // but next insert_dynamic should overwite it
1371
if (status_vars_inited)
1372
sort_dynamic(&all_status_vars, show_var_cmp);
1374
if (status_vars_inited)
1375
pthread_mutex_unlock(&LOCK_status);
1380
Make all_status_vars[] usable for SHOW STATUS
1383
See add_status_vars(). Before init_status_vars() call, add_status_vars()
1384
works in a special fast "startup" mode. Thus init_status_vars()
1385
should be called as late as possible but before enabling multi-threading.
1387
void init_status_vars()
1389
status_vars_inited=1;
1390
sort_dynamic(&all_status_vars, show_var_cmp);
1393
void reset_status_vars()
1395
SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
1396
SHOW_VAR *last= ptr + all_status_vars.elements;
1397
for (; ptr < last; ptr++)
1399
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
1400
if (ptr->type == SHOW_LONG)
1401
*(ulong*) ptr->value= 0;
1406
catch-all cleanup function, cleans up everything no matter what
1409
This function is not strictly required if all add_to_status/
1410
remove_status_vars are properly paired, but it's a safety measure that
1411
deletes everything from the all_status_vars[] even if some
1412
remove_status_vars were forgotten
1414
void free_status_vars()
1416
delete_dynamic(&all_status_vars);
1420
Removes an array of SHOW_VAR entries from the output of SHOW STATUS
1423
remove_status_vars(SHOW_VAR *list)
1424
list - an array of SHOW_VAR entries to remove to all_status_vars
1425
the last entry must be {0,0,SHOW_UNDEF}
1428
there's lots of room for optimizing this, especially in non-sorted mode,
1429
but nobody cares - it may be called only in case of failed plugin
1430
initialization in the mysqld startup.
1433
void remove_status_vars(SHOW_VAR *list)
1435
if (status_vars_inited)
1437
pthread_mutex_lock(&LOCK_status);
1438
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1439
int a= 0, b= all_status_vars.elements, c= (a+b)/2;
1441
for (; list->name; list++)
1444
for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
1446
res= show_var_cmp(list, all+c);
1455
all[c].type= SHOW_UNDEF;
1457
shrink_var_array(&all_status_vars);
1458
pthread_mutex_unlock(&LOCK_status);
1462
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1464
for (; list->name; list++)
1466
for (i= 0; i < all_status_vars.elements; i++)
1468
if (show_var_cmp(list, all+i))
1470
all[i].type= SHOW_UNDEF;
1474
shrink_var_array(&all_status_vars);
1478
inline void make_upper(char *buf)
1481
*buf= my_toupper(system_charset_info, *buf);
1484
static bool show_status_array(THD *thd, const char *wild,
1485
SHOW_VAR *variables,
1486
enum enum_var_type value_type,
1487
struct system_status_var *status_var,
1488
const char *prefix, TABLE *table,
1491
MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
1492
char * const buff= (char *) &buff_data;
1494
/* the variable name should not be longer than 64 characters */
1495
char name_buffer[64];
1497
LEX_STRING null_lex_str;
1500
null_lex_str.str= 0; // For sys_var->value_ptr()
1501
null_lex_str.length= 0;
1503
prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
1506
len=name_buffer + sizeof(name_buffer) - prefix_end;
1508
for (; variables->name; variables++)
1510
strnmov(prefix_end, variables->name, len);
1511
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
1513
make_upper(name_buffer);
1516
if var->type is SHOW_FUNC, call the function.
1517
Repeat as necessary, if new var is again SHOW_FUNC
1519
for (var=variables; var->type == SHOW_FUNC; var= &tmp)
1520
((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(thd, &tmp, buff);
1522
SHOW_TYPE show_type=var->type;
1523
if (show_type == SHOW_ARRAY)
1525
show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
1526
status_var, name_buffer, table, ucase_names);
1530
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
1531
name_buffer, wild)))
1533
char *value=var->value;
1534
const char *pos, *end; // We assign a lot of const's
1536
pthread_mutex_lock(&LOCK_global_system_variables);
1538
if (show_type == SHOW_SYS)
1540
show_type= ((sys_var*) value)->show_type();
1541
value= (char*) ((sys_var*) value)->value_ptr(thd, value_type,
1547
note that value may be == buff. All SHOW_xxx code below
1548
should still work in this case
1550
switch (show_type) {
1551
case SHOW_DOUBLE_STATUS:
1552
value= ((char *) status_var + (ulong) value);
1555
/* 6 is the default precision for '%f' in sprintf() */
1556
end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
1558
case SHOW_LONG_STATUS:
1559
value= ((char *) status_var + (ulong) value);
1562
case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
1563
end= int10_to_str(*(long*) value, buff, 10);
1565
case SHOW_LONGLONG_STATUS:
1566
value= ((char *) status_var + (uint64_t) value);
1569
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1572
end= int64_t10_to_str((int64_t) *(ha_rows*) value, buff, 10);
1575
end= strmov(buff, *(bool*) value ? "ON" : "OFF");
1578
end= strmov(buff, *(bool*) value ? "ON" : "OFF");
1581
end= int10_to_str((long) *(uint32_t*) value, buff, 10);
1585
SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
1586
pos= show_comp_option_name[(int) tmp];
1599
if (!(pos= *(char**) value))
1604
case SHOW_KEY_CACHE_LONG:
1605
value= (char*) dflt_key_cache + (ulong)value;
1606
end= int10_to_str(*(long*) value, buff, 10);
1608
case SHOW_KEY_CACHE_LONGLONG:
1609
value= (char*) dflt_key_cache + (ulong)value;
1610
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1613
break; // Return empty string
1614
case SHOW_SYS: // Cannot happen
1619
restore_record(table, s->default_values);
1620
table->field[0]->store(name_buffer, strlen(name_buffer),
1621
system_charset_info);
1622
table->field[1]->store(pos, (uint32_t) (end - pos), system_charset_info);
1623
table->field[1]->set_notnull();
1625
pthread_mutex_unlock(&LOCK_global_system_variables);
1627
if (schema_table_store_record(thd, table))
1637
/* collect status for all running threads */
1639
void calc_sum_of_all_status(STATUS_VAR *to)
1642
/* Ensure that thread id not killed during loop */
1643
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
1645
I_List_iterator<THD> it(threads);
1648
/* Get global values as base */
1649
*to= global_status_var;
1651
/* Add to this status from existing threads */
1653
add_to_status(to, &tmp->status_var);
1655
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1660
/* This is only used internally, but we need it here as a forward reference */
1661
extern ST_SCHEMA_TABLE schema_tables[];
1663
typedef struct st_lookup_field_values
1665
LEX_STRING db_value, table_value;
1666
bool wild_db_value, wild_table_value;
1667
} LOOKUP_FIELD_VALUES;
1671
Store record to I_S table, convert HEAP table
1672
to MyISAM if necessary
1675
schema_table_store_record()
1677
table Information schema table to be updated
1684
bool schema_table_store_record(THD *thd, TABLE *table)
1687
if ((error= table->file->ha_write_row(table->record[0])))
1689
TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
1691
if (create_myisam_from_heap(thd, table, param->start_recinfo,
1692
¶m->recinfo, error, 0))
1699
int make_table_list(THD *thd, SELECT_LEX *sel,
1700
LEX_STRING *db_name, LEX_STRING *table_name)
1702
Table_ident *table_ident;
1703
table_ident= new Table_ident(thd, *db_name, *table_name, 1);
1705
if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
1712
@brief Get lookup value from the part of 'WHERE' condition
1714
@details This function gets lookup value from
1715
the part of 'WHERE' condition if it's possible and
1716
fill appropriate lookup_field_vals struct field
1719
@param[in] thd thread handler
1720
@param[in] item_func part of WHERE condition
1721
@param[in] table I_S table
1722
@param[in, out] lookup_field_vals Struct which holds lookup values
1726
1 error, there can be no matching records for the condition
1729
bool get_lookup_value(THD *thd, Item_func *item_func,
1731
LOOKUP_FIELD_VALUES *lookup_field_vals)
1733
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1734
ST_FIELD_INFO *field_info= schema_table->fields_info;
1735
const char *field_name1= schema_table->idx_field1 >= 0 ?
1736
field_info[schema_table->idx_field1].field_name : "";
1737
const char *field_name2= schema_table->idx_field2 >= 0 ?
1738
field_info[schema_table->idx_field2].field_name : "";
1740
if (item_func->functype() == Item_func::EQ_FUNC ||
1741
item_func->functype() == Item_func::EQUAL_FUNC)
1743
int idx_field, idx_val;
1744
char tmp[MAX_FIELD_WIDTH];
1745
String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
1746
Item_field *item_field;
1747
CHARSET_INFO *cs= system_charset_info;
1749
if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
1750
item_func->arguments()[1]->const_item())
1755
else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
1756
item_func->arguments()[0]->const_item())
1764
item_field= (Item_field*) item_func->arguments()[idx_field];
1765
if (table->table != item_field->field->table)
1767
tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
1769
/* impossible value */
1773
/* Lookup value is database name */
1774
if (!cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
1775
(uchar *) item_field->field_name,
1776
strlen(item_field->field_name), 0))
1778
thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
1779
tmp_str->length(), false);
1781
/* Lookup value is table name */
1782
else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2,
1783
strlen(field_name2),
1784
(uchar *) item_field->field_name,
1785
strlen(item_field->field_name), 0))
1787
thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
1788
tmp_str->length(), false);
1796
@brief Calculates lookup values from 'WHERE' condition
1798
@details This function calculates lookup value(database name, table name)
1799
from 'WHERE' condition if it's possible and
1800
fill lookup_field_vals struct fields with these values.
1802
@param[in] thd thread handler
1803
@param[in] cond WHERE condition
1804
@param[in] table I_S table
1805
@param[in, out] lookup_field_vals Struct which holds lookup values
1809
1 error, there can be no matching records for the condition
1812
bool calc_lookup_values_from_cond(THD *thd, COND *cond, TABLE_LIST *table,
1813
LOOKUP_FIELD_VALUES *lookup_field_vals)
1818
if (cond->type() == Item::COND_ITEM)
1820
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1822
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1824
while ((item= li++))
1826
if (item->type() == Item::FUNC_ITEM)
1828
if (get_lookup_value(thd, (Item_func*)item, table, lookup_field_vals))
1833
if (calc_lookup_values_from_cond(thd, item, table, lookup_field_vals))
1840
else if (cond->type() == Item::FUNC_ITEM &&
1841
get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals))
1847
bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
1849
if (item->type() == Item::FUNC_ITEM)
1851
Item_func *item_func= (Item_func*)item;
1852
for (uint i=0; i<item_func->argument_count(); i++)
1854
if (!uses_only_table_name_fields(item_func->arguments()[i], table))
1858
else if (item->type() == Item::FIELD_ITEM)
1860
Item_field *item_field= (Item_field*)item;
1861
CHARSET_INFO *cs= system_charset_info;
1862
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1863
ST_FIELD_INFO *field_info= schema_table->fields_info;
1864
const char *field_name1= schema_table->idx_field1 >= 0 ?
1865
field_info[schema_table->idx_field1].field_name : "";
1866
const char *field_name2= schema_table->idx_field2 >= 0 ?
1867
field_info[schema_table->idx_field2].field_name : "";
1868
if (table->table != item_field->field->table ||
1869
(cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
1870
(uchar *) item_field->field_name,
1871
strlen(item_field->field_name), 0) &&
1872
cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2),
1873
(uchar *) item_field->field_name,
1874
strlen(item_field->field_name), 0)))
1877
else if (item->type() == Item::REF_ITEM)
1878
return uses_only_table_name_fields(item->real_item(), table);
1880
if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
1887
static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
1891
if (cond->type() == Item::COND_ITEM)
1893
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1895
/* Create new top level AND item */
1896
Item_cond_and *new_cond=new Item_cond_and;
1899
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1903
Item *fix= make_cond_for_info_schema(item, table);
1905
new_cond->argument_list()->push_back(fix);
1907
switch (new_cond->argument_list()->elements) {
1911
return new_cond->argument_list()->head();
1913
new_cond->quick_fix_field();
1919
Item_cond_or *new_cond=new Item_cond_or;
1922
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1926
Item *fix=make_cond_for_info_schema(item, table);
1929
new_cond->argument_list()->push_back(fix);
1931
new_cond->quick_fix_field();
1932
new_cond->top_level_item();
1937
if (!uses_only_table_name_fields(cond, table))
1944
@brief Calculate lookup values(database name, table name)
1946
@details This function calculates lookup values(database name, table name)
1947
from 'WHERE' condition or wild values (for 'SHOW' commands only)
1948
from LEX struct and fill lookup_field_vals struct field
1951
@param[in] thd thread handler
1952
@param[in] cond WHERE condition
1953
@param[in] tables I_S table
1954
@param[in, out] lookup_field_values Struct which holds lookup values
1958
1 error, there can be no matching records for the condition
1961
bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables,
1962
LOOKUP_FIELD_VALUES *lookup_field_values)
1965
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
1966
bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES));
1967
switch (lex->sql_command) {
1968
case SQLCOM_SHOW_DATABASES:
1971
lookup_field_values->db_value.str= (char*) wild;
1972
lookup_field_values->db_value.length= strlen(wild);
1973
lookup_field_values->wild_db_value= 1;
1976
case SQLCOM_SHOW_TABLES:
1977
case SQLCOM_SHOW_TABLE_STATUS:
1978
lookup_field_values->db_value.str= lex->select_lex.db;
1979
lookup_field_values->db_value.length=strlen(lex->select_lex.db);
1982
lookup_field_values->table_value.str= (char*)wild;
1983
lookup_field_values->table_value.length= strlen(wild);
1984
lookup_field_values->wild_table_value= 1;
1989
The "default" is for queries over I_S.
1990
All previous cases handle SHOW commands.
1992
return calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
1997
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
1999
return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
2004
Create db names list. Information schema name always is first in list
2009
files list of db names
2011
idx_field_vals idx_field_vals->db_name contains db name or
2013
with_i_schema returns 1 if we added 'IS' name to list
2021
int make_db_list(THD *thd, List<LEX_STRING> *files,
2022
LOOKUP_FIELD_VALUES *lookup_field_vals,
2023
bool *with_i_schema)
2025
LEX_STRING *i_s_name_copy= 0;
2026
i_s_name_copy= thd->make_lex_string(i_s_name_copy,
2027
INFORMATION_SCHEMA_NAME.str,
2028
INFORMATION_SCHEMA_NAME.length, true);
2030
if (lookup_field_vals->wild_db_value)
2033
This part of code is only for SHOW DATABASES command.
2034
idx_field_vals->db_value can be 0 when we don't use
2035
LIKE clause (see also get_index_field_values() function)
2037
if (!lookup_field_vals->db_value.str ||
2038
!wild_case_compare(system_charset_info,
2039
INFORMATION_SCHEMA_NAME.str,
2040
lookup_field_vals->db_value.str))
2043
if (files->push_back(i_s_name_copy))
2046
return (find_files(thd, files, NullS, mysql_data_home,
2047
lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
2052
If we have db lookup vaule we just add it to list and
2053
exit from the function
2055
if (lookup_field_vals->db_value.str)
2057
if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
2058
lookup_field_vals->db_value.str))
2061
if (files->push_back(i_s_name_copy))
2065
if (files->push_back(&lookup_field_vals->db_value))
2071
Create list of existing databases. It is used in case
2072
of select from information schema table
2074
if (files->push_back(i_s_name_copy))
2077
return (find_files(thd, files, NullS,
2078
mysql_data_home, NullS, 1) != FIND_FILES_OK);
2082
struct st_add_schema_table
2084
List<LEX_STRING> *files;
2089
static bool add_schema_table(THD *thd, plugin_ref plugin,
2092
LEX_STRING *file_name= 0;
2093
st_add_schema_table *data= (st_add_schema_table *)p_data;
2094
List<LEX_STRING> *file_list= data->files;
2095
const char *wild= data->wild;
2096
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
2098
if (schema_table->hidden)
2102
if (lower_case_table_names)
2104
if (wild_case_compare(files_charset_info,
2105
schema_table->table_name,
2109
else if (wild_compare(schema_table->table_name, wild, 0))
2113
if ((file_name= thd->make_lex_string(file_name, schema_table->table_name,
2114
strlen(schema_table->table_name),
2116
!file_list->push_back(file_name))
2122
int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
2124
LEX_STRING *file_name= 0;
2125
ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
2126
st_add_schema_table add_data;
2128
for (; tmp_schema_table->table_name; tmp_schema_table++)
2130
if (tmp_schema_table->hidden)
2134
if (lower_case_table_names)
2136
if (wild_case_compare(files_charset_info,
2137
tmp_schema_table->table_name,
2141
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2145
thd->make_lex_string(file_name, tmp_schema_table->table_name,
2146
strlen(tmp_schema_table->table_name), true)) &&
2147
!files->push_back(file_name))
2152
add_data.files= files;
2153
add_data.wild= wild;
2154
if (plugin_foreach(thd, add_schema_table,
2155
MYSQL_INFORMATION_SCHEMA_PLUGIN, &add_data))
2163
@brief Create table names list
2165
@details The function creates the list of table names in
2168
@param[in] thd thread handler
2169
@param[in] table_names List of table names in database
2170
@param[in] lex pointer to LEX struct
2171
@param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
2172
@param[in] with_i_schema true means that we add I_S tables to list
2173
@param[in] db_name database name
2175
@return Operation status
2177
@retval 1 fatal error
2178
@retval 2 Not fatal error; Safe to ignore this file list
2182
make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
2183
LOOKUP_FIELD_VALUES *lookup_field_vals,
2184
bool with_i_schema, LEX_STRING *db_name)
2186
char path[FN_REFLEN];
2187
build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
2188
if (!lookup_field_vals->wild_table_value &&
2189
lookup_field_vals->table_value.str)
2193
if (find_schema_table(thd, lookup_field_vals->table_value.str))
2195
if (table_names->push_back(&lookup_field_vals->table_value))
2201
if (table_names->push_back(&lookup_field_vals->table_value))
2208
This call will add all matching the wildcards (if specified) IS tables
2212
return (schema_tables_add(thd, table_names,
2213
lookup_field_vals->table_value.str));
2215
find_files_result res= find_files(thd, table_names, db_name->str, path,
2216
lookup_field_vals->table_value.str, 0);
2217
if (res != FIND_FILES_OK)
2220
Downgrade errors about problems with database directory to
2221
warnings if this is not a 'SHOW' command. Another thread
2222
may have dropped database, and we may still have a name
2225
if (res == FIND_FILES_DIR)
2227
if (lex->sql_command != SQLCOM_SELECT)
2239
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
2241
@param[in] thd thread handler
2242
@param[in] tables TABLE_LIST for I_S table
2243
@param[in] schema_table pointer to I_S structure
2244
@param[in] open_tables_state_backup pointer to Open_tables_state object
2245
which is used to save|restore original
2246
status of variables related to
2249
@return Operation status
2255
fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
2256
ST_SCHEMA_TABLE *schema_table,
2257
Open_tables_state *open_tables_state_backup)
2261
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
2262
enum_sql_command save_sql_command= lex->sql_command;
2263
TABLE_LIST *show_table_list= (TABLE_LIST*) tables->schema_select_lex->
2265
TABLE *table= tables->table;
2268
lex->all_selects_list= tables->schema_select_lex;
2270
Restore thd->temporary_tables to be able to process
2271
temporary tables(only for 'show index' & 'show columns').
2272
This should be changed when processing of temporary tables for
2273
I_S tables will be done.
2275
thd->temporary_tables= open_tables_state_backup->temporary_tables;
2277
Let us set fake sql_command so views won't try to merge
2278
themselves into main statement. If we don't do this,
2279
SELECT * from information_schema.xxxx will cause problems.
2280
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
2282
lex->sql_command= SQLCOM_SHOW_FIELDS;
2283
res= open_normal_and_derived_tables(thd, show_table_list,
2284
MYSQL_LOCK_IGNORE_FLUSH);
2285
lex->sql_command= save_sql_command;
2287
get_all_tables() returns 1 on failure and 0 on success thus
2288
return only these and not the result code of ::process_table()
2290
We should use show_table_list->alias instead of
2291
show_table_list->table_name because table_name
2292
could be changed during opening of I_S tables. It's safe
2293
to use alias because alias contains original table name
2294
in this case(this part of code is used only for
2295
'show columns' & 'show statistics' commands).
2297
table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
2298
strlen(show_table_list->alias), false);
2299
db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db,
2300
show_table_list->db_length, false);
2303
error= test(schema_table->process_table(thd, show_table_list,
2304
table, res, db_name,
2306
thd->temporary_tables= 0;
2307
close_tables_for_reopen(thd, &show_table_list);
2313
@brief Fill I_S table for SHOW TABLE NAMES commands
2315
@param[in] thd thread handler
2316
@param[in] table TABLE struct for I_S table
2317
@param[in] db_name database name
2318
@param[in] table_name table name
2319
@param[in] with_i_schema I_S table if true
2321
@return Operation status
2326
static int fill_schema_table_names(THD *thd, TABLE *table,
2327
LEX_STRING *db_name, LEX_STRING *table_name,
2332
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
2333
system_charset_info);
2337
enum legacy_db_type not_used;
2338
char path[FN_REFLEN];
2339
(void) build_table_filename(path, sizeof(path), db_name->str,
2340
table_name->str, reg_ext, 0);
2341
switch (mysql_frm_type(thd, path, ¬_used)) {
2343
table->field[3]->store(STRING_WITH_LEN("ERROR"),
2344
system_charset_info);
2347
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"),
2348
system_charset_info);
2353
if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2359
if (schema_table_store_record(thd, table))
2366
@brief Get open table method
2368
@details The function calculates the method which will be used
2370
SKIP_OPEN_TABLE - do not open table
2371
OPEN_FRM_ONLY - open FRM file only
2372
OPEN_FULL_TABLE - open FRM, data, index files
2373
@param[in] tables I_S table table_list
2374
@param[in] schema_table I_S table struct
2375
@param[in] schema_table_idx I_S table index
2377
@return return a set of flags
2378
@retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
2381
static uint get_table_open_method(TABLE_LIST *tables,
2382
ST_SCHEMA_TABLE *schema_table,
2383
enum enum_schema_tables schema_table_idx __attribute__((__unused__)))
2386
determine which method will be used for table opening
2388
if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
2390
Field **ptr, *field;
2391
int table_open_method= 0, field_indx= 0;
2392
for (ptr=tables->table->field; (field= *ptr) ; ptr++)
2394
if (bitmap_is_set(tables->table->read_set, field->field_index))
2395
table_open_method|= schema_table->fields_info[field_indx].open_method;
2398
return table_open_method;
2400
/* I_S tables which use get_all_tables but can not be optimized */
2401
return (uint) OPEN_FULL_TABLE;
2406
@brief Fill I_S table with data from FRM file only
2408
@param[in] thd thread handler
2409
@param[in] table TABLE struct for I_S table
2410
@param[in] schema_table I_S table struct
2411
@param[in] db_name database name
2412
@param[in] table_name table name
2413
@param[in] schema_table_idx I_S table index
2415
@return Operation status
2416
@retval 0 Table is processed and we can continue
2418
@retval 1 It's view and we have to use
2419
open_tables function for this table
2422
static int fill_schema_table_from_frm(THD *thd,TABLE_LIST *tables,
2423
ST_SCHEMA_TABLE *schema_table,
2424
LEX_STRING *db_name,
2425
LEX_STRING *table_name,
2426
enum enum_schema_tables schema_table_idx __attribute__((__unused__)))
2428
TABLE *table= tables->table;
2431
TABLE_LIST table_list;
2434
char key[MAX_DBKEY_LENGTH];
2437
bzero((char*) &table_list, sizeof(TABLE_LIST));
2438
bzero((char*) &tbl, sizeof(TABLE));
2440
table_list.table_name= table_name->str;
2441
table_list.db= db_name->str;
2443
key_length= create_table_def_key(thd, key, &table_list, 0);
2444
pthread_mutex_lock(&LOCK_open);
2445
share= get_table_share(thd, &table_list, key,
2446
key_length, OPEN_VIEW, &error);
2455
table_list.table= &tbl;
2456
res= schema_table->process_table(thd, &table_list, table,
2457
res, db_name, table_name);
2460
release_table_share(share, RELEASE_NORMAL);
2463
pthread_mutex_unlock(&LOCK_open);
2471
@brief Fill I_S tables whose data are retrieved
2472
from frm files and storage engine
2474
@details The information schema tables are internally represented as
2475
temporary tables that are filled at query execution time.
2476
Those I_S tables whose data are retrieved
2477
from frm files and storage engine are filled by the function
2480
@param[in] thd thread handler
2481
@param[in] tables I_S table
2482
@param[in] cond 'WHERE' condition
2484
@return Operation status
2489
int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
2492
TABLE *table= tables->table;
2493
SELECT_LEX *old_all_select_lex= lex->all_selects_list;
2494
enum_sql_command save_sql_command= lex->sql_command;
2495
SELECT_LEX *lsel= tables->schema_select_lex;
2496
ST_SCHEMA_TABLE *schema_table= tables->schema_table;
2498
LOOKUP_FIELD_VALUES lookup_field_vals;
2499
LEX_STRING *db_name, *table_name;
2501
enum enum_schema_tables schema_table_idx;
2502
List<LEX_STRING> db_names;
2503
List_iterator_fast<LEX_STRING> it(db_names);
2504
COND *partial_cond= 0;
2505
uint derived_tables= lex->derived_tables;
2507
Open_tables_state open_tables_state_backup;
2508
Query_tables_list query_tables_list_backup;
2509
uint table_open_method;
2510
bool old_value= thd->no_warnings_for_error;
2512
lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
2515
We should not introduce deadlocks even if we already have some
2516
tables open and locked, since we won't lock tables which we will
2517
open and will ignore possible name-locks for these tables.
2519
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
2521
schema_table_idx= get_schema_table_idx(schema_table);
2522
tables->table_open_method= table_open_method=
2523
get_table_open_method(tables, schema_table, schema_table_idx);
2525
this branch processes SHOW FIELDS, SHOW INDEXES commands.
2526
see sql_parse.cc, prepare_schema_table() function where
2527
this values are initialized
2529
if (lsel && lsel->table_list.first)
2531
error= fill_schema_show_cols_or_idxs(thd, tables, schema_table,
2532
&open_tables_state_backup);
2536
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2542
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
2545
if lookup value is empty string then
2546
it's impossible table name or db name
2548
if ((lookup_field_vals.db_value.str && !lookup_field_vals.db_value.str[0]) ||
2549
(lookup_field_vals.table_value.str && !lookup_field_vals.table_value.str[0]))
2556
if (lookup_field_vals.db_value.length &&
2557
!lookup_field_vals.wild_db_value)
2558
tables->has_db_lookup_value= true;
2559
if (lookup_field_vals.table_value.length &&
2560
!lookup_field_vals.wild_table_value)
2561
tables->has_table_lookup_value= true;
2563
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
2566
partial_cond= make_cond_for_info_schema(cond, tables);
2570
/* EXPLAIN SELECT */
2575
if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
2577
it.rewind(); /* To get access to new elements in basis list */
2578
while ((db_name= it++))
2581
thd->no_warnings_for_error= 1;
2582
List<LEX_STRING> table_names;
2583
int res= make_table_name_list(thd, &table_names, lex,
2585
with_i_schema, db_name);
2586
if (res == 2) /* Not fatal error, continue */
2591
List_iterator_fast<LEX_STRING> it_files(table_names);
2592
while ((table_name= it_files++))
2594
restore_record(table, s->default_values);
2595
table->field[schema_table->idx_field1]->
2596
store(db_name->str, db_name->length, system_charset_info);
2597
table->field[schema_table->idx_field2]->
2598
store(table_name->str, table_name->length, system_charset_info);
2600
if (!partial_cond || partial_cond->val_int())
2603
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
2604
we can skip table opening and we don't have lookup value for
2605
table name or lookup value is wild string(table name list is
2606
already created by make_table_name_list() function).
2608
if (!table_open_method && schema_table_idx == SCH_TABLES &&
2609
(!lookup_field_vals.table_value.length ||
2610
lookup_field_vals.wild_table_value))
2612
if (schema_table_store_record(thd, table))
2613
goto err; /* Out of space in temporary table */
2617
/* SHOW TABLE NAMES command */
2618
if (schema_table_idx == SCH_TABLE_NAMES)
2620
if (fill_schema_table_names(thd, tables->table, db_name,
2621
table_name, with_i_schema))
2626
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
2629
if (!fill_schema_table_from_frm(thd, tables, schema_table, db_name,
2630
table_name, schema_table_idx))
2635
LEX_STRING tmp_lex_string, orig_db_name;
2637
Set the parent lex of 'sel' because it is needed by
2638
sel.init_query() which is called inside make_table_list.
2640
thd->no_warnings_for_error= 1;
2641
sel.parent_lex= lex;
2642
/* db_name can be changed in make_table_list() func */
2643
if (!thd->make_lex_string(&orig_db_name, db_name->str,
2644
db_name->length, false))
2646
if (make_table_list(thd, &sel, db_name, table_name))
2648
TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first;
2649
lex->all_selects_list= &sel;
2650
lex->derived_tables= 0;
2651
lex->sql_command= SQLCOM_SHOW_FIELDS;
2652
show_table_list->i_s_requested_object=
2653
schema_table->i_s_requested_object;
2654
res= open_normal_and_derived_tables(thd, show_table_list,
2655
MYSQL_LOCK_IGNORE_FLUSH);
2656
lex->sql_command= save_sql_command;
2658
XXX: show_table_list has a flag i_is_requested,
2659
and when it's set, open_normal_and_derived_tables()
2660
can return an error without setting an error message
2661
in THD, which is a hack. This is why we have to
2662
check for res, then for thd->is_error() only then
2663
for thd->main_da.sql_errno().
2665
if (res && thd->is_error() &&
2666
thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2669
Hide error for not existing table.
2670
This error can occur for example when we use
2671
where condition with db name and table name and this
2672
table does not exist.
2680
We should use show_table_list->alias instead of
2681
show_table_list->table_name because table_name
2682
could be changed during opening of I_S tables. It's safe
2683
to use alias because alias contains original table name
2686
thd->make_lex_string(&tmp_lex_string, show_table_list->alias,
2687
strlen(show_table_list->alias), false);
2688
res= schema_table->process_table(thd, show_table_list, table,
2691
close_tables_for_reopen(thd, &show_table_list);
2693
assert(!lex->query_tables_own_last);
2700
If we have information schema its always the first table and only
2701
the first table. Reset for other tables.
2709
thd->restore_backup_open_tables_state(&open_tables_state_backup);
2710
lex->restore_backup_query_tables_list(&query_tables_list_backup);
2711
lex->derived_tables= derived_tables;
2712
lex->all_selects_list= old_all_select_lex;
2713
lex->sql_command= save_sql_command;
2714
thd->no_warnings_for_error= old_value;
2719
bool store_schema_shemata(THD* thd, TABLE *table, LEX_STRING *db_name,
2722
restore_record(table, s->default_values);
2723
table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2724
table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2725
table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2726
return schema_table_store_record(thd, table);
2730
int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
2733
TODO: fill_schema_shemata() is called when new client is connected.
2734
Returning error status in this case leads to client hangup.
2737
LOOKUP_FIELD_VALUES lookup_field_vals;
2738
List<LEX_STRING> db_names;
2739
LEX_STRING *db_name;
2741
HA_CREATE_INFO create;
2742
TABLE *table= tables->table;
2744
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2746
if (make_db_list(thd, &db_names, &lookup_field_vals,
2751
If we have lookup db value we should check that the database exists
2753
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
2756
char path[FN_REFLEN+16];
2758
struct stat stat_info;
2759
if (!lookup_field_vals.db_value.str[0])
2761
path_len= build_table_filename(path, sizeof(path),
2762
lookup_field_vals.db_value.str, "", "", 0);
2763
path[path_len-1]= 0;
2764
if (stat(path,&stat_info))
2768
List_iterator_fast<LEX_STRING> it(db_names);
2769
while ((db_name=it++))
2771
if (with_i_schema) // information schema name is always first in list
2773
if (store_schema_shemata(thd, table, db_name,
2774
system_charset_info))
2780
load_db_opt_by_name(thd, db_name->str, &create);
2781
if (store_schema_shemata(thd, table, db_name,
2782
create.default_table_charset))
2790
static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
2791
TABLE *table, bool res,
2792
LEX_STRING *db_name,
2793
LEX_STRING *table_name)
2795
const char *tmp_buff;
2797
CHARSET_INFO *cs= system_charset_info;
2799
restore_record(table, s->default_values);
2800
table->field[1]->store(db_name->str, db_name->length, cs);
2801
table->field[2]->store(table_name->str, table_name->length, cs);
2805
there was errors during opening tables
2807
const char *error= thd->is_error() ? thd->main_da.message() : "";
2808
if (tables->schema_table)
2809
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2811
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
2812
table->field[20]->store(error, strlen(error), cs);
2817
char option_buff[350],*ptr;
2818
TABLE *show_table= tables->table;
2819
TABLE_SHARE *share= show_table->s;
2820
handler *file= show_table->file;
2821
handlerton *tmp_db_type= share->db_type();
2822
if (share->tmp_table == SYSTEM_TMP_TABLE)
2823
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2824
else if (share->tmp_table)
2825
table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
2827
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
2829
for (int i= 4; i < 20; i++)
2831
if (i == 7 || (i > 12 && i < 17) || i == 18)
2833
table->field[i]->set_notnull();
2835
tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
2836
table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
2837
table->field[5]->store((int64_t) share->frm_version, true);
2840
if (share->min_rows)
2842
ptr=strmov(ptr," min_rows=");
2843
ptr=int64_t10_to_str(share->min_rows,ptr,10);
2845
if (share->max_rows)
2847
ptr=strmov(ptr," max_rows=");
2848
ptr=int64_t10_to_str(share->max_rows,ptr,10);
2850
if (share->avg_row_length)
2852
ptr=strmov(ptr," avg_row_length=");
2853
ptr=int64_t10_to_str(share->avg_row_length,ptr,10);
2855
if (share->db_create_options & HA_OPTION_PACK_KEYS)
2856
ptr=strmov(ptr," pack_keys=1");
2857
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
2858
ptr=strmov(ptr," pack_keys=0");
2859
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2860
if (share->db_create_options & HA_OPTION_CHECKSUM)
2861
ptr=strmov(ptr," checksum=1");
2862
if (share->page_checksum != HA_CHOICE_UNDEF)
2863
ptr= strxmov(ptr, " page_checksum=",
2864
ha_choice_values[(uint) share->page_checksum], NullS);
2865
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
2866
ptr=strmov(ptr," delay_key_write=1");
2867
if (share->row_type != ROW_TYPE_DEFAULT)
2868
ptr=strxmov(ptr, " row_format=",
2869
ha_row_type[(uint) share->row_type],
2871
if (share->transactional != HA_CHOICE_UNDEF)
2873
ptr= strxmov(ptr, " TRANSACTIONAL=",
2874
(share->transactional == HA_CHOICE_YES ? "1" : "0"),
2877
if (share->transactional != HA_CHOICE_UNDEF)
2878
ptr= strxmov(ptr, " transactional=",
2879
ha_choice_values[(uint) share->transactional], NullS);
2880
table->field[19]->store(option_buff+1,
2881
(ptr == option_buff ? 0 :
2882
(uint) (ptr-option_buff)-1), cs);
2884
tmp_buff= (share->table_charset ?
2885
share->table_charset->name : "default");
2886
table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
2888
if (share->comment.str)
2889
table->field[20]->store(share->comment.str, share->comment.length, cs);
2893
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
2895
enum row_type row_type = file->get_row_type();
2897
case ROW_TYPE_NOT_USED:
2898
case ROW_TYPE_DEFAULT:
2899
tmp_buff= ((share->db_options_in_use &
2900
HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
2901
(share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
2902
"Dynamic" : "Fixed");
2904
case ROW_TYPE_FIXED:
2907
case ROW_TYPE_DYNAMIC:
2908
tmp_buff= "Dynamic";
2910
case ROW_TYPE_COMPRESSED:
2911
tmp_buff= "Compressed";
2913
case ROW_TYPE_REDUNDANT:
2914
tmp_buff= "Redundant";
2916
case ROW_TYPE_COMPACT:
2917
tmp_buff= "Compact";
2923
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
2924
if (!tables->schema_table)
2926
table->field[7]->store((int64_t) file->stats.records, true);
2927
table->field[7]->set_notnull();
2929
table->field[8]->store((int64_t) file->stats.mean_rec_length, true);
2930
table->field[9]->store((int64_t) file->stats.data_file_length, true);
2931
if (file->stats.max_data_file_length)
2933
table->field[10]->store((int64_t) file->stats.max_data_file_length,
2936
table->field[11]->store((int64_t) file->stats.index_file_length, true);
2937
table->field[12]->store((int64_t) file->stats.delete_length, true);
2938
if (show_table->found_next_number_field)
2940
table->field[13]->store((int64_t) file->stats.auto_increment_value,
2942
table->field[13]->set_notnull();
2944
if (file->stats.create_time)
2946
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2947
(my_time_t) file->stats.create_time);
2948
table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
2949
table->field[14]->set_notnull();
2951
if (file->stats.update_time)
2953
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2954
(my_time_t) file->stats.update_time);
2955
table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
2956
table->field[15]->set_notnull();
2958
if (file->stats.check_time)
2960
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2961
(my_time_t) file->stats.check_time);
2962
table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
2963
table->field[16]->set_notnull();
2965
if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
2967
table->field[18]->store((int64_t) file->checksum(), true);
2968
table->field[18]->set_notnull();
2972
return(schema_table_store_record(thd, table));
2977
@brief Store field characteristics into appropriate I_S table columns
2979
@param[in] table I_S table
2980
@param[in] field processed field
2981
@param[in] cs I_S table charset
2982
@param[in] offset offset from beginning of table
2983
to DATE_TYPE column in I_S table
2988
void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs,
2992
int decimals, field_length;
2993
const char *tmp_buff;
2994
char column_type_buff[MAX_FIELD_WIDTH];
2995
String column_type(column_type_buff, sizeof(column_type_buff), cs);
2997
field->sql_type(column_type);
2998
/* DTD_IDENTIFIER column */
2999
table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs);
3000
table->field[offset + 7]->set_notnull();
3001
tmp_buff= strchr(column_type.ptr(), '(');
3002
/* DATA_TYPE column */
3003
table->field[offset]->store(column_type.ptr(),
3004
(tmp_buff ? tmp_buff - column_type.ptr() :
3005
column_type.length()), cs);
3006
is_blob= (field->type() == MYSQL_TYPE_BLOB);
3007
if (field->has_charset() || is_blob ||
3008
field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type
3009
field->real_type() == MYSQL_TYPE_STRING) // For binary type
3011
uint32_t octet_max_length= field->max_display_length();
3012
if (is_blob && octet_max_length != (uint32_t) 4294967295U)
3013
octet_max_length /= field->charset()->mbmaxlen;
3014
int64_t char_max_len= is_blob ?
3015
(int64_t) octet_max_length / field->charset()->mbminlen :
3016
(int64_t) octet_max_length / field->charset()->mbmaxlen;
3017
/* CHARACTER_MAXIMUM_LENGTH column*/
3018
table->field[offset + 1]->store(char_max_len, true);
3019
table->field[offset + 1]->set_notnull();
3020
/* CHARACTER_OCTET_LENGTH column */
3021
table->field[offset + 2]->store((int64_t) octet_max_length, true);
3022
table->field[offset + 2]->set_notnull();
3026
Calculate field_length and decimals.
3027
They are set to -1 if they should not be set (we should return NULL)
3030
decimals= field->decimals();
3031
switch (field->type()) {
3032
case MYSQL_TYPE_NEWDECIMAL:
3033
field_length= ((Field_new_decimal*) field)->precision;
3035
case MYSQL_TYPE_TINY:
3036
case MYSQL_TYPE_SHORT:
3037
case MYSQL_TYPE_LONG:
3038
case MYSQL_TYPE_LONGLONG:
3039
field_length= field->max_display_length() - 1;
3041
case MYSQL_TYPE_DOUBLE:
3042
field_length= field->field_length;
3043
if (decimals == NOT_FIXED_DEC)
3044
decimals= -1; // return NULL
3047
field_length= decimals= -1;
3051
/* NUMERIC_PRECISION column */
3052
if (field_length >= 0)
3054
table->field[offset + 3]->store((int64_t) field_length, true);
3055
table->field[offset + 3]->set_notnull();
3057
/* NUMERIC_SCALE column */
3060
table->field[offset + 4]->store((int64_t) decimals, true);
3061
table->field[offset + 4]->set_notnull();
3063
if (field->has_charset())
3065
/* CHARACTER_SET_NAME column*/
3066
tmp_buff= field->charset()->csname;
3067
table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs);
3068
table->field[offset + 5]->set_notnull();
3069
/* COLLATION_NAME column */
3070
tmp_buff= field->charset()->name;
3071
table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs);
3072
table->field[offset + 6]->set_notnull();
3077
static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
3078
TABLE *table, bool res,
3079
LEX_STRING *db_name,
3080
LEX_STRING *table_name)
3083
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3084
CHARSET_INFO *cs= system_charset_info;
3086
TABLE_SHARE *show_table_share;
3087
Field **ptr, *field, *timestamp_field;
3092
if (lex->sql_command != SQLCOM_SHOW_FIELDS)
3095
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
3096
rather than in SHOW COLUMNS
3098
if (thd->is_error())
3099
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3100
thd->main_da.sql_errno(), thd->main_da.message());
3107
show_table= tables->table;
3108
show_table_share= show_table->s;
3111
if (tables->schema_table)
3113
ptr= show_table->field;
3114
timestamp_field= show_table->timestamp_field;
3115
show_table->use_all_columns(); // Required for default
3119
ptr= show_table_share->field;
3120
timestamp_field= show_table_share->timestamp_field;
3122
read_set may be inited in case of
3125
if (!show_table->read_set)
3127
/* to satisfy 'field->val_str' ASSERTs */
3129
uint bitmap_size= show_table_share->column_bitmap_size;
3130
if (!(bitmaps= (uchar*) alloc_root(thd->mem_root, bitmap_size)))
3132
bitmap_init(&show_table->def_read_set,
3133
(my_bitmap_map*) bitmaps, show_table_share->fields, false);
3134
bitmap_set_all(&show_table->def_read_set);
3135
show_table->read_set= &show_table->def_read_set;
3137
bitmap_set_all(show_table->read_set);
3140
for (; (field= *ptr) ; ptr++)
3143
char tmp[MAX_FIELD_WIDTH];
3144
String type(tmp,sizeof(tmp), system_charset_info);
3147
/* to satisfy 'field->val_str' ASSERTs */
3148
field->table= show_table;
3149
show_table->in_use= thd;
3151
if (wild && wild[0] &&
3152
wild_case_compare(system_charset_info, field->field_name,wild))
3156
/* Get default row, with all NULL fields set to NULL */
3157
restore_record(table, s->default_values);
3159
table->field[1]->store(db_name->str, db_name->length, cs);
3160
table->field[2]->store(table_name->str, table_name->length, cs);
3161
table->field[3]->store(field->field_name, strlen(field->field_name),
3163
table->field[4]->store((int64_t) count, true);
3165
if (get_field_default_value(thd, timestamp_field, field, &type, 0))
3167
table->field[5]->store(type.ptr(), type.length(), cs);
3168
table->field[5]->set_notnull();
3170
pos=(uchar*) ((field->flags & NOT_NULL_FLAG) ? "NO" : "YES");
3171
table->field[6]->store((const char*) pos,
3172
strlen((const char*) pos), cs);
3173
store_column_type(table, field, cs, 7);
3175
pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
3176
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
3177
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
3178
table->field[15]->store((const char*) pos,
3179
strlen((const char*) pos), cs);
3182
if (field->unireg_check == Field::NEXT_NUMBER)
3183
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
3184
if (timestamp_field == field &&
3185
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3186
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3189
table->field[18]->store(field->comment.str, field->comment.length, cs);
3191
enum column_format_type column_format= (enum column_format_type)
3192
((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
3193
pos=(uchar*)"Default";
3194
table->field[19]->store((const char*) pos,
3195
strlen((const char*) pos), cs);
3196
pos=(uchar*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
3197
column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
3199
table->field[20]->store((const char*) pos,
3200
strlen((const char*) pos), cs);
3202
if (schema_table_store_record(thd, table))
3210
int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3213
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3214
TABLE *table= tables->table;
3215
CHARSET_INFO *scs= system_charset_info;
3217
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3219
CHARSET_INFO *tmp_cs= cs[0];
3220
if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
3221
(tmp_cs->state & MY_CS_AVAILABLE) &&
3222
!(tmp_cs->state & MY_CS_HIDDEN) &&
3223
!(wild && wild[0] &&
3224
wild_case_compare(scs, tmp_cs->csname,wild)))
3226
const char *comment;
3227
restore_record(table, s->default_values);
3228
table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3229
table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3230
comment= tmp_cs->comment ? tmp_cs->comment : "";
3231
table->field[2]->store(comment, strlen(comment), scs);
3232
table->field[3]->store((int64_t) tmp_cs->mbmaxlen, true);
3233
if (schema_table_store_record(thd, table))
3241
int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3244
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3245
TABLE *table= tables->table;
3246
CHARSET_INFO *scs= system_charset_info;
3247
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3250
CHARSET_INFO *tmp_cs= cs[0];
3251
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3252
(tmp_cs->state & MY_CS_HIDDEN) ||
3253
!(tmp_cs->state & MY_CS_PRIMARY))
3255
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3257
CHARSET_INFO *tmp_cl= cl[0];
3258
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3259
!my_charset_same(tmp_cs, tmp_cl))
3261
if (!(wild && wild[0] &&
3262
wild_case_compare(scs, tmp_cl->name,wild)))
3264
const char *tmp_buff;
3265
restore_record(table, s->default_values);
3266
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3267
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3268
table->field[2]->store((int64_t) tmp_cl->number, true);
3269
tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
3270
table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
3271
tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
3272
table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
3273
table->field[5]->store((int64_t) tmp_cl->strxfrm_multiply, true);
3274
if (schema_table_store_record(thd, table))
3283
int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3286
TABLE *table= tables->table;
3287
CHARSET_INFO *scs= system_charset_info;
3288
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3291
CHARSET_INFO *tmp_cs= cs[0];
3292
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3293
!(tmp_cs->state & MY_CS_PRIMARY))
3295
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3297
CHARSET_INFO *tmp_cl= cl[0];
3298
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3299
!my_charset_same(tmp_cs,tmp_cl))
3301
restore_record(table, s->default_values);
3302
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3303
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3304
if (schema_table_store_record(thd, table))
3312
static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
3313
TABLE *table, bool res,
3314
LEX_STRING *db_name,
3315
LEX_STRING *table_name)
3317
CHARSET_INFO *cs= system_charset_info;
3320
if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
3323
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
3324
rather than in SHOW KEYS
3326
if (thd->is_error())
3327
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3328
thd->main_da.sql_errno(), thd->main_da.message());
3336
TABLE *show_table= tables->table;
3337
KEY *key_info=show_table->s->key_info;
3338
if (show_table->file)
3339
show_table->file->info(HA_STATUS_VARIABLE |
3342
for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
3344
KEY_PART_INFO *key_part= key_info->key_part;
3346
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3348
restore_record(table, s->default_values);
3349
table->field[1]->store(db_name->str, db_name->length, cs);
3350
table->field[2]->store(table_name->str, table_name->length, cs);
3351
table->field[3]->store((int64_t) ((key_info->flags &
3352
HA_NOSAME) ? 0 : 1), true);
3353
table->field[4]->store(db_name->str, db_name->length, cs);
3354
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
3355
table->field[6]->store((int64_t) (j+1), true);
3356
str=(key_part->field ? key_part->field->field_name :
3358
table->field[7]->store(str, strlen(str), cs);
3359
if (show_table->file)
3361
if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
3363
table->field[8]->store(((key_part->key_part_flag &
3366
table->field[8]->set_notnull();
3368
KEY *key=show_table->key_info+i;
3369
if (key->rec_per_key[j])
3371
ha_rows records=(show_table->file->stats.records /
3372
key->rec_per_key[j]);
3373
table->field[9]->store((int64_t) records, true);
3374
table->field[9]->set_notnull();
3376
str= show_table->file->index_type(i);
3377
table->field[13]->store(str, strlen(str), cs);
3379
if ((key_part->field &&
3381
show_table->s->field[key_part->fieldnr-1]->key_length()))
3383
table->field[10]->store((int64_t) key_part->length /
3384
key_part->field->charset()->mbmaxlen, true);
3385
table->field[10]->set_notnull();
3387
uint flags= key_part->field ? key_part->field->flags : 0;
3388
const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3389
table->field[12]->store(pos, strlen(pos), cs);
3390
if (!show_table->s->keys_in_use.is_set(i))
3391
table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3393
table->field[14]->store("", 0, cs);
3394
table->field[14]->set_notnull();
3395
assert(test(key_info->flags & HA_USES_COMMENT) ==
3396
(key_info->comment.length > 0));
3397
if (key_info->flags & HA_USES_COMMENT)
3398
table->field[15]->store(key_info->comment.str,
3399
key_info->comment.length, cs);
3400
if (schema_table_store_record(thd, table))
3409
bool store_constraints(THD *thd, TABLE *table, LEX_STRING *db_name,
3410
LEX_STRING *table_name, const char *key_name,
3411
uint key_len, const char *con_type, uint con_len)
3413
CHARSET_INFO *cs= system_charset_info;
3414
restore_record(table, s->default_values);
3415
table->field[1]->store(db_name->str, db_name->length, cs);
3416
table->field[2]->store(key_name, key_len, cs);
3417
table->field[3]->store(db_name->str, db_name->length, cs);
3418
table->field[4]->store(table_name->str, table_name->length, cs);
3419
table->field[5]->store(con_type, con_len, cs);
3420
return schema_table_store_record(thd, table);
3424
static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
3425
TABLE *table, bool res,
3426
LEX_STRING *db_name,
3427
LEX_STRING *table_name)
3431
if (thd->is_error())
3432
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3433
thd->main_da.sql_errno(), thd->main_da.message());
3439
List<FOREIGN_KEY_INFO> f_key_list;
3440
TABLE *show_table= tables->table;
3441
KEY *key_info=show_table->key_info;
3442
uint primary_key= show_table->s->primary_key;
3443
show_table->file->info(HA_STATUS_VARIABLE |
3446
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3448
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3451
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
3453
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3454
strlen(key_info->name),
3455
STRING_WITH_LEN("PRIMARY KEY")))
3458
else if (key_info->flags & HA_NOSAME)
3460
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3461
strlen(key_info->name),
3462
STRING_WITH_LEN("UNIQUE")))
3467
show_table->file->get_foreign_key_list(thd, &f_key_list);
3468
FOREIGN_KEY_INFO *f_key_info;
3469
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3470
while ((f_key_info=it++))
3472
if (store_constraints(thd, table, db_name, table_name,
3473
f_key_info->forein_id->str,
3474
strlen(f_key_info->forein_id->str),
3483
void store_key_column_usage(TABLE *table, LEX_STRING *db_name,
3484
LEX_STRING *table_name, const char *key_name,
3485
uint key_len, const char *con_type, uint con_len,
3488
CHARSET_INFO *cs= system_charset_info;
3489
table->field[1]->store(db_name->str, db_name->length, cs);
3490
table->field[2]->store(key_name, key_len, cs);
3491
table->field[4]->store(db_name->str, db_name->length, cs);
3492
table->field[5]->store(table_name->str, table_name->length, cs);
3493
table->field[6]->store(con_type, con_len, cs);
3494
table->field[7]->store((int64_t) idx, true);
3498
static int get_schema_key_column_usage_record(THD *thd,
3500
TABLE *table, bool res,
3501
LEX_STRING *db_name,
3502
LEX_STRING *table_name)
3506
if (thd->is_error())
3507
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3508
thd->main_da.sql_errno(), thd->main_da.message());
3514
List<FOREIGN_KEY_INFO> f_key_list;
3515
TABLE *show_table= tables->table;
3516
KEY *key_info=show_table->key_info;
3517
uint primary_key= show_table->s->primary_key;
3518
show_table->file->info(HA_STATUS_VARIABLE |
3521
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3523
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3526
KEY_PART_INFO *key_part= key_info->key_part;
3527
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3529
if (key_part->field)
3532
restore_record(table, s->default_values);
3533
store_key_column_usage(table, db_name, table_name,
3535
strlen(key_info->name),
3536
key_part->field->field_name,
3537
strlen(key_part->field->field_name),
3539
if (schema_table_store_record(thd, table))
3545
show_table->file->get_foreign_key_list(thd, &f_key_list);
3546
FOREIGN_KEY_INFO *f_key_info;
3547
List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
3548
while ((f_key_info= fkey_it++))
3552
List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
3553
it1(f_key_info->referenced_fields);
3555
while ((f_info= it++))
3559
restore_record(table, s->default_values);
3560
store_key_column_usage(table, db_name, table_name,
3561
f_key_info->forein_id->str,
3562
f_key_info->forein_id->length,
3563
f_info->str, f_info->length,
3565
table->field[8]->store((int64_t) f_idx, true);
3566
table->field[8]->set_notnull();
3567
table->field[9]->store(f_key_info->referenced_db->str,
3568
f_key_info->referenced_db->length,
3569
system_charset_info);
3570
table->field[9]->set_notnull();
3571
table->field[10]->store(f_key_info->referenced_table->str,
3572
f_key_info->referenced_table->length,
3573
system_charset_info);
3574
table->field[10]->set_notnull();
3575
table->field[11]->store(r_info->str, r_info->length,
3576
system_charset_info);
3577
table->field[11]->set_notnull();
3578
if (schema_table_store_record(thd, table))
3587
int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3589
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3590
TABLE *table= tables->table;
3591
CHARSET_INFO *cs= system_charset_info;
3592
OPEN_TABLE_LIST *open_list;
3593
if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
3594
&& thd->is_fatal_error)
3597
for (; open_list ; open_list=open_list->next)
3599
restore_record(table, s->default_values);
3600
table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3601
table->field[1]->store(open_list->table, strlen(open_list->table), cs);
3602
table->field[2]->store((int64_t) open_list->in_use, true);
3603
table->field[3]->store((int64_t) open_list->locked, true);
3604
if (schema_table_store_record(thd, table))
3611
int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3615
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3616
enum enum_schema_tables schema_table_idx=
3617
get_schema_table_idx(tables->schema_table);
3618
enum enum_var_type option_type= OPT_SESSION;
3619
bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
3620
bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
3622
if (lex->option_type == OPT_GLOBAL ||
3623
schema_table_idx == SCH_GLOBAL_VARIABLES)
3624
option_type= OPT_GLOBAL;
3626
rw_rdlock(&LOCK_system_variables_hash);
3627
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
3628
option_type, NULL, "", tables->table, upper_case_names);
3629
rw_unlock(&LOCK_system_variables_hash);
3634
int fill_status(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3637
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3639
STATUS_VAR *tmp1, tmp;
3640
enum enum_schema_tables schema_table_idx=
3641
get_schema_table_idx(tables->schema_table);
3642
enum enum_var_type option_type;
3643
bool upper_case_names= (schema_table_idx != SCH_STATUS);
3645
if (schema_table_idx == SCH_STATUS)
3647
option_type= lex->option_type;
3648
if (option_type == OPT_GLOBAL)
3651
tmp1= thd->initial_status_var;
3653
else if (schema_table_idx == SCH_GLOBAL_STATUS)
3655
option_type= OPT_GLOBAL;
3660
option_type= OPT_SESSION;
3661
tmp1= &thd->status_var;
3664
pthread_mutex_lock(&LOCK_status);
3665
if (option_type == OPT_GLOBAL)
3666
calc_sum_of_all_status(&tmp);
3667
res= show_status_array(thd, wild,
3668
(SHOW_VAR *)all_status_vars.buffer,
3669
option_type, tmp1, "", tables->table,
3671
pthread_mutex_unlock(&LOCK_status);
3677
Fill and store records into I_S.referential_constraints table
3680
get_referential_constraints_record()
3682
tables table list struct(processed table)
3684
res 1 means the error during opening of the processed table
3685
0 means processed table is opened without error
3687
file_name table name
3695
get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
3696
TABLE *table, bool res,
3697
LEX_STRING *db_name, LEX_STRING *table_name)
3699
CHARSET_INFO *cs= system_charset_info;
3703
if (thd->is_error())
3704
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3705
thd->main_da.sql_errno(), thd->main_da.message());
3711
List<FOREIGN_KEY_INFO> f_key_list;
3712
TABLE *show_table= tables->table;
3713
show_table->file->info(HA_STATUS_VARIABLE |
3717
show_table->file->get_foreign_key_list(thd, &f_key_list);
3718
FOREIGN_KEY_INFO *f_key_info;
3719
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3720
while ((f_key_info= it++))
3722
restore_record(table, s->default_values);
3723
table->field[1]->store(db_name->str, db_name->length, cs);
3724
table->field[9]->store(table_name->str, table_name->length, cs);
3725
table->field[2]->store(f_key_info->forein_id->str,
3726
f_key_info->forein_id->length, cs);
3727
table->field[4]->store(f_key_info->referenced_db->str,
3728
f_key_info->referenced_db->length, cs);
3729
table->field[10]->store(f_key_info->referenced_table->str,
3730
f_key_info->referenced_table->length, cs);
3731
if (f_key_info->referenced_key_name)
3733
table->field[5]->store(f_key_info->referenced_key_name->str,
3734
f_key_info->referenced_key_name->length, cs);
3735
table->field[5]->set_notnull();
3738
table->field[5]->set_null();
3739
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3740
table->field[7]->store(f_key_info->update_method->str,
3741
f_key_info->update_method->length, cs);
3742
table->field[8]->store(f_key_info->delete_method->str,
3743
f_key_info->delete_method->length, cs);
3744
if (schema_table_store_record(thd, table))
3752
struct schema_table_ref
3754
const char *table_name;
3755
ST_SCHEMA_TABLE *schema_table;
3760
Find schema_tables elment by name
3763
find_schema_table_in_plugin()
3766
table_name table name
3770
1 found the schema table
3772
static bool find_schema_table_in_plugin(THD *thd __attribute__((__unused__)),
3776
schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
3777
const char* table_name= p_schema_table->table_name;
3778
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
3780
if (!my_strcasecmp(system_charset_info,
3781
schema_table->table_name,
3783
p_schema_table->schema_table= schema_table;
3792
Find schema_tables elment by name
3797
table_name table name
3801
# pointer to 'schema_tables' element
3804
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
3806
schema_table_ref schema_table_a;
3807
ST_SCHEMA_TABLE *schema_table= schema_tables;
3809
for (; schema_table->table_name; schema_table++)
3811
if (!my_strcasecmp(system_charset_info,
3812
schema_table->table_name,
3814
return(schema_table);
3817
schema_table_a.table_name= table_name;
3818
if (plugin_foreach(thd, find_schema_table_in_plugin,
3819
MYSQL_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
3820
return(schema_table_a.schema_table);
3826
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
3828
return &schema_tables[schema_table_idx];
3833
Create information_schema table using schema_table data.
3840
@param table_list Used to pass I_S table information(fields info, tables
3841
parameters etc) and table name.
3843
@retval \# Pointer to created table
3844
@retval NULL Can't create table
3847
TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
3852
List<Item> field_list;
3853
ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
3854
ST_FIELD_INFO *fields_info= schema_table->fields_info;
3855
CHARSET_INFO *cs= system_charset_info;
3857
for (; fields_info->field_name; fields_info++)
3859
switch (fields_info->field_type) {
3860
case MYSQL_TYPE_TINY:
3861
case MYSQL_TYPE_LONG:
3862
case MYSQL_TYPE_SHORT:
3863
case MYSQL_TYPE_LONGLONG:
3864
if (!(item= new Item_return_int(fields_info->field_name,
3865
fields_info->field_length,
3866
fields_info->field_type,
3867
fields_info->value)))
3871
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3873
case MYSQL_TYPE_NEWDATE:
3874
case MYSQL_TYPE_TIME:
3875
case MYSQL_TYPE_TIMESTAMP:
3876
case MYSQL_TYPE_DATETIME:
3877
if (!(item=new Item_return_date_time(fields_info->field_name,
3878
fields_info->field_type)))
3883
case MYSQL_TYPE_DOUBLE:
3884
if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
3885
fields_info->field_length)) == NULL)
3888
case MYSQL_TYPE_NEWDECIMAL:
3889
if (!(item= new Item_decimal((int64_t) fields_info->value, false)))
3893
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3894
item->decimals= fields_info->field_length%10;
3895
item->max_length= (fields_info->field_length/100)%100;
3896
if (item->unsigned_flag == 0)
3897
item->max_length+= 1;
3898
if (item->decimals > 0)
3899
item->max_length+= 1;
3900
item->set_name(fields_info->field_name,
3901
strlen(fields_info->field_name), cs);
3903
case MYSQL_TYPE_BLOB:
3904
if (!(item= new Item_blob(fields_info->field_name,
3905
fields_info->field_length)))
3911
/* Don't let unimplemented types pass through. Could be a grave error. */
3912
assert(fields_info->field_type == MYSQL_TYPE_STRING);
3914
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
3918
item->set_name(fields_info->field_name,
3919
strlen(fields_info->field_name), cs);
3922
field_list.push_back(item);
3923
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
3926
TMP_TABLE_PARAM *tmp_table_param =
3927
(TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
3928
tmp_table_param->init();
3929
tmp_table_param->table_charset= cs;
3930
tmp_table_param->field_count= field_count;
3931
tmp_table_param->schema_table= 1;
3932
SELECT_LEX *select_lex= thd->lex->current_select;
3933
if (!(table= create_tmp_table(thd, tmp_table_param,
3934
field_list, (ORDER*) 0, 0, 0,
3935
(select_lex->options | thd->options |
3936
TMP_TABLE_ALL_COLUMNS),
3937
HA_POS_ERROR, table_list->alias)))
3939
my_bitmap_map* bitmaps=
3940
(my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
3941
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
3943
table->read_set= &table->def_read_set;
3944
bitmap_clear_all(table->read_set);
3945
table_list->schema_table_param= tmp_table_param;
3951
For old SHOW compatibility. It is used when
3952
old SHOW doesn't have generated column names
3953
Make list of fields for SHOW
3958
schema_table pointer to 'schema_tables' element
3965
int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
3967
ST_FIELD_INFO *field_info= schema_table->fields_info;
3968
Name_resolution_context *context= &thd->lex->select_lex.context;
3969
for (; field_info->field_name; field_info++)
3971
if (field_info->old_name)
3973
Item_field *field= new Item_field(context,
3974
NullS, NullS, field_info->field_name);
3977
field->set_name(field_info->old_name,
3978
strlen(field_info->old_name),
3979
system_charset_info);
3980
if (add_item_to_list(thd, field))
3989
int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
3993
SELECT_LEX *sel= lex->current_select;
3994
Name_resolution_context *context= &sel->context;
3996
if (!sel->item_list.elements)
3998
ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
3999
String buffer(tmp,sizeof(tmp), system_charset_info);
4000
Item_field *field= new Item_field(context,
4001
NullS, NullS, field_info->field_name);
4002
if (!field || add_item_to_list(thd, field))
4005
buffer.append(field_info->old_name);
4006
if (lex->wild && lex->wild->ptr())
4008
buffer.append(STRING_WITH_LEN(" ("));
4009
buffer.append(lex->wild->ptr());
4012
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4018
int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4021
String buffer(tmp,sizeof(tmp), thd->charset());
4023
Name_resolution_context *context= &lex->select_lex.context;
4025
ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
4027
buffer.append(field_info->old_name);
4028
buffer.append(lex->select_lex.db);
4029
if (lex->wild && lex->wild->ptr())
4031
buffer.append(STRING_WITH_LEN(" ("));
4032
buffer.append(lex->wild->ptr());
4035
Item_field *field= new Item_field(context,
4036
NullS, NullS, field_info->field_name);
4037
if (add_item_to_list(thd, field))
4039
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4040
if (thd->lex->verbose)
4042
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4043
field_info= &schema_table->fields_info[3];
4044
field= new Item_field(context, NullS, NullS, field_info->field_name);
4045
if (add_item_to_list(thd, field))
4047
field->set_name(field_info->old_name, strlen(field_info->old_name),
4048
system_charset_info);
4054
int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4056
int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
4057
int *field_num= fields_arr;
4058
ST_FIELD_INFO *field_info;
4059
Name_resolution_context *context= &thd->lex->select_lex.context;
4061
for (; *field_num >= 0; field_num++)
4063
field_info= &schema_table->fields_info[*field_num];
4064
if (!thd->lex->verbose && (*field_num == 13 ||
4068
Item_field *field= new Item_field(context,
4069
NullS, NullS, field_info->field_name);
4072
field->set_name(field_info->old_name,
4073
strlen(field_info->old_name),
4074
system_charset_info);
4075
if (add_item_to_list(thd, field))
4083
int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4085
int fields_arr[]= {0, 2, 1, 3, -1};
4086
int *field_num= fields_arr;
4087
ST_FIELD_INFO *field_info;
4088
Name_resolution_context *context= &thd->lex->select_lex.context;
4090
for (; *field_num >= 0; field_num++)
4092
field_info= &schema_table->fields_info[*field_num];
4093
Item_field *field= new Item_field(context,
4094
NullS, NullS, field_info->field_name);
4097
field->set_name(field_info->old_name,
4098
strlen(field_info->old_name),
4099
system_charset_info);
4100
if (add_item_to_list(thd, field))
4109
Create information_schema table
4112
mysql_schema_table()
4115
table_list pointer to table_list
4122
int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
4125
if (!(table= table_list->schema_table->create_table(thd, table_list)))
4127
table->s->tmp_table= SYSTEM_TMP_TABLE;
4129
This test is necessary to make
4130
case insensitive file systems +
4131
upper case table names(information schema tables) +
4135
if (table_list->schema_table_name)
4136
table->alias_name_used= my_strcasecmp(table_alias_charset,
4137
table_list->schema_table_name,
4139
table_list->table_name= table->s->table_name.str;
4140
table_list->table_name_length= table->s->table_name.length;
4141
table_list->table= table;
4142
table->next= thd->derived_tables;
4143
thd->derived_tables= table;
4144
table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
4146
if (table_list->schema_table_reformed) // show command
4148
SELECT_LEX *sel= lex->current_select;
4150
Field_translator *transl, *org_transl;
4152
if (table_list->field_translation)
4154
Field_translator *end= table_list->field_translation_end;
4155
for (transl= table_list->field_translation; transl < end; transl++)
4157
if (!transl->item->fixed &&
4158
transl->item->fix_fields(thd, &transl->item))
4163
List_iterator_fast<Item> it(sel->item_list);
4165
(Field_translator*)(thd->stmt_arena->
4166
alloc(sel->item_list.elements *
4167
sizeof(Field_translator)))))
4171
for (org_transl= transl; (item= it++); transl++)
4174
transl->name= item->name;
4175
if (!item->fixed && item->fix_fields(thd, &transl->item))
4180
table_list->field_translation= org_transl;
4181
table_list->field_translation_end= transl;
4189
Generate select from information_schema table
4192
make_schema_select()
4194
sel pointer to SELECT_LEX
4195
schema_table_idx index of 'schema_tables' element
4202
int make_schema_select(THD *thd, SELECT_LEX *sel,
4203
enum enum_schema_tables schema_table_idx)
4205
ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
4206
LEX_STRING db, table;
4208
We have to make non const db_name & table_name
4209
because of lower_case_table_names
4211
thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str,
4212
INFORMATION_SCHEMA_NAME.length, 0);
4213
thd->make_lex_string(&table, schema_table->table_name,
4214
strlen(schema_table->table_name), 0);
4215
if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
4216
!sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
4226
Fill temporary schema tables before SELECT
4229
get_schema_tables_result()
4230
join join which use schema tables
4231
executed_place place where I_S table processed
4238
bool get_schema_tables_result(JOIN *join,
4239
enum enum_schema_table_state executed_place)
4241
JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
4242
THD *thd= join->thd;
4246
thd->no_warnings_for_error= 1;
4247
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
4249
if (!tab->table || !tab->table->pos_in_table_list)
4252
TABLE_LIST *table_list= tab->table->pos_in_table_list;
4253
if (table_list->schema_table)
4255
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
4256
lex->current_select->master_unit()->item);
4259
/* skip I_S optimizations specific to get_all_tables */
4260
if (thd->lex->describe &&
4261
(table_list->schema_table->fill_table != get_all_tables))
4265
If schema table is already processed and
4266
the statement is not a subselect then
4267
we don't need to fill this table again.
4268
If schema table is already processed and
4269
schema_table_state != executed_place then
4270
table is already processed and
4271
we should skip second data processing.
4273
if (table_list->schema_table_state &&
4274
(!is_subselect || table_list->schema_table_state != executed_place))
4278
if table is used in a subselect and
4279
table has been processed earlier with the same
4280
'executed_place' value then we should refresh the table.
4282
if (table_list->schema_table_state && is_subselect)
4284
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
4285
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
4286
table_list->table->file->ha_delete_all_rows();
4287
free_io_cache(table_list->table);
4288
filesort_free_buffers(table_list->table,1);
4289
table_list->table->null_row= 0;
4292
table_list->table->file->stats.records= 0;
4294
if (table_list->schema_table->fill_table(thd, table_list,
4299
tab->read_record.file= table_list->table->file;
4300
table_list->schema_table_state= executed_place;
4303
tab->read_record.file= table_list->table->file;
4304
table_list->schema_table_state= executed_place;
4307
thd->no_warnings_for_error= 0;
4311
ST_FIELD_INFO schema_fields_info[]=
4313
{"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4314
{"SCHEMA_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
4316
{"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0,
4318
{"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4319
{"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4320
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4324
ST_FIELD_INFO tables_fields_info[]=
4326
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4327
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4328
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
4330
{"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4331
{"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine", OPEN_FRM_ONLY},
4332
{"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4333
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
4334
{"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", OPEN_FULL_TABLE},
4335
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4336
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
4337
{"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4338
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
4339
{"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4340
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
4341
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4342
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
4343
{"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4344
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
4345
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4346
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
4347
{"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0,
4348
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
4349
{"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4350
{"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4351
{"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
4352
{"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
4353
{"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4354
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
4355
{"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options",
4357
{"TABLE_COMMENT", TABLE_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
4358
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4362
ST_FIELD_INFO columns_fields_info[]=
4364
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
4365
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4366
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4367
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Field",
4369
{"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4370
MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
4371
{"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0,
4372
1, "Default", OPEN_FRM_ONLY},
4373
{"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
4374
{"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4375
{"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
4376
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4377
{"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
4378
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4379
{"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
4380
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4381
{"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
4382
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4383
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
4384
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
4385
{"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type", OPEN_FRM_ONLY},
4386
{"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key", OPEN_FRM_ONLY},
4387
{"EXTRA", 27, MYSQL_TYPE_STRING, 0, 0, "Extra", OPEN_FRM_ONLY},
4388
{"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges", OPEN_FRM_ONLY},
4389
{"COLUMN_COMMENT", COLUMN_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
4390
{"STORAGE", 8, MYSQL_TYPE_STRING, 0, 0, "Storage", OPEN_FRM_ONLY},
4391
{"FORMAT", 8, MYSQL_TYPE_STRING, 0, 0, "Format", OPEN_FRM_ONLY},
4392
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4396
ST_FIELD_INFO charsets_fields_info[]=
4398
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset",
4400
{"DEFAULT_COLLATE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Default collation",
4402
{"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description",
4404
{"MAXLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
4405
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4409
ST_FIELD_INFO collation_fields_info[]=
4411
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Collation", SKIP_OPEN_TABLE},
4412
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset",
4414
{"ID", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Id",
4416
{"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default", SKIP_OPEN_TABLE},
4417
{"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled", SKIP_OPEN_TABLE},
4418
{"SORTLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
4419
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4423
ST_FIELD_INFO events_fields_info[]=
4425
{"EVENT_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4426
{"EVENT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db",
4428
{"EVENT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
4430
{"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
4431
{"TIME_ZONE", 64, MYSQL_TYPE_STRING, 0, 0, "Time zone", SKIP_OPEN_TABLE},
4432
{"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4433
{"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4434
{"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
4435
{"EXECUTE_AT", 0, MYSQL_TYPE_DATETIME, 0, 1, "Execute at", SKIP_OPEN_TABLE},
4436
{"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value",
4438
{"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field",
4440
{"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4441
{"STARTS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Starts", SKIP_OPEN_TABLE},
4442
{"ENDS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Ends", SKIP_OPEN_TABLE},
4443
{"STATUS", 18, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
4444
{"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4445
{"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
4446
{"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
4447
{"LAST_EXECUTED", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
4448
{"EVENT_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4449
{"ORIGINATOR", 10, MYSQL_TYPE_LONGLONG, 0, 0, "Originator", SKIP_OPEN_TABLE},
4450
{"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
4451
"character_set_client", SKIP_OPEN_TABLE},
4452
{"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
4453
"collation_connection", SKIP_OPEN_TABLE},
4454
{"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
4455
"Database Collation", SKIP_OPEN_TABLE},
4456
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4461
ST_FIELD_INFO coll_charset_app_fields_info[]=
4463
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4464
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4465
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4469
ST_FIELD_INFO stat_fields_info[]=
4471
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
4472
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4473
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", OPEN_FRM_ONLY},
4474
{"NON_UNIQUE", 1, MYSQL_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
4475
{"INDEX_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4476
{"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name",
4478
{"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
4479
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name",
4481
{"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
4482
{"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 1,
4483
"Cardinality", OPEN_FULL_TABLE},
4484
{"SUB_PART", 3, MYSQL_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
4485
{"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed", OPEN_FRM_ONLY},
4486
{"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
4487
{"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type", OPEN_FULL_TABLE},
4488
{"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment", OPEN_FRM_ONLY},
4489
{"INDEX_COMMENT", INDEX_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0, "Index_Comment", OPEN_FRM_ONLY},
4490
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4494
ST_FIELD_INFO user_privileges_fields_info[]=
4496
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4497
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4498
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4499
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4500
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4504
ST_FIELD_INFO schema_privileges_fields_info[]=
4506
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4507
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4508
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4509
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4510
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4511
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4515
ST_FIELD_INFO table_privileges_fields_info[]=
4517
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4518
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4519
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4520
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4521
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4522
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4523
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4527
ST_FIELD_INFO column_privileges_fields_info[]=
4529
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4530
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4531
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4532
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4533
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4534
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4535
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4536
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4540
ST_FIELD_INFO table_constraints_fields_info[]=
4542
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4543
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4545
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4547
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4548
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4549
{"CONSTRAINT_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4551
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4555
ST_FIELD_INFO key_column_usage_fields_info[]=
4557
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4558
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4560
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4562
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4563
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4564
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4565
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4566
{"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
4567
{"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONGLONG, 0, 1, 0,
4569
{"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
4571
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
4573
{"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
4575
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4579
ST_FIELD_INFO table_names_fields_info[]=
4581
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4582
{"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4583
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_",
4585
{"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type",
4587
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4591
ST_FIELD_INFO open_tables_fields_info[]=
4593
{"Database", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
4595
{"Table",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", SKIP_OPEN_TABLE},
4596
{"In_use", 1, MYSQL_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
4597
{"Name_locked", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
4598
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4602
ST_FIELD_INFO variables_fields_info[]=
4604
{"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name",
4606
{"VARIABLE_VALUE", 16300, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE},
4607
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4611
ST_FIELD_INFO processlist_fields_info[]=
4613
{"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
4614
{"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
4615
{"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host",
4617
{"DB", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Db", SKIP_OPEN_TABLE},
4618
{"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command", SKIP_OPEN_TABLE},
4619
{"TIME", 7, MYSQL_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
4620
{"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE},
4621
{"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info",
4623
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4627
ST_FIELD_INFO plugin_fields_info[]=
4629
{"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
4631
{"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4632
{"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
4633
{"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
4634
{"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library",
4636
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4637
{"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4638
{"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
4639
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4642
ST_FIELD_INFO referential_constraints_fields_info[]=
4644
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4645
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4647
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4649
{"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0,
4651
{"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4653
{"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0,
4654
MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
4655
{"MATCH_OPTION", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4656
{"UPDATE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4657
{"DELETE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4658
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4659
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4661
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4665
ST_FIELD_INFO parameters_fields_info[]=
4667
{"SPECIFIC_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4668
{"SPECIFIC_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4669
{"SPECIFIC_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4670
{"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FULL_TABLE},
4671
{"PARAMETER_MODE", 5, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4672
{"PARAMETER_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4673
{"DATA_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4674
{"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4675
{"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4676
{"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4677
{"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4678
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4679
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4680
{"DTD_IDENTIFIER", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4681
{"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4682
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}
4687
Description of ST_FIELD_INFO in table.h
4689
Make sure that the order of schema_tables and enum_schema_tables are the same.
4693
ST_SCHEMA_TABLE schema_tables[]=
4695
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
4696
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4697
{"COLLATIONS", collation_fields_info, create_schema_table,
4698
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4699
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4700
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4701
{"COLUMNS", columns_fields_info, create_schema_table,
4702
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
4703
OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL},
4704
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4705
fill_status, make_old_format, 0, -1, -1, 0, 0},
4706
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
4707
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4708
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
4709
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
4711
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
4712
fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
4713
{"PLUGINS", plugin_fields_info, create_schema_table,
4714
fill_plugins, make_old_format, 0, -1, -1, 0, 0},
4715
{"PROCESSLIST", processlist_fields_info, create_schema_table,
4716
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
4717
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
4718
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
4719
1, 9, 0, OPEN_TABLE_ONLY},
4720
{"SCHEMATA", schema_fields_info, create_schema_table,
4721
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
4722
{"SESSION_STATUS", variables_fields_info, create_schema_table,
4723
fill_status, make_old_format, 0, -1, -1, 0, 0},
4724
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4725
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4726
{"STATISTICS", stat_fields_info, create_schema_table,
4727
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4728
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4729
{"STATUS", variables_fields_info, create_schema_table, fill_status,
4730
make_old_format, 0, -1, -1, 1, 0},
4731
{"TABLES", tables_fields_info, create_schema_table,
4732
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4733
OPTIMIZE_I_S_TABLE},
4734
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4735
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
4736
{"TABLE_NAMES", table_names_fields_info, create_schema_table,
4737
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
4738
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
4739
make_old_format, 0, -1, -1, 1, 0},
4740
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
4744
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
4745
template class List_iterator_fast<char>;
4746
template class List<char>;
4749
int initialize_schema_table(st_plugin_int *plugin)
4751
ST_SCHEMA_TABLE *schema_table;
4753
if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
4754
MYF(MY_WME | MY_ZEROFILL))))
4756
/* Historical Requirement */
4757
plugin->data= schema_table; // shortcut for the future
4758
if (plugin->plugin->init)
4760
schema_table->create_table= create_schema_table;
4761
schema_table->old_format= make_old_format;
4762
schema_table->idx_field1= -1,
4763
schema_table->idx_field2= -1;
4765
/* Make the name available to the init() function. */
4766
schema_table->table_name= plugin->name.str;
4768
if (plugin->plugin->init(schema_table))
4770
sql_print_error("Plugin '%s' init function returned error.",
4775
/* Make sure the plugin name is not set inside the init() function. */
4776
schema_table->table_name= plugin->name.str;
4781
my_free(schema_table, MYF(0));
4785
int finalize_schema_table(st_plugin_int *plugin)
4787
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
4789
if (schema_table && plugin->plugin->deinit)
4790
my_free(schema_table, MYF(0));