List:Commits« Previous MessageNext Message »
From:Jon Olav Hauglid Date:March 31 2011 3:23pm
Subject:bzr commit into mysql-trunk branch (jon.hauglid:3350) Bug#11765416
View as plain text  
#At file:///export/home/x/mysql-trunk-bug11765416/ based on revid:magne.mahre@stripped

 3350 Jon Olav Hauglid	2011-03-31
      Bug #11765416 (former 58381)
      FAILED DROP DATABASE CAN BREAK STATEMENT BASED REPLICATION
      
      This is a follow-up patch.
      
      This patch changes the binlogging code for DROP DATABASE to be
      more similar to DROP TABLE. It also refactors the DROP TABLE
      code so that binlogging is handled separately.

    modified:
      mysql-test/suite/binlog/r/binlog_database.result
      sql/sql_db.cc
      sql/sql_table.cc
=== modified file 'mysql-test/suite/binlog/r/binlog_database.result'
--- a/mysql-test/suite/binlog/r/binlog_database.result	2011-03-15 10:54:06 +0000
+++ b/mysql-test/suite/binlog/r/binlog_database.result	2011-03-31 15:23:43 +0000
@@ -79,7 +79,7 @@ Tables_in_db1
 t2
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	use `db1`; DROP TABLE IF EXISTS `t1`
+master-bin.000001	#	Query	#	#	DROP TABLE IF EXISTS `db1`.`t1` /* generated by server */
 DROP TABLE t3;
 DROP DATABASE db1;
 set binlog_format=mixed;
@@ -163,7 +163,7 @@ Tables_in_db1
 t2
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	use `db1`; DROP TABLE IF EXISTS `t1`
+master-bin.000001	#	Query	#	#	DROP TABLE IF EXISTS `db1`.`t1` /* generated by server */
 DROP TABLE t3;
 DROP DATABASE db1;
 set binlog_format=row;
@@ -248,7 +248,7 @@ Tables_in_db1
 t2
 show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	#	Query	#	#	use `db1`; DROP TABLE IF EXISTS `t1`
+master-bin.000001	#	Query	#	#	DROP TABLE IF EXISTS `db1`.`t1` /* generated by server */
 DROP TABLE t3;
 DROP DATABASE db1;
 show databases;

=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc	2011-03-17 09:47:50 +0000
+++ b/sql/sql_db.cc	2011-03-31 15:23:43 +0000
@@ -41,8 +41,6 @@
 #include <direct.h>
 #endif
 
-#define MAX_DROP_TABLE_Q_LEN      1024
-
 const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
 static TYPELIB deletable_extentions=
 {array_elements(del_exts)-1,"del_exts", del_exts, NULL};
