diff --git a/client/mysqltest.c b/client/mysqltest.c
index e3e3d19984acf9b9997f470f33aeab7f222c338f..b3b8cd55221e7143e0aa388c7d66f0716b6911c8 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -42,7 +42,7 @@
 
 **********************************************************************/
 
-#define MTEST_VERSION "2.0"
+#define MTEST_VERSION "2.1"
 
 #include <my_global.h>
 #include <mysql_embed.h>
@@ -54,13 +54,9 @@
 #include <m_ctype.h>
 #include <my_dir.h>
 #include <hash.h>
-#include <stdio.h>
-#include <stdlib.h>
 #include <my_getopt.h>
 #include <stdarg.h>
 #include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
 #include <violite.h>
 
 #define MAX_QUERY	65536
@@ -90,7 +86,8 @@
 #define MAX_CON_TRIES	5
 
 #define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */
-
+#define DEFAULT_DELIMITER ";"
+#define MAX_DELIMITER 16
 
 enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
       OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC,
@@ -118,6 +115,8 @@ static FILE** cur_file;
 static FILE** file_stack_end;
 static uint lineno_stack[MAX_INCLUDE_DEPTH];
 static char TMPDIR[FN_REFLEN];
+static char delimiter[MAX_DELIMITER]= DEFAULT_DELIMITER;
+static uint delimiter_length= 1;
 
 static int *cur_block, *block_stack_end;
 static int block_stack[BLOCK_STACK_DEPTH];
@@ -213,7 +212,8 @@ Q_WAIT_FOR_SLAVE_TO_STOP,
 Q_REQUIRE_VERSION,
 Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS,
 Q_ENABLE_INFO, Q_DISABLE_INFO,
-Q_EXEC,
+Q_EXEC, Q_DELIMITER,
+
 Q_UNKNOWN,			       /* Unknown command.   */
 Q_COMMENT,			       /* Comments, ignored. */
 Q_COMMENT_WITH_COMMAND
@@ -285,6 +285,7 @@ const char *command_names[]=
   "enable_info",
   "disable_info",
   "exec",
+  "delimiter",
   0
 };
 
