diff --git a/Docs/manual.texi b/Docs/manual.texi
index 73feaa50aa3aea4ac0220bc354759d5736f9ec72..75e62b022598ea4b469ea5263a8acc58f926f88b 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -27956,8 +27956,8 @@ Debug log. Default is 'd:t:o,/tmp/mysql.trace'
 @item -D, --database=..
 Database to use;  This is mainly useful in the @code{my.cnf} file.
 @cindex default character set option
-@item
---default-character-set=...    Set the default character set.
+@item --default-character-set=... 
+Set the default character set.
 @cindex execute option
 @item -e, --execute=...
 Execute command and quit. (Output like with --batch)
@@ -27992,6 +27992,12 @@ Produce HTML output.
 @item -L, --skip-line-numbers
 Don't write line number for errors. Useful when one want's to compare result
 files that includes error messages
+@cindex no pager option
+@item --no-pager
+Disable pager and print to stdout. See interactive help (\h) also.
+@cindex no tee option
+@item --no-tee
+Disable outfile. See interactive help (\h) also.
 @cindex unbuffered option.
 @item -n, --unbuffered
 Flush buffer after each query.
@@ -28005,7 +28011,11 @@ Give a variable a value. @code{--help} lists variables.
 @item -o, --one-database
 Only update the default database. This is useful for skipping updates to
 other database in the update log.
-@item
+@cindex pager option
+@item @code{--pager[=...]}
+Output type. Default is your @code{ENV} variable @code{PAGER}. Valid
+pagers are less, more, cat [> filename], etc.  See interactive help (\h)
+also. This option does not work in batch mode. Pager works only in UNIX.
 @cindex password option
 @item -p[password], --password[=...]
 Password to use when connecting to server. If password is not given on
@@ -28031,6 +28041,10 @@ Socket file to use for connection.
 Output in table format. This is default in non-batch mode.
 @item -T, --debug-info
 Print some debug info at exit.
+@cindex tee option
+@item --tee=...
+Append everything into outfile. See interactive help (\h) also. Does not
+work in batch mode.
 @cindex user option
 @item -u, --user=#
 User for login if not current user.
@@ -28058,21 +28072,27 @@ commands that it supports:
 mysql> help
 
 MySQL commands:
