After merge fixes

Added push_back(void *, MEM_ROOT *) to make some list-handling code easier that needs to be allocated in a different mem-root
(Before one had to change thd->mem_root ; push_back(); restore mem_root.
This commit is contained in:
monty@mysql.com 2004-11-09 03:58:44 +02:00
parent 1087186657
commit 2bba55b57f
19 changed files with 91 additions and 101 deletions

View File

@ -432,3 +432,4 @@ explain select * from t1 where a=binary 'aaa';
explain select * from t1 where a='aaa' collate latin1_bin; explain select * from t1 where a='aaa' collate latin1_bin;
# this one cannot: # this one cannot:
explain select * from t1 where a='aaa' collate latin1_german1_ci; explain select * from t1 where a='aaa' collate latin1_german1_ci;
drop table t1;

View File

@ -3514,7 +3514,7 @@ Item_func_sp::func_name() const
1 + // . 1 + // .
1 + // end of string 1 + // end of string
ALIGN_SIZE(1)); // to avoid String reallocation ALIGN_SIZE(1)); // to avoid String reallocation
String qname((char *)alloc_root(&thd->mem_root, len), len, String qname((char *)alloc_root(thd->mem_root, len), len,
system_charset_info); system_charset_info);
qname.length(0); qname.length(0);

View File

@ -313,7 +313,7 @@ Item_sum_sum_distinct::~Item_sum_sum_distinct()
Item * Item *
Item_sum_sum_distinct::copy_or_same(THD *thd) Item_sum_sum_distinct::copy_or_same(THD *thd)
{ {
return new (&thd->mem_root) Item_sum_sum_distinct(thd, this); return new (thd->mem_root) Item_sum_sum_distinct(thd, this);
} }
C_MODE_START C_MODE_START

View File

@ -1041,7 +1041,7 @@ QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param,
rowid_length= table->file->ref_length; rowid_length= table->file->ref_length;
record= head->record[0]; record= head->record[0];
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0); init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
thd_param->malloc= &alloc; thd_param->mem_root= &alloc;
} }
@ -7497,7 +7497,7 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg,
if (!parent_alloc) if (!parent_alloc)
{ {
init_sql_alloc(&alloc, join->thd->variables.range_alloc_block_size, 0); init_sql_alloc(&alloc, join->thd->variables.range_alloc_block_size, 0);
thd->mem_root= &alloc; join->thd->mem_root= &alloc;
} }
else else
bzero(&alloc, sizeof(MEM_ROOT)); // ensure that it's not used bzero(&alloc, sizeof(MEM_ROOT)); // ensure that it's not used

View File

@ -608,15 +608,13 @@ parse_quoted_escaped_string(char *ptr, char *end,
my_bool my_bool
File_parser::parse(gptr base, MEM_ROOT *mem_root, File_parser::parse(gptr base, MEM_ROOT *mem_root,
struct File_option *parameters, uint required) struct File_option *parameters, uint required)
{ {
uint first_param= 0, found= 0; uint first_param= 0, found= 0;
register char *ptr= start; register char *ptr= start;
char *eol; char *eol;
LEX_STRING *str; LEX_STRING *str;
MEM_ROOT *sql_mem;
List<LEX_STRING> *list; List<LEX_STRING> *list;
bool change_mem;
DBUG_ENTER("File_parser::parse"); DBUG_ENTER("File_parser::parse");
while (ptr < end && found < required) while (ptr < end && found < required)
@ -720,18 +718,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root,
} }
case FILE_OPTIONS_STRLIST: case FILE_OPTIONS_STRLIST:
{ {
/* list= (List<LEX_STRING>*)(base + parameter->offset);
TODO: remove play with mem_root, when List will be able
to store MEM_ROOT* pointer for list elements allocation
FIXME: we can't handle empty lists
*/
sql_mem= my_pthread_getspecific_ptr(MEM_ROOT*, THR_MALLOC);
list= (List<LEX_STRING>*)(base + parameter->offset);
if ((change_mem= (sql_mem != mem_root)))
{
change_mem= 1;
my_pthread_setspecific_ptr(THR_MALLOC, mem_root);
}
list->empty(); list->empty();
// list parsing // list parsing
@ -739,7 +726,7 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root,
{ {
if (!(str= (LEX_STRING*)alloc_root(mem_root, if (!(str= (LEX_STRING*)alloc_root(mem_root,
sizeof(LEX_STRING))) || sizeof(LEX_STRING))) ||
list->push_back(str)) list->push_back(str, mem_root))
goto list_err; goto list_err;
if(!(ptr= parse_quoted_escaped_string(ptr, end, mem_root, str))) if(!(ptr= parse_quoted_escaped_string(ptr, end, mem_root, str)))
goto list_err_w_message; goto list_err_w_message;
@ -754,20 +741,15 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root,
goto list_err_w_message; goto list_err_w_message;
} }
} }
end_of_list: end_of_list:
if (*(ptr++) != '\n') if (*(ptr++) != '\n')
goto list_err; goto list_err;
if (change_mem)
my_pthread_setspecific_ptr(THR_MALLOC, sql_mem);
break; break;
list_err_w_message: list_err_w_message:
my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
parameter->name.str, line); parameter->name.str, line);
list_err: list_err:
if (change_mem)
my_pthread_setspecific_ptr(THR_MALLOC, sql_mem);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
default: default:

