List:Commits« Previous MessageNext Message »
From:Mayank Prasad Date:May 9 2011 1:55pm
Subject:[Resend] bzr commit into mysql-5.1 branch (mayank.prasad:3685) 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:karen.langford@stripped

 3685 Mayank Prasad	2011-05-09
      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.
      
      Test case:
      Test case automation is not possible as current (following) code doesn't 
      allow '\T' to be executed from command line (OR command read from a file):
      [client/mysql.cc]
      ...
       static int
       com_tee(String *buffer __attribute__((unused)),
               char *line __attribute__((unused)))
       {
         char file_name[FN_REFLEN], *end, *param;
      
         if (status.batch) << THIS IS TRUE WHILE EXECUTING FROM COMMAND LINE.
            return 0;
       ...
      So, not adding test case in GA. WIll add a test case in mysql-trunk after 
      removing above code so that this could be properly tested before GA.
     @ libmysqld/lib_sql.cc
        Added code to call client/server error handler based on in control is in
client/server code respectively.
     @ sql/mysql_priv.h
        Added comments for THR_THD, THR_MALLOC keys.
     @ 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/mysql_priv.h
      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-09 10:17:49 +0000
@@ -41,7 +41,17 @@ 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);
-
+/* 
+  Wrapper error handler to call client/server error handler based on whether 
+  thread is in client/server context
+*/
+static int embedded_error_handler(uint error, const char *str, myf MyFlags);
+/*
+  Pointer to client error handler. It gets assigned in init_embedded_server. 
+  It is used to call client error handling routine in embedded_error_handler.
+*/
+static int (*client_error_handler_hook)(uint my_err, const char *str, 
+            myf MyFlags);
 
 extern "C" void unireg_clear(int exit_code)
 {
@@ -51,6 +61,23 @@ extern "C" void unireg_clear(int exit_co
   DBUG_VOID_RETURN;
 }
 
+/*
+  Wrapper error handler for embedded server. Based on thread's state, call 
+  the error handler accordingly.
+*/
+
+int embedded_error_handler(uint error, const char *str, myf MyFlags)
+{
+  DBUG_ENTER("embedded_error_handler");
+
+  /* 
+    If _current_thd() returns NULL, it means restore_global has been
+    called and thread is in client context, then call client error handler
+    else call server error handler.
+  */
+  DBUG_RETURN(_current_thd() ? my_message_sql(error, str, MyFlags):
+              client_error_handler_hook(error, str, MyFlags));
+}
 
 /*
   Reads error information from the MYSQL_DATA and puts
@@ -107,7 +134,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 +175,9 @@ emb_advanced_command(MYSQL *mysql, enum 
 #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
   thd->profiling.finish_current_query();
 #endif
+
+end:
+  thd->restore_globals();
   return result;
 }
 
@@ -525,7 +556,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/mysql_priv.h'
--- a/sql/mysql_priv.h	2011-03-15 11:36:12 +0000
+++ b/sql/mysql_priv.h	2011-05-09 10:17:49 +0000
@@ -670,6 +670,10 @@ enum enum_check_fields
 extern "C" THD *_current_thd_noinline();
 #define _current_thd() _current_thd_noinline()
 #else
+/*
+  THR_THD is a key which will be used to set/get THD* for a thread,
+  using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr().
+*/
 extern pthread_key(THD*, THR_THD);
 inline THD *_current_thd(void)
 {
@@ -2022,6 +2026,10 @@ extern TABLE_LIST general_log, slow_log;
 extern FILE *bootstrap_file;
 extern int bootstrap_error;
 extern FILE *stderror_file;
+/*
+  THR_MALLOC is a key which will be used to set/get MEM_ROOT** for a thread,
+  using my_pthread_setspecific_ptr()/my_thread_getspecific_ptr().
+*/
 extern pthread_key(MEM_ROOT**,THR_MALLOC);
 extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_lock_db,
        LOCK_mapped_file,LOCK_user_locks, LOCK_status,

=== 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-09 10:17:49 +0000
@@ -1196,6 +1196,25 @@ bool THD::store_globals()
   return 0;
 }
 
+/*
+  Remove the thread specific info (THD and mem_root pointer) stored during
+  store_global call for this thread.
+*/
+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-09 10:17:49 +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-20110509101749-qm1j9j5knu0jbfqq.bundle
Thread
[Resend] bzr commit into mysql-5.1 branch (mayank.prasad:3685) Bug#11764633Mayank Prasad9 May
  • Re: [Resend] bzr commit into mysql-5.1 branch (mayank.prasad:3685)Bug#11764633Davi Arnaut11 May
Re: [Resend] bzr commit into mysql-5.1 branch (mayank.prasad:3685)Bug#11764633Davi Arnaut12 May
Re: [Resend] bzr commit into mysql-5.1 branch (mayank.prasad:3685)Bug#11764633Davi Arnaut13 May