diff --git a/Docs/manual.texi b/Docs/manual.texi
index 93447f9072f77f041b6334bc3ce192c25ce7f8ef..8bfd6aca44e5fa0c88dd462010287051619b5adc 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -32537,7 +32537,7 @@ mysql> select MD5("testing");
 This is an "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
 
 @findex DES_ENCRYPT()
-@item DES_ENCRYPT(string_to_encrypt, flag, [, (key_number | key_string) ] )
+@item DES_ENCRYPT(string_to_encrypt [, (key_number | key_string) ] )
 
 Encrypts the string with the given key using the DES algorithm, which
 provides strong encryption.
@@ -48931,6 +48931,8 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
 
 @itemize @bullet
 @item
+Don't give an error for @code{CREATE TABLE ...(... VARCHAR(0))}.
+@item
 Fixed @code{SIGINT} and @code{SIGQUIT} problems in @file{mysql.cc} on Linux
 with some @code{glibc} versions.
 @item
diff --git a/acinclude.m4 b/acinclude.m4
index 85149d64dc788d86e2e0de66a421de64f45df9db..9c5fbfbbb78f450a426a9be33f69cdf58bca0aed 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -703,14 +703,14 @@ AC_DEFUN(MYSQL_CHECK_VIO, [
 AC_DEFUN(MYSQL_FIND_OPENSSL, [
  for d in /usr/ssl/include /usr/local/ssl/include /usr/include/openssl \
 /usr/include/ssl /opt/ssl/include /opt/openssl/include \
-/usr/local/ssl/include/openssl ; do
+/usr/local/ssl/include/openssl /usr/local/include/openssl ; do
   if test -f $d/ssl.h  ; then
     OPENSSL_INCLUDE=$d
   fi
  done
 
  for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \
-/usr/lib /opt/ssl/lib /opt/openssl/lib ; do
+/usr/lib /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do
   if test -f $d/libssl.a ; then
     OPENSSL_LIB=$d
   fi
diff --git a/client/mysql.cc b/client/mysql.cc
index edb6738463eed6c736a6af53eaf3f4a2600dd43e..be776997059c34ec57f33c900f395e4971fea6e0 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -2340,7 +2340,7 @@ static int
 com_status(String *buffer __attribute__((unused)),
 	   char *line __attribute__((unused)))
 {
-  char *status;
+  const char *status;
   tee_puts("--------------", stdout);
   usage(1);					/* Print version */
   if (connected)
@@ -2635,18 +2635,21 @@ static const char* construct_prompt() {
 	processed_prompt.append(current_db ? current_db : "(none)");
 	break;
       case 'h':
-	if (strstr(mysql_get_host_info(&mysql),"Localhost")) {
+      {
+	const char *prompt=mysql_get_host_info(&mysql);
+	if (strstr(prompt, "Localhost"))
 	  processed_prompt.append("localhost");
-	}
-	else {
-	  processed_prompt.append(strtok(mysql_get_host_info(&mysql)," "));
+	else
+	{
+	  const char *end=strcend(prompt,' ');
+	  processed_prompt.append(prompt, (uint) (end-prompt));
 	}
 	break;
+      }
       case 'p':
-	if (strstr(mysql_get_host_info(&mysql),"TCP/IP") 
-	    || ! mysql.unix_socket) {
+	if (strstr(mysql_get_host_info(&mysql),"TCP/IP") ||
+	    ! mysql.unix_socket)
 	  add_int_to_prompt(mysql.port);
-	}
 	else
 	  processed_prompt.append(strrchr(mysql.unix_socket,'/')+1);
 	break;
diff --git a/client/mysqladmin.c b/client/mysqladmin.c
index f6ebffea087c7d58ddd908f3d841478ae13fa172..17a453adbdf3d5156e51bc9227e322862c9d9595 100644
--- a/client/mysqladmin.c
+++ b/client/mysqladmin.c
@@ -400,7 +400,7 @@ static my_bool sql_connect(MYSQL *mysql,const char *host, const char *user,
 
 static int execute_commands(MYSQL *mysql,int argc, char **argv)
 {
-  char *status;
+  const char *status;
 
   for (; argc > 0 ; argv++,argc--)
   {
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 4ae74d129b9adb297328ab9c4615f699ebe146f1..a007c7778e0c7acfd1512271e9ce5e3519f078d3 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -268,7 +268,7 @@ struct st_replace;
 struct st_replace *init_replace(my_string *from, my_string *to, uint count,
 				my_string word_end_chars);
 uint replace_strings(struct st_replace *rep, my_string *start,
-		     uint *max_length, my_string from);
+		     uint *max_length, const char *from);
 void free_replace();
 static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name);
 void free_pointer_array(POINTER_ARRAY *pa);
@@ -2041,7 +2041,8 @@ void reject_dump(const char* record_file, char* buf, int size)
 
 /* Append the string to ds, with optional replace */
 
-static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, char *val, int len)
+static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
+				      int len)
 {
   if (glob_replace)
   {
@@ -3236,7 +3237,7 @@ static uint replace_len(my_string str)
 	/* Replace strings;  Return length of result string */
 
 uint replace_strings(REPLACE *rep, my_string *start,uint *max_length, 
-		     my_string from)
+		     const char *from)
 {
   reg1 REPLACE *rep_pos;
   reg2 REPLACE_STRING *rep_str;
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 4ca423398973cfcc65a1e98f9411555c0bba54ca..cfc1ea326f48c8ded6b60c66bbd8d549c7bb1943 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -602,6 +602,11 @@ struct st_my_thread_var
 extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
 #define my_thread_var (_my_thread_var())
 #define my_errno my_thread_var->thr_errno
+/*
+  Keep track of shutdown,signal, and main threads so that my_end() will not
+  report errors with them
+*/
+extern pthread_t shutdown_th, main_th, signal_th;
 
 	/* statistics_xxx functions are for not essential statistic */
 
diff --git a/include/my_sys.h b/include/my_sys.h
index 3950bfce75899bcebad19335fa907b51ed4eca60..5867368198fbd4e1badd7906bb1190e4ed6d4ddb 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -137,10 +137,7 @@ extern int NEAR my_errno;		/* Last error in mysys */
 #define NORMAL_SAFEMALLOC sf_malloc_quick=0
 extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick;
 extern ulonglong safemalloc_mem_limit;
-/* keep track of shutdown,signal, and main threads so that my_end() will not
-   report errors with them
-*/
-extern pthread_t shutdown_th, main_th,signal_th;
+
 #define CALLER_INFO_PROTO   , const char *sFile, uint uLine
 #define CALLER_INFO         , __FILE__, __LINE__
 #define ORIG_CALLER_INFO    , sFile, uLine
diff --git a/include/mysql.h b/include/mysql.h
index 074ea0a18764b53918ea5201174a93a28577bed4..7a16cbbe1d2a59448ffded8c5b956eb8142ed073 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -272,15 +272,15 @@ my_bool STDCALL mysql_eof(MYSQL_RES *res);
 MYSQL_FIELD *STDCALL mysql_fetch_field_direct(MYSQL_RES *res,
 					      unsigned int fieldnr);
 MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res);
-MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res);
-unsigned int STDCALL mysql_field_tell(MYSQL_RES *res);
+MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res);
+MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res);
 
 unsigned int STDCALL mysql_field_count(MYSQL *mysql);
 my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql);
 my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql);
 unsigned int STDCALL mysql_errno(MYSQL *mysql);
-char * STDCALL mysql_error(MYSQL *mysql);
-char * STDCALL mysql_info(MYSQL *mysql);
+const char * STDCALL mysql_error(MYSQL *mysql);
+const char * STDCALL mysql_info(MYSQL *mysql);
 unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
 const char * STDCALL mysql_character_set_name(MYSQL *mysql);
 
@@ -353,10 +353,10 @@ int		STDCALL mysql_refresh(MYSQL *mysql,
 				     unsigned int refresh_options);
 int		STDCALL mysql_kill(MYSQL *mysql,unsigned long pid);
 int		STDCALL mysql_ping(MYSQL *mysql);
-char *		STDCALL mysql_stat(MYSQL *mysql);
-char *		STDCALL mysql_get_server_info(MYSQL *mysql);
-char *		STDCALL mysql_get_client_info(void);
-char *		STDCALL mysql_get_host_info(MYSQL *mysql);
+const char *		STDCALL mysql_stat(MYSQL *mysql);
+const char *		STDCALL mysql_get_server_info(MYSQL *mysql);
+const char *		STDCALL mysql_get_client_info(void);
+const char *		STDCALL mysql_get_host_info(MYSQL *mysql);
 unsigned int	STDCALL mysql_get_proto_info(MYSQL *mysql);
 MYSQL_RES *	STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild);
 MYSQL_RES *	STDCALL mysql_list_tables(MYSQL *mysql,const char *wild);
@@ -370,7 +370,8 @@ int		STDCALL mysql_options(MYSQL *mysql,enum mysql_option option,
 void		STDCALL mysql_free_result(MYSQL_RES *result);
 void		STDCALL mysql_data_seek(MYSQL_RES *result,
 					my_ulonglong offset);
-MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET);
+MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result,
+						MYSQL_ROW_OFFSET offset);
 MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result,
 					   MYSQL_FIELD_OFFSET offset);
 MYSQL_ROW	STDCALL mysql_fetch_row(MYSQL_RES *result);
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 31b0ea0fb534d97a195abfc1e2ffa0ecc5866eae..f861f3c96c5b3f7db92f61c0ff73ef1895518006 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -2673,7 +2673,7 @@ mysql_dump_debug_info(MYSQL *mysql)
   DBUG_RETURN(simple_command(mysql,COM_DEBUG,0,0,0));
 }
 
