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.cc469
1 files changed, 287 insertions, 182 deletions
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 1e4723d1529..42da649e3d7 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
- Copyright (c) 2009, 2014, SkySQL Ab.
+/* Copyright (c) 2000, 2015, Oracle and/or its affiliates.
+ Copyright (c) 2009, 2015, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -106,8 +106,7 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
/* Match the values of enum ha_choice */
static const char *ha_choice_values[] = {"", "0", "1"};
-static void store_key_options(THD *thd, String *packet, TABLE *table,
- KEY *key_info);
+static void store_key_options(THD *, String *, TABLE *, KEY *);
#ifdef WITH_PARTITION_STORAGE_ENGINE
static void get_cs_converted_string_value(THD *thd,
@@ -451,14 +450,19 @@ bool mysqld_show_authors(THD *thd)
{
List<Item> field_list;
Protocol *protocol= thd->protocol;
+ MEM_ROOT *mem_root= thd->mem_root;
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",512));
+ field_list.push_back(new (mem_root) Item_empty_string(thd, "Name", 40),
+ mem_root);
+ field_list.push_back(new (mem_root) Item_empty_string(thd, "Location", 40),
+ mem_root);
+ field_list.push_back(new (mem_root) Item_empty_string(thd, "Comment", 512),
+ mem_root);
if (protocol->send_result_set_metadata(&field_list,
- Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
show_table_authors_st *authors;
@@ -485,14 +489,19 @@ bool mysqld_show_contributors(THD *thd)
{
List<Item> field_list;
Protocol *protocol= thd->protocol;
+ MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("mysqld_show_contributors");
- 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", 512));
+ field_list.push_back(new (mem_root) Item_empty_string(thd, "Name", 40),
+ mem_root);
+ field_list.push_back(new (mem_root) Item_empty_string(thd, "Location", 40),
+ mem_root);
+ field_list.push_back(new (mem_root) Item_empty_string(thd, "Comment", 512),
+ mem_root);
if (protocol->send_result_set_metadata(&field_list,
- Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
show_table_contributors_st *contributors;
@@ -562,14 +571,20 @@ bool mysqld_show_privileges(THD *thd)
{
List<Item> field_list;
Protocol *protocol= thd->protocol;
+ MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("mysqld_show_privileges");
- field_list.push_back(new Item_empty_string("Privilege",10));
- field_list.push_back(new Item_empty_string("Context",15));
- field_list.push_back(new Item_empty_string("Comment",NAME_CHAR_LEN));
+ field_list.push_back(new (mem_root) Item_empty_string(thd, "Privilege", 10),
+ mem_root);
+ field_list.push_back(new (mem_root) Item_empty_string(thd, "Context", 15),
+ mem_root);
+ field_list.push_back(new (mem_root) Item_empty_string(thd, "Comment",
+ NAME_CHAR_LEN),
+ mem_root);
if (protocol->send_result_set_metadata(&field_list,
- Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
show_privileges_st *privilege= sys_privileges;
@@ -1002,13 +1017,13 @@ public:
failed is not available at this point. The only way for us to check is by
reconstructing the actual error message and see if it's the same.
*/
- char* get_view_access_denied_message()
+ char* get_view_access_denied_message(THD *thd)
{
if (!m_view_access_denied_message_ptr)
{
m_view_access_denied_message_ptr= m_view_access_denied_message;
my_snprintf(m_view_access_denied_message, MYSQL_ERRMSG_SIZE,
- ER(ER_TABLEACCESS_DENIED_ERROR), "SHOW VIEW",
+ ER_THD(thd, ER_TABLEACCESS_DENIED_ERROR), "SHOW VIEW",
m_sctx->priv_user,
m_sctx->host_or_ip, m_top_view->get_table_name());
}
@@ -1033,7 +1048,7 @@ public:
switch (sql_errno)
{
case ER_TABLEACCESS_DENIED_ERROR:
- if (!strcmp(get_view_access_denied_message(), message))
+ if (!strcmp(get_view_access_denied_message(thd), message))
{
/* Access to top view is not granted, don't interfere. */
is_handled= FALSE;
@@ -1053,7 +1068,7 @@ public:
are missing. */
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_VIEW_INVALID,
- ER(ER_VIEW_INVALID),
+ ER_THD(thd, ER_VIEW_INVALID),
m_top_view->get_db_name(),
m_top_view->get_table_name());
is_handled= TRUE;
@@ -1092,6 +1107,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
String buffer(buff, sizeof(buff), system_charset_info);
List<Item> field_list;
bool error= TRUE;
+ MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("mysqld_show_create");
DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
table_list->table_name));
@@ -1144,24 +1160,37 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
if (table_list->view)
{
- field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
- field_list.push_back(new Item_empty_string("Create View",
- MY_MAX(buffer.length(),1024)));
- field_list.push_back(new Item_empty_string("character_set_client",
- MY_CS_NAME_SIZE));
- field_list.push_back(new Item_empty_string("collation_connection",
- MY_CS_NAME_SIZE));
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "View", NAME_CHAR_LEN),
+ mem_root);
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "Create View",
+ MY_MAX(buffer.length(),1024)),
+ mem_root);
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "character_set_client",
+ MY_CS_NAME_SIZE),
+ mem_root);
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "collation_connection",
+ MY_CS_NAME_SIZE),
+ mem_root);
}
else
{
- field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "Table", NAME_CHAR_LEN),
+ mem_root);
// 1024 is for not to confuse old clients
- field_list.push_back(new Item_empty_string("Create Table",
- MY_MAX(buffer.length(),1024)));
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "Create Table",
+ MY_MAX(buffer.length(),1024)),
+ mem_root);
}
if (protocol->send_result_set_metadata(&field_list,
- Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
goto exit;
protocol->prepare_for_resend();
@@ -1215,6 +1244,7 @@ bool mysqld_show_create_db(THD *thd, LEX_STRING *dbname,
#endif
Schema_specification_st create;
Protocol *protocol=thd->protocol;
+ MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("mysql_show_create_db");
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -1228,7 +1258,7 @@ bool mysqld_show_create_db(THD *thd, LEX_STRING *dbname,
status_var_increment(thd->status_var.access_denied_errors);
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user, sctx->host_or_ip, dbname->str);
- general_log_print(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
+ general_log_print(thd,COM_INIT_DB,ER_THD(thd, ER_DBACCESS_DENIED_ERROR),
sctx->priv_user, sctx->host_or_ip, orig_dbname->str);
DBUG_RETURN(TRUE);
}
@@ -1249,11 +1279,16 @@ bool mysqld_show_create_db(THD *thd, LEX_STRING *dbname,
load_db_opt_by_name(thd, dbname->str, &create);
}
List<Item> field_list;
- field_list.push_back(new Item_empty_string("Database",NAME_CHAR_LEN));
- field_list.push_back(new Item_empty_string("Create Database",1024));
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "Database", NAME_CHAR_LEN),
+ mem_root);
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "Create Database", 1024),
+ mem_root);
if (protocol->send_result_set_metadata(&field_list,
- Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
protocol->prepare_for_resend();
@@ -1295,6 +1330,7 @@ void
mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
{
TABLE *table;
+ MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("mysqld_list_fields");
DBUG_PRINT("enter",("table: %s",table_list->table_name));
@@ -1313,16 +1349,19 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
!wild_case_compare(system_charset_info, field->field_name,wild))
{
if (table_list->view)
- field_list.push_back(new Item_ident_for_show(field,
- table_list->view_db.str,
- table_list->view_name.str));
+ field_list.push_back(new (mem_root)
+ Item_ident_for_show(thd, field,
+ table_list->view_db.str,
+ table_list->view_name.str),
+ mem_root);
else
- field_list.push_back(new Item_field(field));
+ field_list.push_back(new (mem_root) Item_field(thd, field), mem_root);
}
}
restore_record(table, s->default_values); // Get empty record
table->use_all_columns();
- if (thd->protocol->send_result_set_metadata(&field_list, Protocol::SEND_DEFAULTS))
+ if (thd->protocol->send_result_set_metadata(&field_list,
+ Protocol::SEND_DEFAULTS))
DBUG_VOID_RETURN;
my_eof(thd);
DBUG_VOID_RETURN;
@@ -1810,35 +1849,36 @@ int show_create_table(THD *thd, TABLE_LIST *table_list, String *packet,
else
packet->append(STRING_WITH_LEN(" VIRTUAL"));
}
-
- if (flags & NOT_NULL_FLAG)
- packet->append(STRING_WITH_LEN(" NOT NULL"));
- else if (field->type() == MYSQL_TYPE_TIMESTAMP)
- {
- /*
- TIMESTAMP field require explicit NULL flag, because unlike
- all other fields they are treated as NOT NULL by default.
- */
- packet->append(STRING_WITH_LEN(" NULL"));
- }
-
- if (!field->vcol_info &&
- get_field_default_value(thd, field, &def_value, 1))
+ else
{
- packet->append(STRING_WITH_LEN(" DEFAULT "));
- packet->append(def_value.ptr(), def_value.length(), system_charset_info);
- }
+ if (flags & NOT_NULL_FLAG)
+ packet->append(STRING_WITH_LEN(" NOT NULL"));
+ else if (field->type() == MYSQL_TYPE_TIMESTAMP)
+ {
+ /*
+ TIMESTAMP field require explicit NULL flag, because unlike
+ all other fields they are treated as NOT NULL by default.
+ */
+ packet->append(STRING_WITH_LEN(" NULL"));
+ }
- if (!limited_mysql_mode && print_on_update_clause(field, &def_value, false))
- {
- packet->append(STRING_WITH_LEN(" "));
- packet->append(def_value);
- }
+ if (get_field_default_value(thd, field, &def_value, 1))
+ {
+ packet->append(STRING_WITH_LEN(" DEFAULT "));
+ packet->append(def_value.ptr(), def_value.length(), system_charset_info);
+ }
+ if (!limited_mysql_mode &&
+ print_on_update_clause(field, &def_value, false))
+ {
+ packet->append(STRING_WITH_LEN(" "));
+ packet->append(def_value);
+ }
- if (field->unireg_check == Field::NEXT_NUMBER &&
- !(sql_mode & MODE_NO_FIELD_OPTIONS))
- packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
+ if (field->unireg_check == Field::NEXT_NUMBER &&
+ !(sql_mode & MODE_NO_FIELD_OPTIONS))
+ packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
+ }
if (field->comment.length)
{
@@ -2152,11 +2192,13 @@ static void store_key_options(THD *thd, String *packet, TABLE *table,
}
-void
-view_store_options(THD *thd, TABLE_LIST *table, String *buff)
+void view_store_options(THD *thd, TABLE_LIST *table, String *buff)
{
- buff->append(STRING_WITH_LEN("ALGORITHM="));
- buff->append(view_algorithm(table));
+ if (table->algorithm != VIEW_ALGORITHM_INHERIT)
+ {
+ buff->append(STRING_WITH_LEN("ALGORITHM="));
+ buff->append(view_algorithm(table));
+ }
buff->append(' ');
append_definer(thd, buff, &table->definer.user, &table->definer.host);
if (table->view_suid)
@@ -2166,15 +2208,8 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff)
}
-/*
- Append DEFINER clause to the given buffer.
-
- SYNOPSIS
- append_definer()
- thd [in] thread handle
- buffer [inout] buffer to hold DEFINER clause
- definer_user [in] user name part of definer
- definer_host [in] host name part of definer
+/**
+ Returns ALGORITHM clause of a view
*/
static const LEX_STRING *view_algorithm(TABLE_LIST *table)
@@ -2292,16 +2327,15 @@ static int show_create_view(THD *thd, TABLE_LIST *table, String *buff)
class thread_info :public ilink {
public:
- static void *operator new(size_t size)
- {
- return (void*) sql_alloc((uint) size);
- }
+ static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
+ { return alloc_root(mem_root, size); }
static void operator delete(void *ptr __attribute__((unused)),
size_t size __attribute__((unused)))
{ TRASH(ptr, size); }
ulong thread_id;
- time_t start_time;
+ ulong os_thread_id;
+ ulonglong start_time;
uint command;
const char *user,*host,*db,*proc_info,*state_info;
CSET_STRING query_string;
@@ -2340,28 +2374,49 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
PROCESS_LIST_WIDTH);
Protocol *protocol= thd->protocol;
+ MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("mysqld_list_processes");
- field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
- field_list.push_back(new Item_empty_string("User", USERNAME_CHAR_LENGTH));
- field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
- field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
+ field_list.push_back(new (mem_root)
+ Item_int(thd, "Id", 0, MY_INT32_NUM_DECIMAL_DIGITS),
+ mem_root);
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "User",
+ USERNAME_CHAR_LENGTH),
+ mem_root);
+ field_list.push_back(new (mem_root)
+ Item_empty_string(thd, "Host",
+ LIST_PROCESS_HOST_LEN),
+ mem_root);
+ field_list.push_back(field=new (mem_root)
+ Item_empty_string(thd, "db", NAME_CHAR_LEN),
+ mem_root);
field->maybe_null=1;
- field_list.push_back(new Item_empty_string("Command",16));
- field_list.push_back(field= new Item_return_int("Time",7, MYSQL_TYPE_LONG));
+ field_list.push_back(new (mem_root) Item_empty_string(thd, "Command", 16),
+ mem_root);
+ field_list.push_back(field= new (mem_root)
+ Item_return_int(thd, "Time", 7, MYSQL_TYPE_LONG),
+ mem_root);
field->unsigned_flag= 0;
- field_list.push_back(field=new Item_empty_string("State",30));
+ field_list.push_back(field=new (mem_root)
+ Item_empty_string(thd, "State", 30),
+ mem_root);
field->maybe_null=1;
- field_list.push_back(field=new Item_empty_string("Info",max_query_length));
+ field_list.push_back(field=new (mem_root)
+ Item_empty_string(thd, "Info", max_query_length),
+ mem_root);
field->maybe_null=1;
if (!thd->variables.old_mode &&
!(thd->variables.old_behavior & OLD_MODE_NO_PROGRESS_INFO))
{
- field_list.push_back(field= new Item_float("Progress", 0.0, 3, 7));
+ field_list.push_back(field= new (mem_root)
+ Item_float(thd, "Progress", 0.0, 3, 7),
+ mem_root);
field->maybe_null= 0;
}
if (protocol->send_result_set_metadata(&field_list,
- Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
DBUG_VOID_RETURN;
if (thd->killed)
@@ -2375,11 +2430,13 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
Security_context *tmp_sctx= tmp->security_ctx;
struct st_my_thread_var *mysys_var;
if ((tmp->vio_ok() || tmp->system_thread) &&
- (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
+ (!user || (!tmp->system_thread &&
+ tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
{
- thread_info *thd_info= new thread_info;
+ thread_info *thd_info= new (thd->mem_root) thread_info;
thd_info->thread_id=tmp->thread_id;
+ thd_info->os_thread_id=tmp->os_thread_id;
thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
(tmp->system_thread ?
"system user" : "unauthenticated user"));
@@ -2432,7 +2489,10 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
}
else
thd_info->progress= 0.0;
- thd_info->start_time= tmp->start_time;
+ thd_info->start_time= tmp->start_utime;
+ ulonglong utime_after_query_snapshot= tmp->utime_after_query;
+ if (thd_info->start_time < utime_after_query_snapshot)
+ thd_info->start_time= utime_after_query_snapshot; // COM_SLEEP
mysql_mutex_unlock(&tmp->LOCK_thd_data);
thread_infos.append(thd_info);
}
@@ -2440,7 +2500,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
mysql_mutex_unlock(&LOCK_thread_count);
thread_info *thd_info;
- time_t now= my_time(0);
+ ulonglong now= microsecond_interval_timer();
char buff[20]; // For progress
String store_buffer(buff, sizeof(buff), system_charset_info);
@@ -2455,8 +2515,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
protocol->store(thd_info->proc_info, system_charset_info);
else
protocol->store(command_name[thd_info->command].str, system_charset_info);
- if (thd_info->start_time)
- protocol->store_long ((longlong) (now - thd_info->start_time));
+ if (thd_info->start_time && now > thd_info->start_time)
+ protocol->store_long((now - thd_info->start_time) / HRTIME_RESOLUTION);
else
protocol->store_null();
protocol->store(thd_info->state_info, system_charset_info);
@@ -2530,11 +2590,11 @@ int select_result_explain_buffer::send_data(List<Item> &items)
DBUG_RETURN(MY_TEST(res));
}
-bool select_result_text_buffer::send_result_set_metadata(List<Item> &fields, uint flag)
+bool select_result_text_buffer::send_result_set_metadata(List<Item> &fields,
+ uint flag)
{
n_columns= fields.elements;
return append_row(fields, true /*send item names */);
- return send_data(fields);
}
@@ -2550,16 +2610,18 @@ int select_result_text_buffer::append_row(List<Item> &items, bool send_names)
char **row;
int column= 0;
- if (!(row= (char**) thd->alloc(sizeof(char*) * n_columns)))
+ if (!(row= (char**) thd->alloc(sizeof(char*) * n_columns)) ||
+ rows.push_back(row, thd->mem_root))
return true;
- rows.push_back(row);
while ((item= it++))
{
DBUG_ASSERT(column < n_columns);
StringBuffer<32> buf;
const char *data_ptr;
+ char *ptr;
size_t data_len;
+
if (send_names)
{
data_ptr= item->name;
@@ -2581,8 +2643,8 @@ int select_result_text_buffer::append_row(List<Item> &items, bool send_names)
}
}
- char *ptr= (char*)thd->alloc(data_len + 1);
- memcpy(ptr, data_ptr, data_len + 1);
+ if (!(ptr= (char*) thd->memdup(data_ptr, data_len + 1)))
+ return true;
row[column]= ptr;
column++;
@@ -2730,7 +2792,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
TABLE *table= tables->table;
CHARSET_INFO *cs= system_charset_info;
char *user;
- my_hrtime_t unow= my_hrtime();
+ ulonglong unow= microsecond_interval_timer();
DBUG_ENTER("fill_schema_processlist");
DEBUG_SYNC(thd,"fill_schema_processlist_after_unow");
@@ -2753,7 +2815,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
ulonglong max_counter;
if ((!tmp->vio_ok() && !tmp->system_thread) ||
- (user && (!tmp_sctx->user || strcmp(tmp_sctx->user, user))))
+ (user && (tmp->system_thread || !tmp_sctx->user ||
+ strcmp(tmp_sctx->user, user))))
continue;
restore_record(table, s->default_values);
@@ -2793,9 +2856,12 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
table->field[4]->store(command_name[tmp->get_command()].str,
command_name[tmp->get_command()].length, cs);
/* MYSQL_TIME */
- ulonglong start_utime= tmp->start_time * HRTIME_RESOLUTION + tmp->start_time_sec_part;
- ulonglong utime= start_utime && start_utime < unow.val
- ? unow.val - start_utime : 0;
+ ulonglong utime= tmp->start_utime;
+ ulonglong utime_after_query_snapshot= tmp->utime_after_query;
+ if (utime < utime_after_query_snapshot)
+ utime= utime_after_query_snapshot; // COM_SLEEP
+ utime= utime && utime < unow ? unow - utime : 0;
+
table->field[5]->store(utime / HRTIME_RESOLUTION, TRUE);
/* STATE */
if ((val= thread_state_info(tmp)))
@@ -2859,6 +2925,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
table->field[15]->set_notnull();
}
+ table->field[16]->store(tmp->os_thread_id);
+
if (schema_table_store_record(thd, table))
{
mysql_mutex_unlock(&LOCK_thread_count);
@@ -3293,7 +3361,10 @@ void calc_sum_of_all_status(STATUS_VAR *to)
/* Add to this status from existing threads */
while ((tmp= it++))
- add_to_status(to, &tmp->status_var);
+ {
+ if (!tmp->status_in_global)
+ add_to_status(to, &tmp->status_var);
+ }
mysql_mutex_unlock(&LOCK_thread_count);
DBUG_VOID_RETURN;
@@ -3519,7 +3590,7 @@ bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
}
-COND *make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
+COND *make_cond_for_info_schema(THD *thd, COND *cond, TABLE_LIST *table)
{
if (!cond)
return (COND*) 0;
@@ -3528,16 +3599,16 @@ COND *make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
{
/* Create new top level AND item */
- Item_cond_and *new_cond=new Item_cond_and;
+ Item_cond_and *new_cond=new (thd->mem_root) Item_cond_and(thd);
if (!new_cond)
return (COND*) 0;
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
Item *item;
while ((item=li++))
{
- Item *fix= make_cond_for_info_schema(item, table);
+ Item *fix= make_cond_for_info_schema(thd, item, table);
if (fix)
- new_cond->argument_list()->push_back(fix);
+ new_cond->argument_list()->push_back(fix, thd->mem_root);
}
switch (new_cond->argument_list()->elements) {
case 0:
@@ -3551,17 +3622,17 @@ COND *make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
}
else
{ // Or list
- Item_cond_or *new_cond=new Item_cond_or;
+ Item_cond_or *new_cond= new (thd->mem_root) Item_cond_or(thd);
if (!new_cond)
return (COND*) 0;
List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
Item *item;
while ((item=li++))
{
- Item *fix=make_cond_for_info_schema(item, table);
+ Item *fix=make_cond_for_info_schema(thd, item, table);
if (!fix)
return (COND*) 0;
- new_cond->argument_list()->push_back(fix);
+ new_cond->argument_list()->push_back(fix, thd->mem_root);
}
new_cond->quick_fix_field();
new_cond->top_level_item();
@@ -4353,7 +4424,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables,
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_WARN_I_S_SKIPPED_TABLE,
- ER(ER_WARN_I_S_SKIPPED_TABLE),
+ ER_THD(thd, ER_WARN_I_S_SKIPPED_TABLE),
table_list.db, table_list.table_name);
return 0;
}
@@ -5518,6 +5589,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
sp_head *sp;
stored_procedure_type routine_type;
bool free_sp_head;
+ bool error= 0;
DBUG_ENTER("store_schema_params");
bzero((char*) &tbl, sizeof(TABLE));
@@ -5568,7 +5640,8 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
&tmp_string);
table->field[15]->store(tmp_string.ptr(), tmp_string.length(), cs);
field_def= &sp->m_return_field_def;
- field= make_field(&share, (uchar*) 0, field_def->length,
+ field= make_field(&share, thd->mem_root,
+ (uchar*) 0, field_def->length,
(uchar*) "", 0, field_def->pack_flag,
field_def->sql_type, field_def->charset,
field_def->geom_type, field_def->srid, Field::NONE,
@@ -5621,7 +5694,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
&tmp_string);
table->field[15]->store(tmp_string.ptr(), tmp_string.length(), cs);
- field= make_field(&share, (uchar*) 0, field_def->length,
+ field= make_field(&share, thd->mem_root, (uchar*) 0, field_def->length,
(uchar*) "", 0, field_def->pack_flag,
field_def->sql_type, field_def->charset,
field_def->geom_type, field_def->srid, Field::NONE,
@@ -5632,17 +5705,15 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
store_column_type(table, field, cs, 6);
if (schema_table_store_record(thd, table))
{
- free_table_share(&share);
- if (free_sp_head)
- delete sp;
- DBUG_RETURN(1);
+ error= 1;
+ break;
}
}
if (free_sp_head)
delete sp;
}
free_table_share(&share);
- DBUG_RETURN(0);
+ DBUG_RETURN(error);
}
@@ -5720,7 +5791,8 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
bzero((char*) &tbl, sizeof(TABLE));
(void) build_table_filename(path, sizeof(path), "", "", "", 0);
init_tmp_table_share(thd, &share, "", 0, "", path);
- field= make_field(&share, (uchar*) 0, field_def->length,
+ field= make_field(&share, thd->mem_root, (uchar*) 0,
+ field_def->length,
(uchar*) "", 0, field_def->pack_flag,
field_def->sql_type, field_def->charset,
field_def->geom_type, field_def->srid, Field::NONE,
@@ -7049,7 +7121,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
schema_table_idx == SCH_GLOBAL_VARIABLES)
scope= OPT_GLOBAL;
- COND *partial_cond= make_cond_for_info_schema(cond, tables);
+ COND *partial_cond= make_cond_for_info_schema(thd, cond, tables);
mysql_rwlock_rdlock(&LOCK_system_variables_hash);
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, scope),
@@ -7091,7 +7163,7 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
tmp1= &thd->status_var;
}
- COND *partial_cond= make_cond_for_info_schema(cond, tables);
+ COND *partial_cond= make_cond_for_info_schema(thd, cond, tables);
// Evaluate and cache const subqueries now, before the mutex.
if (partial_cond)
partial_cond->val_int();
@@ -7304,6 +7376,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
ST_FIELD_INFO *fields_info= schema_table->fields_info;
CHARSET_INFO *cs= system_charset_info;
+ MEM_ROOT *mem_root= thd->mem_root;
DBUG_ENTER("create_schema_table");
for (; fields_info->field_name; fields_info++)
@@ -7314,43 +7387,50 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_INT24:
- if (!(item= new Item_return_int(fields_info->field_name,
- fields_info->field_length,
- fields_info->field_type,
- fields_info->value)))
+ if (!(item= new (mem_root)
+ Item_return_int(thd, fields_info->field_name,
+ fields_info->field_length,
+ fields_info->field_type,
+ fields_info->value)))
{
DBUG_RETURN(0);
}
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
break;
case MYSQL_TYPE_DATE:
- if (!(item=new Item_return_date_time(fields_info->field_name,
- strlen(fields_info->field_name),
- fields_info->field_type)))
+ if (!(item=new (mem_root)
+ Item_return_date_time(thd, fields_info->field_name,
+ strlen(fields_info->field_name),
+ fields_info->field_type)))
DBUG_RETURN(0);
break;
case MYSQL_TYPE_TIME:
- if (!(item=new Item_return_date_time(fields_info->field_name,
- strlen(fields_info->field_name),
- fields_info->field_type)))
+ if (!(item=new (mem_root)
+ Item_return_date_time(thd, fields_info->field_name,
+ strlen(fields_info->field_name),
+ fields_info->field_type)))
DBUG_RETURN(0);
break;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
- if (!(item=new Item_return_date_time(fields_info->field_name,
- strlen(fields_info->field_name),
- fields_info->field_type)))
+ if (!(item=new (mem_root)
+ Item_return_date_time(thd, fields_info->field_name,
+ strlen(fields_info->field_name),
+ fields_info->field_type)))
DBUG_RETURN(0);
break;
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
- if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
- fields_info->field_length)) == NULL)
+ if ((item= new (mem_root)
+ Item_float(thd, fields_info->field_name, 0.0,
+ NOT_FIXED_DEC,
+ fields_info->field_length)) == NULL)
DBUG_RETURN(NULL);
break;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
- if (!(item= new Item_decimal((longlong) fields_info->value, false)))
+ if (!(item= new (mem_root)
+ Item_decimal(thd, (longlong) fields_info->value, false)))
{
DBUG_RETURN(0);
}
@@ -7358,7 +7438,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
Create a type holder, as we want the type of the item to defined
the type of the object, not the value
*/
- if (!(item= new Item_type_holder(thd, item)))
+ if (!(item= new (mem_root) Item_type_holder(thd, item)))
DBUG_RETURN(0);
item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
item->decimals= fields_info->field_length%10;
@@ -7374,8 +7454,9 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
- if (!(item= new Item_blob(fields_info->field_name,
- fields_info->field_length)))
+ if (!(item= new (mem_root)
+ Item_blob(thd, fields_info->field_name,
+ fields_info->field_length)))
{
DBUG_RETURN(0);
}
@@ -7384,7 +7465,8 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
/* Don't let unimplemented types pass through. Could be a grave error. */
DBUG_ASSERT(fields_info->field_type == MYSQL_TYPE_STRING);
- if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
+ if (!(item= new (mem_root)
+ Item_empty_string(thd, "", fields_info->field_length, cs)))
{
DBUG_RETURN(0);
}
@@ -7392,7 +7474,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
strlen(fields_info->field_name), cs);
break;
}
- field_list.push_back(item);
+ field_list.push_back(item, thd->mem_root);
item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
field_count++;
}
@@ -7443,8 +7525,8 @@ static int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
{
if (field_info->old_name)
{
- Item_field *field= new Item_field(context,
- NullS, NullS, field_info->field_name);
+ Item_field *field= new (thd->mem_root)
+ Item_field(thd, context, NullS, NullS, field_info->field_name);
if (field)
{
field->set_name(field_info->old_name,
@@ -7470,7 +7552,7 @@ int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
{
ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
String buffer(tmp,sizeof(tmp), system_charset_info);
- Item_field *field= new Item_field(context,
+ Item_field *field= new (thd->mem_root) Item_field(thd, context,
NullS, NullS, field_info->field_name);
if (!field || add_item_to_list(thd, field))
return 1;
@@ -7505,7 +7587,7 @@ int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
buffer.append(lex->wild->ptr());
buffer.append(')');
}
- Item_field *field= new Item_field(context,
+ Item_field *field= new (thd->mem_root) Item_field(thd, context,
NullS, NullS, field_info->field_name);
if (add_item_to_list(thd, field))
return 1;
@@ -7514,7 +7596,7 @@ int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
{
field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
field_info= &schema_table->fields_info[3];
- field= new Item_field(context, NullS, NullS, field_info->field_name);
+ field= new (thd->mem_root) Item_field(thd, context, NullS, NullS, field_info->field_name);
if (add_item_to_list(thd, field))
return 1;
field->set_name(field_info->old_name, strlen(field_info->old_name),
@@ -7538,7 +7620,7 @@ int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
*field_num == 18 ||
*field_num == 19))
continue;
- Item_field *field= new Item_field(context,
+ Item_field *field= new (thd->mem_root) Item_field(thd, context,
NullS, NullS, field_info->field_name);
if (field)
{
@@ -7563,7 +7645,7 @@ int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
for (; *field_num >= 0; field_num++)
{
field_info= &schema_table->fields_info[*field_num];
- Item_field *field= new Item_field(context,
+ Item_field *field= new (thd->mem_root) Item_field(thd, context,
NullS, NullS, field_info->field_name);
if (field)
{
@@ -7588,7 +7670,7 @@ int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
for (; *field_num >= 0; field_num++)
{
field_info= &schema_table->fields_info[*field_num];
- Item_field *field= new Item_field(context,
+ Item_field *field= new (thd->mem_root) Item_field(thd, context,
NullS, NullS, field_info->field_name);
if (field)
{
@@ -7806,7 +7888,7 @@ static bool optimize_for_get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond
if (plan->has_db_lookup_value() && plan->has_table_lookup_value())
plan->partial_cond= 0;
else
- plan->partial_cond= make_cond_for_info_schema(cond, tables);
+ plan->partial_cond= make_cond_for_info_schema(thd, cond, tables);
end:
DBUG_RETURN(0);
@@ -7905,15 +7987,28 @@ bool get_schema_tables_result(JOIN *join,
TABLE_LIST *table_list= tab->table->pos_in_table_list;
if (table_list->schema_table && thd->fill_information_schema_tables())
{
- bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
- lex->current_select->master_unit()->item);
+ /*
+ Note, currently I_S tables are filled once per query.
+ This needs to be changed if if make_cond_for_info_schema()
+ will preserve outer fields (and thus I_S content will depend on
+ the outer subquery) - in this new case I_S tables will need to
+ be re-populated here.
+
+ And in that case, get_all_tables() might be called O(N^2) times
+ (in self-join of TABLES, for example) and it will allocate
+ table names on THD::mem_root O(N^2) times. To fix it, get_all_tables
+ needs to be fixed to use a local memroot, that is reset or destroyed
+ between get_all_tables invocations. Or fixed not to allocate
+ table names on THD::memroot if these names don't satisfy lookup_field
+ */
+ const bool is_subselect= false;
/* A value of 0 indicates a dummy implementation */
if (table_list->schema_table->fill_table == 0)
continue;
/* skip I_S optimizations specific to get_all_tables */
- if (thd->lex->describe &&
+ if (lex->describe &&
(table_list->schema_table->fill_table != get_all_tables))
continue;
@@ -7946,7 +8041,6 @@ bool get_schema_tables_result(JOIN *join,
}
else
table_list->table->file->stats.records= 0;
-
Item *cond= tab->select_cond;
if (tab->cache_select && tab->cache_select->cond)
@@ -8599,7 +8693,7 @@ ST_FIELD_INFO variables_fields_info[]=
{
{"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name",
SKIP_OPEN_TABLE},
- {"VARIABLE_VALUE", 1024, MYSQL_TYPE_STRING, 0, 0, "Value", SKIP_OPEN_TABLE},
+ {"VARIABLE_VALUE", 2048, MYSQL_TYPE_STRING, 0, 0, "Value", SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
@@ -8607,10 +8701,10 @@ ST_FIELD_INFO variables_fields_info[]=
ST_FIELD_INFO sysvars_fields_info[]=
{
{"VARIABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, 0},
- {"SESSION_VALUE", 1024, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, 0},
- {"GLOBAL_VALUE", 1024, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, 0},
+ {"SESSION_VALUE", 2048, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, 0},
+ {"GLOBAL_VALUE", 2048, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, 0},
{"GLOBAL_VALUE_ORIGIN", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, 0},
- {"DEFAULT_VALUE", 1024, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, 0},
+ {"DEFAULT_VALUE", 2048, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, 0, 0},
{"VARIABLE_SCOPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, 0},
{"VARIABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, 0},
{"VARIABLE_COMMENT", TABLE_COMMENT_MAXLEN, MYSQL_TYPE_STRING, 0, 0, 0, 0},
@@ -8648,6 +8742,7 @@ ST_FIELD_INFO processlist_fields_info[]=
{"QUERY_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
{"INFO_BINARY", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_BLOB, 0, 1,
"Info_binary", SKIP_OPEN_TABLE},
+ {"TID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Tid", SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
@@ -9087,10 +9182,8 @@ static bool show_create_trigger_impl(THD *thd,
int trigger_idx)
{
int ret_code;
-
Protocol *p= thd->protocol;
List<Item> fields;
-
LEX_STRING trg_name;
ulonglong trg_sql_mode;
LEX_STRING trg_sql_mode_str;
@@ -9098,8 +9191,8 @@ static bool show_create_trigger_impl(THD *thd,
LEX_STRING trg_client_cs_name;
LEX_STRING trg_connection_cl_name;
LEX_STRING trg_db_cl_name;
-
CHARSET_INFO *trg_client_cs;
+ MEM_ROOT *mem_root= thd->mem_root;
/*
TODO: Check privileges here. This functionality will be added by
@@ -9131,8 +9224,11 @@ static bool show_create_trigger_impl(THD *thd,
/* Send header. */
- fields.push_back(new Item_empty_string("Trigger", NAME_LEN));
- fields.push_back(new Item_empty_string("sql_mode", trg_sql_mode_str.length));
+ fields.push_back(new (mem_root) Item_empty_string(thd, "Trigger", NAME_LEN),
+ mem_root);
+ fields.push_back(new (mem_root)
+ Item_empty_string(thd, "sql_mode", trg_sql_mode_str.length),
+ mem_root);
{
/*
@@ -9141,24 +9237,33 @@ static bool show_create_trigger_impl(THD *thd,
*/
Item_empty_string *stmt_fld=
- new Item_empty_string("SQL Original Statement",
- MY_MAX(trg_sql_original_stmt.length, 1024));
+ new (mem_root) Item_empty_string(thd, "SQL Original Statement",
+ MY_MAX(trg_sql_original_stmt.length,
+ 1024));
stmt_fld->maybe_null= TRUE;
- fields.push_back(stmt_fld);
+ fields.push_back(stmt_fld, mem_root);
}
- fields.push_back(new Item_empty_string("character_set_client",
- MY_CS_NAME_SIZE));
+ fields.push_back(new (mem_root)
+ Item_empty_string(thd, "character_set_client",
+ MY_CS_NAME_SIZE),
+ mem_root);
- fields.push_back(new Item_empty_string("collation_connection",
- MY_CS_NAME_SIZE));
+ fields.push_back(new (mem_root)
+ Item_empty_string(thd, "collation_connection",
+ MY_CS_NAME_SIZE),
+ mem_root);
- fields.push_back(new Item_empty_string("Database Collation",
- MY_CS_NAME_SIZE));
+ fields.push_back(new (mem_root)
+ Item_empty_string(thd, "Database Collation",
+ MY_CS_NAME_SIZE),
+ mem_root);
- if (p->send_result_set_metadata(&fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ if (p->send_result_set_metadata(&fields,
+ Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
return TRUE;
/* Send data. */