138
542
# Quote character
141
int get_quote_char_for_identifier()
545
int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
548
!is_keyword(name,length) &&
549
!require_quotes(name, length) &&
550
!(thd->options & OPTION_QUOTE_SHOW_CREATE))
146
} /* namespace drizzled */
556
/* Append directory name (if exists) to CREATE INFO */
558
static void append_directory(THD *thd __attribute__((unused)),
559
String *packet, const char *dir_type,
560
const char *filename)
564
uint length= dirname_length(filename);
566
packet->append(dir_type);
567
packet->append(STRING_WITH_LEN(" DIRECTORY='"));
568
packet->append(filename, length);
569
packet->append('\'');
574
#define LIST_PROCESS_HOST_LEN 64
576
static bool get_field_default_value(THD *thd __attribute__((unused)),
577
Field *timestamp_field,
578
Field *field, String *def_value,
582
bool has_now_default;
585
We are using CURRENT_TIMESTAMP instead of NOW because it is
588
has_now_default= (timestamp_field == field &&
589
field->unireg_check != Field::TIMESTAMP_UN_FIELD);
591
has_default= (field->type() != DRIZZLE_TYPE_BLOB &&
592
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
593
field->unireg_check != Field::NEXT_NUMBER
596
def_value->length(0);
600
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
601
else if (!field->is_null())
602
{ // Not null by default
603
char tmp[MAX_FIELD_WIDTH];
604
String type(tmp, sizeof(tmp), field->charset());
605
field->val_str(&type);
610
/* convert to system_charset_info == utf8 */
611
def_val.copy(type.ptr(), type.length(), field->charset(),
612
system_charset_info, &dummy_errors);
614
append_unescaped(def_value, def_val.ptr(), def_val.length());
616
def_value->append(def_val.ptr(), def_val.length());
619
def_value->append(STRING_WITH_LEN("''"));
621
else if (field->maybe_null() && quoted)
622
def_value->append(STRING_WITH_LEN("NULL")); // Null as default
631
Build a CREATE TABLE statement for a table.
636
table_list A list containing one table to write statement
638
packet Pointer to a string where statement will be
640
create_info_arg Pointer to create information that can be used
641
to tailor the format of the statement. Can be
642
NULL, in which case only SQL_MODE is considered
643
when building the statement.
646
Currently always return 0, but might return error code in the
653
int store_create_info(THD *thd, TableList *table_list, String *packet,
654
HA_CREATE_INFO *create_info_arg)
656
List<Item> field_list;
657
char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
659
String type(tmp, sizeof(tmp), system_charset_info);
660
String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
664
Table *table= table_list->table;
665
handler *file= table->file;
666
TABLE_SHARE *share= table->s;
667
HA_CREATE_INFO create_info;
668
bool show_table_options= false;
669
my_bitmap_map *old_map;
671
restore_record(table, s->default_values); // Get empty record
673
if (share->tmp_table)
674
packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
676
packet->append(STRING_WITH_LEN("CREATE TABLE "));
677
if (create_info_arg &&
678
(create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
679
packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
680
if (table_list->schema_table)
681
alias= table_list->schema_table->table_name;
684
if (lower_case_table_names == 2)
688
alias= share->table_name.str;
691
append_identifier(thd, packet, alias, strlen(alias));
692
packet->append(STRING_WITH_LEN(" (\n"));
694
We need this to get default values from the table
695
We have to restore the read_set if we are called from insert in case
696
of row based replication.
698
old_map= table->use_all_columns(table->read_set);
700
for (ptr=table->field ; (field= *ptr); ptr++)
702
uint flags = field->flags;
704
if (ptr != table->field)
705
packet->append(STRING_WITH_LEN(",\n"));
707
packet->append(STRING_WITH_LEN(" "));
708
append_identifier(thd,packet,field->field_name, strlen(field->field_name));
710
// check for surprises from the previous call to Field::sql_type()
711
if (type.ptr() != tmp)
712
type.set(tmp, sizeof(tmp), system_charset_info);
714
type.set_charset(system_charset_info);
716
field->sql_type(type);
717
packet->append(type.ptr(), type.length(), system_charset_info);
719
if (field->has_charset())
721
if (field->charset() != share->table_charset)
723
packet->append(STRING_WITH_LEN(" CHARACTER SET "));
724
packet->append(field->charset()->csname);
727
For string types dump collation name only if
728
collation is not primary for the given charset
730
if (!(field->charset()->state & MY_CS_PRIMARY))
732
packet->append(STRING_WITH_LEN(" COLLATE "));
733
packet->append(field->charset()->name);
737
if (flags & NOT_NULL_FLAG)
738
packet->append(STRING_WITH_LEN(" NOT NULL"));
739
else if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
742
TIMESTAMP field require explicit NULL flag, because unlike
743
all other fields they are treated as NOT NULL by default.
745
packet->append(STRING_WITH_LEN(" NULL"));
749
Add field flags about FIELD FORMAT (FIXED or DYNAMIC)
750
and about STORAGE (DISK or MEMORY).
752
enum column_format_type column_format= (enum column_format_type)
753
((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
756
packet->append(STRING_WITH_LEN(" /*!"));
757
packet->append(STRING_WITH_LEN(DRIZZLE_VERSION_TABLESPACE_IN_FRM_STR));
758
packet->append(STRING_WITH_LEN(" COLUMN_FORMAT"));
759
if (column_format == COLUMN_FORMAT_TYPE_FIXED)
760
packet->append(STRING_WITH_LEN(" FIXED */"));
762
packet->append(STRING_WITH_LEN(" DYNAMIC */"));
765
if (get_field_default_value(thd, table->timestamp_field,
766
field, &def_value, 1))
768
packet->append(STRING_WITH_LEN(" DEFAULT "));
769
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
772
if (table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_DN_FIELD)
773
packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
775
if (field->unireg_check == Field::NEXT_NUMBER)
776
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
778
if (field->comment.length)
780
packet->append(STRING_WITH_LEN(" COMMENT "));
781
append_unescaped(packet, field->comment.str, field->comment.length);
785
key_info= table->key_info;
786
memset(&create_info, 0, sizeof(create_info));
787
/* Allow update_create_info to update row type */
788
create_info.row_type= share->row_type;
789
file->update_create_info(&create_info);
790
primary_key= share->primary_key;
792
for (uint i=0 ; i < share->keys ; i++,key_info++)
794
KEY_PART_INFO *key_part= key_info->key_part;
795
bool found_primary=0;
796
packet->append(STRING_WITH_LEN(",\n "));
798
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
802
No space at end, because a space will be added after where the
803
identifier would go, but that is not added for primary key.
805
packet->append(STRING_WITH_LEN("PRIMARY KEY"));
807
else if (key_info->flags & HA_NOSAME)
808
packet->append(STRING_WITH_LEN("UNIQUE KEY "));
810
packet->append(STRING_WITH_LEN("KEY "));
813
append_identifier(thd, packet, key_info->name, strlen(key_info->name));
815
packet->append(STRING_WITH_LEN(" ("));
817
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
823
append_identifier(thd,packet,key_part->field->field_name,
824
strlen(key_part->field->field_name));
825
if (key_part->field &&
827
table->field[key_part->fieldnr-1]->key_length()))
831
end= int10_to_str((long) key_part->length /
832
key_part->field->charset()->mbmaxlen,
835
packet->append(buff,(uint) (end-buff));
839
store_key_options(thd, packet, table, key_info);
843
Get possible foreign key definitions stored in InnoDB and append them
844
to the CREATE TABLE statement
847
if ((for_str= file->get_foreign_key_create_info()))
849
packet->append(for_str, strlen(for_str));
850
file->free_foreign_key_create_info(for_str);
853
packet->append(STRING_WITH_LEN("\n)"));
855
show_table_options= true;
857
Get possible table space definitions and append them
858
to the CREATE TABLE statement
863
THEN add ENGINE only if it was used when creating the table
865
if (!create_info_arg ||
866
(create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
868
packet->append(STRING_WITH_LEN(" ENGINE="));
869
packet->append(file->table_type());
873
Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
874
and NEXT_ID > 1 (the default). We must not print the clause
875
for engines that do not support this as it would break the
876
import of dumps, but as of this writing, the test for whether
877
AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
878
is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
879
Because of that, we do not explicitly test for the feature,
880
but may extrapolate its existence from that of an AUTO_INCREMENT column.
883
if (create_info.auto_increment_value > 1)
886
packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
887
end= int64_t10_to_str(create_info.auto_increment_value, buff,10);
888
packet->append(buff, (uint) (end - buff));
894
packet->append(STRING_WITH_LEN(" MIN_ROWS="));
895
end= int64_t10_to_str(share->min_rows, buff, 10);
896
packet->append(buff, (uint) (end- buff));
899
if (share->max_rows && !table_list->schema_table)
902
packet->append(STRING_WITH_LEN(" MAX_ROWS="));
903
end= int64_t10_to_str(share->max_rows, buff, 10);
904
packet->append(buff, (uint) (end - buff));
907
if (share->avg_row_length)
910
packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
911
end= int64_t10_to_str(share->avg_row_length, buff,10);
912
packet->append(buff, (uint) (end - buff));
915
if (share->db_create_options & HA_OPTION_PACK_KEYS)
916
packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
917
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
918
packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
919
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
920
if (share->db_create_options & HA_OPTION_CHECKSUM)
921
packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
922
if (share->page_checksum != HA_CHOICE_UNDEF)
924
packet->append(STRING_WITH_LEN(" PAGE_CHECKSUM="));
925
packet->append(ha_choice_values[(uint) share->page_checksum], 1);
927
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
928
packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
929
if (create_info.row_type != ROW_TYPE_DEFAULT)
931
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
932
packet->append(ha_row_type[(uint) create_info.row_type]);
934
if (share->transactional != HA_CHOICE_UNDEF)
936
packet->append(STRING_WITH_LEN(" TRANSACTIONAL="));
937
packet->append(ha_choice_values[(uint) share->transactional], 1);
939
if (table->s->key_block_size)
942
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
943
end= int64_t10_to_str(table->s->key_block_size, buff, 10);
944
packet->append(buff, (uint) (end - buff));
946
if (share->block_size)
949
packet->append(STRING_WITH_LEN(" BLOCK_SIZE="));
950
end= int64_t10_to_str(share->block_size, buff,10);
951
packet->append(buff, (uint) (end - buff));
953
table->file->append_create_info(packet);
954
if (share->comment.length)
956
packet->append(STRING_WITH_LEN(" COMMENT="));
957
append_unescaped(packet, share->comment.str, share->comment.length);
959
if (share->connect_string.length)
961
packet->append(STRING_WITH_LEN(" CONNECTION="));
962
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
964
append_directory(thd, packet, "DATA", create_info.data_file_name);
965
append_directory(thd, packet, "INDEX", create_info.index_file_name);
967
table->restore_column_map(old_map);
972
Get a CREATE statement for a given database.
974
The database is identified by its name, passed as @c dbname parameter.
975
The name should be encoded using the system character set (UTF8 currently).
977
Resulting statement is stored in the string pointed by @c buffer. The string
978
is emptied first and its character set is set to the system character set.
980
If HA_LEX_CREATE_IF_NOT_EXISTS flag is set in @c create_info->options, then
981
the resulting CREATE statement contains "IF NOT EXISTS" clause. Other flags
982
in @c create_options are ignored.
984
@param thd The current thread instance.
985
@param dbname The name of the database.
986
@param buffer A String instance where the statement is stored.
987
@param create_info If not NULL, the options member influences the resulting
990
@returns true if errors are detected, false otherwise.
993
bool store_db_create_info(THD *thd, const char *dbname, String *buffer,
994
HA_CREATE_INFO *create_info)
996
HA_CREATE_INFO create;
997
uint create_options = create_info ? create_info->options : 0;
999
if (!my_strcasecmp(system_charset_info, dbname,
1000
INFORMATION_SCHEMA_NAME.str))
1002
dbname= INFORMATION_SCHEMA_NAME.str;
1003
create.default_table_charset= system_charset_info;
1007
if (check_db_dir_existence(dbname))
1010
load_db_opt_by_name(thd, dbname, &create);
1015
buffer->set_charset(system_charset_info);
1016
buffer->append(STRING_WITH_LEN("CREATE DATABASE "));
1018
if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
1019
buffer->append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
1021
append_identifier(thd, buffer, dbname, strlen(dbname));
1023
if (create.default_table_charset)
1025
buffer->append(STRING_WITH_LEN(" /*!40100"));
1026
buffer->append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
1027
buffer->append(create.default_table_charset->csname);
1028
if (!(create.default_table_charset->state & MY_CS_PRIMARY))
1030
buffer->append(STRING_WITH_LEN(" COLLATE "));
1031
buffer->append(create.default_table_charset->name);
1033
buffer->append(STRING_WITH_LEN(" */"));
1039
static void store_key_options(THD *thd __attribute__((unused)),
1040
String *packet, Table *table,
1043
char *end, buff[32];
1045
if (key_info->algorithm == HA_KEY_ALG_BTREE)
1046
packet->append(STRING_WITH_LEN(" USING BTREE"));
1048
if (key_info->algorithm == HA_KEY_ALG_HASH)
1049
packet->append(STRING_WITH_LEN(" USING HASH"));
1051
if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
1052
table->s->key_block_size != key_info->block_size)
1054
packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
1055
end= int64_t10_to_str(key_info->block_size, buff, 10);
1056
packet->append(buff, (uint) (end - buff));
1059
assert(test(key_info->flags & HA_USES_COMMENT) ==
1060
(key_info->comment.length > 0));
1061
if (key_info->flags & HA_USES_COMMENT)
1063
packet->append(STRING_WITH_LEN(" COMMENT "));
1064
append_unescaped(packet, key_info->comment.str,
1065
key_info->comment.length);
1070
/****************************************************************************
1071
Return info about all processes
1072
returns for each thread: thread id, user, host, db, command, info
1073
****************************************************************************/
1075
class thread_info :public ilink {
1077
static void *operator new(size_t size)
1079
return (void*) sql_alloc((uint) size);
1081
static void operator delete(void *ptr __attribute__((unused)),
1082
size_t size __attribute__((unused)))
1083
{ TRASH(ptr, size); }
1088
const char *user,*host,*db,*proc_info,*state_info;
1092
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1093
template class I_List<thread_info>;
1096
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
1099
List<Item> field_list;
1100
I_List<thread_info> thread_infos;
1101
ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
1102
PROCESS_LIST_WIDTH);
1103
Protocol *protocol= thd->protocol;
1105
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1106
field_list.push_back(new Item_empty_string("User",16));
1107
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1108
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1109
field->maybe_null=1;
1110
field_list.push_back(new Item_empty_string("Command",16));
1111
field_list.push_back(new Item_return_int("Time",7, DRIZZLE_TYPE_LONG));
1112
field_list.push_back(field=new Item_empty_string("State",30));
1113
field->maybe_null=1;
1114
field_list.push_back(field=new Item_empty_string("Info",max_query_length));
1115
field->maybe_null=1;
1116
if (protocol->send_fields(&field_list,
1117
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
1120
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
1123
I_List_iterator<THD> it(threads);
1127
Security_context *tmp_sctx= tmp->security_ctx;
1128
struct st_my_thread_var *mysys_var;
1129
if ((tmp->vio_ok() || tmp->system_thread) && (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
1131
thread_info *thd_info= new thread_info;
1133
thd_info->thread_id=tmp->thread_id;
1134
thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
1135
(tmp->system_thread ?
1136
"system user" : "unauthenticated user"));
1137
thd_info->host= thd->strdup(tmp_sctx->ip);
1138
if ((thd_info->db=tmp->db)) // Safe test
1139
thd_info->db=thd->strdup(thd_info->db);
1140
thd_info->command=(int) tmp->command;
1141
if ((mysys_var= tmp->mysys_var))
1142
pthread_mutex_lock(&mysys_var->mutex);
1143
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
1144
thd_info->state_info= (char*) (tmp->net.reading_or_writing ?
1145
(tmp->net.reading_or_writing == 2 ?
1147
thd_info->command == COM_SLEEP ? NullS :
1148
"Reading from net") :
1149
tmp->get_proc_info() ? tmp->get_proc_info() :
1151
tmp->mysys_var->current_cond ?
1152
"Waiting on cond" : NullS);
1154
pthread_mutex_unlock(&mysys_var->mutex);
1156
thd_info->start_time= tmp->start_time;
1161
query_length is always set to 0 when we set query = NULL; see
1162
the comment in sql_class.h why this prevents crashes in possible
1163
races with query_length
1165
uint length= min((uint32_t)max_query_length, tmp->query_length);
1166
thd_info->query=(char*) thd->strmake(tmp->query,length);
1168
thread_infos.append(thd_info);
1172
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1174
thread_info *thd_info;
1175
time_t now= my_time(0);
1176
while ((thd_info=thread_infos.get()))
1178
protocol->prepare_for_resend();
1179
protocol->store((uint64_t) thd_info->thread_id);
1180
protocol->store(thd_info->user, system_charset_info);
1181
protocol->store(thd_info->host, system_charset_info);
1182
protocol->store(thd_info->db, system_charset_info);
1183
if (thd_info->proc_info)
1184
protocol->store(thd_info->proc_info, system_charset_info);
1186
protocol->store(command_name[thd_info->command].str, system_charset_info);
1187
if (thd_info->start_time)
1188
protocol->store((uint32_t) (now - thd_info->start_time));
1190
protocol->store_null();
1191
protocol->store(thd_info->state_info, system_charset_info);
1192
protocol->store(thd_info->query, system_charset_info);
1193
if (protocol->write())
1194
break; /* purecov: inspected */
1200
int fill_schema_processlist(THD* thd, TableList* tables,
1201
COND* cond __attribute__((unused)))
1203
Table *table= tables->table;
1204
const CHARSET_INFO * const cs= system_charset_info;
1206
time_t now= my_time(0);
1210
VOID(pthread_mutex_lock(&LOCK_thread_count));
1214
I_List_iterator<THD> it(threads);
1219
Security_context *tmp_sctx= tmp->security_ctx;
1220
struct st_my_thread_var *mysys_var;
1223
if ((!tmp->vio_ok() && !tmp->system_thread))
1226
restore_record(table, s->default_values);
1228
table->field[0]->store((int64_t) tmp->thread_id, true);
1230
val= tmp_sctx->user ? tmp_sctx->user :
1231
(tmp->system_thread ? "system user" : "unauthenticated user");
1232
table->field[1]->store(val, strlen(val), cs);
1234
table->field[2]->store(tmp_sctx->ip, strlen(tmp_sctx->ip), cs);
1238
table->field[3]->store(tmp->db, strlen(tmp->db), cs);
1239
table->field[3]->set_notnull();
1242
if ((mysys_var= tmp->mysys_var))
1243
pthread_mutex_lock(&mysys_var->mutex);
1245
if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
1246
table->field[4]->store(val, strlen(val), cs);
1248
table->field[4]->store(command_name[tmp->command].str,
1249
command_name[tmp->command].length, cs);
1251
table->field[5]->store((uint32_t)(tmp->start_time ?
1252
now - tmp->start_time : 0), true);
1254
val= (char*) (tmp->net.reading_or_writing ?
1255
(tmp->net.reading_or_writing == 2 ?
1257
tmp->command == COM_SLEEP ? NullS :
1258
"Reading from net") :
1259
tmp->get_proc_info() ? tmp->get_proc_info() :
1261
tmp->mysys_var->current_cond ?
1262
"Waiting on cond" : NullS);
1265
table->field[6]->store(val, strlen(val), cs);
1266
table->field[6]->set_notnull();
1270
pthread_mutex_unlock(&mysys_var->mutex);
1275
table->field[7]->store(tmp->query,
1276
min((uint32_t)PROCESS_LIST_INFO_WIDTH,
1277
tmp->query_length), cs);
1278
table->field[7]->set_notnull();
1281
if (schema_table_store_record(thd, table))
1283
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1289
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1293
/*****************************************************************************
1295
*****************************************************************************/
1297
static DYNAMIC_ARRAY all_status_vars;
1298
static bool status_vars_inited= 0;
1299
static int show_var_cmp(const void *var1, const void *var2)
1301
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1305
deletes all the SHOW_UNDEF elements from the array and calls
1306
delete_dynamic() if it's completely empty.
1308
static void shrink_var_array(DYNAMIC_ARRAY *array)
1311
SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
1313
for (a= b= 0; b < array->elements; b++)
1314
if (all[b].type != SHOW_UNDEF)
1318
memset(all+a, 0, sizeof(SHOW_VAR)); // writing NULL-element to the end
1321
else // array is completely empty - delete it
1322
delete_dynamic(array);
1326
Adds an array of SHOW_VAR entries to the output of SHOW STATUS
1329
add_status_vars(SHOW_VAR *list)
1330
list - an array of SHOW_VAR entries to add to all_status_vars
1331
the last entry must be {0,0,SHOW_UNDEF}
1334
The handling of all_status_vars[] is completely internal, it's allocated
1335
automatically when something is added to it, and deleted completely when
1336
the last entry is removed.
1338
As a special optimization, if add_status_vars() is called before
1339
init_status_vars(), it assumes "startup mode" - neither concurrent access
1340
to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
1342
The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
1344
int add_status_vars(SHOW_VAR *list)
1347
if (status_vars_inited)
1348
pthread_mutex_lock(&LOCK_status);
1349
if (!all_status_vars.buffer && // array is not allocated yet - do it now
1350
my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
1356
res|= insert_dynamic(&all_status_vars, (uchar*)list++);
1357
res|= insert_dynamic(&all_status_vars, (uchar*)list); // appending NULL-element
1358
all_status_vars.elements--; // but next insert_dynamic should overwite it
1359
if (status_vars_inited)
1360
sort_dynamic(&all_status_vars, show_var_cmp);
1362
if (status_vars_inited)
1363
pthread_mutex_unlock(&LOCK_status);
1368
Make all_status_vars[] usable for SHOW STATUS
1371
See add_status_vars(). Before init_status_vars() call, add_status_vars()
1372
works in a special fast "startup" mode. Thus init_status_vars()
1373
should be called as late as possible but before enabling multi-threading.
1375
void init_status_vars()
1377
status_vars_inited=1;
1378
sort_dynamic(&all_status_vars, show_var_cmp);
1381
void reset_status_vars()
1383
SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
1384
SHOW_VAR *last= ptr + all_status_vars.elements;
1385
for (; ptr < last; ptr++)
1387
/* Note that SHOW_LONG_NOFLUSH variables are not reset */
1388
if (ptr->type == SHOW_LONG)
1389
*(ulong*) ptr->value= 0;
1394
catch-all cleanup function, cleans up everything no matter what
1397
This function is not strictly required if all add_to_status/
1398
remove_status_vars are properly paired, but it's a safety measure that
1399
deletes everything from the all_status_vars[] even if some
1400
remove_status_vars were forgotten
1402
void free_status_vars()
1404
delete_dynamic(&all_status_vars);
1408
Removes an array of SHOW_VAR entries from the output of SHOW STATUS
1411
remove_status_vars(SHOW_VAR *list)
1412
list - an array of SHOW_VAR entries to remove to all_status_vars
1413
the last entry must be {0,0,SHOW_UNDEF}
1416
there's lots of room for optimizing this, especially in non-sorted mode,
1417
but nobody cares - it may be called only in case of failed plugin
1418
initialization in the mysqld startup.
1421
void remove_status_vars(SHOW_VAR *list)
1423
if (status_vars_inited)
1425
pthread_mutex_lock(&LOCK_status);
1426
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1427
int a= 0, b= all_status_vars.elements, c= (a+b)/2;
1429
for (; list->name; list++)
1432
for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
1434
res= show_var_cmp(list, all+c);
1443
all[c].type= SHOW_UNDEF;
1445
shrink_var_array(&all_status_vars);
1446
pthread_mutex_unlock(&LOCK_status);
1450
SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
1452
for (; list->name; list++)
1454
for (i= 0; i < all_status_vars.elements; i++)
1456
if (show_var_cmp(list, all+i))
1458
all[i].type= SHOW_UNDEF;
1462
shrink_var_array(&all_status_vars);
1466
inline void make_upper(char *buf)
1469
*buf= my_toupper(system_charset_info, *buf);
1472
static bool show_status_array(THD *thd, const char *wild,
1473
SHOW_VAR *variables,
1474
enum enum_var_type value_type,
1475
struct system_status_var *status_var,
1476
const char *prefix, Table *table,
1479
MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
1480
char * const buff= (char *) &buff_data;
1482
/* the variable name should not be longer than 64 characters */
1483
char name_buffer[64];
1485
LEX_STRING null_lex_str;
1488
null_lex_str.str= 0; // For sys_var->value_ptr()
1489
null_lex_str.length= 0;
1491
prefix_end=stpncpy(name_buffer, prefix, sizeof(name_buffer)-1);
1494
len=name_buffer + sizeof(name_buffer) - prefix_end;
1496
for (; variables->name; variables++)
1498
stpncpy(prefix_end, variables->name, len);
1499
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
1501
make_upper(name_buffer);
1504
if var->type is SHOW_FUNC, call the function.
1505
Repeat as necessary, if new var is again SHOW_FUNC
1507
for (var=variables; var->type == SHOW_FUNC; var= &tmp)
1508
((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(thd, &tmp, buff);
1510
SHOW_TYPE show_type=var->type;
1511
if (show_type == SHOW_ARRAY)
1513
show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
1514
status_var, name_buffer, table, ucase_names);
1518
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
1519
name_buffer, wild)))
1521
char *value=var->value;
1522
const char *pos, *end; // We assign a lot of const's
1524
pthread_mutex_lock(&LOCK_global_system_variables);
1526
if (show_type == SHOW_SYS)
1528
show_type= ((sys_var*) value)->show_type();
1529
value= (char*) ((sys_var*) value)->value_ptr(thd, value_type,
1535
note that value may be == buff. All SHOW_xxx code below
1536
should still work in this case
1538
switch (show_type) {
1539
case SHOW_DOUBLE_STATUS:
1540
value= ((char *) status_var + (ulong) value);
1543
/* 6 is the default precision for '%f' in sprintf() */
1544
end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
1546
case SHOW_LONG_STATUS:
1547
value= ((char *) status_var + (ulong) value);
1550
case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
1551
end= int10_to_str(*(long*) value, buff, 10);
1553
case SHOW_LONGLONG_STATUS:
1554
value= ((char *) status_var + (uint64_t) value);
1557
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1560
end= int64_t10_to_str((int64_t) *(ha_rows*) value, buff, 10);
1563
end= stpcpy(buff, *(bool*) value ? "ON" : "OFF");
1566
end= stpcpy(buff, *(bool*) value ? "ON" : "OFF");
1569
end= int10_to_str((long) *(uint32_t*) value, buff, 10);
1573
SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
1574
pos= show_comp_option_name[(int) tmp];
1575
end= strchr(pos, '\0');
1582
end= strchr(pos, '\0');
1587
if (!(pos= *(char**) value))
1589
end= strchr(pos, '\0');
1592
case SHOW_KEY_CACHE_LONG:
1593
value= (char*) dflt_key_cache + (ulong)value;
1594
end= int10_to_str(*(long*) value, buff, 10);
1596
case SHOW_KEY_CACHE_LONGLONG:
1597
value= (char*) dflt_key_cache + (ulong)value;
1598
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1601
break; // Return empty string
1602
case SHOW_SYS: // Cannot happen
1607
restore_record(table, s->default_values);
1608
table->field[0]->store(name_buffer, strlen(name_buffer),
1609
system_charset_info);
1610
table->field[1]->store(pos, (uint32_t) (end - pos), system_charset_info);
1611
table->field[1]->set_notnull();
1613
pthread_mutex_unlock(&LOCK_global_system_variables);
1615
if (schema_table_store_record(thd, table))
1625
/* collect status for all running threads */
1627
void calc_sum_of_all_status(STATUS_VAR *to)
1630
/* Ensure that thread id not killed during loop */
1631
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
1633
I_List_iterator<THD> it(threads);
1636
/* Get global values as base */
1637
*to= global_status_var;
1639
/* Add to this status from existing threads */
1641
add_to_status(to, &tmp->status_var);
1643
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1648
/* This is only used internally, but we need it here as a forward reference */
1649
extern ST_SCHEMA_TABLE schema_tables[];
1651
typedef struct st_lookup_field_values
1653
LEX_STRING db_value, table_value;
1654
bool wild_db_value, wild_table_value;
1655
} LOOKUP_FIELD_VALUES;
1659
Store record to I_S table, convert HEAP table
1660
to MyISAM if necessary
1663
schema_table_store_record()
1665
table Information schema table to be updated
1672
bool schema_table_store_record(THD *thd, Table *table)
1675
if ((error= table->file->ha_write_row(table->record[0])))
1677
TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
1679
if (create_myisam_from_heap(thd, table, param->start_recinfo,
1680
¶m->recinfo, error, 0))
1687
int make_table_list(THD *thd, SELECT_LEX *sel,
1688
LEX_STRING *db_name, LEX_STRING *table_name)
1690
Table_ident *table_ident;
1691
table_ident= new Table_ident(thd, *db_name, *table_name, 1);
1693
if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
1700
@brief Get lookup value from the part of 'WHERE' condition
1702
@details This function gets lookup value from
1703
the part of 'WHERE' condition if it's possible and
1704
fill appropriate lookup_field_vals struct field
1707
@param[in] thd thread handler
1708
@param[in] item_func part of WHERE condition
1709
@param[in] table I_S table
1710
@param[in, out] lookup_field_vals Struct which holds lookup values
1714
1 error, there can be no matching records for the condition
1717
bool get_lookup_value(THD *thd, Item_func *item_func,
1719
LOOKUP_FIELD_VALUES *lookup_field_vals)
1721
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1722
ST_FIELD_INFO *field_info= schema_table->fields_info;
1723
const char *field_name1= schema_table->idx_field1 >= 0 ?
1724
field_info[schema_table->idx_field1].field_name : "";
1725
const char *field_name2= schema_table->idx_field2 >= 0 ?
1726
field_info[schema_table->idx_field2].field_name : "";
1728
if (item_func->functype() == Item_func::EQ_FUNC ||
1729
item_func->functype() == Item_func::EQUAL_FUNC)
1731
int idx_field, idx_val;
1732
char tmp[MAX_FIELD_WIDTH];
1733
String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
1734
Item_field *item_field;
1735
const CHARSET_INFO * const cs= system_charset_info;
1737
if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
1738
item_func->arguments()[1]->const_item())
1743
else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
1744
item_func->arguments()[0]->const_item())
1752
item_field= (Item_field*) item_func->arguments()[idx_field];
1753
if (table->table != item_field->field->table)
1755
tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
1757
/* impossible value */
1761
/* Lookup value is database name */
1762
if (!cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
1763
(uchar *) item_field->field_name,
1764
strlen(item_field->field_name), 0))
1766
thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
1767
tmp_str->length(), false);
1769
/* Lookup value is table name */
1770
else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2,
1771
strlen(field_name2),
1772
(uchar *) item_field->field_name,
1773
strlen(item_field->field_name), 0))
1775
thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
1776
tmp_str->length(), false);
1784
@brief Calculates lookup values from 'WHERE' condition
1786
@details This function calculates lookup value(database name, table name)
1787
from 'WHERE' condition if it's possible and
1788
fill lookup_field_vals struct fields with these values.
1790
@param[in] thd thread handler
1791
@param[in] cond WHERE condition
1792
@param[in] table I_S table
1793
@param[in, out] lookup_field_vals Struct which holds lookup values
1797
1 error, there can be no matching records for the condition
1800
bool calc_lookup_values_from_cond(THD *thd, COND *cond, TableList *table,
1801
LOOKUP_FIELD_VALUES *lookup_field_vals)
1806
if (cond->type() == Item::COND_ITEM)
1808
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1810
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1812
while ((item= li++))
1814
if (item->type() == Item::FUNC_ITEM)
1816
if (get_lookup_value(thd, (Item_func*)item, table, lookup_field_vals))
1821
if (calc_lookup_values_from_cond(thd, item, table, lookup_field_vals))
1828
else if (cond->type() == Item::FUNC_ITEM &&
1829
get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals))
1835
bool uses_only_table_name_fields(Item *item, TableList *table)
1837
if (item->type() == Item::FUNC_ITEM)
1839
Item_func *item_func= (Item_func*)item;
1840
for (uint i=0; i<item_func->argument_count(); i++)
1842
if (!uses_only_table_name_fields(item_func->arguments()[i], table))
1846
else if (item->type() == Item::FIELD_ITEM)
1848
Item_field *item_field= (Item_field*)item;
1849
const CHARSET_INFO * const cs= system_charset_info;
1850
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1851
ST_FIELD_INFO *field_info= schema_table->fields_info;
1852
const char *field_name1= schema_table->idx_field1 >= 0 ?
1853
field_info[schema_table->idx_field1].field_name : "";
1854
const char *field_name2= schema_table->idx_field2 >= 0 ?
1855
field_info[schema_table->idx_field2].field_name : "";
1856
if (table->table != item_field->field->table ||
1857
(cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
1858
(uchar *) item_field->field_name,
1859
strlen(item_field->field_name), 0) &&
1860
cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2),
1861
(uchar *) item_field->field_name,
1862
strlen(item_field->field_name), 0)))
1865
else if (item->type() == Item::REF_ITEM)
1866
return uses_only_table_name_fields(item->real_item(), table);
1868
if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
1875
static COND * make_cond_for_info_schema(COND *cond, TableList *table)
1879
if (cond->type() == Item::COND_ITEM)
1881
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1883
/* Create new top level AND item */
1884
Item_cond_and *new_cond=new Item_cond_and;
1887
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1891
Item *fix= make_cond_for_info_schema(item, table);
1893
new_cond->argument_list()->push_back(fix);
1895
switch (new_cond->argument_list()->elements) {
1899
return new_cond->argument_list()->head();
1901
new_cond->quick_fix_field();
1907
Item_cond_or *new_cond=new Item_cond_or;
1910
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1914
Item *fix=make_cond_for_info_schema(item, table);
1917
new_cond->argument_list()->push_back(fix);
1919
new_cond->quick_fix_field();
1920
new_cond->top_level_item();
1925
if (!uses_only_table_name_fields(cond, table))
1932
@brief Calculate lookup values(database name, table name)
1934
@details This function calculates lookup values(database name, table name)
1935
from 'WHERE' condition or wild values (for 'SHOW' commands only)
1936
from LEX struct and fill lookup_field_vals struct field
1939
@param[in] thd thread handler
1940
@param[in] cond WHERE condition
1941
@param[in] tables I_S table
1942
@param[in, out] lookup_field_values Struct which holds lookup values
1946
1 error, there can be no matching records for the condition
1949
bool get_lookup_field_values(THD *thd, COND *cond, TableList *tables,
1950
LOOKUP_FIELD_VALUES *lookup_field_values)
1953
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
1954
memset(lookup_field_values, 0, sizeof(LOOKUP_FIELD_VALUES));
1955
switch (lex->sql_command) {
1956
case SQLCOM_SHOW_DATABASES:
1959
lookup_field_values->db_value.str= (char*) wild;
1960
lookup_field_values->db_value.length= strlen(wild);
1961
lookup_field_values->wild_db_value= 1;
1964
case SQLCOM_SHOW_TABLES:
1965
case SQLCOM_SHOW_TABLE_STATUS:
1966
lookup_field_values->db_value.str= lex->select_lex.db;
1967
lookup_field_values->db_value.length=strlen(lex->select_lex.db);
1970
lookup_field_values->table_value.str= (char*)wild;
1971
lookup_field_values->table_value.length= strlen(wild);
1972
lookup_field_values->wild_table_value= 1;
1977
The "default" is for queries over I_S.
1978
All previous cases handle SHOW commands.
1980
return calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
1985
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
1987
return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
1992
Create db names list. Information schema name always is first in list
1997
files list of db names
1999
idx_field_vals idx_field_vals->db_name contains db name or
2001
with_i_schema returns 1 if we added 'IS' name to list
2009
int make_db_list(THD *thd, List<LEX_STRING> *files,
2010
LOOKUP_FIELD_VALUES *lookup_field_vals,
2011
bool *with_i_schema)
2013
LEX_STRING *i_s_name_copy= 0;
2014
i_s_name_copy= thd->make_lex_string(i_s_name_copy,
2015
INFORMATION_SCHEMA_NAME.str,
2016
INFORMATION_SCHEMA_NAME.length, true);
2018
if (lookup_field_vals->wild_db_value)
2021
This part of code is only for SHOW DATABASES command.
2022
idx_field_vals->db_value can be 0 when we don't use
2023
LIKE clause (see also get_index_field_values() function)
2025
if (!lookup_field_vals->db_value.str ||
2026
!wild_case_compare(system_charset_info,
2027
INFORMATION_SCHEMA_NAME.str,
2028
lookup_field_vals->db_value.str))
2031
if (files->push_back(i_s_name_copy))
2034
return (find_files(thd, files, NullS, mysql_data_home,
2035
lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
2040
If we have db lookup vaule we just add it to list and
2041
exit from the function
2043
if (lookup_field_vals->db_value.str)
2045
if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
2046
lookup_field_vals->db_value.str))
2049
if (files->push_back(i_s_name_copy))
2053
if (files->push_back(&lookup_field_vals->db_value))
2059
Create list of existing databases. It is used in case
2060
of select from information schema table
2062
if (files->push_back(i_s_name_copy))
2065
return (find_files(thd, files, NullS,
2066
mysql_data_home, NullS, 1) != FIND_FILES_OK);
2070
struct st_add_schema_table
2072
List<LEX_STRING> *files;
2077
static bool add_schema_table(THD *thd, plugin_ref plugin,
2080
LEX_STRING *file_name= 0;
2081
st_add_schema_table *data= (st_add_schema_table *)p_data;
2082
List<LEX_STRING> *file_list= data->files;
2083
const char *wild= data->wild;
2084
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
2086
if (schema_table->hidden)
2090
if (lower_case_table_names)
2092
if (wild_case_compare(files_charset_info,
2093
schema_table->table_name,
2097
else if (wild_compare(schema_table->table_name, wild, 0))
2101
if ((file_name= thd->make_lex_string(file_name, schema_table->table_name,
2102
strlen(schema_table->table_name),
2104
!file_list->push_back(file_name))
2110
int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
2112
LEX_STRING *file_name= 0;
2113
ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
2114
st_add_schema_table add_data;
2116
for (; tmp_schema_table->table_name; tmp_schema_table++)
2118
if (tmp_schema_table->hidden)
2122
if (lower_case_table_names)
2124
if (wild_case_compare(files_charset_info,
2125
tmp_schema_table->table_name,
2129
else if (wild_compare(tmp_schema_table->table_name, wild, 0))
2133
thd->make_lex_string(file_name, tmp_schema_table->table_name,
2134
strlen(tmp_schema_table->table_name), true)) &&
2135
!files->push_back(file_name))
2140
add_data.files= files;
2141
add_data.wild= wild;
2142
if (plugin_foreach(thd, add_schema_table,
2143
DRIZZLE_INFORMATION_SCHEMA_PLUGIN, &add_data))
2151
@brief Create table names list
2153
@details The function creates the list of table names in
2156
@param[in] thd thread handler
2157
@param[in] table_names List of table names in database
2158
@param[in] lex pointer to LEX struct
2159
@param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
2160
@param[in] with_i_schema true means that we add I_S tables to list
2161
@param[in] db_name database name
2163
@return Operation status
2165
@retval 1 fatal error
2166
@retval 2 Not fatal error; Safe to ignore this file list
2170
make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
2171
LOOKUP_FIELD_VALUES *lookup_field_vals,
2172
bool with_i_schema, LEX_STRING *db_name)
2174
char path[FN_REFLEN];
2175
build_table_filename(path, sizeof(path), db_name->str, "", "", 0);
2176
if (!lookup_field_vals->wild_table_value &&
2177
lookup_field_vals->table_value.str)
2181
if (find_schema_table(thd, lookup_field_vals->table_value.str))
2183
if (table_names->push_back(&lookup_field_vals->table_value))
2189
if (table_names->push_back(&lookup_field_vals->table_value))
2196
This call will add all matching the wildcards (if specified) IS tables
2200
return (schema_tables_add(thd, table_names,
2201
lookup_field_vals->table_value.str));
2203
find_files_result res= find_files(thd, table_names, db_name->str, path,
2204
lookup_field_vals->table_value.str, 0);
2205
if (res != FIND_FILES_OK)
2208
Downgrade errors about problems with database directory to
2209
warnings if this is not a 'SHOW' command. Another thread
2210
may have dropped database, and we may still have a name
2213
if (res == FIND_FILES_DIR)
2215
if (lex->sql_command != SQLCOM_SELECT)
2227
@brief Fill I_S table for SHOW COLUMNS|INDEX commands
2229
@param[in] thd thread handler
2230
@param[in] tables TableList for I_S table
2231
@param[in] schema_table pointer to I_S structure
2232
@param[in] open_tables_state_backup pointer to Open_tables_state object
2233
which is used to save|restore original
2234
status of variables related to
2237
@return Operation status
2243
fill_schema_show_cols_or_idxs(THD *thd, TableList *tables,
2244
ST_SCHEMA_TABLE *schema_table,
2245
Open_tables_state *open_tables_state_backup)
2249
LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
2250
enum_sql_command save_sql_command= lex->sql_command;
2251
TableList *show_table_list= (TableList*) tables->schema_select_lex->
2253
Table *table= tables->table;
2256
lex->all_selects_list= tables->schema_select_lex;
2258
Restore thd->temporary_tables to be able to process
2259
temporary tables(only for 'show index' & 'show columns').
2260
This should be changed when processing of temporary tables for
2261
I_S tables will be done.
2263
thd->temporary_tables= open_tables_state_backup->temporary_tables;
2265
Let us set fake sql_command so views won't try to merge
2266
themselves into main statement. If we don't do this,
2267
SELECT * from information_schema.xxxx will cause problems.
2268
SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
2270
lex->sql_command= SQLCOM_SHOW_FIELDS;
2271
res= open_normal_and_derived_tables(thd, show_table_list,
2272
DRIZZLE_LOCK_IGNORE_FLUSH);
2273
lex->sql_command= save_sql_command;
2275
get_all_tables() returns 1 on failure and 0 on success thus
2276
return only these and not the result code of ::process_table()
2278
We should use show_table_list->alias instead of
2279
show_table_list->table_name because table_name
2280
could be changed during opening of I_S tables. It's safe
2281
to use alias because alias contains original table name
2282
in this case(this part of code is used only for
2283
'show columns' & 'show statistics' commands).
2285
table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
2286
strlen(show_table_list->alias), false);
2287
db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db,
2288
show_table_list->db_length, false);
2291
error= test(schema_table->process_table(thd, show_table_list,
2292
table, res, db_name,
2294
thd->temporary_tables= 0;
2295
close_tables_for_reopen(thd, &show_table_list);
2301
@brief Fill I_S table for SHOW Table NAMES commands
2303
@param[in] thd thread handler
2304
@param[in] table Table struct for I_S table
2305
@param[in] db_name database name
2306
@param[in] table_name table name
2307
@param[in] with_i_schema I_S table if true
2309
@return Operation status
2314
static int fill_schema_table_names(THD *thd, Table *table,
2315
LEX_STRING *db_name, LEX_STRING *table_name,
2320
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
2321
system_charset_info);
2325
enum legacy_db_type not_used;
2326
char path[FN_REFLEN];
2327
(void) build_table_filename(path, sizeof(path), db_name->str,
2328
table_name->str, reg_ext, 0);
2329
if (mysql_frm_type(thd, path, ¬_used))
2331
table->field[3]->store(STRING_WITH_LEN("BASE Table"),
2332
system_charset_info);
2336
table->field[3]->store(STRING_WITH_LEN("ERROR"),
2337
system_charset_info);
2340
if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2346
if (schema_table_store_record(thd, table))
2353
@brief Get open table method
2355
@details The function calculates the method which will be used
2357
SKIP_OPEN_TABLE - do not open table
2358
OPEN_FRM_ONLY - open FRM file only
2359
OPEN_FULL_TABLE - open FRM, data, index files
2360
@param[in] tables I_S table table_list
2361
@param[in] schema_table I_S table struct
2362
@param[in] schema_table_idx I_S table index
2364
@return return a set of flags
2365
@retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
2368
static uint get_table_open_method(TableList *tables,
2369
ST_SCHEMA_TABLE *schema_table,
2370
enum enum_schema_tables schema_table_idx __attribute__((unused)))
2373
determine which method will be used for table opening
2375
if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
2377
Field **ptr, *field;
2378
int table_open_method= 0, field_indx= 0;
2379
for (ptr=tables->table->field; (field= *ptr) ; ptr++)
2381
if (bitmap_is_set(tables->table->read_set, field->field_index))
2382
table_open_method|= schema_table->fields_info[field_indx].open_method;
2385
return table_open_method;
2387
/* I_S tables which use get_all_tables but can not be optimized */
2388
return (uint) OPEN_FULL_TABLE;
2393
@brief Fill I_S table with data from FRM file only
2395
@param[in] thd thread handler
2396
@param[in] table Table struct for I_S table
2397
@param[in] schema_table I_S table struct
2398
@param[in] db_name database name
2399
@param[in] table_name table name
2400
@param[in] schema_table_idx I_S table index
2402
@return Operation status
2403
@retval 0 Table is processed and we can continue
2405
@retval 1 It's view and we have to use
2406
open_tables function for this table
2409
static int fill_schema_table_from_frm(THD *thd,TableList *tables,
2410
ST_SCHEMA_TABLE *schema_table,
2411
LEX_STRING *db_name,
2412
LEX_STRING *table_name,
2413
enum enum_schema_tables schema_table_idx __attribute__((unused)))
2415
Table *table= tables->table;
2418
TableList table_list;
2421
char key[MAX_DBKEY_LENGTH];
2424
memset(&table_list, 0, sizeof(TableList));
2425
memset(&tbl, 0, sizeof(Table));
2427
table_list.table_name= table_name->str;
2428
table_list.db= db_name->str;
2430
key_length= create_table_def_key(thd, key, &table_list, 0);
2431
pthread_mutex_lock(&LOCK_open);
2432
share= get_table_share(thd, &table_list, key,
2433
key_length, 0, &error);
2442
table_list.table= &tbl;
2443
res= schema_table->process_table(thd, &table_list, table,
2444
res, db_name, table_name);
2447
release_table_share(share, RELEASE_NORMAL);
2450
pthread_mutex_unlock(&LOCK_open);
2458
@brief Fill I_S tables whose data are retrieved
2459
from frm files and storage engine
2461
@details The information schema tables are internally represented as
2462
temporary tables that are filled at query execution time.
2463
Those I_S tables whose data are retrieved
2464
from frm files and storage engine are filled by the function
2467
@param[in] thd thread handler
2468
@param[in] tables I_S table
2469
@param[in] cond 'WHERE' condition
2471
@return Operation status
2476
int get_all_tables(THD *thd, TableList *tables, COND *cond)
2479
Table *table= tables->table;
2480
SELECT_LEX *old_all_select_lex= lex->all_selects_list;
2481
enum_sql_command save_sql_command= lex->sql_command;
2482
SELECT_LEX *lsel= tables->schema_select_lex;
2483
ST_SCHEMA_TABLE *schema_table= tables->schema_table;
2485
LOOKUP_FIELD_VALUES lookup_field_vals;
2486
LEX_STRING *db_name, *table_name;
2488
enum enum_schema_tables schema_table_idx;
2489
List<LEX_STRING> db_names;
2490
List_iterator_fast<LEX_STRING> it(db_names);
2491
COND *partial_cond= 0;
2492
uint derived_tables= lex->derived_tables;
2494
Open_tables_state open_tables_state_backup;
2495
Query_tables_list query_tables_list_backup;
2496
uint table_open_method;
2497
bool old_value= thd->no_warnings_for_error;
2499
lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
2502
We should not introduce deadlocks even if we already have some
2503
tables open and locked, since we won't lock tables which we will
2504
open and will ignore possible name-locks for these tables.
2506
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
2508
schema_table_idx= get_schema_table_idx(schema_table);
2509
tables->table_open_method= table_open_method=
2510
get_table_open_method(tables, schema_table, schema_table_idx);
2512
this branch processes SHOW FIELDS, SHOW INDEXES commands.
2513
see sql_parse.cc, prepare_schema_table() function where
2514
this values are initialized
2516
if (lsel && lsel->table_list.first)
2518
error= fill_schema_show_cols_or_idxs(thd, tables, schema_table,
2519
&open_tables_state_backup);
2523
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2529
if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
2532
if lookup value is empty string then
2533
it's impossible table name or db name
2535
if ((lookup_field_vals.db_value.str && !lookup_field_vals.db_value.str[0]) ||
2536
(lookup_field_vals.table_value.str && !lookup_field_vals.table_value.str[0]))
2543
if (lookup_field_vals.db_value.length &&
2544
!lookup_field_vals.wild_db_value)
2545
tables->has_db_lookup_value= true;
2546
if (lookup_field_vals.table_value.length &&
2547
!lookup_field_vals.wild_table_value)
2548
tables->has_table_lookup_value= true;
2550
if (tables->has_db_lookup_value && tables->has_table_lookup_value)
2553
partial_cond= make_cond_for_info_schema(cond, tables);
2557
/* EXPLAIN SELECT */
2562
if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
2564
it.rewind(); /* To get access to new elements in basis list */
2565
while ((db_name= it++))
2568
thd->no_warnings_for_error= 1;
2569
List<LEX_STRING> table_names;
2570
int res= make_table_name_list(thd, &table_names, lex,
2572
with_i_schema, db_name);
2573
if (res == 2) /* Not fatal error, continue */
2578
List_iterator_fast<LEX_STRING> it_files(table_names);
2579
while ((table_name= it_files++))
2581
restore_record(table, s->default_values);
2582
table->field[schema_table->idx_field1]->
2583
store(db_name->str, db_name->length, system_charset_info);
2584
table->field[schema_table->idx_field2]->
2585
store(table_name->str, table_name->length, system_charset_info);
2587
if (!partial_cond || partial_cond->val_int())
2590
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
2591
we can skip table opening and we don't have lookup value for
2592
table name or lookup value is wild string(table name list is
2593
already created by make_table_name_list() function).
2595
if (!table_open_method && schema_table_idx == SCH_TABLES &&
2596
(!lookup_field_vals.table_value.length ||
2597
lookup_field_vals.wild_table_value))
2599
if (schema_table_store_record(thd, table))
2600
goto err; /* Out of space in temporary table */
2604
/* SHOW Table NAMES command */
2605
if (schema_table_idx == SCH_TABLE_NAMES)
2607
if (fill_schema_table_names(thd, tables->table, db_name,
2608
table_name, with_i_schema))
2613
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
2616
if (!fill_schema_table_from_frm(thd, tables, schema_table, db_name,
2617
table_name, schema_table_idx))
2622
LEX_STRING tmp_lex_string, orig_db_name;
2624
Set the parent lex of 'sel' because it is needed by
2625
sel.init_query() which is called inside make_table_list.
2627
thd->no_warnings_for_error= 1;
2628
sel.parent_lex= lex;
2629
/* db_name can be changed in make_table_list() func */
2630
if (!thd->make_lex_string(&orig_db_name, db_name->str,
2631
db_name->length, false))
2633
if (make_table_list(thd, &sel, db_name, table_name))
2635
TableList *show_table_list= (TableList*) sel.table_list.first;
2636
lex->all_selects_list= &sel;
2637
lex->derived_tables= 0;
2638
lex->sql_command= SQLCOM_SHOW_FIELDS;
2639
show_table_list->i_s_requested_object=
2640
schema_table->i_s_requested_object;
2641
res= open_normal_and_derived_tables(thd, show_table_list,
2642
DRIZZLE_LOCK_IGNORE_FLUSH);
2643
lex->sql_command= save_sql_command;
2645
XXX: show_table_list has a flag i_is_requested,
2646
and when it's set, open_normal_and_derived_tables()
2647
can return an error without setting an error message
2648
in THD, which is a hack. This is why we have to
2649
check for res, then for thd->is_error() only then
2650
for thd->main_da.sql_errno().
2652
if (res && thd->is_error() &&
2653
thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2656
Hide error for not existing table.
2657
This error can occur for example when we use
2658
where condition with db name and table name and this
2659
table does not exist.
2667
We should use show_table_list->alias instead of
2668
show_table_list->table_name because table_name
2669
could be changed during opening of I_S tables. It's safe
2670
to use alias because alias contains original table name
2673
thd->make_lex_string(&tmp_lex_string, show_table_list->alias,
2674
strlen(show_table_list->alias), false);
2675
res= schema_table->process_table(thd, show_table_list, table,
2678
close_tables_for_reopen(thd, &show_table_list);
2680
assert(!lex->query_tables_own_last);
2687
If we have information schema its always the first table and only
2688
the first table. Reset for other tables.
2696
thd->restore_backup_open_tables_state(&open_tables_state_backup);
2697
lex->restore_backup_query_tables_list(&query_tables_list_backup);
2698
lex->derived_tables= derived_tables;
2699
lex->all_selects_list= old_all_select_lex;
2700
lex->sql_command= save_sql_command;
2701
thd->no_warnings_for_error= old_value;
2706
bool store_schema_shemata(THD* thd, Table *table, LEX_STRING *db_name,
2707
const CHARSET_INFO * const cs)
2709
restore_record(table, s->default_values);
2710
table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2711
table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2712
table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2713
return schema_table_store_record(thd, table);
2717
int fill_schema_schemata(THD *thd, TableList *tables, COND *cond)
2720
TODO: fill_schema_shemata() is called when new client is connected.
2721
Returning error status in this case leads to client hangup.
2724
LOOKUP_FIELD_VALUES lookup_field_vals;
2725
List<LEX_STRING> db_names;
2726
LEX_STRING *db_name;
2728
HA_CREATE_INFO create;
2729
Table *table= tables->table;
2731
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2733
if (make_db_list(thd, &db_names, &lookup_field_vals,
2738
If we have lookup db value we should check that the database exists
2740
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
2743
char path[FN_REFLEN+16];
2745
struct stat stat_info;
2746
if (!lookup_field_vals.db_value.str[0])
2748
path_len= build_table_filename(path, sizeof(path),
2749
lookup_field_vals.db_value.str, "", "", 0);
2750
path[path_len-1]= 0;
2751
if (stat(path,&stat_info))
2755
List_iterator_fast<LEX_STRING> it(db_names);
2756
while ((db_name=it++))
2758
if (with_i_schema) // information schema name is always first in list
2760
if (store_schema_shemata(thd, table, db_name,
2761
system_charset_info))
2767
load_db_opt_by_name(thd, db_name->str, &create);
2768
if (store_schema_shemata(thd, table, db_name,
2769
create.default_table_charset))
2777
static int get_schema_tables_record(THD *thd, TableList *tables,
2778
Table *table, bool res,
2779
LEX_STRING *db_name,
2780
LEX_STRING *table_name)
2782
const char *tmp_buff;
2784
const CHARSET_INFO * const cs= system_charset_info;
2786
restore_record(table, s->default_values);
2787
table->field[1]->store(db_name->str, db_name->length, cs);
2788
table->field[2]->store(table_name->str, table_name->length, cs);
2792
there was errors during opening tables
2794
const char *error= thd->is_error() ? thd->main_da.message() : "";
2795
if (tables->schema_table)
2796
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2798
table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
2799
table->field[20]->store(error, strlen(error), cs);
2804
char option_buff[400],*ptr;
2805
Table *show_table= tables->table;
2806
TABLE_SHARE *share= show_table->s;
2807
handler *file= show_table->file;
2808
handlerton *tmp_db_type= share->db_type();
2809
if (share->tmp_table == SYSTEM_TMP_TABLE)
2810
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2811
else if (share->tmp_table)
2812
table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
2814
table->field[3]->store(STRING_WITH_LEN("BASE Table"), cs);
2816
for (int i= 4; i < 20; i++)
2818
if (i == 7 || (i > 12 && i < 17) || i == 18)
2820
table->field[i]->set_notnull();
2822
tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
2823
table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
2824
table->field[5]->store((int64_t) share->frm_version, true);
2827
if (share->min_rows)
2829
ptr=stpcpy(ptr," min_rows=");
2830
ptr=int64_t10_to_str(share->min_rows,ptr,10);
2832
if (share->max_rows)
2834
ptr=stpcpy(ptr," max_rows=");
2835
ptr=int64_t10_to_str(share->max_rows,ptr,10);
2837
if (share->avg_row_length)
2839
ptr=stpcpy(ptr," avg_row_length=");
2840
ptr=int64_t10_to_str(share->avg_row_length,ptr,10);
2842
if (share->db_create_options & HA_OPTION_PACK_KEYS)
2843
ptr=stpcpy(ptr," pack_keys=1");
2844
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
2845
ptr=stpcpy(ptr," pack_keys=0");
2846
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2847
if (share->db_create_options & HA_OPTION_CHECKSUM)
2848
ptr=stpcpy(ptr," checksum=1");
2849
if (share->page_checksum != HA_CHOICE_UNDEF)
2850
ptr= strxmov(ptr, " page_checksum=",
2851
ha_choice_values[(uint) share->page_checksum], NullS);
2852
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
2853
ptr=stpcpy(ptr," delay_key_write=1");
2854
if (share->row_type != ROW_TYPE_DEFAULT)
2855
ptr=strxmov(ptr, " row_format=",
2856
ha_row_type[(uint) share->row_type],
2858
if (share->block_size)
2860
ptr= stpcpy(ptr, " block_size=");
2861
ptr= int64_t10_to_str(share->block_size, ptr, 10);
2864
if (share->transactional != HA_CHOICE_UNDEF)
2866
ptr= strxmov(ptr, " TRANSACTIONAL=",
2867
(share->transactional == HA_CHOICE_YES ? "1" : "0"),
2870
if (share->transactional != HA_CHOICE_UNDEF)
2871
ptr= strxmov(ptr, " transactional=",
2872
ha_choice_values[(uint) share->transactional], NullS);
2873
table->field[19]->store(option_buff+1,
2874
(ptr == option_buff ? 0 :
2875
(uint) (ptr-option_buff)-1), cs);
2877
tmp_buff= (share->table_charset ?
2878
share->table_charset->name : "default");
2879
table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
2881
if (share->comment.str)
2882
table->field[20]->store(share->comment.str, share->comment.length, cs);
2886
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
2888
enum row_type row_type = file->get_row_type();
2890
case ROW_TYPE_NOT_USED:
2891
case ROW_TYPE_DEFAULT:
2892
tmp_buff= ((share->db_options_in_use &
2893
HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
2894
(share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
2895
"Dynamic" : "Fixed");
2897
case ROW_TYPE_FIXED:
2900
case ROW_TYPE_DYNAMIC:
2901
tmp_buff= "Dynamic";
2903
case ROW_TYPE_COMPRESSED:
2904
tmp_buff= "Compressed";
2906
case ROW_TYPE_REDUNDANT:
2907
tmp_buff= "Redundant";
2909
case ROW_TYPE_COMPACT:
2910
tmp_buff= "Compact";
2916
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
2917
if (!tables->schema_table)
2919
table->field[7]->store((int64_t) file->stats.records, true);
2920
table->field[7]->set_notnull();
2922
table->field[8]->store((int64_t) file->stats.mean_rec_length, true);
2923
table->field[9]->store((int64_t) file->stats.data_file_length, true);
2924
if (file->stats.max_data_file_length)
2926
table->field[10]->store((int64_t) file->stats.max_data_file_length,
2929
table->field[11]->store((int64_t) file->stats.index_file_length, true);
2930
table->field[12]->store((int64_t) file->stats.delete_length, true);
2931
if (show_table->found_next_number_field)
2933
table->field[13]->store((int64_t) file->stats.auto_increment_value,
2935
table->field[13]->set_notnull();
2937
if (file->stats.create_time)
2939
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2940
(my_time_t) file->stats.create_time);
2941
table->field[14]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2942
table->field[14]->set_notnull();
2944
if (file->stats.update_time)
2946
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2947
(my_time_t) file->stats.update_time);
2948
table->field[15]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2949
table->field[15]->set_notnull();
2951
if (file->stats.check_time)
2953
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2954
(my_time_t) file->stats.check_time);
2955
table->field[16]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2956
table->field[16]->set_notnull();
2958
if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
2960
table->field[18]->store((int64_t) file->checksum(), true);
2961
table->field[18]->set_notnull();
2965
return(schema_table_store_record(thd, table));
2970
@brief Store field characteristics into appropriate I_S table columns
2972
@param[in] table I_S table
2973
@param[in] field processed field
2974
@param[in] cs I_S table charset
2975
@param[in] offset offset from beginning of table
2976
to DATE_TYPE column in I_S table
2981
void store_column_type(Table *table, Field *field, const CHARSET_INFO * const cs,
2985
int decimals, field_length;
2986
const char *tmp_buff;
2987
char column_type_buff[MAX_FIELD_WIDTH];
2988
String column_type(column_type_buff, sizeof(column_type_buff), cs);
2990
field->sql_type(column_type);
2991
/* DTD_IDENTIFIER column */
2992
table->field[offset + 7]->store(column_type.ptr(), column_type.length(), cs);
2993
table->field[offset + 7]->set_notnull();
2994
tmp_buff= strchr(column_type.ptr(), '(');
2995
/* DATA_TYPE column */
2996
table->field[offset]->store(column_type.ptr(),
2997
(tmp_buff ? tmp_buff - column_type.ptr() :
2998
column_type.length()), cs);
2999
is_blob= (field->type() == DRIZZLE_TYPE_BLOB);
3000
if (field->has_charset() || is_blob ||
3001
field->real_type() == DRIZZLE_TYPE_VARCHAR) // For varbinary type
3003
uint32_t octet_max_length= field->max_display_length();
3004
if (is_blob && octet_max_length != (uint32_t) 4294967295U)
3005
octet_max_length /= field->charset()->mbmaxlen;
3006
int64_t char_max_len= is_blob ?
3007
(int64_t) octet_max_length / field->charset()->mbminlen :
3008
(int64_t) octet_max_length / field->charset()->mbmaxlen;
3009
/* CHARACTER_MAXIMUM_LENGTH column*/
3010
table->field[offset + 1]->store(char_max_len, true);
3011
table->field[offset + 1]->set_notnull();
3012
/* CHARACTER_OCTET_LENGTH column */
3013
table->field[offset + 2]->store((int64_t) octet_max_length, true);
3014
table->field[offset + 2]->set_notnull();
3018
Calculate field_length and decimals.
3019
They are set to -1 if they should not be set (we should return NULL)
3022
decimals= field->decimals();
3023
switch (field->type()) {
3024
case DRIZZLE_TYPE_NEWDECIMAL:
3025
field_length= ((Field_new_decimal*) field)->precision;
3027
case DRIZZLE_TYPE_TINY:
3028
case DRIZZLE_TYPE_SHORT:
3029
case DRIZZLE_TYPE_LONG:
3030
case DRIZZLE_TYPE_LONGLONG:
3031
field_length= field->max_display_length() - 1;
3033
case DRIZZLE_TYPE_DOUBLE:
3034
field_length= field->field_length;
3035
if (decimals == NOT_FIXED_DEC)
3036
decimals= -1; // return NULL
3039
field_length= decimals= -1;
3043
/* NUMERIC_PRECISION column */
3044
if (field_length >= 0)
3046
table->field[offset + 3]->store((int64_t) field_length, true);
3047
table->field[offset + 3]->set_notnull();
3049
/* NUMERIC_SCALE column */
3052
table->field[offset + 4]->store((int64_t) decimals, true);
3053
table->field[offset + 4]->set_notnull();
3055
if (field->has_charset())
3057
/* CHARACTER_SET_NAME column*/
3058
tmp_buff= field->charset()->csname;
3059
table->field[offset + 5]->store(tmp_buff, strlen(tmp_buff), cs);
3060
table->field[offset + 5]->set_notnull();
3061
/* COLLATION_NAME column */
3062
tmp_buff= field->charset()->name;
3063
table->field[offset + 6]->store(tmp_buff, strlen(tmp_buff), cs);
3064
table->field[offset + 6]->set_notnull();
3069
static int get_schema_column_record(THD *thd, TableList *tables,
3070
Table *table, bool res,
3071
LEX_STRING *db_name,
3072
LEX_STRING *table_name)
3075
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3076
const CHARSET_INFO * const cs= system_charset_info;
3078
TABLE_SHARE *show_table_share;
3079
Field **ptr, *field, *timestamp_field;
3084
if (lex->sql_command != SQLCOM_SHOW_FIELDS)
3087
I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
3088
rather than in SHOW COLUMNS
3090
if (thd->is_error())
3091
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3092
thd->main_da.sql_errno(), thd->main_da.message());
3099
show_table= tables->table;
3100
show_table_share= show_table->s;
3103
if (tables->schema_table)
3105
ptr= show_table->field;
3106
timestamp_field= show_table->timestamp_field;
3107
show_table->use_all_columns(); // Required for default
3111
ptr= show_table_share->field;
3112
timestamp_field= show_table_share->timestamp_field;
3114
read_set may be inited in case of
3117
if (!show_table->read_set)
3119
/* to satisfy 'field->val_str' ASSERTs */
3121
uint bitmap_size= show_table_share->column_bitmap_size;
3122
if (!(bitmaps= (uchar*) alloc_root(thd->mem_root, bitmap_size)))
3124
bitmap_init(&show_table->def_read_set,
3125
(my_bitmap_map*) bitmaps, show_table_share->fields, false);
3126
bitmap_set_all(&show_table->def_read_set);
3127
show_table->read_set= &show_table->def_read_set;
3129
bitmap_set_all(show_table->read_set);
3132
for (; (field= *ptr) ; ptr++)
3135
char tmp[MAX_FIELD_WIDTH];
3136
String type(tmp,sizeof(tmp), system_charset_info);
3139
/* to satisfy 'field->val_str' ASSERTs */
3140
field->table= show_table;
3141
show_table->in_use= thd;
3143
if (wild && wild[0] &&
3144
wild_case_compare(system_charset_info, field->field_name,wild))
3148
/* Get default row, with all NULL fields set to NULL */
3149
restore_record(table, s->default_values);
3151
table->field[1]->store(db_name->str, db_name->length, cs);
3152
table->field[2]->store(table_name->str, table_name->length, cs);
3153
table->field[3]->store(field->field_name, strlen(field->field_name),
3155
table->field[4]->store((int64_t) count, true);
3157
if (get_field_default_value(thd, timestamp_field, field, &type, 0))
3159
table->field[5]->store(type.ptr(), type.length(), cs);
3160
table->field[5]->set_notnull();
3162
pos=(uchar*) ((field->flags & NOT_NULL_FLAG) ? "NO" : "YES");
3163
table->field[6]->store((const char*) pos,
3164
strlen((const char*) pos), cs);
3165
store_column_type(table, field, cs, 7);
3167
pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
3168
(field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
3169
(field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
3170
table->field[15]->store((const char*) pos,
3171
strlen((const char*) pos), cs);
3174
if (field->unireg_check == Field::NEXT_NUMBER)
3175
table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
3176
if (timestamp_field == field &&
3177
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3178
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3181
table->field[18]->store(field->comment.str, field->comment.length, cs);
3183
enum column_format_type column_format= (enum column_format_type)
3184
((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
3185
pos=(uchar*)"Default";
3186
table->field[19]->store((const char*) pos,
3187
strlen((const char*) pos), cs);
3188
pos=(uchar*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
3189
column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
3191
table->field[20]->store((const char*) pos,
3192
strlen((const char*) pos), cs);
3194
if (schema_table_store_record(thd, table))
3202
int fill_schema_charsets(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3205
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3206
Table *table= tables->table;
3207
const CHARSET_INFO * const scs= system_charset_info;
3209
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3211
const CHARSET_INFO * const tmp_cs= cs[0];
3212
if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
3213
(tmp_cs->state & MY_CS_AVAILABLE) &&
3214
!(tmp_cs->state & MY_CS_HIDDEN) &&
3215
!(wild && wild[0] &&
3216
wild_case_compare(scs, tmp_cs->csname,wild)))
3218
const char *comment;
3219
restore_record(table, s->default_values);
3220
table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3221
table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3222
comment= tmp_cs->comment ? tmp_cs->comment : "";
3223
table->field[2]->store(comment, strlen(comment), scs);
3224
table->field[3]->store((int64_t) tmp_cs->mbmaxlen, true);
3225
if (schema_table_store_record(thd, table))
3233
int fill_schema_collation(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3236
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3237
Table *table= tables->table;
3238
const CHARSET_INFO * const scs= system_charset_info;
3239
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3242
const CHARSET_INFO *tmp_cs= cs[0];
3243
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3244
(tmp_cs->state & MY_CS_HIDDEN) ||
3245
!(tmp_cs->state & MY_CS_PRIMARY))
3247
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3249
const CHARSET_INFO *tmp_cl= cl[0];
3250
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3251
!my_charset_same(tmp_cs, tmp_cl))
3253
if (!(wild && wild[0] &&
3254
wild_case_compare(scs, tmp_cl->name,wild)))
3256
const char *tmp_buff;
3257
restore_record(table, s->default_values);
3258
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3259
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3260
table->field[2]->store((int64_t) tmp_cl->number, true);
3261
tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
3262
table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
3263
tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
3264
table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
3265
table->field[5]->store((int64_t) tmp_cl->strxfrm_multiply, true);
3266
if (schema_table_store_record(thd, table))
3275
int fill_schema_coll_charset_app(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3278
Table *table= tables->table;
3279
const CHARSET_INFO * const scs= system_charset_info;
3280
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3283
const CHARSET_INFO *tmp_cs= cs[0];
3284
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3285
!(tmp_cs->state & MY_CS_PRIMARY))
3287
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3289
const CHARSET_INFO *tmp_cl= cl[0];
3290
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3291
!my_charset_same(tmp_cs,tmp_cl))
3293
restore_record(table, s->default_values);
3294
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3295
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3296
if (schema_table_store_record(thd, table))
3304
static int get_schema_stat_record(THD *thd, TableList *tables,
3305
Table *table, bool res,
3306
LEX_STRING *db_name,
3307
LEX_STRING *table_name)
3309
const CHARSET_INFO * const cs= system_charset_info;
3312
if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
3315
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
3316
rather than in SHOW KEYS
3318
if (thd->is_error())
3319
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3320
thd->main_da.sql_errno(), thd->main_da.message());
3328
Table *show_table= tables->table;
3329
KEY *key_info=show_table->s->key_info;
3330
if (show_table->file)
3331
show_table->file->info(HA_STATUS_VARIABLE |
3334
for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
3336
KEY_PART_INFO *key_part= key_info->key_part;
3338
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3340
restore_record(table, s->default_values);
3341
table->field[1]->store(db_name->str, db_name->length, cs);
3342
table->field[2]->store(table_name->str, table_name->length, cs);
3343
table->field[3]->store((int64_t) ((key_info->flags &
3344
HA_NOSAME) ? 0 : 1), true);
3345
table->field[4]->store(db_name->str, db_name->length, cs);
3346
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
3347
table->field[6]->store((int64_t) (j+1), true);
3348
str=(key_part->field ? key_part->field->field_name :
3350
table->field[7]->store(str, strlen(str), cs);
3351
if (show_table->file)
3353
if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
3355
table->field[8]->store(((key_part->key_part_flag &
3358
table->field[8]->set_notnull();
3360
KEY *key=show_table->key_info+i;
3361
if (key->rec_per_key[j])
3363
ha_rows records=(show_table->file->stats.records /
3364
key->rec_per_key[j]);
3365
table->field[9]->store((int64_t) records, true);
3366
table->field[9]->set_notnull();
3368
str= show_table->file->index_type(i);
3369
table->field[13]->store(str, strlen(str), cs);
3371
if ((key_part->field &&
3373
show_table->s->field[key_part->fieldnr-1]->key_length()))
3375
table->field[10]->store((int64_t) key_part->length /
3376
key_part->field->charset()->mbmaxlen, true);
3377
table->field[10]->set_notnull();
3379
uint flags= key_part->field ? key_part->field->flags : 0;
3380
const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3381
table->field[12]->store(pos, strlen(pos), cs);
3382
if (!show_table->s->keys_in_use.is_set(i))
3383
table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3385
table->field[14]->store("", 0, cs);
3386
table->field[14]->set_notnull();
3387
assert(test(key_info->flags & HA_USES_COMMENT) ==
3388
(key_info->comment.length > 0));
3389
if (key_info->flags & HA_USES_COMMENT)
3390
table->field[15]->store(key_info->comment.str,
3391
key_info->comment.length, cs);
3392
if (schema_table_store_record(thd, table))
3401
bool store_constraints(THD *thd, Table *table, LEX_STRING *db_name,
3402
LEX_STRING *table_name, const char *key_name,
3403
uint key_len, const char *con_type, uint con_len)
3405
const CHARSET_INFO * const cs= system_charset_info;
3406
restore_record(table, s->default_values);
3407
table->field[1]->store(db_name->str, db_name->length, cs);
3408
table->field[2]->store(key_name, key_len, cs);
3409
table->field[3]->store(db_name->str, db_name->length, cs);
3410
table->field[4]->store(table_name->str, table_name->length, cs);
3411
table->field[5]->store(con_type, con_len, cs);
3412
return schema_table_store_record(thd, table);
3416
static int get_schema_constraints_record(THD *thd, TableList *tables,
3417
Table *table, bool res,
3418
LEX_STRING *db_name,
3419
LEX_STRING *table_name)
3423
if (thd->is_error())
3424
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3425
thd->main_da.sql_errno(), thd->main_da.message());
3431
List<FOREIGN_KEY_INFO> f_key_list;
3432
Table *show_table= tables->table;
3433
KEY *key_info=show_table->key_info;
3434
uint primary_key= show_table->s->primary_key;
3435
show_table->file->info(HA_STATUS_VARIABLE |
3438
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3440
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3443
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
3445
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3446
strlen(key_info->name),
3447
STRING_WITH_LEN("PRIMARY KEY")))
3450
else if (key_info->flags & HA_NOSAME)
3452
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3453
strlen(key_info->name),
3454
STRING_WITH_LEN("UNIQUE")))
3459
show_table->file->get_foreign_key_list(thd, &f_key_list);
3460
FOREIGN_KEY_INFO *f_key_info;
3461
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3462
while ((f_key_info=it++))
3464
if (store_constraints(thd, table, db_name, table_name,
3465
f_key_info->forein_id->str,
3466
strlen(f_key_info->forein_id->str),
3475
void store_key_column_usage(Table *table, LEX_STRING *db_name,
3476
LEX_STRING *table_name, const char *key_name,
3477
uint key_len, const char *con_type, uint con_len,
3480
const CHARSET_INFO * const cs= system_charset_info;
3481
table->field[1]->store(db_name->str, db_name->length, cs);
3482
table->field[2]->store(key_name, key_len, cs);
3483
table->field[4]->store(db_name->str, db_name->length, cs);
3484
table->field[5]->store(table_name->str, table_name->length, cs);
3485
table->field[6]->store(con_type, con_len, cs);
3486
table->field[7]->store((int64_t) idx, true);
3490
static int get_schema_key_column_usage_record(THD *thd,
3492
Table *table, bool res,
3493
LEX_STRING *db_name,
3494
LEX_STRING *table_name)
3498
if (thd->is_error())
3499
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3500
thd->main_da.sql_errno(), thd->main_da.message());
3506
List<FOREIGN_KEY_INFO> f_key_list;
3507
Table *show_table= tables->table;
3508
KEY *key_info=show_table->key_info;
3509
uint primary_key= show_table->s->primary_key;
3510
show_table->file->info(HA_STATUS_VARIABLE |
3513
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3515
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3518
KEY_PART_INFO *key_part= key_info->key_part;
3519
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3521
if (key_part->field)
3524
restore_record(table, s->default_values);
3525
store_key_column_usage(table, db_name, table_name,
3527
strlen(key_info->name),
3528
key_part->field->field_name,
3529
strlen(key_part->field->field_name),
3531
if (schema_table_store_record(thd, table))
3537
show_table->file->get_foreign_key_list(thd, &f_key_list);
3538
FOREIGN_KEY_INFO *f_key_info;
3539
List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
3540
while ((f_key_info= fkey_it++))
3544
List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
3545
it1(f_key_info->referenced_fields);
3547
while ((f_info= it++))
3551
restore_record(table, s->default_values);
3552
store_key_column_usage(table, db_name, table_name,
3553
f_key_info->forein_id->str,
3554
f_key_info->forein_id->length,
3555
f_info->str, f_info->length,
3557
table->field[8]->store((int64_t) f_idx, true);
3558
table->field[8]->set_notnull();
3559
table->field[9]->store(f_key_info->referenced_db->str,
3560
f_key_info->referenced_db->length,
3561
system_charset_info);
3562
table->field[9]->set_notnull();
3563
table->field[10]->store(f_key_info->referenced_table->str,
3564
f_key_info->referenced_table->length,
3565
system_charset_info);
3566
table->field[10]->set_notnull();
3567
table->field[11]->store(r_info->str, r_info->length,
3568
system_charset_info);
3569
table->field[11]->set_notnull();
3570
if (schema_table_store_record(thd, table))
3579
int fill_open_tables(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3581
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3582
Table *table= tables->table;
3583
const CHARSET_INFO * const cs= system_charset_info;
3584
OPEN_TableList *open_list;
3585
if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
3586
&& thd->is_fatal_error)
3589
for (; open_list ; open_list=open_list->next)
3591
restore_record(table, s->default_values);
3592
table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3593
table->field[1]->store(open_list->table, strlen(open_list->table), cs);
3594
table->field[2]->store((int64_t) open_list->in_use, true);
3595
table->field[3]->store((int64_t) open_list->locked, true);
3596
if (schema_table_store_record(thd, table))
3603
int fill_variables(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3607
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3608
enum enum_schema_tables schema_table_idx=
3609
get_schema_table_idx(tables->schema_table);
3610
enum enum_var_type option_type= OPT_SESSION;
3611
bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
3612
bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
3614
if (lex->option_type == OPT_GLOBAL ||
3615
schema_table_idx == SCH_GLOBAL_VARIABLES)
3616
option_type= OPT_GLOBAL;
3618
rw_rdlock(&LOCK_system_variables_hash);
3619
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
3620
option_type, NULL, "", tables->table, upper_case_names);
3621
rw_unlock(&LOCK_system_variables_hash);
3626
int fill_status(THD *thd, TableList *tables, COND *cond __attribute__((unused)))
3629
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3631
STATUS_VAR *tmp1, tmp;
3632
enum enum_schema_tables schema_table_idx=
3633
get_schema_table_idx(tables->schema_table);
3634
enum enum_var_type option_type;
3635
bool upper_case_names= (schema_table_idx != SCH_STATUS);
3637
if (schema_table_idx == SCH_STATUS)
3639
option_type= lex->option_type;
3640
if (option_type == OPT_GLOBAL)
3643
tmp1= thd->initial_status_var;
3645
else if (schema_table_idx == SCH_GLOBAL_STATUS)
3647
option_type= OPT_GLOBAL;
3652
option_type= OPT_SESSION;
3653
tmp1= &thd->status_var;
3656
pthread_mutex_lock(&LOCK_status);
3657
if (option_type == OPT_GLOBAL)
3658
calc_sum_of_all_status(&tmp);
3659
res= show_status_array(thd, wild,
3660
(SHOW_VAR *)all_status_vars.buffer,
3661
option_type, tmp1, "", tables->table,
3663
pthread_mutex_unlock(&LOCK_status);
3669
Fill and store records into I_S.referential_constraints table
3672
get_referential_constraints_record()
3674
tables table list struct(processed table)
3676
res 1 means the error during opening of the processed table
3677
0 means processed table is opened without error
3679
file_name table name
3687
get_referential_constraints_record(THD *thd, TableList *tables,
3688
Table *table, bool res,
3689
LEX_STRING *db_name, LEX_STRING *table_name)
3691
const CHARSET_INFO * const cs= system_charset_info;
3695
if (thd->is_error())
3696
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3697
thd->main_da.sql_errno(), thd->main_da.message());
3703
List<FOREIGN_KEY_INFO> f_key_list;
3704
Table *show_table= tables->table;
3705
show_table->file->info(HA_STATUS_VARIABLE |
3709
show_table->file->get_foreign_key_list(thd, &f_key_list);
3710
FOREIGN_KEY_INFO *f_key_info;
3711
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3712
while ((f_key_info= it++))
3714
restore_record(table, s->default_values);
3715
table->field[1]->store(db_name->str, db_name->length, cs);
3716
table->field[9]->store(table_name->str, table_name->length, cs);
3717
table->field[2]->store(f_key_info->forein_id->str,
3718
f_key_info->forein_id->length, cs);
3719
table->field[4]->store(f_key_info->referenced_db->str,
3720
f_key_info->referenced_db->length, cs);
3721
table->field[10]->store(f_key_info->referenced_table->str,
3722
f_key_info->referenced_table->length, cs);
3723
if (f_key_info->referenced_key_name)
3725
table->field[5]->store(f_key_info->referenced_key_name->str,
3726
f_key_info->referenced_key_name->length, cs);
3727
table->field[5]->set_notnull();
3730
table->field[5]->set_null();
3731
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3732
table->field[7]->store(f_key_info->update_method->str,
3733
f_key_info->update_method->length, cs);
3734
table->field[8]->store(f_key_info->delete_method->str,
3735
f_key_info->delete_method->length, cs);
3736
if (schema_table_store_record(thd, table))
3744
struct schema_table_ref
3746
const char *table_name;
3747
ST_SCHEMA_TABLE *schema_table;
3752
Find schema_tables elment by name
3755
find_schema_table_in_plugin()
3758
table_name table name
3762
1 found the schema table
3764
static bool find_schema_table_in_plugin(THD *thd __attribute__((unused)),
3768
schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
3769
const char* table_name= p_schema_table->table_name;
3770
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
3772
if (!my_strcasecmp(system_charset_info,
3773
schema_table->table_name,
3775
p_schema_table->schema_table= schema_table;
3784
Find schema_tables elment by name
3789
table_name table name
3793
# pointer to 'schema_tables' element
3796
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
3798
schema_table_ref schema_table_a;
3799
ST_SCHEMA_TABLE *schema_table= schema_tables;
3801
for (; schema_table->table_name; schema_table++)
3803
if (!my_strcasecmp(system_charset_info,
3804
schema_table->table_name,
3806
return(schema_table);
3809
schema_table_a.table_name= table_name;
3810
if (plugin_foreach(thd, find_schema_table_in_plugin,
3811
DRIZZLE_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
3812
return(schema_table_a.schema_table);
3818
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
3820
return &schema_tables[schema_table_idx];
3825
Create information_schema table using schema_table data.
3832
@param table_list Used to pass I_S table information(fields info, tables
3833
parameters etc) and table name.
3835
@retval \# Pointer to created table
3836
@retval NULL Can't create table
3839
Table *create_schema_table(THD *thd, TableList *table_list)
3844
List<Item> field_list;
3845
ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
3846
ST_FIELD_INFO *fields_info= schema_table->fields_info;
3847
const CHARSET_INFO * const cs= system_charset_info;
3849
for (; fields_info->field_name; fields_info++)
3851
switch (fields_info->field_type) {
3852
case DRIZZLE_TYPE_TINY:
3853
case DRIZZLE_TYPE_LONG:
3854
case DRIZZLE_TYPE_SHORT:
3855
case DRIZZLE_TYPE_LONGLONG:
3856
if (!(item= new Item_return_int(fields_info->field_name,
3857
fields_info->field_length,
3858
fields_info->field_type,
3859
fields_info->value)))
3863
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3865
case DRIZZLE_TYPE_NEWDATE:
3866
case DRIZZLE_TYPE_TIME:
3867
case DRIZZLE_TYPE_TIMESTAMP:
3868
case DRIZZLE_TYPE_DATETIME:
3869
if (!(item=new Item_return_date_time(fields_info->field_name,
3870
fields_info->field_type)))
3875
case DRIZZLE_TYPE_DOUBLE:
3876
if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
3877
fields_info->field_length)) == NULL)
3880
case DRIZZLE_TYPE_NEWDECIMAL:
3881
if (!(item= new Item_decimal((int64_t) fields_info->value, false)))
3885
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3886
item->decimals= fields_info->field_length%10;
3887
item->max_length= (fields_info->field_length/100)%100;
3888
if (item->unsigned_flag == 0)
3889
item->max_length+= 1;
3890
if (item->decimals > 0)
3891
item->max_length+= 1;
3892
item->set_name(fields_info->field_name,
3893
strlen(fields_info->field_name), cs);
3895
case DRIZZLE_TYPE_BLOB:
3896
if (!(item= new Item_blob(fields_info->field_name,
3897
fields_info->field_length)))
3903
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
3907
item->set_name(fields_info->field_name,
3908
strlen(fields_info->field_name), cs);
3911
field_list.push_back(item);
3912
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
3915
TMP_TABLE_PARAM *tmp_table_param =
3916
(TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
3917
tmp_table_param->init();
3918
tmp_table_param->table_charset= cs;
3919
tmp_table_param->field_count= field_count;
3920
tmp_table_param->schema_table= 1;
3921
SELECT_LEX *select_lex= thd->lex->current_select;
3922
if (!(table= create_tmp_table(thd, tmp_table_param,
3923
field_list, (order_st*) 0, 0, 0,
3924
(select_lex->options | thd->options |
3925
TMP_TABLE_ALL_COLUMNS),
3926
HA_POS_ERROR, table_list->alias)))
3928
my_bitmap_map* bitmaps=
3929
(my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
3930
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
3932
table->read_set= &table->def_read_set;
3933
bitmap_clear_all(table->read_set);
3934
table_list->schema_table_param= tmp_table_param;
3940
For old SHOW compatibility. It is used when
3941
old SHOW doesn't have generated column names
3942
Make list of fields for SHOW
3947
schema_table pointer to 'schema_tables' element
3954
int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
3956
ST_FIELD_INFO *field_info= schema_table->fields_info;
3957
Name_resolution_context *context= &thd->lex->select_lex.context;
3958
for (; field_info->field_name; field_info++)
3960
if (field_info->old_name)
3962
Item_field *field= new Item_field(context,
3963
NullS, NullS, field_info->field_name);
3966
field->set_name(field_info->old_name,
3967
strlen(field_info->old_name),
3968
system_charset_info);
3969
if (add_item_to_list(thd, field))
3978
int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
3982
SELECT_LEX *sel= lex->current_select;
3983
Name_resolution_context *context= &sel->context;
3985
if (!sel->item_list.elements)
3987
ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
3988
String buffer(tmp,sizeof(tmp), system_charset_info);
3989
Item_field *field= new Item_field(context,
3990
NullS, NullS, field_info->field_name);
3991
if (!field || add_item_to_list(thd, field))
3994
buffer.append(field_info->old_name);
3995
if (lex->wild && lex->wild->ptr())
3997
buffer.append(STRING_WITH_LEN(" ("));
3998
buffer.append(lex->wild->ptr());
4001
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4007
int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4010
String buffer(tmp,sizeof(tmp), thd->charset());
4012
Name_resolution_context *context= &lex->select_lex.context;
4014
ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
4016
buffer.append(field_info->old_name);
4017
buffer.append(lex->select_lex.db);
4018
if (lex->wild && lex->wild->ptr())
4020
buffer.append(STRING_WITH_LEN(" ("));
4021
buffer.append(lex->wild->ptr());
4024
Item_field *field= new Item_field(context,
4025
NullS, NullS, field_info->field_name);
4026
if (add_item_to_list(thd, field))
4028
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4029
if (thd->lex->verbose)
4031
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
4032
field_info= &schema_table->fields_info[3];
4033
field= new Item_field(context, NullS, NullS, field_info->field_name);
4034
if (add_item_to_list(thd, field))
4036
field->set_name(field_info->old_name, strlen(field_info->old_name),
4037
system_charset_info);
4043
int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4045
int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
4046
int *field_num= fields_arr;
4047
ST_FIELD_INFO *field_info;
4048
Name_resolution_context *context= &thd->lex->select_lex.context;
4050
for (; *field_num >= 0; field_num++)
4052
field_info= &schema_table->fields_info[*field_num];
4053
if (!thd->lex->verbose && (*field_num == 13 ||
4057
Item_field *field= new Item_field(context,
4058
NullS, NullS, field_info->field_name);
4061
field->set_name(field_info->old_name,
4062
strlen(field_info->old_name),
4063
system_charset_info);
4064
if (add_item_to_list(thd, field))
4072
int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
4074
int fields_arr[]= {0, 2, 1, 3, -1};
4075
int *field_num= fields_arr;
4076
ST_FIELD_INFO *field_info;
4077
Name_resolution_context *context= &thd->lex->select_lex.context;
4079
for (; *field_num >= 0; field_num++)
4081
field_info= &schema_table->fields_info[*field_num];
4082
Item_field *field= new Item_field(context,
4083
NullS, NullS, field_info->field_name);
4086
field->set_name(field_info->old_name,
4087
strlen(field_info->old_name),
4088
system_charset_info);
4089
if (add_item_to_list(thd, field))
4098
Create information_schema table
4101
mysql_schema_table()
4104
table_list pointer to table_list
4111
int mysql_schema_table(THD *thd, LEX *lex, TableList *table_list)
4114
if (!(table= table_list->schema_table->create_table(thd, table_list)))
4116
table->s->tmp_table= SYSTEM_TMP_TABLE;
4118
This test is necessary to make
4119
case insensitive file systems +
4120
upper case table names(information schema tables) +
4124
if (table_list->schema_table_name)
4125
table->alias_name_used= my_strcasecmp(table_alias_charset,
4126
table_list->schema_table_name,
4128
table_list->table_name= table->s->table_name.str;
4129
table_list->table_name_length= table->s->table_name.length;
4130
table_list->table= table;
4131
table->next= thd->derived_tables;
4132
thd->derived_tables= table;
4133
table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
4135
if (table_list->schema_table_reformed) // show command
4137
SELECT_LEX *sel= lex->current_select;
4139
Field_translator *transl, *org_transl;
4141
if (table_list->field_translation)
4143
Field_translator *end= table_list->field_translation_end;
4144
for (transl= table_list->field_translation; transl < end; transl++)
4146
if (!transl->item->fixed &&
4147
transl->item->fix_fields(thd, &transl->item))
4152
List_iterator_fast<Item> it(sel->item_list);
4154
(Field_translator*)(thd->stmt_arena->
4155
alloc(sel->item_list.elements *
4156
sizeof(Field_translator)))))
4160
for (org_transl= transl; (item= it++); transl++)
4163
transl->name= item->name;
4164
if (!item->fixed && item->fix_fields(thd, &transl->item))
4169
table_list->field_translation= org_transl;
4170
table_list->field_translation_end= transl;
4178
Generate select from information_schema table
4181
make_schema_select()
4183
sel pointer to SELECT_LEX
4184
schema_table_idx index of 'schema_tables' element
4191
int make_schema_select(THD *thd, SELECT_LEX *sel,
4192
enum enum_schema_tables schema_table_idx)
4194
ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
4195
LEX_STRING db, table;
4197
We have to make non const db_name & table_name
4198
because of lower_case_table_names
4200
thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str,
4201
INFORMATION_SCHEMA_NAME.length, 0);
4202
thd->make_lex_string(&table, schema_table->table_name,
4203
strlen(schema_table->table_name), 0);
4204
if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
4205
!sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
4215
Fill temporary schema tables before SELECT
4218
get_schema_tables_result()
4219
join join which use schema tables
4220
executed_place place where I_S table processed
4227
bool get_schema_tables_result(JOIN *join,
4228
enum enum_schema_table_state executed_place)
4230
JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
4231
THD *thd= join->thd;
4235
thd->no_warnings_for_error= 1;
4236
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
4238
if (!tab->table || !tab->table->pos_in_table_list)
4241
TableList *table_list= tab->table->pos_in_table_list;
4242
if (table_list->schema_table)
4244
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
4245
lex->current_select->master_unit()->item);
4248
/* skip I_S optimizations specific to get_all_tables */
4249
if (thd->lex->describe &&
4250
(table_list->schema_table->fill_table != get_all_tables))
4254
If schema table is already processed and
4255
the statement is not a subselect then
4256
we don't need to fill this table again.
4257
If schema table is already processed and
4258
schema_table_state != executed_place then
4259
table is already processed and
4260
we should skip second data processing.
4262
if (table_list->schema_table_state &&
4263
(!is_subselect || table_list->schema_table_state != executed_place))
4267
if table is used in a subselect and
4268
table has been processed earlier with the same
4269
'executed_place' value then we should refresh the table.
4271
if (table_list->schema_table_state && is_subselect)
4273
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
4274
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
4275
table_list->table->file->ha_delete_all_rows();
4276
free_io_cache(table_list->table);
4277
filesort_free_buffers(table_list->table,1);
4278
table_list->table->null_row= 0;
4281
table_list->table->file->stats.records= 0;
4283
if (table_list->schema_table->fill_table(thd, table_list,
4288
tab->read_record.file= table_list->table->file;
4289
table_list->schema_table_state= executed_place;
4292
tab->read_record.file= table_list->table->file;
4293
table_list->schema_table_state= executed_place;
4296
thd->no_warnings_for_error= 0;
4300
ST_FIELD_INFO schema_fields_info[]=
4302
{"CATALOG_NAME", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4303
{"SCHEMA_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4305
{"DEFAULT_CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4307
{"DEFAULT_COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4308
{"SQL_PATH", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4309
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4313
ST_FIELD_INFO tables_fields_info[]=
4315
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4316
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4317
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4319
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4320
{"ENGINE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Engine", OPEN_FRM_ONLY},
4321
{"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4322
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
4323
{"ROW_FORMAT", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Row_format", OPEN_FULL_TABLE},
4324
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4325
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
4326
{"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4327
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
4328
{"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4329
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
4330
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4331
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
4332
{"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4333
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
4334
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4335
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
4336
{"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG, 0,
4337
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
4338
{"CREATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4339
{"UPDATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4340
{"CHECK_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
4341
{"TABLE_COLLATION", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4342
{"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4343
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
4344
{"CREATE_OPTIONS", 255, DRIZZLE_TYPE_VARCHAR, 0, 1, "Create_options",
4346
{"TABLE_COMMENT", TABLE_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4347
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4351
ST_FIELD_INFO columns_fields_info[]=
4353
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4354
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4355
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4356
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Field",
4358
{"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4359
MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
4360
{"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, DRIZZLE_TYPE_VARCHAR, 0,
4361
1, "Default", OPEN_FRM_ONLY},
4362
{"IS_NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4363
{"DATA_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4364
{"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4365
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4366
{"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4367
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4368
{"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4369
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4370
{"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4371
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4372
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4373
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4374
{"COLUMN_TYPE", 65535, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", OPEN_FRM_ONLY},
4375
{"COLUMN_KEY", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key", OPEN_FRM_ONLY},
4376
{"EXTRA", 27, DRIZZLE_TYPE_VARCHAR, 0, 0, "Extra", OPEN_FRM_ONLY},
4377
{"PRIVILEGES", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Privileges", OPEN_FRM_ONLY},
4378
{"COLUMN_COMMENT", COLUMN_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4379
{"STORAGE", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Storage", OPEN_FRM_ONLY},
4380
{"FORMAT", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Format", OPEN_FRM_ONLY},
4381
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4385
ST_FIELD_INFO charsets_fields_info[]=
4387
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4389
{"DEFAULT_COLLATE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default collation",
4391
{"DESCRIPTION", 60, DRIZZLE_TYPE_VARCHAR, 0, 0, "Description",
4393
{"MAXLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
4394
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4398
ST_FIELD_INFO collation_fields_info[]=
4400
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Collation", SKIP_OPEN_TABLE},
4401
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4403
{"ID", MY_INT32_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id",
4405
{"IS_DEFAULT", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default", SKIP_OPEN_TABLE},
4406
{"IS_COMPILED", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Compiled", SKIP_OPEN_TABLE},
4407
{"SORTLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
4408
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4413
ST_FIELD_INFO coll_charset_app_fields_info[]=
4415
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4416
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4417
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4421
ST_FIELD_INFO stat_fields_info[]=
4423
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4424
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4425
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", OPEN_FRM_ONLY},
4426
{"NON_UNIQUE", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
4427
{"INDEX_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4428
{"INDEX_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key_name",
4430
{"SEQ_IN_INDEX", 2, DRIZZLE_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
4431
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Column_name",
4433
{"COLLATION", 1, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4434
{"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 1,
4435
"Cardinality", OPEN_FULL_TABLE},
4436
{"SUB_PART", 3, DRIZZLE_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
4437
{"PACKED", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Packed", OPEN_FRM_ONLY},
4438
{"NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4439
{"INDEX_TYPE", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_type", OPEN_FULL_TABLE},
4440
{"COMMENT", 16, DRIZZLE_TYPE_VARCHAR, 0, 1, "Comment", OPEN_FRM_ONLY},
4441
{"INDEX_COMMENT", INDEX_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_Comment", OPEN_FRM_ONLY},
4442
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4446
ST_FIELD_INFO table_constraints_fields_info[]=
4448
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4449
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4451
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4453
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4454
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4455
{"CONSTRAINT_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4457
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4461
ST_FIELD_INFO key_column_usage_fields_info[]=
4463
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4464
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4466
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4468
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4469
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4470
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4471
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4472
{"ORDINAL_POSITION", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
4473
{"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 1, 0,
4475
{"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4477
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4479
{"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4481
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4485
ST_FIELD_INFO table_names_fields_info[]=
4487
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4488
{"TABLE_SCHEMA",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4489
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Tables_in_",
4491
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table_type",
4493
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4497
ST_FIELD_INFO open_tables_fields_info[]=
4499
{"Database", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4501
{"Table",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", SKIP_OPEN_TABLE},
4502
{"In_use", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
4503
{"Name_locked", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
4504
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4508
ST_FIELD_INFO variables_fields_info[]=
4510
{"VARIABLE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Variable_name",
4512
{"VARIABLE_VALUE", 16300, DRIZZLE_TYPE_VARCHAR, 0, 1, "Value", SKIP_OPEN_TABLE},
4513
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4517
ST_FIELD_INFO processlist_fields_info[]=
4519
{"ID", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
4520
{"USER", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "User", SKIP_OPEN_TABLE},
4521
{"HOST", LIST_PROCESS_HOST_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Host",
4523
{"DB", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Db", SKIP_OPEN_TABLE},
4524
{"COMMAND", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Command", SKIP_OPEN_TABLE},
4525
{"TIME", 7, DRIZZLE_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
4526
{"STATE", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "State", SKIP_OPEN_TABLE},
4527
{"INFO", PROCESS_LIST_INFO_WIDTH, DRIZZLE_TYPE_VARCHAR, 0, 1, "Info",
4529
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4533
ST_FIELD_INFO plugin_fields_info[]=
4535
{"PLUGIN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4537
{"PLUGIN_VERSION", 20, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4538
{"PLUGIN_STATUS", 10, DRIZZLE_TYPE_VARCHAR, 0, 0, "Status", SKIP_OPEN_TABLE},
4539
{"PLUGIN_TYPE", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", SKIP_OPEN_TABLE},
4540
{"PLUGIN_LIBRARY", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Library",
4542
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4543
{"PLUGIN_DESCRIPTION", 65535, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4544
{"PLUGIN_LICENSE", 80, DRIZZLE_TYPE_VARCHAR, 0, 1, "License", SKIP_OPEN_TABLE},
4545
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4548
ST_FIELD_INFO referential_constraints_fields_info[]=
4550
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4551
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4553
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4555
{"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4557
{"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4559
{"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0,
4560
MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
4561
{"MATCH_OPTION", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4562
{"UPDATE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4563
{"DELETE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4564
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4565
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4567
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4572
Description of ST_FIELD_INFO in table.h
4574
Make sure that the order of schema_tables and enum_schema_tables are the same.
4578
ST_SCHEMA_TABLE schema_tables[]=
4580
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
4581
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4582
{"COLLATIONS", collation_fields_info, create_schema_table,
4583
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4584
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4585
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4586
{"COLUMNS", columns_fields_info, create_schema_table,
4587
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
4588
OPTIMIZE_I_S_TABLE},
4589
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4590
fill_status, make_old_format, 0, -1, -1, 0, 0},
4591
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
4592
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4593
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
4594
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
4596
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
4597
fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
4598
{"PLUGINS", plugin_fields_info, create_schema_table,
4599
fill_plugins, make_old_format, 0, -1, -1, 0, 0},
4600
{"PROCESSLIST", processlist_fields_info, create_schema_table,
4601
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
4602
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
4603
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
4604
1, 9, 0, OPEN_TABLE_ONLY},
4605
{"SCHEMATA", schema_fields_info, create_schema_table,
4606
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
4607
{"SESSION_STATUS", variables_fields_info, create_schema_table,
4608
fill_status, make_old_format, 0, -1, -1, 0, 0},
4609
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4610
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4611
{"STATISTICS", stat_fields_info, create_schema_table,
4612
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4613
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4614
{"STATUS", variables_fields_info, create_schema_table, fill_status,
4615
make_old_format, 0, -1, -1, 1, 0},
4616
{"TABLES", tables_fields_info, create_schema_table,
4617
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4618
OPTIMIZE_I_S_TABLE},
4619
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4620
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
4621
{"TABLE_NAMES", table_names_fields_info, create_schema_table,
4622
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
4623
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
4624
make_old_format, 0, -1, -1, 1, 0},
4625
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
4629
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
4630
template class List_iterator_fast<char>;
4631
template class List<char>;
4634
int initialize_schema_table(st_plugin_int *plugin)
4636
ST_SCHEMA_TABLE *schema_table;
4638
if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
4639
MYF(MY_WME | MY_ZEROFILL))))
4641
/* Historical Requirement */
4642
plugin->data= schema_table; // shortcut for the future
4643
if (plugin->plugin->init)
4645
schema_table->create_table= create_schema_table;
4646
schema_table->old_format= make_old_format;
4647
schema_table->idx_field1= -1,
4648
schema_table->idx_field2= -1;
4650
/* Make the name available to the init() function. */
4651
schema_table->table_name= plugin->name.str;
4653
if (plugin->plugin->init(schema_table))
4655
sql_print_error(_("Plugin '%s' init function returned error."),
4660
/* Make sure the plugin name is not set inside the init() function. */
4661
schema_table->table_name= plugin->name.str;
4666
my_free(schema_table, MYF(0));
4670
int finalize_schema_table(st_plugin_int *plugin)
4672
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
4674
if (schema_table && plugin->plugin->deinit)
4675
my_free(schema_table, MYF(0));