List:Internals« Previous MessageNext Message »
From:Sasha Pachev Date:October 22 2005 4:05am
Subject:bk commit into 5.0 tree (sasha:1.1942) BUG#11312
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of sasha. When sasha 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.1942 05/10/21 22:05:42 sasha@stripped +5 -0
  fix for BUG#11312: binlog does not replay via mysql command line client when stored
  procedures are used. The problem is that mysql command line client needs DELIMITER 
  commands to properly deal with the semicolons in the stored procedures syntax. We
  fix it by adding a capability to mysqlbinlog to connect to a mysql server directly
  and replay the log thus eliminating the need to go through the mysql command line
  client.

  sql/log_event.h
    1.115 05/10/21 22:05:26 sasha@stripped +49 -24
    fix for mysqlbinlog to handle --replay-host

  sql/log_event.cc
    1.190 05/10/21 22:05:26 sasha@stripped +489 -198
    fix for mysqlbinlog to handle --replay-host

  client/mysqlbinlog.cc
    1.114 05/10/21 22:05:26 sasha@stripped +134 -18
    fix for mysqlbinlog to handle --replay-host

  client/client_priv.h
    1.43 05/10/21 22:05:26 sasha@stripped +3 -1
    fix for mysqlbinlog to handle --replay-host

  client/Makefile.am
    1.50 05/10/21 22:05:26 sasha@stripped +1 -1
    fix for mysqlbinlog to handle --replay-host

# 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:	sasha
# Host:	mysql.sashanet.com
# Root:	/reiser-data/mysql-dev/mysql-5.0-mysqlbinlog

--- 1.49/client/Makefile.am	2005-07-05 15:48:39 -06:00
+++ 1.50/client/Makefile.am	2005-10-21 22:05:26 -06:00
@@ -38,7 +38,7 @@
 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/mf_tempfile.c $(top_srcdir)/mysys/my_new.cc
 mysqlbinlog_LDADD =		$(LDADD) $(CXXLDFLAGS)
 mysqltestmanager_pwgen_SOURCES =   mysqlmanager-pwgen.c 
 mysqltestmanagerc_SOURCES=      mysqlmanagerc.c $(yassl_dummy_link_fix)

--- 1.189/sql/log_event.cc	2005-08-30 12:19:07 -06:00
+++ 1.190/sql/log_event.cc	2005-10-21 22:05:26 -06:00
@@ -28,34 +28,47 @@
 
 #define log_cs	&my_charset_latin1
 
-/*
-  pretty_print_str()
-*/
-
 #ifdef MYSQL_CLIENT
-static void pretty_print_str(FILE* file, char* str, int len)
-{
-  char* end = str + len;
-  fputc('\'', file);
-  while (str < end)
-  {
-    char c;
-    switch ((c=*str++)) {
-    case '\n': fprintf(file, "\\n"); break;
-    case '\r': fprintf(file, "\\r"); break;
-    case '\\': fprintf(file, "\\\\"); break;
-    case '\b': fprintf(file, "\\b"); break;
-    case '\t': fprintf(file, "\\t"); break;
-    case '\'': fprintf(file, "\\'"); break;
-    case 0   : fprintf(file, "\\0"); break;
-    default:
-      fputc(c, file);
-      break;
-    }
-  }
-  fputc('\'', file);
-}
-#endif /* MYSQL_CLIENT */
+
+char* event_buf= 0;
+uint event_buf_size= 0;
+extern MYSQL* replay_mysql;
+extern my_bool force_replay_opt;
+
+#define EVENT_BUF_PADDING   4096
+
+#define UPDATE_BUF_INFO buf += bytes_written;\
+                        buf_size -= bytes_written;\
+                        byte_count += bytes_written;\
+                        if (buf_size <= 0) \
+                          return byte_count;
+                          
+#define APPEND_PRETTY(str,str_len) if (str_len*2+2 > buf_size) \
+                                     return byte_count; \
+                                   tmp= pretty_print_str(buf,str,str_len);\
+                                   bytes_written= tmp-buf;\
+                                   buf_size -= bytes_written; \
+                                   byte_count += bytes_written; \
+                                   buf= tmp; \
+                                   if (buf_size <= 0) \
+                                     return byte_count; 
+
+#define APPEND_CHAR(c)  if (buf_size < 1) \
+                          return byte_count; \
+                        *buf++ = (c); \
+                        byte_count++; \
+                        buf_size--;  
+
+#define APPEND_STR(str,str_len)  if ((str_len) > buf_size) \
+                                   return byte_count; \
+                                 memcpy(buf,(str),(str_len)); \
+                                 buf += (str_len); \
+                                 byte_count += (str_len); \
+                                 buf_size -= (str_len);
+                                                                                                                                                             
+                                                              
+                        
+#endif
 
 
 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
@@ -85,7 +98,6 @@
   pretty_print_str()
 */
 
-#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 static char *pretty_print_str(char *packet, char *str, int len)
 {
   char *end= str + len;
@@ -110,7 +122,6 @@
   *pos++= '\'';
   return pos;
 }
-#endif /* !MYSQL_CLIENT */
 
 
 /*
@@ -236,16 +247,23 @@
   commands just before it prints a query.
 */
 
