146
} /* namespace drizzled */
503
/* Append directory name (if exists) to CREATE INFO */
505
static void append_directory(String *packet, const char *dir_type,
506
const char *filename)
510
uint32_t length= dirname_length(filename);
512
packet->append(dir_type);
513
packet->append(STRING_WITH_LEN(" DIRECTORY='"));
514
packet->append(filename, length);
515
packet->append('\'');
520
#define LIST_PROCESS_HOST_LEN 64
522
static bool get_field_default_value(Field *timestamp_field,
523
Field *field, String *def_value,
527
bool has_now_default;
530
We are using CURRENT_TIMESTAMP instead of NOW because it is
533
has_now_default= (timestamp_field == field &&
534
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
536
has_default= (field->type() != DRIZZLE_TYPE_BLOB &&
537
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
538
field->unireg_check != Field::NEXT_NUMBER);
540
def_value->length(0);
544
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
545
else if (!field->is_null())
546
{ // Not null by default
547
char tmp[MAX_FIELD_WIDTH];
548
String type(tmp, sizeof(tmp), field->charset());
549
field->val_str(&type);
553
uint32_t dummy_errors;
554
/* convert to system_charset_info == utf8 */
555
def_val.copy(type.ptr(), type.length(), field->charset(),
556
system_charset_info, &dummy_errors);
558
append_unescaped(def_value, def_val.ptr(), def_val.length());
560
def_value->append(def_val.ptr(), def_val.length());
563
def_value->append(STRING_WITH_LEN("''"));
565
else if (field->maybe_null() && quoted)
566
def_value->append(STRING_WITH_LEN("NULL")); // Null as default
574
Build a CREATE TABLE statement for a table.
578
table_list A list containing one table to write statement
580
packet Pointer to a string where statement will be
582
create_info_arg Pointer to create information that can be used
583
to tailor the format of the statement. Can be
584
NULL, in which case only SQL_MODE is considered
585
when building the statement.
588
Currently always return 0, but might return error code in the
595
int store_create_info(TableList *table_list, String *packet, HA_CREATE_INFO *create_info_arg)
597
List<Item> field_list;
598
char tmp[MAX_FIELD_WIDTH], *for_str, def_value_buf[MAX_FIELD_WIDTH];
601
String type(tmp, sizeof(tmp), system_charset_info);
602
String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
604
uint32_t primary_key;
606
Table *table= table_list->table;
607
handler *file= table->file;
608
TableShare *share= table->s;
609
HA_CREATE_INFO create_info;
610
bool show_table_options= false;
611
my_bitmap_map *old_map;
613
table->restoreRecordAsDefault(); // Get empty record
615
if (share->tmp_table)
616
packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
618
packet->append(STRING_WITH_LEN("CREATE TABLE "));
619
if (create_info_arg &&
620
(create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
621
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
622
if (table_list->schema_table)
623
alias= table_list->schema_table->table_name;
626
if (lower_case_table_names == 2)
629
alias= share->table_name.str;
631
packet->append_identifier(alias, strlen(alias));
632
packet->append(STRING_WITH_LEN(" (\n"));
634
We need this to get default values from the table
635
We have to restore the read_set if we are called from insert in case
636
of row based replication.
638
old_map= table->use_all_columns(table->read_set);
640
for (ptr=table->field ; (field= *ptr); ptr++)
642
uint32_t flags = field->flags;
644
if (ptr != table->field)
645
packet->append(STRING_WITH_LEN(",\n"));
647
packet->append(STRING_WITH_LEN(" "));
648
packet->append_identifier(field->field_name, strlen(field->field_name));
650
// check for surprises from the previous call to Field::sql_type()
651
if (type.ptr() != tmp)
652
type.set(tmp, sizeof(tmp), system_charset_info);
654
type.set_charset(system_charset_info);
656
field->sql_type(type);
657
packet->append(type.ptr(), type.length(), system_charset_info);
659
if (field->has_charset())
661
if (field->charset() != share->table_charset)
663
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
664
packet->append(field->charset()->csname);
668
For string types dump collation name only if
669
collation is not primary for the given charset
671
if (!(field->charset()->state & MY_CS_PRIMARY))
673
packet->append(STRING_WITH_LEN(" COLLATE "));
674
packet->append(field->charset()->name);
678
if (flags & NOT_NULL_FLAG)
679
packet->append(STRING_WITH_LEN(" NOT NULL"));
680
else if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
683
TIMESTAMP field require explicit NULL flag, because unlike
684
all other fields they are treated as NOT NULL by default.
686
packet->append(STRING_WITH_LEN(" NULL"));
690
Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
691
and about STORAGE (DISK or MEMORY).
693
enum column_format_type column_format= (enum column_format_type)
694
((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
697
packet->append(STRING_WITH_LEN(" /*!"));
698
packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
699
if (column_format == COLUMN_FORMAT_TYPE_FIXED)
700
packet->append(STRING_WITH_LEN(" FIXED */"));
702
packet->append(STRING_WITH_LEN(" DYNAMIC */"));
705
if (get_field_default_value(table->timestamp_field, field, &def_value, 1))
707
packet->append(STRING_WITH_LEN(" DEFAULT "));
708
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
711
if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
712
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
714
if (field->unireg_check == Field::NEXT_NUMBER)
715
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
717
if (field->comment.length)
719
packet->append(STRING_WITH_LEN(" COMMENT "));
720
append_unescaped(packet, field->comment.str, field->comment.length);
724
key_info= table->key_info;
725
memset(&create_info, 0, sizeof(create_info));
726
/* Allow update_create_info to update row type */
727
create_info.row_type= share->row_type;
728
file->update_create_info(&create_info);
729
primary_key= share->primary_key;
731
for (uint32_t i=0 ; i < share->keys ; i++,key_info++)
733
KEY_PART_INFO *key_part= key_info->key_part;
734
bool found_primary=0;
735
packet->append(STRING_WITH_LEN(",\n "));
737
if (i == primary_key && is_primary_key(key_info))
741
No space at end, because a space will be added after where the
742
identifier would go, but that is not added for primary key.
744
packet->append(STRING_WITH_LEN("PRIMARY KEY"));
746
else if (key_info->flags & HA_NOSAME)
747
packet->append(STRING_WITH_LEN("UNIQUE KEY "));
749
packet->append(STRING_WITH_LEN("KEY "));
752
packet->append_identifier(key_info->name, strlen(key_info->name));
754
packet->append(STRING_WITH_LEN(" ("));
756
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
762
packet->append_identifier(key_part->field->field_name,
763
strlen(key_part->field->field_name));
764
if (key_part->field &&
766
table->field[key_part->fieldnr-1]->key_length()))
769
buff.append(to_string((int32_t) key_part->length /
770
key_part->field->charset()->mbmaxlen));
772
packet->append(buff.c_str(), buff.length());
776
store_key_options(packet, table, key_info);
780
Get possible foreign key definitions stored in InnoDB and append them
781
to the CREATE TABLE statement
784
if ((for_str= file->get_foreign_key_create_info()))
786
packet->append(for_str, strlen(for_str));
787
file->free_foreign_key_create_info(for_str);
790
packet->append(STRING_WITH_LEN("\n)"));
792
show_table_options= true;
794
Get possible table space definitions and append them
795
to the CREATE TABLE statement
800
THEN add ENGINE only if it was used when creating the table
802
if (!create_info_arg ||
803
(create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
805
packet->append(STRING_WITH_LEN(" ENGINE="));
806
packet->append(file->engine->getName().c_str());
810
Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
811
and NEXT_ID > 1 (the default). We must not print the clause
812
for engines that do not support this as it would break the
813
import of dumps, but as of this writing, the test for whether
814
AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
815
is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
816
Because of that, we do not explicitly test for the feature,
817
but may extrapolate its existence from that of an AUTO_INCREMENT column.
820
if (create_info.auto_increment_value > 1)
822
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
823
buff= to_string(create_info.auto_increment_value);
824
packet->append(buff.c_str(), buff.length());
829
packet->append(STRING_WITH_LEN(" MIN_ROWS="));
830
buff= to_string(share->min_rows);
831
packet->append(buff.c_str(), buff.length());
834
if (share->max_rows && !table_list->schema_table)
836
packet->append(STRING_WITH_LEN(" MAX_ROWS="));
837
buff= to_string(share->max_rows);
838
packet->append(buff.c_str(), buff.length());
841
if (share->avg_row_length)
843
packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
844
buff= to_string(share->avg_row_length);
845
packet->append(buff.c_str(), buff.length());
848
if (share->db_create_options & HA_OPTION_PACK_KEYS)
849
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
850
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
851
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
852
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
853
if (share->db_create_options & HA_OPTION_CHECKSUM)
854
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
855
if (share->page_checksum != HA_CHOICE_UNDEF)
857
packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
858
packet->append(ha_choice_values[(uint32_t) share->page_checksum], 1);
860
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
861
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
862
if (create_info.row_type != ROW_TYPE_DEFAULT)
864
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
865
packet->append(ha_row_type[(uint32_t) create_info.row_type]);
867
if (table->s->key_block_size)
869
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
870
buff= to_string(table->s->key_block_size);
871
packet->append(buff.c_str(), buff.length());
873
if (share->block_size)
875
packet->append(STRING_WITH_LEN(" BLOCK_SIZE="));
876
buff= to_string(share->block_size);
877
packet->append(buff.c_str(), buff.length());
879
table->file->append_create_info(packet);
880
if (share->comment.length)
882
packet->append(STRING_WITH_LEN(" COMMENT="));
883
append_unescaped(packet, share->comment.str, share->comment.length);
885
if (share->connect_string.length)
887
packet->append(STRING_WITH_LEN(" CONNECTION="));
888
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
890
append_directory(packet, "DATA", create_info.data_file_name);
891
append_directory(packet, "INDEX", create_info.index_file_name);
893
table->restore_column_map(old_map);
898
Get a CREATE statement for a given database.
900
The database is identified by its name, passed as @c dbname parameter.
901
The name should be encoded using the system character set (UTF8 currently).
903
Resulting statement is stored in the string pointed by @c buffer. The string
904
is emptied first and its character set is set to the system character set.
906
If HA_LEX_CREATE_IF_NOT_EXISTS flag is set in @c create_info->options, then
907
the resulting CREATE statement contains "IF NOT EXISTS" clause. Other flags
908
in @c create_options are ignored.
910
@param session The current thread instance.
911
@param dbname The name of the database.
912
@param buffer A String instance where the statement is stored.
913
@param create_info If not NULL, the options member influences the resulting
916
@returns true if errors are detected, false otherwise.
919
bool store_db_create_info(const char *dbname, String *buffer, HA_CREATE_INFO *create_info)
921
HA_CREATE_INFO create;
922
uint32_t create_options = create_info ? create_info->options : 0;
924
if (!my_strcasecmp(system_charset_info, dbname,
925
INFORMATION_SCHEMA_NAME.c_str()))
927
dbname= INFORMATION_SCHEMA_NAME.c_str();
928
create.default_table_charset= system_charset_info;
932
if (check_db_dir_existence(dbname))
935
load_db_opt_by_name(dbname, &create);
940
buffer->set_charset(system_charset_info);
941
buffer->append(STRING_WITH_LEN("CREATE DATABASE "));
943
if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
944
buffer->append(STRING_WITH_LEN("IF NOT EXISTS "));
946
buffer->append_identifier(dbname, strlen(dbname));
951
static void store_key_options(String *packet, Table *table, KEY *key_info)
955
if (key_info->algorithm == HA_KEY_ALG_BTREE)
956
packet->append(STRING_WITH_LEN(" USING BTREE"));
958
if (key_info->algorithm == HA_KEY_ALG_HASH)
959
packet->append(STRING_WITH_LEN(" USING HASH"));
961
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
962
table->s->key_block_size != key_info->block_size)
964
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
965
end= int64_t10_to_str(key_info->block_size, buff, 10);
966
packet->append(buff, (uint32_t) (end - buff));
969
assert(test(key_info->flags & HA_USES_COMMENT) ==
970
(key_info->comment.length > 0));
971
if (key_info->flags & HA_USES_COMMENT)
973
packet->append(STRING_WITH_LEN(" COMMENT "));
974
append_unescaped(packet, key_info->comment.str,
975
key_info->comment.length);
980
/****************************************************************************
981
Return info about all processes
982
returns for each thread: thread id, user, host, db, command, info
983
****************************************************************************/
985
class thread_info :public ilink {
987
static void *operator new(size_t size)
989
return (void*) sql_alloc((uint32_t) size);
991
static void operator delete(void *, size_t)
992
{ TRASH(ptr, size); }
994
my_thread_id thread_id;
997
const char *user,*host,*db,*proc_info,*state_info;
1001
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1002
template class I_List<thread_info>;
1005
void mysqld_list_processes(Session *session,const char *user, bool)
1008
List<Item> field_list;
1009
I_List<thread_info> thread_infos;
1010
Protocol *protocol= session->protocol;
1012
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1013
field_list.push_back(new Item_empty_string("User",16));
1014
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1015
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1016
field->maybe_null= true;
1017
field_list.push_back(new Item_empty_string("Command",16));
1018
field_list.push_back(new Item_return_int("Time",7, DRIZZLE_TYPE_LONG));
1019
field_list.push_back(field=new Item_empty_string("State",30));
1020
field->maybe_null= true;
1021
field_list.push_back(field=new Item_empty_string("Info", PROCESS_LIST_WIDTH));
1022
field->maybe_null= true;
1023
if (protocol->sendFields(&field_list,
1024
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1027
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1028
if (!session->killed)
1031
for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
1034
Security_context *tmp_sctx= &tmp->security_ctx;
1035
struct st_my_thread_var *mysys_var;
1036
if (tmp->protocol->isConnected() && (!user || (tmp_sctx->user.c_str() && !strcmp(tmp_sctx->user.c_str(), user))))
1038
thread_info *session_info= new thread_info;
1040
session_info->thread_id=tmp->thread_id;
1041
session_info->user= session->strdup(tmp_sctx->user.c_str() ? tmp_sctx->user.c_str() : "unauthenticated user");
1042
session_info->host= session->strdup(tmp_sctx->ip.c_str());
1043
if ((session_info->db=tmp->db)) // Safe test
1044
session_info->db=session->strdup(session_info->db);
1045
session_info->command=(int) tmp->command;
1046
if ((mysys_var= tmp->mysys_var))
1047
pthread_mutex_lock(&mysys_var->mutex);
1049
if (tmp->killed == Session::KILL_CONNECTION)
1050
session_info->proc_info= (char*) "Killed";
1052
session_info->proc_info= command_name[session_info->command].str;
1054
session_info->state_info= (char*) (tmp->protocol->isWriting() ?
1056
tmp->protocol->isReading() ?
1057
(session_info->command == COM_SLEEP ?
1058
NULL : "Reading from net") :
1059
tmp->get_proc_info() ? tmp->get_proc_info() :
1061
tmp->mysys_var->current_cond ?
1062
"Waiting on cond" : NULL);
1064
pthread_mutex_unlock(&mysys_var->mutex);
1066
session_info->start_time= tmp->start_time;
1067
session_info->query= NULL;
1068
if (tmp->process_list_info[0])
1069
session_info->query= session->strdup(tmp->process_list_info);
1070
thread_infos.append(session_info);
1074
pthread_mutex_unlock(&LOCK_thread_count);
1076
thread_info *session_info;
1077
time_t now= time(NULL);
1078
while ((session_info=thread_infos.get()))
1080
protocol->prepareForResend();
1081
protocol->store((uint64_t) session_info->thread_id);
1082
protocol->store(session_info->user, system_charset_info);
1083
protocol->store(session_info->host, system_charset_info);
1084
protocol->store(session_info->db, system_charset_info);
1085
protocol->store(session_info->proc_info, system_charset_info);
1087
if (session_info->start_time)
1088
protocol->store((uint32_t) (now - session_info->start_time));
1092
protocol->store(session_info->state_info, system_charset_info);
1093
protocol->store(session_info->query, system_charset_info);
1095
if (protocol->write())
1096
break; /* purecov: inspected */
1102
int fill_schema_processlist(Session* session, TableList* tables, COND*)
1104
Table *table= tables->table;
1105
const CHARSET_INFO * const cs= system_charset_info;
1107
time_t now= time(NULL);
1110
if (now == (time_t)-1)
1115
pthread_mutex_lock(&LOCK_thread_count);
1117
if (!session->killed)
1121
for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
1124
Security_context *tmp_sctx= &tmp->security_ctx;
1125
struct st_my_thread_var *mysys_var;
1128
if (! tmp->protocol->isConnected())
1131
table->restoreRecordAsDefault();
1133
table->field[0]->store((int64_t) tmp->thread_id, true);
1135
val= tmp_sctx->user.c_str() ? tmp_sctx->user.c_str() : "unauthenticated user";
1136
table->field[1]->store(val, strlen(val), cs);
1138
table->field[2]->store(tmp_sctx->ip.c_str(), strlen(tmp_sctx->ip.c_str()), cs);
1142
table->field[3]->store(tmp->db, strlen(tmp->db), cs);
1143
table->field[3]->set_notnull();
1146
if ((mysys_var= tmp->mysys_var))
1147
pthread_mutex_lock(&mysys_var->mutex);
1149
if ((val= (char *) (tmp->killed == Session::KILL_CONNECTION? "Killed" : 0)))
1150
table->field[4]->store(val, strlen(val), cs);
1152
table->field[4]->store(command_name[tmp->command].str,
1153
command_name[tmp->command].length, cs);
1155
table->field[5]->store((uint32_t)(tmp->start_time ?
1156
now - tmp->start_time : 0), true);
1158
val= (char*) (tmp->protocol->isWriting() ?
1160
tmp->protocol->isReading() ?
1161
(tmp->command == COM_SLEEP ?
1162
NULL : "Reading from net") :
1163
tmp->get_proc_info() ? tmp->get_proc_info() :
1165
tmp->mysys_var->current_cond ?
1166
"Waiting on cond" : NULL);
1169
table->field[6]->store(val, strlen(val), cs);
1170
table->field[6]->set_notnull();
1174
pthread_mutex_unlock(&mysys_var->mutex);
1176
length= strlen(tmp->process_list_info);
1180
table->field[7]->store(tmp->process_list_info, length, cs);
1181
table->field[7]->set_notnull();
1184
if (schema_table_store_record(session, table))
1186
pthread_mutex_unlock(&LOCK_thread_count);
1192
pthread_mutex_unlock(&LOCK_thread_count);
1196
/*****************************************************************************
1198
*****************************************************************************/
1200
static vector<SHOW_VAR *> all_status_vars;
1201
static bool status_vars_inited= 0;
1202
int show_var_cmp(const void *var1, const void *var2)
1204
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1207
class show_var_cmp_functor
1210
show_var_cmp_functor() { }
1211
inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2) const
1213
int val= strcmp(var1->name, var2->name);
1218
class show_var_remove_if
1221
show_var_remove_if() { }
1222
inline bool operator()(const SHOW_VAR *curr) const
1224
return (curr->type == SHOW_UNDEF);
1229
Adds an array of SHOW_VAR entries to the output of SHOW STATUS
1232
add_status_vars(SHOW_VAR *list)
1233
list - an array of SHOW_VAR entries to add to all_status_vars
1234
the last entry must be {0,0,SHOW_UNDEF}
1237
The handling of all_status_vars[] is completely internal, it's allocated
1238
automatically when something is added to it, and deleted completely when
1239
the last entry is removed.
1241
As a special optimization, if add_status_vars() is called before
1242
init_status_vars(), it assumes "startup mode" - neither concurrent access
1243
to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
1245
int add_status_vars(SHOW_VAR *list)
1248
if (status_vars_inited)
1249
pthread_mutex_lock(&LOCK_status);
1251
all_status_vars.insert(all_status_vars.begin(), list++);
1252
if (status_vars_inited)
1253
sort(all_status_vars.begin(), all_status_vars.end(),
1254
show_var_cmp_functor());
1255
if (status_vars_inited)
1256
pthread_mutex_unlock(&LOCK_status);
1261
Make all_status_vars[] usable for SHOW STATUS
1264
See add_status_vars(). Before init_status_vars() call, add_status_vars()
1265
works in a special fast "startup" mode. Thus init_status_vars()
1266
should be called as late as possible but before enabling multi-threading.
1268
void init_status_vars()
1270
status_vars_inited= 1;
1271
sort(all_status_vars.begin(), all_status_vars.end(),
1272
show_var_cmp_functor());
1275
void reset_status_vars()
1277
vector<SHOW_VAR *>::iterator p= all_status_vars.begin();
1278
while (p != all_status_vars.end())
1280
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
1281
if ((*p)->type == SHOW_LONG)
1288
catch-all cleanup function, cleans up everything no matter what
1291
This function is not strictly required if all add_to_status/
1292
remove_status_vars are properly paired, but it's a safety measure that
1293
deletes everything from the all_status_vars vector even if some
1294
remove_status_vars were forgotten
1296
void free_status_vars()
1298
all_status_vars.clear();
1302
Removes an array of SHOW_VAR entries from the output of SHOW STATUS
1305
remove_status_vars(SHOW_VAR *list)
1306
list - an array of SHOW_VAR entries to remove to all_status_vars
1307
the last entry must be {0,0,SHOW_UNDEF}
1310
there's lots of room for optimizing this, especially in non-sorted mode,
1311
but nobody cares - it may be called only in case of failed plugin
1312
initialization in the mysqld startup.
1315
void remove_status_vars(SHOW_VAR *list)
1317
if (status_vars_inited)
1319
pthread_mutex_lock(&LOCK_status);
1320
SHOW_VAR *all= all_status_vars.front();
1321
int a= 0, b= all_status_vars.size(), c= (a+b)/2;
1323
for (; list->name; list++)
1326
for (a= 0, b= all_status_vars.size(); b-a > 1; c= (a+b)/2)
1328
res= show_var_cmp(list, all+c);
1337
all[c].type= SHOW_UNDEF;
1339
/* removes all the SHOW_UNDEF elements from the vector */
1340
all_status_vars.erase(std::remove_if(all_status_vars.begin(),
1341
all_status_vars.end(),show_var_remove_if()),
1342
all_status_vars.end());
1343
pthread_mutex_unlock(&LOCK_status);
1347
SHOW_VAR *all= all_status_vars.front();
1349
for (; list->name; list++)
1351
for (i= 0; i < all_status_vars.size(); i++)
1353
if (show_var_cmp(list, all+i))
1355
all[i].type= SHOW_UNDEF;
1359
/* removes all the SHOW_UNDEF elements from the vector */
1360
all_status_vars.erase(std::remove_if(all_status_vars.begin(),
1361
all_status_vars.end(),show_var_remove_if()),
1362
all_status_vars.end());
1366
inline void make_upper(char *buf)
1369
*buf= my_toupper(system_charset_info, *buf);
1372
static bool show_status_array(Session *session, const char *wild,
1373
SHOW_VAR *variables,
1374
enum enum_var_type value_type,
1375
struct system_status_var *status_var,
1376
const char *prefix, Table *table,
1379
MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, int64_t);
1380
char * const buff= (char *) &buff_data;
1382
/* the variable name should not be longer than 64 characters */
1383
char name_buffer[64];
1387
prefix_end= strncpy(name_buffer, prefix, sizeof(name_buffer)-1);
1388
prefix_end+= strlen(prefix);
1392
len=name_buffer + sizeof(name_buffer) - prefix_end;
1394
for (; variables->name; variables++)
1396
strncpy(prefix_end, variables->name, len);
1397
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
1399
make_upper(name_buffer);
1402
if var->type is SHOW_FUNC, call the function.
1403
Repeat as necessary, if new var is again SHOW_FUNC
1405
for (var=variables; var->type == SHOW_FUNC; var= &tmp)
1406
((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(&tmp, buff);
1408
SHOW_TYPE show_type=var->type;
1409
if (show_type == SHOW_ARRAY)
1411
show_status_array(session, wild, (SHOW_VAR *) var->value, value_type,
1412
status_var, name_buffer, table, ucase_names);
1416
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
1417
name_buffer, wild)))
1419
char *value=var->value;
1420
const char *pos, *end; // We assign a lot of const's
1421
pthread_mutex_lock(&LOCK_global_system_variables);
1423
if (show_type == SHOW_SYS)
1425
show_type= ((sys_var*) value)->show_type();
1426
value= (char*) ((sys_var*) value)->value_ptr(session, value_type,
1432
note that value may be == buff. All SHOW_xxx code below
1433
should still work in this case
1435
switch (show_type) {
1436
case SHOW_DOUBLE_STATUS:
1437
value= ((char *) status_var + (ulong) value);
1440
/* 6 is the default precision for '%f' in sprintf() */
1441
end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
1443
case SHOW_LONG_STATUS:
1444
value= ((char *) status_var + (ulong) value);
1447
end= int10_to_str(*(long*) value, buff, 10);
1449
case SHOW_LONGLONG_STATUS:
1450
value= ((char *) status_var + (uint64_t) value);
1453
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1457
stringstream ss (stringstream::in);
1458
ss << *(size_t*) value;
1460
string str= ss.str();
1461
strncpy(buff, str.c_str(), str.length());
1462
end= buff+ str.length();
1466
end= int64_t10_to_str((int64_t) *(ha_rows*) value, buff, 10);
1469
end+= sprintf(buff,"%s", *(bool*) value ? "ON" : "OFF");
1472
end+= sprintf(buff,"%s", *(bool*) value ? "ON" : "OFF");
1475
case SHOW_INT_NOFLUSH: // the difference lies in refresh_status()
1476
end= int10_to_str((long) *(uint32_t*) value, buff, 10);
1480
SHOW_COMP_OPTION tmp_option= *(SHOW_COMP_OPTION *)value;
1481
pos= show_comp_option_name[(int) tmp_option];
1482
end= strchr(pos, '\0');
1489
end= strchr(pos, '\0');
1494
if (!(pos= *(char**) value))
1496
end= strchr(pos, '\0');
1499
case SHOW_KEY_CACHE_LONG:
1500
value= (char*) dflt_key_cache + (ulong)value;
1501
end= int10_to_str(*(long*) value, buff, 10);
1503
case SHOW_KEY_CACHE_LONGLONG:
1504
value= (char*) dflt_key_cache + (ulong)value;
1505
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1508
break; // Return empty string
1509
case SHOW_SYS: // Cannot happen
1514
table->restoreRecordAsDefault();
1515
table->field[0]->store(name_buffer, strlen(name_buffer),
1516
system_charset_info);
1517
table->field[1]->store(pos, (uint32_t) (end - pos), system_charset_info);
1518
table->field[1]->set_notnull();
1520
pthread_mutex_unlock(&LOCK_global_system_variables);
1522
if (schema_table_store_record(session, table))
1532
/* collect status for all running threads */
1534
void calc_sum_of_all_status(STATUS_VAR *to)
1536
/* Ensure that thread id not killed during loop */
1537
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1539
/* Get global values as base */
1540
*to= global_status_var;
1542
/* Add to this status from existing threads */
1543
for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
1545
add_to_status(to, &((*it)->status_var));
1548
pthread_mutex_unlock(&LOCK_thread_count);
1553
/* This is only used internally, but we need it here as a forward reference */
1554
extern InfoSchemaTable schema_tables[];
1556
typedef struct st_lookup_field_values
1558
LEX_STRING db_value, table_value;
1559
bool wild_db_value, wild_table_value;
1560
} LOOKUP_FIELD_VALUES;
1564
Store record to I_S table, convert HEAP table
1565
to MyISAM if necessary
1568
schema_table_store_record()
1569
session thread handler
1570
table Information schema table to be updated
1577
bool schema_table_store_record(Session *session, Table *table)
1580
if ((error= table->file->ha_write_row(table->record[0])))
1582
Tmp_Table_Param *param= table->pos_in_table_list->schema_table_param;
1584
if (create_myisam_from_heap(session, table, param->start_recinfo,
1585
¶m->recinfo, error, 0))
1592
int make_table_list(Session *session, Select_Lex *sel,
1593
LEX_STRING *db_name, LEX_STRING *table_name)
1595
Table_ident *table_ident;
1596
table_ident= new Table_ident(session, *db_name, *table_name, 1);
1598
if (!sel->add_table_to_list(session, table_ident, 0, 0, TL_READ))
1605
@brief Get lookup value from the part of 'WHERE' condition
1607
@details This function gets lookup value from
1608
the part of 'WHERE' condition if it's possible and
1609
fill appropriate lookup_field_vals struct field
1612
@param[in] session thread handler
1613
@param[in] item_func part of WHERE condition
1614
@param[in] table I_S table
1615
@param[in, out] lookup_field_vals Struct which holds lookup values
1619
1 error, there can be no matching records for the condition
1622
bool get_lookup_value(Session *session, Item_func *item_func,
1624
LOOKUP_FIELD_VALUES *lookup_field_vals)
1626
InfoSchemaTable *schema_table= table->schema_table;
1627
ST_FIELD_INFO *field_info= schema_table->fields_info;
1628
const char *field_name1= schema_table->idx_field1 >= 0 ?
1629
field_info[schema_table->idx_field1].field_name : "";
1630
const char *field_name2= schema_table->idx_field2 >= 0 ?
1631
field_info[schema_table->idx_field2].field_name : "";
1633
if (item_func->functype() == Item_func::EQ_FUNC ||
1634
item_func->functype() == Item_func::EQUAL_FUNC)
1636
int idx_field, idx_val;
1637
char tmp[MAX_FIELD_WIDTH];
1638
String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
1639
Item_field *item_field;
1640
const CHARSET_INFO * const cs= system_charset_info;
1642
if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
1643
item_func->arguments()[1]->const_item())
1648
else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
1649
item_func->arguments()[0]->const_item())
1657
item_field= (Item_field*) item_func->arguments()[idx_field];
1658
if (table->table != item_field->field->table)
1660
tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
1662
/* impossible value */
1666
/* Lookup value is database name */
1667
if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1668
(unsigned char *) item_field->field_name,
1669
strlen(item_field->field_name), 0))
1671
session->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
1672
tmp_str->length(), false);
1674
/* Lookup value is table name */
1675
else if (!cs->coll->strnncollsp(cs, (unsigned char *) field_name2,
1676
strlen(field_name2),
1677
(unsigned char *) item_field->field_name,
1678
strlen(item_field->field_name), 0))
1680
session->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
1681
tmp_str->length(), false);
1689
@brief Calculates lookup values from 'WHERE' condition
1691
@details This function calculates lookup value(database name, table name)
1692
from 'WHERE' condition if it's possible and
1693
fill lookup_field_vals struct fields with these values.
1695
@param[in] session thread handler
1696
@param[in] cond WHERE condition
1697
@param[in] table I_S table
1698
@param[in, out] lookup_field_vals Struct which holds lookup values
1702
1 error, there can be no matching records for the condition
1705
bool calc_lookup_values_from_cond(Session *session, COND *cond, TableList *table,
1706
LOOKUP_FIELD_VALUES *lookup_field_vals)
1711
if (cond->type() == Item::COND_ITEM)
1713
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1715
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1717
while ((item= li++))
1719
if (item->type() == Item::FUNC_ITEM)
1721
if (get_lookup_value(session, (Item_func*)item, table, lookup_field_vals))
1726
if (calc_lookup_values_from_cond(session, item, table, lookup_field_vals))
1733
else if (cond->type() == Item::FUNC_ITEM &&
1734
get_lookup_value(session, (Item_func*) cond, table, lookup_field_vals))
1740
bool uses_only_table_name_fields(Item *item, TableList *table)
1742
if (item->type() == Item::FUNC_ITEM)
1744
Item_func *item_func= (Item_func*)item;
1745
for (uint32_t i=0; i<item_func->argument_count(); i++)
1747
if (!uses_only_table_name_fields(item_func->arguments()[i], table))
1751
else if (item->type() == Item::FIELD_ITEM)
1753
Item_field *item_field= (Item_field*)item;
1754
const CHARSET_INFO * const cs= system_charset_info;
1755
InfoSchemaTable *schema_table= table->schema_table;
1756
ST_FIELD_INFO *field_info= schema_table->fields_info;
1757
const char *field_name1= schema_table->idx_field1 >= 0 ?
1758
field_info[schema_table->idx_field1].field_name : "";
1759
const char *field_name2= schema_table->idx_field2 >= 0 ?
1760
field_info[schema_table->idx_field2].field_name : "";
1761
if (table->table != item_field->field->table ||
1762
(cs->coll->strnncollsp(cs, (unsigned char *) field_name1, strlen(field_name1),
1763
(unsigned char *) item_field->field_name,
1764
strlen(item_field->field_name), 0) &&
1765
cs->coll->strnncollsp(cs, (unsigned char *) field_name2, strlen(field_name2),
1766
(unsigned char *) item_field->field_name,
1767
strlen(item_field->field_name), 0)))
1770
else if (item->type() == Item::REF_ITEM)
1771
return uses_only_table_name_fields(item->real_item(), table);
1773
if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
1780
static COND * make_cond_for_info_schema(COND *cond, TableList *table)
1784
if (cond->type() == Item::COND_ITEM)
1786
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1788
/* Create new top level AND item */
1789
Item_cond_and *new_cond=new Item_cond_and;
1792
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1796
Item *fix= make_cond_for_info_schema(item, table);
1798
new_cond->argument_list()->push_back(fix);
1800
switch (new_cond->argument_list()->elements) {
1804
return new_cond->argument_list()->head();
1806
new_cond->quick_fix_field();
1812
Item_cond_or *new_cond=new Item_cond_or;
1815
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1819
Item *fix=make_cond_for_info_schema(item, table);
1822
new_cond->argument_list()->push_back(fix);
1824
new_cond->quick_fix_field();
1825
new_cond->top_level_item();
1830
if (!uses_only_table_name_fields(cond, table))
1837
@brief Calculate lookup values(database name, table name)
1839
@details This function calculates lookup values(database name, table name)
1840
from 'WHERE' condition or wild values (for 'SHOW' commands only)
1841
from LEX struct and fill lookup_field_vals struct field
1844
@param[in] session thread handler
1845
@param[in] cond WHERE condition
1846
@param[in] tables I_S table
1847
@param[in, out] lookup_field_values Struct which holds lookup values
1851
1 error, there can be no matching records for the condition
1854
bool get_lookup_field_values(Session *session, COND *cond, TableList *tables,
1855
LOOKUP_FIELD_VALUES *lookup_field_values)
1857
LEX *lex= session->lex;
1858
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
1859
memset(lookup_field_values, 0, sizeof(LOOKUP_FIELD_VALUES));
1860
switch (lex->sql_command) {
1861
case SQLCOM_SHOW_DATABASES:
1864
lookup_field_values->db_value.str= (char*) wild;
1865
lookup_field_values->db_value.length= strlen(wild);
1866
lookup_field_values->wild_db_value= 1;
1869
case SQLCOM_SHOW_TABLES:
1870
case SQLCOM_SHOW_TABLE_STATUS:
1871
lookup_field_values->db_value.str= lex->select_lex.db;
1872
lookup_field_values->db_value.length=strlen(lex->select_lex.db);
1875
lookup_field_values->table_value.str= (char*)wild;
1876
lookup_field_values->table_value.length= strlen(wild);
1877
lookup_field_values->wild_table_value= 1;
1882
The "default" is for queries over I_S.
1883
All previous cases handle SHOW commands.
1885
return calc_lookup_values_from_cond(session, cond, tables, lookup_field_values);
1890
enum enum_schema_tables get_schema_table_idx(InfoSchemaTable *schema_table)
1892
return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
1897
Create db names list. Information schema name always is first in list
1901
session thread handler
1902
files list of db names
1904
idx_field_vals idx_field_vals->db_name contains db name or
1906
with_i_schema returns 1 if we added 'IS' name to list
1914
int make_db_list(Session *session, List<LEX_STRING> *files,
1915
LOOKUP_FIELD_VALUES *lookup_field_vals,
1916
bool *with_i_schema)
1918
LEX_STRING *i_s_name_copy= 0;
1919
i_s_name_copy= session->make_lex_string(i_s_name_copy,
1920
INFORMATION_SCHEMA_NAME.c_str(),
1921
INFORMATION_SCHEMA_NAME.length(), true);
1923
if (lookup_field_vals->wild_db_value)
1926
This part of code is only for SHOW DATABASES command.
1927
idx_field_vals->db_value can be 0 when we don't use
1928
LIKE clause (see also get_index_field_values() function)
1930
if (!lookup_field_vals->db_value.str ||
1931
!wild_case_compare(system_charset_info,
1932
INFORMATION_SCHEMA_NAME.c_str(),
1933
lookup_field_vals->db_value.str))
1936
if (files->push_back(i_s_name_copy))
1939
return (find_files(session, files, NULL, drizzle_data_home,
1940
lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
1945
If we have db lookup vaule we just add it to list and
1946
exit from the function
1948
if (lookup_field_vals->db_value.str)
1950
if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.c_str(),
1951
lookup_field_vals->db_value.str))
1954
if (files->push_back(i_s_name_copy))
1958
if (files->push_back(&lookup_field_vals->db_value))
1964
Create list of existing databases. It is used in case
1965
of select from information schema table
1967
if (files->push_back(i_s_name_copy))
1970
return (find_files(session, files, NULL,
1971
drizzle_data_home, NULL, 1) != FIND_FILES_OK);
1975
struct st_add_schema_table
1977
List<LEX_STRING> *files;
1982
class AddSchemaTable : public unary_function<InfoSchemaTable *, bool>
1985
st_add_schema_table *data;
1987
AddSchemaTable(Session *session_arg, st_add_schema_table *data_arg)
1988
: session(session_arg), data(data_arg) {}
1989
result_type operator() (argument_type schema_table)
1991
LEX_STRING *file_name= 0;
1992
List<LEX_STRING> *file_list= data->files;
1993
const char *wild= data->wild;
1995
if (schema_table->hidden)
1999
if (lower_case_table_names)
2001
if (wild_case_compare(files_charset_info,
2002
schema_table->table_name,
2006
else if (wild_compare(schema_table->table_name, wild, 0))
2010
if ((file_name= session->make_lex_string(file_name, schema_table->table_name,
2011
strlen(schema_table->table_name),
2013
!file_list->push_back(file_name))
2020
int schema_tables_add(Session *session, List<LEX_STRING> *files, const char *wild)
2022
LEX_STRING *file_name= 0;
2023
InfoSchemaTable *tmp_schema_table= schema_tables;
2024
st_add_schema_table add_data;
2026
for (; tmp_schema_table->table_name; tmp_schema_table++)
2028
if (tmp_schema_table->hidden)
2032
if (lower_case_table_names)
2034
if (wild_case_compare(files_charset_info,
2035
tmp_schema_table->table_name,
2039
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2043
session->make_lex_string(file_name, tmp_schema_table->table_name,
2044
strlen(tmp_schema_table->table_name), true)) &&
2045
!files->push_back(file_name))
2050
add_data.files= files;
2051
add_data.wild= wild;
2052
vector<InfoSchemaTable *>::iterator iter=
2053
find_if(all_schema_tables.begin(), all_schema_tables.end(),
2054
AddSchemaTable(session, &add_data));
2055
if (iter != all_schema_tables.end())
2062
@brief Create table names list
2064
@details The function creates the list of table names in
2067
@param[in] session thread handler
2068
@param[in] table_names List of table names in database
2069
@param[in] lex pointer to LEX struct
2070
@param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
2071
@param[in] with_i_schema true means that we add I_S tables to list
2072
@param[in] db_name database name
2074
@return Operation status
2076
@retval 1 fatal error
2077
@retval 2 Not fatal error; Safe to ignore this file list
2081
make_table_name_list(Session *session, List<LEX_STRING> *table_names, LEX *lex,
2082
LOOKUP_FIELD_VALUES *lookup_field_vals,
2083
bool with_i_schema, LEX_STRING *db_name)
2085
char path[FN_REFLEN];
2086
build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
2087
if (!lookup_field_vals->wild_table_value &&
2088
lookup_field_vals->table_value.str)
2092
if (find_schema_table(lookup_field_vals->table_value.str))
2094
if (table_names->push_back(&lookup_field_vals->table_value))
2100
if (table_names->push_back(&lookup_field_vals->table_value))
2107
This call will add all matching the wildcards (if specified) IS tables
2111
return (schema_tables_add(session, table_names,
2112
lookup_field_vals->table_value.str));
2114
find_files_result res= find_files(session, table_names, db_name->str, path,
2115
lookup_field_vals->table_value.str, 0);
2116
if (res != FIND_FILES_OK)
2119
Downgrade errors about problems with database directory to
2120
warnings if this is not a 'SHOW' command. Another thread
2121
may have dropped database, and we may still have a name
2124
if (res == FIND_FILES_DIR)
2126
if (lex->sql_command != SQLCOM_SELECT)
2128
session->clear_error();
2138
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
2140
@param[in] session thread handler
2141
@param[in] tables TableList for I_S table
2142
@param[in] schema_table pointer to I_S structure
2143
@param[in] open_tables_state_backup pointer to Open_tables_state object
2144
which is used to save|restore original
2145
status of variables related to
2148
@return Operation status
2154
fill_schema_show_cols_or_idxs(Session *session, TableList *tables,
2155
InfoSchemaTable *schema_table,
2156
Open_tables_state *open_tables_state_backup)
2158
LEX *lex= session->lex;
2160
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
2161
enum_sql_command save_sql_command= lex->sql_command;
2162
TableList *show_table_list= (TableList*) tables->schema_select_lex->
2164
Table *table= tables->table;
2167
lex->all_selects_list= tables->schema_select_lex;
2169
Restore session->temporary_tables to be able to process
2170
temporary tables(only for 'show index' & 'show columns').
2171
This should be changed when processing of temporary tables for
2172
I_S tables will be done.
2174
session->temporary_tables= open_tables_state_backup->temporary_tables;
2176
Let us set fake sql_command so views won't try to merge
2177
themselves into main statement. If we don't do this,
2178
SELECT * from information_schema.xxxx will cause problems.
2179
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
2181
lex->sql_command= SQLCOM_SHOW_FIELDS;
2182
res= open_normal_and_derived_tables(session, show_table_list,
2183
DRIZZLE_LOCK_IGNORE_FLUSH);
2184
lex->sql_command= save_sql_command;
2186
get_all_tables() returns 1 on failure and 0 on success thus
2187
return only these and not the result code of ::process_table()
2189
We should use show_table_list->alias instead of
2190
show_table_list->table_name because table_name
2191
could be changed during opening of I_S tables. It's safe
2192
to use alias because alias contains original table name
2193
in this case(this part of code is used only for
2194
'show columns' & 'show statistics' commands).
2196
table_name= session->make_lex_string(&tmp_lex_string1, show_table_list->alias,
2197
strlen(show_table_list->alias), false);
2198
db_name= session->make_lex_string(&tmp_lex_string, show_table_list->db,
2199
show_table_list->db_length, false);
2202
error= test(schema_table->process_table(session, show_table_list,
2203
table, res, db_name,
2205
session->temporary_tables= 0;
2206
close_tables_for_reopen(session, &show_table_list);
2212
@brief Fill I_S table for SHOW Table NAMES commands
2214
@param[in] session thread handler
2215
@param[in] table Table struct for I_S table
2216
@param[in] db_name database name
2217
@param[in] table_name table name
2218
@param[in] with_i_schema I_S table if true
2220
@return Operation status
2225
static int fill_schema_table_names(Session *session, Table *table,
2226
LEX_STRING *db_name, LEX_STRING *table_name,
2231
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
2232
system_charset_info);
2236
char path[FN_REFLEN];
2237
(void) build_table_filename(path, sizeof(path), db_name->str,
2238
table_name->str, "", 0);
2240
table->field[3]->store(STRING_WITH_LEN("BASE Table"),
2241
system_charset_info);
2243
if (session->is_error() && session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2245
session->clear_error();
2249
if (schema_table_store_record(session, table))
2256
@brief Get open table method
2258
@details The function calculates the method which will be used
2260
SKIP_OPEN_TABLE - do not open table
2261
OPEN_FRM_ONLY - open FRM file only
2262
OPEN_FULL_TABLE - open FRM, data, index files
2263
@param[in] tables I_S table table_list
2264
@param[in] schema_table I_S table struct
2265
@param[in] schema_table_idx I_S table index
2267
@return return a set of flags
2268
@retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
2271
static uint32_t get_table_open_method(TableList *tables,
2272
InfoSchemaTable *schema_table,
2273
enum enum_schema_tables)
2276
determine which method will be used for table opening
2278
if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
2280
Field **ptr, *field;
2281
int table_open_method= 0, field_indx= 0;
2282
for (ptr=tables->table->field; (field= *ptr) ; ptr++)
2284
if (field->isReadSet())
2285
table_open_method|= schema_table->fields_info[field_indx].open_method;
2288
return table_open_method;
2290
/* I_S tables which use get_all_tables but can not be optimized */
2291
return (uint32_t) OPEN_FULL_TABLE;
2296
@brief Fill I_S table with data from FRM file only
2298
@param[in] session thread handler
2299
@param[in] table Table struct for I_S table
2300
@param[in] schema_table I_S table struct
2301
@param[in] db_name database name
2302
@param[in] table_name table name
2303
@param[in] schema_table_idx I_S table index
2305
@return Operation status
2306
@retval 0 Table is processed and we can continue
2308
@retval 1 It's view and we have to use
2309
open_tables function for this table
2312
static int fill_schema_table_from_frm(Session *session,TableList *tables,
2313
InfoSchemaTable *schema_table,
2314
LEX_STRING *db_name,
2315
LEX_STRING *table_name,
2316
enum enum_schema_tables)
2318
Table *table= tables->table;
2321
TableList table_list;
2324
char key[MAX_DBKEY_LENGTH];
2325
uint32_t key_length;
2327
memset(&table_list, 0, sizeof(TableList));
2328
memset(&tbl, 0, sizeof(Table));
2330
table_list.table_name= table_name->str;
2331
table_list.db= db_name->str;
2333
key_length= create_table_def_key(key, &table_list);
2334
pthread_mutex_lock(&LOCK_open);
2335
share= get_table_share(session, &table_list, key,
2336
key_length, 0, &error);
2345
table_list.table= &tbl;
2346
res= schema_table->process_table(session, &table_list, table,
2347
res, db_name, table_name);
2350
release_table_share(share, RELEASE_NORMAL);
2353
pthread_mutex_unlock(&LOCK_open);
2354
session->clear_error();
2361
@brief Fill I_S tables whose data are retrieved
2362
from frm files and storage engine
2364
@details The information schema tables are internally represented as
2365
temporary tables that are filled at query execution time.
2366
Those I_S tables whose data are retrieved
2367
from frm files and storage engine are filled by the function
2370
@param[in] session thread handler
2371
@param[in] tables I_S table
2372
@param[in] cond 'WHERE' condition
2374
@return Operation status
2379
int get_all_tables(Session *session, TableList *tables, COND *cond)
2381
LEX *lex= session->lex;
2382
Table *table= tables->table;
2383
Select_Lex *old_all_select_lex= lex->all_selects_list;
2384
enum_sql_command save_sql_command= lex->sql_command;
2385
Select_Lex *lsel= tables->schema_select_lex;
2386
InfoSchemaTable *schema_table= tables->schema_table;
2388
LOOKUP_FIELD_VALUES lookup_field_vals;
2389
LEX_STRING *db_name, *table_name;
2391
enum enum_schema_tables schema_table_idx;
2392
List<LEX_STRING> db_names;
2393
List_iterator_fast<LEX_STRING> it(db_names);
2394
COND *partial_cond= 0;
2395
uint32_t derived_tables= lex->derived_tables;
2397
Open_tables_state open_tables_state_backup;
2398
Query_tables_list query_tables_list_backup;
2399
uint32_t table_open_method;
2400
bool old_value= session->no_warnings_for_error;
2403
We should not introduce deadlocks even if we already have some
2404
tables open and locked, since we won't lock tables which we will
2405
open and will ignore possible name-locks for these tables.
2407
session->reset_n_backup_open_tables_state(&open_tables_state_backup);
2409
schema_table_idx= get_schema_table_idx(schema_table);
2410
tables->table_open_method= table_open_method=
2411
get_table_open_method(tables, schema_table, schema_table_idx);
2413
this branch processes SHOW FIELDS, SHOW INDEXES commands.
2414
see sql_parse.cc, prepare_schema_table() function where
2415
this values are initialized
2417
if (lsel && lsel->table_list.first)
2419
error= fill_schema_show_cols_or_idxs(session, tables, schema_table,
2420
&open_tables_state_backup);
2424
if (get_lookup_field_values(session, cond, tables, &lookup_field_vals))
2430
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
2433
if lookup value is empty string then
2434
it's impossible table name or db name
2436
if ((lookup_field_vals.db_value.str && !lookup_field_vals.db_value.str[0]) ||
2437
(lookup_field_vals.table_value.str && !lookup_field_vals.table_value.str[0]))
2444
if (lookup_field_vals.db_value.length &&
2445
!lookup_field_vals.wild_db_value)
2446
tables->has_db_lookup_value= true;
2447
if (lookup_field_vals.table_value.length &&
2448
!lookup_field_vals.wild_table_value)
2449
tables->has_table_lookup_value= true;
2451
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
2454
partial_cond= make_cond_for_info_schema(cond, tables);
2458
/* EXPLAIN SELECT */
2463
if (make_db_list(session, &db_names, &lookup_field_vals, &with_i_schema))
2465
it.rewind(); /* To get access to new elements in basis list */
2466
while ((db_name= it++))
2469
session->no_warnings_for_error= 1;
2470
List<LEX_STRING> table_names;
2471
int res= make_table_name_list(session, &table_names, lex,
2473
with_i_schema, db_name);
2474
if (res == 2) /* Not fatal error, continue */
2479
List_iterator_fast<LEX_STRING> it_files(table_names);
2480
while ((table_name= it_files++))
2482
table->restoreRecordAsDefault();
2483
table->field[schema_table->idx_field1]->
2484
store(db_name->str, db_name->length, system_charset_info);
2485
table->field[schema_table->idx_field2]->
2486
store(table_name->str, table_name->length, system_charset_info);
2488
if (!partial_cond || partial_cond->val_int())
2491
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
2492
we can skip table opening and we don't have lookup value for
2493
table name or lookup value is wild string(table name list is
2494
already created by make_table_name_list() function).
2496
if (!table_open_method && schema_table_idx == SCH_TABLES &&
2497
(!lookup_field_vals.table_value.length ||
2498
lookup_field_vals.wild_table_value))
2500
if (schema_table_store_record(session, table))
2501
goto err; /* Out of space in temporary table */
2505
/* SHOW Table NAMES command */
2506
if (schema_table_idx == SCH_TABLE_NAMES)
2508
if (fill_schema_table_names(session, tables->table, db_name,
2509
table_name, with_i_schema))
2514
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
2517
if (!fill_schema_table_from_frm(session, tables, schema_table, db_name,
2518
table_name, schema_table_idx))
2522
LEX_STRING tmp_lex_string, orig_db_name;
2524
Set the parent lex of 'sel' because it is needed by
2525
sel.init_query() which is called inside make_table_list.
2527
session->no_warnings_for_error= 1;
2528
sel.parent_lex= lex;
2529
/* db_name can be changed in make_table_list() func */
2530
if (!session->make_lex_string(&orig_db_name, db_name->str,
2531
db_name->length, false))
2533
if (make_table_list(session, &sel, db_name, table_name))
2535
TableList *show_table_list= (TableList*) sel.table_list.first;
2536
lex->all_selects_list= &sel;
2537
lex->derived_tables= 0;
2538
lex->sql_command= SQLCOM_SHOW_FIELDS;
2539
show_table_list->i_s_requested_object=
2540
schema_table->i_s_requested_object;
2541
res= open_normal_and_derived_tables(session, show_table_list,
2542
DRIZZLE_LOCK_IGNORE_FLUSH);
2543
lex->sql_command= save_sql_command;
2545
XXX: show_table_list has a flag i_is_requested,
2546
and when it's set, open_normal_and_derived_tables()
2547
can return an error without setting an error message
2548
in Session, which is a hack. This is why we have to
2549
check for res, then for session->is_error() only then
2550
for session->main_da.sql_errno().
2552
if (res && session->is_error() &&
2553
session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2556
Hide error for not existing table.
2557
This error can occur for example when we use
2558
where condition with db name and table name and this
2559
table does not exist.
2562
session->clear_error();
2567
We should use show_table_list->alias instead of
2568
show_table_list->table_name because table_name
2569
could be changed during opening of I_S tables. It's safe
2570
to use alias because alias contains original table name
2573
session->make_lex_string(&tmp_lex_string, show_table_list->alias,
2574
strlen(show_table_list->alias), false);
2575
res= schema_table->process_table(session, show_table_list, table,
2578
close_tables_for_reopen(session, &show_table_list);
2580
assert(!lex->query_tables_own_last);
2587
If we have information schema its always the first table and only
2588
the first table. Reset for other tables.
2596
session->restore_backup_open_tables_state(&open_tables_state_backup);
2597
lex->derived_tables= derived_tables;
2598
lex->all_selects_list= old_all_select_lex;
2599
lex->sql_command= save_sql_command;
2600
session->no_warnings_for_error= old_value;
2605
bool store_schema_shemata(Session* session, Table *table, LEX_STRING *db_name,
2606
const CHARSET_INFO * const cs)
2608
table->restoreRecordAsDefault();
2609
table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2610
table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2611
table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2612
return schema_table_store_record(session, table);
2616
int fill_schema_schemata(Session *session, TableList *tables, COND *cond)
2619
TODO: fill_schema_shemata() is called when new client is connected.
2620
Returning error status in this case leads to client hangup.
2623
LOOKUP_FIELD_VALUES lookup_field_vals;
2624
List<LEX_STRING> db_names;
2625
LEX_STRING *db_name;
2627
Table *table= tables->table;
2629
if (get_lookup_field_values(session, cond, tables, &lookup_field_vals))
2631
if (make_db_list(session, &db_names, &lookup_field_vals,
2636
If we have lookup db value we should check that the database exists
2638
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
2641
char path[FN_REFLEN+16];
2643
struct stat stat_info;
2644
if (!lookup_field_vals.db_value.str[0])
2646
path_len= build_table_filename(path, sizeof(path),
2647
lookup_field_vals.db_value.str, "", "", 0);
2648
path[path_len-1]= 0;
2649
if (stat(path,&stat_info))
2653
List_iterator_fast<LEX_STRING> it(db_names);
2654
while ((db_name=it++))
2656
if (with_i_schema) // information schema name is always first in list
2658
if (store_schema_shemata(session, table, db_name,
2659
system_charset_info))
2665
HA_CREATE_INFO create;
2666
load_db_opt_by_name(db_name->str, &create);
2668
if (store_schema_shemata(session, table, db_name,
2669
create.default_table_charset))
2677
static int get_schema_tables_record(Session *session, TableList *tables,
2678
Table *table, bool res,
2679
LEX_STRING *db_name,
2680
LEX_STRING *table_name)
2682
const char *tmp_buff;
2684
const CHARSET_INFO * const cs= system_charset_info;
2686
table->restoreRecordAsDefault();
2687
table->field[1]->store(db_name->str, db_name->length, cs);
2688
table->field[2]->store(table_name->str, table_name->length, cs);
2692
there was errors during opening tables
2694
const char *error= session->is_error() ? session->main_da.message() : "";
2695
if (tables->schema_table)
2696
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2698
table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
2699
table->field[20]->store(error, strlen(error), cs);
2700
session->clear_error();
2704
char option_buff[400],*ptr;
2705
Table *show_table= tables->table;
2706
TableShare *share= show_table->s;
2707
handler *file= show_table->file;
2708
StorageEngine *tmp_db_type= share->db_type();
2709
if (share->tmp_table == SYSTEM_TMP_TABLE)
2710
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2711
else if (share->tmp_table)
2712
table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
2714
table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
2716
for (int i= 4; i < 20; i++)
2718
if (i == 7 || (i > 12 && i < 17) || i == 18)
2720
table->field[i]->set_notnull();
2722
string engine_name= ha_resolve_storage_engine_name(tmp_db_type);
2723
table->field[4]->store(engine_name.c_str(), engine_name.size(), cs);
2724
table->field[5]->store((int64_t) 0, true);
2727
if (share->min_rows)
2729
ptr= strcpy(ptr," min_rows=")+10;
2730
ptr= int64_t10_to_str(share->min_rows,ptr,10);
2732
if (share->max_rows)
2734
ptr= strcpy(ptr," max_rows=")+10;
2735
ptr= int64_t10_to_str(share->max_rows,ptr,10);
2737
if (share->avg_row_length)
2739
ptr= strcpy(ptr," avg_row_length=")+16;
2740
ptr= int64_t10_to_str(share->avg_row_length,ptr,10);
2742
if (share->db_create_options & HA_OPTION_PACK_KEYS)
2743
ptr= strcpy(ptr," pack_keys=1")+12;
2744
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
2745
ptr= strcpy(ptr," pack_keys=0")+12;
2746
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2747
if (share->db_create_options & HA_OPTION_CHECKSUM)
2748
ptr= strcpy(ptr," checksum=1")+11;
2749
if (share->page_checksum != HA_CHOICE_UNDEF)
2750
ptr+= sprintf(ptr, " page_checksum=%s",
2751
ha_choice_values[(uint32_t) share->page_checksum]);
2752
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
2753
ptr= strcpy(ptr," delay_key_write=1")+18;
2754
if (share->row_type != ROW_TYPE_DEFAULT)
2755
ptr+= sprintf(ptr, " row_format=%s", ha_row_type[(uint32_t)share->row_type]);
2756
if (share->block_size)
2758
ptr= strcpy(ptr, " block_size=")+12;
2759
ptr= int64_t10_to_str(share->block_size, ptr, 10);
2762
table->field[19]->store(option_buff+1,
2763
(ptr == option_buff ? 0 :
2764
(uint32_t) (ptr-option_buff)-1), cs);
2766
tmp_buff= (share->table_charset ?
2767
share->table_charset->name : "default");
2768
table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
2770
if (share->comment.str)
2771
table->field[20]->store(share->comment.str, share->comment.length, cs);
2775
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
2777
enum row_type row_type = file->get_row_type();
2779
case ROW_TYPE_NOT_USED:
2780
case ROW_TYPE_DEFAULT:
2781
tmp_buff= ((share->db_options_in_use &
2782
HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
2783
(share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
2784
"Dynamic" : "Fixed");
2786
case ROW_TYPE_FIXED:
2789
case ROW_TYPE_DYNAMIC:
2790
tmp_buff= "Dynamic";
2792
case ROW_TYPE_COMPRESSED:
2793
tmp_buff= "Compressed";
2795
case ROW_TYPE_REDUNDANT:
2796
tmp_buff= "Redundant";
2798
case ROW_TYPE_COMPACT:
2799
tmp_buff= "Compact";
2805
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
2806
if (!tables->schema_table)
2808
table->field[7]->store((int64_t) file->stats.records, true);
2809
table->field[7]->set_notnull();
2811
table->field[8]->store((int64_t) file->stats.mean_rec_length, true);
2812
table->field[9]->store((int64_t) file->stats.data_file_length, true);
2813
if (file->stats.max_data_file_length)
2815
table->field[10]->store((int64_t) file->stats.max_data_file_length,
2818
table->field[11]->store((int64_t) file->stats.index_file_length, true);
2819
table->field[12]->store((int64_t) file->stats.delete_length, true);
2820
if (show_table->found_next_number_field)
2822
table->field[13]->store((int64_t) file->stats.auto_increment_value,
2824
table->field[13]->set_notnull();
2826
if (file->stats.create_time)
2828
session->variables.time_zone->gmt_sec_to_TIME(&time,
2829
(time_t) file->stats.create_time);
2830
table->field[14]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2831
table->field[14]->set_notnull();
2833
if (file->stats.update_time)
2835
session->variables.time_zone->gmt_sec_to_TIME(&time,
2836
(time_t) file->stats.update_time);
2837
table->field[15]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2838
table->field[15]->set_notnull();
2840
if (file->stats.check_time)
2842
session->variables.time_zone->gmt_sec_to_TIME(&time,
2843
(time_t) file->stats.check_time);
2844
table->field[16]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2845
table->field[16]->set_notnull();
2847
if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
2849
table->field[18]->store((int64_t) file->checksum(), true);
2850
table->field[18]->set_notnull();
2854
return(schema_table_store_record(session, table));
2859
@brief Store field characteristics into appropriate I_S table columns
2861
@param[in] table I_S table
2862
@param[in] field processed field
2863
@param[in] cs I_S table charset
2864
@param[in] offset offset from beginning of table
2865
to DATE_TYPE column in I_S table
2870
void store_column_type(Table *table, Field *field, const CHARSET_INFO * const cs,
2874
int decimals, field_length;
2875
const char *tmp_buff;
2876
char column_type_buff[MAX_FIELD_WIDTH];
2877
String column_type(column_type_buff, sizeof(column_type_buff), cs);
2879
field->sql_type(column_type);
2880
/* DTD_IDENTIFIER column */
2881
table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs);
2882
table->field[offset + 7]->set_notnull();
2883
tmp_buff= strchr(column_type.ptr(), '(');
2884
/* DATA_TYPE column */
2885
table->field[offset]->store(column_type.ptr(),
2886
(tmp_buff ? tmp_buff - column_type.ptr() :
2887
column_type.length()), cs);
2888
is_blob= (field->type() == DRIZZLE_TYPE_BLOB);
2889
if (field->has_charset() || is_blob ||
2890
field->real_type() == DRIZZLE_TYPE_VARCHAR) // For varbinary type
2892
uint32_t octet_max_length= field->max_display_length();
2893
if (is_blob && octet_max_length != (uint32_t) 4294967295U)
2894
octet_max_length /= field->charset()->mbmaxlen;
2895
int64_t char_max_len= is_blob ?
2896
(int64_t) octet_max_length / field->charset()->mbminlen :
2897
(int64_t) octet_max_length / field->charset()->mbmaxlen;
2898
/* CHARACTER_MAXIMUM_LENGTH column*/
2899
table->field[offset + 1]->store(char_max_len, true);
2900
table->field[offset + 1]->set_notnull();
2901
/* CHARACTER_OCTET_LENGTH column */
2902
table->field[offset + 2]->store((int64_t) octet_max_length, true);
2903
table->field[offset + 2]->set_notnull();
2907
Calculate field_length and decimals.
2908
They are set to -1 if they should not be set (we should return NULL)
2911
decimals= field->decimals();
2912
switch (field->type()) {
2913
case DRIZZLE_TYPE_NEWDECIMAL:
2914
field_length= ((Field_new_decimal*) field)->precision;
2916
case DRIZZLE_TYPE_LONG:
2917
case DRIZZLE_TYPE_LONGLONG:
2918
field_length= field->max_display_length() - 1;
2920
case DRIZZLE_TYPE_DOUBLE:
2921
field_length= field->field_length;
2922
if (decimals == NOT_FIXED_DEC)
2923
decimals= -1; // return NULL
2926
field_length= decimals= -1;
2930
/* NUMERIC_PRECISION column */
2931
if (field_length >= 0)
2933
table->field[offset + 3]->store((int64_t) field_length, true);
2934
table->field[offset + 3]->set_notnull();
2936
/* NUMERIC_SCALE column */
2939
table->field[offset + 4]->store((int64_t) decimals, true);
2940
table->field[offset + 4]->set_notnull();
2942
if (field->has_charset())
2944
/* CHARACTER_SET_NAME column*/
2945
tmp_buff= field->charset()->csname;
2946
table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs);
2947
table->field[offset + 5]->set_notnull();
2948
/* COLLATION_NAME column */
2949
tmp_buff= field->charset()->name;
2950
table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs);
2951
table->field[offset + 6]->set_notnull();
2956
static int get_schema_column_record(Session *session, TableList *tables,
2957
Table *table, bool res,
2958
LEX_STRING *db_name,
2959
LEX_STRING *table_name)
2961
LEX *lex= session->lex;
2962
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
2963
const CHARSET_INFO * const cs= system_charset_info;
2965
TableShare *show_table_share;
2966
Field **ptr, *field, *timestamp_field;
2971
if (lex->sql_command != SQLCOM_SHOW_FIELDS)
2974
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
2975
rather than in SHOW COLUMNS
2977
if (session->is_error())
2978
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2979
session->main_da.sql_errno(), session->main_da.message());
2980
session->clear_error();
2986
show_table= tables->table;
2987
show_table_share= show_table->s;
2990
if (tables->schema_table)
2992
ptr= show_table->field;
2993
timestamp_field= show_table->timestamp_field;
2994
show_table->use_all_columns(); // Required for default
2998
ptr= show_table_share->field;
2999
timestamp_field= show_table_share->timestamp_field;
3001
read_set may be inited in case of
3004
if (!show_table->read_set)
3006
/* to satisfy 'field->val_str' ASSERTs */
3007
unsigned char *bitmaps;
3008
uint32_t bitmap_size= show_table_share->column_bitmap_size;
3009
if (!(bitmaps= (unsigned char*) alloc_root(session->mem_root, bitmap_size)))
3011
bitmap_init(&show_table->def_read_set,
3012
(my_bitmap_map*) bitmaps, show_table_share->fields, false);
3013
bitmap_set_all(&show_table->def_read_set);
3014
show_table->read_set= &show_table->def_read_set;
3016
show_table->setReadSet();
3019
for (; (field= *ptr) ; ptr++)
3022
char tmp[MAX_FIELD_WIDTH];
3023
String type(tmp,sizeof(tmp), system_charset_info);
3026
/* to satisfy 'field->val_str' ASSERTs */
3027
field->table= show_table;
3028
show_table->in_use= session;
3030
if (wild && wild[0] &&
3031
wild_case_compare(system_charset_info, field->field_name,wild))
3035
/* Get default row, with all NULL fields set to NULL */
3036
table->restoreRecordAsDefault();
3038
table->field[1]->store(db_name->str, db_name->length, cs);
3039
table->field[2]->store(table_name->str, table_name->length, cs);
3040
table->field[3]->store(field->field_name, strlen(field->field_name),
3042
table->field[4]->store((int64_t) count, true);
3044
if (get_field_default_value(timestamp_field, field, &type, 0))
3046
table->field[5]->store(type.ptr(), type.length(), cs);
3047
table->field[5]->set_notnull();
3049
pos=(unsigned char*) ((field->flags & NOT_NULL_FLAG) ? "NO" : "YES");
3050
table->field[6]->store((const char*) pos,
3051
strlen((const char*) pos), cs);
3052
store_column_type(table, field, cs, 7);
3054
pos=(unsigned char*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
3055
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
3056
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
3057
table->field[15]->store((const char*) pos,
3058
strlen((const char*) pos), cs);
3061
if (field->unireg_check == Field::NEXT_NUMBER)
3062
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
3063
if (timestamp_field == field &&
3064
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3065
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3067
table->field[18]->store(field->comment.str, field->comment.length, cs);
3069
enum column_format_type column_format= (enum column_format_type)
3070
((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
3071
pos=(unsigned char*)"Default";
3072
table->field[19]->store((const char*) pos,
3073
strlen((const char*) pos), cs);
3074
pos=(unsigned char*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
3075
column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
3077
table->field[20]->store((const char*) pos,
3078
strlen((const char*) pos), cs);
3080
if (schema_table_store_record(session, table))
3088
int fill_schema_charsets(Session *session, TableList *tables, COND *)
3091
const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3092
Table *table= tables->table;
3093
const CHARSET_INFO * const scs= system_charset_info;
3095
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3097
const CHARSET_INFO * const tmp_cs= cs[0];
3098
if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
3099
(tmp_cs->state & MY_CS_AVAILABLE) &&
3100
!(tmp_cs->state & MY_CS_HIDDEN) &&
3101
!(wild && wild[0] &&
3102
wild_case_compare(scs, tmp_cs->csname,wild)))
3104
const char *comment;
3105
table->restoreRecordAsDefault();
3106
table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3107
table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3108
comment= tmp_cs->comment ? tmp_cs->comment : "";
3109
table->field[2]->store(comment, strlen(comment), scs);
3110
table->field[3]->store((int64_t) tmp_cs->mbmaxlen, true);
3111
if (schema_table_store_record(session, table))
3119
int fill_schema_collation(Session *session, TableList *tables, COND *)
3122
const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3123
Table *table= tables->table;
3124
const CHARSET_INFO * const scs= system_charset_info;
3125
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3128
const CHARSET_INFO *tmp_cs= cs[0];
3129
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3130
(tmp_cs->state & MY_CS_HIDDEN) ||
3131
!(tmp_cs->state & MY_CS_PRIMARY))
3133
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3135
const CHARSET_INFO *tmp_cl= cl[0];
3136
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3137
!my_charset_same(tmp_cs, tmp_cl))
3139
if (!(wild && wild[0] &&
3140
wild_case_compare(scs, tmp_cl->name,wild)))
3142
const char *tmp_buff;
3143
table->restoreRecordAsDefault();
3144
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3145
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3146
table->field[2]->store((int64_t) tmp_cl->number, true);
3147
tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
3148
table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
3149
tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
3150
table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
3151
table->field[5]->store((int64_t) tmp_cl->strxfrm_multiply, true);
3152
if (schema_table_store_record(session, table))
3161
int fill_schema_coll_charset_app(Session *session, TableList *tables, COND *)
3164
Table *table= tables->table;
3165
const CHARSET_INFO * const scs= system_charset_info;
3166
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3169
const CHARSET_INFO *tmp_cs= cs[0];
3170
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3171
!(tmp_cs->state & MY_CS_PRIMARY))
3173
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3175
const CHARSET_INFO *tmp_cl= cl[0];
3176
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3177
!my_charset_same(tmp_cs,tmp_cl))
3179
table->restoreRecordAsDefault();
3180
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3181
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3182
if (schema_table_store_record(session, table))
3190
static int get_schema_stat_record(Session *session, TableList *tables,
3191
Table *table, bool res,
3192
LEX_STRING *db_name,
3193
LEX_STRING *table_name)
3195
const CHARSET_INFO * const cs= system_charset_info;
3198
if (session->lex->sql_command != SQLCOM_SHOW_KEYS)
3201
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
3202
rather than in SHOW KEYS
3204
if (session->is_error())
3205
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3206
session->main_da.sql_errno(), session->main_da.message());
3207
session->clear_error();
3214
Table *show_table= tables->table;
3215
KEY *key_info=show_table->s->key_info;
3216
if (show_table->file)
3217
show_table->file->info(HA_STATUS_VARIABLE |
3220
for (uint32_t i=0 ; i < show_table->s->keys ; i++,key_info++)
3222
KEY_PART_INFO *key_part= key_info->key_part;
3224
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
3226
table->restoreRecordAsDefault();
3227
table->field[1]->store(db_name->str, db_name->length, cs);
3228
table->field[2]->store(table_name->str, table_name->length, cs);
3229
table->field[3]->store((int64_t) ((key_info->flags &
3230
HA_NOSAME) ? 0 : 1), true);
3231
table->field[4]->store(db_name->str, db_name->length, cs);
3232
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
3233
table->field[6]->store((int64_t) (j+1), true);
3234
str=(key_part->field ? key_part->field->field_name :
3236
table->field[7]->store(str, strlen(str), cs);
3237
if (show_table->file)
3239
if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
3241
table->field[8]->store(((key_part->key_part_flag &
3244
table->field[8]->set_notnull();
3246
KEY *key=show_table->key_info+i;
3247
if (key->rec_per_key[j])
3249
ha_rows records=(show_table->file->stats.records /
3250
key->rec_per_key[j]);
3251
table->field[9]->store((int64_t) records, true);
3252
table->field[9]->set_notnull();
3254
str= show_table->file->index_type(i);
3255
table->field[13]->store(str, strlen(str), cs);
3257
if ((key_part->field &&
3259
show_table->s->field[key_part->fieldnr-1]->key_length()))
3261
table->field[10]->store((int64_t) key_part->length /
3262
key_part->field->charset()->mbmaxlen, true);
3263
table->field[10]->set_notnull();
3265
uint32_t flags= key_part->field ? key_part->field->flags : 0;
3266
const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3267
table->field[12]->store(pos, strlen(pos), cs);
3268
if (!show_table->s->keys_in_use.test(i))
3269
table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3271
table->field[14]->store("", 0, cs);
3272
table->field[14]->set_notnull();
3273
assert(test(key_info->flags & HA_USES_COMMENT) ==
3274
(key_info->comment.length > 0));
3275
if (key_info->flags & HA_USES_COMMENT)
3276
table->field[15]->store(key_info->comment.str,
3277
key_info->comment.length, cs);
3278
if (schema_table_store_record(session, table))
3287
bool store_constraints(Session *session, Table *table, LEX_STRING *db_name,
3288
LEX_STRING *table_name, const char *key_name,
3289
uint32_t key_len, const char *con_type, uint32_t con_len)
3291
const CHARSET_INFO * const cs= system_charset_info;
3292
table->restoreRecordAsDefault();
3293
table->field[1]->store(db_name->str, db_name->length, cs);
3294
table->field[2]->store(key_name, key_len, cs);
3295
table->field[3]->store(db_name->str, db_name->length, cs);
3296
table->field[4]->store(table_name->str, table_name->length, cs);
3297
table->field[5]->store(con_type, con_len, cs);
3298
return schema_table_store_record(session, table);
3302
static int get_schema_constraints_record(Session *session, TableList *tables,
3303
Table *table, bool res,
3304
LEX_STRING *db_name,
3305
LEX_STRING *table_name)
3309
if (session->is_error())
3310
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3311
session->main_da.sql_errno(), session->main_da.message());
3312
session->clear_error();
3317
List<FOREIGN_KEY_INFO> f_key_list;
3318
Table *show_table= tables->table;
3319
KEY *key_info=show_table->key_info;
3320
uint32_t primary_key= show_table->s->primary_key;
3321
show_table->file->info(HA_STATUS_VARIABLE |
3324
for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3326
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3329
if (i == primary_key && is_primary_key(key_info))
3331
if (store_constraints(session, table, db_name, table_name, key_info->name,
3332
strlen(key_info->name),
3333
STRING_WITH_LEN("PRIMARY KEY")))
3336
else if (key_info->flags & HA_NOSAME)
3338
if (store_constraints(session, table, db_name, table_name, key_info->name,
3339
strlen(key_info->name),
3340
STRING_WITH_LEN("UNIQUE")))
3345
show_table->file->get_foreign_key_list(session, &f_key_list);
3346
FOREIGN_KEY_INFO *f_key_info;
3347
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3348
while ((f_key_info=it++))
3350
if (store_constraints(session, table, db_name, table_name,
3351
f_key_info->forein_id->str,
3352
strlen(f_key_info->forein_id->str),
3361
void store_key_column_usage(Table *table, LEX_STRING *db_name,
3362
LEX_STRING *table_name, const char *key_name,
3363
uint32_t key_len, const char *con_type, uint32_t con_len,
3366
const CHARSET_INFO * const cs= system_charset_info;
3367
table->field[1]->store(db_name->str, db_name->length, cs);
3368
table->field[2]->store(key_name, key_len, cs);
3369
table->field[4]->store(db_name->str, db_name->length, cs);
3370
table->field[5]->store(table_name->str, table_name->length, cs);
3371
table->field[6]->store(con_type, con_len, cs);
3372
table->field[7]->store((int64_t) idx, true);
3376
static int get_schema_key_column_usage_record(Session *session,
3378
Table *table, bool res,
3379
LEX_STRING *db_name,
3380
LEX_STRING *table_name)
3384
if (session->is_error())
3385
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3386
session->main_da.sql_errno(), session->main_da.message());
3387
session->clear_error();
3392
List<FOREIGN_KEY_INFO> f_key_list;
3393
Table *show_table= tables->table;
3394
KEY *key_info=show_table->key_info;
3395
uint32_t primary_key= show_table->s->primary_key;
3396
show_table->file->info(HA_STATUS_VARIABLE |
3399
for (uint32_t i=0 ; i < show_table->s->keys ; i++, key_info++)
3401
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3404
KEY_PART_INFO *key_part= key_info->key_part;
3405
for (uint32_t j=0 ; j < key_info->key_parts ; j++,key_part++)
3407
if (key_part->field)
3410
table->restoreRecordAsDefault();
3411
store_key_column_usage(table, db_name, table_name,
3413
strlen(key_info->name),
3414
key_part->field->field_name,
3415
strlen(key_part->field->field_name),
3417
if (schema_table_store_record(session, table))
3423
show_table->file->get_foreign_key_list(session, &f_key_list);
3424
FOREIGN_KEY_INFO *f_key_info;
3425
List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
3426
while ((f_key_info= fkey_it++))
3430
List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
3431
it1(f_key_info->referenced_fields);
3433
while ((f_info= it++))
3437
table->restoreRecordAsDefault();
3438
store_key_column_usage(table, db_name, table_name,
3439
f_key_info->forein_id->str,
3440
f_key_info->forein_id->length,
3441
f_info->str, f_info->length,
3443
table->field[8]->store((int64_t) f_idx, true);
3444
table->field[8]->set_notnull();
3445
table->field[9]->store(f_key_info->referenced_db->str,
3446
f_key_info->referenced_db->length,
3447
system_charset_info);
3448
table->field[9]->set_notnull();
3449
table->field[10]->store(f_key_info->referenced_table->str,
3450
f_key_info->referenced_table->length,
3451
system_charset_info);
3452
table->field[10]->set_notnull();
3453
table->field[11]->store(r_info->str, r_info->length,
3454
system_charset_info);
3455
table->field[11]->set_notnull();
3456
if (schema_table_store_record(session, table))
3465
int fill_open_tables(Session *session, TableList *tables, COND *)
3467
const char *wild= session->lex->wild ? session->lex->wild->ptr() : NULL;
3468
Table *table= tables->table;
3469
const CHARSET_INFO * const cs= system_charset_info;
3470
OPEN_TableList *open_list;
3471
if (!(open_list=list_open_tables(session->lex->select_lex.db, wild))
3472
&& session->is_fatal_error)
3475
for (; open_list ; open_list=open_list->next)
3477
table->restoreRecordAsDefault();
3478
table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3479
table->field[1]->store(open_list->table, strlen(open_list->table), cs);
3480
table->field[2]->store((int64_t) open_list->in_use, true);
3481
table->field[3]->store((int64_t) open_list->locked, true);
3482
if (schema_table_store_record(session, table))
3489
int fill_variables(Session *session, TableList *tables, COND *)
3492
LEX *lex= session->lex;
3493
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3494
enum enum_schema_tables schema_table_idx=
3495
get_schema_table_idx(tables->schema_table);
3496
enum enum_var_type option_type= OPT_SESSION;
3497
bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
3498
bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
3500
if (lex->option_type == OPT_GLOBAL ||
3501
schema_table_idx == SCH_GLOBAL_VARIABLES)
3502
option_type= OPT_GLOBAL;
3504
pthread_rwlock_rdlock(&LOCK_system_variables_hash);
3505
res= show_status_array(session, wild, enumerate_sys_vars(session, sorted_vars),
3506
option_type, NULL, "", tables->table, upper_case_names);
3507
pthread_rwlock_unlock(&LOCK_system_variables_hash);
3512
int fill_status(Session *session, TableList *tables, COND *)
3514
LEX *lex= session->lex;
3515
const char *wild= lex->wild ? lex->wild->ptr() : NULL;
3517
STATUS_VAR *tmp1, tmp;
3518
enum enum_schema_tables schema_table_idx=
3519
get_schema_table_idx(tables->schema_table);
3520
enum enum_var_type option_type;
3521
bool upper_case_names= (schema_table_idx != SCH_STATUS);
3523
if (schema_table_idx == SCH_STATUS)
3525
option_type= lex->option_type;
3526
if (option_type == OPT_GLOBAL)
3529
tmp1= session->initial_status_var;
3531
else if (schema_table_idx == SCH_GLOBAL_STATUS)
3533
option_type= OPT_GLOBAL;
3538
option_type= OPT_SESSION;
3539
tmp1= &session->status_var;
3542
pthread_mutex_lock(&LOCK_status);
3543
if (option_type == OPT_GLOBAL)
3544
calc_sum_of_all_status(&tmp);
3545
res= show_status_array(session, wild,
3546
(SHOW_VAR *) all_status_vars.front(),
3547
option_type, tmp1, "", tables->table,
3549
pthread_mutex_unlock(&LOCK_status);
3555
Fill and store records into I_S.referential_constraints table
3558
get_referential_constraints_record()
3559
session thread handle
3560
tables table list struct(processed table)
3562
res 1 means the error during opening of the processed table
3563
0 means processed table is opened without error
3565
file_name table name
3573
get_referential_constraints_record(Session *session, TableList *tables,
3574
Table *table, bool res,
3575
LEX_STRING *db_name, LEX_STRING *table_name)
3577
const CHARSET_INFO * const cs= system_charset_info;
3581
if (session->is_error())
3582
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3583
session->main_da.sql_errno(), session->main_da.message());
3584
session->clear_error();
3589
List<FOREIGN_KEY_INFO> f_key_list;
3590
Table *show_table= tables->table;
3591
show_table->file->info(HA_STATUS_VARIABLE |
3595
show_table->file->get_foreign_key_list(session, &f_key_list);
3596
FOREIGN_KEY_INFO *f_key_info;
3597
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3598
while ((f_key_info= it++))
3600
table->restoreRecordAsDefault();
3601
table->field[1]->store(db_name->str, db_name->length, cs);
3602
table->field[9]->store(table_name->str, table_name->length, cs);
3603
table->field[2]->store(f_key_info->forein_id->str,
3604
f_key_info->forein_id->length, cs);
3605
table->field[4]->store(f_key_info->referenced_db->str,
3606
f_key_info->referenced_db->length, cs);
3607
table->field[10]->store(f_key_info->referenced_table->str,
3608
f_key_info->referenced_table->length, cs);
3609
if (f_key_info->referenced_key_name)
3611
table->field[5]->store(f_key_info->referenced_key_name->str,
3612
f_key_info->referenced_key_name->length, cs);
3613
table->field[5]->set_notnull();
3616
table->field[5]->set_null();
3617
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3618
table->field[7]->store(f_key_info->update_method->str,
3619
f_key_info->update_method->length, cs);
3620
table->field[8]->store(f_key_info->delete_method->str,
3621
f_key_info->delete_method->length, cs);
3622
if (schema_table_store_record(session, table))
3630
class FindSchemaTableByName : public unary_function<InfoSchemaTable *, bool>
3632
const char *table_name;
3634
FindSchemaTableByName(const char *table_name_arg)
3635
: table_name(table_name_arg) {}
3636
result_type operator() (argument_type schema_table)
3638
return !my_strcasecmp(system_charset_info,
3639
schema_table->table_name,
3646
Find schema_tables elment by name
3650
table_name table name
3654
# pointer to 'schema_tables' element
3657
InfoSchemaTable *find_schema_table(const char* table_name)
3659
InfoSchemaTable *schema_table= schema_tables;
3661
for (; schema_table->table_name; schema_table++)
3663
if (!my_strcasecmp(system_charset_info,
3664
schema_table->table_name,
3666
return(schema_table);
3669
vector<InfoSchemaTable *>::iterator iter=
3670
find_if(all_schema_tables.begin(), all_schema_tables.end(),
3671
FindSchemaTableByName(table_name));
3672
if (iter != all_schema_tables.end())
3678
InfoSchemaTable *get_schema_table(enum enum_schema_tables schema_table_idx)
3680
return &schema_tables[schema_table_idx];
3685
Create information_schema table using schema_table data.
3690
session thread handler
3692
@param table_list Used to pass I_S table information(fields info, tables
3693
parameters etc) and table name.
3695
@retval \# Pointer to created table
3696
@retval NULL Can't create table
3699
Table *create_schema_table(Session *session, TableList *table_list)
3704
List<Item> field_list;
3705
InfoSchemaTable *schema_table= table_list->schema_table;
3706
ST_FIELD_INFO *fields_info= schema_table->fields_info;
3707
const CHARSET_INFO * const cs= system_charset_info;
3709
for (; fields_info->field_name; fields_info++)
3711
switch (fields_info->field_type) {
3712
case DRIZZLE_TYPE_LONG:
3713
case DRIZZLE_TYPE_LONGLONG:
3714
if (!(item= new Item_return_int(fields_info->field_name,
3715
fields_info->field_length,
3716
fields_info->field_type,
3717
fields_info->value)))
3721
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3723
case DRIZZLE_TYPE_DATE:
3724
case DRIZZLE_TYPE_TIMESTAMP:
3725
case DRIZZLE_TYPE_DATETIME:
3726
if (!(item=new Item_return_date_time(fields_info->field_name,
3727
fields_info->field_type)))
3732
case DRIZZLE_TYPE_DOUBLE:
3733
if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
3734
fields_info->field_length)) == NULL)
3737
case DRIZZLE_TYPE_NEWDECIMAL:
3738
if (!(item= new Item_decimal((int64_t) fields_info->value, false)))
3742
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3743
item->decimals= fields_info->field_length%10;
3744
item->max_length= (fields_info->field_length/100)%100;
3745
if (item->unsigned_flag == 0)
3746
item->max_length+= 1;
3747
if (item->decimals > 0)
3748
item->max_length+= 1;
3749
item->set_name(fields_info->field_name,
3750
strlen(fields_info->field_name), cs);
3752
case DRIZZLE_TYPE_BLOB:
3753
if (!(item= new Item_blob(fields_info->field_name,
3754
fields_info->field_length)))
3760
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
3764
item->set_name(fields_info->field_name,
3765
strlen(fields_info->field_name), cs);
3768
field_list.push_back(item);
3769
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
3772
Tmp_Table_Param *tmp_table_param =
3773
(Tmp_Table_Param*) (session->alloc(sizeof(Tmp_Table_Param)));
3774
tmp_table_param->init();
3775
tmp_table_param->table_charset= cs;
3776
tmp_table_param->field_count= field_count;
3777
tmp_table_param->schema_table= 1;
3778
Select_Lex *select_lex= session->lex->current_select;
3779
if (!(table= create_tmp_table(session, tmp_table_param,
3780
field_list, (order_st*) 0, 0, 0,
3781
(select_lex->options | session->options |
3782
TMP_TABLE_ALL_COLUMNS),
3783
HA_POS_ERROR, table_list->alias)))
3785
my_bitmap_map* bitmaps=
3786
(my_bitmap_map*) session->alloc(bitmap_buffer_size(field_count));
3787
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
3789
table->read_set= &table->def_read_set;
3790
bitmap_clear_all(table->read_set);
3791
table_list->schema_table_param= tmp_table_param;
3797
For old SHOW compatibility. It is used when
3798
old SHOW doesn't have generated column names
3799
Make list of fields for SHOW
3803
session thread handler
3804
schema_table pointer to 'schema_tables' element
3811
int make_old_format(Session *session, InfoSchemaTable *schema_table)
3813
ST_FIELD_INFO *field_info= schema_table->fields_info;
3814
Name_resolution_context *context= &session->lex->select_lex.context;
3815
for (; field_info->field_name; field_info++)
3817
if (field_info->old_name)
3819
Item_field *field= new Item_field(context,
3820
NULL, NULL, field_info->field_name);
3823
field->set_name(field_info->old_name,
3824
strlen(field_info->old_name),
3825
system_charset_info);
3826
if (session->add_item_to_list(field))
3835
int make_schemata_old_format(Session *session, InfoSchemaTable *schema_table)
3838
LEX *lex= session->lex;
3839
Select_Lex *sel= lex->current_select;
3840
Name_resolution_context *context= &sel->context;
3842
if (!sel->item_list.elements)
3844
ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
3845
String buffer(tmp,sizeof(tmp), system_charset_info);
3846
Item_field *field= new Item_field(context,
3847
NULL, NULL, field_info->field_name);
3848
if (!field || session->add_item_to_list(field))
3851
buffer.append(field_info->old_name);
3852
if (lex->wild && lex->wild->ptr())
3854
buffer.append(STRING_WITH_LEN(" ("));
3855
buffer.append(lex->wild->ptr());
3858
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
3864
int make_table_names_old_format(Session *session, InfoSchemaTable *schema_table)
3867
String buffer(tmp,sizeof(tmp), session->charset());
3868
LEX *lex= session->lex;
3869
Name_resolution_context *context= &lex->select_lex.context;
3871
ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
3873
buffer.append(field_info->old_name);
3874
buffer.append(lex->select_lex.db);
3875
if (lex->wild && lex->wild->ptr())
3877
buffer.append(STRING_WITH_LEN(" ("));
3878
buffer.append(lex->wild->ptr());
3881
Item_field *field= new Item_field(context,
3882
NULL, NULL, field_info->field_name);
3883
if (session->add_item_to_list(field))
3885
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
3886
if (session->lex->verbose)
3888
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
3889
field_info= &schema_table->fields_info[3];
3890
field= new Item_field(context, NULL, NULL, field_info->field_name);
3891
if (session->add_item_to_list(field))
3893
field->set_name(field_info->old_name, strlen(field_info->old_name),
3894
system_charset_info);
3900
int make_columns_old_format(Session *session, InfoSchemaTable *schema_table)
3902
int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
3903
int *field_num= fields_arr;
3904
ST_FIELD_INFO *field_info;
3905
Name_resolution_context *context= &session->lex->select_lex.context;
3907
for (; *field_num >= 0; field_num++)
3909
field_info= &schema_table->fields_info[*field_num];
3910
if (!session->lex->verbose && (*field_num == 13 ||
3914
Item_field *field= new Item_field(context,
3915
NULL, NULL, field_info->field_name);
3918
field->set_name(field_info->old_name,
3919
strlen(field_info->old_name),
3920
system_charset_info);
3921
if (session->add_item_to_list(field))
3929
int make_character_sets_old_format(Session *session, InfoSchemaTable *schema_table)
3931
int fields_arr[]= {0, 2, 1, 3, -1};
3932
int *field_num= fields_arr;
3933
ST_FIELD_INFO *field_info;
3934
Name_resolution_context *context= &session->lex->select_lex.context;
3936
for (; *field_num >= 0; field_num++)
3938
field_info= &schema_table->fields_info[*field_num];
3939
Item_field *field= new Item_field(context,
3940
NULL, NULL, field_info->field_name);
3943
field->set_name(field_info->old_name,
3944
strlen(field_info->old_name),
3945
system_charset_info);
3946
if (session->add_item_to_list(field))
3955
Create information_schema table
3958
mysql_schema_table()
3959
session thread handler
3961
table_list pointer to table_list
3968
int mysql_schema_table(Session *session, LEX *, TableList *table_list)
3971
if (!(table= table_list->schema_table->create_table(session, table_list)))
3973
table->s->tmp_table= SYSTEM_TMP_TABLE;
3975
This test is necessary to make
3976
case insensitive file systems +
3977
upper case table names(information schema tables) +
3981
if (table_list->schema_table_name)
3982
table->alias_name_used= my_strcasecmp(table_alias_charset,
3983
table_list->schema_table_name,
3985
table_list->table_name= table->s->table_name.str;
3986
table_list->table_name_length= table->s->table_name.length;
3987
table_list->table= table;
3988
table->next= session->derived_tables;
3989
session->derived_tables= table;
3990
table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
3997
Generate select from information_schema table
4000
make_schema_select()
4001
session thread handler
4002
sel pointer to Select_Lex
4003
schema_table_idx index of 'schema_tables' element
4010
int make_schema_select(Session *session, Select_Lex *sel,
4011
enum enum_schema_tables schema_table_idx)
4013
InfoSchemaTable *schema_table= get_schema_table(schema_table_idx);
4014
LEX_STRING db, table;
4016
We have to make non const db_name & table_name
4017
because of lower_case_table_names
4019
session->make_lex_string(&db, INFORMATION_SCHEMA_NAME.c_str(),
4020
INFORMATION_SCHEMA_NAME.length(), 0);
4021
session->make_lex_string(&table, schema_table->table_name,
4022
strlen(schema_table->table_name), 0);
4023
if (schema_table->old_format(session, schema_table) || /* Handle old syntax */
4024
!sel->add_table_to_list(session, new Table_ident(session, db, table, 0),
4034
Fill temporary schema tables before SELECT
4037
get_schema_tables_result()
4038
join join which use schema tables
4039
executed_place place where I_S table processed
4046
bool get_schema_tables_result(JOIN *join,
4047
enum enum_schema_table_state executed_place)
4049
JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
4050
Session *session= join->session;
4051
LEX *lex= session->lex;
4054
session->no_warnings_for_error= 1;
4055
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
4057
if (!tab->table || !tab->table->pos_in_table_list)
4060
TableList *table_list= tab->table->pos_in_table_list;
4061
if (table_list->schema_table)
4063
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
4064
lex->current_select->master_unit()->item);
4067
/* skip I_S optimizations specific to get_all_tables */
4068
if (session->lex->describe &&
4069
(table_list->schema_table->fill_table != get_all_tables))
4073
If schema table is already processed and
4074
the statement is not a subselect then
4075
we don't need to fill this table again.
4076
If schema table is already processed and
4077
schema_table_state != executed_place then
4078
table is already processed and
4079
we should skip second data processing.
4081
if (table_list->schema_table_state &&
4082
(!is_subselect || table_list->schema_table_state != executed_place))
4086
if table is used in a subselect and
4087
table has been processed earlier with the same
4088
'executed_place' value then we should refresh the table.
4090
if (table_list->schema_table_state && is_subselect)
4092
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
4093
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
4094
table_list->table->file->ha_delete_all_rows();
4095
free_io_cache(table_list->table);
4096
filesort_free_buffers(table_list->table,1);
4097
table_list->table->null_row= 0;
4100
table_list->table->file->stats.records= 0;
4102
if (table_list->schema_table->fill_table(session, table_list,
4107
tab->read_record.file= table_list->table->file;
4108
table_list->schema_table_state= executed_place;
4111
tab->read_record.file= table_list->table->file;
4112
table_list->schema_table_state= executed_place;
4115
session->no_warnings_for_error= 0;
4119
ST_FIELD_INFO schema_fields_info[]=
4121
{"CATALOG_NAME", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4122
{"SCHEMA_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4124
{"DEFAULT_CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4126
{"DEFAULT_COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4127
{"SQL_PATH", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4128
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4132
ST_FIELD_INFO tables_fields_info[]=
4134
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4135
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4136
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4138
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4139
{"ENGINE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Engine", OPEN_FRM_ONLY},
4140
{"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4141
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
4142
{"ROW_FORMAT", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Row_format", OPEN_FULL_TABLE},
4143
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4144
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
4145
{"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4146
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
4147
{"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4148
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
4149
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4150
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
4151
{"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4152
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
4153
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4154
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
4155
{"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG, 0,
4156
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
4157
{"CREATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4158
{"UPDATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4159
{"CHECK_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
4160
{"TABLE_COLLATION", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4161
{"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4162
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
4163
{"CREATE_OPTIONS", 255, DRIZZLE_TYPE_VARCHAR, 0, 1, "Create_options",
4165
{"TABLE_COMMENT", TABLE_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4166
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4170
ST_FIELD_INFO columns_fields_info[]=
4172
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4173
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4174
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4175
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Field",
4177
{"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4178
MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
4179
{"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, DRIZZLE_TYPE_VARCHAR, 0,
4180
1, "Default", OPEN_FRM_ONLY},
4181
{"IS_NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4182
{"DATA_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4183
{"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4184
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4185
{"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4186
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4187
{"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4188
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4189
{"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4190
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4191
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4192
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4193
{"COLUMN_TYPE", 65535, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", OPEN_FRM_ONLY},
4194
{"COLUMN_KEY", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key", OPEN_FRM_ONLY},
4195
{"EXTRA", 27, DRIZZLE_TYPE_VARCHAR, 0, 0, "Extra", OPEN_FRM_ONLY},
4196
{"PRIVILEGES", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Privileges", OPEN_FRM_ONLY},
4197
{"COLUMN_COMMENT", COLUMN_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4198
{"STORAGE", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Storage", OPEN_FRM_ONLY},
4199
{"FORMAT", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Format", OPEN_FRM_ONLY},
4200
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4204
ST_FIELD_INFO charsets_fields_info[]=
4206
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4208
{"DEFAULT_COLLATE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default collation",
4210
{"DESCRIPTION", 60, DRIZZLE_TYPE_VARCHAR, 0, 0, "Description",
4212
{"MAXLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
4213
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4217
ST_FIELD_INFO collation_fields_info[]=
4219
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Collation", SKIP_OPEN_TABLE},
4220
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4222
{"ID", MY_INT32_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id",
4224
{"IS_DEFAULT", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default", SKIP_OPEN_TABLE},
4225
{"IS_COMPILED", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Compiled", SKIP_OPEN_TABLE},
4226
{"SORTLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
4227
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4232
ST_FIELD_INFO coll_charset_app_fields_info[]=
4234
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4235
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4236
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4240
ST_FIELD_INFO stat_fields_info[]=
4242
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4243
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4244
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", OPEN_FRM_ONLY},
4245
{"NON_UNIQUE", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
4246
{"INDEX_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4247
{"INDEX_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key_name",
4249
{"SEQ_IN_INDEX", 2, DRIZZLE_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
4250
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Column_name",
4252
{"COLLATION", 1, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4253
{"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 1,
4254
"Cardinality", OPEN_FULL_TABLE},
4255
{"SUB_PART", 3, DRIZZLE_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
4256
{"PACKED", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Packed", OPEN_FRM_ONLY},
4257
{"NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4258
{"INDEX_TYPE", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_type", OPEN_FULL_TABLE},
4259
{"COMMENT", 16, DRIZZLE_TYPE_VARCHAR, 0, 1, "Comment", OPEN_FRM_ONLY},
4260
{"INDEX_COMMENT", INDEX_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_Comment", OPEN_FRM_ONLY},
4261
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4265
ST_FIELD_INFO table_constraints_fields_info[]=
4267
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4268
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4270
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4272
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4273
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4274
{"CONSTRAINT_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4276
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4280
ST_FIELD_INFO key_column_usage_fields_info[]=
4282
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4283
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4285
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4287
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4288
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4289
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4290
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4291
{"ORDINAL_POSITION", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
4292
{"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 1, 0,
4294
{"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4296
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4298
{"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4300
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4304
ST_FIELD_INFO table_names_fields_info[]=
4306
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4307
{"TABLE_SCHEMA",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4308
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Tables_in_",
4310
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table_type",
4312
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4316
ST_FIELD_INFO open_tables_fields_info[]=
4318
{"Database", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4320
{"Table",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", SKIP_OPEN_TABLE},
4321
{"In_use", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
4322
{"Name_locked", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
4323
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4327
ST_FIELD_INFO variables_fields_info[]=
4329
{"VARIABLE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Variable_name",
4331
{"VARIABLE_VALUE", 16300, DRIZZLE_TYPE_VARCHAR, 0, 1, "Value", SKIP_OPEN_TABLE},
4332
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4336
ST_FIELD_INFO processlist_fields_info[]=
4338
{"ID", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
4339
{"USER", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "User", SKIP_OPEN_TABLE},
4340
{"HOST", LIST_PROCESS_HOST_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Host",
4342
{"DB", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Db", SKIP_OPEN_TABLE},
4343
{"COMMAND", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Command", SKIP_OPEN_TABLE},
4344
{"TIME", 7, DRIZZLE_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
4345
{"STATE", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "State", SKIP_OPEN_TABLE},
4346
{"INFO", PROCESS_LIST_INFO_WIDTH, DRIZZLE_TYPE_VARCHAR, 0, 1, "Info",
4348
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4352
ST_FIELD_INFO plugin_fields_info[]=
4354
{"PLUGIN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4356
{"PLUGIN_VERSION", 20, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4357
{"PLUGIN_STATUS", 10, DRIZZLE_TYPE_VARCHAR, 0, 0, "Status", SKIP_OPEN_TABLE},
4358
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4359
{"PLUGIN_DESCRIPTION", 65535, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4360
{"PLUGIN_LICENSE", 80, DRIZZLE_TYPE_VARCHAR, 0, 1, "License", SKIP_OPEN_TABLE},
4361
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4364
ST_FIELD_INFO referential_constraints_fields_info[]=
4366
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4367
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4369
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4371
{"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4373
{"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4375
{"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0,
4376
MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
4377
{"MATCH_OPTION", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4378
{"UPDATE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4379
{"DELETE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4380
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4381
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4383
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4388
Description of ST_FIELD_INFO in table.h
4390
Make sure that the order of schema_tables and enum_schema_tables are the same.
4394
InfoSchemaTable schema_tables[]=
4396
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
4397
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4398
{"COLLATIONS", collation_fields_info, create_schema_table,
4399
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4400
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4401
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4402
{"COLUMNS", columns_fields_info, create_schema_table,
4403
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
4404
OPTIMIZE_I_S_TABLE},
4405
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4406
fill_status, make_old_format, 0, -1, -1, 0, 0},
4407
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
4408
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4409
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
4410
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
4412
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
4413
fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
4414
{"PLUGINS", plugin_fields_info, create_schema_table,
4415
fill_plugins, make_old_format, 0, -1, -1, 0, 0},
4416
{"PROCESSLIST", processlist_fields_info, create_schema_table,
4417
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
4418
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
4419
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
4420
1, 9, 0, OPEN_TABLE_ONLY},
4421
{"SCHEMATA", schema_fields_info, create_schema_table,
4422
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
4423
{"SESSION_STATUS", variables_fields_info, create_schema_table,
4424
fill_status, make_old_format, 0, -1, -1, 0, 0},
4425
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4426
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4427
{"STATISTICS", stat_fields_info, create_schema_table,
4428
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4429
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4430
{"STATUS", variables_fields_info, create_schema_table, fill_status,
4431
make_old_format, 0, -1, -1, 1, 0},
4432
{"TABLES", tables_fields_info, create_schema_table,
4433
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4434
OPTIMIZE_I_S_TABLE},
4435
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4436
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
4437
{"TABLE_NAMES", table_names_fields_info, create_schema_table,
4438
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
4439
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
4440
make_old_format, 0, -1, -1, 1, 0},
4441
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}