132
551
# Quote character
135
int get_quote_char_for_identifier()
142
bool buildScemas(Session *session)
144
session->getLex()->sql_command= SQLCOM_SELECT;
145
session->getLex()->statement= new statement::Show(session);
147
std::string column_name= "Database";
148
if (session->getLex()->wild)
150
column_name.append(" (");
151
column_name.append(session->getLex()->wild->ptr());
152
column_name.append(")");
155
if (session->getLex()->current_select->where)
157
if (prepare_new_schema_table(session, session->getLex(), "SCHEMAS"))
162
if (prepare_new_schema_table(session, session->getLex(), "SHOW_SCHEMAS"))
166
Item_field *my_field= new Item_field(&session->getLex()->current_select->context, NULL, NULL, "SCHEMA_NAME");
167
my_field->is_autogenerated_name= false;
168
my_field->set_name(column_name.c_str(), column_name.length(), system_charset_info);
170
if (session->add_item_to_list(my_field))
173
if (session->add_order_to_list(my_field, true))
179
bool buildTables(Session *session, const char *ident)
181
session->getLex()->sql_command= SQLCOM_SELECT;
183
drizzled::statement::Show *select= new statement::Show(session);
184
session->getLex()->statement= select;
186
std::string column_name= "Tables_in_";
188
util::string::const_shared_ptr schema(session->schema());
191
identifier::Schema identifier(ident);
192
column_name.append(ident);
193
session->getLex()->select_lex.db= const_cast<char *>(ident);
194
if (not plugin::StorageEngine::doesSchemaExist(identifier))
196
my_error(ER_BAD_DB_ERROR, identifier);
198
select->setShowPredicate(ident, "");
200
else if (schema and not schema->empty())
202
column_name.append(*schema);
203
select->setShowPredicate(*schema, "");
207
my_error(ER_NO_DB_ERROR, MYF(0));
212
if (session->getLex()->wild)
214
column_name.append(" (");
215
column_name.append(session->getLex()->wild->ptr());
216
column_name.append(")");
219
if (prepare_new_schema_table(session, session->getLex(), "SHOW_TABLES"))
222
Item_field *my_field= new Item_field(&session->getLex()->current_select->context, NULL, NULL, "TABLE_NAME");
223
my_field->is_autogenerated_name= false;
224
my_field->set_name(column_name.c_str(), column_name.length(), system_charset_info);
226
if (session->add_item_to_list(my_field))
229
if (session->add_order_to_list(my_field, true))
235
bool buildTemporaryTables(Session *session)
237
session->getLex()->sql_command= SQLCOM_SELECT;
239
session->getLex()->statement= new statement::Show(session);
242
if (prepare_new_schema_table(session, session->getLex(), "SHOW_TEMPORARY_TABLES"))
245
if (session->add_item_to_list( new Item_field(&session->getLex()->current_select->context, NULL, NULL, "*")))
248
(session->getLex()->current_select->with_wild)++;
253
bool buildTableStatus(Session *session, const char *ident)
255
session->getLex()->sql_command= SQLCOM_SELECT;
256
drizzled::statement::Show *select= new statement::Show(session);
257
session->getLex()->statement= select;
259
std::string column_name= "Tables_in_";
261
util::string::const_shared_ptr schema(session->schema());
264
session->getLex()->select_lex.db= const_cast<char *>(ident);
266
identifier::Schema identifier(ident);
267
if (not plugin::StorageEngine::doesSchemaExist(identifier))
269
my_error(ER_BAD_DB_ERROR, identifier);
272
select->setShowPredicate(ident, "");
276
select->setShowPredicate(*schema, "");
280
my_error(ER_NO_DB_ERROR, MYF(0));
284
if (prepare_new_schema_table(session, session->getLex(), "SHOW_TABLE_STATUS"))
287
if (session->add_item_to_list( new Item_field(&session->getLex()->current_select->
292
(session->getLex()->current_select->with_wild)++;
297
bool buildEngineStatus(Session *session, LEX_STRING)
299
session->getLex()->sql_command= SQLCOM_SELECT;
300
drizzled::statement::Show *select= new statement::Show(session);
301
session->getLex()->statement= select;
303
my_error(ER_USE_DATA_DICTIONARY);
307
bool buildColumns(Session *session, const char *schema_ident, Table_ident *table_ident)
309
session->getLex()->sql_command= SQLCOM_SELECT;
311
drizzled::statement::Show *select= new statement::Show(session);
312
session->getLex()->statement= select;
314
util::string::const_shared_ptr schema(session->schema());
317
select->setShowPredicate(schema_ident, table_ident->table.str);
319
else if (table_ident->db.str)
321
select->setShowPredicate(table_ident->db.str, table_ident->table.str);
325
select->setShowPredicate(*schema, table_ident->table.str);
329
my_error(ER_NO_DB_ERROR, MYF(0));
334
drizzled::identifier::Table identifier(select->getShowSchema().c_str(), table_ident->table.str);
335
if (not plugin::StorageEngine::doesTableExist(*session, identifier))
337
my_error(ER_TABLE_UNKNOWN, identifier);
341
if (prepare_new_schema_table(session, session->getLex(), "SHOW_COLUMNS"))
344
if (session->add_item_to_list( new Item_field(&session->getLex()->current_select->context, NULL, NULL, "*")))
347
(session->getLex()->current_select->with_wild)++;
352
void buildSelectWarning(Session *session)
354
(void) create_select_for_variable(session, "warning_count");
355
session->getLex()->statement= new statement::Show(session);
358
void buildSelectError(Session *session)
360
(void) create_select_for_variable(session, "error_count");
361
session->getLex()->statement= new statement::Show(session);
364
void buildWarnings(Session *session)
366
session->getLex()->statement= new statement::ShowWarnings(session);
369
void buildErrors(Session *session)
371
session->getLex()->statement= new statement::ShowErrors(session);
374
bool buildIndex(Session *session, const char *schema_ident, Table_ident *table_ident)
376
session->getLex()->sql_command= SQLCOM_SELECT;
377
drizzled::statement::Show *select= new statement::Show(session);
378
session->getLex()->statement= select;
380
util::string::const_shared_ptr schema(session->schema());
383
select->setShowPredicate(schema_ident, table_ident->table.str);
385
else if (table_ident->db.str)
387
select->setShowPredicate(table_ident->db.str, table_ident->table.str);
391
select->setShowPredicate(*schema, table_ident->table.str);
395
my_error(ER_NO_DB_ERROR, MYF(0));
400
drizzled::identifier::Table identifier(select->getShowSchema().c_str(), table_ident->table.str);
401
if (not plugin::StorageEngine::doesTableExist(*session, identifier))
403
my_error(ER_TABLE_UNKNOWN, identifier);
407
if (prepare_new_schema_table(session, session->getLex(), "SHOW_INDEXES"))
410
if (session->add_item_to_list( new Item_field(&session->getLex()->current_select->context, NULL, NULL, "*")))
413
(session->getLex()->current_select->with_wild)++;
418
bool buildStatus(Session *session, const drizzled::sql_var_t is_global)
420
session->getLex()->sql_command= SQLCOM_SELECT;
421
session->getLex()->statement= new statement::Show(session);
423
if (is_global == OPT_GLOBAL)
425
if (prepare_new_schema_table(session, session->getLex(), "GLOBAL_STATUS"))
430
if (prepare_new_schema_table(session, session->getLex(), "SESSION_STATUS"))
434
std::string key("Variable_name");
435
std::string value("Value");
437
Item_field *my_field= new Item_field(&session->getLex()->current_select->context, NULL, NULL, "VARIABLE_NAME");
438
my_field->is_autogenerated_name= false;
439
my_field->set_name(key.c_str(), key.length(), system_charset_info);
441
if (session->add_item_to_list(my_field))
444
my_field= new Item_field(&session->getLex()->current_select->context, NULL, NULL, "VARIABLE_VALUE");
445
my_field->is_autogenerated_name= false;
446
my_field->set_name(value.c_str(), value.length(), system_charset_info);
448
if (session->add_item_to_list(my_field))
454
bool buildCreateTable(Session *session, Table_ident *ident)
456
session->getLex()->sql_command= SQLCOM_SELECT;
457
statement::Show *select= new statement::Show(session);
458
session->getLex()->statement= select;
460
if (session->getLex()->statement == NULL)
463
if (prepare_new_schema_table(session, session->getLex(), "TABLE_SQL_DEFINITION"))
466
util::string::const_shared_ptr schema(session->schema());
469
select->setShowPredicate(ident->db.str, ident->table.str);
473
select->setShowPredicate(*schema, ident->table.str);
477
my_error(ER_NO_DB_ERROR, MYF(0));
481
std::string key("Table");
482
std::string value("Create Table");
484
Item_field *my_field= new Item_field(&session->getLex()->current_select->context, NULL, NULL, "TABLE_NAME");
485
my_field->is_autogenerated_name= false;
486
my_field->set_name(key.c_str(), key.length(), system_charset_info);
488
if (session->add_item_to_list(my_field))
491
my_field= new Item_field(&session->getLex()->current_select->context, NULL, NULL, "TABLE_SQL_DEFINITION");
492
my_field->is_autogenerated_name= false;
493
my_field->set_name(value.c_str(), value.length(), system_charset_info);
495
if (session->add_item_to_list(my_field))
501
bool buildProcesslist(Session *session)
503
session->getLex()->sql_command= SQLCOM_SELECT;
504
session->getLex()->statement= new statement::Show(session);
506
if (prepare_new_schema_table(session, session->getLex(), "PROCESSLIST"))
509
if (session->add_item_to_list( new Item_field(&session->getLex()->current_select->context, NULL, NULL, "*")))
512
(session->getLex()->current_select->with_wild)++;
517
bool buildVariables(Session *session, const drizzled::sql_var_t is_global)
519
session->getLex()->sql_command= SQLCOM_SELECT;
520
session->getLex()->statement= new statement::Show(session);
522
if (is_global == OPT_GLOBAL)
524
if (prepare_new_schema_table(session, session->getLex(), "GLOBAL_VARIABLES"))
529
if (prepare_new_schema_table(session, session->getLex(), "SESSION_VARIABLES"))
533
std::string key("Variable_name");
534
std::string value("Value");
536
Item_field *my_field= new Item_field(&session->getLex()->current_select->context, NULL, NULL, "VARIABLE_NAME");
537
my_field->is_autogenerated_name= false;
538
my_field->set_name(key.c_str(), key.length(), system_charset_info);
540
if (session->add_item_to_list(my_field))
543
my_field= new Item_field(&session->getLex()->current_select->context, NULL, NULL, "VARIABLE_VALUE");
544
my_field->is_autogenerated_name= false;
545
my_field->set_name(value.c_str(), value.length(), system_charset_info);
547
if (session->add_item_to_list(my_field))
553
bool buildCreateSchema(Session *session, LEX_STRING &ident)
555
session->getLex()->sql_command= SQLCOM_SELECT;
556
drizzled::statement::Show *select= new statement::Show(session);
557
session->getLex()->statement= select;
559
if (prepare_new_schema_table(session, session->getLex(), "SCHEMA_SQL_DEFINITION"))
562
util::string::const_shared_ptr schema(session->schema());
565
select->setShowPredicate(ident.str);
569
select->setShowPredicate(*schema);
573
my_error(ER_NO_DB_ERROR, MYF(0));
577
std::string key("Database");
578
std::string value("Create Database");
580
Item_field *my_field= new Item_field(&session->getLex()->current_select->context, NULL, NULL, "SCHEMA_NAME");
581
my_field->is_autogenerated_name= false;
582
my_field->set_name(key.c_str(), key.length(), system_charset_info);
584
if (session->add_item_to_list(my_field))
587
my_field= new Item_field(&session->getLex()->current_select->context, NULL, NULL, "SCHEMA_SQL_DEFINITION");
588
my_field->is_autogenerated_name= false;
589
my_field->set_name(value.c_str(), value.length(), system_charset_info);
591
if (session->add_item_to_list(my_field))
597
bool buildDescribe(Session *session, Table_ident *ident)
599
session->getLex()->lock_option= TL_READ;
600
init_select(session->getLex());
601
session->getLex()->current_select->parsing_place= SELECT_LIST;
602
session->getLex()->sql_command= SQLCOM_SELECT;
603
drizzled::statement::Show *select= new statement::Show(session);
604
session->getLex()->statement= select;
605
session->getLex()->select_lex.db= 0;
607
util::string::const_shared_ptr schema(session->schema());
610
select->setShowPredicate(ident->db.str, ident->table.str);
614
select->setShowPredicate(*schema, ident->table.str);
618
my_error(ER_NO_DB_ERROR, MYF(0));
623
drizzled::identifier::Table identifier(select->getShowSchema().c_str(), ident->table.str);
624
if (not plugin::StorageEngine::doesTableExist(*session, identifier))
626
my_error(ER_TABLE_UNKNOWN, identifier);
630
if (prepare_new_schema_table(session, session->getLex(), "SHOW_COLUMNS"))
635
if (session->add_item_to_list( new Item_field(&session->getLex()->current_select->
642
(session->getLex()->current_select->with_wild)++;
647
} /* namespace drizzled */
649
} /* namespace drizzled */
554
int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
557
!is_keyword(name,length) &&
558
!require_quotes(name, length) &&
559
!(thd->options & OPTION_QUOTE_SHOW_CREATE))
565
/* Append directory name (if exists) to CREATE INFO */
567
static void append_directory(THD *thd __attribute__((__unused__)),
568
String *packet, const char *dir_type,
569
const char *filename)
573
uint length= dirname_length(filename);
575
packet->append(dir_type);
576
packet->append(STRING_WITH_LEN(" DIRECTORY='"));
577
packet->append(filename, length);
578
packet->append('\'');
583
#define LIST_PROCESS_HOST_LEN 64
585
static bool get_field_default_value(THD *thd __attribute__((__unused__)),
586
Field *timestamp_field,
587
Field *field, String *def_value,
591
bool has_now_default;
594
We are using CURRENT_TIMESTAMP instead of NOW because it is
597
has_now_default= (timestamp_field == field &&
598
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
600
has_default= (field->type() != FIELD_TYPE_BLOB &&
601
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
602
field->unireg_check != Field::NEXT_NUMBER
605
def_value->length(0);
609
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
610
else if (!field->is_null())
611
{ // Not null by default
612
char tmp[MAX_FIELD_WIDTH];
613
String type(tmp, sizeof(tmp), field->charset());
614
field->val_str(&type);
619
/* convert to system_charset_info == utf8 */
620
def_val.copy(type.ptr(), type.length(), field->charset(),
621
system_charset_info, &dummy_errors);
623
append_unescaped(def_value, def_val.ptr(), def_val.length());
625
def_value->append(def_val.ptr(), def_val.length());
628
def_value->append(STRING_WITH_LEN("''"));
630
else if (field->maybe_null() && quoted)
631
def_value->append(STRING_WITH_LEN("NULL")); // Null as default
640
Build a CREATE TABLE statement for a table.
645
table_list A list containing one table to write statement
647
packet Pointer to a string where statement will be
649
create_info_arg Pointer to create information that can be used
650
to tailor the format of the statement. Can be
651
NULL, in which case only SQL_MODE is considered
652
when building the statement.
655
Currently always return 0, but might return error code in the
662
int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
663
HA_CREATE_INFO *create_info_arg)
665
List<Item> field_list;
666
char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
668
String type(tmp, sizeof(tmp), system_charset_info);
669
String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
673
TABLE *table= table_list->table;
674
handler *file= table->file;
675
TABLE_SHARE *share= table->s;
676
HA_CREATE_INFO create_info;
677
bool show_table_options= false;
678
my_bitmap_map *old_map;
680
restore_record(table, s->default_values); // Get empty record
682
if (share->tmp_table)
683
packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
685
packet->append(STRING_WITH_LEN("CREATE TABLE "));
686
if (create_info_arg &&
687
(create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
688
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
689
if (table_list->schema_table)
690
alias= table_list->schema_table->table_name;
693
if (lower_case_table_names == 2)
697
alias= share->table_name.str;
700
append_identifier(thd, packet, alias, strlen(alias));
701
packet->append(STRING_WITH_LEN(" (\n"));
703
We need this to get default values from the table
704
We have to restore the read_set if we are called from insert in case
705
of row based replication.
707
old_map= tmp_use_all_columns(table, table->read_set);
709
for (ptr=table->field ; (field= *ptr); ptr++)
711
uint flags = field->flags;
713
if (ptr != table->field)
714
packet->append(STRING_WITH_LEN(",\n"));
716
packet->append(STRING_WITH_LEN(" "));
717
append_identifier(thd,packet,field->field_name, strlen(field->field_name));
719
// check for surprises from the previous call to Field::sql_type()
720
if (type.ptr() != tmp)
721
type.set(tmp, sizeof(tmp), system_charset_info);
723
type.set_charset(system_charset_info);
725
field->sql_type(type);
726
packet->append(type.ptr(), type.length(), system_charset_info);
728
if (field->has_charset())
730
if (field->charset() != share->table_charset)
732
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
733
packet->append(field->charset()->csname);
736
For string types dump collation name only if
737
collation is not primary for the given charset
739
if (!(field->charset()->state & MY_CS_PRIMARY))
741
packet->append(STRING_WITH_LEN(" COLLATE "));
742
packet->append(field->charset()->name);
746
if (flags & NOT_NULL_FLAG)
747
packet->append(STRING_WITH_LEN(" NOT NULL"));
748
else if (field->type() == MYSQL_TYPE_TIMESTAMP)
751
TIMESTAMP field require explicit NULL flag, because unlike
752
all other fields they are treated as NOT NULL by default.
754
packet->append(STRING_WITH_LEN(" NULL"));
758
Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
759
and about STORAGE (DISK or MEMORY).
761
enum column_format_type column_format= (enum column_format_type)
762
((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
765
packet->append(STRING_WITH_LEN(" /*!"));
766
packet->append(STRING_WITH_LEN(MYSQL_VERSION_TABLESPACE_IN_FRM_STR));
767
packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
768
if (column_format == COLUMN_FORMAT_TYPE_FIXED)
769
packet->append(STRING_WITH_LEN(" FIXED */"));
771
packet->append(STRING_WITH_LEN(" DYNAMIC */"));
774
if (get_field_default_value(thd, table->timestamp_field,
775
field, &def_value, 1))
777
packet->append(STRING_WITH_LEN(" DEFAULT "));
778
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
781
if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
782
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
784
if (field->unireg_check == Field::NEXT_NUMBER)
785
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
787
if (field->comment.length)
789
packet->append(STRING_WITH_LEN(" COMMENT "));
790
append_unescaped(packet, field->comment.str, field->comment.length);
794
key_info= table->key_info;
795
bzero((char*) &create_info, sizeof(create_info));
796
/* Allow update_create_info to update row type */
797
create_info.row_type= share->row_type;
798
file->update_create_info(&create_info);
799
primary_key= share->primary_key;
801
for (uint i=0 ; i < share->keys ; i++,key_info++)
803
KEY_PART_INFO *key_part= key_info->key_part;
804
bool found_primary=0;
805
packet->append(STRING_WITH_LEN(",\n "));
807
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
811
No space at end, because a space will be added after where the
812
identifier would go, but that is not added for primary key.
814
packet->append(STRING_WITH_LEN("PRIMARY KEY"));
816
else if (key_info->flags & HA_NOSAME)
817
packet->append(STRING_WITH_LEN("UNIQUE KEY "));
819
packet->append(STRING_WITH_LEN("KEY "));
822
append_identifier(thd, packet, key_info->name, strlen(key_info->name));
824
packet->append(STRING_WITH_LEN(" ("));
826
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
832
append_identifier(thd,packet,key_part->field->field_name,
833
strlen(key_part->field->field_name));
834
if (key_part->field &&
836
table->field[key_part->fieldnr-1]->key_length()))
840
end= int10_to_str((long) key_part->length /
841
key_part->field->charset()->mbmaxlen,
844
packet->append(buff,(uint) (end-buff));
848
store_key_options(thd, packet, table, key_info);
852
Get possible foreign key definitions stored in InnoDB and append them
853
to the CREATE TABLE statement
856
if ((for_str= file->get_foreign_key_create_info()))
858
packet->append(for_str, strlen(for_str));
859
file->free_foreign_key_create_info(for_str);
862
packet->append(STRING_WITH_LEN("\n)"));
864
show_table_options= true;
866
Get possible table space definitions and append them
867
to the CREATE TABLE statement
872
THEN add ENGINE only if it was used when creating the table
874
if (!create_info_arg ||
875
(create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
877
packet->append(STRING_WITH_LEN(" ENGINE="));
878
packet->append(file->table_type());
882
Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
883
and NEXT_ID > 1 (the default). We must not print the clause
884
for engines that do not support this as it would break the
885
import of dumps, but as of this writing, the test for whether
886
AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
887
is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
888
Because of that, we do not explicitly test for the feature,
889
but may extrapolate its existence from that of an AUTO_INCREMENT column.
892
if (create_info.auto_increment_value > 1)
895
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
896
end= int64_t10_to_str(create_info.auto_increment_value, buff,10);
897
packet->append(buff, (uint) (end - buff));
901
if (share->table_charset)
905
THEN add DEFAULT CHARSET only if it was used when creating the table
907
if (!create_info_arg ||
908
(create_info_arg->used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
910
packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
911
packet->append(share->table_charset->csname);
912
if (!(share->table_charset->state & MY_CS_PRIMARY))
914
packet->append(STRING_WITH_LEN(" COLLATE="));
915
packet->append(table->s->table_charset->name);
923
packet->append(STRING_WITH_LEN(" MIN_ROWS="));
924
end= int64_t10_to_str(share->min_rows, buff, 10);
925
packet->append(buff, (uint) (end- buff));
928
if (share->max_rows && !table_list->schema_table)
931
packet->append(STRING_WITH_LEN(" MAX_ROWS="));
932
end= int64_t10_to_str(share->max_rows, buff, 10);
933
packet->append(buff, (uint) (end - buff));
936
if (share->avg_row_length)
939
packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
940
end= int64_t10_to_str(share->avg_row_length, buff,10);
941
packet->append(buff, (uint) (end - buff));
944
if (share->db_create_options & HA_OPTION_PACK_KEYS)
945
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
946
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
947
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
948
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
949
if (share->db_create_options & HA_OPTION_CHECKSUM)
950
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
951
if (share->page_checksum != HA_CHOICE_UNDEF)
953
packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
954
packet->append(ha_choice_values[(uint) share->page_checksum], 1);
956
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
957
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
958
if (create_info.row_type != ROW_TYPE_DEFAULT)
960
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
961
packet->append(ha_row_type[(uint) create_info.row_type]);
963
if (share->transactional != HA_CHOICE_UNDEF)
965
packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
966
packet->append(ha_choice_values[(uint) share->transactional], 1);
968
if (table->s->key_block_size)
971
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
972
end= int64_t10_to_str(table->s->key_block_size, buff, 10);
973
packet->append(buff, (uint) (end - buff));
975
table->file->append_create_info(packet);
976
if (share->comment.length)
978
packet->append(STRING_WITH_LEN(" COMMENT="));
979
append_unescaped(packet, share->comment.str, share->comment.length);
981
if (share->connect_string.length)
983
packet->append(STRING_WITH_LEN(" CONNECTION="));
984
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
986
append_directory(thd, packet, "DATA", create_info.data_file_name);
987
append_directory(thd, packet, "INDEX", create_info.index_file_name);
989
tmp_restore_column_map(table->read_set, old_map);
994
Get a CREATE statement for a given database.
996
The database is identified by its name, passed as @c dbname parameter.
997
The name should be encoded using the system character set (UTF8 currently).
999
Resulting statement is stored in the string pointed by @c buffer. The string
1000
is emptied first and its character set is set to the system character set.
1002
If HA_LEX_CREATE_IF_NOT_EXISTS flag is set in @c create_info->options, then
1003
the resulting CREATE statement contains "IF NOT EXISTS" clause. Other flags
1004
in @c create_options are ignored.
1006
@param thd The current thread instance.
1007
@param dbname The name of the database.
1008
@param buffer A String instance where the statement is stored.
1009
@param create_info If not NULL, the options member influences the resulting
1012
@returns true if errors are detected, false otherwise.
1015
bool store_db_create_info(THD *thd, const char *dbname, String *buffer,
1016
HA_CREATE_INFO *create_info)
1018
HA_CREATE_INFO create;
1019
uint create_options = create_info ? create_info->options : 0;
1021
if (!my_strcasecmp(system_charset_info, dbname,
1022
INFORMATION_SCHEMA_NAME.str))
1024
dbname= INFORMATION_SCHEMA_NAME.str;
1025
create.default_table_charset= system_charset_info;
1029
if (check_db_dir_existence(dbname))
1032
load_db_opt_by_name(thd, dbname, &create);
1037
buffer->set_charset(system_charset_info);
1038
buffer->append(STRING_WITH_LEN("CREATE DATABASE "));
1040
if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
1041
buffer->append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
1043
append_identifier(thd, buffer, dbname, strlen(dbname));
1045
if (create.default_table_charset)
1047
buffer->append(STRING_WITH_LEN(" /*!40100"));
1048
buffer->append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
1049
buffer->append(create.default_table_charset->csname);
1050
if (!(create.default_table_charset->state & MY_CS_PRIMARY))
1052
buffer->append(STRING_WITH_LEN(" COLLATE "));
1053
buffer->append(create.default_table_charset->name);
1055
buffer->append(STRING_WITH_LEN(" */"));
1061
static void store_key_options(THD *thd __attribute__((__unused__)),
1062
String *packet, TABLE *table,
1065
char *end, buff[32];
1067
if (key_info->algorithm == HA_KEY_ALG_BTREE)
1068
packet->append(STRING_WITH_LEN(" USING BTREE"));
1070
if (key_info->algorithm == HA_KEY_ALG_HASH)
1071
packet->append(STRING_WITH_LEN(" USING HASH"));
1073
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
1074
table->s->key_block_size != key_info->block_size)
1076
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
1077
end= int64_t10_to_str(key_info->block_size, buff, 10);
1078
packet->append(buff, (uint) (end - buff));
1081
assert(test(key_info->flags & HA_USES_COMMENT) ==
1082
(key_info->comment.length > 0));
1083
if (key_info->flags & HA_USES_COMMENT)
1085
packet->append(STRING_WITH_LEN(" COMMENT "));
1086
append_unescaped(packet, key_info->comment.str,
1087
key_info->comment.length);
1092
/****************************************************************************
1093
Return info about all processes
1094
returns for each thread: thread id, user, host, db, command, info
1095
****************************************************************************/
1097
class thread_info :public ilink {
1099
static void *operator new(size_t size)
1101
return (void*) sql_alloc((uint) size);
1103
static void operator delete(void *ptr __attribute__((unused)),
1104
size_t size __attribute__((unused)))
1105
{ TRASH(ptr, size); }
1110
const char *user,*host,*db,*proc_info,*state_info;
1114
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1115
template class I_List<thread_info>;
1118
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
1121
List<Item> field_list;
1122
I_List<thread_info> thread_infos;
1123
ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
1124
PROCESS_LIST_WIDTH);
1125
Protocol *protocol= thd->protocol;
1127
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1128
field_list.push_back(new Item_empty_string("User",16));
1129
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1130
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1131
field->maybe_null=1;
1132
field_list.push_back(new Item_empty_string("Command",16));
1133
field_list.push_back(new Item_return_int("Time",7, MYSQL_TYPE_LONG));
1134
field_list.push_back(field=new Item_empty_string("State",30));
1135
field->maybe_null=1;
1136
field_list.push_back(field=new Item_empty_string("Info",max_query_length));
1137
field->maybe_null=1;
1138
if (protocol->send_fields(&field_list,
1139
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1142
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
1145
I_List_iterator<THD> it(threads);
1149
Security_context *tmp_sctx= tmp->security_ctx;
1150
struct st_my_thread_var *mysys_var;
1151
if ((tmp->vio_ok() || tmp->system_thread) && (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
1153
thread_info *thd_info= new thread_info;
1155
thd_info->thread_id=tmp->thread_id;
1156
thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
1157
(tmp->system_thread ?
1158
"system user" : "unauthenticated user"));
1159
thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
1160
tmp_sctx->host_or_ip :
1161
tmp_sctx->host ? tmp_sctx->host : "");
1162
if ((thd_info->db=tmp->db)) // Safe test
1163
thd_info->db=thd->strdup(thd_info->db);
1164
thd_info->command=(int) tmp->command;
1165
if ((mysys_var= tmp->mysys_var))
1166
pthread_mutex_lock(&mysys_var->mutex);
1167
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
1168
thd_info->state_info= (char*) (tmp->net.reading_or_writing ?
1169
(tmp->net.reading_or_writing == 2 ?
1171
thd_info->command == COM_SLEEP ? NullS :
1172
"Reading from net") :
1173
tmp->proc_info ? tmp->proc_info :
1175
tmp->mysys_var->current_cond ?
1176
"Waiting on cond" : NullS);
1178
pthread_mutex_unlock(&mysys_var->mutex);
1180
thd_info->start_time= tmp->start_time;
1185
query_length is always set to 0 when we set query = NULL; see
1186
the comment in sql_class.h why this prevents crashes in possible
1187
races with query_length
1189
uint length= min(max_query_length, tmp->query_length);
1190
thd_info->query=(char*) thd->strmake(tmp->query,length);
1192
thread_infos.append(thd_info);
1196
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1198
thread_info *thd_info;
1199
time_t now= my_time(0);
1200
while ((thd_info=thread_infos.get()))
1202
protocol->prepare_for_resend();
1203
protocol->store((uint64_t) thd_info->thread_id);
1204
protocol->store(thd_info->user, system_charset_info);
1205
protocol->store(thd_info->host, system_charset_info);
1206
protocol->store(thd_info->db, system_charset_info);
1207
if (thd_info->proc_info)
1208
protocol->store(thd_info->proc_info, system_charset_info);
1210
protocol->store(command_name[thd_info->command].str, system_charset_info);
1211
if (thd_info->start_time)
1212
protocol->store((uint32) (now - thd_info->start_time));
1214
protocol->store_null();
1215
protocol->store(thd_info->state_info, system_charset_info);
1216
protocol->store(thd_info->query, system_charset_info);
1217
if (protocol->write())
1218
break; /* purecov: inspected */
1224
int fill_schema_processlist(THD* thd, TABLE_LIST* tables,
1225
COND* cond __attribute__((__unused__)))
1227
TABLE *table= tables->table;
1228
CHARSET_INFO *cs= system_charset_info;
1230
time_t now= my_time(0);
1234
VOID(pthread_mutex_lock(&LOCK_thread_count));
1238
I_List_iterator<THD> it(threads);
1243
Security_context *tmp_sctx= tmp->security_ctx;
1244
struct st_my_thread_var *mysys_var;
1247
if ((!tmp->vio_ok() && !tmp->system_thread))
1250
restore_record(table, s->default_values);
1252
table->field[0]->store((int64_t) tmp->thread_id, true);
1254
val= tmp_sctx->user ? tmp_sctx->user :
1255
(tmp->system_thread ? "system user" : "unauthenticated user");
1256
table->field[1]->store(val, strlen(val), cs);
1258
table->field[2]->store(tmp_sctx->host_or_ip,
1259
strlen(tmp_sctx->host_or_ip), cs);
1263
table->field[3]->store(tmp->db, strlen(tmp->db), cs);
1264
table->field[3]->set_notnull();
1267
if ((mysys_var= tmp->mysys_var))
1268
pthread_mutex_lock(&mysys_var->mutex);
1270
if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
1271
table->field[4]->store(val, strlen(val), cs);
1273
table->field[4]->store(command_name[tmp->command].str,
1274
command_name[tmp->command].length, cs);
1276
table->field[5]->store((uint32)(tmp->start_time ?
1277
now - tmp->start_time : 0), true);
1279
val= (char*) (tmp->net.reading_or_writing ?
1280
(tmp->net.reading_or_writing == 2 ?
1282
tmp->command == COM_SLEEP ? NullS :
1283
"Reading from net") :
1284
tmp->proc_info ? tmp->proc_info :
1286
tmp->mysys_var->current_cond ?
1287
"Waiting on cond" : NullS);
1290
table->field[6]->store(val, strlen(val), cs);
1291
table->field[6]->set_notnull();
1295
pthread_mutex_unlock(&mysys_var->mutex);
1300
table->field[7]->store(tmp->query,
1301
min(PROCESS_LIST_INFO_WIDTH,
1302
tmp->query_length), cs);
1303
table->field[7]->set_notnull();
1306
if (schema_table_store_record(thd, table))
1308
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1314
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1318
/*****************************************************************************
1320
*****************************************************************************/
1322
static DYNAMIC_ARRAY all_status_vars;
1323
static bool status_vars_inited= 0;
1324
static int show_var_cmp(const void *var1, const void *var2)
1326
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1330
deletes all the SHOW_UNDEF elements from the array and calls
1331
delete_dynamic() if it's completely empty.
1333
static void shrink_var_array(DYNAMIC_ARRAY *array)
1336
SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
1338
for (a= b= 0; b < array->elements; b++)
1339
if (all[b].type != SHOW_UNDEF)
1343
bzero(all+a, sizeof(SHOW_VAR)); // writing NULL-element to the end
1346
else // array is completely empty - delete it
1347
delete_dynamic(array);
1351
Adds an array of SHOW_VAR entries to the output of SHOW STATUS
1354
add_status_vars(SHOW_VAR *list)
1355
list - an array of SHOW_VAR entries to add to all_status_vars
1356
the last entry must be {0,0,SHOW_UNDEF}
1359
The handling of all_status_vars[] is completely internal, it's allocated
1360
automatically when something is added to it, and deleted completely when
1361
the last entry is removed.
1363
As a special optimization, if add_status_vars() is called before
1364
init_status_vars(), it assumes "startup mode" - neither concurrent access
1365
to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
1367
The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
1369
int add_status_vars(SHOW_VAR *list)
1372
if (status_vars_inited)
1373
pthread_mutex_lock(&LOCK_status);
1374
if (!all_status_vars.buffer && // array is not allocated yet - do it now
1375
my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
1381
res|= insert_dynamic(&all_status_vars, (uchar*)list++);
1382
res|= insert_dynamic(&all_status_vars, (uchar*)list); // appending NULL-element
1383
all_status_vars.elements--; // but next insert_dynamic should overwite it
1384
if (status_vars_inited)
1385
sort_dynamic(&all_status_vars, show_var_cmp);
1387
if (status_vars_inited)
1388
pthread_mutex_unlock(&LOCK_status);
1393
Make all_status_vars[] usable for SHOW STATUS
1396
See add_status_vars(). Before init_status_vars() call, add_status_vars()
1397
works in a special fast "startup" mode. Thus init_status_vars()
1398
should be called as late as possible but before enabling multi-threading.
1400
void init_status_vars()
1402
status_vars_inited=1;
1403
sort_dynamic(&all_status_vars, show_var_cmp);
1406
void reset_status_vars()
1408
SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
1409
SHOW_VAR *last= ptr + all_status_vars.elements;
1410
for (; ptr < last; ptr++)
1412
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
1413
if (ptr->type == SHOW_LONG)
1414
*(ulong*) ptr->value= 0;
1419
catch-all cleanup function, cleans up everything no matter what
1422
This function is not strictly required if all add_to_status/
1423
remove_status_vars are properly paired, but it's a safety measure that
1424
deletes everything from the all_status_vars[] even if some
1425
remove_status_vars were forgotten
1427
void free_status_vars()
1429
delete_dynamic(&all_status_vars);
1433
Removes an array of SHOW_VAR entries from the output of SHOW STATUS
1436
remove_status_vars(SHOW_VAR *list)
1437
list - an array of SHOW_VAR entries to remove to all_status_vars
1438
the last entry must be {0,0,SHOW_UNDEF}
1441
there's lots of room for optimizing this, especially in non-sorted mode,
1442
but nobody cares - it may be called only in case of failed plugin
1443
initialization in the mysqld startup.
1446
void remove_status_vars(SHOW_VAR *list)
1448
if (status_vars_inited)
1450
pthread_mutex_lock(&LOCK_status);
1451
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1452
int a= 0, b= all_status_vars.elements, c= (a+b)/2;
1454
for (; list->name; list++)
1457
for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
1459
res= show_var_cmp(list, all+c);
1468
all[c].type= SHOW_UNDEF;
1470
shrink_var_array(&all_status_vars);
1471
pthread_mutex_unlock(&LOCK_status);
1475
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1477
for (; list->name; list++)
1479
for (i= 0; i < all_status_vars.elements; i++)
1481
if (show_var_cmp(list, all+i))
1483
all[i].type= SHOW_UNDEF;
1487
shrink_var_array(&all_status_vars);
1491
inline void make_upper(char *buf)
1494
*buf= my_toupper(system_charset_info, *buf);
1497
static bool show_status_array(THD *thd, const char *wild,
1498
SHOW_VAR *variables,
1499
enum enum_var_type value_type,
1500
struct system_status_var *status_var,
1501
const char *prefix, TABLE *table,
1504
MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
1505
char * const buff= (char *) &buff_data;
1507
/* the variable name should not be longer than 64 characters */
1508
char name_buffer[64];
1510
LEX_STRING null_lex_str;
1513
null_lex_str.str= 0; // For sys_var->value_ptr()
1514
null_lex_str.length= 0;
1516
prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
1519
len=name_buffer + sizeof(name_buffer) - prefix_end;
1521
for (; variables->name; variables++)
1523
strnmov(prefix_end, variables->name, len);
1524
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
1526
make_upper(name_buffer);
1529
if var->type is SHOW_FUNC, call the function.
1530
Repeat as necessary, if new var is again SHOW_FUNC
1532
for (var=variables; var->type == SHOW_FUNC; var= &tmp)
1533
((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(thd, &tmp, buff);
1535
SHOW_TYPE show_type=var->type;
1536
if (show_type == SHOW_ARRAY)
1538
show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
1539
status_var, name_buffer, table, ucase_names);
1543
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
1544
name_buffer, wild)))
1546
char *value=var->value;
1547
const char *pos, *end; // We assign a lot of const's
1549
pthread_mutex_lock(&LOCK_global_system_variables);
1551
if (show_type == SHOW_SYS)
1553
show_type= ((sys_var*) value)->show_type();
1554
value= (char*) ((sys_var*) value)->value_ptr(thd, value_type,
1560
note that value may be == buff. All SHOW_xxx code below
1561
should still work in this case
1563
switch (show_type) {
1564
case SHOW_DOUBLE_STATUS:
1565
value= ((char *) status_var + (ulong) value);
1568
/* 6 is the default precision for '%f' in sprintf() */
1569
end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
1571
case SHOW_LONG_STATUS:
1572
value= ((char *) status_var + (ulong) value);
1575
case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
1576
end= int10_to_str(*(long*) value, buff, 10);
1578
case SHOW_LONGLONG_STATUS:
1579
value= ((char *) status_var + (uint64_t) value);
1582
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1585
end= int64_t10_to_str((int64_t) *(ha_rows*) value, buff, 10);
1588
end= strmov(buff, *(bool*) value ? "ON" : "OFF");
1591
end= strmov(buff, *(bool*) value ? "ON" : "OFF");
1594
end= int10_to_str((long) *(uint32*) value, buff, 10);
1598
SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
1599
pos= show_comp_option_name[(int) tmp];
1612
if (!(pos= *(char**) value))
1617
case SHOW_KEY_CACHE_LONG:
1618
value= (char*) dflt_key_cache + (ulong)value;
1619
end= int10_to_str(*(long*) value, buff, 10);
1621
case SHOW_KEY_CACHE_LONGLONG:
1622
value= (char*) dflt_key_cache + (ulong)value;
1623
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1626
break; // Return empty string
1627
case SHOW_SYS: // Cannot happen
1632
restore_record(table, s->default_values);
1633
table->field[0]->store(name_buffer, strlen(name_buffer),
1634
system_charset_info);
1635
table->field[1]->store(pos, (uint32) (end - pos), system_charset_info);
1636
table->field[1]->set_notnull();
1638
pthread_mutex_unlock(&LOCK_global_system_variables);
1640
if (schema_table_store_record(thd, table))
1650
/* collect status for all running threads */
1652
void calc_sum_of_all_status(STATUS_VAR *to)
1655
/* Ensure that thread id not killed during loop */
1656
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
1658
I_List_iterator<THD> it(threads);
1661
/* Get global values as base */
1662
*to= global_status_var;
1664
/* Add to this status from existing threads */
1666
add_to_status(to, &tmp->status_var);
1668
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1673
/* This is only used internally, but we need it here as a forward reference */
1674
extern ST_SCHEMA_TABLE schema_tables[];
1676
typedef struct st_lookup_field_values
1678
LEX_STRING db_value, table_value;
1679
bool wild_db_value, wild_table_value;
1680
} LOOKUP_FIELD_VALUES;
1684
Store record to I_S table, convert HEAP table
1685
to MyISAM if necessary
1688
schema_table_store_record()
1690
table Information schema table to be updated
1697
bool schema_table_store_record(THD *thd, TABLE *table)
1700
if ((error= table->file->ha_write_row(table->record[0])))
1702
TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
1704
if (create_myisam_from_heap(thd, table, param->start_recinfo,
1705
¶m->recinfo, error, 0))
1712
int make_table_list(THD *thd, SELECT_LEX *sel,
1713
LEX_STRING *db_name, LEX_STRING *table_name)
1715
Table_ident *table_ident;
1716
table_ident= new Table_ident(thd, *db_name, *table_name, 1);
1718
if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
1725
@brief Get lookup value from the part of 'WHERE' condition
1727
@details This function gets lookup value from
1728
the part of 'WHERE' condition if it's possible and
1729
fill appropriate lookup_field_vals struct field
1732
@param[in] thd thread handler
1733
@param[in] item_func part of WHERE condition
1734
@param[in] table I_S table
1735
@param[in, out] lookup_field_vals Struct which holds lookup values
1739
1 error, there can be no matching records for the condition
1742
bool get_lookup_value(THD *thd, Item_func *item_func,
1744
LOOKUP_FIELD_VALUES *lookup_field_vals)
1746
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1747
ST_FIELD_INFO *field_info= schema_table->fields_info;
1748
const char *field_name1= schema_table->idx_field1 >= 0 ?
1749
field_info[schema_table->idx_field1].field_name : "";
1750
const char *field_name2= schema_table->idx_field2 >= 0 ?
1751
field_info[schema_table->idx_field2].field_name : "";
1753
if (item_func->functype() == Item_func::EQ_FUNC ||
1754
item_func->functype() == Item_func::EQUAL_FUNC)
1756
int idx_field, idx_val;
1757
char tmp[MAX_FIELD_WIDTH];
1758
String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
1759
Item_field *item_field;
1760
CHARSET_INFO *cs= system_charset_info;
1762
if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
1763
item_func->arguments()[1]->const_item())
1768
else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
1769
item_func->arguments()[0]->const_item())
1777
item_field= (Item_field*) item_func->arguments()[idx_field];
1778
if (table->table != item_field->field->table)
1780
tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
1782
/* impossible value */
1786
/* Lookup value is database name */
1787
if (!cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
1788
(uchar *) item_field->field_name,
1789
strlen(item_field->field_name), 0))
1791
thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
1792
tmp_str->length(), false);
1794
/* Lookup value is table name */
1795
else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2,
1796
strlen(field_name2),
1797
(uchar *) item_field->field_name,
1798
strlen(item_field->field_name), 0))
1800
thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
1801
tmp_str->length(), false);
1809
@brief Calculates lookup values from 'WHERE' condition
1811
@details This function calculates lookup value(database name, table name)
1812
from 'WHERE' condition if it's possible and
1813
fill lookup_field_vals struct fields with these values.
1815
@param[in] thd thread handler
1816
@param[in] cond WHERE condition
1817
@param[in] table I_S table
1818
@param[in, out] lookup_field_vals Struct which holds lookup values
1822
1 error, there can be no matching records for the condition
1825
bool calc_lookup_values_from_cond(THD *thd, COND *cond, TABLE_LIST *table,
1826
LOOKUP_FIELD_VALUES *lookup_field_vals)
1831
if (cond->type() == Item::COND_ITEM)
1833
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1835
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1837
while ((item= li++))
1839
if (item->type() == Item::FUNC_ITEM)
1841
if (get_lookup_value(thd, (Item_func*)item, table, lookup_field_vals))
1846
if (calc_lookup_values_from_cond(thd, item, table, lookup_field_vals))
1853
else if (cond->type() == Item::FUNC_ITEM &&
1854
get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals))
1860
bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
1862
if (item->type() == Item::FUNC_ITEM)
1864
Item_func *item_func= (Item_func*)item;
1865
for (uint i=0; i<item_func->argument_count(); i++)
1867
if (!uses_only_table_name_fields(item_func->arguments()[i], table))
1871
else if (item->type() == Item::FIELD_ITEM)
1873
Item_field *item_field= (Item_field*)item;
1874
CHARSET_INFO *cs= system_charset_info;
1875
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1876
ST_FIELD_INFO *field_info= schema_table->fields_info;
1877
const char *field_name1= schema_table->idx_field1 >= 0 ?
1878
field_info[schema_table->idx_field1].field_name : "";
1879
const char *field_name2= schema_table->idx_field2 >= 0 ?
1880
field_info[schema_table->idx_field2].field_name : "";
1881
if (table->table != item_field->field->table ||
1882
(cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
1883
(uchar *) item_field->field_name,
1884
strlen(item_field->field_name), 0) &&
1885
cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2),
1886
(uchar *) item_field->field_name,
1887
strlen(item_field->field_name), 0)))
1890
else if (item->type() == Item::REF_ITEM)
1891
return uses_only_table_name_fields(item->real_item(), table);
1893
if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
1900
static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
1904
if (cond->type() == Item::COND_ITEM)
1906
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1908
/* Create new top level AND item */
1909
Item_cond_and *new_cond=new Item_cond_and;
1912
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1916
Item *fix= make_cond_for_info_schema(item, table);
1918
new_cond->argument_list()->push_back(fix);
1920
switch (new_cond->argument_list()->elements) {
1924
return new_cond->argument_list()->head();
1926
new_cond->quick_fix_field();
1932
Item_cond_or *new_cond=new Item_cond_or;
1935
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1939
Item *fix=make_cond_for_info_schema(item, table);
1942
new_cond->argument_list()->push_back(fix);
1944
new_cond->quick_fix_field();
1945
new_cond->top_level_item();
1950
if (!uses_only_table_name_fields(cond, table))
1957
@brief Calculate lookup values(database name, table name)
1959
@details This function calculates lookup values(database name, table name)
1960
from 'WHERE' condition or wild values (for 'SHOW' commands only)
1961
from LEX struct and fill lookup_field_vals struct field
1964
@param[in] thd thread handler
1965
@param[in] cond WHERE condition
1966
@param[in] tables I_S table
1967
@param[in, out] lookup_field_values Struct which holds lookup values
1971
1 error, there can be no matching records for the condition
1974
bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables,
1975
LOOKUP_FIELD_VALUES *lookup_field_values)
1978
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
1979
bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES));
1980
switch (lex->sql_command) {
1981
case SQLCOM_SHOW_DATABASES:
1984
lookup_field_values->db_value.str= (char*) wild;
1985
lookup_field_values->db_value.length= strlen(wild);
1986
lookup_field_values->wild_db_value= 1;
1989
case SQLCOM_SHOW_TABLES:
1990
case SQLCOM_SHOW_TABLE_STATUS:
1991
lookup_field_values->db_value.str= lex->select_lex.db;
1992
lookup_field_values->db_value.length=strlen(lex->select_lex.db);
1995
lookup_field_values->table_value.str= (char*)wild;
1996
lookup_field_values->table_value.length= strlen(wild);
1997
lookup_field_values->wild_table_value= 1;
2002
The "default" is for queries over I_S.
2003
All previous cases handle SHOW commands.
2005
return calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
2010
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
2012
return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
2017
Create db names list. Information schema name always is first in list
2022
files list of db names
2024
idx_field_vals idx_field_vals->db_name contains db name or
2026
with_i_schema returns 1 if we added 'IS' name to list
2034
int make_db_list(THD *thd, List<LEX_STRING> *files,
2035
LOOKUP_FIELD_VALUES *lookup_field_vals,
2036
bool *with_i_schema)
2038
LEX_STRING *i_s_name_copy= 0;
2039
i_s_name_copy= thd->make_lex_string(i_s_name_copy,
2040
INFORMATION_SCHEMA_NAME.str,
2041
INFORMATION_SCHEMA_NAME.length, true);
2043
if (lookup_field_vals->wild_db_value)
2046
This part of code is only for SHOW DATABASES command.
2047
idx_field_vals->db_value can be 0 when we don't use
2048
LIKE clause (see also get_index_field_values() function)
2050
if (!lookup_field_vals->db_value.str ||
2051
!wild_case_compare(system_charset_info,
2052
INFORMATION_SCHEMA_NAME.str,
2053
lookup_field_vals->db_value.str))
2056
if (files->push_back(i_s_name_copy))
2059
return (find_files(thd, files, NullS, mysql_data_home,
2060
lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
2065
If we have db lookup vaule we just add it to list and
2066
exit from the function
2068
if (lookup_field_vals->db_value.str)
2070
if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
2071
lookup_field_vals->db_value.str))
2074
if (files->push_back(i_s_name_copy))
2078
if (files->push_back(&lookup_field_vals->db_value))
2084
Create list of existing databases. It is used in case
2085
of select from information schema table
2087
if (files->push_back(i_s_name_copy))
2090
return (find_files(thd, files, NullS,
2091
mysql_data_home, NullS, 1) != FIND_FILES_OK);
2095
struct st_add_schema_table
2097
List<LEX_STRING> *files;
2102
static bool add_schema_table(THD *thd, plugin_ref plugin,
2105
LEX_STRING *file_name= 0;
2106
st_add_schema_table *data= (st_add_schema_table *)p_data;
2107
List<LEX_STRING> *file_list= data->files;
2108
const char *wild= data->wild;
2109
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
2111
if (schema_table->hidden)
2115
if (lower_case_table_names)
2117
if (wild_case_compare(files_charset_info,
2118
schema_table->table_name,
2122
else if (wild_compare(schema_table->table_name, wild, 0))
2126
if ((file_name= thd->make_lex_string(file_name, schema_table->table_name,
2127
strlen(schema_table->table_name),
2129
!file_list->push_back(file_name))
2135
int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
2137
LEX_STRING *file_name= 0;
2138
ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
2139
st_add_schema_table add_data;
2141
for (; tmp_schema_table->table_name; tmp_schema_table++)
2143
if (tmp_schema_table->hidden)
2147
if (lower_case_table_names)
2149
if (wild_case_compare(files_charset_info,
2150
tmp_schema_table->table_name,
2154
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2158
thd->make_lex_string(file_name, tmp_schema_table->table_name,
2159
strlen(tmp_schema_table->table_name), true)) &&
2160
!files->push_back(file_name))
2165
add_data.files= files;
2166
add_data.wild= wild;
2167
if (plugin_foreach(thd, add_schema_table,
2168
MYSQL_INFORMATION_SCHEMA_PLUGIN, &add_data))
2176
@brief Create table names list
2178
@details The function creates the list of table names in
2181
@param[in] thd thread handler
2182
@param[in] table_names List of table names in database
2183
@param[in] lex pointer to LEX struct
2184
@param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
2185
@param[in] with_i_schema true means that we add I_S tables to list
2186
@param[in] db_name database name
2188
@return Operation status
2190
@retval 1 fatal error
2191
@retval 2 Not fatal error; Safe to ignore this file list
2195
make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
2196
LOOKUP_FIELD_VALUES *lookup_field_vals,
2197
bool with_i_schema, LEX_STRING *db_name)
2199
char path[FN_REFLEN];
2200
build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
2201
if (!lookup_field_vals->wild_table_value &&
2202
lookup_field_vals->table_value.str)
2206
if (find_schema_table(thd, lookup_field_vals->table_value.str))
2208
if (table_names->push_back(&lookup_field_vals->table_value))
2214
if (table_names->push_back(&lookup_field_vals->table_value))
2221
This call will add all matching the wildcards (if specified) IS tables
2225
return (schema_tables_add(thd, table_names,
2226
lookup_field_vals->table_value.str));
2228
find_files_result res= find_files(thd, table_names, db_name->str, path,
2229
lookup_field_vals->table_value.str, 0);
2230
if (res != FIND_FILES_OK)
2233
Downgrade errors about problems with database directory to
2234
warnings if this is not a 'SHOW' command. Another thread
2235
may have dropped database, and we may still have a name
2238
if (res == FIND_FILES_DIR)
2240
if (lex->sql_command != SQLCOM_SELECT)
2252
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
2254
@param[in] thd thread handler
2255
@param[in] tables TABLE_LIST for I_S table
2256
@param[in] schema_table pointer to I_S structure
2257
@param[in] open_tables_state_backup pointer to Open_tables_state object
2258
which is used to save|restore original
2259
status of variables related to
2262
@return Operation status
2268
fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
2269
ST_SCHEMA_TABLE *schema_table,
2270
Open_tables_state *open_tables_state_backup)
2274
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
2275
enum_sql_command save_sql_command= lex->sql_command;
2276
TABLE_LIST *show_table_list= (TABLE_LIST*) tables->schema_select_lex->
2278
TABLE *table= tables->table;
2281
lex->all_selects_list= tables->schema_select_lex;
2283
Restore thd->temporary_tables to be able to process
2284
temporary tables(only for 'show index' & 'show columns').
2285
This should be changed when processing of temporary tables for
2286
I_S tables will be done.
2288
thd->temporary_tables= open_tables_state_backup->temporary_tables;
2290
Let us set fake sql_command so views won't try to merge
2291
themselves into main statement. If we don't do this,
2292
SELECT * from information_schema.xxxx will cause problems.
2293
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
2295
lex->sql_command= SQLCOM_SHOW_FIELDS;
2296
res= open_normal_and_derived_tables(thd, show_table_list,
2297
MYSQL_LOCK_IGNORE_FLUSH);
2298
lex->sql_command= save_sql_command;
2300
get_all_tables() returns 1 on failure and 0 on success thus
2301
return only these and not the result code of ::process_table()
2303
We should use show_table_list->alias instead of
2304
show_table_list->table_name because table_name
2305
could be changed during opening of I_S tables. It's safe
2306
to use alias because alias contains original table name
2307
in this case(this part of code is used only for
2308
'show columns' & 'show statistics' commands).
2310
table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
2311
strlen(show_table_list->alias), false);
2312
db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db,
2313
show_table_list->db_length, false);
2316
error= test(schema_table->process_table(thd, show_table_list,
2317
table, res, db_name,
2319
thd->temporary_tables= 0;
2320
close_tables_for_reopen(thd, &show_table_list);
2326
@brief Fill I_S table for SHOW TABLE NAMES commands
2328
@param[in] thd thread handler
2329
@param[in] table TABLE struct for I_S table
2330
@param[in] db_name database name
2331
@param[in] table_name table name
2332
@param[in] with_i_schema I_S table if true
2334
@return Operation status
2339
static int fill_schema_table_names(THD *thd, TABLE *table,
2340
LEX_STRING *db_name, LEX_STRING *table_name,
2345
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
2346
system_charset_info);
2350
enum legacy_db_type not_used;
2351
char path[FN_REFLEN];
2352
(void) build_table_filename(path, sizeof(path), db_name->str,
2353
table_name->str, reg_ext, 0);
2354
switch (mysql_frm_type(thd, path, ¬_used)) {
2356
table->field[3]->store(STRING_WITH_LEN("ERROR"),
2357
system_charset_info);
2360
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"),
2361
system_charset_info);
2366
if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2372
if (schema_table_store_record(thd, table))
2379
@brief Get open table method
2381
@details The function calculates the method which will be used
2383
SKIP_OPEN_TABLE - do not open table
2384
OPEN_FRM_ONLY - open FRM file only
2385
OPEN_FULL_TABLE - open FRM, data, index files
2386
@param[in] tables I_S table table_list
2387
@param[in] schema_table I_S table struct
2388
@param[in] schema_table_idx I_S table index
2390
@return return a set of flags
2391
@retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
2394
static uint get_table_open_method(TABLE_LIST *tables,
2395
ST_SCHEMA_TABLE *schema_table,
2396
enum enum_schema_tables schema_table_idx __attribute__((__unused__)))
2399
determine which method will be used for table opening
2401
if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
2403
Field **ptr, *field;
2404
int table_open_method= 0, field_indx= 0;
2405
for (ptr=tables->table->field; (field= *ptr) ; ptr++)
2407
if (bitmap_is_set(tables->table->read_set, field->field_index))
2408
table_open_method|= schema_table->fields_info[field_indx].open_method;
2411
return table_open_method;
2413
/* I_S tables which use get_all_tables but can not be optimized */
2414
return (uint) OPEN_FULL_TABLE;
2419
@brief Fill I_S table with data from FRM file only
2421
@param[in] thd thread handler
2422
@param[in] table TABLE struct for I_S table
2423
@param[in] schema_table I_S table struct
2424
@param[in] db_name database name
2425
@param[in] table_name table name
2426
@param[in] schema_table_idx I_S table index
2428
@return Operation status
2429
@retval 0 Table is processed and we can continue
2431
@retval 1 It's view and we have to use
2432
open_tables function for this table
2435
static int fill_schema_table_from_frm(THD *thd,TABLE_LIST *tables,
2436
ST_SCHEMA_TABLE *schema_table,
2437
LEX_STRING *db_name,
2438
LEX_STRING *table_name,
2439
enum enum_schema_tables schema_table_idx __attribute__((__unused__)))
2441
TABLE *table= tables->table;
2444
TABLE_LIST table_list;
2447
char key[MAX_DBKEY_LENGTH];
2450
bzero((char*) &table_list, sizeof(TABLE_LIST));
2451
bzero((char*) &tbl, sizeof(TABLE));
2453
table_list.table_name= table_name->str;
2454
table_list.db= db_name->str;
2456
key_length= create_table_def_key(thd, key, &table_list, 0);
2457
pthread_mutex_lock(&LOCK_open);
2458
share= get_table_share(thd, &table_list, key,
2459
key_length, OPEN_VIEW, &error);
2468
table_list.table= &tbl;
2469
res= schema_table->process_table(thd, &table_list, table,
2470
res, db_name, table_name);
2473
release_table_share(share, RELEASE_NORMAL);
2476
pthread_mutex_unlock(&LOCK_open);
2484
@brief Fill I_S tables whose data are retrieved
2485
from frm files and storage engine
2487
@details The information schema tables are internally represented as
2488
temporary tables that are filled at query execution time.
2489
Those I_S tables whose data are retrieved
2490
from frm files and storage engine are filled by the function
2493
@param[in] thd thread handler
2494
@param[in] tables I_S table
2495
@param[in] cond 'WHERE' condition
2497
@return Operation status
2502
int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
2505
TABLE *table= tables->table;
2506
SELECT_LEX *old_all_select_lex= lex->all_selects_list;
2507
enum_sql_command save_sql_command= lex->sql_command;
2508
SELECT_LEX *lsel= tables->schema_select_lex;
2509
ST_SCHEMA_TABLE *schema_table= tables->schema_table;
2511
LOOKUP_FIELD_VALUES lookup_field_vals;
2512
LEX_STRING *db_name, *table_name;
2514
enum enum_schema_tables schema_table_idx;
2515
List<LEX_STRING> db_names;
2516
List_iterator_fast<LEX_STRING> it(db_names);
2517
COND *partial_cond= 0;
2518
uint derived_tables= lex->derived_tables;
2520
Open_tables_state open_tables_state_backup;
2521
Query_tables_list query_tables_list_backup;
2522
uint table_open_method;
2523
bool old_value= thd->no_warnings_for_error;
2525
lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
2528
We should not introduce deadlocks even if we already have some
2529
tables open and locked, since we won't lock tables which we will
2530
open and will ignore possible name-locks for these tables.
2532
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
2534
schema_table_idx= get_schema_table_idx(schema_table);
2535
tables->table_open_method= table_open_method=
2536
get_table_open_method(tables, schema_table, schema_table_idx);
2538
this branch processes SHOW FIELDS, SHOW INDEXES commands.
2539
see sql_parse.cc, prepare_schema_table() function where
2540
this values are initialized
2542
if (lsel && lsel->table_list.first)
2544
error= fill_schema_show_cols_or_idxs(thd, tables, schema_table,
2545
&open_tables_state_backup);
2549
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2555
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
2558
if lookup value is empty string then
2559
it's impossible table name or db name
2561
if ((lookup_field_vals.db_value.str && !lookup_field_vals.db_value.str[0]) ||
2562
(lookup_field_vals.table_value.str && !lookup_field_vals.table_value.str[0]))
2569
if (lookup_field_vals.db_value.length &&
2570
!lookup_field_vals.wild_db_value)
2571
tables->has_db_lookup_value= true;
2572
if (lookup_field_vals.table_value.length &&
2573
!lookup_field_vals.wild_table_value)
2574
tables->has_table_lookup_value= true;
2576
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
2579
partial_cond= make_cond_for_info_schema(cond, tables);
2583
/* EXPLAIN SELECT */
2588
if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
2590
it.rewind(); /* To get access to new elements in basis list */
2591
while ((db_name= it++))
2594
thd->no_warnings_for_error= 1;
2595
List<LEX_STRING> table_names;
2596
int res= make_table_name_list(thd, &table_names, lex,
2598
with_i_schema, db_name);
2599
if (res == 2) /* Not fatal error, continue */
2604
List_iterator_fast<LEX_STRING> it_files(table_names);
2605
while ((table_name= it_files++))
2607
restore_record(table, s->default_values);
2608
table->field[schema_table->idx_field1]->
2609
store(db_name->str, db_name->length, system_charset_info);
2610
table->field[schema_table->idx_field2]->
2611
store(table_name->str, table_name->length, system_charset_info);
2613
if (!partial_cond || partial_cond->val_int())
2616
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
2617
we can skip table opening and we don't have lookup value for
2618
table name or lookup value is wild string(table name list is
2619
already created by make_table_name_list() function).
2621
if (!table_open_method && schema_table_idx == SCH_TABLES &&
2622
(!lookup_field_vals.table_value.length ||
2623
lookup_field_vals.wild_table_value))
2625
if (schema_table_store_record(thd, table))
2626
goto err; /* Out of space in temporary table */
2630
/* SHOW TABLE NAMES command */
2631
if (schema_table_idx == SCH_TABLE_NAMES)
2633
if (fill_schema_table_names(thd, tables->table, db_name,
2634
table_name, with_i_schema))
2639
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
2642
if (!fill_schema_table_from_frm(thd, tables, schema_table, db_name,
2643
table_name, schema_table_idx))
2648
LEX_STRING tmp_lex_string, orig_db_name;
2650
Set the parent lex of 'sel' because it is needed by
2651
sel.init_query() which is called inside make_table_list.
2653
thd->no_warnings_for_error= 1;
2654
sel.parent_lex= lex;
2655
/* db_name can be changed in make_table_list() func */
2656
if (!thd->make_lex_string(&orig_db_name, db_name->str,
2657
db_name->length, false))
2659
if (make_table_list(thd, &sel, db_name, table_name))
2661
TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first;
2662
lex->all_selects_list= &sel;
2663
lex->derived_tables= 0;
2664
lex->sql_command= SQLCOM_SHOW_FIELDS;
2665
show_table_list->i_s_requested_object=
2666
schema_table->i_s_requested_object;
2667
res= open_normal_and_derived_tables(thd, show_table_list,
2668
MYSQL_LOCK_IGNORE_FLUSH);
2669
lex->sql_command= save_sql_command;
2671
XXX: show_table_list has a flag i_is_requested,
2672
and when it's set, open_normal_and_derived_tables()
2673
can return an error without setting an error message
2674
in THD, which is a hack. This is why we have to
2675
check for res, then for thd->is_error() only then
2676
for thd->main_da.sql_errno().
2678
if (res && thd->is_error() &&
2679
thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2682
Hide error for not existing table.
2683
This error can occur for example when we use
2684
where condition with db name and table name and this
2685
table does not exist.
2693
We should use show_table_list->alias instead of
2694
show_table_list->table_name because table_name
2695
could be changed during opening of I_S tables. It's safe
2696
to use alias because alias contains original table name
2699
thd->make_lex_string(&tmp_lex_string, show_table_list->alias,
2700
strlen(show_table_list->alias), false);
2701
res= schema_table->process_table(thd, show_table_list, table,
2704
close_tables_for_reopen(thd, &show_table_list);
2706
assert(!lex->query_tables_own_last);
2713
If we have information schema its always the first table and only
2714
the first table. Reset for other tables.
2722
thd->restore_backup_open_tables_state(&open_tables_state_backup);
2723
lex->restore_backup_query_tables_list(&query_tables_list_backup);
2724
lex->derived_tables= derived_tables;
2725
lex->all_selects_list= old_all_select_lex;
2726
lex->sql_command= save_sql_command;
2727
thd->no_warnings_for_error= old_value;
2732
bool store_schema_shemata(THD* thd, TABLE *table, LEX_STRING *db_name,
2735
restore_record(table, s->default_values);
2736
table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2737
table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2738
table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2739
return schema_table_store_record(thd, table);
2743
int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
2746
TODO: fill_schema_shemata() is called when new client is connected.
2747
Returning error status in this case leads to client hangup.
2750
LOOKUP_FIELD_VALUES lookup_field_vals;
2751
List<LEX_STRING> db_names;
2752
LEX_STRING *db_name;
2754
HA_CREATE_INFO create;
2755
TABLE *table= tables->table;
2757
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2759
if (make_db_list(thd, &db_names, &lookup_field_vals,
2764
If we have lookup db value we should check that the database exists
2766
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
2769
char path[FN_REFLEN+16];
2771
struct stat stat_info;
2772
if (!lookup_field_vals.db_value.str[0])
2774
path_len= build_table_filename(path, sizeof(path),
2775
lookup_field_vals.db_value.str, "", "", 0);
2776
path[path_len-1]= 0;
2777
if (stat(path,&stat_info))
2781
List_iterator_fast<LEX_STRING> it(db_names);
2782
while ((db_name=it++))
2784
if (with_i_schema) // information schema name is always first in list
2786
if (store_schema_shemata(thd, table, db_name,
2787
system_charset_info))
2793
load_db_opt_by_name(thd, db_name->str, &create);
2794
if (store_schema_shemata(thd, table, db_name,
2795
create.default_table_charset))
2803
static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
2804
TABLE *table, bool res,
2805
LEX_STRING *db_name,
2806
LEX_STRING *table_name)
2808
const char *tmp_buff;
2810
CHARSET_INFO *cs= system_charset_info;
2812
restore_record(table, s->default_values);
2813
table->field[1]->store(db_name->str, db_name->length, cs);
2814
table->field[2]->store(table_name->str, table_name->length, cs);
2818
there was errors during opening tables
2820
const char *error= thd->is_error() ? thd->main_da.message() : "";
2821
if (tables->schema_table)
2822
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2824
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
2825
table->field[20]->store(error, strlen(error), cs);
2830
char option_buff[350],*ptr;
2831
TABLE *show_table= tables->table;
2832
TABLE_SHARE *share= show_table->s;
2833
handler *file= show_table->file;
2834
handlerton *tmp_db_type= share->db_type();
2835
if (share->tmp_table == SYSTEM_TMP_TABLE)
2836
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2837
else if (share->tmp_table)
2838
table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
2840
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
2842
for (int i= 4; i < 20; i++)
2844
if (i == 7 || (i > 12 && i < 17) || i == 18)
2846
table->field[i]->set_notnull();
2848
tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
2849
table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
2850
table->field[5]->store((int64_t) share->frm_version, true);
2853
if (share->min_rows)
2855
ptr=strmov(ptr," min_rows=");
2856
ptr=int64_t10_to_str(share->min_rows,ptr,10);
2858
if (share->max_rows)
2860
ptr=strmov(ptr," max_rows=");
2861
ptr=int64_t10_to_str(share->max_rows,ptr,10);
2863
if (share->avg_row_length)
2865
ptr=strmov(ptr," avg_row_length=");
2866
ptr=int64_t10_to_str(share->avg_row_length,ptr,10);
2868
if (share->db_create_options & HA_OPTION_PACK_KEYS)
2869
ptr=strmov(ptr," pack_keys=1");
2870
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
2871
ptr=strmov(ptr," pack_keys=0");
2872
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2873
if (share->db_create_options & HA_OPTION_CHECKSUM)
2874
ptr=strmov(ptr," checksum=1");
2875
if (share->page_checksum != HA_CHOICE_UNDEF)
2876
ptr= strxmov(ptr, " page_checksum=",
2877
ha_choice_values[(uint) share->page_checksum], NullS);
2878
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
2879
ptr=strmov(ptr," delay_key_write=1");
2880
if (share->row_type != ROW_TYPE_DEFAULT)
2881
ptr=strxmov(ptr, " row_format=",
2882
ha_row_type[(uint) share->row_type],
2884
if (share->transactional != HA_CHOICE_UNDEF)
2886
ptr= strxmov(ptr, " TRANSACTIONAL=",
2887
(share->transactional == HA_CHOICE_YES ? "1" : "0"),
2890
if (share->transactional != HA_CHOICE_UNDEF)
2891
ptr= strxmov(ptr, " transactional=",
2892
ha_choice_values[(uint) share->transactional], NullS);
2893
table->field[19]->store(option_buff+1,
2894
(ptr == option_buff ? 0 :
2895
(uint) (ptr-option_buff)-1), cs);
2897
tmp_buff= (share->table_charset ?
2898
share->table_charset->name : "default");
2899
table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
2901
if (share->comment.str)
2902
table->field[20]->store(share->comment.str, share->comment.length, cs);
2906
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
2908
enum row_type row_type = file->get_row_type();
2910
case ROW_TYPE_NOT_USED:
2911
case ROW_TYPE_DEFAULT:
2912
tmp_buff= ((share->db_options_in_use &
2913
HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
2914
(share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
2915
"Dynamic" : "Fixed");
2917
case ROW_TYPE_FIXED:
2920
case ROW_TYPE_DYNAMIC:
2921
tmp_buff= "Dynamic";
2923
case ROW_TYPE_COMPRESSED:
2924
tmp_buff= "Compressed";
2926
case ROW_TYPE_REDUNDANT:
2927
tmp_buff= "Redundant";
2929
case ROW_TYPE_COMPACT:
2930
tmp_buff= "Compact";
2936
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
2937
if (!tables->schema_table)
2939
table->field[7]->store((int64_t) file->stats.records, true);
2940
table->field[7]->set_notnull();
2942
table->field[8]->store((int64_t) file->stats.mean_rec_length, true);
2943
table->field[9]->store((int64_t) file->stats.data_file_length, true);
2944
if (file->stats.max_data_file_length)
2946
table->field[10]->store((int64_t) file->stats.max_data_file_length,
2949
table->field[11]->store((int64_t) file->stats.index_file_length, true);
2950
table->field[12]->store((int64_t) file->stats.delete_length, true);
2951
if (show_table->found_next_number_field)
2953
table->field[13]->store((int64_t) file->stats.auto_increment_value,
2955
table->field[13]->set_notnull();
2957
if (file->stats.create_time)
2959
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2960
(my_time_t) file->stats.create_time);
2961
table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
2962
table->field[14]->set_notnull();
2964
if (file->stats.update_time)
2966
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2967
(my_time_t) file->stats.update_time);
2968
table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
2969
table->field[15]->set_notnull();
2971
if (file->stats.check_time)
2973
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2974
(my_time_t) file->stats.check_time);
2975
table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
2976
table->field[16]->set_notnull();
2978
if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
2980
table->field[18]->store((int64_t) file->checksum(), true);
2981
table->field[18]->set_notnull();
2985
return(schema_table_store_record(thd, table));
2990
@brief Store field characteristics into appropriate I_S table columns
2992
@param[in] table I_S table
2993
@param[in] field processed field
2994
@param[in] cs I_S table charset
2995
@param[in] offset offset from beginning of table
2996
to DATE_TYPE column in I_S table
3001
void store_column_type(TABLE *table, Field *field, CHARSET_INFO *cs,
3005
int decimals, field_length;
3006
const char *tmp_buff;
3007
char column_type_buff[MAX_FIELD_WIDTH];
3008
String column_type(column_type_buff, sizeof(column_type_buff), cs);
3010
field->sql_type(column_type);
3011
/* DTD_IDENTIFIER column */
3012
table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs);
3013
table->field[offset + 7]->set_notnull();
3014
tmp_buff= strchr(column_type.ptr(), '(');
3015
/* DATA_TYPE column */
3016
table->field[offset]->store(column_type.ptr(),
3017
(tmp_buff ? tmp_buff - column_type.ptr() :
3018
column_type.length()), cs);
3019
is_blob= (field->type() == MYSQL_TYPE_BLOB);
3020
if (field->has_charset() || is_blob ||
3021
field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type
3022
field->real_type() == MYSQL_TYPE_STRING) // For binary type
3024
uint32 octet_max_length= field->max_display_length();
3025
if (is_blob && octet_max_length != (uint32) 4294967295U)
3026
octet_max_length /= field->charset()->mbmaxlen;
3027
int64_t char_max_len= is_blob ?
3028
(int64_t) octet_max_length / field->charset()->mbminlen :
3029
(int64_t) octet_max_length / field->charset()->mbmaxlen;
3030
/* CHARACTER_MAXIMUM_LENGTH column*/
3031
table->field[offset + 1]->store(char_max_len, true);
3032
table->field[offset + 1]->set_notnull();
3033
/* CHARACTER_OCTET_LENGTH column */
3034
table->field[offset + 2]->store((int64_t) octet_max_length, true);
3035
table->field[offset + 2]->set_notnull();
3039
Calculate field_length and decimals.
3040
They are set to -1 if they should not be set (we should return NULL)
3043
decimals= field->decimals();
3044
switch (field->type()) {
3045
case MYSQL_TYPE_NEWDECIMAL:
3046
field_length= ((Field_new_decimal*) field)->precision;
3048
case MYSQL_TYPE_TINY:
3049
case MYSQL_TYPE_SHORT:
3050
case MYSQL_TYPE_LONG:
3051
case MYSQL_TYPE_LONGLONG:
3052
field_length= field->max_display_length() - 1;
3054
case MYSQL_TYPE_DOUBLE:
3055
field_length= field->field_length;
3056
if (decimals == NOT_FIXED_DEC)
3057
decimals= -1; // return NULL
3060
field_length= decimals= -1;
3064
/* NUMERIC_PRECISION column */
3065
if (field_length >= 0)
3067
table->field[offset + 3]->store((int64_t) field_length, true);
3068
table->field[offset + 3]->set_notnull();
3070
/* NUMERIC_SCALE column */
3073
table->field[offset + 4]->store((int64_t) decimals, true);
3074
table->field[offset + 4]->set_notnull();
3076
if (field->has_charset())
3078
/* CHARACTER_SET_NAME column*/
3079
tmp_buff= field->charset()->csname;
3080
table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs);
3081
table->field[offset + 5]->set_notnull();
3082
/* COLLATION_NAME column */
3083
tmp_buff= field->charset()->name;
3084
table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs);
3085
table->field[offset + 6]->set_notnull();
3090
static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
3091
TABLE *table, bool res,
3092
LEX_STRING *db_name,
3093
LEX_STRING *table_name)
3096
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3097
CHARSET_INFO *cs= system_charset_info;
3099
TABLE_SHARE *show_table_share;
3100
Field **ptr, *field, *timestamp_field;
3105
if (lex->sql_command != SQLCOM_SHOW_FIELDS)
3108
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
3109
rather than in SHOW COLUMNS
3111
if (thd->is_error())
3112
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3113
thd->main_da.sql_errno(), thd->main_da.message());
3120
show_table= tables->table;
3121
show_table_share= show_table->s;
3124
if (tables->schema_table)
3126
ptr= show_table->field;
3127
timestamp_field= show_table->timestamp_field;
3128
show_table->use_all_columns(); // Required for default
3132
ptr= show_table_share->field;
3133
timestamp_field= show_table_share->timestamp_field;
3135
read_set may be inited in case of
3138
if (!show_table->read_set)
3140
/* to satisfy 'field->val_str' ASSERTs */
3142
uint bitmap_size= show_table_share->column_bitmap_size;
3143
if (!(bitmaps= (uchar*) alloc_root(thd->mem_root, bitmap_size)))
3145
bitmap_init(&show_table->def_read_set,
3146
(my_bitmap_map*) bitmaps, show_table_share->fields, false);
3147
bitmap_set_all(&show_table->def_read_set);
3148
show_table->read_set= &show_table->def_read_set;
3150
bitmap_set_all(show_table->read_set);
3153
for (; (field= *ptr) ; ptr++)
3156
char tmp[MAX_FIELD_WIDTH];
3157
String type(tmp,sizeof(tmp), system_charset_info);
3160
/* to satisfy 'field->val_str' ASSERTs */
3161
field->table= show_table;
3162
show_table->in_use= thd;
3164
if (wild && wild[0] &&
3165
wild_case_compare(system_charset_info, field->field_name,wild))
3169
/* Get default row, with all NULL fields set to NULL */
3170
restore_record(table, s->default_values);
3172
table->field[1]->store(db_name->str, db_name->length, cs);
3173
table->field[2]->store(table_name->str, table_name->length, cs);
3174
table->field[3]->store(field->field_name, strlen(field->field_name),
3176
table->field[4]->store((int64_t) count, true);
3178
if (get_field_default_value(thd, timestamp_field, field, &type, 0))
3180
table->field[5]->store(type.ptr(), type.length(), cs);
3181
table->field[5]->set_notnull();
3183
pos=(uchar*) ((field->flags & NOT_NULL_FLAG) ? "NO" : "YES");
3184
table->field[6]->store((const char*) pos,
3185
strlen((const char*) pos), cs);
3186
store_column_type(table, field, cs, 7);
3188
pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
3189
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
3190
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
3191
table->field[15]->store((const char*) pos,
3192
strlen((const char*) pos), cs);
3195
if (field->unireg_check == Field::NEXT_NUMBER)
3196
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
3197
if (timestamp_field == field &&
3198
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3199
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3202
table->field[18]->store(field->comment.str, field->comment.length, cs);
3204
enum column_format_type column_format= (enum column_format_type)
3205
((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
3206
pos=(uchar*)"Default";
3207
table->field[19]->store((const char*) pos,
3208
strlen((const char*) pos), cs);
3209
pos=(uchar*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
3210
column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
3212
table->field[20]->store((const char*) pos,
3213
strlen((const char*) pos), cs);
3215
if (schema_table_store_record(thd, table))
3223
int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3226
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3227
TABLE *table= tables->table;
3228
CHARSET_INFO *scs= system_charset_info;
3230
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3232
CHARSET_INFO *tmp_cs= cs[0];
3233
if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
3234
(tmp_cs->state & MY_CS_AVAILABLE) &&
3235
!(tmp_cs->state & MY_CS_HIDDEN) &&
3236
!(wild && wild[0] &&
3237
wild_case_compare(scs, tmp_cs->csname,wild)))
3239
const char *comment;
3240
restore_record(table, s->default_values);
3241
table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3242
table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3243
comment= tmp_cs->comment ? tmp_cs->comment : "";
3244
table->field[2]->store(comment, strlen(comment), scs);
3245
table->field[3]->store((int64_t) tmp_cs->mbmaxlen, true);
3246
if (schema_table_store_record(thd, table))
3254
int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3257
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3258
TABLE *table= tables->table;
3259
CHARSET_INFO *scs= system_charset_info;
3260
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3263
CHARSET_INFO *tmp_cs= cs[0];
3264
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3265
(tmp_cs->state & MY_CS_HIDDEN) ||
3266
!(tmp_cs->state & MY_CS_PRIMARY))
3268
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3270
CHARSET_INFO *tmp_cl= cl[0];
3271
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3272
!my_charset_same(tmp_cs, tmp_cl))
3274
if (!(wild && wild[0] &&
3275
wild_case_compare(scs, tmp_cl->name,wild)))
3277
const char *tmp_buff;
3278
restore_record(table, s->default_values);
3279
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3280
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3281
table->field[2]->store((int64_t) tmp_cl->number, true);
3282
tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
3283
table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
3284
tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
3285
table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
3286
table->field[5]->store((int64_t) tmp_cl->strxfrm_multiply, true);
3287
if (schema_table_store_record(thd, table))
3296
int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3299
TABLE *table= tables->table;
3300
CHARSET_INFO *scs= system_charset_info;
3301
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3304
CHARSET_INFO *tmp_cs= cs[0];
3305
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3306
!(tmp_cs->state & MY_CS_PRIMARY))
3308
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3310
CHARSET_INFO *tmp_cl= cl[0];
3311
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3312
!my_charset_same(tmp_cs,tmp_cl))
3314
restore_record(table, s->default_values);
3315
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3316
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3317
if (schema_table_store_record(thd, table))
3325
static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
3326
TABLE *table, bool res,
3327
LEX_STRING *db_name,
3328
LEX_STRING *table_name)
3330
CHARSET_INFO *cs= system_charset_info;
3333
if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
3336
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
3337
rather than in SHOW KEYS
3339
if (thd->is_error())
3340
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3341
thd->main_da.sql_errno(), thd->main_da.message());
3349
TABLE *show_table= tables->table;
3350
KEY *key_info=show_table->s->key_info;
3351
if (show_table->file)
3352
show_table->file->info(HA_STATUS_VARIABLE |
3355
for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
3357
KEY_PART_INFO *key_part= key_info->key_part;
3359
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3361
restore_record(table, s->default_values);
3362
table->field[1]->store(db_name->str, db_name->length, cs);
3363
table->field[2]->store(table_name->str, table_name->length, cs);
3364
table->field[3]->store((int64_t) ((key_info->flags &
3365
HA_NOSAME) ? 0 : 1), true);
3366
table->field[4]->store(db_name->str, db_name->length, cs);
3367
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
3368
table->field[6]->store((int64_t) (j+1), true);
3369
str=(key_part->field ? key_part->field->field_name :
3371
table->field[7]->store(str, strlen(str), cs);
3372
if (show_table->file)
3374
if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
3376
table->field[8]->store(((key_part->key_part_flag &
3379
table->field[8]->set_notnull();
3381
KEY *key=show_table->key_info+i;
3382
if (key->rec_per_key[j])
3384
ha_rows records=(show_table->file->stats.records /
3385
key->rec_per_key[j]);
3386
table->field[9]->store((int64_t) records, true);
3387
table->field[9]->set_notnull();
3389
str= show_table->file->index_type(i);
3390
table->field[13]->store(str, strlen(str), cs);
3392
if ((key_part->field &&
3394
show_table->s->field[key_part->fieldnr-1]->key_length()))
3396
table->field[10]->store((int64_t) key_part->length /
3397
key_part->field->charset()->mbmaxlen, true);
3398
table->field[10]->set_notnull();
3400
uint flags= key_part->field ? key_part->field->flags : 0;
3401
const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3402
table->field[12]->store(pos, strlen(pos), cs);
3403
if (!show_table->s->keys_in_use.is_set(i))
3404
table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3406
table->field[14]->store("", 0, cs);
3407
table->field[14]->set_notnull();
3408
assert(test(key_info->flags & HA_USES_COMMENT) ==
3409
(key_info->comment.length > 0));
3410
if (key_info->flags & HA_USES_COMMENT)
3411
table->field[15]->store(key_info->comment.str,
3412
key_info->comment.length, cs);
3413
if (schema_table_store_record(thd, table))
3422
bool store_constraints(THD *thd, TABLE *table, LEX_STRING *db_name,
3423
LEX_STRING *table_name, const char *key_name,
3424
uint key_len, const char *con_type, uint con_len)
3426
CHARSET_INFO *cs= system_charset_info;
3427
restore_record(table, s->default_values);
3428
table->field[1]->store(db_name->str, db_name->length, cs);
3429
table->field[2]->store(key_name, key_len, cs);
3430
table->field[3]->store(db_name->str, db_name->length, cs);
3431
table->field[4]->store(table_name->str, table_name->length, cs);
3432
table->field[5]->store(con_type, con_len, cs);
3433
return schema_table_store_record(thd, table);
3437
static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
3438
TABLE *table, bool res,
3439
LEX_STRING *db_name,
3440
LEX_STRING *table_name)
3444
if (thd->is_error())
3445
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3446
thd->main_da.sql_errno(), thd->main_da.message());
3452
List<FOREIGN_KEY_INFO> f_key_list;
3453
TABLE *show_table= tables->table;
3454
KEY *key_info=show_table->key_info;
3455
uint primary_key= show_table->s->primary_key;
3456
show_table->file->info(HA_STATUS_VARIABLE |
3459
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3461
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3464
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
3466
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3467
strlen(key_info->name),
3468
STRING_WITH_LEN("PRIMARY KEY")))
3471
else if (key_info->flags & HA_NOSAME)
3473
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3474
strlen(key_info->name),
3475
STRING_WITH_LEN("UNIQUE")))
3480
show_table->file->get_foreign_key_list(thd, &f_key_list);
3481
FOREIGN_KEY_INFO *f_key_info;
3482
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3483
while ((f_key_info=it++))
3485
if (store_constraints(thd, table, db_name, table_name,
3486
f_key_info->forein_id->str,
3487
strlen(f_key_info->forein_id->str),
3496
void store_key_column_usage(TABLE *table, LEX_STRING *db_name,
3497
LEX_STRING *table_name, const char *key_name,
3498
uint key_len, const char *con_type, uint con_len,
3501
CHARSET_INFO *cs= system_charset_info;
3502
table->field[1]->store(db_name->str, db_name->length, cs);
3503
table->field[2]->store(key_name, key_len, cs);
3504
table->field[4]->store(db_name->str, db_name->length, cs);
3505
table->field[5]->store(table_name->str, table_name->length, cs);
3506
table->field[6]->store(con_type, con_len, cs);
3507
table->field[7]->store((int64_t) idx, true);
3511
static int get_schema_key_column_usage_record(THD *thd,
3513
TABLE *table, bool res,
3514
LEX_STRING *db_name,
3515
LEX_STRING *table_name)
3519
if (thd->is_error())
3520
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3521
thd->main_da.sql_errno(), thd->main_da.message());
3527
List<FOREIGN_KEY_INFO> f_key_list;
3528
TABLE *show_table= tables->table;
3529
KEY *key_info=show_table->key_info;
3530
uint primary_key= show_table->s->primary_key;
3531
show_table->file->info(HA_STATUS_VARIABLE |
3534
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3536
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3539
KEY_PART_INFO *key_part= key_info->key_part;
3540
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3542
if (key_part->field)
3545
restore_record(table, s->default_values);
3546
store_key_column_usage(table, db_name, table_name,
3548
strlen(key_info->name),
3549
key_part->field->field_name,
3550
strlen(key_part->field->field_name),
3552
if (schema_table_store_record(thd, table))
3558
show_table->file->get_foreign_key_list(thd, &f_key_list);
3559
FOREIGN_KEY_INFO *f_key_info;
3560
List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
3561
while ((f_key_info= fkey_it++))
3565
List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
3566
it1(f_key_info->referenced_fields);
3568
while ((f_info= it++))
3572
restore_record(table, s->default_values);
3573
store_key_column_usage(table, db_name, table_name,
3574
f_key_info->forein_id->str,
3575
f_key_info->forein_id->length,
3576
f_info->str, f_info->length,
3578
table->field[8]->store((int64_t) f_idx, true);
3579
table->field[8]->set_notnull();
3580
table->field[9]->store(f_key_info->referenced_db->str,
3581
f_key_info->referenced_db->length,
3582
system_charset_info);
3583
table->field[9]->set_notnull();
3584
table->field[10]->store(f_key_info->referenced_table->str,
3585
f_key_info->referenced_table->length,
3586
system_charset_info);
3587
table->field[10]->set_notnull();
3588
table->field[11]->store(r_info->str, r_info->length,
3589
system_charset_info);
3590
table->field[11]->set_notnull();
3591
if (schema_table_store_record(thd, table))
3600
int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3602
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3603
TABLE *table= tables->table;
3604
CHARSET_INFO *cs= system_charset_info;
3605
OPEN_TABLE_LIST *open_list;
3606
if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
3607
&& thd->is_fatal_error)
3610
for (; open_list ; open_list=open_list->next)
3612
restore_record(table, s->default_values);
3613
table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3614
table->field[1]->store(open_list->table, strlen(open_list->table), cs);
3615
table->field[2]->store((int64_t) open_list->in_use, true);
3616
table->field[3]->store((int64_t) open_list->locked, true);
3617
if (schema_table_store_record(thd, table))
3624
int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3628
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3629
enum enum_schema_tables schema_table_idx=
3630
get_schema_table_idx(tables->schema_table);
3631
enum enum_var_type option_type= OPT_SESSION;
3632
bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
3633
bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
3635
if (lex->option_type == OPT_GLOBAL ||
3636
schema_table_idx == SCH_GLOBAL_VARIABLES)
3637
option_type= OPT_GLOBAL;
3639
rw_rdlock(&LOCK_system_variables_hash);
3640
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
3641
option_type, NULL, "", tables->table, upper_case_names);
3642
rw_unlock(&LOCK_system_variables_hash);
3647
int fill_status(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((__unused__)))
3650
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3652
STATUS_VAR *tmp1, tmp;
3653
enum enum_schema_tables schema_table_idx=
3654
get_schema_table_idx(tables->schema_table);
3655
enum enum_var_type option_type;
3656
bool upper_case_names= (schema_table_idx != SCH_STATUS);
3658
if (schema_table_idx == SCH_STATUS)
3660
option_type= lex->option_type;
3661
if (option_type == OPT_GLOBAL)
3664
tmp1= thd->initial_status_var;
3666
else if (schema_table_idx == SCH_GLOBAL_STATUS)
3668
option_type= OPT_GLOBAL;
3673
option_type= OPT_SESSION;
3674
tmp1= &thd->status_var;
3677
pthread_mutex_lock(&LOCK_status);
3678
if (option_type == OPT_GLOBAL)
3679
calc_sum_of_all_status(&tmp);
3680
res= show_status_array(thd, wild,
3681
(SHOW_VAR *)all_status_vars.buffer,
3682
option_type, tmp1, "", tables->table,
3684
pthread_mutex_unlock(&LOCK_status);
3690
Fill and store records into I_S.referential_constraints table
3693
get_referential_constraints_record()
3695
tables table list struct(processed table)
3697
res 1 means the error during opening of the processed table
3698
0 means processed table is opened without error
3700
file_name table name
3708
get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
3709
TABLE *table, bool res,
3710
LEX_STRING *db_name, LEX_STRING *table_name)
3712
CHARSET_INFO *cs= system_charset_info;
3716
if (thd->is_error())
3717
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
3718
thd->main_da.sql_errno(), thd->main_da.message());
3724
List<FOREIGN_KEY_INFO> f_key_list;
3725
TABLE *show_table= tables->table;
3726
show_table->file->info(HA_STATUS_VARIABLE |
3730
show_table->file->get_foreign_key_list(thd, &f_key_list);
3731
FOREIGN_KEY_INFO *f_key_info;
3732
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3733
while ((f_key_info= it++))
3735
restore_record(table, s->default_values);
3736
table->field[1]->store(db_name->str, db_name->length, cs);
3737
table->field[9]->store(table_name->str, table_name->length, cs);
3738
table->field[2]->store(f_key_info->forein_id->str,
3739
f_key_info->forein_id->length, cs);
3740
table->field[4]->store(f_key_info->referenced_db->str,
3741
f_key_info->referenced_db->length, cs);
3742
table->field[10]->store(f_key_info->referenced_table->str,
3743
f_key_info->referenced_table->length, cs);
3744
if (f_key_info->referenced_key_name)
3746
table->field[5]->store(f_key_info->referenced_key_name->str,
3747
f_key_info->referenced_key_name->length, cs);
3748
table->field[5]->set_notnull();
3751
table->field[5]->set_null();
3752
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3753
table->field[7]->store(f_key_info->update_method->str,
3754
f_key_info->update_method->length, cs);
3755
table->field[8]->store(f_key_info->delete_method->str,
3756
f_key_info->delete_method->length, cs);
3757
if (schema_table_store_record(thd, table))
3765
struct schema_table_ref
3767
const char *table_name;
3768
ST_SCHEMA_TABLE *schema_table;
3773
Find schema_tables elment by name
3776
find_schema_table_in_plugin()
3779
table_name table name
3783
1 found the schema table
3785
static bool find_schema_table_in_plugin(THD *thd __attribute__((__unused__)),
3789
schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
3790
const char* table_name= p_schema_table->table_name;
3791
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
3793
if (!my_strcasecmp(system_charset_info,
3794
schema_table->table_name,
3796
p_schema_table->schema_table= schema_table;
3805
Find schema_tables elment by name
3810
table_name table name
3814
# pointer to 'schema_tables' element
3817
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
3819
schema_table_ref schema_table_a;
3820
ST_SCHEMA_TABLE *schema_table= schema_tables;
3822
for (; schema_table->table_name; schema_table++)
3824
if (!my_strcasecmp(system_charset_info,
3825
schema_table->table_name,
3827
return(schema_table);
3830
schema_table_a.table_name= table_name;
3831
if (plugin_foreach(thd, find_schema_table_in_plugin,
3832
MYSQL_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
3833
return(schema_table_a.schema_table);
3839
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
3841
return &schema_tables[schema_table_idx];
3846
Create information_schema table using schema_table data.
3853
@param table_list Used to pass I_S table information(fields info, tables
3854
parameters etc) and table name.
3856
@retval \# Pointer to created table
3857
@retval NULL Can't create table
3860
TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
3865
List<Item> field_list;
3866
ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
3867
ST_FIELD_INFO *fields_info= schema_table->fields_info;
3868
CHARSET_INFO *cs= system_charset_info;
3870
for (; fields_info->field_name; fields_info++)
3872
switch (fields_info->field_type) {
3873
case MYSQL_TYPE_TINY:
3874
case MYSQL_TYPE_LONG:
3875
case MYSQL_TYPE_SHORT:
3876
case MYSQL_TYPE_LONGLONG:
3877
if (!(item= new Item_return_int(fields_info->field_name,
3878
fields_info->field_length,
3879
fields_info->field_type,
3880
fields_info->value)))
3884
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3886
case MYSQL_TYPE_NEWDATE:
3887
case MYSQL_TYPE_TIME:
3888
case MYSQL_TYPE_TIMESTAMP:
3889
case MYSQL_TYPE_DATETIME:
3890
if (!(item=new Item_return_date_time(fields_info->field_name,
3891
fields_info->field_type)))
3896
case MYSQL_TYPE_DOUBLE:
3897
if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
3898
fields_info->field_length)) == NULL)
3901
case MYSQL_TYPE_NEWDECIMAL:
3902
if (!(item= new Item_decimal((int64_t) fields_info->value, false)))
3906
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3907
item->decimals= fields_info->field_length%10;
3908
item->max_length= (fields_info->field_length/100)%100;
3909
if (item->unsigned_flag == 0)
3910
item->max_length+= 1;
3911
if (item->decimals > 0)
3912
item->max_length+= 1;
3913
item->set_name(fields_info->field_name,
3914
strlen(fields_info->field_name), cs);
3916
case MYSQL_TYPE_BLOB:
3917
if (!(item= new Item_blob(fields_info->field_name,
3918
fields_info->field_length)))
3924
/* Don't let unimplemented types pass through. Could be a grave error. */
3925
assert(fields_info->field_type == MYSQL_TYPE_STRING);
3927
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
3931
item->set_name(fields_info->field_name,
3932
strlen(fields_info->field_name), cs);
3935
field_list.push_back(item);
3936
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
3939
TMP_TABLE_PARAM *tmp_table_param =
3940
(TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
3941
tmp_table_param->init();
3942
tmp_table_param->table_charset= cs;
3943
tmp_table_param->field_count= field_count;
3944
tmp_table_param->schema_table= 1;
3945
SELECT_LEX *select_lex= thd->lex->current_select;
3946
if (!(table= create_tmp_table(thd, tmp_table_param,
3947
field_list, (ORDER*) 0, 0, 0,
3948
(select_lex->options | thd->options |
3949
TMP_TABLE_ALL_COLUMNS),
3950
HA_POS_ERROR, table_list->alias)))
3952
my_bitmap_map* bitmaps=
3953
(my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
3954
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
3956
table->read_set= &table->def_read_set;
3957
bitmap_clear_all(table->read_set);
3958
table_list->schema_table_param= tmp_table_param;
3964
For old SHOW compatibility. It is used when
3965
old SHOW doesn't have generated column names
3966
Make list of fields for SHOW
3971
schema_table pointer to 'schema_tables' element
3978
int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
3980
ST_FIELD_INFO *field_info= schema_table->fields_info;
3981
Name_resolution_context *context= &thd->lex->select_lex.context;
3982
for (; field_info->field_name; field_info++)
3984
if (field_info->old_name)
3986
Item_field *field= new Item_field(context,
3987
NullS, NullS, field_info->field_name);
3990
field->set_name(field_info->old_name,
3991
strlen(field_info->old_name),
3992
system_charset_info);
3993
if (add_item_to_list(thd, field))
4002
int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4006
SELECT_LEX *sel= lex->current_select;
4007
Name_resolution_context *context= &sel->context;
4009
if (!sel->item_list.elements)
4011
ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
4012
String buffer(tmp,sizeof(tmp), system_charset_info);
4013
Item_field *field= new Item_field(context,
4014
NullS, NullS, field_info->field_name);
4015
if (!field || add_item_to_list(thd, field))
4018
buffer.append(field_info->old_name);
4019
if (lex->wild && lex->wild->ptr())
4021
buffer.append(STRING_WITH_LEN(" ("));
4022
buffer.append(lex->wild->ptr());
4025
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4031
int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4034
String buffer(tmp,sizeof(tmp), thd->charset());
4036
Name_resolution_context *context= &lex->select_lex.context;
4038
ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
4040
buffer.append(field_info->old_name);
4041
buffer.append(lex->select_lex.db);
4042
if (lex->wild && lex->wild->ptr())
4044
buffer.append(STRING_WITH_LEN(" ("));
4045
buffer.append(lex->wild->ptr());
4048
Item_field *field= new Item_field(context,
4049
NullS, NullS, field_info->field_name);
4050
if (add_item_to_list(thd, field))
4052
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4053
if (thd->lex->verbose)
4055
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4056
field_info= &schema_table->fields_info[3];
4057
field= new Item_field(context, NullS, NullS, field_info->field_name);
4058
if (add_item_to_list(thd, field))
4060
field->set_name(field_info->old_name, strlen(field_info->old_name),
4061
system_charset_info);
4067
int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4069
int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
4070
int *field_num= fields_arr;
4071
ST_FIELD_INFO *field_info;
4072
Name_resolution_context *context= &thd->lex->select_lex.context;
4074
for (; *field_num >= 0; field_num++)
4076
field_info= &schema_table->fields_info[*field_num];
4077
if (!thd->lex->verbose && (*field_num == 13 ||
4081
Item_field *field= new Item_field(context,
4082
NullS, NullS, field_info->field_name);
4085
field->set_name(field_info->old_name,
4086
strlen(field_info->old_name),
4087
system_charset_info);
4088
if (add_item_to_list(thd, field))
4096
int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4098
int fields_arr[]= {0, 2, 1, 3, -1};
4099
int *field_num= fields_arr;
4100
ST_FIELD_INFO *field_info;
4101
Name_resolution_context *context= &thd->lex->select_lex.context;
4103
for (; *field_num >= 0; field_num++)
4105
field_info= &schema_table->fields_info[*field_num];
4106
Item_field *field= new Item_field(context,
4107
NullS, NullS, field_info->field_name);
4110
field->set_name(field_info->old_name,
4111
strlen(field_info->old_name),
4112
system_charset_info);
4113
if (add_item_to_list(thd, field))
4122
Create information_schema table
4125
mysql_schema_table()
4128
table_list pointer to table_list
4135
int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
4138
if (!(table= table_list->schema_table->create_table(thd, table_list)))
4140
table->s->tmp_table= SYSTEM_TMP_TABLE;
4142
This test is necessary to make
4143
case insensitive file systems +
4144
upper case table names(information schema tables) +
4148
if (table_list->schema_table_name)
4149
table->alias_name_used= my_strcasecmp(table_alias_charset,
4150
table_list->schema_table_name,
4152
table_list->table_name= table->s->table_name.str;
4153
table_list->table_name_length= table->s->table_name.length;
4154
table_list->table= table;
4155
table->next= thd->derived_tables;
4156
thd->derived_tables= table;
4157
table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
4159
if (table_list->schema_table_reformed) // show command
4161
SELECT_LEX *sel= lex->current_select;
4163
Field_translator *transl, *org_transl;
4165
if (table_list->field_translation)
4167
Field_translator *end= table_list->field_translation_end;
4168
for (transl= table_list->field_translation; transl < end; transl++)
4170
if (!transl->item->fixed &&
4171
transl->item->fix_fields(thd, &transl->item))
4176
List_iterator_fast<Item> it(sel->item_list);
4178
(Field_translator*)(thd->stmt_arena->
4179
alloc(sel->item_list.elements *
4180
sizeof(Field_translator)))))
4184
for (org_transl= transl; (item= it++); transl++)
4187
transl->name= item->name;
4188
if (!item->fixed && item->fix_fields(thd, &transl->item))
4193
table_list->field_translation= org_transl;
4194
table_list->field_translation_end= transl;
4202
Generate select from information_schema table
4205
make_schema_select()
4207
sel pointer to SELECT_LEX
4208
schema_table_idx index of 'schema_tables' element
4215
int make_schema_select(THD *thd, SELECT_LEX *sel,
4216
enum enum_schema_tables schema_table_idx)
4218
ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
4219
LEX_STRING db, table;
4221
We have to make non const db_name & table_name
4222
because of lower_case_table_names
4224
thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str,
4225
INFORMATION_SCHEMA_NAME.length, 0);
4226
thd->make_lex_string(&table, schema_table->table_name,
4227
strlen(schema_table->table_name), 0);
4228
if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
4229
!sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
4239
Fill temporary schema tables before SELECT
4242
get_schema_tables_result()
4243
join join which use schema tables
4244
executed_place place where I_S table processed
4251
bool get_schema_tables_result(JOIN *join,
4252
enum enum_schema_table_state executed_place)
4254
JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
4255
THD *thd= join->thd;
4259
thd->no_warnings_for_error= 1;
4260
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
4262
if (!tab->table || !tab->table->pos_in_table_list)
4265
TABLE_LIST *table_list= tab->table->pos_in_table_list;
4266
if (table_list->schema_table)
4268
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
4269
lex->current_select->master_unit()->item);
4272
/* skip I_S optimizations specific to get_all_tables */
4273
if (thd->lex->describe &&
4274
(table_list->schema_table->fill_table != get_all_tables))
4278
If schema table is already processed and
4279
the statement is not a subselect then
4280
we don't need to fill this table again.
4281
If schema table is already processed and
4282
schema_table_state != executed_place then
4283
table is already processed and
4284
we should skip second data processing.
4286
if (table_list->schema_table_state &&
4287
(!is_subselect || table_list->schema_table_state != executed_place))
4291
if table is used in a subselect and
4292
table has been processed earlier with the same
4293
'executed_place' value then we should refresh the table.
4295
if (table_list->schema_table_state && is_subselect)
4297
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
4298
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
4299
table_list->table->file->ha_delete_all_rows();
4300
free_io_cache(table_list->table);
4301
filesort_free_buffers(table_list->table,1);
4302
table_list->table->null_row= 0;
4305
table_list->table->file->stats.records= 0;
4307
if (table_list->schema_table->fill_table(thd, table_list,
4312
tab->read_record.file= table_list->table->file;
4313
table_list->schema_table_state= executed_place;
4316
tab->read_record.file= table_list->table->file;
4317
table_list->schema_table_state= executed_place;
4320
thd->no_warnings_for_error= 0;
4324
ST_FIELD_INFO schema_fields_info[]=
4326
{"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4327
{"SCHEMA_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
4329
{"DEFAULT_CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0,
4331
{"DEFAULT_COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4332
{"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4333
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4337
ST_FIELD_INFO tables_fields_info[]=
4339
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4340
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4341
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
4343
{"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4344
{"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine", OPEN_FRM_ONLY},
4345
{"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4346
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
4347
{"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", OPEN_FULL_TABLE},
4348
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4349
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
4350
{"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4351
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
4352
{"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4353
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
4354
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4355
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
4356
{"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4357
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
4358
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4359
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
4360
{"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0,
4361
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
4362
{"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4363
{"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4364
{"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
4365
{"TABLE_COLLATION", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
4366
{"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4367
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
4368
{"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options",
4370
{"TABLE_COMMENT", TABLE_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
4371
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4375
ST_FIELD_INFO columns_fields_info[]=
4377
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
4378
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4379
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4380
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Field",
4382
{"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
4383
MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
4384
{"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0,
4385
1, "Default", OPEN_FRM_ONLY},
4386
{"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
4387
{"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4388
{"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
4389
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4390
{"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
4391
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4392
{"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
4393
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4394
{"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
4395
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4396
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
4397
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
4398
{"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type", OPEN_FRM_ONLY},
4399
{"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key", OPEN_FRM_ONLY},
4400
{"EXTRA", 27, MYSQL_TYPE_STRING, 0, 0, "Extra", OPEN_FRM_ONLY},
4401
{"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges", OPEN_FRM_ONLY},
4402
{"COLUMN_COMMENT", COLUMN_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
4403
{"STORAGE", 8, MYSQL_TYPE_STRING, 0, 0, "Storage", OPEN_FRM_ONLY},
4404
{"FORMAT", 8, MYSQL_TYPE_STRING, 0, 0, "Format", OPEN_FRM_ONLY},
4405
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4409
ST_FIELD_INFO charsets_fields_info[]=
4411
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset",
4413
{"DEFAULT_COLLATE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Default collation",
4415
{"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description",
4417
{"MAXLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
4418
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4422
ST_FIELD_INFO collation_fields_info[]=
4424
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Collation", SKIP_OPEN_TABLE},
4425
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Charset",
4427
{"ID", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Id",
4429
{"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default", SKIP_OPEN_TABLE},
4430
{"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled", SKIP_OPEN_TABLE},
4431
{"SORTLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
4432
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4436
ST_FIELD_INFO events_fields_info[]=
4438
{"EVENT_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4439
{"EVENT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db",
4441
{"EVENT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
4443
{"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
4444
{"TIME_ZONE", 64, MYSQL_TYPE_STRING, 0, 0, "Time zone", SKIP_OPEN_TABLE},
4445
{"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4446
{"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4447
{"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
4448
{"EXECUTE_AT", 0, MYSQL_TYPE_DATETIME, 0, 1, "Execute at", SKIP_OPEN_TABLE},
4449
{"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value",
4451
{"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field",
4453
{"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4454
{"STARTS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Starts", SKIP_OPEN_TABLE},
4455
{"ENDS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Ends", SKIP_OPEN_TABLE},
4456
{"STATUS", 18, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
4457
{"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4458
{"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
4459
{"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
4460
{"LAST_EXECUTED", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
4461
{"EVENT_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4462
{"ORIGINATOR", 10, MYSQL_TYPE_LONGLONG, 0, 0, "Originator", SKIP_OPEN_TABLE},
4463
{"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
4464
"character_set_client", SKIP_OPEN_TABLE},
4465
{"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
4466
"collation_connection", SKIP_OPEN_TABLE},
4467
{"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
4468
"Database Collation", SKIP_OPEN_TABLE},
4469
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4474
ST_FIELD_INFO coll_charset_app_fields_info[]=
4476
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4477
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4478
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4482
ST_FIELD_INFO stat_fields_info[]=
4484
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
4485
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4486
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", OPEN_FRM_ONLY},
4487
{"NON_UNIQUE", 1, MYSQL_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
4488
{"INDEX_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
4489
{"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name",
4491
{"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
4492
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name",
4494
{"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
4495
{"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 1,
4496
"Cardinality", OPEN_FULL_TABLE},
4497
{"SUB_PART", 3, MYSQL_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
4498
{"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed", OPEN_FRM_ONLY},
4499
{"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
4500
{"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type", OPEN_FULL_TABLE},
4501
{"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment", OPEN_FRM_ONLY},
4502
{"INDEX_COMMENT", INDEX_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0, "Index_Comment", OPEN_FRM_ONLY},
4503
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4507
ST_FIELD_INFO user_privileges_fields_info[]=
4509
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4510
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4511
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4512
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4513
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4517
ST_FIELD_INFO schema_privileges_fields_info[]=
4519
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4520
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4521
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4522
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4523
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4524
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4528
ST_FIELD_INFO table_privileges_fields_info[]=
4530
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4531
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4532
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4533
{"TABLE_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 column_privileges_fields_info[]=
4542
{"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4543
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4544
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4545
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4546
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4547
{"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4548
{"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4549
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4553
ST_FIELD_INFO table_constraints_fields_info[]=
4555
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4556
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4558
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4560
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4561
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4562
{"CONSTRAINT_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4564
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4568
ST_FIELD_INFO key_column_usage_fields_info[]=
4570
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4571
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4573
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4575
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4576
{"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4577
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4578
{"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4579
{"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
4580
{"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONGLONG, 0, 1, 0,
4582
{"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
4584
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
4586
{"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
4588
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4592
ST_FIELD_INFO table_names_fields_info[]=
4594
{"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4595
{"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4596
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_",
4598
{"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type",
4600
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4604
ST_FIELD_INFO open_tables_fields_info[]=
4606
{"Database", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
4608
{"Table",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", SKIP_OPEN_TABLE},
4609
{"In_use", 1, MYSQL_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
4610
{"Name_locked", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
4611
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4615
ST_FIELD_INFO variables_fields_info[]=
4617
{"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name",
4619
{"VARIABLE_VALUE", 16300, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE},
4620
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4624
ST_FIELD_INFO processlist_fields_info[]=
4626
{"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
4627
{"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
4628
{"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host",
4630
{"DB", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Db", SKIP_OPEN_TABLE},
4631
{"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command", SKIP_OPEN_TABLE},
4632
{"TIME", 7, MYSQL_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
4633
{"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE},
4634
{"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info",
4636
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4640
ST_FIELD_INFO plugin_fields_info[]=
4642
{"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
4644
{"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4645
{"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
4646
{"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
4647
{"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
4648
{"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library",
4650
{"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4651
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4652
{"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
4653
{"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
4654
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4657
ST_FIELD_INFO referential_constraints_fields_info[]=
4659
{"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4660
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4662
{"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4664
{"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0,
4666
{"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4668
{"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0,
4669
MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
4670
{"MATCH_OPTION", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4671
{"UPDATE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4672
{"DELETE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4673
{"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4674
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
4676
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
4680
ST_FIELD_INFO parameters_fields_info[]=
4682
{"SPECIFIC_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4683
{"SPECIFIC_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4684
{"SPECIFIC_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4685
{"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0, OPEN_FULL_TABLE},
4686
{"PARAMETER_MODE", 5, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4687
{"PARAMETER_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4688
{"DATA_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4689
{"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4690
{"CHARACTER_OCTET_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4691
{"NUMERIC_PRECISION", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4692
{"NUMERIC_SCALE", 21 , MYSQL_TYPE_LONG, 0, 1, 0, OPEN_FULL_TABLE},
4693
{"CHARACTER_SET_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4694
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
4695
{"DTD_IDENTIFIER", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4696
{"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
4697
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE}
4702
Description of ST_FIELD_INFO in table.h
4704
Make sure that the order of schema_tables and enum_schema_tables are the same.
4708
ST_SCHEMA_TABLE schema_tables[]=
4710
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
4711
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4712
{"COLLATIONS", collation_fields_info, create_schema_table,
4713
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4714
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4715
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4716
{"COLUMNS", columns_fields_info, create_schema_table,
4717
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
4718
OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL},
4719
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4720
fill_status, make_old_format, 0, -1, -1, 0, 0},
4721
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
4722
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4723
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
4724
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
4726
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
4727
fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
4728
{"PLUGINS", plugin_fields_info, create_schema_table,
4729
fill_plugins, make_old_format, 0, -1, -1, 0, 0},
4730
{"PROCESSLIST", processlist_fields_info, create_schema_table,
4731
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
4732
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
4733
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
4734
1, 9, 0, OPEN_TABLE_ONLY},
4735
{"SCHEMATA", schema_fields_info, create_schema_table,
4736
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
4737
{"SESSION_STATUS", variables_fields_info, create_schema_table,
4738
fill_status, make_old_format, 0, -1, -1, 0, 0},
4739
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4740
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4741
{"STATISTICS", stat_fields_info, create_schema_table,
4742
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4743
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4744
{"STATUS", variables_fields_info, create_schema_table, fill_status,
4745
make_old_format, 0, -1, -1, 1, 0},
4746
{"TABLES", tables_fields_info, create_schema_table,
4747
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4748
OPTIMIZE_I_S_TABLE},
4749
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4750
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
4751
{"TABLE_NAMES", table_names_fields_info, create_schema_table,
4752
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
4753
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
4754
make_old_format, 0, -1, -1, 1, 0},
4755
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
4759
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
4760
template class List_iterator_fast<char>;
4761
template class List<char>;
4764
int initialize_schema_table(st_plugin_int *plugin)
4766
ST_SCHEMA_TABLE *schema_table;
4768
if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
4769
MYF(MY_WME | MY_ZEROFILL))))
4771
/* Historical Requirement */
4772
plugin->data= schema_table; // shortcut for the future
4773
if (plugin->plugin->init)
4775
schema_table->create_table= create_schema_table;
4776
schema_table->old_format= make_old_format;
4777
schema_table->idx_field1= -1,
4778
schema_table->idx_field2= -1;
4780
/* Make the name available to the init() function. */
4781
schema_table->table_name= plugin->name.str;
4783
if (plugin->plugin->init(schema_table))
4785
sql_print_error("Plugin '%s' init function returned error.",
4790
/* Make sure the plugin name is not set inside the init() function. */
4791
schema_table->table_name= plugin->name.str;
4796
my_free(schema_table, MYF(0));
4800
int finalize_schema_table(st_plugin_int *plugin)
4802
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
4804
if (schema_table && plugin->plugin->deinit)
4805
my_free(schema_table, MYF(0));