1
/* Copyright (C) 2000-2004 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
21
/* Function with list databases, tables or fields */
18
#include <drizzled/server_includes.h>
19
23
#include <drizzled/sql_select.h>
20
#include <drizzled/sql_show.h>
21
#include "repl_failsafe.h"
22
#include <mysys/my_dir.h>
24
#define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
26
/* Match the values of enum ha_choice */
27
static const char *ha_choice_values[] = {"", "0", "1"};
29
static void store_key_options(THD *thd, String *packet, TABLE *table,
24
#include <drizzled/show.h>
25
#include <drizzled/gettext.h>
26
#include <drizzled/util/convert.h>
27
#include <drizzled/error.h>
28
#include <drizzled/tztime.h>
29
#include <drizzled/data_home.h>
30
#include <drizzled/item/blob.h>
31
#include <drizzled/item/cmpfunc.h>
32
#include <drizzled/item/return_int.h>
33
#include <drizzled/item/empty_string.h>
34
#include <drizzled/item/return_date_time.h>
35
#include <drizzled/sql_base.h>
36
#include <drizzled/db.h>
37
#include <drizzled/field/timestamp.h>
38
#include <drizzled/field/decimal.h>
39
#include <drizzled/lock.h>
40
#include <drizzled/item/return_date_time.h>
41
#include <drizzled/item/empty_string.h>
42
#include "drizzled/plugin/registry.h"
43
#include "drizzled/session_list.h"
44
#include <drizzled/plugin/info_schema_table.h>
45
#include <drizzled/message/schema.pb.h>
46
#include <drizzled/plugin/client.h>
47
#include <drizzled/cached_directory.h>
48
#include "drizzled/sql_table.h"
49
#include "drizzled/global_charset_info.h"
50
#include "drizzled/pthread_globals.h"
51
#include "drizzled/internal/m_string.h"
52
#include "drizzled/internal/my_sys.h"
68
str_or_nil(const char *str)
70
return str ? str : "<nil>";
73
static void store_key_options(String *packet, Table *table, KEY *key_info);
34
75
int wild_case_compare(const CHARSET_INFO * const cs, const char *str,const char *wildstr)
39
while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
80
while (*wildstr && *wildstr != internal::wild_many && *wildstr != internal::wild_one)
41
if (*wildstr == wild_prefix && wildstr[1])
82
if (*wildstr == internal::wild_prefix && wildstr[1])
43
84
if (my_toupper(cs, *wildstr++) != my_toupper(cs, *str++))
47
88
return (*str != 0);
48
if (*wildstr++ == wild_one)
89
if (*wildstr++ == internal::wild_one)
51
92
return (1); /* One char; skip */
56
return(0); /* '*' as last char: OK */
57
flag=(*wildstr != wild_many && *wildstr != wild_one);
97
return (0); /* '*' as last char: OK */
98
flag=(*wildstr != internal::wild_many && *wildstr != internal::wild_one);
63
if ((cmp= *wildstr) == wild_prefix && wildstr[1])
65
cmp=my_toupper(cs, cmp);
66
while (*str && my_toupper(cs, *str) != cmp)
104
if ((cmp= *wildstr) == internal::wild_prefix && wildstr[1])
106
cmp= my_toupper(cs, cmp);
107
while (*str && my_toupper(cs, *str) != cmp)
112
if (wild_case_compare(cs, str, wildstr) == 0)
71
if (wild_case_compare(cs, str,wildstr) == 0)
77
118
return (*str != '\0');
80
/***************************************************************************
81
** List all table types supported
82
***************************************************************************/
84
static bool show_plugins(THD *thd, plugin_ref plugin,
87
TABLE *table= (TABLE*) arg;
88
struct st_mysql_plugin *plug= plugin_decl(plugin);
89
struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
90
const CHARSET_INFO * const cs= system_charset_info;
92
restore_record(table, s->default_values);
94
table->field[0]->store(plugin_name(plugin)->str,
95
plugin_name(plugin)->length, cs);
99
table->field[1]->store(plug->version, strlen(plug->version), cs);
100
table->field[1]->set_notnull();
103
table->field[1]->set_null();
105
switch (plugin_state(plugin)) {
106
/* case PLUGIN_IS_FREED: does not happen */
107
case PLUGIN_IS_DELETED:
108
table->field[2]->store(STRING_WITH_LEN("DELETED"), cs);
110
case PLUGIN_IS_UNINITIALIZED:
111
table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs);
113
case PLUGIN_IS_READY:
114
table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
120
table->field[3]->store(plugin_type_names[plug->type].str,
121
plugin_type_names[plug->type].length,
126
table->field[4]->store(plugin_dl->dl.str, plugin_dl->dl.length, cs);
127
table->field[4]->set_notnull();
131
table->field[4]->set_null();
136
table->field[5]->store(plug->author, strlen(plug->author), cs);
137
table->field[5]->set_notnull();
140
table->field[5]->set_null();
144
table->field[6]->store(plug->descr, strlen(plug->descr), cs);
145
table->field[6]->set_notnull();
148
table->field[6]->set_null();
150
switch (plug->license) {
151
case PLUGIN_LICENSE_GPL:
152
table->field[7]->store(PLUGIN_LICENSE_GPL_STRING,
153
strlen(PLUGIN_LICENSE_GPL_STRING), cs);
155
case PLUGIN_LICENSE_BSD:
156
table->field[7]->store(PLUGIN_LICENSE_BSD_STRING,
157
strlen(PLUGIN_LICENSE_BSD_STRING), cs);
160
table->field[7]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
161
strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
164
table->field[7]->set_notnull();
166
return schema_table_store_record(thd, table);
170
int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((unused)))
172
TABLE *table= tables->table;
174
if (plugin_foreach_with_mask(thd, show_plugins, DRIZZLE_ANY_PLUGIN,
175
~PLUGIN_IS_FREED, table))
183
find_files() - find files in a given directory.
188
files put found files in this list
189
db database name to set in TABLE_LIST structure
190
path path to database
191
wild filter for found files
192
dir read databases in path if true, read .frm files in
196
FIND_FILES_OK success
197
FIND_FILES_OOM out of memory error
198
FIND_FILES_DIR no such directory, or directory can't be read
203
find_files(THD *thd, List<LEX_STRING> *files, const char *db,
204
const char *path, const char *wild, bool dir)
210
LEX_STRING *file_name= 0;
212
TABLE_LIST table_list;
214
if (wild && !wild[0])
217
memset(&table_list, 0, sizeof(table_list));
219
if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
221
if (my_errno == ENOENT)
222
my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db);
224
my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
225
return(FIND_FILES_DIR);
228
for (i=0 ; i < (uint) dirp->number_off_files ; i++)
124
* Find subdirectories (schemas) in a given directory (datadir).
126
* @param[in] session Thread Cursor
127
* @param[out] files Put found entries in this list
128
* @param[in] path Path to database
129
* @param[in] wild Filter for found entries
131
* @retval false Success
134
static bool find_schemas(Session *session, vector<LEX_STRING*> &files,
135
const char *path, const char *wild)
137
if (wild && (wild[0] == '\0'))
140
CachedDirectory directory(path);
142
if (directory.fail())
144
errno= directory.getError();
145
my_error(ER_CANT_READ_DIR, MYF(0), path, errno);
150
CachedDirectory::Entries entries= directory.getEntries();
151
CachedDirectory::Entries::iterator entry_iter= entries.begin();
153
while (entry_iter != entries.end())
155
uint32_t file_name_len;
230
156
char uname[NAME_LEN + 1]; /* Unencoded name */
231
file=dirp->dir_entry+i;
233
{ /* Return databases */
234
if ((file->name[0] == '.' &&
235
((file->name[1] == '.' && file->name[2] == '\0') ||
236
file->name[1] == '\0')))
237
continue; /* . or .. */
240
char buff[FN_REFLEN];
241
if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym"))
243
/* Only show the sym file if it points to a directory */
245
*ext=0; /* Remove extension */
246
unpack_dirname(buff, file->name);
248
if (end != buff && end[-1] == FN_LIBCHAR)
249
end[-1]= 0; // Remove end FN_LIBCHAR
250
if (stat(buff, file->mystat))
254
if (!S_ISDIR(file->mystat->st_mode))
257
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
258
if (wild && wild_compare(uname, wild, 0))
261
thd->make_lex_string(file_name, uname, file_name_len, true)))
264
return(FIND_FILES_OOM);
269
// Return only .frm files which aren't temp files.
270
if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) ||
271
is_prefix(file->name, tmp_file_prefix))
274
file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
277
if (lower_case_table_names)
279
if (wild_case_compare(files_charset_info, uname, wild))
282
else if (wild_compare(uname, wild, 0))
287
thd->make_lex_string(file_name, uname, file_name_len, true)) ||
288
files->push_back(file_name))
291
return(FIND_FILES_OOM);
157
struct stat entry_stat;
158
CachedDirectory::Entry *entry= *entry_iter;
160
if ((entry->filename == ".") || (entry->filename == ".."))
166
if (stat(entry->filename.c_str(), &entry_stat))
169
my_error(ER_CANT_GET_STAT, MYF(0), entry->filename.c_str(), errno);
173
if (! S_ISDIR(entry_stat.st_mode))
179
file_name_len= filename_to_tablename(entry->filename.c_str(), uname,
181
if (wild && internal::wild_compare(uname, wild, 0))
187
LEX_STRING *file_name= 0;
188
file_name= session->make_lex_string(file_name, uname, file_name_len, true);
189
if (file_name == NULL)
192
files.push_back(file_name);
296
return(FIND_FILES_OK);
301
mysqld_show_create(THD *thd, TABLE_LIST *table_list)
200
bool drizzled_show_create(Session *session, TableList *table_list, bool is_if_not_exists)
303
Protocol *protocol= thd->protocol;
305
203
String buffer(buff, sizeof(buff), system_charset_info);
307
205
/* Only one table for now, but VIEW can involve several tables */
308
if (open_normal_and_derived_tables(thd, table_list, 0))
206
if (session->openTables(table_list))
310
if (thd->is_error() && thd->main_da.sql_errno() != ER_VIEW_INVALID)
208
if (session->is_error())
314
212
Clear all messages with 'error' level status and
315
issue a warning with 'warning' level status in
213
issue a warning with 'warning' level status in
316
214
case of invalid view and last error is ER_VIEW_INVALID
318
drizzle_reset_errors(thd, true);
216
drizzle_reset_errors(session, true);
217
session->clear_error();
322
220
buffer.length(0);
324
if (store_create_info(thd, table_list, &buffer, NULL))
222
if (store_create_info(table_list, &buffer, is_if_not_exists))
327
225
List<Item> field_list;
1087
701
returns for each thread: thread id, user, host, db, command, info
1088
702
****************************************************************************/
1090
class thread_info :public ilink {
1092
static void *operator new(size_t size)
1094
return (void*) sql_alloc((uint) size);
1096
static void operator delete(void *ptr __attribute__((unused)),
1097
size_t size __attribute__((unused)))
1098
{ TRASH(ptr, size); }
1101
709
time_t start_time;
1103
const char *user,*host,*db,*proc_info,*state_info;
711
string user, host, db, proc_info, state_info, query;
712
thread_info(uint64_t thread_id_arg,
713
time_t start_time_arg,
714
uint32_t command_arg,
715
const string &user_arg,
716
const string &host_arg,
717
const string &db_arg,
718
const string &proc_info_arg,
719
const string &state_info_arg,
720
const string &query_arg)
721
: thread_id(thread_id_arg), start_time(start_time_arg), command(command_arg),
722
user(user_arg), host(host_arg), db(db_arg), proc_info(proc_info_arg),
723
state_info(state_info_arg), query(query_arg)
1107
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
1108
template class I_List<thread_info>;
1111
void mysqld_list_processes(THD *thd,const char *user, bool verbose)
727
void mysqld_list_processes(Session *session,const char *user, bool)
1114
730
List<Item> field_list;
1115
I_List<thread_info> thread_infos;
1116
ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
1117
PROCESS_LIST_WIDTH);
1118
Protocol *protocol= thd->protocol;
731
vector<thread_info> thread_infos;
1120
733
field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
1121
734
field_list.push_back(new Item_empty_string("User",16));
1122
735
field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
1123
736
field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
1124
field->maybe_null=1;
737
field->maybe_null= true;
1125
738
field_list.push_back(new Item_empty_string("Command",16));
1126
739
field_list.push_back(new Item_return_int("Time",7, DRIZZLE_TYPE_LONG));
1127
740
field_list.push_back(field=new Item_empty_string("State",30));
1128
field->maybe_null=1;
1129
field_list.push_back(field=new Item_empty_string("Info",max_query_length));
1130
field->maybe_null=1;
1131
if (protocol->send_fields(&field_list,
1132
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
741
field->maybe_null= true;
742
field_list.push_back(field=new Item_empty_string("Info", PROCESS_LIST_WIDTH));
743
field->maybe_null= true;
744
if (session->client->sendFields(&field_list))
1135
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
747
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
748
if (!session->killed)
1138
I_List_iterator<THD> it(threads);
751
for(vector<Session*>::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it)
1142
Security_context *tmp_sctx= tmp->security_ctx;
1143
struct st_my_thread_var *mysys_var;
1144
if ((tmp->vio_ok() || tmp->system_thread) && (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
754
Security_context *tmp_sctx= &tmp->security_ctx;
755
internal::st_my_thread_var *mysys_var;
756
if (tmp->client->isConnected() && (!user || (tmp_sctx->user.c_str() && !strcmp(tmp_sctx->user.c_str(), user))))
1146
thread_info *thd_info= new thread_info;
1148
thd_info->thread_id=tmp->thread_id;
1149
thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
1150
(tmp->system_thread ?
1151
"system user" : "unauthenticated user"));
1152
thd_info->host= thd->strdup(tmp_sctx->ip);
1153
if ((thd_info->db=tmp->db)) // Safe test
1154
thd_info->db=thd->strdup(thd_info->db);
1155
thd_info->command=(int) tmp->command;
1156
759
if ((mysys_var= tmp->mysys_var))
1157
760
pthread_mutex_lock(&mysys_var->mutex);
1158
thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
1159
thd_info->state_info= (char*) (tmp->net.reading_or_writing ?
1160
(tmp->net.reading_or_writing == 2 ?
1162
thd_info->command == COM_SLEEP ? NullS :
1163
"Reading from net") :
1164
tmp->proc_info ? tmp->proc_info :
1166
tmp->mysys_var->current_cond ?
1167
"Waiting on cond" : NullS);
762
const string tmp_proc_info((tmp->killed == Session::KILL_CONNECTION) ? "Killed" : command_name[tmp->command].str);
764
const string tmp_state_info(tmp->client->isWriting()
766
: tmp->client->isReading()
767
? (tmp->command == COM_SLEEP
769
: "Reading from net")
770
: tmp->get_proc_info()
771
? tmp->get_proc_info()
772
: (tmp->mysys_var && tmp->mysys_var->current_cond)
1169
776
pthread_mutex_unlock(&mysys_var->mutex);
1171
thd_info->start_time= tmp->start_time;
1176
query_length is always set to 0 when we set query = NULL; see
1177
the comment in sql_class.h why this prevents crashes in possible
1178
races with query_length
1180
uint length= min((uint32_t)max_query_length, tmp->query_length);
1181
thd_info->query=(char*) thd->strmake(tmp->query,length);
1183
thread_infos.append(thd_info);
778
const string tmp_query((tmp->process_list_info[0]) ? tmp->process_list_info : "");
779
thread_infos.push_back(thread_info(tmp->thread_id,
782
tmp_sctx->user.empty()
783
? string("unauthenticated user")
1187
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1189
thread_info *thd_info;
1190
time_t now= my_time(0);
1191
while ((thd_info=thread_infos.get()))
793
pthread_mutex_unlock(&LOCK_thread_count);
794
time_t now= time(NULL);
795
for(vector<thread_info>::iterator iter= thread_infos.begin();
796
iter != thread_infos.end();
1193
protocol->prepare_for_resend();
1194
protocol->store((uint64_t) thd_info->thread_id);
1195
protocol->store(thd_info->user, system_charset_info);
1196
protocol->store(thd_info->host, system_charset_info);
1197
protocol->store(thd_info->db, system_charset_info);
1198
if (thd_info->proc_info)
1199
protocol->store(thd_info->proc_info, system_charset_info);
1201
protocol->store(command_name[thd_info->command].str, system_charset_info);
1202
if (thd_info->start_time)
1203
protocol->store((uint32_t) (now - thd_info->start_time));
1205
protocol->store_null();
1206
protocol->store(thd_info->state_info, system_charset_info);
1207
protocol->store(thd_info->query, system_charset_info);
1208
if (protocol->write())
1209
break; /* purecov: inspected */
799
session->client->store((uint64_t) (*iter).thread_id);
800
session->client->store((*iter).user);
801
session->client->store((*iter).host);
802
session->client->store((*iter).db);
803
session->client->store((*iter).proc_info);
805
if ((*iter).start_time)
806
session->client->store((uint32_t) (now - (*iter).start_time));
808
session->client->store();
810
session->client->store((*iter).state_info);
811
session->client->store((*iter).query);
813
if (session->client->flush())
1215
int fill_schema_processlist(THD* thd, TABLE_LIST* tables,
1216
COND* cond __attribute__((unused)))
1218
TABLE *table= tables->table;
1219
const CHARSET_INFO * const cs= system_charset_info;
1221
time_t now= my_time(0);
1225
VOID(pthread_mutex_lock(&LOCK_thread_count));
1229
I_List_iterator<THD> it(threads);
1234
Security_context *tmp_sctx= tmp->security_ctx;
1235
struct st_my_thread_var *mysys_var;
1238
if ((!tmp->vio_ok() && !tmp->system_thread))
1241
restore_record(table, s->default_values);
1243
table->field[0]->store((int64_t) tmp->thread_id, true);
1245
val= tmp_sctx->user ? tmp_sctx->user :
1246
(tmp->system_thread ? "system user" : "unauthenticated user");
1247
table->field[1]->store(val, strlen(val), cs);
1249
table->field[2]->store(tmp_sctx->ip, strlen(tmp_sctx->ip), cs);
1253
table->field[3]->store(tmp->db, strlen(tmp->db), cs);
1254
table->field[3]->set_notnull();
1257
if ((mysys_var= tmp->mysys_var))
1258
pthread_mutex_lock(&mysys_var->mutex);
1260
if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
1261
table->field[4]->store(val, strlen(val), cs);
1263
table->field[4]->store(command_name[tmp->command].str,
1264
command_name[tmp->command].length, cs);
1266
table->field[5]->store((uint32_t)(tmp->start_time ?
1267
now - tmp->start_time : 0), true);
1269
val= (char*) (tmp->net.reading_or_writing ?
1270
(tmp->net.reading_or_writing == 2 ?
1272
tmp->command == COM_SLEEP ? NullS :
1273
"Reading from net") :
1274
tmp->proc_info ? tmp->proc_info :
1276
tmp->mysys_var->current_cond ?
1277
"Waiting on cond" : NullS);
1280
table->field[6]->store(val, strlen(val), cs);
1281
table->field[6]->set_notnull();
1285
pthread_mutex_unlock(&mysys_var->mutex);
1290
table->field[7]->store(tmp->query,
1291
min((uint32_t)PROCESS_LIST_INFO_WIDTH,
1292
tmp->query_length), cs);
1293
table->field[7]->set_notnull();
1296
if (schema_table_store_record(thd, table))
1298
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1304
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1308
821
/*****************************************************************************
1309
822
Status functions
1310
823
*****************************************************************************/
1312
static DYNAMIC_ARRAY all_status_vars;
825
static vector<SHOW_VAR *> all_status_vars;
1313
826
static bool status_vars_inited= 0;
1314
827
static int show_var_cmp(const void *var1, const void *var2)
1316
829
return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
1320
deletes all the SHOW_UNDEF elements from the array and calls
1321
delete_dynamic() if it's completely empty.
1323
static void shrink_var_array(DYNAMIC_ARRAY *array)
1326
SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
1328
for (a= b= 0; b < array->elements; b++)
1329
if (all[b].type != SHOW_UNDEF)
1333
memset(all+a, 0, sizeof(SHOW_VAR)); // writing NULL-element to the end
1336
else // array is completely empty - delete it
1337
delete_dynamic(array);
832
class show_var_cmp_functor
835
show_var_cmp_functor() { }
836
inline bool operator()(const SHOW_VAR *var1, const SHOW_VAR *var2) const
838
int val= strcmp(var1->name, var2->name);
843
class show_var_remove_if
846
show_var_remove_if() { }
847
inline bool operator()(const SHOW_VAR *curr) const
849
return (curr->type == SHOW_UNDEF);
853
SHOW_VAR *getFrontOfStatusVars()
855
return all_status_vars.front();
1477
shrink_var_array(&all_status_vars);
1481
inline void make_upper(char *buf)
1484
*buf= my_toupper(system_charset_info, *buf);
1487
static bool show_status_array(THD *thd, const char *wild,
1488
SHOW_VAR *variables,
1489
enum enum_var_type value_type,
1490
struct system_status_var *status_var,
1491
const char *prefix, TABLE *table,
1494
MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
1495
char * const buff= (char *) &buff_data;
1497
/* the variable name should not be longer than 64 characters */
1498
char name_buffer[64];
1500
LEX_STRING null_lex_str;
1503
null_lex_str.str= 0; // For sys_var->value_ptr()
1504
null_lex_str.length= 0;
1506
prefix_end=stpncpy(name_buffer, prefix, sizeof(name_buffer)-1);
1509
len=name_buffer + sizeof(name_buffer) - prefix_end;
1511
for (; variables->name; variables++)
1513
stpncpy(prefix_end, variables->name, len);
1514
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
1516
make_upper(name_buffer);
1519
if var->type is SHOW_FUNC, call the function.
1520
Repeat as necessary, if new var is again SHOW_FUNC
1522
for (var=variables; var->type == SHOW_FUNC; var= &tmp)
1523
((mysql_show_var_func)((st_show_var_func_container *)var->value)->func)(thd, &tmp, buff);
1525
SHOW_TYPE show_type=var->type;
1526
if (show_type == SHOW_ARRAY)
1528
show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
1529
status_var, name_buffer, table, ucase_names);
1533
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
1534
name_buffer, wild)))
1536
char *value=var->value;
1537
const char *pos, *end; // We assign a lot of const's
1539
pthread_mutex_lock(&LOCK_global_system_variables);
1541
if (show_type == SHOW_SYS)
1543
show_type= ((sys_var*) value)->show_type();
1544
value= (char*) ((sys_var*) value)->value_ptr(thd, value_type,
1550
note that value may be == buff. All SHOW_xxx code below
1551
should still work in this case
1553
switch (show_type) {
1554
case SHOW_DOUBLE_STATUS:
1555
value= ((char *) status_var + (ulong) value);
1558
/* 6 is the default precision for '%f' in sprintf() */
1559
end= buff + my_fcvt(*(double *) value, 6, buff, NULL);
1561
case SHOW_LONG_STATUS:
1562
value= ((char *) status_var + (ulong) value);
1565
case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
1566
end= int10_to_str(*(long*) value, buff, 10);
1568
case SHOW_LONGLONG_STATUS:
1569
value= ((char *) status_var + (uint64_t) value);
1572
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1575
end= int64_t10_to_str((int64_t) *(ha_rows*) value, buff, 10);
1578
end= stpcpy(buff, *(bool*) value ? "ON" : "OFF");
1581
end= stpcpy(buff, *(bool*) value ? "ON" : "OFF");
1584
end= int10_to_str((long) *(uint32_t*) value, buff, 10);
1588
SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
1589
pos= show_comp_option_name[(int) tmp];
1602
if (!(pos= *(char**) value))
1607
case SHOW_KEY_CACHE_LONG:
1608
value= (char*) dflt_key_cache + (ulong)value;
1609
end= int10_to_str(*(long*) value, buff, 10);
1611
case SHOW_KEY_CACHE_LONGLONG:
1612
value= (char*) dflt_key_cache + (ulong)value;
1613
end= int64_t10_to_str(*(int64_t*) value, buff, 10);
1616
break; // Return empty string
1617
case SHOW_SYS: // Cannot happen
1622
restore_record(table, s->default_values);
1623
table->field[0]->store(name_buffer, strlen(name_buffer),
1624
system_charset_info);
1625
table->field[1]->store(pos, (uint32_t) (end - pos), system_charset_info);
1626
table->field[1]->set_notnull();
1628
pthread_mutex_unlock(&LOCK_global_system_variables);
1630
if (schema_table_store_record(thd, table))
989
/* removes all the SHOW_UNDEF elements from the vector */
990
all_status_vars.erase(std::remove_if(all_status_vars.begin(),
991
all_status_vars.end(),show_var_remove_if()),
992
all_status_vars.end());
1640
996
/* collect status for all running threads */
1642
998
void calc_sum_of_all_status(STATUS_VAR *to)
1645
1000
/* Ensure that thread id not killed during loop */
1646
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
1001
pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1648
I_List_iterator<THD> it(threads);
1651
1003
/* Get global values as base */
1652
1004
*to= global_status_var;
1654
1006
/* Add to this status from existing threads */
1656
add_to_status(to, &tmp->status_var);
1658
VOID(pthread_mutex_unlock(&LOCK_thread_count));
1663
/* This is only used internally, but we need it here as a forward reference */
1664
extern ST_SCHEMA_TABLE schema_tables[];
1666
typedef struct st_lookup_field_values
1668
LEX_STRING db_value, table_value;
1669
bool wild_db_value, wild_table_value;
1670
} LOOKUP_FIELD_VALUES;
1674
Store record to I_S table, convert HEAP table
1675
to MyISAM if necessary
1678
schema_table_store_record()
1680
table Information schema table to be updated
1687
bool schema_table_store_record(THD *thd, TABLE *table)
1690
if ((error= table->file->ha_write_row(table->record[0])))
1007
for(vector<Session*>::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
1692
TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
1694
if (create_myisam_from_heap(thd, table, param->start_recinfo,
1695
¶m->recinfo, error, 0))
1009
add_to_status(to, &((*it)->status_var));
1012
pthread_mutex_unlock(&LOCK_thread_count);
1702
int make_table_list(THD *thd, SELECT_LEX *sel,
1703
LEX_STRING *db_name, LEX_STRING *table_name)
1017
static int make_table_list(Session *session, Select_Lex *sel,
1018
LEX_STRING *db_name, LEX_STRING *table_name)
1705
1020
Table_ident *table_ident;
1706
table_ident= new Table_ident(thd, *db_name, *table_name, 1);
1021
table_ident= new Table_ident(*db_name, *table_name);
1707
1022
sel->init_query();
1708
if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
1023
if (! sel->add_table_to_list(session, table_ident, 0, 0, TL_READ))
1715
@brief Get lookup value from the part of 'WHERE' condition
1030
@brief Get lookup value from the part of 'WHERE' condition
1717
@details This function gets lookup value from
1718
the part of 'WHERE' condition if it's possible and
1032
@details This function gets lookup value from
1033
the part of 'WHERE' condition if it's possible and
1719
1034
fill appropriate lookup_field_vals struct field
1720
1035
with this value.
1722
@param[in] thd thread handler
1037
@param[in] session thread Cursor
1723
1038
@param[in] item_func part of WHERE condition
1724
1039
@param[in] table I_S table
1725
@param[in, out] lookup_field_vals Struct which holds lookup values
1040
@param[in, out] lookup_field_vals Struct which holds lookup values
1729
1044
1 error, there can be no matching records for the condition
1732
bool get_lookup_value(THD *thd, Item_func *item_func,
1734
LOOKUP_FIELD_VALUES *lookup_field_vals)
1047
static bool get_lookup_value(Session *session, Item_func *item_func,
1049
LOOKUP_FIELD_VALUES *lookup_field_vals,
1050
plugin::InfoSchemaTable *schema_table)
1736
ST_SCHEMA_TABLE *schema_table= table->schema_table;
1737
ST_FIELD_INFO *field_info= schema_table->fields_info;
1738
const char *field_name1= schema_table->idx_field1 >= 0 ?
1739
field_info[schema_table->idx_field1].field_name : "";
1740
const char *field_name2= schema_table->idx_field2 >= 0 ?
1741
field_info[schema_table->idx_field2].field_name : "";
1052
const char *field_name1= schema_table->getFirstColumnIndex() >= 0 ?
1053
schema_table->getColumnName(schema_table->getFirstColumnIndex()).c_str() : "";
1054
const char *field_name2= schema_table->getSecondColumnIndex() >= 0 ?
1055
schema_table->getColumnName(schema_table->getSecondColumnIndex()).c_str() : "";
1743
1057
if (item_func->functype() == Item_func::EQ_FUNC ||
1744
1058
item_func->functype() == Item_func::EQUAL_FUNC)
2578
if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
1691
table->setWriteSet();
1692
if (make_db_list(session, db_names, &lookup_field_vals, &with_i_schema))
2580
it.rewind(); /* To get access to new elements in basis list */
2581
while ((db_name= it++))
1695
for (vector<LEX_STRING*>::iterator db_name= db_names.begin(); db_name != db_names.end(); ++db_name )
1697
session->no_warnings_for_error= 1;
1698
table_names.clear();
1699
int res= make_table_name_list(session, table_names,
1701
with_i_schema, *db_name);
1703
if (res == 2) /* Not fatal error, continue */
1710
for (vector<LEX_STRING*>::iterator table_name= table_names.begin(); table_name != table_names.end(); ++table_name)
2584
thd->no_warnings_for_error= 1;
2585
List<LEX_STRING> table_names;
2586
int res= make_table_name_list(thd, &table_names, lex,
2588
with_i_schema, db_name);
2589
if (res == 2) /* Not fatal error, continue */
1712
table->restoreRecordAsDefault();
1713
table->field[schema_table->getFirstColumnIndex()]->
1714
store((*db_name)->str, (*db_name)->length, system_charset_info);
1715
table->field[schema_table->getSecondColumnIndex()]->
1716
store((*table_name)->str, (*table_name)->length, system_charset_info);
2594
List_iterator_fast<LEX_STRING> it_files(table_names);
2595
while ((table_name= it_files++))
1718
if (!partial_cond || partial_cond->val_int())
2597
restore_record(table, s->default_values);
2598
table->field[schema_table->idx_field1]->
2599
store(db_name->str, db_name->length, system_charset_info);
2600
table->field[schema_table->idx_field2]->
2601
store(table_name->str, table_name->length, system_charset_info);
2603
if (!partial_cond || partial_cond->val_int())
1720
/* SHOW Table NAMES command */
1721
if (schema_table->getTableName().compare("TABLE_NAMES") == 0)
2606
If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
2607
we can skip table opening and we don't have lookup value for
2608
table name or lookup value is wild string(table name list is
2609
already created by make_table_name_list() function).
2611
if (!table_open_method && schema_table_idx == SCH_TABLES &&
2612
(!lookup_field_vals.table_value.length ||
2613
lookup_field_vals.wild_table_value))
2615
if (schema_table_store_record(thd, table))
2616
goto err; /* Out of space in temporary table */
1723
if (fill_schema_table_names(session,
1733
LEX_STRING tmp_lex_string, orig_db_name;
1735
Set the parent lex of 'sel' because it is needed by
1736
sel.init_query() which is called inside make_table_list.
1738
session->no_warnings_for_error= 1;
1739
sel.parent_lex= lex;
1740
/* db_name can be changed in make_table_list() func */
1741
if (! session->make_lex_string(&orig_db_name,
2620
/* SHOW TABLE NAMES command */
2621
if (schema_table_idx == SCH_TABLE_NAMES)
1749
if (make_table_list(session, &sel, *db_name, *table_name))
1752
TableList *show_table_list= (TableList*) sel.table_list.first;
1753
lex->all_selects_list= &sel;
1754
lex->derived_tables= 0;
1755
lex->sql_command= SQLCOM_SHOW_FIELDS;
1756
show_table_list->i_s_requested_object=
1757
schema_table->getRequestedObject();
1758
res= session->openTables(show_table_list, DRIZZLE_LOCK_IGNORE_FLUSH);
1759
lex->sql_command= save_sql_command;
1761
XXX-> show_table_list has a flag i_is_requested,
1762
and when it's set, openTables()
1763
can return an error without setting an error message
1764
in Session, which is a hack. This is why we have to
1765
check for res, then for session->is_error() only then
1766
for session->main_da.sql_errno().
1768
if (res && session->is_error() &&
1769
session->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2623
if (fill_schema_table_names(thd, tables->table, db_name,
2624
table_name, with_i_schema))
1772
Hide error for not existing table.
1773
This error can occur for example when we use
1774
where condition with db name and table name and this
1775
table does not exist.
1778
session->clear_error();
2629
if (!(table_open_method & ~OPEN_FRM_ONLY) &&
2632
if (!fill_schema_table_from_frm(thd, tables, schema_table, db_name,
2633
table_name, schema_table_idx))
2638
LEX_STRING tmp_lex_string, orig_db_name;
2640
Set the parent lex of 'sel' because it is needed by
2641
sel.init_query() which is called inside make_table_list.
2643
thd->no_warnings_for_error= 1;
2644
sel.parent_lex= lex;
2645
/* db_name can be changed in make_table_list() func */
2646
if (!thd->make_lex_string(&orig_db_name, db_name->str,
2647
db_name->length, false))
2649
if (make_table_list(thd, &sel, db_name, table_name))
2651
TABLE_LIST *show_table_list= (TABLE_LIST*) sel.table_list.first;
2652
lex->all_selects_list= &sel;
2653
lex->derived_tables= 0;
2654
lex->sql_command= SQLCOM_SHOW_FIELDS;
2655
show_table_list->i_s_requested_object=
2656
schema_table->i_s_requested_object;
2657
res= open_normal_and_derived_tables(thd, show_table_list,
2658
DRIZZLE_LOCK_IGNORE_FLUSH);
2659
lex->sql_command= save_sql_command;
2661
XXX: show_table_list has a flag i_is_requested,
2662
and when it's set, open_normal_and_derived_tables()
2663
can return an error without setting an error message
2664
in THD, which is a hack. This is why we have to
2665
check for res, then for thd->is_error() only then
2666
for thd->main_da.sql_errno().
2668
if (res && thd->is_error() &&
2669
thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
2672
Hide error for not existing table.
2673
This error can occur for example when we use
2674
where condition with db name and table name and this
2675
table does not exist.
2683
We should use show_table_list->alias instead of
2684
show_table_list->table_name because table_name
2685
could be changed during opening of I_S tables. It's safe
2686
to use alias because alias contains original table name
2689
thd->make_lex_string(&tmp_lex_string, show_table_list->alias,
2690
strlen(show_table_list->alias), false);
2691
res= schema_table->process_table(thd, show_table_list, table,
2694
close_tables_for_reopen(thd, &show_table_list);
2696
assert(!lex->query_tables_own_last);
1783
We should use show_table_list->alias instead of
1784
show_table_list->table_name because table_name
1785
could be changed during opening of I_S tables. It's safe
1786
to use alias because alias contains original table name
1789
session->make_lex_string(&tmp_lex_string, show_table_list->alias,
1790
strlen(show_table_list->alias), false);
1791
res= schema_table->processTable(session, show_table_list, table,
1794
session->close_tables_for_reopen(&show_table_list);
1796
assert(!lex->query_tables_own_last);
2703
If we have information schema its always the first table and only
2704
the first table. Reset for other tables.
1803
If we have information schema its always the first table and only
1804
the first table. Reset for other tables.
2712
thd->restore_backup_open_tables_state(&open_tables_state_backup);
2713
lex->restore_backup_query_tables_list(&query_tables_list_backup);
1812
session->restore_backup_open_tables_state(&open_tables_state_backup);
2714
1813
lex->derived_tables= derived_tables;
2715
1814
lex->all_selects_list= old_all_select_lex;
2716
1815
lex->sql_command= save_sql_command;
2717
thd->no_warnings_for_error= old_value;
1816
session->no_warnings_for_error= old_value;
2722
bool store_schema_shemata(THD* thd, TABLE *table, LEX_STRING *db_name,
2723
const CHARSET_INFO * const cs)
2725
restore_record(table, s->default_values);
2726
table->field[1]->store(db_name->str, db_name->length, system_charset_info);
2727
table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
2728
table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
2729
return schema_table_store_record(thd, table);
2733
int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
2736
TODO: fill_schema_shemata() is called when new client is connected.
2737
Returning error status in this case leads to client hangup.
2740
LOOKUP_FIELD_VALUES lookup_field_vals;
2741
List<LEX_STRING> db_names;
2742
LEX_STRING *db_name;
2744
HA_CREATE_INFO create;
2745
TABLE *table= tables->table;
2747
if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
2749
if (make_db_list(thd, &db_names, &lookup_field_vals,
2754
If we have lookup db value we should check that the database exists
2756
if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
2759
char path[FN_REFLEN+16];
2761
struct stat stat_info;
2762
if (!lookup_field_vals.db_value.str[0])
2764
path_len= build_table_filename(path, sizeof(path),
2765
lookup_field_vals.db_value.str, "", "", 0);
2766
path[path_len-1]= 0;
2767
if (stat(path,&stat_info))
2771
List_iterator_fast<LEX_STRING> it(db_names);
2772
while ((db_name=it++))
2774
if (with_i_schema) // information schema name is always first in list
2776
if (store_schema_shemata(thd, table, db_name,
2777
system_charset_info))
2783
load_db_opt_by_name(thd, db_name->str, &create);
2784
if (store_schema_shemata(thd, table, db_name,
2785
create.default_table_charset))
2793
static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
2794
TABLE *table, bool res,
2795
LEX_STRING *db_name,
2796
LEX_STRING *table_name)
2798
const char *tmp_buff;
2800
const CHARSET_INFO * const cs= system_charset_info;
2802
restore_record(table, s->default_values);
2803
table->field[1]->store(db_name->str, db_name->length, cs);
2804
table->field[2]->store(table_name->str, table_name->length, cs);
2808
there was errors during opening tables
2810
const char *error= thd->is_error() ? thd->main_da.message() : "";
2811
if (tables->schema_table)
2812
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2814
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
2815
table->field[20]->store(error, strlen(error), cs);
2820
char option_buff[400],*ptr;
2821
TABLE *show_table= tables->table;
2822
TABLE_SHARE *share= show_table->s;
2823
handler *file= show_table->file;
2824
handlerton *tmp_db_type= share->db_type();
2825
if (share->tmp_table == SYSTEM_TMP_TABLE)
2826
table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
2827
else if (share->tmp_table)
2828
table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
2830
table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
2832
for (int i= 4; i < 20; i++)
2834
if (i == 7 || (i > 12 && i < 17) || i == 18)
2836
table->field[i]->set_notnull();
2838
tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
2839
table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
2840
table->field[5]->store((int64_t) share->frm_version, true);
2843
if (share->min_rows)
2845
ptr=stpcpy(ptr," min_rows=");
2846
ptr=int64_t10_to_str(share->min_rows,ptr,10);
2848
if (share->max_rows)
2850
ptr=stpcpy(ptr," max_rows=");
2851
ptr=int64_t10_to_str(share->max_rows,ptr,10);
2853
if (share->avg_row_length)
2855
ptr=stpcpy(ptr," avg_row_length=");
2856
ptr=int64_t10_to_str(share->avg_row_length,ptr,10);
2858
if (share->db_create_options & HA_OPTION_PACK_KEYS)
2859
ptr=stpcpy(ptr," pack_keys=1");
2860
if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
2861
ptr=stpcpy(ptr," pack_keys=0");
2862
/* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
2863
if (share->db_create_options & HA_OPTION_CHECKSUM)
2864
ptr=stpcpy(ptr," checksum=1");
2865
if (share->page_checksum != HA_CHOICE_UNDEF)
2866
ptr= strxmov(ptr, " page_checksum=",
2867
ha_choice_values[(uint) share->page_checksum], NullS);
2868
if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
2869
ptr=stpcpy(ptr," delay_key_write=1");
2870
if (share->row_type != ROW_TYPE_DEFAULT)
2871
ptr=strxmov(ptr, " row_format=",
2872
ha_row_type[(uint) share->row_type],
2874
if (share->block_size)
2876
ptr= stpcpy(ptr, " block_size=");
2877
ptr= int64_t10_to_str(share->block_size, ptr, 10);
2880
if (share->transactional != HA_CHOICE_UNDEF)
2882
ptr= strxmov(ptr, " TRANSACTIONAL=",
2883
(share->transactional == HA_CHOICE_YES ? "1" : "0"),
2886
if (share->transactional != HA_CHOICE_UNDEF)
2887
ptr= strxmov(ptr, " transactional=",
2888
ha_choice_values[(uint) share->transactional], NullS);
2889
table->field[19]->store(option_buff+1,
2890
(ptr == option_buff ? 0 :
2891
(uint) (ptr-option_buff)-1), cs);
2893
tmp_buff= (share->table_charset ?
2894
share->table_charset->name : "default");
2895
table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
2897
if (share->comment.str)
2898
table->field[20]->store(share->comment.str, share->comment.length, cs);
2902
file->info(HA_STATUS_VARIABLE | HA_STATUS_TIME | HA_STATUS_AUTO |
2904
enum row_type row_type = file->get_row_type();
2906
case ROW_TYPE_NOT_USED:
2907
case ROW_TYPE_DEFAULT:
2908
tmp_buff= ((share->db_options_in_use &
2909
HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
2910
(share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
2911
"Dynamic" : "Fixed");
2913
case ROW_TYPE_FIXED:
2916
case ROW_TYPE_DYNAMIC:
2917
tmp_buff= "Dynamic";
2919
case ROW_TYPE_COMPRESSED:
2920
tmp_buff= "Compressed";
2922
case ROW_TYPE_REDUNDANT:
2923
tmp_buff= "Redundant";
2925
case ROW_TYPE_COMPACT:
2926
tmp_buff= "Compact";
2932
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
2933
if (!tables->schema_table)
2935
table->field[7]->store((int64_t) file->stats.records, true);
2936
table->field[7]->set_notnull();
2938
table->field[8]->store((int64_t) file->stats.mean_rec_length, true);
2939
table->field[9]->store((int64_t) file->stats.data_file_length, true);
2940
if (file->stats.max_data_file_length)
2942
table->field[10]->store((int64_t) file->stats.max_data_file_length,
2945
table->field[11]->store((int64_t) file->stats.index_file_length, true);
2946
table->field[12]->store((int64_t) file->stats.delete_length, true);
2947
if (show_table->found_next_number_field)
2949
table->field[13]->store((int64_t) file->stats.auto_increment_value,
2951
table->field[13]->set_notnull();
2953
if (file->stats.create_time)
2955
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2956
(my_time_t) file->stats.create_time);
2957
table->field[14]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2958
table->field[14]->set_notnull();
2960
if (file->stats.update_time)
2962
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2963
(my_time_t) file->stats.update_time);
2964
table->field[15]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2965
table->field[15]->set_notnull();
2967
if (file->stats.check_time)
2969
thd->variables.time_zone->gmt_sec_to_TIME(&time,
2970
(my_time_t) file->stats.check_time);
2971
table->field[16]->store_time(&time, DRIZZLE_TIMESTAMP_DATETIME);
2972
table->field[16]->set_notnull();
2974
if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
2976
table->field[18]->store((int64_t) file->checksum(), true);
2977
table->field[18]->set_notnull();
2981
return(schema_table_store_record(thd, table));
2986
1822
@brief Store field characteristics into appropriate I_S table columns
3193
2013
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
3194
2014
table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
3197
2016
table->field[18]->store(field->comment.str, field->comment.length, cs);
3199
2018
enum column_format_type column_format= (enum column_format_type)
3200
2019
((field->flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
3201
pos=(uchar*)"Default";
2020
pos=(unsigned char*)"Default";
3202
2021
table->field[19]->store((const char*) pos,
3203
2022
strlen((const char*) pos), cs);
3204
pos=(uchar*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
2023
pos=(unsigned char*)(column_format == COLUMN_FORMAT_TYPE_DEFAULT ? "Default" :
3205
2024
column_format == COLUMN_FORMAT_TYPE_FIXED ? "Fixed" :
3207
2026
table->field[20]->store((const char*) pos,
3208
2027
strlen((const char*) pos), cs);
3210
if (schema_table_store_record(thd, table))
3218
int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((unused)))
3221
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3222
TABLE *table= tables->table;
3223
const CHARSET_INFO * const scs= system_charset_info;
3225
for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
3227
const CHARSET_INFO * const tmp_cs= cs[0];
3228
if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
3229
(tmp_cs->state & MY_CS_AVAILABLE) &&
3230
!(tmp_cs->state & MY_CS_HIDDEN) &&
3231
!(wild && wild[0] &&
3232
wild_case_compare(scs, tmp_cs->csname,wild)))
3234
const char *comment;
3235
restore_record(table, s->default_values);
3236
table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
3237
table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
3238
comment= tmp_cs->comment ? tmp_cs->comment : "";
3239
table->field[2]->store(comment, strlen(comment), scs);
3240
table->field[3]->store((int64_t) tmp_cs->mbmaxlen, true);
3241
if (schema_table_store_record(thd, table))
3249
int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((unused)))
3252
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3253
TABLE *table= tables->table;
3254
const CHARSET_INFO * const scs= system_charset_info;
3255
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3258
const CHARSET_INFO *tmp_cs= cs[0];
3259
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3260
(tmp_cs->state & MY_CS_HIDDEN) ||
3261
!(tmp_cs->state & MY_CS_PRIMARY))
3263
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3265
const CHARSET_INFO *tmp_cl= cl[0];
3266
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3267
!my_charset_same(tmp_cs, tmp_cl))
3269
if (!(wild && wild[0] &&
3270
wild_case_compare(scs, tmp_cl->name,wild)))
3272
const char *tmp_buff;
3273
restore_record(table, s->default_values);
3274
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3275
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3276
table->field[2]->store((int64_t) tmp_cl->number, true);
3277
tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
3278
table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
3279
tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
3280
table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
3281
table->field[5]->store((int64_t) tmp_cl->strxfrm_multiply, true);
3282
if (schema_table_store_record(thd, table))
3291
int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((unused)))
3294
TABLE *table= tables->table;
3295
const CHARSET_INFO * const scs= system_charset_info;
3296
for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
3299
const CHARSET_INFO *tmp_cs= cs[0];
3300
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
3301
!(tmp_cs->state & MY_CS_PRIMARY))
3303
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
3305
const CHARSET_INFO *tmp_cl= cl[0];
3306
if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
3307
!my_charset_same(tmp_cs,tmp_cl))
3309
restore_record(table, s->default_values);
3310
table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
3311
table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
3312
if (schema_table_store_record(thd, table))
3320
static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
3321
TABLE *table, bool res,
3322
LEX_STRING *db_name,
3323
LEX_STRING *table_name)
3325
const CHARSET_INFO * const cs= system_charset_info;
3328
if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
3331
I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
3332
rather than in SHOW KEYS
3334
if (thd->is_error())
3335
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3336
thd->main_da.sql_errno(), thd->main_da.message());
3344
TABLE *show_table= tables->table;
3345
KEY *key_info=show_table->s->key_info;
3346
if (show_table->file)
3347
show_table->file->info(HA_STATUS_VARIABLE |
3350
for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
3352
KEY_PART_INFO *key_part= key_info->key_part;
3354
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3356
restore_record(table, s->default_values);
3357
table->field[1]->store(db_name->str, db_name->length, cs);
3358
table->field[2]->store(table_name->str, table_name->length, cs);
3359
table->field[3]->store((int64_t) ((key_info->flags &
3360
HA_NOSAME) ? 0 : 1), true);
3361
table->field[4]->store(db_name->str, db_name->length, cs);
3362
table->field[5]->store(key_info->name, strlen(key_info->name), cs);
3363
table->field[6]->store((int64_t) (j+1), true);
3364
str=(key_part->field ? key_part->field->field_name :
3366
table->field[7]->store(str, strlen(str), cs);
3367
if (show_table->file)
3369
if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
3371
table->field[8]->store(((key_part->key_part_flag &
3374
table->field[8]->set_notnull();
3376
KEY *key=show_table->key_info+i;
3377
if (key->rec_per_key[j])
3379
ha_rows records=(show_table->file->stats.records /
3380
key->rec_per_key[j]);
3381
table->field[9]->store((int64_t) records, true);
3382
table->field[9]->set_notnull();
3384
str= show_table->file->index_type(i);
3385
table->field[13]->store(str, strlen(str), cs);
3387
if ((key_part->field &&
3389
show_table->s->field[key_part->fieldnr-1]->key_length()))
3391
table->field[10]->store((int64_t) key_part->length /
3392
key_part->field->charset()->mbmaxlen, true);
3393
table->field[10]->set_notnull();
3395
uint flags= key_part->field ? key_part->field->flags : 0;
3396
const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
3397
table->field[12]->store(pos, strlen(pos), cs);
3398
if (!show_table->s->keys_in_use.is_set(i))
3399
table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
3401
table->field[14]->store("", 0, cs);
3402
table->field[14]->set_notnull();
3403
assert(test(key_info->flags & HA_USES_COMMENT) ==
3404
(key_info->comment.length > 0));
3405
if (key_info->flags & HA_USES_COMMENT)
3406
table->field[15]->store(key_info->comment.str,
3407
key_info->comment.length, cs);
3408
if (schema_table_store_record(thd, table))
3417
bool store_constraints(THD *thd, TABLE *table, LEX_STRING *db_name,
3418
LEX_STRING *table_name, const char *key_name,
3419
uint key_len, const char *con_type, uint con_len)
3421
const CHARSET_INFO * const cs= system_charset_info;
3422
restore_record(table, s->default_values);
3423
table->field[1]->store(db_name->str, db_name->length, cs);
3424
table->field[2]->store(key_name, key_len, cs);
3425
table->field[3]->store(db_name->str, db_name->length, cs);
3426
table->field[4]->store(table_name->str, table_name->length, cs);
3427
table->field[5]->store(con_type, con_len, cs);
3428
return schema_table_store_record(thd, table);
3432
static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
3433
TABLE *table, bool res,
3434
LEX_STRING *db_name,
3435
LEX_STRING *table_name)
3439
if (thd->is_error())
3440
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3441
thd->main_da.sql_errno(), thd->main_da.message());
3447
List<FOREIGN_KEY_INFO> f_key_list;
3448
TABLE *show_table= tables->table;
3449
KEY *key_info=show_table->key_info;
3450
uint primary_key= show_table->s->primary_key;
3451
show_table->file->info(HA_STATUS_VARIABLE |
3454
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3456
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3459
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
3461
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3462
strlen(key_info->name),
3463
STRING_WITH_LEN("PRIMARY KEY")))
3466
else if (key_info->flags & HA_NOSAME)
3468
if (store_constraints(thd, table, db_name, table_name, key_info->name,
3469
strlen(key_info->name),
3470
STRING_WITH_LEN("UNIQUE")))
3475
show_table->file->get_foreign_key_list(thd, &f_key_list);
3476
FOREIGN_KEY_INFO *f_key_info;
3477
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3478
while ((f_key_info=it++))
3480
if (store_constraints(thd, table, db_name, table_name,
3481
f_key_info->forein_id->str,
3482
strlen(f_key_info->forein_id->str),
3491
void store_key_column_usage(TABLE *table, LEX_STRING *db_name,
3492
LEX_STRING *table_name, const char *key_name,
3493
uint key_len, const char *con_type, uint con_len,
3496
const CHARSET_INFO * const cs= system_charset_info;
3497
table->field[1]->store(db_name->str, db_name->length, cs);
3498
table->field[2]->store(key_name, key_len, cs);
3499
table->field[4]->store(db_name->str, db_name->length, cs);
3500
table->field[5]->store(table_name->str, table_name->length, cs);
3501
table->field[6]->store(con_type, con_len, cs);
3502
table->field[7]->store((int64_t) idx, true);
3506
static int get_schema_key_column_usage_record(THD *thd,
3508
TABLE *table, bool res,
3509
LEX_STRING *db_name,
3510
LEX_STRING *table_name)
3514
if (thd->is_error())
3515
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3516
thd->main_da.sql_errno(), thd->main_da.message());
3522
List<FOREIGN_KEY_INFO> f_key_list;
3523
TABLE *show_table= tables->table;
3524
KEY *key_info=show_table->key_info;
3525
uint primary_key= show_table->s->primary_key;
3526
show_table->file->info(HA_STATUS_VARIABLE |
3529
for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
3531
if (i != primary_key && !(key_info->flags & HA_NOSAME))
3534
KEY_PART_INFO *key_part= key_info->key_part;
3535
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
3537
if (key_part->field)
3540
restore_record(table, s->default_values);
3541
store_key_column_usage(table, db_name, table_name,
3543
strlen(key_info->name),
3544
key_part->field->field_name,
3545
strlen(key_part->field->field_name),
3547
if (schema_table_store_record(thd, table))
3553
show_table->file->get_foreign_key_list(thd, &f_key_list);
3554
FOREIGN_KEY_INFO *f_key_info;
3555
List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
3556
while ((f_key_info= fkey_it++))
3560
List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
3561
it1(f_key_info->referenced_fields);
3563
while ((f_info= it++))
3567
restore_record(table, s->default_values);
3568
store_key_column_usage(table, db_name, table_name,
3569
f_key_info->forein_id->str,
3570
f_key_info->forein_id->length,
3571
f_info->str, f_info->length,
3573
table->field[8]->store((int64_t) f_idx, true);
3574
table->field[8]->set_notnull();
3575
table->field[9]->store(f_key_info->referenced_db->str,
3576
f_key_info->referenced_db->length,
3577
system_charset_info);
3578
table->field[9]->set_notnull();
3579
table->field[10]->store(f_key_info->referenced_table->str,
3580
f_key_info->referenced_table->length,
3581
system_charset_info);
3582
table->field[10]->set_notnull();
3583
table->field[11]->store(r_info->str, r_info->length,
3584
system_charset_info);
3585
table->field[11]->set_notnull();
3586
if (schema_table_store_record(thd, table))
3595
int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((unused)))
3597
const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
3598
TABLE *table= tables->table;
3599
const CHARSET_INFO * const cs= system_charset_info;
3600
OPEN_TABLE_LIST *open_list;
3601
if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
3602
&& thd->is_fatal_error)
3605
for (; open_list ; open_list=open_list->next)
3607
restore_record(table, s->default_values);
3608
table->field[0]->store(open_list->db, strlen(open_list->db), cs);
3609
table->field[1]->store(open_list->table, strlen(open_list->table), cs);
3610
table->field[2]->store((int64_t) open_list->in_use, true);
3611
table->field[3]->store((int64_t) open_list->locked, true);
3612
if (schema_table_store_record(thd, table))
3619
int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((unused)))
3623
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3624
enum enum_schema_tables schema_table_idx=
3625
get_schema_table_idx(tables->schema_table);
3626
enum enum_var_type option_type= OPT_SESSION;
3627
bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
3628
bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
3630
if (lex->option_type == OPT_GLOBAL ||
3631
schema_table_idx == SCH_GLOBAL_VARIABLES)
3632
option_type= OPT_GLOBAL;
3634
rw_rdlock(&LOCK_system_variables_hash);
3635
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
3636
option_type, NULL, "", tables->table, upper_case_names);
3637
rw_unlock(&LOCK_system_variables_hash);
3642
int fill_status(THD *thd, TABLE_LIST *tables, COND *cond __attribute__((unused)))
3645
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
3647
STATUS_VAR *tmp1, tmp;
3648
enum enum_schema_tables schema_table_idx=
3649
get_schema_table_idx(tables->schema_table);
3650
enum enum_var_type option_type;
3651
bool upper_case_names= (schema_table_idx != SCH_STATUS);
3653
if (schema_table_idx == SCH_STATUS)
3655
option_type= lex->option_type;
3656
if (option_type == OPT_GLOBAL)
3659
tmp1= thd->initial_status_var;
3661
else if (schema_table_idx == SCH_GLOBAL_STATUS)
3663
option_type= OPT_GLOBAL;
3668
option_type= OPT_SESSION;
3669
tmp1= &thd->status_var;
3672
pthread_mutex_lock(&LOCK_status);
3673
if (option_type == OPT_GLOBAL)
3674
calc_sum_of_all_status(&tmp);
3675
res= show_status_array(thd, wild,
3676
(SHOW_VAR *)all_status_vars.buffer,
3677
option_type, tmp1, "", tables->table,
3679
pthread_mutex_unlock(&LOCK_status);
3685
Fill and store records into I_S.referential_constraints table
3688
get_referential_constraints_record()
3690
tables table list struct(processed table)
3692
res 1 means the error during opening of the processed table
3693
0 means processed table is opened without error
3695
file_name table name
3703
get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
3704
TABLE *table, bool res,
3705
LEX_STRING *db_name, LEX_STRING *table_name)
3707
const CHARSET_INFO * const cs= system_charset_info;
3711
if (thd->is_error())
3712
push_warning(thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
3713
thd->main_da.sql_errno(), thd->main_da.message());
3719
List<FOREIGN_KEY_INFO> f_key_list;
3720
TABLE *show_table= tables->table;
3721
show_table->file->info(HA_STATUS_VARIABLE |
3725
show_table->file->get_foreign_key_list(thd, &f_key_list);
3726
FOREIGN_KEY_INFO *f_key_info;
3727
List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
3728
while ((f_key_info= it++))
3730
restore_record(table, s->default_values);
3731
table->field[1]->store(db_name->str, db_name->length, cs);
3732
table->field[9]->store(table_name->str, table_name->length, cs);
3733
table->field[2]->store(f_key_info->forein_id->str,
3734
f_key_info->forein_id->length, cs);
3735
table->field[4]->store(f_key_info->referenced_db->str,
3736
f_key_info->referenced_db->length, cs);
3737
table->field[10]->store(f_key_info->referenced_table->str,
3738
f_key_info->referenced_table->length, cs);
3739
if (f_key_info->referenced_key_name)
3741
table->field[5]->store(f_key_info->referenced_key_name->str,
3742
f_key_info->referenced_key_name->length, cs);
3743
table->field[5]->set_notnull();
3746
table->field[5]->set_null();
3747
table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
3748
table->field[7]->store(f_key_info->update_method->str,
3749
f_key_info->update_method->length, cs);
3750
table->field[8]->store(f_key_info->delete_method->str,
3751
f_key_info->delete_method->length, cs);
3752
if (schema_table_store_record(thd, table))
3760
struct schema_table_ref
3762
const char *table_name;
3763
ST_SCHEMA_TABLE *schema_table;
3768
Find schema_tables elment by name
3771
find_schema_table_in_plugin()
3774
table_name table name
3778
1 found the schema table
3780
static bool find_schema_table_in_plugin(THD *thd __attribute__((unused)),
3784
schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
3785
const char* table_name= p_schema_table->table_name;
3786
ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
3788
if (!my_strcasecmp(system_charset_info,
3789
schema_table->table_name,
3791
p_schema_table->schema_table= schema_table;
3800
Find schema_tables elment by name
3805
table_name table name
3809
# pointer to 'schema_tables' element
3812
ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
3814
schema_table_ref schema_table_a;
3815
ST_SCHEMA_TABLE *schema_table= schema_tables;
3817
for (; schema_table->table_name; schema_table++)
3819
if (!my_strcasecmp(system_charset_info,
3820
schema_table->table_name,
3822
return(schema_table);
3825
schema_table_a.table_name= table_name;
3826
if (plugin_foreach(thd, find_schema_table_in_plugin,
3827
DRIZZLE_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
3828
return(schema_table_a.schema_table);
3834
ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
3836
return &schema_tables[schema_table_idx];
3841
Create information_schema table using schema_table data.
3848
@param table_list Used to pass I_S table information(fields info, tables
3849
parameters etc) and table name.
3851
@retval \# Pointer to created table
3852
@retval NULL Can't create table
3855
TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
3860
List<Item> field_list;
3861
ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
3862
ST_FIELD_INFO *fields_info= schema_table->fields_info;
3863
const CHARSET_INFO * const cs= system_charset_info;
3865
for (; fields_info->field_name; fields_info++)
3867
switch (fields_info->field_type) {
3868
case DRIZZLE_TYPE_TINY:
3869
case DRIZZLE_TYPE_LONG:
3870
case DRIZZLE_TYPE_SHORT:
3871
case DRIZZLE_TYPE_LONGLONG:
3872
if (!(item= new Item_return_int(fields_info->field_name,
3873
fields_info->field_length,
3874
fields_info->field_type,
3875
fields_info->value)))
3879
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3881
case DRIZZLE_TYPE_NEWDATE:
3882
case DRIZZLE_TYPE_TIME:
3883
case DRIZZLE_TYPE_TIMESTAMP:
3884
case DRIZZLE_TYPE_DATETIME:
3885
if (!(item=new Item_return_date_time(fields_info->field_name,
3886
fields_info->field_type)))
3891
case DRIZZLE_TYPE_DOUBLE:
3892
if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
3893
fields_info->field_length)) == NULL)
3896
case DRIZZLE_TYPE_NEWDECIMAL:
3897
if (!(item= new Item_decimal((int64_t) fields_info->value, false)))
3901
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
3902
item->decimals= fields_info->field_length%10;
3903
item->max_length= (fields_info->field_length/100)%100;
3904
if (item->unsigned_flag == 0)
3905
item->max_length+= 1;
3906
if (item->decimals > 0)
3907
item->max_length+= 1;
3908
item->set_name(fields_info->field_name,
3909
strlen(fields_info->field_name), cs);
3911
case DRIZZLE_TYPE_BLOB:
3912
if (!(item= new Item_blob(fields_info->field_name,
3913
fields_info->field_length)))
3919
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
3923
item->set_name(fields_info->field_name,
3924
strlen(fields_info->field_name), cs);
3927
field_list.push_back(item);
3928
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
3931
TMP_TABLE_PARAM *tmp_table_param =
3932
(TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
3933
tmp_table_param->init();
3934
tmp_table_param->table_charset= cs;
3935
tmp_table_param->field_count= field_count;
3936
tmp_table_param->schema_table= 1;
3937
SELECT_LEX *select_lex= thd->lex->current_select;
3938
if (!(table= create_tmp_table(thd, tmp_table_param,
3939
field_list, (ORDER*) 0, 0, 0,
3940
(select_lex->options | thd->options |
3941
TMP_TABLE_ALL_COLUMNS),
3942
HA_POS_ERROR, table_list->alias)))
3944
my_bitmap_map* bitmaps=
3945
(my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
3946
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
3948
table->read_set= &table->def_read_set;
3949
bitmap_clear_all(table->read_set);
3950
table_list->schema_table_param= tmp_table_param;
2029
store_table->addRow(table->record[0], table->s->reclength);
4197
2084
make_schema_select()
4199
sel pointer to SELECT_LEX
4200
schema_table_idx index of 'schema_tables' element
2085
session thread Cursor
2086
sel pointer to Select_Lex
2087
schema_table_name name of 'schema_tables' element
4207
int make_schema_select(THD *thd, SELECT_LEX *sel,
4208
enum enum_schema_tables schema_table_idx)
2093
bool make_schema_select(Session *session, Select_Lex *sel,
2094
const string& schema_table_name)
4210
ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
2096
plugin::InfoSchemaTable *schema_table= plugin::InfoSchemaTable::getTable(schema_table_name.c_str());
4211
2097
LEX_STRING db, table;
4213
2099
We have to make non const db_name & table_name
4214
2100
because of lower_case_table_names
4216
thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str,
4217
INFORMATION_SCHEMA_NAME.length, 0);
4218
thd->make_lex_string(&table, schema_table->table_name,
4219
strlen(schema_table->table_name), 0);
4220
if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
4221
!sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
4231
Fill temporary schema tables before SELECT
4234
get_schema_tables_result()
4235
join join which use schema tables
4236
executed_place place where I_S table processed
4243
bool get_schema_tables_result(JOIN *join,
4244
enum enum_schema_table_state executed_place)
4246
JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
4247
THD *thd= join->thd;
4251
thd->no_warnings_for_error= 1;
4252
for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
4254
if (!tab->table || !tab->table->pos_in_table_list)
4257
TABLE_LIST *table_list= tab->table->pos_in_table_list;
4258
if (table_list->schema_table)
4260
bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
4261
lex->current_select->master_unit()->item);
4264
/* skip I_S optimizations specific to get_all_tables */
4265
if (thd->lex->describe &&
4266
(table_list->schema_table->fill_table != get_all_tables))
4270
If schema table is already processed and
4271
the statement is not a subselect then
4272
we don't need to fill this table again.
4273
If schema table is already processed and
4274
schema_table_state != executed_place then
4275
table is already processed and
4276
we should skip second data processing.
4278
if (table_list->schema_table_state &&
4279
(!is_subselect || table_list->schema_table_state != executed_place))
4283
if table is used in a subselect and
4284
table has been processed earlier with the same
4285
'executed_place' value then we should refresh the table.
4287
if (table_list->schema_table_state && is_subselect)
4289
table_list->table->file->extra(HA_EXTRA_NO_CACHE);
4290
table_list->table->file->extra(HA_EXTRA_RESET_STATE);
4291
table_list->table->file->ha_delete_all_rows();
4292
free_io_cache(table_list->table);
4293
filesort_free_buffers(table_list->table,1);
4294
table_list->table->null_row= 0;
4297
table_list->table->file->stats.records= 0;
4299
if (table_list->schema_table->fill_table(thd, table_list,
4304
tab->read_record.file= table_list->table->file;
4305
table_list->schema_table_state= executed_place;
4308
tab->read_record.file= table_list->table->file;
4309
table_list->schema_table_state= executed_place;
4312
thd->no_warnings_for_error= 0;
4316
ST_FIELD_INFO schema_fields_info[]=
4318
{"CATALOG_NAME", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4319
{"SCHEMA_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4321
{"DEFAULT_CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4323
{"DEFAULT_COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4324
{"SQL_PATH", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4325
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4329
ST_FIELD_INFO tables_fields_info[]=
4331
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4332
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4333
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4335
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4336
{"ENGINE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Engine", OPEN_FRM_ONLY},
4337
{"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4338
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
4339
{"ROW_FORMAT", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Row_format", OPEN_FULL_TABLE},
4340
{"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4341
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
4342
{"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4343
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
4344
{"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4345
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
4346
{"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4347
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
4348
{"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4349
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
4350
{"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4351
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
4352
{"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG, 0,
4353
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
4354
{"CREATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
4355
{"UPDATE_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
4356
{"CHECK_TIME", 0, DRIZZLE_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
4357
{"TABLE_COLLATION", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4358
{"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4359
(MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
4360
{"CREATE_OPTIONS", 255, DRIZZLE_TYPE_VARCHAR, 0, 1, "Create_options",
4362
{"TABLE_COMMENT", TABLE_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4363
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4367
ST_FIELD_INFO columns_fields_info[]=
4369
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4370
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4371
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4372
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Field",
4374
{"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0,
4375
MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
4376
{"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, DRIZZLE_TYPE_VARCHAR, 0,
4377
1, "Default", OPEN_FRM_ONLY},
4378
{"IS_NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4379
{"DATA_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4380
{"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4381
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4382
{"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4383
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4384
{"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG,
4385
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4386
{"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , DRIZZLE_TYPE_LONGLONG,
4387
0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
4388
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4389
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4390
{"COLUMN_TYPE", 65535, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", OPEN_FRM_ONLY},
4391
{"COLUMN_KEY", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key", OPEN_FRM_ONLY},
4392
{"EXTRA", 27, DRIZZLE_TYPE_VARCHAR, 0, 0, "Extra", OPEN_FRM_ONLY},
4393
{"PRIVILEGES", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Privileges", OPEN_FRM_ONLY},
4394
{"COLUMN_COMMENT", COLUMN_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Comment", OPEN_FRM_ONLY},
4395
{"STORAGE", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Storage", OPEN_FRM_ONLY},
4396
{"FORMAT", 8, DRIZZLE_TYPE_VARCHAR, 0, 0, "Format", OPEN_FRM_ONLY},
4397
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4401
ST_FIELD_INFO charsets_fields_info[]=
4403
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4405
{"DEFAULT_COLLATE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default collation",
4407
{"DESCRIPTION", 60, DRIZZLE_TYPE_VARCHAR, 0, 0, "Description",
4409
{"MAXLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
4410
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4414
ST_FIELD_INFO collation_fields_info[]=
4416
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Collation", SKIP_OPEN_TABLE},
4417
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Charset",
4419
{"ID", MY_INT32_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id",
4421
{"IS_DEFAULT", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Default", SKIP_OPEN_TABLE},
4422
{"IS_COMPILED", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Compiled", SKIP_OPEN_TABLE},
4423
{"SORTLEN", 3, DRIZZLE_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
4424
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4429
ST_FIELD_INFO coll_charset_app_fields_info[]=
4431
{"COLLATION_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4432
{"CHARACTER_SET_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4433
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4437
ST_FIELD_INFO stat_fields_info[]=
4439
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FRM_ONLY},
4440
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4441
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", OPEN_FRM_ONLY},
4442
{"NON_UNIQUE", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
4443
{"INDEX_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FRM_ONLY},
4444
{"INDEX_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Key_name",
4446
{"SEQ_IN_INDEX", 2, DRIZZLE_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
4447
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Column_name",
4449
{"COLLATION", 1, DRIZZLE_TYPE_VARCHAR, 0, 1, "Collation", OPEN_FRM_ONLY},
4450
{"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, DRIZZLE_TYPE_LONGLONG, 0, 1,
4451
"Cardinality", OPEN_FULL_TABLE},
4452
{"SUB_PART", 3, DRIZZLE_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
4453
{"PACKED", 10, DRIZZLE_TYPE_VARCHAR, 0, 1, "Packed", OPEN_FRM_ONLY},
4454
{"NULLABLE", 3, DRIZZLE_TYPE_VARCHAR, 0, 0, "Null", OPEN_FRM_ONLY},
4455
{"INDEX_TYPE", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_type", OPEN_FULL_TABLE},
4456
{"COMMENT", 16, DRIZZLE_TYPE_VARCHAR, 0, 1, "Comment", OPEN_FRM_ONLY},
4457
{"INDEX_COMMENT", INDEX_COMMENT_MAXLEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Index_Comment", OPEN_FRM_ONLY},
4458
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4462
ST_FIELD_INFO table_constraints_fields_info[]=
4464
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4465
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4467
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
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
{"CONSTRAINT_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4473
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4477
ST_FIELD_INFO key_column_usage_fields_info[]=
4479
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4480
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4482
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4484
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4485
{"TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4486
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4487
{"COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4488
{"ORDINAL_POSITION", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
4489
{"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,DRIZZLE_TYPE_LONGLONG, 0, 1, 0,
4491
{"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4493
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4495
{"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4497
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4501
ST_FIELD_INFO table_names_fields_info[]=
4503
{"TABLE_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4504
{"TABLE_SCHEMA",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4505
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Tables_in_",
4507
{"TABLE_TYPE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table_type",
4509
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4513
ST_FIELD_INFO open_tables_fields_info[]=
4515
{"Database", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Database",
4517
{"Table",NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Table", SKIP_OPEN_TABLE},
4518
{"In_use", 1, DRIZZLE_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
4519
{"Name_locked", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
4520
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4524
ST_FIELD_INFO variables_fields_info[]=
4526
{"VARIABLE_NAME", 64, DRIZZLE_TYPE_VARCHAR, 0, 0, "Variable_name",
4528
{"VARIABLE_VALUE", 16300, DRIZZLE_TYPE_VARCHAR, 0, 1, "Value", SKIP_OPEN_TABLE},
4529
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4533
ST_FIELD_INFO processlist_fields_info[]=
4535
{"ID", 4, DRIZZLE_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
4536
{"USER", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "User", SKIP_OPEN_TABLE},
4537
{"HOST", LIST_PROCESS_HOST_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Host",
4539
{"DB", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Db", SKIP_OPEN_TABLE},
4540
{"COMMAND", 16, DRIZZLE_TYPE_VARCHAR, 0, 0, "Command", SKIP_OPEN_TABLE},
4541
{"TIME", 7, DRIZZLE_TYPE_LONGLONG, 0, 0, "Time", SKIP_OPEN_TABLE},
4542
{"STATE", 64, DRIZZLE_TYPE_VARCHAR, 0, 1, "State", SKIP_OPEN_TABLE},
4543
{"INFO", PROCESS_LIST_INFO_WIDTH, DRIZZLE_TYPE_VARCHAR, 0, 1, "Info",
4545
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4549
ST_FIELD_INFO plugin_fields_info[]=
4551
{"PLUGIN_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, "Name",
4553
{"PLUGIN_VERSION", 20, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE},
4554
{"PLUGIN_STATUS", 10, DRIZZLE_TYPE_VARCHAR, 0, 0, "Status", SKIP_OPEN_TABLE},
4555
{"PLUGIN_TYPE", 80, DRIZZLE_TYPE_VARCHAR, 0, 0, "Type", SKIP_OPEN_TABLE},
4556
{"PLUGIN_LIBRARY", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, "Library",
4558
{"PLUGIN_AUTHOR", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4559
{"PLUGIN_DESCRIPTION", 65535, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, SKIP_OPEN_TABLE},
4560
{"PLUGIN_LICENSE", 80, DRIZZLE_TYPE_VARCHAR, 0, 1, "License", SKIP_OPEN_TABLE},
4561
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4564
ST_FIELD_INFO referential_constraints_fields_info[]=
4566
{"CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0, OPEN_FULL_TABLE},
4567
{"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4569
{"CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4571
{"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, DRIZZLE_TYPE_VARCHAR, 0, 1, 0,
4573
{"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4575
{"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0,
4576
MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
4577
{"MATCH_OPTION", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4578
{"UPDATE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4579
{"DELETE_RULE", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4580
{"TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, OPEN_FULL_TABLE},
4581
{"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, DRIZZLE_TYPE_VARCHAR, 0, 0, 0,
4583
{0, 0, DRIZZLE_TYPE_VARCHAR, 0, 0, 0, SKIP_OPEN_TABLE}
4588
Description of ST_FIELD_INFO in table.h
4590
Make sure that the order of schema_tables and enum_schema_tables are the same.
4594
ST_SCHEMA_TABLE schema_tables[]=
4596
{"CHARACTER_SETS", charsets_fields_info, create_schema_table,
4597
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
4598
{"COLLATIONS", collation_fields_info, create_schema_table,
4599
fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
4600
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
4601
create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
4602
{"COLUMNS", columns_fields_info, create_schema_table,
4603
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
4604
OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL},
4605
{"GLOBAL_STATUS", variables_fields_info, create_schema_table,
4606
fill_status, make_old_format, 0, -1, -1, 0, 0},
4607
{"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
4608
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4609
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
4610
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
4612
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
4613
fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
4614
{"PLUGINS", plugin_fields_info, create_schema_table,
4615
fill_plugins, make_old_format, 0, -1, -1, 0, 0},
4616
{"PROCESSLIST", processlist_fields_info, create_schema_table,
4617
fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
4618
{"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
4619
create_schema_table, get_all_tables, 0, get_referential_constraints_record,
4620
1, 9, 0, OPEN_TABLE_ONLY},
4621
{"SCHEMATA", schema_fields_info, create_schema_table,
4622
fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
4623
{"SESSION_STATUS", variables_fields_info, create_schema_table,
4624
fill_status, make_old_format, 0, -1, -1, 0, 0},
4625
{"SESSION_VARIABLES", variables_fields_info, create_schema_table,
4626
fill_variables, make_old_format, 0, -1, -1, 0, 0},
4627
{"STATISTICS", stat_fields_info, create_schema_table,
4628
get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
4629
OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
4630
{"STATUS", variables_fields_info, create_schema_table, fill_status,
4631
make_old_format, 0, -1, -1, 1, 0},
4632
{"TABLES", tables_fields_info, create_schema_table,
4633
get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
4634
OPTIMIZE_I_S_TABLE},
4635
{"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
4636
get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
4637
{"TABLE_NAMES", table_names_fields_info, create_schema_table,
4638
get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
4639
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
4640
make_old_format, 0, -1, -1, 1, 0},
4641
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
4645
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
4646
template class List_iterator_fast<char>;
4647
template class List<char>;
4650
int initialize_schema_table(st_plugin_int *plugin)
4652
ST_SCHEMA_TABLE *schema_table;
4654
if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
4655
MYF(MY_WME | MY_ZEROFILL))))
4657
/* Historical Requirement */
4658
plugin->data= schema_table; // shortcut for the future
4659
if (plugin->plugin->init)
4661
schema_table->create_table= create_schema_table;
4662
schema_table->old_format= make_old_format;
4663
schema_table->idx_field1= -1,
4664
schema_table->idx_field2= -1;
4666
/* Make the name available to the init() function. */
4667
schema_table->table_name= plugin->name.str;
4669
if (plugin->plugin->init(schema_table))
4671
sql_print_error("Plugin '%s' init function returned error.",
4676
/* Make sure the plugin name is not set inside the init() function. */
4677
schema_table->table_name= plugin->name.str;
4682
my_free(schema_table, MYF(0));
4686
int finalize_schema_table(st_plugin_int *plugin)
4688
ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
4690
if (schema_table && plugin->plugin->deinit)
4691
my_free(schema_table, MYF(0));
2102
session->make_lex_string(&db, INFORMATION_SCHEMA_NAME.c_str(),
2103
INFORMATION_SCHEMA_NAME.length(), 0);
2104
session->make_lex_string(&table, schema_table->getTableName().c_str(),
2105
schema_table->getTableName().length(), 0);
2106
if (schema_table->oldFormat(session, schema_table) || /* Handle old syntax */
2107
! sel->add_table_to_list(session, new Table_ident(db, table), 0, 0, TL_READ))
2114
} /* namespace drizzled */