diff --git a/Docs/manual.texi b/Docs/manual.texi
index ccc6da16ddd406e4799e2de0037380f23efe6fad..7d60130e819bcecb86275753a661a57789385cb4 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -1807,6 +1807,13 @@ is as tested as the other table types.
 This only affects the new code that checks if the table was closed properly
 on open and executes an automatic check/repair of the table if it wasn't.
 
+@item MERGE tables -- Alpha / Beta
+The usage of keys on @code{MERGE} tables is still not that tested.  The
+other part of the @code{MERGE} code is quite well tested.
+
+@item FULLTEXT -- Alpha / Beta
+Text search seams to work, but is still not widely used.
+
 @end table
 
 MySQL AB provides e-mail support for paying customers, but the @strong{MySQL}
@@ -21903,6 +21910,9 @@ properly locked if one another thread issues a table lock.
 @item
 Internal locking in @code{BDB} tables are done on page level.
 @item
+@code{SELECT COUNT(*) FROM table_name} is slow as @code{BDB} tables doesn't
+maintain a count of the number of rows in the table.
+@item
 Scanning is slower than with @code{MyISAM} tables as one has data in BDB
 tables is stored in B-trees and not in a separate data file.
 @item
@@ -37025,7 +37035,7 @@ This listing.
 Perl @code{Data-Dumper} module.  Useful with @code{DBI}/@code{DBD} support for
 older perl installations.
 
