diff --git a/include/my_sys.h b/include/my_sys.h
index c492262d9258ba55641bad8d9e97f4277c286686..307e286a289a376b63d21e05c754b1a5c4f830ab 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -270,12 +270,17 @@ typedef struct st_dynamic_string {
   uint length,max_length,alloc_increment;
 } DYNAMIC_STRING;
 
+struct st_io_cache;
+typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
 
 typedef struct st_io_cache		/* Used when cacheing files */
 {
   my_off_t pos_in_file,end_of_file;
   byte	*rc_pos,*rc_end,*buffer,*rc_request_pos;
   int (*read_function)(struct st_io_cache *,byte *,uint);
+  /* callbacks when the actual read I/O happens */
+  IO_CACHE_CALLBACK pre_read;
+  IO_CACHE_CALLBACK post_read;
   char *file_name;			/* if used with 'open_cached_file' */
   char *dir,*prefix;
   File file;
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 0d1c227c2b24e53737a7d6e80e63901990495274..99af418f6bdd0e50c0b56b6d4964eee2342ab306 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -56,6 +56,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
   DBUG_PRINT("enter",("type: %d  pos: %ld",(int) type, (ulong) seek_offset));
 
   info->file=file;
+  info->pre_read = info->post_read = 0;
   if (!cachesize)
     if (! (cachesize= my_default_record_cache_size))
       DBUG_RETURN(1);				/* No cache requested */
@@ -467,8 +468,13 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
 int _my_b_get(IO_CACHE *info)
 {
   byte buff;
+  IO_CACHE_CALLBACK pre_read,post_read;
+  if ((pre_read = info->pre_read))
+    (*pre_read)(info);
   if ((*(info)->read_function)(info,&buff,1))
     return my_b_EOF;
+  if ((post_read = info->post_read))
+    (*post_read)(info);
   return (int) (uchar) buff;
 }
 
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 5538e6c0b7fefa468ff5da08ffc1373cb18769a2..ba7e121847e4acb8e4cfa0922d2166119c2cca30 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -23,7 +23,7 @@
 #include "slave.h"
 #endif /* MYSQL_CLIENT */
 
-
+#ifdef MYSQL_CLIENT
 static void pretty_print_char(FILE* file, int c)
 {
   fputc('\'', file);
@@ -41,6 +41,7 @@ static void pretty_print_char(FILE* file, int c)
   }
   fputc('\'', file);
 }
+#endif
 
 #ifndef MYSQL_CLIENT
 
@@ -444,6 +445,7 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len)
   return NULL;  // default value
 }
 
+#ifdef MYSQL_CLIENT
 void Log_event::print_header(FILE* file)
 {
   fputc('#', file);
@@ -508,6 +510,8 @@ void Rotate_log_event::print(FILE* file, bool short_form, char* last_db)
   fflush(file);
 }
 
+#endif /* #ifdef MYSQL_CLIENT */
+
 Start_log_event::Start_log_event(const char* buf) :Log_event(buf)
 {
   binlog_version = uint2korr(buf + LOG_EVENT_HEADER_LEN +
@@ -576,6 +580,8 @@ Query_log_event::Query_log_event(const char* buf, int event_len):
   *((char*)query+q_len) = 0;
 }
 
+#ifdef MYSQL_CLIENT
+
 void Query_log_event::print(FILE* file, bool short_form, char* last_db)
 {
   char buff[40],*end;				// Enough for SET TIMESTAMP
@@ -604,6 +610,8 @@ void Query_log_event::print(FILE* file, bool short_form, char* last_db)
   fprintf(file, ";\n");
 }
 
+#endif
+
 int Query_log_event::write_data(IO_CACHE* file)
 {
   if (!query) return -1;
@@ -644,6 +652,7 @@ int Intvar_log_event::write_data(IO_CACHE* file)
   return my_b_write(file, (byte*) buf, sizeof(buf));
 }
 
+#ifdef MYSQL_CLIENT
 void Intvar_log_event::print(FILE* file, bool short_form, char* last_db)
 {
   char llbuff[22];
@@ -667,6 +676,7 @@ void Intvar_log_event::print(FILE* file, bool short_form, char* last_db)
   fflush(file);
   
 }
+#endif
 
 int Load_log_event::write_data(IO_CACHE* file)
 {
@@ -742,6 +752,7 @@ void Load_log_event::copy_log_event(const char *buf, ulong data_len)
     field_block_len;
 }
 
+#ifdef MYSQL_CLIENT
 
 void Load_log_event::print(FILE* file, bool short_form, char* last_db)
 {
@@ -825,6 +836,8 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db)
   fprintf(file, ";\n");
 }
 
+#endif /* #ifdef MYSQL_CLIENT */
+
 #ifndef MYSQL_CLIENT
 
 void Log_event::set_log_seq(THD* thd, MYSQL_LOG* log)
@@ -879,6 +892,8 @@ Slave_log_event::~Slave_log_event()
   my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
 }
 
+#ifdef MYSQL_CLIENT
+
 void Slave_log_event::print(FILE* file, bool short_form = 0,
 			    char* last_db = 0)
 {
@@ -892,6 +907,8 @@ void Slave_log_event::print(FILE* file, bool short_form = 0,
 	  llstr(master_pos, llbuff));
 }
 
+#endif
+
 int Slave_log_event::get_data_size()
 {
   return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
@@ -934,3 +951,41 @@ Slave_log_event::Slave_log_event(const char* buf, int event_len):
   mem_pool[event_len] = 0;
   init_from_mem_pool(event_len);
 }
+
+#ifndef MYSQL_CLIENT
+Create_file_log_event::Create_file_log_event(THD* thd, TABLE_LIST * table,
+					     char* block_arg,
+					     uint block_len_arg) :
+  Log_event(thd->start_time), db(table->db),tbl_name(table->real_name),
+ db_len(strlen(table->db)),tbl_name_len(strlen(table->real_name)),
+ block(block_arg),block_len(block_len_arg),
+  file_id(thd->file_id = thd->query_id)
+{
+  set_log_seq(thd, &mysql_bin_log);
+}
+#endif
+
+int Create_file_log_event::write_data(IO_CACHE* file)
+{
+  return 0;
+}
+
+#ifdef MYSQL_CLIENT
+void Create_file_log_event::print(FILE* file, bool short_form = 0,
+				  char* last_db = 0)
+{
+}
+#endif
+
+#ifndef MYSQL_CLIENT
+void Create_file_log_event::pack_info(String* packet)
+{
+}
+#endif  
+
+
+
+
+
+
+
diff --git a/sql/log_event.h b/sql/log_event.h
index d203894cf27f2ae7cdd2adad349c0f110c9d3f90..9c110128ff439ab9a9805d269bee4b570196bda7 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -55,6 +55,7 @@
 #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 6
 
 /* event header offsets */
 
@@ -108,6 +109,7 @@
 #define QUERY_DATA_OFFSET (LOG_EVENT_HEADER_LEN+QUERY_HEADER_LEN)
 #define ROTATE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+ROTATE_HEADER_LEN)
 #define LOAD_EVENT_OVERHEAD   (LOG_EVENT_HEADER_LEN+LOAD_HEADER_LEN+sizeof(sql_ex_info))
+#define CREATE_FILE_EVENT_OVERHEAD (LOG_EVENT_HEADER_LEN+CREATE_FILE_HEADER_LEN)
 
 #define BINLOG_MAGIC        "\xfe\x62\x69\x6e"
 
@@ -116,7 +118,8 @@
 
 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, FILE_EVENT=8};
+                      LOAD_EVENT=6, SLAVE_EVENT=7, CREATE_FILE_EVENT=8,
+ APPEND_TO_FILE_EVENT=9, EXEC_LOAD_EVENT=10, DELETE_FILE_EVENT=11};
 enum Int_event_type { INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
  };
 
@@ -175,10 +178,11 @@ public:
   virtual ~Log_event() {}
 
   virtual int get_data_size() { return 0;}
+#ifdef MYSQL_CLIENT  
   virtual void print(FILE* file, bool short_form = 0, char* last_db = 0) = 0;
-
   void print_timestamp(FILE* file, time_t *ts = 0);
   void print_header(FILE* file);
+#endif
 
   // if mutex is 0, the read will proceed without mutex
   static Log_event* read_log_event(IO_CACHE* file, pthread_mutex_t* log_lock);
@@ -250,8 +254,9 @@ public:
       + 2	// error_code
       ;
   }
-
+#ifdef MYSQL_CLIENT
   void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif  
 };
 
 class Slave_log_event: public Log_event
@@ -276,7 +281,9 @@ public:
   ~Slave_log_event();
   int get_data_size();
   Log_event_type get_type_code() { return SLAVE_EVENT; }
+#ifdef MYSQL_CLIENT  
   void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif  
   int write_data(IO_CACHE* file );
 
 };
