summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <konstantin@bodhi.netgear>2006-07-06 23:59:04 +0400
committerunknown <konstantin@bodhi.netgear>2006-07-06 23:59:04 +0400
commit6f73fca1f03c64d2db44ae37a915c081e8d25a24 (patch)
tree3688ab01357b1d5fa6a6f036bd6ed40206160dc4 /sql
parentef318ff8a35926f42fa18caf8cf8f0a1a7678112 (diff)
downloadmariadb-git-6f73fca1f03c64d2db44ae37a915c081e8d25a24.tar.gz
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().
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_prepare.cc20
-rw-r--r--sql/table.cc17
-rw-r--r--sql/table.h5
4 files changed, 36 insertions, 7 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 29ea8ab2ae2..fb9a765f12c 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -125,6 +125,7 @@ void lex_start(THD *thd, uchar *buf,uint length)
lex->value_list.empty();
lex->update_list.empty();
lex->param_list.empty();
+ lex->auxilliary_table_list.empty();
lex->unit.next= lex->unit.master=
lex->unit.link_next= lex->unit.return_to= 0;
lex->unit.prev= lex->unit.link_prev= 0;
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();
diff --git a/sql/table.cc b/sql/table.cc
index 513f42665a6..26da6dc4605 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1523,6 +1523,23 @@ db_type get_table_type(const char *name)
DBUG_RETURN(ha_checktype((enum db_type) (uint) *(head+3)));
}
+/*
+ Cleanup this table for re-execution.
+
+ SYNOPSIS
+ st_table_list::reinit_before_use()
+*/
+
+void st_table_list::reinit_before_use(THD * /* thd */)
+{
+ /*
+ Reset old pointers to TABLEs: they are not valid since the tables
+ were closed in the end of previous prepare or execute call.
+ */
+ table= 0;
+ table_list= 0;
+}
+
/*****************************************************************************
** Instansiate templates
diff --git a/sql/table.h b/sql/table.h
index 8cb15d3a69c..d615623cc37 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -238,6 +238,11 @@ typedef struct st_table_list
bool cacheable_table; /* stop PS caching */
/* used in multi-upd privelege check */
bool table_in_update_from_clause;
+ /*
+ Cleanup for re-execution in a prepared statement or a stored
+ procedure.
+ */
+ void reinit_before_use(THD *thd);
} TABLE_LIST;
typedef struct st_changed_table_list