@@ -91,20 +89,6 @@ uchar* dboptions_get_key(my_dbopt_t *opt
 
 
 /*
-  Helper function to write a query to binlog used by mysql_rm_db()
-*/
-
-static inline int write_to_binlog(THD *thd, char *query, uint q_len,
-                                  char *db, uint db_len)
-{
-  Query_log_event qinfo(thd, query, q_len, FALSE, TRUE, FALSE, 0);
-  qinfo.db= db;
-  qinfo.db_len= db_len;
-  return mysql_bin_log.write(&qinfo);
-}  
-
-
-/*
   Function to free dboptions hash element
 */
 
@@ -836,7 +820,7 @@ bool mysql_rm_db(THD *thd,char *db,bool
   thd->push_internal_handler(&err_handler);
   if (!thd->killed &&
       !(tables &&
-        mysql_rm_table_no_locks(thd, tables, true, false, true, true)))
+        mysql_rm_table_no_locks(thd, tables, true, false, true, false)))
   {
     /*
       We temporarily disable the binary log while dropping the objects
@@ -923,19 +907,15 @@ update_binlog:
   }
   else if (mysql_bin_log.is_open() && !silent)
   {
-    char *query, *query_pos, *query_end, *query_data_start;
+    String built_query;
     TABLE_LIST *tbl;
-    uint db_len;
+    bool table_deleted= false;
 
-    if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
-      goto exit; /* not much else we can do */
-    query_pos= query_data_start= strmov(query,"DROP TABLE IF EXISTS ");
-    query_end= query + MAX_DROP_TABLE_Q_LEN;
-    db_len= strlen(db);
+    built_query.set_charset(system_charset_info);
+    built_query.append("DROP TABLE IF EXISTS ");
 
     for (tbl= tables; tbl; tbl= tbl->next_local)
     {
-      uint tbl_name_len;
       bool exists;
 
       // Only write drop table to the binlog for tables that no longer exist.
@@ -944,42 +924,31 @@ update_binlog:
         error= true;
         goto exit;
       }
-      if (exists)
-        continue;
-
-      /* 3 for the quotes and the comma*/
-      tbl_name_len= strlen(tbl->table_name) + 3;
-      if (query_pos + tbl_name_len + 1 >= query_end)
+      if (!exists)
       {
-        /*
-          These DDL methods and logging are protected with the exclusive
-          metadata lock on the schema.
-        */
-        if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len))
-        {
-          error= true;
-          goto exit;
-        }
-        query_pos= query_data_start;
+        table_deleted= true;
+        built_query.append("`");
+        built_query.append(db);
+        built_query.append("`.`");
+        built_query.append(tbl->table_name);
+        built_query.append("`,");
       }
-
-      *query_pos++ = '`';
-      query_pos= strmov(query_pos,tbl->table_name);
-      *query_pos++ = '`';
-      *query_pos++ = ',';
     }
 
-    if (query_pos != query_data_start)
+    if (table_deleted)
     {
+      /* Chop of the last comma */
+      built_query.chop();
+      built_query.append(" /* generated by server */");
+
       /*
         These DDL methods and logging are protected with the exclusive
         metadata lock on the schema.
       */
-      if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len))
-      {
-        error= true;
-        goto exit;
-      }
+      error= thd->binlog_query(THD::STMT_QUERY_TYPE,
+                               built_query.ptr(),
+                               built_query.length(),
+                               false, true, true, 0);
     }
   }
 

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2011-03-30 11:43:32 +0000
+++ b/sql/sql_table.cc	2011-03-31 15:23:43 +0000
@@ -2107,7 +2107,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST
   /* mark for close and remove all cached entries */
   thd->push_internal_handler(&err_handler);
   error= mysql_rm_table_no_locks(thd, tables, if_exists, drop_temporary,
-                                 false, false);
+                                 false, true);
   thd->pop_internal_handler();
 
   if (error)
@@ -2117,8 +2117,166 @@ bool mysql_rm_table(THD *thd,TABLE_LIST
 }
 
 
