From 3154b2bee4dc99b3313081effe2ac9c4c4a487f9 Mon Sep 17 00:00:00 2001
From: "kostja@bodhi.(none)" <>
Date: Wed, 31 Oct 2007 18:33:13 +0300
Subject: [PATCH] Cleanup: rename select_send::status to
 select_send::is_result_set_started. Add select_send::cleanup. Fix a
 compilation warning. Issues spotted while working on the fix for Bug#12713.

---
 sql-common/client.c |  1 -
 sql/sql_class.cc    | 30 ++++++++++++++++++++++--------
 sql/sql_class.h     | 10 ++++++++--
 3 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/sql-common/client.c b/sql-common/client.c
index a6e02376a40..e92a9bd0cdc 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1714,7 +1714,6 @@ static MYSQL_METHODS client_methods=
 C_MODE_START
 int mysql_init_character_set(MYSQL *mysql)
 {
-  NET		*net= &mysql->net;
   const char *default_collation_name;
   
   /* Set character set */
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index b5a29783044..a904023cbff 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1305,23 +1305,26 @@ bool select_send::send_fields(List<Item> &list, uint flags)
 {
   bool res;
   if (!(res= thd->protocol->send_fields(&list, flags)))
-    status= 1;
+    is_result_set_started= 1;
   return res;
 }
 
 void select_send::abort()
 {
   DBUG_ENTER("select_send::abort");
-  if (status && thd->spcont &&
+  if (is_result_set_started && thd->spcont &&
       thd->spcont->find_handler(thd, thd->net.last_errno,
                                 MYSQL_ERROR::WARN_LEVEL_ERROR))
   {
     /*
-      Executing stored procedure without a handler.
-      Here we should actually send an error to the client,
-      but as an error will break a multiple result set, the only thing we
-      can do for now is to nicely end the current data set and remembering
-      the error so that the calling routine will abort
+      We're executing a stored procedure, have an open result
+      set, an SQL exception conditiona and a handler for it.
+      In this situation we must abort the current statement,
+      silence the error and start executing the continue/exit
+      handler.
+      Before aborting the statement, let's end the open result set, as
+      otherwise the client will hang due to the violation of the
+      client/server protocol.
     */
     thd->net.report_error= 0;
     send_eof();
@@ -1331,6 +1334,17 @@ void select_send::abort()
 }
 
 
+/** 
+  Cleanup an instance of this class for re-use
+  at next execution of a prepared statement/
+  stored procedure statement.
+*/
+
+void select_send::cleanup()
+{
+  is_result_set_started= FALSE;
+}
+
 /* Send data to client. Returns 0 if ok */
 
 bool select_send::send_data(List<Item> &items)
@@ -1392,7 +1406,7 @@ bool select_send::send_eof()
   if (! thd->is_error())
   {
     ::send_eof(thd);
-    status= 0;
+    is_result_set_started= 0;
     return 0;
   }
   else
diff --git a/sql/sql_class.h b/sql/sql_class.h
index db847c814a0..632c440266f 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2051,14 +2051,20 @@ class select_result_interceptor: public select_result
 
 
 class select_send :public select_result {
-  int status;
+  /**
+    True if we have sent result set metadata to the client.
+    In this case the client always expects us to end the result
+    set with an eof or error packet
+  */
+  bool is_result_set_started;
 public:
-  select_send() :status(0) {}
+  select_send() :is_result_set_started(FALSE) {}
   bool send_fields(List<Item> &list, uint flags);
   bool send_data(List<Item> &items);
   bool send_eof();
   virtual bool check_simple_select() const { return FALSE; }
   void abort();
+  virtual void cleanup();
 };
 
 
-- 
2.30.9