@@ -1476,7 +1477,8 @@ int safe_connect(MYSQL* con, const char* host, const char* user,
   int i;
   for (i = 0; i < MAX_CON_TRIES; ++i)
   {
-    if (mysql_real_connect(con, host,user, pass, db, port, sock, 0))
+    if (mysql_real_connect(con, host,user, pass, db, port, sock,
+			   CLIENT_MULTI_STATEMENTS))
     {
       con_error = 0;
       break;
@@ -1626,24 +1628,46 @@ int do_while(struct st_query* q)
 }
 
 
+my_bool end_of_query(int c, char* p)
+{
+  uint i, j;
+  int tmp[MAX_DELIMITER]= {0};
+
+  for (i= 0; c == *(delimiter + i) && i < delimiter_length;
+       i++, c= fgetc(*cur_file))
+    tmp[i]= c;
+  tmp[i]= c;
+
+  for (j= i; j > 0 && i != delimiter_length; j--)
+    ungetc(tmp[j], *cur_file);
+  if (i == delimiter_length)
+  {
+    ungetc(tmp[i], *cur_file);
+    *p= 0;
+    return 1;
+  }
+  return 0;
+}
+
+
 int read_line(char* buf, int size)
 {
   int c;
-  char* p = buf, *buf_end = buf + size-1;
-  int no_save = 0;
+  char* p= buf, *buf_end= buf + size - 1;
+  int no_save= 0;
   enum {R_NORMAL, R_Q1, R_ESC_Q_Q1, R_ESC_Q_Q2,
 	R_ESC_SLASH_Q1, R_ESC_SLASH_Q2,
-	R_Q2, R_COMMENT, R_LINE_START} state = R_LINE_START;
+	R_Q2, R_COMMENT, R_LINE_START} state= R_LINE_START;
 
   start_lineno= *lineno;
   for (; p < buf_end ;)
   {
-    no_save = 0;
-    c = fgetc(*cur_file);
+    no_save= 0;
+    c= fgetc(*cur_file);
     if (feof(*cur_file))
     {
       if ((*cur_file) != stdin)
-	my_fclose(*cur_file,MYF(0));
+	my_fclose(*cur_file, MYF(0));
       cur_file--;
       lineno--;
       if (cur_file == file_stack)
@@ -1654,11 +1678,8 @@ int read_line(char* buf, int size)
     switch(state) {
     case R_NORMAL:
       /*  Only accept '{' in the beginning of a line */
-      if (c == ';')
-      {
-	*p = 0;
+      if (end_of_query(c, p))
 	return 0;
-      }
       else if (c == '\'')
 	state = R_Q1;
       else if (c == '"')
@@ -1672,7 +1693,7 @@ int read_line(char* buf, int size)
     case R_COMMENT:
       if (c == '\n')
       {
-	*p=0;
+	*p= 0;
 	(*lineno)++;
 	return 0;
       }
@@ -1682,78 +1703,72 @@ int read_line(char* buf, int size)
       {
 	state = R_COMMENT;
       }
-      else if (my_isspace(charset_info,c))
+      else if (my_isspace(charset_info, c))
       {
 	if (c == '\n')
 	  start_lineno= ++*lineno;		/* Query hasn't started yet */
-	no_save = 1;
+	no_save= 1;
       }
       else if (c == '}')
       {
-	*buf++ = '}';
-	*buf = 0;
+	*buf++= '}';
+	*buf= 0;
 	return 0;
       }
-      else if (c == ';' || c == '{')
+      else if (end_of_query(c, p) || c == '{')
       {
-	*p = 0;
+	*p= 0;
 	return 0;
       }
       else if (c == '\'')
-	state = R_Q1;
+	state= R_Q1;
       else if (c == '"')
-	state = R_Q2;
+	state= R_Q2;
       else
-	state = R_NORMAL;
+	state= R_NORMAL;
       break;
 
     case R_Q1:
       if (c == '\'')
-	state = R_ESC_Q_Q1;
+	state= R_ESC_Q_Q1;
       else if (c == '\\')
-	state = R_ESC_SLASH_Q1;
+	state= R_ESC_SLASH_Q1;
       break;
     case R_ESC_Q_Q1:
-      if (c == ';')
-      {
-	*p = 0;
+      if (end_of_query(c, p))
 	return 0;
-      }
       if (c != '\'')
-	state = R_NORMAL;
+	state= R_NORMAL;
       else
-	state = R_Q1;
+	state= R_Q1;
       break;
     case R_ESC_SLASH_Q1:
-      state = R_Q1;
+      state= R_Q1;
       break;
 
     case R_Q2:
       if (c == '"')
-	state = R_ESC_Q_Q2;
+	state= R_ESC_Q_Q2;
       else if (c == '\\')
-	state = R_ESC_SLASH_Q2;
+	state= R_ESC_SLASH_Q2;
       break;
     case R_ESC_Q_Q2:
-      if (c == ';')
-      {
-	*p = 0;
+      if (end_of_query(c, p))
 	return 0;
-      }
       if (c != '"')
-	state = R_NORMAL;
+	state= R_NORMAL;
       else
-	state = R_Q2;
+	state= R_Q2;
       break;
     case R_ESC_SLASH_Q2:
-      state = R_Q2;
+      state= R_Q2;
       break;
     }
 
     if (!no_save)
-      *p++ = c;
+      *p++= c;
   }
-  *p=0;						/* Always end with \0 */
+  *p= 0;					/* Always end with \0 */
   return feof(*cur_file);
 }
 
@@ -1770,22 +1785,22 @@ int read_query(struct st_query** q_ptr)
     get_dynamic(&q_lines, (gptr) q_ptr, parser.current_line) ;
     return 0;
   }
-  if (!(*q_ptr=q=(struct st_query*) my_malloc(sizeof(*q), MYF(MY_WME))) ||
+  if (!(*q_ptr= q= (struct st_query*) my_malloc(sizeof(*q), MYF(MY_WME))) ||
       insert_dynamic(&q_lines, (gptr) &q))
     die(NullS);
 
-  q->record_file[0] = 0;
-  q->require_file=0;
-  q->first_word_len = 0;
+  q->record_file[0]= 0;
+  q->require_file= 0;
+  q->first_word_len= 0;
   memcpy((gptr) q->expected_errno, (gptr) global_expected_errno,
 	 sizeof(global_expected_errno));
-  q->expected_errors=global_expected_errors;
-  q->abort_on_error = global_expected_errno[0] == 0;
-  bzero((gptr) global_expected_errno,sizeof(global_expected_errno));
+  q->expected_errors= global_expected_errors;
+  q->abort_on_error= global_expected_errno[0] == 0;
+  bzero((gptr) global_expected_errno, sizeof(global_expected_errno));
   global_expected_errors=0;
 
   q->type = Q_UNKNOWN;
-  q->query_buf=q->query=0;
+  q->query_buf= q->query= 0;
   if (read_line(read_query_buf, sizeof(read_query_buf)))
     return 1;
 
@@ -1795,20 +1810,20 @@ int read_query(struct st_query** q_ptr)
   }
   else if (p[0] == '-' && p[1] == '-')
   {
-    q->type = Q_COMMENT_WITH_COMMAND;
-    p+=2;					/* To calculate first word */
+    q->type= Q_COMMENT_WITH_COMMAND;
+    p+= 2;					/* To calculate first word */
   }
   else
   {
     if (*p == '!')
     {
-      q->abort_on_error = 0;
+      q->abort_on_error= 0;
       p++;
       if (*p == '$')
       {
-	expected_errno = 0;
+	expected_errno= 0;
 	p++;
-	for (;my_isdigit(charset_info,*p);p++)
+	for (; my_isdigit(charset_info, *p); p++)
 	  expected_errno = expected_errno * 10 + *p - '0';
 	q->expected_errno[0] = expected_errno;
 	q->expected_errno[1] = 0;
@@ -1816,30 +1831,30 @@ int read_query(struct st_query** q_ptr)
       }
     }
 
-    while (*p && my_isspace(charset_info,*p))
+    while (*p && my_isspace(charset_info, *p))
       p++ ;
     if (*p == '@')
     {
       p++;
       p1 = q->record_file;
-      while (!my_isspace(charset_info,*p) &&
+      while (!my_isspace(charset_info, *p) &&
 	     p1 < q->record_file + sizeof(q->record_file) - 1)
 	*p1++ = *p++;
       *p1 = 0;
     }
   }
-  while (*p && my_isspace(charset_info,*p))
+  while (*p && my_isspace(charset_info, *p))
     p++;
-  if (!(q->query_buf=q->query=my_strdup(p,MYF(MY_WME))))
+  if (!(q->query_buf= q->query= my_strdup(p, MYF(MY_WME))))
     die(NullS);
 
   /* Calculate first word and first argument */
-  for (p=q->query; *p && !my_isspace(charset_info,*p) ; p++) ;
-  q->first_word_len = (uint) (p - q->query);
-  while (*p && my_isspace(charset_info,*p))
+  for (p= q->query; *p && !my_isspace(charset_info, *p) ; p++) ;
+  q->first_word_len= (uint) (p - q->query);
+  while (*p && my_isspace(charset_info, *p))
     p++;
-  q->first_argument=p;
-  q->end = strend(q->query);
+  q->first_argument= p;
+  q->end= strend(q->query);
   parser.read_lines++;
   return 0;
 }
@@ -2133,12 +2148,12 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
 
 int run_query(MYSQL* mysql, struct st_query* q, int flags)
 {
-  MYSQL_RES* res = 0;
-  int i, error = 0;
+  MYSQL_RES* res= 0;
+  int i, error= 0, err= 0, counter= 0;
   DYNAMIC_STRING *ds;
   DYNAMIC_STRING ds_tmp;
   DYNAMIC_STRING eval_query;
-  char* query;
+  char* query, buff[MAX_DELIMITER + 1]= {0};
   int query_len;
   DBUG_ENTER("run_query");
   
@@ -2166,150 +2181,159 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
 
   if ((flags & QUERY_SEND) && mysql_send_query(mysql, query, query_len))
     die("At line %u: unable to send query '%s'(mysql_errno=%d,errno=%d)",
-	start_lineno, query,
-	mysql_errno(mysql), errno);
-  if ((flags & QUERY_SEND) && !disable_query_log)
-  {
-    replace_dynstr_append_mem(ds,query, query_len);
-    dynstr_append_mem(ds,";\n",2);
-  }
-  if (!(flags & QUERY_REAP))
-    DBUG_RETURN(0);
+	start_lineno, query, mysql_errno(mysql), errno);
 
-  if ((*mysql->methods->read_query_result)(mysql) ||
-      (!(last_result = res = mysql_store_result(mysql)) &&
-       mysql_field_count(mysql)))
+  do
   {
-    if (q->require_file)
+    if ((flags & QUERY_SEND) && !disable_query_log && !counter)
     {
-      abort_not_supported_test();
+      replace_dynstr_append_mem(ds,query, query_len);
+      sprintf(buff, "%s\n", delimiter);
+      dynstr_append_mem(ds, buff, delimiter_length + 1);
     }
-    if (q->abort_on_error)
-      die("At line %u: query '%s' failed: %d: %s", start_lineno, query,
-	  mysql_errno(mysql), mysql_error(mysql));
-    else
+    if (!(flags & QUERY_REAP))
+      DBUG_RETURN(0);
+
+    if ((!counter && (*mysql->methods->read_query_result)(mysql)) ||
+	(!(last_result= res= mysql_store_result(mysql)) &&
+	 mysql_field_count(mysql)))
     {
-      for (i=0 ; (uint) i < q->expected_errors ; i++)
+      if (q->require_file)
+      {
+	abort_not_supported_test();
+      }
+      if (q->abort_on_error)
+	die("At line %u: query '%s' failed: %d: %s", start_lineno, query,
+	    mysql_errno(mysql), mysql_error(mysql));
+      else
       {
-	if ((q->expected_errno[i] == mysql_errno(mysql)))
+	for (i=0 ; (uint) i < q->expected_errors ; i++)
 	{
-	  if (i == 0 && q->expected_errors == 1)
+	  if ((q->expected_errno[i] == mysql_errno(mysql)))
 	  {
-	    /* Only log error if there is one possible error */
-	    dynstr_append_mem(ds,"ERROR ",6);
-	    replace_dynstr_append_mem(ds, mysql_sqlstate(mysql),
-				      strlen(mysql_sqlstate(mysql)));
-	    dynstr_append_mem(ds,": ",2);
-	    replace_dynstr_append_mem(ds,mysql_error(mysql),
-				      strlen(mysql_error(mysql)));
-	    dynstr_append_mem(ds,"\n",1);
+	    if (i == 0 && q->expected_errors == 1)
+	    {
+	      /* Only log error if there is one possible error */
+	      dynstr_append_mem(ds,"ERROR ",6);
+	      replace_dynstr_append_mem(ds, mysql_sqlstate(mysql),
+					strlen(mysql_sqlstate(mysql)));
+	      dynstr_append_mem(ds, ": ", 2);
+	      replace_dynstr_append_mem(ds,mysql_error(mysql),
+					strlen(mysql_error(mysql)));
+	      dynstr_append_mem(ds,"\n",1);
+	    }
+	    /* Don't log error if we may not get an error */
+	    else if (q->expected_errno[0] != 0)
+	      dynstr_append(ds,"Got one of the listed errors\n");
+	    goto end;				/* Ok */
 	  }
-	  /* Don't log error if we may not get an error */
-	  else if (q->expected_errno[0] != 0)
-	    dynstr_append(ds,"Got one of the listed errors\n");
-	  goto end;				/* Ok */
 	}
-      }
-      DBUG_PRINT("info",("i: %d  expected_errors: %d", i, q->expected_errors));
-      dynstr_append_mem(ds,"ERROR ",6);
-      replace_dynstr_append_mem(ds, mysql_sqlstate(mysql),
-				strlen(mysql_sqlstate(mysql)));
-      dynstr_append_mem(ds,": ",2);
-      replace_dynstr_append_mem(ds, mysql_error(mysql),
-				strlen(mysql_error(mysql)));
-      dynstr_append_mem(ds,"\n",1);
-      if (i)
-      {
-	verbose_msg("query '%s' failed with wrong errno %d instead of %d...",
-		    q->query, mysql_errno(mysql), q->expected_errno[0]);
-	error= 1;
+	DBUG_PRINT("info",("i: %d  expected_errors: %d", i, q->expected_errors));
+	dynstr_append_mem(ds, "ERROR ",6);
+	replace_dynstr_append_mem(ds, mysql_sqlstate(mysql),
+				  strlen(mysql_sqlstate(mysql)));
+	dynstr_append_mem(ds,": ",2);
+	replace_dynstr_append_mem(ds, mysql_error(mysql),
+				  strlen(mysql_error(mysql)));
+	dynstr_append_mem(ds,"\n",1);
+	if (i)
+	{
+	  verbose_msg("query '%s' failed with wrong errno %d instead of %d...",
+		      q->query, mysql_errno(mysql), q->expected_errno[0]);
+	  error= 1;
+	  goto end;
+	}
+	verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql),
+		    mysql_error(mysql));
+	/*
+	  if we do not abort on error, failure to run the query does
+	  not fail the whole test case
+	*/
 	goto end;
       }
-      verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql),
-		  mysql_error(mysql));
-      /*
-	if we do not abort on error, failure to run the query does
-	not fail the whole test case
-      */
-      goto end;
+      /*{
+	verbose_msg("failed in mysql_store_result for query '%s' (%d)", query,
+	mysql_errno(mysql));
+	error = 1;
+	goto end;
+	}*/
     }
