132
549
# Quote character
135
int get_quote_char_for_identifier()
552
int get_quote_char_for_identifier(Session *session, const char *name, uint32_t length)
555
!is_keyword(name,length) &&
556
!require_quotes(name, length) &&
557
!(session->options & OPTION_QUOTE_SHOW_CREATE))
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 */
563
/* Append directory name (if exists) to CREATE INFO */
565
static void append_directory(Session *session __attribute__((unused)),
566
String *packet, const char *dir_type,
567
const char *filename)
571
uint32_t length= dirname_length(filename);
573
packet->append(dir_type);
574
packet->append(STRING_WITH_LEN(" DIRECTORY='"));
575
packet->append(filename, length);
576
packet->append('\'');
581
#define LIST_PROCESS_HOST_LEN 64
583
static bool get_field_default_value(Session *session __attribute__((unused)),
584
Field *timestamp_field,
585
Field *field, String *def_value,
589
bool has_now_default;
592
We are using CURRENT_TIMESTAMP instead of NOW because it is
595
has_now_default= (timestamp_field == field &&
596
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
598
has_default= (field->type() != DRIZZLE_TYPE_BLOB &&
599
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
600
field->unireg_check != Field::NEXT_NUMBER
603
def_value->length(0);
607
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
608
else if (!field->is_null())
609
{ // Not null by default
610
char tmp[MAX_FIELD_WIDTH];
611
String type(tmp, sizeof(tmp), field->charset());
612
field->val_str(&type);
616
uint32_t dummy_errors;
617
/* convert to system_charset_info == utf8 */
618
def_val.copy(type.ptr(), type.length(), field->charset(),
619
system_charset_info, &dummy_errors);
621
append_unescaped(def_value, def_val.ptr(), def_val.length());
623
def_value->append(def_val.ptr(), def_val.length());
626
def_value->append(STRING_WITH_LEN("''"));
628
else if (field->maybe_null() && quoted)
629
def_value->append(STRING_WITH_LEN("NULL")); // Null as default
638
Build a CREATE TABLE statement for a table.
643
table_list A list containing one table to write statement
645
packet Pointer to a string where statement will be
647
create_info_arg Pointer to create information that can be used
648
to tailor the format of the statement. Can be
649
NULL, in which case only SQL_MODE is considered
650
when building the statement.
653
Currently always return 0, but might return error code in the
660
int store_create_info(Session *session, TableList *table_list, String *packet,
661
HA_CREATE_INFO *create_info_arg)
663
List<Item> field_list;
664
char tmp[MAX_FIELD_WIDTH], *for_str, def_value_buf[MAX_FIELD_WIDTH];
667
String type(tmp, sizeof(tmp), system_charset_info);
668
String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
670
uint32_t primary_key;
672
Table *table= table_list->table;
673
handler *file= table->file;
674
TABLE_SHARE *share= table->s;
675
HA_CREATE_INFO create_info;
676
bool show_table_options= false;
677
my_bitmap_map *old_map;
679
restore_record(table, s->default_values); // Get empty record
681
if (share->tmp_table)
682
packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
684
packet->append(STRING_WITH_LEN("CREATE TABLE "));
685
if (create_info_arg &&
686
(create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
687
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
688
if (table_list->schema_table)
689
alias= table_list->schema_table->table_name;
692
if (lower_case_table_names == 2)
696
alias= share->table_name.str;
699
append_identifier(session, packet, alias, strlen(alias));
700
packet->append(STRING_WITH_LEN(" (\n"));
702
We need this to get default values from the table
703
We have to restore the read_set if we are called from insert in case
704
of row based replication.
706
old_map= table->use_all_columns(table->read_set);
708
for (ptr=table->field ; (field= *ptr); ptr++)
710
uint32_t flags = field->flags;
712
if (ptr != table->field)
713
packet->append(STRING_WITH_LEN(",\n"));
715
packet->append(STRING_WITH_LEN(" "));
716
append_identifier(session,packet,field->field_name, strlen(field->field_name));
718
// check for surprises from the previous call to Field::sql_type()
719
if (type.ptr() != tmp)
720
type.set(tmp, sizeof(tmp), system_charset_info);
722
type.set_charset(system_charset_info);
724
if (field->vcol_info)
726
packet->append(STRING_WITH_LEN("VIRTUAL "));
729
field->sql_type(type);
730
packet->append(type.ptr(), type.length(), system_charset_info);
732
if (field->vcol_info)
734
packet->append(STRING_WITH_LEN(" AS ("));
735
packet->append(field->vcol_info->expr_str.str,
736
field->vcol_info->expr_str.length,
737
system_charset_info);
738
packet->append(STRING_WITH_LEN(")"));
739
if (field->is_stored)
740
packet->append(STRING_WITH_LEN(" STORED"));
743
if (field->has_charset())
745
if (field->charset() != share->table_charset)
747
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
748
packet->append(field->charset()->csname);
751
For string types dump collation name only if
752
collation is not primary for the given charset
754
if (!(field->charset()->state & MY_CS_PRIMARY))
756
packet->append(STRING_WITH_LEN(" COLLATE "));
757
packet->append(field->charset()->name);
761
if (flags & NOT_NULL_FLAG)
762
packet->append(STRING_WITH_LEN(" NOT NULL"));
763
else if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
766
TIMESTAMP field require explicit NULL flag, because unlike
767
all other fields they are treated as NOT NULL by default.
769
packet->append(STRING_WITH_LEN(" NULL"));
773
Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
774
and about STORAGE (DISK or MEMORY).
776
enum column_format_type column_format= (enum column_format_type)
777
((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
780
packet->append(STRING_WITH_LEN(" /*!"));
781
packet->append(STRING_WITH_LEN(DRIZZLE_VERSION_TABLESPACE_IN_FRM_STR));
782
packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
783
if (column_format == COLUMN_FORMAT_TYPE_FIXED)
784
packet->append(STRING_WITH_LEN(" FIXED */"));
786
packet->append(STRING_WITH_LEN(" DYNAMIC */"));
789
if (!field->vcol_info &&
790
get_field_default_value(session, table->timestamp_field,
791
field, &def_value, 1))
793
packet->append(STRING_WITH_LEN(" DEFAULT "));
794
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
797
if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
798
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
800
if (field->unireg_check == Field::NEXT_NUMBER)
801
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
803
if (field->comment.length)
805
packet->append(STRING_WITH_LEN(" COMMENT "));
806
append_unescaped(packet, field->comment.str, field->comment.length);
810
key_info= table->key_info;
811
memset(&create_info, 0, sizeof(create_info));
812
/* Allow update_create_info to update row type */
813
create_info.row_type= share->row_type;
814
file->update_create_info(&create_info);
815
primary_key= share->primary_key;
817
for (uint32_t i=0 ; i < share->keys ; i++,key_info++)
819
KEY_PART_INFO *key_part= key_info->key_part;
820
bool found_primary=0;
821
packet->append(STRING_WITH_LEN(",\n "));
823
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
827
No space at end, because a space will be added after where the
828
identifier would go, but that is not added for primary key.
830
packet->append(STRING_WITH_LEN("PRIMARY KEY"));
832
else if (key_info->flags & HA_NOSAME)
833
packet->append(STRING_WITH_LEN("UNIQUE KEY "));
835
packet->append(STRING_WITH_LEN("KEY "));
838
append_identifier(session, packet, key_info->name, strlen(key_info->name));
840
packet->append(STRING_WITH_LEN(" ("));
842
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
848
append_identifier(session,packet,key_part->field->field_name,
849
strlen(key_part->field->field_name));
850
if (key_part->field &&
852
table->field[key_part->fieldnr-1]->key_length()))
855
buff= to_string(buff, (int32_t) key_part->length /
856
key_part->field->charset()->mbmaxlen);
858
packet->append(buff.c_str(), buff.length());
862
store_key_options(session, packet, table, key_info);
866
Get possible foreign key definitions stored in InnoDB and append them
867
to the CREATE TABLE statement
870
if ((for_str= file->get_foreign_key_create_info()))
872
packet->append(for_str, strlen(for_str));
873
file->free_foreign_key_create_info(for_str);
876
packet->append(STRING_WITH_LEN("\n)"));
878
show_table_options= true;
880
Get possible table space definitions and append them
881
to the CREATE TABLE statement
886
THEN add ENGINE only if it was used when creating the table
888
if (!create_info_arg ||
889
(create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
891
packet->append(STRING_WITH_LEN(" ENGINE="));
892
packet->append(file->table_type());
896
Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
897
and NEXT_ID > 1 (the default). We must not print the clause
898
for engines that do not support this as it would break the
899
import of dumps, but as of this writing, the test for whether
900
AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
901
is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
902
Because of that, we do not explicitly test for the feature,
903
but may extrapolate its existence from that of an AUTO_INCREMENT column.
906
if (create_info.auto_increment_value > 1)
908
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
909
buff= to_string(create_info.auto_increment_value);
910
packet->append(buff.c_str(), buff.length());
915
packet->append(STRING_WITH_LEN(" MIN_ROWS="));
916
buff= to_string(share->min_rows);
917
packet->append(buff.c_str(), buff.length());
920
if (share->max_rows && !table_list->schema_table)
922
packet->append(STRING_WITH_LEN(" MAX_ROWS="));
923
buff= to_string(share->max_rows);
924
packet->append(buff.c_str(), buff.length());
927
if (share->avg_row_length)
929
packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
930
buff= to_string(share->avg_row_length);
931
packet->append(buff.c_str(), buff.length());
934
if (share->db_create_options & HA_OPTION_PACK_KEYS)
935
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
936
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
937
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
938
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
939
if (share->db_create_options & HA_OPTION_CHECKSUM)
940
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
941
if (share->page_checksum != HA_CHOICE_UNDEF)
943
packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
944
packet->append(ha_choice_values[(uint) share->page_checksum], 1);
946
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
947
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
948
if (create_info.row_type != ROW_TYPE_DEFAULT)
950
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
951
packet->append(ha_row_type[(uint) create_info.row_type]);
953
if (share->transactional != HA_CHOICE_UNDEF)
955
packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
956
packet->append(ha_choice_values[(uint) share->transactional], 1);
958
if (table->s->key_block_size)
960
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
961
buff= to_string(table->s->key_block_size);
962
packet->append(buff.c_str(), buff.length());
964
if (share->block_size)
966
packet->append(STRING_WITH_LEN(" BLOCK_SIZE="));
967
buff= to_string(share->block_size);
968
packet->append(buff.c_str(), buff.length());
970
table->file->append_create_info(packet);
971
if (share->comment.length)
973
packet->append(STRING_WITH_LEN(" COMMENT="));
974
append_unescaped(packet, share->comment.str, share->comment.length);
976
if (share->connect_string.length)
978
packet->append(STRING_WITH_LEN(" CONNECTION="));
979
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
981
append_directory(session, packet, "DATA", create_info.data_file_name);
982
append_directory(session, packet, "INDEX", create_info.index_file_name);
984
table->restore_column_map(old_map);
989
Get a CREATE statement for a given database.
991
The database is identified by its name, passed as @c dbname parameter.
992
The name should be encoded using the system character set (UTF8 currently).
994
Resulting statement is stored in the string pointed by @c buffer. The string
995
is emptied first and its character set is set to the system character set.
997
If HA_LEX_CREATE_IF_NOT_EXISTS flag is set in @c create_info->options, then
998
the resulting CREATE statement contains "IF NOT EXISTS" clause. Other flags
999
in @c create_options are ignored.
1001
@param session The current thread instance.
1002
@param dbname The name of the database.
1003
@param buffer A String instance where the statement is stored.
1004
@param create_info If not NULL, the options member influences the resulting
1007
@returns true if errors are detected, false otherwise.
1010
bool store_db_create_info(Session *session, const char *dbname, String *buffer,
1011
HA_CREATE_INFO *create_info)
1013
HA_CREATE_INFO create;
1014
uint32_t create_options = create_info ? create_info->options : 0;
1016
if (!my_strcasecmp(system_charset_info, dbname,
1017
INFORMATION_SCHEMA_NAME.str))
1019
dbname= INFORMATION_SCHEMA_NAME.str;
1020
create.default_table_charset= system_charset_info;
1024
if (check_db_dir_existence(dbname))
1027
load_db_opt_by_name(session, dbname, &create);
1032
buffer->set_charset(system_charset_info);
1033
buffer->append(STRING_WITH_LEN("CREATE DATABASE "));
1035
if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
1036
buffer->append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
1038
append_identifier(session, buffer, dbname, strlen(dbname));
1040
if (create.default_table_charset)
1042
buffer->append(STRING_WITH_LEN(" /*!40100"));
1043
buffer->append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
1044
buffer->append(create.default_table_charset->csname);
1045
if (!(create.default_table_charset->state & MY_CS_PRIMARY))
1047
buffer->append(STRING_WITH_LEN(" COLLATE "));
1048
buffer->append(create.default_table_charset->name);
1050
buffer->append(STRING_WITH_LEN(" */"));
1056
static void store_key_options(Session *session __attribute__((unused)),
1057
String *packet, Table *table,
1060
char *end, buff[32];
1062
if (key_info->algorithm == HA_KEY_ALG_BTREE)
1063
packet->append(STRING_WITH_LEN(" USING BTREE"));
1065
if (key_info->algorithm == HA_KEY_ALG_HASH)
1066
packet->append(STRING_WITH_LEN(" USING HASH"));
1068
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
1069
table->s->key_block_size != key_info->block_size)
1071
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
1072
end= int64_t10_to_str(key_info->block_size, buff, 10);
1073
packet->append(buff, (uint) (end - buff));
1076
assert(test(key_info->flags & HA_USES_COMMENT) ==
1077
(key_info->comment.length > 0));
1078
if (key_info->flags & HA_USES_COMMENT)
1080
packet->append(STRING_WITH_LEN(" COMMENT "));
1081
append_unescaped(packet, key_info->comment.str,
1082
key_info->comment.length);
1087
/****************************************************************************
1088
Return info about all processes
1089
returns for each thread: thread id, user, host, db, command, info
1090
****************************************************************************/
1092
class thread_info :public ilink {
1094
static void *operator new(size_t size)
1096
return (void*) sql_alloc((uint) size);
1098
static void operator delete(void *ptr __attribute__((unused)),
1099
size_t size __attribute__((unused)))
1100
{ TRASH(ptr, size); }
1105
const char *user,*host,*db,*proc_info,*state_info;
1109
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1110
template class I_List<thread_info>;
1113
void mysqld_list_processes(Session *session,const char *user, bool verbose)
1116
List<Item> field_list;
1117
I_List<thread_info> thread_infos;
1118
ulong max_query_length= (verbose ? session->variables.max_allowed_packet :
1119
PROCESS_LIST_WIDTH);
1120
Protocol *protocol= session->protocol;
1122
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1123
field_list.push_back(new Item_empty_string("User",16));
1124
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1125
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1126
field->maybe_null=1;
1127
field_list.push_back(new Item_empty_string("Command",16));
1128
field_list.push_back(new Item_return_int("Time",7, DRIZZLE_TYPE_LONG));
1129
field_list.push_back(field=new Item_empty_string("State",30));
1130
field->maybe_null=1;
1131
field_list.push_back(field=new Item_empty_string("Info",max_query_length));
1132
field->maybe_null=1;
1133
if (protocol->send_fields(&field_list,
1134
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1137
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1138
if (!session->killed)
1140
I_List_iterator<Session> it(threads);
1144
Security_context *tmp_sctx= tmp->security_ctx;
1145
struct st_my_thread_var *mysys_var;
1146
if ((tmp->vio_ok() || tmp->system_thread) && (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
1148
thread_info *session_info= new thread_info;
1150
session_info->thread_id=tmp->thread_id;
1151
session_info->user= session->strdup(tmp_sctx->user ? tmp_sctx->user :
1152
(tmp->system_thread ?
1153
"system user" : "unauthenticated user"));
1154
session_info->host= session->strdup(tmp_sctx->ip);
1155
if ((session_info->db=tmp->db)) // Safe test
1156
session_info->db=session->strdup(session_info->db);
1157
session_info->command=(int) tmp->command;
1158
if ((mysys_var= tmp->mysys_var))
1159
pthread_mutex_lock(&mysys_var->mutex);
1160
session_info->proc_info= (char*) (tmp->killed == Session::KILL_CONNECTION? "Killed" : 0);
1161
session_info->state_info= (char*) (tmp->net.reading_or_writing ?
1162
(tmp->net.reading_or_writing == 2 ?
1164
session_info->command == COM_SLEEP ? NULL :
1165
"Reading from net") :
1166
tmp->get_proc_info() ? tmp->get_proc_info() :
1168
tmp->mysys_var->current_cond ?
1169
"Waiting on cond" : NULL);
1171
pthread_mutex_unlock(&mysys_var->mutex);
1173
session_info->start_time= tmp->start_time;
1174
session_info->query=0;
1178
query_length is always set to 0 when we set query = NULL; see
1179
the comment in sql_class.h why this prevents crashes in possible
1180
races with query_length
1182
uint32_t length= cmin((uint32_t)max_query_length, tmp->query_length);
1183
session_info->query=(char*) session->strmake(tmp->query,length);
1185
thread_infos.append(session_info);
1189
pthread_mutex_unlock(&LOCK_thread_count);
1191
thread_info *session_info;
1192
time_t now= my_time(0);
1193
while ((session_info=thread_infos.get()))
1195
protocol->prepare_for_resend();
1196
protocol->store((uint64_t) session_info->thread_id);
1197
protocol->store(session_info->user, system_charset_info);
1198
protocol->store(session_info->host, system_charset_info);
1199
protocol->store(session_info->db, system_charset_info);
1200
if (session_info->proc_info)
1201
protocol->store(session_info->proc_info, system_charset_info);
1203
protocol->store(command_name[session_info->command].str, system_charset_info);
1204
if (session_info->start_time)
1205
protocol->store((uint32_t) (now - session_info->start_time));
1207
protocol->store_null();
1208
protocol->store(session_info->state_info, system_charset_info);
1209
protocol->store(session_info->query, system_charset_info);
1210
if (protocol->write())
1211
break; /* purecov: inspected */
1217
int fill_schema_processlist(Session* session, TableList* tables,
1218
COND* cond __attribute__((unused)))
1220
Table *table= tables->table;
1221
const CHARSET_INFO * const cs= system_charset_info;
1223
time_t now= my_time(0);
1227
pthread_mutex_lock(&LOCK_thread_count);
1229
if (!session->killed)
1231
I_List_iterator<Session> it(threads);
1236
Security_context *tmp_sctx= tmp->security_ctx;
1237
struct st_my_thread_var *mysys_var;
1240
if ((!tmp->vio_ok() && !tmp->system_thread))
1243
restore_record(table, s->default_values);
1245
table->field[0]->store((int64_t) tmp->thread_id, true);
1247
val= tmp_sctx->user ? tmp_sctx->user :
1248
(tmp->system_thread ? "system user" : "unauthenticated user");
1249
table->field[1]->store(val, strlen(val), cs);
1251
table->field[2]->store(tmp_sctx->ip, strlen(tmp_sctx->ip), cs);
1255
table->field[3]->store(tmp->db, strlen(tmp->db), cs);
1256
table->field[3]->set_notnull();
1259
if ((mysys_var= tmp->mysys_var))
1260
pthread_mutex_lock(&mysys_var->mutex);
1262
if ((val= (char *) (tmp->killed == Session::KILL_CONNECTION? "Killed" : 0)))
1263
table->field[4]->store(val, strlen(val), cs);
1265
table->field[4]->store(command_name[tmp->command].str,
1266
command_name[tmp->command].length, cs);
1268
table->field[5]->store((uint32_t)(tmp->start_time ?
1269
now - tmp->start_time : 0), true);
1271
val= (char*) (tmp->net.reading_or_writing ?
1272
(tmp->net.reading_or_writing == 2 ?
1274
tmp->command == COM_SLEEP ? NULL :
1275
"Reading from net") :
1276
tmp->get_proc_info() ? tmp->get_proc_info() :
1278
tmp->mysys_var->current_cond ?
1279
"Waiting on cond" : NULL);
1282
table->field[6]->store(val, strlen(val), cs);
1283
table->field[6]->set_notnull();
1287
pthread_mutex_unlock(&mysys_var->mutex);
1292
table->field[7]->store(tmp->query,
1293
cmin((uint32_t)PROCESS_LIST_INFO_WIDTH,
1294
tmp->query_length), cs);
1295
table->field[7]->set_notnull();
1298
if (schema_table_store_record(session, table))
1300
pthread_mutex_unlock(&LOCK_thread_count);
1306
pthread_mutex_unlock(&LOCK_thread_count);
1310
/*****************************************************************************
1312
*****************************************************************************/
1314
static DYNAMIC_ARRAY all_status_vars;
1315
static bool status_vars_inited= 0;
1316
static int show_var_cmp(const void *var1, const void *var2)
1318
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1322
deletes all the SHOW_UNDEF elements from the array and calls
1323
delete_dynamic() if it's completely empty.
1325
static void shrink_var_array(DYNAMIC_ARRAY *array)
1328
SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
1330
for (a= b= 0; b < array->elements; b++)
1331
if (all[b].type != SHOW_UNDEF)
1335
memset(all+a, 0, sizeof(SHOW_VAR)); // writing NULL-element to the end
1338
else // array is completely empty - delete it
1339
delete_dynamic(array);
1343
Adds an array of SHOW_VAR entries to the output of SHOW STATUS
1346
add_status_vars(SHOW_VAR *list)
1347
list - an array of SHOW_VAR entries to add to all_status_vars
1348
the last entry must be {0,0,SHOW_UNDEF}
1351
The handling of all_status_vars[] is completely internal, it's allocated
1352
automatically when something is added to it, and deleted completely when
1353
the last entry is removed.
1355
As a special optimization, if add_status_vars() is called before
1356
init_status_vars(), it assumes "startup mode" - neither concurrent access
1357
to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
1359
The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
1361
int add_status_vars(SHOW_VAR *list)
1364
if (status_vars_inited)
1365
pthread_mutex_lock(&LOCK_status);
1366
if (!all_status_vars.buffer && // array is not allocated yet - do it now
1367
my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
1373
res|= insert_dynamic(&all_status_vars, (unsigned char*)list++);
1374
res|= insert_dynamic(&all_status_vars, (unsigned char*)list); // appending NULL-element
1375
all_status_vars.elements--; // but next insert_dynamic should overwite it
1376
if (status_vars_inited)
1377
sort_dynamic(&all_status_vars, show_var_cmp);
1379
if (status_vars_inited)
1380
pthread_mutex_unlock(&LOCK_status);
1385
Make all_status_vars[] usable for SHOW STATUS
1388
See add_status_vars(). Before init_status_vars() call, add_status_vars()
1389
works in a special fast "startup" mode. Thus init_status_vars()
1390
should be called as late as possible but before enabling multi-threading.
1392
void init_status_vars()
1394
status_vars_inited=1;
1395
sort_dynamic(&all_status_vars, show_var_cmp);
1398
void reset_status_vars()
1400
SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
1401
SHOW_VAR *last= ptr + all_status_vars.elements;
1402
for (; ptr < last; ptr++)
1404
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
1405
if (ptr->type == SHOW_LONG)
1406
*(ulong*) ptr->value= 0;
1411
catch-all cleanup function, cleans up everything no matter what
1414
This function is not strictly required if all add_to_status/
1415
remove_status_vars are properly paired, but it's a safety measure that
1416
deletes everything from the all_status_vars[] even if some
1417
remove_status_vars were forgotten
1419
void free_status_vars()
1421
delete_dynamic(&all_status_vars);
1425
Removes an array of SHOW_VAR entries from the output of SHOW STATUS
1428
remove_status_vars(SHOW_VAR *list)
1429
list - an array of SHOW_VAR entries to remove to all_status_vars
1430
the last entry must be {0,0,SHOW_UNDEF}
1433
there's lots of room for optimizing this, especially in non-sorted mode,
1434
but nobody cares - it may be called only in case of failed plugin
1435
initialization in the mysqld startup.
1438
void remove_status_vars(SHOW_VAR *list)
1440
if (status_vars_inited)
1442
pthread_mutex_lock(&LOCK_status);
1443
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1444
int a= 0, b= all_status_vars.elements, c= (a+b)/2;
1446
for (; list->name; list++)
1449
for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
1451
res= show_var_cmp(list, all+c);
1460
all[c].type= SHOW_UNDEF;
1462
shrink_var_array(&all_status_vars);
1463
pthread_mutex_unlock(&LOCK_status);
1467
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1469
for (; list->name; list++)
1471
for (i= 0; i < all_status_vars.elements; i++)
1473
if (show_var_cmp(list, all+i))
1475
all[i].type= SHOW_UNDEF;
1479
shrink_var_array(&all_status_vars);
1483
inline void make_upper(char *buf)
1486
*buf= my_toupper(system_charset_info, *buf);
1489
static bool show_status_array(Session *session, const char *wild,
1490
SHOW_VAR *variables,
1491
enum enum_var_type value_type,
1492
struct system_status_var *status_var,
1493
const char *prefix, Table *table,
1496
MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
1497
char * const buff= (char *) &buff_data;
1499
/* the variable name should not be longer than 64 characters */
1500
char name_buffer[64];
1502
LEX_STRING null_lex_str;
1505
null_lex_str.str= 0; // For sys_var->value_ptr()
1506
null_lex_str.length= 0;
1508
prefix_end=my_stpncpy(name_buffer, prefix, sizeof(name_buffer)-1);
1511
len=name_buffer + sizeof(name_buffer) - prefix_end;
1513
for (; variables->name; variables++)
1515
my_stpncpy(prefix_end, variables->name, len);
1516
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
1518
make_upper(name_buffer);
1521
if var->type is SHOW_FUNC, call the function.
1522
Repeat as necessary, if new var is again SHOW_FUNC
1524
for (var=variables; var->type == SHOW_FUNC; var= &tmp)
1525
((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(session, &tmp, buff);
1527
SHOW_TYPE show_type=var->type;
1528
if (show_type == SHOW_ARRAY)
1530
show_status_array(session, wild, (SHOW_VAR *) var->value, value_type,
1531
status_var, name_buffer, table, ucase_names);
1535
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
1536
name_buffer, wild)))
1538
char *value=var->value;
1539
const char *pos, *end; // We assign a lot of const's
1541
pthread_mutex_lock(&LOCK_global_system_variables);
1543
if (show_type == SHOW_SYS)
1545
show_type= ((sys_var*) value)->show_type();
1546
value= (char*) ((sys_var*) value)->value_ptr(session, value_type,
1552
note that value may be == buff. All SHOW_xxx code below
1553
should still work in this case
1555
switch (show_type) {
1556
case SHOW_DOUBLE_STATUS:
1557
value= ((char *) status_var + (ulong) value);
1560
/* 6 is the default precision for '%f' in sprintf() */
1561
end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
1563
case SHOW_LONG_STATUS:
1564
value= ((char *) status_var + (ulong) value);
1567
case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
1568
end= int10_to_str(*(long*) value, buff, 10);
1570
case SHOW_LONGLONG_STATUS:
1571
value= ((char *) status_var + (uint64_t) value);
1574
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1577
end= int64_t10_to_str((int64_t) *(ha_rows*) value, buff, 10);
1580
end= my_stpcpy(buff, *(bool*) value ? "ON" : "OFF");
1583
end= my_stpcpy(buff, *(bool*) value ? "ON" : "OFF");
1586
end= int10_to_str((long) *(uint32_t*) value, buff, 10);
1590
SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
1591
pos= show_comp_option_name[(int) tmp];
1592
end= strchr(pos, '\0');
1599
end= strchr(pos, '\0');
1604
if (!(pos= *(char**) value))
1606
end= strchr(pos, '\0');
1609
case SHOW_KEY_CACHE_LONG:
1610
value= (char*) dflt_key_cache + (ulong)value;
1611
end= int10_to_str(*(long*) value, buff, 10);
1613
case SHOW_KEY_CACHE_LONGLONG:
1614
value= (char*) dflt_key_cache + (ulong)value;
1615
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1618
break; // Return empty string
1619
case SHOW_SYS: // Cannot happen
1624
restore_record(table, s->default_values);
1625
table->field[0]->store(name_buffer, strlen(name_buffer),
1626
system_charset_info);
1627
table->field[1]->store(pos, (uint32_t) (end - pos), system_charset_info);
1628
table->field[1]->set_notnull();
1630
pthread_mutex_unlock(&LOCK_global_system_variables);
1632
if (schema_table_store_record(session, table))
1642
/* collect status for all running threads */
1644
void calc_sum_of_all_status(STATUS_VAR *to)
1647
/* Ensure that thread id not killed during loop */
1648
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1650
I_List_iterator<Session> it(threads);
1653
/* Get global values as base */
1654
*to= global_status_var;
1656
/* Add to this status from existing threads */
1658
add_to_status(to, &tmp->status_var);
1660
pthread_mutex_unlock(&LOCK_thread_count);
1665
/* This is only used internally, but we need it here as a forward reference */
1666
extern ST_SCHEMA_TABLE schema_tables[];
1668
typedef struct st_lookup_field_values
1670
LEX_STRING db_value, table_value;
1671
bool wild_db_value, wild_table_value;
1672
} LOOKUP_FIELD_VALUES;
1676
Store record to I_S table, convert HEAP table
1677
to MyISAM if necessary
1680
schema_table_store_record()
1681
session thread handler
1682
table Information schema table to be updated
1689
bool schema_table_store_record(Session *session, Table *table)
1692
if ((error= table->file->ha_write_row(table->record[0])))
1694
TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
1696
if (create_myisam_from_heap(session, table, param->start_recinfo,
1697
¶m->recinfo, error, 0))
1704
int make_table_list(Session *session, SELECT_LEX *sel,
1705
LEX_STRING *db_name, LEX_STRING *table_name)
1707
Table_ident *table_ident;
1708
table_ident= new Table_ident(session, *db_name, *table_name, 1);
1710
if (!sel->add_table_to_list(session, table_ident, 0, 0, TL_READ))
1717
@brief Get lookup value from the part of 'WHERE' condition
1719
@details This function gets lookup value from
1720
the part of 'WHERE' condition if it's possible and
1721
fill appropriate lookup_field_vals struct field
1724
@param[in] session thread handler
1725
@param[in] item_func part of WHERE condition
1726
@param[in] table I_S table
1727
@param[in, out] lookup_field_vals Struct which holds lookup values
1731
1 error, there can be no matching records for the condition
1734
bool get_lookup_value(Session *session, Item_func *item_func,
1736
LOOKUP_FIELD_VALUES *lookup_field_vals)
1738
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1739
ST_FIELD_INFO *field_info= schema_table->fields_info;
1740
const char *field_name1= schema_table->idx_field1 >= 0 ?
1741
field_info[schema_table->idx_field1].field_name : "";
1742
const char *field_name2= schema_table->idx_field2 >= 0 ?
1743
field_info[schema_table->idx_field2].field_name : "";
1745
if (item_func->functype() == Item_func::EQ_FUNC ||
1746
item_func->functype() == Item_func::EQUAL_FUNC)
1748
int idx_field, idx_val;
1749
char tmp[MAX_FIELD_WIDTH];
1750
String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
1751
Item_field *item_field;
1752
const CHARSET_INFO * const cs= system_charset_info;
1754
if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
1755
item_func->arguments()[1]->const_item())
1760
else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
1761
item_func->arguments()[0]->const_item())
1769
item_field= (Item_field*) item_func->arguments()[idx_field];
1770
if (table->table != item_field->field->table)
1772
tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
1774
/* impossible value */
1778
/* Lookup value is database name */
1779
if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1780
(unsigned char *) item_field->field_name,
1781
strlen(item_field->field_name), 0))
1783
session->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
1784
tmp_str->length(), false);
1786
/* Lookup value is table name */
1787
else if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name2,
1788
strlen(field_name2),
1789
(unsigned char *) item_field->field_name,
1790
strlen(item_field->field_name), 0))
1792
session->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
1793
tmp_str->length(), false);
1801
@brief Calculates lookup values from 'WHERE' condition
1803
@details This function calculates lookup value(database name, table name)
1804
from 'WHERE' condition if it's possible and
1805
fill lookup_field_vals struct fields with these values.
1807
@param[in] session thread handler
1808
@param[in] cond WHERE condition
1809
@param[in] table I_S table
1810
@param[in, out] lookup_field_vals Struct which holds lookup values
1814
1 error, there can be no matching records for the condition
1817
bool calc_lookup_values_from_cond(Session *session, COND *cond, TableList *table,
1818
LOOKUP_FIELD_VALUES *lookup_field_vals)
1823
if (cond->type() == Item::COND_ITEM)
1825
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1827
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1829
while ((item= li++))
1831
if (item->type() == Item::FUNC_ITEM)
1833
if (get_lookup_value(session, (Item_func*)item, table, lookup_field_vals))
1838
if (calc_lookup_values_from_cond(session, item, table, lookup_field_vals))
1845
else if (cond->type() == Item::FUNC_ITEM &&
1846
get_lookup_value(session, (Item_func*) cond, table, lookup_field_vals))
1852
bool uses_only_table_name_fields(Item *item, TableList *table)
1854
if (item->type() == Item::FUNC_ITEM)
1856
Item_func *item_func= (Item_func*)item;
1857
for (uint32_t i=0; i<item_func->argument_count(); i++)
1859
if (!uses_only_table_name_fields(item_func->arguments()[i], table))
1863
else if (item->type() == Item::FIELD_ITEM)
1865
Item_field *item_field= (Item_field*)item;
1866
const CHARSET_INFO * const cs= system_charset_info;
1867
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1868
ST_FIELD_INFO *field_info= schema_table->fields_info;
1869
const char *field_name1= schema_table->idx_field1 >= 0 ?
1870
field_info[schema_table->idx_field1].field_name : "";
1871
const char *field_name2= schema_table->idx_field2 >= 0 ?
1872
field_info[schema_table->idx_field2].field_name : "";
1873
if (table->table != item_field->field->table ||
1874
(cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1875
(unsigned char *) item_field->field_name,
1876
strlen(item_field->field_name), 0) &&
1877
cs->coll->strnncollsp(cs, (unsigned char *) field_name2, strlen(field_name2),
1878
(unsigned char *) item_field->field_name,
1879
strlen(item_field->field_name), 0)))
1882
else if (item->type() == Item::REF_ITEM)
1883
return uses_only_table_name_fields(item->real_item(), table);
1885
if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
1892
static COND * make_cond_for_info_schema(COND *cond, TableList *table)
1896
if (cond->type() == Item::COND_ITEM)
1898
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1900
/* Create new top level AND item */
1901
Item_cond_and *new_cond=new Item_cond_and;
1904
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1908
Item *fix= make_cond_for_info_schema(item, table);
1910
new_cond->argument_list()->push_back(fix);
1912
switch (new_cond->argument_list()->elements) {
1916
return new_cond->argument_list()->head();
1918
new_cond->quick_fix_field();
1924
Item_cond_or *new_cond=new Item_cond_or;
1927
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1931
Item *fix=make_cond_for_info_schema(item, table);
1934
new_cond->argument_list()->push_back(fix);
1936
new_cond->quick_fix_field();
1937
new_cond->top_level_item();
1942
if (!uses_only_table_name_fields(cond, table))
1949
@brief Calculate lookup values(database name, table name)
1951
@details This function calculates lookup values(database name, table name)
1952
from 'WHERE' condition or wild values (for 'SHOW' commands only)
1953
from LEX struct and fill lookup_field_vals struct field
1956
@param[in] session thread handler
1957
@param[in] cond WHERE condition
1958
@param[in] tables I_S table
1959
@param[in, out] lookup_field_values Struct which holds lookup values
1963
1 error, there can be no matching records for the condition
1966
bool get_lookup_field_values(Session *session, COND *cond, TableList *tables,
1967
LOOKUP_FIELD_VALUES *lookup_field_values)
1969
LEX *lex= session->lex;
1970
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
1971
memset(lookup_field_values, 0, sizeof(LOOKUP_FIELD_VALUES));
1972
switch (lex->sql_command) {
1973
case SQLCOM_SHOW_DATABASES:
1976
lookup_field_values->db_value.str= (char*) wild;
1977
lookup_field_values->db_value.length= strlen(wild);
1978
lookup_field_values->wild_db_value= 1;
1981
case SQLCOM_SHOW_TABLES:
1982
case SQLCOM_SHOW_TABLE_STATUS:
1983
lookup_field_values->db_value.str= lex->select_lex.db;
1984
lookup_field_values->db_value.length=strlen(lex->select_lex.db);
1987
lookup_field_values->table_value.str= (char*)wild;
1988
lookup_field_values->table_value.length= strlen(wild);
1989
lookup_field_values->wild_table_value= 1;
1994
The "default" is for queries over I_S.
1995
All previous cases handle SHOW commands.
1997
return calc_lookup_values_from_cond(session, cond, tables, lookup_field_values);
2002
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
2004
return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
2009
Create db names list. Information schema name always is first in list
2013
session thread handler
2014
files list of db names
2016
idx_field_vals idx_field_vals->db_name contains db name or
2018
with_i_schema returns 1 if we added 'IS' name to list
2026
int make_db_list(Session *session, List<LEX_STRING> *files,
2027
LOOKUP_FIELD_VALUES *lookup_field_vals,
2028
bool *with_i_schema)
2030
LEX_STRING *i_s_name_copy= 0;
2031
i_s_name_copy= session->make_lex_string(i_s_name_copy,
2032
INFORMATION_SCHEMA_NAME.str,
2033
INFORMATION_SCHEMA_NAME.length, true);
2035
if (lookup_field_vals->wild_db_value)
2038
This part of code is only for SHOW DATABASES command.
2039
idx_field_vals->db_value can be 0 when we don't use
2040
LIKE clause (see also get_index_field_values() function)
2042
if (!lookup_field_vals->db_value.str ||
2043
!wild_case_compare(system_charset_info,
2044
INFORMATION_SCHEMA_NAME.str,
2045
lookup_field_vals->db_value.str))
2048
if (files->push_back(i_s_name_copy))
2051
return (find_files(session, files, NULL, mysql_data_home,
2052
lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
2057
If we have db lookup vaule we just add it to list and
2058
exit from the function
2060
if (lookup_field_vals->db_value.str)
2062
if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
2063
lookup_field_vals->db_value.str))
2066
if (files->push_back(i_s_name_copy))
2070
if (files->push_back(&lookup_field_vals->db_value))
2076
Create list of existing databases. It is used in case
2077
of select from information schema table
2079
if (files->push_back(i_s_name_copy))
2082
return (find_files(session, files, NULL,
2083
mysql_data_home, NULL, 1) != FIND_FILES_OK);
2087
struct st_add_schema_table
2089
List<LEX_STRING> *files;
2094
static bool add_schema_table(Session *session, plugin_ref plugin,
2097
LEX_STRING *file_name= 0;
2098
st_add_schema_table *data= (st_add_schema_table *)p_data;
2099
List<LEX_STRING> *file_list= data->files;
2100
const char *wild= data->wild;
2101
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
2103
if (schema_table->hidden)
2107
if (lower_case_table_names)
2109
if (wild_case_compare(files_charset_info,
2110
schema_table->table_name,
2114
else if (wild_compare(schema_table->table_name, wild, 0))
2118
if ((file_name= session->make_lex_string(file_name, schema_table->table_name,
2119
strlen(schema_table->table_name),
2121
!file_list->push_back(file_name))
2127
int schema_tables_add(Session *session, List<LEX_STRING> *files, const char *wild)
2129
LEX_STRING *file_name= 0;
2130
ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
2131
st_add_schema_table add_data;
2133
for (; tmp_schema_table->table_name; tmp_schema_table++)
2135
if (tmp_schema_table->hidden)
2139
if (lower_case_table_names)
2141
if (wild_case_compare(files_charset_info,
2142
tmp_schema_table->table_name,
2146
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2150
session->make_lex_string(file_name, tmp_schema_table->table_name,
2151
strlen(tmp_schema_table->table_name), true)) &&
2152
!files->push_back(file_name))
2157
add_data.files= files;
2158
add_data.wild= wild;
2159
if (plugin_foreach(session, add_schema_table,
2160
DRIZZLE_INFORMATION_SCHEMA_PLUGIN, &add_data))
2168
@brief Create table names list
2170
@details The function creates the list of table names in
2173
@param[in] session thread handler
2174
@param[in] table_names List of table names in database
2175
@param[in] lex pointer to LEX struct
2176
@param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
2177
@param[in] with_i_schema true means that we add I_S tables to list
2178
@param[in] db_name database name
2180
@return Operation status
2182
@retval 1 fatal error
2183
@retval 2 Not fatal error; Safe to ignore this file list
2187
make_table_name_list(Session *session, List<LEX_STRING> *table_names, LEX *lex,
2188
LOOKUP_FIELD_VALUES *lookup_field_vals,
2189
bool with_i_schema, LEX_STRING *db_name)
2191
char path[FN_REFLEN];
2192
build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
2193
if (!lookup_field_vals->wild_table_value &&
2194
lookup_field_vals->table_value.str)
2198
if (find_schema_table(session, lookup_field_vals->table_value.str))
2200
if (table_names->push_back(&lookup_field_vals->table_value))
2206
if (table_names->push_back(&lookup_field_vals->table_value))
2213
This call will add all matching the wildcards (if specified) IS tables
2217
return (schema_tables_add(session, table_names,
2218
lookup_field_vals->table_value.str));
2220
find_files_result res= find_files(session, table_names, db_name->str, path,
2221
lookup_field_vals->table_value.str, 0);
2222
if (res != FIND_FILES_OK)
2225
Downgrade errors about problems with database directory to
2226
warnings if this is not a 'SHOW' command. Another thread
2227
may have dropped database, and we may still have a name
2230
if (res == FIND_FILES_DIR)
2232
if (lex->sql_command != SQLCOM_SELECT)
2234
session->clear_error();
2244
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
2246
@param[in] session thread handler
2247
@param[in] tables TableList for I_S table
2248
@param[in] schema_table pointer to I_S structure
2249
@param[in] open_tables_state_backup pointer to Open_tables_state object
2250
which is used to save|restore original
2251
status of variables related to
2254
@return Operation status
2260
fill_schema_show_cols_or_idxs(Session *session, TableList *tables,
2261
ST_SCHEMA_TABLE *schema_table,
2262
Open_tables_state *open_tables_state_backup)
2264
LEX *lex= session->lex;
2266
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
2267
enum_sql_command save_sql_command= lex->sql_command;
2268
TableList *show_table_list= (TableList*) tables->schema_select_lex->
2270
Table *table= tables->table;
2273
lex->all_selects_list= tables->schema_select_lex;
2275
Restore session->temporary_tables to be able to process
2276
temporary tables(only for 'show index' & 'show columns').
2277
This should be changed when processing of temporary tables for
2278
I_S tables will be done.
2280
session->temporary_tables= open_tables_state_backup->temporary_tables;
2282
Let us set fake sql_command so views won't try to merge
2283
themselves into main statement. If we don't do this,
2284
SELECT * from information_schema.xxxx will cause problems.
2285
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
2287
lex->sql_command= SQLCOM_SHOW_FIELDS;
2288
res= open_normal_and_derived_tables(session, show_table_list,
2289
DRIZZLE_LOCK_IGNORE_FLUSH);
2290
lex->sql_command= save_sql_command;
2292
get_all_tables() returns 1 on failure and 0 on success thus
2293
return only these and not the result code of ::process_table()
2295
We should use show_table_list->alias instead of
2296
show_table_list->table_name because table_name
2297
could be changed during opening of I_S tables. It's safe
2298
to use alias because alias contains original table name
2299
in this case(this part of code is used only for
2300
'show columns' & 'show statistics' commands).
2302
table_name= session->make_lex_string(&tmp_lex_string1, show_table_list->alias,
2303
strlen(show_table_list->alias), false);
2304
db_name= session->make_lex_string(&tmp_lex_string, show_table_list->db,
2305
show_table_list->db_length, false);
2308
error= test(schema_table->process_table(session, show_table_list,
2309
table, res, db_name,
2311
session->temporary_tables= 0;
2312
close_tables_for_reopen(session, &show_table_list);
2318
@brief Fill I_S table for SHOW Table NAMES commands
2320
@param[in] session thread handler
2321
@param[in] table Table struct for I_S table
2322
@param[in] db_name database name
2323
@param[in] table_name table name
2324
@param[in] with_i_schema I_S table if true
2326
@return Operation status
2331
static int fill_schema_table_names(Session *session, Table *table,
2332
LEX_STRING *db_name, LEX_STRING *table_name,
2337
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
2338
system_charset_info);
2342
enum legacy_db_type not_used;
2343
char path[FN_REFLEN];
2344
(void) build_table_filename(path, sizeof(path), db_name->str,
2345
table_name->str, reg_ext, 0);
2346
if (mysql_frm_type(session, path, ¬_used))
2348
table->field[3]->store(STRING_WITH_LEN("BASE Table"),
2349
system_charset_info);
2353
table->field[3]->store(STRING_WITH_LEN("ERROR"),
2354
system_charset_info);
2357
if (session->is_error() && session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2359
session->clear_error();
2363
if (schema_table_store_record(session, table))
2370
@brief Get open table method
2372
@details The function calculates the method which will be used
2374
SKIP_OPEN_TABLE - do not open table
2375
OPEN_FRM_ONLY - open FRM file only
2376
OPEN_FULL_TABLE - open FRM, data, index files
2377
@param[in] tables I_S table table_list
2378
@param[in] schema_table I_S table struct
2379
@param[in] schema_table_idx I_S table index
2381
@return return a set of flags
2382
@retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
2385
static uint32_t get_table_open_method(TableList *tables,
2386
ST_SCHEMA_TABLE *schema_table,
2387
enum enum_schema_tables schema_table_idx __attribute__((unused)))
2390
determine which method will be used for table opening
2392
if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
2394
Field **ptr, *field;
2395
int table_open_method= 0, field_indx= 0;
2396
for (ptr=tables->table->field; (field= *ptr) ; ptr++)
2398
if (bitmap_is_set(tables->table->read_set, field->field_index))
2399
table_open_method|= schema_table->fields_info[field_indx].open_method;
2402
return table_open_method;
2404
/* I_S tables which use get_all_tables but can not be optimized */
2405
return (uint) OPEN_FULL_TABLE;
2410
@brief Fill I_S table with data from FRM file only
2412
@param[in] session thread handler
2413
@param[in] table Table struct for I_S table
2414
@param[in] schema_table I_S table struct
2415
@param[in] db_name database name
2416
@param[in] table_name table name
2417
@param[in] schema_table_idx I_S table index
2419
@return Operation status
2420
@retval 0 Table is processed and we can continue
2422
@retval 1 It's view and we have to use
2423
open_tables function for this table
2426
static int fill_schema_table_from_frm(Session *session,TableList *tables,
2427
ST_SCHEMA_TABLE *schema_table,
2428
LEX_STRING *db_name,
2429
LEX_STRING *table_name,
2430
enum enum_schema_tables schema_table_idx __attribute__((unused)))
2432
Table *table= tables->table;
2435
TableList table_list;
2438
char key[MAX_DBKEY_LENGTH];
2439
uint32_t key_length;
2441
memset(&table_list, 0, sizeof(TableList));
2442
memset(&tbl, 0, sizeof(Table));
2444
table_list.table_name= table_name->str;
2445
table_list.db= db_name->str;
2447
key_length= create_table_def_key(session, key, &table_list, 0);
2448
pthread_mutex_lock(&LOCK_open);
2449
share= get_table_share(session, &table_list, key,
2450
key_length, 0, &error);
2459
table_list.table= &tbl;
2460
res= schema_table->process_table(session, &table_list, table,
2461
res, db_name, table_name);
2464
release_table_share(share, RELEASE_NORMAL);
2467
pthread_mutex_unlock(&LOCK_open);
2468
session->clear_error();
2475
@brief Fill I_S tables whose data are retrieved
2476
from frm files and storage engine
2478
@details The information schema tables are internally represented as
2479
temporary tables that are filled at query execution time.
2480
Those I_S tables whose data are retrieved
2481
from frm files and storage engine are filled by the function
2484
@param[in] session thread handler
2485
@param[in] tables I_S table
2486
@param[in] cond 'WHERE' condition
2488
@return Operation status
2493
int get_all_tables(Session *session, TableList *tables, COND *cond)
2495
LEX *lex= session->lex;
2496
Table *table= tables->table;
2497
SELECT_LEX *old_all_select_lex= lex->all_selects_list;
2498
enum_sql_command save_sql_command= lex->sql_command;
2499
SELECT_LEX *lsel= tables->schema_select_lex;
2500
ST_SCHEMA_TABLE *schema_table= tables->schema_table;
2502
LOOKUP_FIELD_VALUES lookup_field_vals;
2503
LEX_STRING *db_name, *table_name;
2505
enum enum_schema_tables schema_table_idx;
2506
List<LEX_STRING> db_names;
2507
List_iterator_fast<LEX_STRING> it(db_names);
2508
COND *partial_cond= 0;
2509
uint32_t derived_tables= lex->derived_tables;
2511
Open_tables_state open_tables_state_backup;
2512
Query_tables_list query_tables_list_backup;
2513
uint32_t table_open_method;
2514
bool old_value= session->no_warnings_for_error;
2516
lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
2519
We should not introduce deadlocks even if we already have some
2520
tables open and locked, since we won't lock tables which we will
2521
open and will ignore possible name-locks for these tables.
2523
session->reset_n_backup_open_tables_state(&open_tables_state_backup);
2525
schema_table_idx= get_schema_table_idx(schema_table);
2526
tables->table_open_method= table_open_method=
2527
get_table_open_method(tables, schema_table, schema_table_idx);
2529
this branch processes SHOW FIELDS, SHOW INDEXES commands.
2530
see sql_parse.cc, prepare_schema_table() function where
2531
this values are initialized
2533
if (lsel && lsel->table_list.first)
2535
error= fill_schema_show_cols_or_idxs(session, tables, schema_table,
2536
&open_tables_state_backup);
2540
if (get_lookup_field_values(session, cond, tables, &lookup_field_vals))
2546
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
2549
if lookup value is empty string then
2550
it's impossible table name or db name
2552
if ((lookup_field_vals.db_value.str && !lookup_field_vals.db_value.str[0]) ||
2553
(lookup_field_vals.table_value.str && !lookup_field_vals.table_value.str[0]))
2560
if (lookup_field_vals.db_value.length &&
2561
!lookup_field_vals.wild_db_value)
2562
tables->has_db_lookup_value= true;
2563
if (lookup_field_vals.table_value.length &&
2564
!lookup_field_vals.wild_table_value)
2565
tables->has_table_lookup_value= true;
2567
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
2570
partial_cond= make_cond_for_info_schema(cond, tables);
2574
/* EXPLAIN SELECT */
2579
if (make_db_list(session, &db_names, &lookup_field_vals, &with_i_schema))
2581
it.rewind(); /* To get access to new elements in basis list */
2582
while ((db_name= it++))
2585
session->no_warnings_for_error= 1;
2586
List<LEX_STRING> table_names;
2587
int res= make_table_name_list(session, &table_names, lex,
2589
with_i_schema, db_name);
2590
if (res == 2) /* Not fatal error, continue */
2595
List_iterator_fast<LEX_STRING> it_files(table_names);
2596
while ((table_name= it_files++))
2598
restore_record(table, s->default_values);
2599
table->field[schema_table->idx_field1]->
2600
store(db_name->str, db_name->length, system_charset_info);
2601
table->field[schema_table->idx_field2]->
2602
store(table_name->str, table_name->length, system_charset_info);
2604
if (!partial_cond || partial_cond->val_int())
2607
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
2608
we can skip table opening and we don't have lookup value for
2609
table name or lookup value is wild string(table name list is
2610
already created by make_table_name_list() function).
2612
if (!table_open_method && schema_table_idx == SCH_TABLES &&
2613
(!lookup_field_vals.table_value.length ||
2614
lookup_field_vals.wild_table_value))
2616
if (schema_table_store_record(session, table))
2617
goto err; /* Out of space in temporary table */
2621
/* SHOW Table NAMES command */
2622
if (schema_table_idx == SCH_TABLE_NAMES)
2624
if (fill_schema_table_names(session, tables->table, db_name,
2625
table_name, with_i_schema))
2630
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
2633
if (!fill_schema_table_from_frm(session, tables, schema_table, db_name,
2634
table_name, schema_table_idx))
2639
LEX_STRING tmp_lex_string, orig_db_name;
2641
Set the parent lex of 'sel' because it is needed by
2642
sel.init_query() which is called inside make_table_list.
2644
session->no_warnings_for_error= 1;
2645
sel.parent_lex= lex;
2646
/* db_name can be changed in make_table_list() func */
2647
if (!session->make_lex_string(&orig_db_name, db_name->str,
2648
db_name->length, false))
2650
if (make_table_list(session, &sel, db_name, table_name))
2652
TableList *show_table_list= (TableList*) sel.table_list.first;
2653
lex->all_selects_list= &sel;
2654
lex->derived_tables= 0;
2655
lex->sql_command= SQLCOM_SHOW_FIELDS;
2656
show_table_list->i_s_requested_object=
2657
schema_table->i_s_requested_object;
2658
res= open_normal_and_derived_tables(session, show_table_list,
2659
DRIZZLE_LOCK_IGNORE_FLUSH);
2660
lex->sql_command= save_sql_command;
2662
XXX: show_table_list has a flag i_is_requested,
2663
and when it's set, open_normal_and_derived_tables()
2664
can return an error without setting an error message
2665
in Session, which is a hack. This is why we have to
2666
check for res, then for session->is_error() only then
2667
for session->main_da.sql_errno().
2669
if (res && session->is_error() &&
2670
session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2673
Hide error for not existing table.
2674
This error can occur for example when we use
2675
where condition with db name and table name and this
2676
table does not exist.
2679
session->clear_error();
2684
We should use show_table_list->alias instead of
2685
show_table_list->table_name because table_name
2686
could be changed during opening of I_S tables. It's safe
2687
to use alias because alias contains original table name
2690
session->make_lex_string(&tmp_lex_string, show_table_list->alias,
2691
strlen(show_table_list->alias), false);
2692
res= schema_table->process_table(session, show_table_list, table,
2695
close_tables_for_reopen(session, &show_table_list);
2697
assert(!lex->query_tables_own_last);
2704
If we have information schema its always the first table and only
2705
the first table. Reset for other tables.
2713
session->restore_backup_open_tables_state(&open_tables_state_backup);
2714
lex->restore_backup_query_tables_list(&query_tables_list_backup);
2715
lex->derived_tables= derived_tables;
2716
lex->all_selects_list= old_all_select_lex;
2717
lex->sql_command= save_sql_command;
2718
session->no_warnings_for_error= old_value;
2723
bool store_schema_shemata(Session* session, Table *table, LEX_STRING *db_name,
2724
const CHARSET_INFO * const cs)
2726
restore_record(table, s->default_values);
2727
table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2728
table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2729
table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2730
return schema_table_store_record(session, table);
2734
int fill_schema_schemata(Session *session, TableList *tables, COND *cond)
2737
TODO: fill_schema_shemata() is called when new client is connected.
2738
Returning error status in this case leads to client hangup.
2741
LOOKUP_FIELD_VALUES lookup_field_vals;
2742
List<LEX_STRING> db_names;
2743
LEX_STRING *db_name;
2745
HA_CREATE_INFO create;
2746
Table *table= tables->table;
2748
if (get_lookup_field_values(session, cond, tables, &lookup_field_vals))
2750
if (make_db_list(session, &db_names, &lookup_field_vals,
2755
If we have lookup db value we should check that the database exists
2757
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
2760
char path[FN_REFLEN+16];
2762
struct stat stat_info;
2763
if (!lookup_field_vals.db_value.str[0])
2765
path_len= build_table_filename(path, sizeof(path),
2766
lookup_field_vals.db_value.str, "", "", 0);
2767
path[path_len-1]= 0;
2768
if (stat(path,&stat_info))
2772
List_iterator_fast<LEX_STRING> it(db_names);
2773
while ((db_name=it++))
2775
if (with_i_schema) // information schema name is always first in list
2777
if (store_schema_shemata(session, table, db_name,
2778
system_charset_info))
2784
load_db_opt_by_name(session, db_name->str, &create);
2785
if (store_schema_shemata(session, table, db_name,
2786
create.default_table_charset))
2794
static int get_schema_tables_record(Session *session, TableList *tables,
2795
Table *table, bool res,
2796
LEX_STRING *db_name,
2797
LEX_STRING *table_name)
2799
const char *tmp_buff;
2801
const CHARSET_INFO * const cs= system_charset_info;
2803
restore_record(table, s->default_values);
2804
table->field[1]->store(db_name->str, db_name->length, cs);
2805
table->field[2]->store(table_name->str, table_name->length, cs);
2809
there was errors during opening tables
2811
const char *error= session->is_error() ? session->main_da.message() : "";
2812
if (tables->schema_table)
2813
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2815
table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
2816
table->field[20]->store(error, strlen(error), cs);
2817
session->clear_error();
2821
char option_buff[400],*ptr;
2822
Table *show_table= tables->table;
2823
TABLE_SHARE *share= show_table->s;
2824
handler *file= show_table->file;
2825
handlerton *tmp_db_type= share->db_type();
2826
if (share->tmp_table == SYSTEM_TMP_TABLE)
2827
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2828
else if (share->tmp_table)
2829
table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
2831
table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
2833
for (int i= 4; i < 20; i++)
2835
if (i == 7 || (i > 12 && i < 17) || i == 18)
2837
table->field[i]->set_notnull();
2839
tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
2840
table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
2841
table->field[5]->store((int64_t) share->frm_version, true);
2844
if (share->min_rows)
2846
ptr=my_stpcpy(ptr," min_rows=");
2847
ptr=int64_t10_to_str(share->min_rows,ptr,10);
2849
if (share->max_rows)
2851
ptr=my_stpcpy(ptr," max_rows=");
2852
ptr=int64_t10_to_str(share->max_rows,ptr,10);
2854
if (share->avg_row_length)
2856
ptr=my_stpcpy(ptr," avg_row_length=");
2857
ptr=int64_t10_to_str(share->avg_row_length,ptr,10);
2859
if (share->db_create_options & HA_OPTION_PACK_KEYS)
2860
ptr=my_stpcpy(ptr," pack_keys=1");
2861
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
2862
ptr=my_stpcpy(ptr," pack_keys=0");
2863
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2864
if (share->db_create_options & HA_OPTION_CHECKSUM)
2865
ptr=my_stpcpy(ptr," checksum=1");
2866
if (share->page_checksum != HA_CHOICE_UNDEF)
2867
ptr= strxmov(ptr, " page_checksum=",
2868
ha_choice_values[(uint) share->page_checksum], NULL);
2869
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
2870
ptr=my_stpcpy(ptr," delay_key_write=1");
2871
if (share->row_type != ROW_TYPE_DEFAULT)
2872
ptr=strxmov(ptr, " row_format=",
2873
ha_row_type[(uint) share->row_type],
2875
if (share->block_size)
2877
ptr= my_stpcpy(ptr, " block_size=");
2878
ptr= int64_t10_to_str(share->block_size, ptr, 10);
2881
if (share->transactional != HA_CHOICE_UNDEF)
2883
ptr= strxmov(ptr, " TRANSACTIONAL=",
2884
(share->transactional == HA_CHOICE_YES ? "1" : "0"),
2887
if (share->transactional != HA_CHOICE_UNDEF)
2888
ptr= strxmov(ptr, " transactional=",
2889
ha_choice_values[(uint) share->transactional], NULL);
2890
table->field[19]->store(option_buff+1,
2891
(ptr == option_buff ? 0 :
2892
(uint) (ptr-option_buff)-1), cs);
2894
tmp_buff= (share->table_charset ?
2895
share->table_charset->name : "default");
2896
table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
2898
if (share->comment.str)
2899
table->field[20]->store(share->comment.str, share->comment.length, cs);
2903
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
2905
enum row_type row_type = file->get_row_type();
2907
case ROW_TYPE_NOT_USED:
2908
case ROW_TYPE_DEFAULT:
2909
tmp_buff= ((share->db_options_in_use &
2910
HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
2911
(share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
2912
"Dynamic" : "Fixed");
2914
case ROW_TYPE_FIXED:
2917
case ROW_TYPE_DYNAMIC:
2918
tmp_buff= "Dynamic";
2920
case ROW_TYPE_COMPRESSED:
2921
tmp_buff= "Compressed";
2923
case ROW_TYPE_REDUNDANT:
2924
tmp_buff= "Redundant";
2926
case ROW_TYPE_COMPACT:
2927
tmp_buff= "Compact";
2933
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
2934
if (!tables->schema_table)
2936
table->field[7]->store((int64_t) file->stats.records, true);
2937
table->field[7]->set_notnull();
2939
table->field[8]->store((int64_t) file->stats.mean_rec_length, true);
2940
table->field[9]->store((int64_t) file->stats.data_file_length, true);
2941
if (file->stats.max_data_file_length)
2943
table->field[10]->store((int64_t) file->stats.max_data_file_length,
2946
table->field[11]->store((int64_t) file->stats.index_file_length, true);
2947
table->field[12]->store((int64_t) file->stats.delete_length, true);
2948
if (show_table->found_next_number_field)
2950
table->field[13]->store((int64_t) file->stats.auto_increment_value,
2952
table->field[13]->set_notnull();
2954
if (file->stats.create_time)
2956
session->variables.time_zone->gmt_sec_to_TIME(&time,
2957
(my_time_t) file->stats.create_time);
2958
table->field[14]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2959
table->field[14]->set_notnull();
2961
if (file->stats.update_time)
2963
session->variables.time_zone->gmt_sec_to_TIME(&time,
2964
(my_time_t) file->stats.update_time);
2965
table->field[15]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2966
table->field[15]->set_notnull();
2968
if (file->stats.check_time)
2970
session->variables.time_zone->gmt_sec_to_TIME(&time,
2971
(my_time_t) file->stats.check_time);
2972
table->field[16]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2973
table->field[16]->set_notnull();
2975
if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
2977
table->field[18]->store((int64_t) file->checksum(), true);
2978
table->field[18]->set_notnull();
2982
return(schema_table_store_record(session, table));
2987
@brief Store field characteristics into appropriate I_S table columns
2989
@param[in] table I_S table
2990
@param[in] field processed field
2991
@param[in] cs I_S table charset
2992
@param[in] offset offset from beginning of table
2993
to DATE_TYPE column in I_S table
2998
void store_column_type(Table *table, Field *field, const CHARSET_INFO * const cs,
3002
int decimals, field_length;
3003
const char *tmp_buff;
3004
char column_type_buff[MAX_FIELD_WIDTH];
3005
String column_type(column_type_buff, sizeof(column_type_buff), cs);
3007
field->sql_type(column_type);
3008
/* DTD_IDENTIFIER column */
3009
table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs);
3010
table->field[offset + 7]->set_notnull();
3011
tmp_buff= strchr(column_type.ptr(), '(');
3012
/* DATA_TYPE column */
3013
table->field[offset]->store(column_type.ptr(),
3014
(tmp_buff ? tmp_buff - column_type.ptr() :
3015
column_type.length()), cs);
3016
is_blob= (field->type() == DRIZZLE_TYPE_BLOB);
3017
if (field->has_charset() || is_blob ||
3018
field->real_type() == DRIZZLE_TYPE_VARCHAR) // For varbinary type
3020
uint32_t octet_max_length= field->max_display_length();
3021
if (is_blob && octet_max_length != (uint32_t) 4294967295U)
3022
octet_max_length /= field->charset()->mbmaxlen;
3023
int64_t char_max_len= is_blob ?
3024
(int64_t) octet_max_length / field->charset()->mbminlen :
3025
(int64_t) octet_max_length / field->charset()->mbmaxlen;
3026
/* CHARACTER_MAXIMUM_LENGTH column*/
3027
table->field[offset + 1]->store(char_max_len, true);
3028
table->field[offset + 1]->set_notnull();
3029
/* CHARACTER_OCTET_LENGTH column */
3030
table->field[offset + 2]->store((int64_t) octet_max_length, true);
3031
table->field[offset + 2]->set_notnull();
3035
Calculate field_length and decimals.
3036
They are set to -1 if they should not be set (we should return NULL)
3039
decimals= field->decimals();
3040
switch (field->type()) {
3041
case DRIZZLE_TYPE_NEWDECIMAL:
3042
field_length= ((Field_new_decimal*) field)->precision;
3044
case DRIZZLE_TYPE_LONG:
3045
case DRIZZLE_TYPE_LONGLONG:
3046
field_length= field->max_display_length() - 1;
3048
case DRIZZLE_TYPE_DOUBLE:
3049
field_length= field->field_length;
3050
if (decimals == NOT_FIXED_DEC)
3051
decimals= -1; // return NULL
3054
field_length= decimals= -1;
3058
/* NUMERIC_PRECISION column */
3059
if (field_length >= 0)
3061
table->field[offset + 3]->store((int64_t) field_length, true);
3062
table->field[offset + 3]->set_notnull();
3064
/* NUMERIC_SCALE column */
3067
table->field[offset + 4]->store((int64_t) decimals, true);
3068
table->field[offset + 4]->set_notnull();
3070
if (field->has_charset())
3072
/* CHARACTER_SET_NAME column*/
3073
tmp_buff= field->charset()->csname;
3074
table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs);
3075
table->field[offset + 5]->set_notnull();
3076
/* COLLATION_NAME column */
3077
tmp_buff= field->charset()->name;
3078
table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs);
3079
table->field[offset + 6]->set_notnull();
3084
static int get_schema_column_record(Session *session, TableList *tables,
3085
Table *table, bool res,
3086
LEX_STRING *db_name,
3087
LEX_STRING *table_name)
3089
LEX *lex= session->lex;
3090
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3091
const CHARSET_INFO * const cs= system_charset_info;
3093
TABLE_SHARE *show_table_share;
3094
Field **ptr, *field, *timestamp_field;
3099
if (lex->sql_command != SQLCOM_SHOW_FIELDS)
3102
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
3103
rather than in SHOW COLUMNS
3105
if (session->is_error())
3106
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3107
session->main_da.sql_errno(), session->main_da.message());
3108
session->clear_error();
3114
show_table= tables->table;
3115
show_table_share= show_table->s;
3118
if (tables->schema_table)
3120
ptr= show_table->field;
3121
timestamp_field= show_table->timestamp_field;
3122
show_table->use_all_columns(); // Required for default
3126
ptr= show_table_share->field;
3127
timestamp_field= show_table_share->timestamp_field;
3129
read_set may be inited in case of
3132
if (!show_table->read_set)
3134
/* to satisfy 'field->val_str' ASSERTs */
3135
unsigned char *bitmaps;
3136
uint32_t bitmap_size= show_table_share->column_bitmap_size;
3137
if (!(bitmaps= (unsigned char*) alloc_root(session->mem_root, bitmap_size)))
3139
bitmap_init(&show_table->def_read_set,
3140
(my_bitmap_map*) bitmaps, show_table_share->fields, false);
3141
bitmap_set_all(&show_table->def_read_set);
3142
show_table->read_set= &show_table->def_read_set;
3144
bitmap_set_all(show_table->read_set);
3147
for (; (field= *ptr) ; ptr++)
3150
char tmp[MAX_FIELD_WIDTH];
3151
String type(tmp,sizeof(tmp), system_charset_info);
3154
/* to satisfy 'field->val_str' ASSERTs */
3155
field->table= show_table;
3156
show_table->in_use= session;
3158
if (wild && wild[0] &&
3159
wild_case_compare(system_charset_info, field->field_name,wild))
3163
/* Get default row, with all NULL fields set to NULL */
3164
restore_record(table, s->default_values);
3166
table->field[1]->store(db_name->str, db_name->length, cs);
3167
table->field[2]->store(table_name->str, table_name->length, cs);
3168
table->field[3]->store(field->field_name, strlen(field->field_name),
3170
table->field[4]->store((int64_t) count, true);
3172
if (get_field_default_value(session, timestamp_field, field, &type, 0))
3174
table->field[5]->store(type.ptr(), type.length(), cs);
3175
table->field[5]->set_notnull();
3177
pos=(unsigned char*) ((field->flags & NOT_NULL_FLAG) ? "NO" : "YES");
3178
table->field[6]->store((const char*) pos,
3179
strlen((const char*) pos), cs);
3180
store_column_type(table, field, cs, 7);
3182
pos=(unsigned char*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
3183
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
3184
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
3185
table->field[15]->store((const char*) pos,
3186
strlen((const char*) pos), cs);
3189
if (field->unireg_check == Field::NEXT_NUMBER)
3190
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
3191
if (timestamp_field == field &&
3192
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3193
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3195
if (field->vcol_info)
3196
table->field[16]->store(STRING_WITH_LEN("VIRTUAL"), cs);
3197
table->field[18]->store(field->comment.str, field->comment.length, cs);
3199
enum column_format_type column_format= (enum column_format_type)
3200
((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
3201
pos=(unsigned char*)"Default";
3202
table->field[19]->store((const char*) pos,
3203
strlen((const char*) pos), cs);
3204
pos=(unsigned char*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
3205
column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
3207
table->field[20]->store((const char*) pos,
3208
strlen((const char*) pos), cs);
3210
if (schema_table_store_record(session, table))
3218
int fill_schema_charsets(Session *session, TableList *tables, COND *cond __attribute__((unused)))
3221
const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3222
Table *table= tables->table;
3223
const CHARSET_INFO * const scs= system_charset_info;
3225
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3227
const CHARSET_INFO * const tmp_cs= cs[0];
3228
if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
3229
(tmp_cs->state & MY_CS_AVAILABLE) &&
3230
!(tmp_cs->state & MY_CS_HIDDEN) &&
3231
!(wild && wild[0] &&
3232
wild_case_compare(scs, tmp_cs->csname,wild)))
3234
const char *comment;
3235
restore_record(table, s->default_values);
3236
table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3237
table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3238
comment= tmp_cs->comment ? tmp_cs->comment : "";
3239
table->field[2]->store(comment, strlen(comment), scs);
3240
table->field[3]->store((int64_t) tmp_cs->mbmaxlen, true);
3241
if (schema_table_store_record(session, table))
3249
int fill_schema_collation(Session *session, TableList *tables, COND *cond __attribute__((unused)))
3252
const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3253
Table *table= tables->table;
3254
const CHARSET_INFO * const scs= system_charset_info;
3255
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3258
const CHARSET_INFO *tmp_cs= cs[0];
3259
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3260
(tmp_cs->state & MY_CS_HIDDEN) ||
3261
!(tmp_cs->state & MY_CS_PRIMARY))
3263
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3265
const CHARSET_INFO *tmp_cl= cl[0];
3266
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3267
!my_charset_same(tmp_cs, tmp_cl))
3269
if (!(wild && wild[0] &&
3270
wild_case_compare(scs, tmp_cl->name,wild)))
3272
const char *tmp_buff;
3273
restore_record(table, s->default_values);
3274
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3275
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3276
table->field[2]->store((int64_t) tmp_cl->number, true);
3277
tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
3278
table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
3279
tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
3280
table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
3281
table->field[5]->store((int64_t) tmp_cl->strxfrm_multiply, true);
3282
if (schema_table_store_record(session, table))
3291
int fill_schema_coll_charset_app(Session *session, TableList *tables, COND *cond __attribute__((unused)))
3294
Table *table= tables->table;
3295
const CHARSET_INFO * const scs= system_charset_info;
3296
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3299
const CHARSET_INFO *tmp_cs= cs[0];
3300
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3301
!(tmp_cs->state & MY_CS_PRIMARY))
3303
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3305
const CHARSET_INFO *tmp_cl= cl[0];
3306
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3307
!my_charset_same(tmp_cs,tmp_cl))
3309
restore_record(table, s->default_values);
3310
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3311
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3312
if (schema_table_store_record(session, table))
3320
static int get_schema_stat_record(Session *session, TableList *tables,
3321
Table *table, bool res,
3322
LEX_STRING *db_name,
3323
LEX_STRING *table_name)
3325
const CHARSET_INFO * const cs= system_charset_info;
3328
if (session->lex->sql_command != SQLCOM_SHOW_KEYS)
3331
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
3332
rather than in SHOW KEYS
3334
if (session->is_error())
3335
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3336
session->main_da.sql_errno(), session->main_da.message());
3337
session->clear_error();
3344
Table *show_table= tables->table;
3345
KEY *key_info=show_table->s->key_info;
3346
if (show_table->file)
3347
show_table->file->info(HA_STATUS_VARIABLE |
3350
for (uint32_t i=0 ; i < show_table->s->keys ; i++,key_info++)
3352
KEY_PART_INFO *key_part= key_info->key_part;
3354
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
3356
restore_record(table, s->default_values);
3357
table->field[1]->store(db_name->str, db_name->length, cs);
3358
table->field[2]->store(table_name->str, table_name->length, cs);
3359
table->field[3]->store((int64_t) ((key_info->flags &
3360
HA_NOSAME) ? 0 : 1), true);
3361
table->field[4]->store(db_name->str, db_name->length, cs);
3362
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
3363
table->field[6]->store((int64_t) (j+1), true);
3364
str=(key_part->field ? key_part->field->field_name :
3366
table->field[7]->store(str, strlen(str), cs);
3367
if (show_table->file)
3369
if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
3371
table->field[8]->store(((key_part->key_part_flag &
3374
table->field[8]->set_notnull();
3376
KEY *key=show_table->key_info+i;
3377
if (key->rec_per_key[j])
3379
ha_rows records=(show_table->file->stats.records /
3380
key->rec_per_key[j]);
3381
table->field[9]->store((int64_t) records, true);
3382
table->field[9]->set_notnull();
3384
str= show_table->file->index_type(i);
3385
table->field[13]->store(str, strlen(str), cs);
3387
if ((key_part->field &&
3389
show_table->s->field[key_part->fieldnr-1]->key_length()))
3391
table->field[10]->store((int64_t) key_part->length /
3392
key_part->field->charset()->mbmaxlen, true);
3393
table->field[10]->set_notnull();
3395
uint32_t flags= key_part->field ? key_part->field->flags : 0;
3396
const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3397
table->field[12]->store(pos, strlen(pos), cs);
3398
if (!show_table->s->keys_in_use.is_set(i))
3399
table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3401
table->field[14]->store("", 0, cs);
3402
table->field[14]->set_notnull();
3403
assert(test(key_info->flags & HA_USES_COMMENT) ==
3404
(key_info->comment.length > 0));
3405
if (key_info->flags & HA_USES_COMMENT)
3406
table->field[15]->store(key_info->comment.str,
3407
key_info->comment.length, cs);
3408
if (schema_table_store_record(session, table))
3417
bool store_constraints(Session *session, Table *table, LEX_STRING *db_name,
3418
LEX_STRING *table_name, const char *key_name,
3419
uint32_t key_len, const char *con_type, uint32_t con_len)
3421
const CHARSET_INFO * const cs= system_charset_info;
3422
restore_record(table, s->default_values);
3423
table->field[1]->store(db_name->str, db_name->length, cs);
3424
table->field[2]->store(key_name, key_len, cs);
3425
table->field[3]->store(db_name->str, db_name->length, cs);
3426
table->field[4]->store(table_name->str, table_name->length, cs);
3427
table->field[5]->store(con_type, con_len, cs);
3428
return schema_table_store_record(session, table);
3432
static int get_schema_constraints_record(Session *session, TableList *tables,
3433
Table *table, bool res,
3434
LEX_STRING *db_name,
3435
LEX_STRING *table_name)
3439
if (session->is_error())
3440
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3441
session->main_da.sql_errno(), session->main_da.message());
3442
session->clear_error();
3447
List<FOREIGN_KEY_INFO> f_key_list;
3448
Table *show_table= tables->table;
3449
KEY *key_info=show_table->key_info;
3450
uint32_t primary_key= show_table->s->primary_key;
3451
show_table->file->info(HA_STATUS_VARIABLE |
3454
for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3456
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3459
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
3461
if (store_constraints(session, table, db_name, table_name, key_info->name,
3462
strlen(key_info->name),
3463
STRING_WITH_LEN("PRIMARY KEY")))
3466
else if (key_info->flags & HA_NOSAME)
3468
if (store_constraints(session, table, db_name, table_name, key_info->name,
3469
strlen(key_info->name),
3470
STRING_WITH_LEN("UNIQUE")))
3475
show_table->file->get_foreign_key_list(session, &f_key_list);
3476
FOREIGN_KEY_INFO *f_key_info;
3477
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3478
while ((f_key_info=it++))
3480
if (store_constraints(session, table, db_name, table_name,
3481
f_key_info->forein_id->str,
3482
strlen(f_key_info->forein_id->str),
3491
void store_key_column_usage(Table *table, LEX_STRING *db_name,
3492
LEX_STRING *table_name, const char *key_name,
3493
uint32_t key_len, const char *con_type, uint32_t con_len,
3496
const CHARSET_INFO * const cs= system_charset_info;
3497
table->field[1]->store(db_name->str, db_name->length, cs);
3498
table->field[2]->store(key_name, key_len, cs);
3499
table->field[4]->store(db_name->str, db_name->length, cs);
3500
table->field[5]->store(table_name->str, table_name->length, cs);
3501
table->field[6]->store(con_type, con_len, cs);
3502
table->field[7]->store((int64_t) idx, true);
3506
static int get_schema_key_column_usage_record(Session *session,
3508
Table *table, bool res,
3509
LEX_STRING *db_name,
3510
LEX_STRING *table_name)
3514
if (session->is_error())
3515
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3516
session->main_da.sql_errno(), session->main_da.message());
3517
session->clear_error();
3522
List<FOREIGN_KEY_INFO> f_key_list;
3523
Table *show_table= tables->table;
3524
KEY *key_info=show_table->key_info;
3525
uint32_t primary_key= show_table->s->primary_key;
3526
show_table->file->info(HA_STATUS_VARIABLE |
3529
for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3531
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3534
KEY_PART_INFO *key_part= key_info->key_part;
3535
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
3537
if (key_part->field)
3540
restore_record(table, s->default_values);
3541
store_key_column_usage(table, db_name, table_name,
3543
strlen(key_info->name),
3544
key_part->field->field_name,
3545
strlen(key_part->field->field_name),
3547
if (schema_table_store_record(session, table))
3553
show_table->file->get_foreign_key_list(session, &f_key_list);
3554
FOREIGN_KEY_INFO *f_key_info;
3555
List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
3556
while ((f_key_info= fkey_it++))
3560
List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
3561
it1(f_key_info->referenced_fields);
3563
while ((f_info= it++))
3567
restore_record(table, s->default_values);
3568
store_key_column_usage(table, db_name, table_name,
3569
f_key_info->forein_id->str,
3570
f_key_info->forein_id->length,
3571
f_info->str, f_info->length,
3573
table->field[8]->store((int64_t) f_idx, true);
3574
table->field[8]->set_notnull();
3575
table->field[9]->store(f_key_info->referenced_db->str,
3576
f_key_info->referenced_db->length,
3577
system_charset_info);
3578
table->field[9]->set_notnull();
3579
table->field[10]->store(f_key_info->referenced_table->str,
3580
f_key_info->referenced_table->length,
3581
system_charset_info);
3582
table->field[10]->set_notnull();
3583
table->field[11]->store(r_info->str, r_info->length,
3584
system_charset_info);
3585
table->field[11]->set_notnull();
3586
if (schema_table_store_record(session, table))
3595
int fill_open_tables(Session *session, TableList *tables, COND *cond __attribute__((unused)))
3597
const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3598
Table *table= tables->table;
3599
const CHARSET_INFO * const cs= system_charset_info;
3600
OPEN_TableList *open_list;
3601
if (!(open_list=list_open_tables(session,session->lex->select_lex.db, wild))
3602
&& session->is_fatal_error)
3605
for (; open_list ; open_list=open_list->next)
3607
restore_record(table, s->default_values);
3608
table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3609
table->field[1]->store(open_list->table, strlen(open_list->table), cs);
3610
table->field[2]->store((int64_t) open_list->in_use, true);
3611
table->field[3]->store((int64_t) open_list->locked, true);
3612
if (schema_table_store_record(session, table))
3619
int fill_variables(Session *session, TableList *tables, COND *cond __attribute__((unused)))
3622
LEX *lex= session->lex;
3623
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3624
enum enum_schema_tables schema_table_idx=
3625
get_schema_table_idx(tables->schema_table);
3626
enum enum_var_type option_type= OPT_SESSION;
3627
bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
3628
bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
3630
if (lex->option_type == OPT_GLOBAL ||
3631
schema_table_idx == SCH_GLOBAL_VARIABLES)
3632
option_type= OPT_GLOBAL;
3634
rw_rdlock(&LOCK_system_variables_hash);
3635
res= show_status_array(session, wild, enumerate_sys_vars(session, sorted_vars),
3636
option_type, NULL, "", tables->table, upper_case_names);
3637
rw_unlock(&LOCK_system_variables_hash);
3642
int fill_status(Session *session, TableList *tables, COND *cond __attribute__((unused)))
3644
LEX *lex= session->lex;
3645
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3647
STATUS_VAR *tmp1, tmp;
3648
enum enum_schema_tables schema_table_idx=
3649
get_schema_table_idx(tables->schema_table);
3650
enum enum_var_type option_type;
3651
bool upper_case_names= (schema_table_idx != SCH_STATUS);
3653
if (schema_table_idx == SCH_STATUS)
3655
option_type= lex->option_type;
3656
if (option_type == OPT_GLOBAL)
3659
tmp1= session->initial_status_var;
3661
else if (schema_table_idx == SCH_GLOBAL_STATUS)
3663
option_type= OPT_GLOBAL;
3668
option_type= OPT_SESSION;
3669
tmp1= &session->status_var;
3672
pthread_mutex_lock(&LOCK_status);
3673
if (option_type == OPT_GLOBAL)
3674
calc_sum_of_all_status(&tmp);
3675
res= show_status_array(session, wild,
3676
(SHOW_VAR *)all_status_vars.buffer,
3677
option_type, tmp1, "", tables->table,
3679
pthread_mutex_unlock(&LOCK_status);
3685
Fill and store records into I_S.referential_constraints table
3688
get_referential_constraints_record()
3689
session thread handle
3690
tables table list struct(processed table)
3692
res 1 means the error during opening of the processed table
3693
0 means processed table is opened without error
3695
file_name table name
3703
get_referential_constraints_record(Session *session, TableList *tables,
3704
Table *table, bool res,
3705
LEX_STRING *db_name, LEX_STRING *table_name)
3707
const CHARSET_INFO * const cs= system_charset_info;
3711
if (session->is_error())
3712
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3713
session->main_da.sql_errno(), session->main_da.message());
3714
session->clear_error();
3719
List<FOREIGN_KEY_INFO> f_key_list;
3720
Table *show_table= tables->table;
3721
show_table->file->info(HA_STATUS_VARIABLE |
3725
show_table->file->get_foreign_key_list(session, &f_key_list);
3726
FOREIGN_KEY_INFO *f_key_info;
3727
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3728
while ((f_key_info= it++))
3730
restore_record(table, s->default_values);
3731
table->field[1]->store(db_name->str, db_name->length, cs);
3732
table->field[9]->store(table_name->str, table_name->length, cs);
3733
table->field[2]->store(f_key_info->forein_id->str,
3734
f_key_info->forein_id->length, cs);
3735
table->field[4]->store(f_key_info->referenced_db->str,
3736
f_key_info->referenced_db->length, cs);
3737
table->field[10]->store(f_key_info->referenced_table->str,
3738
f_key_info->referenced_table->length, cs);
3739
if (f_key_info->referenced_key_name)
3741
table->field[5]->store(f_key_info->referenced_key_name->str,
3742
f_key_info->referenced_key_name->length, cs);
3743
table->field[5]->set_notnull();
3746
table->field[5]->set_null();
3747
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3748
table->field[7]->store(f_key_info->update_method->str,
3749
f_key_info->update_method->length, cs);
3750
table->field[8]->store(f_key_info->delete_method->str,
3751
f_key_info->delete_method->length, cs);
3752
if (schema_table_store_record(session, table))
3760
struct schema_table_ref
3762
const char *table_name;
3763
ST_SCHEMA_TABLE *schema_table;
3768
Find schema_tables elment by name
3771
find_schema_table_in_plugin()
3772
session thread handler
3774
table_name table name
3778
1 found the schema table
3780
static bool find_schema_table_in_plugin(Session *session __attribute__((unused)),
3784
schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
3785
const char* table_name= p_schema_table->table_name;
3786
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
3788
if (!my_strcasecmp(system_charset_info,
3789
schema_table->table_name,
3791
p_schema_table->schema_table= schema_table;
3800
Find schema_tables elment by name
3804
session thread handler
3805
table_name table name
3809
# pointer to 'schema_tables' element
3812
ST_SCHEMA_TABLE *find_schema_table(Session *session, const char* table_name)
3814
schema_table_ref schema_table_a;
3815
ST_SCHEMA_TABLE *schema_table= schema_tables;
3817
for (; schema_table->table_name; schema_table++)
3819
if (!my_strcasecmp(system_charset_info,
3820
schema_table->table_name,
3822
return(schema_table);
3825
schema_table_a.table_name= table_name;
3826
if (plugin_foreach(session, find_schema_table_in_plugin,
3827
DRIZZLE_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
3828
return(schema_table_a.schema_table);
3834
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
3836
return &schema_tables[schema_table_idx];
3841
Create information_schema table using schema_table data.
3846
session thread handler
3848
@param table_list Used to pass I_S table information(fields info, tables
3849
parameters etc) and table name.
3851
@retval \# Pointer to created table
3852
@retval NULL Can't create table
3855
Table *create_schema_table(Session *session, TableList *table_list)
3860
List<Item> field_list;
3861
ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
3862
ST_FIELD_INFO *fields_info= schema_table->fields_info;
3863
const CHARSET_INFO * const cs= system_charset_info;
3865
for (; fields_info->field_name; fields_info++)
3867
switch (fields_info->field_type) {
3868
case DRIZZLE_TYPE_LONG:
3869
case DRIZZLE_TYPE_LONGLONG:
3870
if (!(item= new Item_return_int(fields_info->field_name,
3871
fields_info->field_length,
3872
fields_info->field_type,
3873
fields_info->value)))
3877
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3879
case DRIZZLE_TYPE_NEWDATE:
3880
case DRIZZLE_TYPE_TIME:
3881
case DRIZZLE_TYPE_TIMESTAMP:
3882
case DRIZZLE_TYPE_DATETIME:
3883
if (!(item=new Item_return_date_time(fields_info->field_name,
3884
fields_info->field_type)))
3889
case DRIZZLE_TYPE_DOUBLE:
3890
if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
3891
fields_info->field_length)) == NULL)
3894
case DRIZZLE_TYPE_NEWDECIMAL:
3895
if (!(item= new Item_decimal((int64_t) fields_info->value, false)))
3899
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3900
item->decimals= fields_info->field_length%10;
3901
item->max_length= (fields_info->field_length/100)%100;
3902
if (item->unsigned_flag == 0)
3903
item->max_length+= 1;
3904
if (item->decimals > 0)
3905
item->max_length+= 1;
3906
item->set_name(fields_info->field_name,
3907
strlen(fields_info->field_name), cs);
3909
case DRIZZLE_TYPE_BLOB:
3910
if (!(item= new Item_blob(fields_info->field_name,
3911
fields_info->field_length)))
3917
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
3921
item->set_name(fields_info->field_name,
3922
strlen(fields_info->field_name), cs);
3925
field_list.push_back(item);
3926
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
3929
TMP_TABLE_PARAM *tmp_table_param =
3930
(TMP_TABLE_PARAM*) (session->alloc(sizeof(TMP_TABLE_PARAM)));
3931
tmp_table_param->init();
3932
tmp_table_param->table_charset= cs;
3933
tmp_table_param->field_count= field_count;
3934
tmp_table_param->schema_table= 1;
3935
SELECT_LEX *select_lex= session->lex->current_select;
3936
if (!(table= create_tmp_table(session, tmp_table_param,
3937
field_list, (order_st*) 0, 0, 0,
3938
(select_lex->options | session->options |
3939
TMP_TABLE_ALL_COLUMNS),
3940
HA_POS_ERROR, table_list->alias)))
3942
my_bitmap_map* bitmaps=
3943
(my_bitmap_map*) session->alloc(bitmap_buffer_size(field_count));
3944
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
3946
table->read_set= &table->def_read_set;
3947
bitmap_clear_all(table->read_set);
3948
table_list->schema_table_param= tmp_table_param;
3954
For old SHOW compatibility. It is used when
3955
old SHOW doesn't have generated column names
3956
Make list of fields for SHOW
3960
session thread handler
3961
schema_table pointer to 'schema_tables' element
3968
int make_old_format(Session *session, ST_SCHEMA_TABLE *schema_table)
3970
ST_FIELD_INFO *field_info= schema_table->fields_info;
3971
Name_resolution_context *context= &session->lex->select_lex.context;
3972
for (; field_info->field_name; field_info++)
3974
if (field_info->old_name)
3976
Item_field *field= new Item_field(context,
3977
NULL, NULL, field_info->field_name);
3980
field->set_name(field_info->old_name,
3981
strlen(field_info->old_name),
3982
system_charset_info);
3983
if (add_item_to_list(session, field))
3992
int make_schemata_old_format(Session *session, ST_SCHEMA_TABLE *schema_table)
3995
LEX *lex= session->lex;
3996
SELECT_LEX *sel= lex->current_select;
3997
Name_resolution_context *context= &sel->context;
3999
if (!sel->item_list.elements)
4001
ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
4002
String buffer(tmp,sizeof(tmp), system_charset_info);
4003
Item_field *field= new Item_field(context,
4004
NULL, NULL, field_info->field_name);
4005
if (!field || add_item_to_list(session, field))
4008
buffer.append(field_info->old_name);
4009
if (lex->wild && lex->wild->ptr())
4011
buffer.append(STRING_WITH_LEN(" ("));
4012
buffer.append(lex->wild->ptr());
4015
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4021
int make_table_names_old_format(Session *session, ST_SCHEMA_TABLE *schema_table)
4024
String buffer(tmp,sizeof(tmp), session->charset());
4025
LEX *lex= session->lex;
4026
Name_resolution_context *context= &lex->select_lex.context;
4028
ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
4030
buffer.append(field_info->old_name);
4031
buffer.append(lex->select_lex.db);
4032
if (lex->wild && lex->wild->ptr())
4034
buffer.append(STRING_WITH_LEN(" ("));
4035
buffer.append(lex->wild->ptr());
4038
Item_field *field= new Item_field(context,
4039
NULL, NULL, field_info->field_name);
4040
if (add_item_to_list(session, field))
4042
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4043
if (session->lex->verbose)
4045
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4046
field_info= &schema_table->fields_info[3];
4047
field= new Item_field(context, NULL, NULL, field_info->field_name);
4048
if (add_item_to_list(session, field))
4050
field->set_name(field_info->old_name, strlen(field_info->old_name),
4051
system_charset_info);
4057
int make_columns_old_format(Session *session, ST_SCHEMA_TABLE *schema_table)
4059
int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
4060
int *field_num= fields_arr;
4061
ST_FIELD_INFO *field_info;
4062
Name_resolution_context *context= &session->lex->select_lex.context;
4064
for (; *field_num >= 0; field_num++)
4066
field_info= &schema_table->fields_info[*field_num];
4067
if (!session->lex->verbose && (*field_num == 13 ||
4071
Item_field *field= new Item_field(context,
4072
NULL, NULL, field_info->field_name);
4075
field->set_name(field_info->old_name,
4076
strlen(field_info->old_name),
4077
system_charset_info);
4078
if (add_item_to_list(session, field))
4086
int make_character_sets_old_format(Session *session, ST_SCHEMA_TABLE *schema_table)
4088
int fields_arr[]= {0, 2, 1, 3, -1};
4089
int *field_num= fields_arr;
4090
ST_FIELD_INFO *field_info;
4091
Name_resolution_context *context= &session->lex->select_lex.context;
4093
for (; *field_num >= 0; field_num++)
4095
field_info= &schema_table->fields_info[*field_num];
4096
Item_field *field= new Item_field(context,
4097
NULL, NULL, field_info->field_name);
4100
field->set_name(field_info->old_name,
4101
strlen(field_info->old_name),
4102
system_charset_info);
4103
if (add_item_to_list(session, field))
4112
Create information_schema table
4115
mysql_schema_table()
4116
session thread handler
4118
table_list pointer to table_list
4125
int mysql_schema_table(Session *session, LEX *lex, TableList *table_list)
4128
if (!(table= table_list->schema_table->create_table(session, table_list)))
4130
table->s->tmp_table= SYSTEM_TMP_TABLE;
4132
This test is necessary to make
4133
case insensitive file systems +
4134
upper case table names(information schema tables) +
4138
if (table_list->schema_table_name)
4139
table->alias_name_used= my_strcasecmp(table_alias_charset,
4140
table_list->schema_table_name,
4142
table_list->table_name= table->s->table_name.str;
4143
table_list->table_name_length= table->s->table_name.length;
4144
table_list->table= table;
4145
table->next= session->derived_tables;
4146
session->derived_tables= table;
4147
table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
4149
if (table_list->schema_table_reformed) // show command
4151
SELECT_LEX *sel= lex->current_select;
4153
Field_translator *transl, *org_transl;
4155
if (table_list->field_translation)
4157
Field_translator *end= table_list->field_translation_end;
4158
for (transl= table_list->field_translation; transl < end; transl++)
4160
if (!transl->item->fixed &&
4161
transl->item->fix_fields(session, &transl->item))
4166
List_iterator_fast<Item> it(sel->item_list);
4168
(Field_translator*)(session->alloc(sel->item_list.elements *
4169
sizeof(Field_translator)))))
4173
for (org_transl= transl; (item= it++); transl++)
4176
transl->name= item->name;
4177
if (!item->fixed && item->fix_fields(session, &transl->item))
4182
table_list->field_translation= org_transl;
4183
table_list->field_translation_end= transl;
4191
Generate select from information_schema table
4194
make_schema_select()
4195
session thread handler
4196
sel pointer to SELECT_LEX
4197
schema_table_idx index of 'schema_tables' element
4204
int make_schema_select(Session *session, SELECT_LEX *sel,
4205
enum enum_schema_tables schema_table_idx)
4207
ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
4208
LEX_STRING db, table;
4210
We have to make non const db_name & table_name
4211
because of lower_case_table_names
4213
session->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str,
4214
INFORMATION_SCHEMA_NAME.length, 0);
4215
session->make_lex_string(&table, schema_table->table_name,
4216
strlen(schema_table->table_name), 0);
4217
if (schema_table->old_format(session, schema_table) || /* Handle old syntax */
4218
!sel->add_table_to_list(session, new Table_ident(session, db, table, 0),
4228
Fill temporary schema tables before SELECT
4231
get_schema_tables_result()
4232
join join which use schema tables
4233
executed_place place where I_S table processed
4240
bool get_schema_tables_result(JOIN *join,
4241
enum enum_schema_table_state executed_place)
4243
JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
4244
Session *session= join->session;
4245
LEX *lex= session->lex;
4248
session->no_warnings_for_error= 1;
4249
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
4251
if (!tab->table || !tab->table->pos_in_table_list)
4254
TableList *table_list= tab->table->pos_in_table_list;
4255
if (table_list->schema_table)
4257
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
4258
lex->current_select->master_unit()->item);
4261
/* skip I_S optimizations specific to get_all_tables */
4262
if (session->lex->describe &&
4263
(table_list->schema_table->fill_table != get_all_tables))
4267
If schema table is already processed and
4268
the statement is not a subselect then
4269
we don't need to fill this table again.
4270
If schema table is already processed and
4271
schema_table_state != executed_place then
4272
table is already processed and
4273
we should skip second data processing.
4275
if (table_list->schema_table_state &&
4276
(!is_subselect || table_list->schema_table_state != executed_place))
4280
if table is used in a subselect and
4281
table has been processed earlier with the same
4282
'executed_place' value then we should refresh the table.
4284
if (table_list->schema_table_state && is_subselect)
4286
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
4287
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
4288
table_list->table->file->ha_delete_all_rows();
4289
free_io_cache(table_list->table);
4290
filesort_free_buffers(table_list->table,1);
4291
table_list->table->null_row= 0;
4294
table_list->table->file->stats.records= 0;
4296
if (table_list->schema_table->fill_table(session, table_list,
4301
tab->read_record.file= table_list->table->file;
4302
table_list->schema_table_state= executed_place;
4305
tab->read_record.file= table_list->table->file;
4306
table_list->schema_table_state= executed_place;
4309
session->no_warnings_for_error= 0;
4313
ST_FIELD_INFO schema_fields_info[]=
4315
{"CATALOG_NAME", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4316
{"SCHEMA_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4318
{"DEFAULT_CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4320
{"DEFAULT_COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4321
{"SQL_PATH", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4322
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4326
ST_FIELD_INFO tables_fields_info[]=
4328
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4329
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4330
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4332
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4333
{"ENGINE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Engine", OPEN_FRM_ONLY},
4334
{"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4335
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
4336
{"ROW_FORMAT", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Row_format", OPEN_FULL_TABLE},
4337
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4338
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
4339
{"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4340
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
4341
{"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4342
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
4343
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4344
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
4345
{"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4346
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
4347
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4348
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
4349
{"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG, 0,
4350
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
4351
{"CREATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4352
{"UPDATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4353
{"CHECK_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
4354
{"TABLE_COLLATION", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4355
{"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4356
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
4357
{"CREATE_OPTIONS", 255, DRIZZLE_TYPE_VARCHAR, 0, 1, "Create_options",
4359
{"TABLE_COMMENT", TABLE_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4360
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4364
ST_FIELD_INFO columns_fields_info[]=
4366
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4367
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4368
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4369
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Field",
4371
{"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4372
MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
4373
{"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, DRIZZLE_TYPE_VARCHAR, 0,
4374
1, "Default", OPEN_FRM_ONLY},
4375
{"IS_NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4376
{"DATA_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4377
{"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4378
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4379
{"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4380
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4381
{"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4382
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4383
{"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4384
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4385
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4386
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4387
{"COLUMN_TYPE", 65535, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", OPEN_FRM_ONLY},
4388
{"COLUMN_KEY", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key", OPEN_FRM_ONLY},
4389
{"EXTRA", 27, DRIZZLE_TYPE_VARCHAR, 0, 0, "Extra", OPEN_FRM_ONLY},
4390
{"PRIVILEGES", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Privileges", OPEN_FRM_ONLY},
4391
{"COLUMN_COMMENT", COLUMN_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4392
{"STORAGE", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Storage", OPEN_FRM_ONLY},
4393
{"FORMAT", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Format", OPEN_FRM_ONLY},
4394
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4398
ST_FIELD_INFO charsets_fields_info[]=
4400
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4402
{"DEFAULT_COLLATE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default collation",
4404
{"DESCRIPTION", 60, DRIZZLE_TYPE_VARCHAR, 0, 0, "Description",
4406
{"MAXLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
4407
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4411
ST_FIELD_INFO collation_fields_info[]=
4413
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Collation", SKIP_OPEN_TABLE},
4414
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4416
{"ID", MY_INT32_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id",
4418
{"IS_DEFAULT", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default", SKIP_OPEN_TABLE},
4419
{"IS_COMPILED", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Compiled", SKIP_OPEN_TABLE},
4420
{"SORTLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
4421
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4426
ST_FIELD_INFO coll_charset_app_fields_info[]=
4428
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4429
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4430
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4434
ST_FIELD_INFO stat_fields_info[]=
4436
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4437
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4438
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", OPEN_FRM_ONLY},
4439
{"NON_UNIQUE", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
4440
{"INDEX_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4441
{"INDEX_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key_name",
4443
{"SEQ_IN_INDEX", 2, DRIZZLE_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
4444
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Column_name",
4446
{"COLLATION", 1, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4447
{"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 1,
4448
"Cardinality", OPEN_FULL_TABLE},
4449
{"SUB_PART", 3, DRIZZLE_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
4450
{"PACKED", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Packed", OPEN_FRM_ONLY},
4451
{"NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4452
{"INDEX_TYPE", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_type", OPEN_FULL_TABLE},
4453
{"COMMENT", 16, DRIZZLE_TYPE_VARCHAR, 0, 1, "Comment", OPEN_FRM_ONLY},
4454
{"INDEX_COMMENT", INDEX_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_Comment", OPEN_FRM_ONLY},
4455
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4459
ST_FIELD_INFO table_constraints_fields_info[]=
4461
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4462
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4464
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4466
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4467
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4468
{"CONSTRAINT_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4470
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4474
ST_FIELD_INFO key_column_usage_fields_info[]=
4476
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4477
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4479
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4481
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4482
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4483
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4484
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4485
{"ORDINAL_POSITION", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
4486
{"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 1, 0,
4488
{"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4490
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4492
{"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4494
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4498
ST_FIELD_INFO table_names_fields_info[]=
4500
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4501
{"TABLE_SCHEMA",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4502
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Tables_in_",
4504
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table_type",
4506
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4510
ST_FIELD_INFO open_tables_fields_info[]=
4512
{"Database", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4514
{"Table",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", SKIP_OPEN_TABLE},
4515
{"In_use", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
4516
{"Name_locked", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
4517
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4521
ST_FIELD_INFO variables_fields_info[]=
4523
{"VARIABLE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Variable_name",
4525
{"VARIABLE_VALUE", 16300, DRIZZLE_TYPE_VARCHAR, 0, 1, "Value", SKIP_OPEN_TABLE},
4526
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4530
ST_FIELD_INFO processlist_fields_info[]=
4532
{"ID", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
4533
{"USER", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "User", SKIP_OPEN_TABLE},
4534
{"HOST", LIST_PROCESS_HOST_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Host",
4536
{"DB", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Db", SKIP_OPEN_TABLE},
4537
{"COMMAND", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Command", SKIP_OPEN_TABLE},
4538
{"TIME", 7, DRIZZLE_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
4539
{"STATE", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "State", SKIP_OPEN_TABLE},
4540
{"INFO", PROCESS_LIST_INFO_WIDTH, DRIZZLE_TYPE_VARCHAR, 0, 1, "Info",
4542
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4546
ST_FIELD_INFO plugin_fields_info[]=
4548
{"PLUGIN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4550
{"PLUGIN_VERSION", 20, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4551
{"PLUGIN_STATUS", 10, DRIZZLE_TYPE_VARCHAR, 0, 0, "Status", SKIP_OPEN_TABLE},
4552
{"PLUGIN_TYPE", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", SKIP_OPEN_TABLE},
4553
{"PLUGIN_LIBRARY", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Library",
4555
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4556
{"PLUGIN_DESCRIPTION", 65535, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4557
{"PLUGIN_LICENSE", 80, DRIZZLE_TYPE_VARCHAR, 0, 1, "License", SKIP_OPEN_TABLE},
4558
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4561
ST_FIELD_INFO referential_constraints_fields_info[]=
4563
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4564
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4566
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4568
{"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4570
{"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4572
{"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0,
4573
MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
4574
{"MATCH_OPTION", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4575
{"UPDATE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4576
{"DELETE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4577
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4578
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4580
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4585
Description of ST_FIELD_INFO in table.h
4587
Make sure that the order of schema_tables and enum_schema_tables are the same.
4591
ST_SCHEMA_TABLE schema_tables[]=
4593
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
4594
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4595
{"COLLATIONS", collation_fields_info, create_schema_table,
4596
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4597
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4598
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4599
{"COLUMNS", columns_fields_info, create_schema_table,
4600
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
4601
OPTIMIZE_I_S_TABLE},
4602
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4603
fill_status, make_old_format, 0, -1, -1, 0, 0},
4604
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
4605
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4606
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
4607
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
4609
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
4610
fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
4611
{"PLUGINS", plugin_fields_info, create_schema_table,
4612
fill_plugins, make_old_format, 0, -1, -1, 0, 0},
4613
{"PROCESSLIST", processlist_fields_info, create_schema_table,
4614
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
4615
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
4616
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
4617
1, 9, 0, OPEN_TABLE_ONLY},
4618
{"SCHEMATA", schema_fields_info, create_schema_table,
4619
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
4620
{"SESSION_STATUS", variables_fields_info, create_schema_table,
4621
fill_status, make_old_format, 0, -1, -1, 0, 0},
4622
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4623
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4624
{"STATISTICS", stat_fields_info, create_schema_table,
4625
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4626
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4627
{"STATUS", variables_fields_info, create_schema_table, fill_status,
4628
make_old_format, 0, -1, -1, 1, 0},
4629
{"TABLES", tables_fields_info, create_schema_table,
4630
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4631
OPTIMIZE_I_S_TABLE},
4632
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4633
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
4634
{"TABLE_NAMES", table_names_fields_info, create_schema_table,
4635
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
4636
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
4637
make_old_format, 0, -1, -1, 1, 0},
4638
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
4642
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
4643
template class List_iterator_fast<char>;
4644
template class List<char>;
4647
int initialize_schema_table(st_plugin_int *plugin)
4649
ST_SCHEMA_TABLE *schema_table;
4651
if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
4652
MYF(MY_WME | MY_ZEROFILL))))
4654
/* Historical Requirement */
4655
plugin->data= schema_table; // shortcut for the future
4656
if (plugin->plugin->init)
4658
schema_table->create_table= create_schema_table;
4659
schema_table->old_format= make_old_format;
4660
schema_table->idx_field1= -1,
4661
schema_table->idx_field2= -1;
4663
/* Make the name available to the init() function. */
4664
schema_table->table_name= plugin->name.str;
4666
if (plugin->plugin->init(schema_table))
4668
sql_print_error(_("Plugin '%s' init function returned error."),
4673
/* Make sure the plugin name is not set inside the init() function. */
4674
schema_table->table_name= plugin->name.str;
4683
int finalize_schema_table(st_plugin_int *plugin)
4685
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
4687
if (schema_table && plugin->plugin->deinit)