List:Commits« Previous MessageNext Message »
From:rsomla Date:August 24 2007 5:58pm
Subject:bk commit into 5.1 tree (rafal:1.2570) BUG#21842
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of rafal. When rafal 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-08-24 19:58:22+02:00, rafal@quant.(none) +6 -0
  BUG#21842: 
  
  This patch contains changes needed to support replication for a table
  which has extra columns on master as introduced by WL#3228 (before only
  extra slave-side columns were supported). It also contains some 
  improvements suggested by reviewers.

  sql/log_event.cc@stripped, 2007-08-24 19:58:17+02:00, rafal@quant.(none) +66 -54
    - Added initialization for Rows_log_event::m_table member.
    - Adapt code to changed signatures of row processing primitives.
    - Updated documentation.
    - Remove assertion in Update_rows_log_event::do_exec_row() which fails
      in case there are extra columns on master.

  sql/log_event.h@stripped, 2007-08-24 19:58:17+02:00, rafal@quant.(none) +20 -16
    - Rename find_and_fetch_row() -> find_row()
    - Remove THD* parameter from row processing primitives - there is a thd
      member in the class.
    - Add Slave_reporting_capability* argument to primitives which might need
      error reporting.

  sql/log_event_old.h@stripped, 2007-08-24 19:58:17+02:00, rafal@quant.(none) +1 -1
    Old_rows_log_event needs not to be virtual.

  sql/rpl_record.cc@stripped, 2007-08-24 19:58:17+02:00, rafal@quant.(none) +13 -1
    Updated documentation for prepare_record().
    
    In prepare_record() allow skip parameter to be bigger than number of 
    columns in the table. This happens in case of replication from master
    with extra columns.

  sql/rpl_utility.cc@stripped, 2007-08-24 19:58:18+02:00, rafal@quant.(none) +1 -1
    Make tabe_def::calc_field_size() a const method.

  sql/rpl_utility.h@stripped, 2007-08-24 19:58:18+02:00, rafal@quant.(none) +1 -1
    Make tabe_def::calc_field_size() a const method.

diff -Nrup a/sql/log_event.cc b/sql/log_event.cc
--- a/sql/log_event.cc	2007-08-24 15:05:47 +02:00
+++ b/sql/log_event.cc	2007-08-24 19:58:17 +02:00
@@ -5697,6 +5697,7 @@ Rows_log_event::Rows_log_event(const cha
                                *description_event)
   : Log_event(buf, description_event),
     m_row_count(0),
+    m_table(NULL),
     m_rows_buf(0), m_rows_cur(0), m_rows_end(0),
     m_curr_row(NULL), m_curr_row_end(NULL),
     m_key(NULL)