-    /*{
-      verbose_msg("failed in mysql_store_result for query '%s' (%d)", query,
-      mysql_errno(mysql));
+
+    if (q->expected_errno[0])
+    {
       error = 1;
+      verbose_msg("query '%s' succeeded - should have failed with errno %d...",
+		  q->query, q->expected_errno[0]);
       goto end;
-      }*/
-  }
-
-  if (q->expected_errno[0])
-  {
-    error = 1;
-    verbose_msg("query '%s' succeeded - should have failed with errno %d...",
-		q->query, q->expected_errno[0]);
-    goto end;
-  }
+    }
 
-  if (!disable_result_log)
-  {
-    if (res)
+    if (!disable_result_log)
     {
-      int num_fields= mysql_num_fields(res);
-      MYSQL_FIELD *fields= mysql_fetch_fields(res);
-      for (i = 0; i < num_fields; i++)
+      if (res)
       {
-	if (i)
-	  dynstr_append_mem(ds, "\t", 1);
-	dynstr_append(ds, fields[i].name);
+	int num_fields= mysql_num_fields(res);
+	MYSQL_FIELD *fields= mysql_fetch_fields(res);
+
+	for (i = 0; i < num_fields; i++)
+	{
+	  if (i)
+	    dynstr_append_mem(ds, "\t", 1);
+	  dynstr_append(ds, fields[i].name);
+	}
+	dynstr_append_mem(ds, "\n", 1);
+	append_result(ds, res);
       }
-      dynstr_append_mem(ds, "\n", 1);
-      append_result(ds, res);
-    }
 
-    /* Add all warnings to the result */
-    if (!disable_warnings && mysql_warning_count(mysql))
-    {
-      MYSQL_RES *warn_res=0;
-      uint count= mysql_warning_count(mysql);
-      if (!mysql_real_query(mysql, "SHOW WARNINGS", 13))
+      /* Add all warnings to the result */
+      if (!disable_warnings && mysql_warning_count(mysql))
       {
-	warn_res=mysql_store_result(mysql);
+	MYSQL_RES *warn_res=0;
+	uint count= mysql_warning_count(mysql);
+	if (!mysql_real_query(mysql, "SHOW WARNINGS", 13))
+	{
+	  warn_res= mysql_store_result(mysql);
+	}
+	if (!warn_res)
+	  verbose_msg("Warning count is %u but didn't get any warnings\n",
+		      count);
+	else
+	{
+	  dynstr_append_mem(ds, "Warnings:\n", 10);
+	  append_result(ds, warn_res);
+	  mysql_free_result(warn_res);
+	}
       }
-      if (!warn_res)
-	verbose_msg("Warning count is %u but didn't get any warnings\n",
-		    count);
-      else
+      if (!disable_info && mysql_info(mysql))
       {
-	dynstr_append_mem(ds, "Warnings:\n", 10);
-	append_result(ds, warn_res);
-	mysql_free_result(warn_res);
+	dynstr_append(ds, "info: ");
+	dynstr_append(ds, mysql_info(mysql));
+	dynstr_append_mem(ds, "\n", 1);
       }
     }
-    if (!disable_info && mysql_info(mysql))
-    {
-      dynstr_append(ds, "info: ");
-      dynstr_append(ds, mysql_info(mysql));
-      dynstr_append_mem(ds, "\n", 1);
-    }
-  }
 
