summaryrefslogtreecommitdiff
path: root/sql/sql_show.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r--sql/sql_show.cc1967
1 files changed, 1544 insertions, 423 deletions
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 70bdef302df..28bedf62ea5 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -19,14 +19,17 @@
#include "mysql_priv.h"
#include "sql_select.h" // For select_describe
+#include "sql_show.h"
#include "repl_failsafe.h"
#include "sp.h"
#include "sp_head.h"
#include "sql_trigger.h"
+#include "authors.h"
+#include "event.h"
#include <my_dir.h>
-#ifdef HAVE_BERKELEY_DB
-#include "ha_berkeley.h" // For berkeley_show_logs
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+#include "ha_partition.h"
#endif
static const char *grant_names[]={
@@ -39,17 +42,39 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
grant_names, NULL};
#endif
-static int
-store_create_info(THD *thd, TABLE_LIST *table_list, String *packet);
-static int
-view_store_create_info(THD *thd, TABLE_LIST *table, String *buff);
-static bool schema_table_store_record(THD *thd, TABLE *table);
-
+static void store_key_options(THD *thd, String *packet, TABLE *table,
+ KEY *key_info);
/***************************************************************************
** List all table types supported
***************************************************************************/
+static my_bool show_handlerton(THD *thd, st_plugin_int *plugin,
+ void *arg)
+{
+ handlerton *default_type= (handlerton *) arg;
+ Protocol *protocol= thd->protocol;
+ handlerton *hton= (handlerton *) plugin->plugin->info;
+
+ if (!(hton->flags & HTON_HIDDEN))
+ {
+ protocol->prepare_for_resend();
+ protocol->store(hton->name, system_charset_info);
+ const char *option_name= show_comp_option_name[(int) hton->state];
+
+ if (hton->state == SHOW_OPTION_YES && default_type == hton)
+ option_name= "DEFAULT";
+ protocol->store(option_name, system_charset_info);
+ protocol->store(hton->comment, system_charset_info);
+ protocol->store(hton->commit ? "YES" : "NO", system_charset_info);
+ protocol->store(hton->prepare ? "YES" : "NO", system_charset_info);
+ protocol->store(hton->savepoint_set ? "YES" : "NO", system_charset_info);
+
+ return protocol->write() ? 1 : 0;
+ }
+ return 0;
+}
+
bool mysqld_show_storage_engines(THD *thd)
{
List<Item> field_list;
@@ -59,37 +84,151 @@ bool mysqld_show_storage_engines(THD *thd)
field_list.push_back(new Item_empty_string("Engine",10));
field_list.push_back(new Item_empty_string("Support",10));
field_list.push_back(new Item_empty_string("Comment",80));
+ field_list.push_back(new Item_empty_string("Transactions",3));
+ field_list.push_back(new Item_empty_string("XA",3));
+ field_list.push_back(new Item_empty_string("Savepoints",3));
if (protocol->send_fields(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
- const char *default_type_name=
- ha_get_storage_engine((enum db_type)thd->variables.table_type);
+ if (plugin_foreach(thd, show_handlerton,
+ MYSQL_STORAGE_ENGINE_PLUGIN, thd->variables.table_type))
+ DBUG_RETURN(TRUE);
+
+ send_eof(thd);
+ DBUG_RETURN(FALSE);
+}
- handlerton **types;
- for (types= sys_table_types; *types; types++)
+static int make_version_string(char *buf, int buf_length, uint version)
+{
+ return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
+}
+
+static my_bool show_plugins(THD *thd, st_plugin_int *plugin,
+ void *arg)
+{
+ TABLE *table= (TABLE*) arg;
+ struct st_mysql_plugin *plug= plugin->plugin;
+ Protocol *protocol= thd->protocol;
+ CHARSET_INFO *cs= system_charset_info;
+ char version_buf[20];
+
+ restore_record(table, s->default_values);
+
+ table->field[0]->store(plugin->name.str, plugin->name.length, cs);
+
+ table->field[1]->store(version_buf,
+ make_version_string(version_buf, sizeof(version_buf), plug->version),
+ cs);
+
+
+ switch (plugin->state)
{
- if (!((*types)->flags & HTON_HIDDEN))
- {
- protocol->prepare_for_resend();
- protocol->store((*types)->name, system_charset_info);
- const char *option_name= show_comp_option_name[(int) (*types)->state];
-
- if ((*types)->state == SHOW_OPTION_YES &&
- !my_strcasecmp(system_charset_info, default_type_name, (*types)->name))
- option_name= "DEFAULT";
- protocol->store(option_name, system_charset_info);
- protocol->store((*types)->comment, system_charset_info);
- if (protocol->write())
- DBUG_RETURN(TRUE);
- }
+ /* case PLUGIN_IS_FREED: does not happen */
+ case PLUGIN_IS_DELETED:
+ table->field[2]->store(STRING_WITH_LEN("DELETED"), cs);
+ break;
+ case PLUGIN_IS_UNINITIALIZED:
+ table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs);
+ break;
+ case PLUGIN_IS_READY:
+ table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ }
+
+ table->field[3]->store(plugin_type_names[plug->type].str,
+ plugin_type_names[plug->type].length,
+ cs);
+ table->field[4]->store(version_buf,
+ make_version_string(version_buf, sizeof(version_buf),
+ *(uint *)plug->info), cs);
+
+ if (plugin->plugin_dl)
+ {
+ table->field[5]->store(plugin->plugin_dl->dl.str,
+ plugin->plugin_dl->dl.length, cs);
+ table->field[5]->set_notnull();
+ table->field[6]->store(version_buf,
+ make_version_string(version_buf, sizeof(version_buf),
+ plugin->plugin_dl->version),
+ cs);
+ table->field[6]->set_notnull();
+ }
+ else
+ {
+ table->field[5]->set_null();
+ table->field[6]->set_null();
+ }
+
+
+ if (plug->author)
+ {
+ table->field[7]->store(plug->author, strlen(plug->author), cs);
+ table->field[7]->set_notnull();
+ }
+ else
+ table->field[7]->set_null();
+
+ if (plug->descr)
+ {
+ table->field[8]->store(plug->descr, strlen(plug->descr), cs);
+ table->field[8]->set_notnull();
+ }
+ else
+ table->field[8]->set_null();
+
+ return schema_table_store_record(thd, table);
+}
+
+
+int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+ DBUG_ENTER("fill_plugins");
+ TABLE *table= tables->table;
+
+ if (plugin_foreach(thd, show_plugins, MYSQL_ANY_PLUGIN, table))
+ DBUG_RETURN(1);
+
+ DBUG_RETURN(0);
+}
+
+
+/***************************************************************************
+** List all Authors.
+** If you can update it, you get to be in it :)
+***************************************************************************/
+
+bool mysqld_show_authors(THD *thd)
+{
+ List<Item> field_list;
+ Protocol *protocol= thd->protocol;
+ DBUG_ENTER("mysqld_show_authors");
+
+ field_list.push_back(new Item_empty_string("Name",40));
+ field_list.push_back(new Item_empty_string("Location",40));
+ field_list.push_back(new Item_empty_string("Comment",80));
+
+ if (protocol->send_fields(&field_list,
+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ DBUG_RETURN(TRUE);
+
+ show_table_authors_st *authors;
+ for (authors= show_table_authors; authors->name; authors++)
+ {
+ protocol->prepare_for_resend();
+ protocol->store(authors->name, system_charset_info);
+ protocol->store(authors->location, system_charset_info);
+ protocol->store(authors->comment, system_charset_info);
+ if (protocol->write())
+ DBUG_RETURN(TRUE);
}
send_eof(thd);
DBUG_RETURN(FALSE);
}
-
/***************************************************************************
List all privileges supported
***************************************************************************/
@@ -111,6 +250,7 @@ static struct show_privileges_st sys_privileges[]=
{"Create user", "Server Admin", "To create new users"},
{"Delete", "Tables", "To delete existing rows"},
{"Drop", "Databases,Tables", "To drop databases, tables, and views"},
+ {"Event","Server Admin","To create, alter, drop and execute events"},
{"Execute", "Functions,Procedures", "To execute stored routines"},
{"File", "File access on server", "To read and write files on the server"},
{"Grant option", "Databases,Tables,Functions,Procedures", "To give to other users those privileges you possess"},
@@ -127,6 +267,7 @@ static struct show_privileges_st sys_privileges[]=
{"Show view","Tables","To see views with SHOW CREATE VIEW"},
{"Shutdown","Server Admin", "To shut down the server"},
{"Super","Server Admin","To use KILL thread, SET GLOBAL, CHANGE MASTER, etc."},
+ {"Trigger","Tables", "To use triggers"},
{"Update", "Tables", "To update existing rows"},
{"Usage","Server Admin","No privileges - allow connect only"},
{NullS, NullS, NullS}
@@ -278,9 +419,14 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
for (i=0 ; i < (uint) dirp->number_off_files ; i++)
{
+ char uname[NAME_LEN*3+1]; /* Unencoded name */
file=dirp->dir_entry+i;
if (dir)
{ /* Return databases */
+ if ((file->name[0] == '.' &&
+ ((file->name[1] == '.' && file->name[2] == '\0') ||
+ file->name[1] == '\0')))
+ continue; /* . or .. */
#ifdef USE_SYMDIR
char *ext;
char buff[FN_REFLEN];
@@ -297,17 +443,22 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
continue;
}
#endif
- if (file->name[0] == '.' || !MY_S_ISDIR(file->mystat->st_mode) ||
- (wild && wild_compare(file->name,wild,0)))
- continue;
+ if (!MY_S_ISDIR(file->mystat->st_mode))
+ continue;
+ VOID(filename_to_tablename(file->name, uname, sizeof(uname)));
+ if (wild && wild_compare(uname, wild, 0))
+ continue;
+ file->name= uname;
}
else
{
// Return only .frm files which aren't temp files.
- if (my_strcasecmp(system_charset_info, ext=fn_ext(file->name),reg_ext) ||
+ if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) ||
is_prefix(file->name,tmp_file_prefix))
continue;
*ext=0;
+ VOID(filename_to_tablename(file->name, uname, sizeof(uname)));
+ file->name= uname;
if (wild)
{
if (lower_case_table_names)
@@ -392,7 +543,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
buffer.length(0);
if ((table_list->view ?
view_store_create_info(thd, table_list, &buffer) :
- store_create_info(thd, table_list, &buffer)))
+ store_create_info(thd, table_list, &buffer, NULL)))
DBUG_RETURN(TRUE);
List<Item> field_list;
@@ -449,12 +600,6 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
Protocol *protocol=thd->protocol;
DBUG_ENTER("mysql_show_create_db");
- if (check_db_name(dbname))
- {
- my_error(ER_WRONG_DB_NAME, MYF(0), dbname);
- DBUG_RETURN(TRUE);
- }
-
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (test_all_bits(sctx->master_access, DB_ACLS))
db_access=DB_ACLS;
@@ -465,8 +610,8 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user, sctx->host_or_ip, dbname);
- mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
- sctx->priv_user, sctx->host_or_ip, dbname);
+ general_log_print(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
+ sctx->priv_user, sctx->host_or_ip, dbname);
DBUG_RETURN(TRUE);
}
#endif
@@ -478,8 +623,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
}
else
{
- (void) sprintf(path,"%s/%s",mysql_data_home, dbname);
- length=unpack_dirname(path,path); // Convert if not unix
+ length= build_table_filename(path, sizeof(path), dbname, "", "");
found_libchar= 0;
if (length && path[length-1] == FN_LIBCHAR)
{
@@ -532,29 +676,6 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
DBUG_RETURN(FALSE);
}
-bool
-mysqld_show_logs(THD *thd)
-{
- List<Item> field_list;
- Protocol *protocol= thd->protocol;
- DBUG_ENTER("mysqld_show_logs");
-
- field_list.push_back(new Item_empty_string("File",FN_REFLEN));
- field_list.push_back(new Item_empty_string("Type",10));
- field_list.push_back(new Item_empty_string("Status",10));
-
- if (protocol->send_fields(&field_list,
- Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
- DBUG_RETURN(TRUE);
-
-#ifdef HAVE_BERKELEY_DB
- if ((have_berkeley_db == SHOW_OPTION_YES) && berkeley_show_logs(protocol))
- DBUG_RETURN(TRUE);
-#endif
-
- send_eof(thd);
- DBUG_RETURN(FALSE);
-}
/****************************************************************************
@@ -597,10 +718,10 @@ mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd)
Protocol *protocol= thd->protocol;
String *packet= protocol->storage_packet();
DBUG_ENTER("mysqld_dump_create_info");
- DBUG_PRINT("enter",("table: %s",table_list->table->s->table_name));
+ DBUG_PRINT("enter",("table: %s",table_list->table->s->table_name.str));
protocol->prepare_for_resend();
- if (store_create_info(thd, table_list, packet))
+ if (store_create_info(thd, table_list, packet, NULL))
DBUG_RETURN(-1);
if (fd < 0)
@@ -635,6 +756,7 @@ mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd)
static const char *require_quotes(const char *name, uint name_length)
{
uint length;
+ bool pure_digit= TRUE;
const char *end= name + name_length;
for (; name < end ; name++)
@@ -643,7 +765,11 @@ static const char *require_quotes(const char *name, uint name_length)
length= my_mbcharlen(system_charset_info, chr);
if (length == 1 && !system_charset_info->ident_map[chr])
return name;
+ if (length == 1 && (chr < '0' || chr > '9'))
+ pure_digit= FALSE;
}
+ if (pure_digit)
+ return name;
return 0;
}
@@ -769,11 +895,34 @@ static void append_directory(THD *thd, String *packet, const char *dir_type,
#define LIST_PROCESS_HOST_LEN 64
-static int
-store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
+/*
+ Build a CREATE TABLE statement for a table.
+
+ SYNOPSIS
+ store_create_info()
+ thd The thread
+ table_list A list containing one table to write statement
+ for.
+ packet Pointer to a string where statement will be
+ written.
+ create_info_arg Pointer to create information that can be used
+ to tailor the format of the statement. Can be
+ NULL, in which case only SQL_MODE is considered
+ when building the statement.
+
+ NOTE
+ Currently always return 0, but might return error code in the
+ future.
+
+ RETURN
+ 0 OK
+ */
+int
+store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
+ HA_CREATE_INFO *create_info_arg)
{
List<Item> field_list;
- char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], *end;
+ char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], *end, uname[NAME_LEN*3+1];
const char *alias;
String type(tmp, sizeof(tmp), system_charset_info);
Field **ptr,*field;
@@ -783,17 +932,17 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
handler *file= table->file;
TABLE_SHARE *share= table->s;
HA_CREATE_INFO create_info;
- my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
- MODE_ORACLE |
- MODE_MSSQL |
- MODE_DB2 |
- MODE_MAXDB |
- MODE_ANSI)) != 0;
- my_bool limited_mysql_mode= (thd->variables.sql_mode &
- (MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 |
- MODE_MYSQL40)) != 0;
+ bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
+ MODE_ORACLE |
+ MODE_MSSQL |
+ MODE_DB2 |
+ MODE_MAXDB |
+ MODE_ANSI)) != 0;
+ bool limited_mysql_mode= (thd->variables.sql_mode & (MODE_NO_FIELD_OPTIONS |
+ MODE_MYSQL323 |
+ MODE_MYSQL40)) != 0;
DBUG_ENTER("store_create_info");
- DBUG_PRINT("enter",("table: %s", table->s->table_name));
+ DBUG_PRINT("enter",("table: %s", table->s->table_name.str));
restore_record(table, s->default_values); // Get empty record
@@ -804,8 +953,14 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
if (table_list->schema_table)
alias= table_list->schema_table->table_name;
else
- alias= (lower_case_table_names == 2 ? table->alias :
- share->table_name);
+ {
+ if (lower_case_table_names == 2)
+ alias= table->alias;
+ else
+ {
+ alias= share->table_name.str;
+ }
+ }
append_identifier(thd, packet, alias, strlen(alias));
packet->append(STRING_WITH_LEN(" (\n"));
@@ -835,7 +990,7 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
{
if (field->charset() != share->table_charset)
{
- packet->append(STRING_WITH_LEN(" character set "));
+ packet->append(STRING_WITH_LEN(" CHARACTER SET "));
packet->append(field->charset()->csname);
}
/*
@@ -844,7 +999,7 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
*/
if (!(field->charset()->state & MY_CS_PRIMARY))
{
- packet->append(STRING_WITH_LEN(" collate "));
+ packet->append(STRING_WITH_LEN(" COLLATE "));
packet->append(field->charset()->name);
}
}
@@ -875,7 +1030,7 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
if (has_default)
{
- packet->append(STRING_WITH_LEN(" default "));
+ packet->append(STRING_WITH_LEN(" DEFAULT "));
if (has_now_default)
packet->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
else if (!field->is_null())
@@ -902,11 +1057,11 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
if (!limited_mysql_mode && table->timestamp_field == field &&
field->unireg_check != Field::TIMESTAMP_DN_FIELD)
- packet->append(STRING_WITH_LEN(" on update CURRENT_TIMESTAMP"));
+ packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
if (field->unireg_check == Field::NEXT_NUMBER &&
!(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
- packet->append(STRING_WITH_LEN(" auto_increment"));
+ packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
if (field->comment.length)
{
@@ -929,35 +1084,24 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
if (i == primary_key && !strcmp(key_info->name, primary_key_name))
{
found_primary=1;
- packet->append(STRING_WITH_LEN("PRIMARY "));
+ /*
+ No space at end, because a space will be added after where the
+ identifier would go, but that is not added for primary key.
+ */
+ packet->append(STRING_WITH_LEN("PRIMARY KEY"));
}
else if (key_info->flags & HA_NOSAME)
- packet->append(STRING_WITH_LEN("UNIQUE "));
+ packet->append(STRING_WITH_LEN("UNIQUE KEY "));
else if (key_info->flags & HA_FULLTEXT)
- packet->append(STRING_WITH_LEN("FULLTEXT "));
+ packet->append(STRING_WITH_LEN("FULLTEXT KEY "));
else if (key_info->flags & HA_SPATIAL)
- packet->append(STRING_WITH_LEN("SPATIAL "));
- packet->append(STRING_WITH_LEN("KEY "));
+ packet->append(STRING_WITH_LEN("SPATIAL KEY "));
+ else
+ packet->append(STRING_WITH_LEN("KEY "));
if (!found_primary)
append_identifier(thd, packet, key_info->name, strlen(key_info->name));
- if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
- !limited_mysql_mode && !foreign_db_mode)
- {
- if (key_info->algorithm == HA_KEY_ALG_BTREE)
- packet->append(STRING_WITH_LEN(" USING BTREE"));
-
- if (key_info->algorithm == HA_KEY_ALG_HASH)
- packet->append(STRING_WITH_LEN(" USING HASH"));
-
- // +BAR: send USING only in non-default case: non-spatial rtree
- if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
- !(key_info->flags & HA_SPATIAL))
- packet->append(STRING_WITH_LEN(" USING RTREE"));
-
- // No need to send USING FULLTEXT, it is sent as FULLTEXT KEY
- }
packet->append(STRING_WITH_LEN(" ("));
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
@@ -982,6 +1126,13 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
}
}
packet->append(')');
+ store_key_options(thd, packet, table, key_info);
+ if (key_info->parser)
+ {
+ packet->append(" WITH PARSER ", 13);
+ append_identifier(thd, packet, key_info->parser->name.str,
+ key_info->parser->name.length);
+ }
}
/*
@@ -998,11 +1149,40 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
packet->append(STRING_WITH_LEN("\n)"));
if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
{
- if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
- packet->append(STRING_WITH_LEN(" TYPE="));
+ /*
+ Get possible table space definitions and append them
+ to the CREATE TABLE statement
+ */
+
+ if ((for_str= file->get_tablespace_name(thd)))
+ {
+ packet->append(" TABLESPACE ");
+ packet->append(for_str, strlen(for_str));
+ packet->append(" STORAGE DISK");
+ my_free(for_str, MYF(0));
+ }
+
+ /*
+ IF check_create_info
+ THEN add ENGINE only if it was used when creating the table
+ */
+ if (!create_info_arg ||
+ (create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
+ {
+ if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
+ packet->append(STRING_WITH_LEN(" TYPE="));
+ else
+ packet->append(STRING_WITH_LEN(" ENGINE="));
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (table->part_info)
+ packet->append(ha_resolve_storage_engine_name(
+ table->part_info->default_engine_type));
else
- packet->append(STRING_WITH_LEN(" ENGINE="));
- packet->append(file->table_type());
+ packet->append(file->table_type());
+#else
+ packet->append(file->table_type());
+#endif
+ }
/*
Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
@@ -1027,12 +1207,20 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
!(thd->variables.sql_mode & MODE_MYSQL323) &&
!(thd->variables.sql_mode & MODE_MYSQL40))
{
- packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
- packet->append(share->table_charset->csname);
- if (!(share->table_charset->state & MY_CS_PRIMARY))
+ /*
+ IF check_create_info
+ THEN add DEFAULT CHARSET only if it was used when creating the table
+ */
+ if (!create_info_arg ||
+ (create_info_arg->used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
{
- packet->append(STRING_WITH_LEN(" COLLATE="));
- packet->append(table->s->table_charset->name);
+ packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
+ packet->append(share->table_charset->csname);
+ if (!(share->table_charset->state & MY_CS_PRIMARY))
+ {
+ packet->append(STRING_WITH_LEN(" COLLATE="));
+ packet->append(table->s->table_charset->name);
+ }
}
}
@@ -1070,6 +1258,12 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
packet->append(ha_row_type[(uint) share->row_type]);
}
+ if (table->s->key_block_size)
+ {
+ packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
+ end= longlong10_to_str(table->s->key_block_size, buff, 10);
+ packet->append(buff, (uint) (end - buff));
+ }
table->file->append_create_info(packet);
if (share->comment && share->comment[0])
{
@@ -1081,21 +1275,71 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
packet->append(STRING_WITH_LEN(" CONNECTION="));
append_unescaped(packet, share->connect_string.str, share->connect_string.length);
}
- if (file->raid_type)
- {
- uint length;
- length= my_snprintf(buff,sizeof(buff),
- " RAID_TYPE=%s RAID_CHUNKS=%d RAID_CHUNKSIZE=%ld",
- my_raid_type(file->raid_type), file->raid_chunks,
- file->raid_chunksize/RAID_BLOCK_SIZE);
- packet->append(buff, length);
- }
append_directory(thd, packet, "DATA", create_info.data_file_name);
append_directory(thd, packet, "INDEX", create_info.index_file_name);
}
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ {
+ /*
+ Partition syntax for CREATE TABLE is at the end of the syntax.
+ */
+ uint part_syntax_len;
+ char *part_syntax;
+ if (table->part_info &&
+ (!table->part_info->is_auto_partitioned) &&
+ ((part_syntax= generate_partition_syntax(table->part_info,
+ &part_syntax_len,
+ FALSE,FALSE))))
+ {
+ packet->append(part_syntax, part_syntax_len);
+ my_free(part_syntax, MYF(0));
+ }
+ }
+#endif
DBUG_RETURN(0);
}
+
+static void store_key_options(THD *thd, String *packet, TABLE *table,
+ KEY *key_info)
+{
+ bool limited_mysql_mode= (thd->variables.sql_mode &
+ (MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 |
+ MODE_MYSQL40)) != 0;
+ bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
+ MODE_ORACLE |
+ MODE_MSSQL |
+ MODE_DB2 |
+ MODE_MAXDB |
+ MODE_ANSI)) != 0;
+ char *end, buff[32];
+
+ if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
+ !limited_mysql_mode && !foreign_db_mode)
+ {
+
+ if (key_info->algorithm == HA_KEY_ALG_BTREE)
+ packet->append(STRING_WITH_LEN(" USING BTREE"));
+
+ if (key_info->algorithm == HA_KEY_ALG_HASH)
+ packet->append(STRING_WITH_LEN(" USING HASH"));
+
+ /* send USING only in non-default case: non-spatial rtree */
+ if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
+ !(key_info->flags & HA_SPATIAL))
+ packet->append(STRING_WITH_LEN(" USING RTREE"));
+
+ if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
+ table->s->key_block_size != key_info->block_size)
+ {
+ packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
+ end= longlong10_to_str(key_info->block_size, buff, 10);
+ packet->append(buff, (uint) (end - buff));
+ }
+ }
+}
+
+
void
view_store_options(THD *thd, TABLE_LIST *table, String *buff)
{
@@ -1120,7 +1364,6 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff)
buff->append(STRING_WITH_LEN("SQL SECURITY INVOKER "));
}
-
/*
Append DEFINER clause to the given buffer.
@@ -1143,7 +1386,7 @@ void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
}
-static int
+int
view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
{
my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
@@ -1345,7 +1588,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
if (thd_info->proc_info)
protocol->store(thd_info->proc_info, system_charset_info);
else
- protocol->store(command_name[thd_info->command], system_charset_info);
+ protocol->store(command_name[thd_info->command].str, system_charset_info);
if (thd_info->start_time)
protocol->store((uint32) (now - thd_info->start_time));
else
@@ -1359,46 +1602,323 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
DBUG_VOID_RETURN;
}
+int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
+{
+ TABLE *table= tables->table;
+ CHARSET_INFO *cs= system_charset_info;
+ char *user;
+ time_t now= time(0);
+ DBUG_ENTER("fill_process_list");
+
+ user= thd->security_ctx->master_access & PROCESS_ACL ?
+ NullS : thd->security_ctx->priv_user;
+
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+
+ if (!thd->killed)
+ {
+ I_List_iterator<THD> it(threads);
+ THD* tmp;
+
+ while ((tmp= it++))
+ {
+ Security_context *tmp_sctx= tmp->security_ctx;
+ struct st_my_thread_var *mysys_var;
+ const char *val;
+
+ if ((!tmp->vio_ok() && !tmp->system_thread) ||
+ (user && (!tmp_sctx->user || strcmp(tmp_sctx->user, user))))
+ continue;
+
+ restore_record(table, s->default_values);
+ /* ID */
+ table->field[0]->store((longlong) tmp->thread_id, TRUE);
+ /* USER */
+ val= tmp_sctx->user ? tmp_sctx->user :
+ (tmp->system_thread ? "system user" : "unauthenticated user");
+ table->field[1]->store(val, strlen(val), cs);
+ /* HOST */
+ if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
+ thd->security_ctx->host_or_ip[0])
+ {
+ char host[LIST_PROCESS_HOST_LEN + 1];
+ my_snprintf(host, LIST_PROCESS_HOST_LEN, "%s:%u",
+ tmp_sctx->host_or_ip, tmp->peer_port);
+ table->field[2]->store(host, strlen(host), cs);
+ }
+ else
+ table->field[2]->store(tmp_sctx->host_or_ip,
+ strlen(tmp_sctx->host_or_ip), cs);
+ /* DB */
+ if (tmp->db)
+ {
+ table->field[3]->store(tmp->db, strlen(tmp->db), cs);
+ table->field[3]->set_notnull();
+ }
+
+ if ((mysys_var= tmp->mysys_var))
+ pthread_mutex_lock(&mysys_var->mutex);
+ /* COMMAND */
+ if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
+ table->field[4]->store(val, strlen(val), cs);
+ else
+ table->field[4]->store(command_name[tmp->command].str,
+ command_name[tmp->command].length, cs);
+ /* TIME */
+ table->field[5]->store((uint32)(tmp->start_time ?
+ now - tmp->start_time : 0), TRUE);
+ /* STATE */
+#ifndef EMBEDDED_LIBRARY
+ val= (char*) (tmp->locked ? "Locked" :
+ tmp->net.reading_or_writing ?
+ (tmp->net.reading_or_writing == 2 ?
+ "Writing to net" :
+ tmp->command == COM_SLEEP ? "" :
+ "Reading from net") :
+ tmp->proc_info ? tmp->proc_info :
+ tmp->mysys_var &&
+ tmp->mysys_var->current_cond ?
+ "Waiting on cond" : NullS);
+#else
+ val= (char *) "Writing to net";
+#endif
+ if (val)
+ {
+ table->field[6]->store(val, strlen(val), cs);
+ table->field[6]->set_notnull();
+ }
+
+ if (mysys_var)
+ pthread_mutex_unlock(&mysys_var->mutex);
+
+ /* INFO */
+ if (tmp->query)
+ {
+ table->field[7]->store(tmp->query,
+ min(PROCESS_LIST_INFO_WIDTH,
+ tmp->query_length), cs);
+ table->field[7]->set_notnull();
+ }
+
+ if (schema_table_store_record(thd, table))
+ {
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ DBUG_RETURN(1);
+ }
+ }
+ }
+
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ DBUG_RETURN(0);
+}
+
/*****************************************************************************
Status functions
*****************************************************************************/
+static DYNAMIC_ARRAY all_status_vars;
+static bool status_vars_inited= 0;
+static int show_var_cmp(const void *var1, const void *var2)
+{
+ return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
+}
+
+/*
+ deletes all the SHOW_UNDEF elements from the array and calls
+ delete_dynamic() if it's completely empty.
+*/
+static void shrink_var_array(DYNAMIC_ARRAY *array)
+{
+ uint a,b;
+ SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
+
+ for (a= b= 0; b < array->elements; b++)
+ if (all[b].type != SHOW_UNDEF)
+ all[a++]= all[b];
+ if (a)
+ {
+ bzero(all+a, sizeof(SHOW_VAR)); // writing NULL-element to the end
+ array->elements= a;
+ }
+ else // array is completely empty - delete it
+ delete_dynamic(array);
+}
+
+/*
+ Adds an array of SHOW_VAR entries to the output of SHOW STATUS
+
+ SYNOPSIS
+ add_status_vars(SHOW_VAR *list)
+ list - an array of SHOW_VAR entries to add to all_status_vars
+ the last entry must be {0,0,SHOW_UNDEF}
+
+ NOTE
+ The handling of all_status_vars[] is completely internal, it's allocated
+ automatically when something is added to it, and deleted completely when
+ the last entry is removed.
+
+ As a special optimization, if add_status_vars() is called before
+ init_status_vars(), it assumes "startup mode" - neither concurrent access
+ to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
+
+ The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
+*/
+int add_status_vars(SHOW_VAR *list)
+{
+ int res= 0;
+ if (status_vars_inited)
+ pthread_mutex_lock(&LOCK_status);
+ if (!all_status_vars.buffer && // array is not allocated yet - do it now
+ my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
+ {
+ res= 1;
+ goto err;
+ }
+ while (list->name)
+ res|= insert_dynamic(&all_status_vars, (gptr)list++);
+ res|= insert_dynamic(&all_status_vars, (gptr)list); // appending NULL-element
+ all_status_vars.elements--; // but next insert_dynamic should overwite it
+ if (status_vars_inited)
+ sort_dynamic(&all_status_vars, show_var_cmp);
+err:
+ if (status_vars_inited)
+ pthread_mutex_unlock(&LOCK_status);
+ return res;
+}
+
+/*
+ Make all_status_vars[] usable for SHOW STATUS
+
+ NOTE
+ See add_status_vars(). Before init_status_vars() call, add_status_vars()
+ works in a special fast "startup" mode. Thus init_status_vars()
+ should be called as late as possible but before enabling multi-threading.
+*/
+void init_status_vars()
+{
+ status_vars_inited=1;
+ sort_dynamic(&all_status_vars, show_var_cmp);
+}
+
+/*
+ catch-all cleanup function, cleans up everything no matter what
+
+ DESCRIPTION
+ This function is not strictly required if all add_to_status/
+ remove_status_vars are properly paired, but it's a safety measure that
+ deletes everything from the all_status_vars[] even if some
+ remove_status_vars were forgotten
+*/
+void free_status_vars()
+{
+ delete_dynamic(&all_status_vars);
+}
+
+/*
+ Removes an array of SHOW_VAR entries from the output of SHOW STATUS
+
+ SYNOPSIS
+ remove_status_vars(SHOW_VAR *list)
+ list - an array of SHOW_VAR entries to remove to all_status_vars
+ the last entry must be {0,0,SHOW_UNDEF}
+
+ NOTE
+ there's lots of room for optimizing this, especially in non-sorted mode,
+ but nobody cares - it may be called only in case of failed plugin
+ initialization in the mysqld startup.
+*/
+
+void remove_status_vars(SHOW_VAR *list)
+{
+ if (status_vars_inited)
+ {
+ pthread_mutex_lock(&LOCK_status);
+ SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
+ int a= 0, b= all_status_vars.elements, c= (a+b)/2;
+
+ for (; list->name; list++)
+ {
+ int res= 0;
+ for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
+ {
+ res= show_var_cmp(list, all+c);
+ if (res < 0)
+ b= c;
+ else if (res > 0)
+ a= c;
+ else
+ break;
+ }
+ if (res == 0)
+ all[c].type= SHOW_UNDEF;
+ }
+ shrink_var_array(&all_status_vars);
+ pthread_mutex_unlock(&LOCK_status);
+ }
+ else
+ {
+ SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
+ uint i;
+ for (; list->name; list++)
+ {
+ for (i= 0; i < all_status_vars.elements; i++)
+ {
+ if (show_var_cmp(list, all+i))
+ continue;
+ all[i].type= SHOW_UNDEF;
+ break;
+ }
+ }
+ shrink_var_array(&all_status_vars);
+ }
+}
static bool show_status_array(THD *thd, const char *wild,
- show_var_st *variables,
+ SHOW_VAR *variables,
enum enum_var_type value_type,
struct system_status_var *status_var,
const char *prefix, TABLE *table)
{
- char buff[1024], *prefix_end;
+ char buff[SHOW_VAR_FUNC_BUFF_SIZE], *prefix_end;
/* the variable name should not be longer then 80 characters */
char name_buffer[80];
int len;
LEX_STRING null_lex_str;
+ SHOW_VAR tmp, *var;
DBUG_ENTER("show_status_array");
null_lex_str.str= 0; // For sys_var->value_ptr()
null_lex_str.length= 0;
prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
+ if (*prefix)
+ *prefix_end++= '_';
len=name_buffer + sizeof(name_buffer) - prefix_end;
for (; variables->name; variables++)
{
strnmov(prefix_end, variables->name, len);
name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
- SHOW_TYPE show_type=variables->type;
- if (show_type == SHOW_VARS)
+
+ /*
+ if var->type is SHOW_FUNC, call the function.
+ Repeat as necessary, if new var is again SHOW_FUNC
+ */
+ for (var=variables; var->type == SHOW_FUNC; var= &tmp)
+ ((mysql_show_var_func)(var->value))(thd, &tmp, buff);
+
+ SHOW_TYPE show_type=var->type;
+ if (show_type == SHOW_ARRAY)
{
- show_status_array(thd, wild, (show_var_st *) variables->value,
- value_type, status_var, variables->name, table);
+ show_status_array(thd, wild, (SHOW_VAR *) var->value,
+ value_type, status_var, name_buffer, table);
}
else
{
if (!(wild && wild[0] && wild_case_compare(system_charset_info,
name_buffer, wild)))
{
- char *value=variables->value;
+ char *value=var->value;
const char *pos, *end; // We assign a lot of const's
long nr;
if (show_type == SHOW_SYS)
@@ -1409,13 +1929,22 @@ static bool show_status_array(THD *thd, const char *wild,
}
pos= end= buff;
+ /*
+ note that value may be == buff. All SHOW_xxx code below
+ should still work in this case
+ */
switch (show_type) {
+ case SHOW_DOUBLE_STATUS:
+ {
+ value= ((char *) status_var + (ulong) value);
+ end= buff + sprintf(buff, "%f", *(double*) value);
+ break;
+ }
case SHOW_LONG_STATUS:
- case SHOW_LONG_CONST_STATUS:
value= ((char *) status_var + (ulong) value);
/* fall through */
case SHOW_LONG:
- case SHOW_LONG_CONST:
+ case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
end= int10_to_str(*(long*) value, buff, 10);
break;
case SHOW_LONGLONG:
@@ -1430,7 +1959,6 @@ static bool show_status_array(THD *thd, const char *wild,
case SHOW_MY_BOOL:
end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
break;
- case SHOW_INT_CONST:
case SHOW_INT:
end= int10_to_str((long) *(uint32*) value, buff, 10);
break;
@@ -1448,77 +1976,6 @@ static bool show_status_array(THD *thd, const char *wild,
end= strend(pos);
break;
}
- case SHOW_STARTTIME:
- nr= (long) (thd->query_start() - start_time);
- end= int10_to_str(nr, buff, 10);
- break;
- case SHOW_QUESTION:
- end= int10_to_str((long) thd->query_id, buff, 10);
- break;
-#ifdef HAVE_REPLICATION
- case SHOW_RPL_STATUS:
- end= strmov(buff, rpl_status_type[(int)rpl_status]);
- break;
- case SHOW_SLAVE_RUNNING:
- {
- pthread_mutex_lock(&LOCK_active_mi);
- end= strmov(buff, (active_mi && active_mi->slave_running &&
- active_mi->rli.slave_running) ? "ON" : "OFF");
- pthread_mutex_unlock(&LOCK_active_mi);
- break;
- }
- case SHOW_SLAVE_RETRIED_TRANS:
- {
- /*
- TODO: in 5.1 with multimaster, have one such counter per line in
- SHOW SLAVE STATUS, and have the sum over all lines here.
- */
- pthread_mutex_lock(&LOCK_active_mi);
- if (active_mi)
- {
- pthread_mutex_lock(&active_mi->rli.data_lock);
- end= int10_to_str(active_mi->rli.retried_trans, buff, 10);
- pthread_mutex_unlock(&active_mi->rli.data_lock);
- }
- pthread_mutex_unlock(&LOCK_active_mi);
- break;
- }
- case SHOW_SLAVE_SKIP_ERRORS:
- {
- MY_BITMAP *bitmap= (MY_BITMAP *)value;
- if (!use_slave_mask || bitmap_is_clear_all(bitmap))
- {
- end= strmov(buff, "OFF");
- }
- else if (bitmap_is_set_all(bitmap))
- {
- end= strmov(buff, "ALL");
- }
- else
- {
- /* 10 is enough assuming errors are max 4 digits */
- int i;
- for (i= 1;
- i < MAX_SLAVE_ERROR && (uint) (end-buff) < sizeof(buff)-10;
- i++)
- {
- if (bitmap_is_set(bitmap, i))
- {
- end= int10_to_str(i, (char*) end, 10);
- *(char*) end++= ',';
- }
- }
- if (end != buff)
- end--; // Remove last ','
- if (i < MAX_SLAVE_ERROR)
- end= strmov((char*) end, "..."); // Couldn't show all errors
- }
- break;
- }
-#endif /* HAVE_REPLICATION */
- case SHOW_OPENTABLES:
- end= int10_to_str((long) cached_tables(), buff, 10);
- break;
case SHOW_CHAR_PTR:
{
if (!(pos= *(char**) value))
@@ -1526,203 +1983,19 @@ static bool show_status_array(THD *thd, const char *wild,
end= strend(pos);
break;
}
- case SHOW_DOUBLE_STATUS:
- {
- value= ((char *) status_var + (ulong) value);
- end= buff + sprintf(buff, "%f", *(double*) value);
- break;
- }
-#ifdef HAVE_OPENSSL
- /* First group - functions relying on CTX */
- case SHOW_SSL_CTX_SESS_ACCEPT:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_accept(ssl_acceptor_fd->
- ssl_context)),
- buff, 10);
- break;
- case SHOW_SSL_CTX_SESS_ACCEPT_GOOD:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_accept_good(ssl_acceptor_fd->
- ssl_context)),
- buff, 10);
- break;
- case SHOW_SSL_CTX_SESS_CONNECT_GOOD:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_connect_good(ssl_acceptor_fd->
- ssl_context)),
- buff, 10);
- break;
- case SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context)),
- buff, 10);
- break;
- case SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd-> ssl_context)),
- buff, 10);
- break;
- case SHOW_SSL_CTX_SESS_CB_HITS:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_cb_hits(ssl_acceptor_fd->
- ssl_context)),
- buff, 10);
- break;
- case SHOW_SSL_CTX_SESS_HITS:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_hits(ssl_acceptor_fd->
- ssl_context)),
- buff, 10);
- break;
- case SHOW_SSL_CTX_SESS_CACHE_FULL:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_cache_full(ssl_acceptor_fd->
- ssl_context)),
- buff, 10);
- break;
- case SHOW_SSL_CTX_SESS_MISSES:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_misses(ssl_acceptor_fd->
- ssl_context)),
- buff, 10);
- break;
- case SHOW_SSL_CTX_SESS_TIMEOUTS:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context)),
- buff,10);
- break;
- case SHOW_SSL_CTX_SESS_NUMBER:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context)),
- buff,10);
- break;
- case SHOW_SSL_CTX_SESS_CONNECT:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context)),
- buff,10);
- break;
- case SHOW_SSL_CTX_SESS_GET_CACHE_SIZE:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context)),
- buff,10);
- break;
- case SHOW_SSL_CTX_GET_VERIFY_MODE:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context)),
- buff,10);
- break;
- case SHOW_SSL_CTX_GET_VERIFY_DEPTH:
- end= int10_to_str((long) (!ssl_acceptor_fd ? 0 :
- SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context)),
- buff,10);
- break;
- case SHOW_SSL_CTX_GET_SESSION_CACHE_MODE:
- if (!ssl_acceptor_fd)
- {
- pos= "NONE";
- end= pos+4;
- break;
- }
- switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
- {
- case SSL_SESS_CACHE_OFF:
- pos= "OFF";
- break;
- case SSL_SESS_CACHE_CLIENT:
- pos= "CLIENT";
- break;
- case SSL_SESS_CACHE_SERVER:
- pos= "SERVER";
- break;
- case SSL_SESS_CACHE_BOTH:
- pos= "BOTH";
- break;
- case SSL_SESS_CACHE_NO_AUTO_CLEAR:
- pos= "NO_AUTO_CLEAR";
- break;
- case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
- pos= "NO_INTERNAL_LOOKUP";
- break;
- default:
- pos= "Unknown";
- break;
- }
- end= strend(pos);
- break;
- /* First group - functions relying on SSL */
- case SHOW_SSL_GET_VERSION:
- pos= (thd->net.vio->ssl_arg ?
- SSL_get_version((SSL*) thd->net.vio->ssl_arg) : "");
- end= strend(pos);
- break;
- case SHOW_SSL_SESSION_REUSED:
- end= int10_to_str((long) (thd->net.vio->ssl_arg ?
- SSL_session_reused((SSL*) thd->net.vio->
- ssl_arg) :
- 0),
- buff, 10);
- break;
- case SHOW_SSL_GET_DEFAULT_TIMEOUT:
- end= int10_to_str((long) (thd->net.vio->ssl_arg ?
- SSL_get_default_timeout((SSL*) thd->net.vio->
- ssl_arg) :
- 0),
- buff, 10);
- break;
- case SHOW_SSL_GET_VERIFY_MODE:
- end= int10_to_str((long) (thd->net.vio->ssl_arg ?
- SSL_get_verify_mode((SSL*) thd->net.vio->
- ssl_arg):
- 0),
- buff, 10);
- break;
- case SHOW_SSL_GET_VERIFY_DEPTH:
- end= int10_to_str((long) (thd->net.vio->ssl_arg ?
- SSL_get_verify_depth((SSL*) thd->net.vio->
- ssl_arg):
- 0),
- buff, 10);
- break;
- case SHOW_SSL_GET_CIPHER:
- pos= (thd->net.vio->ssl_arg ?
- SSL_get_cipher((SSL*) thd->net.vio->ssl_arg) : "" );
- end= strend(pos);
- break;
- case SHOW_SSL_GET_CIPHER_LIST:
- if (thd->net.vio->ssl_arg)
- {
- char *to= buff;
- for (int i=0 ; i++ ;)
- {
- const char *p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i);
- if (p == NULL)
- break;
- to= strmov(to, p);
- *to++= ':';
- }
- if (to != buff)
- to--; // Remove last ':'
- end= to;
- }
- break;
-
-#endif /* HAVE_OPENSSL */
case SHOW_KEY_CACHE_LONG:
- case SHOW_KEY_CACHE_CONST_LONG:
- value= (value-(char*) &dflt_key_cache_var)+ (char*) dflt_key_cache;
+ value= (char*) dflt_key_cache + (ulong)value;
end= int10_to_str(*(long*) value, buff, 10);
break;
case SHOW_KEY_CACHE_LONGLONG:
- value= (value-(char*) &dflt_key_cache_var)+ (char*) dflt_key_cache;
+ value= (char*) dflt_key_cache + (ulong)value;
end= longlong10_to_str(*(longlong*) value, buff, 10);
break;
- case SHOW_NET_COMPRESSION:
- end= strmov(buff, thd->net.compress ? "ON" : "OFF");
- break;
- case SHOW_UNDEF: // Show never happen
- case SHOW_SYS:
- break; // Return empty string
+ case SHOW_UNDEF:
+ break; // Return empty string
+ case SHOW_SYS: // Cannot happen
default:
+ DBUG_ASSERT(0);
break;
}
restore_record(table, s->default_values);
@@ -1803,10 +2076,10 @@ typedef struct st_index_field_values
1 error
*/
-static bool schema_table_store_record(THD *thd, TABLE *table)
+bool schema_table_store_record(THD *thd, TABLE *table)
{
int error;
- if ((error= table->file->write_row(table->record[0])))
+ if ((error= table->file->ha_write_row(table->record[0])))
{
if (create_myisam_from_heap(thd, table,
table->pos_in_table_list->schema_table_param,
@@ -1827,6 +2100,7 @@ void get_index_field_values(LEX *lex, INDEX_FIELD_VALUES *index_field_values)
case SQLCOM_SHOW_TABLES:
case SQLCOM_SHOW_TABLE_STATUS:
case SQLCOM_SHOW_TRIGGERS:
+ case SQLCOM_SHOW_EVENTS:
index_field_values->db_value= lex->select_lex.db;
index_field_values->table_value= wild;
break;
@@ -2081,7 +2355,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
Security_context *sctx= thd->security_ctx;
uint derived_tables= lex->derived_tables;
int error= 1;
- db_type not_used;
+ enum legacy_db_type not_used;
Open_tables_state open_tables_state_backup;
bool save_view_prepare_mode= lex->view_prepare_mode;
lex->view_prepare_mode= TRUE;
@@ -2174,8 +2448,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
}
else
{
- strxmov(path, mysql_data_home, "/", base_name, NullS);
- end= path + (len= unpack_dirname(path,path));
+ len= build_table_filename(path, sizeof(path), base_name, "", "");
+ end= path + len;
len= FN_LEN - len;
if (mysql_find_files(thd, &files, base_name,
path, idx_field_vals.table_value, 0))
@@ -2323,8 +2597,7 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond)
(grant_option && !check_grant_db(thd, file_name)))
#endif
{
- strxmov(path, mysql_data_home, "/", file_name, NullS);
- length=unpack_dirname(path,path); // Convert if not unix
+ length= build_table_filename(path, sizeof(path), file_name, "", "");
found_libchar= 0;
if (length && path[length-1] == FN_LIBCHAR)
{
@@ -2504,15 +2777,12 @@ static int get_schema_tables_record(THD *thd, struct st_table_list *tables,
ptr=strxmov(ptr, " row_format=",
ha_row_type[(uint) share->row_type],
NullS);
- if (file->raid_type)
- {
- char buff[100];
- my_snprintf(buff,sizeof(buff),
- " raid_type=%s raid_chunks=%d raid_chunksize=%ld",
- my_raid_type(file->raid_type), file->raid_chunks,
- file->raid_chunksize/RAID_BLOCK_SIZE);
- ptr=strmov(ptr,buff);
- }
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (show_table->s->db_type == &partition_hton &&
+ show_table->part_info != NULL &&
+ show_table->part_info->no_parts > 0)
+ ptr= strmov(ptr, " partitioned");
+#endif
table->field[19]->store(option_buff+1,
(ptr == option_buff ? 0 :
(uint) (ptr-option_buff)-1), cs);
@@ -2762,6 +3032,7 @@ int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
CHARSET_INFO *tmp_cs= cs[0];
if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
(tmp_cs->state & MY_CS_AVAILABLE) &&
+ !(tmp_cs->state & MY_CS_HIDDEN) &&
!(wild && wild[0] &&
wild_case_compare(scs, tmp_cs->csname,wild)))
{
@@ -2780,6 +3051,49 @@ int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
}
+static my_bool iter_schema_engines(THD *thd, st_plugin_int *plugin,
+ void *ptable)
+{
+ TABLE *table= (TABLE *) ptable;
+ handlerton *hton= (handlerton *) plugin->plugin->info;
+ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
+ CHARSET_INFO *scs= system_charset_info;
+ DBUG_ENTER("iter_schema_engines");
+
+ if (!(hton->flags & HTON_HIDDEN))
+ {
+ if (!(wild && wild[0] &&
+ wild_case_compare(scs, hton->name,wild)))
+ {
+ const char *tmp;
+ restore_record(table, s->default_values);
+
+ table->field[0]->store(hton->name, strlen(hton->name), scs);
+ tmp= hton->state ? "DISABLED" : "ENABLED";
+ table->field[1]->store( tmp, strlen(tmp), scs);
+ table->field[2]->store(hton->comment, strlen(hton->comment), scs);
+ tmp= hton->commit ? "YES" : "NO";
+ table->field[3]->store( tmp, strlen(tmp), scs);
+ tmp= hton->prepare ? "YES" : "NO";
+ table->field[4]->store( tmp, strlen(tmp), scs);
+ tmp= hton->savepoint_set ? "YES" : "NO";
+ table->field[5]->store( tmp, strlen(tmp), scs);
+
+ if (schema_table_store_record(thd, table))
+ DBUG_RETURN(1);
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
+int fill_schema_engines(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+ return plugin_foreach(thd, iter_schema_engines,
+ MYSQL_STORAGE_ENGINE_PLUGIN, tables->table);
+}
+
+
int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
{
CHARSET_INFO **cs;
@@ -2791,6 +3105,7 @@ int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
CHARSET_INFO **cl;
CHARSET_INFO *tmp_cs= cs[0];
if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
+ (tmp_cs->state & MY_CS_HIDDEN) ||
!(tmp_cs->state & MY_CS_PRIMARY))
continue;
for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
@@ -2947,7 +3262,7 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
{
DBUG_RETURN(1);
}
- proc_table->file->ha_index_init(0);
+ proc_table->file->ha_index_init(0, 1);
if ((res= proc_table->file->index_first(proc_table->record[0])))
{
res= (res == HA_ERR_END_OF_FILE) ? 0 : 1;
@@ -3382,6 +3697,536 @@ static int get_schema_key_column_usage_record(THD *thd,
}
+static void collect_partition_expr(List<char> &field_list, String *str)
+{
+ List_iterator<char> part_it(field_list);
+ ulong no_fields= field_list.elements;
+ const char *field_str;
+ str->length(0);
+ while ((field_str= part_it++))
+ {
+ str->append(field_str);
+ if (--no_fields != 0)
+ str->append(",");
+ }
+ return;
+}
+
+
+static void store_schema_partitions_record(THD *thd, TABLE *table,
+ partition_element *part_elem,
+ handler *file, uint part_id)
+{
+ CHARSET_INFO *cs= system_charset_info;
+ PARTITION_INFO stat_info;
+ TIME time;
+ file->get_dynamic_partition_info(&stat_info, part_id);
+ table->field[12]->store((longlong) stat_info.records, TRUE);
+ table->field[13]->store((longlong) stat_info.mean_rec_length, TRUE);
+ table->field[14]->store((longlong) stat_info.data_file_length, TRUE);
+ if (stat_info.max_data_file_length)
+ {
+ table->field[15]->store((longlong) stat_info.max_data_file_length, TRUE);
+ table->field[15]->set_notnull();
+ }
+ table->field[16]->store((longlong) stat_info.index_file_length, TRUE);
+ table->field[17]->store((longlong) stat_info.delete_length, TRUE);
+ if (stat_info.create_time)
+ {
+ thd->variables.time_zone->gmt_sec_to_TIME(&time,
+ stat_info.create_time);
+ table->field[18]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[18]->set_notnull();
+ }
+ if (stat_info.update_time)
+ {
+ thd->variables.time_zone->gmt_sec_to_TIME(&time,
+ stat_info.update_time);
+ table->field[19]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[19]->set_notnull();
+ }
+ if (stat_info.check_time)
+ {
+ thd->variables.time_zone->gmt_sec_to_TIME(&time, stat_info.check_time);
+ table->field[20]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+ table->field[20]->set_notnull();
+ }
+ if (file->table_flags() & (ulong) HA_HAS_CHECKSUM)
+ {
+ table->field[21]->store((longlong) stat_info.check_sum, TRUE);
+ table->field[21]->set_notnull();
+ }
+ if (part_elem)
+ {
+ if (part_elem->part_comment)
+ table->field[22]->store(part_elem->part_comment,
+ strlen(part_elem->part_comment), cs);
+ else
+ table->field[22]->store(STRING_WITH_LEN("default"), cs);
+ if (part_elem->nodegroup_id != UNDEF_NODEGROUP)
+ table->field[23]->store((longlong) part_elem->nodegroup_id, TRUE);
+ else
+ table->field[23]->store(STRING_WITH_LEN("default"), cs);
+ if (part_elem->tablespace_name)
+ table->field[24]->store(part_elem->tablespace_name,
+ strlen(part_elem->tablespace_name), cs);
+ else
+ table->field[24]->store(STRING_WITH_LEN("default"), cs);
+ }
+ return;
+}
+
+
+static int get_schema_partitions_record(THD *thd, struct st_table_list *tables,
+ TABLE *table, bool res,
+ const char *base_name,
+ const char *file_name)
+{
+ CHARSET_INFO *cs= system_charset_info;
+ char buff[61];
+ String tmp_res(buff, sizeof(buff), cs);
+ String tmp_str;
+ TIME time;
+ TABLE *show_table= tables->table;
+ handler *file;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ partition_info *part_info;
+#endif
+ DBUG_ENTER("get_schema_partitions_record");
+
+ if (res)
+ {
+ if (!tables->view)
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ thd->net.last_errno, thd->net.last_error);
+ thd->clear_error();
+ DBUG_RETURN(0);
+ }
+ file= show_table->file;
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ part_info= show_table->part_info;
+ if (part_info)
+ {
+ partition_element *part_elem;
+ List_iterator<partition_element> part_it(part_info->partitions);
+ uint part_pos= 0, part_id= 0;
+ uint no_parts= part_info->no_parts;
+ handler *part_file;
+
+ restore_record(table, s->default_values);
+ table->field[1]->store(base_name, strlen(base_name), cs);
+ table->field[2]->store(file_name, strlen(file_name), cs);
+
+
+ /* Partition method*/
+ switch (part_info->part_type) {
+ case RANGE_PARTITION:
+ table->field[7]->store(partition_keywords[PKW_RANGE].str,
+ partition_keywords[PKW_RANGE].length, cs);
+ break;
+ case LIST_PARTITION:
+ table->field[7]->store(partition_keywords[PKW_LIST].str,
+ partition_keywords[PKW_LIST].length, cs);
+ break;
+ case HASH_PARTITION:
+ tmp_res.length(0);
+ if (part_info->linear_hash_ind)
+ tmp_res.append(partition_keywords[PKW_LINEAR].str,
+ partition_keywords[PKW_LINEAR].length);
+ if (part_info->list_of_part_fields)
+ tmp_res.append(partition_keywords[PKW_KEY].str,
+ partition_keywords[PKW_KEY].length);
+ else
+ tmp_res.append(partition_keywords[PKW_HASH].str,
+ partition_keywords[PKW_HASH].length);
+ table->field[7]->store(tmp_res.ptr(), tmp_res.length(), cs);
+ break;
+ default:
+ DBUG_ASSERT(0);
+ current_thd->fatal_error();
+ DBUG_RETURN(1);
+ }
+ table->field[7]->set_notnull();
+
+ /* Partition expression */
+ if (part_info->part_expr)
+ {
+ table->field[9]->store(part_info->part_func_string,
+ part_info->part_func_len, cs);
+ table->field[9]->set_notnull();
+ }
+ else if (part_info->list_of_part_fields)
+ {
+ collect_partition_expr(part_info->part_field_list, &tmp_str);
+ table->field[9]->store(tmp_str.ptr(), tmp_str.length(), cs);
+ table->field[9]->set_notnull();
+ }
+
+ if (part_info->is_sub_partitioned())
+ {
+ /* Subpartition method */
+ if (part_info->list_of_subpart_fields)
+ table->field[8]->store(partition_keywords[PKW_KEY].str,
+ partition_keywords[PKW_KEY].length, cs);
+ else
+ table->field[8]->store(partition_keywords[PKW_HASH].str,
+ partition_keywords[PKW_HASH].length, cs);
+ table->field[8]->set_notnull();
+
+ /* Subpartition expression */
+ if (part_info->subpart_expr)
+ {
+ table->field[10]->store(part_info->subpart_func_string,
+ part_info->subpart_func_len, cs);
+ table->field[10]->set_notnull();
+ }
+ else if (part_info->list_of_subpart_fields)
+ {
+ collect_partition_expr(part_info->subpart_field_list, &tmp_str);
+ table->field[10]->store(tmp_str.ptr(), tmp_str.length(), cs);
+ table->field[10]->set_notnull();
+ }
+ }
+
+ while ((part_elem= part_it++))
+ {
+
+
+ table->field[3]->store(part_elem->partition_name,
+ strlen(part_elem->partition_name), cs);
+ table->field[3]->set_notnull();
+ /* PARTITION_ORDINAL_POSITION */
+ table->field[5]->store((longlong) ++part_pos, TRUE);
+ table->field[5]->set_notnull();
+
+ /* Partition description */
+ if (part_info->part_type == RANGE_PARTITION)
+ {
+ if (part_elem->range_value != LONGLONG_MAX)
+ table->field[11]->store((longlong) part_elem->range_value, FALSE);
+ else
+ table->field[11]->store(partition_keywords[PKW_MAXVALUE].str,
+ partition_keywords[PKW_MAXVALUE].length, cs);
+ table->field[11]->set_notnull();
+ }
+ else if (part_info->part_type == LIST_PARTITION)
+ {
+ List_iterator<longlong> list_val_it(part_elem->list_val_list);
+ longlong *list_value;
+ uint no_items= part_elem->list_val_list.elements;
+ tmp_str.length(0);
+ tmp_res.length(0);
+ if (part_elem->has_null_value)
+ {
+ tmp_str.append("NULL");
+ if (no_items > 0)
+ tmp_str.append(",");
+ }
+ while ((list_value= list_val_it++))
+ {
+ tmp_res.set(*list_value, cs);
+ tmp_str.append(tmp_res);
+ if (--no_items != 0)
+ tmp_str.append(",");
+ };
+ table->field[11]->store(tmp_str.ptr(), tmp_str.length(), cs);
+ table->field[11]->set_notnull();
+ }
+
+ if (part_elem->subpartitions.elements)
+ {
+ List_iterator<partition_element> sub_it(part_elem->subpartitions);
+ partition_element *subpart_elem;
+ uint subpart_pos= 0;
+
+ while ((subpart_elem= sub_it++))
+ {
+ table->field[4]->store(subpart_elem->partition_name,
+ strlen(subpart_elem->partition_name), cs);
+ table->field[4]->set_notnull();
+ /* SUBPARTITION_ORDINAL_POSITION */
+ table->field[6]->store((longlong) ++subpart_pos, TRUE);
+ table->field[6]->set_notnull();
+
+ store_schema_partitions_record(thd, table, subpart_elem,
+ file, part_id);
+ part_id++;
+ if(schema_table_store_record(thd, table))
+ DBUG_RETURN(1);
+ }
+ }
+ else
+ {
+ store_schema_partitions_record(thd, table, part_elem,
+ file, part_id);
+ part_id++;
+ if(schema_table_store_record(thd, table))
+ DBUG_RETURN(1);
+ }
+ }
+ DBUG_RETURN(0);
+ }
+ else
+#endif
+ {
+ store_schema_partitions_record(thd, table, 0, file, 0);
+ if(schema_table_store_record(thd, table))
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+}
+
+
+static interval_type get_real_interval_type(interval_type i_type)
+{
+ switch (i_type) {
+ case INTERVAL_YEAR:
+ return INTERVAL_YEAR;
+
+ case INTERVAL_QUARTER:
+ case INTERVAL_YEAR_MONTH:
+ case INTERVAL_MONTH:
+ return INTERVAL_MONTH;
+
+ case INTERVAL_WEEK:
+ case INTERVAL_DAY:
+ return INTERVAL_DAY;
+
+ case INTERVAL_DAY_HOUR:
+ case INTERVAL_HOUR:
+ return INTERVAL_HOUR;
+
+ case INTERVAL_DAY_MINUTE:
+ case INTERVAL_HOUR_MINUTE:
+ case INTERVAL_MINUTE:
+ return INTERVAL_MINUTE;
+
+ case INTERVAL_DAY_SECOND:
+ case INTERVAL_HOUR_SECOND:
+ case INTERVAL_MINUTE_SECOND:
+ case INTERVAL_SECOND:
+ return INTERVAL_SECOND;
+
+ case INTERVAL_DAY_MICROSECOND:
+ case INTERVAL_HOUR_MICROSECOND:
+ case INTERVAL_MINUTE_MICROSECOND:
+ case INTERVAL_SECOND_MICROSECOND:
+ case INTERVAL_MICROSECOND:
+ return INTERVAL_MICROSECOND;
+ }
+ DBUG_ASSERT(0);
+ return INTERVAL_SECOND;
+}
+
+extern LEX_STRING interval_type_to_name[];
+
+static int
+fill_events_copy_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
+{
+ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
+ CHARSET_INFO *scs= system_charset_info;
+ TIME time;
+ Event_timed et;
+ DBUG_ENTER("fill_events_copy_to_schema_tab");
+
+ restore_record(sch_table, s->default_values);
+
+ if (et.load_from_row(thd->mem_root, event_table))
+ {
+ my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0));
+ DBUG_RETURN(1);
+ }
+
+ if (!(!wild || !wild[0] || !wild_compare(et.name.str, wild, 0)))
+ DBUG_RETURN(0);
+
+ /* ->field[0] is EVENT_CATALOG and is by default NULL */
+
+ sch_table->field[1]->store(et.dbname.str, et.dbname.length, scs);
+ sch_table->field[2]->store(et.name.str, et.name.length, scs);
+ sch_table->field[3]->store(et.definer.str, et.definer.length, scs);
+ sch_table->field[4]->store(et.body.str, et.body.length, scs);
+
+ /* [9] is SQL_MODE */
+ {
+ byte *sql_mode_str;
+ ulong sql_mode_len=0;
+ sql_mode_str=
+ sys_var_thd_sql_mode::symbolic_mode_representation(thd, et.sql_mode,
+ &sql_mode_len);
+ sch_table->field[9]->store((const char*)sql_mode_str, sql_mode_len, scs);
+ }
+
+ if (et.expression)
+ {
+ String show_str;
+ /* type */
+ sch_table->field[5]->store(STRING_WITH_LEN("RECURRING"), scs);
+
+ if (event_reconstruct_interval_expression(&show_str, et.interval,
+ et.expression))
+ DBUG_RETURN(1);
+
+ sch_table->field[7]->set_notnull();
+ sch_table->field[7]->store(show_str.c_ptr(), show_str.length(), scs);
+
+ LEX_STRING *ival= &interval_type_to_name[et.interval];
+ sch_table->field[8]->set_notnull();
+ sch_table->field[8]->store(ival->str, ival->length, scs);
+
+ //starts & ends
+ sch_table->field[10]->set_notnull();
+ sch_table->field[10]->store_time(&et.starts, MYSQL_TIMESTAMP_DATETIME);
+
+ if (!et.ends_null)
+ {
+ sch_table->field[11]->set_notnull();
+ sch_table->field[11]->store_time(&et.ends, MYSQL_TIMESTAMP_DATETIME);
+ }
+ }
+ else
+ {
+ //type
+ sch_table->field[5]->store(STRING_WITH_LEN("ONE TIME"), scs);
+
+ sch_table->field[6]->set_notnull();
+ sch_table->field[6]->store_time(&et.execute_at, MYSQL_TIMESTAMP_DATETIME);
+ }
+
+ //status
+ if (et.status == MYSQL_EVENT_ENABLED)
+ sch_table->field[12]->store(STRING_WITH_LEN("ENABLED"), scs);
+ else
+ sch_table->field[12]->store(STRING_WITH_LEN("DISABLED"), scs);
+
+ //on_completion
+ if (et.on_completion == MYSQL_EVENT_ON_COMPLETION_DROP)
+ sch_table->field[13]->store(STRING_WITH_LEN("NOT PRESERVE"), scs);
+ else
+ sch_table->field[13]->store(STRING_WITH_LEN("PRESERVE"), scs);
+
+ int not_used=0;
+ number_to_datetime(et.created, &time, 0, &not_used);
+ DBUG_ASSERT(not_used==0);
+ sch_table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+
+ number_to_datetime(et.modified, &time, 0, &not_used);
+ DBUG_ASSERT(not_used==0);
+ sch_table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
+
+ if (et.last_executed.year)
+ {
+ sch_table->field[16]->set_notnull();
+ sch_table->field[16]->store_time(&et.last_executed,MYSQL_TIMESTAMP_DATETIME);
+ }
+
+ sch_table->field[17]->store(et.comment.str, et.comment.length, scs);
+
+ if (schema_table_store_record(thd, sch_table))
+ DBUG_RETURN(1);
+
+ DBUG_RETURN(0);
+}
+
+
+int fill_schema_events(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+ TABLE *table= tables->table;
+ CHARSET_INFO *scs= system_charset_info;
+ TABLE *event_table= NULL;
+ Open_tables_state backup;
+ int ret=0;
+ bool verbose= false;
+ char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
+ bool use_prefix_scanning= true;
+ uint key_len= 0;
+ byte *key_buf= NULL;
+ LINT_INIT(key_buf);
+
+ DBUG_ENTER("fill_schema_events");
+
+ strxmov(definer, thd->security_ctx->priv_user,"@",thd->security_ctx->priv_host,
+ NullS);
+
+ DBUG_PRINT("info",("db=%s current_user=%s", thd->lex->select_lex.db, definer));
+
+ thd->reset_n_backup_open_tables_state(&backup);
+
+ if ((ret= evex_open_event_table(thd, TL_READ, &event_table)))
+ {
+ sql_print_error("Table mysql.event is damaged.");
+ ret= 1;
+ goto err;
+ }
+
+ event_table->file->ha_index_init(0, 1);
+
+ /*
+ see others' events only if you have PROCESS_ACL !!
+ thd->lex->verbose is set either if SHOW FULL EVENTS or
+ in case of SELECT FROM I_S.EVENTS
+ */
+ verbose= (thd->lex->verbose
+ && (thd->security_ctx->master_access & PROCESS_ACL));
+
+ if (verbose && thd->security_ctx->user)
+ {
+ ret= event_table->file->index_first(event_table->record[0]);
+ use_prefix_scanning= false;
+ }
+ else
+ {
+ event_table->field[EVEX_FIELD_DEFINER]->store(definer, strlen(definer), scs);
+ key_len= event_table->key_info->key_part[0].store_length;
+
+ if (thd->lex->select_lex.db)
+ {
+ event_table->field[EVEX_FIELD_DB]->
+ store(thd->lex->select_lex.db, strlen(thd->lex->select_lex.db), scs);
+ key_len+= event_table->key_info->key_part[1].store_length;
+ }
+ if (!(key_buf= (byte *)alloc_root(thd->mem_root, key_len)))
+ {
+ ret= 1;
+ goto err;
+ }
+
+ key_copy(key_buf, event_table->record[0], event_table->key_info, key_len);
+ ret= event_table->file->index_read(event_table->record[0], key_buf, key_len,
+ HA_READ_PREFIX);
+ }
+
+ if (ret)
+ {
+ ret= (ret == HA_ERR_END_OF_FILE || ret == HA_ERR_KEY_NOT_FOUND) ? 0 : 1;
+ goto err;
+ }
+
+ while (!ret)
+ {
+ if ((ret= fill_events_copy_to_schema_table(thd, table, event_table)))
+ goto err;
+
+ if (use_prefix_scanning)
+ ret= event_table->file->
+ index_next_same(event_table->record[0], key_buf, key_len);
+ else
+ ret= event_table->file->index_next(event_table->record[0]);
+ }
+ // ret is guaranteed to be != 0
+ ret= (ret != HA_ERR_END_OF_FILE);
+err:
+ if (event_table)
+ {
+ event_table->file->ha_index_end();
+ close_thread_tables(thd);
+ }
+
+ thd->restore_backup_open_tables_state(&backup);
+ DBUG_RETURN(ret);
+}
+
+
int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
{
DBUG_ENTER("fill_open_tables");
@@ -3414,7 +4259,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
LEX *lex= thd->lex;
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
pthread_mutex_lock(&LOCK_global_system_variables);
- res= show_status_array(thd, wild, init_vars,
+ res= show_status_array(thd, wild, init_vars,
lex->option_type, 0, "", tables->table);
pthread_mutex_unlock(&LOCK_global_system_variables);
DBUG_RETURN(res);
@@ -3428,12 +4273,13 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
int res= 0;
STATUS_VAR tmp;
- ha_update_statistics(); /* Export engines statistics */
pthread_mutex_lock(&LOCK_status);
if (lex->option_type == OPT_GLOBAL)
calc_sum_of_all_status(&tmp);
- res= show_status_array(thd, wild, status_vars, OPT_GLOBAL,
- (lex->option_type == OPT_GLOBAL ?
+ res= show_status_array(thd, wild,
+ (SHOW_VAR *)all_status_vars.buffer,
+ OPT_GLOBAL,
+ (lex->option_type == OPT_GLOBAL ?
&tmp: &thd->status_var), "",tables->table);
pthread_mutex_unlock(&LOCK_status);
DBUG_RETURN(res);
@@ -3441,6 +4287,75 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
/*
+ Fill and store records into I_S.referential_constraints table
+
+ SYNOPSIS
+ get_referential_constraints_record()
+ thd thread handle
+ tables table list struct(processed table)
+ table I_S table
+ res 1 means the error during opening of the processed table
+ 0 means processed table is opened without error
+ base_name db name
+ file_name table name
+
+ RETURN
+ 0 ok
+ # error
+*/
+
+static int
+get_referential_constraints_record(THD *thd, struct st_table_list *tables,
+ TABLE *table, bool res,
+ const char *base_name, const char *file_name)
+{
+ CHARSET_INFO *cs= system_charset_info;
+ DBUG_ENTER("get_referential_constraints_record");
+
+ if (res)
+ {
+ if (!tables->view)
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ thd->net.last_errno, thd->net.last_error);
+ thd->clear_error();
+ DBUG_RETURN(0);
+ }
+ if (!tables->view)
+ {
+ List<FOREIGN_KEY_INFO> f_key_list;
+ TABLE *show_table= tables->table;
+ show_table->file->info(HA_STATUS_VARIABLE |
+ HA_STATUS_NO_LOCK |
+ HA_STATUS_TIME);
+
+ show_table->file->get_foreign_key_list(thd, &f_key_list);
+ FOREIGN_KEY_INFO *f_key_info;
+ List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
+ while ((f_key_info= it++))
+ {
+ restore_record(table, s->default_values);
+ table->field[1]->store(base_name, strlen(base_name), cs);
+ table->field[9]->store(file_name, strlen(file_name), cs);
+ table->field[2]->store(f_key_info->forein_id->str,
+ f_key_info->forein_id->length, cs);
+ table->field[4]->store(f_key_info->referenced_db->str,
+ f_key_info->referenced_db->length, cs);
+ table->field[5]->store(f_key_info->referenced_table->str,
+ f_key_info->referenced_table->length, cs);
+ table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
+ table->field[7]->store(f_key_info->update_method->str,
+ f_key_info->update_method->length, cs);
+ table->field[8]->store(f_key_info->delete_method->str,
+ f_key_info->delete_method->length, cs);
+ if (schema_table_store_record(thd, table))
+ DBUG_RETURN(1);
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
+/*
Find schema_tables elment by name
SYNOPSIS
@@ -3765,8 +4680,8 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
table->alias_name_used= my_strcasecmp(table_alias_charset,
table_list->schema_table_name,
table_list->alias);
- table_list->table_name= (char*) table->s->table_name;
- table_list->table_name_length= strlen(table->s->table_name);
+ table_list->table_name= table->s->table_name.str;
+ table_list->table_name_length= table->s->table_name.length;
table_list->table= table;
table->next= thd->derived_tables;
thd->derived_tables= table;
@@ -3835,6 +4750,7 @@ int make_schema_select(THD *thd, SELECT_LEX *sel,
ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
LEX_STRING db, table;
DBUG_ENTER("mysql_schema_select");
+ DBUG_PRINT("enter", ("mysql_schema_select: %s", schema_table->table_name));
/*
We have to make non const db_name & table_name
because of lower_case_table_names
@@ -3913,6 +4829,38 @@ bool get_schema_tables_result(JOIN *join)
DBUG_RETURN(result);
}
+struct run_hton_fill_schema_files_args
+{
+ TABLE_LIST *tables;
+ COND *cond;
+};
+
+static my_bool run_hton_fill_schema_files(THD *thd, st_plugin_int *plugin,
+ void *arg)
+{
+ struct run_hton_fill_schema_files_args *args=
+ (run_hton_fill_schema_files_args *) arg;
+ handlerton *hton= (handlerton *) plugin->plugin->info;
+ if(hton->fill_files_table)
+ hton->fill_files_table(thd, args->tables, args->cond);
+ return false;
+}
+
+int fill_schema_files(THD *thd, TABLE_LIST *tables, COND *cond)
+{
+ int i;
+ TABLE *table= tables->table;
+ DBUG_ENTER("fill_schema_files");
+
+ struct run_hton_fill_schema_files_args args;
+ args.tables= tables;
+ args.cond= cond;
+
+ plugin_foreach(thd, run_hton_fill_schema_files,
+ MYSQL_STORAGE_ENGINE_PLUGIN, &args);
+
+ DBUG_RETURN(0);
+}
ST_FIELD_INFO schema_fields_info[]=
{
@@ -3999,6 +4947,43 @@ ST_FIELD_INFO collation_fields_info[]=
};
+ST_FIELD_INFO engines_fields_info[]=
+{
+ {"ENGINE", 64, MYSQL_TYPE_STRING, 0, 0, "Engine"},
+ {"SUPPORT", 8, MYSQL_TYPE_STRING, 0, 0, "Support"},
+ {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment"},
+ {"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 0, "Transactions"},
+ {"XA", 3, MYSQL_TYPE_STRING, 0, 0, "XA"},
+ {"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 0, "Savepoints"},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+};
+
+
+ST_FIELD_INFO events_fields_info[]=
+{
+ {"EVENT_CATALOG", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"EVENT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Db"},
+ {"EVENT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
+ {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"},
+ {"EVENT_BODY", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type"},
+ {"EXECUTE_AT", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Execute at"},
+ {"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value"},
+ {"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field"},
+ {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"STARTS", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Starts"},
+ {"ENDS", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Ends"},
+ {"STATUS", 8, MYSQL_TYPE_STRING, 0, 0, "Status"},
+ {"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
+ {"LAST_ALTERED", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
+ {"LAST_EXECUTED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
+ {"EVENT_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+};
+
+
+
ST_FIELD_INFO coll_charset_app_fields_info[]=
{
{"COLLATION_NAME", 64, MYSQL_TYPE_STRING, 0, 0, 0},
@@ -4189,6 +5174,37 @@ ST_FIELD_INFO triggers_fields_info[]=
};
+ST_FIELD_INFO partitions_fields_info[]=
+{
+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"TABLE_SCHEMA",NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"PARTITION_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"SUBPARTITION_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"PARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
+ {"SUBPARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
+ {"PARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"SUBPARTITION_METHOD", 5, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"PARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"SUBPARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"PARTITION_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
+ {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
+ {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
+ {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
+ {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
+ {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
+ {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
+ {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
+ {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, 0},
+ {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, 0},
+ {"PARTITION_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"NODEGROUP", 21 , MYSQL_TYPE_LONG, 0, 0, 0},
+ {"TABLESPACE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+};
+
+
ST_FIELD_INFO variables_fields_info[]=
{
{"Variable_name", 80, MYSQL_TYPE_STRING, 0, 0, "Variable_name"},
@@ -4197,8 +5213,98 @@ ST_FIELD_INFO variables_fields_info[]=
};
+ST_FIELD_INFO processlist_fields_info[]=
+{
+ {"ID", 4, MYSQL_TYPE_LONG, 0, 0, "Id"},
+ {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User"},
+ {"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host"},
+ {"DB", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Db"},
+ {"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command"},
+ {"TIME", 7, MYSQL_TYPE_LONG, 0, 0, "Time"},
+ {"STATE", 30, MYSQL_TYPE_STRING, 0, 1, "State"},
+ {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info"},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+};
+
+
+ST_FIELD_INFO plugin_fields_info[]=
+{
+ {"PLUGIN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Name"},
+ {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status"},
+ {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type"},
+ {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"PLUGIN_LIBRARY", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Library"},
+ {"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"PLUGIN_AUTHOR", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+};
+
+ST_FIELD_INFO files_fields_info[]=
+{
+ {"FILE_ID", 4, MYSQL_TYPE_LONG, 0, 0, 0},
+ {"FILE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"TABLESPACE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"TABLE_CATALOG", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"LOGFILE_GROUP_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"LOGFILE_GROUP_NUMBER", 4, MYSQL_TYPE_LONG, 0, 0, 0},
+ {"ENGINE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"FULLTEXT_KEYS", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"DELETED_ROWS", 4, MYSQL_TYPE_LONG, 0, 0, 0},
+ {"UPDATE_COUNT", 4, MYSQL_TYPE_LONG, 0, 0, 0},
+ {"FREE_EXTENTS", 4, MYSQL_TYPE_LONG, 0, 0, 0},
+ {"TOTAL_EXTENTS", 4, MYSQL_TYPE_LONG, 0, 0, 0},
+ {"EXTENT_SIZE", 4, MYSQL_TYPE_LONG, 0, 0, 0},
+ {"INITIAL_SIZE", 8, MYSQL_TYPE_LONGLONG, 0, 0, 0},
+ {"MAXIMUM_SIZE", 8, MYSQL_TYPE_LONGLONG, 0, 0, 0},
+ {"AUTOEXTEND_SIZE", 8, MYSQL_TYPE_LONGLONG, 0, 0, 0},
+ {"CREATION_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
+ {"LAST_UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
+ {"LAST_ACCESS_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 0, 0},
+ {"RECOVER_TIME", 4, MYSQL_TYPE_LONG, 0, 0, 0},
+ {"TRANSACTION_COUNTER", 4, MYSQL_TYPE_LONG, 0, 0, 0},
+ {"VERSION", 21 , MYSQL_TYPE_LONG, 0, 1, "Version"},
+ {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format"},
+ {"TABLE_ROWS", 21 , MYSQL_TYPE_LONG, 0, 1, "Rows"},
+ {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Avg_row_length"},
+ {"DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_length"},
+ {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Max_data_length"},
+ {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, "Index_length"},
+ {"DATA_FREE", 21 , MYSQL_TYPE_LONG, 0, 1, "Data_free"},
+ {"CREATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Create_time"},
+ {"UPDATE_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Update_time"},
+ {"CHECK_TIME", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Check_time"},
+ {"CHECKSUM", 21 , MYSQL_TYPE_LONG, 0, 1, "Checksum"},
+ {"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"EXTRA", 255, MYSQL_TYPE_STRING, 0, 0, 0},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+};
+
+ST_FIELD_INFO referential_constraints_fields_info[]=
+{
+ {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0},
+ {"UNIQUE_CONSTRAINT_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"UNIQUE_CONSTRAINT_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"MATCH_OPTION", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"UPDATE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"DELETE_RULE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0},
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+};
+
+
/*
Description of ST_FIELD_INFO in table.h
+
+ Make sure that the order of schema_tables and enum_schema_tables are the same.
+
*/
ST_SCHEMA_TABLE schema_tables[]=
@@ -4213,10 +5319,25 @@ ST_SCHEMA_TABLE schema_tables[]=
get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0},
{"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
fill_schema_column_privileges, 0, 0, -1, -1, 0},
+ {"ENGINES", engines_fields_info, create_schema_table,
+ fill_schema_engines, make_old_format, 0, -1, -1, 0},
+ {"EVENTS", events_fields_info, create_schema_table,
+ fill_schema_events, make_old_format, 0, -1, -1, 0},
+ {"FILES", files_fields_info, create_schema_table,
+ fill_schema_files, 0, 0, -1, -1, 0},
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
fill_open_tables, make_old_format, 0, -1, -1, 1},
+ {"PARTITIONS", partitions_fields_info, create_schema_table,
+ get_all_tables, 0, get_schema_partitions_record, 1, 2, 0},
+ {"PLUGINS", plugin_fields_info, create_schema_table,
+ fill_plugins, make_old_format, 0, -1, -1, 0},
+ {"PROCESSLIST", processlist_fields_info, create_schema_table,
+ fill_schema_processlist, make_old_format, 0, -1, -1, 0},
+ {"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
+ create_schema_table, get_all_tables, 0, get_referential_constraints_record,
+ 1, 9, 0},
{"ROUTINES", proc_fields_info, create_schema_table,
fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
{"SCHEMATA", schema_fields_info, create_schema_table,