#At file:///export/home/tmp/ss156133/z/43560-51g/ based on
revid:pstoev@stripped
2884 Staale Smedseng 2009-05-15
Bug #43560 client crashes in mysql_stmt_execute/
mysql_stmt_close after connection loss
The invalidation of client-side prepared statments
in the event of connection loss is now factored out
into a new function mysql_prune_stmt_list(). This
is now used in conjunction with the end_server()
function, rather than after-the-fact in
mysql_reconnect() as was previously the case.
@ libmysql/client_settings.h
Declaration of new function mysql_prune_stmt_list().
@ sql-common/client.c
Definition and use of new function mysql_prune_stmt_list().
Removal of previously used code in mysql_reconnect().
modified:
libmysql/client_settings.h
sql-common/client.c
=== modified file 'libmysql/client_settings.h'
--- a/libmysql/client_settings.h 2007-09-29 19:31:08 +0000
+++ b/libmysql/client_settings.h 2009-05-15 10:14:12 +0000
@@ -41,6 +41,7 @@ my_bool handle_local_infile(MYSQL *mysql
void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group);
+void mysql_prune_stmt_list(MYSQL *mysql);
void mysql_detach_stmt_list(LIST **stmt_list, const char *func_name);
MYSQL * STDCALL
cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
=== modified file 'sql-common/client.c'
--- a/sql-common/client.c 2009-03-19 13:42:36 +0000
+++ b/sql-common/client.c 2009-05-15 10:14:12 +0000
@@ -924,6 +924,7 @@ void end_server(MYSQL *mysql)
vio_delete(mysql->net.vio);
reset_sigpipe(mysql);
mysql->net.vio= 0; /* Marker */
+ mysql_prune_stmt_list(mysql);
}
net_end(&mysql->net);
free_old_query(mysql);
@@ -2526,31 +2527,6 @@ my_bool mysql_reconnect(MYSQL *mysql)
tmp_mysql.reconnect= 1;
tmp_mysql.free_me= mysql->free_me;
- /*
- For each stmt in mysql->stmts, move it to tmp_mysql if it is
- in state MYSQL_STMT_INIT_DONE, otherwise close it.
- */
- {
- LIST *element= mysql->stmts;
- for (; element; element= element->next)
- {
- MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
- if (stmt->state != MYSQL_STMT_INIT_DONE)
- {
- stmt->mysql= 0;
- stmt->last_errno= CR_SERVER_LOST;
- strmov(stmt->last_error, ER(CR_SERVER_LOST));
- strmov(stmt->sqlstate, unknown_sqlstate);
- }
- else
- {
- tmp_mysql.stmts= list_add(tmp_mysql.stmts, &stmt->list);
- }
- /* No need to call list_delete for statement here */
- }
- mysql->stmts= NULL;
- }
-
/* Don't free options as these are now used in tmp_mysql */
bzero((char*) &mysql->options,sizeof(mysql->options));
mysql->free_me=0;
@@ -2638,6 +2614,44 @@ static void mysql_close_free(MYSQL *mysq
mysql->host_info= mysql->user= mysql->passwd= mysql->db= 0;
}
+/**
+ For use when the connection to the server has been lost (in which case
+ the server has discarded all information about prepared statements
+ associated with the connection).
+
+ Mark all statements in mysql->stmts by setting stmt->mysql= 0 if the
+ statement has transitioned beyond the MYSQL_STMT_INIT_DONE state, and
+ unlink the statement from the mysql->stmts list.
+
+ The remaining pruned list of statements (if any) is kept in mysql->stmts.
+
+ @param mysql pointer to the MYSQL object
+
+ @return none
+*/
+void mysql_prune_stmt_list(MYSQL *mysql)
+{
+ LIST *element= mysql->stmts;
+ LIST *pruned_list= 0;
+
+ for (; element; element= element->next)
+ {
+ MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
+ if (stmt->state != MYSQL_STMT_INIT_DONE)
+ {
+ stmt->mysql= 0;
+ stmt->last_errno= CR_SERVER_LOST;
+ strmov(stmt->last_error, ER(CR_SERVER_LOST));
+ strmov(stmt->sqlstate, unknown_sqlstate);
+ }
+ else
+ {
+ pruned_list= list_add(pruned_list, element);
+ }
+ }
+
+ mysql->stmts= pruned_list;
+}
/*
Clear connection pointer of every statement: this is necessary
Attachment: [text/bzr-bundle] bzr/staale.smedseng@sun.com-20090515101412-w8jso9ty5609dst4.bundle