+enum enum_drop_table_result {
+  DROP_TABLE_ERROR,
+  DROP_TABLE_TMP_TABLE_NOT_FOUND,
+  DROP_TABLE_TRANS_TMP_TABLE,
+  DROP_TABLE_NON_TRANS_TMP_TABLE,
+  DROP_TABLE_NORMAL_TABLE_NOT_FOUND,
+  DROP_TABLE_NORMAL_TABLE_FK_ERROR,
+  DROP_TABLE_NORMAL_TABLE
+};
+
+
 /**
-  Execute the drop of a normal or temporary table.
+  Execute the drop of a single normal or temporary table.
+
+  @param  thd             Thread handler
+  @param  tables          Table to drop
+  @param  if_exists       If set, don't give an error if table doesn't exists.
+                          In this case we give an warning of level 'NOTE'
+  @param  drop_temporary  Only drop if the table is a temporary table
+  @param  drop_view       Allow to delete VIEW .frm
+  @param  log_query       Write query to log files. This will also
+                          generate warnings if the handler files doesn't exists
+
+  @note This function assumes that metadata lock has already been taken.
+        It is also assumed that the table has been removed from TDC.
+*/
+
+static enum_drop_table_result drop_table_no_lock(THD *thd, TABLE_LIST *table,
+                                                 bool if_exists,
+                                                 bool drop_temporary,
+                                                 bool drop_view, bool log_query)
+{
+  bool is_trans;
+  int drop_tmp_error= 1, error= 0;
+  enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN;
+  char path[FN_REFLEN + 1], *alias= NULL, *end;
+  uint path_length= 0;
+  handlerton *table_type;
+
+  DBUG_PRINT("table", ("table_l: '%s'.'%s'  table: 0x%lx  s: 0x%lx",
+                       table->db, table->table_name, (long) table->table,
+                       table->table ? (long) table->table->s : (long) -1));
+
+  /*
+    If we are in locked tables mode and are dropping a temporary table,
+    the ticket should be NULL to ensure that we don't release a lock
+    on a base table later.
+  */
+  DBUG_ASSERT(!(thd->locked_tables_mode &&
+                table->open_type != OT_BASE_ONLY &&
+                find_temporary_table(thd, table) &&
+                table->mdl_request.ticket != NULL));
+
+  /*
+    drop_temporary_table may return one of the following error codes:
+    .  0 - a temporary table was successfully dropped.
+    .  1 - a temporary table was not found.
+    . -1 - a temporary table is used by an outer statement.
+  */
+  if (table->open_type != OT_BASE_ONLY)
+  {
+    drop_tmp_error= drop_temporary_table(thd, table, &is_trans);
+    if (drop_tmp_error == -1)
+    {
+      DBUG_ASSERT(thd->in_sub_stmt);
+      return DROP_TABLE_ERROR;
+    }
+  }
+
+  // A temporary table should have been dropped, but was not found.
+  if (drop_temporary && drop_tmp_error == 1)
+    return DROP_TABLE_TMP_TABLE_NOT_FOUND;
+
+  // Temporary table was dropped.
+  if (drop_tmp_error == 0)
+    return is_trans ? DROP_TABLE_TRANS_TMP_TABLE :
+                      DROP_TABLE_NON_TRANS_TMP_TABLE;
+
+  // Drop normal table or view
+  if (thd->locked_tables_mode)
+  {
+    if (wait_while_table_is_used(thd, table->table, HA_EXTRA_FORCE_REOPEN))
+      return DROP_TABLE_ERROR;
+
+    close_all_tables_for_name(thd, table->table->s, TRUE);
+    table->table= NULL;
+  }
+
+  /* Check that we have an exclusive lock on the table to be dropped. */
+  DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db,
+                                             table->table_name,
+                                             MDL_EXCLUSIVE));
+  if (thd->killed)
+    return DROP_TABLE_ERROR;
+
+  DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
+  DBUG_EXECUTE_IF("sleep_before_no_locks_delete_table", my_sleep(100000););
+
+  alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
+  /* remove .frm file and engine files */
+  path_length= build_table_filename(path, sizeof(path) - 1, table->db, alias,
+                                    reg_ext,
+                                    table->internal_tmp_table ?
+                                    FN_IS_TMP : 0);
+  if ((access(path, F_OK) &&
+       ha_create_table_from_engine(thd, table->db, alias)) ||
+      (!drop_view && dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE))
+  {
+    /*
+      One of the following cases happened:
+      . "DROP" but table was not found on disk and table can't be
+      created from engine.
+      . ./sql/datadict.cc +32 /Alfranio - TODO: We need to test this.
+    */
+    return DROP_TABLE_NORMAL_TABLE_NOT_FOUND;
+  }
+
+  if (frm_db_type == DB_TYPE_UNKNOWN)
+  {
+    dd_frm_type(thd, path, &frm_db_type);
+    DBUG_PRINT("info", ("frm_db_type %d from %s", frm_db_type, path));
+  }
+  table_type= ha_resolve_by_legacy_type(thd, frm_db_type);
+  // Remove extension for delete
+  *(end= path + path_length - reg_ext_length)= '\0';
+  DBUG_PRINT("info", ("deleting table of type %d",
+                      (table_type ? table_type->db_type : 0)));
+  error= ha_delete_table(thd, table_type, path, table->db, table->table_name,
+                         log_query);
+
+  if (error == HA_ERR_ROW_IS_REFERENCED)
+    return DROP_TABLE_NORMAL_TABLE_FK_ERROR;
+
+  /* No error if non existent table and 'IF EXIST' clause or view */
+  if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
+      (if_exists || table_type == NULL))
+  {
+    error= 0;
+    thd->clear_error();
+  }
+
+  if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
+  {
+    int new_error;
+    /* Delete the table definition file */
+    strmov(end,reg_ext);
+    if (!(new_error= mysql_file_delete(key_file_frm, path, MYF(MY_WME))))
+    {
+      new_error= Table_triggers_list::drop_all_triggers(thd, table->db,
+                                                        table->table_name);
+    }
+    error|= new_error;
+  }
+  return error ? DROP_TABLE_NORMAL_TABLE_NOT_FOUND :
+                 DROP_TABLE_NORMAL_TABLE;
+}
+
+
+/**
+  Execute the drop of normal or temporary tables.
 
   @param  thd             Thread handler
   @param  tables          Tables to drop
@@ -2126,7 +2284,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST
                           In this case we give an warning of level 'NOTE'
   @param  drop_temporary  Only drop temporary tables
   @param  drop_view       Allow to delete VIEW .frm
-  @param  dont_log_query  Don't write query to log files. This will also not
+  @param  log_query       Write query to log files. This will also
                           generate warnings if the handler files doesn't exists
 
   @retval  0  ok
@@ -2147,19 +2305,15 @@ bool mysql_rm_table(THD *thd,TABLE_LIST
 
 int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
                             bool drop_temporary, bool drop_view,
-                            bool dont_log_query)
+                            bool log_query)
 {
   TABLE_LIST *table;
-  char path[FN_REFLEN + 1], *alias= NULL;
-  uint path_length= 0;
-  String wrong_tables;
-  int error= 0;
-  int non_temp_tables_count= 0;
-  bool foreign_key_error=0;
-  bool non_tmp_error= 0;
-  bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0;
-  bool non_tmp_table_deleted= 0;
-  String built_query;
+  int error= 0, non_temp_tables_count= 0;
+  bool foreign_key_error= false, non_tmp_error= false;
+  bool trans_tmp_table_deleted= false;
+  bool non_trans_tmp_table_deleted= false;
+  bool non_tmp_table_deleted= false;
+  String wrong_tables, built_query;
   String built_trans_tmp_query, built_non_trans_tmp_query;
   DBUG_ENTER("mysql_rm_table_no_locks");
 
@@ -2188,7 +2342,7 @@ int mysql_rm_table_no_locks(THD *thd, TA
     transaction and changes to non-transactional tables must be written
     ahead of the transaction in some circumstances.
   */