@@ -419,8 +426,9 @@ public:
       + sizeof(sql_ex) + field_block_len + num_fields*sizeof(uchar) ;
       ;
   }
-
+#ifdef MYSQL_CLIENT
   void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif  
 };
 
 extern char server_version[SERVER_VERSION_LENGTH];
@@ -448,8 +456,10 @@ public:
   }
 #ifndef MYSQL_CLIENT
   void pack_info(String* packet);
-#endif  
+#endif
+#ifdef MYSQL_CLIENT  
   void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif  
 };
 
 class Intvar_log_event: public Log_event
@@ -470,8 +480,9 @@ public:
   void pack_info(String* packet);
 #endif  
   
-  
+#ifdef MYSQL_CLIENT  
   void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif  
 };
 
 class Stop_log_event: public Log_event
@@ -484,7 +495,9 @@ public:
   }
   ~Stop_log_event() {}
   Log_event_type get_type_code() { return STOP_EVENT;}
+#ifdef MYSQL_CLIENT  
   void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif  
 };
 
 class Rotate_log_event: public Log_event
@@ -513,13 +526,50 @@ public:
   Log_event_type get_type_code() { return ROTATE_EVENT;}
   int get_data_size() { return  ident_len + ROTATE_HEADER_LEN;}
   int write_data(IO_CACHE* file);
+#ifdef MYSQL_CLIENT  
+  void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif  
+#ifndef MYSQL_CLIENT
+  void pack_info(String* packet);
+#endif  
+};
+
+/* the classes below are for the new LOAD DATA INFILE logging */
+
+class Create_file_log_event: public Log_event
+{
+public:
+  char* db;
+  char* tbl_name;
+  uint db_len;
+  uint tbl_name_len;
+  char* block;
+  uint block_len;
+  uint file_id;
+  
+#ifndef MYSQL_CLIENT  
+ Create_file_log_event(THD* thd, TABLE_LIST * table, char* block_arg,
+		       uint block_len_arg);
+#endif  
   
+  Create_file_log_event(const char* buf, int event_len);
+  ~Create_file_log_event()
+  {
+  }
+  Log_event_type get_type_code() { return CREATE_FILE_EVENT;}
+  int get_data_size() { return  tbl_name_len + block_len +
+			  CREATE_FILE_HEADER_LEN ;}
+  int write_data(IO_CACHE* file);
+
+#ifdef MYSQL_CLIENT  
   void print(FILE* file, bool short_form = 0, char* last_db = 0);
+#endif  
 #ifndef MYSQL_CLIENT
   void pack_info(String* packet);
 #endif  
 };
 
+
 #endif
 
 
diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc
index cddacaa820fdcd043d2508b3f93981f0dd865182..bf2f2c37409e56f54aef60917aea95d15a30dcbf 100644
--- a/sql/mf_iocache.cc
+++ b/sql/mf_iocache.cc
@@ -57,6 +57,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
 
   /* There is no file in net_reading */
   info->file= file;
+  info->pre_read = info->post_read = 0;
   if (!cachesize)
     if (! (cachesize= my_default_record_cache_size))
       DBUG_RETURN(1);				/* No cache requested */
@@ -535,8 +536,13 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count)
 int _my_b_get(IO_CACHE *info)
 {
   byte buff;
+  IO_CACHE_CALLBACK pre_read,post_read;
+  if ((pre_read = info->pre_read))
+    (*pre_read)(info);
   if ((*(info)->read_function)(info,&buff,1))
     return my_b_EOF;
+  if ((post_read = info->post_read))
+    (*post_read)(info);
   return (int) (uchar) buff;
 }
 
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index f196e4ff852ee3d138f3a62472ae5d679c6abe52..992cd30a02cf2339e118810aa31004d9e789daae 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -99,6 +99,7 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
   slave_thread = 0;
   slave_proxy_id = 0;
   log_seq = 0;
+  file_id = 0;
   cond_count=0;
   convert_set=0;
   mysys_var=0;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 5cec5341dc35d698b24f0c3fb21f1bd9c05dcb88..5b20c62924a5401b8e1603e28b210c23ca5517fe 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -248,6 +248,7 @@ public:
   enum enum_server_command command;
   uint32 server_id;
   uint32 log_seq;
+  uint32 file_id; // for LOAD DATA INFILE
   const char *where;
   time_t  start_time,time_after_lock,user_time;
   time_t  connect_time,thr_create_time; // track down slow pthread_create