Commit 0d3f926a authored by unknown's avatar unknown
Browse files

WL#2735: Refactor replication

Factoring out pack_row() and unpack_row() into new files
rpl_record.{cc,h}.


libmysqld/Makefile.am:
  Adding file rpl_record.cc
sql/CMakeLists.txt:
  Adding file rpl_record.cc
sql/Makefile.am:
  Adding file rpl_record.cc and rpl_record.h
sql/log_event.cc:
  Moving implementation of unpack_row() into "rpl_record.cc".
  Adding inclusion of header file "rpl_record.h".
sql/log_event_old.cc:
  Signature of do_prepare_row() changed.
sql/log_event_old.h:
  Adding copyright.
sql/rpl_record_old.cc:
  Signature of do_prepare_row() changed.
sql/rpl_record_old.h:
  Adding copyright.
  Signature of do_prepare_row() changed.
sql/sql_class.cc:
  Moving implementation THD::pack_row() into "rpl_record.cc" and rewriting
  it to be a global function.
  Adding inclusion of header file "rpl_record.h".
sql/sql_class.h:
  Removing pack_row() as THD member function.
sql/rpl_record.cc:
  New BitKeeper file ``sql/rpl_record.cc''
sql/rpl_record.h:
  New BitKeeper file ``sql/rpl_record.h''
parent dc125bb3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
	item_geofunc.cc item_subselect.cc item_row.cc\
	item_xmlfunc.cc \
	key.cc lock.cc log.cc sql_state.c \
	log_event.cc \
	log_event.cc rpl_record.cc \
	log_event_old.cc rpl_record_old.cc \
	protocol.cc net_serv.cc opt_range.cc \
	opt_sum.cc procedure.cc records.cc sql_acl.cc \