-  if (!dont_log_query)
+  if (log_query)
   {
     if (!drop_temporary)
     {
@@ -2217,244 +2371,113 @@ int mysql_rm_table_no_locks(THD *thd, TA
 
   for (table= tables; table; table= table->next_local)
   {
-    bool is_trans;
-    char *db=table->db;
-    handlerton *table_type;
-    enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN;
+    String *built_ptr_query= NULL;
+    enum_drop_table_result result;
 
     DBUG_PRINT("table", ("table_l: '%s'.'%s'  table: 0x%lx  s: 0x%lx",
                          table->db, table->table_name, (long) table->table,
                          table->table ? (long) table->table->s : (long) -1));
 
-    /*
-      If we are in locked tables mode and are dropping a temporary table,
-      the ticket should be NULL to ensure that we don't release a lock
-      on a base table later.
-    */
-    DBUG_ASSERT(!(thd->locked_tables_mode &&
-                  table->open_type != OT_BASE_ONLY &&
-                  find_temporary_table(thd, table) &&
-                  table->mdl_request.ticket != NULL));
+    result= drop_table_no_lock(thd, table, if_exists, drop_temporary,
+                               drop_view, log_query);
 
-    /*
-      drop_temporary_table may return one of the following error codes:
-      .  0 - a temporary table was successfully dropped.
-      .  1 - a temporary table was not found.
-      . -1 - a temporary table is used by an outer statement.
-    */
-    if (table->open_type == OT_BASE_ONLY)
-      error= 1;
-    else if ((error= drop_temporary_table(thd, table, &is_trans)) == -1)
+    if (result == DROP_TABLE_ERROR)
     {
-      DBUG_ASSERT(thd->in_sub_stmt);
+      error= 1;
       goto err;
     }
 
-    if ((drop_temporary && if_exists) || !error)
-    {
-      /*
-        This handles the case of temporary tables. We have the following cases:
+    DBUG_PRINT("table", ("table: 0x%lx  s: 0x%lx", (long) table->table,
+                         table->table ? (long) table->table->s : (long) -1));
 
-          . "DROP TEMPORARY" was executed and a temporary table was affected
-          (i.e. drop_temporary && !error) or the if_exists was specified (i.e.
-          drop_temporary && if_exists).
+    DBUG_EXECUTE_IF("bug43138",
+                    my_printf_error(ER_BAD_TABLE_ERROR,
+                                    ER(ER_BAD_TABLE_ERROR), MYF(0),
+                                    table->table_name););
 
-          . "DROP" was executed but a temporary table was affected (.i.e
-          !error).
-      */
-      if (!dont_log_query)
-      {
-        /*
-          If there is an error, we don't know the type of the engine
-          at this point. So, we keep it in the trx-cache.
-        */
-        is_trans= error ? TRUE : is_trans;
-        if (is_trans)
-          trans_tmp_table_deleted= TRUE;
-        else
-          non_trans_tmp_table_deleted= TRUE;
-
-        String *built_ptr_query=
-          (is_trans ? &built_trans_tmp_query : &built_non_trans_tmp_query);
-        /*
-          Don't write the database name if it is the current one (or if
-          thd->db is NULL).
-        */
-        built_ptr_query->append("`");
-        if (thd->db == NULL || strcmp(db,thd->db) != 0)
-        {
-          built_ptr_query->append(db);
-          built_ptr_query->append("`.`");
-        }
-        built_ptr_query->append(table->table_name);
-        built_ptr_query->append("`,");
-      }
-      /*
-        This means that a temporary table was droped and as such there
-        is no need to proceed with the code that tries to drop a regular
-        table.
-      */
-      if (!error) continue;
-    }
-    else if (!drop_temporary)
+    if (result == DROP_TABLE_TMP_TABLE_NOT_FOUND ||
+        result == DROP_TABLE_NORMAL_TABLE_NOT_FOUND ||
+        result == DROP_TABLE_NORMAL_TABLE_FK_ERROR)
     {
-      non_temp_tables_count++;
-
-      if (thd->locked_tables_mode)
-      {
-        if (wait_while_table_is_used(thd, table->table, HA_EXTRA_FORCE_REOPEN))
-        {
-          error= -1;
-          goto err;
-        }
-        close_all_tables_for_name(thd, table->table->s, TRUE);
-        table->table= 0;
-      }
-
-      /* Check that we have an exclusive lock on the table to be dropped. */
-      DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db,
-                                                 table->table_name,
-                                                 MDL_EXCLUSIVE));
-      if (thd->killed)
-      {
-        error= -1;
-        goto err;
-      }
-      alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
-      /* remove .frm file and engine files */
-      path_length= build_table_filename(path, sizeof(path) - 1, db, alias,
-                                        reg_ext,
-                                        table->internal_tmp_table ?
-                                        FN_IS_TMP : 0);
-
-      /*
-        This handles the case where a "DROP" was executed and a regular
-        table "may be" dropped as drop_temporary is FALSE and error is
-        TRUE. If the error was FALSE a temporary table was dropped and
-        regardless of the status of drop_tempoary a "DROP TEMPORARY"
-        must be used.
-      */
-      if (!dont_log_query)
+      String tbl_name;
+      tbl_name.append(String(table->db,system_charset_info));
+      tbl_name.append('.');
+      tbl_name.append(String(table->table_name,system_charset_info));
+
+      if (if_exists && result != DROP_TABLE_NORMAL_TABLE_FK_ERROR)
+        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                            ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
+                            tbl_name.c_ptr());
+      else
       {
-        /*
-          Note that unless if_exists is TRUE or a temporary table was deleted, 
-          there is no means to know if the statement should be written to the
-          binary log. See further information on this variable in what follows.
-        */
-        non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted);
-        /*
-          Don't write the database name if it is the current one (or if
-          thd->db is NULL).
-        */
-        built_query.append("`");
-        if (thd->db == NULL || strcmp(db,thd->db) != 0)
-        {
-          built_query.append(db);
-          built_query.append("`.`");
-        }
-
-        built_query.append(table->table_name);
-        built_query.append("`,");
+        if (wrong_tables.length())
+          wrong_tables.append(',');
+        wrong_tables.append(tbl_name);
       }
     }