View File

@ -166,7 +166,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
} }
bzero((char *)&chistics, sizeof(chistics)); bzero((char *)&chistics, sizeof(chistics));
if ((ptr= get_field(&thd->mem_root, if ((ptr= get_field(thd->mem_root,
table->field[MYSQL_PROC_FIELD_ACCESS])) == NULL) table->field[MYSQL_PROC_FIELD_ACCESS])) == NULL)
{ {
ret= SP_GET_FIELD_FAILED; ret= SP_GET_FIELD_FAILED;
@ -189,7 +189,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
chistics.daccess= SP_CONTAINS_SQL; chistics.daccess= SP_CONTAINS_SQL;
} }
if ((ptr= get_field(&thd->mem_root, if ((ptr= get_field(thd->mem_root,
table->field[MYSQL_PROC_FIELD_DETERMINISTIC])) == NULL) table->field[MYSQL_PROC_FIELD_DETERMINISTIC])) == NULL)
{ {
ret= SP_GET_FIELD_FAILED; ret= SP_GET_FIELD_FAILED;
@ -197,7 +197,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
} }
chistics.detistic= (ptr[0] == 'N' ? FALSE : TRUE); chistics.detistic= (ptr[0] == 'N' ? FALSE : TRUE);
if ((ptr= get_field(&thd->mem_root, if ((ptr= get_field(thd->mem_root,
table->field[MYSQL_PROC_FIELD_SECURITY_TYPE])) == NULL) table->field[MYSQL_PROC_FIELD_SECURITY_TYPE])) == NULL)
{ {
ret= SP_GET_FIELD_FAILED; ret= SP_GET_FIELD_FAILED;
@ -205,7 +205,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
} }
chistics.suid= (ptr[0] == 'I' ? SP_IS_NOT_SUID : SP_IS_SUID); chistics.suid= (ptr[0] == 'I' ? SP_IS_NOT_SUID : SP_IS_SUID);
if ((params= get_field(&thd->mem_root, if ((params= get_field(thd->mem_root,
table->field[MYSQL_PROC_FIELD_PARAM_LIST])) == NULL) table->field[MYSQL_PROC_FIELD_PARAM_LIST])) == NULL)
{ {
params= ""; params= "";
@ -213,14 +213,14 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
if (type == TYPE_ENUM_PROCEDURE) if (type == TYPE_ENUM_PROCEDURE)
returns= ""; returns= "";
else if ((returns= get_field(&thd->mem_root, else if ((returns= get_field(thd->mem_root,
table->field[MYSQL_PROC_FIELD_RETURNS])) == NULL) table->field[MYSQL_PROC_FIELD_RETURNS])) == NULL)
{ {
ret= SP_GET_FIELD_FAILED; ret= SP_GET_FIELD_FAILED;
goto done; goto done;
} }
if ((body= get_field(&thd->mem_root, if ((body= get_field(thd->mem_root,
table->field[MYSQL_PROC_FIELD_BODY])) == NULL) table->field[MYSQL_PROC_FIELD_BODY])) == NULL)
{ {
ret= SP_GET_FIELD_FAILED; ret= SP_GET_FIELD_FAILED;
@ -228,7 +228,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
} }
// Get additional information // Get additional information
if ((definer= get_field(&thd->mem_root, if ((definer= get_field(thd->mem_root,
table->field[MYSQL_PROC_FIELD_DEFINER])) == NULL) table->field[MYSQL_PROC_FIELD_DEFINER])) == NULL)
{ {
ret= SP_GET_FIELD_FAILED; ret= SP_GET_FIELD_FAILED;
@ -511,10 +511,10 @@ print_field_values(THD *thd, TABLE *table,
String name_string; String name_string;
struct st_used_field *used_field= used_fields; struct st_used_field *used_field= used_fields;
if (get_field(&thd->mem_root, used_field->field, &db_string)) if (get_field(thd->mem_root, used_field->field, &db_string))
db_string.set_ascii("", 0); db_string.set_ascii("", 0);
used_field+= 1; used_field+= 1;
get_field(&thd->mem_root, used_field->field, &name_string); get_field(thd->mem_root, used_field->field, &name_string);
if (!wild || !wild[0] || !wild_compare(name_string.ptr(), wild, 0)) if (!wild || !wild[0] || !wild_compare(name_string.ptr(), wild, 0))
{ {
@ -539,7 +539,7 @@ print_field_values(THD *thd, TABLE *table,
{ {
String tmp_string; String tmp_string;
get_field(&thd->mem_root, used_field->field, &tmp_string); get_field(thd->mem_root, used_field->field, &tmp_string);
protocol->store(&tmp_string); protocol->store(&tmp_string);
} }
break; break;
@ -982,7 +982,7 @@ sp_cache_functions(THD *thd, LEX *lex)
newlex->proc_table= oldlex->proc_table; // hint if mysql.oper is opened newlex->proc_table= oldlex->proc_table; // hint if mysql.oper is opened
name.m_name.str= strchr(name.m_qname.str, '.'); name.m_name.str= strchr(name.m_qname.str, '.');
name.m_db.length= name.m_name.str - name.m_qname.str; name.m_db.length= name.m_name.str - name.m_qname.str;
name.m_db.str= strmake_root(&thd->mem_root, name.m_db.str= strmake_root(thd->mem_root,
name.m_qname.str, name.m_db.length); name.m_qname.str, name.m_db.length);
name.m_name.str+= 1; name.m_name.str+= 1;
name.m_name.length= name.m_qname.length - name.m_db.length - 1; name.m_name.length= name.m_qname.length - name.m_db.length - 1;

View File

@ -190,7 +190,7 @@ void
sp_name::init_qname(THD *thd) sp_name::init_qname(THD *thd)
{ {
m_qname.length= m_db.length+m_name.length+1; m_qname.length= m_db.length+m_name.length+1;
m_qname.str= alloc_root(&thd->mem_root, m_qname.length+1); m_qname.str= thd->alloc(m_qname.length+1);
sprintf(m_qname.str, "%*s.%*s", sprintf(m_qname.str, "%*s.%*s",
m_db.length, (m_db.length ? m_db.str : ""), m_db.length, (m_db.length ? m_db.str : ""),
m_name.length, m_name.str); m_name.length, m_name.str);
@ -232,10 +232,9 @@ sp_head::operator new(size_t size)
MEM_ROOT own_root; MEM_ROOT own_root;
sp_head *sp; sp_head *sp;
bzero((char *)&own_root, sizeof(own_root));
init_alloc_root(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); init_alloc_root(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC);
sp= (sp_head *)alloc_root(&own_root, size); sp= (sp_head *) alloc_root(&own_root, size);
sp->mem_root= own_root; sp->main_mem_root= own_root;
DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root)); DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root));
DBUG_RETURN(sp); DBUG_RETURN(sp);
} }
@ -245,9 +244,10 @@ sp_head::operator delete(void *ptr, size_t size)
{ {
DBUG_ENTER("sp_head::operator delete"); DBUG_ENTER("sp_head::operator delete");
MEM_ROOT own_root; MEM_ROOT own_root;
sp_head *sp= (sp_head *)ptr; sp_head *sp= (sp_head *) ptr;
memcpy(&own_root, (const void *)&sp->mem_root, sizeof(MEM_ROOT)); /* Make a copy of main_mem_root as free_root will free the sp */
own_root= sp->main_mem_root;
DBUG_PRINT("info", ("mem_root 0x%lx moved to 0x%lx", DBUG_PRINT("info", ("mem_root 0x%lx moved to 0x%lx",
(ulong) &sp->mem_root, (ulong) &own_root)); (ulong) &sp->mem_root, (ulong) &own_root));
free_root(&own_root, MYF(0)); free_root(&own_root, MYF(0));
@ -291,7 +291,7 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
DBUG_ENTER("sp_head::init_strings"); DBUG_ENTER("sp_head::init_strings");
uint n; /* Counter for nul trimming */ uint n; /* Counter for nul trimming */
/* During parsing, we must use thd->mem_root */ /* During parsing, we must use thd->mem_root */
MEM_ROOT *root= &thd->mem_root; MEM_ROOT *root= thd->mem_root;
/* We have to copy strings to get them into the right memroot */ /* We have to copy strings to get them into the right memroot */
if (name) if (name)
@ -916,19 +916,19 @@ sp_head::set_info(char *definer, uint definerlen,
if (! p) if (! p)
p= definer; // Weird... p= definer; // Weird...
len= p-definer; len= p-definer;
m_definer_user.str= strmake_root(&mem_root, definer, len); m_definer_user.str= strmake_root(mem_root, definer, len);
m_definer_user.length= len; m_definer_user.length= len;
len= definerlen-len-1; len= definerlen-len-1;
m_definer_host.str= strmake_root(&mem_root, p+1, len); m_definer_host.str= strmake_root(mem_root, p+1, len);
m_definer_host.length= len; m_definer_host.length= len;
m_created= created; m_created= created;
m_modified= modified; m_modified= modified;
m_chistics= (st_sp_chistics *)alloc_root(&mem_root, sizeof(st_sp_chistics)); m_chistics= (st_sp_chistics *) memdup_root(mem_root, (char*) chistics,
memcpy(m_chistics, chistics, sizeof(st_sp_chistics)); sizeof(*chistics));
if (m_chistics->comment.length == 0) if (m_chistics->comment.length == 0)
m_chistics->comment.str= 0; m_chistics->comment.str= 0;
else else
m_chistics->comment.str= strmake_root(&mem_root, m_chistics->comment.str= strmake_root(mem_root,
m_chistics->comment.str, m_chistics->comment.str,
m_chistics->comment.length); m_chistics->comment.length);
m_sql_mode= sql_mode; m_sql_mode= sql_mode;
@ -939,14 +939,14 @@ sp_head::reset_thd_mem_root(THD *thd)
{ {
DBUG_ENTER("sp_head::reset_thd_mem_root"); DBUG_ENTER("sp_head::reset_thd_mem_root");
m_thd_root= thd->mem_root; m_thd_root= thd->mem_root;
thd->mem_root= mem_root; thd->mem_root= &main_mem_root;
DBUG_PRINT("info", ("mem_root 0x%lx moved to thd mem root 0x%lx", DBUG_PRINT("info", ("mem_root 0x%lx moved to thd mem root 0x%lx",
(ulong) &mem_root, (ulong) &thd->mem_root)); (ulong) &mem_root, (ulong) &thd->mem_root));
free_list= thd->free_list; // Keep the old list free_list= thd->free_list; // Keep the old list
thd->free_list= NULL; // Start a new one thd->free_list= NULL; // Start a new one
/* Copy the db, since substatements will point to it */ /* Copy the db, since substatements will point to it */
m_thd_db= thd->db; m_thd_db= thd->db;
thd->db= strmake_root(&thd->mem_root, thd->db, thd->db_length); thd->db= thd->strmake(thd->db, thd->db_length);
m_thd= thd; m_thd= thd;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }

View File

@ -231,7 +231,7 @@ public:
private: private:
MEM_ROOT m_thd_root; // Temp. store for thd's mem_root MEM_ROOT *m_thd_root; // Temp. store for thd's mem_root
THD *m_thd; // Set if we have reset mem_root THD *m_thd; // Set if we have reset mem_root
char *m_thd_db; // Original thd->db pointer char *m_thd_db; // Original thd->db pointer

View File

@ -815,7 +815,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);
if (open_unireg_entry(thd, table, db, table_name, table_name, 0, if (open_unireg_entry(thd, table, db, table_name, table_name, 0,
&thd->mem_root) || thd->mem_root) ||
!(table->table_cache_key =memdup_root(&table->mem_root,(char*) key, !(table->table_cache_key =memdup_root(&table->mem_root,(char*) key,
key_length))) key_length)))
{ {
@ -1135,7 +1135,7 @@ bool reopen_table(TABLE *table,bool locked)
safe_mutex_assert_owner(&LOCK_open); safe_mutex_assert_owner(&LOCK_open);
if (open_unireg_entry(table->in_use, &tmp, db, table_name, if (open_unireg_entry(table->in_use, &tmp, db, table_name,
table->table_name, 0, &table->in_use->mem_root)) table->table_name, 0, table->in_use->mem_root))
goto end; goto end;
free_io_cache(table); free_io_cache(table);
@ -1774,7 +1774,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
thd->current_tablenr= 0; thd->current_tablenr= 0;
/* open_ltable can be used only for BASIC TABLEs */ /* open_ltable can be used only for BASIC TABLEs */
table_list->required_type= FRMTYPE_TABLE; table_list->required_type= FRMTYPE_TABLE;
while (!(table= open_table(thd, table_list, &thd->mem_root, &refresh)) && while (!(table= open_table(thd, table_list, thd->mem_root, &refresh)) &&
refresh) refresh)
; ;
@ -2999,7 +2999,8 @@ insert_fields(THD *thd, TABLE_LIST *tables, const char *db_name,
during cleunup() this item will be put in list to replace during cleunup() this item will be put in list to replace
expression from VIEW expression from VIEW
*/ */
thd->nocheck_register_item_tree_change(it->ref(), item, &thd->mem_root); thd->nocheck_register_item_tree_change(it->ref(), item,
thd->mem_root);
} }
} }
/* All fields are used */ /* All fields are used */

View File

@ -1174,7 +1174,7 @@ public:
use new arena if we are in a prepared statements and we have not use new arena if we are in a prepared statements and we have not
already changed to use this arena. already changed to use this arena.
*/ */
if (current_arena->is_stmt_prepare() && if (!current_arena->is_conventional() &&
mem_root != &current_arena->main_mem_root) mem_root != &current_arena->main_mem_root)
{ {
set_n_backup_item_arena(current_arena, backup); set_n_backup_item_arena(current_arena, backup);

View File

@ -113,6 +113,16 @@ public:
} }
return 1; return 1;
} }
inline bool push_back(void *info, MEM_ROOT *mem_root)
{
if (((*last)=new (mem_root) list_node(info, &end_of_list)))
{
last= &(*last)->next;
elements++;
return 0;
}
return 1;
}
inline bool push_front(void *info) inline bool push_front(void *info)
{ {
list_node *node=new list_node(info,first); list_node *node=new list_node(info,first);
@ -284,6 +294,8 @@ public:
inline List() :base_list() {} inline List() :base_list() {}
inline List(const List<T> &tmp) :base_list(tmp) {} inline List(const List<T> &tmp) :base_list(tmp) {}
inline bool push_back(T *a) { return base_list::push_back(a); } inline bool push_back(T *a) { return base_list::push_back(a); }
inline bool push_back(T *a, MEM_ROOT *mem_root)
{ return base_list::push_back(a, mem_root); }
inline bool push_front(T *a) { return base_list::push_front(a); } inline bool push_front(T *a) { return base_list::push_front(a); }
inline T* head() {return (T*) base_list::head(); } inline T* head() {return (T*) base_list::head(); }
inline T** head_ref() {return (T**) base_list::head_ref(); } inline T** head_ref() {return (T**) base_list::head_ref(); }

View File

@ -1828,7 +1828,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
{ {
DBUG_PRINT("info",("Using READ_ONLY cursor")); DBUG_PRINT("info",("Using READ_ONLY cursor"));
if (!stmt->cursor && if (!stmt->cursor &&
!(stmt->cursor= new (&stmt->mem_root) Cursor())) !(stmt->cursor= new (&stmt->main_mem_root) Cursor()))
{ {
send_error(thd, ER_OUT_OF_RESOURCES); send_error(thd, ER_OUT_OF_RESOURCES);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -2013,7 +2013,12 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
/* /*
COM_FETCH handler: fetches requested amount of rows from cursor COM_FETCH handler: fetches requested amount of rows from cursor
SYNOPSIS SYNOPSIS
mysql_stmt_fetch()
thd Thread handler
packet Packet from client (with stmt_id & num_rows)
packet_length Length of packet
*/ */
void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
@ -2023,7 +2028,6 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
ulong num_rows= uint4korr(packet+=4); ulong num_rows= uint4korr(packet+=4);
Statement *stmt; Statement *stmt;
int error; int error;
DBUG_ENTER("mysql_stmt_fetch"); DBUG_ENTER("mysql_stmt_fetch");
if (!(stmt= thd->stmt_map.find(stmt_id)) || if (!(stmt= thd->stmt_map.find(stmt_id)) ||

View File

@ -1497,7 +1497,6 @@ JOIN::exec()
are fixed or do not need fix_fields, too are fixed or do not need fix_fields, too
*/ */
curr_table->select->cond->quick_fix_field(); curr_table->select->cond->quick_fix_field();
cur_tabl
} }
curr_table->select_cond= curr_table->select->cond; curr_table->select_cond= curr_table->select->cond;
curr_table->select_cond->top_level_item(); curr_table->select_cond->top_level_item();
@ -1653,9 +1652,13 @@ Cursor::init_from_thd(THD *thd)
/* /*
We need to save and reset thd->mem_root, otherwise it'll be freed We need to save and reset thd->mem_root, otherwise it'll be freed
later in mysql_parse. later in mysql_parse.
We can't just change the thd->mem_root here as we want to keep the things
that is already allocated in thd->mem_root for Cursor::fetch()
*/ */
mem_root= thd->mem_root; main_mem_root= *thd->mem_root;
init_sql_alloc(&thd->mem_root, /* Allocate new memory root for thd */
init_sql_alloc(thd->mem_root,
thd->variables.query_alloc_block_size, thd->variables.query_alloc_block_size,
thd->variables.query_prealloc_size); thd->variables.query_prealloc_size);
@ -1669,7 +1672,7 @@ Cursor::init_from_thd(THD *thd)
open_tables= thd->open_tables; open_tables= thd->open_tables;
lock= thd->lock; lock= thd->lock;
query_id= thd->query_id; query_id= thd->query_id;
free_list= thd->free_list; free_list= thd->free_list;
reset_thd(thd); reset_thd(thd);
/* /*
XXX: thd->locked_tables is not changed. XXX: thd->locked_tables is not changed.
@ -1684,8 +1687,11 @@ Cursor::init_from_thd(THD *thd)
void void
Cursor::init_thd(THD *thd) Cursor::init_thd(THD *thd)
{ {
thd->mem_root= mem_root; /*
Use the original mem_root, in which we store all memory allocated
during the lifetime of the cursor.
*/
thd->mem_root= &main_mem_root;
DBUG_ASSERT(thd->derived_tables == 0); DBUG_ASSERT(thd->derived_tables == 0);
thd->derived_tables= derived_tables; thd->derived_tables= derived_tables;
@ -1773,11 +1779,10 @@ int
Cursor::fetch(ulong num_rows) Cursor::fetch(ulong num_rows)
{ {
THD *thd= join->thd; THD *thd= join->thd;
JOIN_TAB *join_tab= join->join_tab + join->const_tables;; JOIN_TAB *join_tab= join->join_tab + join->const_tables;
COND *on_expr= *join_tab->on_expr_ref; COND *on_expr= *join_tab->on_expr_ref;
COND *select_cond= join_tab->select_cond; COND *select_cond= join_tab->select_cond;
READ_RECORD *info= &join_tab->read_record; READ_RECORD *info= &join_tab->read_record;
int error= 0; int error= 0;
join->fetch_limit+= num_rows; join->fetch_limit+= num_rows;
@ -1853,7 +1858,6 @@ Cursor::fetch(ulong num_rows)
::send_eof(thd); ::send_eof(thd);
thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS; thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
/* save references to memory, allocated during fetch */ /* save references to memory, allocated during fetch */
mem_root= thd->mem_root;
free_list= thd->free_list; free_list= thd->free_list;
break; break;
/* Limit clause worked: this is the same as 'no more rows' */ /* Limit clause worked: this is the same as 'no more rows' */
@ -1875,8 +1879,7 @@ Cursor::fetch(ulong num_rows)
Must be last, as some memory might be allocated for free purposes, Must be last, as some memory might be allocated for free purposes,
like in free_tmp_table() (TODO: fix this issue) like in free_tmp_table() (TODO: fix this issue)
*/ */
mem_root= thd->mem_root; free_root(&main_mem_root, MYF(0));
free_root(&mem_root, MYF(0));
break; break;
default: default:
close(); close();
@ -1888,8 +1891,7 @@ Cursor::fetch(ulong num_rows)
Must be last, as some memory might be allocated for free purposes, Must be last, as some memory might be allocated for free purposes,
like in free_tmp_table() (TODO: fix this issue) like in free_tmp_table() (TODO: fix this issue)
*/ */
mem_root= thd->mem_root; free_root(&main_mem_root, MYF(0));
free_root(&mem_root, MYF(0));
break; break;
} }
return error; return error;
@ -1940,7 +1942,7 @@ Cursor::~Cursor()
Must be last, as some memory might be allocated for free purposes, Must be last, as some memory might be allocated for free purposes,
like in free_tmp_table() (TODO: fix this issue) like in free_tmp_table() (TODO: fix this issue)
*/ */
free_root(&mem_root, MYF(0)); free_root(&main_mem_root, MYF(0));
} }
/*********************************************************************/ /*********************************************************************/

View File

@ -1401,7 +1401,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
create_info, *extra_fields, *keys, 0, create_info, *extra_fields, *keys, 0,
select_field_count)) select_field_count))
{ {
if (!(table= open_table(thd, create_table, &thd->mem_root, (bool*) 0))) if (!(table= open_table(thd, create_table, thd->mem_root, (bool*) 0)))
quick_rm_table(create_info->db_type, create_table->db, quick_rm_table(create_info->db_type, create_table->db,
table_case_name(create_info, create_table->real_name)); table_case_name(create_info, create_table->real_name));
} }
@ -3077,7 +3077,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
bzero((void*) &tbl, sizeof(tbl)); bzero((void*) &tbl, sizeof(tbl));
tbl.db= new_db; tbl.db= new_db;
tbl.real_name= tbl.alias= tmp_name; tbl.real_name= tbl.alias= tmp_name;
new_table= open_table(thd, &tbl, &thd->mem_root, 0); new_table= open_table(thd, &tbl, thd->mem_root, 0);
} }
else else
{ {
@ -3516,6 +3516,8 @@ int mysql_recreate_table(THD *thd, TABLE_LIST *table_list,
create_info.db_type=DB_TYPE_DEFAULT; create_info.db_type=DB_TYPE_DEFAULT;
create_info.row_type=ROW_TYPE_DEFAULT; create_info.row_type=ROW_TYPE_DEFAULT;
create_info.default_table_charset=default_charset_info; create_info.default_table_charset=default_charset_info;
/* Force alter table to recreate table */
lex->alter_info.flags= ALTER_CHANGE_COLUMN;
DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info, DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
table_list, lex->create_list, table_list, lex->create_list,
lex->key_list, 0, (ORDER *) 0, lex->key_list, 0, (ORDER *) 0,

View File

@ -134,7 +134,6 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables)
TABLE *table= tables->table; TABLE *table= tables->table;
char dir_buff[FN_REFLEN], file_buff[FN_REFLEN]; char dir_buff[FN_REFLEN], file_buff[FN_REFLEN];
LEX_STRING dir, file; LEX_STRING dir, file;
MEM_ROOT *old_global_root;
LEX_STRING *trg_def, *name; LEX_STRING *trg_def, *name;
List_iterator_fast<LEX_STRING> it(names_list); List_iterator_fast<LEX_STRING> it(names_list);
@ -168,9 +167,6 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables)
triggers_file_ext, NullS) - file_buff; triggers_file_ext, NullS) - file_buff;
file.str= file_buff; file.str= file_buff;
old_global_root= my_pthread_getspecific_ptr(MEM_ROOT*, THR_MALLOC);
my_pthread_setspecific_ptr(THR_MALLOC, &table->mem_root);
/* /*
Soon we will invalidate table object and thus Table_triggers_list object Soon we will invalidate table object and thus Table_triggers_list object
so don't care about place to which trg_def->ptr points and other so don't care about place to which trg_def->ptr points and other
@ -181,17 +177,12 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables)
*/ */
if (!(trg_def= (LEX_STRING *)alloc_root(&table->mem_root, if (!(trg_def= (LEX_STRING *)alloc_root(&table->mem_root,
sizeof(LEX_STRING))) || sizeof(LEX_STRING))) ||
definitions_list.push_back(trg_def)) definitions_list.push_back(trg_def, &table->mem_root))
{
my_pthread_setspecific_ptr(THR_MALLOC, old_global_root);
return 1; return 1;
}
trg_def->str= thd->query; trg_def->str= thd->query;
trg_def->length= thd->query_length; trg_def->length= thd->query_length;
my_pthread_setspecific_ptr(THR_MALLOC, old_global_root);
return sql_create_definition_file(&dir, &file, &triggers_file_type, return sql_create_definition_file(&dir, &file, &triggers_file_type,
(gptr)this, triggers_file_parameters, 3); (gptr)this, triggers_file_parameters, 3);
} }
@ -302,7 +293,6 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
char path_buff[FN_REFLEN]; char path_buff[FN_REFLEN];
LEX_STRING path; LEX_STRING path;
File_parser *parser; File_parser *parser;
MEM_ROOT *old_global_mem_root;
DBUG_ENTER("Table_triggers_list::check_n_load"); DBUG_ENTER("Table_triggers_list::check_n_load");
@ -406,14 +396,9 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
trg_name_str->str= trg_name_buff; trg_name_str->str= trg_name_buff;
trg_name_str->length= lex.name_and_length.length; trg_name_str->length= lex.name_and_length.length;
old_global_mem_root= my_pthread_getspecific_ptr(MEM_ROOT*, THR_MALLOC); if (triggers->names_list.push_back(trg_name_str, &table->mem_root))
my_pthread_setspecific_ptr(THR_MALLOC, &table->mem_root);
if (triggers->names_list.push_back(trg_name_str))
goto err_with_lex_cleanup; goto err_with_lex_cleanup;
my_pthread_setspecific_ptr(THR_MALLOC, old_global_mem_root);
lex_end(&lex); lex_end(&lex);
} }
thd->lex= old_lex; thd->lex= old_lex;
@ -431,7 +416,8 @@ err_with_lex_cleanup:
We don't care about this error message much because .TRG files will We don't care about this error message much because .TRG files will
be merged into .FRM anyway. be merged into .FRM anyway.
*/ */
my_error(ER_WRONG_OBJECT, MYF(0), table_name, triggers_file_ext, "TRIGGER"); my_error(ER_WRONG_OBJECT, MYF(0), table_name, triggers_file_ext,
"TRIGGER");
DBUG_RETURN(1); DBUG_RETURN(1);
} }