-char * STDCALL
+const char * STDCALL
 mysql_stat(MYSQL *mysql)
 {
   DBUG_ENTER("mysql_stat");
@@ -2698,14 +2698,14 @@ mysql_ping(MYSQL *mysql)
 }
 
 
-char * STDCALL
+const char * STDCALL
 mysql_get_server_info(MYSQL *mysql)
 {
   return((char*) mysql->server_version);
 }
 
 
-char * STDCALL
+const char * STDCALL
 mysql_get_host_info(MYSQL *mysql)
 {
   return(mysql->host_info);
@@ -2718,7 +2718,7 @@ mysql_get_proto_info(MYSQL *mysql)
   return (mysql->protocol_version);
 }
 
-char * STDCALL
+const char * STDCALL
 mysql_get_client_info(void)
 {
   return (char*) MYSQL_SERVER_VERSION;
@@ -2803,12 +2803,12 @@ MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res)
   return (res)->fields;
 }
 
-MYSQL_ROWS * STDCALL mysql_row_tell(MYSQL_RES *res)
+MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res)
 {
   return res->data_cursor;
 }
 
-uint STDCALL mysql_field_tell(MYSQL_RES *res)
+MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res)
 {
   return (res)->current_field;
 }
@@ -2835,12 +2835,12 @@ uint STDCALL mysql_errno(MYSQL *mysql)
   return mysql->net.last_errno;
 }
 
