146
} /* namespace drizzled */
501
/* Append directory name (if exists) to CREATE INFO */
503
static void append_directory(String *packet, const char *dir_type,
504
const char *filename)
508
uint32_t length= dirname_length(filename);
510
packet->append(dir_type);
511
packet->append(STRING_WITH_LEN(" DIRECTORY='"));
512
packet->append(filename, length);
513
packet->append('\'');
518
#define LIST_PROCESS_HOST_LEN 64
520
static bool get_field_default_value(Field *timestamp_field,
521
Field *field, String *def_value,
525
bool has_now_default;
528
We are using CURRENT_TIMESTAMP instead of NOW because it is
531
has_now_default= (timestamp_field == field &&
532
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
534
has_default= (field->type() != DRIZZLE_TYPE_BLOB &&
535
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
536
field->unireg_check != Field::NEXT_NUMBER);
538
def_value->length(0);
542
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
543
else if (!field->is_null())
544
{ // Not null by default
545
char tmp[MAX_FIELD_WIDTH];
546
String type(tmp, sizeof(tmp), field->charset());
547
field->val_str(&type);
551
uint32_t dummy_errors;
552
/* convert to system_charset_info == utf8 */
553
def_val.copy(type.ptr(), type.length(), field->charset(),
554
system_charset_info, &dummy_errors);
556
append_unescaped(def_value, def_val.ptr(), def_val.length());
558
def_value->append(def_val.ptr(), def_val.length());
561
def_value->append(STRING_WITH_LEN("''"));
563
else if (field->maybe_null() && quoted)
564
def_value->append(STRING_WITH_LEN("NULL")); // Null as default
572
Build a CREATE TABLE statement for a table.
576
table_list A list containing one table to write statement
578
packet Pointer to a string where statement will be
580
create_info_arg Pointer to create information that can be used
581
to tailor the format of the statement. Can be
582
NULL, in which case only SQL_MODE is considered
583
when building the statement.
586
Currently always return 0, but might return error code in the
593
int store_create_info(TableList *table_list, String *packet, HA_CREATE_INFO *create_info_arg)
595
List<Item> field_list;
596
char tmp[MAX_FIELD_WIDTH], *for_str, def_value_buf[MAX_FIELD_WIDTH];
599
String type(tmp, sizeof(tmp), system_charset_info);
600
String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
602
uint32_t primary_key;
604
Table *table= table_list->table;
605
handler *file= table->file;
606
TableShare *share= table->s;
607
HA_CREATE_INFO create_info;
608
bool show_table_options= false;
609
my_bitmap_map *old_map;
611
table->restoreRecordAsDefault(); // Get empty record
613
if (share->tmp_table)
614
packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
616
packet->append(STRING_WITH_LEN("CREATE TABLE "));
617
if (create_info_arg &&
618
(create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
619
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
620
if (table_list->schema_table)
621
alias= table_list->schema_table->table_name;
624
if (lower_case_table_names == 2)
627
alias= share->table_name.str;
629
packet->append_identifier(alias, strlen(alias));
630
packet->append(STRING_WITH_LEN(" (\n"));
632
We need this to get default values from the table
633
We have to restore the read_set if we are called from insert in case
634
of row based replication.
636
old_map= table->use_all_columns(table->read_set);
638
for (ptr=table->field ; (field= *ptr); ptr++)
640
uint32_t flags = field->flags;
642
if (ptr != table->field)
643
packet->append(STRING_WITH_LEN(",\n"));
645
packet->append(STRING_WITH_LEN(" "));
646
packet->append_identifier(field->field_name, strlen(field->field_name));
648
// check for surprises from the previous call to Field::sql_type()
649
if (type.ptr() != tmp)
650
type.set(tmp, sizeof(tmp), system_charset_info);
652
type.set_charset(system_charset_info);
654
field->sql_type(type);
655
packet->append(type.ptr(), type.length(), system_charset_info);
657
if (field->has_charset())
659
if (field->charset() != share->table_charset)
661
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
662
packet->append(field->charset()->csname);
666
For string types dump collation name only if
667
collation is not primary for the given charset
669
if (!(field->charset()->state & MY_CS_PRIMARY))
671
packet->append(STRING_WITH_LEN(" COLLATE "));
672
packet->append(field->charset()->name);
676
if (flags & NOT_NULL_FLAG)
677
packet->append(STRING_WITH_LEN(" NOT NULL"));
678
else if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
681
TIMESTAMP field require explicit NULL flag, because unlike
682
all other fields they are treated as NOT NULL by default.
684
packet->append(STRING_WITH_LEN(" NULL"));
688
Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
689
and about STORAGE (DISK or MEMORY).
691
enum column_format_type column_format= (enum column_format_type)
692
((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
695
packet->append(STRING_WITH_LEN(" /*!"));
696
packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
697
if (column_format == COLUMN_FORMAT_TYPE_FIXED)
698
packet->append(STRING_WITH_LEN(" FIXED */"));
700
packet->append(STRING_WITH_LEN(" DYNAMIC */"));
703
if (get_field_default_value(table->timestamp_field, field, &def_value, 1))
705
packet->append(STRING_WITH_LEN(" DEFAULT "));
706
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
709
if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
710
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
712
if (field->unireg_check == Field::NEXT_NUMBER)
713
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
715
if (field->comment.length)
717
packet->append(STRING_WITH_LEN(" COMMENT "));
718
append_unescaped(packet, field->comment.str, field->comment.length);
722
key_info= table->key_info;
723
memset(&create_info, 0, sizeof(create_info));
724
/* Allow update_create_info to update row type */
725
create_info.row_type= share->row_type;
726
file->update_create_info(&create_info);
727
primary_key= share->primary_key;
729
for (uint32_t i=0 ; i < share->keys ; i++,key_info++)
731
KEY_PART_INFO *key_part= key_info->key_part;
732
bool found_primary=0;
733
packet->append(STRING_WITH_LEN(",\n "));
735
if (i == primary_key && is_primary_key(key_info))
739
No space at end, because a space will be added after where the
740
identifier would go, but that is not added for primary key.
742
packet->append(STRING_WITH_LEN("PRIMARY KEY"));
744
else if (key_info->flags & HA_NOSAME)
745
packet->append(STRING_WITH_LEN("UNIQUE KEY "));
747
packet->append(STRING_WITH_LEN("KEY "));
750
packet->append_identifier(key_info->name, strlen(key_info->name));
752
packet->append(STRING_WITH_LEN(" ("));
754
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
760
packet->append_identifier(key_part->field->field_name,
761
strlen(key_part->field->field_name));
762
if (key_part->field &&
764
table->field[key_part->fieldnr-1]->key_length()))
767
buff.append(to_string((int32_t) key_part->length /
768
key_part->field->charset()->mbmaxlen));
770
packet->append(buff.c_str(), buff.length());
774
store_key_options(packet, table, key_info);
778
Get possible foreign key definitions stored in InnoDB and append them
779
to the CREATE TABLE statement
782
if ((for_str= file->get_foreign_key_create_info()))
784
packet->append(for_str, strlen(for_str));
785
file->free_foreign_key_create_info(for_str);
788
packet->append(STRING_WITH_LEN("\n)"));
790
show_table_options= true;
792
Get possible table space definitions and append them
793
to the CREATE TABLE statement
798
THEN add ENGINE only if it was used when creating the table
800
if (!create_info_arg ||
801
(create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
803
packet->append(STRING_WITH_LEN(" ENGINE="));
804
packet->append(file->engine->getName().c_str());
808
Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
809
and NEXT_ID > 1 (the default). We must not print the clause
810
for engines that do not support this as it would break the
811
import of dumps, but as of this writing, the test for whether
812
AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
813
is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
814
Because of that, we do not explicitly test for the feature,
815
but may extrapolate its existence from that of an AUTO_INCREMENT column.
818
if (create_info.auto_increment_value > 1)
820
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
821
buff= to_string(create_info.auto_increment_value);
822
packet->append(buff.c_str(), buff.length());
827
packet->append(STRING_WITH_LEN(" MIN_ROWS="));
828
buff= to_string(share->min_rows);
829
packet->append(buff.c_str(), buff.length());
832
if (share->max_rows && !table_list->schema_table)
834
packet->append(STRING_WITH_LEN(" MAX_ROWS="));
835
buff= to_string(share->max_rows);
836
packet->append(buff.c_str(), buff.length());
839
if (share->avg_row_length)
841
packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
842
buff= to_string(share->avg_row_length);
843
packet->append(buff.c_str(), buff.length());
846
if (share->db_create_options & HA_OPTION_PACK_KEYS)
847
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
848
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
849
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
850
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
851
if (share->db_create_options & HA_OPTION_CHECKSUM)
852
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
853
if (share->page_checksum != HA_CHOICE_UNDEF)
855
packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
856
packet->append(ha_choice_values[(uint32_t) share->page_checksum], 1);
858
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
859
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
860
if (create_info.row_type != ROW_TYPE_DEFAULT)
862
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
863
packet->append(ha_row_type[(uint32_t) create_info.row_type]);
865
if (table->s->key_block_size)
867
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
868
buff= to_string(table->s->key_block_size);
869
packet->append(buff.c_str(), buff.length());
871
if (share->block_size)
873
packet->append(STRING_WITH_LEN(" BLOCK_SIZE="));
874
buff= to_string(share->block_size);
875
packet->append(buff.c_str(), buff.length());
877
table->file->append_create_info(packet);
878
if (share->comment.length)
880
packet->append(STRING_WITH_LEN(" COMMENT="));
881
append_unescaped(packet, share->comment.str, share->comment.length);
883
if (share->connect_string.length)
885
packet->append(STRING_WITH_LEN(" CONNECTION="));
886
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
888
append_directory(packet, "DATA", create_info.data_file_name);
889
append_directory(packet, "INDEX", create_info.index_file_name);
891
table->restore_column_map(old_map);
896
Get a CREATE statement for a given database.
898
The database is identified by its name, passed as @c dbname parameter.
899
The name should be encoded using the system character set (UTF8 currently).
901
Resulting statement is stored in the string pointed by @c buffer. The string
902
is emptied first and its character set is set to the system character set.
904
If HA_LEX_CREATE_IF_NOT_EXISTS flag is set in @c create_info->options, then
905
the resulting CREATE statement contains "IF NOT EXISTS" clause. Other flags
906
in @c create_options are ignored.
908
@param session The current thread instance.
909
@param dbname The name of the database.
910
@param buffer A String instance where the statement is stored.
911
@param create_info If not NULL, the options member influences the resulting
914
@returns true if errors are detected, false otherwise.
917
bool store_db_create_info(const char *dbname, String *buffer, HA_CREATE_INFO *create_info)
919
HA_CREATE_INFO create;
920
uint32_t create_options = create_info ? create_info->options : 0;
922
if (!my_strcasecmp(system_charset_info, dbname,
923
INFORMATION_SCHEMA_NAME.c_str()))
925
dbname= INFORMATION_SCHEMA_NAME.c_str();
926
create.default_table_charset= system_charset_info;
930
if (check_db_dir_existence(dbname))
933
load_db_opt_by_name(dbname, &create);
938
buffer->set_charset(system_charset_info);
939
buffer->append(STRING_WITH_LEN("CREATE DATABASE "));
941
if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
942
buffer->append(STRING_WITH_LEN("IF NOT EXISTS "));
944
buffer->append_identifier(dbname, strlen(dbname));
949
static void store_key_options(String *packet, Table *table, KEY *key_info)
953
if (key_info->algorithm == HA_KEY_ALG_BTREE)
954
packet->append(STRING_WITH_LEN(" USING BTREE"));
956
if (key_info->algorithm == HA_KEY_ALG_HASH)
957
packet->append(STRING_WITH_LEN(" USING HASH"));
959
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
960
table->s->key_block_size != key_info->block_size)
962
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
963
end= int64_t10_to_str(key_info->block_size, buff, 10);
964
packet->append(buff, (uint32_t) (end - buff));
967
assert(test(key_info->flags & HA_USES_COMMENT) ==
968
(key_info->comment.length > 0));
969
if (key_info->flags & HA_USES_COMMENT)
971
packet->append(STRING_WITH_LEN(" COMMENT "));
972
append_unescaped(packet, key_info->comment.str,
973
key_info->comment.length);
978
/****************************************************************************
979
Return info about all processes
980
returns for each thread: thread id, user, host, db, command, info
981
****************************************************************************/
983
class thread_info :public ilink {
985
static void *operator new(size_t size)
987
return (void*) sql_alloc((uint32_t) size);
989
static void operator delete(void *, size_t)
990
{ TRASH(ptr, size); }
992
my_thread_id thread_id;
995
const char *user,*host,*db,*proc_info,*state_info;
999
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1000
template class I_List<thread_info>;
1003
void mysqld_list_processes(Session *session,const char *user, bool)
1006
List<Item> field_list;
1007
I_List<thread_info> thread_infos;
1008
Protocol *protocol= session->protocol;
1010
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1011
field_list.push_back(new Item_empty_string("User",16));
1012
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1013
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1014
field->maybe_null= true;
1015
field_list.push_back(new Item_empty_string("Command",16));
1016
field_list.push_back(new Item_return_int("Time",7, DRIZZLE_TYPE_LONG));
1017
field_list.push_back(field=new Item_empty_string("State",30));
1018
field->maybe_null= true;
1019
field_list.push_back(field=new Item_empty_string("Info", PROCESS_LIST_WIDTH));
1020
field->maybe_null= true;
1021
if (protocol->sendFields(&field_list,
1022
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1025
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1026
if (!session->killed)
1029
for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
1032
Security_context *tmp_sctx= &tmp->security_ctx;
1033
struct st_my_thread_var *mysys_var;
1034
if (tmp->protocol->isConnected() && (!user || (tmp_sctx->user.c_str() && !strcmp(tmp_sctx->user.c_str(), user))))
1036
thread_info *session_info= new thread_info;
1038
session_info->thread_id=tmp->thread_id;
1039
session_info->user= session->strdup(tmp_sctx->user.c_str() ? tmp_sctx->user.c_str() : "unauthenticated user");
1040
session_info->host= session->strdup(tmp_sctx->ip.c_str());
1041
if ((session_info->db=tmp->db)) // Safe test
1042
session_info->db=session->strdup(session_info->db);
1043
session_info->command=(int) tmp->command;
1044
if ((mysys_var= tmp->mysys_var))
1045
pthread_mutex_lock(&mysys_var->mutex);
1047
if (tmp->killed == Session::KILL_CONNECTION)
1048
session_info->proc_info= (char*) "Killed";
1050
session_info->proc_info= command_name[session_info->command].str;
1052
session_info->state_info= (char*) (tmp->protocol->isWriting() ?
1054
tmp->protocol->isReading() ?
1055
(session_info->command == COM_SLEEP ?
1056
NULL : "Reading from net") :
1057
tmp->get_proc_info() ? tmp->get_proc_info() :
1059
tmp->mysys_var->current_cond ?
1060
"Waiting on cond" : NULL);
1062
pthread_mutex_unlock(&mysys_var->mutex);
1064
session_info->start_time= tmp->start_time;
1065
session_info->query= NULL;
1066
if (tmp->process_list_info[0])
1067
session_info->query= session->strdup(tmp->process_list_info);
1068
thread_infos.append(session_info);
1072
pthread_mutex_unlock(&LOCK_thread_count);
1074
thread_info *session_info;
1075
time_t now= time(NULL);
1076
while ((session_info=thread_infos.get()))
1078
protocol->prepareForResend();
1079
protocol->store((uint64_t) session_info->thread_id);
1080
protocol->store(session_info->user, system_charset_info);
1081
protocol->store(session_info->host, system_charset_info);
1082
protocol->store(session_info->db, system_charset_info);
1083
protocol->store(session_info->proc_info, system_charset_info);
1085
if (session_info->start_time)
1086
protocol->store((uint32_t) (now - session_info->start_time));
1090
protocol->store(session_info->state_info, system_charset_info);
1091
protocol->store(session_info->query, system_charset_info);
1093
if (protocol->write())
1094
break; /* purecov: inspected */
1100
int fill_schema_processlist(Session* session, TableList* tables, COND*)
1102
Table *table= tables->table;
1103
const CHARSET_INFO * const cs= system_charset_info;
1105
time_t now= time(NULL);
1108
if (now == (time_t)-1)
1113
pthread_mutex_lock(&LOCK_thread_count);
1115
if (!session->killed)
1119
for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
1122
Security_context *tmp_sctx= &tmp->security_ctx;
1123
struct st_my_thread_var *mysys_var;
1126
if (! tmp->protocol->isConnected())
1129
table->restoreRecordAsDefault();
1131
table->field[0]->store((int64_t) tmp->thread_id, true);
1133
val= tmp_sctx->user.c_str() ? tmp_sctx->user.c_str() : "unauthenticated user";
1134
table->field[1]->store(val, strlen(val), cs);
1136
table->field[2]->store(tmp_sctx->ip.c_str(), strlen(tmp_sctx->ip.c_str()), cs);
1140
table->field[3]->store(tmp->db, strlen(tmp->db), cs);
1141
table->field[3]->set_notnull();
1144
if ((mysys_var= tmp->mysys_var))
1145
pthread_mutex_lock(&mysys_var->mutex);
1147
if ((val= (char *) (tmp->killed == Session::KILL_CONNECTION? "Killed" : 0)))
1148
table->field[4]->store(val, strlen(val), cs);
1150
table->field[4]->store(command_name[tmp->command].str,
1151
command_name[tmp->command].length, cs);
1153
table->field[5]->store((uint32_t)(tmp->start_time ?
1154
now - tmp->start_time : 0), true);
1156
val= (char*) (tmp->protocol->isWriting() ?
1158
tmp->protocol->isReading() ?
1159
(tmp->command == COM_SLEEP ?
1160
NULL : "Reading from net") :
1161
tmp->get_proc_info() ? tmp->get_proc_info() :
1163
tmp->mysys_var->current_cond ?
1164
"Waiting on cond" : NULL);
1167
table->field[6]->store(val, strlen(val), cs);
1168
table->field[6]->set_notnull();
1172
pthread_mutex_unlock(&mysys_var->mutex);
1174
length= strlen(tmp->process_list_info);
1178
table->field[7]->store(tmp->process_list_info, length, cs);
1179
table->field[7]->set_notnull();
1182
if (schema_table_store_record(session, table))
1184
pthread_mutex_unlock(&LOCK_thread_count);
1190
pthread_mutex_unlock(&LOCK_thread_count);
1194
/*****************************************************************************
1196
*****************************************************************************/
1198
static vector<SHOW_VAR *> all_status_vars;
1199
static bool status_vars_inited= 0;
1200
int show_var_cmp(const void *var1, const void *var2)
1202
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1205
class show_var_cmp_functor
1208
show_var_cmp_functor() { }
1209
inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2) const
1211
int val= strcmp(var1->name, var2->name);
1216
class show_var_remove_if
1219
show_var_remove_if() { }
1220
inline bool operator()(const SHOW_VAR *curr) const
1222
return (curr->type == SHOW_UNDEF);
1227
Adds an array of SHOW_VAR entries to the output of SHOW STATUS
1230
add_status_vars(SHOW_VAR *list)
1231
list - an array of SHOW_VAR entries to add to all_status_vars
1232
the last entry must be {0,0,SHOW_UNDEF}
1235
The handling of all_status_vars[] is completely internal, it's allocated
1236
automatically when something is added to it, and deleted completely when
1237
the last entry is removed.
1239
As a special optimization, if add_status_vars() is called before
1240
init_status_vars(), it assumes "startup mode" - neither concurrent access
1241
to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
1243
int add_status_vars(SHOW_VAR *list)
1246
if (status_vars_inited)
1247
pthread_mutex_lock(&LOCK_status);
1249
all_status_vars.insert(all_status_vars.begin(), list++);
1250
if (status_vars_inited)
1251
sort(all_status_vars.begin(), all_status_vars.end(),
1252
show_var_cmp_functor());
1253
if (status_vars_inited)
1254
pthread_mutex_unlock(&LOCK_status);
1259
Make all_status_vars[] usable for SHOW STATUS
1262
See add_status_vars(). Before init_status_vars() call, add_status_vars()
1263
works in a special fast "startup" mode. Thus init_status_vars()
1264
should be called as late as possible but before enabling multi-threading.
1266
void init_status_vars()
1268
status_vars_inited= 1;
1269
sort(all_status_vars.begin(), all_status_vars.end(),
1270
show_var_cmp_functor());
1273
void reset_status_vars()
1275
vector<SHOW_VAR *>::iterator p= all_status_vars.begin();
1276
while (p != all_status_vars.end())
1278
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
1279
if ((*p)->type == SHOW_LONG)
1286
catch-all cleanup function, cleans up everything no matter what
1289
This function is not strictly required if all add_to_status/
1290
remove_status_vars are properly paired, but it's a safety measure that
1291
deletes everything from the all_status_vars vector even if some
1292
remove_status_vars were forgotten
1294
void free_status_vars()
1296
all_status_vars.clear();
1300
Removes an array of SHOW_VAR entries from the output of SHOW STATUS
1303
remove_status_vars(SHOW_VAR *list)
1304
list - an array of SHOW_VAR entries to remove to all_status_vars
1305
the last entry must be {0,0,SHOW_UNDEF}
1308
there's lots of room for optimizing this, especially in non-sorted mode,
1309
but nobody cares - it may be called only in case of failed plugin
1310
initialization in the mysqld startup.
1313
void remove_status_vars(SHOW_VAR *list)
1315
if (status_vars_inited)
1317
pthread_mutex_lock(&LOCK_status);
1318
SHOW_VAR *all= all_status_vars.front();
1319
int a= 0, b= all_status_vars.size(), c= (a+b)/2;
1321
for (; list->name; list++)
1324
for (a= 0, b= all_status_vars.size(); b-a > 1; c= (a+b)/2)
1326
res= show_var_cmp(list, all+c);
1335
all[c].type= SHOW_UNDEF;
1337
/* removes all the SHOW_UNDEF elements from the vector */
1338
all_status_vars.erase(std::remove_if(all_status_vars.begin(),
1339
all_status_vars.end(),show_var_remove_if()),
1340
all_status_vars.end());
1341
pthread_mutex_unlock(&LOCK_status);
1345
SHOW_VAR *all= all_status_vars.front();
1347
for (; list->name; list++)
1349
for (i= 0; i < all_status_vars.size(); i++)
1351
if (show_var_cmp(list, all+i))
1353
all[i].type= SHOW_UNDEF;
1357
/* removes all the SHOW_UNDEF elements from the vector */
1358
all_status_vars.erase(std::remove_if(all_status_vars.begin(),
1359
all_status_vars.end(),show_var_remove_if()),
1360
all_status_vars.end());
1364
inline void make_upper(char *buf)
1367
*buf= my_toupper(system_charset_info, *buf);
1370
static bool show_status_array(Session *session, const char *wild,
1371
SHOW_VAR *variables,
1372
enum enum_var_type value_type,
1373
struct system_status_var *status_var,
1374
const char *prefix, Table *table,
1377
MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, int64_t);
1378
char * const buff= (char *) &buff_data;
1380
/* the variable name should not be longer than 64 characters */
1381
char name_buffer[64];
1385
prefix_end= strncpy(name_buffer, prefix, sizeof(name_buffer)-1);
1386
prefix_end+= strlen(prefix);
1390
len=name_buffer + sizeof(name_buffer) - prefix_end;
1392
for (; variables->name; variables++)
1394
strncpy(prefix_end, variables->name, len);
1395
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
1397
make_upper(name_buffer);
1400
if var->type is SHOW_FUNC, call the function.
1401
Repeat as necessary, if new var is again SHOW_FUNC
1403
for (var=variables; var->type == SHOW_FUNC; var= &tmp)
1404
((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(&tmp, buff);
1406
SHOW_TYPE show_type=var->type;
1407
if (show_type == SHOW_ARRAY)
1409
show_status_array(session, wild, (SHOW_VAR *) var->value, value_type,
1410
status_var, name_buffer, table, ucase_names);
1414
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
1415
name_buffer, wild)))
1417
char *value=var->value;
1418
const char *pos, *end; // We assign a lot of const's
1419
pthread_mutex_lock(&LOCK_global_system_variables);
1421
if (show_type == SHOW_SYS)
1423
show_type= ((sys_var*) value)->show_type();
1424
value= (char*) ((sys_var*) value)->value_ptr(session, value_type,
1430
note that value may be == buff. All SHOW_xxx code below
1431
should still work in this case
1433
switch (show_type) {
1434
case SHOW_DOUBLE_STATUS:
1435
value= ((char *) status_var + (ulong) value);
1438
/* 6 is the default precision for '%f' in sprintf() */
1439
end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
1441
case SHOW_LONG_STATUS:
1442
value= ((char *) status_var + (ulong) value);
1445
end= int10_to_str(*(long*) value, buff, 10);
1447
case SHOW_LONGLONG_STATUS:
1448
value= ((char *) status_var + (uint64_t) value);
1451
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1455
stringstream ss (stringstream::in);
1456
ss << *(size_t*) value;
1458
string str= ss.str();
1459
strncpy(buff, str.c_str(), str.length());
1460
end= buff+ str.length();
1464
end= int64_t10_to_str((int64_t) *(ha_rows*) value, buff, 10);
1467
end+= sprintf(buff,"%s", *(bool*) value ? "ON" : "OFF");
1470
end+= sprintf(buff,"%s", *(bool*) value ? "ON" : "OFF");
1473
case SHOW_INT_NOFLUSH: // the difference lies in refresh_status()
1474
end= int10_to_str((long) *(uint32_t*) value, buff, 10);
1478
SHOW_COMP_OPTION tmp_option= *(SHOW_COMP_OPTION *)value;
1479
pos= show_comp_option_name[(int) tmp_option];
1480
end= strchr(pos, '\0');
1487
end= strchr(pos, '\0');
1492
if (!(pos= *(char**) value))
1494
end= strchr(pos, '\0');
1497
case SHOW_KEY_CACHE_LONG:
1498
value= (char*) dflt_key_cache + (ulong)value;
1499
end= int10_to_str(*(long*) value, buff, 10);
1501
case SHOW_KEY_CACHE_LONGLONG:
1502
value= (char*) dflt_key_cache + (ulong)value;
1503
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1506
break; // Return empty string
1507
case SHOW_SYS: // Cannot happen
1512
table->restoreRecordAsDefault();
1513
table->field[0]->store(name_buffer, strlen(name_buffer),
1514
system_charset_info);
1515
table->field[1]->store(pos, (uint32_t) (end - pos), system_charset_info);
1516
table->field[1]->set_notnull();
1518
pthread_mutex_unlock(&LOCK_global_system_variables);
1520
if (schema_table_store_record(session, table))
1530
/* collect status for all running threads */
1532
void calc_sum_of_all_status(STATUS_VAR *to)
1534
/* Ensure that thread id not killed during loop */
1535
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1537
/* Get global values as base */
1538
*to= global_status_var;
1540
/* Add to this status from existing threads */
1541
for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
1543
add_to_status(to, &((*it)->status_var));
1546
pthread_mutex_unlock(&LOCK_thread_count);
1551
/* This is only used internally, but we need it here as a forward reference */
1552
extern InfoSchemaTable schema_tables[];
1554
typedef struct st_lookup_field_values
1556
LEX_STRING db_value, table_value;
1557
bool wild_db_value, wild_table_value;
1558
} LOOKUP_FIELD_VALUES;
1562
Store record to I_S table, convert HEAP table
1563
to MyISAM if necessary
1566
schema_table_store_record()
1567
session thread handler
1568
table Information schema table to be updated
1575
bool schema_table_store_record(Session *session, Table *table)
1578
if ((error= table->file->ha_write_row(table->record[0])))
1580
Tmp_Table_Param *param= table->pos_in_table_list->schema_table_param;
1582
if (create_myisam_from_heap(session, table, param->start_recinfo,
1583
¶m->recinfo, error, 0))
1590
int make_table_list(Session *session, Select_Lex *sel,
1591
LEX_STRING *db_name, LEX_STRING *table_name)
1593
Table_ident *table_ident;
1594
table_ident= new Table_ident(session, *db_name, *table_name, 1);
1596
if (!sel->add_table_to_list(session, table_ident, 0, 0, TL_READ))
1603
@brief Get lookup value from the part of 'WHERE' condition
1605
@details This function gets lookup value from
1606
the part of 'WHERE' condition if it's possible and
1607
fill appropriate lookup_field_vals struct field
1610
@param[in] session thread handler
1611
@param[in] item_func part of WHERE condition
1612
@param[in] table I_S table
1613
@param[in, out] lookup_field_vals Struct which holds lookup values
1617
1 error, there can be no matching records for the condition
1620
bool get_lookup_value(Session *session, Item_func *item_func,
1622
LOOKUP_FIELD_VALUES *lookup_field_vals)
1624
InfoSchemaTable *schema_table= table->schema_table;
1625
ST_FIELD_INFO *field_info= schema_table->fields_info;
1626
const char *field_name1= schema_table->idx_field1 >= 0 ?
1627
field_info[schema_table->idx_field1].field_name : "";
1628
const char *field_name2= schema_table->idx_field2 >= 0 ?
1629
field_info[schema_table->idx_field2].field_name : "";
1631
if (item_func->functype() == Item_func::EQ_FUNC ||
1632
item_func->functype() == Item_func::EQUAL_FUNC)
1634
int idx_field, idx_val;
1635
char tmp[MAX_FIELD_WIDTH];
1636
String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
1637
Item_field *item_field;
1638
const CHARSET_INFO * const cs= system_charset_info;
1640
if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
1641
item_func->arguments()[1]->const_item())
1646
else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
1647
item_func->arguments()[0]->const_item())
1655
item_field= (Item_field*) item_func->arguments()[idx_field];
1656
if (table->table != item_field->field->table)
1658
tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
1660
/* impossible value */
1664
/* Lookup value is database name */
1665
if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1666
(unsigned char *) item_field->field_name,
1667
strlen(item_field->field_name), 0))
1669
session->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
1670
tmp_str->length(), false);
1672
/* Lookup value is table name */
1673
else if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name2,
1674
strlen(field_name2),
1675
(unsigned char *) item_field->field_name,
1676
strlen(item_field->field_name), 0))
1678
session->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
1679
tmp_str->length(), false);
1687
@brief Calculates lookup values from 'WHERE' condition
1689
@details This function calculates lookup value(database name, table name)
1690
from 'WHERE' condition if it's possible and
1691
fill lookup_field_vals struct fields with these values.
1693
@param[in] session thread handler
1694
@param[in] cond WHERE condition
1695
@param[in] table I_S table
1696
@param[in, out] lookup_field_vals Struct which holds lookup values
1700
1 error, there can be no matching records for the condition
1703
bool calc_lookup_values_from_cond(Session *session, COND *cond, TableList *table,
1704
LOOKUP_FIELD_VALUES *lookup_field_vals)
1709
if (cond->type() == Item::COND_ITEM)
1711
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1713
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1715
while ((item= li++))
1717
if (item->type() == Item::FUNC_ITEM)
1719
if (get_lookup_value(session, (Item_func*)item, table, lookup_field_vals))
1724
if (calc_lookup_values_from_cond(session, item, table, lookup_field_vals))
1731
else if (cond->type() == Item::FUNC_ITEM &&
1732
get_lookup_value(session, (Item_func*) cond, table, lookup_field_vals))
1738
bool uses_only_table_name_fields(Item *item, TableList *table)
1740
if (item->type() == Item::FUNC_ITEM)
1742
Item_func *item_func= (Item_func*)item;
1743
for (uint32_t i=0; i<item_func->argument_count(); i++)
1745
if (!uses_only_table_name_fields(item_func->arguments()[i], table))
1749
else if (item->type() == Item::FIELD_ITEM)
1751
Item_field *item_field= (Item_field*)item;
1752
const CHARSET_INFO * const cs= system_charset_info;
1753
InfoSchemaTable *schema_table= table->schema_table;
1754
ST_FIELD_INFO *field_info= schema_table->fields_info;
1755
const char *field_name1= schema_table->idx_field1 >= 0 ?
1756
field_info[schema_table->idx_field1].field_name : "";
1757
const char *field_name2= schema_table->idx_field2 >= 0 ?
1758
field_info[schema_table->idx_field2].field_name : "";
1759
if (table->table != item_field->field->table ||
1760
(cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1761
(unsigned char *) item_field->field_name,
1762
strlen(item_field->field_name), 0) &&
1763
cs->coll->strnncollsp(cs, (unsigned char *) field_name2, strlen(field_name2),
1764
(unsigned char *) item_field->field_name,
1765
strlen(item_field->field_name), 0)))
1768
else if (item->type() == Item::REF_ITEM)
1769
return uses_only_table_name_fields(item->real_item(), table);
1771
if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
1778
static COND * make_cond_for_info_schema(COND *cond, TableList *table)
1782
if (cond->type() == Item::COND_ITEM)
1784
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1786
/* Create new top level AND item */
1787
Item_cond_and *new_cond=new Item_cond_and;
1790
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1794
Item *fix= make_cond_for_info_schema(item, table);
1796
new_cond->argument_list()->push_back(fix);
1798
switch (new_cond->argument_list()->elements) {
1802
return new_cond->argument_list()->head();
1804
new_cond->quick_fix_field();
1810
Item_cond_or *new_cond=new Item_cond_or;
1813
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1817
Item *fix=make_cond_for_info_schema(item, table);
1820
new_cond->argument_list()->push_back(fix);
1822
new_cond->quick_fix_field();
1823
new_cond->top_level_item();
1828
if (!uses_only_table_name_fields(cond, table))
1835
@brief Calculate lookup values(database name, table name)
1837
@details This function calculates lookup values(database name, table name)
1838
from 'WHERE' condition or wild values (for 'SHOW' commands only)
1839
from LEX struct and fill lookup_field_vals struct field
1842
@param[in] session thread handler
1843
@param[in] cond WHERE condition
1844
@param[in] tables I_S table
1845
@param[in, out] lookup_field_values Struct which holds lookup values
1849
1 error, there can be no matching records for the condition
1852
bool get_lookup_field_values(Session *session, COND *cond, TableList *tables,
1853
LOOKUP_FIELD_VALUES *lookup_field_values)
1855
LEX *lex= session->lex;
1856
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
1857
memset(lookup_field_values, 0, sizeof(LOOKUP_FIELD_VALUES));
1858
switch (lex->sql_command) {
1859
case SQLCOM_SHOW_DATABASES:
1862
lookup_field_values->db_value.str= (char*) wild;
1863
lookup_field_values->db_value.length= strlen(wild);
1864
lookup_field_values->wild_db_value= 1;
1867
case SQLCOM_SHOW_TABLES:
1868
case SQLCOM_SHOW_TABLE_STATUS:
1869
lookup_field_values->db_value.str= lex->select_lex.db;
1870
lookup_field_values->db_value.length=strlen(lex->select_lex.db);
1873
lookup_field_values->table_value.str= (char*)wild;
1874
lookup_field_values->table_value.length= strlen(wild);
1875
lookup_field_values->wild_table_value= 1;
1880
The "default" is for queries over I_S.
1881
All previous cases handle SHOW commands.
1883
return calc_lookup_values_from_cond(session, cond, tables, lookup_field_values);
1888
enum enum_schema_tables get_schema_table_idx(InfoSchemaTable *schema_table)
1890
return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
1895
Create db names list. Information schema name always is first in list
1899
session thread handler
1900
files list of db names
1902
idx_field_vals idx_field_vals->db_name contains db name or
1904
with_i_schema returns 1 if we added 'IS' name to list
1912
int make_db_list(Session *session, List<LEX_STRING> *files,
1913
LOOKUP_FIELD_VALUES *lookup_field_vals,
1914
bool *with_i_schema)
1916
LEX_STRING *i_s_name_copy= 0;
1917
i_s_name_copy= session->make_lex_string(i_s_name_copy,
1918
INFORMATION_SCHEMA_NAME.c_str(),
1919
INFORMATION_SCHEMA_NAME.length(), true);
1921
if (lookup_field_vals->wild_db_value)
1924
This part of code is only for SHOW DATABASES command.
1925
idx_field_vals->db_value can be 0 when we don't use
1926
LIKE clause (see also get_index_field_values() function)
1928
if (!lookup_field_vals->db_value.str ||
1929
!wild_case_compare(system_charset_info,
1930
INFORMATION_SCHEMA_NAME.c_str(),
1931
lookup_field_vals->db_value.str))
1934
if (files->push_back(i_s_name_copy))
1937
return (find_files(session, files, NULL, drizzle_data_home,
1938
lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
1943
If we have db lookup vaule we just add it to list and
1944
exit from the function
1946
if (lookup_field_vals->db_value.str)
1948
if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.c_str(),
1949
lookup_field_vals->db_value.str))
1952
if (files->push_back(i_s_name_copy))
1956
if (files->push_back(&lookup_field_vals->db_value))
1962
Create list of existing databases. It is used in case
1963
of select from information schema table
1965
if (files->push_back(i_s_name_copy))
1968
return (find_files(session, files, NULL,
1969
drizzle_data_home, NULL, 1) != FIND_FILES_OK);
1973
struct st_add_schema_table
1975
List<LEX_STRING> *files;
1980
class AddSchemaTable : public unary_function<InfoSchemaTable *, bool>
1983
st_add_schema_table *data;
1985
AddSchemaTable(Session *session_arg, st_add_schema_table *data_arg)
1986
: session(session_arg), data(data_arg) {}
1987
result_type operator() (argument_type schema_table)
1989
LEX_STRING *file_name= 0;
1990
List<LEX_STRING> *file_list= data->files;
1991
const char *wild= data->wild;
1993
if (schema_table->hidden)
1997
if (lower_case_table_names)
1999
if (wild_case_compare(files_charset_info,
2000
schema_table->table_name,
2004
else if (wild_compare(schema_table->table_name, wild, 0))
2008
if ((file_name= session->make_lex_string(file_name, schema_table->table_name,
2009
strlen(schema_table->table_name),
2011
!file_list->push_back(file_name))
2018
int schema_tables_add(Session *session, List<LEX_STRING> *files, const char *wild)
2020
LEX_STRING *file_name= 0;
2021
InfoSchemaTable *tmp_schema_table= schema_tables;
2022
st_add_schema_table add_data;
2024
for (; tmp_schema_table->table_name; tmp_schema_table++)
2026
if (tmp_schema_table->hidden)
2030
if (lower_case_table_names)
2032
if (wild_case_compare(files_charset_info,
2033
tmp_schema_table->table_name,
2037
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2041
session->make_lex_string(file_name, tmp_schema_table->table_name,
2042
strlen(tmp_schema_table->table_name), true)) &&
2043
!files->push_back(file_name))
2048
add_data.files= files;
2049
add_data.wild= wild;
2050
vector<InfoSchemaTable *>::iterator iter=
2051
find_if(all_schema_tables.begin(), all_schema_tables.end(),
2052
AddSchemaTable(session, &add_data));
2053
if (iter != all_schema_tables.end())
2060
@brief Create table names list
2062
@details The function creates the list of table names in
2065
@param[in] session thread handler
2066
@param[in] table_names List of table names in database
2067
@param[in] lex pointer to LEX struct
2068
@param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
2069
@param[in] with_i_schema true means that we add I_S tables to list
2070
@param[in] db_name database name
2072
@return Operation status
2074
@retval 1 fatal error
2075
@retval 2 Not fatal error; Safe to ignore this file list
2079
make_table_name_list(Session *session, List<LEX_STRING> *table_names, LEX *lex,
2080
LOOKUP_FIELD_VALUES *lookup_field_vals,
2081
bool with_i_schema, LEX_STRING *db_name)
2083
char path[FN_REFLEN];
2084
build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
2085
if (!lookup_field_vals->wild_table_value &&
2086
lookup_field_vals->table_value.str)
2090
if (find_schema_table(lookup_field_vals->table_value.str))
2092
if (table_names->push_back(&lookup_field_vals->table_value))
2098
if (table_names->push_back(&lookup_field_vals->table_value))
2105
This call will add all matching the wildcards (if specified) IS tables
2109
return (schema_tables_add(session, table_names,
2110
lookup_field_vals->table_value.str));
2112
find_files_result res= find_files(session, table_names, db_name->str, path,
2113
lookup_field_vals->table_value.str, 0);
2114
if (res != FIND_FILES_OK)
2117
Downgrade errors about problems with database directory to
2118
warnings if this is not a 'SHOW' command. Another thread
2119
may have dropped database, and we may still have a name
2122
if (res == FIND_FILES_DIR)
2124
if (lex->sql_command != SQLCOM_SELECT)
2126
session->clear_error();
2136
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
2138
@param[in] session thread handler
2139
@param[in] tables TableList for I_S table
2140
@param[in] schema_table pointer to I_S structure
2141
@param[in] open_tables_state_backup pointer to Open_tables_state object
2142
which is used to save|restore original
2143
status of variables related to
2146
@return Operation status
2152
fill_schema_show_cols_or_idxs(Session *session, TableList *tables,
2153
InfoSchemaTable *schema_table,
2154
Open_tables_state *open_tables_state_backup)
2156
LEX *lex= session->lex;
2158
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
2159
enum_sql_command save_sql_command= lex->sql_command;
2160
TableList *show_table_list= (TableList*) tables->schema_select_lex->
2162
Table *table= tables->table;
2165
lex->all_selects_list= tables->schema_select_lex;
2167
Restore session->temporary_tables to be able to process
2168
temporary tables(only for 'show index' & 'show columns').
2169
This should be changed when processing of temporary tables for
2170
I_S tables will be done.
2172
session->temporary_tables= open_tables_state_backup->temporary_tables;
2174
Let us set fake sql_command so views won't try to merge
2175
themselves into main statement. If we don't do this,
2176
SELECT * from information_schema.xxxx will cause problems.
2177
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
2179
lex->sql_command= SQLCOM_SHOW_FIELDS;
2180
res= open_normal_and_derived_tables(session, show_table_list,
2181
DRIZZLE_LOCK_IGNORE_FLUSH);
2182
lex->sql_command= save_sql_command;
2184
get_all_tables() returns 1 on failure and 0 on success thus
2185
return only these and not the result code of ::process_table()
2187
We should use show_table_list->alias instead of
2188
show_table_list->table_name because table_name
2189
could be changed during opening of I_S tables. It's safe
2190
to use alias because alias contains original table name
2191
in this case(this part of code is used only for
2192
'show columns' & 'show statistics' commands).
2194
table_name= session->make_lex_string(&tmp_lex_string1, show_table_list->alias,
2195
strlen(show_table_list->alias), false);
2196
db_name= session->make_lex_string(&tmp_lex_string, show_table_list->db,
2197
show_table_list->db_length, false);
2200
error= test(schema_table->process_table(session, show_table_list,
2201
table, res, db_name,
2203
session->temporary_tables= 0;
2204
close_tables_for_reopen(session, &show_table_list);
2210
@brief Fill I_S table for SHOW Table NAMES commands
2212
@param[in] session thread handler
2213
@param[in] table Table struct for I_S table
2214
@param[in] db_name database name
2215
@param[in] table_name table name
2216
@param[in] with_i_schema I_S table if true
2218
@return Operation status
2223
static int fill_schema_table_names(Session *session, Table *table,
2224
LEX_STRING *db_name, LEX_STRING *table_name,
2229
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
2230
system_charset_info);
2234
char path[FN_REFLEN];
2235
(void) build_table_filename(path, sizeof(path), db_name->str,
2236
table_name->str, "", 0);
2238
table->field[3]->store(STRING_WITH_LEN("BASE Table"),
2239
system_charset_info);
2241
if (session->is_error() && session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2243
session->clear_error();
2247
if (schema_table_store_record(session, table))
2254
@brief Get open table method
2256
@details The function calculates the method which will be used
2258
SKIP_OPEN_TABLE - do not open table
2259
OPEN_FRM_ONLY - open FRM file only
2260
OPEN_FULL_TABLE - open FRM, data, index files
2261
@param[in] tables I_S table table_list
2262
@param[in] schema_table I_S table struct
2263
@param[in] schema_table_idx I_S table index
2265
@return return a set of flags
2266
@retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
2269
static uint32_t get_table_open_method(TableList *tables,
2270
InfoSchemaTable *schema_table,
2271
enum enum_schema_tables)
2274
determine which method will be used for table opening
2276
if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
2278
Field **ptr, *field;
2279
int table_open_method= 0, field_indx= 0;
2280
for (ptr=tables->table->field; (field= *ptr) ; ptr++)
2282
if (field->isReadSet())
2283
table_open_method|= schema_table->fields_info[field_indx].open_method;
2286
return table_open_method;
2288
/* I_S tables which use get_all_tables but can not be optimized */
2289
return (uint32_t) OPEN_FULL_TABLE;
2294
@brief Fill I_S table with data from FRM file only
2296
@param[in] session thread handler
2297
@param[in] table Table struct for I_S table
2298
@param[in] schema_table I_S table struct
2299
@param[in] db_name database name
2300
@param[in] table_name table name
2301
@param[in] schema_table_idx I_S table index
2303
@return Operation status
2304
@retval 0 Table is processed and we can continue
2306
@retval 1 It's view and we have to use
2307
open_tables function for this table
2310
static int fill_schema_table_from_frm(Session *session,TableList *tables,
2311
InfoSchemaTable *schema_table,
2312
LEX_STRING *db_name,
2313
LEX_STRING *table_name,
2314
enum enum_schema_tables)
2316
Table *table= tables->table;
2319
TableList table_list;
2322
char key[MAX_DBKEY_LENGTH];
2323
uint32_t key_length;
2325
memset(&tbl, 0, sizeof(Table));
2327
table_list.table_name= table_name->str;
2328
table_list.db= db_name->str;
2330
key_length= create_table_def_key(key, &table_list);
2331
pthread_mutex_lock(&LOCK_open);
2332
share= get_table_share(session, &table_list, key,
2333
key_length, 0, &error);
2342
table_list.table= &tbl;
2343
res= schema_table->process_table(session, &table_list, table,
2344
res, db_name, table_name);
2347
release_table_share(share, RELEASE_NORMAL);
2350
pthread_mutex_unlock(&LOCK_open);
2351
session->clear_error();
2358
@brief Fill I_S tables whose data are retrieved
2359
from frm files and storage engine
2361
@details The information schema tables are internally represented as
2362
temporary tables that are filled at query execution time.
2363
Those I_S tables whose data are retrieved
2364
from frm files and storage engine are filled by the function
2367
@param[in] session thread handler
2368
@param[in] tables I_S table
2369
@param[in] cond 'WHERE' condition
2371
@return Operation status
2376
int get_all_tables(Session *session, TableList *tables, COND *cond)
2378
LEX *lex= session->lex;
2379
Table *table= tables->table;
2380
Select_Lex *old_all_select_lex= lex->all_selects_list;
2381
enum_sql_command save_sql_command= lex->sql_command;
2382
Select_Lex *lsel= tables->schema_select_lex;
2383
InfoSchemaTable *schema_table= tables->schema_table;
2385
LOOKUP_FIELD_VALUES lookup_field_vals;
2386
LEX_STRING *db_name, *table_name;
2388
enum enum_schema_tables schema_table_idx;
2389
List<LEX_STRING> db_names;
2390
List_iterator_fast<LEX_STRING> it(db_names);
2391
COND *partial_cond= 0;
2392
uint32_t derived_tables= lex->derived_tables;
2394
Open_tables_state open_tables_state_backup;
2395
Query_tables_list query_tables_list_backup;
2396
uint32_t table_open_method;
2397
bool old_value= session->no_warnings_for_error;
2400
We should not introduce deadlocks even if we already have some
2401
tables open and locked, since we won't lock tables which we will
2402
open and will ignore possible name-locks for these tables.
2404
session->reset_n_backup_open_tables_state(&open_tables_state_backup);
2406
schema_table_idx= get_schema_table_idx(schema_table);
2407
tables->table_open_method= table_open_method=
2408
get_table_open_method(tables, schema_table, schema_table_idx);
2410
this branch processes SHOW FIELDS, SHOW INDEXES commands.
2411
see sql_parse.cc, prepare_schema_table() function where
2412
this values are initialized
2414
if (lsel && lsel->table_list.first)
2416
error= fill_schema_show_cols_or_idxs(session, tables, schema_table,
2417
&open_tables_state_backup);
2421
if (get_lookup_field_values(session, cond, tables, &lookup_field_vals))
2427
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
2430
if lookup value is empty string then
2431
it's impossible table name or db name
2433
if ((lookup_field_vals.db_value.str && !lookup_field_vals.db_value.str[0]) ||
2434
(lookup_field_vals.table_value.str && !lookup_field_vals.table_value.str[0]))
2441
if (lookup_field_vals.db_value.length &&
2442
!lookup_field_vals.wild_db_value)
2443
tables->has_db_lookup_value= true;
2444
if (lookup_field_vals.table_value.length &&
2445
!lookup_field_vals.wild_table_value)
2446
tables->has_table_lookup_value= true;
2448
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
2451
partial_cond= make_cond_for_info_schema(cond, tables);
2455
/* EXPLAIN SELECT */
2460
if (make_db_list(session, &db_names, &lookup_field_vals, &with_i_schema))
2462
it.rewind(); /* To get access to new elements in basis list */
2463
while ((db_name= it++))
2466
session->no_warnings_for_error= 1;
2467
List<LEX_STRING> table_names;
2468
int res= make_table_name_list(session, &table_names, lex,
2470
with_i_schema, db_name);
2471
if (res == 2) /* Not fatal error, continue */
2476
List_iterator_fast<LEX_STRING> it_files(table_names);
2477
while ((table_name= it_files++))
2479
table->restoreRecordAsDefault();
2480
table->field[schema_table->idx_field1]->
2481
store(db_name->str, db_name->length, system_charset_info);
2482
table->field[schema_table->idx_field2]->
2483
store(table_name->str, table_name->length, system_charset_info);
2485
if (!partial_cond || partial_cond->val_int())
2488
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
2489
we can skip table opening and we don't have lookup value for
2490
table name or lookup value is wild string(table name list is
2491
already created by make_table_name_list() function).
2493
if (!table_open_method && schema_table_idx == SCH_TABLES &&
2494
(!lookup_field_vals.table_value.length ||
2495
lookup_field_vals.wild_table_value))
2497
if (schema_table_store_record(session, table))
2498
goto err; /* Out of space in temporary table */
2502
/* SHOW Table NAMES command */
2503
if (schema_table_idx == SCH_TABLE_NAMES)
2505
if (fill_schema_table_names(session, tables->table, db_name,
2506
table_name, with_i_schema))
2511
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
2514
if (!fill_schema_table_from_frm(session, tables, schema_table, db_name,
2515
table_name, schema_table_idx))
2519
LEX_STRING tmp_lex_string, orig_db_name;
2521
Set the parent lex of 'sel' because it is needed by
2522
sel.init_query() which is called inside make_table_list.
2524
session->no_warnings_for_error= 1;
2525
sel.parent_lex= lex;
2526
/* db_name can be changed in make_table_list() func */
2527
if (!session->make_lex_string(&orig_db_name, db_name->str,
2528
db_name->length, false))
2530
if (make_table_list(session, &sel, db_name, table_name))
2532
TableList *show_table_list= (TableList*) sel.table_list.first;
2533
lex->all_selects_list= &sel;
2534
lex->derived_tables= 0;
2535
lex->sql_command= SQLCOM_SHOW_FIELDS;
2536
show_table_list->i_s_requested_object=
2537
schema_table->i_s_requested_object;
2538
res= open_normal_and_derived_tables(session, show_table_list,
2539
DRIZZLE_LOCK_IGNORE_FLUSH);
2540
lex->sql_command= save_sql_command;
2542
XXX: show_table_list has a flag i_is_requested,
2543
and when it's set, open_normal_and_derived_tables()
2544
can return an error without setting an error message
2545
in Session, which is a hack. This is why we have to
2546
check for res, then for session->is_error() only then
2547
for session->main_da.sql_errno().
2549
if (res && session->is_error() &&
2550
session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2553
Hide error for not existing table.
2554
This error can occur for example when we use
2555
where condition with db name and table name and this
2556
table does not exist.
2559
session->clear_error();
2564
We should use show_table_list->alias instead of
2565
show_table_list->table_name because table_name
2566
could be changed during opening of I_S tables. It's safe
2567
to use alias because alias contains original table name
2570
session->make_lex_string(&tmp_lex_string, show_table_list->alias,
2571
strlen(show_table_list->alias), false);
2572
res= schema_table->process_table(session, show_table_list, table,
2575
close_tables_for_reopen(session, &show_table_list);
2577
assert(!lex->query_tables_own_last);
2584
If we have information schema its always the first table and only
2585
the first table. Reset for other tables.
2593
session->restore_backup_open_tables_state(&open_tables_state_backup);
2594
lex->derived_tables= derived_tables;
2595
lex->all_selects_list= old_all_select_lex;
2596
lex->sql_command= save_sql_command;
2597
session->no_warnings_for_error= old_value;
2602
bool store_schema_shemata(Session* session, Table *table, LEX_STRING *db_name,
2603
const CHARSET_INFO * const cs)
2605
table->restoreRecordAsDefault();
2606
table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2607
table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2608
table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2609
return schema_table_store_record(session, table);
2613
int fill_schema_schemata(Session *session, TableList *tables, COND *cond)
2616
TODO: fill_schema_shemata() is called when new client is connected.
2617
Returning error status in this case leads to client hangup.
2620
LOOKUP_FIELD_VALUES lookup_field_vals;
2621
List<LEX_STRING> db_names;
2622
LEX_STRING *db_name;
2624
Table *table= tables->table;
2626
if (get_lookup_field_values(session, cond, tables, &lookup_field_vals))
2628
if (make_db_list(session, &db_names, &lookup_field_vals,
2633
If we have lookup db value we should check that the database exists
2635
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
2638
char path[FN_REFLEN+16];
2640
struct stat stat_info;
2641
if (!lookup_field_vals.db_value.str[0])
2643
path_len= build_table_filename(path, sizeof(path),
2644
lookup_field_vals.db_value.str, "", "", 0);
2645
path[path_len-1]= 0;
2646
if (stat(path,&stat_info))
2650
List_iterator_fast<LEX_STRING> it(db_names);
2651
while ((db_name=it++))
2653
if (with_i_schema) // information schema name is always first in list
2655
if (store_schema_shemata(session, table, db_name,
2656
system_charset_info))
2662
HA_CREATE_INFO create;
2663
load_db_opt_by_name(db_name->str, &create);
2665
if (store_schema_shemata(session, table, db_name,
2666
create.default_table_charset))
2674
static int get_schema_tables_record(Session *session, TableList *tables,
2675
Table *table, bool res,
2676
LEX_STRING *db_name,
2677
LEX_STRING *table_name)
2679
const char *tmp_buff;
2681
const CHARSET_INFO * const cs= system_charset_info;
2683
table->restoreRecordAsDefault();
2684
table->field[1]->store(db_name->str, db_name->length, cs);
2685
table->field[2]->store(table_name->str, table_name->length, cs);
2689
there was errors during opening tables
2691
const char *error= session->is_error() ? session->main_da.message() : "";
2692
if (tables->schema_table)
2693
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2695
table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
2696
table->field[20]->store(error, strlen(error), cs);
2697
session->clear_error();
2701
char option_buff[400],*ptr;
2702
Table *show_table= tables->table;
2703
TableShare *share= show_table->s;
2704
handler *file= show_table->file;
2705
StorageEngine *tmp_db_type= share->db_type();
2706
if (share->tmp_table == SYSTEM_TMP_TABLE)
2707
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2708
else if (share->tmp_table)
2709
table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
2711
table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
2713
for (int i= 4; i < 20; i++)
2715
if (i == 7 || (i > 12 && i < 17) || i == 18)
2717
table->field[i]->set_notnull();
2719
string engine_name= ha_resolve_storage_engine_name(tmp_db_type);
2720
table->field[4]->store(engine_name.c_str(), engine_name.size(), cs);
2721
table->field[5]->store((int64_t) 0, true);
2724
if (share->min_rows)
2726
ptr= strcpy(ptr," min_rows=")+10;
2727
ptr= int64_t10_to_str(share->min_rows,ptr,10);
2729
if (share->max_rows)
2731
ptr= strcpy(ptr," max_rows=")+10;
2732
ptr= int64_t10_to_str(share->max_rows,ptr,10);
2734
if (share->avg_row_length)
2736
ptr= strcpy(ptr," avg_row_length=")+16;
2737
ptr= int64_t10_to_str(share->avg_row_length,ptr,10);
2739
if (share->db_create_options & HA_OPTION_PACK_KEYS)
2740
ptr= strcpy(ptr," pack_keys=1")+12;
2741
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
2742
ptr= strcpy(ptr," pack_keys=0")+12;
2743
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2744
if (share->db_create_options & HA_OPTION_CHECKSUM)
2745
ptr= strcpy(ptr," checksum=1")+11;
2746
if (share->page_checksum != HA_CHOICE_UNDEF)
2747
ptr+= sprintf(ptr, " page_checksum=%s",
2748
ha_choice_values[(uint32_t) share->page_checksum]);
2749
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
2750
ptr= strcpy(ptr," delay_key_write=1")+18;
2751
if (share->row_type != ROW_TYPE_DEFAULT)
2752
ptr+= sprintf(ptr, " row_format=%s", ha_row_type[(uint32_t)share->row_type]);
2753
if (share->block_size)
2755
ptr= strcpy(ptr, " block_size=")+12;
2756
ptr= int64_t10_to_str(share->block_size, ptr, 10);
2759
table->field[19]->store(option_buff+1,
2760
(ptr == option_buff ? 0 :
2761
(uint32_t) (ptr-option_buff)-1), cs);
2763
tmp_buff= (share->table_charset ?
2764
share->table_charset->name : "default");
2765
table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
2767
if (share->comment.str)
2768
table->field[20]->store(share->comment.str, share->comment.length, cs);
2772
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
2774
enum row_type row_type = file->get_row_type();
2776
case ROW_TYPE_NOT_USED:
2777
case ROW_TYPE_DEFAULT:
2778
tmp_buff= ((share->db_options_in_use &
2779
HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
2780
(share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
2781
"Dynamic" : "Fixed");
2783
case ROW_TYPE_FIXED:
2786
case ROW_TYPE_DYNAMIC:
2787
tmp_buff= "Dynamic";
2789
case ROW_TYPE_COMPRESSED:
2790
tmp_buff= "Compressed";
2792
case ROW_TYPE_REDUNDANT:
2793
tmp_buff= "Redundant";
2795
case ROW_TYPE_COMPACT:
2796
tmp_buff= "Compact";
2802
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
2803
if (!tables->schema_table)
2805
table->field[7]->store((int64_t) file->stats.records, true);
2806
table->field[7]->set_notnull();
2808
table->field[8]->store((int64_t) file->stats.mean_rec_length, true);
2809
table->field[9]->store((int64_t) file->stats.data_file_length, true);
2810
if (file->stats.max_data_file_length)
2812
table->field[10]->store((int64_t) file->stats.max_data_file_length,
2815
table->field[11]->store((int64_t) file->stats.index_file_length, true);
2816
table->field[12]->store((int64_t) file->stats.delete_length, true);
2817
if (show_table->found_next_number_field)
2819
table->field[13]->store((int64_t) file->stats.auto_increment_value,
2821
table->field[13]->set_notnull();
2823
if (file->stats.create_time)
2825
session->variables.time_zone->gmt_sec_to_TIME(&time,
2826
(time_t) file->stats.create_time);
2827
table->field[14]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2828
table->field[14]->set_notnull();
2830
if (file->stats.update_time)
2832
session->variables.time_zone->gmt_sec_to_TIME(&time,
2833
(time_t) file->stats.update_time);
2834
table->field[15]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2835
table->field[15]->set_notnull();
2837
if (file->stats.check_time)
2839
session->variables.time_zone->gmt_sec_to_TIME(&time,
2840
(time_t) file->stats.check_time);
2841
table->field[16]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2842
table->field[16]->set_notnull();
2844
if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
2846
table->field[18]->store((int64_t) file->checksum(), true);
2847
table->field[18]->set_notnull();
2851
return(schema_table_store_record(session, table));
2856
@brief Store field characteristics into appropriate I_S table columns
2858
@param[in] table I_S table
2859
@param[in] field processed field
2860
@param[in] cs I_S table charset
2861
@param[in] offset offset from beginning of table
2862
to DATE_TYPE column in I_S table
2867
void store_column_type(Table *table, Field *field, const CHARSET_INFO * const cs,
2871
int decimals, field_length;
2872
const char *tmp_buff;
2873
char column_type_buff[MAX_FIELD_WIDTH];
2874
String column_type(column_type_buff, sizeof(column_type_buff), cs);
2876
field->sql_type(column_type);
2877
/* DTD_IDENTIFIER column */
2878
table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs);
2879
table->field[offset + 7]->set_notnull();
2880
tmp_buff= strchr(column_type.ptr(), '(');
2881
/* DATA_TYPE column */
2882
table->field[offset]->store(column_type.ptr(),
2883
(tmp_buff ? tmp_buff - column_type.ptr() :
2884
column_type.length()), cs);
2885
is_blob= (field->type() == DRIZZLE_TYPE_BLOB);
2886
if (field->has_charset() || is_blob ||
2887
field->real_type() == DRIZZLE_TYPE_VARCHAR) // For varbinary type
2889
uint32_t octet_max_length= field->max_display_length();
2890
if (is_blob && octet_max_length != (uint32_t) 4294967295U)
2891
octet_max_length /= field->charset()->mbmaxlen;
2892
int64_t char_max_len= is_blob ?
2893
(int64_t) octet_max_length / field->charset()->mbminlen :
2894
(int64_t) octet_max_length / field->charset()->mbmaxlen;
2895
/* CHARACTER_MAXIMUM_LENGTH column*/
2896
table->field[offset + 1]->store(char_max_len, true);
2897
table->field[offset + 1]->set_notnull();
2898
/* CHARACTER_OCTET_LENGTH column */
2899
table->field[offset + 2]->store((int64_t) octet_max_length, true);
2900
table->field[offset + 2]->set_notnull();
2904
Calculate field_length and decimals.
2905
They are set to -1 if they should not be set (we should return NULL)
2908
decimals= field->decimals();
2909
switch (field->type()) {
2910
case DRIZZLE_TYPE_NEWDECIMAL:
2911
field_length= ((Field_new_decimal*) field)->precision;
2913
case DRIZZLE_TYPE_LONG:
2914
case DRIZZLE_TYPE_LONGLONG:
2915
field_length= field->max_display_length() - 1;
2917
case DRIZZLE_TYPE_DOUBLE:
2918
field_length= field->field_length;
2919
if (decimals == NOT_FIXED_DEC)
2920
decimals= -1; // return NULL
2923
field_length= decimals= -1;
2927
/* NUMERIC_PRECISION column */
2928
if (field_length >= 0)
2930
table->field[offset + 3]->store((int64_t) field_length, true);
2931
table->field[offset + 3]->set_notnull();
2933
/* NUMERIC_SCALE column */
2936
table->field[offset + 4]->store((int64_t) decimals, true);
2937
table->field[offset + 4]->set_notnull();
2939
if (field->has_charset())
2941
/* CHARACTER_SET_NAME column*/
2942
tmp_buff= field->charset()->csname;
2943
table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs);
2944
table->field[offset + 5]->set_notnull();
2945
/* COLLATION_NAME column */
2946
tmp_buff= field->charset()->name;
2947
table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs);
2948
table->field[offset + 6]->set_notnull();
2953
static int get_schema_column_record(Session *session, TableList *tables,
2954
Table *table, bool res,
2955
LEX_STRING *db_name,
2956
LEX_STRING *table_name)
2958
LEX *lex= session->lex;
2959
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
2960
const CHARSET_INFO * const cs= system_charset_info;
2962
TableShare *show_table_share;
2963
Field **ptr, *field, *timestamp_field;
2968
if (lex->sql_command != SQLCOM_SHOW_FIELDS)
2971
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
2972
rather than in SHOW COLUMNS
2974
if (session->is_error())
2975
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2976
session->main_da.sql_errno(), session->main_da.message());
2977
session->clear_error();
2983
show_table= tables->table;
2984
show_table_share= show_table->s;
2987
if (tables->schema_table)
2989
ptr= show_table->field;
2990
timestamp_field= show_table->timestamp_field;
2991
show_table->use_all_columns(); // Required for default
2995
ptr= show_table_share->field;
2996
timestamp_field= show_table_share->timestamp_field;
2998
read_set may be inited in case of
3001
if (!show_table->read_set)
3003
/* to satisfy 'field->val_str' ASSERTs */
3004
unsigned char *bitmaps;
3005
uint32_t bitmap_size= show_table_share->column_bitmap_size;
3006
if (!(bitmaps= (unsigned char*) alloc_root(session->mem_root, bitmap_size)))
3008
bitmap_init(&show_table->def_read_set,
3009
(my_bitmap_map*) bitmaps, show_table_share->fields, false);
3010
bitmap_set_all(&show_table->def_read_set);
3011
show_table->read_set= &show_table->def_read_set;
3013
show_table->setReadSet();
3016
for (; (field= *ptr) ; ptr++)
3019
char tmp[MAX_FIELD_WIDTH];
3020
String type(tmp,sizeof(tmp), system_charset_info);
3023
/* to satisfy 'field->val_str' ASSERTs */
3024
field->table= show_table;
3025
show_table->in_use= session;
3027
if (wild && wild[0] &&
3028
wild_case_compare(system_charset_info, field->field_name,wild))
3032
/* Get default row, with all NULL fields set to NULL */
3033
table->restoreRecordAsDefault();
3035
table->field[1]->store(db_name->str, db_name->length, cs);
3036
table->field[2]->store(table_name->str, table_name->length, cs);
3037
table->field[3]->store(field->field_name, strlen(field->field_name),
3039
table->field[4]->store((int64_t) count, true);
3041
if (get_field_default_value(timestamp_field, field, &type, 0))
3043
table->field[5]->store(type.ptr(), type.length(), cs);
3044
table->field[5]->set_notnull();
3046
pos=(unsigned char*) ((field->flags & NOT_NULL_FLAG) ? "NO" : "YES");
3047
table->field[6]->store((const char*) pos,
3048
strlen((const char*) pos), cs);
3049
store_column_type(table, field, cs, 7);
3051
pos=(unsigned char*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
3052
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
3053
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
3054
table->field[15]->store((const char*) pos,
3055
strlen((const char*) pos), cs);
3058
if (field->unireg_check == Field::NEXT_NUMBER)
3059
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
3060
if (timestamp_field == field &&
3061
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3062
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3064
table->field[18]->store(field->comment.str, field->comment.length, cs);
3066
enum column_format_type column_format= (enum column_format_type)
3067
((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
3068
pos=(unsigned char*)"Default";
3069
table->field[19]->store((const char*) pos,
3070
strlen((const char*) pos), cs);
3071
pos=(unsigned char*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
3072
column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
3074
table->field[20]->store((const char*) pos,
3075
strlen((const char*) pos), cs);
3077
if (schema_table_store_record(session, table))
3085
int fill_schema_charsets(Session *session, TableList *tables, COND *)
3088
const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3089
Table *table= tables->table;
3090
const CHARSET_INFO * const scs= system_charset_info;
3092
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3094
const CHARSET_INFO * const tmp_cs= cs[0];
3095
if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
3096
(tmp_cs->state & MY_CS_AVAILABLE) &&
3097
!(tmp_cs->state & MY_CS_HIDDEN) &&
3098
!(wild && wild[0] &&
3099
wild_case_compare(scs, tmp_cs->csname,wild)))
3101
const char *comment;
3102
table->restoreRecordAsDefault();
3103
table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3104
table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3105
comment= tmp_cs->comment ? tmp_cs->comment : "";
3106
table->field[2]->store(comment, strlen(comment), scs);
3107
table->field[3]->store((int64_t) tmp_cs->mbmaxlen, true);
3108
if (schema_table_store_record(session, table))
3116
int fill_schema_collation(Session *session, TableList *tables, COND *)
3119
const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3120
Table *table= tables->table;
3121
const CHARSET_INFO * const scs= system_charset_info;
3122
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3125
const CHARSET_INFO *tmp_cs= cs[0];
3126
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3127
(tmp_cs->state & MY_CS_HIDDEN) ||
3128
!(tmp_cs->state & MY_CS_PRIMARY))
3130
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3132
const CHARSET_INFO *tmp_cl= cl[0];
3133
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3134
!my_charset_same(tmp_cs, tmp_cl))
3136
if (!(wild && wild[0] &&
3137
wild_case_compare(scs, tmp_cl->name,wild)))
3139
const char *tmp_buff;
3140
table->restoreRecordAsDefault();
3141
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3142
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3143
table->field[2]->store((int64_t) tmp_cl->number, true);
3144
tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
3145
table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
3146
tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
3147
table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
3148
table->field[5]->store((int64_t) tmp_cl->strxfrm_multiply, true);
3149
if (schema_table_store_record(session, table))
3158
int fill_schema_coll_charset_app(Session *session, TableList *tables, COND *)
3161
Table *table= tables->table;
3162
const CHARSET_INFO * const scs= system_charset_info;
3163
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3166
const CHARSET_INFO *tmp_cs= cs[0];
3167
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3168
!(tmp_cs->state & MY_CS_PRIMARY))
3170
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3172
const CHARSET_INFO *tmp_cl= cl[0];
3173
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3174
!my_charset_same(tmp_cs,tmp_cl))
3176
table->restoreRecordAsDefault();
3177
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3178
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3179
if (schema_table_store_record(session, table))
3187
static int get_schema_stat_record(Session *session, TableList *tables,
3188
Table *table, bool res,
3189
LEX_STRING *db_name,
3190
LEX_STRING *table_name)
3192
const CHARSET_INFO * const cs= system_charset_info;
3195
if (session->lex->sql_command != SQLCOM_SHOW_KEYS)
3198
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
3199
rather than in SHOW KEYS
3201
if (session->is_error())
3202
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3203
session->main_da.sql_errno(), session->main_da.message());
3204
session->clear_error();
3211
Table *show_table= tables->table;
3212
KEY *key_info=show_table->s->key_info;
3213
if (show_table->file)
3214
show_table->file->info(HA_STATUS_VARIABLE |
3217
for (uint32_t i=0 ; i < show_table->s->keys ; i++,key_info++)
3219
KEY_PART_INFO *key_part= key_info->key_part;
3221
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
3223
table->restoreRecordAsDefault();
3224
table->field[1]->store(db_name->str, db_name->length, cs);
3225
table->field[2]->store(table_name->str, table_name->length, cs);
3226
table->field[3]->store((int64_t) ((key_info->flags &
3227
HA_NOSAME) ? 0 : 1), true);
3228
table->field[4]->store(db_name->str, db_name->length, cs);
3229
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
3230
table->field[6]->store((int64_t) (j+1), true);
3231
str=(key_part->field ? key_part->field->field_name :
3233
table->field[7]->store(str, strlen(str), cs);
3234
if (show_table->file)
3236
if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
3238
table->field[8]->store(((key_part->key_part_flag &
3241
table->field[8]->set_notnull();
3243
KEY *key=show_table->key_info+i;
3244
if (key->rec_per_key[j])
3246
ha_rows records=(show_table->file->stats.records /
3247
key->rec_per_key[j]);
3248
table->field[9]->store((int64_t) records, true);
3249
table->field[9]->set_notnull();
3251
str= show_table->file->index_type(i);
3252
table->field[13]->store(str, strlen(str), cs);
3254
if ((key_part->field &&
3256
show_table->s->field[key_part->fieldnr-1]->key_length()))
3258
table->field[10]->store((int64_t) key_part->length /
3259
key_part->field->charset()->mbmaxlen, true);
3260
table->field[10]->set_notnull();
3262
uint32_t flags= key_part->field ? key_part->field->flags : 0;
3263
const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3264
table->field[12]->store(pos, strlen(pos), cs);
3265
if (!show_table->s->keys_in_use.test(i))
3266
table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3268
table->field[14]->store("", 0, cs);
3269
table->field[14]->set_notnull();
3270
assert(test(key_info->flags & HA_USES_COMMENT) ==
3271
(key_info->comment.length > 0));
3272
if (key_info->flags & HA_USES_COMMENT)
3273
table->field[15]->store(key_info->comment.str,
3274
key_info->comment.length, cs);
3275
if (schema_table_store_record(session, table))
3284
bool store_constraints(Session *session, Table *table, LEX_STRING *db_name,
3285
LEX_STRING *table_name, const char *key_name,
3286
uint32_t key_len, const char *con_type, uint32_t con_len)
3288
const CHARSET_INFO * const cs= system_charset_info;
3289
table->restoreRecordAsDefault();
3290
table->field[1]->store(db_name->str, db_name->length, cs);
3291
table->field[2]->store(key_name, key_len, cs);
3292
table->field[3]->store(db_name->str, db_name->length, cs);
3293
table->field[4]->store(table_name->str, table_name->length, cs);
3294
table->field[5]->store(con_type, con_len, cs);
3295
return schema_table_store_record(session, table);
3299
static int get_schema_constraints_record(Session *session, TableList *tables,
3300
Table *table, bool res,
3301
LEX_STRING *db_name,
3302
LEX_STRING *table_name)
3306
if (session->is_error())
3307
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3308
session->main_da.sql_errno(), session->main_da.message());
3309
session->clear_error();
3314
List<FOREIGN_KEY_INFO> f_key_list;
3315
Table *show_table= tables->table;
3316
KEY *key_info=show_table->key_info;
3317
uint32_t primary_key= show_table->s->primary_key;
3318
show_table->file->info(HA_STATUS_VARIABLE |
3321
for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3323
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3326
if (i == primary_key && is_primary_key(key_info))
3328
if (store_constraints(session, table, db_name, table_name, key_info->name,
3329
strlen(key_info->name),
3330
STRING_WITH_LEN("PRIMARY KEY")))
3333
else if (key_info->flags & HA_NOSAME)
3335
if (store_constraints(session, table, db_name, table_name, key_info->name,
3336
strlen(key_info->name),
3337
STRING_WITH_LEN("UNIQUE")))
3342
show_table->file->get_foreign_key_list(session, &f_key_list);
3343
FOREIGN_KEY_INFO *f_key_info;
3344
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3345
while ((f_key_info=it++))
3347
if (store_constraints(session, table, db_name, table_name,
3348
f_key_info->forein_id->str,
3349
strlen(f_key_info->forein_id->str),
3358
void store_key_column_usage(Table *table, LEX_STRING *db_name,
3359
LEX_STRING *table_name, const char *key_name,
3360
uint32_t key_len, const char *con_type, uint32_t con_len,
3363
const CHARSET_INFO * const cs= system_charset_info;
3364
table->field[1]->store(db_name->str, db_name->length, cs);
3365
table->field[2]->store(key_name, key_len, cs);
3366
table->field[4]->store(db_name->str, db_name->length, cs);
3367
table->field[5]->store(table_name->str, table_name->length, cs);
3368
table->field[6]->store(con_type, con_len, cs);
3369
table->field[7]->store((int64_t) idx, true);
3373
static int get_schema_key_column_usage_record(Session *session,
3375
Table *table, bool res,
3376
LEX_STRING *db_name,
3377
LEX_STRING *table_name)
3381
if (session->is_error())
3382
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3383
session->main_da.sql_errno(), session->main_da.message());
3384
session->clear_error();
3389
List<FOREIGN_KEY_INFO> f_key_list;
3390
Table *show_table= tables->table;
3391
KEY *key_info=show_table->key_info;
3392
uint32_t primary_key= show_table->s->primary_key;
3393
show_table->file->info(HA_STATUS_VARIABLE |
3396
for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3398
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3401
KEY_PART_INFO *key_part= key_info->key_part;
3402
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
3404
if (key_part->field)
3407
table->restoreRecordAsDefault();
3408
store_key_column_usage(table, db_name, table_name,
3410
strlen(key_info->name),
3411
key_part->field->field_name,
3412
strlen(key_part->field->field_name),
3414
if (schema_table_store_record(session, table))
3420
show_table->file->get_foreign_key_list(session, &f_key_list);
3421
FOREIGN_KEY_INFO *f_key_info;
3422
List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
3423
while ((f_key_info= fkey_it++))
3427
List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
3428
it1(f_key_info->referenced_fields);
3430
while ((f_info= it++))
3434
table->restoreRecordAsDefault();
3435
store_key_column_usage(table, db_name, table_name,
3436
f_key_info->forein_id->str,
3437
f_key_info->forein_id->length,
3438
f_info->str, f_info->length,
3440
table->field[8]->store((int64_t) f_idx, true);
3441
table->field[8]->set_notnull();
3442
table->field[9]->store(f_key_info->referenced_db->str,
3443
f_key_info->referenced_db->length,
3444
system_charset_info);
3445
table->field[9]->set_notnull();
3446
table->field[10]->store(f_key_info->referenced_table->str,
3447
f_key_info->referenced_table->length,
3448
system_charset_info);
3449
table->field[10]->set_notnull();
3450
table->field[11]->store(r_info->str, r_info->length,
3451
system_charset_info);
3452
table->field[11]->set_notnull();
3453
if (schema_table_store_record(session, table))
3462
int fill_open_tables(Session *session, TableList *tables, COND *)
3464
const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3465
Table *table= tables->table;
3466
const CHARSET_INFO * const cs= system_charset_info;
3467
OPEN_TableList *open_list;
3468
if (!(open_list=list_open_tables(session->lex->select_lex.db, wild))
3469
&& session->is_fatal_error)
3472
for (; open_list ; open_list=open_list->next)
3474
table->restoreRecordAsDefault();
3475
table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3476
table->field[1]->store(open_list->table, strlen(open_list->table), cs);
3477
table->field[2]->store((int64_t) open_list->in_use, true);
3478
table->field[3]->store((int64_t) open_list->locked, true);
3479
if (schema_table_store_record(session, table))
3486
int fill_variables(Session *session, TableList *tables, COND *)
3489
LEX *lex= session->lex;
3490
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3491
enum enum_schema_tables schema_table_idx=
3492
get_schema_table_idx(tables->schema_table);
3493
enum enum_var_type option_type= OPT_SESSION;
3494
bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
3495
bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
3497
if (lex->option_type == OPT_GLOBAL ||
3498
schema_table_idx == SCH_GLOBAL_VARIABLES)
3499
option_type= OPT_GLOBAL;
3501
pthread_rwlock_rdlock(&LOCK_system_variables_hash);
3502
res= show_status_array(session, wild, enumerate_sys_vars(session, sorted_vars),
3503
option_type, NULL, "", tables->table, upper_case_names);
3504
pthread_rwlock_unlock(&LOCK_system_variables_hash);
3509
int fill_status(Session *session, TableList *tables, COND *)
3511
LEX *lex= session->lex;
3512
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3514
STATUS_VAR *tmp1, tmp;
3515
enum enum_schema_tables schema_table_idx=
3516
get_schema_table_idx(tables->schema_table);
3517
enum enum_var_type option_type;
3518
bool upper_case_names= (schema_table_idx != SCH_STATUS);
3520
if (schema_table_idx == SCH_STATUS)
3522
option_type= lex->option_type;
3523
if (option_type == OPT_GLOBAL)
3526
tmp1= session->initial_status_var;
3528
else if (schema_table_idx == SCH_GLOBAL_STATUS)
3530
option_type= OPT_GLOBAL;
3535
option_type= OPT_SESSION;
3536
tmp1= &session->status_var;
3539
pthread_mutex_lock(&LOCK_status);
3540
if (option_type == OPT_GLOBAL)
3541
calc_sum_of_all_status(&tmp);
3542
res= show_status_array(session, wild,
3543
(SHOW_VAR *) all_status_vars.front(),
3544
option_type, tmp1, "", tables->table,
3546
pthread_mutex_unlock(&LOCK_status);
3552
Fill and store records into I_S.referential_constraints table
3555
get_referential_constraints_record()
3556
session thread handle
3557
tables table list struct(processed table)
3559
res 1 means the error during opening of the processed table
3560
0 means processed table is opened without error
3562
file_name table name
3570
get_referential_constraints_record(Session *session, TableList *tables,
3571
Table *table, bool res,
3572
LEX_STRING *db_name, LEX_STRING *table_name)
3574
const CHARSET_INFO * const cs= system_charset_info;
3578
if (session->is_error())
3579
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3580
session->main_da.sql_errno(), session->main_da.message());
3581
session->clear_error();
3586
List<FOREIGN_KEY_INFO> f_key_list;
3587
Table *show_table= tables->table;
3588
show_table->file->info(HA_STATUS_VARIABLE |
3592
show_table->file->get_foreign_key_list(session, &f_key_list);
3593
FOREIGN_KEY_INFO *f_key_info;
3594
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3595
while ((f_key_info= it++))
3597
table->restoreRecordAsDefault();
3598
table->field[1]->store(db_name->str, db_name->length, cs);
3599
table->field[9]->store(table_name->str, table_name->length, cs);
3600
table->field[2]->store(f_key_info->forein_id->str,
3601
f_key_info->forein_id->length, cs);
3602
table->field[4]->store(f_key_info->referenced_db->str,
3603
f_key_info->referenced_db->length, cs);
3604
table->field[10]->store(f_key_info->referenced_table->str,
3605
f_key_info->referenced_table->length, cs);
3606
if (f_key_info->referenced_key_name)
3608
table->field[5]->store(f_key_info->referenced_key_name->str,
3609
f_key_info->referenced_key_name->length, cs);
3610
table->field[5]->set_notnull();
3613
table->field[5]->set_null();
3614
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3615
table->field[7]->store(f_key_info->update_method->str,
3616
f_key_info->update_method->length, cs);
3617
table->field[8]->store(f_key_info->delete_method->str,
3618
f_key_info->delete_method->length, cs);
3619
if (schema_table_store_record(session, table))
3627
class FindSchemaTableByName : public unary_function<InfoSchemaTable *, bool>
3629
const char *table_name;
3631
FindSchemaTableByName(const char *table_name_arg)
3632
: table_name(table_name_arg) {}
3633
result_type operator() (argument_type schema_table)
3635
return !my_strcasecmp(system_charset_info,
3636
schema_table->table_name,
3643
Find schema_tables elment by name
3647
table_name table name
3651
# pointer to 'schema_tables' element
3654
InfoSchemaTable *find_schema_table(const char* table_name)
3656
InfoSchemaTable *schema_table= schema_tables;
3658
for (; schema_table->table_name; schema_table++)
3660
if (!my_strcasecmp(system_charset_info,
3661
schema_table->table_name,
3663
return(schema_table);
3666
vector<InfoSchemaTable *>::iterator iter=
3667
find_if(all_schema_tables.begin(), all_schema_tables.end(),
3668
FindSchemaTableByName(table_name));
3669
if (iter != all_schema_tables.end())
3675
InfoSchemaTable *get_schema_table(enum enum_schema_tables schema_table_idx)
3677
return &schema_tables[schema_table_idx];
3682
Create information_schema table using schema_table data.
3687
session thread handler
3689
@param table_list Used to pass I_S table information(fields info, tables
3690
parameters etc) and table name.
3692
@retval \# Pointer to created table
3693
@retval NULL Can't create table
3696
Table *create_schema_table(Session *session, TableList *table_list)
3701
List<Item> field_list;
3702
InfoSchemaTable *schema_table= table_list->schema_table;
3703
ST_FIELD_INFO *fields_info= schema_table->fields_info;
3704
const CHARSET_INFO * const cs= system_charset_info;
3706
for (; fields_info->field_name; fields_info++)
3708
switch (fields_info->field_type) {
3709
case DRIZZLE_TYPE_LONG:
3710
case DRIZZLE_TYPE_LONGLONG:
3711
if (!(item= new Item_return_int(fields_info->field_name,
3712
fields_info->field_length,
3713
fields_info->field_type,
3714
fields_info->value)))
3718
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3720
case DRIZZLE_TYPE_DATE:
3721
case DRIZZLE_TYPE_TIMESTAMP:
3722
case DRIZZLE_TYPE_DATETIME:
3723
if (!(item=new Item_return_date_time(fields_info->field_name,
3724
fields_info->field_type)))
3729
case DRIZZLE_TYPE_DOUBLE:
3730
if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
3731
fields_info->field_length)) == NULL)
3734
case DRIZZLE_TYPE_NEWDECIMAL:
3735
if (!(item= new Item_decimal((int64_t) fields_info->value, false)))
3739
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3740
item->decimals= fields_info->field_length%10;
3741
item->max_length= (fields_info->field_length/100)%100;
3742
if (item->unsigned_flag == 0)
3743
item->max_length+= 1;
3744
if (item->decimals > 0)
3745
item->max_length+= 1;
3746
item->set_name(fields_info->field_name,
3747
strlen(fields_info->field_name), cs);
3749
case DRIZZLE_TYPE_BLOB:
3750
if (!(item= new Item_blob(fields_info->field_name,
3751
fields_info->field_length)))
3757
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
3761
item->set_name(fields_info->field_name,
3762
strlen(fields_info->field_name), cs);
3765
field_list.push_back(item);
3766
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
3769
Tmp_Table_Param *tmp_table_param =
3770
(Tmp_Table_Param*) (session->alloc(sizeof(Tmp_Table_Param)));
3771
tmp_table_param->init();
3772
tmp_table_param->table_charset= cs;
3773
tmp_table_param->field_count= field_count;
3774
tmp_table_param->schema_table= 1;
3775
Select_Lex *select_lex= session->lex->current_select;
3776
if (!(table= create_tmp_table(session, tmp_table_param,
3777
field_list, (order_st*) 0, 0, 0,
3778
(select_lex->options | session->options |
3779
TMP_TABLE_ALL_COLUMNS),
3780
HA_POS_ERROR, table_list->alias)))
3782
my_bitmap_map* bitmaps=
3783
(my_bitmap_map*) session->alloc(bitmap_buffer_size(field_count));
3784
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
3786
table->read_set= &table->def_read_set;
3787
bitmap_clear_all(table->read_set);
3788
table_list->schema_table_param= tmp_table_param;
3794
For old SHOW compatibility. It is used when
3795
old SHOW doesn't have generated column names
3796
Make list of fields for SHOW
3800
session thread handler
3801
schema_table pointer to 'schema_tables' element
3808
int make_old_format(Session *session, InfoSchemaTable *schema_table)
3810
ST_FIELD_INFO *field_info= schema_table->fields_info;
3811
Name_resolution_context *context= &session->lex->select_lex.context;
3812
for (; field_info->field_name; field_info++)
3814
if (field_info->old_name)
3816
Item_field *field= new Item_field(context,
3817
NULL, NULL, field_info->field_name);
3820
field->set_name(field_info->old_name,
3821
strlen(field_info->old_name),
3822
system_charset_info);
3823
if (session->add_item_to_list(field))
3832
int make_schemata_old_format(Session *session, InfoSchemaTable *schema_table)
3835
LEX *lex= session->lex;
3836
Select_Lex *sel= lex->current_select;
3837
Name_resolution_context *context= &sel->context;
3839
if (!sel->item_list.elements)
3841
ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
3842
String buffer(tmp,sizeof(tmp), system_charset_info);
3843
Item_field *field= new Item_field(context,
3844
NULL, NULL, field_info->field_name);
3845
if (!field || session->add_item_to_list(field))
3848
buffer.append(field_info->old_name);
3849
if (lex->wild && lex->wild->ptr())
3851
buffer.append(STRING_WITH_LEN(" ("));
3852
buffer.append(lex->wild->ptr());
3855
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
3861
int make_table_names_old_format(Session *session, InfoSchemaTable *schema_table)
3864
String buffer(tmp,sizeof(tmp), session->charset());
3865
LEX *lex= session->lex;
3866
Name_resolution_context *context= &lex->select_lex.context;
3868
ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
3870
buffer.append(field_info->old_name);
3871
buffer.append(lex->select_lex.db);
3872
if (lex->wild && lex->wild->ptr())
3874
buffer.append(STRING_WITH_LEN(" ("));
3875
buffer.append(lex->wild->ptr());
3878
Item_field *field= new Item_field(context,
3879
NULL, NULL, field_info->field_name);
3880
if (session->add_item_to_list(field))
3882
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
3883
if (session->lex->verbose)
3885
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
3886
field_info= &schema_table->fields_info[3];
3887
field= new Item_field(context, NULL, NULL, field_info->field_name);
3888
if (session->add_item_to_list(field))
3890
field->set_name(field_info->old_name, strlen(field_info->old_name),
3891
system_charset_info);
3897
int make_columns_old_format(Session *session, InfoSchemaTable *schema_table)
3899
int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
3900
int *field_num= fields_arr;
3901
ST_FIELD_INFO *field_info;
3902
Name_resolution_context *context= &session->lex->select_lex.context;
3904
for (; *field_num >= 0; field_num++)
3906
field_info= &schema_table->fields_info[*field_num];
3907
if (!session->lex->verbose && (*field_num == 13 ||
3911
Item_field *field= new Item_field(context,
3912
NULL, NULL, field_info->field_name);
3915
field->set_name(field_info->old_name,
3916
strlen(field_info->old_name),
3917
system_charset_info);
3918
if (session->add_item_to_list(field))
3926
int make_character_sets_old_format(Session *session, InfoSchemaTable *schema_table)
3928
int fields_arr[]= {0, 2, 1, 3, -1};
3929
int *field_num= fields_arr;
3930
ST_FIELD_INFO *field_info;
3931
Name_resolution_context *context= &session->lex->select_lex.context;
3933
for (; *field_num >= 0; field_num++)
3935
field_info= &schema_table->fields_info[*field_num];
3936
Item_field *field= new Item_field(context,
3937
NULL, NULL, field_info->field_name);
3940
field->set_name(field_info->old_name,
3941
strlen(field_info->old_name),
3942
system_charset_info);
3943
if (session->add_item_to_list(field))
3952
Create information_schema table
3955
mysql_schema_table()
3956
session thread handler
3958
table_list pointer to table_list
3964
bool mysql_schema_table(Session *session, LEX *, TableList *table_list)
3967
if (!(table= table_list->schema_table->create_table(session, table_list)))
3969
table->s->tmp_table= SYSTEM_TMP_TABLE;
3971
This test is necessary to make
3972
case insensitive file systems +
3973
upper case table names(information schema tables) +
3977
if (table_list->schema_table_name)
3978
table->alias_name_used= my_strcasecmp(table_alias_charset,
3979
table_list->schema_table_name,
3981
table_list->table_name= table->s->table_name.str;
3982
table_list->table_name_length= table->s->table_name.length;
3983
table_list->table= table;
3984
table->next= session->derived_tables;
3985
session->derived_tables= table;
3986
table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
3993
Generate select from information_schema table
3996
make_schema_select()
3997
session thread handler
3998
sel pointer to Select_Lex
3999
schema_table_idx index of 'schema_tables' element
4005
bool make_schema_select(Session *session, Select_Lex *sel,
4006
enum enum_schema_tables schema_table_idx)
4008
InfoSchemaTable *schema_table= get_schema_table(schema_table_idx);
4009
LEX_STRING db, table;
4011
We have to make non const db_name & table_name
4012
because of lower_case_table_names
4014
session->make_lex_string(&db, INFORMATION_SCHEMA_NAME.c_str(),
4015
INFORMATION_SCHEMA_NAME.length(), 0);
4016
session->make_lex_string(&table, schema_table->table_name,
4017
strlen(schema_table->table_name), 0);
4018
if (schema_table->old_format(session, schema_table) || /* Handle old syntax */
4019
!sel->add_table_to_list(session, new Table_ident(session, db, table, 0),
4029
Fill temporary schema tables before SELECT
4032
get_schema_tables_result()
4033
join join which use schema tables
4034
executed_place place where I_S table processed
4041
bool get_schema_tables_result(JOIN *join,
4042
enum enum_schema_table_state executed_place)
4044
JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
4045
Session *session= join->session;
4046
LEX *lex= session->lex;
4049
session->no_warnings_for_error= 1;
4050
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
4052
if (!tab->table || !tab->table->pos_in_table_list)
4055
TableList *table_list= tab->table->pos_in_table_list;
4056
if (table_list->schema_table)
4058
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
4059
lex->current_select->master_unit()->item);
4062
/* skip I_S optimizations specific to get_all_tables */
4063
if (session->lex->describe &&
4064
(table_list->schema_table->fill_table != get_all_tables))
4068
If schema table is already processed and
4069
the statement is not a subselect then
4070
we don't need to fill this table again.
4071
If schema table is already processed and
4072
schema_table_state != executed_place then
4073
table is already processed and
4074
we should skip second data processing.
4076
if (table_list->schema_table_state &&
4077
(!is_subselect || table_list->schema_table_state != executed_place))
4081
if table is used in a subselect and
4082
table has been processed earlier with the same
4083
'executed_place' value then we should refresh the table.
4085
if (table_list->schema_table_state && is_subselect)
4087
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
4088
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
4089
table_list->table->file->ha_delete_all_rows();
4090
free_io_cache(table_list->table);
4091
filesort_free_buffers(table_list->table,1);
4092
table_list->table->null_row= 0;
4095
table_list->table->file->stats.records= 0;
4097
if (table_list->schema_table->fill_table(session, table_list,
4102
tab->read_record.file= table_list->table->file;
4103
table_list->schema_table_state= executed_place;
4106
tab->read_record.file= table_list->table->file;
4107
table_list->schema_table_state= executed_place;
4110
session->no_warnings_for_error= 0;
4114
ST_FIELD_INFO schema_fields_info[]=
4116
{"CATALOG_NAME", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4117
{"SCHEMA_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4119
{"DEFAULT_CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4121
{"DEFAULT_COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4122
{"SQL_PATH", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4123
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4127
ST_FIELD_INFO tables_fields_info[]=
4129
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4130
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4131
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4133
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4134
{"ENGINE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Engine", OPEN_FRM_ONLY},
4135
{"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4136
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
4137
{"ROW_FORMAT", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Row_format", OPEN_FULL_TABLE},
4138
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4139
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
4140
{"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4141
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
4142
{"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4143
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
4144
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4145
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
4146
{"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4147
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
4148
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4149
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
4150
{"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG, 0,
4151
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
4152
{"CREATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4153
{"UPDATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4154
{"CHECK_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
4155
{"TABLE_COLLATION", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4156
{"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4157
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
4158
{"CREATE_OPTIONS", 255, DRIZZLE_TYPE_VARCHAR, 0, 1, "Create_options",
4160
{"TABLE_COMMENT", TABLE_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4161
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4165
ST_FIELD_INFO columns_fields_info[]=
4167
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4168
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4169
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4170
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Field",
4172
{"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4173
MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
4174
{"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, DRIZZLE_TYPE_VARCHAR, 0,
4175
1, "Default", OPEN_FRM_ONLY},
4176
{"IS_NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4177
{"DATA_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4178
{"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4179
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4180
{"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4181
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4182
{"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4183
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4184
{"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4185
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4186
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4187
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4188
{"COLUMN_TYPE", 65535, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", OPEN_FRM_ONLY},
4189
{"COLUMN_KEY", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key", OPEN_FRM_ONLY},
4190
{"EXTRA", 27, DRIZZLE_TYPE_VARCHAR, 0, 0, "Extra", OPEN_FRM_ONLY},
4191
{"PRIVILEGES", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Privileges", OPEN_FRM_ONLY},
4192
{"COLUMN_COMMENT", COLUMN_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4193
{"STORAGE", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Storage", OPEN_FRM_ONLY},
4194
{"FORMAT", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Format", OPEN_FRM_ONLY},
4195
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4199
ST_FIELD_INFO charsets_fields_info[]=
4201
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4203
{"DEFAULT_COLLATE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default collation",
4205
{"DESCRIPTION", 60, DRIZZLE_TYPE_VARCHAR, 0, 0, "Description",
4207
{"MAXLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
4208
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4212
ST_FIELD_INFO collation_fields_info[]=
4214
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Collation", SKIP_OPEN_TABLE},
4215
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4217
{"ID", MY_INT32_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id",
4219
{"IS_DEFAULT", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default", SKIP_OPEN_TABLE},
4220
{"IS_COMPILED", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Compiled", SKIP_OPEN_TABLE},
4221
{"SORTLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
4222
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4227
ST_FIELD_INFO coll_charset_app_fields_info[]=
4229
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4230
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4231
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4235
ST_FIELD_INFO stat_fields_info[]=
4237
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4238
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4239
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", OPEN_FRM_ONLY},
4240
{"NON_UNIQUE", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
4241
{"INDEX_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4242
{"INDEX_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key_name",
4244
{"SEQ_IN_INDEX", 2, DRIZZLE_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
4245
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Column_name",
4247
{"COLLATION", 1, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4248
{"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 1,
4249
"Cardinality", OPEN_FULL_TABLE},
4250
{"SUB_PART", 3, DRIZZLE_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
4251
{"PACKED", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Packed", OPEN_FRM_ONLY},
4252
{"NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4253
{"INDEX_TYPE", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_type", OPEN_FULL_TABLE},
4254
{"COMMENT", 16, DRIZZLE_TYPE_VARCHAR, 0, 1, "Comment", OPEN_FRM_ONLY},
4255
{"INDEX_COMMENT", INDEX_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_Comment", OPEN_FRM_ONLY},
4256
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4260
ST_FIELD_INFO table_constraints_fields_info[]=
4262
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4263
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4265
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4267
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4268
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4269
{"CONSTRAINT_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4271
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4275
ST_FIELD_INFO key_column_usage_fields_info[]=
4277
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4278
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4280
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4282
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4283
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4284
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4285
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4286
{"ORDINAL_POSITION", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
4287
{"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 1, 0,
4289
{"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4291
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4293
{"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4295
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4299
ST_FIELD_INFO table_names_fields_info[]=
4301
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4302
{"TABLE_SCHEMA",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4303
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Tables_in_",
4305
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table_type",
4307
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4311
ST_FIELD_INFO open_tables_fields_info[]=
4313
{"Database", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4315
{"Table",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", SKIP_OPEN_TABLE},
4316
{"In_use", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
4317
{"Name_locked", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
4318
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4322
ST_FIELD_INFO variables_fields_info[]=
4324
{"VARIABLE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Variable_name",
4326
{"VARIABLE_VALUE", 16300, DRIZZLE_TYPE_VARCHAR, 0, 1, "Value", SKIP_OPEN_TABLE},
4327
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4331
ST_FIELD_INFO processlist_fields_info[]=
4333
{"ID", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
4334
{"USER", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "User", SKIP_OPEN_TABLE},
4335
{"HOST", LIST_PROCESS_HOST_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Host",
4337
{"DB", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Db", SKIP_OPEN_TABLE},
4338
{"COMMAND", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Command", SKIP_OPEN_TABLE},
4339
{"TIME", 7, DRIZZLE_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
4340
{"STATE", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "State", SKIP_OPEN_TABLE},
4341
{"INFO", PROCESS_LIST_INFO_WIDTH, DRIZZLE_TYPE_VARCHAR, 0, 1, "Info",
4343
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4347
ST_FIELD_INFO plugin_fields_info[]=
4349
{"PLUGIN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4351
{"PLUGIN_VERSION", 20, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4352
{"PLUGIN_STATUS", 10, DRIZZLE_TYPE_VARCHAR, 0, 0, "Status", SKIP_OPEN_TABLE},
4353
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4354
{"PLUGIN_DESCRIPTION", 65535, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4355
{"PLUGIN_LICENSE", 80, DRIZZLE_TYPE_VARCHAR, 0, 1, "License", SKIP_OPEN_TABLE},
4356
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4359
ST_FIELD_INFO referential_constraints_fields_info[]=
4361
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4362
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4364
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4366
{"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4368
{"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4370
{"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0,
4371
MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
4372
{"MATCH_OPTION", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4373
{"UPDATE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4374
{"DELETE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4375
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4376
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4378
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4383
Description of ST_FIELD_INFO in table.h
4385
Make sure that the order of schema_tables and enum_schema_tables are the same.
4389
InfoSchemaTable schema_tables[]=
4391
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
4392
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4393
{"COLLATIONS", collation_fields_info, create_schema_table,
4394
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4395
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4396
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4397
{"COLUMNS", columns_fields_info, create_schema_table,
4398
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
4399
OPTIMIZE_I_S_TABLE},
4400
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4401
fill_status, make_old_format, 0, -1, -1, 0, 0},
4402
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
4403
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4404
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
4405
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
4407
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
4408
fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
4409
{"PLUGINS", plugin_fields_info, create_schema_table,
4410
fill_plugins, make_old_format, 0, -1, -1, 0, 0},
4411
{"PROCESSLIST", processlist_fields_info, create_schema_table,
4412
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
4413
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
4414
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
4415
1, 9, 0, OPEN_TABLE_ONLY},
4416
{"SCHEMATA", schema_fields_info, create_schema_table,
4417
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
4418
{"SESSION_STATUS", variables_fields_info, create_schema_table,
4419
fill_status, make_old_format, 0, -1, -1, 0, 0},
4420
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4421
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4422
{"STATISTICS", stat_fields_info, create_schema_table,
4423
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4424
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4425
{"STATUS", variables_fields_info, create_schema_table, fill_status,
4426
make_old_format, 0, -1, -1, 1, 0},
4427
{"TABLES", tables_fields_info, create_schema_table,
4428
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4429
OPTIMIZE_I_S_TABLE},
4430
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4431
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
4432
{"TABLE_NAMES", table_names_fields_info, create_schema_table,
4433
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
4434
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
4435
make_old_format, 0, -1, -1, 1, 0},
4436
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}