List:Commits« Previous MessageNext Message »
From:konstantin Date:October 30 2007 7:32pm
Subject:bk commit into 5.1 tree (kostja:1.2598) BUG#12713
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of kostja. When kostja does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-10-30 22:32:20+03:00, kostja@bodhi.(none) +7 -0
  In ha_delete_table, use a standard mechanism to intercept the error message
  and convert it to a warning instead of direct manipulation with the
  thread error stack.
  Fix a bug in handler::print_erorr when a garbled message was
  printed for HA_ERR_NO_SUCH_TABLE.
  This is a pre-requisite patch for the fix for Bug#12713 Error in a stored
  function called from a SELECT doesn't cause ROLLBACK of statem"

  sql/handler.cc@stripped, 2007-10-30 22:32:17+03:00, kostja@bodhi.(none) +45 -25
    Use a standard mechanism to intercept the error message, instead
    of direct manipulation with thread error stack. 
    Fix a bug when for HA_ERR_NO_SUCH_TABLE handler::print_error() would
    print a garbled message.

  sql/log.cc@stripped, 2007-10-30 22:32:17+03:00, kostja@bodhi.(none) +2 -1
    Extend internal error handler interface to carry the message text.

  sql/mysqld.cc@stripped, 2007-10-30 22:32:17+03:00, kostja@bodhi.(none) +1 -1
    Extend internal error handler interface to carry the message text.

  sql/sql_base.cc@stripped, 2007-10-30 22:32:17+03:00, kostja@bodhi.(none) +2 -1
    Extend internal error handler interface to carry the message text.

  sql/sql_class.cc@stripped, 2007-10-30 22:32:17+03:00, kostja@bodhi.(none) +2 -2
    Extend internal error handler interface to carry the message text.

  sql/sql_class.h@stripped, 2007-10-30 22:32:17+03:00, kostja@bodhi.(none) +2 -1
    Extend internal error handler interface to carry the message text.

  sql/sql_error.cc@stripped, 2007-10-30 22:32:17+03:00, kostja@bodhi.(none) +1 -1
    Extend internal error handler interface to carry the message text.

diff -Nrup a/sql/handler.cc b/sql/handler.cc
--- a/sql/handler.cc	2007-10-29 17:07:14 +03:00
+++ b/sql/handler.cc	2007-10-30 22:32:17 +03:00
@@ -1414,6 +1414,36 @@ static const char *check_lowercase_names
 }
 
 
+/**
+  An interceptor to hijack the text of the error message without
+  setting an error in the thread. We need the text to present it
+  in the form of a warning to the user.
+*/
+
+struct Ha_delete_table_error_handler: public Internal_error_handler
+{
+public:
+  virtual bool handle_error(uint sql_errno,
+                            const char *message,
+                            MYSQL_ERROR::enum_warning_level level,
+                            THD *thd);
+  char buff[MYSQL_ERRMSG_SIZE];
+};
+
+
+bool
+Ha_delete_table_error_handler::
+handle_error(uint sql_errno,
+             const char *message,
+             MYSQL_ERROR::enum_warning_level level,
+             THD *thd)
+{
+  /* Grab the error message */
+  strmake(buff, message, sizeof(buff)-1);
+  return TRUE;
+}
+
+
 /** @brief
   This should return ENOENT if the file doesn't exists.
   The .frm file will be deleted only if we return 0 or ENOENT
@@ -1442,23 +1472,11 @@ int ha_delete_table(THD *thd, handlerton
   {
     /*
       Because file->print_error() use my_error() to generate the error message
-      we must store the error state in thd, reset it and restore it to
-      be able to get hold of the error message.
-      (We should in the future either rewrite handler::print_error() or make
-      a nice method of this.
+      we use an internal error handler to intercept it and store the text
+      in a temporary buffer. Later the message will be presented to user
+      as a warning.
     */
-    bool is_slave_error= thd->is_slave_error;
-    sp_rcontext *spcont= thd->spcont;
-    SELECT_LEX *current_select= thd->lex->current_select;
-    char buff[sizeof(thd->net.last_error)];
-    char new_error[sizeof(thd->net.last_error)];
-    int last_errno= thd->net.last_errno;
-
-    strmake(buff, thd->net.last_error, sizeof(buff)-1);
-    thd->is_slave_error= 0;
-    thd->spcont= NULL;
-    thd->lex->current_select= 0;
-    thd->net.last_error[0]= 0;
+    Ha_delete_table_error_handler ha_delete_table_error_handler;
 
     /* Fill up strucutures that print_error may need */
     dummy_share.path.str= (char*) path;
@@ -1471,16 +1489,18 @@ int ha_delete_table(THD *thd, handlerton
 
     file->table_share= &dummy_share;
     file->table= &dummy_table;
+
+    thd->push_internal_handler(&ha_delete_table_error_handler);
     file->print_error(error, 0);
-    strmake(new_error, thd->net.last_error, sizeof(buff)-1);
 
-    /* restore thd */
-    thd->is_slave_error= is_slave_error;
-    thd->spcont= spcont;
-    thd->lex->current_select= current_select;
-    thd->net.last_errno= last_errno;
-    strmake(thd->net.last_error, buff, sizeof(buff)-1);
-    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, new_error);
+    thd->pop_internal_handler();
+
+    /*
+      XXX: should we convert *all* errors to warnings here?
+      What if the error is fatal?
+    */
+    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error,
+                ha_delete_table_error_handler.buff);
   }
   delete file;
   DBUG_RETURN(error);