-@item @uref{http://www.mysql.com/Downloads/Contrib/DBI-1.13.tar.gz, DBI-1.13.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/DBI-1.14.tar.gz, DBI-1.14.tar.gz}
 Perl @code{DBI} module.
 
 @item @uref{http://www.mysql.com/Downloads/Contrib/KAMXbase1.0.tar.gz,KAMXbase1.0.tar.gz}
@@ -37034,7 +37044,7 @@ module written by Pratap Pereira @email{pereira@@ee.eng.ohio-state.edu},
 extened by Kevin A. McGrail @email{kmcgrail@@digital1.peregrinehw.com}.
 This converter can handle MEMO fields.
 
-@item @uref{http://www.mysql.com/Downloads/Contrib/Msql-Mysql-modules-1.2214.tar.gz, Msql-Mysql-modules-1.2214.tar.gz}
+@item @uref{http://www.mysql.com/Downloads/Contrib/Msql-Mysql-modules-1.2215.tar.gz, Msql-Mysql-modules-1.2215.tar.gz}
 Perl @code{DBD} module to access mSQL and @strong{MySQL} databases..
 
 @item @uref{http://www.mysql.com/Downloads/Contrib/Data-ShowTable-3.3.tar.gz,  Data-ShowTable-3.3.tar.gz}
@@ -37991,6 +38001,12 @@ though, so 3.23 is not released as a stable version yet.
 @appendixsubsec Changes in release 3.23.26
 @itemize @bullet
 @item
+Fixed problem with @code{SUBSTRING_INDEX()} and @code{REPLACE()}.
+(Patch by Alexander Igonitchev)
+@item
+@code{CREATE TEMPORARY TABLE IF NOT EXISTS} doesn't anymore give an error
+if the table existed.
+@item
 If one don't create a @code{PRIMARY KEY} in a BDB table, a hidden
 @code{PRIMARY KEY} will be created.
 @item
diff --git a/include/Makefile.am b/include/Makefile.am
index 1833ea8096bd3661b3d324552a76c41ef3f3e3f9..f5f290e35da9be5df199405f5f03477762ce1baa 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -30,16 +30,14 @@ noinst_HEADERS =	global.h config-win.h \
 			my_tree.h hash.h thr_alarm.h thr_lock.h \
 			getopt.h t_ctype.h violite.h \
 			mysql_version.h.in
-EXTRA_DIST=		my_config.h
 
 # mysql_version.h are generated
-SUPERCLEANFILES =	mysql_version.h my_global.h
+SUPERCLEANFILES =	mysql_version.h my_global.h my_config.h
 
 # Some include files that may be moved and patched by configure
 DISTCLEANFILES =	sched.h
-CLEANFILES =		my_config.h
 
-all-local:		my_global.h
+all-local:		my_global.h my_config.h
 
 # Since we include my_config.h it better exist from the beginning
 link_sources:
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 1722c5cf9b25e08e0bd17222d0c61aa46863b658..bef7da93451b7fe3e4e3b615ab63d96957500b19 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -57,8 +57,8 @@ struct timespec {		/* For pthread_cond_timedwait() */
 
 typedef int pthread_mutexattr_t;
 #define win_pthread_self my_thread_var->pthread_self
-#define pthread_handler_decl(A,B) unsigned __cdecl A(void *B)
-typedef unsigned (__cdecl *pthread_handler)(void *);
+#define pthread_handler_decl(A,B) void * __cdecl A(void *B)
+typedef void * (__cdecl *pthread_handler)(void *);
 
 void win_pthread_init(void);
 int win_pthread_setspecific(void *A,void *B,uint length);
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index a35ccc7edf48f7080f71e3c07693ff76872427c3..31d4aca1309d78517163edf729f25f0182fa5131 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -1172,9 +1172,9 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
       if (my_errno != HA_ERR_FOUND_DUPP_KEY) goto err;
       DBUG_DUMP("record",(byte*) sort_info->record,share->base.pack_reclength);
       mi_check_print_info(param,"Duplicate key %2d for record at %10s against new record at %10s",
-		 info->errkey+1,
-		 llstr(sort_info->start_recpos,llbuff),
-		 llstr(info->lastpos,llbuff2));
+			  info->errkey+1,
+			  llstr(sort_info->start_recpos,llbuff),
+			  llstr(info->dupp_key_pos,llbuff2));
       if (param->testflag & T_VERBOSE)
       {
 	VOID(_mi_make_key(info,(uint) info->errkey,info->lastkey,
@@ -2350,8 +2350,8 @@ int sort_write_record(SORT_INFO *sort_info)
 	if (sort_info->buff_length < reclength)
 	{
 	  if (!(sort_info->buff=my_realloc(sort_info->buff, (uint) reclength,
-					  MYF(MY_FREE_ON_ERROR |
-					      MY_ALLOW_ZERO_PTR))))
+					   MYF(MY_FREE_ON_ERROR |
+					       MY_ALLOW_ZERO_PTR))))
 	    DBUG_RETURN(1);
 	  sort_info->buff_length=reclength;
 	}
diff --git a/myisam/mi_open.c b/myisam/mi_open.c
index 942b4cee49164ab20606eb118d876b3b9dad5460..aeaf9e5e9b49f4ddc0fb2d714107ffaf8e0b1332 100644
--- a/myisam/mi_open.c
+++ b/myisam/mi_open.c
@@ -101,6 +101,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
 	  (kfile=my_open(name_buff,(open_mode=O_RDONLY) | O_SHARE,MYF(0))) < 0)
 	goto err;
     }
+    share->mode=open_mode;
     errpos=1;
     if (my_read(kfile,(char*) share->state.header.file_version,head_length,
 		MYF(MY_NABP)))
@@ -343,28 +344,11 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
       lock_error=1;			/* Database unlocked */
     }
 
-#ifdef USE_RAID
-    if (share->base.raid_type)
-    {
-      if ((info.dfile=my_raid_open(fn_format(name_buff,name,"",MI_NAME_DEXT,
-					     2+4),
-				   mode | O_SHARE,
-				   share->base.raid_type,
-				   share->base.raid_chunks,
-				   share->base.raid_chunksize,
-				   MYF(MY_WME | MY_RAID))) < 0)
+    if (mi_open_datafile(&info, share))
       goto err;
-    }
-    else
-#endif
-      if ((info.dfile=my_open(fn_format(name_buff,name,"",MI_NAME_DEXT,2+4),
-			      mode | O_SHARE,
-			      MYF(MY_WME))) < 0)
-	goto err;
     errpos=5;
 
     share->kfile=kfile;
-    share->mode=open_mode;
     share->this_process=(ulong) getpid();
     share->rnd= (int)	 share->this_process;	/* rnd-counter for splits */
 #ifndef DBUG_OFF
@@ -433,27 +417,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
       my_errno=EACCES;				/* Can't open in write mode */
       goto err;
     }
-#ifdef USE_RAID
-    if (share->base.raid_type)
-    {
-      if ((info.dfile=my_raid_open(fn_format(name_buff,old_info->filename,"",
-					     MI_NAME_DEXT, 2+4),
-				   mode | O_SHARE,
-				   share->base.raid_type,
-				   share->base.raid_chunks,
-				   share->base.raid_chunksize,
-				   MYF(MY_WME | MY_RAID))) < 0)
+    if (mi_open_datafile(&info, share))
       goto err;
-    }
-    else
-#endif
-      if ((info.dfile=my_open(fn_format(name_buff,old_info->filename,"",
-					MI_NAME_DEXT,2+4),
-			      mode | O_SHARE,MYF(MY_WME))) < 0)
-	{
-	  my_errno=errno;
-	  goto err;
-	}
     errpos=5;
   }
 
@@ -1009,3 +974,40 @@ char *mi_recinfo_read(char *ptr, MI_COLUMNDEF *recinfo)
    recinfo->null_pos=mi_uint2korr(ptr); ptr +=2;
    return ptr;
 }
