From 8995277acc05f9998e9f7a24aa8cb9e1d917945e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 6 Jul 2006 23:59:04 +0400 Subject: A fix and a test case for Bug#19399 "res 'Lost Connection' when dropping/creating tables". The bug could lead to a crash when multi-delete statements were prepared and used with temporary tables. The bug was caused by lack of clean-up of multi-delete tables before re-execution of a prepared statement. In a statement like DELETE t1 FROM t1, t2 WHERE ... the first table list (t1) is moved to lex->auxilliary_table_list and excluded from lex->query_tables or select_lex->tables. Thus it was unaccessible to reinit_stmt_before_use and not cleaned up before re-execution of a prepared statement. mysql-test/r/ps.result: Updated test results (Bug#19399) mysql-test/t/ps.test: A test case for Bug#19399 "Stored Procedures 'Lost Connection' when dropping/creating tables": test that multi-delete tables are cleaned up properly before re-execution. sql/sql_lex.cc: Always initialize auxilliary_table_list when we initialize the lex: this way we don't have to check that lex->sql_command equals to SQLCOM_DELETE_MULTI whenever we need to access auxilliary_table_list. In particular, in reinit_stmt_before_use we can simply check that auxilliary_table_list is not NULL and clean it up if the check returns a true value. sql/sql_prepare.cc: Move the one table clean-up functionality to a method of st_table_list. Clean up auxiliary_table_list if it's not empty. sql/table.cc: Implement st_table_list::reinit_before_use(). sql/table.h: Declare st_table_list::reinit_before_use(). --- sql/sql_prepare.cc | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'sql/sql_prepare.cc') diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 2d9e80df63c..2688841d96c 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1727,14 +1727,9 @@ static void reset_stmt_for_execute(Prepared_statement *stmt) tables; tables= tables->next) { - /* - Reset old pointers to TABLEs: they are not valid since the tables - were closed in the end of previous prepare or execute call. - */ - tables->table= 0; - tables->table_list= 0; + tables->reinit_before_use(thd); } - + { SELECT_LEX_UNIT *unit= sl->master_unit(); unit->unclean(); @@ -1743,6 +1738,17 @@ static void reset_stmt_for_execute(Prepared_statement *stmt) unit->reinit_exec_mechanism(); } } + /* + Cleanup of the special case of DELETE t1, t2 FROM t1, t2, t3 ... + (multi-delete). We do a full clean up, although at the moment all we + need to clean in the tables of MULTI-DELETE list is 'table' member. + */ + for (TABLE_LIST *tables= (TABLE_LIST*) lex->auxilliary_table_list.first; + tables; + tables= tables->next) + { + tables->reinit_before_use(thd); + } lex->current_select= &lex->select_lex; if (lex->result) lex->result->cleanup(); -- cgit v1.2.1