-static void print_set_option(FILE* file, uint32 bits_changed, uint32 option,
+static int print_set_option(char* buf, uint buf_size, uint32 bits_changed, uint32 option,
                              uint32 flags, const char* name, bool* need_comma) 
 {
+  int byte_count= 0;
   if (bits_changed & option)
   {
     if (*need_comma)
-      fprintf(file,", ");
-    fprintf(file,"%s=%d", name, test(flags & option));
+    {
+      byte_count += my_snprintf(buf,buf_size,", ");
+      buf_size -= byte_count;
+      buf += byte_count;
+    }  
+    byte_count += my_snprintf(buf,buf_size,"%s=%d", name, 
+      test(flags & option));
     *need_comma= 1;
   }
+  return byte_count;
 }
 
 /**************************************************************************
@@ -761,6 +779,80 @@
   DBUG_RETURN(res);
 }
 
+#ifdef MYSQL_CLIENT
+
+void Log_event::secure_event_buf()
+{
+  uint buf_size = 2 * get_data_size() + EVENT_BUF_PADDING; 
+  if (event_buf_size < buf_size)
+  {
+    event_buf= (char*)my_realloc(event_buf,buf_size,MYF(MY_ALLOW_ZERO_PTR));
+    if (!event_buf)
+    {
+      fprintf(stderr, "Out of memory trying to allocate %d bytes\n",
+        buf_size);
+      exit(1); 
+    }
+    event_buf_size= buf_size;
+  }
+}
+
+void Log_event::flush_event_buf(FILE* file,int bytes_written)
+{
+  if (file)
+    my_fwrite(file,(byte*)event_buf,(uint)bytes_written,MYF(MY_NABP|MY_WME));
+  else if (replay_mysql)
+  {
+    if (mysql_real_query(replay_mysql,event_buf,bytes_written))
+    {
+      fprintf(stderr, "Query %.*s failed: %s\n", bytes_written, event_buf,
+        mysql_error(replay_mysql));
+      mysql_close(replay_mysql);
+      if (!force_replay_opt)
+      { 
+        fprintf(stderr, "Aborting replay because of failed query. Use\
+         --force-replay to override");
+        exit(1);  
+      }  
+      else
+        return;
+    }
+    
+    for (;;)
+    {
+      int error;
+      MYSQL_RES* res;
+      
+      if ((res= mysql_store_result(replay_mysql)))
+      {
+        mysql_free_result(res);  
+      } 
+      else
+      {
+        if (mysql_errno(replay_mysql) != 0)
+          die("Error processing replay query: %s\n", 
+            mysql_error(replay_mysql));
+      }
+      if (!(error= mysql_next_result(replay_mysql)))
+        continue;
+      if (error < 0)
+        break;
+      die("Error processing query in mysql_next_result(): %s", 
+        mysql_error(replay_mysql));    
+    }   
+  }  
+}                                    
+
+void Log_event::print(FILE* file, bool short_form, 
+    LAST_EVENT_INFO* last_event_info)
+{
+  secure_event_buf();
+  flush_event_buf(file,print_to_buf(event_buf,event_buf_size,short_form,
+    last_event_info));
+}    
+
+#endif
+
 
 /*
   Log_event::read_log_event()
@@ -881,22 +973,27 @@
   Log_event::print_header()
 */
 
-void Log_event::print_header(FILE* file)
+int Log_event::print_header(char* buf,uint buf_size)
 {
   char llbuff[22];
-  fputc('#', file);
-  print_timestamp(file);
-  fprintf(file, " server id %d  end_log_pos %s ", server_id,
+  int bytes_written,byte_count= 0;
+  APPEND_CHAR('#');
+  bytes_written= print_timestamp(buf,buf_size);
+  UPDATE_BUF_INFO;
+  bytes_written= my_snprintf(buf,buf_size, " server id %d  end_log_pos %s ", server_id,
 	  llstr(log_pos,llbuff)); 
+  UPDATE_BUF_INFO;  
+  return byte_count;
 }
 
 /*
   Log_event::print_timestamp()
 */
 
-void Log_event::print_timestamp(FILE* file, time_t* ts)
+int Log_event::print_timestamp(char* buf, uint buf_size, time_t* ts)
 {
   struct tm *res;
+  int bytes_written,byte_count= 0;
   if (!ts)
     ts = &when;
 #ifdef MYSQL_SERVER				// This is always false
@@ -906,13 +1003,15 @@
   res=localtime(ts);
 #endif
 
-  fprintf(file,"%02d%02d%02d %2d:%02d:%02d",
+  bytes_written= my_snprintf(buf,buf_size,"%02d%02d%02d %2d:%02d:%02d",
 	  res->tm_year % 100,
 	  res->tm_mon+1,
 	  res->tm_mday,
 	  res->tm_hour,
 	  res->tm_min,
 	  res->tm_sec);
+  UPDATE_BUF_INFO;
+  return byte_count;  
 }
 
 #endif /* MYSQL_CLIENT */
@@ -1372,19 +1471,25 @@
 */
 
 #ifdef MYSQL_CLIENT
-void Query_log_event::print_query_header(FILE* file, bool short_form,
+int Query_log_event::print_query_header(char* buf, uint buf_size,
+ bool short_form,
                                          LAST_EVENT_INFO* last_event_info)
 {
   // TODO: print the catalog ??
+  int byte_count= 0, bytes_written;
   char buff[40],*end;				// Enough for SET TIMESTAMP
   bool different_db= 1;
   uint32 tmp;
 
   if (!short_form)
   {
-    print_header(file);
-    fprintf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
+    bytes_written= print_header(buf,buf_size);
+    UPDATE_BUF_INFO;
+    
+    bytes_written= my_snprintf(buf,buf_size,
+     "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
 	    get_type_str(), (ulong) thread_id, (ulong) exec_time, error_code);
+    UPDATE_BUF_INFO;  
   }
 
   if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
@@ -1392,15 +1497,23 @@
     if (different_db= memcmp(last_event_info->db, db, db_len + 1))
       memcpy(last_event_info->db, db, db_len + 1);
     if (db[0] && different_db) 
-      fprintf(file, "use %s;\n", db);
+    {
+      bytes_written= my_snprintf(buf,buf_size, "use %s;\n", db);
+      UPDATE_BUF_INFO;  
+    }  
   }
 
   end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
   *end++=';';
   *end++='\n';
-  my_fwrite(file, (byte*) buff, (uint) (end-buff),MYF(MY_NABP | MY_WME));
+  APPEND_STR(buff,(uint)(end-buff));
+  
   if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
-    fprintf(file,"SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id);
+  {
+    bytes_written= my_snprintf(buf,buf_size,
+    "SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id);
+    UPDATE_BUF_INFO;  
+  }  
 
   /*
     If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
@@ -1422,14 +1535,22 @@
     if (unlikely(tmp)) /* some bits have changed */
     {
       bool need_comma= 0;
-      fprintf(file, "SET ");
-      print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
+      bytes_written= my_snprintf(buf,buf_size, "SET ");
+      UPDATE_BUF_INFO;  
+      bytes_written= print_set_option(buf,buf_size, tmp,
+       OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
                    "@@session.foreign_key_checks", &need_comma);
-      print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
+      UPDATE_BUF_INFO;               
+      bytes_written= print_set_option(buf,buf_size, tmp, 
+        OPTION_AUTO_IS_NULL, flags2,
                    "@@session.sql_auto_is_null", &need_comma);
-      print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
+      UPDATE_BUF_INFO;               
+      bytes_written= print_set_option(buf,buf_size, tmp,
+       OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
                    "@@session.unique_checks", &need_comma);
-      fprintf(file,";\n");
+      UPDATE_BUF_INFO;               
+      bytes_written= my_snprintf(buf,buf_size,";\n");
+      UPDATE_BUF_INFO;  
       last_event_info->flags2= flags2;
     }
   }
@@ -1457,15 +1578,19 @@
     }
     if (unlikely(last_event_info->sql_mode != sql_mode))
     {
-      fprintf(file,"SET @@session.sql_mode=%lu;\n",(ulong)sql_mode);
+      bytes_written= my_snprintf(buf,buf_size,
+        "SET @@session.sql_mode=%lu;\n",(ulong)sql_mode);
+      UPDATE_BUF_INFO;    
       last_event_info->sql_mode= sql_mode;
     }
   }
   if (last_event_info->auto_increment_increment != auto_increment_increment ||
       last_event_info->auto_increment_offset != auto_increment_offset)
   {
-    fprintf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu;\n",
+    bytes_written= my_snprintf(buf,buf_size,
+    "SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu;\n",
             auto_increment_increment,auto_increment_offset);
+    UPDATE_BUF_INFO;          
     last_event_info->auto_increment_increment= auto_increment_increment;
     last_event_info->auto_increment_offset=    auto_increment_offset;
   }
@@ -1481,7 +1606,7 @@
     }
     if (unlikely(bcmp(last_event_info->charset, charset, 6)))
     {
-      fprintf(file,"SET "
+      bytes_written= my_snprintf(buf,buf_size,"SET "
               "@@session.character_set_client=%d,"
               "@@session.collation_connection=%d,"
               "@@session.collation_server=%d"
@@ -1489,6 +1614,7 @@
               uint2korr(charset),
               uint2korr(charset+2),
               uint2korr(charset+4));
+      UPDATE_BUF_INFO;          
       memcpy(last_event_info->charset, charset, 6);
     }
   }
@@ -1496,19 +1622,30 @@
   {
     if (bcmp(last_event_info->time_zone_str, time_zone_str, time_zone_len+1))
     {
-      fprintf(file,"SET @@session.time_zone='%s';\n", time_zone_str);
+      bytes_written= my_snprintf(buf,buf_size,
+      "SET @@session.time_zone='%s';\n", time_zone_str);
+      UPDATE_BUF_INFO;  
       memcpy(last_event_info->time_zone_str, time_zone_str, time_zone_len+1);
     }
   }
+  
+  return byte_count;
 }
 
 
-void Query_log_event::print(FILE* file, bool short_form,
+int Query_log_event::print_to_buf(char* buf, uint buf_size, bool short_form,
                             LAST_EVENT_INFO* last_event_info)
 {
-  print_query_header(file, short_form, last_event_info);
-  my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
-  fputs(";\n", file);
+  int bytes_written,byte_count= 0; 
+  bytes_written= print_query_header(buf,buf_size, short_form, last_event_info);
+  UPDATE_BUF_INFO;
+  if (buf_size < q_len + 2)
+    return bytes_written;
+  memcpy(buf,query,q_len);
+  buf += q_len;
+  *buf++ = ';';
+  *buf++ = '\n';  
+  return byte_count + q_len + 2;
 }
 #endif /* MYSQL_CLIENT */
 
@@ -1794,20 +1931,35 @@
 */
 
 #ifdef MYSQL_CLIENT
-void Start_log_event_v3::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+int Start_log_event_v3::print_to_buf(char* buf, uint buf_size, 
+   bool short_form, LAST_EVENT_INFO* last_event_info)
 {
+  int bytes_written,byte_count= 0;
   if (!short_form)
   {
-    print_header(file);
-    fprintf(file, "\tStart: binlog v %d, server v %s created ", binlog_version,
+    bytes_written= print_header(buf,buf_size);
+    UPDATE_BUF_INFO;
+    bytes_written= my_snprintf(buf,buf_size, 
+      "\tStart: binlog v %d, server v %s created ", binlog_version,
             server_version);
-    print_timestamp(file);
+    UPDATE_BUF_INFO;        
+    bytes_written= print_timestamp(buf,buf_size);
+    UPDATE_BUF_INFO;
     if (created)
-      fprintf(file," at startup");
-    fputc('\n', file);
+    {
+      bytes_written= my_snprintf(buf,buf_size," at startup");
+      UPDATE_BUF_INFO;
+    }  
+    
+    APPEND_CHAR('\n');
+    
     if (flags & LOG_EVENT_BINLOG_IN_USE_F)
-      fprintf(file, "# Warning: this binlog was not closed properly. "
+    {
+      bytes_written= my_snprintf(buf,buf_size,
+       "# Warning: this binlog was not closed properly. "
               "Most probably mysqld crashed writing it.\n");
+      UPDATE_BUF_INFO;        
+    }          
   }
   if (!artificial_event && created)
   {
@@ -1818,12 +1970,14 @@
       and rollback unfinished transaction.
       Probably this can be done with RESET CONNECTION (syntax to be defined).
     */
-    fprintf(file,"RESET CONNECTION;\n");
+    bytes_written= my_snprintf(buf,buf_size,"RESET CONNECTION;\n");
+    UPDATE_BUF_INFO;
 #else
-    fprintf(file,"ROLLBACK;\n");
+    bytes_written= my_snprintf(buf,buf_size,"ROLLBACK;\n");
+    UPDATE_BUF_INFO;
 #endif
   }
-  fflush(file);
+  return byte_count;
 }
 #endif /* MYSQL_CLIENT */
 
@@ -2522,21 +2676,26 @@
 */
 
 #ifdef MYSQL_CLIENT
-void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+int Load_log_event::print_to_buf(char* buf, uint buf_size, bool short_form, LAST_EVENT_INFO* last_event_info)
 {
-  print(file, short_form, last_event_info, 0);
+  return print_to_buf(buf, buf_size, short_form, last_event_info, 0);
 }
 
 
-void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info,
+int Load_log_event::print_to_buf(char* buf, uint buf_size, bool short_form, LAST_EVENT_INFO* last_event_info,
 			   bool commented)
 {
+  int bytes_written,byte_count= 0;
+  char* tmp;
   DBUG_ENTER("Load_log_event::print");
   if (!short_form)
   {
-    print_header(file);
-    fprintf(file, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
+    bytes_written= print_header(buf,buf_size);
+    UPDATE_BUF_INFO;
+    bytes_written= my_snprintf(buf,buf_size, 
+      "\tQuery\tthread_id=%ld\texec_time=%ld\n",
 	    thread_id, exec_time);
+    UPDATE_BUF_INFO;  
   }
 
   bool different_db= 1;
@@ -2554,66 +2713,97 @@
   }
   
   if (db && db[0] && different_db)
-    fprintf(file, "%suse %s;\n", 
+  {
+    bytes_written= my_snprintf(buf,buf_size, "%suse %s;\n", 
             commented ? "# " : "",
             db);
+    UPDATE_BUF_INFO;        
+  }          
 
   if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
-    fprintf(file,"%sSET @@session.pseudo_thread_id=%lu;\n",
+  {
+    bytes_written= my_snprintf(buf,buf_size,
+    "%sSET @@session.pseudo_thread_id=%lu;\n",
             commented ? "# " : "", (ulong)thread_id);
-  fprintf(file, "%sLOAD DATA ",
+    UPDATE_BUF_INFO;        
+  }          
+  bytes_written= my_snprintf(buf,buf_size, "%sLOAD DATA ",
           commented ? "# " : "");
+  UPDATE_BUF_INFO;        
   if (check_fname_outside_temp_buf())
-    fprintf(file, "LOCAL ");
-  fprintf(file, "INFILE '%-*s' ", fname_len, fname);
-
+  {
+    bytes_written= my_snprintf(buf,buf_size, "LOCAL ");
+    UPDATE_BUF_INFO;
+  }  
+  bytes_written= my_snprintf(buf,buf_size, "INFILE '%-*s' ", fname_len, fname);
+  UPDATE_BUF_INFO;
+  
   if (sql_ex.opt_flags & REPLACE_FLAG)
-    fprintf(file," REPLACE ");
+  {
+    bytes_written= my_snprintf(buf,buf_size," REPLACE ");
+    UPDATE_BUF_INFO;
+  }  
   else if (sql_ex.opt_flags & IGNORE_FLAG)
-    fprintf(file," IGNORE ");
+  {
+    bytes_written= my_snprintf(buf,buf_size," IGNORE ");
+    UPDATE_BUF_INFO;
+  }  
+  
+  bytes_written= my_snprintf(buf,buf_size, 
+    "INTO TABLE `%s` FIELDS TERMINATED BY ", table_name);
+  UPDATE_BUF_INFO;
+  APPEND_PRETTY(sql_ex.field_term, (uint)sql_ex.field_term_len);
   
-  fprintf(file, "INTO TABLE `%s`", table_name);
-  fprintf(file, " FIELDS TERMINATED BY ");
-  pretty_print_str(file, sql_ex.field_term, sql_ex.field_term_len);
-
   if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
-    fprintf(file," OPTIONALLY ");
-  fprintf(file, " ENCLOSED BY ");
-  pretty_print_str(file, sql_ex.enclosed, sql_ex.enclosed_len);
+  {
+    bytes_written= my_snprintf(buf,buf_size," OPTIONALLY ");
+    UPDATE_BUF_INFO;
+  }  
+  bytes_written= my_snprintf(buf,buf_size, " ENCLOSED BY ");
+  APPEND_PRETTY(sql_ex.enclosed, (uint)sql_ex.enclosed_len);
      
-  fprintf(file, " ESCAPED BY ");
-  pretty_print_str(file, sql_ex.escaped, sql_ex.escaped_len);
+  bytes_written= my_snprintf(buf,buf_size, " ESCAPED BY ");
+  APPEND_PRETTY(sql_ex.escaped, (uint)sql_ex.escaped_len);
      
-  fprintf(file," LINES TERMINATED BY ");
-  pretty_print_str(file, sql_ex.line_term, sql_ex.line_term_len);
+  bytes_written= my_snprintf(buf,buf_size," LINES TERMINATED BY ");
+  APPEND_PRETTY(sql_ex.line_term, (uint)sql_ex.line_term_len);
 
 
   if (sql_ex.line_start)
   {
-    fprintf(file," STARTING BY ");
-    pretty_print_str(file, sql_ex.line_start, sql_ex.line_start_len);
+    bytes_written= my_snprintf(buf,buf_size," STARTING BY ");
+    APPEND_PRETTY(sql_ex.line_start, (uint)sql_ex.line_start_len);
   }
   if ((long) skip_lines > 0)
-    fprintf(file, " IGNORE %ld LINES", (long) skip_lines);
+  {
+    bytes_written= my_snprintf(buf,buf_size, " IGNORE %ld LINES", 
+      (long) skip_lines);
+    UPDATE_BUF_INFO;  
+  }    
 
   if (num_fields)
   {
     uint i;
     const char* field = fields;
-    fprintf(file, " (");
+    bytes_written= my_snprintf(buf,buf_size, " (");
+    UPDATE_BUF_INFO;
     for (i = 0; i < num_fields; i++)
     {
       if (i)
-	fputc(',', file);
-      fprintf(file, field);
+      {
+        APPEND_CHAR(',');
+      }  
+      bytes_written= my_snprintf(buf,buf_size, field);
+      UPDATE_BUF_INFO;
 	  
       field += field_lens[i]  + 1;
     }
-    fputc(')', file);
+    APPEND_CHAR(')');
   }
 
-  fprintf(file, ";\n");
-  DBUG_VOID_RETURN;
+  bytes_written= my_snprintf(buf,buf_size, ";\n");
+  UPDATE_BUF_INFO;
+  DBUG_RETURN(byte_count);
 }
 #endif /* MYSQL_CLIENT */
 
@@ -2929,20 +3119,26 @@
 */
 
 #ifdef MYSQL_CLIENT
-void Rotate_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+int Rotate_log_event::print_to_buf(char* buf, uint buf_size, bool short_form, LAST_EVENT_INFO* last_event_info)
 {
-  char buf[22];
+  int bytes_written,byte_count= 0;
+  char num_buf[22];
 
   if (short_form)
-    return;
-  print_header(file);
-  fprintf(file, "\tRotate to ");
+    return 0;
+  bytes_written= print_header(buf,buf_size);
+  UPDATE_BUF_INFO;
+  bytes_written= my_snprintf(buf,buf_size, "\tRotate to ");
+  UPDATE_BUF_INFO;
   if (new_log_ident)
-    my_fwrite(file, (byte*) new_log_ident, (uint)ident_len, 
-              MYF(MY_NABP | MY_WME));
-  fprintf(file, "  pos: %s", llstr(pos, buf));
-  fputc('\n', file);
-  fflush(file);
+  {
+    APPEND_STR(new_log_ident,ident_len);
+  }            
+  bytes_written= my_snprintf(buf,buf_size, "  pos: %s", 
+    llstr(pos, num_buf));
+  UPDATE_BUF_INFO;
+  APPEND_CHAR('\n');
+  return byte_count;
 }
 #endif /* MYSQL_CLIENT */
 
@@ -3131,20 +3327,24 @@
 */
 
 #ifdef MYSQL_CLIENT
-void Intvar_log_event::print(FILE* file, bool short_form,
+int Intvar_log_event::print_to_buf(char* buf, uint buf_size, bool short_form,
                              LAST_EVENT_INFO* last_event_info)
 {
+  int bytes_written,byte_count= 0;
   char llbuff[22];
   const char *msg;
   LINT_INIT(msg);
 
   if (!short_form)
   {
-    print_header(file);
-    fprintf(file, "\tIntvar\n");
+    bytes_written= print_header(buf,buf_size);
+    UPDATE_BUF_INFO;
+    bytes_written= my_snprintf(buf,buf_size, "\tIntvar\n");
+    UPDATE_BUF_INFO;
   }
 
-  fprintf(file, "SET ");
+  bytes_written= my_snprintf(buf,buf_size, "SET ");
+  UPDATE_BUF_INFO;
   switch (type) {
   case LAST_INSERT_ID_EVENT:
     msg="LAST_INSERT_ID";
@@ -3153,8 +3353,9 @@
     msg="INSERT_ID";
     break;
   }
-  fprintf(file, "%s=%s;\n", msg, llstr(val,llbuff));
-  fflush(file);
+  bytes_written= my_snprintf(buf,buf_size, "%s=%s;\n", msg, llstr(val,llbuff));
+  UPDATE_BUF_INFO;
+  return byte_count;
 }
 #endif
 
@@ -3221,17 +3422,21 @@
 
 
 #ifdef MYSQL_CLIENT
-void Rand_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+int Rand_log_event::print_to_buf(char* buf, uint buf_size, bool short_form, LAST_EVENT_INFO* last_event_info)
 {
+  int bytes_written,byte_count= 0;
   char llbuff[22],llbuff2[22];
   if (!short_form)
   {
-    print_header(file);
-    fprintf(file, "\tRand\n");
+    bytes_written= print_header(buf,buf_size);
+    bytes_written= my_snprintf(buf,buf_size, "\tRand\n");
+    UPDATE_BUF_INFO;
   }
-  fprintf(file, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;\n",
+  bytes_written= my_snprintf(buf,buf_size, 
+  "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s;\n",
 	  llstr(seed1, llbuff),llstr(seed2, llbuff2));
-  fflush(file);
+  UPDATE_BUF_INFO;  
+  return byte_count;
 }
 #endif /* MYSQL_CLIENT */
 
@@ -3291,18 +3496,22 @@
 
 
 #ifdef MYSQL_CLIENT
-void Xid_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+int Xid_log_event::print_to_buf(char* buf, uint buf_size, bool short_form, LAST_EVENT_INFO* last_event_info)
 {
+  int bytes_written,byte_count= 0;
   if (!short_form)
   {
-    char buf[64];
-    longlong10_to_str(xid, buf, 10);
+    char num_buf[64];
+    longlong10_to_str(xid, num_buf, 10);
 
-    print_header(file);
-    fprintf(file, "\tXid = %s\n", buf);
-    fflush(file);
-  }
-  fprintf(file, "COMMIT;\n");
+    bytes_written= print_header(buf,buf_size);
+    UPDATE_BUF_INFO;
+    bytes_written= my_snprintf(buf,buf_size, "\tXid = %s\n", num_buf);
+    UPDATE_BUF_INFO;
+  }
+  bytes_written= my_snprintf(buf,buf_size, "COMMIT;\n");
+  UPDATE_BUF_INFO;
+  return byte_count;
 }
 #endif /* MYSQL_CLIENT */
 
@@ -3489,21 +3698,27 @@
 */
 
 #ifdef MYSQL_CLIENT
-void User_var_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+int User_var_log_event::print_to_buf(char* buf, uint buf_size, bool short_form, LAST_EVENT_INFO* last_event_info)
 {
+  int bytes_written,byte_count= 0;
+  
   if (!short_form)
   {
-    print_header(file);
-    fprintf(file, "\tUser_var\n");
+    bytes_written= print_header(buf,buf_size);
+    UPDATE_BUF_INFO;
+    bytes_written= my_snprintf(buf,buf_size, "\tUser_var\n");
+    UPDATE_BUF_INFO;
   }
 
-  fprintf(file, "SET @`");
-  my_fwrite(file, (byte*) name, (uint) (name_len), MYF(MY_NABP | MY_WME));
-  fprintf(file, "`");
+  bytes_written= my_snprintf(buf,buf_size, "SET @`");
+  UPDATE_BUF_INFO;
+  APPEND_STR(name,name_len);
+  APPEND_CHAR('`');
 
   if (is_null)
   {
-    fprintf(file, ":=NULL;\n");
+    bytes_written= my_snprintf(buf,buf_size, ":=NULL;\n");
+    UPDATE_BUF_INFO;
   }
   else
   {
@@ -3511,12 +3726,14 @@
     case REAL_RESULT:
       double real_val;
       float8get(real_val, val);
-      fprintf(file, ":=%.14g;\n", real_val);
+      bytes_written= my_snprintf(buf,buf_size, ":=%.14g;\n", real_val);
+      UPDATE_BUF_INFO;
       break;
     case INT_RESULT:
       char int_buf[22];
       longlong10_to_str(uint8korr(val), int_buf, -10);
-      fprintf(file, ":=%s;\n", int_buf);
+      bytes_written= my_snprintf(buf,buf_size, ":=%s;\n", int_buf);
+      UPDATE_BUF_INFO;
       break;
     case DECIMAL_RESULT:
     {
@@ -3532,7 +3749,8 @@
       bin2decimal(val+2, &dec, precision, scale);
       decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
       str_buf[str_len]= 0;
-      fprintf(file, ":=%s;\n",str_buf);
+      bytes_written= my_snprintf(buf,buf_size, ":=%s;\n",str_buf);
+      UPDATE_BUF_INFO;
       break;
     }
     case STRING_RESULT:
@@ -3564,23 +3782,30 @@
         character set. But there's not much to do about this and it's unlikely.
       */
       if (!(cs= get_charset(charset_number, MYF(0))))
+      {
         /*
           Generate an unusable command (=> syntax error) is probably the best
           thing we can do here.
         */
-        fprintf(file, ":=???;\n");
+        bytes_written= my_snprintf(buf,buf_size, ":=???;\n");
+        UPDATE_BUF_INFO;
+      }  
       else
-        fprintf(file, ":=_%s %s COLLATE `%s`;\n", cs->csname, hex_str, cs->name);
+      {
+        bytes_written= my_snprintf(buf,buf_size, 
+          ":=_%s %s COLLATE `%s`;\n", cs->csname, hex_str, cs->name);
+        UPDATE_BUF_INFO;  
+      }  
       my_afree(hex_str);
     }
       break;
     case ROW_RESULT:
     default:
       DBUG_ASSERT(1);
-      return;
+      return byte_count;
     }
   }
-  fflush(file);
+  return byte_count;
 }
 #endif
 
@@ -3664,13 +3889,17 @@
 
 #ifdef HAVE_REPLICATION
 #ifdef MYSQL_CLIENT
-void Unknown_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+int Unknown_log_event::print_to_buf(char* buf, uint buf_size, bool short_form, LAST_EVENT_INFO* last_event_info)
 {
+  int bytes_written,byte_count= 0;
   if (short_form)
-    return;
-  print_header(file);
-  fputc('\n', file);
-  fprintf(file, "# %s", "Unknown event\n");
+    return 0;
+  bytes_written= print_header(buf,buf_size);
+  UPDATE_BUF_INFO;
+  APPEND_CHAR('\n');
+  bytes_written= my_snprintf(buf,buf_size, "# %s", "Unknown event\n");
+  UPDATE_BUF_INFO;
+  return byte_count;
 }
 #endif  
 
@@ -3735,16 +3964,21 @@
 
 
 #ifdef MYSQL_CLIENT
-void Slave_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+int Slave_log_event::print_to_buf(char* buf, uint buf_size, bool short_form, LAST_EVENT_INFO* last_event_info)
 {
+  int bytes_written,byte_count= 0;
   char llbuff[22];
   if (short_form)
-    return;
-  print_header(file);
-  fputc('\n', file);
-  fprintf(file, "\
+    return 0;
+  bytes_written= print_header(buf,buf_size);
+  UPDATE_BUF_INFO;
+  APPEND_CHAR('\n');
+  
+  bytes_written= my_snprintf(buf,buf_size, "\
 Slave: master_host: '%s'  master_port: %d  master_log: '%s'  master_pos: %s\n",
 	  master_host, master_port, master_log, llstr(master_pos, llbuff));
+  UPDATE_BUF_INFO;
+  return byte_count;  
 }
 #endif /* MYSQL_CLIENT */
 
@@ -3820,14 +4054,17 @@
 */
 
 #ifdef MYSQL_CLIENT
-void Stop_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
+int Stop_log_event::print_to_buf(char* buf, uint buf_size, bool short_form, LAST_EVENT_INFO* last_event_info)
 {
+  int bytes_written,byte_count= 0;
   if (short_form)
-    return;
+    return 0;
 
-  print_header(file);
-  fprintf(file, "\tStop\n");
-  fflush(file);
+  bytes_written= print_header(buf,buf_size);
+  UPDATE_BUF_INFO;
+  bytes_written= my_snprintf(buf,buf_size, "\tStop\n");
+  UPDATE_BUF_INFO;
+  return byte_count;
 }
 #endif /* MYSQL_CLIENT */
 
@@ -3999,34 +4236,50 @@
 */
 
 #ifdef MYSQL_CLIENT
-void Create_file_log_event::print(FILE* file, bool short_form, 
+
+void Create_file_log_event::print(FILE* file,bool short_form,
+   LAST_EVENT_INFO* last_event_info, bool enable_local)
+{
+  secure_event_buf();
+  flush_event_buf(file,print_to_buf(::event_buf,event_buf_size,short_form,
+    last_event_info,enable_local));
+}   
+
+
+int Create_file_log_event::print_to_buf(char* buf, uint buf_size, bool short_form, 
 				  LAST_EVENT_INFO* last_event_info, bool enable_local)
 {
+  int bytes_written,byte_count= 0;
   if (short_form)
   {
     if (enable_local && check_fname_outside_temp_buf())
-      Load_log_event::print(file, 1, last_event_info);
-    return;
+      return Load_log_event::print_to_buf(buf,buf_size, 1, last_event_info);
   }
 
   if (enable_local)
   {
-    Load_log_event::print(file, short_form, last_event_info, !check_fname_outside_temp_buf());
+    bytes_written= Load_log_event::print_to_buf(buf,buf_size, short_form,
+     last_event_info, !check_fname_outside_temp_buf());
+    UPDATE_BUF_INFO; 
     /* 
        That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
        SHOW BINLOG EVENTS we don't.
     */
-    fprintf(file, "#"); 
+    bytes_written= my_snprintf(buf,buf_size, "#"); 
+    UPDATE_BUF_INFO;
   }
 
-  fprintf(file, " file_id: %d  block_len: %d\n", file_id, block_len);
+  bytes_written= my_snprintf(buf,buf_size, 
+    " file_id: %d  block_len: %d\n", file_id, block_len);
+  UPDATE_BUF_INFO;
+  return byte_count;  
 }
 
 
-void Create_file_log_event::print(FILE* file, bool short_form,
+int Create_file_log_event::print_to_buf(char* buf, uint buf_size, bool short_form,
 				  LAST_EVENT_INFO* last_event_info)
 {
-  print(file,short_form,last_event_info,0);
+  return print_to_buf(buf,buf_size,short_form,last_event_info,0);
 }
 #endif /* MYSQL_CLIENT */
 
@@ -4186,15 +4439,20 @@
 */
 
 #ifdef MYSQL_CLIENT  
-void Append_block_log_event::print(FILE* file, bool short_form,
+int Append_block_log_event::print_to_buf(char* buf, uint buf_size, bool short_form,
 				   LAST_EVENT_INFO* last_event_info)
 {
+  int bytes_written,byte_count= 0;
   if (short_form)
-    return;
-  print_header(file);
-  fputc('\n', file);
-  fprintf(file, "#%s: file_id: %d  block_len: %d\n",
+    return 0;
+  bytes_written= print_header(buf,buf_size);
+  UPDATE_BUF_INFO;
+  APPEND_CHAR('\n');
+  
+  bytes_written= my_snprintf(buf,buf_size, "#%s: file_id: %d  block_len: %d\n",
 	  get_type_str(), file_id, block_len);
+  UPDATE_BUF_INFO;
+  return byte_count;  
 }
 #endif /* MYSQL_CLIENT */
 
@@ -4330,14 +4588,19 @@
 */
 
 #ifdef MYSQL_CLIENT  
-void Delete_file_log_event::print(FILE* file, bool short_form,
+int Delete_file_log_event::print_to_buf(char* buf, uint buf_size, bool short_form,
 				  LAST_EVENT_INFO* last_event_info)
 {
+  int bytes_written,byte_count= 0;
   if (short_form)
-    return;
-  print_header(file);
-  fputc('\n', file);
-  fprintf(file, "#Delete_file: file_id=%u\n", file_id);
+    return 0;
+  bytes_written= print_header(buf,buf_size);
+  UPDATE_BUF_INFO;
+  APPEND_CHAR('\n');
+  bytes_written= my_snprintf(buf,buf_size, "#Delete_file: file_id=%u\n",
+   file_id);
+  UPDATE_BUF_INFO;
+  return byte_count; 
 }
 #endif /* MYSQL_CLIENT */
 
@@ -4426,15 +4689,19 @@
 */
 
 #ifdef MYSQL_CLIENT  
-void Execute_load_log_event::print(FILE* file, bool short_form,
+int Execute_load_log_event::print_to_buf(char* buf, uint buf_size, bool short_form,
 				   LAST_EVENT_INFO* last_event_info)
 {
+  int bytes_written,byte_count= 0;
   if (short_form)
-    return;
-  print_header(file);
-  fputc('\n', file);
-  fprintf(file, "#Exec_load: file_id=%d\n",
+    return 0;
+  bytes_written= print_header(buf,buf_size);
+  UPDATE_BUF_INFO;
+  APPEND_CHAR('\n');
+  bytes_written= my_snprintf(buf,buf_size, "#Exec_load: file_id=%d\n",
 	  file_id);
+  UPDATE_BUF_INFO;
+  return byte_count;  
 }
 #endif
 
@@ -4638,40 +4905,64 @@
 
 
 #ifdef MYSQL_CLIENT
-void Execute_load_query_log_event::print(FILE* file, bool short_form,
+int Execute_load_query_log_event::print_to_buf(char* buf, uint buf_size, bool short_form,
                                          LAST_EVENT_INFO* last_event_info)
 {
-  print(file, short_form, last_event_info, 0);
+  return print_to_buf(buf,buf_size, short_form, last_event_info, 0);
 }
 
+void Execute_load_query_log_event::print(FILE* file, bool short_form, 
+    LAST_EVENT_INFO* last_event_info,
+    const char *local_fname)
+{
+  secure_event_buf();
+  flush_event_buf(file,print_to_buf(event_buf,event_buf_size,short_form,
+    last_event_info,local_fname));
+}    
+
 
-void Execute_load_query_log_event::print(FILE* file, bool short_form,
+int Execute_load_query_log_event::print_to_buf(char* buf, uint buf_size, bool short_form,
                                          LAST_EVENT_INFO* last_event_info,
                                          const char *local_fname)
 {
-  print_query_header(file, short_form, last_event_info);
-
+  int bytes_written,byte_count= 0;
+  bytes_written= print_query_header(buf,buf_size, short_form, last_event_info);
+  UPDATE_BUF_INFO;
+  
   if (local_fname)
   {
-    my_fwrite(file, (byte*) query, fn_pos_start, MYF(MY_NABP | MY_WME));
-    fprintf(file, " LOCAL INFILE \'");
-    fprintf(file, local_fname);
-    fprintf(file, "\'");
+    APPEND_STR(query,fn_pos_start);
+    
+    bytes_written= my_snprintf(buf,buf_size, " LOCAL INFILE \'");
+    UPDATE_BUF_INFO;
+    bytes_written= my_snprintf(buf,buf_size, local_fname);
+    UPDATE_BUF_INFO;
+    bytes_written= my_snprintf(buf,buf_size, "\'");
+    UPDATE_BUF_INFO;
     if (dup_handling == LOAD_DUP_REPLACE)
-      fprintf(file, " REPLACE");
-    fprintf(file, " INTO");
-    my_fwrite(file, (byte*) query + fn_pos_end, q_len-fn_pos_end,
-        MYF(MY_NABP | MY_WME));
-    fprintf(file, ";\n");
+    {
+      bytes_written= my_snprintf(buf,buf_size, " REPLACE");
+      UPDATE_BUF_INFO;
+    }  
+    bytes_written= my_snprintf(buf,buf_size, " INTO");
+    UPDATE_BUF_INFO;
+    APPEND_STR((byte*)query + fn_pos_end, q_len-fn_pos_end);
+    bytes_written= my_snprintf(buf,buf_size, ";\n");
+    UPDATE_BUF_INFO;
   }
   else
   {
-    my_fwrite(file, (byte*) query, q_len, MYF(MY_NABP | MY_WME));
-    fprintf(file, ";\n");
+    APPEND_STR(query,q_len);
+    bytes_written= my_snprintf(buf,buf_size, ";\n");
+    UPDATE_BUF_INFO;
   }
 
   if (!short_form)
-    fprintf(file, "# file_id: %d \n", file_id);
+  {
+    bytes_written= my_snprintf(buf,buf_size, "# file_id: %d \n", file_id);
+    UPDATE_BUF_INFO;
+  }  
+  return byte_count;
 }
 #endif
 

--- 1.114/sql/log_event.h	2005-08-19 12:55:19 -06:00
+++ 1.115/sql/log_event.h	2005-10-21 22:05:26 -06:00
@@ -588,10 +588,17 @@
     /* avoid having to link mysqlbinlog against libpthread */
   static Log_event* read_log_event(IO_CACHE* file,
                                    const Format_description_log_event *description_event);
+  
+  /* helper methods for print() */                                   
+  void secure_event_buf();
+  void flush_event_buf(FILE* file,int bytes_written);                                                                  
+                                   
   /* print*() functions are used by mysqlbinlog */
-  virtual void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0) = 0;
-  void print_timestamp(FILE* file, time_t *ts = 0);
-  void print_header(FILE* file);
+  void print(FILE* file, bool short_form = 0, 
+    LAST_EVENT_INFO* last_event_info= 0);
+  virtual int print_to_buf(char* buf, uint buf_size, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0) = 0;
+  int print_timestamp(char* buf, uint buf_size, time_t *ts = 0);
+  int print_header(char* buf, uint buf_size);
 #endif
 
   static void *operator new(size_t size)
@@ -751,8 +758,8 @@
                  uint32 q_len_arg);
 #endif /* HAVE_REPLICATION */
 #else
-  void print_query_header(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_query_header(char* buf, uint buf_size, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
 #endif
 
   Query_log_event(const char* buf, uint event_len,
@@ -806,7 +813,8 @@
   void pack_info(Protocol* protocol);
   int exec_event(struct st_relay_log_info* rli);
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0,
+   LAST_EVENT_INFO* last_event_info= 0);
 #endif
 
   Slave_log_event(const char* buf, uint event_len);
@@ -894,8 +902,10 @@
 		 bool use_rli_only_for_errors);
 #endif /* HAVE_REPLICATION */
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info = 0);
-  void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, bool commented);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0,
+   LAST_EVENT_INFO* last_event_info = 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form, 
+    LAST_EVENT_INFO* last_event_info, bool commented);
 #endif
 
   /*
@@ -984,7 +994,8 @@
 #endif /* HAVE_REPLICATION */
 #else
   Start_log_event_v3() {}
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0,
+   LAST_EVENT_INFO* last_event_info= 0);
 #endif
 
   Start_log_event_v3(const char* buf,
@@ -1079,7 +1090,8 @@
   int exec_event(struct st_relay_log_info* rli);
 #endif /* HAVE_REPLICATION */
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0,
+   LAST_EVENT_INFO* last_event_info= 0);
 #endif
 
   Intvar_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1120,7 +1132,8 @@
   int exec_event(struct st_relay_log_info* rli);
 #endif /* HAVE_REPLICATION */
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0, 
+    LAST_EVENT_INFO* last_event_info= 0);
 #endif
 
   Rand_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1157,7 +1170,8 @@
   int exec_event(struct st_relay_log_info* rli);
 #endif /* HAVE_REPLICATION */
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0,
+   LAST_EVENT_INFO* last_event_info= 0);
 #endif
 
   Xid_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1202,7 +1216,8 @@
   void pack_info(Protocol* protocol);
   int exec_event(struct st_relay_log_info* rli);
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0,
+   LAST_EVENT_INFO* last_event_info= 0);
 #endif
 
   User_var_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1228,7 +1243,8 @@
   {}
   int exec_event(struct st_relay_log_info* rli);
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0,
+   LAST_EVENT_INFO* last_event_info= 0);
 #endif
 
   Stop_log_event(const char* buf, const Format_description_log_event* description_event):
@@ -1267,7 +1283,8 @@
   int exec_event(struct st_relay_log_info* rli);
 #endif /* HAVE_REPLICATION */
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0, 
+    LAST_EVENT_INFO* last_event_info= 0);
 #endif
 
   Rotate_log_event(const char* buf, uint event_len,
@@ -1320,8 +1337,12 @@
   int exec_event(struct st_relay_log_info* rli);
 #endif /* HAVE_REPLICATION */
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
-  void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, bool enable_local);
+  void print(FILE* file,bool short_form,
+   LAST_EVENT_INFO* last_event_info, bool enable_local);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0,
+   LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form,
+   LAST_EVENT_INFO* last_event_info, bool enable_local);
 #endif
 
   Create_file_log_event(const char* buf, uint event_len,
@@ -1388,7 +1409,8 @@
   virtual int get_create_or_append() const;
 #endif /* HAVE_REPLICATION */
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size,bool short_form = 0,
+   LAST_EVENT_INFO* last_event_info= 0);
 #endif
 
   Append_block_log_event(const char* buf, uint event_len,
@@ -1423,8 +1445,8 @@
   int exec_event(struct st_relay_log_info* rli);
 #endif /* HAVE_REPLICATION */
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
-  void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info, bool enable_local);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form, LAST_EVENT_INFO* last_event_info, bool enable_local);
 #endif
 
   Delete_file_log_event(const char* buf, uint event_len,
@@ -1459,7 +1481,7 @@
   int exec_event(struct st_relay_log_info* rli);
 #endif /* HAVE_REPLICATION */
 #else
-  void print(FILE* file, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0, LAST_EVENT_INFO* last_event_info= 0);
 #endif
 
   Execute_load_log_event(const char* buf, uint event_len,
@@ -1544,10 +1566,13 @@
   int exec_event(struct st_relay_log_info* rli);
 #endif /* HAVE_REPLICATION */
 #else
-  void print(FILE* file, bool short_form = 0,
+  void print(FILE* file, bool short_form, 
+    LAST_EVENT_INFO* last_event_info,
+    const char *local_fname);
+  int print_to_buf(char* buf, uint buf_size, bool short_form = 0,
              LAST_EVENT_INFO* last_event_info= 0);
   /* Prints the query as LOAD DATA LOCAL and with rewritten filename */
-  void print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info,
+  int print_to_buf(char* buf, uint buf_size, bool short_form, LAST_EVENT_INFO* last_event_info,
              const char *local_fname);
 #endif
   Execute_load_query_log_event(const char* buf, uint event_len,
@@ -1577,7 +1602,7 @@
     Log_event(buf, description_event)
   {}
   ~Unknown_log_event() {}
-  void print(FILE* file, bool short_form= 0, LAST_EVENT_INFO* last_event_info= 0);
+  int print_to_buf(char* buf, uint buf_size, bool short_form= 0, LAST_EVENT_INFO* last_event_info= 0);
   Log_event_type get_type_code() { return UNKNOWN_EVENT;}
   bool is_valid() const { return 1; }
 };

--- 1.113/client/mysqlbinlog.cc	2005-08-26 06:56:46 -06:00
+++ 1.114/client/mysqlbinlog.cc	2005-10-21 22:05:26 -06:00
@@ -64,6 +64,7 @@
 static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0;
 static const char* database= 0;
 static my_bool force_opt= 0, short_form= 0, remote_opt= 0;
+static my_bool replay_opt= 0;
 static ulonglong offset = 0;
 static const char* host = 0;
 static int port = MYSQL_PORT;
@@ -71,6 +72,17 @@
 static const char* user = 0;
 static char* pass = 0;
 
+/* Options for the binary log content replay */
+static const char* replay_host= 0;
+static int replay_port= MYSQL_PORT;
+static const char* replay_sock= 0;
+static const char* replay_user= 0;
+static char* replay_pass= 0;
+static const char* replay_db= 0;
+static char replay_temp_fname[FN_REFLEN];
+MYSQL* replay_mysql= 0;
+my_bool force_replay_opt= 0;
+
 static ulonglong start_position, stop_position;
 #define start_position_mot ((my_off_t)start_position)
 #define stop_position_mot  ((my_off_t)stop_position)
@@ -96,8 +108,13 @@
 static int dump_log_entries(const char* logname);
 static int dump_remote_file(NET* net, const char* fname);
 static void die(const char* fmt, ...);
-static MYSQL* safe_connect();
-
+static MYSQL* safe_connect(const char* l_host, const char* l_user, 
+  const char* l_pass, const char* l_db, int l_port, const char* l_sock,
+  uint l_protocol);
+
+static void init_replay();
+static void end_replay();
+static void safe_fprintf(FILE* file, const char* fmt, ...);
 
 class Load_log_processor
 {
@@ -488,6 +505,13 @@
 */
 
 
+static void safe_fprintf(FILE* file, const char* fmt, ...)
+{
+  va_list ap;
+  va_start(ap,fmt);
+  if (file)
+    vfprintf(file,fmt,ap);
+}
 
 int process_event(LAST_EVENT_INFO *last_event_info, Log_event *ev,
                   my_off_t pos)
@@ -520,8 +544,10 @@
       stop_passed= 1; // skip all next binlogs
       DBUG_RETURN(-1);
     }
+    
+    
     if (!short_form)
-      fprintf(result_file, "# at %s\n",llstr(pos,ll_buff));
+      safe_fprintf(result_file, "# at %s\n",llstr(pos,ll_buff));
     
     switch (ev_type) {
     case QUERY_EVENT:
@@ -667,6 +693,11 @@
   {"force-read", 'f', "Force reading unknown binlog events.",
    (gptr*) &force_opt, (gptr*) &force_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
    0, 0},
+  {"force-replay", OPT_FORCE_REPLAY, 
+    "Continue replaying queries even if an error occurs.",
+   (gptr*) &force_replay_opt, (gptr*) &force_replay_opt, 0, GET_BOOL, 
+   NO_ARG, 0, 0, 0, 0,
+   0, 0},
   {"help", '?', "Display this help and exit.",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"host", 'h', "Get the binlog from server.", (gptr*) &host, (gptr*) &host,
@@ -691,6 +722,9 @@
   {"read-from-remote-server", 'R', "Read binary logs from a MySQL server",
    (gptr*) &remote_opt, (gptr*) &remote_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
    0, 0},
+  {"write-to-remote-server", 'W', "Replay binary logs on a MySQL server",
+   (gptr*) &replay_opt, (gptr*) &replay_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+   0, 0},
   {"open_files_limit", OPT_OPEN_FILES_LIMIT,
    "Used to reserve file descriptors for usage by this program",
    (gptr*) &open_files_limit, (gptr*) &open_files_limit, 0, GET_ULONG,
@@ -742,6 +776,31 @@
   {"local-load", 'l', "Prepare local temporary files for LOAD DATA INFILE in the specified directory.",
    (gptr*) &dirname_for_local_load, (gptr*) &dirname_for_local_load, 0,
    GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"replay-host", OPT_REPLAY_HOST,
+     "MySQL server to replay the contents of the binary logs on.",
+     (gptr*) &replay_host, (gptr*) &replay_host, 0, GET_STR_ALLOC,
+     REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 
+  {"replay-user", OPT_REPLAY_USER,
+     "The user on the replay-host.",
+     (gptr*) &replay_user, (gptr*) &replay_user, 0, GET_STR_ALLOC,
+     REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 
+  {"replay-password", OPT_REPLAY_PASS,
+     "The password for the replay-user on the replay-host.",
+     (gptr*) &replay_pass, (gptr*) &replay_pass, 0, GET_STR,
+     REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 
+  {"replay-db", OPT_REPLAY_DB,
+     "The default database to connect to on the replay-host.",
+     (gptr*) &replay_db, (gptr*) &replay_db, 0, GET_STR_ALLOC,
+     REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 
+  {"replay-port", OPT_REPLAY_USER,
+     "The port to connect to on the replay-host.",
+     (gptr*) &replay_port, (gptr*) &replay_port, 0, GET_INT,
+     REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 
+  {"replay-socket", OPT_REPLAY_SOCKET,
+     "The Unix socket to connect to on the replay-host (only if localhost).",
+     (gptr*) &replay_sock, (gptr*) &replay_sock, 0, GET_STR_ALLOC,
+     REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 
+     
   {"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
    0, 0, 0, 0, 0},
   {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
@@ -764,7 +823,16 @@
   my_free((char*) database, MYF(MY_ALLOW_ZERO_PTR));
   my_free((char*) host, MYF(MY_ALLOW_ZERO_PTR));
   my_free((char*) user, MYF(MY_ALLOW_ZERO_PTR));
+  
+  my_free(replay_pass,MYF(MY_ALLOW_ZERO_PTR));
+  my_free((char*) replay_db, MYF(MY_ALLOW_ZERO_PTR));
+  my_free((char*) replay_host, MYF(MY_ALLOW_ZERO_PTR));
+  my_free((char*) replay_user, MYF(MY_ALLOW_ZERO_PTR));
+  
+  
   my_free((char*) dirname_for_local_load, MYF(MY_ALLOW_ZERO_PTR));
+  
+  end_replay();
 }
 
 static void die(const char* fmt, ...)
@@ -849,11 +917,14 @@
     one_database = 1;
     break;
   case 'p':
+  case OPT_REPLAY_PASS:
+  {
+    char* pass_ptr = (optid == 'p') ? pass : replay_pass;
     if (argument)
     {
-      my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
+      my_free(pass_ptr,MYF(MY_ALLOW_ZERO_PTR));
       char *start=argument;
-      pass= my_strdup(argument,MYF(MY_FAE));
+      pass_ptr= my_strdup(argument,MYF(MY_FAE));
       while (*argument) *argument++= 'x';		/* Destroy argument */
       if (*start)
         start[1]=0;				/* Cut length of argument */
@@ -861,6 +932,7 @@
     else
       tty_password=1;
     break;
+  }  
   case 'r':
     if (!(result_file = my_fopen(argument, O_WRONLY | O_BINARY, MYF(MY_WME))))
       exit(1);
@@ -891,8 +963,13 @@
     exit(0);
   }
   if (tty_password)
-    pass= get_tty_password(NullS);
-
+  {
+    char* tmp= get_tty_password(NullS);
+    if (optid == 'p')
+      pass= tmp;
+    else
+      replay_pass= tmp;  
+  }
   return 0;
 }
 
@@ -909,16 +986,22 @@
   return 0;
 }
 
-static MYSQL* safe_connect()
+/* Arguments prefixed with l_ to avoid conflict with the globals with
+   matching names.
+ */
+static MYSQL* safe_connect(const char* l_host, const char* l_user, 
+  const char* l_pass, const char* l_db, int l_port, const char* l_sock,
+  uint l_protocol)
 {
   MYSQL *local_mysql= mysql_init(NULL);
 
   if (!local_mysql)
     die("Failed on mysql_init");
 
-  if (opt_protocol)
-    mysql_options(local_mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
-  if (!mysql_real_connect(local_mysql, host, user, pass, 0, port, sock, 0))
+  if (l_protocol)
+    mysql_options(local_mysql, MYSQL_OPT_PROTOCOL, (char*) &l_protocol);
+  if (!mysql_real_connect(local_mysql, l_host, l_user, l_pass, 
+       l_db, l_port, l_sock, 0))
   {
     char errmsg[256];
     strmake(errmsg, mysql_error(local_mysql), sizeof(errmsg)-1);
@@ -997,6 +1080,34 @@
   return 0;
 }
 
+static void init_replay()
+{
+  if (!replay_opt) 
+    return;
+
+  result_file= 0;    
+  
+  replay_mysql= safe_connect(replay_host,replay_user,replay_pass,
+    replay_db,replay_port,replay_sock,opt_protocol);  
+  if (mysql_set_server_option(replay_mysql,
+      MYSQL_OPTION_MULTI_STATEMENTS_ON))
+  {
+    die("Cannot replay binary logs on a server that does not support\
+multi-statements");    
+  }
+
+}
+
+static void end_replay()
+{
+  if (!replay_opt) 
+     return;
+  if (replay_mysql)
+  {
+    mysql_close(replay_mysql);
+    replay_mysql= 0;
+  }  
+}
 
 static int dump_remote_log_entries(const char* logname)
 
@@ -1015,7 +1126,7 @@
     we cannot re-use the same connection as before, because it is now dead
     (COM_BINLOG_DUMP kills the thread when it finishes).
   */
-  mysql= safe_connect();
+  mysql= safe_connect(host,user,pass,0,port,sock,opt_protocol);
   net= &mysql->net;
 
   if (check_master_version(mysql, &description_event))
@@ -1393,6 +1504,8 @@
     dirname_for_local_load= my_strdup(my_tmpdir(&tmpdir), MY_WME);
   }
 
+  init_replay();
+  
   if (load_processor.init())
     exit(1);
   if (dirname_for_local_load)
@@ -1400,18 +1513,18 @@
   else
     load_processor.init_by_cur_dir();
 
-  fprintf(result_file,
+  safe_fprintf(result_file,
 	  "/*!40019 SET @@session.max_insert_delayed_threads=0*/;\n");
 
   if (disable_log_bin)
-    fprintf(result_file,
+    safe_fprintf(result_file,
             "/*!32316 SET @OLD_SQL_LOG_BIN=@@SQL_LOG_BIN, SQL_LOG_BIN=0*/;\n");
 
   /*
     In mysqlbinlog|mysql, don't want mysql to be disconnected after each
     transaction (which would be the case with GLOBAL.COMPLETION_TYPE==2).
   */
-  fprintf(result_file,
+  safe_fprintf(result_file,
           "/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,"
           "COMPLETION_TYPE=0*/;\n");
 
@@ -1433,16 +1546,19 @@
     Issue a ROLLBACK in case the last printed binlog was crashed and had half
     of transaction.
   */
-  fprintf(result_file,
+  safe_fprintf(result_file,
           "ROLLBACK;\n"
           "/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;\n");
   if (disable_log_bin)
-    fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n");
+    safe_fprintf(result_file, "/*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;\n");
 
   if (tmpdir.list)
     free_tmpdir(&tmpdir);
-  if (result_file != stdout)
+  if (result_file && result_file != stdout)
+  {
     my_fclose(result_file, MYF(0));
+    result_file= 0;
+  }  
   cleanup();
   free_defaults(defaults_argv);
   my_free_open_file_info();

--- 1.42/client/client_priv.h	2005-08-26 06:56:46 -06:00
+++ 1.43/client/client_priv.h	2005-10-21 22:05:26 -06:00
@@ -51,5 +51,7 @@
 #endif
   OPT_TRIGGERS,
   OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
-  OPT_AUTO_CLOSE
+  OPT_AUTO_CLOSE,
+  OPT_REPLAY_HOST,OPT_REPLAY_USER,OPT_REPLAY_PASS,OPT_REPLAY_DB,
+  OPT_REPLAY_PORT,OPT_REPLAY_SOCKET,OPT_FORCE_REPLAY
 };
Thread
bk commit into 5.0 tree (sasha:1.1942) BUG#11312Sasha Pachev22 Oct