-  if (glob_replace)
-    free_replace();
+    if (glob_replace)
+      free_replace();
 
-  if (record)
-  {
-    if (!q->record_file[0] && !result_file)
-      die("At line %u: Missing result file", start_lineno);
-    if (!result_file)
-      str_to_file(q->record_file, ds->str, ds->length);
-  }
-  else if (q->record_file[0])
-  {
-    error = check_result(ds, q->record_file, q->require_file);
-  }
+    if (record)
+    {
+      if (!q->record_file[0] && !result_file)
+	die("At line %u: Missing result file", start_lineno);
+      if (!result_file)
+	str_to_file(q->record_file, ds->str, ds->length);
+    }
+    else if (q->record_file[0])
+    {
+      error = check_result(ds, q->record_file, q->require_file);
+    }
+    if (res)
+      mysql_free_result(res);
+    last_result= 0;
+    counter++;
+  } while (!(err= mysql_next_result(mysql)));
+  if (err >= 1)
+    mysql_error(mysql);
 
 end:
-  if (res)
-    mysql_free_result(res);
   last_result=0;
   if (ds == &ds_tmp)
     dynstr_free(&ds_tmp);
@@ -2524,6 +2548,10 @@ int main(int argc, char **argv)
       case Q_DEC: do_dec(q); break;
       case Q_ECHO: do_echo(q); break;
       case Q_SYSTEM: do_system(q); break;
+      case Q_DELIMITER:
+	strmake(delimiter, q->first_argument, sizeof(delimiter) - 1);
+	delimiter_length= strlen(delimiter);
+	break;
       case Q_LET: do_let(q); break;
       case Q_EVAL_RESULT: eval_result = 1; break;
       case Q_EVAL:
@@ -2653,6 +2681,7 @@ int main(int argc, char **argv)
   }
 }
 
+
 /*
   Read arguments for embedded server and put them into
   embedded_server_args_count and embedded_server_args[]
diff --git a/heap/hp_hash.c b/heap/hp_hash.c
index 2843407f3fe9e52106c469f1dd624400b4a74e03..d30cbc9b82f32446f53a6bd5d43e462eb8e0c3b6 100644
--- a/heap/hp_hash.c
+++ b/heap/hp_hash.c
@@ -18,6 +18,7 @@
 
 #include "heapdef.h"
 #include <m_ctype.h>
+#include <assert.h>
 
 ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key,
 			       uint start_key_len,
@@ -566,50 +567,87 @@ my_bool hp_if_null_in_key(HP_KEYDEF *keydef, const byte *record)
   return 0;
 }
 
+
+/*
+  Update auto_increment info
+
+  SYNOPSIS
+    update_auto_increment()
+    info			MyISAM handler
+    record			Row to update
+
+  IMPLEMENTATION
+    Only replace the auto_increment value if it is higher than the previous
+    one. For signed columns we don't update the auto increment value if it's
+    less than zero.
+*/
+
 void heap_update_auto_increment(HP_INFO *info, const byte *record)
 {
-  ulonglong value;
+  ulonglong value= 0;			/* Store unsigned values here */
+  longlong s_value= 0;			/* Store signed values here */
+
   HA_KEYSEG *keyseg= info->s->keydef[info->s->auto_key - 1].seg;
   const uchar *key=  (uchar*) record + keyseg->start;
 
   switch (info->s->auto_key_type) {
   case HA_KEYTYPE_INT8:
+    s_value= (longlong) *(char*)key;
+    break;
   case HA_KEYTYPE_BINARY:
-    value= (ulonglong) *(uchar*) key;
+    value=(ulonglong)  *(uchar*) key;
     break;
   case HA_KEYTYPE_SHORT_INT:
+    s_value= (longlong) sint2korr(key);
+    break;
   case HA_KEYTYPE_USHORT_INT:
-    value= (ulonglong) uint2korr(key);
+    value=(ulonglong) uint2korr(key);
     break;
   case HA_KEYTYPE_LONG_INT:
+    s_value= (longlong) sint4korr(key);
+    break;
   case HA_KEYTYPE_ULONG_INT:
-    value= (ulonglong) uint4korr(key);
+    value=(ulonglong) uint4korr(key);
     break;
   case HA_KEYTYPE_INT24:
+    s_value= (longlong) sint3korr(key);
+    break;
   case HA_KEYTYPE_UINT24:
-    value= (ulonglong) uint3korr(key);
+    value=(ulonglong) uint3korr(key);
     break;
-  case HA_KEYTYPE_FLOAT:			/* This shouldn't be used */
+  case HA_KEYTYPE_FLOAT:                        /* This shouldn't be used */
   {
     float f_1;
-    float4get(f_1, key);
-    value= (ulonglong) f_1;
+    float4get(f_1,key);
+    /* Ignore negative values */
+    value = (f_1 < (float) 0.0) ? 0 : (ulonglong) f_1;
     break;
   }
-  case HA_KEYTYPE_DOUBLE:			/* This shouldn't be used */
+  case HA_KEYTYPE_DOUBLE:                       /* This shouldn't be used */
   {
     double f_1;
-    float8get(f_1, key);
-    value= (ulonglong) f_1;
+    float8get(f_1,key);
+    /* Ignore negative values */
+    value = (f_1 < 0.0) ? 0 : (ulonglong) f_1;
     break;
   }
   case HA_KEYTYPE_LONGLONG:
+    s_value= sint8korr(key);
+    break;
   case HA_KEYTYPE_ULONGLONG:
     value= uint8korr(key);
     break;
   default:
-    value= 0;					/* Error */
+    DBUG_ASSERT(0);
+    value=0;                                    /* Error */
     break;
   }
-  set_if_bigger(info->s->auto_increment, value);
+
+  /*
+    The following code works becasue if s_value < 0 then value is 0
+    and if s_value == 0 then value will contain either s_value or the
+    correct value.
+  */
+  set_if_bigger(info->s->auto_increment,
+                (s_value > 0) ? (ulonglong) s_value : value);
 }
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 4056938845639633696b0fc12a59446c7a9ebca9..78433c100146b2aef9eb37d12a9ab14203f82016 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -407,6 +407,28 @@ a	b	c	d	e	f	g	h	dd
 1	-7	7	2000-01-01	b	2000-01-01 00:00:00	05:04:03	yet another binary data	02:00:00
 2	-2	2	1825-12-14	a	2003-01-01 03:02:01	04:03:02	binary data	02:00:00
 drop table t1, t2;
