mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
Fix for Bug#5034 "prepared "select 1 into @arg15", second
execute crashes server": we were deleting lex->result
after each execute, but prepared statements assumed that
it's left intact.
The fix adds cleanup() method to select_result hierarchy,
so that result objects can be reused.
Plus we now need to delete result objects more wisely.
mysql-test/r/ps.result:
Test results fixed: test case for bug#5034
mysql-test/t/ps.test:
A test case for bug#5034, few followups
sql/sql_class.cc:
- fix warning in THD::THD
- implementation of cleanup() for select_result hierarchy
- select_export::send_eof was identical to
select_dump::send_eof: moved to the base class select_to_file.
- Statement::end_statement() to end lex, free items, and
delete possible select_result
sql/sql_class.h:
- select_result::cleanup() declaration
-
sql/sql_insert.cc:
- implementation of select_insert::cleanup(): currently
we always create a new instance of select_insert/
select_create on each execute.
sql/sql_lex.cc:
- with more complicated logic of freeing lex->result it's
easier to have it non-zero only if it points to a valid
result.
sql/sql_lex.h:
Now st_lex::st_lex is not empty.
sql/sql_parse.cc:
mysql_execute_command():
- delete select_result *result only if it was created in
this function.
- use end_statement() to cleanup lex and thd in the end of
each statement.
- no need to save THD::lock if this is explain. This save
apparently left from times when derived tables were
materialized here, not in open_and_lock_tables.
sql/sql_prepare.cc:
- call result->cleanup() in reset_stmt_for_execute
- now Statement is responsible for freeing its lex->result.
sql/sql_select.cc:
handle_select():
- don't delete result, it might be needed
for next executions
- result is never null
This commit is contained in:
@@ -1630,7 +1630,8 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
|
||||
static void reset_stmt_for_execute(Prepared_statement *stmt)
|
||||
{
|
||||
THD *thd= stmt->thd;
|
||||
SELECT_LEX *sl= stmt->lex->all_selects_list;
|
||||
LEX *lex= stmt->lex;
|
||||
SELECT_LEX *sl= lex->all_selects_list;
|
||||
|
||||
for (; sl; sl= sl->next_select_in_list())
|
||||
{
|
||||
@@ -1678,7 +1679,9 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
|
||||
unit->reinit_exec_mechanism();
|
||||
}
|
||||
}
|
||||
stmt->lex->current_select= &stmt->lex->select_lex;
|
||||
lex->current_select= &lex->select_lex;
|
||||
if (lex->result)
|
||||
lex->result->cleanup();
|
||||
}
|
||||
|
||||
|
||||
@@ -2053,6 +2056,7 @@ void Prepared_statement::setup_set_params()
|
||||
Prepared_statement::~Prepared_statement()
|
||||
{
|
||||
free_items(free_list);
|
||||
delete lex->result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user