List:Internals« Previous MessageNext Message »
From:guilhem Date:August 2 2005 8:06pm
Subject:bk commit into 5.0 tree (guilhem:1.1893)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of guilhem. When guilhem 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
  1.1893 05/08/02 22:06:35 guilhem@stripped +22 -0
  Bunch of changes to row-based replication WL#1012, following the comments I made during first review.
  The present changes are not supposed to change functionality, just style fixes, compilation fixes, test fixes, comments.
  The only user-visible change is that SHOW VARIABLES LIKE 'binlog_format' now returns uppercase,
  and mysqld aborts if --binlog-format without --log-bin.

  mysql-test/t/rpl_row_001-master.opt
    1.1 05/08/02 22:06:24 guilhem@stripped +1 -0
    New BitKeeper file ``mysql-test/t/rpl_row_001-master.opt''

  sql/sql_delete.cc
    1.156 05/08/02 22:06:24 guilhem@stripped +4 -0
    comment to explain TRUNCATE vs row-based binlogging

  sql/sql_class.h
    1.253 05/08/02 22:06:24 guilhem@stripped +43 -38
    name changes in THD:: methods related to binlog. size_t->my_size_t, int->bool.

  sql/sql_class.cc
    1.197 05/08/02 22:06:24 guilhem@stripped +84 -135
    Comments. Lengthening names of THD:: methods related to binlog. size_t -> my_size_t. likely().

  sql/slave.cc
    1.254 05/08/02 22:06:24 guilhem@stripped +28 -9
    comments. Replacement for bsearch() if not available.

  sql/rpl_tblmap.cc
    1.2 05/08/02 22:06:24 guilhem@stripped +12 -16
    style, comments

  sql/mysqld.cc
    1.488 05/08/02 22:06:24 guilhem@stripped +68 -41
    "statement"->"STATEMENT". Refuse --binlog-format if no --log-bin. Changes to the description of row-based binlogging options.

  sql/mysql_priv.h
    1.336 05/08/02 22:06:24 guilhem@stripped +2 -2
    fixing typo in variable name

  mysql-test/t/rpl_row_001-master.opt
    1.0 05/08/02 22:06:24 guilhem@stripped +0 -0
    BitKeeper file /home/mysql_src/mysql-5.0-wl1012/mysql-test/t/rpl_row_001-master.opt

  sql/log_event.h
    1.115 05/08/02 22:06:23 guilhem@stripped +7 -10
    style fixes. Conditional definitions (HAVE_REPLICATION means "include slave code"). size_t -> my_size_t. Removing unused members and empty destructor.

  sql/log_event.cc
    1.187 05/08/02 22:06:23 guilhem@stripped +155 -201
    style (class name and method on same line, <> instead of "" for include/). Removing some zeroing specific
    of debug builds. Comments. Changing find_tables() to use a pointer as the comment said. Adding and removing assertions.
    Removig unused class member. Indentation. HAVE_REPLICATION fix to enable compilation of libmysqld.
    Removing dummy functions by making their definition conditional in log_event.h.

  sql/handler.h
    1.148 05/08/02 22:06:23 guilhem@stripped +9 -9
    comments, style, removing unused member

  sql/handler.cc
    1.184 05/08/02 22:06:23 guilhem@stripped +69 -93
    Comments. Style (declarations on one line if possible). Some likely(). Less DBUG_.

  mysys/my_vle.c
    1.2 05/08/02 22:06:23 guilhem@stripped +12 -2
    unneeded includes. Comments on return values of VLE functions.

  mysql-test/t/rpl_row_basic_3innodb-master.opt
    1.2 05/08/02 22:06:23 guilhem@stripped +1 -1
    missing row format

  mysql-test/t/date_formats.test
    1.14 05/08/02 22:06:23 guilhem@stripped +3 -3
    case change

  mysql-test/r/have_binlog_format_statement.require
    1.2 05/08/02 22:06:23 guilhem@stripped +1 -1
    case change

  mysql-test/r/have_binlog_format_row.require
    1.2 05/08/02 22:06:23 guilhem@stripped +1 -1
    case change

  libmysql/Makefile.shared
    1.66 05/08/02 22:06:23 guilhem@stripped +0 -2
    no need to add VLE to libmysql, it's not used by libmysql. Added it to mysqlbinlog only, instead

  include/my_vle.h
    1.2 05/08/02 22:06:23 guilhem@stripped +0 -3
    unneeded includes

  configure.in
    1.327 05/08/02 22:06:23 guilhem@stripped +2 -1
    check for bsearch() on the platform

  client/Makefile.am
    1.50 05/08/02 22:06:23 guilhem@stripped +5 -1
    adding VLE and bitmap to only mysqlbinlog (removed it from libmysql)

  BitKeeper/etc/config
    1.17 05/08/02 22:06:23 guilhem@stripped +1 -0
    speedup "bk citool" infinitely for only me - should not affect others.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	guilhem
# Host:	gbichot3.local
# Root:	/home/mysql_src/mysql-5.0-wl1012

--- 1.49/client/Makefile.am	2005-07-05 23:48:39 +02:00
+++ 1.50/client/Makefile.am	2005-08-02 22:06:23 +02:00
@@ -38,7 +38,11 @@
 mysqltest_SOURCES=              mysqltest.c $(top_srcdir)/mysys/my_getsystime.c \
                                 $(yassl_dummy_link_fix)
 mysqltest_LDADD =		$(top_builddir)/regex/libregex.a $(LDADD)
-mysqlbinlog_SOURCES =   mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c $(top_srcdir)/mysys/my_new.cc
+mysqlbinlog_SOURCES =		mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c \
+				$(top_srcdir)/mysys/my_new.cc \
+				$(top_srcdir)/mysys/my_bit.c \
+				$(top_srcdir)/mysys/my_bitmap.c \
+				$(top_srcdir)/mysys/my_vle.c
 mysqlbinlog_LDADD =		$(LDADD) $(CXXLDFLAGS)
 mysqltestmanager_pwgen_SOURCES =   mysqlmanager-pwgen.c 
 mysqltestmanagerc_SOURCES=      mysqlmanagerc.c $(yassl_dummy_link_fix)

--- 1.326/configure.in	2005-07-28 20:24:54 +02:00
+++ 1.327/configure.in	2005-08-02 22:06:23 +02:00
@@ -1897,7 +1897,8 @@
 AC_FUNC_UTIME_NULL
 AC_FUNC_VPRINTF
 
-AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \
+AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \
+  chsize cuserid fchmod fcntl \
   fconvert fdatasync finite fpresetsticky fpsetmask fsync ftruncate \
   getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \
   getpwuid getrlimit getrusage getwd gmtime_r index initgroups isnan \

--- 1.183/sql/handler.cc	2005-07-28 20:24:54 +02:00
+++ 1.184/sql/handler.cc	2005-08-02 22:06:23 +02:00
@@ -622,7 +622,7 @@
     DBUG_RETURN(2);
   }
 #ifdef USING_TRANSACTIONS
-  thd->prepare_for_commit(all);
+  thd->prepare_for_commit(all); // TODO! catch the return code
   if (trans->nht)
   {
     if (is_real_trans && wait_if_global_read_lock(thd, 0, 0))
@@ -2480,18 +2480,20 @@
 }
 
 /*
-  Function to check if the conditions for replication row-based is
+  Function to check if the conditions for row-based binlogging is
   correct for the table. 
 
   A row in the given table should be replicated if:
   - Row-based replication is on
   - It is not a temporary table
-  - The database the table is in shall be replicated
+  - The table shall be replicated
+  - TODO: sort out why "mysql" is checked below; we want to be able to
+  replicate CREATE PROCEDURE row-based (because it uses info which depends
+  on user's context).
 */
   
 #ifdef HAVE_ROW_BASED
-static bool 
-check_table_replication_row_based(TABLE *table) 
+static bool check_table_binlog_row_based(TABLE *table) 
 {
   return
     opt_binlog_row_based_logging &&
@@ -2506,115 +2508,89 @@
 ha_write_row(byte *buf) 
 {
   int error;
-  DBUG_ENTER("handler::ha_write_row");
-  DBUG_PRINT("enter", ("table=%p (%s), row=%p", 
-		       table, table->s->table_name, buf));
-
-  if ((error= write_row(buf)))
+  if (likely(!(error= write_row(buf))))
   {
-    DBUG_PRINT("exit", ("error=%d", error));
-    DBUG_RETURN(error);
-  }
 #ifdef HAVE_ROW_BASED
-#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-  if (check_table_replication_row_based(table)) 
-  {
-    MY_BITMAP cols;
-    /* Potential buffer on the stack for the bitmap */
-    uchar bitbuf[BITMAP_STACKBUF_SIZE];
-    uint n_fields= table->s->fields;
-    my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
-    bitmap_init(&cols,
-                use_bitbuf ? bitbuf : NULL, 
-                (n_fields + 7) & ~7UL, 
-                false);
-    bitmap_set_all(&cols);
-    current_thd->write_row(table, table->file->has_transactions(), 
-                           &cols, table->s->fields, buf);
-    if (!use_bitbuf)
-      bitmap_free(&cols);
-  }
-#endif
+    if (check_table_binlog_row_based(table)) 
+    {
+      MY_BITMAP cols;
+      /* Potential buffer on the stack for the bitmap */
+      uchar bitbuf[BITMAP_STACKBUF_SIZE];
+      uint n_fields= table->s->fields;
+      my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
+      bitmap_init(&cols,
+                  use_bitbuf ? bitbuf : NULL, 
+                  (n_fields + 7) & ~7UL, 
+                  false);
+      bitmap_set_all(&cols);
+      /* TODO: catch return code below */
+      current_thd->binlog_write_row(table, table->file->has_transactions(), 
+                                    &cols, table->s->fields, buf);
+      if (!use_bitbuf)
+        bitmap_free(&cols);
+    }
 #endif
-  DBUG_PRINT("exit", ("error=%d", 0));
-  DBUG_RETURN(0);
+  }
+  return error;
 }
   
 int handler::
 ha_update_row(const byte *old_data, byte *new_data) 
 {
-  DBUG_ENTER("handler::ha_update_row");
-  DBUG_PRINT("enter", ("table=%p (%s), before: %p; after: %p", 
-		       table, table->s->table_name, old_data, new_data));
-
   int error;
-  if ((error= update_row(old_data, new_data)))
+  if (likely(!(error= update_row(old_data, new_data))))
   {
-    DBUG_PRINT("error", ("error=%d", error));
-    DBUG_RETURN(error);
-  }
 #ifdef HAVE_ROW_BASED
-#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-  if (check_table_replication_row_based(table)) 
-  {
-    MY_BITMAP cols;
-    /* Potential buffer on the stack for the bitmap */
-    uchar bitbuf[BITMAP_STACKBUF_SIZE];
-    uint n_fields= table->s->fields;
-    my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
-    bitmap_init(&cols, 
-                use_bitbuf ? bitbuf : NULL, 
-                (n_fields + 7) & ~7UL, 
-                false);
-    bitmap_set_all(&cols);
-    current_thd->update_row(table, table->file->has_transactions(), 
-                            &cols, table->s->fields,
-                            old_data, new_data);
-    if (!use_bitbuf)
-      bitmap_free(&cols);
-  }
-#endif
+    if (check_table_binlog_row_based(table)) 
+    {
+      MY_BITMAP cols;
+      /* Potential buffer on the stack for the bitmap */
+      uchar bitbuf[BITMAP_STACKBUF_SIZE];
+      uint n_fields= table->s->fields;
+      my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
+      bitmap_init(&cols, 
+                  use_bitbuf ? bitbuf : NULL, 
+                  (n_fields + 7) & ~7UL, 
+                  false);
+      bitmap_set_all(&cols);
+      current_thd->binlog_update_row(table, table->file->has_transactions(), 
+                                     &cols, table->s->fields,
+                                     old_data, new_data);
+      if (!use_bitbuf)
+        bitmap_free(&cols);
+    }
 #endif /* HAVE_ROW_BASED */
-  DBUG_PRINT("return", ("error=%d", 0));
-  DBUG_RETURN(0);
+  }
+  return error;
 }
   
 int handler::
 ha_delete_row(const byte *buf) 
 {
-  DBUG_ENTER("handler::ha_delete_row");
-  DBUG_PRINT("enter", ("table=%p (%s), row=%p", 
-		       table, table->s->table_name, buf));
-
   int error;
-  if ((error= delete_row(buf)))
+  if (likely(!(error= delete_row(buf))))
   {
-    DBUG_PRINT("exit", ("error=%d", error));
-    DBUG_RETURN(error);
-  }
 #ifdef HAVE_ROW_BASED
-#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-  if (check_table_replication_row_based(table)) 
-  {
-    MY_BITMAP cols;
-    /* Potential buffer on the stack for the bitmap */
-    uchar bitbuf[BITMAP_STACKBUF_SIZE];
-    uint n_fields= table->s->fields;
-    my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
-    bitmap_init(&cols, 
-                use_bitbuf ? bitbuf : NULL, 
-                (n_fields + 7) & ~7UL, 
-                false);
-    bitmap_set_all(&cols);
-    current_thd->delete_row(table, table->file->has_transactions(),
-                            &cols, table->s->fields, buf);
-    if (!use_bitbuf)
-      bitmap_free(&cols);
-  }
-#endif
+    if (check_table_binlog_row_based(table)) 
+    {
+      MY_BITMAP cols;
+      /* Potential buffer on the stack for the bitmap */
+      uchar bitbuf[BITMAP_STACKBUF_SIZE];
+      uint n_fields= table->s->fields;
+      my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
+      bitmap_init(&cols, 
+                  use_bitbuf ? bitbuf : NULL, 
+                  (n_fields + 7) & ~7UL, 
+                  false);
+      bitmap_set_all(&cols);
+      current_thd->binlog_delete_row(table, table->file->has_transactions(),
+                                     &cols, table->s->fields, buf);
+      if (!use_bitbuf)
+        bitmap_free(&cols);
+    }
 #endif /* HAVE_ROW_BASED */
-  DBUG_PRINT("exit", ("error=%d", 0));
-  DBUG_RETURN(0);
+  }
+  return error;
 }    
 
 

