Commit 7f5d7d47 authored by patg@radha.local's avatar patg@radha.local

Merge pgalbraith@bk-internal.mysql.com:/home/bk/mysql-5.0

into radha.local:/Volumes/disk2s1/mysql-5.0
parents 144045ff 6a0adade
...@@ -156,9 +156,15 @@ bool foreign_key_prefix(Key *a, Key *b) ...@@ -156,9 +156,15 @@ bool foreign_key_prefix(Key *a, Key *b)
/**************************************************************************** /****************************************************************************
** Thread specific functions ** Thread specific functions
****************************************************************************/ ****************************************************************************/
/*
Pass nominal parameters to Statement constructor only to ensure that
the destructor works OK in case of error. The main_mem_root will be
re-initialized in init().
*/
THD::THD() THD::THD()
:user_time(0), global_read_lock(0), is_fatal_error(0), :Statement(CONVENTIONAL_EXECUTION, 0, ALLOC_ROOT_MIN_BLOCK_SIZE, 0),
user_time(0), global_read_lock(0), is_fatal_error(0),
rand_used(0), time_zone_used(0), rand_used(0), time_zone_used(0),
last_insert_id_used(0), insert_id_used(0), clear_next_insert_id(0), last_insert_id_used(0), insert_id_used(0), clear_next_insert_id(0),
in_lock_tables(0), bootstrap(0), derived_tables_processing(FALSE), in_lock_tables(0), bootstrap(0), derived_tables_processing(FALSE),
...@@ -1483,9 +1489,10 @@ Query_arena::Type Query_arena::type() const ...@@ -1483,9 +1489,10 @@ Query_arena::Type Query_arena::type() const
Statement functions Statement functions
*/ */
Statement::Statement(THD *thd) Statement::Statement(enum enum_state state_arg, ulong id_arg,
:Query_arena(&main_mem_root, INITIALIZED), ulong alloc_block_size, ulong prealloc_size)
id(++thd->statement_id_counter), :Query_arena(&main_mem_root, state_arg),
id(id_arg),
set_query_id(1), set_query_id(1),
allow_sum_func(0), allow_sum_func(0),
lex(&main_lex), lex(&main_lex),
...@@ -1494,33 +1501,7 @@ Statement::Statement(THD *thd) ...@@ -1494,33 +1501,7 @@ Statement::Statement(THD *thd)
cursor(0) cursor(0)
{ {
name.str= NULL; name.str= NULL;
init_sql_alloc(&main_mem_root, init_sql_alloc(&main_mem_root, alloc_block_size, prealloc_size);
thd->variables.query_alloc_block_size,
thd->variables.query_prealloc_size);
}
/*
This constructor is called when Statement is a parent of THD and
for the backup statement. Some variables are initialized in
THD::init due to locking problems.
*/
Statement::Statement()
:Query_arena(&main_mem_root, CONVENTIONAL_EXECUTION),
id(0),
set_query_id(1),
allow_sum_func(0), /* initialized later */
lex(&main_lex),
query(0), /* these two are set */
query_length(0), /* in alloc_query() */
cursor(0)
{
/*
This is just to ensure that the destructor works correctly in
case of an error and the backup statement. The memory root will
be re-initialized in THD::init.
*/
init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0);
} }
......
...@@ -809,13 +809,11 @@ public: ...@@ -809,13 +809,11 @@ public:
public: public:
/* /* This constructor is called for backup statements */
This constructor is called when statement is a subobject of THD: Statement() { clear_alloc_root(&main_mem_root); }
some variables are initialized in THD::init due to locking problems
*/
Statement();
Statement(THD *thd); Statement(enum enum_state state_arg, ulong id_arg,
ulong alloc_block_size, ulong prealloc_size);
virtual ~Statement(); virtual ~Statement();
/* Assign execution context (note: not all members) of given stmt to self */ /* Assign execution context (note: not all members) of given stmt to self */
...@@ -957,11 +955,6 @@ public: ...@@ -957,11 +955,6 @@ public:
pthread_mutex_t LOCK_delete; // Locked before thd is deleted pthread_mutex_t LOCK_delete; // Locked before thd is deleted
/* all prepared statements and cursors of this connection */ /* all prepared statements and cursors of this connection */
Statement_map stmt_map; Statement_map stmt_map;
/*
keeps THD state while it is used for active statement
Note: we perform special cleanup for it in THD destructor.
*/
Statement stmt_backup;
/* /*
A pointer to the stack frame of handle_one_connection(), A pointer to the stack frame of handle_one_connection(),
which is called first in the thread for handling a client which is called first in the thread for handling a client
......
...@@ -1706,6 +1706,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, ...@@ -1706,6 +1706,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
LEX_STRING *name) LEX_STRING *name)
{ {
LEX *lex; LEX *lex;
Statement stmt_backup;
Prepared_statement *stmt= new Prepared_statement(thd); Prepared_statement *stmt= new Prepared_statement(thd);
bool error; bool error;
DBUG_ENTER("mysql_stmt_prepare"); DBUG_ENTER("mysql_stmt_prepare");
...@@ -1739,13 +1740,13 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, ...@@ -1739,13 +1740,13 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
thd->set_n_backup_statement(stmt, &thd->stmt_backup); thd->set_n_backup_statement(stmt, &stmt_backup);
thd->set_n_backup_item_arena(stmt, &thd->stmt_backup); thd->set_n_backup_item_arena(stmt, &stmt_backup);
if (alloc_query(thd, packet, packet_length)) if (alloc_query(thd, packet, packet_length))
{ {
thd->restore_backup_statement(stmt, &thd->stmt_backup); thd->restore_backup_statement(stmt, &stmt_backup);
thd->restore_backup_item_arena(stmt, &thd->stmt_backup); thd->restore_backup_item_arena(stmt, &stmt_backup);
/* Statement map deletes statement on erase */ /* Statement map deletes statement on erase */
thd->stmt_map.erase(stmt); thd->stmt_map.erase(stmt);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
...@@ -1770,7 +1771,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, ...@@ -1770,7 +1771,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
transformation can be reused on execute, we set again thd->mem_root from transformation can be reused on execute, we set again thd->mem_root from
stmt->mem_root (see setup_wild for one place where we do that). stmt->mem_root (see setup_wild for one place where we do that).
*/ */
thd->restore_backup_item_arena(stmt, &thd->stmt_backup); thd->restore_backup_item_arena(stmt, &stmt_backup);
if (!error) if (!error)
error= check_prepared_statement(stmt, test(name)); error= check_prepared_statement(stmt, test(name));
...@@ -1786,7 +1787,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, ...@@ -1786,7 +1787,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
lex_end(lex); lex_end(lex);
close_thread_tables(thd); close_thread_tables(thd);
cleanup_stmt_and_thd_after_use(stmt, thd); cleanup_stmt_and_thd_after_use(stmt, thd);
thd->restore_backup_statement(stmt, &thd->stmt_backup); thd->restore_backup_statement(stmt, &stmt_backup);
thd->current_arena= thd; thd->current_arena= thd;
if (error) if (error)
...@@ -1949,6 +1950,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) ...@@ -1949,6 +1950,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
{ {
ulong stmt_id= uint4korr(packet); ulong stmt_id= uint4korr(packet);
ulong flags= (ulong) ((uchar) packet[4]); ulong flags= (ulong) ((uchar) packet[4]);
Statement stmt_backup;
Cursor *cursor; Cursor *cursor;
/* /*
Query text for binary log, or empty string if the query is not put into Query text for binary log, or empty string if the query is not put into
...@@ -2026,8 +2028,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) ...@@ -2026,8 +2028,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
if (stmt->param_count && stmt->set_params_data(stmt, &expanded_query)) if (stmt->param_count && stmt->set_params_data(stmt, &expanded_query))
goto set_params_data_err; goto set_params_data_err;
#endif #endif
thd->stmt_backup.set_statement(thd); thd->set_n_backup_statement(stmt, &stmt_backup);
thd->set_statement(stmt);
thd->current_arena= stmt; thd->current_arena= stmt;
reinit_stmt_before_use(thd, stmt->lex); reinit_stmt_before_use(thd, stmt->lex);
/* From now cursors assume that thd->mem_root is clean */ /* From now cursors assume that thd->mem_root is clean */
...@@ -2064,7 +2065,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) ...@@ -2064,7 +2065,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
reset_stmt_params(stmt); reset_stmt_params(stmt);
} }
thd->set_statement(&thd->stmt_backup); thd->set_statement(&stmt_backup);
thd->current_arena= thd; thd->current_arena= thd;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -2089,6 +2090,7 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name) ...@@ -2089,6 +2090,7 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
binary log. binary log.
*/ */
String expanded_query; String expanded_query;
Statement stmt_backup;
DBUG_ENTER("mysql_sql_stmt_execute"); DBUG_ENTER("mysql_sql_stmt_execute");
DBUG_ASSERT(thd->free_list == NULL); DBUG_ASSERT(thd->free_list == NULL);
...@@ -2110,16 +2112,16 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name) ...@@ -2110,16 +2112,16 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
/* Must go before setting variables, as it clears thd->user_var_events */ /* Must go before setting variables, as it clears thd->user_var_events */
mysql_reset_thd_for_next_command(thd); mysql_reset_thd_for_next_command(thd);
thd->set_n_backup_statement(stmt, &thd->stmt_backup); thd->set_n_backup_statement(stmt, &stmt_backup);
thd->set_statement(stmt);
if (stmt->set_params_from_vars(stmt, if (stmt->set_params_from_vars(stmt,
thd->stmt_backup.lex->prepared_stmt_params, stmt_backup.lex->prepared_stmt_params,
&expanded_query)) &expanded_query))
{ {
my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE"); my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
} }
thd->command= COM_STMT_EXECUTE; /* For nice messages in general log */ thd->command= COM_STMT_EXECUTE; /* For nice messages in general log */
execute_stmt(thd, stmt, &expanded_query); execute_stmt(thd, stmt, &expanded_query);
thd->set_statement(&stmt_backup);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -2176,7 +2178,6 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, ...@@ -2176,7 +2178,6 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
close_thread_tables(thd); // to close derived tables close_thread_tables(thd); // to close derived tables
cleanup_stmt_and_thd_after_use(stmt, thd); cleanup_stmt_and_thd_after_use(stmt, thd);
reset_stmt_params(stmt); reset_stmt_params(stmt);
thd->set_statement(&thd->stmt_backup);
thd->current_arena= thd; thd->current_arena= thd;
if (stmt->state == Query_arena::PREPARED) if (stmt->state == Query_arena::PREPARED)
...@@ -2201,6 +2202,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) ...@@ -2201,6 +2202,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
ulong stmt_id= uint4korr(packet); ulong stmt_id= uint4korr(packet);
ulong num_rows= uint4korr(packet+4); ulong num_rows= uint4korr(packet+4);
Prepared_statement *stmt; Prepared_statement *stmt;
Statement stmt_backup;
DBUG_ENTER("mysql_stmt_fetch"); DBUG_ENTER("mysql_stmt_fetch");
statistic_increment(thd->status_var.com_stmt_fetch, &LOCK_status); statistic_increment(thd->status_var.com_stmt_fetch, &LOCK_status);
...@@ -2214,7 +2216,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) ...@@ -2214,7 +2216,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
} }
thd->current_arena= stmt; thd->current_arena= stmt;
thd->set_n_backup_statement(stmt, &thd->stmt_backup); thd->set_n_backup_statement(stmt, &stmt_backup);
if (!(specialflag & SPECIAL_NO_PRIOR)) if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), QUERY_PRIOR); my_pthread_setprio(pthread_self(), QUERY_PRIOR);
...@@ -2226,7 +2228,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length) ...@@ -2226,7 +2228,7 @@ void mysql_stmt_fetch(THD *thd, char *packet, uint packet_length)
if (!(specialflag & SPECIAL_NO_PRIOR)) if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR); my_pthread_setprio(pthread_self(), WAIT_PRIOR);
thd->restore_backup_statement(stmt, &thd->stmt_backup); thd->restore_backup_statement(stmt, &stmt_backup);
thd->current_arena= thd; thd->current_arena= thd;
if (!stmt->cursor->is_open()) if (!stmt->cursor->is_open())
...@@ -2386,7 +2388,9 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) ...@@ -2386,7 +2388,9 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
Prepared_statement::Prepared_statement(THD *thd_arg) Prepared_statement::Prepared_statement(THD *thd_arg)
:Statement(thd_arg), :Statement(INITIALIZED, ++thd_arg->statement_id_counter,
thd_arg->variables.query_alloc_block_size,
thd_arg->variables.query_prealloc_size),
thd(thd_arg), thd(thd_arg),
param_array(0), param_array(0),
param_count(0), param_count(0),
......
...@@ -1824,6 +1824,7 @@ Cursor::fetch(ulong num_rows) ...@@ -1824,6 +1824,7 @@ 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;
enum_nested_loop_state error= NESTED_LOOP_OK; enum_nested_loop_state error= NESTED_LOOP_OK;
Query_arena backup_arena;
DBUG_ENTER("Cursor::fetch"); DBUG_ENTER("Cursor::fetch");
DBUG_PRINT("enter",("rows: %lu", num_rows)); DBUG_PRINT("enter",("rows: %lu", num_rows));
...@@ -1835,7 +1836,7 @@ Cursor::fetch(ulong num_rows) ...@@ -1835,7 +1836,7 @@ Cursor::fetch(ulong num_rows)
thd->lock= lock; thd->lock= lock;
thd->query_id= query_id; thd->query_id= query_id;
/* save references to memory, allocated during fetch */ /* save references to memory, allocated during fetch */
thd->set_n_backup_item_arena(this, &thd->stmt_backup); thd->set_n_backup_item_arena(this, &backup_arena);
join->fetch_limit+= num_rows; join->fetch_limit+= num_rows;
...@@ -1851,7 +1852,7 @@ Cursor::fetch(ulong num_rows) ...@@ -1851,7 +1852,7 @@ Cursor::fetch(ulong num_rows)
ha_release_temporary_latches(thd); ha_release_temporary_latches(thd);
#endif #endif
thd->restore_backup_item_arena(this, &thd->stmt_backup); thd->restore_backup_item_arena(this, &backup_arena);
DBUG_ASSERT(thd->free_list == 0); DBUG_ASSERT(thd->free_list == 0);
reset_thd(thd); reset_thd(thd);
......
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