View File

@ -314,6 +314,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
thd_arg->lex->current_select= lex_select_save; thd_arg->lex->current_select= lex_select_save;
if (!item_list.elements) if (!item_list.elements)
{ {
Field **field;
Item_arena *tmp_arena,backup; Item_arena *tmp_arena,backup;
tmp_arena= thd->change_arena_if_needed(&backup); tmp_arena= thd->change_arena_if_needed(&backup);

View File

@ -434,7 +434,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (!(parser= sql_parse_prepare(&path, &thd->mem_root, 0))) if (!(parser= sql_parse_prepare(&path, thd->mem_root, 0)))
DBUG_RETURN(1); DBUG_RETURN(1);
if (!parser->ok() || if (!parser->ok() ||
@ -451,7 +451,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
TODO: read dependence list, too, to process cascade/restrict TODO: read dependence list, too, to process cascade/restrict
TODO: special cascade/restrict procedure for alter? TODO: special cascade/restrict procedure for alter?
*/ */
if (parser->parse((gptr)view, &thd->mem_root, if (parser->parse((gptr)view, thd->mem_root,
view_parameters + revision_number_position, 1)) view_parameters + revision_number_position, 1))
{ {
DBUG_RETURN(thd->net.report_error? -1 : 0); DBUG_RETURN(thd->net.report_error? -1 : 0);
@ -565,7 +565,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
TODO: when VIEWs will be stored in cache, table mem_root should TODO: when VIEWs will be stored in cache, table mem_root should
be used here be used here
*/ */
if (parser->parse((gptr)table, &thd->mem_root, view_parameters, if (parser->parse((gptr)table, thd->mem_root, view_parameters,
required_view_parameters)) required_view_parameters))
goto err; goto err;
@ -586,7 +586,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
now Lex placed in statement memory now Lex placed in statement memory
*/ */
table->view= lex= thd->lex= (LEX*) new(&thd->mem_root) st_lex_local; table->view= lex= thd->lex= (LEX*) new(thd->mem_root) st_lex_local;
lex_start(thd, (uchar*)table->query.str, table->query.length); lex_start(thd, (uchar*)table->query.str, table->query.length);
lex->select_lex.select_number= ++thd->select_number; lex->select_lex.select_number= ++thd->select_number;
old_lex->derived_tables|= DERIVED_VIEW; old_lex->derived_tables|= DERIVED_VIEW;

View File

@ -1848,7 +1848,7 @@ sp_proc_stmt:
i->m_query.length= lex->ptr - sp->m_tmp_query; i->m_query.length= lex->ptr - sp->m_tmp_query;
else else
i->m_query.length= lex->tok_end - sp->m_tmp_query; i->m_query.length= lex->tok_end - sp->m_tmp_query;
i->m_query.str= strmake_root(&YYTHD->mem_root, i->m_query.str= strmake_root(YYTHD->mem_root,
(char *)sp->m_tmp_query, (char *)sp->m_tmp_query,
i->m_query.length); i->m_query.length);
i->set_lex(lex); i->set_lex(lex);

View File

@ -89,7 +89,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
error=1; error=1;
disk_buff=NULL; disk_buff=NULL;
old_root= my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC);
old_root= *root_ptr;
if ((file=my_open(fn_format(index_file, name, "", reg_ext, if ((file=my_open(fn_format(index_file, name, "", reg_ext,
MY_UNPACK_FILENAME), MY_UNPACK_FILENAME),
@ -123,8 +124,6 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
outparam->blob_ptr_size=sizeof(char*); outparam->blob_ptr_size=sizeof(char*);
outparam->db_stat = db_stat; outparam->db_stat = db_stat;
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC);
old_root= *root_ptr;
*root_ptr= &outparam->mem_root; *root_ptr= &outparam->mem_root;
outparam->real_name=strdup_root(&outparam->mem_root, outparam->real_name=strdup_root(&outparam->mem_root,