+
+/**************************************************************************
+ ** Help functions for recover
+ *************************************************************************/
+
+int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share)
+{
+  char name_buff[FN_REFLEN];
+  (void) fn_format(name_buff, share->filename,"",MI_NAME_DEXT, 2+4);
+
+#ifdef USE_RAID
+  if (share->base.raid_type)
+  {
+    if ((info->dfile=my_raid_open(name_buff,
+				  share->mode | O_SHARE,
+				  share->base.raid_type,
+				  share->base.raid_chunks,
+				  share->base.raid_chunksize,
+				  MYF(MY_WME | MY_RAID))) < 0)
+      return 1;
+  }
+  else
+#endif
+    if ((info->dfile=my_open(name_buff, share->mode | O_SHARE,
+			     MYF(MY_WME))) < 0)
+      return 1;
+  return 0;
+}
+
+
+int mi_open_keyfile(MYISAM_SHARE *share)
+{
+  if ((share->kfile=my_open(share->filename, share->mode | O_SHARE,
+			    MYF(MY_WME))) < 0)
+    return 1;
+  return 0;
+}
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index 7fad3349d371b68be75b8c1e1f74f3c80dd989b7..26e1699a07c02f4597477e1aa08915769175c3fb 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -196,7 +196,7 @@ static struct option long_options[] =
 
 static void print_version(void)
 {
-  printf("%s  Ver 1.34 for %s at %s\n",my_progname,SYSTEM_TYPE,
+  printf("%s  Ver 1.35 for %s at %s\n",my_progname,SYSTEM_TYPE,
 	 MACHINE_TYPE);
 }
 
@@ -677,27 +677,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
 	  error|=change_to_newfile(fixed_name,MI_NAME_DEXT,DATA_TMP_EXT,
 				   raid_chunks,
 				   MYF(0));
-#ifdef USE_RAID
-	  if (share->base.raid_type)
-	  {
-	    mi_check_print_info(&check_param,"Opening as RAID-ed table\n");
-	    info->dfile=my_raid_open(fn_format(param->temp_filename,
-					       fixed_name,"",
-					       MI_NAME_DEXT, 2+4),
-				     O_RDWR | O_SHARE,
-				     share->base.raid_type,
-				     raid_chunks,
-				     share->base.raid_chunksize,
-				     MYF(MY_WME | MY_RAID));
-	  }
-	  else
-#endif
-	    info->dfile=my_open(fn_format(param->temp_filename,
-					  fixed_name,"",
-					  MI_NAME_DEXT,2+4),
-				O_RDWR | O_SHARE,
-				MYF(MY_WME));
-	  if (info->dfile < 0)
+	  if (mi_open_datafile(info,info->s))
 	    error=1;
 	  param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */
 	  param->read_cache.file=info->dfile;
@@ -1142,7 +1122,8 @@ static int mi_sort_records(MI_CHECK *param,
   SORT_INFO *sort_info= &param->sort_info;
   DBUG_ENTER("sort_records");
 
-  bzero((char*) sort_info,sizeof(sort_info));
+  bzero((char*) sort_info,sizeof(*sort_info));
+  sort_info->param=param;
   keyinfo= &share->keyinfo[sort_key];
   got_error=1;
   temp_buff=0;
diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h
index e436e0872ca42d0f52b72d3120167d6c2ffb423c..1af94de1990d8fae952644c2193df2a1cfee2d86 100644
--- a/myisam/myisamdef.h
+++ b/myisam/myisamdef.h
@@ -626,6 +626,8 @@ int _mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
 	     enum ha_rkey_function search_flag, bool raw_key);
 
 my_bool check_table_is_closed(const char *name, const char *where);
+int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share);
+int mi_open_keyfile(MYISAM_SHARE *share);
 
 /* Functions needed by mi_check */
 #ifdef	__cplusplus
diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c
index e78cb3ca2aeca4907acf7f4f141949fe353ba6f5..c3fccda09bf89b6a810f322e6d4ca021c087e5d1 100644
--- a/mysys/mf_tempfile.c
+++ b/mysys/mf_tempfile.c
@@ -100,7 +100,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix,
       return 1;
     }
     strmov(to,dir);
-    strmov(convert_dirname(to),prefix);
+    strmov(convert_dirname(to),prefix_buff);
     file=mkstemp(to);
   }
 #elif defined(HAVE_TEMPNAM)
diff --git a/sql-bench/bench-init.pl.sh b/sql-bench/bench-init.pl.sh
index 3b9e343bc4a4385ea7d9dcd96db77029ca97407f..3f650885c216050abcd8c4c88372c8a7e0500a08 100755
--- a/sql-bench/bench-init.pl.sh
+++ b/sql-bench/bench-init.pl.sh
@@ -51,7 +51,7 @@ $log_prog_args=join(" ", skip_arguments(\@ARGV,"comments","cmp","server",
 					"user", "host", "database", "password",
 					"use-old-results","skip-test",
 					"machine", "dir", "suffix", "log"));
