List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:December 18 2007 5:27pm
Subject:bk commit into 6.0 tree (mats:1.2759) BUG#33055
View as plain text  
Below is the list of changes that have just been committed into a local
6.0 repository of mats. When mats does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-12-18 18:26:54+01:00, mats@stripped +10 -0
  BUG#33055 (Replication fails for UPDATE when using falcon Storage engine):
  
  The read- and write-sets were not respected when deciding what fields to
  transfer to the slave, nor when writing the row to the handler on the sla-
  ve side.
  
  This patch adds code that only writes the columns actually needed to be 
  able to replicate row-based. This means that the columns in the write set
  of the table is used for ha_write_row(), the columns in the read set for
  ha_delete_row(), and for ha_update_row() the columns in the read set is
  used for the before image, and the columns of the write set for the after
  image.
  
  In addition, for cursor-based delete and update, the necessary bits are
  set to be able to get enough information to locate the affected row on
  the slave side, which means that it behaves as if HA_PRIMARY_KEY_REQUIRED_
  FOR_DELETE was set for the table when row-based logging is active.

  mysql-test/suite/rpl/r/rpl_temporary_errors.result@stripped, 2007-12-18 18:26:43+01:00, mats@stripped +2 -2
    Result change.

  sql/handler.cc@stripped, 2007-12-18 18:26:44+01:00, mats@stripped +6 -23
    The function binlog_row_logging_function() does not need column
    information any more: that information is fetched directly from
    the read- and write-sets of the table instead. Hence, an unused
    initialization of a bitmap is removed, as well as error handling
    code for that initialization.

  sql/log_event.cc@stripped, 2007-12-18 18:26:44+01:00, mats@stripped +15 -25
    Passing columns to new unpack_current_row() function: it now
    takes a column bitmap with the columns to unpack. When preparing
    the record before filling it in, the column vector now has to be
    passed so that the function knows what columns to initialize.
    
    The constructors for Write_rows, Delete_rows, and Update_rows
    now use either the read- or write-set of the table when packing
    rows for transfer, so the column vector parameter was removed.
    As a consequence, an overloaded version of the Update_rows
    constructor was removed.

  sql/log_event.h@stripped, 2007-12-18 18:26:44+01:00, mats@stripped +8 -21
    The function unpack_current_row() now takes an extra column
    vector giving the columns to unpack and passes that to
    ::unpack_row() instead of m_cols previously (it can now be
    either m_cols or m_cols_ai, depending on situation).
    
    Removing redundant column vector parameter from constructors
    for Write_rows, Delete_rows, and Update_rows and removing
    a redundant constructor.
    
    Removing column vector parameters to binlog_row_logging_
    function() since they are no longer needed.

  sql/log_event_old.h@stripped, 2007-12-18 18:26:45+01:00, mats@stripped +6 -6
    Removing redundant column vector parameter from constructors
    for Write_rows, Delete_rows, and Update_rows and removing
    a redundant constructor.

  sql/rpl_record.cc@stripped, 2007-12-18 18:26:45+01:00, mats@stripped +55 -21
    Adding debug printouts to be able to debug packing and unpacking of rows.
    
    Adding column vector to prepare_record(). The function prepare_record()
    now initializes all fields of the record, not just the "extra" ones that
    could be present on a slave with more columns. The function still prints
    an error for extra fields that does not have a default value (in the same
    manner as the old function), but does not print anything for columns that
    are present on the master and the slave.

  sql/rpl_record.h@stripped, 2007-12-18 18:26:45+01:00, mats@stripped +1 -1
    Adding column vector parameter to prepare_record().

  sql/sql_class.cc@stripped, 2007-12-18 18:26:45+01:00, mats@stripped +13 -24
    Columns bitmap and number of columns no longer needed for binlog_*_row().
    The correct columns are fetched from the read- and write-set of the table
    instead. Consequence: binlog_prepare_pending_rows_event() does not need
    this info either.
    
    The function pack_row() is called with either the read- or the write-set
    of the table.

  sql/sql_class.h@stripped, 2007-12-18 18:26:46+01:00, mats@stripped +2 -7
    Columns bitmap and number of columns no longer needed for binlog_*_row().
    The correct columns are fetched from the read- and write-set of the table
    instead. Consequence: binlog_prepare_pending_rows_event() does not need
    this info either.

  sql/table.cc@stripped, 2007-12-18 18:26:46+01:00, mats@stripped +12 -6
    Columns marked for delete are marked in the same way as if
    HA_PRIMARY_KEY_REQUIRED_FOR_DELETE when row-based replication
    is active since the primary key (or entire row) has to be
    transfered to the slave. There is no way that the slave can
    know what row the master's cursor is positioned on when del-
    eting a row. This is done for both DELETE and UPDATE.