--- 1.147/sql/handler.h	2005-07-25 12:48:02 +02:00
+++ 1.148/sql/handler.h	2005-08-02 22:06:23 +02:00
@@ -76,10 +76,11 @@
 */
 #define HA_CAN_INSERT_DELAYED  (1 << 14)
 #define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
-/* 
-   The position of an arbitrary record can be retrieved using position() when
-   the table has a primary key, effectively allowing random access on the
-   table based on a given record.
+/*
+  If HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS is set, it means that the engine can
+  do this: the position of an arbitrary record can be retrieved using
+  position() when the table has a primary key, effectively allowing random
+  access on the table based on a given record.
 */ 
 #define HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS (1 << 16) 
 #define HA_NOT_DELETE_WITH_CACHE (1 << 18)
@@ -512,7 +513,7 @@
     key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
     ref_length(sizeof(my_off_t)), block_size(0),
     raid_type(0), ft_handler(0), inited(NONE), implicit_emptied(0),
-    pushed_cond(NULL), repl_flags(rplf)
+    pushed_cond(NULL)
     {}
   virtual ~handler(void) { /* TODO: DBUG_ASSERT(inited == NONE); */ }
   int ha_open(const char *name, int mode, int test_if_locked);
@@ -807,7 +808,6 @@
  virtual void cond_pop() { return; };
 
 private:
-  ulong repl_flags;
 
   /*
     Row-level primitives for storage engines. 
@@ -816,17 +816,17 @@
   */
   friend int ndb_add_binlog_index(THD *, void *);
 
-  virtual int write_row(byte * buf) 
+  virtual int write_row(byte *buf) 
   { 
     return HA_ERR_WRONG_COMMAND; 
   }
 
-  virtual int update_row(const byte * old_data, byte * new_data)
+  virtual int update_row(const byte *old_data, byte *new_data)
   { 
     return HA_ERR_WRONG_COMMAND; 
   }
 
-  virtual int delete_row(const byte * buf)
+  virtual int delete_row(const byte *buf)
   { 
     return HA_ERR_WRONG_COMMAND; 
   }

--- 1.186/sql/log_event.cc	2005-07-28 20:24:54 +02:00
+++ 1.187/sql/log_event.cc	2005-08-02 22:06:23 +02:00
@@ -21,14 +21,14 @@
 #pragma implementation				// gcc: Class implementation
 #endif
 
-#include  "mysql_priv.h"
+#include "mysql_priv.h"
 #include "slave.h"
 #include "rpl_filter.h"
 #include <my_dir.h>
 #endif /* MYSQL_CLIENT */
 
-#include "my_bitmap.h"
-#include "my_vle.h"
+#include <my_bitmap.h>
+#include <my_vle.h>
 
 #define log_cs	&my_charset_latin1
 
@@ -239,6 +239,7 @@
   commands just before it prints a query.
 */
 
+#ifdef MYSQL_CLIENT
 static void print_set_option(FILE* file, uint32 bits_changed, uint32 option,
                              uint32 flags, const char* name, bool* need_comma) 
 {
@@ -250,6 +251,7 @@
     *need_comma= 1;
   }
 }
+#endif
 
 /**************************************************************************
 	Log_event methods (= the parent class of all events)
@@ -4861,16 +4863,13 @@
 
 #ifdef HAVE_ROW_BASED
 
-extern unsigned long opt_binlog_rows_event_max_size;
-
 /**************************************************************************
 	Rows_log_event member functions
 **************************************************************************/
 
 #ifndef MYSQL_CLIENT
-Rows_log_event::
-Rows_log_event(THD* thd_arg, TABLE* tbl_arg, ulong tid, 
-	       MY_BITMAP const* cols, bool is_transactional)
+Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid, 
+                               MY_BITMAP const *cols, bool is_transactional)
   : Log_event(thd_arg, 0, is_transactional),
     m_dbnam(tbl_arg->s->db), m_dblen(m_dbnam ? strlen(m_dbnam) : 0),
     m_table(tbl_arg), 
@@ -4882,8 +4881,7 @@
     m_rows_buf(my_malloc(opt_binlog_rows_event_max_size * sizeof(*m_rows_buf), MYF(MY_WME))),
     m_rows_cur(m_rows_buf),
     m_rows_end(m_rows_buf + opt_binlog_rows_event_max_size),
-    m_flags(0),
-    m_is_transactional(is_transactional)
+    m_flags(0)
 {
   DBUG_ENTER("Rows_log_event::Rows_log_event(THD*, ...)");
   DBUG_PRINT("enter", ("cols->bitmap_size=%u", cols->bitmap_size));
@@ -4902,9 +4900,10 @@
 }
 #endif
 
-Rows_log_event::
-Rows_log_event(const char* buf, uint event_len, Log_event_type event_type,
-	       const Format_description_log_event *description_event)
+Rows_log_event::Rows_log_event(const char *buf, uint event_len,
+                               Log_event_type event_type,
+                               const Format_description_log_event
+                               *description_event)
   : Log_event(buf, description_event),
     m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
 {
@@ -4925,7 +4924,9 @@
   byte const* const var_begin= post_begin + ROWS_HEADER_LEN;
 
   byte const* const ptr_width= var_begin;
-  my_size_t len= my_vle_decode(&m_width, ptr_width);
+
+  my_size_t decode_len= my_vle_decode(&m_width, ptr_width);
+  DBUG_ASSERT(decode_len < sizeof(m_width));
 
   const uint byte_count= (m_width + 7) / 8;
   const char* const ptr_rows_data= var_begin + byte_count + 1;
@@ -4948,26 +4949,20 @@
     memcpy(m_rows_buf, ptr_rows_data, data_size);
     DBUG_PRINT("info",("m_rows_buf=%p, m_rows_cur=%p, m_rows_end=%p", 
 		       m_rows_buf, m_rows_cur, m_rows_end));
-    DBUG_DUMP("rows_data", m_rows_buf, data_size);
   }
 
   DBUG_VOID_RETURN;
 }
 
-Rows_log_event::
-~Rows_log_event()
+Rows_log_event::~Rows_log_event()
 {
   my_free(m_rows_buf, MYF(MY_ALLOW_ZERO_PTR));
-#ifndef DBUG_OFF
-  m_rows_buf= m_rows_cur= m_rows_end= NULL;
-  m_dbnam= m_tblnam= NULL;
-#endif
 }
 
