List:Commits« Previous MessageNext Message »
From:He Zhenxing Date:March 1 2011 6:24am
Subject:bzr commit into mysql-trunk branch (hezx:3519) WL#5778
View as plain text  
#At file:///home/hezx/work/mysql/bzr/w5778/trunk/ based on revid:zhenxing.he@stripped

 3519 He Zhenxing	2011-03-01
      WL#5778
      
      Move all binlog related functions from THD to Binlog

    modified:
      sql/binlog.cc
      sql/binlog.h
      sql/event_db_repository.cc
      sql/events.cc
      sql/ha_partition.cc
      sql/handler.cc
      sql/log_event.cc
      sql/log_event.h
      sql/log_event_old.cc
      sql/log_event_old.h
      sql/rpl_injector.cc
      sql/sp.cc
      sql/sp_head.cc
      sql/sql_acl.cc
      sql/sql_base.cc
      sql/sql_class.cc
      sql/sql_class.h
      sql/sql_delete.cc
      sql/sql_insert.cc
      sql/sql_load.cc
      sql/sql_parse.cc
      sql/sql_table.cc
      sql/sql_truncate.cc
      sql/sql_udf.cc
      sql/sys_vars.cc
      sql/table.cc
=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc	2011-01-31 07:32:53 +0000
+++ b/sql/binlog.cc	2011-03-01 06:23:58 +0000
@@ -464,7 +464,7 @@ binlog_trans_log_savepos(THD *thd, my_of
   DBUG_ENTER("binlog_trans_log_savepos");
   DBUG_ASSERT(pos != NULL);
   if (thd_get_ha_data(thd, binlog_hton) == NULL)
-    thd->binlog_setup_trx_data();
+    binlog.binlog_setup_trx_data(thd);
   binlog_cache_mngr *const cache_mngr=
     (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
   DBUG_ASSERT(mysql_bin_log.is_open());
@@ -560,7 +560,7 @@ binlog_flush_cache(THD *thd, binlog_cach
 
   if (!cache_data->empty())
   {
-    if (thd->binlog_flush_pending_rows_event(TRUE, is_transactional))
+    if (binlog.binlog_flush_pending_rows_event(thd, TRUE, is_transactional))
       DBUG_RETURN(1);
     /*
       Doing a commit or a rollback including non-transactional tables,
@@ -683,7 +683,7 @@ binlog_truncate_trx_cache(THD *thd, binl
                       FLAGSTR(thd->variables.option_bits, OPTION_BEGIN),
                       all ? "all" : "stmt"));
 
-  thd->binlog_remove_pending_rows_event(TRUE, is_transactional);
+  binlog.binlog_remove_pending_rows_event(thd, TRUE, is_transactional);
   /*
     If rolling back an entire transaction or a single statement not
     inside a transaction, we reset the transaction cache.
@@ -693,7 +693,7 @@ binlog_truncate_trx_cache(THD *thd, binl
     if (cache_mngr->trx_cache.has_incident())
       error= mysql_bin_log.write_incident(thd, TRUE);
 
-    thd->clear_binlog_table_maps();
+    binlog.clear_binlog_table_maps(thd);
 
     cache_mngr->reset_cache(&cache_mngr->trx_cache);
   }
@@ -704,7 +704,7 @@ binlog_truncate_trx_cache(THD *thd, binl
   else
     cache_mngr->trx_cache.restore_prev_position();
 
-  DBUG_ASSERT(thd->binlog_get_pending_rows_event(is_transactional) == NULL);
+  DBUG_ASSERT(binlog.binlog_get_pending_rows_event(thd, is_transactional) == NULL);
   DBUG_RETURN(error);
 }
 
@@ -1177,13 +1177,13 @@ stmt_has_updated_trans_table(const THD *
   @return
     @c true if a trx-cache should be used, @c false otherwise.
 */
-bool use_trans_cache(const THD* thd, bool is_transactional)
+bool use_trans_cache(THD* thd, bool is_transactional)
 {
   binlog_cache_mngr *const cache_mngr=
     (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
 
   return
-    ((thd->is_current_stmt_binlog_format_row() ||
+    ((binlog.is_current_stmt_binlog_format_row(thd) ||
      thd->variables.binlog_direct_non_trans_update) ? is_transactional :
      (is_transactional || !cache_mngr->trx_cache.empty()));
 }
@@ -1400,7 +1400,7 @@ int binlog_loaded_block(IO_CACHE* file)
   uchar* buffer= (uchar*) my_b_get_buffer_start(file);
   uint max_event_size= current_thd->variables.max_allowed_packet;
   lf_info= (LOAD_FILE_INFO*) file->arg;
-  if (lf_info->thd->is_current_stmt_binlog_format_row())
+  if (binlog.is_current_stmt_binlog_format_row(lf_info->thd))
     DBUG_RETURN(0);
   if (lf_info->last_pos_in_file != HA_POS_ERROR &&
       lf_info->last_pos_in_file >= my_b_get_pos_in_file(file))
@@ -3334,7 +3334,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_row
     delete pending;
   }
 
-  thd->binlog_set_pending_rows_event(event, is_transactional);
+  binlog.binlog_set_pending_rows_event(thd, event, is_transactional);
 
   DBUG_RETURN(error);
 }
@@ -3370,8 +3370,8 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
   */
   bool const end_stmt=
     thd->locked_tables_mode && thd->lex->requires_prelocking();
-  if (thd->binlog_flush_pending_rows_event(end_stmt,
-                                           event_info->use_trans_cache()))
+  if (binlog.binlog_flush_pending_rows_event(thd, end_stmt,
+                                             event_info->use_trans_cache()))
     DBUG_RETURN(error);
 
   /*
@@ -3404,7 +3404,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
     }
     else
     {
-      if (thd->binlog_setup_trx_data())
+      if (binlog.binlog_setup_trx_data(thd))
         goto err;
 
       binlog_cache_mngr *const cache_mngr=
@@ -3417,7 +3417,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
       if (thd->lex->stmt_accessed_non_trans_temp_table())
         cache_data->set_changes_to_non_trans_temp_table();
 
-      thd->binlog_start_trans_and_stmt();
+      binlog.binlog_start_trans_and_stmt(thd);
     }
     DBUG_PRINT("info",("event type: %d",event_info->get_type_code()));
 
@@ -3431,7 +3431,7 @@ bool MYSQL_BIN_LOG::write(Log_event *eve
     */
     if (thd)
     {
-      if (!thd->is_current_stmt_binlog_format_row())
+      if (!binlog.is_current_stmt_binlog_format_row(thd))
       {
         /* three possibility for cache_type at this point */
         DBUG_ASSERT(event_info->cache_type == Log_event::EVENT_TRANSACTIONAL_CACHE ||
@@ -4368,11 +4368,11 @@ err1:
   binlog_hton, which has internal linkage.
 */
 
-int THD::binlog_setup_trx_data()
+int Binlog::binlog_setup_trx_data(THD* thd)
 {
-  DBUG_ENTER("THD::binlog_setup_trx_data");
+  DBUG_ENTER("Binlog::binlog_setup_trx_data");
   binlog_cache_mngr *cache_mngr=
-    (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
+    (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
 
   if (cache_mngr)
     DBUG_RETURN(0);                             // Already set up
@@ -4387,9 +4387,9 @@ int THD::binlog_setup_trx_data()
     my_free(cache_mngr);
     DBUG_RETURN(1);                      // Didn't manage to set it up
   }
-  thd_set_ha_data(this, binlog_hton, cache_mngr);
+  thd_set_ha_data(thd, binlog_hton, cache_mngr);
 
-  cache_mngr= new (thd_get_ha_data(this, binlog_hton))
+  cache_mngr= new (thd_get_ha_data(thd, binlog_hton))
               binlog_cache_mngr(max_binlog_stmt_cache_size,
                                 max_binlog_cache_size,
                                 &binlog_stmt_cache_use,
@@ -4420,16 +4420,16 @@ int THD::binlog_setup_trx_data()
       We only update the saved position if the old one was undefined,
       the reason is that there are some cases (e.g., for CREATE-SELECT)
       where the position is saved twice (e.g., both in
-      select_create::prepare() and THD::binlog_write_table_map()) , but
+      select_create::prepare() and Binlog::binlog_write_table_map()) , but
       we should use the first. This means that calls to this function
       can be used to start the statement before the first table map
       event, to include some extra events.
  */
 
 void
-THD::binlog_start_trans_and_stmt()
+Binlog::binlog_start_trans_and_stmt(THD* thd)
 {
-  binlog_cache_mngr *cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
+  binlog_cache_mngr *cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
   DBUG_ENTER("binlog_start_trans_and_stmt");
   DBUG_PRINT("enter", ("cache_mngr: %p  cache_mngr->trx_cache.get_prev_position(): %lu",
                        cache_mngr,
@@ -4439,10 +4439,10 @@ THD::binlog_start_trans_and_stmt()
   if (cache_mngr == NULL ||
       cache_mngr->trx_cache.get_prev_position() == MY_OFF_T_UNDEF)
   {
-    this->binlog_set_stmt_begin();
-    if (in_multi_stmt_transaction_mode())
-      trans_register_ha(this, TRUE, binlog_hton);
-    trans_register_ha(this, FALSE, binlog_hton);
+    binlog_set_stmt_begin(thd);
+    if (thd->in_multi_stmt_transaction_mode())
+      trans_register_ha(thd, TRUE, binlog_hton);
+    trans_register_ha(thd, FALSE, binlog_hton);
     /*
       Mark statement transaction as read/write. We never start
       a binary log transaction and keep it read-only,
@@ -4452,14 +4452,14 @@ THD::binlog_start_trans_and_stmt()
       since the statement-level flag will be propagated automatically
       inside ha_commit_trans.
     */
-    ha_data[binlog_hton->slot].ha_info[0].set_trx_read_write();
+    thd->ha_data[binlog_hton->slot].ha_info[0].set_trx_read_write();
   }
   DBUG_VOID_RETURN;
 }
 
-void THD::binlog_set_stmt_begin() {
+void Binlog::binlog_set_stmt_begin(THD* thd) {
   binlog_cache_mngr *cache_mngr=
-    (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
+    (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
 
   /*
     The call to binlog_trans_log_savepos() might create the cache_mngr
@@ -4468,8 +4468,8 @@ void THD::binlog_set_stmt_begin() {
     data for the binary log (i.e., cache_mngr).
   */
   my_off_t pos= 0;
-  binlog_trans_log_savepos(this, &pos);
-  cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
+  binlog_trans_log_savepos(thd, &pos);
+  cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
   cache_mngr->trx_cache.set_prev_position(pos);
 }
 
@@ -4493,36 +4493,36 @@ void THD::binlog_set_stmt_begin() {
     nonzero if an error pops up when writing the table map event
     or the Rows_query log event.
 */
-int THD::binlog_write_table_map(TABLE *table, bool is_transactional,
+int Binlog::binlog_write_table_map(THD* thd, TABLE *table, bool is_transactional,
                                 bool binlog_rows_query)
 {
   int error;
-  DBUG_ENTER("THD::binlog_write_table_map");
+  DBUG_ENTER("Binlog::binlog_write_table_map");
   DBUG_PRINT("enter", ("table: 0x%lx  (%s: #%lu)",
                        (long) table, table->s->table_name.str,
                        table->s->table_map_id));
 
   /* Pre-conditions */
-  DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
+  DBUG_ASSERT(is_current_stmt_binlog_format_row(thd) && enabled());
   DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
 
   Table_map_log_event
-    the_event(this, table, table->s->table_map_id, is_transactional);
+    the_event(thd, table, table->s->table_map_id, is_transactional);
 
-  if (binlog_table_maps == 0)
-    binlog_start_trans_and_stmt();
+  if (thd->binlog_table_maps == 0)
+    binlog_start_trans_and_stmt(thd);
 
   binlog_cache_mngr *const cache_mngr=
-    (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
+    (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
 
   IO_CACHE *file=
-    cache_mngr->get_binlog_cache_log(use_trans_cache(this, is_transactional));
+    cache_mngr->get_binlog_cache_log(use_trans_cache(thd, is_transactional));
 
-  if (binlog_rows_query && this->query())
+  if (binlog_rows_query && thd->query())
   {
     /* Write the Rows_query_log_event into binlog before the table map */
     Rows_query_log_event
-      rows_query_ev(this, this->query(), this->query_length());
+      rows_query_ev(thd, thd->query(), thd->query_length());
     if ((error= rows_query_ev.write(file)))
       DBUG_RETURN(error);
   }
@@ -4530,7 +4530,7 @@ int THD::binlog_write_table_map(TABLE *t
   if ((error= the_event.write(file)))
     DBUG_RETURN(error);
 
-  binlog_table_maps++;
+  thd->binlog_table_maps++;
   DBUG_RETURN(0);
 }
 
@@ -4546,11 +4546,11 @@ int THD::binlog_write_table_map(TABLE *t
     The row event if any. 
 */
 Rows_log_event*
-THD::binlog_get_pending_rows_event(bool is_transactional) const
+Binlog::binlog_get_pending_rows_event(THD* thd, bool is_transactional) const
 {
   Rows_log_event* rows= NULL;
   binlog_cache_mngr *const cache_mngr=
-    (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
+    (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
 
   /*
     This is less than ideal, but here's the story: If there is no cache_mngr,
@@ -4560,7 +4560,7 @@ THD::binlog_get_pending_rows_event(bool 
   if (cache_mngr)
   {
     binlog_cache_data *cache_data=
-      cache_mngr->get_binlog_cache_data(use_trans_cache(this, is_transactional));
+      cache_mngr->get_binlog_cache_data(use_trans_cache(thd, is_transactional));
 
     rows= cache_data->pending();
   }
@@ -4578,18 +4578,18 @@ THD::binlog_get_pending_rows_event(bool 
                            otherwise @c false a non-transactional.
 */
 void
-THD::binlog_set_pending_rows_event(Rows_log_event* ev, bool is_transactional)
+Binlog::binlog_set_pending_rows_event(THD* thd, Rows_log_event* ev, bool is_transactional)
 {
-  if (thd_get_ha_data(this, binlog_hton) == NULL)
-    binlog_setup_trx_data();
+  if (thd_get_ha_data(thd, binlog_hton) == NULL)
+    binlog_setup_trx_data(thd);
 
   binlog_cache_mngr *const cache_mngr=
-    (binlog_cache_mngr*) thd_get_ha_data(this, binlog_hton);
+    (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
 
   DBUG_ASSERT(cache_mngr);
 
   binlog_cache_data *cache_data=
-    cache_mngr->get_binlog_cache_data(use_trans_cache(this, is_transactional));
+    cache_mngr->get_binlog_cache_data(use_trans_cache(thd, is_transactional));
 
   cache_data->set_pending(ev);
 }
@@ -4683,7 +4683,7 @@ THD::binlog_set_pending_rows_event(Rows_
   warnings, we set the thd->binlog_flags variable: the warning will be
   printed only if the statement is successfully logged.
 
-  @see THD::binlog_query
+  @see Binlog::binlog_query
 
   @param[in] thd    Client thread
   @param[in] tables Tables involved in the query
@@ -4692,12 +4692,13 @@ THD::binlog_set_pending_rows_event(Rows_
   @retval -1 One of the error conditions above applies (1, 2, 4, 5, or 6).
 */
 
-int THD::decide_logging_format(TABLE_LIST *tables)
+int Binlog::decide_logging_format(THD* thd, TABLE_LIST *tables)
 {
-  DBUG_ENTER("THD::decide_logging_format");
-  DBUG_PRINT("info", ("query: %s", query()));
+  LEX* lex= thd->lex;
+  DBUG_ENTER("Binlog::decide_logging_format");
+  DBUG_PRINT("info", ("query: %s", thd->query()));
   DBUG_PRINT("info", ("variables.binlog_format: %lu",
-                      variables.binlog_format));
+                      thd->variables.binlog_format));
   DBUG_PRINT("info", ("lex->get_stmt_unsafe_flags(): 0x%x",
                       lex->get_stmt_unsafe_flags()));
 
@@ -4706,9 +4707,9 @@ int THD::decide_logging_format(TABLE_LIS
     binlogging is off, or if the statement is filtered out from the
     binlog by filtering rules.
   */
-  if (mysql_bin_log.is_open() && (variables.option_bits & OPTION_BIN_LOG) &&
-      !(variables.binlog_format == BINLOG_FORMAT_STMT &&
-        !binlog_filter->db_ok(db)))
+  if (enabled(thd) &&
+      !(thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
+        !binlog_filter->db_ok(thd->db)))
   {
     /*
       Compute one bit field with the union of all the engine
@@ -4752,7 +4753,7 @@ int THD::decide_logging_format(TABLE_LIS
         "PRELOCKED_UNDER_LOCK_TABLES",
       };
       DBUG_PRINT("debug", ("prelocked_mode: %s",
-                           prelocked_mode_name[locked_tables_mode]));
+                           prelocked_mode_name[thd->locked_tables_mode]));
     }
 #endif
 
@@ -4826,12 +4827,12 @@ int THD::decide_logging_format(TABLE_LIS
     int error= 0;
     int unsafe_flags;
 
-    bool multi_stmt_trans= in_multi_stmt_transaction_mode();
-    bool trans_table= trans_has_updated_trans_table(this);
-    bool binlog_direct= variables.binlog_direct_non_trans_update;
+    bool multi_stmt_trans= thd->in_multi_stmt_transaction_mode();
+    bool trans_table= trans_has_updated_trans_table(thd);
+    bool binlog_direct= thd->variables.binlog_direct_non_trans_update;
 
     if (lex->is_mixed_stmt_unsafe(multi_stmt_trans, binlog_direct,
-                                  trans_table, tx_isolation))
+                                  trans_table, thd->tx_isolation))
       lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_MIXED_STATEMENT);
     else if (multi_stmt_trans && trans_table && !binlog_direct &&
              lex->stmt_accessed_table(LEX::STMT_WRITES_NON_TRANS_TABLE))
@@ -4870,8 +4871,8 @@ int THD::decide_logging_format(TABLE_LIS
         */
         my_error((error= ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE), MYF(0));
       }
-      else if (variables.binlog_format == BINLOG_FORMAT_ROW &&
-               sqlcom_can_generate_row_events(this))
+      else if (thd->variables.binlog_format == BINLOG_FORMAT_ROW &&
+               sqlcom_can_generate_row_events(thd))
       {
         /*
           2. Error: Cannot modify table that uses a storage engine
@@ -4899,7 +4900,7 @@ int THD::decide_logging_format(TABLE_LIS
     else
     {
       /* binlog_format = STATEMENT */
-      if (variables.binlog_format == BINLOG_FORMAT_STMT)
+      if (thd->variables.binlog_format == BINLOG_FORMAT_STMT)
       {
         if (lex->is_stmt_row_injection())
         {
@@ -4910,7 +4911,7 @@ int THD::decide_logging_format(TABLE_LIS
           my_error((error= ER_BINLOG_ROW_INJECTION_AND_STMT_MODE), MYF(0));
         }
         else if ((flags_write_all_set & HA_BINLOG_STMT_CAPABLE) == 0 &&
-                 sqlcom_can_generate_row_events(this))
+                 sqlcom_can_generate_row_events(thd))
         {
           /*
             5. Error: Cannot modify table that uses a storage engine
@@ -4924,12 +4925,12 @@ int THD::decide_logging_format(TABLE_LIS
             7. Warning: Unsafe statement logged as statement due to
                binlog_format = STATEMENT
           */
-          binlog_unsafe_warning_flags|= unsafe_flags;
+          thd->binlog_unsafe_warning_flags|= unsafe_flags;
           DBUG_PRINT("info", ("Scheduling warning to be issued by "
                               "binlog_query: '%s'",
                               ER(ER_BINLOG_UNSAFE_STATEMENT)));
           DBUG_PRINT("info", ("binlog_unsafe_warning_flags: 0x%x",
-                              binlog_unsafe_warning_flags));
+                              thd->binlog_unsafe_warning_flags));
         }
         /* log in statement format! */
       }
@@ -4941,7 +4942,7 @@ int THD::decide_logging_format(TABLE_LIS
             || (flags_write_all_set & HA_BINLOG_STMT_CAPABLE) == 0)
         {
           /* log in row format! */
-          set_current_stmt_binlog_format_row_if_mixed();
+          set_current_stmt_binlog_format_row_if_mixed(thd);
         }
       }
     }
@@ -4951,7 +4952,7 @@ int THD::decide_logging_format(TABLE_LIS
       DBUG_RETURN(-1);
     }
     DBUG_PRINT("info", ("decision: logging in %s format",
-                        is_current_stmt_binlog_format_row() ?
+                        is_current_stmt_binlog_format_row(thd) ?
                         "ROW" : "STATEMENT"));
   }
 #ifndef DBUG_OFF
@@ -4961,10 +4962,10 @@ int THD::decide_logging_format(TABLE_LIS
                         "and (options & OPTION_BIN_LOG) = 0x%llx "
                         "and binlog_format = %lu "
                         "and binlog_filter->db_ok(db) = %d",
-                        mysql_bin_log.is_open(),
-                        (variables.option_bits & OPTION_BIN_LOG),
-                        variables.binlog_format,
-                        binlog_filter->db_ok(db)));
+                        enabled(),
+                        (thd->variables.option_bits & OPTION_BIN_LOG),
+                        thd->variables.binlog_format,
+                        binlog_filter->db_ok(thd->db)));
 #endif
 
   DBUG_RETURN(0);
@@ -5001,7 +5002,7 @@ int THD::decide_logging_format(TABLE_LIS
  */
 
 template <class RowsEventT> Rows_log_event* 
-THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
+Binlog::binlog_prepare_pending_rows_event(THD* thd, TABLE* table, uint32 serv_id,
                                        size_t needed,
                                        bool is_transactional,
 				       RowsEventT *hint __attribute__((unused)))
@@ -5017,10 +5018,10 @@ THD::binlog_prepare_pending_rows_event(T
     There is no good place to set up the transactional data, so we
     have to do it here.
   */
-  if (binlog_setup_trx_data())
+  if (binlog_setup_trx_data(thd))
     DBUG_RETURN(NULL);
 
-  Rows_log_event* pending= binlog_get_pending_rows_event(is_transactional);
+  Rows_log_event* pending= binlog_get_pending_rows_event(thd, is_transactional);
 
   if (unlikely(pending && !pending->is_valid()))
     DBUG_RETURN(NULL);
@@ -5044,7 +5045,7 @@ THD::binlog_prepare_pending_rows_event(T
   {
     /* Create a new RowsEventT... */
     Rows_log_event* const
-	ev= new RowsEventT(this, table, table->s->table_map_id,
+	ev= new RowsEventT(thd, table, table->s->table_map_id,
                            is_transactional);
     if (unlikely(!ev))
       DBUG_RETURN(NULL);
@@ -5054,7 +5055,7 @@ THD::binlog_prepare_pending_rows_event(T
       event...
     */
     if (unlikely(
-        mysql_bin_log.flush_and_set_pending_rows_event(this, ev,
+        mysql_bin_log.flush_and_set_pending_rows_event(thd, ev,
                                                        is_transactional)))
     {
       delete ev;
@@ -5072,15 +5073,15 @@ THD::binlog_prepare_pending_rows_event(T
   compiling option.
 */
 template Rows_log_event*
-THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
+Binlog::binlog_prepare_pending_rows_event(THD* thd, TABLE*, uint32, size_t, bool,
 				       Write_rows_log_event*);
 
 template Rows_log_event*
-THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
+Binlog::binlog_prepare_pending_rows_event(THD* thd, TABLE*, uint32, size_t, bool,
 				       Delete_rows_log_event *);
 
 template Rows_log_event* 
-THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
+Binlog::binlog_prepare_pending_rows_event(THD* thd, TABLE*, uint32, size_t, bool,
 				       Update_rows_log_event *);
 #endif
 
@@ -5208,10 +5209,11 @@ CPP_UNNAMED_NS_START
 
 CPP_UNNAMED_NS_END
 
-int THD::binlog_write_row(TABLE* table, bool is_trans, 
-                          uchar const *record) 
+int Binlog::binlog_write_row(THD* thd, TABLE* table, bool is_trans, 
+                             uchar const *before __attribute__((unused)),
+                             uchar const *record)
 { 
-  DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
+  DBUG_ASSERT(is_current_stmt_binlog_format_row(thd) && enabled());
 
   /*
     Pack records into format for transfer. We are allocating more
@@ -5226,7 +5228,7 @@ int THD::binlog_write_row(TABLE* table, 
   size_t const len= pack_row(table, table->write_set, row_data, record);
 
   Rows_log_event* const ev=
-    binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
+    binlog_prepare_pending_rows_event(thd, table, server_id, len, is_trans,
                                       static_cast<Write_rows_log_event*>(0));
 
   if (unlikely(ev == 0))
@@ -5235,11 +5237,11 @@ int THD::binlog_write_row(TABLE* table, 
   return ev->add_row_data(row_data, len);
 }
 
-int THD::binlog_update_row(TABLE* table, bool is_trans,
+int Binlog::binlog_update_row(THD* thd, TABLE* table, bool is_trans,
                            const uchar *before_record,
                            const uchar *after_record)
 { 
-  DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
+  DBUG_ASSERT(is_current_stmt_binlog_format_row(thd) && enabled());
   int error= 0;
 
   /**
@@ -5283,7 +5285,7 @@ int THD::binlog_update_row(TABLE* table,
 #endif
 
   Rows_log_event* const ev=
-    binlog_prepare_pending_rows_event(table, server_id,
+    binlog_prepare_pending_rows_event(thd, table, server_id,
 				      before_size + after_size, is_trans,
 				      static_cast<Update_rows_log_event*>(0));
 
@@ -5300,10 +5302,12 @@ int THD::binlog_update_row(TABLE* table,
   return error;
 }
 
-int THD::binlog_delete_row(TABLE* table, bool is_trans, 
-                           uchar const *record)
+int Binlog::binlog_delete_row(THD* thd, TABLE* table, bool is_trans, 
+                              uchar const *record,
+                              uchar const *after __attribute__((unused)))
+
 { 
-  DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
+  DBUG_ASSERT(is_current_stmt_binlog_format_row(thd) && enabled());
   int error= 0;
 
   /**
@@ -5334,7 +5338,7 @@ int THD::binlog_delete_row(TABLE* table,
   size_t const len= pack_row(table, table->read_set, row_data, record);
 
   Rows_log_event* const ev=
-    binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
+    binlog_prepare_pending_rows_event(thd, table, server_id, len, is_trans,
 				      static_cast<Delete_rows_log_event*>(0));
 
   if (unlikely(ev == 0))
@@ -5349,9 +5353,9 @@ int THD::binlog_delete_row(TABLE* table,
   return error;
 }
 
-void THD::binlog_prepare_row_images(TABLE *table) 
+void Binlog::binlog_prepare_row_images(TABLE *table)
 {
-  DBUG_ENTER("THD::binlog_prepare_row_images");
+  DBUG_ENTER("Binlog::binlog_prepare_row_images");
   /** 
     Remove from read_set spurious columns. The write_set has been
     handled before in table->mark_columns_needed_for_update. 
@@ -5410,31 +5414,32 @@ void THD::binlog_prepare_row_images(TABL
 }
 
 
-int THD::binlog_remove_pending_rows_event(bool clear_maps,
+int Binlog::binlog_remove_pending_rows_event(THD* thd, bool clear_maps,
                                           bool is_transactional)
 {
-  DBUG_ENTER("THD::binlog_remove_pending_rows_event");
+  DBUG_ENTER("Binlog::binlog_remove_pending_rows_event");
 
-  if (!mysql_bin_log.is_open())
+  if (!enabled())
     DBUG_RETURN(0);
 
-  mysql_bin_log.remove_pending_rows_event(this, is_transactional);
+  mysql_bin_log.remove_pending_rows_event(thd, is_transactional);
 
   if (clear_maps)
-    binlog_table_maps= 0;
+    thd->binlog_table_maps= 0;
 
   DBUG_RETURN(0);
 }
 
-int THD::binlog_flush_pending_rows_event(bool stmt_end, bool is_transactional)
+int Binlog::binlog_flush_pending_rows_event(THD* thd, bool stmt_end,
+                                            bool is_transactional)
 {
-  DBUG_ENTER("THD::binlog_flush_pending_rows_event");
+  DBUG_ENTER("Binlog::binlog_flush_pending_rows_event");
   /*
     We shall flush the pending event even if we are not in row-based
     mode: it might be the case that we left row-based mode before
     flushing anything (e.g., if we have explicitly locked tables).
    */
-  if (!mysql_bin_log.is_open())
+  if (!enabled())
     DBUG_RETURN(0);
 
   /*
@@ -5442,15 +5447,16 @@ int THD::binlog_flush_pending_rows_event
     flag is set.
   */
   int error= 0;
-  if (Rows_log_event *pending= binlog_get_pending_rows_event(is_transactional))
+  if (Rows_log_event *pending=
+      binlog_get_pending_rows_event(thd, is_transactional))
   {
     if (stmt_end)
     {
       pending->set_flags(Rows_log_event::STMT_END_F);
-      binlog_table_maps= 0;
+      thd->binlog_table_maps= 0;
     }
 
-    error= mysql_bin_log.flush_and_set_pending_rows_event(this, 0,
+    error= mysql_bin_log.flush_and_set_pending_rows_event(thd, 0,
                                                           is_transactional);
   }
 
@@ -5462,9 +5468,9 @@ int THD::binlog_flush_pending_rows_event
   Auxiliary method used by @c binlog_query() to raise warnings.
 
   The type of warning and the type of unsafeness is stored in
-  THD::binlog_unsafe_warning_flags.
+  Binlog::binlog_unsafe_warning_flags.
 */
-void THD::issue_unsafe_warnings()
+void Binlog::issue_unsafe_warnings(THD* thd)
 {
   DBUG_ENTER("issue_unsafe_warnings");
   /*
@@ -5472,9 +5478,9 @@ void THD::issue_unsafe_warnings()
     bits.  This is actually a constant expression.
   */
   DBUG_ASSERT(LEX::BINLOG_STMT_UNSAFE_COUNT <=
-              sizeof(binlog_unsafe_warning_flags) * CHAR_BIT);
+              sizeof(thd->binlog_unsafe_warning_flags) * CHAR_BIT);
 
-  uint32 unsafe_type_flags= binlog_unsafe_warning_flags;
+  uint32 unsafe_type_flags= thd->binlog_unsafe_warning_flags;
 
   /*
     For each unsafe_type, check if the statement is unsafe in this way
@@ -5486,7 +5492,7 @@ void THD::issue_unsafe_warnings()
   {
     if ((unsafe_type_flags & (1 << unsafe_type)) != 0)
     {
-      push_warning_printf(this, MYSQL_ERROR::WARN_LEVEL_NOTE,
+      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
                           ER_BINLOG_UNSAFE_STATEMENT,
                           ER(ER_BINLOG_UNSAFE_STATEMENT),
                           ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type]));
@@ -5495,7 +5501,7 @@ void THD::issue_unsafe_warnings()
         char buf[MYSQL_ERRMSG_SIZE * 2];
         sprintf(buf, ER(ER_BINLOG_UNSAFE_STATEMENT),
                 ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type]));
-        sql_print_warning(ER(ER_MESSAGE_AND_STATEMENT), buf, query());
+        sql_print_warning(ER(ER_MESSAGE_AND_STATEMENT), buf, thd->query());
       }
     }
   }
@@ -5599,10 +5605,10 @@ static bool check_table_binlog_row_based
   DBUG_ASSERT(table->s->cached_row_logging_check == 0 ||
               table->s->cached_row_logging_check == 1);
 
-  return (thd->is_current_stmt_binlog_format_row() &&
+  return (binlog.is_current_stmt_binlog_format_row(thd) &&
           table->s->cached_row_logging_check &&
           (thd->variables.option_bits & OPTION_BIN_LOG) &&
-          mysql_bin_log.is_open());
+          binlog.enabled());
 }
 
 /**
@@ -5650,7 +5656,7 @@ int Binlog::binlog_query(THD* thd,
     top-most close_thread_tables().
   */
   if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
-    if (int error= thd->binlog_flush_pending_rows_event(TRUE, is_trans))
+    if (int error= binlog_flush_pending_rows_event(thd, TRUE, is_trans))
       DBUG_RETURN(error);
 
   /*
@@ -5677,7 +5683,7 @@ int Binlog::binlog_query(THD* thd,
   */
   if ((thd->variables.option_bits & OPTION_BIN_LOG) &&
       thd->spcont == NULL && !thd->binlog_evt_union.do_union)
-    thd->issue_unsafe_warnings();
+    issue_unsafe_warnings(thd);
 
   switch (qtype) {
     /*
@@ -5690,8 +5696,8 @@ int Binlog::binlog_query(THD* thd,
   case ROW_QUERY_TYPE:
     DBUG_PRINT("debug",
                ("is_current_stmt_binlog_format_row: %d",
-                thd->is_current_stmt_binlog_format_row()));
-    if (thd->is_current_stmt_binlog_format_row())
+                is_current_stmt_binlog_format_row(thd)));
+    if (is_current_stmt_binlog_format_row(thd))
       DBUG_RETURN(0);
     /* Fall through */
 
@@ -5820,7 +5826,7 @@ err:
 int Binlog::log_row(TABLE* table,
                     const uchar *before_record,
                     const uchar *after_record,
-                    Log_func *log_func)
+                    Log_func log_func)
 {
   if (table->no_replicate)
     return 0;
@@ -5850,7 +5856,7 @@ int Binlog::log_row(TABLE* table,
       bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
                            table->file->has_transactions();
       error=
-        (*log_func)(thd, table, has_trans, before_record, after_record);
+        (this->*log_func)(thd, table, has_trans, before_record, after_record);
     }
   }
   return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
@@ -5883,9 +5889,9 @@ int Binlog::write_locked_table_maps(THD 
                        "thd->extra_lock: 0x%lx",
                        (long) thd, (long) thd->lock, (long) thd->extra_lock));
 
-  DBUG_PRINT("debug", ("get_binlog_table_maps(): %d", thd->get_binlog_table_maps()));
+  DBUG_PRINT("debug", ("get_binlog_table_maps(): %d", get_binlog_table_maps(thd)));
 
-  if (thd->get_binlog_table_maps() == 0)
+  if (get_binlog_table_maps(thd) == 0)
   {
     MYSQL_LOCK *locks[2];
     locks[0]= thd->extra_lock;
@@ -5922,8 +5928,8 @@ int Binlog::write_locked_table_maps(THD 
           */
           bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
                                 table->file->has_transactions();
-          int const error= thd->binlog_write_table_map(table, has_trans,
-                                                       need_binlog_rows_query);
+          int const error= binlog_write_table_map(thd, table, has_trans,
+                                                  need_binlog_rows_query);
           /* Binlog Rows_query log event once for one statement which updates
              two or more tables.*/
           if (need_binlog_rows_query)
@@ -5959,10 +5965,10 @@ int Binlog::before_handle_delayed_row(TH
 {
   if (log_query)
   {
-    if (thd->is_current_stmt_binlog_format_row())
+    if (is_current_stmt_binlog_format_row(thd))
     {
       /* Flush rows of previous statement*/
-      if (thd->binlog_flush_pending_rows_event(TRUE, FALSE))
+      if (binlog_flush_pending_rows_event(thd, TRUE, FALSE))
         return 1;
       /* Set query for Rows_query_log event in RBR*/
       thd->set_query(query->str, query->length);
@@ -6141,21 +6147,109 @@ int Binlog::write_incident(THD* thd, Inc
 }
 int Binlog::write_row(TABLE* table, const uchar* record)
 {
-  Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
+  Log_func log_func= &Binlog::binlog_write_row;
   return log_row(table, 0, record, log_func);
 }
 int Binlog::update_row(TABLE* table, const uchar* before_record,
                const uchar* after_record)
 {
-  Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;
+  Log_func log_func= &Binlog::binlog_update_row;
   return log_row(table, before_record, after_record, log_func);
 }
 int Binlog::delete_row(TABLE* table, const uchar* record)
 {
-  Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function;
+  Log_func log_func= &Binlog::binlog_delete_row;
   return log_row(table, record, 0, log_func);
 }
 int Binlog::get_current_log(LOG_INFO* log_info)
 {
   return mysql_bin_log.get_current_log(log_info);
 }
+int Binlog::is_current_stmt_binlog_format_row(THD* thd) const {
+  DBUG_ASSERT(thd->current_stmt_binlog_format == BINLOG_FORMAT_STMT ||
+              thd->current_stmt_binlog_format == BINLOG_FORMAT_ROW);
+  return thd->current_stmt_binlog_format == BINLOG_FORMAT_ROW;
+}
+uint Binlog::get_binlog_table_maps(THD* thd) const {
+  return thd->binlog_table_maps;
+}
+void Binlog::clear_binlog_table_maps(THD* thd) {
+  thd->binlog_table_maps= 0;
+}
+void Binlog::set_current_stmt_binlog_format_row_if_mixed(THD* thd)
+{
+  DBUG_ENTER("set_current_stmt_binlog_format_row_if_mixed");
+  /*
+    This should only be called from decide_logging_format.
+    
+    @todo Once we have ensured this, uncomment the following
+    statement, remove the big comment below that, and remove the
+    in_sub_stmt==0 condition from the following 'if'.
+  */
+  /* DBUG_ASSERT(thd->in_sub_stmt == 0); */
+  /*
+    If in a stored/function trigger, the caller should already have done the
+    change. We test in_sub_stmt to prevent introducing bugs where people
+    wouldn't ensure that, and would switch to row-based mode in the middle
+    of executing a stored function/trigger (which is too late, see also
+    reset_current_stmt_binlog_format_row()); this condition will make their
+    tests fail and so force them to propagate the
+    lex->binlog_row_based_if_mixed upwards to the caller.
+  */
+  if ((thd->variables.binlog_format == BINLOG_FORMAT_MIXED) &&
+      (thd->in_sub_stmt == 0))
+    binlog.set_current_stmt_binlog_format_row(thd);
+  
+  DBUG_VOID_RETURN;
+}
+void Binlog::set_current_stmt_binlog_format_row(THD* thd)
+{
+  DBUG_ENTER("set_current_stmt_binlog_format_row");
+  thd->current_stmt_binlog_format= BINLOG_FORMAT_ROW;
+  DBUG_VOID_RETURN;
+}
+void Binlog::clear_current_stmt_binlog_format_row(THD* thd)
+{
+  DBUG_ENTER("clear_current_stmt_binlog_format_row");
+  thd->current_stmt_binlog_format= BINLOG_FORMAT_STMT;
+  DBUG_VOID_RETURN;
+}
+void Binlog::reset_current_stmt_binlog_format_row(THD* thd)
+{
+  DBUG_ENTER("reset_current_stmt_binlog_format_row");
+  /*
+    If there are temporary tables, don't reset back to
+    statement-based. Indeed it could be that:
+    CREATE TEMPORARY TABLE t SELECT UUID(); # row-based
+    # and row-based does not store updates to temp tables
+    # in the binlog.
+    INSERT INTO u SELECT * FROM t; # stmt-based
+    and then the INSERT will fail as data inserted into t was not logged.
+    So we continue with row-based until the temp table is dropped.
+    If we are in a stored function or trigger, we mustn't reset in the
+    middle of its execution (as the binary logging way of a stored function
+    or trigger is decided when it starts executing, depending for example on
+    the caller (for a stored function: if caller is SELECT or
+    INSERT/UPDATE/DELETE...).
+  */
+  DBUG_PRINT("debug",
+             ("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
+              YESNO(thd->temporary_tables), YESNO(thd->in_sub_stmt),
+              show_system_thread(thd->system_thread)));
+  if (thd->in_sub_stmt == 0)
+  {
+    if (thd->variables.binlog_format == BINLOG_FORMAT_ROW)
+      binlog.set_current_stmt_binlog_format_row(thd);
+    else if (thd->temporary_tables == NULL)
+      binlog.clear_current_stmt_binlog_format_row(thd);
+  }
+  DBUG_VOID_RETURN;
+}
+void Binlog::binlog_invoker(THD* thd)
+{
+  thd->m_binlog_invoker= TRUE;
+}
+bool Binlog::need_binlog_invoker(THD* thd)
+{
+  return thd->m_binlog_invoker;
+}

=== modified file 'sql/binlog.h'
--- a/sql/binlog.h	2011-01-31 07:32:53 +0000
+++ b/sql/binlog.h	2011-03-01 06:23:58 +0000
@@ -20,6 +20,7 @@
 #include "rpl_constants.h"                       /* Incident */
 
 class Log_event;
+class Rows_log_event;
 class Incident_log_event; 
 
 extern char *opt_bin_logname;
@@ -106,12 +107,85 @@ private:
   }
 #endif
   int write_locked_table_maps(THD* thd);
-  typedef bool Log_func(THD*, TABLE*, bool,
-                        const uchar*, const uchar*);
+  typedef int (Binlog::*Log_func)(THD*, TABLE*, bool,
+                                  const uchar*, const uchar*);
   int log_row(TABLE* table,
               const uchar* before_record,
               const uchar* after_record,
-              Log_func* log_func);
+              Log_func log_func);
+
+public:
+  int binlog_setup_trx_data(THD* thd);
+
+  /*
+    Public interface to write RBR events to the binlog
+  */
+  void binlog_start_trans_and_stmt(THD* thd);
+  void binlog_set_stmt_begin(THD* thd);
+  int binlog_write_table_map(THD* thd, TABLE *table, bool is_transactional,
+                             bool binlog_rows_query);
+  int binlog_write_row(THD* thd, TABLE* table, bool is_transactional,
+                       const uchar *not_used, /* not used */
+                       const uchar *new_data);
+  int binlog_delete_row(THD* thd, TABLE* table, bool is_transactional,
+                        const uchar *old_data,
+                        const uchar *not_used /* not used */);
+  int binlog_update_row(THD* thd, TABLE* table, bool is_transactional,
+                        const uchar *old_data, const uchar *new_data);
+  void binlog_prepare_row_images(TABLE* table);
+
+  /*
+    Member functions to handle pending event for row-level logging.
+  */
+  template <class RowsEventT> Rows_log_event*
+    binlog_prepare_pending_rows_event(THD* thd, TABLE* table, uint32 serv_id,
+                                      size_t needed,
+                                      bool is_transactional,
+				      RowsEventT* hint);
+  Rows_log_event* binlog_get_pending_rows_event(THD* thd, bool is_transactional) const;
+  void binlog_set_pending_rows_event(THD* thd, Rows_log_event* ev, bool is_transactional);
+  inline int binlog_flush_pending_rows_event(THD* thd, bool stmt_end)
+  {
+    return (binlog_flush_pending_rows_event(thd, stmt_end, FALSE) || 
+            binlog_flush_pending_rows_event(thd, stmt_end, TRUE));
+  }
+  int binlog_flush_pending_rows_event(THD* thd, bool stmt_end, bool is_transactional);
+  int binlog_remove_pending_rows_event(THD* thd, bool clear_maps, bool is_transactional);
+
+  /**
+    Determine the binlog format of the current statement.
+
+    @retval 0 if the current statement will be logged in statement
+    format.
+    @retval nonzero if the current statement will be logged in row
+    format.
+   */
+  int is_current_stmt_binlog_format_row(THD* thd) const;
+  void issue_unsafe_warnings(THD* thd);
+  uint get_binlog_table_maps(THD* thd) const;
+  void clear_binlog_table_maps(THD* thd);
+  /*
+    @todo Make these methods private or remove them completely.  Only
+    decide_logging_format should call them. /Sven
+  */
+  void set_current_stmt_binlog_format_row_if_mixed(THD* thd);
+  void set_current_stmt_binlog_format_row(THD* thd);
+  void clear_current_stmt_binlog_format_row(THD* thd);
+  void reset_current_stmt_binlog_format_row(THD* thd);
+  int decide_logging_format(THD* thd, TABLE_LIST *tables);
+  void binlog_invoker(THD* thd);
+  bool need_binlog_invoker(THD* thd);
+  friend class Query_log_event;
+  friend class Query_log_event_old;
+  friend class Rows_log_event;
+  friend class Old_rows_log_event;
+  friend class Write_rows_log_event;
+  friend class Update_rows_log_event;
+  friend class Delete_rows_log_event;
+  friend class Write_rows_log_event_old;
+  friend class Update_rows_log_event_old;
+  friend class Delete_rows_log_event_old;
+  friend int rows_event_stmt_cleanup(Relay_log_info const *, THD*);
 };
 
 extern MYSQL_PLUGIN_IMPORT Binlog binlog;

=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc	2010-11-29 16:27:58 +0000
+++ b/sql/event_db_repository.cc	2011-03-01 06:23:58 +0000
@@ -1076,8 +1076,8 @@ update_timing_fields_for_event(THD *thd,
     Turn off row binlogging of event timing updates. These are not used
     for RBR of events replicated to the slave.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   DBUG_ASSERT(thd->security_ctx->master_access & SUPER_ACL);
 
@@ -1113,9 +1113,9 @@ end:
     close_mysql_tables(thd);
 
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
 
   DBUG_RETURN(test(ret));
 }

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2010-11-18 16:34:56 +0000
+++ b/sql/events.cc	2011-03-01 06:23:58 +0000
@@ -337,8 +337,8 @@ Events::create_event(THD *thd, Event_par
     Turn off row binlogging of this statement and use statement-based 
     so that all supporting tables are updated for CREATE EVENT command.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   if (lock_object_name(thd, MDL_key::EVENT,
                        parse_data->dbname.str, parse_data->name.str))
@@ -391,9 +391,9 @@ Events::create_event(THD *thd, Event_par
     }
   }
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
 
   DBUG_RETURN(ret);
 }
@@ -470,8 +470,8 @@ Events::update_event(THD *thd, Event_par
     Turn off row binlogging of this statement and use statement-based 
     so that all supporting tables are updated for UPDATE EVENT command.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   if (lock_object_name(thd, MDL_key::EVENT,
                        parse_data->dbname.str, parse_data->name.str))
@@ -506,9 +506,9 @@ Events::update_event(THD *thd, Event_par
     }
   }
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
 
   DBUG_RETURN(ret);
 }
@@ -555,8 +555,8 @@ Events::drop_event(THD *thd, LEX_STRING 
     Turn off row binlogging of this statement and use statement-based so
     that all supporting tables are updated for DROP EVENT command.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   if (lock_object_name(thd, MDL_key::EVENT,
                        dbname.str, name.str))
@@ -571,9 +571,9 @@ Events::drop_event(THD *thd, LEX_STRING 
     ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
   }
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
   DBUG_RETURN(ret);
 }
 

=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc	2011-01-31 07:32:53 +0000
+++ b/sql/ha_partition.cc	2011-03-01 06:23:58 +0000
@@ -6796,7 +6796,7 @@ void ha_partition::get_auto_increment(ul
     if (!auto_increment_safe_stmt_log_lock &&
         thd->lex->sql_command != SQLCOM_INSERT &&
         binlog.enabled(thd) &&
-        !thd->is_current_stmt_binlog_format_row())
+        !binlog.is_current_stmt_binlog_format_row(thd))
     {
       DBUG_PRINT("info", ("locking auto_increment_safe_stmt_log_lock"));
       auto_increment_safe_stmt_log_lock= TRUE;

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2011-01-31 07:32:53 +0000
+++ b/sql/handler.cc	2011-03-01 06:23:58 +0000
@@ -2690,7 +2690,7 @@ int handler::update_auto_increment()
                                           variables->auto_increment_increment);
     auto_inc_intervals_count++;
     /* Row-based replication does not need to store intervals in binlog */
-    if (binlog.enabled() && !thd->is_current_stmt_binlog_format_row())
+    if (binlog.enabled() && !binlog.is_current_stmt_binlog_format_row(thd))
         thd->auto_inc_intervals_in_cur_stmt_for_binlog.append(auto_inc_interval_for_cur_row.minimum(),
                                                               auto_inc_interval_for_cur_row.values(),
                                                               variables->auto_increment_increment);

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2011-01-31 07:32:53 +0000
+++ b/sql/log_event.cc	2011-03-01 06:23:58 +0000
@@ -101,7 +101,7 @@ const ulong checksum_version_product=
   checksum_version_split[2];
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
+int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
 
 static const char *HA_ERR(int i)
 {
@@ -2594,7 +2594,7 @@ bool Query_log_event::write(IO_CACHE* fi
     start+= 4;
   }
 
-  if (thd && thd->need_binlog_invoker())
+  if (thd && binlog.need_binlog_invoker(thd))
   {
     LEX_STRING user;
     LEX_STRING host;
@@ -2815,7 +2815,7 @@ Query_log_event::Query_log_event(THD* th
 
     case SQLCOM_CREATE_TABLE:
       trx_cache= (lex->select_lex.item_list.elements &&
-                  thd->is_current_stmt_binlog_format_row());
+                  binlog.is_current_stmt_binlog_format_row(thd));
       use_cache= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
                    thd->in_multi_stmt_transaction_mode()) || trx_cache;
       break;
@@ -8213,7 +8213,7 @@ int Rows_log_event::do_apply_event(Relay
       Note: this applies to log_event_old.cc too.
       /Sven
     */
-    thd->reset_current_stmt_binlog_format_row();
+    binlog.reset_current_stmt_binlog_format_row(thd);
     thd->is_slave_error= 1;
     DBUG_RETURN(error);
   }
@@ -8253,7 +8253,7 @@ Rows_log_event::do_shall_skip(Relay_log_
    @retval  non-zero  Error at the commit.
  */
 
-static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
+int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
 {
   int error;
   {
@@ -8272,7 +8272,7 @@ static int rows_event_stmt_cleanup(Relay
       (assume the last master's transaction is ignored by the slave because of
       replicate-ignore rules).
     */
-    error= thd->binlog_flush_pending_rows_event(TRUE);
+    error= binlog.binlog_flush_pending_rows_event(thd, TRUE);
 
     /*
       If this event is not in a transaction, the call below will, if some
@@ -8305,7 +8305,7 @@ static int rows_event_stmt_cleanup(Relay
       seem related to anything that happens here.
       /Sven
     */
-    thd->reset_current_stmt_binlog_format_row();
+    binlog.reset_current_stmt_binlog_format_row(thd);
 
     const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
   }

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2011-01-31 07:32:53 +0000
+++ b/sql/log_event.h	2011-03-01 06:23:58 +0000
@@ -3799,17 +3799,6 @@ public:
   Write_rows_log_event(const char *buf, uint event_len, 
                        const Format_description_log_event *description_event);
 #endif
-#if defined(MYSQL_SERVER) 
-  static bool binlog_row_logging_function(THD *thd, TABLE *table,
-                                          bool is_transactional,
-                                          const uchar *before_record
-                                          __attribute__((unused)),
-                                          const uchar *after_record)
-  {
-    return thd->binlog_write_row(table, is_transactional,
-                                 after_record);
-  }
-#endif
 
 private:
   virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
@@ -3866,17 +3855,6 @@ public:
 			const Format_description_log_event *description_event);
 #endif
 
-#ifdef MYSQL_SERVER
-  static bool binlog_row_logging_function(THD *thd, TABLE *table,
-                                          bool is_transactional,
-                                          const uchar *before_record,
-                                          const uchar *after_record)
-  {
-    return thd->binlog_update_row(table, is_transactional,
-                                  before_record, after_record);
-  }
-#endif
-
   virtual bool is_valid() const
   {
     return Rows_log_event::is_valid() && m_cols_ai.bitmap;
@@ -3933,17 +3911,6 @@ public:
   Delete_rows_log_event(const char *buf, uint event_len, 
 			const Format_description_log_event *description_event);
 #endif
-#ifdef MYSQL_SERVER
-  static bool binlog_row_logging_function(THD *thd, TABLE *table,
-                                          bool is_transactional,
-                                          const uchar *before_record,
-                                          const uchar *after_record
-                                          __attribute__((unused)))
-  {
-    return thd->binlog_delete_row(table, is_transactional,
-                                  before_record);
-  }
-#endif
   
 protected:
   virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }

=== modified file 'sql/log_event_old.cc'
--- a/sql/log_event_old.cc	2010-11-01 05:40:27 +0000
+++ b/sql/log_event_old.cc	2011-03-01 06:23:58 +0000
@@ -277,7 +277,7 @@ Old_rows_log_event::do_apply_event(Old_r
       thread is certainly going to stop.
       rollback at the caller along with sbr.
     */
-    ev_thd->reset_current_stmt_binlog_format_row();
+    binlog.reset_current_stmt_binlog_format_row(ev_thd);
     const_cast<Relay_log_info*>(rli)->cleanup_context(ev_thd, error);
     ev_thd->is_slave_error= 1;
     DBUG_RETURN(error);
@@ -1734,7 +1734,7 @@ int Old_rows_log_event::do_apply_event(R
       thread is certainly going to stop.
       rollback at the caller along with sbr.
     */
-    thd->reset_current_stmt_binlog_format_row();
+    binlog.reset_current_stmt_binlog_format_row(thd);
     const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
     thd->is_slave_error= 1;
     DBUG_RETURN(error);
@@ -1784,7 +1784,7 @@ int Old_rows_log_event::do_apply_event(R
       (assume the last master's transaction is ignored by the slave because of
       replicate-ignore rules).
     */
-    int binlog_error= thd->binlog_flush_pending_rows_event(TRUE);
+    int binlog_error= binlog.binlog_flush_pending_rows_event(thd, TRUE);
 
     /*
       If this event is not in a transaction, the call below will, if some
@@ -1806,14 +1806,14 @@ int Old_rows_log_event::do_apply_event(R
     /*
       Now what if this is not a transactional engine? we still need to
       flush the pending event to the binlog; we did it with
-      thd->binlog_flush_pending_rows_event(). Note that we imitate
+      binlog_flush_pending_rows_event(). Note that we imitate
       what is done for real queries: a call to
       ha_autocommit_or_rollback() (sometimes only if involves a
       transactional engine), and a call to be sure to have the pending
       event flushed.
     */
 
-    thd->reset_current_stmt_binlog_format_row();
+    binlog.reset_current_stmt_binlog_format_row(thd);
     const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
   }
 

=== modified file 'sql/log_event_old.h'
--- a/sql/log_event_old.h	2010-09-04 00:46:58 +0000
+++ b/sql/log_event_old.h	2011-03-01 06:23:58 +0000
@@ -365,17 +365,6 @@ public:
   Write_rows_log_event_old(const char *buf, uint event_len,
                            const Format_description_log_event *description_event);
 #endif
-#if !defined(MYSQL_CLIENT) 
-  static bool binlog_row_logging_function(THD *thd, TABLE *table,
-                                          bool is_transactional,
-                                          const uchar *before_record
-                                          __attribute__((unused)),
-                                          const uchar *after_record)
-  {
-    return thd->binlog_write_row(table, is_transactional,
-                                 after_record);
-  }
-#endif
 
 private:
 #ifdef MYSQL_CLIENT
@@ -440,17 +429,6 @@ public:
                             const Format_description_log_event *description_event);
 #endif
 
-#if !defined(MYSQL_CLIENT) 
-  static bool binlog_row_logging_function(THD *thd, TABLE *table,
-                                          bool is_transactional,
-                                          const uchar *before_record,
-                                          const uchar *after_record)
-  {
-    return thd->binlog_update_row(table, is_transactional,
-                                  before_record, after_record);
-  }
-#endif
-
 protected:
 #ifdef MYSQL_CLIENT
   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
@@ -513,17 +491,6 @@ public:
   Delete_rows_log_event_old(const char *buf, uint event_len,
                             const Format_description_log_event *description_event);
 #endif
-#if !defined(MYSQL_CLIENT) 
-  static bool binlog_row_logging_function(THD *thd, TABLE *table,
-                                          bool is_transactional,
-                                          const uchar *before_record,
-                                          const uchar *after_record
-                                          __attribute__((unused)))
-  {
-    return thd->binlog_delete_row(table, is_transactional,
-                                  before_record);
-  }
-#endif
   
 protected:
 #ifdef MYSQL_CLIENT

=== modified file 'sql/rpl_injector.cc'
--- a/sql/rpl_injector.cc	2011-01-31 07:32:53 +0000
+++ b/sql/rpl_injector.cc	2011-03-01 06:23:58 +0000
@@ -69,7 +69,7 @@ injector::transaction::~transaction()
 int injector::transaction::commit()
 {
    DBUG_ENTER("injector::transaction::commit()");
-   int error= m_thd->binlog_flush_pending_rows_event(true);
+   int error= binlog.binlog_flush_pending_rows_event(m_thd, true);
    /*
      Cluster replication does not preserve statement or
      transaction boundaries of the master.  Instead, a new
@@ -110,7 +110,7 @@ int injector::transaction::use_table(ser
 
   server_id_type save_id= m_thd->server_id;
   m_thd->set_server_id(sid);
-  error= m_thd->binlog_write_table_map(tbl.get_table(),
+  error= binlog.binlog_write_table_map(m_thd, tbl.get_table(),
                                        tbl.is_transactional(), FALSE);
   m_thd->set_server_id(save_id);
   DBUG_RETURN(error);
@@ -131,8 +131,8 @@ int injector::transaction::write_row (se
    m_thd->set_server_id(sid);
    table::save_sets saveset(tbl, cols, cols);
 
-   error= m_thd->binlog_write_row(tbl.get_table(), tbl.is_transactional(), 
-                                  record);
+   error= binlog.binlog_write_row(m_thd, tbl.get_table(), tbl.is_transactional(), 
+                                  0, record);
    m_thd->set_server_id(save_id);
    DBUG_RETURN(error);
 }
@@ -151,8 +151,8 @@ int injector::transaction::delete_row(se
    server_id_type save_id= m_thd->server_id;
    m_thd->set_server_id(sid);
    table::save_sets saveset(tbl, cols, cols);
-   error= m_thd->binlog_delete_row(tbl.get_table(), tbl.is_transactional(), 
-                                   record);
+   error= binlog.binlog_delete_row(m_thd, tbl.get_table(), tbl.is_transactional(), 
+                                   record, 0);
    m_thd->set_server_id(save_id);
    DBUG_RETURN(error);
 }
@@ -173,7 +173,7 @@ int injector::transaction::update_row(se
    // The read- and write sets with autorestore (in the destructor)
    table::save_sets saveset(tbl, cols, cols);
 
-   error= m_thd->binlog_update_row(tbl.get_table(), tbl.is_transactional(), 
+   error= binlog.binlog_update_row(m_thd, tbl.get_table(), tbl.is_transactional(), 
                                    before, after);
    m_thd->set_server_id(save_id);
    DBUG_RETURN(error);

=== modified file 'sql/sp.cc'
--- a/sql/sp.cc	2011-01-31 07:32:53 +0000
+++ b/sql/sp.cc	2011-03-01 06:23:58 +0000
@@ -954,8 +954,8 @@ sp_create_routine(THD *thd, int type, sp
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   saved_count_cuted_fields= thd->count_cuted_fields;
   thd->count_cuted_fields= CHECK_FIELD_WARN;
@@ -1163,9 +1163,9 @@ done:
   thd->count_cuted_fields= saved_count_cuted_fields;
   thd->variables.sql_mode= saved_mode;
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
   DBUG_RETURN(ret);
 }
 
@@ -1212,8 +1212,8 @@ sp_drop_routine(THD *thd, int type, sp_n
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK)
   {
@@ -1242,9 +1242,9 @@ sp_drop_routine(THD *thd, int type, sp_n
     }
   }
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
   DBUG_RETURN(ret);
 }
 
@@ -1293,8 +1293,8 @@ sp_update_routine(THD *thd, int type, sp
     row-based replication. The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK)
   {
@@ -1350,9 +1350,9 @@ sp_update_routine(THD *thd, int type, sp
   }
 err:
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
   DBUG_RETURN(ret);
 }
 

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2011-01-31 07:32:53 +0000
+++ b/sql/sp_head.cc	2011-03-01 06:23:58 +0000
@@ -1860,7 +1860,7 @@ sp_head::execute_function(THD *thd, Item
     each substatement be binlogged its way.
   */
   need_binlog_call= (binlog.enabled(thd) &&
-                     !thd->is_current_stmt_binlog_format_row());
+                     !binlog.is_current_stmt_binlog_format_row(thd));
 
   /*
     Remember the original arguments for unrolled replication of functions
@@ -1992,7 +1992,7 @@ err_with_cleanup:
   */
   if (need_binlog_call && 
       thd->spcont == NULL && !thd->binlog_evt_union.do_union)
-    thd->issue_unsafe_warnings();
+    binlog.issue_unsafe_warnings(thd);
 
   DBUG_RETURN(err_status);
 }
@@ -2246,10 +2246,10 @@ sp_head::execute_procedure(THD *thd, Lis
     messsages.
   */ 
   bool need_binlog_call= binlog.enabled(thd) &&
-                         !thd->is_current_stmt_binlog_format_row();
+                         !binlog.is_current_stmt_binlog_format_row(thd);
   if (need_binlog_call && thd->spcont == NULL &&
       !thd->binlog_evt_union.do_union)
-    thd->issue_unsafe_warnings();
+    binlog.issue_unsafe_warnings(thd);
 
   DBUG_RETURN(err_status);
 }

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2011-01-31 07:32:53 +0000
+++ b/sql/sql_acl.cc	2011-03-01 06:23:58 +0000
@@ -1871,8 +1871,8 @@ bool change_password(THD *thd, const cha
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   mysql_mutex_lock(&acl_cache->lock);
   ACL_USER *acl_user;
@@ -1921,9 +1921,9 @@ end:
   close_mysql_tables(thd);
 
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
 
   DBUG_RETURN(result);
 }
@@ -3601,8 +3601,8 @@ int mysql_table_grant(THD *thd, TABLE_LI
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
 #ifdef HAVE_REPLICATION
   /*
@@ -3619,9 +3619,9 @@ int mysql_table_grant(THD *thd, TABLE_LI
     if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
     {
       /* Restore the state of binlog format */
-      DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+      DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
       if (save_binlog_row_based)
-        thd->set_current_stmt_binlog_format_row();
+        binlog.set_current_stmt_binlog_format_row(thd);
       DBUG_RETURN(FALSE);
     }
   }
@@ -3642,9 +3642,9 @@ int mysql_table_grant(THD *thd, TABLE_LI
   if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
   {						// Should never happen
     /* Restore the state of binlog format */
-    DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+    DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
     if (save_binlog_row_based)
-      thd->set_current_stmt_binlog_format_row();
+      binlog.set_current_stmt_binlog_format_row(thd);
     DBUG_RETURN(TRUE);				/* purecov: deadcode */
   }
 
@@ -3779,9 +3779,9 @@ int mysql_table_grant(THD *thd, TABLE_LI
   /* Tables are automatically closed */
   thd->lex->restore_backup_query_tables_list(&backup);
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
   DBUG_RETURN(result);
 }
 
@@ -3845,8 +3845,8 @@ bool mysql_routine_grant(THD *thd, TABLE
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
 #ifdef HAVE_REPLICATION
   /*
@@ -3863,9 +3863,9 @@ bool mysql_routine_grant(THD *thd, TABLE
     if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
     {
       /* Restore the state of binlog format */
-      DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+      DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
       if (save_binlog_row_based)
-        thd->set_current_stmt_binlog_format_row();
+        binlog.set_current_stmt_binlog_format_row(thd);
       DBUG_RETURN(FALSE);
     }
   }
@@ -3874,9 +3874,9 @@ bool mysql_routine_grant(THD *thd, TABLE
   if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
   {						// Should never happen
     /* Restore the state of binlog format */
-    DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+    DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
     if (save_binlog_row_based)
-      thd->set_current_stmt_binlog_format_row();
+      binlog.set_current_stmt_binlog_format_row(thd);
     DBUG_RETURN(TRUE);
   }
 
@@ -3960,9 +3960,9 @@ bool mysql_routine_grant(THD *thd, TABLE
 
   mysql_rwlock_unlock(&LOCK_grant);
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
 
   /* Tables are automatically closed */
   DBUG_RETURN(result);
@@ -4021,8 +4021,8 @@ bool mysql_grant(THD *thd, const char *d
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
 #ifdef HAVE_REPLICATION
   /*
@@ -4039,9 +4039,9 @@ bool mysql_grant(THD *thd, const char *d
     if (!(thd->spcont || rpl_filter->tables_ok(0, tables)))
     {
       /* Restore the state of binlog format */
-      DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+      DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
       if (save_binlog_row_based)
-        thd->set_current_stmt_binlog_format_row();
+        binlog.set_current_stmt_binlog_format_row(thd);
       DBUG_RETURN(FALSE);
     }
   }
@@ -4050,9 +4050,9 @@ bool mysql_grant(THD *thd, const char *d
   if (open_and_lock_tables(thd, tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT))
   {						// This should never happen
     /* Restore the state of binlog format */
-    DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+    DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
     if (save_binlog_row_based)
-      thd->set_current_stmt_binlog_format_row();
+      binlog.set_current_stmt_binlog_format_row(thd);
     DBUG_RETURN(TRUE);				/* purecov: deadcode */
   }
 
@@ -4123,9 +4123,9 @@ bool mysql_grant(THD *thd, const char *d
   if (!result)
     my_ok(thd);
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
 
   DBUG_RETURN(result);
 }
@@ -6407,16 +6407,16 @@ bool mysql_create_user(THD *thd, List <L
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   /* CREATE USER may be skipped on replication client. */
   if ((result= open_grant_tables(thd, tables)))
   {
     /* Restore the state of binlog format */
-    DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+    DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
     if (save_binlog_row_based)
-      thd->set_current_stmt_binlog_format_row();
+      binlog.set_current_stmt_binlog_format_row(thd);
     DBUG_RETURN(result != 1);
   }
 
@@ -6469,9 +6469,9 @@ bool mysql_create_user(THD *thd, List <L
 
   mysql_rwlock_unlock(&LOCK_grant);
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
   DBUG_RETURN(result);
 }
 
@@ -6506,16 +6506,16 @@ bool mysql_drop_user(THD *thd, List <LEX
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   /* DROP USER may be skipped on replication client. */
   if ((result= open_grant_tables(thd, tables)))
   {
     /* Restore the state of binlog format */
-    DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+    DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
     if (save_binlog_row_based)
-      thd->set_current_stmt_binlog_format_row();
+      binlog.set_current_stmt_binlog_format_row(thd);
     DBUG_RETURN(result != 1);
   }
 
@@ -6554,9 +6554,9 @@ bool mysql_drop_user(THD *thd, List <LEX
   mysql_rwlock_unlock(&LOCK_grant);
   thd->variables.sql_mode= old_sql_mode;
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
   DBUG_RETURN(result);
 }
 
@@ -6591,16 +6591,16 @@ bool mysql_rename_user(THD *thd, List <L
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   /* RENAME USER may be skipped on replication client. */
   if ((result= open_grant_tables(thd, tables)))
   {
     /* Restore the state of binlog format */
-    DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+    DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
     if (save_binlog_row_based)
-      thd->set_current_stmt_binlog_format_row();
+      binlog.set_current_stmt_binlog_format_row(thd);
     DBUG_RETURN(result != 1);
   }
 
@@ -6649,9 +6649,9 @@ bool mysql_rename_user(THD *thd, List <L
 
   mysql_rwlock_unlock(&LOCK_grant);
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
   DBUG_RETURN(result);
 }
 
@@ -6684,15 +6684,15 @@ bool mysql_revoke_all(THD *thd,  List <L
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   if ((result= open_grant_tables(thd, tables)))
   {
     /* Restore the state of binlog format */
-    DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+    DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
     if (save_binlog_row_based)
-      thd->set_current_stmt_binlog_format_row();
+      binlog.set_current_stmt_binlog_format_row(thd);
     DBUG_RETURN(result != 1);
   }
 
@@ -6854,9 +6854,9 @@ bool mysql_revoke_all(THD *thd,  List <L
 
   mysql_rwlock_unlock(&LOCK_grant);
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
 
   DBUG_RETURN(result);
 }
@@ -6965,8 +6965,8 @@ bool sp_revoke_privileges(THD *thd, cons
     row-based replication.  The flag will be reset at the end of the
     statement.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   /* Remove procedure access */
   do
@@ -7002,9 +7002,9 @@ bool sp_revoke_privileges(THD *thd, cons
 
   thd->pop_internal_handler();
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
 
   DBUG_RETURN(error_handler.has_errors());
 }

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2011-01-31 07:32:53 +0000
+++ b/sql/sql_base.cc	2011-03-01 06:23:58 +0000
@@ -1494,7 +1494,7 @@ void close_thread_tables(THD *thd)
       handled either before writing a query log event (inside
       binlog_query()) or when preparing a pending event.
      */
-    (void)thd->binlog_flush_pending_rows_event(TRUE);
+    (void)binlog.binlog_flush_pending_rows_event(thd, TRUE);
     mysql_unlock_tables(thd, thd->lock);
     thd->lock=0;
   }
@@ -5563,7 +5563,7 @@ bool lock_tables(THD *thd, TABLE_LIST *t
               !thd->lex->requires_prelocking());
 
   if (!tables && !thd->lex->requires_prelocking())
-    DBUG_RETURN(thd->decide_logging_format(tables));
+    DBUG_RETURN(binlog.decide_logging_format(thd, tables));
 
   /*
     Check for thd->locked_tables_mode to avoid a redundant
@@ -5705,7 +5705,7 @@ bool lock_tables(THD *thd, TABLE_LIST *t
     }
   }
 
-  DBUG_RETURN(thd->decide_logging_format(tables));
+  DBUG_RETURN(binlog.decide_logging_format(thd, tables));
 }
 
 

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2011-01-31 07:32:53 +0000
+++ b/sql/sql_class.cc	2011-03-01 06:23:58 +0000
@@ -946,7 +946,7 @@ void THD::init(void)
 			TL_WRITE);
   tx_isolation= (enum_tx_isolation) variables.tx_isolation;
   update_charset();
-  reset_current_stmt_binlog_format_row();
+  binlog.reset_current_stmt_binlog_format_row(this);
   bzero((char *) &status_var, sizeof(status_var));
 
   if (variables.sql_log_bin)
@@ -3396,14 +3396,14 @@ void THD::reset_sub_statement_state(Sub_
     first_successful_insert_id_in_cur_stmt;
 
   if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
-      !is_current_stmt_binlog_format_row())
+      !binlog.is_current_stmt_binlog_format_row(this))
   {
     variables.option_bits&= ~OPTION_BIN_LOG;
   }
 
   if ((backup->option_bits & OPTION_BIN_LOG) &&
        is_update_query(lex->sql_command) &&
-       !is_current_stmt_binlog_format_row())
+       !binlog.is_current_stmt_binlog_format_row(this))
     binlog.start_union_events(this, this->query_id);
 
   /* Disable result sets */
@@ -3467,7 +3467,7 @@ void THD::restore_sub_statement_state(Su
     is_fatal_sub_stmt_error= FALSE;
 
   if ((variables.option_bits & OPTION_BIN_LOG) && is_update_query(lex->sql_command) &&
-       !is_current_stmt_binlog_format_row())
+       !binlog.is_current_stmt_binlog_format_row(this))
     binlog.stop_union_events(this);
 
   /*
@@ -3562,7 +3562,7 @@ void THD::leave_locked_tables_mode()
 
 void THD::get_definer(LEX_USER *definer)
 {
-  binlog_invoker();
+  binlog.binlog_invoker(this);
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
   if (slave_thread && has_invoker())
   {

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2011-01-31 07:32:53 +0000
+++ b/sql/sql_class.h	2011-03-01 06:23:58 +0000
@@ -1635,63 +1635,15 @@ public:
     TABLE_LIST *emb_on_expr_nest;
   } thd_marker;
 #ifndef MYSQL_CLIENT
-  int binlog_setup_trx_data();
-
-  /*
-    Public interface to write RBR events to the binlog
-  */
-  void binlog_start_trans_and_stmt();
-  void binlog_set_stmt_begin();
-  int binlog_write_table_map(TABLE *table, bool is_transactional,
-                             bool binlog_rows_query);
-  int binlog_write_row(TABLE* table, bool is_transactional,
-                       const uchar *new_data);
-  int binlog_delete_row(TABLE* table, bool is_transactional,
-                        const uchar *old_data);
-  int binlog_update_row(TABLE* table, bool is_transactional,
-                        const uchar *old_data, const uchar *new_data);
-  void binlog_prepare_row_images(TABLE* table);
-
   void set_server_id(uint32 sid) { server_id = sid; }
 
-  /*
-    Member functions to handle pending event for row-level logging.
-  */
-  template <class RowsEventT> Rows_log_event*
-    binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
-                                      size_t needed,
-                                      bool is_transactional,
-				      RowsEventT* hint);
-  Rows_log_event* binlog_get_pending_rows_event(bool is_transactional) const;
-  void binlog_set_pending_rows_event(Rows_log_event* ev, bool is_transactional);
-  inline int binlog_flush_pending_rows_event(bool stmt_end)
-  {
-    return (binlog_flush_pending_rows_event(stmt_end, FALSE) || 
-            binlog_flush_pending_rows_event(stmt_end, TRUE));
-  }
-  int binlog_flush_pending_rows_event(bool stmt_end, bool is_transactional);
-  int binlog_remove_pending_rows_event(bool clear_maps, bool is_transactional);
-
-  /**
-    Determine the binlog format of the current statement.
-
-    @retval 0 if the current statement will be logged in statement
-    format.
-    @retval nonzero if the current statement will be logged in row
-    format.
-   */
-  int is_current_stmt_binlog_format_row() const {
-    DBUG_ASSERT(current_stmt_binlog_format == BINLOG_FORMAT_STMT ||
-                current_stmt_binlog_format == BINLOG_FORMAT_ROW);
-    return current_stmt_binlog_format == BINLOG_FORMAT_ROW;
-  }
   /** Tells whether the given optimizer_switch flag is on */
   inline bool optimizer_switch_flag(ulonglong flag)
   {
     return (variables.optimizer_switch & flag);
   }
 
-private:
+public:
   /**
     Indicates the format in which the current statement will be
     logged.  This can only be set from @c decide_logging_format().
@@ -1718,14 +1670,6 @@ public:
     transaction cache.
   */
   uint binlog_table_maps;
-  void issue_unsafe_warnings();
-
-  uint get_binlog_table_maps() const {
-    return binlog_table_maps;
-  }
-  void clear_binlog_table_maps() {
-    binlog_table_maps= 0;
-  }
 #endif /* MYSQL_CLIENT */
 
 public:
@@ -2569,80 +2513,6 @@ public:
   void set_n_backup_active_arena(Query_arena *set, Query_arena *backup);
   void restore_active_arena(Query_arena *set, Query_arena *backup);
 
-  /*
-    @todo Make these methods private or remove them completely.  Only
-    decide_logging_format should call them. /Sven
-  */
-  inline void set_current_stmt_binlog_format_row_if_mixed()
-  {
-    DBUG_ENTER("set_current_stmt_binlog_format_row_if_mixed");
-    /*
-      This should only be called from decide_logging_format.
-
-      @todo Once we have ensured this, uncomment the following
-      statement, remove the big comment below that, and remove the
-      in_sub_stmt==0 condition from the following 'if'.
-    */
-    /* DBUG_ASSERT(in_sub_stmt == 0); */
-    /*
-      If in a stored/function trigger, the caller should already have done the
-      change. We test in_sub_stmt to prevent introducing bugs where people
-      wouldn't ensure that, and would switch to row-based mode in the middle
-      of executing a stored function/trigger (which is too late, see also
-      reset_current_stmt_binlog_format_row()); this condition will make their
-      tests fail and so force them to propagate the
-      lex->binlog_row_based_if_mixed upwards to the caller.
-    */
-    if ((variables.binlog_format == BINLOG_FORMAT_MIXED) &&
-        (in_sub_stmt == 0))
-      set_current_stmt_binlog_format_row();
-
-    DBUG_VOID_RETURN;
-  }
-  inline void set_current_stmt_binlog_format_row()
-  {
-    DBUG_ENTER("set_current_stmt_binlog_format_row");
-    current_stmt_binlog_format= BINLOG_FORMAT_ROW;
-    DBUG_VOID_RETURN;
-  }
-  inline void clear_current_stmt_binlog_format_row()
-  {
-    DBUG_ENTER("clear_current_stmt_binlog_format_row");
-    current_stmt_binlog_format= BINLOG_FORMAT_STMT;
-    DBUG_VOID_RETURN;
-  }
-  inline void reset_current_stmt_binlog_format_row()
-  {
-    DBUG_ENTER("reset_current_stmt_binlog_format_row");
-    /*
-      If there are temporary tables, don't reset back to
-      statement-based. Indeed it could be that:
-      CREATE TEMPORARY TABLE t SELECT UUID(); # row-based
-      # and row-based does not store updates to temp tables
-      # in the binlog.
-      INSERT INTO u SELECT * FROM t; # stmt-based
-      and then the INSERT will fail as data inserted into t was not logged.
-      So we continue with row-based until the temp table is dropped.
-      If we are in a stored function or trigger, we mustn't reset in the
-      middle of its execution (as the binary logging way of a stored function
-      or trigger is decided when it starts executing, depending for example on
-      the caller (for a stored function: if caller is SELECT or
-      INSERT/UPDATE/DELETE...).
-    */
-    DBUG_PRINT("debug",
-               ("temporary_tables: %s, in_sub_stmt: %s, system_thread: %s",
-                YESNO(temporary_tables), YESNO(in_sub_stmt),
-                show_system_thread(system_thread)));
-    if (in_sub_stmt == 0)
-    {
-      if (variables.binlog_format == BINLOG_FORMAT_ROW)
-        set_current_stmt_binlog_format_row();
-      else if (temporary_tables == NULL)
-        clear_current_stmt_binlog_format_row();
-    }
-    DBUG_VOID_RETURN;
-  }
-
   /**
     Set the current database; use deep copy of C-string.
 
@@ -2862,9 +2732,6 @@ public:
     locked_tables_mode= mode_arg;
   }
   void leave_locked_tables_mode();
-  int decide_logging_format(TABLE_LIST *tables);
-  void binlog_invoker() { m_binlog_invoker= TRUE; }
-  bool need_binlog_invoker() { return m_binlog_invoker; }
   void get_definer(LEX_USER *definer);
   void set_invoker(const LEX_STRING *user, const LEX_STRING *host)
   {
@@ -2897,6 +2764,7 @@ private:
   Warning_info main_warning_info;
   Diagnostics_area main_da;
 
+public:
   /**
     It will be set TURE if CURRENT_USER() is called in account management
     statements or default definer is set in CREATE/ALTER SP, SF, Event,

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2011-01-31 07:32:53 +0000
+++ b/sql/sql_delete.cc	2011-03-01 06:23:58 +0000
@@ -138,7 +138,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   */
   if (!using_limit && const_cond_result &&
       !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
-       (!thd->is_current_stmt_binlog_format_row() &&
+       (!binlog.is_current_stmt_binlog_format_row(thd) &&
         !(table->triggers && table->triggers->has_delete_triggers())))
   {
     /* Update the table->file->stats.records number */

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2011-01-31 07:32:53 +0000
+++ b/sql/sql_insert.cc	2011-03-01 06:23:58 +0000
@@ -2657,7 +2657,7 @@ pthread_handler_t handle_delayed_insert(
       INSERT DELAYED has to go to row-based format because the time
       at which rows are inserted cannot be determined in mixed mode.
     */
-    thd->set_current_stmt_binlog_format_row_if_mixed();
+    binlog.set_current_stmt_binlog_format_row_if_mixed(thd);
 
     /*
       Clone tickets representing protection against GRL and the lock on
@@ -2941,12 +2941,12 @@ bool Delayed_insert::handle_inserts(void
         in SBR when mysql binlog is enabled.
       */
       DBUG_ASSERT(!(binlog.enabled() &&
-                  !thd.is_current_stmt_binlog_format_row()));
+                  !binlog.is_current_stmt_binlog_format_row(&thd)));
 
       if (binlog.enabled())
       {
         /* Flush rows of previous statement*/
-        if (thd.binlog_flush_pending_rows_event(TRUE, FALSE))
+        if (binlog.binlog_flush_pending_rows_event(&thd, TRUE, FALSE))
         {
           delete row;
           goto err;
@@ -3101,7 +3101,7 @@ bool Delayed_insert::handle_inserts(void
   has_trans= thd.lex->sql_command == SQLCOM_CREATE_TABLE ||
               table->file->has_transactions();
   if (binlog.enabled() &&
-      thd.binlog_flush_pending_rows_event(TRUE, has_trans))
+      binlog.binlog_flush_pending_rows_event(&thd, TRUE, has_trans))
     goto err;
 
   if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
@@ -3880,7 +3880,7 @@ select_create::prepare(List<Item> &value
 
       create_table->next_global= select_tables;
 
-      error= thd->decide_logging_format(create_table);
+      error= binlog.decide_logging_format(thd, create_table);
 
       create_table->next_global= save_next_global;
 
@@ -3888,7 +3888,7 @@ select_create::prepare(List<Item> &value
         return error;
 
       TABLE const *const table = *tables;
-      if (thd->is_current_stmt_binlog_format_row()  &&
+      if (binlog.is_current_stmt_binlog_format_row(thd)  &&
           !table->s->tmp_table)
       {
         if (int error= ptr->binlog_show_create_table(tables, count))
@@ -3912,10 +3912,10 @@ select_create::prepare(List<Item> &value
     temporary table, we need to start a statement transaction.
   */
   if ((thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) == 0 &&
-      thd->is_current_stmt_binlog_format_row() &&
+      binlog.is_current_stmt_binlog_format_row(thd) &&
       binlog.enabled())
   {
-    thd->binlog_start_trans_and_stmt();
+    binlog.binlog_start_trans_and_stmt(thd);
   }
 
   DBUG_ASSERT(create_table->table == NULL);
@@ -3999,7 +3999,7 @@ select_create::binlog_show_create_table(
     schema that will do a close_thread_tables(), destroying the
     statement transaction cache.
   */
-  DBUG_ASSERT(thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(binlog.is_current_stmt_binlog_format_row(thd));
   DBUG_ASSERT(tables && *tables && count > 0);
 
   char buf[2048];
@@ -4041,7 +4041,7 @@ void select_create::send_error(uint errc
 
   DBUG_PRINT("info",
              ("Current statement %s row-based",
-              thd->is_current_stmt_binlog_format_row() ? "is" : "is NOT"));
+              binlog.is_current_stmt_binlog_format_row(thd) ? "is" : "is NOT"));
   DBUG_PRINT("info",
              ("Current table (at 0x%lu) %s a temporary (or non-existant) table",
               (ulong) table,
@@ -4120,7 +4120,7 @@ void select_create::abort_result_set()
   thd->transaction.stmt.modified_non_trans_table= FALSE;
   reenable_binlog(thd);
   /* possible error of writing binary log is ignored deliberately */
-  (void) thd->binlog_flush_pending_rows_event(TRUE, TRUE);
+  (void) binlog.binlog_flush_pending_rows_event(thd, TRUE, TRUE);
 
   if (m_plock)
   {

=== modified file 'sql/sql_load.cc'
--- a/sql/sql_load.cc	2011-01-31 07:32:53 +0000
+++ b/sql/sql_load.cc	2011-03-01 06:23:58 +0000
@@ -195,7 +195,7 @@ int mysql_load(THD *thd,sql_exchange *ex
     load data infile, so in mixed mode we go to row-based for
     avoiding the problem.
   */
-  thd->set_current_stmt_binlog_format_row_if_mixed();
+  binlog.set_current_stmt_binlog_format_row_if_mixed(thd);
 
 #ifdef EMBEDDED_LIBRARY
   read_file_from_client  = 0; //server is always in the same process 
@@ -605,8 +605,8 @@ int mysql_load(THD *thd,sql_exchange *ex
       version for the binary log to mark that table maps are invalid
       after this point.
      */
-    if (thd->is_current_stmt_binlog_format_row())
-      error= thd->binlog_flush_pending_rows_event(TRUE, transactional_table);
+    if (binlog.is_current_stmt_binlog_format_row(thd))
+      error= binlog.binlog_flush_pending_rows_event(thd, TRUE, transactional_table);
     else
     {
       /*

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2011-01-31 07:32:53 +0000
+++ b/sql/sql_parse.cc	2011-03-01 06:23:58 +0000
@@ -3423,7 +3423,7 @@ end_with_restore_list:
       break;
 
     /* Replicate current user as grantor */
-    thd->binlog_invoker();
+    binlog.binlog_invoker(thd);
 
     /* Conditionally writes to binlog */
     if (!(res = mysql_revoke_all(thd, lex->users_list)))
@@ -3442,7 +3442,7 @@ end_with_restore_list:
       goto error;
 
     /* Replicate current user as grantor */
-    thd->binlog_invoker();
+    binlog.binlog_invoker(thd);
 
     if (thd->security_ctx->user)              // If not replication
     {
@@ -5288,12 +5288,12 @@ void THD::reset_for_next_command()
   thd->sent_row_count= thd->examined_row_count= 0;
   thd->thd_marker.emb_on_expr_nest= NULL;
 
-  thd->reset_current_stmt_binlog_format_row();
+  binlog.reset_current_stmt_binlog_format_row(thd);
   thd->binlog_unsafe_warning_flags= 0;
 
   DBUG_PRINT("debug",
              ("is_current_stmt_binlog_format_row(): %d",
-              thd->is_current_stmt_binlog_format_row()));
+              binlog.is_current_stmt_binlog_format_row(thd)));
 
   DBUG_VOID_RETURN;
 }

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2011-01-31 07:32:53 +0000
+++ b/sql/sql_table.cc	2011-03-01 06:23:58 +0000
@@ -2199,7 +2199,7 @@ int mysql_rm_table_no_locks(THD *thd, TA
         built_query.append("DROP TABLE ");
     }
 
-    if (thd->is_current_stmt_binlog_format_row() || if_exists)
+    if (binlog.is_current_stmt_binlog_format_row(thd) || if_exists)
     {
       built_trans_tmp_query.set_charset(system_charset_info);
       built_trans_tmp_query.append("DROP TEMPORARY TABLE IF EXISTS ");
@@ -4559,8 +4559,8 @@ bool mysql_create_table(THD *thd, TABLE_
     Otherwise, the statement shall be binlogged.
   */
   if (!result &&
-      (!thd->is_current_stmt_binlog_format_row() ||
-       (thd->is_current_stmt_binlog_format_row() &&
+      (!binlog.is_current_stmt_binlog_format_row(thd) ||
+       (binlog.is_current_stmt_binlog_format_row(thd) &&
         !(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
     result= write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans);
 
@@ -4785,7 +4785,7 @@ bool mysql_create_like_table(THD* thd, T
   /*
     We have to write the query before we unlock the tables.
   */
-  if (thd->is_current_stmt_binlog_format_row())
+  if (binlog.is_current_stmt_binlog_format_row(thd))
   {
     /*
        Since temporary tables are not replicated under row-based
@@ -6745,7 +6745,7 @@ bool mysql_alter_table(THD *thd,char *ne
     if (rename_temporary_table(thd, new_table, new_db, new_name))
       goto err_new_table_cleanup;
     /* We don't replicate alter table statement on temporary tables */
-    if (!thd->is_current_stmt_binlog_format_row() &&
+    if (!binlog.is_current_stmt_binlog_format_row(thd) &&
         write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
       DBUG_RETURN(TRUE);
     goto end_temporary;
@@ -6905,7 +6905,7 @@ bool mysql_alter_table(THD *thd,char *ne
                       db, table_name);
 
   DBUG_ASSERT(!(binlog.enabled() &&
-                thd->is_current_stmt_binlog_format_row() &&
+                binlog.is_current_stmt_binlog_format_row(thd) &&
                 (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
   if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
     DBUG_RETURN(TRUE);

=== modified file 'sql/sql_truncate.cc'
--- a/sql/sql_truncate.cc	2010-11-18 13:50:08 +0000
+++ b/sql/sql_truncate.cc	2011-03-01 06:23:58 +0000
@@ -24,6 +24,7 @@
 #include "sql_acl.h"     // DROP_ACL
 #include "sql_parse.h"   // check_one_table_access()
 #include "sql_truncate.h"
+#include "binlog.h"
 
 
 /**
@@ -407,7 +408,7 @@ bool Sql_cmd_truncate_table::truncate_ta
   if ((table= find_temporary_table(thd, table_ref)))
   {
     /* In RBR, the statement is not binlogged if the table is temporary. */
-    binlog_stmt= !thd->is_current_stmt_binlog_format_row();
+    binlog_stmt= !binlog.is_current_stmt_binlog_format_row(thd);
 
     /* Note that a temporary table cannot be partitioned. */
     if (ha_check_storage_engine_flag(table->s->db_type(), HTON_CAN_RECREATE))

=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc	2011-01-10 16:27:45 +0000
+++ b/sql/sql_udf.cc	2011-03-01 06:23:58 +0000
@@ -39,6 +39,7 @@
 #include "records.h"          // init_read_record, end_read_record
 #include <my_pthread.h>
 #include "lock.h"                               // MYSQL_LOCK_IGNORE_TIMEOUT
+#include "binlog.h"
 
 #ifdef HAVE_DLOPEN
 extern "C"
@@ -460,8 +461,8 @@ int mysql_create_function(THD *thd,udf_f
     Turn off row binlogging of this statement and use statement-based 
     so that all supporting tables are updated for CREATE FUNCTION command.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   mysql_rwlock_wrlock(&THR_LOCK_udf);
   if ((my_hash_search(&udf_hash,(uchar*) udf->name.str, udf->name.length)))
@@ -526,15 +527,15 @@ int mysql_create_function(THD *thd,udf_f
   if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
   {
     /* Restore the state of binlog format */
-    DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+    DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
     if (save_binlog_row_based)
-      thd->set_current_stmt_binlog_format_row();
+      binlog.set_current_stmt_binlog_format_row(thd);
     DBUG_RETURN(1);
   }
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
   DBUG_RETURN(0);
 
  err:
@@ -542,9 +543,9 @@ int mysql_create_function(THD *thd,udf_f
     dlclose(dl);
   mysql_rwlock_unlock(&THR_LOCK_udf);
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
   DBUG_RETURN(1);
 }
 
@@ -577,8 +578,8 @@ int mysql_drop_function(THD *thd,const L
     Turn off row binlogging of this statement and use statement-based
     so that all supporting tables are updated for DROP FUNCTION command.
   */
-  if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
-    thd->clear_current_stmt_binlog_format_row();
+  if ((save_binlog_row_based= binlog.is_current_stmt_binlog_format_row(thd)))
+    binlog.clear_current_stmt_binlog_format_row(thd);
 
   mysql_rwlock_wrlock(&THR_LOCK_udf);
   if (!(udf=(udf_func*) my_hash_search(&udf_hash,(uchar*) udf_name->str,
@@ -619,9 +620,9 @@ int mysql_drop_function(THD *thd,const L
     error= 0;
 exit:
   /* Restore the state of binlog format */
-  DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
+  DBUG_ASSERT(!binlog.is_current_stmt_binlog_format_row(thd));
   if (save_binlog_row_based)
-    thd->set_current_stmt_binlog_format_row();
+    binlog.set_current_stmt_binlog_format_row(thd);
   DBUG_RETURN(error);
 }
 

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2011-01-31 07:32:53 +0000
+++ b/sql/sys_vars.cc	2011-03-01 06:23:58 +0000
@@ -324,7 +324,7 @@ static bool binlog_format_check(sys_var 
   if (thd->temporary_tables && var->type == OPT_SESSION &&
       var->save_result.ulonglong_value == BINLOG_FORMAT_STMT &&
       ((thd->variables.binlog_format == BINLOG_FORMAT_MIXED &&
-        thd->is_current_stmt_binlog_format_row()) ||
+        binlog.is_current_stmt_binlog_format_row(thd)) ||
        thd->variables.binlog_format == BINLOG_FORMAT_ROW))
   {
     my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR, MYF(0));
@@ -355,7 +355,7 @@ static bool fix_binlog_format_after_upda
                                            enum_var_type type)
 {
   if (type == OPT_SESSION)
-    thd->reset_current_stmt_binlog_format_row();
+    binlog.reset_current_stmt_binlog_format_row(thd);
   return false;
 }
 

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2011-01-31 07:32:53 +0000
+++ b/sql/table.cc	2011-03-01 06:23:58 +0000
@@ -4896,7 +4896,7 @@ void TABLE::mark_columns_needed_for_dele
         the hidden primary key
       */
       if (!(binlog.enabled() && in_use &&
-          in_use->is_current_stmt_binlog_format_row()))
+          binlog.is_current_stmt_binlog_format_row(in_use)))
         file->use_hidden_primary_key();
     }
     else
@@ -4960,7 +4960,7 @@ void TABLE::mark_columns_needed_for_upda
         the hidden primary key
       */
       if (!(binlog.enabled() && in_use &&
-          in_use->is_current_stmt_binlog_format_row()))
+          binlog.is_current_stmt_binlog_format_row(in_use)))
         file->use_hidden_primary_key();
     }
     else
@@ -5013,7 +5013,7 @@ void TABLE::mark_columns_per_binlog_row_
     depending on the binlog-row-image command line argument.
    */
   if ((binlog.enabled() && in_use &&
-       in_use->is_current_stmt_binlog_format_row() &&
+       binlog.is_current_stmt_binlog_format_row(in_use) &&
        !ha_check_storage_engine_flag(s->db_type(), HTON_NO_BINLOG_ROW_OPT)))
   {
 


Attachment: [text/bzr-bundle] bzr/hezx@greatopensource.com-20110301062358-q3b7rtebx64wjxqr.bundle
Thread
bzr commit into mysql-trunk branch (hezx:3519) WL#5778He Zhenxing1 Mar