diff -Nrup a/mysql-test/suite/rpl/r/rpl_temporary_errors.result b/mysql-test/suite/rpl/r/rpl_temporary_errors.result
--- a/mysql-test/suite/rpl/r/rpl_temporary_errors.result	2007-10-24 16:02:32 +02:00
+++ b/mysql-test/suite/rpl/r/rpl_temporary_errors.result	2007-12-18 18:26:43 +01:00
@@ -44,7 +44,7 @@ Master_User	root
 Master_Port	MASTER_PORT
 Connect_Retry	1
 Master_Log_File	master-bin.000001
-Read_Master_Log_Pos	408
+Read_Master_Log_Pos	404
 Relay_Log_File	#
 Relay_Log_Pos	#
 Relay_Master_Log_File	master-bin.000001
@@ -59,7 +59,7 @@ Replicate_Wild_Ignore_Table	
 Last_Errno	0
 Last_Error	
 Skip_Counter	0
-Exec_Master_Log_Pos	408
+Exec_Master_Log_Pos	404
 Relay_Log_Space	#
 Until_Condition	None
 Until_Log_File	
diff -Nrup a/sql/handler.cc b/sql/handler.cc
--- a/sql/handler.cc	2007-12-05 20:44:35 +01:00
+++ b/sql/handler.cc	2007-12-18 18:26:44 +01:00
@@ -4516,35 +4516,18 @@ namespace
 
     if (check_table_binlog_row_based(thd, table))
     {
-      MY_BITMAP cols;
-      /* Potential buffer on the stack for the bitmap */
-      uint32 bitbuf[BITMAP_STACKBUF_SIZE/sizeof(uint32)];
-      uint n_fields= table->s->fields;
-      my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
-
+      DBUG_DUMP("read_set 10", (uchar*) table->read_set->bitmap, (table->s->fields + 7) / 8);
       /*
         If there are no table maps written to the binary log, this is
         the first row handled in this statement. In that case, we need
         to write table maps for all locked tables to the binary log.
       */
-      if (likely(!(error= bitmap_init(&cols,
-                                      use_bitbuf ? bitbuf : NULL,
-                                      (n_fields + 7) & ~7UL,
-                                      FALSE))))
+      if (likely(!(error= write_locked_table_maps(thd))))
       {
-        bitmap_set_all(&cols);
-        if (likely(!(error= write_locked_table_maps(thd))))
-        {
-          error=
-            RowsEventT::binlog_row_logging_function(thd, table,
-                                                    table->file->
-                                                    has_transactions(),
-                                                    &cols, table->s->fields,
-                                                    before_record,
-                                                    after_record);
-        }
-        if (!use_bitbuf)
-          bitmap_free(&cols);
+        bool const has_trans= table->file->has_transactions();
+        error=
+          RowsEventT::binlog_row_logging_function(thd, table, has_trans,
+                                                  before_record, after_record);
       }
     }
     return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
