Commit 36be33b0 authored by Sergey Glukhov's avatar Sergey Glukhov

Bug#48729 SELECT ... FROM INFORMATION_SCHEMA.ROUTINES causes memory to grow

Analysis showed that in case of accessing I_S table
ROUTINES we perform unnecessary allocations
with get_field() function for every processed row that
in their turn causes significant memory growth.
the fix is to avoid use of get_field().


sql/sql_show.cc:
  Functions store_schema_proc() are changed
  to avoid use of get_field() function.
parent 59b4dfcc
...@@ -4182,24 +4182,37 @@ int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -4182,24 +4182,37 @@ int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
} }
static inline void copy_field_as_string(Field *to_field, Field *from_field)
{
char buff[MAX_FIELD_WIDTH];
String tmp_str(buff, sizeof(buff), system_charset_info);
from_field->val_str(&tmp_str);
to_field->store(tmp_str.ptr(), tmp_str.length(), system_charset_info);
}
bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
const char *wild, bool full_access, const char *sp_user) const char *wild, bool full_access, const char *sp_user)
{ {
String tmp_string;
String sp_db, sp_name, definer;
MYSQL_TIME time; MYSQL_TIME time;
LEX *lex= thd->lex; LEX *lex= thd->lex;
CHARSET_INFO *cs= system_charset_info; CHARSET_INFO *cs= system_charset_info;
get_field(thd->mem_root, proc_table->field[0], &sp_db); char sp_db_buff[NAME_LEN + 1], sp_name_buff[NAME_LEN + 1],
get_field(thd->mem_root, proc_table->field[1], &sp_name); definer_buff[USERNAME_LENGTH + HOSTNAME_LENGTH + 2];
get_field(thd->mem_root, proc_table->field[11], &definer); String sp_db(sp_db_buff, sizeof(sp_db_buff), cs);
String sp_name(sp_name_buff, sizeof(sp_name_buff), cs);
String definer(definer_buff, sizeof(definer_buff), cs);
proc_table->field[0]->val_str(&sp_db);
proc_table->field[1]->val_str(&sp_name);
proc_table->field[11]->val_str(&definer);
if (!full_access) if (!full_access)
full_access= !strcmp(sp_user, definer.ptr()); full_access= !strcmp(sp_user, definer.c_ptr_safe());
if (!full_access && check_some_routine_access(thd, sp_db.ptr(), if (!full_access &&
sp_name.ptr(), check_some_routine_access(thd, sp_db.c_ptr_safe(), sp_name.c_ptr_safe(),
proc_table->field[2]-> proc_table->field[2]->val_int() ==
val_int() == TYPE_ENUM_PROCEDURE))
TYPE_ENUM_PROCEDURE))
return 0; return 0;
if ((lex->sql_command == SQLCOM_SHOW_STATUS_PROC && if ((lex->sql_command == SQLCOM_SHOW_STATUS_PROC &&
...@@ -4209,55 +4222,42 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table, ...@@ -4209,55 +4222,42 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0) (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)
{ {
restore_record(table, s->default_values); restore_record(table, s->default_values);
if (!wild || !wild[0] || !wild_compare(sp_name.ptr(), wild, 0)) if (!wild || !wild[0] || !wild_compare(sp_name.c_ptr_safe(), wild, 0))
{ {
int enum_idx= (int) proc_table->field[5]->val_int(); int enum_idx= (int) proc_table->field[5]->val_int();
table->field[3]->store(sp_name.ptr(), sp_name.length(), cs); table->field[3]->store(sp_name.ptr(), sp_name.length(), cs);
get_field(thd->mem_root, proc_table->field[3], &tmp_string); copy_field_as_string(table->field[0], proc_table->field[3]);
table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs);
table->field[2]->store(sp_db.ptr(), sp_db.length(), cs); table->field[2]->store(sp_db.ptr(), sp_db.length(), cs);
get_field(thd->mem_root, proc_table->field[2], &tmp_string); copy_field_as_string(table->field[4], proc_table->field[2]);
table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs);
if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION)
{ {
get_field(thd->mem_root, proc_table->field[9], &tmp_string); copy_field_as_string(table->field[5], proc_table->field[9]);
table->field[5]->store(tmp_string.ptr(), tmp_string.length(), cs);
table->field[5]->set_notnull(); table->field[5]->set_notnull();
} }
if (full_access) if (full_access)
{ {
get_field(thd->mem_root, proc_table->field[19], &tmp_string); copy_field_as_string(table->field[7], proc_table->field[19]);
table->field[7]->store(tmp_string.ptr(), tmp_string.length(), cs);
table->field[7]->set_notnull(); table->field[7]->set_notnull();
} }
table->field[6]->store(STRING_WITH_LEN("SQL"), cs); table->field[6]->store(STRING_WITH_LEN("SQL"), cs);
table->field[10]->store(STRING_WITH_LEN("SQL"), cs); table->field[10]->store(STRING_WITH_LEN("SQL"), cs);
get_field(thd->mem_root, proc_table->field[6], &tmp_string); copy_field_as_string(table->field[11], proc_table->field[6]);
table->field[11]->store(tmp_string.ptr(), tmp_string.length(), cs);
table->field[12]->store(sp_data_access_name[enum_idx].str, table->field[12]->store(sp_data_access_name[enum_idx].str,
sp_data_access_name[enum_idx].length , cs); sp_data_access_name[enum_idx].length , cs);
get_field(thd->mem_root, proc_table->field[7], &tmp_string); copy_field_as_string(table->field[14], proc_table->field[7]);
table->field[14]->store(tmp_string.ptr(), tmp_string.length(), cs);
bzero((char *)&time, sizeof(time)); bzero((char *)&time, sizeof(time));
((Field_timestamp *) proc_table->field[12])->get_time(&time); ((Field_timestamp *) proc_table->field[12])->get_time(&time);
table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
bzero((char *)&time, sizeof(time)); bzero((char *)&time, sizeof(time));
((Field_timestamp *) proc_table->field[13])->get_time(&time); ((Field_timestamp *) proc_table->field[13])->get_time(&time);
table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME); table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
get_field(thd->mem_root, proc_table->field[14], &tmp_string); copy_field_as_string(table->field[17], proc_table->field[14]);
table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs); copy_field_as_string(table->field[18], proc_table->field[15]);
get_field(thd->mem_root, proc_table->field[15], &tmp_string);
table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs);
table->field[19]->store(definer.ptr(), definer.length(), cs); table->field[19]->store(definer.ptr(), definer.length(), cs);
copy_field_as_string(table->field[20], proc_table->field[16]);
get_field(thd->mem_root, proc_table->field[16], &tmp_string); copy_field_as_string(table->field[21], proc_table->field[17]);
table->field[20]->store(tmp_string.ptr(), tmp_string.length(), cs); copy_field_as_string(table->field[22], proc_table->field[18]);
get_field(thd->mem_root, proc_table->field[17], &tmp_string);
table->field[21]->store(tmp_string.ptr(), tmp_string.length(), cs);
get_field(thd->mem_root, proc_table->field[18], &tmp_string);
table->field[22]->store(tmp_string.ptr(), tmp_string.length(), cs);
return schema_table_store_record(thd, table); return schema_table_store_record(thd, table);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment