Simpler arena swapping code

Now thd->mem_root is a pointer to thd->main_mem_root and THR_MALLOC is a pointer to thd->mem_root.
This gives us the following benefits:
- Allow us to easily detect if arena has already been swapped before (this fixes a bug in setup_conds() where arena was swaped twice in some cases)
- Faster swaps of arenas (as we don't have to copy the whole MEM_ROOT)
- We don't anymore have to call my_pthread_setspecific_ptr(THR_MALLOC,...) to change where memory is alloced. Now it's enough to set thd->mem_root



client/mysqltest.c:
  Remove some not needed defines
  (Things like this should be done in config-win.h)
include/config-win.h:
  Added popen() and pclose() compatibility macros
mysql-test/t/rpl_failed_optimize-master.opt:
  Portability fix
sql/ha_berkeley.cc:
  New thd->memroot handling
sql/item_cmpfunc.cc:
  Simpler arena swapping code
sql/item_func.cc:
  Simpler arena swapping code
sql/item_subselect.cc:
  Simpler arena swapping code
  New thd->mem_root handling
sql/item_sum.cc:
  New thd->mem_root handling
sql/item_timefunc.cc:
  Fixed not-initalized usage errors found by valgrind
sql/log_event.cc:
  New thd->mem_root handling
sql/mysql_priv.h:
  New thd->mem_root handling
sql/mysqld.cc:
  New thd->mem_root handling
sql/opt_range.cc:
  New thd->mem_root handling
sql/repl_failsafe.cc:
  New thd->mem_root handling
sql/set_var.cc:
  New thd->mem_root handling
sql/sql_acl.cc:
  New thd->mem_root handling
sql/sql_base.cc:
  Simpler arena swapping code
  New thd->mem_root handling
sql/sql_class.cc:
  New thd->mem_root handling
sql/sql_class.h:
  Simpler arena swapping code
  New thd->mem_root handling
sql/sql_db.cc:
  New thd->mem_root handling
sql/sql_error.cc:
  New thd->mem_root handling
sql/sql_help.cc:
  New thd->mem_root handling
sql/sql_insert.cc:
  New thd->mem_root handling
sql/sql_parse.cc:
  New thd->mem_root handling
  Added some extra checking of return value of new
sql/sql_prepare.cc:
  New thd->mem_root handling
sql/sql_select.cc:
  New thd->mem_root handling
sql/sql_select.h:
  New thd->mem_root handling
sql/sql_union.cc:
  Simpler arena swapping code
sql/sql_yacc.yy:
  New thd->mem_root handling
sql/table.cc:
  New thd->mem_root handling
sql/thr_malloc.cc:
  New thd->mem_root handling
tests/client_test.c:
  Added drop table to some tests
  Changed some table names to 't1'
This commit is contained in:
unknown 2004-11-08 01:13:54 +02:00
parent 43c6c27c90
commit 435b20aa68
32 changed files with 243 additions and 216 deletions

View File

@ -949,11 +949,7 @@ static void do_exec(struct st_query* q)
while (fgets(buf, sizeof(buf), res_file))
replace_dynstr_append_mem(ds, buf, strlen(buf));
}
#ifndef __WIN__
error= pclose(res_file);
#else
error= _pclose(res_file);
#endif
if (error != 0)
die("command \"%s\" failed", cmd);
@ -4610,11 +4606,7 @@ FILE *my_popen(const char *cmd, const char *mode __attribute__((unused)))
FILE *res_file;
subst_cmd= subst_env_var(cmd);
#ifndef __WIN__
res_file= popen(subst_cmd, "r0");
#else
res_file= _popen(subst_cmd, "r0");
#endif
my_free(subst_cmd, MYF(0));
return res_file;
}

View File

@ -175,6 +175,8 @@ typedef uint rf_SetTimer;
#define sigset(A,B) signal((A),(B))
#define finite(A) _finite(A)
#define sleep(A) Sleep((A)*1000)
#define popen(A) popen(A,B) _popen((A),(B))
#define pclose(A) _pclose(A)
#ifndef __BORLANDC__
#define access(A,B) _access(A,B)

View File

@ -1 +1 @@
--innodb-lock-wait-timeout=1
--loose-innodb-lock-wait-timeout=1

View File

@ -234,13 +234,13 @@ int berkeley_show_logs(Protocol *protocol)
{
char **all_logs, **free_logs, **a, **f;
int error=1;
MEM_ROOT show_logs_root;
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
MEM_ROOT **root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**,THR_MALLOC);
MEM_ROOT show_logs_root, *old_mem_root= *root_ptr;
DBUG_ENTER("berkeley_show_logs");
init_sql_alloc(&show_logs_root, BDB_LOG_ALLOC_BLOCK_SIZE,
BDB_LOG_ALLOC_BLOCK_SIZE);
my_pthread_setspecific_ptr(THR_MALLOC,&show_logs_root);
*root_ptr= &show_logs_root;
if ((error= db_env->log_archive(db_env, &all_logs,
DB_ARCH_ABS | DB_ARCH_LOG)) ||
@ -277,15 +277,17 @@ int berkeley_show_logs(Protocol *protocol)
}
err:
free_root(&show_logs_root,MYF(0));
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
*root_ptr= old_mem_root;
DBUG_RETURN(error);
}
static void berkeley_print_error(const char *db_errpfx, char *buffer)
{
sql_print_error("%s: %s",db_errpfx,buffer); /* purecov: tested */
}
static void berkeley_noticecall(DB_ENV *db_env, db_notices notice)
{
switch (notice)

View File

@ -1744,9 +1744,9 @@ void Item_func_in::fix_length_and_dec()
Conversion is possible:
All IN arguments are constants.
*/
Item_arena *arena= thd->current_arena, backup;
if (arena->is_stmt_prepare())
thd->set_n_backup_item_arena(arena, &backup);
Item_arena *arena, backup;
arena= thd->change_arena_if_needed(&backup);
for (arg= args+1, arg_end= args+arg_count; arg < arg_end; arg++)
{
if (!arg[0]->null_value &&
@ -1764,7 +1764,7 @@ void Item_func_in::fix_length_and_dec()
arg[0]= conv;
}
}
if (arena->is_stmt_prepare())
if (arena)
thd->restore_backup_item_arena(arena, &backup);
}
}

View File

@ -160,14 +160,13 @@ bool Item_func::agg_arg_charsets(DTCollation &coll,
}
THD *thd= current_thd;
Item_arena *arena= thd->current_arena, backup;
Item_arena *arena, backup;
bool res= FALSE;
/*
In case we're in statement prepare, create conversion item
in its memory: it will be reused on each execute.
*/
if (arena->is_stmt_prepare())
thd->set_n_backup_item_arena(arena, &backup);
arena= thd->change_arena_if_needed(&backup);
for (arg= args, last= args + nargs; arg < last; arg++)
{
@ -193,7 +192,7 @@ bool Item_func::agg_arg_charsets(DTCollation &coll,
conv->fix_fields(thd, 0, &conv);
*arg= conv;
}
if (arena->is_stmt_prepare())
if (arena)
thd->restore_backup_item_arena(arena, &backup);
return res;
}

View File

@ -190,15 +190,16 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
bool Item_subselect::exec()
{
int res;
MEM_ROOT *old_root= my_pthread_getspecific_ptr(MEM_ROOT*, THR_MALLOC);
if (&thd->mem_root != old_root)
{
my_pthread_setspecific_ptr(THR_MALLOC, &thd->mem_root);
res= engine->exec();
my_pthread_setspecific_ptr(THR_MALLOC, old_root);
}
else
MEM_ROOT *old_root= thd->mem_root;
/*
As this is execution, all objects should be allocated through the main
mem root
*/
thd->mem_root= &thd->main_mem_root;
res= engine->exec();
thd->mem_root= old_root;
if (engine_changed)
{
engine_changed= 0;
@ -312,7 +313,6 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
/* Juggle with current arena only if we're in prepared statement prepare */
Item_arena *arena= join->thd->current_arena;
Item_arena backup;
if (!select_lex->master_unit()->first_select()->next_select() &&
!select_lex->table_list.elements &&
@ -655,11 +655,9 @@ Item_in_subselect::single_value_transformer(JOIN *join,
}
SELECT_LEX *select_lex= join->select_lex;
Item_arena *arena= join->thd->current_arena, backup;
Item_arena *arena, backup;
arena= thd->change_arena_if_needed(&backup);
thd->where= "scalar IN/ALL/ANY subquery";
if (arena->is_stmt_prepare())
thd->set_n_backup_item_arena(arena, &backup);
/*
Check that the right part of the subselect contains no more than one
@ -892,7 +890,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_SELECT_REDUCED, warn_buff);
}
if (arena->is_stmt_prepare())
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(RES_REDUCE);
}
@ -900,13 +898,13 @@ Item_in_subselect::single_value_transformer(JOIN *join,
}
ok:
if (arena->is_stmt_prepare())
if (arena)
thd->restore_backup_item_arena(arena, &backup);
thd->where= save_where;
DBUG_RETURN(RES_OK);
err:
if (arena->is_stmt_prepare())
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(RES_ERROR);
}
@ -922,14 +920,12 @@ Item_in_subselect::row_value_transformer(JOIN *join)
{
DBUG_RETURN(RES_OK);
}
Item_arena *arena= join->thd->current_arena, backup;
Item_arena *arena, backup;
Item *item= 0;
SELECT_LEX *select_lex= join->select_lex;
thd->where= "row IN/ALL/ANY subquery";
if (arena->is_stmt_prepare())
thd->set_n_backup_item_arena(arena, &backup);
SELECT_LEX *select_lex= join->select_lex;
arena= thd->change_arena_if_needed(&backup);
if (select_lex->item_list.elements != left_expr->cols())
{
@ -1006,13 +1002,13 @@ Item_in_subselect::row_value_transformer(JOIN *join)
if (join->conds->fix_fields(thd, join->tables_list, 0))
goto err;
}
if (arena->is_stmt_prepare())
if (arena)
thd->restore_backup_item_arena(arena, &backup);
thd->where= save_where;
DBUG_RETURN(RES_OK);
err:
if (arena->is_stmt_prepare())
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(RES_ERROR);
}

View File

@ -254,7 +254,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
Item *Item_sum_sum::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_sum(thd, this);
return new (thd->mem_root) Item_sum_sum(thd, this);
}
@ -282,7 +282,7 @@ double Item_sum_sum::val()
Item *Item_sum_count::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_count(thd, this);
return new (thd->mem_root) Item_sum_count(thd, this);
}
@ -327,7 +327,7 @@ void Item_sum_count::cleanup()
Item *Item_sum_avg::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_avg(thd, this);
return new (thd->mem_root) Item_sum_avg(thd, this);
}
@ -374,7 +374,7 @@ double Item_sum_std::val()
Item *Item_sum_std::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_std(thd, this);
return new (thd->mem_root) Item_sum_std(thd, this);
}
@ -384,7 +384,7 @@ Item *Item_sum_std::copy_or_same(THD* thd)
Item *Item_sum_variance::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_variance(thd, this);
return new (thd->mem_root) Item_sum_variance(thd, this);
}
@ -546,7 +546,7 @@ void Item_sum_hybrid::cleanup()
Item *Item_sum_min::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_min(thd, this);
return new (thd->mem_root) Item_sum_min(thd, this);
}
@ -599,7 +599,7 @@ bool Item_sum_min::add()
Item *Item_sum_max::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_max(thd, this);
return new (thd->mem_root) Item_sum_max(thd, this);
}
@ -666,7 +666,7 @@ void Item_sum_bit::clear()
Item *Item_sum_or::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_or(thd, this);
return new (thd->mem_root) Item_sum_or(thd, this);
}
@ -680,7 +680,7 @@ bool Item_sum_or::add()
Item *Item_sum_xor::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_xor(thd, this);
return new (thd->mem_root) Item_sum_xor(thd, this);
}
@ -694,7 +694,7 @@ bool Item_sum_xor::add()
Item *Item_sum_and::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_and(thd, this);
return new (thd->mem_root) Item_sum_and(thd, this);
}
@ -1337,7 +1337,7 @@ int Item_sum_count_distinct::tree_to_myisam()
Item *Item_sum_count_distinct::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_count_distinct(thd, this);
return new (thd->mem_root) Item_sum_count_distinct(thd, this);
}
@ -1438,7 +1438,7 @@ bool Item_udf_sum::add()
Item *Item_sum_udf_float::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_udf_float(thd, this);
return new (thd->mem_root) Item_sum_udf_float(thd, this);
}
double Item_sum_udf_float::val()
@ -1463,7 +1463,7 @@ String *Item_sum_udf_float::val_str(String *str)
Item *Item_sum_udf_int::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_udf_int(thd, this);
return new (thd->mem_root) Item_sum_udf_int(thd, this);
}
@ -1501,7 +1501,7 @@ void Item_sum_udf_str::fix_length_and_dec()
Item *Item_sum_udf_str::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_sum_udf_str(thd, this);
return new (thd->mem_root) Item_sum_udf_str(thd, this);
}
@ -1815,7 +1815,7 @@ Item_func_group_concat::~Item_func_group_concat()
Item *Item_func_group_concat::copy_or_same(THD* thd)
{
return new (&thd->mem_root) Item_func_group_concat(thd, this);
return new (thd->mem_root) Item_func_group_concat(thd, this);
}

View File

@ -164,10 +164,10 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
CHARSET_INFO *cs= &my_charset_bin;
int error= 0;
bool usa_time= 0;
bool sunday_first_n_first_week_non_iso;
bool sunday_first_n_first_week_non_iso= -2;
bool strict_week_number;
int strict_week_number_year= -1;
bool strict_week_number_year_type;
bool strict_week_number_year_type= -1;
int frac_part;
const char *val_begin= val;
const char *val_end= val + length;
@ -175,9 +175,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
const char *end= ptr + format->format.length;
DBUG_ENTER("extract_date_time");
LINT_INIT(sunday_first_n_first_week_non_iso);
LINT_INIT(strict_week_number);
LINT_INIT(strict_week_number_year_type);
if (!sub_pattern_end)
bzero((char*) l_time, sizeof(*l_time));

View File

@ -1090,7 +1090,7 @@ end:
thd->query_length= thd->db_length =0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
close_thread_tables(thd);
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
/*
If there was an error we stop. Otherwise we increment positions. Note that
we will not increment group* positions if we are just after a SET
@ -1888,10 +1888,10 @@ Slave: load data infile on table '%s' at log position %s in log \
slave_print_error(rli,sql_errno,"\
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
err, (char*)table_name, print_slave_db_safe(db));
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
return 1;
}
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
if (thd->is_fatal_error)
{
@ -2505,7 +2505,7 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli)
*/
e.fix_fields(thd, 0, 0);
e.update_hash(val, val_len, type, charset, DERIVATION_NONE);
free_root(&thd->mem_root,0);
free_root(thd->mem_root,0);
rli->inc_event_relay_log_pos(get_event_len());
return 0;

View File

@ -910,7 +910,7 @@ extern char *default_tz_name;
extern MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log;
extern FILE *bootstrap_file;
extern pthread_key(MEM_ROOT*,THR_MALLOC);
extern pthread_key(MEM_ROOT**,THR_MALLOC);
extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator,

View File

@ -374,7 +374,7 @@ SHOW_COMP_OPTION have_crypt, have_compress;
/* Thread specific variables */
pthread_key(MEM_ROOT*,THR_MALLOC);
pthread_key(MEM_ROOT**,THR_MALLOC);
pthread_key(THD*, THR_THD);
pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_mapped_file, LOCK_status,

View File

@ -400,7 +400,7 @@ QUICK_SELECT::QUICK_SELECT(THD *thd, TABLE *table, uint key_nr, bool no_alloc)
{
// Allocates everything through the internal memroot
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
my_pthread_setspecific_ptr(THR_MALLOC,&alloc);
thd->mem_root= &alloc;
}
else
bzero((char*) &alloc,sizeof(alloc));
@ -668,8 +668,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
DBUG_RETURN(0); // Can't use range
}
key_parts= param.key_parts;
old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
my_pthread_setspecific_ptr(THR_MALLOC,&alloc);
old_root= thd->mem_root;
thd->mem_root= &alloc;
key_info= head->key_info;
for (idx=0 ; idx < head->keys ; idx++, key_info++)
@ -769,7 +769,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
}
}
free_root(&alloc,MYF(0)); // Return memory & allocator
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
thd->mem_root= old_root;
thd->no_errors=0;
}
DBUG_EXECUTE("info",print_quick(quick,&needed_reg););
@ -2563,7 +2563,8 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length)
QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref)
{
MEM_ROOT *old_root= my_pthread_getspecific_ptr(MEM_ROOT*, THR_MALLOC);
MEM_ROOT *old_root= thd->mem_root;
/* The following call may change thd->mem_root */
QUICK_SELECT *quick= new QUICK_SELECT(thd, table, ref->key);
KEY *key_info = &table->key_info[ref->key];
KEY_PART *key_part;
@ -2624,11 +2625,11 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref)
}
ok:
my_pthread_setspecific_ptr(THR_MALLOC, old_root);
thd->mem_root= old_root;
return quick;
err:
my_pthread_setspecific_ptr(THR_MALLOC, old_root);
thd->mem_root= old_root;
delete quick;
return 0;
}

View File

@ -92,7 +92,7 @@ static int init_failsafe_rpl_thread(THD* thd)
VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
#endif
thd->mem_root.free=thd->mem_root.used=0;
thd->mem_root->free= thd->mem_root->used= 0;
if (thd->variables.max_join_size == HA_POS_ERROR)
thd->options|= OPTION_BIG_SELECTS;

View File

@ -1165,7 +1165,7 @@ static void fix_max_connections(THD *thd, enum_var_type type)
static void fix_thd_mem_root(THD *thd, enum_var_type type)
{
if (type != OPT_GLOBAL)
reset_root_defaults(&thd->mem_root,
reset_root_defaults(thd->mem_root,
thd->variables.query_alloc_block_size,
thd->variables.query_prealloc_size);
}

View File

@ -2309,8 +2309,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
create_new_users= test_if_create_new_users(thd);
int result=0;
rw_wrlock(&LOCK_grant);
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
my_pthread_setspecific_ptr(THR_MALLOC,&memex);
MEM_ROOT *old_root= thd->mem_root;
thd->mem_root= &memex;
while ((Str = str_list++))
{
@ -2415,7 +2415,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
}
}
grant_option=TRUE;
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
thd->mem_root= old_root;
rw_unlock(&LOCK_grant);
if (!result)
send_ok(thd);
@ -2549,6 +2549,7 @@ my_bool grant_init(THD *org_thd)
THD *thd;
TABLE_LIST tables[2];
MYSQL_LOCK *lock;
MEM_ROOT *memex_ptr;
my_bool return_val= 1;
TABLE *t_table, *c_table;
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
@ -2596,7 +2597,8 @@ my_bool grant_init(THD *org_thd)
grant_option= TRUE;
/* Will be restored by org_thd->store_globals() */
my_pthread_setspecific_ptr(THR_MALLOC,&memex);
memex_ptr= &memex;
my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr);
do
{
GRANT_TABLE *mem_check;

View File

@ -499,7 +499,7 @@ void close_temporary_tables(THD *thd)
*/
query_buf_size+= table->key_length+1;
if ((query = alloc_root(&thd->mem_root, query_buf_size)))
if ((query = alloc_root(thd->mem_root, query_buf_size)))
// Better add "if exists", in case a RESET MASTER has been done
end=strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
@ -2311,17 +2311,15 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
if (!wild_num)
DBUG_RETURN(0);
Item_arena *arena= thd->current_arena, backup;
reg2 Item *item;
List_iterator<Item> it(fields);
Item_arena *arena, backup;
/*
If we are in preparing prepared statement phase then we have change
temporary mem_root to statement mem root to save changes of SELECT list
*/
if ((is_stmt_prepare= arena->is_stmt_prepare()))
thd->set_n_backup_item_arena(arena, &backup);
arena= thd->change_arena_if_needed(&backup);
reg2 Item *item;
List_iterator<Item> it(fields);
while (wild_num && (item= it++))
{
if (item->type() == Item::FIELD_ITEM &&
@ -2344,7 +2342,7 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
else if (insert_fields(thd,tables,((Item_field*) item)->db_name,
((Item_field*) item)->table_name, &it))
{
if (is_stmt_prepare)
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(-1);
}
@ -2360,7 +2358,7 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List<Item> &fields,
wild_num--;
}
}
if (is_stmt_prepare)
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(0);
}
@ -2589,11 +2587,10 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
table_map not_null_tables= 0;
Item_arena *arena= thd->current_arena, backup;
bool is_stmt_prepare= arena->is_stmt_prepare();
Item_arena *arena= 0, backup;
DBUG_ENTER("setup_conds");
thd->set_query_id=1;
thd->set_query_id=1;
thd->lex->current_select->cond_count= 0;
if (*conds)
{
@ -2628,12 +2625,14 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
!(specialflag & SPECIAL_NO_NEW_FUNC)))
{
table->outer_join= 0;
if (is_stmt_prepare)
thd->set_n_backup_item_arena(arena, &backup);
arena= thd->change_arena_if_needed(&backup);
*conds= and_conds(*conds, table->on_expr);
table->on_expr=0;
if (is_stmt_prepare)
if (arena)
{
thd->restore_backup_item_arena(arena, &backup);
arena= 0; // Safety if goto err
}
if ((*conds) && !(*conds)->fixed &&
(*conds)->fix_fields(thd, tables, conds))
DBUG_RETURN(1);
@ -2641,8 +2640,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
}
if (table->natural_join)
{
if (is_stmt_prepare)
thd->set_n_backup_item_arena(arena, &backup);
arena= thd->change_arena_if_needed(&backup);
/* Make a join of all fields with have the same name */
TABLE *t1= table->table;
TABLE *t2= table->natural_join->table;
@ -2683,7 +2681,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
*conds= and_conds(*conds, cond_and);
// fix_fields() should be made with temporary memory pool
if (is_stmt_prepare)
if (arena)
thd->restore_backup_item_arena(arena, &backup);
if (*conds && !(*conds)->fixed)
{
@ -2695,7 +2693,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{
table->on_expr= and_conds(table->on_expr, cond_and);
// fix_fields() should be made with temporary memory pool
if (is_stmt_prepare)
if (arena)
thd->restore_backup_item_arena(arena, &backup);
if (table->on_expr && !table->on_expr->fixed)
{
@ -2704,12 +2702,15 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
}
}
}
else if (is_stmt_prepare)
else if (arena)
{
thd->restore_backup_item_arena(arena, &backup);
arena= 0; // Safety if goto err
}
}
}
if (is_stmt_prepare)
if (thd->current_arena->is_stmt_prepare())
{
/*
We are in prepared statement preparation code => we should store
@ -2722,7 +2723,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
DBUG_RETURN(test(thd->net.report_error));
err:
if (is_stmt_prepare)
if (arena)
thd->restore_backup_item_arena(arena, &backup);
DBUG_RETURN(1);
}

View File

@ -305,7 +305,7 @@ void THD::init_for_queries()
{
ha_enable_transaction(this,TRUE);
reset_root_defaults(&mem_root, variables.query_alloc_block_size,
reset_root_defaults(mem_root, variables.query_alloc_block_size,
variables.query_prealloc_size);
reset_root_defaults(&transaction.mem_root,
variables.trans_alloc_block_size,
@ -411,7 +411,7 @@ THD::~THD()
dbug_sentry = THD_SENTRY_GONE;
#endif
/* Reset stmt_backup.mem_root to not double-free memory from thd.mem_root */
clear_alloc_root(&stmt_backup.mem_root);
clear_alloc_root(&stmt_backup.main_mem_root);
DBUG_VOID_RETURN;
}
@ -1394,10 +1394,10 @@ void select_dumpvar::cleanup()
for memory root initialization.
*/
Item_arena::Item_arena(THD* thd)
:free_list(0),
:free_list(0), mem_root(&main_mem_root),
state(INITIALIZED)
{
init_sql_alloc(&mem_root,
init_sql_alloc(&main_mem_root,
thd->variables.query_alloc_block_size,
thd->variables.query_prealloc_size);
}
@ -1420,11 +1420,11 @@ Item_arena::Item_arena(THD* thd)
statements.
*/
Item_arena::Item_arena(bool init_mem_root)
:free_list(0),
:free_list(0), mem_root(&main_mem_root),
state(CONVENTIONAL_EXECUTION)
{
if (init_mem_root)
init_sql_alloc(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
}
@ -1518,13 +1518,16 @@ void THD::end_statement()
void Item_arena::set_n_backup_item_arena(Item_arena *set, Item_arena *backup)
{
DBUG_ENTER("Item_arena::set_n_backup_item_arena");
backup->set_item_arena(this);
set_item_arena(set);
DBUG_VOID_RETURN;
}
void Item_arena::restore_backup_item_arena(Item_arena *set, Item_arena *backup)
{
DBUG_ENTER("Item_arena::restore_backup_item_arena");
set->set_item_arena(this);
set_item_arena(backup);
#ifdef NOT_NEEDED_NOW
@ -1537,6 +1540,7 @@ void Item_arena::restore_backup_item_arena(Item_arena *set, Item_arena *backup)
*/
clear_alloc_root(&backup->mem_root);
#endif
DBUG_VOID_RETURN;
}
void Item_arena::set_item_arena(Item_arena *set)
@ -1548,7 +1552,7 @@ void Item_arena::set_item_arena(Item_arena *set)
Statement::~Statement()
{
free_root(&mem_root, MYF(0));
free_root(&main_mem_root, MYF(0));
}
C_MODE_START

View File

@ -429,7 +429,8 @@ public:
itself to the list on creation (see Item::Item() for details))
*/
Item *free_list;
MEM_ROOT mem_root;
MEM_ROOT main_mem_root;
MEM_ROOT *mem_root; // Pointer to current memroot
enum enum_state
{
INITIALIZED= 0, PREPARED= 1, EXECUTED= 3, CONVENTIONAL_EXECUTION= 2,
@ -468,24 +469,24 @@ public:
{ return state == PREPARED || state == EXECUTED; }
inline bool is_conventional_execution() const
{ return state == CONVENTIONAL_EXECUTION; }
inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); }
inline gptr alloc(unsigned int size) { return alloc_root(mem_root,size); }
inline gptr calloc(unsigned int size)
{
gptr ptr;
if ((ptr=alloc_root(&mem_root,size)))
if ((ptr=alloc_root(mem_root,size)))
bzero((char*) ptr,size);
return ptr;
}
inline char *strdup(const char *str)
{ return strdup_root(&mem_root,str); }
{ return strdup_root(mem_root,str); }
inline char *strmake(const char *str, uint size)
{ return strmake_root(&mem_root,str,size); }
{ return strmake_root(mem_root,str,size); }
inline char *memdup(const char *str, uint size)
{ return memdup_root(&mem_root,str,size); }
{ return memdup_root(mem_root,str,size); }
inline char *memdup_w_gap(const char *str, uint size, uint gap)
{
gptr ptr;
if ((ptr=alloc_root(&mem_root,size+gap)))
if ((ptr=alloc_root(mem_root,size+gap)))
memcpy(ptr,str,size);
return ptr;
}
@ -1052,11 +1053,26 @@ public:
inline CHARSET_INFO *charset() { return variables.character_set_client; }
void update_charset();
inline Item_arena *change_arena_if_needed(Item_arena *backup)
{
/*
use new arena if we are in a prepared statements and we have not
already changed to use this arena.
*/
if (current_arena->is_stmt_prepare() &&
mem_root != &current_arena->main_mem_root)
{
set_n_backup_item_arena(current_arena, backup);
return current_arena;
}
return 0;
}
void change_item_tree(Item **place, Item *new_value)
{
/* TODO: check for OOM condition here */
if (!current_arena->is_conventional_execution())
nocheck_register_item_tree_change(place, *place, &mem_root);
nocheck_register_item_tree_change(place, *place, mem_root);
*place= new_value;
}
void nocheck_register_item_tree_change(Item **place, Item *old_value,

View File

@ -725,7 +725,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1)) < 0)
goto err;
if (!(copy_of_path= thd->memdup(newpath, length+1)) ||
!(dir= new (&thd->mem_root) String(copy_of_path, length,
!(dir= new (thd->mem_root) String(copy_of_path, length,
&my_charset_bin)) ||
raid_dirs.push_back(dir))
goto err;

View File

@ -113,12 +113,12 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
The following code is here to change the allocation to not
use the thd->mem_root, which is freed after each query
*/
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
my_pthread_setspecific_ptr(THR_MALLOC, &thd->warn_root);
MEM_ROOT *old_root= thd->mem_root;
thd->mem_root= &thd->warn_root;
err= new MYSQL_ERROR(thd, code, level, msg);
if (err)
thd->warn_list.push_back(err);
my_pthread_setspecific_ptr(THR_MALLOC, old_root);
thd->mem_root= old_root;
}
thd->warn_count[(uint) level]++;
thd->total_warn_count++;

View File

@ -127,7 +127,7 @@ void memorize_variant_topic(THD *thd, TABLE *topics, int count,
String *name, String *description, String *example)
{
DBUG_ENTER("memorize_variant_topic");
MEM_ROOT *mem_root= &thd->mem_root;
MEM_ROOT *mem_root= thd->mem_root;
if (count==0)
{
get_field(mem_root,find_fields[help_topic_name].field, name);
@ -138,7 +138,7 @@ void memorize_variant_topic(THD *thd, TABLE *topics, int count,
{
if (count == 1)
names->push_back(name);
String *new_name= new (&thd->mem_root) String;
String *new_name= new (thd->mem_root) String;
get_field(mem_root,find_fields[help_topic_name].field,new_name);
names->push_back(new_name);
}
@ -351,8 +351,8 @@ int search_categories(THD *thd, TABLE *categories,
{
if (select && !select->cond->val_int())
continue;
String *lname= new (&thd->mem_root) String;
get_field(&thd->mem_root,pfname,lname);
String *lname= new (thd->mem_root) String;
get_field(thd->mem_root,pfname,lname);
if (++count == 1 && res_id)
*res_id= (int16) pcat_id->val_int();
names->push_back(lname);
@ -385,8 +385,8 @@ void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname,
{
if (!select->cond->val_int())
continue;
String *name= new (&thd->mem_root) String();
get_field(&thd->mem_root,pfname,name);
String *name= new (thd->mem_root) String();
get_field(thd->mem_root,pfname,name);
res->push_back(name);
}
end_read_record(&read_record_info);
@ -638,7 +638,7 @@ int mysqld_help(THD *thd, const char *mask)
String name, description, example;
int res, count_topics, count_categories, error;
uint mlen= strlen(mask);
MEM_ROOT *mem_root= &thd->mem_root;
MEM_ROOT *mem_root= thd->mem_root;
if (open_and_lock_tables(thd, tables))
{

View File

@ -202,7 +202,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
{
/* it should be allocated before Item::fix_fields() */
table->insert_values=
(byte *)alloc_root(&thd->mem_root, table->rec_buff_length);
(byte *)alloc_root(thd->mem_root, table->rec_buff_length);
if (!table->insert_values)
goto abort;
}
@ -924,7 +924,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
found_next_number_field=table->found_next_number_field;
for (org_field=table->field ; *org_field ; org_field++,field++)
{
if (!(*field= (*org_field)->new_field(&client_thd->mem_root,copy)))
if (!(*field= (*org_field)->new_field(client_thd->mem_root,copy)))
return 0;
(*field)->orig_table= copy; // Remove connection
(*field)->move_field(adjust_ptrs); // Point at copy->record[0]

View File

@ -1026,7 +1026,7 @@ pthread_handler_decl(handle_one_connection,arg)
}
if (thd->user_connect)
decrease_user_connections(thd->user_connect);
free_root(&thd->mem_root,MYF(0));
free_root(thd->mem_root,MYF(0));
if (net->error && net->vio != 0 && net->report_error)
{
if (!thd->killed && thd->variables.log_warnings > 1)
@ -1121,14 +1121,14 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg)
{
thd->net.error = 0;
close_thread_tables(thd); // Free tables
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
break;
}
mysql_parse(thd,thd->query,length);
close_thread_tables(thd); // Free tables
if (thd->is_fatal_error)
break;
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
}
@ -1681,7 +1681,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
close_connection(thd, 0, 1);
close_thread_tables(thd); // Free before kill
free_root(&thd->mem_root,MYF(0));
free_root(thd->mem_root,MYF(0));
free_root(&thd->transaction.mem_root,MYF(0));
kill_mysql();
error=TRUE;
@ -1808,7 +1808,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thread_running--;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
DBUG_RETURN(error);
}
@ -2062,7 +2062,7 @@ mysql_execute_command(THD *thd)
query_len= need_conversion? (pstr->length() * to_cs->mbmaxlen) :
pstr->length();
if (!(query_str= alloc_root(&thd->mem_root, query_len+1)))
if (!(query_str= alloc_root(thd->mem_root, query_len+1)))
{
res= -1;
break; // EOM (error should be reported by allocator)
@ -3937,8 +3937,8 @@ mysql_init_select(LEX *lex)
bool
mysql_new_select(LEX *lex, bool move_down)
{
SELECT_LEX *select_lex = new(&lex->thd->mem_root) SELECT_LEX();
if (!select_lex)
SELECT_LEX *select_lex;
if (!(select_lex= new(lex->thd->mem_root) SELECT_LEX()))
return 1;
select_lex->select_number= ++lex->thd->select_number;
select_lex->init_query();
@ -3946,9 +3946,10 @@ mysql_new_select(LEX *lex, bool move_down)
if (move_down)
{
/* first select_lex of subselect or derived table */
SELECT_LEX_UNIT *unit= new(&lex->thd->mem_root) SELECT_LEX_UNIT();
if (!unit)
SELECT_LEX_UNIT *unit;
if (!(unit= new(lex->thd->mem_root) SELECT_LEX_UNIT()))
return 1;
unit->init_query();
unit->init_select();
unit->thd= lex->thd;
@ -3970,7 +3971,8 @@ mysql_new_select(LEX *lex, bool move_down)
as far as we included SELECT_LEX for UNION unit should have
fake SELECT_LEX for UNION processing
*/
fake= unit->fake_select_lex= new(&lex->thd->mem_root) SELECT_LEX();
if (!(fake= unit->fake_select_lex= new(lex->thd->mem_root) SELECT_LEX()))
return 1;
fake->include_standalone(unit,
(SELECT_LEX_NODE**)&unit->fake_select_lex);
fake->select_number= INT_MAX;

View File

@ -1065,7 +1065,7 @@ static int mysql_test_select(Prepared_statement *stmt,
DBUG_RETURN(1);
#endif
if (!lex->result && !(lex->result= new (&stmt->mem_root) select_send))
if (!lex->result && !(lex->result= new (stmt->mem_root) select_send))
{
send_error(thd);
goto err;
@ -1503,7 +1503,7 @@ static bool init_param_array(Prepared_statement *stmt)
List_iterator<Item_param> param_iterator(lex->param_list);
/* Use thd->mem_root as it points at statement mem_root */
stmt->param_array= (Item_param **)
alloc_root(&stmt->thd->mem_root,
alloc_root(stmt->thd->mem_root,
sizeof(Item_param*) * stmt->param_count);
if (!stmt->param_array)
{
@ -1569,7 +1569,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
if (name)
{
stmt->name.length= name->length;
if (!(stmt->name.str= memdup_root(&stmt->mem_root, (char*)name->str,
if (!(stmt->name.str= memdup_root(stmt->mem_root, (char*)name->str,
name->length)))
{
delete stmt;

View File

@ -4603,7 +4603,7 @@ static Field* create_tmp_field_from_field(THD *thd, Field* org_field,
org_field->field_name, table,
org_field->charset());
else
new_field= org_field->new_field(&thd->mem_root, table);
new_field= org_field->new_field(thd->mem_root, table);
if (new_field)
{
if (modify_item)
@ -5206,7 +5206,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
if (!using_unique_constraint)
{
group->buff=(char*) group_buff;
if (!(group->field=field->new_field(&thd->mem_root,table)))
if (!(group->field=field->new_field(thd->mem_root,table)))
goto err; /* purecov: inspected */
if (maybe_null)
{
@ -8499,7 +8499,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
saved value
*/
Field *field= item->field;
item->result_field=field->new_field(&thd->mem_root,field->table);
item->result_field=field->new_field(thd->mem_root,field->table);
char *tmp=(char*) sql_alloc(field->pack_length()+1);
if (!tmp)
goto err;
@ -8942,7 +8942,7 @@ bool JOIN::rollup_init()
return 1;
rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
rollup.item_null= new (&thd->mem_root) Item_null();
rollup.item_null= new (thd->mem_root) Item_null();
/*
Prepare space for field list for the different levels

View File

@ -354,7 +354,7 @@ class store_key :public Sql_alloc
field_arg->table, field_arg->charset());
else
{
to_field=field_arg->new_field(&thd->mem_root,field_arg->table);
to_field=field_arg->new_field(thd->mem_root,field_arg->table);
if (to_field)
to_field->move_field(ptr, (uchar*) null, 1);
}

View File

@ -313,24 +313,24 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
We're in statement prepare or in execution
of a conventional statement.
*/
Item_arena backup;
if (arena->is_stmt_prepare())
thd->set_n_backup_item_arena(arena, &backup);
Item_arena *tmp_arena,backup;
tmp_arena= thd->change_arena_if_needed(&backup);
Field **field;
for (field= table->field; *field; field++)
{
Item_field *item= new Item_field(*field);
if (!item || item_list.push_back(item))
{
if (arena->is_stmt_prepare())
thd->restore_backup_item_arena(arena, &backup);
if (tmp_arena)
thd->restore_backup_item_arena(tmp_arena, &backup);
DBUG_RETURN(-1);
}
}
if (tmp_arena)
thd->restore_backup_item_arena(tmp_arena, &backup);
if (arena->is_stmt_prepare())
{
thd->restore_backup_item_arena(arena, &backup);
/* prepare fake select to initialize it correctly */
ulong options_tmp= init_prepare_fake_select_lex(thd);
if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->options,

View File

@ -3297,7 +3297,7 @@ opt_distinct:
|DISTINCT { $$ = 1; };
opt_gconcat_separator:
/* empty */ { $$ = new (&YYTHD->mem_root) String(",",1,default_charset_info); }
/* empty */ { $$ = new (YYTHD->mem_root) String(",",1,default_charset_info); }
|SEPARATOR_SYM text_string { $$ = $2; };
@ -3551,15 +3551,15 @@ key_list_or_empty:
key_usage_list2:
key_usage_list2 ',' ident
{ Select->
interval_list.push_back(new (&YYTHD->mem_root) String((const char*) $3.str, $3.length,
interval_list.push_back(new (YYTHD->mem_root) String((const char*) $3.str, $3.length,
system_charset_info)); }
| ident
{ Select->
interval_list.push_back(new (&YYTHD->mem_root) String((const char*) $1.str, $1.length,
interval_list.push_back(new (YYTHD->mem_root) String((const char*) $1.str, $1.length,
system_charset_info)); }
| PRIMARY_SYM
{ Select->
interval_list.push_back(new (&YYTHD->mem_root) String("PRIMARY", 7,
interval_list.push_back(new (YYTHD->mem_root) String("PRIMARY", 7,
system_charset_info)); };
using_list:
@ -4507,7 +4507,7 @@ opt_db:
wild:
/* empty */
| LIKE TEXT_STRING_sys
{ Lex->wild= new (&YYTHD->mem_root) String($2.str, $2.length,
{ Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length,
system_charset_info); };
opt_full:
@ -4561,7 +4561,7 @@ opt_describe_column:
/* empty */ {}
| text_string { Lex->wild= $1; }
| ident
{ Lex->wild= new (&YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info); };
{ Lex->wild= new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info); };
/* flush things */
@ -4802,7 +4802,7 @@ text_literal:
text_string:
TEXT_STRING_literal
{ $$= new (&YYTHD->mem_root) String($1.str,$1.length,YYTHD->variables.collation_connection); }
{ $$= new (YYTHD->mem_root) String($1.str,$1.length,YYTHD->variables.collation_connection); }
| HEX_NUM
{
Item *tmp = new Item_varbinary($1.str,$1.length);
@ -5821,7 +5821,7 @@ column_list:
column_list_id:
ident
{
String *new_str = new (&YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info);
String *new_str = new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info);
List_iterator <LEX_COLUMN> iter(Lex->columns);
class LEX_COLUMN *point;
LEX *lex=Lex;

View File

@ -81,6 +81,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
uchar *null_pos;
uint null_bit, new_frm_ver, field_pack_length;
SQL_CRYPT *crypted=0;
MEM_ROOT **root_ptr, *old_root;
DBUG_ENTER("openfrm");
DBUG_PRINT("enter",("name: '%s' form: %lx",name,outparam));
@ -91,8 +92,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
error=1;
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
my_pthread_setspecific_ptr(THR_MALLOC,&outparam->mem_root);
root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC);
old_root= *root_ptr;
*root_ptr= &outparam->mem_root;
outparam->real_name=strdup_root(&outparam->mem_root,
name+dirname_length(name));
@ -251,9 +253,9 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
#ifdef HAVE_CRYPTED_FRM
else if (*(head+26) == 2)
{
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
*root_ptr= old_root
crypted=get_crypt_for_frm();
my_pthread_setspecific_ptr(THR_MALLOC,&outparam->mem_root);
*root_ptr= &outparam->mem_root;
outparam->crypted=1;
}
#endif
@ -736,7 +738,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
}
outparam->db_low_byte_first=outparam->file->low_byte_first();
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
*root_ptr= old_root;
opened_tables++;
#ifndef DBUG_OFF
if (use_hash)
@ -751,7 +753,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
err_end: /* Here when no file */
delete crypted;
my_pthread_setspecific_ptr(THR_MALLOC,old_root);
*root_ptr= old_root;
frm_error(error,outparam,name,ME_ERROR+ME_WAITTANG);
delete outparam->file;
outparam->file=0; // For easyer errorchecking

View File

@ -38,7 +38,7 @@ void init_sql_alloc(MEM_ROOT *mem_root, uint block_size, uint pre_alloc)
gptr sql_alloc(uint Size)
{
MEM_ROOT *root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
MEM_ROOT *root= *my_pthread_getspecific_ptr(MEM_ROOT**,THR_MALLOC);
char *ptr= (char*) alloc_root(root,Size);
return ptr;
}

View File

@ -97,8 +97,9 @@ void die(const char *file, int line, const char *expr)
#define myerror(msg) print_error(msg)
#define mysterror(stmt, msg) print_st_error(stmt, msg)
#define myquery(r) \
#define myquery(RES) \
{ \
int r= (RES); \
if (r) \
myerror(NULL); \
DIE_UNLESS(r == 0); \
@ -282,38 +283,40 @@ static void client_query()
myheader("client_query");
rc= mysql_query(mysql, "DROP TABLE IF EXISTS myclient_test");
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
myquery(rc);
rc= mysql_query(mysql, "CREATE TABLE myclient_test("
rc= mysql_query(mysql, "CREATE TABLE t1("
"id int primary key auto_increment, "
"name varchar(20))");
myquery(rc);
rc= mysql_query(mysql, "CREATE TABLE myclient_test(id int, name varchar(20))");
rc= mysql_query(mysql, "CREATE TABLE t1(id int, name varchar(20))");
myquery_r(rc);
rc= mysql_query(mysql, "INSERT INTO myclient_test(name) VALUES('mysql')");
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('mysql')");
myquery(rc);
rc= mysql_query(mysql, "INSERT INTO myclient_test(name) VALUES('monty')");
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('monty')");
myquery(rc);
rc= mysql_query(mysql, "INSERT INTO myclient_test(name) VALUES('venu')");
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('venu')");
myquery(rc);
rc= mysql_query(mysql, "INSERT INTO myclient_test(name) VALUES('deleted')");
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
myquery(rc);
rc= mysql_query(mysql, "INSERT INTO myclient_test(name) VALUES('deleted')");
rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
myquery(rc);
rc= mysql_query(mysql, "UPDATE myclient_test SET name= 'updated' "
rc= mysql_query(mysql, "UPDATE t1 SET name= 'updated' "
"WHERE name= 'deleted'");
myquery(rc);
rc= mysql_query(mysql, "UPDATE myclient_test SET id= 3 WHERE name= 'updated'");
rc= mysql_query(mysql, "UPDATE t1 SET id= 3 WHERE name= 'updated'");
myquery_r(rc);
myquery(mysql_query(mysql, "drop table t1"));
}
@ -743,7 +746,7 @@ static void client_store_result()
myheader("client_store_result");
rc= mysql_query(mysql, "SELECT * FROM myclient_test");
rc= mysql_query(mysql, "SELECT * FROM t1");
myquery(rc);
/* get the result */
@ -763,7 +766,7 @@ static void client_use_result()
int rc;
myheader("client_use_result");
rc= mysql_query(mysql, "SELECT * FROM myclient_test");
rc= mysql_query(mysql, "SELECT * FROM t1");
myquery(rc);
/* get the result */
@ -7537,17 +7540,17 @@ static void test_fetch_seek()
char c2[11], c3[20];
myheader("test_fetch_seek");
rc= mysql_query(mysql, "drop table if exists t1");
rc= mysql_query(mysql, "drop table if exists test_seek");
myquery(rc);
rc= mysql_query(mysql, "create table test_seek(c1 int primary key auto_increment, c2 char(10), c3 timestamp(14))");
rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp(14))");
myquery(rc);
rc= mysql_query(mysql, "insert into test_seek(c2) values('venu'), ('mysql'), ('open'), ('source')");
rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql'), ('open'), ('source')");
myquery(rc);
stmt= mysql_simple_prepare(mysql, "select * from test_seek");
stmt= mysql_simple_prepare(mysql, "select * from t1");
check_stmt(stmt);
bind[0].buffer_type= MYSQL_TYPE_LONG;
@ -7620,6 +7623,7 @@ static void test_fetch_seek()
DIE_UNLESS(rc == MYSQL_NO_DATA);
mysql_stmt_close(stmt);
myquery(mysql_query(mysql, "drop table t1"));
}
@ -7637,16 +7641,16 @@ static void test_fetch_offset()
myheader("test_fetch_offset");
rc= mysql_query(mysql, "drop table if exists test_column");
rc= mysql_query(mysql, "drop table if exists t1");
myquery(rc);
rc= mysql_query(mysql, "create table test_column(a char(10))");
rc= mysql_query(mysql, "create table t1(a char(10))");
myquery(rc);
rc= mysql_query(mysql, "insert into test_column values('abcdefghij'), (null)");
rc= mysql_query(mysql, "insert into t1 values('abcdefghij'), (null)");
myquery(rc);
stmt= mysql_simple_prepare(mysql, "select * from test_column");
stmt= mysql_simple_prepare(mysql, "select * from t1");
check_stmt(stmt);
bind[0].buffer_type= MYSQL_TYPE_STRING;
@ -7706,6 +7710,8 @@ static void test_fetch_offset()
check_execute_r(stmt, rc);
mysql_stmt_close(stmt);
myquery(mysql_query(mysql, "drop table t1"));
}
@ -7721,16 +7727,16 @@ static void test_fetch_column()
myheader("test_fetch_column");
rc= mysql_query(mysql, "drop table if exists test_column");
rc= mysql_query(mysql, "drop table if exists t1");
myquery(rc);
rc= mysql_query(mysql, "create table test_column(c1 int primary key auto_increment, c2 char(10))");
rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10))");
myquery(rc);
rc= mysql_query(mysql, "insert into test_column(c2) values('venu'), ('mysql')");
rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql')");
myquery(rc);
stmt= mysql_simple_prepare(mysql, "select * from test_column order by c2 desc");
stmt= mysql_simple_prepare(mysql, "select * from t1 order by c2 desc");
check_stmt(stmt);
bind[0].buffer_type= MYSQL_TYPE_LONG;
@ -7841,6 +7847,7 @@ static void test_fetch_column()
check_execute_r(stmt, rc);
mysql_stmt_close(stmt);
myquery(mysql_query(mysql, "drop table t1"));
}
@ -7852,27 +7859,28 @@ static void test_list_fields()
int rc;
myheader("test_list_fields");
rc= mysql_query(mysql, "drop table if exists test_list_fields");
rc= mysql_query(mysql, "drop table if exists t1");
myquery(rc);
rc= mysql_query(mysql, "create table test_list_fields(c1 int primary key auto_increment, c2 char(10) default 'mysql')");
rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10) default 'mysql')");
myquery(rc);
result= mysql_list_fields(mysql, "test_list_fields", NULL);
result= mysql_list_fields(mysql, "t1", NULL);
mytest(result);
rc= my_process_result_set(result);
DIE_UNLESS(rc == 0);
verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_LONG,
"test_list_fields", "test_list_fields",
"t1", "t1",
current_db, 11, "0");
verify_prepare_field(result, 1, "c2", "c2", MYSQL_TYPE_STRING,
"test_list_fields", "test_list_fields",
"t1", "t1",
current_db, 10, "mysql");
mysql_free_result(result);
myquery(mysql_query(mysql, "drop table t1"));
}
@ -11140,11 +11148,13 @@ static void test_bug4172()
res= mysql_store_result(mysql);
row= mysql_fetch_row(res);
if (!opt_silent)
{
printf("Binary protocol: float=%s, double=%s, decimal(10,4)=%s\n",
f, d, e);
printf("Text protocol: float=%s, double=%s, decimal(10,4)=%s\n",
row[0], row[1], row[2]);
}
DIE_UNLESS(!strcmp(f, row[0]) && !strcmp(d, row[1]) && !strcmp(e, row[2]));
mysql_free_result(res);