List:Commits« Previous MessageNext Message »
From:Mayank Prasad Date:April 7 2011 8:40am
Subject:bzr commit into mysql-5.1 branch (mayank.prasad:3640) Bug#11764633
View as plain text  
#At file:///home/mayank/mysql-tree/mydefects/5.1_11764633/ based on revid:sergey.glukhov@stripped

 3640 Mayank Prasad	2011-04-07
      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:
        Issue was because error handler was not set correctly to client/server error handler when control goes from client code to server code respectively. Corrected it.
     @ libmysqld/lib_sql.cc
        Added code to set/reset 'error_handler_hook' to server/client error handler accordingly.

    modified:
      libmysqld/lib_sql.cc
=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc	2009-12-18 18:44:24 +0000
+++ b/libmysqld/lib_sql.cc	2011-04-07 08:39:58 +0000
@@ -22,6 +22,12 @@
 #define main main1
 #define mysql_unix_port mysql_inix_port1
 #define mysql_port mysql_port1
+#define set_emb_error_handler_hook                                           \
+  int (*saved_error_handler_hook)(uint my_err, const char *str,myf MyFlags); \
+  saved_error_handler_hook = error_handler_hook;                             \
+  error_handler_hook = my_message_sql;
+#define reset_emb_error_handler_hook                                         \
+   error_handler_hook = saved_error_handler_hook;
 
 extern "C"
 {
@@ -86,15 +92,21 @@ emb_advanced_command(MYSQL *mysql, enum 
                      MYSQL_STMT *stmt)
 {
   my_bool result= 1;
+  my_bool ret_value= 0;
   THD *thd=(THD *) mysql->thd;
   NET *net= &mysql->net;
   my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE;
 
+  set_emb_error_handler_hook;
+
   if (!thd)
   {
     /* Do "reconnect" if possible */
     if (mysql_reconnect(mysql) || stmt_skip)
-      return 1;
+	{
+      ret_value= 1;
+      goto RETURN;
+	}
     thd= (THD *) mysql->thd;
   }
 
@@ -107,7 +119,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;
+    ret_value= 1;
+    goto RETURN;
   }
 
   /* Clear result variables */
@@ -147,12 +160,17 @@ emb_advanced_command(MYSQL *mysql, enum 
 #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
   thd->profiling.finish_current_query();
 #endif
-  return result;
+  ret_value= result;
+
+RETURN:
+  reset_emb_error_handler_hook;
+  return ret_value;
 }
 
 static void emb_flush_use_result(MYSQL *mysql)
 {
   THD *thd= (THD*) mysql->thd;
+  set_emb_error_handler_hook;
   if (thd->cur_data)
   {
     free_rows(thd->cur_data);
@@ -164,6 +182,8 @@ static void emb_flush_use_result(MYSQL *
     thd->first_data= data->embedded_info->next;
     free_rows(data);
   }
+
+  reset_emb_error_handler_hook;
 }
 
 
@@ -187,34 +207,52 @@ emb_read_rows(MYSQL *mysql, MYSQL_FIELD 
 	      unsigned int fields __attribute__((unused)))
 {
   MYSQL_DATA *result= ((THD*)mysql->thd)->cur_data;
+  MYSQL_DATA *ret_value= NULL;
   ((THD*)mysql->thd)->cur_data= 0;
+  set_emb_error_handler_hook;
   if (result->embedded_info->last_errno)
   {
     embedded_get_error(mysql, result);
-    return NULL;
+    ret_value= NULL;
+    goto RETURN;
   }
   *result->embedded_info->prev_ptr= NULL;
-  return result;
+  ret_value= result;
+
+RETURN:
+  reset_emb_error_handler_hook;
+  return ret_value;
 }
 
 
 static MYSQL_FIELD *emb_list_fields(MYSQL *mysql)
 {
   MYSQL_DATA *res;
+  MYSQL_FIELD *ret_value= NULL;
+  set_emb_error_handler_hook;
   if (emb_read_query_result(mysql))
-    return 0;
+  {
+    ret_value= 0;  
+    goto RETURN;
+  }
   res= ((THD*) mysql->thd)->cur_data;
   ((THD*) mysql->thd)->cur_data= 0;
   mysql->field_alloc= res->alloc;
   my_free(res,MYF(0));
   mysql->status= MYSQL_STATUS_READY;
-  return mysql->fields;
+  ret_value= mysql->fields;
+
+RETURN:
+  reset_emb_error_handler_hook;
+  return ret_value;
 }
 
 static my_bool emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
 {
   THD *thd= (THD*) mysql->thd;
   MYSQL_DATA *res;
+  my_bool ret_value= 0;
+  set_emb_error_handler_hook;
 
   stmt->stmt_id= thd->client_stmt_id;
   stmt->param_count= thd->client_param_count;
@@ -224,7 +262,10 @@ static my_bool emb_read_prepare_result(M
   if (thd->first_data)
   {
     if (emb_read_query_result(mysql))
-      return 1;
+	{
+      ret_value= 1;
+      goto RETURN;
+	}
     stmt->field_count= mysql->field_count;
     mysql->status= MYSQL_STATUS_READY;
     res= thd->cur_data;
@@ -238,7 +279,11 @@ static my_bool emb_read_prepare_result(M
     my_free(res,MYF(0));
   }
 
-  return 0;
+  ret_value= 0;
+
+RETURN:
+  reset_emb_error_handler_hook;
+  return ret_value;
 }
 
 /**************************************************************************
@@ -258,15 +303,18 @@ static void emb_fetch_lengths(ulong *to,
 
 static my_bool emb_read_query_result(MYSQL *mysql)
 {
+  my_bool ret_value= 0;
   THD *thd= (THD*) mysql->thd;
   MYSQL_DATA *res= thd->first_data;
   DBUG_ASSERT(!thd->cur_data);
+  set_emb_error_handler_hook;
   thd->first_data= res->embedded_info->next;
   if (res->embedded_info->last_errno &&
       !res->embedded_info->fields_list)
   {
     embedded_get_error(mysql, res);
-    return 1;
+    ret_value= 1;
+    goto RETURN;
   }
 
   mysql->warning_count= res->embedded_info->warning_count;
@@ -294,7 +342,11 @@ static my_bool emb_read_query_result(MYS
   else
     my_free(res, MYF(0));
 
-  return 0;
+  ret_value= 0;
+
+RETURN:
+  reset_emb_error_handler_hook;
+  return ret_value;
 }
 
 static int emb_stmt_execute(MYSQL_STMT *stmt)
@@ -303,6 +355,9 @@ static int emb_stmt_execute(MYSQL_STMT *
   uchar header[5];
   THD *thd;
   my_bool res;
+  int ret_value= 0;
+
+  set_emb_error_handler_hook;
 
   int4store(header, stmt->stmt_id);
   header[4]= (uchar) stmt->flags;
@@ -320,23 +375,36 @@ static int emb_stmt_execute(MYSQL_STMT *
   {
     NET *net= &stmt->mysql->net;
     set_stmt_errmsg(stmt, net);
-    DBUG_RETURN(1);
+    ret_value= 1;
+    goto RETURN;
   }
-  DBUG_RETURN(0);
+  ret_value= 0;
+
+RETURN:
+  reset_emb_error_handler_hook;
+  DBUG_RETURN(ret_value);
 }
 
 int emb_read_binary_rows(MYSQL_STMT *stmt)
 {
   MYSQL_DATA *data;
+  int ret_value= 0;
+  set_emb_error_handler_hook;
+
   if (!(data= emb_read_rows(stmt->mysql, 0, 0)))
   {
     set_stmt_errmsg(stmt, &stmt->mysql->net);
-    return 1;
+    ret_value= 1;
+    goto RETURN;
   }
   stmt->result= *data;
   my_free((char *) data, MYF(0));
   set_stmt_errmsg(stmt, &stmt->mysql->net);
-  return 0;
+  ret_value= 0;
+
+RETURN:
+  reset_emb_error_handler_hook;
+  return ret_value;
 }
 
 int emb_read_rows_from_cursor(MYSQL_STMT *stmt)
@@ -344,13 +412,17 @@ int emb_read_rows_from_cursor(MYSQL_STMT
   MYSQL *mysql= stmt->mysql;
   THD *thd= (THD*) mysql->thd;
   MYSQL_DATA *res= thd->first_data;
+  int ret_value= 0;
+
+  set_emb_error_handler_hook;
   DBUG_ASSERT(!thd->first_data->embedded_info->next);
   thd->first_data= 0;
   if (res->embedded_info->last_errno)
   {
     embedded_get_error(mysql, res);
     set_stmt_errmsg(stmt, &mysql->net);
-    return 1;
+    ret_value= 1;
+    goto RETURN;
   }
 
   thd->cur_data= res;
@@ -358,18 +430,27 @@ int emb_read_rows_from_cursor(MYSQL_STMT
   mysql->server_status= res->embedded_info->server_status;
   net_clear_error(&mysql->net);
 
-  return emb_read_binary_rows(stmt);
+  ret_value= emb_read_binary_rows(stmt);
+
+RETURN:
+  reset_emb_error_handler_hook;
+  return ret_value;
 }
 
 int emb_unbuffered_fetch(MYSQL *mysql, char **row)
 {
   THD *thd= (THD*) mysql->thd;
   MYSQL_DATA *data= thd->cur_data;
+  int ret_value= 0;
+ 
+  set_emb_error_handler_hook;
+
   if (data && data->embedded_info->last_errno)
   {
     embedded_get_error(mysql, data);
     thd->cur_data= 0;
-    return 1;
+    ret_value= 1;
+    goto RETURN;
   }
   if (!data || !data->data)
   {
@@ -386,12 +467,17 @@ int emb_unbuffered_fetch(MYSQL *mysql, c
     *row= (char *)data->data->data;
     data->data= data->data->next;
   }
-  return 0;
+  ret_value= 0;
+
+RETURN:
+  reset_emb_error_handler_hook;
+  return ret_value;
 }
 
 static void emb_free_embedded_thd(MYSQL *mysql)
 {
   THD *thd= (THD*)mysql->thd;
+  set_emb_error_handler_hook;
   thd->clear_data_list();
   thread_count--;
   thd->store_globals();
@@ -399,18 +485,27 @@ static void emb_free_embedded_thd(MYSQL 
   delete thd;
   my_pthread_setspecific_ptr(THR_THD,  0);
   mysql->thd=0;
+  reset_emb_error_handler_hook;
 }
 
 static const char * emb_read_statistics(MYSQL *mysql)
 {
   THD *thd= (THD*)mysql->thd;
-  return thd->is_error() ? thd->main_da.message() : "";
+  const char* ret_value= NULL;
+  set_emb_error_handler_hook;
+  ret_value= thd->is_error() ? thd->main_da.message() : "";
+  reset_emb_error_handler_hook;
+  return ret_value;
 }
 
 
 static MYSQL_RES * emb_store_result(MYSQL *mysql)
 {
-  return mysql_store_result(mysql);
+  set_emb_error_handler_hook; 
+  MYSQL_RES * ret_value= NULL;
+  ret_value= mysql_store_result(mysql);
+  reset_emb_error_handler_hook;
+  return ret_value;
 }
 
 int emb_read_change_user_result(MYSQL *mysql, 
@@ -480,6 +575,7 @@ int init_embedded_server(int argc, char 
   char *fake_argv[] = { (char *)"", 0 };
   const char *fake_groups[] = { "server", "embedded", 0 };
   my_bool acl_error;
+  int ret_code= 0;
   if (argc)
   {
     argcp= &argc;
@@ -504,7 +600,8 @@ int init_embedded_server(int argc, char 
   if (init_common_variables("my", *argcp, *argvp, (const char **)groups))
   {
     mysql_server_end();
-    return 1;
+    ret_code= 1;
+    goto RETURN;
   }
     
   /* Get default temporary directory */
@@ -522,10 +619,15 @@ int init_embedded_server(int argc, char 
   if (init_server_components())
   {
     mysql_server_end();
-    return 1;
+    ret_code= 1;
+    goto RETURN;
   }
 
-  error_handler_hook = my_message_sql;
+  /* 
+     We have to set error handler here because in above call 
+     init_server_components(), it gets set to client error handler.
+  */
+  set_emb_error_handler_hook;
 
   acl_error= 0;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -536,7 +638,8 @@ int init_embedded_server(int argc, char 
   if (acl_error || my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
   {
     mysql_server_end();
-    return 1;
+    ret_code= 1;
+    goto RETURN;
   }
 
   init_max_user_conn();
@@ -563,12 +666,17 @@ int init_embedded_server(int argc, char 
     if (read_init_file(opt_init_file))
     {
       mysql_server_end();
-      return 1;
+      ret_code= 1;
+      goto RETURN;
     }
   }
 
   execute_ddl_log_recovery();
-  return 0;
+  ret_code= 0;
+
+RETURN:
+  reset_emb_error_handler_hook;
+  return ret_code;
 }
 
 void end_embedded_server()


Attachment: [text/bzr-bundle] bzr/mayank.prasad@oracle.com-20110407083958-c5t5j5fl14hehpzy.bundle
Thread
bzr commit into mysql-5.1 branch (mayank.prasad:3640) Bug#11764633Mayank Prasad7 Apr
  • Re: bzr commit into mysql-5.1 branch (mayank.prasad:3640)Bug#11764633Sergei Golubchik7 Apr