diff -Nrup a/sql/log_event.cc b/sql/log_event.cc
--- a/sql/log_event.cc	2007-11-15 14:41:44 +01:00
+++ b/sql/log_event.cc	2007-12-18 18:26:44 +01:00
@@ -6451,7 +6451,7 @@ int Rows_log_event::do_apply_event(Relay
                           (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
 
       if (!m_curr_row_end && !error)
-        unpack_current_row(rli);
+        unpack_current_row(rli, &m_cols);
   
       // at this moment m_curr_row_end should be set
       DBUG_ASSERT(error || m_curr_row_end != NULL); 
@@ -7265,9 +7265,8 @@ void Table_map_log_event::print(FILE *fi
 #if !defined(MYSQL_CLIENT)
 Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
                                            ulong tid_arg,
-                                           MY_BITMAP const *cols,
                                            bool is_transactional)
-  : Rows_log_event(thd_arg, tbl_arg, tid_arg, cols, is_transactional)
+  : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
 {
 }
 #endif
@@ -7344,6 +7343,7 @@ Write_rows_log_event::do_before_row_oper
     analyze if explicit data is provided for slave's TIMESTAMP columns).
   */
   m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
+
   return error;
 }
 
@@ -7455,12 +7455,12 @@ Rows_log_event::write_row(const Relay_lo
 
   /* fill table->record[0] with default values */
 
-  if ((error= prepare_record(rli, table, m_width,
+  if ((error= prepare_record(rli, table, &m_cols, m_width,
                              TRUE /* check if columns have def. values */)))
     DBUG_RETURN(error);
   
   /* unpack row into table->record[0] */
-  error= unpack_current_row(rli); // TODO: how to handle errors?
+  error= unpack_current_row(rli, &m_cols);
 
 #ifndef DBUG_OFF
   DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
@@ -7569,7 +7569,7 @@ Rows_log_event::write_row(const Relay_lo
     if (!get_flags(COMPLETE_ROWS_F))
     {
       restore_record(table,record[1]);
-      error= unpack_current_row(rli);
+      error= unpack_current_row(rli, &m_cols);
     }
 
 #ifndef DBUG_OFF
@@ -7780,8 +7780,8 @@ int Rows_log_event::find_row(const Relay
   /* unpack row - missing fields get default values */
 
   // TODO: shall we check and report errors here?
-  prepare_record(NULL,table,m_width,FALSE /* don't check errors */); 
-  error= unpack_current_row(rli); 
+  prepare_record(NULL, table, &m_cols, m_width, FALSE /* don't check errors */); 
+  error= unpack_current_row(rli, &m_cols);
 
 #ifndef DBUG_OFF
   DBUG_PRINT("info",("looking for the following record"));
@@ -8030,9 +8030,9 @@ int Rows_log_event::find_row(const Relay
 
 #ifndef MYSQL_CLIENT
 Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
-                                             ulong tid, MY_BITMAP const *cols,
+                                             ulong tid,
                                              bool is_transactional)
-  : Rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional)
+  : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
 {
 }
 #endif /* #if !defined(MYSQL_CLIENT) */
@@ -8070,6 +8070,7 @@ Delete_rows_log_event::do_before_row_ope
     if (!m_key)
       return HA_ERR_OUT_OF_MEM;
   }
+
   return 0;
 }
 
@@ -8121,21 +8122,10 @@ void Delete_rows_log_event::print(FILE *
 #if !defined(MYSQL_CLIENT)
 Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
                                              ulong tid,
-                                             MY_BITMAP const *cols_bi,
-                                             MY_BITMAP const *cols_ai,
-                                             bool is_transactional)
-: Rows_log_event(thd_arg, tbl_arg, tid, cols_bi, is_transactional)
-{
-  init(cols_ai);
-}
-
-Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
-                                             ulong tid,
-                                             MY_BITMAP const *cols,
                                              bool is_transactional)
-: Rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional)
+: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
 {
-  init(cols);
+  init(tbl_arg->write_set);
 }
 
 void Update_rows_log_event::init(MY_BITMAP const *cols)
@@ -8221,7 +8211,7 @@ Update_rows_log_event::do_exec_row(const
       able to skip to the next pair of updates
     */
     m_curr_row= m_curr_row_end;
-    unpack_current_row(rli);
+    unpack_current_row(rli, &m_cols_ai);
     return error;
   }
 
@@ -8239,7 +8229,7 @@ Update_rows_log_event::do_exec_row(const
   store_record(m_table,record[1]);
 
   m_curr_row= m_curr_row_end;
-  error= unpack_current_row(rli); // this also updates m_curr_row_end
+  error= unpack_current_row(rli, &m_cols_ai); // this also updates m_curr_row_end
 
   /*
     Now we have the right row to update.  The old row (the one we're
diff -Nrup a/sql/log_event.h b/sql/log_event.h
--- a/sql/log_event.h	2007-11-15 14:41:45 +01:00
+++ b/sql/log_event.h	2007-12-18 18:26:44 +01:00
@@ -3092,11 +3092,12 @@ protected:
   int write_row(const Relay_log_info *const, const bool);
 
   // Unpack the current row into m_table->record[0]
-  int unpack_current_row(const Relay_log_info *const rli)
+  int unpack_current_row(const Relay_log_info *const rli,
+                         MY_BITMAP const *cols)
   { 
     DBUG_ASSERT(m_table);
     ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
-    int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
+    int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, cols,
                                    &m_curr_row_end, &m_master_reclength);
     ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
     return result;
@@ -3185,7 +3186,7 @@ public:
 
 #if !defined(MYSQL_CLIENT)
   Write_rows_log_event(THD*, TABLE*, ulong table_id, 
-		       MY_BITMAP const *cols, bool is_transactional);
+		       bool is_transactional);
 #endif
 #ifdef HAVE_REPLICATION
   Write_rows_log_event(const char *buf, uint event_len, 
@@ -3194,14 +3195,11 @@ public:
 #if !defined(MYSQL_CLIENT) 
   static bool binlog_row_logging_function(THD *thd, TABLE *table,
                                           bool is_transactional,
-                                          MY_BITMAP *cols,
-                                          uint fields,
                                           const uchar *before_record
                                           __attribute__((unused)),
                                           const uchar *after_record)
   {
-    return thd->binlog_write_row(table, is_transactional,
-                                 cols, fields, after_record);
+    return thd->binlog_write_row(table, is_transactional, after_record);
   }
 #endif
 
@@ -3243,12 +3241,6 @@ public:
 
 #ifndef MYSQL_CLIENT
   Update_rows_log_event(THD*, TABLE*, ulong table_id,
-			MY_BITMAP const *cols_bi,
-			MY_BITMAP const *cols_ai,
-                        bool is_transactional);
-
-  Update_rows_log_event(THD*, TABLE*, ulong table_id,
-			MY_BITMAP const *cols,
                         bool is_transactional);
 
   void init(MY_BITMAP const *cols);
@@ -3264,13 +3256,11 @@ public:
 #if !defined(MYSQL_CLIENT) 
   static bool binlog_row_logging_function(THD *thd, TABLE *table,
                                           bool is_transactional,
-                                          MY_BITMAP *cols,
-                                          uint fields,
                                           const uchar *before_record,
                                           const uchar *after_record)
   {
     return thd->binlog_update_row(table, is_transactional,
-                                  cols, fields, before_record, after_record);
+                                  before_record, after_record);
   }
 #endif
 
@@ -3324,7 +3314,7 @@ public:
 
 #ifndef MYSQL_CLIENT
   Delete_rows_log_event(THD*, TABLE*, ulong, 
-			MY_BITMAP const *cols, bool is_transactional);
+			bool is_transactional);
 #endif
 #ifdef HAVE_REPLICATION
   Delete_rows_log_event(const char *buf, uint event_len, 
@@ -3333,14 +3323,11 @@ public:
 #if !defined(MYSQL_CLIENT) 
   static bool binlog_row_logging_function(THD *thd, TABLE *table,
                                           bool is_transactional,
-                                          MY_BITMAP *cols,
-                                          uint fields,
                                           const uchar *before_record,
                                           const uchar *after_record
                                           __attribute__((unused)))
   {
-    return thd->binlog_delete_row(table, is_transactional,
-                                  cols, fields, before_record);
+    return thd->binlog_delete_row(table, is_transactional, before_record);
   }
 #endif
   
diff -Nrup a/sql/log_event_old.h b/sql/log_event_old.h
--- a/sql/log_event_old.h	2007-09-10 13:15:59 +02:00
+++ b/sql/log_event_old.h	2007-12-18 18:26:45 +01:00
@@ -113,8 +113,8 @@ public:
 
 #if !defined(MYSQL_CLIENT)
   Write_rows_log_event_old(THD *thd, TABLE *table, ulong table_id,
-                           MY_BITMAP const *cols, bool is_transactional)
-    : Write_rows_log_event(thd, table, table_id, cols, is_transactional)
+                           bool is_transactional)
+    : Write_rows_log_event(thd, table, table_id, is_transactional)
   {
   }
 #endif
@@ -159,8 +159,8 @@ public:
 
 #if !defined(MYSQL_CLIENT)
   Update_rows_log_event_old(THD *thd, TABLE *table, ulong table_id,
-                           MY_BITMAP const *cols, bool is_transactional)
-    : Update_rows_log_event(thd, table, table_id, cols, is_transactional),
+                           bool is_transactional)
+    : Update_rows_log_event(thd, table, table_id, is_transactional),
       m_after_image(NULL), m_memory(NULL)
   {
   }
@@ -206,8 +206,8 @@ public:
 
 #if !defined(MYSQL_CLIENT)
   Delete_rows_log_event_old(THD *thd, TABLE *table, ulong table_id,
-                           MY_BITMAP const *cols, bool is_transactional)
-    : Delete_rows_log_event(thd, table, table_id, cols, is_transactional),
+                           bool is_transactional)
+    : Delete_rows_log_event(thd, table, table_id, is_transactional),
       m_after_image(NULL), m_memory(NULL)
   {
   }
diff -Nrup a/sql/rpl_record.cc b/sql/rpl_record.cc
--- a/sql/rpl_record.cc	2007-11-15 14:41:46 +01:00
+++ b/sql/rpl_record.cc	2007-12-18 18:26:45 +01:00
@@ -75,15 +75,20 @@ pack_row(TABLE *table, MY_BITMAP const* 
   unsigned int null_bits= (1U << 8) - 1;
   // Mask to mask out the correct but among the null bits
   unsigned int null_mask= 1U;
+  DBUG_PRINT("debug", ("null ptr: 0x%lx; row start: %p; null bytes: %d",
+                       (ulong) null_ptr, row_data, null_byte_count));
+  DBUG_DUMP("cols", (uchar*) cols->bitmap, cols->last_word_ptr - cols->bitmap + 1);
   for ( ; (field= *p_field) ; p_field++)
   {
-    DBUG_PRINT("debug", ("null_mask=%d; null_ptr=%p; row_data=%p; null_byte_count=%d",
-                         null_mask, null_ptr, row_data, null_byte_count));
+    DBUG_PRINT("debug", ("field: %s; null mask: 0x%x",
+                         field->field_name, null_mask));
     if (bitmap_is_set(cols, p_field - table->field))
     {
       my_ptrdiff_t offset;
       if (field->is_null(rec_offset))
       {
+        DBUG_PRINT("debug", ("Is NULL; null_mask: 0x%x; null_bits: 0x%x",
+                             null_mask, null_bits));
         offset= def_offset;
         null_bits |= null_mask;
       }
@@ -104,9 +109,9 @@ pack_row(TABLE *table, MY_BITMAP const* 
 #endif
         pack_ptr= field->pack(pack_ptr, field->ptr + offset,
                               field->max_data_length(), TRUE);
-        DBUG_PRINT("debug", ("field: %s; pack_ptr: 0x%lx;"
+        DBUG_PRINT("debug", ("Packed into row; pack_ptr: 0x%lx;"
                              " pack_ptr':0x%lx; bytes: %d",
-                             field->field_name, (ulong) old_pack_ptr,
+                             (ulong) old_pack_ptr,
                              (ulong) pack_ptr,
                              (int) (pack_ptr - old_pack_ptr)));
       }
@@ -120,6 +125,12 @@ pack_row(TABLE *table, MY_BITMAP const* 
         null_bits= (1U << 8) - 1;
       }
     }
+#ifndef DBUG_OFF
+    else
+    {
+      DBUG_PRINT("debug", ("Skipped"));
+    }
+#endif
   }
 
   /*
@@ -206,6 +217,9 @@ unpack_row(Relay_log_info const *rli,
   {
     Field *const f= *field_ptr;
 
+    DBUG_PRINT("debug", ("field: %s; null mask: 0x%x; null bits: 0x%lx; row start: %p; null bytes: %d",
+                         f->field_name, null_mask, (ulong) null_bits, pack_ptr, master_null_byte_count));
+
     /*
       No need to bother about columns that does not exist: they have
       gotten default values when being emptied above.
@@ -225,7 +239,12 @@ unpack_row(Relay_log_info const *rli,
       DBUG_ASSERT(pack_ptr != NULL);
 
       if ((null_bits & null_mask) && f->maybe_null())
+      {
+        DBUG_PRINT("debug", ("Was NULL; null mask: 0x%x; null bits: 0x%x",
+                             null_mask, null_bits));
+
         f->set_null();
+      }
       else
       {
         f->set_notnull();
@@ -240,15 +259,20 @@ unpack_row(Relay_log_info const *rli,
         uchar const *const old_pack_ptr= pack_ptr;
 #endif
         pack_ptr= f->unpack(f->ptr, pack_ptr, metadata, TRUE);
-	DBUG_PRINT("debug", ("field: %s; metadata: 0x%x;"
+	DBUG_PRINT("debug", ("Unpacked; metadata: 0x%x;"
                              " pack_ptr: 0x%lx; pack_ptr': 0x%lx; bytes: %d",
-                             f->field_name, metadata,
-                             (ulong) old_pack_ptr, (ulong) pack_ptr,
+                             metadata, (ulong) old_pack_ptr, (ulong) pack_ptr,
                              (int) (pack_ptr - old_pack_ptr)));
       }
 
       null_mask <<= 1;
     }
+#ifndef DBUG_OFF
+    else
+    {
+      DBUG_PRINT("debug", ("Non-existent: skipped"));
+    }
+#endif
     i++;
   }
 
@@ -318,35 +342,45 @@ unpack_row(Relay_log_info const *rli,
  */ 
 int prepare_record(const Slave_reporting_capability *const log, 
                    TABLE *const table, 
-                   const uint skip, const bool check)
+                   const MY_BITMAP *cols, uint width, const bool check)
 {
   DBUG_ENTER("prepare_record");
 
   int error= 0;
   empty_record(table);
 
-  if (skip >= table->s->fields)  // nothing to do
-    DBUG_RETURN(0);
-
-  /* Explicit initialization of fields */
+  /*
+    Explicit initialization of fields. For fields that are not in the
+    cols for the row, we set them to default. If the fields are in
+    addition to what exists on the master, we give an error if the
+    have no sensible default.
+  */
 
-  for (Field **field_ptr= table->field+skip ; *field_ptr ; ++field_ptr)
+  for (Field **field_ptr= table->field ; *field_ptr ; ++field_ptr)
   {
     uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
     Field *const f= *field_ptr;
 
     if (check && ((f->flags & mask) == mask))
     {
-      DBUG_ASSERT(log);
-      log->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD,
-                  "Field `%s` of table `%s`.`%s` "
-                  "has no default value and cannot be NULL",
-                  f->field_name, table->s->db.str,
-                  table->s->table_name.str);
-      error = ER_NO_DEFAULT_FOR_FIELD;
+      DBUG_ASSERT(field_ptr >= table->field);
+      if ((uint) (field_ptr - table->field) >= width)
+      {
+        DBUG_ASSERT(log);
+        log->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD,
+                    "Field `%s` of table `%s`.`%s` "
+                    "has no default value and cannot be NULL",
+                    f->field_name, table->s->db.str,
+                    table->s->table_name.str);
+        error = ER_NO_DEFAULT_FOR_FIELD;
+      }
     }
-    else
+    else if (field_ptr - table->field >= cols->n_bits ||
+             !bitmap_is_set(cols, field_ptr - table->field))
+    {
+      DBUG_PRINT("debug", ("Set default; field: %s", f->field_name));
       f->set_default();
+    }
   }
 
   DBUG_RETURN(error);
diff -Nrup a/sql/rpl_record.h b/sql/rpl_record.h
--- a/sql/rpl_record.h	2007-09-10 13:15:59 +02:00
+++ b/sql/rpl_record.h	2007-12-18 18:26:45 +01:00
@@ -31,7 +31,7 @@ int unpack_row(Relay_log_info const *rli
 
 // Fill table's record[0] with default values.
 int prepare_record(const Slave_reporting_capability *const, TABLE *const, 
-                   const uint =0, const bool =FALSE);
+                   const MY_BITMAP *cols, uint width, const bool);
 #endif
 
 #endif
diff -Nrup a/sql/sql_class.cc b/sql/sql_class.cc
--- a/sql/sql_class.cc	2007-11-28 15:34:34 +01:00
+++ b/sql/sql_class.cc	2007-12-18 18:26:45 +01:00
@@ -2950,8 +2950,6 @@ void xid_cache_delete(XID_STATE *xid_sta
 
 template <class RowsEventT> Rows_log_event* 
 THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
-                                       MY_BITMAP const* cols,
-                                       size_t colcnt,
                                        size_t needed,
                                        bool is_transactional,
 				       RowsEventT *hint __attribute__((unused)))
@@ -2989,13 +2987,11 @@ THD::binlog_prepare_pending_rows_event(T
       pending->server_id != serv_id || 
       pending->get_table_id() != table->s->table_map_id ||
       pending->get_type_code() != type_code || 
-      pending->get_data_size() + needed > opt_binlog_rows_event_max_size || 
-      pending->get_width() != colcnt ||
-      !bitmap_cmp(pending->get_cols(), cols)) 
+      pending->get_data_size() + needed > opt_binlog_rows_event_max_size) 
   {
     /* Create a new RowsEventT... */
     Rows_log_event* const
-	ev= new RowsEventT(this, table, table->s->table_map_id, cols,
+	ev= new RowsEventT(this, table, table->s->table_map_id,
                            is_transactional);
     if (unlikely(!ev))
       DBUG_RETURN(NULL);
@@ -3021,18 +3017,15 @@ THD::binlog_prepare_pending_rows_event(T
   compiling option.
 */
 template Rows_log_event*
-THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
-				       size_t, size_t, bool,
+THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
 				       Write_rows_log_event*);
 
 template Rows_log_event*
-THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
-				       size_t colcnt, size_t, bool,
+THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
 				       Delete_rows_log_event *);
 
 template Rows_log_event* 
-THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
-				       size_t colcnt, size_t, bool,
+THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
 				       Update_rows_log_event *);
 #endif
 
