diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result
index 4c7a1e154aaeb3c35288f6eeba8a3930c7524241..2090781caab92729066092448a5f17da54bd8a6a 100644
--- a/mysql-test/r/rpl_log.result
+++ b/mysql-test/r/rpl_log.result
@@ -6,8 +6,8 @@ master-bin.001	200	Query	1	4	use test; insert into t1 values (NULL)
 master-bin.001	263	Query	1	5	use test; drop table t1
 master-bin.001	311	Query	1	6	use test; create table t1 (word char(20) not null)
 master-bin.001	386	Create_file	1	7	db=test;table=t1;file_id=1;block_len=81
-master-bin.001	554	Exec_load	1	8	;file_id=1
-master-bin.001	577	Query	1	9	use test; drop table t1
+master-bin.001	556	Exec_load	1	8	;file_id=1
+master-bin.001	579	Query	1	9	use test; drop table t1
 Log_name	Pos	Event_type	Server_id	Log_seq	Info
 master-bin.001	79	Query	1	2	use test; create table t1(n int not null auto_increment primary key)
 Log_name	Pos	Event_type	Server_id	Log_seq	Info
@@ -23,10 +23,10 @@ master-bin.001	200	Query	1	4	use test; insert into t1 values (NULL)
 master-bin.001	263	Query	1	5	use test; drop table t1
 master-bin.001	311	Query	1	6	use test; create table t1 (word char(20) not null)
 master-bin.001	386	Create_file	1	7	db=test;table=t1;file_id=1;block_len=81
-master-bin.001	554	Exec_load	1	8	;file_id=1
-master-bin.001	577	Query	1	9	use test; drop table t1
-master-bin.001	625	Rotate	1	10	master-bin.002;pos=4
-master-bin.001	666	Stop	1	11	
+master-bin.001	556	Exec_load	1	8	;file_id=1
+master-bin.001	579	Query	1	9	use test; drop table t1
+master-bin.001	627	Rotate	1	10	master-bin.002;pos=4
+master-bin.001	668	Stop	1	11	
 Log_name	Pos	Event_type	Server_id	Log_seq	Info
 master-bin.002	4	Start	1	1	Server ver: $VERSION, Binlog ver: 2
 master-bin.002	79	Query	1	2	use test; create table t1 (n int)
@@ -47,10 +47,10 @@ slave-bin.001	253	Query	1	4	use test; insert into t1 values (NULL)
 slave-bin.001	316	Query	1	5	use test; drop table t1
 slave-bin.001	364	Query	1	6	use test; create table t1 (word char(20) not null)
 slave-bin.001	439	Create_file	1	7	db=test;table=t1;file_id=1;block_len=81
-slave-bin.001	616	Exec_load	1	8	;file_id=1
-slave-bin.001	639	Query	1	9	use test; drop table t1
-slave-bin.001	687	Rotate	1	4	slave-bin.002;pos=4; forced by master
-slave-bin.001	727	Stop	2	5	
+slave-bin.001	618	Exec_load	1	8	;file_id=1
+slave-bin.001	641	Query	1	9	use test; drop table t1
+slave-bin.001	689	Rotate	1	4	slave-bin.002;pos=4; forced by master
+slave-bin.001	729	Stop	2	5	
 Log_name	Pos	Event_type	Server_id	Log_seq	Info
 slave-bin.002	4	Start	2	1	Server ver: $VERSION, Binlog ver: 2
 slave-bin.002	79	Slave	2	10	host=127.0.0.1,port=$MASTER_MYPORT,log=master-bin.002,pos=4
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 4d6dfe7493445c19be674d16b14a799b83e3392a..89f0919cc41d6feec900a7b58bb7731ab34187f9 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -24,20 +24,24 @@
 #endif /* MYSQL_CLIENT */
 
 #ifdef MYSQL_CLIENT