+create table t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float(3,2), g double(4,3), h decimal(5,4), i year, j date, k timestamp, l datetime, m enum('a','b'), n set('a','b'), o char(10));
+create table t2 select ifnull(a,a), ifnull(b,b), ifnull(c,c), ifnull(d,d), ifnull(e,e), ifnull(f,f), ifnull(g,g), ifnull(h,h), ifnull(i,i), ifnull(j,j), ifnull(k,k), ifnull(l,l), ifnull(m,m), ifnull(n,n), ifnull(o,o) from t1;
+show create table t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `ifnull(a,a)` tinyint(4) default NULL,
+  `ifnull(b,b)` smallint(6) default NULL,
+  `ifnull(c,c)` mediumint(9) default NULL,
+  `ifnull(d,d)` int(11) default NULL,
+  `ifnull(e,e)` bigint(20) default NULL,
+  `ifnull(f,f)` float(3,2) default NULL,
+  `ifnull(g,g)` double(4,3) default NULL,
+  `ifnull(h,h)` decimal(5,4) default NULL,
+  `ifnull(i,i)` year(4) default NULL,
+  `ifnull(j,j)` date default NULL,
+  `ifnull(k,k)` datetime NOT NULL default '0000-00-00 00:00:00',
+  `ifnull(l,l)` datetime default NULL,
+  `ifnull(m,m)` char(1) default NULL,
+  `ifnull(n,n)` char(3) default NULL,
+  `ifnull(o,o)` char(10) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1,t2;
 create table t1(str varchar(10) default 'def',strnull varchar(10),intg int default '10',rel double default '3.14');
 insert into t1 values ('','',0,0.0);
 describe t1;
diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result
index d51bc24112a4d59af04f5f274af2689e9810665f..b101c18f505dcc4b9f79b1e19ce2941f08b42672 100644
--- a/mysql-test/r/func_set.result
+++ b/mysql-test/r/func_set.result
@@ -6,6 +6,12 @@ id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
 Warnings:
 Note	1003	select high_priority interval((55,10,20,30,40,50,60,70,80,90,100)) AS `INTERVAL(55,10,20,30,40,50,60,70,80,90,100)`,interval((3,1,(1 + 1),(((1 + 1) + 1) + 1))) AS `interval(3,1,1+1,1+1+1+1)`,field(_latin1'IBM',_latin1'NCA',_latin1'ICL',_latin1'SUN',_latin1'IBM',_latin1'DIGITAL') AS `field("IBM","NCA","ICL","SUN","IBM","DIGITAL")`,field(_latin1'A',_latin1'B',_latin1'C') AS `field("A","B","C")`,elt(2,_latin1'ONE',_latin1'TWO',_latin1'THREE') AS `elt(2,"ONE","TWO","THREE")`,interval((0,1,2,3,4)) AS `interval(0,1,2,3,4)`,(elt(1,1,2,3) | 0) AS `elt(1,1,2,3)|0`,(elt(1,1.1,1.2,1.3) + 0) AS `elt(1,1.1,1.2,1.3)+0`
+SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56);
+INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56)
+1
+SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77);
+INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77)
+1
 select find_in_set("b","a,b,c"),find_in_set("c","a,b,c"),find_in_set("dd","a,bbb,dd"),find_in_set("bbb","a,bbb,dd");
 find_in_set("b","a,b,c")	find_in_set("c","a,b,c")	find_in_set("dd","a,bbb,dd")	find_in_set("bbb","a,bbb,dd")
 2	3	3	2
@@ -50,9 +56,3 @@ id	elt(two.val,'one','two')
 2	one
 4	two
 drop table t1,t2;
-SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56);
-INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56)
-1
-SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77);
-INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77)
-1
diff --git a/mysql-test/r/multi_statement.result b/mysql-test/r/multi_statement.result
new file mode 100644
index 0000000000000000000000000000000000000000..4451b0a355e2c6e79076c3496ad9a008cdcf9b50
--- /dev/null
+++ b/mysql-test/r/multi_statement.result
@@ -0,0 +1,33 @@
+select 1;
+1
+1
+select 2;
+select 3;
+select 4||||
+2
+2
+3
+3
+4
+4
+select 5;
+select 6;
+select 50, 'abc';'abcd'
+5
+5
+6
+6
+50	abc
+50	abc
+select "abcd'";'abcd'
+abcd'
+abcd'
+select "'abcd";'abcd'
+'abcd
+'abcd
+select 5'abcd'
+5
+5
+select 'finish';
+finish
+finish
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index ff1bee2923da8bfa64564e1cfbe19339fc22863b..b49f80127765fb4ec4f256d49575ea28cc88114d 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -64,7 +64,7 @@ INSERT INTO t1 VALUES ("1\""), ("\"2");
 DROP TABLE t1;
 CREATE TABLE t1 (a  VARCHAR(255)) DEFAULT CHARSET koi8r;
 INSERT INTO t1  VALUES (_koi8r x'C1C2C3C4C5');
--- MySQL dump 10.2
+-- MySQL dump 10.3
 --
 -- Host: localhost    Database: test
 -- ------------------------------------------------------
diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result
index 1903037480aea587d4e892a4955fdc9b055eba7b..2ab6695e5c6fddbd51a8e30a0632ce9865fa4c2e 100644
--- a/mysql-test/r/type_enum.result
+++ b/mysql-test/r/type_enum.result
@@ -1636,6 +1636,7 @@ t1	CREATE TABLE `t1` (
   `a` enum('','a','b') NOT NULL default 'b'
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 drop table t1;
+set names latin1;
 create table t1 (a enum(0xE4, '1', '2') not null default 0xE4);
 show columns from t1;
 Field	Type	Null	Key	Default	Extra
@@ -1643,6 +1644,6 @@ a	enum('
 show create table t1;
 Table	Create Table
 t1	CREATE TABLE `t1` (
-  `a` enum('ä','1','2') NOT NULL default '?'
+  `a` enum('ä','1','2') NOT NULL default 'ä'
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 drop table t1;
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index e50d5f41af3b75177d1406ad1dcbc74289a93394..35b6070d10d0e9c1a344f7cd9ed335516174950d 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -318,11 +318,17 @@ select
     addtime(cast('1:0:0' as time),cast('1:0:0' as time))  as dd
 from t1;
 explain t2;
-			
 select * from t2;
-
 drop table t1, t2;
 
+create table t1 (a tinyint, b smallint, c mediumint, d int, e bigint, f float(3,2), g double(4,3), h decimal(5,4), i year, j date, k timestamp, l datetime, m enum('a','b'), n set('a','b'), o char(10));
+create table t2 select ifnull(a,a), ifnull(b,b), ifnull(c,c), ifnull(d,d), ifnull(e,e), ifnull(f,f), ifnull(g,g), ifnull(h,h), ifnull(i,i), ifnull(j,j), ifnull(k,k), ifnull(l,l), ifnull(m,m), ifnull(n,n), ifnull(o,o) from t1;
+show create table t2;
+drop table t1,t2;
+
+#
+# Test of default()
+#
 create table t1(str varchar(10) default 'def',strnull varchar(10),intg int default '10',rel double default '3.14');
 insert into t1 values ('','',0,0.0);
 describe t1;
diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test
index 7a7ad25f9c4119b09b2d6e2adc3c3409beeb2797..03843fd3da55bed7ed0c696a040dae823f34d9cb 100644
--- a/mysql-test/t/func_set.test
+++ b/mysql-test/t/func_set.test
@@ -4,6 +4,10 @@
 
 select interval(55,10,20,30,40,50,60,70,80,90,100),interval(3,1,1+1,1+1+1+1),field("IBM","NCA","ICL","SUN","IBM","DIGITAL"),field("A","B","C"),elt(2,"ONE","TWO","THREE"),interval(0,1,2,3,4),elt(1,1,2,3)|0,elt(1,1.1,1.2,1.3)+0;
 explain extended select INTERVAL(55,10,20,30,40,50,60,70,80,90,100),interval(3,1,1+1,1+1+1+1),field("IBM","NCA","ICL","SUN","IBM","DIGITAL"),field("A","B","C"),elt(2,"ONE","TWO","THREE"),interval(0,1,2,3,4),elt(1,1,2,3)|0,elt(1,1.1,1.2,1.3)+0;
+# Test 8 and 9 values (Bug #1561)
+SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56);
+SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77);
+
 select find_in_set("b","a,b,c"),find_in_set("c","a,b,c"),find_in_set("dd","a,bbb,dd"),find_in_set("bbb","a,bbb,dd");
 select find_in_set("d","a,b,c"),find_in_set("dd","a,bbb,d"),find_in_set("bb","a,bbb,dd");
 select make_set(0,'a','b','c'),make_set(-1,'a','b','c'),make_set(1,'a','b','c'),make_set(2,'a','b','c'),make_set(1+2,concat('a','b'),'c');
@@ -35,8 +39,3 @@ insert into t2 values (1,1),(2,1),(3,1),(4,2);
 select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id;
 select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id;
 drop table t1,t2;
-
-# some more INTERVAL tests 
-
-SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56);
-SELECT INTERVAL(13, 7, 14, 21, 28, 35, 42, 49, 56, 77);
diff --git a/mysql-test/t/multi_statement.test b/mysql-test/t/multi_statement.test
new file mode 100644
index 0000000000000000000000000000000000000000..bd90275c9f5fbc34e5454d5c7e4cd656dc0aecef
--- /dev/null
+++ b/mysql-test/t/multi_statement.test
@@ -0,0 +1,13 @@
+select 1;
+delimiter ||||;
+select 2;
+select 3;
+select 4||||
+delimiter 'abcd'||||
+select 5;
+select 6;
+select 50, 'abc';'abcd'
+select "abcd'";'abcd'select "'abcd";'abcd'
+select 5'abcd'
+delimiter ;'abcd'
+select 'finish';
diff --git a/mysql-test/t/rpl_log_pos.test b/mysql-test/t/rpl_log_pos.test
index b32f68844a25d97856297703b97aae6152212c85..2e54c98c0146769a6e97ce3930d0752de227ec62 100644
--- a/mysql-test/t/rpl_log_pos.test
+++ b/mysql-test/t/rpl_log_pos.test
@@ -24,7 +24,6 @@ sleep 5;
 show slave status;
 stop slave;
 change master to master_log_pos=173;
---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
 start slave;
 sleep 2;
 --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test
index bcebb1a5b27bfd83ef2a8f6d67833895b0974ed7..c53277334a6c5cd96bd661d90b774f4666970060 100644
--- a/mysql-test/t/type_enum.test
+++ b/mysql-test/t/type_enum.test
@@ -29,8 +29,8 @@ drop table t1;
 # Bug #2077
 #
 
+set names latin1;
 create table t1 (a enum(0xE4, '1', '2') not null default 0xE4);
 show columns from t1;
-# should be fixed ASAP
 show create table t1;
 drop table t1;
diff --git a/sql/field.cc b/sql/field.cc
index 23f6e1232b6402edc7675a6a1d14f8d42801bc12..237427a9d80b8eb604377201a48fd8549608e2af 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5192,16 +5192,21 @@ void Field_enum::sort_string(char *to,uint length __attribute__((unused)))
 
 void Field_enum::sql_type(String &res) const
 {
+  char buffer[255];
+  String enum_item(buffer, sizeof(buffer), res.charset());
+
   res.length(0);
   res.append("enum(");
 
   bool flag=0;
-  for (const char **pos=typelib->type_names; *pos ; pos++)
+  for (const char **pos= typelib->type_names; *pos; pos++)
   {
     if (flag)
       res.append(',');
-    append_unescaped(&res, *pos, strlen(*pos));
-    flag=1;
+    /* convert to res.charset() == utf8, then quote */
+    enum_item.copy(*pos, strlen(*pos), charset(), res.charset());
+    append_unescaped(&res, enum_item.ptr(), enum_item.length());
+    flag= 1;
   }
   res.append(')');
 }
