List:Commits« Previous MessageNext Message »
From:Mayank Prasad Date:May 3 2011 1:45pm
Subject:[Resend] bzr commit into mysql-5.1 branch (mayank.prasad:3680) Bug#11764633
View as plain text  
[This commit e-mail is a repeat.]

#At file:///home/mayank/mysql-tree/mydefects/5.1_11764633_3/ based on
revid:vasil.dimov@stripped

 3680 Mayank Prasad	2011-05-03
      Bug#11764633 : 57491: THD->MAIN_DA.IS_OK() ASSERT IN EMBEDDED
      
      Issue:
      TEE command '\T foo/bar' was aborting. This is because, foo/bar
      directory doesn't exist. To report this error, server error handler was
      invoked and diagnostic area was found not reset. So abort was happenning.
      
      Solution:
      Call server/client error handler based on if control is in server/client 
      code respectively.
      
      PS: need to add a test case fot the issue.
     @ libmysqld/lib_sql.cc
        Added code to call client/server error handler based on in control is in
client/server code respectively.
     @ sql/sql_class.cc
        Function definition of new function restore_global to removes thread specific data
from stack (which was stored in store global).
     @ sql/sql_class.h
        Function declaration of new function restore_global.

    modified:
      libmysqld/lib_sql.cc
      sql/sql_class.cc
      sql/sql_class.h
=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc	2009-12-18 18:44:24 +0000
+++ b/libmysqld/lib_sql.cc	2011-05-03 13:42:07 +0000
@@ -22,6 +22,12 @@
 #define main main1
 #define mysql_unix_port mysql_inix_port1
 #define mysql_port mysql_port1
+/* 
+  If my_pthread_getspecific_ptr returns NULL, it means restore_global has been
+  called and thread is in client context.
+ */
+#define IS_THREAD_STATE_IN_SERVER_CODE                                          \
+   (NULL != my_pthread_getspecific_ptr(THD*,THR_THD))
 
 extern "C"
 {
@@ -41,7 +47,8 @@ C_MODE_START
 extern unsigned int mysql_server_last_errno;
 extern char mysql_server_last_error[MYSQL_ERRMSG_SIZE];
 static my_bool emb_read_query_result(MYSQL *mysql);
-
+static int embedded_error_handler(uint error, const char *str, myf MyFlags);
+static int (*client_error_handler_hook)(uint my_err, const char *str,myf MyFlags);
 
 extern "C" void unireg_clear(int exit_code)
 {
@@ -51,6 +58,24 @@ extern "C" void unireg_clear(int exit_co
   DBUG_VOID_RETURN;
 }
 
+/*
+   Wrapper error handler for embedded server. Based on thread state, call 
+   the error handler accordingly
+ */
+
+int embedded_error_handler(uint error, const char *str, myf MyFlags)
+{
+  DBUG_ENTER("embedded_error_handler");
+
+  /* 
+    If thread state is in server code, call server error handler
+    else call client error handler
+   */
+  IS_THREAD_STATE_IN_SERVER_CODE ? my_message_sql(error,str,MyFlags):
+                                  client_error_handler_hook(error,str,MyFlags);
+  DBUG_RETURN(0);
+}
+
 
 /*
   Reads error information from the MYSQL_DATA and puts
@@ -94,7 +119,10 @@ emb_advanced_command(MYSQL *mysql, enum 
   {
     /* Do "reconnect" if possible */
     if (mysql_reconnect(mysql) || stmt_skip)
-      return 1;
+    {
+      result = 1;
+      goto end;
+    }
     thd= (THD *) mysql->thd;
   }
 
@@ -107,7 +135,8 @@ emb_advanced_command(MYSQL *mysql, enum 
   if (mysql->status != MYSQL_STATUS_READY)
   {
     set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
-    return 1;
+    result = 1;
+    goto end;
   }
 
   /* Clear result variables */
@@ -147,6 +176,16 @@ emb_advanced_command(MYSQL *mysql, enum 
 #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
   thd->profiling.finish_current_query();
 #endif
+
+end:
+  /* 
+     It might have come here when connection to server is not there.
+     In that case, thd would be NULL.
+   */
+  if(thd)
+  {
+    thd->restore_globals();
+  }
   return result;
 }
 
@@ -525,7 +564,12 @@ int init_embedded_server(int argc, char 
     return 1;
   }
 
-  error_handler_hook = my_message_sql;
+  /* 
+     store the client error handler hook and set error handler to 
+     embedded_error_handler_hook wrapper.
+  */
+  client_error_handler_hook = error_handler_hook;
+  error_handler_hook = embedded_error_handler;
 
   acl_error= 0;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2011-04-07 18:12:54 +0000
+++ b/sql/sql_class.cc	2011-05-03 13:42:07 +0000
@@ -1196,6 +1196,21 @@ bool THD::store_globals()
   return 0;
 }
 
+bool THD::restore_globals()
+{
+  /*
+    Assert that thread_stack is initialized: it's necessary to be able
+    to track stack overrun.
+  */
+  DBUG_ASSERT(thread_stack);
+  
+  /* Undocking the thread specific data */
+  my_pthread_setspecific_ptr(THR_THD,NULL);
+  my_pthread_setspecific_ptr(THR_MALLOC,NULL);
+  
+  return 0;
+}
+
 
 /*
   Cleanup after query.

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2011-02-22 21:03:32 +0000
+++ b/sql/sql_class.h	2011-05-03 13:42:07 +0000
@@ -1943,6 +1943,7 @@ public:
   void cleanup(void);
   void cleanup_after_query();
   bool store_globals();
+  bool restore_globals();
 #ifdef SIGNAL_WITH_VIO_CLOSE
   inline void set_active_vio(Vio* vio)
   {


Attachment: [text/bzr-bundle] bzr/mayank.prasad@oracle.com-20110503134207-a8t9s7c1e87tn4sp.bundle
Thread
[Resend] bzr commit into mysql-5.1 branch (mayank.prasad:3680) Bug#11764633Mayank Prasad3 May