-char * STDCALL mysql_error(MYSQL *mysql)
+const char * STDCALL mysql_error(MYSQL *mysql)
 {
   return mysql->net.last_error;
 }
 
-char *STDCALL mysql_info(MYSQL *mysql)
+const char *STDCALL mysql_info(MYSQL *mysql)
 {
   return mysql->info;
 }
diff --git a/mysys/my_static.h b/mysys/my_static.h
index ca3840090630b33476dda0bd70a61b1ed51ad27d..88faf24ce825db7ac314fadd4aec131e02ca59c7 100644
--- a/mysys/my_static.h
+++ b/mysys/my_static.h
@@ -57,10 +57,11 @@ extern const char *soundex_map;
 extern USED_MEM* my_once_root_block;
 extern uint	 my_once_extra;
 
-/* these threads are exept from safemalloc leak scrutiny unless
-   PEDANTIC_SAFEMALLOC is defined
+/*
+  These threads are exept from safemalloc leak scrutiny unless
+  PEDANTIC_SAFEMALLOC is defined
 */
-extern pthread_t signal_thread,kill_thread;
+extern pthread_t signal_thread, kill_thread;
 
 #ifndef HAVE_TEMPNAM
 extern int	_my_tempnam_used;
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 2c7fd098c6343461a2308541a9426a264a9bb4a0..5b137df20f84cd915120a917cee3841adf7c8c8e 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -111,6 +111,7 @@ my_bool my_thread_init(void)
 #if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
   pthread_mutex_lock(&THR_LOCK_lock);
 #endif
+
 #if !defined(__WIN__) || defined(USE_TLS)
   if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
   {
@@ -121,17 +122,8 @@ my_bool my_thread_init(void)
     pthread_mutex_unlock(&THR_LOCK_lock);
     return 0;						/* Safequard */
   }