-void Rows_log_event::
-do_add_row_data(byte *const row_data, my_size_t const length)
+void Rows_log_event::do_add_row_data(byte *const row_data,
+                                     my_size_t const length)
 {
-  DBUG_ENTER("Rows_log_event::do_add_row_data(byte* data, my_size_t length)");
+  DBUG_ENTER("Rows_log_event::do_add_row_data(byte *data, my_size_t length)");
   DBUG_PRINT("enter", ("row_data= %p, length= %lu", row_data, length));
   DBUG_ASSERT(m_rows_buf <= m_rows_cur);
   DBUG_ASSERT(m_rows_buf <  m_rows_end);
@@ -5010,12 +5005,11 @@
   for which the bitset represented by 'arr' and 'bits'; the other parts of the
   record are left alone.
  */
-static char const* 
-unpack_row(THD* thd, TABLE* table, 
-	   char* record, char const* row, 
-	   MY_BITMAP const* cols)
+static char const *unpack_row(THD *thd, TABLE *table, 
+                              char *record, char const *row, 
+                              MY_BITMAP const *cols)
 {
-  DBUG_ENTER("unpack_row(char* record, char const* row, TABLE* table)");
+  DBUG_ENTER("unpack_row(char *record, char const *row, TABLE *table)");
   DBUG_PRINT("enter", ("record= %p, row= %p, table= %p (%s)", 
 		       record, row, table, table->s->table_name));
   DBUG_ASSERT(record && row);
@@ -5044,14 +5038,13 @@
   DBUG_RETURN(ptr);
 }
 
-int Rows_log_event::
-exec_event(st_relay_log_info* rli)
+int Rows_log_event::exec_event(st_relay_log_info *rli)
 {
   DBUG_ENTER("Rows_log_event::exec_event(st_relay_log_info*)");
   int error= 0;
   TABLE* const table= rli->m_table_map.get_table(m_table_id);
   THD* const thd= current_thd;
-  char const* row_start= m_rows_buf;
+  char const *row_start= m_rows_buf;
 
   if (table) 
   {	      
@@ -5091,10 +5084,12 @@
         thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
     else
         thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
+    /* A small test to verify that objects have consistent types */
+    DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
 
     error= do_before_row_operations(table);
     while (error == 0 && row_start < m_rows_end) {
-      char const* row_end= do_prepare_row(thd, table, row_start);
+      char const *row_end= do_prepare_row(thd, table, row_start);
       DBUG_ASSERT(row_end != NULL);
       DBUG_ASSERT(row_end <= m_rows_end);
 
@@ -5204,8 +5199,7 @@
 #endif /* HAVE_REPLICATION */
 #endif /* MYSQL_CLIENT */
 
-bool Rows_log_event::
-write_data_header(IO_CACHE* file)
+bool Rows_log_event::write_data_header(IO_CACHE *file)
 {
   byte buf[ROWS_HEADER_LEN];	// No need to init the buffer
   DBUG_ENTER("Rows_log_event::write_data_header(IO_CACHE*)");
@@ -5215,8 +5209,7 @@
   DBUG_RETURN(result);
 }
 
-bool Rows_log_event::
-write_data_body(IO_CACHE* file)
+bool Rows_log_event::write_data_body(IO_CACHE*file)
 {
   DBUG_ENTER("Rows_log_event::write_data_body(IO_CACHE*)");
   /* 
@@ -5224,14 +5217,11 @@
      bytes.
   */
   byte sbuf[my_vle_sizeof(m_width)] = { 0 }; 
-  my_size_t sbuf_len= my_vle_encode(sbuf, sizeof(sbuf), m_width);
   my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
 
+  my_size_t sbuf_len= my_vle_encode(sbuf, sizeof(sbuf), m_width);
   DBUG_ASSERT(sbuf_len <= sizeof(sbuf));
 
-  DBUG_DUMP("sbuf", sbuf, sbuf_len);
-  DBUG_DUMP("rows_data", m_rows_buf, data_size);
-
   DBUG_RETURN(my_b_safe_write(file, sbuf, sbuf_len) || 
               my_b_safe_write(file, reinterpret_cast<byte*>(m_cols.bitmap),
 			      byte_count(&m_cols)) || 
@@ -5239,9 +5229,8 @@
 }
 
 #if defined(MYSQL_CLIENT)
-void Rows_log_event::
-print(FILE* file, bool short_form,
-      LAST_EVENT_INFO* last_event_info)
+void Rows_log_event::print(FILE *file, bool short_form,
+                           LAST_EVENT_INFO *last_event_info)
 {
   if (!short_form)
   {
@@ -5257,16 +5246,17 @@
 
 /*
   Constructor used to build an event for writing to the binary log.
+  Mats says tbl->s lives longer than this event so it's ok to copy pointers
+  (tbl->s->db etc) and not pointer content.
  */
 #if !defined(MYSQL_CLIENT)
-Table_map_log_event::
-Table_map_log_event(THD* thd, TABLE* tbl, ulong tid, 
-		    bool is_transactional, uint16 flags)
-  : Log_event(thd, 0, tbl->file->has_transactions()), 
+Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, 
+                                         bool is_transactional, uint16 flags)
+  : Log_event(thd, 0, is_transactional), 
     m_table(tbl),
     m_dbnam(tbl->s->db), 
     m_dblen(m_dbnam ? strlen(m_dbnam) : 0),
-    m_tblnam(tbl->s->table_name), // Do I need to take a copy???
+    m_tblnam(tbl->s->table_name),
     m_tbllen(strlen(m_tblnam)),
     m_colcnt(tbl->s->fields), m_coltype(0),
     m_memory(0),
@@ -5280,13 +5270,10 @@
   m_data_size+= m_tbllen + 2;	// Include length and terminating \0
   m_data_size+= 1 + m_colcnt;	// COLCNT and column types
 
-  DBUG_ASSERT(m_memory == NULL);
-  if ((m_memory= my_multi_malloc(MYF(0), 
-				 &m_coltype, m_colcnt, 
-				 NULL)))
+  if ((m_memory= m_coltype= my_malloc(m_colcnt, MYF(MY_WME))))
   {
-      for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
-	  m_coltype[i]= m_table->field[i]->type();
+    for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
+      m_coltype[i]= m_table->field[i]->type();
   }
   
   DBUG_VOID_RETURN;
@@ -5297,14 +5284,15 @@
   Constructor used by slave to read the event from the binary log.
  */
 #if defined(HAVE_REPLICATION)
-Table_map_log_event::
-Table_map_log_event(const char* buf, uint event_len,
-		    const Format_description_log_event *description_event)
-#ifdef MYSQL_CLIENT
-  : Log_event(buf, description_event), m_memory(NULL)
-#else
-  : Log_event(buf, description_event), m_table(NULL), m_memory(NULL)
+Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
+                                         const Format_description_log_event
+                                         *description_event)
+
+  : Log_event(buf, description_event),
+#ifndef MYSQL_CLIENT
+  m_table(NULL),
 #endif
+    m_memory(NULL)
 {
   DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
 
@@ -5314,14 +5302,14 @@
                      event_len, common_header_len, post_header_len));
   
   /* Read the post-header */
-  const char* const post_start= buf + common_header_len;	
+  const char *const post_start= buf + common_header_len;	
 
   m_table_id= uint4korr(post_start + TM_MAPID_OFFSET);
 
   m_flags= uint2korr(post_start + TM_FLAGS_OFFSET);
   
   /* Read the variable part of the event */
-  const char* const vpart= post_start + TABLE_MAP_HEADER_LEN;
+  const char *const vpart= post_start + post_header_len;
 
   /* Extract the length of the various parts from the buffer */
   byte const* const ptr_dblen= vpart + 0;
@@ -5333,14 +5321,14 @@
 
   /* Length of table name + counter + terminating null */
   byte const* const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
-  my_vle_decode(&m_colcnt, ptr_colcnt);
+  my_size_t decode_len= my_vle_decode(&m_colcnt, ptr_colcnt);
+  DBUG_ASSERT(decode_len <= sizeof(m_colcnt));
 
   DBUG_PRINT("info",("m_dblen= %d offset %d", m_dblen, ptr_dblen-vpart));
   DBUG_PRINT("info",("m_tbllen= %d offset %d", m_tbllen, ptr_tbllen-vpart));
   DBUG_PRINT("info",("m_colcnt= %d; offset %d", m_colcnt, ptr_colcnt-vpart));
 
   /* Allocate memory for all fields in one go */
-  DBUG_ASSERT(m_memory == NULL);
   m_memory= my_multi_malloc(MYF(0),
 			    &m_dbnam, m_dblen + 1,
 			    &m_tblnam, m_tbllen + 1,
@@ -5359,13 +5347,9 @@
 }
 #endif
 
-Table_map_log_event::
-~Table_map_log_event()
+Table_map_log_event::~Table_map_log_event()
 {
   my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
-#ifndef DBUG_OFF
-  m_memory= NULL;
-#endif
 }
 
 /*
@@ -5381,8 +5365,8 @@
 
     thd        Thread structure
     table_list List of tables to locate in the thd->open_tables list.
-    count      Pointer to count variable that will be set to the number of
-               tables found.  If the pointer is NULL, nothing will be stored.
+    count      Pointer to a variable that will be set to the number of
+               tables found. If the pointer is NULL, nothing will be stored.
 
   RETURN VALUE
 
@@ -5397,30 +5381,32 @@
     open_tables() and lock_tables().
 */
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-static unsigned int
-find_tables(THD* thd, TABLE_LIST* table_list, unsigned int count)
+static uint find_tables(THD *thd, TABLE_LIST *table_list, uint *count)
 {
-  unsigned int result= 0;
+  uint result= 0;
 
-  for (TABLE* table= thd->open_tables; table ; table= table->next) 
+  /* we verify that the caller knows our limitation */
+  DBUG_ASSERT(table_list->next_global == 0);
+  for (TABLE *table= thd->open_tables; table ; table= table->next) 
   {
     if (strcmp(table->s->db, table_list->db) == 0 
 	&& strcmp(table->s->table_name, table_list->table_name) == 0)
     {
-        /* Copy the table pointer into the table list. */
+      /* Copy the table pointer into the table list. */
       table_list->table= table;
       result= 1;
       break;
     }
   }
 
+  if (count)
+    *count= result;
   return result;
 }
 #endif
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-int Table_map_log_event::
-exec_event(st_relay_log_info* rli)
+int Table_map_log_event::exec_event(st_relay_log_info *rli)
 {
   DBUG_ENTER("Table_map_log_event::exec_event(st_relay_log_info*)");
   
@@ -5449,10 +5435,10 @@
       The table map will return NULL and the row-level event will effectively
       be a no-op.
     */
-    unsigned int count= 1;
-    if (find_tables(thd, &table_list, count) == 0) 
+    uint count;
+    if (find_tables(thd, &table_list, &count) == 0) 
     {
-      TABLE_LIST* tables= &table_list;
+      TABLE_LIST *tables= &table_list;
       open_tables(thd, &tables, &count);
     } 
 
@@ -5462,17 +5448,21 @@
     */
     m_table= table_list.table;
 
+    /*
+      We record in the slave's information that the number m_table_id is
+      mapped to the m_table object
+    */
     error= rli->m_table_map.set_table(m_table_id, m_table);
   }
 
-  /* 
-     We explicitly do not call Log_event::exec_event() here since we do not
-     want the relay log position to be flushed to disk. The flushing will be
-     done by the last Rows_log_event that either ends a statement (outside a
-     transaction) or a transaction.
-     
-     A table map event can *never* end a transaction or a statement, so we
-     just step the relay log position.
+  /*
+    We explicitly do not call Log_event::exec_event() here since we do not
+    want the relay log position to be flushed to disk. The flushing will be
+    done by the last Rows_log_event that either ends a statement (outside a
+    transaction) or a transaction.
+    
+    A table map event can *never* end a transaction or a statement, so we
+    just step the relay log position.
   */
 
   rli->inc_event_relay_log_pos();
@@ -5482,8 +5472,7 @@
 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
 #ifndef MYSQL_CLIENT
-bool Table_map_log_event::
-write_data_header(IO_CACHE* file)
+bool Table_map_log_event::write_data_header(IO_CACHE *file)
 {
   DBUG_ENTER("Table_map_log_event::write_data_header(IO_CACHE*)");
 
@@ -5494,14 +5483,13 @@
   DBUG_RETURN(my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
 }
 
-bool Table_map_log_event::
-write_data_body(IO_CACHE* file)
+bool Table_map_log_event::write_data_body(IO_CACHE *file)
 {
   DBUG_ENTER("Table_map_log_event::write_data_body(IO_CACHE*)");
   DBUG_ASSERT(m_dbnam != NULL);
   DBUG_ASSERT(m_tblnam != NULL);
 
-  /* To ensure that we can use VLE in the future. */
+  /* We use only one byte per length for storage in event: */
   DBUG_ASSERT(m_dblen < 128);
   DBUG_ASSERT(m_tbllen < 128);
 
@@ -5510,9 +5498,7 @@
 
   byte cbuf[my_vle_sizeof(m_colcnt)];
   my_size_t cbuf_len= my_vle_encode(cbuf, sizeof(cbuf), m_colcnt);
-
-  DBUG_ASSERT(cbuf_len <= sizeof(m_colcnt));
-  DBUG_DUMP("cbuf", cbuf, cbuf_len);
+  DBUG_ASSERT(cbuf_len <= sizeof(cbuf));
 
   DBUG_RETURN(   my_b_safe_write(file, dbuf,      sizeof(dbuf))
 	      || my_b_safe_write(file, m_dbnam,   m_dblen+1)
@@ -5524,26 +5510,8 @@
 #endif
 
 #ifdef MYSQL_CLIENT
-/*
-  Dummy functions to satisfy linking dependencies
-*/
-bool Table_map_log_event::
-write_data_header(IO_CACHE* file)
-{
-  DBUG_ASSERT(0);		// Shouldn't come here!
-  return 1;
-}
-
-bool Table_map_log_event::
-write_data_body(IO_CACHE* file)
-{
-  DBUG_ASSERT(0);		// Shouldn't come here!
-  return 1;
-}
-
-void Table_map_log_event::
-print(FILE* file, bool short_form,
-      LAST_EVENT_INFO* last_event_info)
+void Table_map_log_event::print(FILE *file, bool short_form,
+                                LAST_EVENT_INFO *last_event_info)
 {
   if (!short_form)
   {
@@ -5561,9 +5529,10 @@
   Constructor used to build an event for writing to the binary log.
  */
 #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)
+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)
 {
 }
@@ -5573,9 +5542,9 @@
   Constructor used by slave to read the event from the binary log.
  */
 #ifdef HAVE_REPLICATION
-Write_rows_log_event::
-Write_rows_log_event(const char* buf, uint event_len,
-		     const Format_description_log_event *description_event)
+Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
+                                           const Format_description_log_event
+                                           *description_event)
 : Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
 {
   DBUG_ENTER("Write_rows_log_event::Write_rows_log_event(char*,...)");
@@ -5584,8 +5553,7 @@
 #endif
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-int Write_rows_log_event::
-do_before_row_operations(TABLE* table)
+int Write_rows_log_event::do_before_row_operations(TABLE *table)
 {
   int error= 0;
   /* idempotency handling */
@@ -5593,13 +5561,16 @@
   table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); // needed for ndbcluster
   /* TODO: Ensure that myisam allow write_row() with duplicate key. */
  
-  /* TODO: better if we know how many... */
+  /*
+    TODO: the cluster team (Tomas?) says that it's better if the engine knows
+    how many rows are going to be inserted, then it can allocate needed memory
+    from the start.
+  */
   table->file->start_bulk_insert(0);
   return error;
 }
 
-int Write_rows_log_event::
-do_after_row_operations(TABLE* table, int error)
+int Write_rows_log_event::do_after_row_operations(TABLE *table, int error)
 {
   DBUG_ENTER("Write_rows_log_event::do_after_row_operations(TABLE*)");
   if (error == 0)
@@ -5607,8 +5578,8 @@
   DBUG_RETURN(error);
 }
 
-char const* Write_rows_log_event::
-do_prepare_row(THD* thd, TABLE* table, char const* row_start)
+char const *Write_rows_log_event::do_prepare_row(THD *thd, TABLE *table,
+                                                 char const *row_start)
 {
   DBUG_ENTER("Write_rows_log_event::do_prepare_row(THD*, TABLE*,...)");
   DBUG_PRINT("enter", ("thd=%p, table=%p, row_start=%p", 
@@ -5619,13 +5590,12 @@
     columns on the slave as on the master.
   */
   DBUG_ASSERT(table->s->fields >= m_width);
-  char const* ptr= row_start;
+  char const *ptr= row_start;
   ptr= unpack_row(thd, table, table->record[0], ptr, &m_cols);
   DBUG_RETURN(ptr);
 }
 
-int Write_rows_log_event::
-do_exec_row(TABLE* table, st_relay_log_info* rli)
+int Write_rows_log_event::do_exec_row(TABLE *table, st_relay_log_info *rli)
 {
   DBUG_ENTER("Write_rows_log_event::do_exec_row(TABLE*,...)");
   DBUG_PRINT("enter", ("table=%p (%s), rli=%p", 
@@ -5637,9 +5607,8 @@
 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
 #ifdef MYSQL_CLIENT
-void Write_rows_log_event::
-print(FILE* file, bool short_form,
-      LAST_EVENT_INFO* last_event_info)
+void Write_rows_log_event::print(FILE *file, bool short_form,
+                                 LAST_EVENT_INFO* last_event_info)
 {
   if (!short_form)
   {
@@ -5654,7 +5623,7 @@
 **************************************************************************/
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-static int record_compare(TABLE* table, byte const *a, byte const *b)
+static int record_compare(TABLE *table, byte const *a, byte const *b)
 {
   for (my_size_t i= 0 ; i < table->s->fields ; ++i) 
   {
@@ -5675,21 +5644,21 @@
   The 'record_buf' will be used as buffer for records while locating the
   correct row.
  */
-static int find_and_fetch_row(TABLE* table, byte* key, byte* record_buf) 
+static int find_and_fetch_row(TABLE *table, byte *key, byte *record_buf) 
 {
-  DBUG_ENTER("find_and_fetch_row(TABLE* table, byte* key, byte* record)");
+  DBUG_ENTER("find_and_fetch_row(TABLE *table, byte *key, byte *record)");
   DBUG_PRINT("enter", ("table=%p, key=%p, record=%p", 
 		       table, key, record_buf));
 
   if ((table->file->table_flags() & HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS)
       && table->s->primary_key < MAX_KEY)
   {
-    /* 
-       Use a more efficient method to fetch the record given by
-       table->record[0] if the engine allows it.  We first compute a
-       row reference using the position() member function (it will be
-       stored in table->file->ref) and the use rnd_pos() to position
-       the "cursor" at the correct row.
+    /*
+      Use a more efficient method to fetch the record given by
+      table->record[0] if the engine allows it.  We first compute a
+      row reference using the position() member function (it will be
+      stored in table->file->ref) and the use rnd_pos() to position
+      the "cursor" at the correct row.
     */
     table->file->position(table->record[0]);
     DBUG_RETURN(table->file->rnd_pos(table->record[0], table->file->ref));
@@ -5758,34 +5727,24 @@
  */
 
 #ifndef MYSQL_CLIENT
-Delete_rows_log_event::
-Delete_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) 
+Delete_rows_log_event::Delete_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)
 #ifdef HAVE_REPLICATION
-    , m_memory(NULL), m_key(NULL), m_search_record(NULL)
+  ,m_memory(NULL), m_key(NULL), m_search_record(NULL)
 #endif
 {
 }
-
-Delete_rows_log_event::
-~Delete_rows_log_event() 
-{
-#ifdef HAVE_REPLICATION
-  /* This free is just a precaution, the memory should be released. */
-  my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
-  m_memory= 0;
-#endif
-}
 #endif /* #if !defined(MYSQL_CLIENT) */
 
 /*
   Constructor used by slave to read the event from the binary log.
  */
 #ifdef HAVE_REPLICATION
-Delete_rows_log_event::
-Delete_rows_log_event(const char* buf, uint event_len,
-		      const Format_description_log_event *description_event)
+Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
+                                             const Format_description_log_event
+                                             *description_event)
 #if defined(MYSQL_CLIENT)
   : Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
 #else
@@ -5799,8 +5758,7 @@
 #endif
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-int Delete_rows_log_event::
-do_before_row_operations(TABLE* table)
+int Delete_rows_log_event::do_before_row_operations(TABLE *table)
 {
   DBUG_ENTER("Delete_rows_log_event::do_before_row_operations(TABLE*)");
   DBUG_ASSERT(m_memory == NULL);
@@ -5808,10 +5766,10 @@
   if ((table->file->table_flags() & HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS) && 
       table->s->primary_key < MAX_KEY)
   {
-    /* 
-       We don't need to allocate any memory for m_search_record and
-       m_key since they are not used.
-     */
+    /*
+      We don't need to allocate any memory for m_search_record and
+      m_key since they are not used.
+    */
     DBUG_RETURN(0);
   }
 
@@ -5841,8 +5799,7 @@
   DBUG_RETURN(error);
 }
 
-int Delete_rows_log_event::
-do_after_row_operations(TABLE* table, int error)
+int Delete_rows_log_event::do_after_row_operations(TABLE *table, int error)
 {
   DBUG_ENTER("Delete_rows_log_event::do_after_row_operations(TABLE*)");
 
@@ -5857,12 +5814,12 @@
   DBUG_RETURN(error);
 }
 
-char const* Delete_rows_log_event::
-do_prepare_row(THD* thd, TABLE* table, char const* row_start)
+char const *Delete_rows_log_event::do_prepare_row(THD *thd, TABLE *table,
+                                                  char const *row_start)
 {
   DBUG_ENTER("Delete_rows_log_event::do_prepare_row(THD*, TABLE*,...)");
 
-  char const* ptr= row_start;
+  char const *ptr= row_start;
 
   /*
     This assertion actually checks that there is at least as many
@@ -5892,8 +5849,7 @@
   DBUG_RETURN(ptr);
 }
 
-int Delete_rows_log_event::
-do_exec_row(TABLE* table, st_relay_log_info* rli)
+int Delete_rows_log_event::do_exec_row(TABLE *table, st_relay_log_info *rli)
 {
   DBUG_ENTER("Delete_rows_log_event::do_exec_row(TABLE*,...)");
   DBUG_PRINT("enter", ("table=%p (%s), rli=%p", 
@@ -5927,9 +5883,9 @@
   Constructor used to build an event for writing to the binary log.
  */
 #if !defined(MYSQL_CLIENT)
-Update_rows_log_event::
-Update_rows_log_event(THD* thd_arg, TABLE* tbl_arg, ulong tid, 
-		      MY_BITMAP const* cols, bool is_transactional)
+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)
 #ifdef HAVE_REPLICATION
   , m_memory(NULL), m_key(NULL)
@@ -5942,9 +5898,10 @@
   Constructor used by slave to read the event from the binary log.
  */
 #ifdef HAVE_REPLICATION
-Update_rows_log_event::
-Update_rows_log_event(const char* buf, uint event_len,
-		      const Format_description_log_event *description_event)
+Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
+                                             const
+                                             Format_description_log_event
+                                             *description_event)
 #if defined(MYSQL_CLIENT)
   : Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
 #else
@@ -5958,8 +5915,7 @@
 #endif
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-int Update_rows_log_event::
-do_before_row_operations(TABLE* table)
+int Update_rows_log_event::do_before_row_operations(TABLE *table)
 {
   DBUG_ENTER("Update_rows_log_event::do_before_row_operations(TABLE*)");
   DBUG_ASSERT(m_memory == NULL);
@@ -5967,10 +5923,10 @@
   if ((table->file->table_flags() & HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS) && 
       table->s->primary_key < MAX_KEY)
   {
-    /* 
-       We don't need to allocate any memory for m_search_record and
-       m_key since they are not used.
-     */
+    /*
+      We don't need to allocate any memory for m_search_record and
+      m_key since they are not used.
+    */
     DBUG_RETURN(0);
   }
 
@@ -6001,8 +5957,7 @@
   DBUG_RETURN(error);
 }
 
-int Update_rows_log_event::
-do_after_row_operations(TABLE* table, int error)
+int Update_rows_log_event::do_after_row_operations(TABLE *table, int error)
 {
   DBUG_ENTER("Update_rows_log_event::do_after_row_operations(TABLE*)");
 
@@ -6017,12 +5972,12 @@
   DBUG_RETURN(error);
 }
 
-char const* Update_rows_log_event::
-do_prepare_row(THD* thd, TABLE* table, char const* row_start)
+char const *Update_rows_log_event::do_prepare_row(THD *thd, TABLE *table,
+                                                  char const *row_start)
 {
   DBUG_ENTER("Update_rows_log_event::do_prepare_row(THD*, TABLE*,...)");
 
-  char const* ptr= row_start;
+  char const *ptr= row_start;
 
   /*
     This assertion actually checks that there is at least as many
@@ -6056,8 +6011,7 @@
   DBUG_RETURN(ptr);
 }
 
-int Update_rows_log_event::
-do_exec_row(TABLE* table, st_relay_log_info* rli)
+int Update_rows_log_event::do_exec_row(TABLE *table, st_relay_log_info *rli)
 {
   DBUG_ENTER("Update_rows_log_event::do_exec_row(TABLE*,...)");
   DBUG_PRINT("enter", ("table=%p (%s), rli=%p", 
@@ -6071,10 +6025,10 @@
     DBUG_RETURN(error);
   }
     
-  /* 
-     Now we should have the right row to update.  The record that has
-     been fetched is guaranteed to be in record[0], so we use that.
-   */
+  /*
+    Now we should have the right row to update.  The record that has
+    been fetched is guaranteed to be in record[0], so we use that.
+  */
   error= table->file->ha_update_row(table->record[0], table->record[1]);
 
   DBUG_PRINT("return", ("error=%d", error));

--- 1.114/sql/log_event.h	2005-07-28 20:24:54 +02:00
+++ 1.115/sql/log_event.h	2005-08-02 22:06:23 +02:00
@@ -26,11 +26,10 @@
 #pragma interface			/* gcc class implementation */
 #endif
 
-#include "my_bitmap.h"
+#include <my_bitmap.h>
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED)
 extern my_bool opt_binlog_row_based_logging;
-extern ulong opt_binlog_row_event_max_size;
 #endif
 
 #define LOG_READ_EOF    -1
@@ -1653,9 +1652,10 @@
   virtual bool is_valid() const { return 1; }
 
   virtual int get_data_size() { return m_data_size; } 
-
+#ifndef MYSQL_CLIENT
   virtual bool write_data_header(IO_CACHE *file);
   virtual bool write_data_body(IO_CACHE *file);
+#endif
   virtual const char *get_db() { return m_dbnam; }
 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
@@ -1749,7 +1749,7 @@
 		     LAST_EVENT_INFO *last_event_info= 0);
 #endif
 
-  void add_row_data(byte *data, size_t length) { 
+  void add_row_data(byte *data, my_size_t length) { 
     do_add_row_data(data,length); 
   }
 
@@ -1761,7 +1761,7 @@
   }
 
   MY_BITMAP const *get_cols() const { return &m_cols; }
-  size_t get_width() const          { return m_width; }
+  my_size_t get_width() const       { return m_width; }
   ulong get_table_id() const        { return m_table_id; }
 
   virtual bool write_data_header(IO_CACHE *file);
@@ -1788,10 +1788,10 @@
       return bits->bitmap_size;
   }
 
-  virtual void do_add_row_data(byte *data, size_t length);
+  virtual void do_add_row_data(byte *data, my_size_t length);
 
   char const *m_dbnam;		/* Database name */
-  size_t m_dblen;		/* Length of database name in bytes */
+  my_size_t m_dblen;		/* Length of database name in bytes */
 
 #ifndef MYSQL_CLIENT
   TABLE *m_table;		/* The table the rows belong to */
@@ -1812,7 +1812,6 @@
   byte    *m_rows_end;		/* One-after the end of the allocated space */
 
   flag_set m_flags;		/* Flags for row-level events */
-  bool     m_is_transactional;	/* The table handler is transactional */
 
 private:
 
@@ -2004,8 +2003,6 @@
 #ifndef MYSQL_CLIENT
   Delete_rows_log_event(THD*, TABLE*, ulong, 
 			MY_BITMAP const *cols, bool is_transactional);
-
-  virtual ~Delete_rows_log_event();
 #endif
 #ifdef HAVE_REPLICATION
   Delete_rows_log_event(const char *buf, uint event_len, 

--- 1.335/sql/mysql_priv.h	2005-07-28 20:24:54 +02:00
+++ 1.336/sql/mysql_priv.h	2005-08-02 22:06:24 +02:00
@@ -1117,10 +1117,10 @@
 extern ulong query_buff_size, thread_stack;
 extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
 extern ulong max_binlog_size, max_relay_log_size;
-extern const char * opt_binlog_format;
+extern const char *opt_binlog_format;
 #ifdef HAVE_ROW_BASED
 extern my_bool opt_binlog_row_based_logging;
-extern ulong opt_binlog_row_event_max_size; 
+extern ulong opt_binlog_rows_event_max_size; 
 #endif
 extern ulong rpl_recovery_rank, thread_cache_size;
 extern ulong back_log;

--- 1.487/sql/mysqld.cc	2005-07-28 20:24:54 +02:00
+++ 1.488/sql/mysqld.cc	2005-08-02 22:06:24 +02:00
@@ -342,22 +342,32 @@
 my_bool opt_noacl;
 my_bool sp_automatic_privileges= 1;
 
-my_bool opt_binlog_row_based_logging= FALSE; // Statement-based is default
+/*
+  This variable below serves as an optimization for (opt_binlog_format ==
+  BF_ROW) as we need to do this test for every row. Stmt-based is default.
+*/
+my_bool opt_binlog_row_based_logging= FALSE;
 
 #ifdef HAVE_ROW_BASED
-unsigned long opt_binlog_rows_event_max_size = 1024L;
-const char *binlog_format_names[]= {"disabled","statement","row", NullS};
-enum Binlog_format { BF_NONE= 0, BF_STMT= 1, BF_ROW= 2 };
+ulong opt_binlog_rows_event_max_size;
+const char *binlog_format_names[]= {"STATEMENT", "ROW", NullS};
+/*
+  Note that BF_UNSPECIFIED is last, after the end of binlog_format_names: it
+  has no corresponding cell in this array. We use this value to be able to
+  know if the user has explicitely specified a binlog format (then we require
+  also --log-bin) or not (then we fall back to statement-based).
+*/
+enum binlog_format { BF_STMT= 0, BF_ROW= 1, BF_UNSPECIFIED= 2 };
 #else
-const char *binlog_format_names[]= {"disabled","statement", NullS};
-enum Binlog_format { BF_NONE= 0, BF_STMT= 1 };
+const char *binlog_format_names[]= {"STATEMENT", NullS};
+enum binlog_format { BF_STMT= 0, BF_UNSPECIFIED= 2 };
 #endif
 
 TYPELIB binlog_format_typelib=
   { array_elements(binlog_format_names)-1,"",
     binlog_format_names, NULL };
 const char *opt_binlog_format= 0;
-enum Binlog_format opt_binlog_format_id= BF_NONE;
+enum binlog_format opt_binlog_format_id= BF_UNSPECIFIED;
 
 #ifdef HAVE_INITGROUPS
 static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */
@@ -2770,9 +2780,43 @@
   {
     sql_print_warning("You need to use --log-bin to make "
                       "--log-slave-updates work.");
-      unireg_abort(1);
+    unireg_abort(1);
   }
 
+  if (!opt_bin_log && (opt_binlog_format_id != BF_UNSPECIFIED))
+  {
+    sql_print_warning("You need to use --log-bin to make "
+                      "--binlog-format work.");
+    unireg_abort(1);
+  }
+  if (opt_binlog_format_id == BF_UNSPECIFIED)
+  {
+    /*
+      We use statement-based by default, but could change this to be row-based
+      if this is a cluster build (i.e. have_ndbcluster is true)...
+    */
+    opt_binlog_format_id= BF_STMT;
+  }
+#ifdef HAVE_ROW_BASED
+  if (opt_binlog_format_id == BF_ROW) 
+  {
+    opt_binlog_row_based_logging= TRUE;
+    /*
+      Row-based binlogging turns on InnoDB unsafe locking, because the locks
+      are not needed when using row-based binlogging. In fact
+      innodb-locks-unsafe-for-binlog is unsafe only for stmt-based, it's
+      safe for row-based.
+    */
+#ifdef HAVE_INNOBASE_DB
+    innobase_locks_unsafe_for_binlog= TRUE;
+#endif
+  }
+#endif
+  /* Check that we have not let the format to unspecified at this point */
+  DBUG_ASSERT(opt_binlog_format_id <=
+              array_elements(binlog_format_names)-1);
+  opt_binlog_format= binlog_format_names[opt_binlog_format_id];
+
   if (opt_slow_log)
     mysql_slow_log.open_slow_log(opt_slow_logname);
 
@@ -4454,12 +4498,15 @@
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"binlog-format", OPT_BINLOG_FORMAT,
 #ifdef HAVE_ROW_BASED
-   "Tell the master the form of logging to use: either 'row' for row-level "
-   "logging or 'statement' for statement-level logging.  "
-   "This option will automatically turn on innodb_locks_unsafe_for_binlog.",
-#else
-   "Option only used when row-based binary logging is enabled.  "
-   "Only legal value is 'statement'.",
+   "Tell the master the form of binary logging to use: either 'row' for "
+   "row-based binary logging (which automatically turns on "
+   "innodb_locks_unsafe_for_binlog as it is safe in this case), or "
+   "'statement' for statement-based logging. ",
+#else
+   "Tell the master the form of binary logging to use: this release build "
+   "supports only statement-based binary logging, so only 'statement' is "
+   "a legal value; MySQL-Max release builds support row-based binary logging "
+   "in addition.",
 #endif
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },   
   {"binlog-do-db", OPT_BINLOG_DO_DB,
@@ -4470,9 +4517,9 @@
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 #ifdef HAVE_ROW_BASED
   {"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
-   "The maximum size of a row-level event in bytes.  A new row event will "
-   "be started when the value of the pending event exceedes this value. "
-   "The value have to be an even multiple of 256.",
+   "The maximum size of a row-based binary log event in bytes. Rows will be "
+   "grouped into events smaller than this size if possible. "
+   "The value has to be a multiple of 256.",
    (gptr*) &opt_binlog_rows_event_max_size, 
    (gptr*) &opt_binlog_rows_event_max_size, 0, 
    GET_ULONG, REQUIRED_ARG, 
@@ -4643,7 +4690,9 @@
    (gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
    0, 0, 0},
   {"innodb_locks_unsafe_for_binlog", OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG,
-   "Force InnoDB not to use next-key locking. Instead use only row-level locking",
+   "Force InnoDB not to use next-key locking, to use only row-level locking."
+   " This is unsafe if you are using statement-based binary logging, and safe"
+   " if you are using row-based binary logging.",
    (gptr*) &innobase_locks_unsafe_for_binlog,
    (gptr*) &innobase_locks_unsafe_for_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"innodb_log_arch_dir", OPT_INNODB_LOG_ARCH_DIR,
@@ -6392,7 +6441,7 @@
 #endif
       exit(1);
     }
-    opt_binlog_format_id= (enum Binlog_format)(id-1);
+    opt_binlog_format_id= (enum binlog_format)(id-1);
     break;
   }
   case (int)OPT_BINLOG_DO_DB:
@@ -6929,28 +6978,6 @@
 				  &global_system_variables.datetime_format))
     exit(1);
 
-  if (opt_bin_log)
-  {
-    if (opt_binlog_format_id == BF_NONE)
-    {
-      opt_binlog_format_id= BF_STMT;
-    }
-#ifdef HAVE_ROW_BASED
-    if (opt_binlog_format_id == BF_ROW) 
-    {
-      opt_binlog_row_based_logging= TRUE;
-      /* Row-based logging turns on InnoDB unsafe locking: the locks
-       * are not needed when using row-based. */
-#ifdef HAVE_INNOBASE_DB
-      innobase_locks_unsafe_for_binlog= TRUE;
-#endif
-    }
-#endif
-  }
-  else
-    opt_binlog_format_id= BF_NONE;
-
-  opt_binlog_format= binlog_format_names[opt_binlog_format_id];
 }
 
 

--- 1.253/sql/slave.cc	2005-07-25 12:54:44 +02:00
+++ 1.254/sql/slave.cc	2005-08-02 22:06:24 +02:00
@@ -4707,6 +4707,13 @@
   DBUG_VOID_RETURN;
 }
 
+/*
+  Some system tables needed to be re-read by the MySQL server after it has
+  updated them; in statement-based replication, the GRANT and other commands
+  are sent verbatim to the slave which then reloads; in row-based replication,
+  changes to these tables are done through ordinary Rows binlog events, so
+  master must add some flag for the slave to know it has to reload the tables.
+*/
 struct st_reload_entry
 {
   char const *table;
@@ -4727,8 +4734,8 @@
   { "user",         st_relay_log_info::RELOAD_ACCESS_F }
 };
 
-static const size_t s_mysql_tables_size = 
-sizeof(s_mysql_tables)/sizeof(*s_mysql_tables);
+static const my_size_t s_mysql_tables_size =
+  sizeof(s_mysql_tables)/sizeof(*s_mysql_tables);
 
 static int reload_entry_compare(const void *lhs, const void *rhs)
 {
@@ -4737,15 +4744,28 @@
   return strcmp(lstr, rstr);
 }
 
-void st_relay_log_info::
-touching_table(char const* db, char const* table, ulong table_id) 
+void st_relay_log_info::touching_table(char const* db, char const* table,
+                                       ulong table_id) 
 {
   if (strcmp(db,"mysql") == 0)
   {
-    void *const ptr= bsearch(table, s_mysql_tables, 
-                       s_mysql_tables_size, sizeof(*s_mysql_tables), 
-                       reload_entry_compare);
+#if defined(HAVE_BSEARCH) && defined(HAVE_SIZE_T)
+    void *const ptr= bsearch(table, s_mysql_tables,
+                             (size_t)s_mysql_tables_size,
+                             sizeof(*s_mysql_tables), reload_entry_compare);
     st_reload_entry const *const entry= static_cast<st_reload_entry*>(ptr);
+#else
+    /*
+      Fall back to full scan, there are few rows anyway and updating the
+      "mysql" database is rare.
+    */
+    st_reload_entry *entry= 0;
+    for (uint i= 0; i < s_mysql_tables_size; i++)
+    {
+      if (reload_entry_compare(table, &s_mysql_tables[i]) == 0)
+        entry= &s_mysql_tables[i];
+    }
+#endif
     if (entry)
     {
       m_reload_flags|= entry->flag;
@@ -4755,8 +4775,7 @@
   }
 }
 
-void st_relay_log_info::
-transaction_end(THD* thd) 
+void st_relay_log_info::transaction_end(THD* thd) 
 {
   if (m_reload_flags != RELOAD_NONE_F)
   {

--- 1.196/sql/sql_class.cc	2005-07-28 20:24:54 +02:00
+++ 1.197/sql/sql_class.cc	2005-08-02 22:06:24 +02:00
@@ -27,7 +27,7 @@
 #endif
 
 #include "mysql_priv.h"
-#include "my_bitmap.h"
+#include <my_bitmap.h>
 #include "log_event.h"
 #include <m_ctype.h>
 #include <sys/stat.h>
@@ -1595,15 +1595,15 @@
   /* Note that free_list is freed in cleanup_after_query() */
 
   /*
-    Flush pending event if we are *not* in a transaction.  This will only do
-    something if we are processing a non-transactional table in statement
-    mode.  Otherwise, the pending event will already have been flushed.
-   */
+    Flush the pending binlog rows event to the binlog if we are *not* in a
+    transaction (otherwise, the pending event will already have been
+    flushed before).
+  */
 #if !defined(MYSQL_CLIENT)
-  if (!(options & OPTION_BEGIN))
+  if (!(options & OPTION_BEGIN)) // TODO not a good test
   {
 #ifdef HAVE_ROW_BASED
-    flush_pending_event(true);
+    binlog_flush_pending_rows_event(true);
 #endif
   }
 #endif
@@ -1865,15 +1865,20 @@
 
 /*
   Implementation of interface to write rows to the binary log through the
-  thread.  The thread is responsible for
- */
+  thread.  The thread is responsible for writing the rows it has
+  inserted/updated/deleted.
+*/
 
 #ifdef HAVE_ROW_BASED
-#ifndef MYSQL_CLIENT
-
-extern ulong opt_binlog_rows_event_max_size;
 
 /*
+  Sounds strange to have ifndef MYSQL_CLIENT, as we don't put a copy of
+  sql_class.cc in client/. But this may happen in the future (for mysqlbinlog
+  to be able to "execute" row-based binlog events, so Mats has already put the
+  ifndef.
+*/
+#ifndef MYSQL_CLIENT
+/*
   Template member function for ensuring that there is an rows log
   event of the apropriate type before proceeding.
 
@@ -1892,8 +1897,8 @@
 template <class RowsEventT>
 Rows_log_event* 
 prepare_pending(THD* thd, TABLE* table, uint32 server_id, 
-		MY_BITMAP const* cols, size_t colcnt, 
-                size_t needed, bool is_transactional) 
+		MY_BITMAP const* cols, my_size_t colcnt,
+                my_size_t needed, bool is_transactional)
 {
   /* Fetch the type code for the RowsEventT template parameter */
   int const type_code= RowsEventT::TYPE_CODE;
@@ -1902,7 +1907,7 @@
 		       table, table->s->table_name,
 		       type_code, needed));
 
-  Rows_log_event* pending= thd->get_pending_event();
+  Rows_log_event* pending= thd->binlog_get_pending_rows_event();
 
   if (pending) 
   {
@@ -1939,7 +1944,7 @@
     Rows_log_event* const 
 	ev= new RowsEventT(thd, table, table_id, cols, is_transactional);
     ev->server_id= server_id; // I don't like this, it's too easy to forget. 
-    if (thd->flush_and_set_pending_event(ev))
+    if (thd->binlog_flush_and_set_pending_rows_event(ev))
     {
       delete ev;
       DBUG_RETURN(NULL);
@@ -1951,7 +1956,7 @@
       of course.
     */
     if (!was_mapped)
-      thd->write_table_map(table, is_transactional);
+      thd->binlog_write_table_map(table, is_transactional); // TODO catch return code
     DBUG_RETURN(ev);
   }
   DBUG_RETURN(pending);
@@ -1964,45 +1969,38 @@
 
 template Rows_log_event* 
 prepare_pending<Write_rows_log_event>(THD*, TABLE*, uint32, 
-                                      MY_BITMAP const*, size_t colcnt, 
+                                      MY_BITMAP const*, my_size_t colcnt,
                                       size_t, bool);
 
 template Rows_log_event* 
 prepare_pending<Delete_rows_log_event>(THD*, TABLE*, uint32, 
-                                       MY_BITMAP const*, size_t colcnt, 
+                                       MY_BITMAP const*, my_size_t colcnt,
                                        size_t, bool);
 
 template Rows_log_event* 
 prepare_pending<Update_rows_log_event>(THD*, TABLE*, uint32, 
-                                       MY_BITMAP const*, size_t colcnt, 
+                                       MY_BITMAP const*, my_size_t colcnt,
                                        size_t, bool);
 
-int THD::
-flush_and_set_pending_event(Rows_log_event* event)
+/*
+  Moves the last bunch of rows from the pending Rows event to the binlog
+  (either cached binlog if transaction, or disk binlog). Sets a new pending
+  event.
+*/
+bool THD::binlog_flush_and_set_pending_rows_event(Rows_log_event* event)
 {
-  DBUG_ENTER("THD::flush_and_set_pending_event");
-  DBUG_PRINT("enter", ("thd = 0x%0x (%s event)", 
-		       this, 
-		       (event ? event->get_type_str() : "No")));
-
-  DBUG_ASSERT(opt_binlog_row_based_logging);
-  DBUG_ASSERT(mysql_bin_log.is_open());
-  
-  if (Rows_log_event* pending= get_pending_event())
+  DBUG_ASSERT(opt_binlog_row_based_logging && mysql_bin_log.is_open());  
+  if (Rows_log_event* pending= binlog_get_pending_rows_event())
   {
     if (mysql_bin_log.write(pending))
     {
-      DBUG_PRINT("exit", ("1"));
-      DBUG_RETURN(1);		// Something failed
+      DBUG_PRINT("info", ("THD::flush_and_set_pending_event returns 1"));
+      return 1;		// Something failed
     }
-
     delete pending;
   }
-
-  set_pending_event(event);
-
-  DBUG_PRINT("exit", ("0"));
-  DBUG_RETURN(0);		// All OK
+  binlog_set_pending_rows_event(event);
+  return 0;
 }
 #endif /* !defined(MYSQL_CLIENT) */
 
@@ -2069,10 +2067,9 @@
   return "Unknown";
 }
 
-size_t THD::
-max_row_length_blob(TABLE *table, const byte *data) const
+my_size_t THD::max_row_length_blob(TABLE *table, const byte *data) const
 {
-  size_t length= 0;
+  my_size_t length= 0;
   TABLE_SHARE *table_s= table->s;
   uint* const beg= table_s->blob_field;
   uint* const end= beg + table_s->blob_fields;
@@ -2086,25 +2083,13 @@
   return length;
 }
 
-size_t THD::
-pack_row(TABLE *table, MY_BITMAP const* cols, byte *row_data, 
-	 size_t max_size, const byte *record) const
-{
-  DBUG_ENTER("THD::pack_row");
-  DBUG_PRINT("enter", ("table=%p %s, row_data=%p, max_size=%lu, record=%p", 
-		       table, table ? table->s->table_name : "",
-		       row_data, max_size, record));
-#ifndef DBUG_OFF
-  bzero(row_data, max_size);
-#endif
-
-
+my_size_t THD::pack_row(TABLE *table, MY_BITMAP const* cols, byte *row_data, 
+                        my_size_t max_size, const byte *record) const
+{
   Field **p_field= table->field, *field= *p_field;
   int n_null_bytes= table->s->null_bytes;
   my_ptrdiff_t const offset= record - (byte*) table->record[0];
 
-  DBUG_DUMP("null_bytes", record , n_null_bytes);
-
   memcpy(row_data, record, n_null_bytes);
   byte *ptr= row_data+n_null_bytes;
 
@@ -2112,14 +2097,8 @@
   {
     if (bitmap_is_set(cols,i))
     {
-      DBUG_PRINT("info", ("pack field '%s' (%s) from "
-                          "%p to %p+%d", 
-                          field->field_name, 
-                          field_type_name(field->type()),
-                          ptr, record, field->ptr + offset - record));
       byte* const old_ptr = ptr;
       ptr= field->pack(ptr, field->ptr + offset);
-      DBUG_DUMP("packed", old_ptr, ptr - old_ptr);
     }
   }
 
@@ -2128,55 +2107,46 @@
     conversion will work correctly.
   */
   DBUG_ASSERT(ptr - row_data >= 0);
-  size_t const size= static_cast<size_t>(ptr - row_data);
-  DBUG_PRINT("return", ("size = %lu", size));
-  DBUG_RETURN(size);
+  return (static_cast<size_t>(ptr - row_data));
 }
 
-int THD::
-write_row(TABLE* table, bool is_trans, 
-	  MY_BITMAP const* cols, size_t colcnt, 
-          byte const *record) 
+bool THD::binlog_write_row(TABLE* table, bool is_trans, 
+                           MY_BITMAP const* cols, my_size_t colcnt, 
+                           byte const *record) 
 { 
-  DBUG_ENTER("THD::write_row");
-  DBUG_PRINT("enter", ("cols = { size: %d bytes, data = %p }; "
-		       "table=%p (%s), record=%p", 
-		       cols->bitmap_size, cols->bitmap, 
-		       table, table->s->table_name, record));
-
   DBUG_ASSERT(opt_binlog_row_based_logging && mysql_bin_log.is_open());
 
   /* 
      Pack records into format for transfer. We are allocating more
      memory than needed, but that doesn't matter.
   */
-  int error= 0;
+  bool error= 0;
   byte *row_data= table->write_row_record;
-  size_t const max_len= max_row_length(table, record);
+  my_size_t const max_len= max_row_length(table, record);
 
   /*
    * Allocate room for a row (if needed)
    */
-  if(unlikely(!row_data))
+  if (!row_data)
   {
     if (!table->s->blob_fields)
     {
       /* multiply max_len by 2 so it can be used for update_row as well */
       table->write_row_record= alloc_root(&table->mem_root, 2*max_len);
-      if(!table->write_row_record)
-	DBUG_RETURN(-1);
+      if (!table->write_row_record)
+        return 1;
       row_data= table->write_row_record;
     }
     else
       row_data= my_malloc(max_len, MYF(MY_WME));
   }
-  size_t const len= pack_row(table, cols, row_data, max_len, record);
+  my_size_t const len= pack_row(table, cols, row_data, max_len, record);
 
   Rows_log_event* const
     ev= prepare_pending<Write_rows_log_event>(this, table, server_id, cols, 
 					      colcnt, len, is_trans);
 
-  if (ev)
+  if (likely(ev != 0))
   {
     /* add_row_data copies row_data to internal buffer */
     ev->add_row_data(row_data,len);
@@ -2187,31 +2157,23 @@
   if (table->write_row_record == 0)
     my_free(row_data, MYF(MY_WME));
 
-  DBUG_RETURN(error);
+  return error;
 }
 
-int THD::
-update_row(TABLE* table, bool is_trans,
-	   MY_BITMAP const* cols, size_t colcnt,
-	   const byte *before_record, const byte *after_record)
+bool THD::binlog_update_row(TABLE* table, bool is_trans,
+                            MY_BITMAP const* cols, my_size_t colcnt,
+                            const byte *before_record,
+                            const byte *after_record)
 { 
-  DBUG_ENTER("THD::update_row");
-  DBUG_PRINT("enter", ("cols = { size: %d bytes, data = %p }; "
-		       "table=%p (%s); "
-		       "before=%p; after=%p", 
-		       cols->bitmap_size, cols->bitmap, 
-		       table, table->s->table_name, 
-		       before_record, after_record));
-
   DBUG_ASSERT(opt_binlog_row_based_logging && mysql_bin_log.is_open());
 
-  int error= 0;
-  size_t const before_maxlen = max_row_length(table, before_record);
-  size_t const after_maxlen  = max_row_length(table, after_record);
+  bool error= 0;
+  my_size_t const before_maxlen = max_row_length(table, before_record);
+  my_size_t const after_maxlen  = max_row_length(table, after_record);
 
   byte *memory= table->write_row_record;
   byte *before_row, *after_row;
-  if (likely(memory != 0))
+  if (memory != 0)
   {
     before_row= memory;
     after_row= before_row+before_maxlen;
@@ -2224,10 +2186,10 @@
 			    NULL);
   }
 
-  size_t const before_size= pack_row(table, cols, before_row, 
-				     before_maxlen, before_record);
-  size_t const after_size= pack_row(table, cols, after_row, 
-				    after_maxlen, after_record);
+  my_size_t const before_size= pack_row(table, cols, before_row, 
+                                        before_maxlen, before_record);
+  my_size_t const after_size= pack_row(table, cols, after_row, 
+                                       after_maxlen, after_record);
   
   Rows_log_event* const
     ev= prepare_pending<Update_rows_log_event>(this, table, server_id, 
@@ -2249,32 +2211,25 @@
     my_free(memory, MYF(MY_WME));
   }
   
-  DBUG_RETURN(error);
+  return error;
 }
 
-int THD::
-delete_row(TABLE* table, bool is_trans, 
-	   MY_BITMAP const* cols, size_t colcnt,
-           byte const *record)
+bool THD::binlog_delete_row(TABLE* table, bool is_trans, 
+                            MY_BITMAP const* cols, my_size_t colcnt,
+                            byte const *record)
 { 
-  DBUG_ENTER("THD::delete_row");
-  DBUG_PRINT("enter", ("cols = { size: %d bytes, data = %p }; "
-		       "table=%p (%s), record=%p", 
-		       cols->bitmap_size, cols->bitmap, 
-		       table, table->s->table_name, record));
-
   DBUG_ASSERT(opt_binlog_row_based_logging && mysql_bin_log.is_open());
 
   /* 
      Pack records into format for transfer. We are allocating more
      memory than needed, but that doesn't matter.
   */
-  int error= 0;
-  size_t const max_len= max_row_length(table, record);
+  bool error= 0;
+  my_size_t const max_len= max_row_length(table, record);
   byte *row_data= table->write_row_record;
-  if(unlikely(!row_data))
+  if (!row_data)
     row_data= my_malloc(max_len, MYF(MY_WME));
-  size_t const len= pack_row(table, cols, row_data, max_len, record);
+  my_size_t const len= pack_row(table, cols, row_data, max_len, record);
 
   Rows_log_event* const
     ev= prepare_pending<Delete_rows_log_event>(this, table, server_id, 
@@ -2286,23 +2241,21 @@
   else
     error= 1;
   /* add_row_data copies row_data */
-  if (unlikely(table->write_row_record == 0))
+  if (table->write_row_record == 0)
     my_free(row_data, MYF(MY_WME));
 
-  DBUG_RETURN(error);
+  return error;
 }
 
-ulong THD::
-get_new_table_id(TABLE* table)
+ulong THD::get_new_table_id(TABLE* table)
 {
   ulong id= mysql_bin_log.get_table_id(table);
   return id;
 }
 
-int THD::
-write_table_map(TABLE* table, bool is_transactional)
+bool THD::binlog_write_table_map(TABLE* table, bool is_transactional)
 {
-  DBUG_ENTER("THD::write_table_map()");
+  DBUG_ENTER("THD::binlog_write_table_map()");
   DBUG_PRINT("enter", ("table=%p (%s)", table, table->s->table_name));
 
   DBUG_ASSERT(opt_binlog_row_based_logging && mysql_bin_log.is_open());
@@ -2323,31 +2276,27 @@
   DBUG_RETURN(0);
 }
 
-int THD::
-flush_pending_event(bool trans_end)
+bool THD::binlog_flush_pending_rows_event(bool trans_end)
 {
-  DBUG_ENTER("THD::flush_pending_event(bool)");
+  DBUG_ENTER("THD::binlog_flush_pending_row_event(bool)");
 
   if (!opt_binlog_row_based_logging || !mysql_bin_log.is_open())
     DBUG_RETURN(0);
 
   /*
-    Mark the event as the last event of a transactio if the trans_end
+    Mark the event as the last event of a transaction if the trans_end
     flag is set.
   */
   if (trans_end)
   {
-    if (Rows_log_event* pending= get_pending_event())
+    if (Rows_log_event* pending= binlog_get_pending_rows_event())
     {
       pending->set_flags(Rows_log_event::TRANS_END_F);
-
-      DBUG_ASSERT(mysql_bin_log.is_open());
       mysql_bin_log.update_table_map_version();
     }
   }
   
-  int const error= flush_and_set_pending_event(0);
-  DBUG_RETURN(error);
+  DBUG_RETURN(binlog_flush_and_set_pending_rows_event(0));
 }
 
 #endif /* !defined(MYSQL_CLIENT) */

--- 1.252/sql/sql_class.h	2005-07-28 20:24:54 +02:00
+++ 1.253/sql/sql_class.h	2005-08-02 22:06:24 +02:00
@@ -1155,53 +1155,51 @@
   void *ha_data[MAX_HA];
 
 #ifdef HAVE_ROW_BASED
+/*
+  When mysqlbinlog is made to understand Rows events, we may have
+  to include sql_class.h in client/ so Mats already put the ifndef below.
+*/
 #if !defined(MYSQL_CLIENT)
 
   /*
     Public interface to write rows to the binlog
   */
-  int write_row(TABLE* table, bool is_transactional,
-		MY_BITMAP const* cols, size_t colcnt, 
-                const byte *buf);
-  int delete_row(TABLE* table, bool is_transactional,
-		 MY_BITMAP const* cols, size_t colcnt,
-                 const byte *buf);
-  int update_row(TABLE* table, bool is_transactional,
-		 MY_BITMAP const* cols, size_t colcnt,
-		 const byte *old_data, const byte *new_data);
+  bool binlog_write_row(TABLE* table, bool is_transactional,
+                        MY_BITMAP const* cols, my_size_t colcnt,
+                        const byte *buf);
+  bool binlog_delete_row(TABLE* table, bool is_transactional,
+                         MY_BITMAP const* cols, my_size_t colcnt,
+                         const byte *buf);
+  bool binlog_update_row(TABLE* table, bool is_transactional,
+                         MY_BITMAP const* cols, my_size_t colcnt,
+                         const byte *old_data, const byte *new_data);
 
   void set_server_id(uint32 sid) { server_id = sid; }
 
-#if 0
-private:
-#endif
   /*
     Member functions to handle pending event for row-level logging.
   */
-  Rows_log_event* get_pending_event() const
-    { return transaction.m_pending_rows_event; }
-  int             set_pending_event(Rows_log_event* ev)
-    { transaction.m_pending_rows_event= ev; return 0; }
-  int             flush_and_set_pending_event(Rows_log_event*);
+  Rows_log_event* binlog_get_pending_rows_event() const
+  { return transaction.m_pending_rows_event; }
+  bool            binlog_set_pending_rows_event(Rows_log_event* ev)
+  { transaction.m_pending_rows_event= ev; return 0; }
+  bool            binlog_flush_and_set_pending_rows_event(Rows_log_event*);
 
-  size_t max_row_length_blob(TABLE* table, const byte *data) const;
-  size_t max_row_length(TABLE* table, const byte *data) const
+  my_size_t max_row_length_blob(TABLE* table, const byte *data) const;
+  my_size_t max_row_length(TABLE* table, const byte *data) const
   {
-    DBUG_ENTER("THD::max_row_length");
-    DBUG_PRINT("enter", ("record = 0x%0x", data));
-
     TABLE_SHARE *table_s= table->s;
-    size_t length= table_s->reclength + 2 * table_s->fields;
+    my_size_t length= table_s->reclength + 2 * table_s->fields;
     if (table_s->blob_fields == 0)
-      DBUG_RETURN(length);
+      return length;
 
-    DBUG_RETURN(length+max_row_length_blob(table,data));
+    return (length+max_row_length_blob(table,data));
   }
 
-  size_t pack_row(TABLE* table, MY_BITMAP const* cols, 
-		  byte *row_data, size_t max_len, const byte *data) const;
+  my_size_t pack_row(TABLE* table, MY_BITMAP const* cols, byte *row_data,
+                     my_size_t max_len, const byte *data) const;
 
-  int flush_pending_event(bool transaction_end);
+  bool binlog_flush_pending_rows_event(bool transaction_end);
 
   ulong get_new_table_id(TABLE* table);
   ulong get_table_id(TABLE* table)
@@ -1212,12 +1210,12 @@
     return get_new_table_id(table);
   }
 
-  int is_table_mapped(TABLE* table) const
+  bool is_table_mapped(TABLE* table) const
   {
     return table->s->table_map_version == *m_table_map_version;
   }
 
-  int write_table_map(TABLE*,bool);
+  bool binlog_write_table_map(TABLE*,bool);
 
   ulonglong const *m_table_map_version;
 #endif
@@ -1227,11 +1225,13 @@
 
   /*
     This function will be called from ha_commit_trans() to prepare for a
-    commit.
+    commit. The thread should take all necessary actions to prepare itself for
+    commit; presently it's writing the last buffered row-based binlog event to
+    the binlog.
   */
-  int prepare_for_commit(bool all) { 
+  bool prepare_for_commit(bool all) { 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED)
-    return flush_pending_event(true); 
+    return binlog_flush_pending_rows_event(true); 
 #else
     return 0;
 #endif
@@ -1239,11 +1239,13 @@
 
   /*
     This function will be called from ha_rollback_trans() to prepare for a
-    rollback.
+    rollback. The thread should take all necessary actions to prepare itself
+    for rollback; presently it's writing the last buffered row-based binlog
+    event to the binlog (so that they do get thrown away if needed).
   */
-  int prepare_for_rollback(bool all) { 
+  bool prepare_for_rollback(bool all) { 
 #if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED)
-    return flush_pending_event(true); 
+    return binlog_flush_pending_rows_event(true); 
 #else
     return 0;
 #endif
@@ -1258,9 +1260,8 @@
     bool in_sub_stmt;
     XID  xid;                           // transaction identifier
     enum xa_states xa_state;            // used by external XA only
-
 #ifdef HAVE_ROW_BASED
-    Rows_log_event* m_pending_rows_event;
+    Rows_log_event *m_pending_rows_event;
 #endif
 
     /*
@@ -1359,6 +1360,10 @@
     update auto-updatable fields (like auto_increment and timestamp).
   */
   query_id_t query_id, warn_id;
+  /*
+    If you change the type of THD::options, you must also change the type of
+    all OPTION_* flags.
+  */
   ulong	     options, thread_id, col_access;
 
   /* Statement id is thread-wide. This counter is used to generate ids */

--- 1.155/sql/sql_delete.cc	2005-07-28 20:24:54 +02:00
+++ 1.156/sql/sql_delete.cc	2005-08-02 22:06:24 +02:00
@@ -836,6 +836,10 @@
     {
       if (mysql_bin_log.is_open())
       {
+        /*
+          TRUNCATE must always be statement-based binlogged (not row-based) so
+          we don't test opt_binlog_row_based_logging.
+        */
         thd->clear_error();
 	Query_log_event qinfo(thd, thd->query, thd->query_length,
 			      0, FALSE);

--- 1.16/BitKeeper/etc/config	2005-07-23 06:53:23 +02:00
+++ 1.17/BitKeeper/etc/config	2005-08-02 22:06:23 +02:00
@@ -71,5 +71,6 @@
 [arjen:]checkout:get
 [kostja:]checkout:get
 [nick:]checkout:get
+[guilhem:]checkout:get
 checkout:edit
 eoln:unix

--- 1.13/mysql-test/t/date_formats.test	2005-07-25 12:48:00 +02:00
+++ 1.14/mysql-test/t/date_formats.test	2005-08-02 22:06:23 +02:00
@@ -6,9 +6,9 @@
 drop table if exists t1;
 --enable_warnings
 
---replace_result row <format> statement <format>
+--replace_result ROW <format> STATEMENT <format>
 SHOW GLOBAL VARIABLES LIKE "%_format%";
---replace_result row <format> statement <format>
+--replace_result ROW <format> STATEMENT <format>
 SHOW SESSION VARIABLES LIKE "%_format%";
 
 #
@@ -36,7 +36,7 @@
 set datetime_format= '%h:%i:%s %p %Y-%m-%d';
 set datetime_format= '%h:%i:%s.%f %p %Y-%m-%d';
 
---replace_result row <format> statement <format>
+--replace_result ROW <format> STATEMENT <format>
 SHOW SESSION VARIABLES LIKE "%format";
 
 --error 1231
--- New file ---
+++ mysql-test/t/rpl_row_001-master.opt	05/08/02 22:06:24
--binlog-format=row


--- 1.1/include/my_vle.h	2005-07-25 12:48:04 +02:00
+++ 1.2/include/my_vle.h	2005-08-02 22:06:23 +02:00
@@ -26,9 +26,6 @@
 
 #include "my_global.h"
 
-#include <stdlib.h>
-#include <limits.h>
-
 /*
   The size (in bytes) required to store the object ITEM, which can be
   either an expression or a type (since sizeof() is used on the item).

--- 1.1/mysql-test/r/have_binlog_format_row.require	2005-07-25 12:48:05 +02:00
+++ 1.2/mysql-test/r/have_binlog_format_row.require	2005-08-02 22:06:23 +02:00
@@ -1,2 +1,2 @@
 Variable_name	Value
-binlog_format	row
+binlog_format	ROW

--- 1.1/mysql-test/r/have_binlog_format_statement.require	2005-07-25 12:48:05 +02:00
+++ 1.2/mysql-test/r/have_binlog_format_statement.require	2005-08-02 22:06:23 +02:00
@@ -1,2 +1,2 @@
 Variable_name	Value
-binlog_format	statement
+binlog_format	STATEMENT

--- 1.1/mysql-test/t/rpl_row_basic_3innodb-master.opt	2005-07-25 12:48:08 +02:00
+++ 1.2/mysql-test/t/rpl_row_basic_3innodb-master.opt	2005-08-02 22:06:23 +02:00
@@ -1 +1 @@
---innodb
+--innodb --binlog-format=row

--- 1.1/mysys/my_vle.c	2005-07-25 12:48:11 +02:00
+++ 1.2/mysys/my_vle.c	2005-08-02 22:06:23 +02:00
@@ -26,8 +26,12 @@
 */
 
 #include "my_vle.h"
-#include <stdlib.h>
-#include <stddef.h>
+
+/*
+  The return value is the number of bytes necessary to encode "n"; if strictly
+  greater than max, my_vle_encode does not fill *out, so caller should check
+  that the return value <= max.
+*/
 
 my_size_t
 my_vle_encode(byte* out, my_size_t max, ulong n) 
@@ -64,6 +68,12 @@
   return len;
 }
 
+/*
+  The return value is the number of bytes necessary to store the decoded
+  number; if strictly greater than the size of *result_ptr (ulong),
+  my_vle_decode does not fill *result_ptr, so caller should check the return
+  value <= sizeof(result_ptr).
+*/
 
 my_size_t
 my_vle_decode(ulong *result_ptr, byte const *vle) 

--- 1.1/sql/rpl_tblmap.cc	2005-07-25 12:48:11 +02:00
+++ 1.2/sql/rpl_tblmap.cc	2005-08-02 22:06:24 +02:00
@@ -25,8 +25,7 @@
 #define TABLE_ID_HASH_SIZE 32
 #define TABLE_ID_CHUNK 256
 
-table_mapping::
-table_mapping()
+table_mapping::table_mapping()
   : m_free(0)
 {
   (void) hash_init(&m_table_ids,&my_charset_bin,TABLE_ID_HASH_SIZE,
@@ -34,15 +33,13 @@
 		   0,0,0);
 }
 
-table_mapping::
-~table_mapping()
+table_mapping::~table_mapping()
 {
   /* must not delete the chunks as they are allocated on the memroot */
   hash_free(&m_table_ids);
 }
 
-st_table* table_mapping::
-get_table(ulong table_id)
+st_table* table_mapping::get_table(ulong table_id)
 {
   DBUG_ENTER("table_mapping::get_table(ulong)");
   DBUG_PRINT("enter", ("table_id=%d", table_id));
@@ -59,8 +56,11 @@
   DBUG_RETURN(NULL);
 }
 
-int table_mapping::
-expand()
+/*
+  Called when we are out of table id entries. Creates TABLE_ID_CHUNK
+  new entries, chains them, and puts them into the list of free entries.
+*/
+int table_mapping::expand()
 {
   entry *tmp= new entry[TABLE_ID_CHUNK];
   if (tmp == NULL)
@@ -77,8 +77,7 @@
   return 0;
 }
 
-int table_mapping::
-set_table(ulong table_id, TABLE* table)
+int table_mapping::set_table(ulong table_id, TABLE* table)
 {
   DBUG_ENTER("table_mapping::set_table(ulong,TABLE*)");
   DBUG_PRINT("enter", ("table_id=%d, table=%p (%s)", 
@@ -93,9 +92,7 @@
     m_free= m_free->next;
   }
   else
-  {
     hash_delete(&m_table_ids,(byte *)e);
-  }
 
   e->table_id= table_id;
   e->table= table;
@@ -107,13 +104,13 @@
   DBUG_RETURN(0);		// All OK
 }
 
-int table_mapping::
-remove_table(ulong table_id)
+int table_mapping::remove_table(ulong table_id)
 {
   entry *e= find_entry(table_id);
   if (e)
   {
     hash_delete(&m_table_ids,(byte *)e);
+    /* we add this entry to the chain of free entries */
     e->next= m_free;
     m_free= e;
     return 0;			// All OK
@@ -121,8 +118,7 @@
   return 1;			// No table to remove
 }
 
-void table_mapping::
-clear_tables()
+void table_mapping::clear_tables()
 {
   DBUG_ENTER("table_mapping::clear_tables()");
   for (uint i= 0; i < m_table_ids.records; i++)

--- 1.65/libmysql/Makefile.shared	2005-07-25 12:47:58 +02:00
+++ 1.66/libmysql/Makefile.shared	2005-08-02 22:06:23 +02:00
@@ -56,8 +56,6 @@
 			my_create.lo my_delete.lo mf_tempfile.lo my_open.lo \
 			my_file.lo my_read.lo my_write.lo errors.lo \
 			my_error.lo my_getwd.lo my_div.lo \
-                        my_bitmap.lo my_bit.lo \
-                        my_vle.lo \
 			mf_pack.lo my_messnc.lo mf_dirname.lo mf_fn_ext.lo\
 			mf_wcomp.lo typelib.lo safemalloc.lo my_alloc.lo \
 			mf_format.lo mf_path.lo mf_unixpath.lo my_fopen.lo \
Thread
bk commit into 5.0 tree (guilhem:1.1893)guilhem2 Aug