Ensure we free all items for prepared statements
Before the fix in ~Prepared_statments we got a memory leak when executing mysql_client_test.test Note that test 'variables.test' fails. This will be fixed when Jimw pushes the fix for Bug 10351
This commit is contained in:
parent
16853d5f14
commit
e60d786dde
@ -1023,7 +1023,7 @@ static void init_default_directories()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/' No parent directory (strange). Use current dir + '\' '*/
|
/* No parent directory (strange). Use current dir + '\' */
|
||||||
last[1]= 0;
|
last[1]= 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2188,6 +2188,7 @@ bool Item_param::set_from_user_var(THD *thd, const user_var_entry *entry)
|
|||||||
|
|
||||||
void Item_param::reset()
|
void Item_param::reset()
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("Item_param::reset");
|
||||||
/* Shrink string buffer if it's bigger than max possible CHAR column */
|
/* Shrink string buffer if it's bigger than max possible CHAR column */
|
||||||
if (str_value.alloced_length() > MAX_CHAR_WIDTH)
|
if (str_value.alloced_length() > MAX_CHAR_WIDTH)
|
||||||
str_value.free();
|
str_value.free();
|
||||||
@ -2212,6 +2213,7 @@ void Item_param::reset()
|
|||||||
DBUG_ASSERTS(state != NO_VALUE) in all Item_param::get_*
|
DBUG_ASSERTS(state != NO_VALUE) in all Item_param::get_*
|
||||||
methods).
|
methods).
|
||||||
*/
|
*/
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1682,10 +1682,12 @@ static bool init_param_array(Prepared_statement *stmt)
|
|||||||
|
|
||||||
static void cleanup_stmt_and_thd_after_use(Statement *stmt, THD *thd)
|
static void cleanup_stmt_and_thd_after_use(Statement *stmt, THD *thd)
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("cleanup_stmt_and_thd_after_use");
|
||||||
stmt->lex->unit.cleanup();
|
stmt->lex->unit.cleanup();
|
||||||
cleanup_items(stmt->free_list);
|
cleanup_items(stmt->free_list);
|
||||||
thd->rollback_item_tree_changes();
|
thd->rollback_item_tree_changes();
|
||||||
thd->cleanup_after_query();
|
thd->cleanup_after_query();
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1982,7 +1984,8 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
|
|||||||
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
|
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
|
|
||||||
DBUG_PRINT("exec_query:", ("%s", stmt->query));
|
DBUG_PRINT("exec_query", ("%s", stmt->query));
|
||||||
|
DBUG_PRINT("info",("stmt: %p", stmt));
|
||||||
|
|
||||||
/* Check if we got an error when sending long data */
|
/* Check if we got an error when sending long data */
|
||||||
if (stmt->state == Query_arena::ERROR)
|
if (stmt->state == Query_arena::ERROR)
|
||||||
@ -2125,6 +2128,8 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DBUG_PRINT("info",("stmt: %p", stmt));
|
||||||
|
|
||||||
/* 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, &stmt_backup);
|
thd->set_n_backup_statement(stmt, &stmt_backup);
|
||||||
@ -2445,19 +2450,26 @@ void Prepared_statement::setup_set_params()
|
|||||||
|
|
||||||
Prepared_statement::~Prepared_statement()
|
Prepared_statement::~Prepared_statement()
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("Prepared_statement::~Prepared_statement");
|
||||||
|
DBUG_PRINT("enter",("stmt: %p cursor: %p", this, cursor));
|
||||||
if (cursor)
|
if (cursor)
|
||||||
{
|
{
|
||||||
if (cursor->is_open())
|
if (cursor->is_open())
|
||||||
{
|
{
|
||||||
cursor->close(FALSE);
|
cursor->close(FALSE);
|
||||||
free_items();
|
cleanup_items(free_list);
|
||||||
|
thd->rollback_item_tree_changes();
|
||||||
free_root(cursor->mem_root, MYF(0));
|
free_root(cursor->mem_root, MYF(0));
|
||||||
}
|
}
|
||||||
cursor->Cursor::~Cursor();
|
cursor->Cursor::~Cursor();
|
||||||
}
|
}
|
||||||
else
|
/*
|
||||||
free_items();
|
We have to call free on the items even if cleanup is called as some items,
|
||||||
|
like Item_param, don't free everything until free_items()
|
||||||
|
*/
|
||||||
|
free_items();
|
||||||
delete lex->result;
|
delete lex->result;
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2469,6 +2481,9 @@ Query_arena::Type Prepared_statement::type() const
|
|||||||
|
|
||||||
void Prepared_statement::close_cursor()
|
void Prepared_statement::close_cursor()
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("Prepared_statement::close_cursor");
|
||||||
|
DBUG_PRINT("enter",("stmt: %p", this));
|
||||||
|
|
||||||
if (cursor && cursor->is_open())
|
if (cursor && cursor->is_open())
|
||||||
{
|
{
|
||||||
thd->change_list= cursor->change_list;
|
thd->change_list= cursor->change_list;
|
||||||
@ -2483,4 +2498,5 @@ void Prepared_statement::close_cursor()
|
|||||||
mysql_stmt_send_long_data() call.
|
mysql_stmt_send_long_data() call.
|
||||||
*/
|
*/
|
||||||
reset_stmt_params(this);
|
reset_stmt_params(this);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user