+2 −1
Original line number Diff line number Diff line
@@ -47,7 +47,8 @@ ADD_EXECUTABLE(mysqld ../sql-common/client.c derror.cc des_key_file.cc
               hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc 
               item_create.cc item_func.cc item_geofunc.cc item_row.cc 
               item_strfunc.cc item_subselect.cc item_sum.cc item_timefunc.cc 
               key.cc log.cc lock.cc log_event.cc message.rc 
               key.cc log.cc lock.cc message.rc 
               log_event.cc rpl_record.cc
               log_event_old.cc rpl_record_old.cc
               message.h mf_iocache.cc my_decimal.cc ../sql-common/my_time.c
               mysqld.cc net_serv.cc 
+4 −3
Original line number Diff line number Diff line
@@ -57,8 +57,8 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
			log.h sql_show.h rpl_rli.h rpl_mi.h \
			sql_select.h structs.h table.h sql_udf.h hash_filo.h \
			lex.h lex_symbol.h sql_acl.h sql_crypt.h  \
			log_event.h sql_repl.h slave.h rpl_filter.h \
			rpl_injector.h \
			sql_repl.h slave.h rpl_filter.h rpl_injector.h \
			log_event.h rpl_record.h \
			log_event_old.h rpl_record_old.h \
			stacktrace.h sql_sort.h sql_cache.h set_var.h \
			spatial.h gstream.h client_settings.h tzfile.h \
@@ -87,8 +87,9 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
			sql_prepare.cc sql_error.cc sql_locale.cc \
			sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
			procedure.cc sql_test.cc \
			log.cc log_event.cc init.cc derror.cc sql_acl.cc \
			log.cc init.cc derror.cc sql_acl.cc \
			unireg.cc des_key_file.cc \
			log_event.cc rpl_record.cc \
			log_event_old.cc rpl_record_old.cc \
			discover.cc time.cc opt_range.cc opt_sum.cc \
		   	records.cc filesort.cc handler.cc \
+1 −157
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "rpl_mi.h"
#include "rpl_filter.h"
#include "rpl_utility.h"
#include "rpl_record.h"
#include <my_dir.h>
#endif /* MYSQL_CLIENT */
#include <base64.h>
@@ -5811,163 +5812,6 @@ int Rows_log_event::do_add_row_data(byte *const row_data,
#endif

#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
/*
  Unpack a row into table->record[0].
  
  SYNOPSIS
    unpack_row()
    rli     Relay log info
    table   Table to unpack into
    colcnt  Number of columns to read from record
    row     Packed row data
    cols    Pointer to columns data to fill in
    row_end Pointer to variable that will hold the value of the
            one-after-end position for the row
    master_reclength
             Pointer to variable that will be set to the length of the
             record on the master side
    rw_set   Pointer to bitmap that holds either the read_set or the
             write_set of the table

  DESCRIPTION

      The function will always unpack into the table->record[0]
      record.  This is because there are too many dependencies on
      where the various member functions of Field and subclasses
      expect to write.

      The row is assumed to only consist of the fields for which the
      bitset represented by 'arr' and 'bits'; the other parts of the
      record are left alone.

      At most 'colcnt' columns are read: if the table is larger than
      that, the remaining fields are not filled in.

  RETURN VALUE

      Error code, or zero if no error. The following error codes can
      be returned:

      ER_NO_DEFAULT_FOR_FIELD
        Returned if one of the fields existing on the slave but not on
        the master does not have a default value (and isn't nullable)
 */
static int
unpack_row(RELAY_LOG_INFO const *rli,
           TABLE *table, uint const colcnt,
           char const *const row_data, MY_BITMAP const *cols,
           char const **const row_end, ulong *const master_reclength,
           MY_BITMAP* const rw_set, Log_event_type const event_type)
{
  DBUG_ENTER("unpack_row");
  DBUG_ASSERT(row_data);
  my_size_t const master_null_byte_count= (bitmap_bits_set(cols) + 7) / 8;
  int error= 0;

  char const *null_ptr= row_data;
  char const *pack_ptr= row_data + master_null_byte_count;

  bitmap_clear_all(rw_set);

  empty_record(table);

  Field **const begin_ptr = table->field;
  Field **field_ptr;
  Field **const end_ptr= begin_ptr + colcnt;

  DBUG_ASSERT(null_ptr < row_data + master_null_byte_count);

  // Mask to mask out the correct bit among the null bits
  unsigned int null_mask= 1U;
  // The "current" null bits
  unsigned int null_bits= *null_ptr++;
  for (field_ptr= begin_ptr ; field_ptr < end_ptr ; ++field_ptr)
  {
    Field *const f= *field_ptr;

    /*
      No need to bother about columns that does not exist: they have
      gotten default values when being emptied above.
     */
    if (bitmap_is_set(cols, field_ptr -  begin_ptr))
    {
      if ((null_mask & 0xFF) == 0)
      {
        DBUG_ASSERT(null_ptr < row_data + master_null_byte_count);
        null_mask= 1U;
        null_bits= *null_ptr++;
      }

      DBUG_ASSERT(null_mask & 0xFF); // One of the 8 LSB should be set

      /* Field...::unpack() cannot return 0 */
      DBUG_ASSERT(pack_ptr != NULL);

      if ((null_bits & null_mask) && f->maybe_null())
        f->set_null();
      else
      {
        f->set_notnull();

        /*
          We only unpack the field if it was non-null
        */
        pack_ptr= f->unpack(f->ptr, pack_ptr);
      }

      bitmap_set_bit(rw_set, f->field_index);
      null_mask <<= 1;
    }
  }

  /*
    We should now have read all the null bytes, otherwise something is
    really wrong.
   */
  DBUG_ASSERT(null_ptr == row_data + master_null_byte_count);

  *row_end = pack_ptr;
  if (master_reclength)
  {
    if (*field_ptr)
      *master_reclength = (*field_ptr)->ptr - (char*) table->record[0];
    else
      *master_reclength = table->s->reclength;
  }

  /*
    Set properties for remaining columns, if there are any. We let the
    corresponding bit in the write_set be set, to write the value if
    it was not there already. We iterate over all remaining columns,
    even if there were an error, to get as many error messages as
    possible.  We are still able to return a pointer to the next row,
    so redo that.

    This generation of error messages is only relevant when inserting
    new rows.
   */
  for ( ; *field_ptr ; ++field_ptr)
  {
    uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
    Field *const f= *field_ptr;

    if (event_type == WRITE_ROWS_EVENT &&
        ((*field_ptr)->flags & mask) == mask)
    {
      slave_print_msg(ERROR_LEVEL, rli, ER_NO_DEFAULT_FOR_FIELD,
                      "Field `%s` of table `%s`.`%s` "
                      "has no default value and cannot be NULL",
                      (*field_ptr)->field_name, table->s->db.str,
                      table->s->table_name.str);
      error = ER_NO_DEFAULT_FOR_FIELD;
    }
    else
      f->set_default();
  }

  DBUG_RETURN(error);
}

int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
  DBUG_ENTER("Rows_log_event::do_apply_event(st_relay_log_info*)");
+14 −7
Original line number Diff line number Diff line
@@ -5,7 +5,8 @@

#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
int
Write_rows_log_event_old::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
Write_rows_log_event_old::do_prepare_row(THD *thd,
                                         RELAY_LOG_INFO const *rli,
                                         TABLE *table,
                                         char const *row_start,
                                         char const **row_end)
@@ -14,7 +15,8 @@ Write_rows_log_event_old::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
  DBUG_ASSERT(row_start && row_end);

  int error;
  error= unpack_row_old(rli, table, m_width, table->record[0],
  error= unpack_row_old(const_cast<RELAY_LOG_INFO*>(rli),
                        table, m_width, table->record[0],
                        row_start, &m_cols, row_end, &m_master_reclength,
                        table->write_set, PRE_GA_WRITE_ROWS_EVENT);
  bitmap_copy(table->read_set, table->write_set);
@@ -23,7 +25,8 @@ Write_rows_log_event_old::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,


int
Delete_rows_log_event_old::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
Delete_rows_log_event_old::do_prepare_row(THD *thd,
                                          RELAY_LOG_INFO const *rli,
                                          TABLE *table,
                                          char const *row_start,
                                          char const **row_end)
@@ -36,7 +39,8 @@ Delete_rows_log_event_old::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
  */
  DBUG_ASSERT(table->s->fields >= m_width);

  error= unpack_row_old(rli, table, m_width, table->record[0],
  error= unpack_row_old(const_cast<RELAY_LOG_INFO*>(rli),
                        table, m_width, table->record[0],
                        row_start, &m_cols, row_end, &m_master_reclength,
                        table->read_set, PRE_GA_DELETE_ROWS_EVENT);
  /*
@@ -54,7 +58,8 @@ Delete_rows_log_event_old::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
}


int Update_rows_log_event_old::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
int Update_rows_log_event_old::do_prepare_row(THD *thd,
                                              RELAY_LOG_INFO const *rli,
                                              TABLE *table,
                                              char const *row_start,
                                              char const **row_end)
@@ -68,12 +73,14 @@ int Update_rows_log_event_old::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
  DBUG_ASSERT(table->s->fields >= m_width);

  /* record[0] is the before image for the update */
  error= unpack_row_old(rli, table, m_width, table->record[0],
  error= unpack_row_old(const_cast<RELAY_LOG_INFO*>(rli),
                        table, m_width, table->record[0],
                        row_start, &m_cols, row_end, &m_master_reclength,
                        table->read_set, PRE_GA_UPDATE_ROWS_EVENT);
  row_start = *row_end;
  /* m_after_image is the after image for the update */
  error= unpack_row_old(rli, table, m_width, m_after_image,
  error= unpack_row_old(const_cast<RELAY_LOG_INFO*>(rli),
                        table, m_width, m_after_image,
                        row_start, &m_cols, row_end, &m_master_reclength,
                        table->write_set, PRE_GA_UPDATE_ROWS_EVENT);

Loading