-    DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
-    DBUG_EXECUTE_IF("sleep_before_no_locks_delete_table",
-                    my_sleep(100000););
-    error= 0;
-    if (drop_temporary ||
-        ((access(path, F_OK) &&
-          ha_create_table_from_engine(thd, db, alias)) ||
-         (!drop_view &&
-          dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
+
+    switch (result)
     {
-      /*
-        One of the following cases happened:
-          . "DROP TEMPORARY" but a temporary table was not found.
-          . "DROP" but table was not found on disk and table can't be
-            created from engine.
-          . ./sql/datadict.cc +32 /Alfranio - TODO: We need to test this.
-      */
+    case DROP_TABLE_TMP_TABLE_NOT_FOUND:
       if (if_exists)
       {
-        String tbl_name;
-        tbl_name.append(String(db,system_charset_info));
-        tbl_name.append('.');
-        tbl_name.append(String(table->table_name,system_charset_info));
-
-	push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-			    ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
-			    tbl_name.c_ptr());
+        trans_tmp_table_deleted= true;
+        built_ptr_query= &built_trans_tmp_query;
       }
+      non_tmp_error= non_tmp_error || !drop_temporary;
+      break;
+    case DROP_TABLE_TRANS_TMP_TABLE:
+      trans_tmp_table_deleted= true;
+      built_ptr_query= &built_trans_tmp_query;
+      break;
+    case DROP_TABLE_NON_TRANS_TMP_TABLE:
+      non_trans_tmp_table_deleted= true;
+      built_ptr_query= &built_non_trans_tmp_query;
+      break;
+    case DROP_TABLE_NORMAL_TABLE_NOT_FOUND:
+      if (if_exists)
+        non_tmp_table_deleted= true;
       else
-      {
-        non_tmp_error = (drop_temporary ? non_tmp_error : TRUE);
-        error= 1;
-      }
+        non_tmp_error= true;
+      built_ptr_query= &built_query;
+      break;
+    case DROP_TABLE_NORMAL_TABLE_FK_ERROR:
+      if (if_exists)
+        non_tmp_table_deleted= true;
+      non_tmp_error= true;
+      foreign_key_error= true;
+      built_ptr_query= &built_query;
+      break;
+    case DROP_TABLE_NORMAL_TABLE:
+      non_temp_tables_count++;
+      non_tmp_table_deleted= true;
+      built_ptr_query= &built_query;
+      break;
+    default:
+      DBUG_ASSERT(false);
+      break;
     }
-    else
+
+    if (log_query && built_ptr_query)
     {
-      char *end;
-      if (frm_db_type == DB_TYPE_UNKNOWN)
-      {
-        dd_frm_type(thd, path, &frm_db_type);
-        DBUG_PRINT("info", ("frm_db_type %d from %s", frm_db_type, path));
-      }
-      table_type= ha_resolve_by_legacy_type(thd, frm_db_type);
-      // Remove extension for delete
-      *(end= path + path_length - reg_ext_length)= '\0';
-      DBUG_PRINT("info", ("deleting table of type %d",
-                          (table_type ? table_type->db_type : 0)));
-      error= ha_delete_table(thd, table_type, path, db, table->table_name,
-                             !dont_log_query);
-
-      /* No error if non existent table and 'IF EXIST' clause or view */
-      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) && 
-	  (if_exists || table_type == NULL))
-      {
-	error= 0;
-        thd->clear_error();
-      }
-      if (error == HA_ERR_ROW_IS_REFERENCED)
-      {
-	/* the table is referenced by a foreign key constraint */
-	foreign_key_error= 1;
-      }
-      if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
+      /*
+        Don't write the database name if it is the current one (or if
+        thd->db is NULL).
+      */
+      built_ptr_query->append("`");
+      if (thd->db == NULL || strcmp(table->db,thd->db) != 0)
       {
-        int new_error;
-	/* Delete the table definition file */
-	strmov(end,reg_ext);
-        if (!(new_error= mysql_file_delete(key_file_frm, path, MYF(MY_WME))))
-        {
-          non_tmp_table_deleted= TRUE;
-          new_error= Table_triggers_list::drop_all_triggers(thd, db,
-                                                            table->table_name);
-        }
-        error|= new_error;
+        built_ptr_query->append(table->db);
+        built_ptr_query->append("`.`");
       }
-       non_tmp_error= error ? TRUE : non_tmp_error;
+      built_ptr_query->append(table->table_name);
+      built_ptr_query->append("`,");
     }