@@ -5300,16 +5305,21 @@ String *Field_set::val_str(String *val_buffer,
 
 void Field_set::sql_type(String &res) const
 {
+  char buffer[255];
+  String set_item(buffer, sizeof(buffer), res.charset());
+
   res.length(0);
   res.append("set(");
 
   bool flag=0;
-  for (const char **pos=typelib->type_names; *pos ; pos++)
+  for (const char **pos= typelib->type_names; *pos; pos++)
   {
     if (flag)
       res.append(',');
-    append_unescaped(&res, *pos, strlen(*pos));
-    flag=1;
+    /* convert to res.charset() == utf8, then quote */
+    set_item.copy(*pos, strlen(*pos), charset(), res.charset());
+    append_unescaped(&res, set_item.ptr(), set_item.length());
+    flag= 1;
   }
   res.append(')');
 }
diff --git a/sql/field.h b/sql/field.h
index 0b6ba7dde092e5f1e14a1099618c44304e91d2f8..508fbad41a1f225d9bf55594d094aeb81a5e91da 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -327,11 +327,6 @@ public:
 	       unireg_check_arg, field_name_arg, table_arg,
 	       dec_arg, zero_arg,unsigned_arg)
     {}
-  Field_decimal(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
-		struct st_table *table_arg,bool unsigned_arg)
-    :Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
-	       NONE, field_name_arg, table_arg,0,0,unsigned_arg)
-    {}
   enum_field_types type() const { return FIELD_TYPE_DECIMAL;}
   enum ha_base_keytype key_type() const
   { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
@@ -362,11 +357,6 @@ public:
 	       unireg_check_arg, field_name_arg, table_arg,
 	       0, zero_arg,unsigned_arg)
     {}
-  Field_tiny(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
-	     struct st_table *table_arg,bool unsigned_arg)
-    :Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0,
-	       NONE, field_name_arg, table_arg,0,0,unsigned_arg)
-    {}
   enum Item_result result_type () const { return INT_RESULT; }
   enum_field_types type() const { return FIELD_TYPE_TINY;}
   enum ha_base_keytype key_type() const
@@ -608,13 +598,9 @@ public:
     :Field_str(ptr_arg, len_arg, null, 1,
 	       unireg_check_arg, field_name_arg, table_arg, cs)
     {}
-  Field_null(uint32 len_arg, const char *field_name_arg,
-	     struct st_table *table_arg, CHARSET_INFO *cs)
-    :Field_str((char*) 0, len_arg, null, 1,
-	       NONE, field_name_arg, table_arg, cs)
-    {}
   enum_field_types type() const { return FIELD_TYPE_NULL;}
-  int  store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; }
+  int  store(const char *to, uint length, CHARSET_INFO *cs)
+  { null[0]=1; return 0; }
   int  store(double nr)   { null[0]=1; return 0; }
   int  store(longlong nr) { null[0]=1; return 0; }
   void reset(void)	  {}
@@ -684,10 +670,6 @@ public:
     :Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
 		unireg_check_arg, field_name_arg, table_arg, 1, 1)
     {}
-  Field_year(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
-	     struct st_table *table_arg)
-    :Field_tiny(len_arg,maybe_null_arg,field_name_arg,table_arg,1)
-    {}
   enum_field_types type() const { return FIELD_TYPE_YEAR;}
   int  store(const char *to,uint length,CHARSET_INFO *charset);
   int  store(double nr);
diff --git a/sql/item.cc b/sql/item.cc
index 9af2c300202a3b1cee5c1b43f838c28410e9935e..072a7e5878fa48d82a1becfc859a9b35e7e211ac 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -995,35 +995,42 @@ enum_field_types Item::field_type() const
 
 Field *Item::tmp_table_field_from_field_type(TABLE *table)
 {
-  switch (field_type()) 
-  {
+  /*
+    The field functions defines a field to be not null if null_ptr is not 0
+  */
+  uchar *null_ptr= maybe_null ? (uchar*) "" : 0;
+
+  switch (field_type()) {
   case MYSQL_TYPE_DECIMAL:
-    return new Field_decimal(max_length, maybe_null, name, table,
-			     unsigned_flag);
+    return new Field_decimal((char*) 0, max_length, null_ptr, 0, Field::NONE,
+			     name, table, decimals, 0, unsigned_flag);
   case MYSQL_TYPE_TINY:
-    return new Field_tiny(max_length, maybe_null, name, table,
-			  unsigned_flag);
+    return new Field_tiny((char*) 0, max_length, null_ptr, 0, Field::NONE,
+			  name, table, 0, unsigned_flag);
   case MYSQL_TYPE_SHORT:
-    return new Field_short(max_length, maybe_null, name, table,
-			   unsigned_flag);
+    return new Field_short((char*) 0, max_length, null_ptr, 0, Field::NONE,
+			   name, table, 0, unsigned_flag);
   case MYSQL_TYPE_LONG:
-    return new Field_long(max_length, maybe_null, name, table,
-			  unsigned_flag);
-  case MYSQL_TYPE_FLOAT:
-    return new Field_float(max_length, maybe_null, name, table, decimals);
-  case MYSQL_TYPE_DOUBLE:
-    return new Field_double(max_length, maybe_null, name, table, decimals);
-  case MYSQL_TYPE_NULL:
-    return new Field_null(max_length, name, table, &my_charset_bin);
+    return new Field_long((char*) 0, max_length, null_ptr, 0, Field::NONE,
+			  name, table, 0, unsigned_flag);
 #ifdef HAVE_LONG_LONG
   case MYSQL_TYPE_LONGLONG:
-    return new Field_longlong(max_length, maybe_null, name, table,
-			      unsigned_flag);
+    return new Field_longlong((char*) 0, max_length, null_ptr, 0, Field::NONE,
+			      name, table, 0, unsigned_flag);
 #endif
+  case MYSQL_TYPE_FLOAT:
+    return new Field_float((char*) 0, max_length, null_ptr, 0, Field::NONE,
+			   name, table, decimals, 0, unsigned_flag);
+  case MYSQL_TYPE_DOUBLE:
+    return new Field_double((char*) 0, max_length, null_ptr, 0, Field::NONE,
+			    name, table, decimals, 0, unsigned_flag);
+  case MYSQL_TYPE_NULL:
+    return new Field_null((char*) 0, max_length, Field::NONE,
+			  name, table, &my_charset_bin);
   case MYSQL_TYPE_NEWDATE:
   case MYSQL_TYPE_INT24:
-    return new Field_long(max_length, maybe_null, name, table,
-			  unsigned_flag);
+    return new Field_medium((char*) 0, max_length, null_ptr, 0, Field::NONE,
+			    name, table, 0, unsigned_flag);
   case MYSQL_TYPE_DATE:
     return new Field_date(maybe_null, name, table, &my_charset_bin);
   case MYSQL_TYPE_TIME:
@@ -1032,34 +1039,38 @@ Field *Item::tmp_table_field_from_field_type(TABLE *table)
   case MYSQL_TYPE_DATETIME:
     return new Field_datetime(maybe_null, name, table, &my_charset_bin);
   case MYSQL_TYPE_YEAR:
-    return new Field_year(max_length, maybe_null, name, table);
+    return new Field_year((char*) 0, max_length, null_ptr, 0, Field::NONE,
+			  name, table);
+  default:
+    /* This case should never be choosen */
+    DBUG_ASSERT(0);
+    /* If something goes awfully wrong, it's better to get a string than die */
   case MYSQL_TYPE_ENUM:
   case MYSQL_TYPE_SET:
-    return new Field_long(max_length, maybe_null, name, table,
-			  unsigned_flag);
+  case MYSQL_TYPE_VAR_STRING:
+    if (max_length > 255)
+      break;					// If blob
+    return new Field_varstring(max_length, maybe_null, name, table,
+			       collation.collation);
+  case MYSQL_TYPE_STRING:
+    if (max_length > 255)			// If blob
+      break;
+    return new Field_string(max_length, maybe_null, name, table,
+			    collation.collation);
   case MYSQL_TYPE_TINY_BLOB:
   case MYSQL_TYPE_MEDIUM_BLOB:
   case MYSQL_TYPE_LONG_BLOB:
   case MYSQL_TYPE_BLOB:
   case MYSQL_TYPE_GEOMETRY:
-    return new Field_blob(max_length, maybe_null, name, table, collation.collation);
-  case MYSQL_TYPE_VAR_STRING:
-    if (max_length > 255)
-      return new Field_blob(max_length, maybe_null, name, table, collation.collation);
-    else
-      return new Field_varstring(max_length, maybe_null, name, table, collation.collation);
-  case MYSQL_TYPE_STRING:
-    if (max_length > 255)
-      return new Field_blob(max_length, maybe_null, name, table, collation.collation);
-    else
-      return new Field_string(max_length, maybe_null, name, table, collation.collation);
-  default:
-    // This case should never be choosen
-    DBUG_ASSERT(0);
-    return 0;
+    break;					// Blob handled outside of case
   }
+
+  /* blob is special as it's generated for both blobs and long strings */
+  return new Field_blob(max_length, maybe_null, name, table,
+			collation.collation);
 }
 
+
 /* ARGSUSED */
 void Item_field::make_field(Send_field *tmp_field)
 {
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 805e6860f655a88fe03ff792a5325729659a0b88..49f0b753549e865a5ca4db75b8553ea1f1171d0b 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2787,6 +2787,9 @@ int main(int argc, char **argv)
   int2str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
           "MySQLShutdown"), 10);
   