-help    (\h)    Display this text
-?       (\h)    Synonym for `help'
-clear   (\c)    Clear command
-connect (\r)    Reconnect to the server. Optional arguments are db and host
-edit    (\e)    Edit command with $EDITOR
-exit    (\q)    Exit mysql. Same as quit
-go      (\g)    Send command to mysql server
-ego     (\G)    Send command to mysql server; Display result vertically
-print   (\p)    Print current command
-quit    (\q)    Quit mysql
-rehash  (\#)    Rebuild completion hash
-source  (\.)    Execute a SQL script file. Takes a file name as an argument
-status  (\s)    Get status information from the server
-use     (\u)    Use another database. Takes database name as argument
-@end example
+help    (\h)    Display this text.
+?       (\h)    Synonym for `help'.
+clear   (\c)    Clear command.
+connect (\r)    Reconnect to the server. Optional arguments are db and host.
+edit    (\e)    Edit command with $EDITOR.
+ego     (\G)    Send command to mysql server, display result vertically.
+exit    (\q)    Exit mysql. Same as quit.
+go      (\g)    Send command to mysql server.
+nopager (\n)    Disable pager, print to stdout.
+notee   (\t)    Don't write into outfile.
+pager   (\P)    Set PAGER [to_pager]. Print the query results via PAGER.
+print   (\p)    Print current command.
+quit    (\q)    Quit mysql.
+rehash  (\#)    Rebuild completion hash.
+source  (\.)    Execute a SQL script file. Takes a file name as an argument.
+status  (\s)    Get status information from the server.
+tee     (\T)    Set outfile [to_outfile]. Append everything into given outfile.
+use     (\u)    Use another database. Takes database name as argument.
+@end example
+
+From the above, pager only works in UNIX.
 
 @cindex status command
 The @code{status} command gives you some information about the
@@ -28112,6 +28132,68 @@ All big results are automatically limited to @code{#select_limit#} rows.
 @code{#max_join_size} row combinations will be aborted.
 @end itemize
 
+Some useful hints about the @code{mysql} client:
+
+Some data is much more readable when displayed vertically, instead of
+the usual horizontal box type output. For example longer text, which
+includes new lines, is often much easier to be read with vertical
+output.
+
+@example
+mysql> select * from mails where length(txt) < 300 limit 300,1\G
+*************************** 1. row ***************************
+  msg_nro: 3068
+     date: 2000-03-01 23:29:50
+time_zone: +0200
+mail_from: Monty
+    reply: monty@@no.spam.com
+  mail_to: "Thimble Smith" <tim@@no.spam.com>
+      sbj: UTF-8
+      txt: >>>>> "Thimble" == Thimble Smith writes:
+
+Thimble> Hi.  I think this is a good idea.  Is anyone familiar with UTF-8
+Thimble> or Unicode?  Otherwise I'll put this on my TODO list and see what
+Thimble> happens.
+
+Yes, please do that.
+
+Regards,
+Monty
+     file: inbox-jani-1
+     hash: 190402944
+1 row in set (0.09 sec)
+@end example
+
+For logging, one can use the @code{tee} option. The @code{tee} can be
+started with option @code{--tee=...}, or from the command line
+interactively with command @code{tee}. All the data displayed on the
+screen will also be appended into a given file. This can be very useful
+for debugging purposes also. The @code{tee} can be disabled from the
+command line with command @code{notee}. Executing @code{tee} again
+starts logging again. Without a parameter the previous file will be
+used. Note that @code{tee} will flush the results into the file after
+each command, just before the command line appears again waiting for the
+next command.
+
+Browsing, or searching the results in the interactive mode in UNIX less,
+more, or any other similar program, is now possible with option
+@code{--pager[=...]}. Without argument, @code{mysql} client will look
+for environment variable PAGER and set @code{pager} to that.
+@code{pager} can be started from the interactive command line with
+command @code{pager} and disabled with command @code{nopager}.  The
+command takes an argument optionally and the @code{pager} will be set to
+that. Command @code{pager} can be called without an argument, but this
+requires that the option @code{--pager} was used, or the @code{pager}
+will default to stdout. @code{pager} works only in UNIX, since it uses
+the popen() function, which doesn't exist in Windows. In Windows, the
+@code{tee} option can be used instead, although it may not be as handy
+as @code{pager} can be in some situations.
+
+You can even combine the two functions above; have the @code{tee}
+enabled, @code{pager} set to 'less' and you will be able to browse the
+results in unix 'less' and still have everything appended into a file
+the same time.
+
 @cindex administration, server
 @cindex server administration
 @cindex @code{mysladmn}
@@ -38720,6 +38802,17 @@ though, so Version 3.23 is not released as a stable version yet.
 @appendixsubsec Changes in release 3.23.28
 @itemize @bullet
 @item
+Fixed crash when automatic repair of @code{MyISAM} table failed.
+@item
+Fixed a major performance bug in the table locking code when one
+constantly had a LOT of @code{SELECT}, @code{UPDATE} and @code{INSERT}
+statements running. The symptom was that the @code{UPDATE} and
+@code{INSERT} queries was locked a long time while new @code{SELECT}
+statements where executed without locks.
+@item
+When reading options_files with @code{mysql_options()} the
+@code{return-found-rows} option was ignored.
+@item
 One can now specify @code{interactive-timeout} in the option file that
 is read by @code{mysql_options()}. This makes it possible to force
 programs that runs for a long time (like @code{mysqlhotcopy}) to use
@@ -43265,6 +43358,8 @@ Secure connections (with SSL).
 @item
 Extend the optimizer to be able to optimize some
 @code{ORDER BY key_name DESC} queries.
+@item
+New key cache
 @end itemize
 
 @node TODO future, TODO sometime, TODO MySQL 4.0, TODO
diff --git a/client/mysql.cc b/client/mysql.cc
index 55990db575038b353f3852bc146392cc2f6abaae..e5246aac6c5efcc7cf860e593bc9dac00e2771ad 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -109,7 +109,7 @@ static HashTable ht;
 enum enum_info_type { INFO_INFO,INFO_ERROR,INFO_RESULT};
 typedef enum enum_info_type INFO_TYPE;
 
-const char *VER="11.4";
+const char *VER="11.6";
 
 static MYSQL mysql;			/* The connection */
 static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0,
@@ -496,14 +496,12 @@ static void usage(int version)
 			Give a variable an value. --help lists variables.\n\
   -o, --one-database	Only update the default database. This is useful\n\
 			for skipping updates to other database in the update\n\
-			log.\n\
-  --tee=...             Append everything into outfile. See interactive help\n\
-                        (\\h) also. Does not work in batch mode.\n");
+			log.\n");
 #ifndef __WIN__
   printf("\
   --pager[=...]         Output type. Default is your ENV variable PAGER.\n\
                         Valid pagers are less, more, cat [> filename], etc.\n\
-                        See interactive help (\\h) also. This options does\n\
+                        See interactive help (\\h) also. This option does\n\
                         not work in batch mode.\n");
 #endif
   printf("\
@@ -524,7 +522,9 @@ static void usage(int version)
 #include "sslopt-usage.h"
   printf("\
   -t  --table		Output in table format.\n\
-  -T, --debug-info	Print some debug info at exit.\n");
+  -T, --debug-info	Print some debug info at exit.\n\
+  --tee=...             Append everything into outfile. See interactive help\n\
+                        (\\h) also. Does not work in batch mode.\n");
 #ifndef DONT_ALLOW_USER_CHANGE
   printf("\
   -u, --user=#		User for login if not current user.\n");
@@ -763,16 +763,6 @@ static int read_lines(bool execute_commands)
 	status.query_start_line=line_number;
     }
     else
-#ifdef __WIN__
-    {
-      tee_fprintf(stdout, glob_buffer.is_empty() ? "mysql> " :
-		  !in_string ? "    -> " :
-		  in_string == '\'' ?
-		  "    '> " : "    \"> ");
-      linebuffer[0]=(char) sizeof(linebuffer);
-      line=_cgets(linebuffer);
-    }
-#else
     {
       if (opt_outfile)
       {
@@ -783,14 +773,22 @@ static int read_lines(bool execute_commands)
 	      in_string == '\'' ?
 	      "    '> " : "    \"> ", OUTFILE);
       }
+#ifdef __WIN__
+      tee_fprintf(stdout, glob_buffer.is_empty() ? "mysql> " :
+		  !in_string ? "    -> " :
+		  in_string == '\'' ?
+		  "    '> " : "    \"> ");
+      linebuffer[0]=(char) sizeof(linebuffer);
+      line=_cgets(linebuffer);
+#else
       line=readline((char*) (glob_buffer.is_empty() ? "mysql> " :
 			     !in_string ? "    -> " :
 			     in_string == '\'' ?
 			     "    '> " : "    \"> "));
+#endif
       if (opt_outfile)
 	fprintf(OUTFILE, "%s\n", line);
     }
-#endif
     if (!line)					// End of file
     {
       status.exit_status=0;
@@ -1762,7 +1760,7 @@ com_pager(String *buffer, char *line __attribute__((unused)))
   {
     if (!strlen(default_pager))
     {
-      tee_fprintf(stdout, "Default pager wasn't available, using stdout.\n");
+      tee_fprintf(stdout, "Default pager wasn't set, using stdout.\n");
       opt_nopager=1;
       strmov(pager, "stdout");
       PAGER= stdout;
diff --git a/client/mysqladmin.c b/client/mysqladmin.c
index d5b2e73451e3fb53ef0559d9ec1c3bba1c47263a..4622e94eb9ce6e119e26fa8cc334c52629e65fe2 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.c
@@ -28,7 +28,7 @@
 #include <my_pthread.h>				/* because of signal()	*/
 #endif
 
-#define ADMIN_VERSION "8.11"
+#define ADMIN_VERSION "8.12"
 #define MAX_MYSQL_VAR 64
 #define MAX_TIME_TO_WAIT 3600			/* Wait for shutdown */
 #define MAX_TRUNC_LENGTH 3
diff --git a/extra/perror.c b/extra/perror.c
index ec523ecba0b83466ebf31d3089f17b6e0ee0579c..5fc1f75785b743b187d99a999cb1b6c9748557a4 100644
--- a/extra/perror.c
+++ b/extra/perror.c
@@ -66,6 +66,7 @@ static HA_ERRORS ha_errlist[]=
   { 142,"Unknown character set used"},
   { 143,"Conflicting table definition between MERGE and mapped table"},
   { 144,"Table is crashed and last repair failed"},
+  { 145,"Table was marked as crashed and should be repaired"},
   { 0,NullS },
 };
 
diff --git a/include/my_base.h b/include/my_base.h
index 5c76b5a6bc33a0bb7690ba1c09851440635f355f..5ab84fb343356318600414b6c7caaedc36e071ef 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -207,6 +207,7 @@ enum ha_base_keytype {
 #define HA_ERR_UNKNOWN_CHARSET	 142	/* Can't open charset */
 #define HA_ERR_WRONG_TABLE_DEF	 143
 #define HA_ERR_CRASHED_ON_REPAIR 144	/* Last (automatic?) repair failed */
+#define HA_ERR_CRASHED_ON_USAGE  145	/* Table must be repaired */
 
 	/* Other constants */
 
diff --git a/isam/rnext.c b/isam/rnext.c
index ebe00fc2fa1df7f043ad916c2215d955849d8df0..451624bb42b2d378f973c5ec3403f690b206fa70 100644
--- a/isam/rnext.c
+++ b/isam/rnext.c
@@ -27,7 +27,7 @@
 
 int nisam_rnext(N_INFO *info, byte *buf, int inx)
 {
-  int error;
+  int error,changed;
   uint flag;
   DBUG_ENTER("nisam_rnext");
 
@@ -40,10 +40,11 @@ int nisam_rnext(N_INFO *info, byte *buf, int inx)
 #ifndef NO_LOCKING
   if (_nisam_readinfo(info,F_RDLCK,1)) DBUG_RETURN(-1);
 #endif
+  changed=_nisam_test_if_changed(info);
   if (!flag)
     error=_nisam_search_first(info,info->s->keyinfo+inx,
 			   info->s->state.key_root[inx]);
-  else if (_nisam_test_if_changed(info) == 0)
+  else if (!changed)
     error=_nisam_search_next(info,info->s->keyinfo+inx,info->lastkey,flag,
 			  info->s->state.key_root[inx]);
   else
diff --git a/isam/rprev.c b/isam/rprev.c
index 18b1e31502c648bd109db26adf74dd3f01af4053..50f22c838fdcdaec909825d4574cb413c06c8620 100644
--- a/isam/rprev.c
+++ b/isam/rprev.c
@@ -27,7 +27,7 @@
 
 int nisam_rprev(N_INFO *info, byte *buf, int inx)
 {
-  int error;
+  int error,changed;
   register uint flag;
   DBUG_ENTER("nisam_rprev");
 
@@ -40,9 +40,10 @@ int nisam_rprev(N_INFO *info, byte *buf, int inx)
 #ifndef NO_LOCKING
   if (_nisam_readinfo(info,F_RDLCK,1)) DBUG_RETURN(-1);
 #endif
+  changed=_nisam_test_if_changed(info);
   if (!flag)
     error=_nisam_search_last(info,info->s->keyinfo+inx,info->s->state.key_root[inx]);
-  else if (_nisam_test_if_changed(info) == 0)
+  else if (!changed)
     error=_nisam_search_next(info,info->s->keyinfo+inx,info->lastkey,flag,
 			  info->s->state.key_root[inx]);
   else
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index c48b3e6140365447a01d28795ba975ac3fa55b7d..b7afcf8a25c95716c3a45ab180ccac826681ebbb 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1450,10 +1450,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
     mysql->unix_socket=0;
   strmov(mysql->server_version,(char*) net->read_pos+1);
   mysql->port=port;
-  mysql->client_flag=client_flag | mysql->options.client_flag;
-  DBUG_PRINT("info",("Server version = '%s'  capabilites: %ld  status: %d",
-		     mysql->server_version,mysql->server_capabilities,
-		     mysql->server_status));
+  client_flag|=mysql->options.client_flag;
 
   /* Send client information for access check */
   client_flag|=CLIENT_CAPABILITIES;
@@ -1510,6 +1507,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
   }
 #endif /* HAVE_OPENSSL */
 
+  DBUG_PRINT("info",("Server version = '%s'  capabilites: %ld  status: %d  client_flag: %d",
+		     mysql->server_version,mysql->server_capabilities,
+		     mysql->server_status, client_flag));
+
   int3store(buff+2,max_allowed_packet);
   if (user && user[0])
     strmake(buff+5,user,32);			/* Max user name */
diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c
index 45bb2cd7164c438144d01bddeb4eb958a873990f..057efb9618587dd33462df44b6a0e0a39b7f6e9d 100644
--- a/myisam/mi_locking.c
+++ b/myisam/mi_locking.c
@@ -382,6 +382,7 @@ int _mi_test_if_changed(register MI_INFO *info)
       share->state.unique  != info->last_unique ||
       share->state.update_count != info->last_loop)
   {						/* Keyfile has changed */
+    DBUG_PRINT("info",("index file changed"));
     if (share->state.process != share->this_process)
       VOID(flush_key_blocks(share->kfile,FLUSH_RELEASE));
     share->last_process=share->state.process;
diff --git a/myisam/mi_open.c b/myisam/mi_open.c
index c29a4a843ca861f111b76e9a2220b10a0b739443..2eab33228dcbada96e9baa9760729ed8b58e62a4 100644
--- a/myisam/mi_open.c
+++ b/myisam/mi_open.c
@@ -182,7 +182,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
     {
       DBUG_PRINT("error",("Table is marked as crashed"));
       my_errno=((share->state.changed & STATE_CRASHED_ON_REPAIR) ?
-		HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED);
+		HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
       goto err;
     }
     /* Correct max_file_length based on length of sizeof_t */
@@ -732,7 +732,8 @@ char *mi_state_info_read(char *ptr, MI_STATE_INFO *state)
   state->process= mi_uint4korr(ptr);		ptr +=4;
   state->unique = mi_uint4korr(ptr);		ptr +=4;
   state->status = mi_uint4korr(ptr);		ptr +=4;
-						ptr +=4; /* extra */
+  state->update_count=mi_uint4korr(ptr);	ptr +=4;
+
   for (i=0; i < keys; i++)
   {
     state->key_root[i]= mi_sizekorr(ptr);	ptr +=8;
diff --git a/myisam/mi_rnext.c b/myisam/mi_rnext.c
index f7e7b61d93405d416b943d49a231ab7c7721d5bd..f297740af60f957935b7a222320fe980d57636ba 100644
--- a/myisam/mi_rnext.c
+++ b/myisam/mi_rnext.c
@@ -25,7 +25,7 @@
 
 int mi_rnext(MI_INFO *info, byte *buf, int inx)
 {
-  int error;
+  int error,changed;
   uint flag;
   DBUG_ENTER("mi_rnext");
 
@@ -39,10 +39,13 @@ int mi_rnext(MI_INFO *info, byte *buf, int inx)
     DBUG_RETURN(my_errno);
   if (info->s->concurrent_insert)
     rw_rdlock(&info->s->key_root_lock[inx]);
+  changed=_mi_test_if_changed(info);
   if (!flag)
+  {
     error=_mi_search_first(info,info->s->keyinfo+inx,
 			   info->s->state.key_root[inx]);
-  else if (_mi_test_if_changed(info) == 0)
+  }
+  else if (!changed)
     error=_mi_search_next(info,info->s->keyinfo+inx,info->lastkey,
 			  info->lastkey_length,flag,
 			  info->s->state.key_root[inx]);
diff --git a/myisam/mi_rprev.c b/myisam/mi_rprev.c
index 471eecc33f588bf121936f7a23ab485b51764202..69d18b1028704eff25d5d12df8eda906bcda8293 100644
--- a/myisam/mi_rprev.c
+++ b/myisam/mi_rprev.c
@@ -25,7 +25,7 @@
 
 int mi_rprev(MI_INFO *info, byte *buf, int inx)
 {
-  int error;
+  int error,changed;
   register uint flag;
   MYISAM_SHARE *share=info->s;
   DBUG_ENTER("mi_rprev");
@@ -38,12 +38,13 @@ int mi_rprev(MI_INFO *info, byte *buf, int inx)
 
   if (_mi_readinfo(info,F_RDLCK,1))
     DBUG_RETURN(my_errno);
+  changed=_mi_test_if_changed(info);
   if (share->concurrent_insert)
     rw_rdlock(&share->key_root_lock[inx]);
   if (!flag)
     error=_mi_search_last(info, share->keyinfo+inx,
 			  share->state.key_root[inx]);
-  else if (_mi_test_if_changed(info) == 0)
+  else if (!changed)
     error=_mi_search_next(info,share->keyinfo+inx,info->lastkey,
 			  info->lastkey_length,flag,
 			  share->state.key_root[inx]);
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index b18f42bfb81fc231180cbf94bbf6b61187ec9663..d045bf0018bc983145d822c65243a1514fd63ea4 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.36 for %s at %s\n",my_progname,SYSTEM_TYPE,
+  printf("%s  Ver 1.37 for %s at %s\n",my_progname,SYSTEM_TYPE,
 	 MACHINE_TYPE);
 }
 
@@ -502,8 +502,15 @@ static int myisamchk(MI_CHECK *param, my_string filename)
     param->error_printed=1;
     switch (my_errno) {
     case HA_ERR_CRASHED:
+    case HA_ERR_WRONG_TABLE_DEF:
       mi_check_print_error(param,"'%s' is not a MyISAM-table",filename);
       break;
+    case HA_ERR_CRASHED_ON_USAGE:
+      mi_check_print_error(param,"'%s' is marked as crashed",filename);
+      break;
+    case HA_ERR_CRASHED_ON_REPAIR:
+      mi_check_print_error(param,"'%s' is marked as crashed after last repair",filename);
+      break;
     case HA_ERR_OLD_FILE:
       mi_check_print_error(param,"'%s' is a old type of MyISAM-table", filename);
       break;
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index b9a9d5274eee6ab8d2bba061d69e291718589662..5c48ad435a4effc280b0c910e2f709b58bd8110e 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -653,7 +653,7 @@ void thr_unlock(THR_LOCK_DATA *data)
   data->type=TL_UNLOCK;				/* Mark unlocked */
   check_locks(lock,"after releasing lock",1);
 
-  if (!lock->write.data)			/* If no active read locks */
+  if (!lock->write.data)			/* If no active write locks */
   {
     data=lock->write_wait.data;
     if (!lock->read.data)			/* If no more locks in use */
@@ -742,7 +742,7 @@ void thr_unlock(THR_LOCK_DATA *data)
 	  data->next->prev= data->prev;
 	else
 	  lock->write_wait.last=data->prev;
-	(*lock->write.last)=data;			/* Put in execute list */
+	(*lock->write.last)=data;		/* Put in execute list */
 	data->prev=lock->write.last;
 	lock->write.last= &data->next;
 	data->next=0;				/* Only one write lock */
@@ -756,7 +756,7 @@ void thr_unlock(THR_LOCK_DATA *data)
 			    (lock_type == TL_WRITE_CONCURRENT_INSERT ||
 			     lock_type == TL_WRITE_ALLOW_WRITE));
     }
-    else if (lock->read_wait.data)
+    else if (!data && lock->read_wait.data)
       free_all_read_locks(lock,0);
   }
 end:
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 4a5f5e582f345e08718592f98ddc4d7d0ced9153..3560fc42d493cb1089e328abef1263411b7e8c5d 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1162,25 +1162,26 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
 			 HA_TRY_READ_ONLY),
 		READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
 		ha_open_options | HA_OPEN_FOR_REPAIR,
-		entry) ||
+		entry) || ! entry->file || 
 	(entry->file->is_crashed() && entry->file->check_and_repair(thd)))
     {
       /* Give right error message */
       thd->net.last_error[0]=0;
       thd->net.last_errno=0;
-      entry->file->print_error(HA_ERR_CRASHED,MYF(0));
+      my_error(ER_NOT_KEYFILE, MYF(0), name, my_errno);
       sql_print_error("Error: Couldn't repair table: %s.%s",db,name);
-      closefrm(entry);
+      if (entry->file)
+	closefrm(entry);
       error=1;
     }
     else
     {
-      thd->net.last_error[0]=0;				// Clear error message
+      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 original lock
+    unlock_table_name(thd,&table_list);
     if (error)
       goto err;
   }
diff --git a/sql/table.cc b/sql/table.cc
index bdc2c0f124e18f5393bf753727c3500185e1994f..c840b36da0567931ef61226f11911a91bb9e18e5 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -542,7 +542,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
 		       HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
     {
       /* Set a flag if the table is crashed and it can be auto. repaired */
-      outparam->crashed=(err == HA_ERR_CRASHED &&
+      outparam->crashed=(err == HA_ERR_CRASHED_ON_USAGE &&
 			 outparam->file->auto_repair() &&
 			 !(ha_open_flags & HA_OPEN_FOR_REPAIR));
       goto err_not_open; /* purecov: inspected */
@@ -569,6 +569,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
   frm_error(error,outparam,name,ME_ERROR+ME_WAITTANG);
   delete outparam->file;
   outparam->file=0;				// For easyer errorchecking
+  outparam->db_stat=0;
   free_root(&outparam->mem_root,MYF(0));
   my_free(outparam->table_name,MYF(MY_ALLOW_ZERO_PTR));
   DBUG_RETURN (error);
diff --git a/strings/llstr.c b/strings/llstr.c
index a8514d7e36920751bab7e419e2132902573888e0..470645a4f658da7fc4961182f4858f55a25eba72 100644
--- a/strings/llstr.c
+++ b/strings/llstr.c
@@ -31,6 +31,6 @@
 
 char *llstr(longlong value,char *buff)
 {
-  longlong2str(value,buff,10);
+  longlong2str(value,buff,-10);
   return buff;
 }