@@ -6123,7 +6124,7 @@ int Rows_log_event::do_apply_event(RELAY
 
     // Do event specific preparations 
     
-    error= do_before_row_operations(thd);
+    error= do_before_row_operations(rli);
 
     // row processing loop
 
@@ -6134,7 +6135,7 @@ int Rows_log_event::do_apply_event(RELAY
       if (!table->in_use)
         table->in_use= thd;
 
-      error= do_exec_row(thd,rli);
+      error= do_exec_row(rli);
 
       table->in_use = old_thd;
       switch (error)
@@ -6159,7 +6160,7 @@ int Rows_log_event::do_apply_event(RELAY
       /*
        If m_curr_row_end  was not set during event execution (e.g., because
        of errors) we can't proceed to the next row. If the error is transient
-       (i.e., error==0 at this point) we must call unpack_row() to set 
+       (i.e., error==0 at this point) we must call unpack_current_row() to set 
        m_curr_row_end.
       */ 
    
@@ -6177,7 +6178,7 @@ int Rows_log_event::do_apply_event(RELAY
 
     DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event",
                     const_cast<RELAY_LOG_INFO*>(rli)->abort_slave= 1;);
-    error= do_after_row_operations(thd, error);
+    error= do_after_row_operations(rli, error);
     if (!cache_stmt)
     {
       DBUG_PRINT("info", ("Marked that we need to keep log"));
@@ -6186,8 +6187,8 @@ int Rows_log_event::do_apply_event(RELAY
   } // if (table)
 
   /*
-    We need to delay this clear until the table def is no longer needed.
-    The table def is needed in unpack_row().
+    We need to delay this clear until the table def stored in m_table_def is no 
+    longer needed. It is used in unpack_current_row().
   */
   if (rli->tables_to_lock && get_flags(STMT_END_F))
     const_cast<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock();
@@ -7075,7 +7076,8 @@ Write_rows_log_event::Write_rows_log_eve
 #endif
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-int Write_rows_log_event::do_before_row_operations(THD *thd)
+int 
+Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
 {
   int error= 0;
 
@@ -7136,7 +7138,9 @@ int Write_rows_log_event::do_before_row_
   return error;
 }
 
-int Write_rows_log_event::do_after_row_operations(THD *thd, int error)
+int 
+Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const, 
+                                              int error)
 {
   int local_error= 0;
   m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
@@ -7194,13 +7198,13 @@ is_duplicate_key_error(int errcode)
 }
 
 /**
-  Write the current row into @c m_table.
+  Write the current row into event's table.
 
   The row is located in the row buffer, pointed by @c m_curr_row member.
-  Number of columns of the row is stored in @c m_width member (it can be smaller
-  than the number of columns in the table to which we insert). Bitmap @c m_cols
-  indicates which columns are present in the row. It is assumed that event's 
-  table is already open and pointed by @c m_table.
+  Number of columns of the row is stored in @c m_width member (it can be 
+  different from the number of columns in the table to which we insert). 
+  Bitmap @c m_cols indicates which columns are present in the row. It is assumed 
+  that event's table is already open and pointed by @c m_table.
 
   If the same record already exists in the table it can be either overwritten 
   or an error is reported depending on the value of @c overwrite flag 
@@ -7210,12 +7214,12 @@ is_duplicate_key_error(int errcode)
 
   The row to be inserted can contain values only for selected columns. The 
   missing columns are filled with default values using @c prepare_record() 
-  function. If a matching record is found in the table and overwritten, the 
-  missing columns are taken from it.
+  function. If a matching record is found in the table and @c overwritte is
+  true, the missing columns are taken from it.
 
-  @param  thd   Thread context for writing the record.
-  @param  log   Logger for error reporting.
-  @param  overwrite  Shall we overwrite if the row already exists or signal 
+  @param  rli   Relay log info (needed for row unpacking).
+  @param  overwrite  
+                Shall we overwrite if the row already exists or signal 
                 error (currently ignored).
 
   @returns Error code on failure, 0 on success.
@@ -7225,13 +7229,11 @@ is_duplicate_key_error(int errcode)
   inserted.
 
   @note If a matching record is found, it is either updated using 
-  @c ha_update_row() function or first deleted and then new record written.
-
+  @c ha_update_row() or first deleted and then new record written.
 */ 
 
 int
-Rows_log_event::write_row(THD *const thd, 
-                          const RELAY_LOG_INFO *const rli,
+Rows_log_event::write_row(const RELAY_LOG_INFO *const rli,
                           const bool overwrite)
 {
   DBUG_ENTER("write_row");
@@ -7243,7 +7245,7 @@ Rows_log_event::write_row(THD *const thd
 
   /* fill m_table->record[0] with default values */
 
-  if ((error= prepare_record(rli, m_table,m_width,
+  if ((error= prepare_record(rli, m_table, m_width,
                              TRUE /* check if columns have def. values */)))
     goto finish; 
   
@@ -7378,15 +7380,18 @@ Rows_log_event::write_row(THD *const thd
       DBUG_PRINT("info",("Updating row using ha_update_row()"));
       error= m_table->file->ha_update_row(m_table->record[1],
                                           m_table->record[0]);
-      if (error == HA_ERR_RECORD_IS_THE_SAME)
-      {
-        DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME ret. value from"
+                                            
+      switch (error) {
+                
+      case HA_ERR_RECORD_IS_THE_SAME:
+        DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
                            " ha_update_row()"));
         error= 0;
-      }
+      
+      case 0:
+        break;
         
-      if (error)
-      {
+      default:    
         DBUG_PRINT("info",("ha_update_row() returns error %d",error));
         goto handler_error;
       }
@@ -7425,11 +7430,11 @@ Rows_log_event::write_row(THD *const thd
 
 #endif
 
-int Write_rows_log_event::do_exec_row(THD *thd, 
-                                      const RELAY_LOG_INFO *const rli)
+int 
+Write_rows_log_event::do_exec_row(const RELAY_LOG_INFO *const rli)
 {
   DBUG_ASSERT(m_table != NULL);
-  int error= write_row(thd, rli, TRUE /* overwrite */);
+  int error= write_row(rli, TRUE /* overwrite */);
   
   if (error && !thd->net.last_errno)
     thd->net.last_errno= error;
@@ -7530,12 +7535,12 @@ record_compare_exit:
 }
 
 /**
-  Locate the current row in @c m_table.
+  Locate the current row in event's table.
 
-  The current row is stored in event's row buffer, pointed by @c m_curr_row 
-  member. Member @c m_width tells how many columns are there in the row (this 
-  number can be smaller than the number of columns in the table). It is assumed 
-  that event's table is already open and pointed by @c m_table.
+  The current row is pointed by @c m_curr_row. Member @c m_width tells how many 
+  columns are there in the row (this can be differnet from the number of columns 
+  in the table). It is assumed that event's table is already open and pointed 
+  by @c m_table.
 
   If a corresponding record is found in the table it is stored in 
   @c m_table->record[0]. Note that when record is located based on a primary 
@@ -7544,17 +7549,19 @@ record_compare_exit:
   If no key is specified or table does not have keys, a table scan is used to 
   find the row. In that case the row should be complete and contain values for
   all columns. However, it can still be shorter than the table, i.e. the table 
-  can contain extra columns not present in the row. 
+  can contain extra columns not present in the row. It is also possible that 
+  the table has fewer columns than the row being located. 
 
-  @returns Error code on failure, 0 on success. If success @c m_table->record[0] 
-  contains the record found. Also, the internal "cursor" of the table is 
-  positioned at the record found.
+  @returns Error code on failure, 0 on success. 
+  
+  @post In case of success @c m_table->record[0] contains the record found. 
+  Also, the internal "cursor" of the table is positioned at the record found.
 
   @note If the engine allows random access of the records, a combination of
   @c position() and @c rnd_pos() will be used. 
  */
 
-int Rows_log_event::find_and_fetch_row(const RELAY_LOG_INFO *const rli)
+int Rows_log_event::find_row(const RELAY_LOG_INFO *rli)
 {
   DBUG_ENTER("find_and_fetch_row");
 
@@ -7564,7 +7571,8 @@ int Rows_log_event::find_and_fetch_row(c
 
   /* unpack row - missing fields get default values */
 
-  prepare_record(NULL,m_table,m_width,FALSE /* don't check errors */); // TODO: shall we check and report errors here?
+  // TODO: shall we check and report errors here?
+  prepare_record(NULL,m_table,m_width,FALSE /* don't check errors */); 
   error= unpack_current_row(rli); 
 
 #ifndef DBUG_OFF
@@ -7863,7 +7871,8 @@ Delete_rows_log_event::Delete_rows_log_e
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
-int Delete_rows_log_event::do_before_row_operations(THD *thd)
+int 
+Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
 {
   if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
       m_table->s->primary_key < MAX_KEY)
@@ -7885,7 +7894,9 @@ int Delete_rows_log_event::do_before_row
   return 0;
 }
 
-int Delete_rows_log_event::do_after_row_operations(THD *thd, int error)
+int 
+Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const, 
+                                               int error)
 {
   /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
   m_table->file->ha_index_or_rnd_end();
@@ -7895,13 +7906,12 @@ int Delete_rows_log_event::do_after_row_
   return error;
 }
 
-int Delete_rows_log_event::do_exec_row(THD *thd,
-                                       const RELAY_LOG_INFO *const rli)
+int Delete_rows_log_event::do_exec_row(const RELAY_LOG_INFO *const rli)
 {
   int error;
   DBUG_ASSERT(m_table != NULL);
 
-  if (!(error= find_and_fetch_row(rli))) 
+  if (!(error= find_row(rli))) 
   { 
     /*
       Delete the record found, located in record[0]
@@ -7991,7 +8001,8 @@ Update_rows_log_event::Update_rows_log_e
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
-int Update_rows_log_event::do_before_row_operations(THD *thd)
+int 
+Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
 {
   if (m_table->s->keys > 0)
   {
@@ -8006,7 +8017,9 @@ int Update_rows_log_event::do_before_row
   return 0;
 }
 
-int Update_rows_log_event::do_after_row_operations(THD *thd, int error)
+int 
+Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const, 
+                                               int error)
 {
   /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
   m_table->file->ha_index_or_rnd_end();
@@ -8016,13 +8029,12 @@ int Update_rows_log_event::do_after_row_
   return error;
 }
 
-int Update_rows_log_event::do_exec_row(THD *thd,
-                                       const RELAY_LOG_INFO *const rli)
+int 
+Update_rows_log_event::do_exec_row(const RELAY_LOG_INFO *const rli)
 {
   DBUG_ASSERT(m_table != NULL);
-  DBUG_ASSERT(m_table->s->fields >= m_width);
 
-  int error= find_and_fetch_row(rli); 
+  int error= find_row(rli); 
   if (error)
     return error;
 
diff -Nrup a/sql/log_event.h b/sql/log_event.h
--- a/sql/log_event.h	2007-08-24 15:05:48 +02:00
+++ b/sql/log_event.h	2007-08-24 19:58:17 +02:00
@@ -2186,7 +2186,7 @@ public:
     /* Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */
     RELAXED_UNIQUE_CHECKS_F = (1U << 2),
 
-    /* 
+    /** 
       Indicates that rows in this event are complete, that is contain
       values for all columns of the table.
      */
@@ -2303,12 +2303,13 @@ protected:
   /* helper functions */
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-  int find_and_fetch_row(const RELAY_LOG_INFO *const);
-  int write_row(THD *const, const RELAY_LOG_INFO *const, const bool);
+  int find_row(const RELAY_LOG_INFO *const);
+  int write_row(const RELAY_LOG_INFO *const, const bool);
 
   // Unpack the current row into m_table->record[0]
-  int unpack_current_row(RELAY_LOG_INFO const *rli)
+  int unpack_current_row(const RELAY_LOG_INFO *const rli)
   { 
+    DBUG_ASSERT(m_table);
     return ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols, 
                         &m_curr_row_end, &m_master_reclength);
   }
@@ -2337,7 +2338,8 @@ private:
       The member function will return 0 if all went OK, or a non-zero
       error code otherwise.
   */
-  virtual int do_before_row_operations(THD*) = 0;
+  virtual 
+  int do_before_row_operations(const Slave_reporting_capability *const log) = 0;
 
   /*
     Primitive to clean up after a sequence of row executions.
@@ -2352,7 +2354,9 @@ private:
       row processing before this function was called. In this case, even if 
       function is successful, it should return the error code given in the argument.
   */
-  virtual int do_after_row_operations(THD*,int error) = 0;
+  virtual 
+  int do_after_row_operations(const Slave_reporting_capability *const log,
+                              int error) = 0;
 
   /*
     Primitive to do the actual execution necessary for a row.
@@ -2367,7 +2371,7 @@ private:
       0 if execution succeeded, 1 if execution failed.
       
   */
-  virtual int do_exec_row(THD*, const RELAY_LOG_INFO *const) = 0;
+  virtual int do_exec_row(const RELAY_LOG_INFO *const rli) = 0;
 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
   friend class Old_rows_log_event;
@@ -2421,9 +2425,9 @@ private:
 #endif
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-  virtual int do_before_row_operations(THD*);
-  virtual int do_after_row_operations(THD*,int);
-  virtual int do_exec_row(THD*,const RELAY_LOG_INFO *const);
+  virtual int do_before_row_operations(const Slave_reporting_capability *const);
+  virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
+  virtual int do_exec_row(const RELAY_LOG_INFO *const);
 #endif
 };
 
@@ -2495,9 +2499,9 @@ protected:
 #endif
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-  virtual int do_before_row_operations(THD*);
-  virtual int do_after_row_operations(THD*,int);
-  virtual int do_exec_row(THD*,const RELAY_LOG_INFO *const);
+  virtual int do_before_row_operations(const Slave_reporting_capability *const);
+  virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
+  virtual int do_exec_row(const RELAY_LOG_INFO *const);
 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 };
 
@@ -2560,9 +2564,9 @@ protected:
 #endif
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-  virtual int do_before_row_operations(THD*);
-  virtual int do_after_row_operations(THD*,int);
-  virtual int do_exec_row(THD*,const RELAY_LOG_INFO *const);
+  virtual int do_before_row_operations(const Slave_reporting_capability *const);
+  virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
+  virtual int do_exec_row(const RELAY_LOG_INFO *const);
 #endif
 };
 
diff -Nrup a/sql/log_event_old.h b/sql/log_event_old.h
--- a/sql/log_event_old.h	2007-08-24 15:05:48 +02:00
+++ b/sql/log_event_old.h	2007-08-24 19:58:17 +02:00
@@ -31,7 +31,7 @@ class Old_rows_log_event
   
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
-  virtual int do_apply_event(Rows_log_event*,const RELAY_LOG_INFO*);
+  int do_apply_event(Rows_log_event*,const RELAY_LOG_INFO*);
 
   /*
     Primitive to prepare for a sequence of row executions.
diff -Nrup a/sql/rpl_record.cc b/sql/rpl_record.cc
--- a/sql/rpl_record.cc	2007-08-24 15:05:48 +02:00
+++ b/sql/rpl_record.cc	2007-08-24 19:58:17 +02:00
@@ -302,7 +302,7 @@ unpack_row(RELAY_LOG_INFO const *rli,
 }
 
 /**
-  Fills table->record[0] with default values.
+  Fills @c table->record[0] with default values.
 
   First @c empty_record() is called and then, additionally, fields are
   initialized explicitly with a call to @c set_default().
@@ -313,6 +313,15 @@ unpack_row(RELAY_LOG_INFO const *rli,
 
   If @c check is true, fields are explicitly initialized only if they have
   default value or can be NULL. Otherwise error is reported.
+ 
+  @param log    Used to report errors.
+  @param table  Table whose record[0] buffer is prepared. 
+  @param skip   Number of columns for which default value initialization 
+                should be skipped.
+  @param check  Indicates if errors should be checked when setting default
+                values.
+                
+  @returns 0 on success. 
  */ 
 int prepare_record(const Slave_reporting_capability *const log, 
                    TABLE *const table, 
@@ -322,6 +331,9 @@ int prepare_record(const Slave_reporting
 
   int error= 0;
   empty_record(table);
+
+  if (skip >= table->s->fields)  // nothing to do
+    DBUG_RETURN(0);
 
   /* Explicit initialization of fields */
 
diff -Nrup a/sql/rpl_utility.cc b/sql/rpl_utility.cc
--- a/sql/rpl_utility.cc	2007-08-03 17:11:37 +02:00
+++ b/sql/rpl_utility.cc	2007-08-24 19:58:18 +02:00
@@ -24,7 +24,7 @@
   This function returns the field size in raw bytes based on the type
   and the encoded field data from the master's raw data.
 */
-uint32 table_def::calc_field_size(uint col, uchar *master_data)
+uint32 table_def::calc_field_size(uint col, uchar *master_data) const
 {
   uint32 length;
 
diff -Nrup a/sql/rpl_utility.h b/sql/rpl_utility.h
--- a/sql/rpl_utility.h	2007-08-24 15:05:48 +02:00
+++ b/sql/rpl_utility.h	2007-08-24 19:58:18 +02:00
@@ -218,7 +218,7 @@ public:
     WL#3915) or needs to advance the pointer for the fields in the raw 
     data from the master to a specific column.
   */
-  uint32 calc_field_size(uint col, uchar *master_data);
+  uint32 calc_field_size(uint col, uchar *master_data) const;
 
   /**
     Decide if the table definition is compatible with a table.
Thread
bk commit into 5.1 tree (rafal:1.2570) BUG#21842rsomla24 Aug