+  /* Must be initialized early for comparison of service name */
+  system_charset_info= &my_charset_utf8_general_ci;
+
   if (Service.GetOS())	/* true NT family */
   {
     char file_path[FN_REFLEN];
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 855b5d1e97ee894c97320a71b1fb8b939c7b5c77..781ee2e708289becc16d69c6c595280d1595d212 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -688,14 +688,14 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild,
       {
         byte *pos;
         uint flags=field->flags;
-        String type(tmp,sizeof(tmp), field->charset());
+        String type(tmp,sizeof(tmp), system_charset_info);
         uint col_access;
         bool null_default_value=0;
 
 	protocol->prepare_for_resend();
         protocol->store(field->field_name, system_charset_info);
         field->sql_type(type);
-        protocol->store(type.ptr(), type.length(), type.charset());
+        protocol->store(type.ptr(), type.length(), system_charset_info);
 	if (verbose)
 	  protocol->store(field->has_charset() ? field->charset()->name : "NULL",
 			system_charset_info);
@@ -1117,7 +1117,13 @@ store_create_info(THD *thd, TABLE *table, String *packet)
         type.set(tmp, sizeof(tmp), field->charset());
         field->val_str(&type,&type);
 	if (type.length())
-          append_unescaped(packet, type.ptr(), type.length());
+	{
+   	  String def_val;
+	  /* convert to system_charset_info == utf8 */
+	  def_val.copy(type.ptr(), type.length(), field->charset(),
+		       system_charset_info);
+          append_unescaped(packet, def_val.ptr(), def_val.length());
+	}
         else
 	  packet->append("''",2);
       }
diff --git a/sql/table.cc b/sql/table.cc
index e87cafd52750a5ca94516f72a1a9e633a5662936..7c12762d9c494ae240fd4e49140fcb0fbdf3bd85 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1058,9 +1058,21 @@ ulong next_io_size(register ulong pos)
 } /* next_io_size */
 
 
-	/* Store in String an SQL quoted string */
+/*
+  Store an SQL quoted string.
+
+  SYNOPSIS  
+    append_unescaped()
+    res		result String
+    pos		string to be quoted
+    length	it's length
+
+  NOTE
+    This function works correctly with utf8 or single-byte charset strings.
+    May fail with some multibyte charsets though.
+*/
 
-void append_unescaped(String *res,const char *pos, uint length)
+void append_unescaped(String *res, const char *pos, uint length)
 {
   const char *end= pos+length;
   res->append('\'');
diff --git a/vio/vio.c b/vio/vio.c
index 05bfb22098641caa887eb7946fcef846bff4e7f1..a356d8edeffb96a5b4b5174ad9d997fbb5ede8af 100644
--- a/vio/vio.c
+++ b/vio/vio.c
@@ -55,6 +55,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type,
     vio->in_addr	=vio_in_addr;
     vio->vioblocking	=vio_blocking;
     vio->is_blocking	=vio_is_blocking;
+    vio->timeout	=vio_ignore_timeout;
   }
   else					/* default is VIO_TYPE_TCPIP */
 #endif
@@ -73,6 +74,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type,
     vio->in_addr	=vio_in_addr;
     vio->vioblocking	=vio_blocking;
     vio->is_blocking	=vio_is_blocking;
+    vio->timeout	=vio_ignore_timeout;
   }
   else
 #endif   
diff --git a/vio/vio_priv.h b/vio/vio_priv.h
index 66a9bde4e0d286a03376eff4921d1a433efad008..9a925a2c4c9ee63ce39c943a01266f1f72a2f2df 100644
--- a/vio/vio_priv.h
+++ b/vio/vio_priv.h
@@ -23,6 +23,8 @@
 #include <m_string.h>
 #include <violite.h>
 
+void	vio_ignore_timeout(Vio *vio, uint timeout);
+
 #ifdef HAVE_OPENSSL
 #include "my_net.h"			/* needed because of struct in_addr */
 
diff --git a/vio/viosocket.c b/vio/viosocket.c
index 9d5c7c0d890cb1f756f68c5fdb41c707b63977ff..8dea06d4adf71fd8d5f488f41335f2bc639aa437 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -355,6 +355,13 @@ int vio_close_pipe(Vio * vio)
   DBUG_RETURN(r);
 }
 
+
+void vio_ignore_timeout(Vio *vio __attribute__((unused)),
+			uint timeout __attribute__((unused)))
+{
+}
+
+
 #ifdef HAVE_SMEM
 
 int vio_read_shared_memory(Vio * vio, gptr buf, int size)