@@ -3224,7 +3217,6 @@ namespace {
 
 
 int THD::binlog_write_row(TABLE* table, bool is_trans, 
-                          MY_BITMAP const* cols, size_t colcnt, 
                           uchar const *record) 
 { 
   DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
@@ -3239,11 +3231,10 @@ int THD::binlog_write_row(TABLE* table, 
 
   uchar *row_data= memory.slot(0);
 
-  size_t const len= pack_row(table, cols, row_data, record);
+  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, cols, colcnt,
-                                      len, is_trans,
+    binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
                                       static_cast<Write_rows_log_event*>(0));
 
   if (unlikely(ev == 0))
@@ -3253,7 +3244,6 @@ int THD::binlog_write_row(TABLE* table, 
 }
 
 int THD::binlog_update_row(TABLE* table, bool is_trans,
-                           MY_BITMAP const* cols, size_t colcnt,
                            const uchar *before_record,
                            const uchar *after_record)
 { 
@@ -3269,9 +3259,9 @@ int THD::binlog_update_row(TABLE* table,
   uchar *before_row= row_data.slot(0);
   uchar *after_row= row_data.slot(1);
 
-  size_t const before_size= pack_row(table, cols, before_row,
+  size_t const before_size= pack_row(table, table->read_set, before_row,
                                         before_record);
-  size_t const after_size= pack_row(table, cols, after_row,
+  size_t const after_size= pack_row(table, table->write_set, after_row,
                                        after_record);
 
   /*
@@ -3286,7 +3276,7 @@ int THD::binlog_update_row(TABLE* table,
 #endif
 
   Rows_log_event* const ev=
-    binlog_prepare_pending_rows_event(table, server_id, cols, colcnt,
+    binlog_prepare_pending_rows_event(table, server_id,
 				      before_size + after_size, is_trans,
 				      static_cast<Update_rows_log_event*>(0));
 
@@ -3299,7 +3289,6 @@ int THD::binlog_update_row(TABLE* table,
 }
 
 int THD::binlog_delete_row(TABLE* table, bool is_trans, 
-                           MY_BITMAP const* cols, size_t colcnt,
                            uchar const *record)
 { 
   DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
@@ -3314,11 +3303,11 @@ int THD::binlog_delete_row(TABLE* table,
 
   uchar *row_data= memory.slot(0);
 
-  size_t const len= pack_row(table, cols, row_data, record);
+  DBUG_DUMP("table->read_set", (uchar*) table->read_set->bitmap, (table->s->fields + 7) / 8);
+  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, cols, colcnt,
-				      len, is_trans,
+    binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
 				      static_cast<Delete_rows_log_event*>(0));
 
   if (unlikely(ev == 0))
diff -Nrup a/sql/sql_class.h b/sql/sql_class.h
--- a/sql/sql_class.h	2007-11-28 20:57:50 +01:00
+++ b/sql/sql_class.h	2007-12-18 18:26:46 +01:00
@@ -1145,13 +1145,10 @@ public:
   void binlog_set_stmt_begin();
   int binlog_write_table_map(TABLE *table, bool is_transactional);
   int binlog_write_row(TABLE* table, bool is_transactional,
-                       MY_BITMAP const* cols, size_t colcnt,
-                       const uchar *buf);
+                       const uchar *new_data);
   int binlog_delete_row(TABLE* table, bool is_transactional,
-                        MY_BITMAP const* cols, size_t colcnt,
-                        const uchar *buf);
+                        const uchar *old_data);
   int binlog_update_row(TABLE* table, bool is_transactional,
-                        MY_BITMAP const* cols, size_t colcnt,
                         const uchar *old_data, const uchar *new_data);
 
   void set_server_id(uint32 sid) { server_id = sid; }
@@ -1161,8 +1158,6 @@ public:
   */
   template <class RowsEventT> Rows_log_event*
     binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
-                                      MY_BITMAP const* cols,
-                                      size_t colcnt,
                                       size_t needed,
                                       bool is_transactional,
 				      RowsEventT* hint);
diff -Nrup a/sql/table.cc b/sql/table.cc
--- a/sql/table.cc	2007-11-28 20:57:51 +01:00
+++ b/sql/table.cc	2007-12-18 18:26:46 +01:00
@@ -4467,12 +4467,15 @@ void st_table::mark_columns_needed_for_d
     }
     file->column_bitmaps_signal();
   }
-  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE)
+  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE ||
+      mysql_bin_log.is_open() && in_use &&
+      in_use->current_stmt_binlog_row_based)
   {
     /*
-      If the handler has no cursor capabilites, we have to read either
-      the primary key, the hidden primary key or all columns to be
-      able to do an delete
+      If the handler has no cursor capabilites, or we have row-based
+      replication active for the current statement, we have to read
+      either the primary key, the hidden primary key or all columns to
+      be able to do an delete
     */
     if (s->primary_key == MAX_KEY)
       file->use_hidden_primary_key();
@@ -4520,10 +4523,13 @@ void st_table::mark_columns_needed_for_u
     }
     file->column_bitmaps_signal();
   }
-  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE)
+  if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE ||
+      mysql_bin_log.is_open() && in_use &&
+      in_use->current_stmt_binlog_row_based)
   {
     /*
-      If the handler has no cursor capabilites, we have to read either
+      If the handler has no cursor capabilites, or we have row-based
+      logging active for the current statement, we have to read either
       the primary key, the hidden primary key or all columns to be
       able to do an update
     */
Thread
bk commit into 6.0 tree (mats:1.2759) BUG#33055Mats Kindahl18 Dec
  • Re: bk commit into 6.0 tree (mats:1.2759) BUG#33055Andrei Elkin19 Dec
    • Re: bk commit into 6.0 tree (mats:1.2759) BUG#33055Mats Kindahl19 Dec