-GetOptions("skip-test=s","comments=s","cmp=s","server=s","user=s","host=s","database=s","password=s","loop-count=i","row-count=i","skip-create","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","field-count=i","regions=i","groups=i","time-limit=i","log","use-old-results","machine=s","dir=s","suffix=s","help","odbc","small-test","small-tables","small-key-tables","stage=i","old-headers","die-on-errors","create-options","hires") || usage();
+GetOptions("skip-test=s","comments=s","cmp=s","server=s","user=s","host=s","database=s","password=s","loop-count=i","row-count=i","skip-create","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","field-count=i","regions=i","groups=i","time-limit=i","log","use-old-results","machine=s","dir=s","suffix=s","help","odbc","small-test","small-tables","small-key-tables","stage=i","old-headers","die-on-errors","create-options=s","hires") || usage();
 
 usage() if ($opt_help);
 $server=get_server($opt_server,$opt_host,$opt_database,$opt_odbc,
@@ -400,6 +400,11 @@ All benchmarks takes the following options:
   with the same --cmp, you will get a test that is comparable between
   the different sql servers.
 
+--create-options=#
+  Extra argument to all create statements.  If you for example want to
+  create all MySQL tables as BDB tables use:
+  --create-options=TYPE=BDB
+
 --database (Default $opt_database)
   In which database the test tables are created.
 
diff --git a/sql-bench/test-insert.sh b/sql-bench/test-insert.sh
index ec269df5d3b7a3344f27a59efc0587ab77c5a799..a6161781ba970fe0ad21ef84d141d2d195a82698 100755
--- a/sql-bench/test-insert.sh
+++ b/sql-bench/test-insert.sh
@@ -572,7 +572,7 @@ if ($limits->{'group_functions'})
 
   $loop_time=new Benchmark;
   $count=$estimated=0;
-  for ($tests=0 ; $tests < $small_loop_count ; $tests++)
+  for ($tests=1 ; $tests <= $small_loop_count ; $tests++)
   {
     $count+=2;
     fetch_all_rows($dbh,"select count(distinct dummy1) from bench1");
@@ -834,7 +834,7 @@ if ($limits->{'func_odbc_floor'} && $limits->{'left_outer_join'})
 
   $count=$estimated=0;
   $loop_time=new Benchmark;
-  for ($i=0 ; $i < $small_loop_count ; $i++)
+  for ($i=1 ; $i <= $small_loop_count ; $i++)
   {
     $count+=fetch_all_rows($dbh,"select count(a.dummy1),count(b.dummy1) from bench1 as a left outer join bench1 as b on (a.id2=b.id3) where b.id3 is null");
     $end_time=new Benchmark;
diff --git a/sql/field.cc b/sql/field.cc
index 67bc84c0e3b994ab3eeaaf63c7c25bb5418e2861..459c53ffcb1cfff170b3fc039a62011d94b012b6 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4574,6 +4574,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
     interval= ((Field_enum*) old_field)->typelib;
   else
     interval=0;
+  def=0;
   if (!old_field->is_real_null() && ! (flags & BLOB_FLAG) &&
       old_field->type() != FIELD_TYPE_TIMESTAMP && old_field->ptr &&
       orig_field)
@@ -4584,15 +4585,14 @@ create_field::create_field(Field *old_field,Field *orig_field)
     /* Get the value from record[2] (the default value row) */
     my_ptrdiff_t diff= (my_ptrdiff_t) (orig_field->table->rec_buff_length*2);
     orig_field->move_field(diff);		// Points now at record[2]
+    bool is_null=orig_field->is_real_null();
     res=orig_field->val_str(&tmp,&tmp);
     orig_field->move_field(-diff);		// Back to record[0]
-    if (res)					// If not NULL value
+    if (!is_null)
     {
       pos= (char*) sql_memdup(tmp.ptr(),tmp.length()+1);
       pos[tmp.length()]=0;
       def=new Item_string(pos,tmp.length());
     }
   }
-  else
-    def=0;
 }
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 22cc5b6964b576e76a18465f18e70f602706338c..274d9164a9bdde19cbce50f9880c668afeda67b0 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -1472,11 +1472,11 @@ ha_rows ha_berkeley::records_in_range(int keynr,
   DB_KEY_RANGE start_range, end_range;
   double start_pos,end_pos,rows;
   DBUG_ENTER("records_in_range");
-  if ((start_key && file->key_range(file,transaction,
+  if ((start_key && file->key_range(key_file[keynr],transaction,
 				    pack_key(&key, keynr, key_buff, start_key,
 					     start_key_len),
 				    &start_range,0)) ||
-      (end_key && file->key_range(file,transaction,
+      (end_key && file->key_range(key_file[keynr],transaction,
 				  pack_key(&key, keynr, key_buff, end_key,
 					   end_key_len),
 				  &end_range,0)))
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 5cb4432dea2e902b2d0ad84b37bbe09e00b6a277..5ceacfd52de934410be85940fc86067e17ca3af2 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -35,7 +35,7 @@ ulong myisam_recover_options= HA_RECOVER_NONE;
 
 /* bits in myisam_recover_options */
 const char *myisam_recover_names[] =
-{ "DEFAULT", "BACKUP", "FORCE"};
+{ "DEFAULT", "BACKUP", "FORCE", "QUICK"};
 TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"",
 				 myisam_recover_names};
 
@@ -423,11 +423,15 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
     if (param.retry_without_quick && param.opt_rep_quick)
     {
       param.opt_rep_quick=0;
+      sql_print_error("Warning: Retrying recover of:  %s without quick",
+		      table->path);
       continue;
     }
     if ((param.testflag & T_REP_BY_SORT))
     {
       param.testflag= (param.testflag & ~T_REP_BY_SORT) | T_REP;      
+      sql_print_error("Warning: Retrying recover of:  %s with safe repair",
+		      table->path);
       continue;
     }
     break;
@@ -532,6 +536,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
   {
     if (param.out_flag & (O_NEW_DATA | O_NEW_INDEX))
     {
+      bool in_auto_repair;
       /*
 	We have to close all instances of this file to ensure that we can
 	do the rename safely on all operating system and to ensure that
@@ -539,9 +544,18 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
       */
       thd->proc_info="renaming file";
       VOID(pthread_mutex_lock(&LOCK_open));
-      if (close_cached_table(thd,table))
-	error=1;
-
+      if (!(in_auto_repair = (table->table_cache_key == 0)))
+      {
+	if (close_cached_table(thd,table))
+	  error=1;
+      }
+      else
+      {
+	if (param.out_flag & O_NEW_DATA)
+	  my_close(file->dfile,MYF(0));
+	if (param.out_flag & O_NEW_INDEX)
+	  my_close(file->s->kfile,MYF(0));
+      }
       if (param.out_flag & O_NEW_DATA)
 	error|=change_to_newfile(fixed_name,MI_NAME_DEXT,
 				 DATA_TMP_EXT, 0, MYF(0));
@@ -549,6 +563,13 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
       if (param.out_flag & O_NEW_INDEX)
 	error|=change_to_newfile(fixed_name,MI_NAME_IEXT,
 				 INDEX_TMP_EXT, 0, MYF(0));
+      if (in_auto_repair)
+      {
+	if ((param.out_flag & O_NEW_DATA) && mi_open_datafile(file,file->s))
+	  error=1;
+	if ((param.out_flag & O_NEW_DATA) && mi_open_keyfile(file->s))
+	  error=1;
+      }
       VOID(pthread_mutex_unlock(&LOCK_open));
     }
   }
@@ -600,16 +621,20 @@ bool ha_myisam::check_and_repair(THD *thd)
   DBUG_ENTER("ha_myisam::auto_check_and_repair");
 
   check_opt.init();
-  check_opt.flags= T_MEDIUM;
-  check_opt.quick= !file->state->del;	// Don't use quick if deleted rows
+  check_opt.flags= T_MEDIUM | T_AUTO_REPAIR;
+  // Don't use quick if deleted rows
+  if (!file->state->del && (myisam_recover_options & HA_RECOVER_QUICK))
+    check_opt.quick=1;
+  sql_print_error("Warning: Checking table:  %s",table->path);
   if (mi_is_crashed(file) || check(thd, &check_opt))
   {
+    sql_print_error("Warning: Recovering table: %s",table->path);
     if (check_opt.retry_without_quick)
       check_opt.quick=0;
     check_opt.flags=(((myisam_recover_options & HA_RECOVER_BACKUP) ? 
 		      T_BACKUP_DATA : 0) |
 		     (!(myisam_recover_options & HA_RECOVER_FORCE) ? 
-		      T_SAFE_REPAIR : 0));
+		      T_SAFE_REPAIR : 0)) | T_AUTO_REPAIR;
     if (repair(thd, &check_opt))
       error=1;
   }
diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h
index ff959ead883807065dbc3c5666481a48ed804dc7..e0165d469207c798e4f6276da913c61cf3636f74 100644
--- a/sql/ha_myisam.h
+++ b/sql/ha_myisam.h
@@ -28,6 +28,7 @@
 #define HA_RECOVER_DEFAULT	1	// Automatic recover active
 #define HA_RECOVER_BACKUP	2	// Make a backupfile on recover
 #define HA_RECOVER_FORCE	4	// Recover even if we loose rows
+#define HA_RECOVER_QUICK	8	// Don't check rows in data file
 
 extern ulong myisam_sort_buffer_size;
 extern TYPELIB myisam_recover_typelib;
diff --git a/sql/handler.cc b/sql/handler.cc
index a0ec18d3614c7ba8252321890f1beebca7297351..c7353a864ff874176282b7e53ece8d53b749ccb2 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -32,6 +32,9 @@
 #ifdef HAVE_BERKELEY_DB
 #include "ha_berkeley.h"
 #endif
+#ifdef HAVE_INNOBASE_DB
+#include "ha_innobase.h"
+#endif
 #include <myisampack.h>
 #include <errno.h>
 
@@ -46,7 +49,7 @@ ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count,
 
 const char *ha_table_type[] = {
   "", "DIAB_ISAM","HASH","MISAM","PISAM","RMS_ISAM","HEAP", "ISAM",
-  "MRG_ISAM","MYISAM", "MRG_MYISAM", "BERKELEY_DB?", "?", "?",NullS
+  "MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNOBASE", "?", "?",NullS
 };
 
 const char *ha_row_type[] = {
@@ -66,6 +69,10 @@ enum db_type ha_checktype(enum db_type database_type)
   case DB_TYPE_BERKELEY_DB:
     return(berkeley_skip ? DB_TYPE_MYISAM : database_type);
 #endif
+#ifdef HAVE_INNOBASE_DB
+  case DB_TYPE_INNOBASE:
+    return(innobase_skip ? DB_TYPE_MYISAM : database_type);
+#endif
 #ifndef NO_HASH
   case DB_TYPE_HASH:
 #endif
@@ -103,6 +110,10 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
 #ifdef HAVE_BERKELEY_DB
   case DB_TYPE_BERKELEY_DB:
     return new ha_berkeley(table);
+#endif
+#ifdef HAVE_INNOBASE_DB
+  case DB_TYPE_INNOBASE_DB:
+    return new ha_innobase(table);
 #endif
   case DB_TYPE_HEAP:
     return new ha_heap(table);
@@ -123,6 +134,14 @@ int ha_init()
     if ((error=berkeley_init()))
       return error;
   }
+#endif
+#ifdef HAVE_INNOBASE_DB
+  if (!innobase_skip)
+  {
+    int error;
+    if ((error=innobase_init()))
+      return error;
+  }
 #endif
   return 0;
 }
@@ -146,6 +165,10 @@ int ha_panic(enum ha_panic_function flag)
 #ifdef HAVE_BERKELEY_DB
   if (!berkeley_skip)
     error|=berkeley_end();
+#endif
+#ifdef HAVE_INNOBASE_DB
+  if (!innobase_skip)
+    error|=innobase_end();
 #endif
   return error;
 } /* ha_panic */
@@ -154,7 +177,7 @@ int ha_panic(enum ha_panic_function flag)
 int ha_autocommit_or_rollback(THD *thd, int error)
 {
   DBUG_ENTER("ha_autocommit_or_rollback");
-#ifdef HAVE_BERKELEY_DB
+#if defined(HAVE_BERKELEY_DB) || defined(HAVE_INNOBASE_DB)
   if ((thd->options & OPTION_AUTO_COMMIT) && !thd->locked_tables)
   {
     if (!error)
@@ -183,6 +206,17 @@ int ha_commit(THD *thd)
       error=1;
     }
   }
+#endif
+#ifdef HAVE_INNOBASE_DB
+  if (thd->transaction.innobase_tid)
+  {
+    int error=innobase_commit(thd);
+    if (error)
+    {
+      my_error(ER_ERROR_DURING_COMMIT, MYF(0), error);
+      error=1;
+    }
+  }
 #endif
   DBUG_RETURN(error);
 }
@@ -201,6 +235,17 @@ int ha_rollback(THD *thd)
       error=1;
     }
   }
