diff options
author | unknown <konstantin@mysql.com> | 2004-08-24 20:17:11 +0400 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2004-08-24 20:17:11 +0400 |
commit | 49bd559eb8f041de97e4ef55f280f3806d1b6c42 (patch) | |
tree | abcc02d1c616c2795f2ca78dd7032b01d865d0ce /sql/sql_prepare.cc | |
parent | 83e3d3f9a3ab6888292b8bcb15e0f77f00249289 (diff) | |
download | mariadb-git-49bd559eb8f041de97e4ef55f280f3806d1b6c42.tar.gz |
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
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r-- | sql/sql_prepare.cc | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 850d41a030b..6d494b83535 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -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; } |