@@ -2203,7 +2223,7 @@ void handler::print_error(int error, myf
   case HA_ERR_NO_SUCH_TABLE:
     my_error(ER_NO_SUCH_TABLE, MYF(0), table_share->db.str,
              table_share->table_name.str);
-    break;
+    DBUG_VOID_RETURN;
   case HA_ERR_RBR_LOGGING_FAILED:
     textno= ER_BINLOG_ROW_LOGGING_FAILED;
     break;
diff -Nrup a/sql/log.cc b/sql/log.cc
--- a/sql/log.cc	2007-10-20 01:20:34 +04:00
+++ b/sql/log.cc	2007-10-30 22:32:17 +03:00
@@ -72,13 +72,14 @@ public:
 
   virtual ~Silence_log_table_errors() {}
 
-  virtual bool handle_error(uint sql_errno,
+  virtual bool handle_error(uint sql_errno, const char *message,
                             MYSQL_ERROR::enum_warning_level level,
                             THD *thd);
 };
 
 bool
 Silence_log_table_errors::handle_error(uint /* sql_errno */,
+                                       const char * /* message */,
                                        MYSQL_ERROR::enum_warning_level /* level */,
                                        THD * /* thd */)
 {
diff -Nrup a/sql/mysqld.cc b/sql/mysqld.cc
--- a/sql/mysqld.cc	2007-10-20 01:20:35 +04:00
+++ b/sql/mysqld.cc	2007-10-30 22:32:17 +03:00
@@ -2583,7 +2583,7 @@ int my_message_sql(uint error, const cha
       TODO: There are two exceptions mechanism (THD and sp_rcontext),
       this could be improved by having a common stack of handlers.
     */
-    if (thd->handle_error(error,
+    if (thd->handle_error(error, str,
                           MYSQL_ERROR::WARN_LEVEL_ERROR))
       DBUG_RETURN(0);
 
diff -Nrup a/sql/sql_base.cc b/sql/sql_base.cc
--- a/sql/sql_base.cc	2007-10-30 20:08:11 +03:00
+++ b/sql/sql_base.cc	2007-10-30 22:32:17 +03:00
@@ -44,7 +44,7 @@ public:
 
   virtual ~Prelock_error_handler() {}
 
-  virtual bool handle_error(uint sql_errno,
+  virtual bool handle_error(uint sql_errno, const char *message,
                             MYSQL_ERROR::enum_warning_level level,
                             THD *thd);
 
@@ -58,6 +58,7 @@ private:
 
 bool
 Prelock_error_handler::handle_error(uint sql_errno,
+                                    const char * /* message */,
                                     MYSQL_ERROR::enum_warning_level /* level */,
                                     THD * /* thd */)
 {
diff -Nrup a/sql/sql_class.cc b/sql/sql_class.cc
--- a/sql/sql_class.cc	2007-10-30 20:08:12 +03:00
+++ b/sql/sql_class.cc	2007-10-30 22:32:17 +03:00
@@ -498,12 +498,12 @@ void THD::push_internal_handler(Internal
 }
 
 
-bool THD::handle_error(uint sql_errno,
+bool THD::handle_error(uint sql_errno, const char *message,
                        MYSQL_ERROR::enum_warning_level level)
 {
   if (m_internal_handler)
   {
-    return m_internal_handler->handle_error(sql_errno, level, this);
+    return m_internal_handler->handle_error(sql_errno, message, level, this);
   }
 
   return FALSE;                                 // 'FALSE', as per coding style
diff -Nrup a/sql/sql_class.h b/sql/sql_class.h
--- a/sql/sql_class.h	2007-10-30 20:08:12 +03:00
+++ b/sql/sql_class.h	2007-10-30 22:32:17 +03:00
@@ -969,6 +969,7 @@ public:
     @return true if the error is handled
   */
   virtual bool handle_error(uint sql_errno,
+                            const char *message,
                             MYSQL_ERROR::enum_warning_level level,
                             THD *thd) = 0;
 };
@@ -1923,7 +1924,7 @@ public:
     @param level the error level
     @return true if the error is handled
   */
-  virtual bool handle_error(uint sql_errno,
+  virtual bool handle_error(uint sql_errno, const char *message,
                             MYSQL_ERROR::enum_warning_level level);
 
   /**
diff -Nrup a/sql/sql_error.cc b/sql/sql_error.cc
--- a/sql/sql_error.cc	2007-07-27 04:26:40 +04:00
+++ b/sql/sql_error.cc	2007-10-30 22:32:17 +03:00
@@ -137,7 +137,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQ
     level= MYSQL_ERROR::WARN_LEVEL_ERROR;
   }
 
-  if (thd->handle_error(code, level))
+  if (thd->handle_error(code, msg, level))
     DBUG_RETURN(NULL);
 
   if (thd->spcont &&
Thread
bk commit into 5.1 tree (kostja:1.2598) BUG#12713konstantin30 Oct
  • Re: bk commit into 5.1 tree (kostja:1.2598) BUG#12713Marc Alff30 Oct