+#endif
+#ifdef HAVE_INNOBASE_DB
+  if (thd->transaction.innobase_tid)
+  {
+    int error=innobase_rollback(thd);
+    if (error)
+    {
+      my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error);
+      error=1;
+    }
+  }
 #endif
   DBUG_RETURN(error);
 }
@@ -212,6 +257,10 @@ bool ha_flush_logs()
 #ifdef HAVE_BERKELEY_DB
   if (!berkeley_skip && berkeley_flush_logs())
     result=1;
+#endif
+#ifdef HAVE_INNOBASE_DB
+  if (!innobase_skip && innobase_flush_logs())
+    result=1;
 #endif
   return result;
 }
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index b3494f7c81dfe1c390faa687d0c6865ca9d7d2c0..a52b9a8585736104fc3707eef3e62b7571ab6d9e 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -448,7 +448,7 @@ skipp:
       res->replace((uint) offset,from_length,*res3);
       offset+=(int) to_length;
     }
-    while ((offset=res->strstr(*res2,(uint) offset)) >0);
+    while ((offset=res->strstr(*res2,(uint) offset)) >= 0);
   return res;
 
 null:
@@ -768,7 +768,7 @@ String *Item_func_substr_index::val_str(String *str)
     }
     else
     {					// Start counting at end
-      for (offset=res->length() ; ; offset-=delimeter_length)
+      for (offset=res->length() ; ; offset-=delimeter_length-1)
       {
 	if ((int) (offset=res->strrstr(*delimeter,offset)) < 0)
 	  return res;			// Didn't find, return org string
diff --git a/sql/log_event.h b/sql/log_event.h
index 9875f7bddacc0375508f5517da654b4f5ce1c78f..4b2739d15923de2eed8722afc3f517df9cf32835 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -308,7 +308,7 @@ public:
   
   Start_log_event() :Log_event(time(NULL)),binlog_version(BINLOG_VERSION)
   {
-    created = when;
+    created = (uint32) when;
     memcpy(server_version, ::server_version, sizeof(server_version));
   }
   Start_log_event(FILE* file, time_t when_arg, uint32 server_id) :
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 8f3532dab46d210b8ccf5f02dbe10e6ba3e9136a..5f15ca9794a5fb20699ed01ca766ca93ffb76c6d 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -21,6 +21,9 @@
 #ifdef HAVE_BERKELEY_DB
 #include "ha_berkeley.h"
 #endif
+#ifdef HAVE_INNOBASE_DB
+#include "ha_innobase.h"
+#endif
 #include "ha_myisam.h"
 #include <nisam.h>
 #include <thr_alarm.h>
@@ -147,8 +150,7 @@ static ulong opt_specialflag=SPECIAL_ENGLISH;
 static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET;
 static ulong back_log,connect_timeout,concurrency;
 static my_string opt_logname=0,opt_update_logname=0,
-  opt_binlog_index_name = 0,opt_slow_logname=0;
-my_string opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
+       opt_binlog_index_name = 0,opt_slow_logname=0;
 static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN];
 static pthread_t select_thread;
 static pthread_t flush_thread;			// Used when debugging
@@ -231,9 +233,11 @@ char mysql_real_data_home[FN_REFLEN],
      default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list,
      blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot,
      *opt_init_file;
+char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc
 char server_version[50]=MYSQL_SERVER_VERSION;
 const char *first_keyword="first";
 const char **errmesg;			/* Error messages */
+const char *myisam_recover_options_str="OFF";
 byte last_ref[MAX_REFLENGTH];		/* Index ref of keys */
 my_string mysql_unix_port=NULL,mysql_tmpdir=NULL;
 ulong my_bind_addr;			/* the address we bind to */
@@ -2219,7 +2223,8 @@ enum options {
                OPT_LOG_SLAVE_UPDATES,    OPT_BINLOG_DO_DB, 
                OPT_BINLOG_IGNORE_DB,     OPT_WANT_CORE,
 	       OPT_SKIP_CONCURRENT_INSERT, OPT_MEMLOCK, OPT_MYISAM_RECOVER,
-	       OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID, OPT_SKIP_SLAVE_START
+	       OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID, OPT_SKIP_SLAVE_START,
+	       OPT_SKIP_INNOBASE
 };
 
 static struct option long_options[] = {
@@ -2292,6 +2297,9 @@ static struct option long_options[] = {
   {"set-variable",          required_argument, 0, 'O'},
 #ifdef HAVE_BERKELEY_DB
   {"skip-bdb",              no_argument,       0, (int) OPT_BDB_SKIP},
+#endif
+#ifdef HAVE_INNOBASE_DB
+  {"skip-innobase",         no_argument,       0, (int) OPT_INNOBASE_SKIP},
 #endif
   {"skip-concurrent-insert", no_argument,      0, (int) OPT_SKIP_CONCURRENT_INSERT},
   {"skip-delay-key-write",  no_argument,       0, (int) OPT_SKIP_DELAY_KEY_WRITE},
@@ -2443,6 +2451,7 @@ struct show_var_st init_vars[]= {
   {"max_sort_length",         (char*) &max_item_sort_length,        SHOW_LONG},
   {"max_tmp_tables",          (char*) &max_tmp_tables,              SHOW_LONG},
   {"max_write_lock_count",    (char*) &max_write_lock_count,        SHOW_LONG},
+  {"myisam_recover_options",  (char*) &myisam_recover_options_str,  SHOW_CHAR_PTR},
   {"myisam_sort_buffer_size", (char*) &myisam_sort_buffer_size,     SHOW_LONG},
   {"net_buffer_length",       (char*) &net_buffer_length,           SHOW_LONG},
   {"net_retry_count",         (char*) &mysqld_net_retry_count,      SHOW_LONG},
@@ -2647,6 +2656,11 @@ static void usage(void)
   --bdb-tmpdir=directory  Berkeley DB tempfile name\n\
   --skip-bdb		  Don't use berkeley db (will save memory)\n\
 ");
+#endif
+#ifdef HAVE_INNOBASE_DB
+  puts("\
+  --skip-innobase	  Don't use innobase (will save memory)\n\
+");
 #endif
   print_defaults("my",load_default_groups);
   puts("");
@@ -2917,11 +2931,13 @@ static void get_options(int argc,char **argv)
       myisam_delay_key_write=0;
       myisam_concurrent_insert=0;
       myisam_recover_options= HA_RECOVER_NONE;
+      ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
       break;
     case (int) OPT_SAFE:
       opt_specialflag|= SPECIAL_SAFE_MODE;
       myisam_delay_key_write=0;
       myisam_recover_options= HA_RECOVER_NONE;	// To be changed
+      ha_open_options&= ~HA_OPEN_ABORT_IF_CRASHED;
       break;
     case (int) OPT_SKIP_CONCURRENT_INSERT:
       myisam_concurrent_insert=0;
@@ -3085,17 +3101,30 @@ static void get_options(int argc,char **argv)
     case OPT_BDB_SKIP:
       berkeley_skip=1;
       break;
+#endif
+#ifdef HAVE_INNOBASE_DB
+    case OPT_INNOBASE_SKIP:
+      innobase_skip=1;
+      break;
 #endif
     case OPT_MYISAM_RECOVER:
     {
       if (!optarg || !optarg[0])
-	myisam_recover_options=HA_RECOVER_DEFAULT;
-      else if ((myisam_recover_options=
-		find_bit_type(optarg, &myisam_recover_typelib)) == ~(ulong) 0)
       {
-	fprintf(stderr, "Unknown option to myisam-recover: %s\n",optarg);
-	exit(1);
+	myisam_recover_options=    HA_RECOVER_DEFAULT;
+	myisam_recover_options_str= myisam_recover_typelib.type_names[0];
+      }
+      else
+      {
+	myisam_recover_options_str=optarg;
+	if ((myisam_recover_options=
+		find_bit_type(optarg, &myisam_recover_typelib)) == ~(ulong) 0)
+	{
+	  fprintf(stderr, "Unknown option to myisam-recover: %s\n",optarg);
+	  exit(1);
+	}
       }
+      ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
       break;
     }
     case OPT_MASTER_HOST:
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 316ba28001a516add94363c52431faa25e23c7d2..a6b563046c799a9149f60ae2ab47bd248bb3ac16 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -706,7 +706,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
     /* make a new table */
     if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME))))
       DBUG_RETURN(NULL);
