[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#11764633 | Mayank Prasad | 3 May |