-static void pretty_print_char(FILE* file, int c)
+static void pretty_print_str(FILE* file, char* str, int len)
 {
+  char* end = str + len;
   fputc('\'', file);
-  switch(c) {
-  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;
+  while (str < end)
+  {
+    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);
 }
@@ -46,20 +50,25 @@ static void pretty_print_char(FILE* file, int c)
 #ifndef MYSQL_CLIENT
 
 
-static void pretty_print_char(String* packet, int c)
+static void pretty_print_str(String* packet, char* str, int len)
 {
+  char* end = str + len;
   packet->append('\'');
-  switch(c) {
-  case '\n': packet->append( "\\n"); break;
-  case '\r': packet->append( "\\r"); break;
-  case '\\': packet->append( "\\\\"); break;
-  case '\b': packet->append( "\\b"); break;
-  case '\t': packet->append( "\\t"); break;
-  case '\'': packet->append( "\\'"); break;
-  case 0   : packet->append( "\\0"); break;
-  default:
-    packet->append((char)c);
-    break;
+  while (str < end)
+  {
+    char c;
+    switch((c=*str++)) {
+    case '\n': packet->append( "\\n"); break;
+    case '\r': packet->append( "\\r"); break;
+    case '\\': packet->append( "\\\\"); break;
+    case '\b': packet->append( "\\b"); break;
+    case '\t': packet->append( "\\t"); break;
+    case '\'': packet->append( "\\'"); break;
+    case 0   : packet->append( "\\0"); break;
+    default:
+      packet->append((char)c);
+      break;
+    }
   }
   packet->append('\'');
 }
@@ -88,6 +97,7 @@ const char* Log_event::get_type_str()
   case ROTATE_EVENT: return "Rotate";
   case INTVAR_EVENT: return "Intvar";
   case LOAD_EVENT:   return "Load";
+  case NEW_LOAD_EVENT:   return "New_load";
   case SLAVE_EVENT:  return "Slave";
   case CREATE_FILE_EVENT: return "Create_file";
   case APPEND_BLOCK_EVENT: return "Append_block";
@@ -201,36 +211,36 @@ void Load_log_event::pack_info(String* packet)
   
   tmp.append("INTO TABLE ");
   tmp.append(table_name);
-  if (!(sql_ex.empty_flags & FIELD_TERM_EMPTY))
+  if (sql_ex.field_term_len)
   {
     tmp.append(" FIELDS TERMINATED BY ");
-    pretty_print_char(&tmp, sql_ex.field_term);
+    pretty_print_str(&tmp, sql_ex.field_term, sql_ex.field_term_len);
   }
 
-  if (!(sql_ex.empty_flags & ENCLOSED_EMPTY))
+  if (sql_ex.enclosed_len)
   {
     if (sql_ex.opt_flags && OPT_ENCLOSED_FLAG )
       tmp.append(" OPTIONALLY ");
     tmp.append( " ENCLOSED BY ");
-    pretty_print_char(&tmp, sql_ex.enclosed);
+    pretty_print_str(&tmp, sql_ex.enclosed, sql_ex.enclosed_len);
   }
      
-  if (!(sql_ex.empty_flags & ESCAPED_EMPTY))
+  if (sql_ex.escaped_len)
   {
     tmp.append( " ESCAPED BY ");
-    pretty_print_char(&tmp, sql_ex.escaped);
+    pretty_print_str(&tmp, sql_ex.escaped, sql_ex.escaped_len);
   }
      
-  if (!(sql_ex.empty_flags & LINE_TERM_EMPTY))
+  if (sql_ex.line_term_len)
   {
     tmp.append(" LINES TERMINATED BY ");
-    pretty_print_char(&tmp, sql_ex.line_term);
+    pretty_print_str(&tmp, sql_ex.line_term, sql_ex.line_term_len);
   }
 
-  if (!(sql_ex.empty_flags & LINE_START_EMPTY))
+  if (sql_ex.line_start_len)
   {
     tmp.append(" LINES STARTING BY ");
-    pretty_print_char(&tmp, sql_ex.line_start);
+    pretty_print_str(&tmp, sql_ex.line_start, sql_ex.line_start_len);
   }
      
   if ((int)skip_lines > 0)
@@ -443,13 +453,14 @@ Log_event* Log_event::read_log_event(IO_CACHE* file)
     error = "Event too small";
     goto err;
   }
-  
-  if (!(buf = my_malloc(data_len, MYF(MY_WME))))
+
+  // some events use the extra byte to null-terminate strings
+  if (!(buf = my_malloc(data_len+1, MYF(MY_WME))))
   {
     error = "Out of memory";
     goto err;
   }
-
+  buf[data_len] = 0;
   memcpy(buf, head, LOG_EVENT_HEADER_LEN);
   if(my_b_read(file, (byte*) buf + LOG_EVENT_HEADER_LEN,
 	       data_len - LOG_EVENT_HEADER_LEN))
@@ -483,6 +494,7 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len)
     ev  = new Query_log_event(buf, event_len);
     break;
   case LOAD_EVENT:
+  case NEW_LOAD_EVENT:
     ev = new Load_log_event(buf, event_len);
     break;
   case ROTATE_EVENT:
@@ -784,12 +796,12 @@ int Load_log_event::write_data_header(IO_CACHE* file)
   buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
   buf[L_DB_LEN_OFFSET] = (char)db_len;
   int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
-  memcpy(buf + L_SQL_EX_OFFSET, &sql_ex, sizeof(sql_ex));
   return my_b_write(file, (byte*)buf, LOAD_HEADER_LEN);
 }
 
 int Load_log_event::write_data_body(IO_CACHE* file)
 {
+  if (sql_ex.write_data(file)) return 1;
   if (num_fields && fields && field_lens)
   {
     if(my_b_write(file, (byte*)field_lens, num_fields) ||
@@ -801,6 +813,76 @@ int Load_log_event::write_data_body(IO_CACHE* file)
     my_b_write(file, (byte*)fname, fname_len);
 }
 
+#define WRITE_STR(name) my_b_write(file,(byte*)&name ## _len, 1) || \
+   my_b_write(file,(byte*)name,name ## _len)
+#define OLD_EX_INIT(name) old_ex.##name = *name
+
+int sql_ex_info::write_data(IO_CACHE* file)
+{
+  if (new_format())
+  {
+    return WRITE_STR(field_term) || WRITE_STR(enclosed) ||
+      WRITE_STR(line_term) || WRITE_STR(line_start) ||
+      WRITE_STR(escaped) || my_b_write(file,(byte*)&opt_flags,1);
+  }
+  else
+  {
+    old_sql_ex old_ex;
+    OLD_EX_INIT(field_term);
+    OLD_EX_INIT(enclosed);
+    OLD_EX_INIT(line_term);
+    OLD_EX_INIT(line_start);
+    OLD_EX_INIT(escaped);
+    old_ex.opt_flags = opt_flags;
+    old_ex.empty_flags = empty_flags;
+    return my_b_write(file,(byte*)&old_ex,sizeof(old_ex));
+  }
+}
+
+#define READ_STR(name) name ## _len = *buf++;\
+ if (buf >= buf_end) return 0;\
+ name = buf; \
+ buf += name ## _len; \
+ if (buf >= buf_end) return 0;
+
+#define READ_OLD_STR(name) name ## _len = 1; \
+  name = buf++; \
+  if (buf >= buf_end) return 0; 
+
+#define FIX_OLD_LEN(name,NAME) if (empty_flags & NAME ## _EMPTY) \
+  name ## _len = 0
+
+char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
+{
+  cached_new_format = use_new_format;
+  if (use_new_format)
+  {
+    READ_STR(field_term);
+    READ_STR(enclosed);
+    READ_STR(line_term);
+    READ_STR(line_start);
+    READ_STR(escaped);
+    opt_flags = *buf++;
+  }
+  else
+  {
+    READ_OLD_STR(field_term);
+    READ_OLD_STR(enclosed);
+    READ_OLD_STR(line_term);
+    READ_OLD_STR(line_start);
+    READ_OLD_STR(escaped);
+    opt_flags = *buf++;
+    empty_flags = *buf++;
+    FIX_OLD_LEN(field_term,FIELD_TERM);
+    FIX_OLD_LEN(enclosed,ENCLOSED);
+    FIX_OLD_LEN(line_term,LINE_TERM);
+    FIX_OLD_LEN(line_start,LINE_START);
+    FIX_OLD_LEN(escaped,ESCAPED);
+  }
+  return buf;
+}
+
+
 #ifndef MYSQL_CLIENT
 Load_log_event::Load_log_event(THD* thd, sql_exchange* ex,
 			       const char* db_arg, const char* table_name_arg,
@@ -809,7 +891,7 @@ Load_log_event::Load_log_event(THD* thd, sql_exchange* ex,
     num_fields(0),fields(0),field_lens(0),field_block_len(0),
     table_name(table_name_arg),
     db(db_arg),
-    fname(ex->file_name),fname_null_term(1)
+    fname(ex->file_name)
   {
     time_t end_time;
     time(&end_time);
@@ -817,12 +899,19 @@ Load_log_event::Load_log_event(THD* thd, sql_exchange* ex,
     db_len = (db) ? (uint32) strlen(db) : 0;
     table_name_len = (table_name) ? (uint32) strlen(table_name) : 0;
     fname_len = (fname) ? (uint) strlen(fname) : 0;
-    sql_ex.field_term = (*ex->field_term)[0];
-    sql_ex.enclosed = (*ex->enclosed)[0];
-    sql_ex.line_term = (*ex->line_term)[0];
-    sql_ex.line_start = (*ex->line_start)[0];
-    sql_ex.escaped = (*ex->escaped)[0];
+    sql_ex.field_term = (char*)ex->field_term->ptr();
+    sql_ex.field_term_len = ex->field_term->length();
+    sql_ex.enclosed = (char*)ex->enclosed->ptr();
+    sql_ex.enclosed_len = ex->enclosed->length();
+    sql_ex.line_term = (char*)ex->line_term->ptr();
+    sql_ex.line_term_len = ex->line_term->length();
+    sql_ex.line_start = (char*)ex->line_start->ptr();
+    sql_ex.line_start_len = ex->line_start->length();
+    sql_ex.escaped = (char*)ex->escaped->ptr();
+    sql_ex.escaped_len = ex->escaped->length();
     sql_ex.opt_flags = 0;
+    sql_ex.cached_new_format = -1;
+    
     if(ex->dumpfile)
       sql_ex.opt_flags |= DUMPFILE_FLAG;
     if(ex->opt_enclosed)
@@ -837,6 +926,7 @@ Load_log_event::Load_log_event(THD* thd, sql_exchange* ex,
       case DUP_ERROR: break;	
       }
 
+
     if(!ex->field_term->length())
       sql_ex.empty_flags |= FIELD_TERM_EMPTY;
     if(!ex->enclosed->length())
@@ -869,10 +959,12 @@ Load_log_event::Load_log_event(THD* thd, sql_exchange* ex,
 
 #endif
 
+// the caller must do buf[event_len] = 0 before he starts using the
+// constructed event
 Load_log_event::Load_log_event(const char* buf, int event_len):
   Log_event(buf),num_fields(0),fields(0),
   field_lens(0),field_block_len(0),
-  table_name(0),db(0),fname(0),fname_null_term(0)
+  table_name(0),db(0),fname(0)
 {
   if (!event_len) // derived class, will call copy_log_event() itself
     return;
@@ -882,12 +974,7 @@ Load_log_event::Load_log_event(const char* buf, int event_len):
 int Load_log_event::copy_log_event(const char *buf, ulong event_len)
 {
   uint data_len;
-  int body_offset = get_data_body_offset();
-  if((int)event_len < body_offset)
-    return 1;
-  memcpy(&sql_ex, buf + L_SQL_EX_OFFSET + LOG_EVENT_HEADER_LEN,
-	 sizeof(sql_ex));
-  data_len = event_len - body_offset;
+  char* buf_end = (char*)buf + event_len;
   thread_id = uint4korr(buf + L_THREAD_ID_OFFSET + LOG_EVENT_HEADER_LEN);
   exec_time = uint4korr(buf + L_EXEC_TIME_OFFSET + LOG_EVENT_HEADER_LEN);
   skip_lines = uint4korr(buf + L_SKIP_LINES_OFFSET + LOG_EVENT_HEADER_LEN);
@@ -895,9 +982,19 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len)
   db_len = (uint)buf[L_DB_LEN_OFFSET + LOG_EVENT_HEADER_LEN];
   num_fields = uint4korr(buf + L_NUM_FIELDS_OFFSET + LOG_EVENT_HEADER_LEN);
 	  
+  int body_offset = get_data_body_offset();
+  if ((int)event_len < body_offset)
+    return 1;
+  //sql_ex.init() on success returns the pointer to the first byte after
+  //the sql_ex structure, which is the start of field lengths array
+  if (!(field_lens=(uchar*)sql_ex.init((char*)buf + body_offset,
+		  buf_end,
+		  buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
+    return 1;
+  
+  data_len = event_len - body_offset;
   if (num_fields > data_len) // simple sanity check against corruption
     return 1;
-  field_lens = (uchar*)buf + body_offset;
   uint i;
   for (i = 0; i < num_fields; i++)
   {
@@ -907,9 +1004,9 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len)
   table_name  = fields + field_block_len;
   db = table_name + table_name_len + 1;
   fname = db + db_len + 1;
-  fname_len = (get_type_code() == LOAD_EVENT) ?
-    data_len - 2 - db_len - table_name_len - num_fields - field_block_len :
-    strlen(fname);
+  int type_code = get_type_code();
+  fname_len = strlen(fname);
+  // null termination is accomplished by the caller doing buf[event_len]=0
   return 0;
 }
 
@@ -943,36 +1040,36 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db)
     fprintf(file," IGNORE ");
   
   fprintf(file, "INTO TABLE %s ", table_name);
-  if(!(sql_ex.empty_flags & FIELD_TERM_EMPTY))
+  if(sql_ex.field_term)
   {
     fprintf(file, " FIELDS TERMINATED BY ");
-    pretty_print_char(file, sql_ex.field_term);
+    pretty_print_str(file, sql_ex.field_term, sql_ex.field_term_len);
   }
 
-  if(!(sql_ex.empty_flags & ENCLOSED_EMPTY))
+  if(sql_ex.enclosed)
   {
     if(sql_ex.opt_flags && OPT_ENCLOSED_FLAG )
       fprintf(file," OPTIONALLY ");
     fprintf(file, " ENCLOSED BY ");
-    pretty_print_char(file, sql_ex.enclosed);
+    pretty_print_str(file, sql_ex.enclosed, sql_ex.enclosed_len);
   }
      
-  if(!(sql_ex.empty_flags & ESCAPED_EMPTY))
+  if (sql_ex.escaped)
   {
     fprintf(file, " ESCAPED BY ");
-    pretty_print_char(file, sql_ex.escaped);
+    pretty_print_str(file, sql_ex.escaped, sql_ex.escaped_len);
   }
      
-  if(!(sql_ex.empty_flags & LINE_TERM_EMPTY))
+  if (sql_ex.line_term)
   {
     fprintf(file," LINES TERMINATED BY ");
-    pretty_print_char(file, sql_ex.line_term);
+    pretty_print_str(file, sql_ex.line_term, sql_ex.line_term_len);
   }
 
-  if(!(sql_ex.empty_flags & LINE_START_EMPTY))
+  if (sql_ex.line_start)
   {
     fprintf(file," LINES STARTING BY ");
-    pretty_print_char(file, sql_ex.line_start);
+    pretty_print_str(file, sql_ex.line_start, sql_ex.line_start_len);
   }
      
   if((int)skip_lines > 0)
@@ -1119,6 +1216,7 @@ Create_file_log_event::Create_file_log_event(THD* thd_arg, sql_exchange* ex,
  fake_base(0),block(block_arg),block_len(block_len_arg),
   file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
 {
+  sql_ex.force_new_format();
 }
 #endif
 
@@ -1155,12 +1253,11 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len):
   int block_offset;
   if (copy_log_event(buf,len))
     return;
-  fname_null_term = 1;
   file_id = uint4korr(buf + LOG_EVENT_HEADER_LEN +
 		      + LOAD_HEADER_LEN + CF_FILE_ID_OFFSET);
   block_offset = LOG_EVENT_HEADER_LEN + Load_log_event::get_data_size() +
     CREATE_FILE_HEADER_LEN + 1; // 1 for \0 terminating fname  
-  if(len < block_offset)
+  if (len < block_offset)
     return;
   block = (char*)buf + block_offset;
   block_len = len - block_offset;
@@ -1443,46 +1540,20 @@ int Load_log_event::exec_event(NET* net, struct st_master_info* mi)
     {
       char llbuff[22];
       enum enum_duplicates handle_dup = DUP_IGNORE;
-      char fname_buf[FN_REFLEN+1], *fname_p;
-      if (fname_null_term)
-	fname_p = (char*)fname;
-      else
-      {
-	int len = min(FN_REFLEN,fname_len);
-	memcpy(fname_buf,fname,len);
-	fname_buf[len] = 0;
-	fname_p = fname_buf;
-      }
       if(sql_ex.opt_flags && REPLACE_FLAG)
 	handle_dup = DUP_REPLACE;
-      sql_exchange ex(fname_p, sql_ex.opt_flags &&
+      sql_exchange ex((char*)fname, sql_ex.opt_flags &&
 		      DUMPFILE_FLAG );
-      String field_term(&sql_ex.field_term, 1),
-	enclosed(&sql_ex.enclosed, 1),
-	line_term(&sql_ex.line_term,1),
-	escaped(&sql_ex.escaped, 1),
-	line_start(&sql_ex.line_start, 1);
-	    
-      ex.field_term = &field_term;
-      if(sql_ex.empty_flags & FIELD_TERM_EMPTY)
-	ex.field_term->length(0);
+      
+#define SET_EX(name) String name(sql_ex.name,sql_ex.name ## _len);\
+ ex.name = &name;
+
+      SET_EX(field_term);
+      SET_EX(enclosed);
+      SET_EX(line_term);
+      SET_EX(line_start);
+      SET_EX(escaped);
 	    
-      ex.enclosed = &enclosed;
-      if(sql_ex.empty_flags & ENCLOSED_EMPTY)
-	ex.enclosed->length(0);
-
-      ex.line_term = &line_term;
-      if(sql_ex.empty_flags & LINE_TERM_EMPTY)
-	ex.line_term->length(0);
-
-      ex.line_start = &line_start;
-      if(sql_ex.empty_flags & LINE_START_EMPTY)
-	ex.line_start->length(0);
-
-      ex.escaped = &escaped;
-      if(sql_ex.empty_flags & ESCAPED_EMPTY)
-	ex.escaped->length(0);
-
       ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
       if(sql_ex.empty_flags & FIELD_TERM_EMPTY)
 	ex.field_term->length(0);
@@ -1528,7 +1599,7 @@ int Load_log_event::exec_event(NET* net, struct st_master_info* mi)
       sql_error = ER_UNKNOWN_ERROR;
 		
     slave_print_error(sql_error, "Slave: Error '%s' running load data infile ",
-		    ER(sql_error));
+		    ER_SAFE(sql_error));
     free_root(&thd->mem_root,0);
     return 1;
   }
@@ -1745,7 +1816,7 @@ int Execute_load_log_event::exec_event(struct st_master_info* mi)
     goto err;
   }
   if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,0))
-      || lev->get_type_code() != LOAD_EVENT)
+      || lev->get_type_code() != NEW_LOAD_EVENT)
   {
     slave_print_error(0, "File '%s' appears corrupted", fname);
     goto err;
diff --git a/sql/log_event.h b/sql/log_event.h
index af6619376b4935620b4c117c6eff4c0ba75d7d5c..ef795e75e2cf15f251cedfe763c3e81ec726cfc8 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -53,16 +53,46 @@
 #define LINE_START_EMPTY 0x8
 #define ESCAPED_EMPTY    0x10
 
-
-struct sql_ex_info
+struct old_sql_ex
   {
     char field_term;
     char enclosed;
     char line_term;
     char line_start;
     char escaped;
-    char opt_flags; // flags for the options
-    char empty_flags; // flags to indicate which of the terminating charact
+    char opt_flags;
+    char empty_flags;
+  };
+
+
+struct sql_ex_info
+  {
+    char* field_term;
+    char* enclosed;
+    char* line_term;
+    char* line_start;
+    char* escaped;
+    uchar field_term_len,enclosed_len,line_term_len,line_start_len,
+      escaped_len;
+    char opt_flags; 
+    char empty_flags;
+    int cached_new_format;
+    
+    // store in new format even if old is possible
+    void force_new_format() { cached_new_format = 1;} 
+    int data_size() { return new_format() ?
+			field_term_len + enclosed_len + line_term_len +
+			line_start_len + escaped_len + 6 : 7;}
+    int write_data(IO_CACHE* file);
+    char* init(char* buf,char* buf_end,bool use_new_format);
+    bool new_format()
+      {
+	return (cached_new_format != -1) ? cached_new_format :
+	  (cached_new_format=(field_term_len > 1 ||
+			      enclosed_len > 1 ||
+			      line_term_len > 1 || line_start_len > 1 ||
+			      escaped_len > 1));
+      }
   } ;
 
 /* Binary log consists of events. Each event has a fixed length header,
@@ -76,7 +106,7 @@ struct sql_ex_info
 /* event-specific post-header sizes */
 #define LOG_EVENT_HEADER_LEN 19
 #define QUERY_HEADER_LEN     (4 + 4 + 1 + 2)
-#define LOAD_HEADER_LEN      (4 + 4 + 4 + 1 +1 + 4+sizeof(struct sql_ex_info))
+#define LOAD_HEADER_LEN      (4 + 4 + 4 + 1 +1 + 4)
 #define START_HEADER_LEN     (2 + ST_SERVER_VER_LEN + 4)
 #define ROTATE_HEADER_LEN    8
 #define CREATE_FILE_HEADER_LEN 4
@@ -162,7 +192,8 @@ struct sql_ex_info
 enum Log_event_type { START_EVENT = 1, QUERY_EVENT =2,
 		      STOP_EVENT=3, ROTATE_EVENT = 4, INTVAR_EVENT=5,
                       LOAD_EVENT=6, SLAVE_EVENT=7, CREATE_FILE_EVENT=8,
- APPEND_BLOCK_EVENT=9, EXEC_LOAD_EVENT=10, DELETE_FILE_EVENT=11};
+ APPEND_BLOCK_EVENT=9, EXEC_LOAD_EVENT=10, DELETE_FILE_EVENT=11,
+ NEW_LOAD_EVENT=12};
 enum Int_event_type { INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
  };
 
@@ -359,7 +390,6 @@ public:
   const char* table_name;
   const char* db;
   const char* fname;
-  bool fname_null_term;
   uint32 skip_lines;
   sql_ex_info sql_ex;
   
@@ -384,7 +414,8 @@ public:
   ~Load_log_event()
   {
   }
-  Log_event_type get_type_code() { return LOAD_EVENT; }
+  Log_event_type get_type_code() { return sql_ex.new_format() ?
+				     NEW_LOAD_EVENT: LOAD_EVENT; }
   int write_data_header(IO_CACHE* file); 
   int write_data_body(IO_CACHE* file); 
   bool is_valid() { return table_name != 0; }
@@ -395,7 +426,7 @@ public:
       + 4 // exec_time
       + 4 // skip_lines
       + 4 // field block len
-      + sizeof(sql_ex) + field_block_len + num_fields;
+      + sql_ex.data_size() + field_block_len + num_fields;
       ;
   }
   int get_data_body_offset() { return LOAD_EVENT_OVERHEAD; }
@@ -545,8 +576,10 @@ public:
   ~Create_file_log_event()
   {
   }
-  Log_event_type get_type_code() { return fake_base ? LOAD_EVENT :
-     CREATE_FILE_EVENT;}
+  Log_event_type get_type_code()
+    {
+     return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT;
+    }
   int get_data_size() { return  fake_base ? Load_log_event::get_data_size() :
 			  Load_log_event::get_data_size() +
 			  4 + 1 + block_len;}
diff --git a/tools/mysqlmngd.c b/tools/mysqlmngd.c
new file mode 100644
index 0000000000000000000000000000000000000000..3f5e404cbdab11d9f4d5246e66c99a28752dbbd6
--- /dev/null
+++ b/tools/mysqlmngd.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+/* MySQL server management daemon
+ *
+ * Written by:
+ *   Sasha Pachev <sasha@mysql.com>
+ **/
+
+#define VERSION "1.0"
+
+#include <global.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <mysql.h>
+