-    if (error)
-    {
-      if (wrong_tables.length())
-	wrong_tables.append(',');
-
-      wrong_tables.append(String(db,system_charset_info));
-      wrong_tables.append('.');
-      wrong_tables.append(String(table->table_name,system_charset_info));
-    }
-    DBUG_PRINT("table", ("table: 0x%lx  s: 0x%lx", (long) table->table,
-                         table->table ? (long) table->table->s : (long) -1));
-
-    DBUG_EXECUTE_IF("bug43138",
-                    my_printf_error(ER_BAD_TABLE_ERROR,
-                                    ER(ER_BAD_TABLE_ERROR), MYF(0),
-                                    table->table_name););
   }
   DEBUG_SYNC(thd, "rm_table_no_locks_before_binlog");
   thd->thread_specific_used|= (trans_tmp_table_deleted ||
                                non_trans_tmp_table_deleted);
-  error= 0;
+
 err:
   if (wrong_tables.length())
   {
@@ -2470,7 +2493,7 @@ err:
       trans_tmp_table_deleted || non_tmp_table_deleted)
   {
     query_cache_invalidate3(thd, tables, 0);
-    if (!dont_log_query && mysql_bin_log.is_open())
+    if (log_query && mysql_bin_log.is_open())
     {
       if (non_trans_tmp_table_deleted)
       {


Attachment: [text/bzr-bundle] bzr/jon.hauglid@oracle.com-20110331152343-09zir6xtefyumr82.bundle
Thread
bzr commit into mysql-trunk branch (jon.hauglid:3350) Bug#11765416Jon Olav Hauglid31 Mar