-    if (open_unireg_entry(thd, table,db,table_name,alias,0) ||
+    if (open_unireg_entry(thd, table,db,table_name,alias,1) ||
 	!(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
 					     key_length)))
     {
@@ -1157,7 +1157,6 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
     thd->net.last_error[0]=0;				// Clear error message
     thd->net.last_errno=0;
     error=0;
-    sql_print_error("Warning: Repairing table: %s.%s",db,name);
     if (openfrm(path,alias,
 		(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
 			 HA_TRY_READ_ONLY),
@@ -1167,11 +1166,17 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
 	(entry->file->is_crashed() && entry->file->check_and_repair(thd)))
     {
       sql_print_error("Error: Couldn't repair table: %s.%s",db,name);
+      closefrm(entry);
       error=1;
     }
+    else
+    {
+      thd->net.last_error[0]=0;				// Clear error message
+      thd->net.last_errno=0;
+    }
     unlock_table_name(thd,&table_list);
     if (locked)
-      pthread_mutex_lock(&LOCK_open);      // Get back old lock
+      pthread_mutex_lock(&LOCK_open);      // Get back original lock
     if (error)
       goto err;
   }
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 23c0f1d05ecf7ed8401de013bbd60be23dca64ab..87c94c221699c193df04859ea03904bef1d2123e 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -501,6 +501,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
   if ((create_info->options & HA_LEX_CREATE_TMP_TABLE)
       && find_temporary_table(thd,db,table_name))
   {
+    if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
+      DBUG_RETURN(0);
     my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
     DBUG_RETURN(-1);
   }