-    /* We must have many calloc() here because these are freed on
-       pthread_exit */
-    /*
-      Sasha: the above comment does not make sense. I have changed calloc() to
-      equivalent my_malloc() but it was calloc() before. It seems like the
-      comment is out of date - we always call my_thread_end() before
-      pthread_exit() to clean up. Note that I have also fixed up DBUG
-      code to be able to call it from my_thread_init()
-     */
   if (!(tmp=(struct st_my_thread_var *)
-	my_malloc(sizeof(struct st_my_thread_var),MYF(MY_WME|MY_ZEROFILL))))
+	calloc(1, sizeof(struct st_my_thread_var))))
   {
     pthread_mutex_unlock(&THR_LOCK_lock);
     return 1;
@@ -139,21 +131,18 @@ my_bool my_thread_init(void)
   pthread_setspecific(THR_KEY_mysys,tmp);
 
 #else
-  /* Sasha: TODO - explain what exactly we are doing on Windows
-     At first glance, I have a hard time following the code
-   */
-  if (THR_KEY_mysys.id)   /* Already initialized */
-  {
-#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
-    pthread_mutex_unlock(&THR_LOCK_lock);
-#endif
-    return 0;
-  }
+  /*
+    Skip initialization if the thread specific variable is already initialized
+  */
+  if (THR_KEY_mysys.id)
+    goto end;
   tmp= &THR_KEY_mysys;
 #endif
   tmp->id= ++thread_id;
   pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
   pthread_cond_init(&tmp->suspend, NULL);
+
+end:
 #if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
   pthread_mutex_unlock(&THR_LOCK_lock);
 #endif
@@ -170,11 +159,7 @@ void my_thread_end(void)
   if (tmp)
   {
 #if !defined(DBUG_OFF)
-    /* Sasha:  tmp->dbug is allocated inside DBUG library
-       so for now we will not mess with trying to use my_malloc()/
-       my_free(), but in the future it would be nice to figure out a
-       way to do it
-    */
+    /* tmp->dbug is allocated inside DBUG library */
     if (tmp->dbug)
     {
       free(tmp->dbug);
@@ -186,15 +171,13 @@ void my_thread_end(void)
 #endif
     pthread_mutex_destroy(&tmp->mutex);
 #if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
-    /* we need to setspecific to 0 BEFORE we call my_free, as my_free
-       uses some DBUG_ macros that will use the follow the specific
-       pointer after the block it is pointing to has been freed if
-       specific does not get reset first
-    */
-    pthread_setspecific(THR_KEY_mysys,0);
-    my_free((gptr)tmp,MYF(MY_WME));
+    free(tmp);
 #endif
   }
+  /* The following free has to be done, even if my_thread_var() is 0 */
+#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
+  pthread_setspecific(THR_KEY_mysys,0);
+#endif
 }
 
 struct st_my_thread_var *_my_thread_var(void)
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 0c83698e60a28fef3c3081ed09bef32fe00f4865..bb773af1ddf5e4a4ea33674edd8e6ae4ce566ea4 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -790,8 +790,9 @@ String *Item_func_coalesce::val_str(String *str)
   null_value=0;
   for (uint i=0 ; i < arg_count ; i++)
   {
-    if (args[i]->val_str(str) != NULL)
-      return args[i]->val_str(str);
+    String *res;
+    if ((res=args[i]->val_str(str)))
+      return res;
   }
   null_value=1;
   return 0;
diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc
index 9e52e4580e671adb1d024877cfdc16e2be6d0dac..1ab3e18424faa9f01e5284499646f215fbbcd96c 100644
--- a/sql/net_pkg.cc
+++ b/sql/net_pkg.cc
@@ -108,10 +108,12 @@ net_printf(NET *net, uint errcode, ...)
     thd->query_error = 1;	// if we are here, something is wrong :-)
   query_cache_abort(net);	// Safety
   va_start(args,errcode);
-  // Sasha: this is needed to make net_printf() work with 0 argument for
-  // errorcode and use the argument after that as the format string. This
-  // is usefull for rare errors that are not worth the hassle to put in
-  // errmsg.sys, but at the same time, the message is not fixed text
+  /*
+    The following is needed to make net_printf() work with 0 argument for
+    errorcode and use the argument after that as the format string. This
+    is useful for rare errors that are not worth the hassle to put in
+    errmsg.sys, but at the same time, the message is not fixed text
+  */
   format=errcode ? ER(errcode) : va_arg(args,char*);
   offset= net->return_errno ? 2 : 0;
   text_pos=(char*) net->buff+head_length+offset+1;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7f4553459f1edfd8ef19fa46f64e842ec6ab5db3..dc89888a1a554cd5b4cace36e1191cdb03c22d0f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2990,7 +2990,7 @@ bool add_field_to_list(char *field_name, enum_field_types type,
 
   if (new_field->length >= MAX_FIELD_WIDTH ||
       (!new_field->length && !(new_field->flags & BLOB_FLAG) &&
-       type != FIELD_TYPE_STRING))
+       type != FIELD_TYPE_STRING && type != FIELD_TYPE_VAR_STRING))
   {
     net_printf(&thd->net,ER_TOO_BIG_FIELDLENGTH,field_name,
 	       MAX_FIELD_WIDTH-1);		/* purecov: inspected */