List:Commits« Previous MessageNext Message »
From:Kristofer Pettersson Date:July 1 2009 9:01pm
Subject:bzr commit into mysql-5.1-bugteam branch (kristofer.pettersson:2935)
Bug#44521
View as plain text  
#At file:///Users/thek/Development/51-bug44521/ based on revid:pstoev@stripped

 2935 Kristofer Pettersson	2009-07-01
      Bug#44521 Prepared Statement: CALL p() - crashes: `! thd->main_da.is_sent' failed et.al.
       
      For discussion.
      
      Executing a stored procedure as a prepared statement can sometimes cause an 
      assertion in a debug build.
      
      The reason is that the C API doesn't support multiple result sets for prepared
      statements and attempting to execute a stored routine which returns multiple result
      sets sometimes lead to a network error. The network error sets the diagnostic area
      prematurely which later leads to the assert when an attempt is made to set a second
      server state.
      
      This patch fixes the issue by changing the scope of the error code returned by
      sp_instr_stmt::execute() to include any error which happened during the execution.
      An extra check is also made to make sure that the diagnostic area isn't set twice.

    modified:
      sql/sp_head.cc
      sql/sql_parse.cc
=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2009-05-30 13:32:28 +0000
+++ b/sql/sp_head.cc	2009-07-01 21:01:14 +0000
@@ -1249,7 +1249,7 @@ sp_head::execute(THD *thd)
     */
     if (thd->prelocked_mode == NON_PRELOCKED)
       thd->user_var_events_alloc= thd->mem_root;
-    
+
     err_status= i->execute(thd, &ip);
 
     if (i->free_list)
@@ -2865,7 +2865,7 @@ sp_instr_stmt::execute(THD *thd, uint *n
     if (!thd->is_error())
       thd->main_da.reset_diagnostics_area();
   }
-  DBUG_RETURN(res);
+  DBUG_RETURN(res || thd->is_error());
 }
 
 

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2009-06-05 11:23:58 +0000
+++ b/sql/sql_parse.cc	2009-07-01 21:01:14 +0000
@@ -954,6 +954,7 @@ bool dispatch_command(enum enum_server_c
 		      char* packet, uint packet_length)
 {
   NET *net= &thd->net;
+  bool eof_has_been_sent= FALSE;
   bool error= 0;
   DBUG_ENTER("dispatch_command");
   DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
@@ -1166,6 +1167,14 @@ bool dispatch_command(enum enum_server_c
   case COM_STMT_EXECUTE:
   {
     mysqld_stmt_execute(thd, packet, packet_length);
+    /*
+      When executing a stored routine a network error may occur
+      (ER_NET_ERROR_ON_WRITE) which causes the diagnositc area
+      to be set. To avoid setting the diagnositc area twice we
+      need to remember this exception.
+    */
+    if (thd->main_da.is_sent)
+      eof_has_been_sent= TRUE;
     break;
   }
   case COM_STMT_FETCH:
@@ -1580,8 +1589,12 @@ bool dispatch_command(enum enum_server_c
     thd->mysys_var->abort= 0;
   }
 
-  net_end_statement(thd);
-  query_cache_end_of_result(thd);
+  if (!eof_has_been_sent)
+  {
+    net_end_statement(thd);
+    query_cache_end_of_result(thd);
+  }
+
 
   thd->proc_info= "closing tables";
   /* Free tables */
@@ -4362,7 +4375,6 @@ create_sp_error:
 	thd->variables.select_limit= select_limit;
 
         thd->server_status&= ~bits_to_be_cleared;
-
 	if (!res)
           my_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
                               thd->row_count_func));


Attachment: [text/bzr-bundle]
Thread
bzr commit into mysql-5.1-bugteam branch (kristofer.pettersson:2935)Bug#44521Kristofer Pettersson1 Jul
  • Re: bzr commit into mysql-5.1-bugteam branch(kristofer.pettersson:2935) Bug#44521Davi Arnaut10 Jul