diff --git a/.bzrignore b/.bzrignore
index c2d82b8a418..5b2bbbfb929 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -8,6 +8,8 @@
 *.lo
 *.o
 *.spec
+*/*_pure_*warnings
+*/.pure
 *~
 .*.swp
 .deps
@@ -121,6 +123,7 @@ bdb/include/gen_server_ext.h
 bdb/include/hash_auto.h
 bdb/include/log_auto.h
 bdb/include/qam_auto.h
+bdb/include/rpc_client_ext.h
 bdb/include/rpc_server_ext.h
 bdb/include/txn_auto.h
 bdb/java/src/com/sleepycat/db/DbConstants.java
@@ -175,6 +178,7 @@ heap/hp_test2
 include/my_config.h
 include/my_global.h
 include/mysql_version.h
+include/widec.h
 innobase/ib_config.h
 innobase/ib_config.h.in
 isam/isamchk
diff --git a/BUILD/compile-solaris-sparc b/BUILD/compile-solaris-sparc
index 0558cfda25d..f8f7c8755df 100755
--- a/BUILD/compile-solaris-sparc
+++ b/BUILD/compile-solaris-sparc
@@ -1,9 +1,16 @@
 #! /bin/sh
 
-path=`dirname $0`
-. "$path/SETUP.sh"
+gmake -k clean || true
+/bin/rm -f */.deps/*.P config.cache
+ 
+aclocal && autoheader && aclocal && automake && autoconf
+(cd bdb/dist && sh s_all)
+(cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
+if [ -d gemini ]
+then
+   (cd gemini && aclocal && autoheader && aclocal && automake && autoconf)
+fi
+ 
+CFLAGS="-g -Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused  -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti  -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa -g" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
 
-extra_flags="$sparc_cflags $fast_cflags"
-extra_configs="$sparc_configs"
-
-. "$path/FINISH.sh"
+gmake -j 4
diff --git a/BUILD/compile-solaris-sparc-purify b/BUILD/compile-solaris-sparc-purify
index 7b655520dab..b5c898bff30 100755
--- a/BUILD/compile-solaris-sparc-purify
+++ b/BUILD/compile-solaris-sparc-purify
@@ -6,6 +6,8 @@ aclocal && autoheader && aclocal && automake && autoconf
 (cd bdb/dist && sh s_all)
 (cd innobase && aclocal && autoheader && aclocal && automake && autoconf)
 
-CFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused  -DHAVE_purify -O2" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti  -DHAVE_PURIFY -O2" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-debug=full
+CFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Wunused  -DHAVE_purify -DEXTRA_DEBUG -O2" CXX=gcc CXXLD=g++ CXXFLAGS="-Wimplicit -Wreturn-type -Wid-clash-51 -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wimplicit-function-dec -Wimplicit-int -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -Wextern-inline -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor -felide-constructors -fno-exceptions -fno-rtti  -DHAVE_purify -DEXTRA_DEBUG -O2" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --with-debug=full --with-berkeley-db --with-innodb
 
 gmake -j 4
+
+cd sql ; rm mysqld ; make CXXLD="purify -best-effort g++"  mysqld
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index d1f33a8ff39..c8e74a50186 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -7,6 +7,7 @@ jcole@abel.spaceapes.com
 jcole@main.burghcom.com
 jcole@tetra.spaceapes.com
 miguel@light.local
+monty@bitch.mysql.fi
 monty@donna.mysql.fi
 monty@hundin.mysql.fi
 monty@tik.mysql.fi
@@ -17,6 +18,7 @@ paul@teton.kitebird.com
 root@x3.internalnet
 sasha@mysql.sashanet.com
 serg@serg.mysql.com
+tim@bitch.mysql.fi
 tim@black.box
 tim@hundin.mysql.fi
 tim@threads.polyesthetic.msg
diff --git a/acinclude.m4 b/acinclude.m4
index c8135970334..be6b625878a 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1299,3 +1299,435 @@ AC_DEFUN(AC_SYS_LARGEFILE,
 	esac])
    fi
   ])
+
+
+## libtool.m4 - Configure libtool for the target system. -*-Shell-script-*-
+## Copyright (C) 1996-1999 Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+  [  --disable-libtool-lock  avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$lt_target" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_SHARED, [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<<  --enable-shared[=PKGS]  build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_STATIC, [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<<  --enable-static[=PKGS]  build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<<  --enable-fast-install[=PKGS]  optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+    # Accept absolute paths.
+changequote(,)dnl
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+	test "$with_gnu_ld" != no && break
+      else
+	test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+	ac_cv_path_NM="$ac_dir/nm -B"
+	break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+	ac_cv_path_NM="$ac_dir/nm -p"
+	break
+      else
+	ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+	continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$lt_target" in
+*-*-beos* | *-*-cygwin*)
+  # These system don't have libm
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, main, LIBM="-lm")
+  ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case "$enable_ltdl_convenience" in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+  INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, main,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+    INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    INCLTDL=
+  fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
diff --git a/bdb/include/rpc_client_ext.h b/bdb/include/rpc_client_ext.h
deleted file mode 100644
index a5c4689cd27..00000000000
--- a/bdb/include/rpc_client_ext.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* DO NOT EDIT: automatically built by dist/s_include. */
-#ifndef	_rpc_client_ext_h_
-#define	_rpc_client_ext_h_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-int __dbcl_envserver __P((DB_ENV *, char *, long, long, u_int32_t));
-int __dbcl_refresh __P((DB_ENV *));
-int __dbcl_txn_close __P((DB_ENV *));
-void __dbcl_txn_end __P((DB_TXN *));
-int __dbcl_c_destroy __P((DBC *));
-void __dbcl_c_refresh __P((DBC *));
-int __dbcl_c_setup __P((long, DB *, DBC **));
-int __dbcl_retcopy __P((DB_ENV *, DBT *, void *, u_int32_t));
-int __dbcl_dbclose_common __P((DB *));
-#if defined(__cplusplus)
-}
-#endif
-#endif /* _rpc_client_ext_h_ */
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 35d6a7f3c4f..f55a5a3f7c4 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -137,7 +137,7 @@ the mysql command line client\n\n");
 -o, --offset=N		Skip the first N entries\n\
 -h, --host=server	Get the binlog from server\n\
 -P, --port=port         Use port to connect to the remote server\n\
--u, --user=username     Connect to the remove server as username\n\
+-u, --user=username     Connect to the remote server as username\n\
 -p, --password=password Password to connect to remote server\n\
 -r, --result-file=file  Direct output to a given file\n\
 -j, --position=N	Start reading the binlog at position N\n\
@@ -467,4 +467,8 @@ int main(int argc, char** argv)
   the server
 */
 
+#ifdef __WIN__
+#include "log_event.cpp"
+#else
 #include "log_event.cc"
+#endif
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 67a483705ee..2d1c5017922 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -226,6 +226,8 @@ void hash_password(unsigned long *result, const char *password);
 void my_init(void);
 void load_defaults(const char *conf_file, const char **groups,
 		   int *argc, char ***argv);
+my_bool my_thread_init(void);
+void my_thread_end(void);
 
 #ifdef __cplusplus
 }
diff --git a/include/mysqld_error.h b/include/mysqld_error.h
index 52f4261c22b..d8b38d96e18 100644
--- a/include/mysqld_error.h
+++ b/include/mysqld_error.h
@@ -216,4 +216,5 @@
 #define ER_ERROR_WHEN_EXECUTING_COMMAND 1213
 #define ER_WRONG_USAGE 1214
 #define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1215
-#define ER_ERROR_MESSAGES 216
+#define ER_NO_PERSMISSION_TO_CREATE_USER 1216
+#define ER_ERROR_MESSAGES 217
diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c
index 82b12103c4c..c87c92ed7e3 100644
--- a/innobase/buf/buf0flu.c
+++ b/innobase/buf/buf0flu.c
@@ -10,6 +10,7 @@ Created 11/11/1995 Heikki Tuuri
 
 #ifdef UNIV_NONINL
 #include "buf0flu.ic"
+#include "trx0sys.h"
 #endif
 
 #include "ut0byte.h"
diff --git a/innobase/include/univ.i b/innobase/include/univ.i
index 6ffbb1b8fef..f3e3b22bb3d 100644
--- a/innobase/include/univ.i
+++ b/innobase/include/univ.i
@@ -9,12 +9,10 @@ Created 1/20/1994 Heikki Tuuri
 #ifndef univ_i
 #define univ_i
 
-#if (defined(_WIN32) || defined(_WIN64))
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(MYSQL_SERVER)
 #define __WIN__
 
-#ifndef MYSQL_SERVER
 #include <windows.h>
-#endif
 
 /* If you want to check for errors with compiler level -W4,
 comment out the above include of windows.h and let the following defines
diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result
index 309ed5dff4e..8f8770e5602 100644
--- a/mysql-test/r/distinct.result
+++ b/mysql-test/r/distinct.result
@@ -167,3 +167,9 @@ a	sec_to_time(sum(time_to_sec(t)))
 a	sec_to_time(sum(time_to_sec(t)))
 1	00:06:15
 1	00:36:30
+a
+4
+3
+a	c
+4	NULL
+3	NULL
diff --git a/mysql-test/r/fulltext_update.result b/mysql-test/r/fulltext_update.result
new file mode 100644
index 00000000000..77ee76ad30d
--- /dev/null
+++ b/mysql-test/r/fulltext_update.result
@@ -0,0 +1,2 @@
+Table	Op	Msg_type	Msg_text
+test.test	check	status	OK
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 3598b15eb0a..aa372737b29 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -438,7 +438,7 @@ hello	1
 Table	Op	Msg_type	Msg_text
 test.t1	optimize	error	The handler for the table doesn't support check/repair
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Comment
-t1	0	PRIMARY	1	a	A	1	NULL	NULL	
+t1	0	PRIMARY	1	a	A	2	NULL	NULL	
 i	j
 1	2
 i	j
diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test
index 29b2fddbe5f..bf8a03ac40d 100644
--- a/mysql-test/t/distinct.test
+++ b/mysql-test/t/distinct.test
@@ -198,3 +198,12 @@ insert into t2 values (1,1),(2,2),(3,3);
 select t1.a,sec_to_time(sum(time_to_sec(t))) from t1 left join t2 on (t1.b=t2.a) group by t1.a,t2.b;
 select distinct t1.a,sec_to_time(sum(time_to_sec(t))) from t1 left join t2 on (t1.b=t2.a) group by t1.a,t2.b;
 drop table t1,t2;
+
+#
+# Test problem with DISTINCT and HAVING
+#
+create table t1 (a int not null,b char(5), c text);
+insert into t1 (a) values (1),(2),(3),(4),(1),(2),(3),(4);
+select distinct a from t1 group by b,a having a > 2 order by a desc;
+select distinct a,c from t1 group by b,c,a having a > 2 order by a desc;
+drop table t1;
diff --git a/mysql-test/t/fulltext_update.test b/mysql-test/t/fulltext_update.test
new file mode 100644
index 00000000000..9e2ce3ccba5
--- /dev/null
+++ b/mysql-test/t/fulltext_update.test
@@ -0,0 +1,25 @@
+#
+# Test for bug by voi@ims.at
+#
+
+drop table if exists test;
+CREATE TABLE test (
+  gnr INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  url VARCHAR(80) DEFAULT '' NOT NULL,
+  shortdesc VARCHAR(200) DEFAULT '' NOT NULL,
+  longdesc text DEFAULT '' NOT NULL,
+  description VARCHAR(80) DEFAULT '' NOT NULL,
+  name VARCHAR(80) DEFAULT '' NOT NULL,
+  FULLTEXT(url,description,shortdesc,longdesc),
+  PRIMARY KEY(gnr)
+);
+
+insert into test (url,shortdesc,longdesc,description,name) VALUES 
+("http:/test.at", "kurz", "lang","desc", "name");
+insert into test (url,shortdesc,longdesc,description,name) VALUES 
+("http:/test.at", "kurz", "","desc", "name");
+update test set url='test', description='ddd', name='nam' where gnr=2;
+update test set url='test', shortdesc='ggg', longdesc='mmm', 
+description='ddd', name='nam' where gnr=2;
+check table test;
+drop table test;
diff --git a/scripts/mysqldumpslow.sh b/scripts/mysqldumpslow.sh
index 02b5d5cd0cd..856c8a09b5e 100644
--- a/scripts/mysqldumpslow.sh
+++ b/scripts/mysqldumpslow.sh
@@ -3,6 +3,7 @@
 
 # Original version by Tim Bunce, sometime in 2000.
 # Further changes by Tim Bunce, 8th March 2001.
+# Handling of strings with \ and double '' by Monty 11 Aug 2001.
 
 use strict;
 use Getopt::Long;
@@ -95,8 +96,8 @@ while ( defined($_ = shift @pending) or defined($_ = <>) ) {
     unless ($opt{a}) {
 	s/\b\d+\b/N/g;
 	s/\b0x[0-9A-Fa-f]+\b/N/g;
-	s/'.*?'/'S'/g;
-	s/".*?"/"S"/g;
+	s/'([^\\\']|\\.|\'\')+'/'S'/g;
+	s/"([^\\\"]|\\.|\"\")+"/"S"/g;
 	# -n=8: turn log_20001231 into log_NNNNNNNN
 	s/([a-z_]+)(\d{$opt{n},})/$1.('N' x length($2))/ieg if $opt{n};
 	# abbreviate massive "in (...)" statements and similar
diff --git a/sql-bench/Makefile.am b/sql-bench/Makefile.am
index 5712373c405..e9c3e07beef 100644
--- a/sql-bench/Makefile.am
+++ b/sql-bench/Makefile.am
@@ -37,12 +37,12 @@ dist-hook:
 	mkdir -p $(distdir)/Data/ATIS $(distdir)/Data/Wisconsin \
 		 $(distdir)/Results  $(distdir)/Results-win32 \
 		 $(distdir)/limits $(distdir)/Comments
-	$(INSTALL_DATA) $(srcdir)/Data/ATIS/*.* $(distdir)/Data/ATIS
-	$(INSTALL_DATA) $(srcdir)/Data/Wisconsin/*.* $(distdir)/Data/Wisconsin
-	$(INSTALL_DATA) $(srcdir)/Results/*-* $(distdir)/Results
-	$(INSTALL_DATA) $(srcdir)/Results-win32/*-* $(distdir)/Results-win32
-	$(INSTALL_DATA) $(srcdir)/limits/*.* $(distdir)/limits
-	$(INSTALL_DATA) $(srcdir)/Comments/*.* $(distdir)/Comments
+	for i in $(srcdir)/Data/ATIS/*.* ; do $(INSTALL_DATA) $$i $(distdir)/Data/ATIS ; done
+	for i in $(srcdir)/Data/Wisconsin/*.* ; do $(INSTALL_DATA) $$i $(distdir)/Data/Wisconsin ; done
+	for i in $(srcdir)/Results/*-* ; do $(INSTALL_DATA) $$i $(distdir)/Results; done
+	for i in $(srcdir)/Results-win32/*-* ; do $(INSTALL_DATA) $$i $(distdir)/Results-win32; done
+	for i in $(srcdir)/limits/*.* ; do $(INSTALL_DATA) $$i $(distdir)/limits; done
+	for i in $(srcdir)/Comments/*.* ; do $(INSTALL_DATA) $$i $(distdir)/Comments; done
 
 install-data-local:
 	$(mkinstalldirs) \
@@ -54,12 +54,13 @@ install-data-local:
 		 $(DESTDIR)$(benchdir)/limits \
 		 $(DESTDIR)$(benchdir)/Comments
 	$(INSTALL_DATA) $(srcdir)/README  $(DESTDIR)$(benchdir)
-	$(INSTALL_DATA) $(srcdir)/Data/ATIS/*.* $(DESTDIR)$(benchdir)/Data/ATIS
-	$(INSTALL_DATA) $(srcdir)/Data/Wisconsin/*.* $(DESTDIR)$(benchdir)/Data/Wisconsin
-	$(INSTALL_DATA) $(srcdir)/Results/*-* $(DESTDIR)$(benchdir)/Results
-	$(INSTALL_DATA) $(srcdir)/Results-win32/*-* $(DESTDIR)$(benchdir)/Results-win32
-	$(INSTALL_DATA) $(srcdir)/limits/*.* $(DESTDIR)$(benchdir)/limits
-	$(INSTALL_DATA) $(srcdir)/Comments/*.* $(DESTDIR)$(benchdir)/Comments
+	for i in $(srcdir)/Data/ATIS/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Data/ATIS ; done
+	for i in $(srcdir)/Data/Wisconsin/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Data/Wisconsin ; done
+	for i in $(srcdir)/Results/*-* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Results; done
+	for i in $(srcdir)/Results-win32/*-* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Results-win32; done
+	for i in $(srcdir)/limits/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/limits; done
+	for i in $(srcdir)/Comments/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Comments; done
+
 
 SUFFIXES = .sh
 
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index e3e1d959438..ddfd48a0e71 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -229,6 +229,7 @@ void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
     MYRG_TABLE *table;
     THD *thd=current_thd;
     create_info->merge_list.next= &create_info->merge_list.first;
+    create_info->merge_list.elements=0;
 
     for (table=file->open_tables ; table != file->end_table ; table++)
     {
@@ -240,6 +241,7 @@ void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info)
       fn_format(buff,name,"","",3);
       if (!(ptr->real_name=thd->strdup(buff)))
 	goto err;
+      create_info->merge_list.elements++;
       (*create_info->merge_list.next) = (byte*) ptr;
       create_info->merge_list.next= (byte**) &ptr->next;
     }
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d368050feaf..4d5ea1d1354 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1532,9 +1532,13 @@ static void open_log(MYSQL_LOG *log, const char *hostname,
   // get rid of extention if the log is binary to avoid problems
   if (type == LOG_BIN)
   {
-    char* p = strrchr((char*) opt_name, FN_EXTCHAR);
+    char *p = fn_ext(opt_name);
     if (p)
-      *p = 0;
+    {
+      uint length=(uint) (p-opt_name);
+      strmake(tmp,opt_name,min(length,FN_REFLEN));
+      opt_name=tmp;
+    }
   }
   log->open(opt_name,type);
 }
@@ -2818,6 +2822,8 @@ CHANGEABLE_VAR changeable_vars[] = {
       0, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE },
   { "record_buffer",           (long*) &my_default_record_cache_size,
       128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
+  { "record_rnd_buffer",           (long*) &record_rnd_cache_size,
+      0, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE },
   { "slave_net_timeout",        (long*) &slave_net_timeout, 
       SLAVE_NET_TIMEOUT, 1, 65535, 0, 1 },
   { "slow_launch_time",        (long*) &slow_launch_time, 
@@ -2907,6 +2913,7 @@ struct show_var_st init_vars[]= {
   {"log_update",              (char*) &opt_update_log,              SHOW_BOOL},
   {"log_bin",                 (char*) &opt_bin_log,                 SHOW_BOOL},
   {"log_slave_updates",       (char*) &opt_log_slave_updates,       SHOW_BOOL},
+  {"log_long_queries",        (char*) &opt_slow_log,                SHOW_BOOL},
   {"long_query_time",         (char*) &long_query_time,             SHOW_LONG},
   {"low_priority_updates",    (char*) &low_priority_updates,        SHOW_BOOL},
   {"lower_case_table_names",  (char*) &lower_case_table_names,      SHOW_LONG},
@@ -2937,6 +2944,7 @@ struct show_var_st init_vars[]= {
   {"port",                    (char*) &mysql_port,                  SHOW_INT},
   {"protocol_version",        (char*) &protocol_version,            SHOW_INT},
   {"record_buffer",           (char*) &my_default_record_cache_size,SHOW_LONG},
+  {"record_rnd_buffer",       (char*) &record_rnd_cache_size,	    SHOW_LONG},
   {"query_buffer_size",       (char*) &query_buff_size,		    SHOW_LONG},
   {"safe_show_database",      (char*) &opt_safe_show_db,            SHOW_BOOL},
   {"server_id",               (char*) &server_id,		    SHOW_LONG},
@@ -2947,7 +2955,7 @@ struct show_var_st init_vars[]= {
   {"slow_launch_time",        (char*) &slow_launch_time,            SHOW_LONG},
   {"socket",                  (char*) &mysql_unix_port,             SHOW_CHAR_PTR},
   {"sort_buffer",             (char*) &sortbuff_size,               SHOW_LONG},
-  {"sql_mode",                (char*) &sql_mode_str,                SHOW_CHAR_PTR},
+  {"sql_mode",                (char*) &opt_sql_mode,                SHOW_LONG},
   {"table_cache",             (char*) &table_cache_size,            SHOW_LONG},
   {"table_type",              (char*) &default_table_type_name,     SHOW_CHAR_PTR},
   {"thread_cache_size",       (char*) &thread_cache_size,           SHOW_LONG},
@@ -3109,6 +3117,8 @@ static void usage(void)
   --safe-mode		Skip some optimize stages (for testing)\n\
   --safe-show-database  Don't show databases for which the user has no\n\
                         privileges\n\
+  --safe-user-create	Don't new users cretaion without privileges to the\n\
+		        mysql.user table\n\
   --skip-concurrent-insert\n\
 		        Don't use concurrent insert with MyISAM\n\
   --skip-delay-key-write\n\
@@ -3817,6 +3827,20 @@ static void get_options(int argc,char **argv)
       ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
       break;
     }
+    case OPT_SQL_MODE:
+    {
+      sql_mode_str = optarg;
+      if ((opt_sql_mode =
+	   find_bit_type(optarg, &sql_mode_typelib)) == ~(ulong) 0)
+      {
+	fprintf(stderr, "Unknown option to sql-mode: %s\n", optarg);
+	exit(1);
+      }
+      default_tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ?
+			     ISO_SERIALIZABLE :
+			     ISO_READ_COMMITTED);
+      break;
+    }
     case OPT_MASTER_HOST:
       master_host=optarg;
       break;
@@ -3850,6 +3874,9 @@ static void get_options(int argc,char **argv)
     case OPT_SAFE_SHOW_DB:
       opt_safe_show_db=1;
       break;
+    case OPT_SAFE_USER_CREATE:
+      opt_safe_user_create=1;
+      break;
     case OPT_SKIP_SAFEMALLOC:
 #ifdef SAFEMALLOC
       sf_malloc_quick=1;
@@ -3874,6 +3901,9 @@ static void get_options(int argc,char **argv)
   fix_paths();
   default_table_type_name=ha_table_typelib.type_names[default_table_type-1];
   default_tx_isolation_name=tx_isolation_typelib.type_names[default_tx_isolation];
+  /* To be deleted in MySQL 4.0 */
+  if (!record_rnd_cache_size)
+    record_rnd_cache_size=my_default_record_cache_size;
 }
 
 
@@ -4149,7 +4179,7 @@ static int get_service_parameters()
     }
     else if ( lstrcmp(szKeyValueName, TEXT("KeyBufferSize")) == 0 )
     {
-      SET_CHANGEABLE_VARVAL( "key_buffer_size" );
+      SET_CHANGEABLE_VARVAL( "key_buffer" );
     }
     else if ( lstrcmp(szKeyValueName, TEXT("LongQueryTime")) == 0 )
     {
@@ -4463,7 +4493,9 @@ static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
   found=0;
   found_end= 0;
   pos=(my_string) x;
-  do
+  while (*pos == ' ') pos++;
+  found_end= *pos == 0;
+  while (!found_end)
   {
     if (!*(end=strcend(pos,',')))		/* Let end point at fieldend */
     {
@@ -4496,7 +4528,7 @@ skipp: ;
       DBUG_RETURN(~(ulong) 0);				// No unique value
     found|=found_int;
     pos=end+1;
-  } while (! found_end);
+  }
 
   DBUG_PRINT("exit",("bit-field: %ld",(ulong) found));
   DBUG_RETURN(found);
diff --git a/sql/records.cc b/sql/records.cc
index 3187aa424d7..0f49b3fa45e 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -66,7 +66,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
     table->file->rnd_init(0);
 
     if (! (specialflag & SPECIAL_SAFE_MODE) &&
-	my_default_record_cache_size &&
+	record_rnd_cache_size &&
 	!table->file->fast_key_read() &&
 	(table->db_stat & HA_READ_ONLY ||
 	 table->reginfo.lock_type <= TL_READ_NO_INSERT) &&
@@ -216,7 +216,7 @@ static int init_rr_cache(READ_RECORD *info)
     info->reclength=ALIGN_SIZE(info->struct_length);
 
   info->error_offset=info->table->reclength;
-  info->cache_records=my_default_record_cache_size/
+  info->cache_records=record_rnd_cache_size/
     (info->reclength+info->struct_length);
   rec_cache_size=info->cache_records*info->reclength;
   info->rec_cache_size=info->cache_records*info->ref_length;
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 0cca3df0b16..86d3f61776c 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -943,16 +943,41 @@ end:
   DBUG_RETURN(error);
 }
 
+
+/* Return 1 if we are allowed to create new users */
+
+static bool test_if_create_new_users(THD *thd)
+{
+  bool create_new_users=1;    // Assume that we are allowed to create new users
+  if (opt_safe_user_create && !(thd->master_access & INSERT_ACL))
+  {
+    TABLE_LIST tl;
+    uint db_access;
+    bzero((char*) &tl,sizeof(tl));
+    tl.db=	   (char*) "mysql";
+    tl.real_name= (char*) "user";
+    db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
+		      thd->priv_user, tl.db);
+    if (!(db_access & INSERT_ACL))
+    {
+      if (check_grant(thd,INSERT_ACL,&tl,0,1))
+	create_new_users=0;
+    }
+  }
+  return create_new_users;
+}
+
+
 /****************************************************************************
 ** Handle GRANT commands
 ****************************************************************************/
 
 static int replace_user_table(TABLE *table, const LEX_USER &combo,
-			      uint rights, char what)
+			      uint rights, char what, bool create_user)
 {
   int error = -1;
   uint i,j;
-  bool ima=0;
+  bool old_row_exists=0;
   char *password,empty_string[1];
   DBUG_ENTER("replace_user_table");
 
@@ -971,14 +996,21 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
 			      (byte*) table->field[0]->ptr,0,
 			      HA_READ_KEY_EXACT))
   {
-    if (what == 'N')
+    if (!create_user)
     {
-      my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
-		      MYF(0),combo.user.str,combo.host.str);
+      THD *thd=current_thd;
+      if (what == 'N')
+	my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT),
+			MYF(0),combo.user.str,combo.host.str);
+      else
+	my_printf_error(ER_NO_PERMISSON_TO_CREATE_USER,
+			ER(ER_NO_PERMISSON_TO_CREATE_USER),
+			MYF(0),thd->user,
+			thd->host ? thd->host : thd->ip ? thd->ip: "");
       error= -1;
       goto end;
     }
-    ima = 0; // no row; ima on Serbian means 'there is something'
+    old_row_exists = 0;
     restore_record(table,2);			// cp empty row from record[2]
     table->field[0]->store(combo.host.str,combo.host.length);
     table->field[1]->store(combo.user.str,combo.user.length);
@@ -986,7 +1018,7 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
   }
   else
   {
-    ima = 1;
+    old_row_exists = 1;
     store_record(table,1);			// Save copy for update
     if (combo.password.str)			// If password given
       table->field[2]->store(password,(uint) strlen(password));
@@ -1001,7 +1033,7 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
   }
   rights=get_access(table,3);
 
-  if (ima)  // there is a row, therefore go to update, instead of insert
+  if (old_row_exists)
   {
     /*
       We should NEVER delete from the user table, as a uses can still
@@ -1033,7 +1065,7 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
     acl_cache->clear(1);			// Clear privilege cache
     if (!combo.password.str)
       password=0;				// No password given on command
-    if (ima)
+    if (old_row_exists)
       acl_update_user(combo.user.str,combo.host.str,password,rights);
     else
       acl_insert_user(combo.user.str,combo.host.str,password,rights);
@@ -1052,7 +1084,7 @@ static int replace_db_table(TABLE *table, const char *db,
 			    uint rights, char what)
 {
   uint i,j,store_rights;
-  bool ima=0;
+  bool old_row_exists=0;
   int error;
   DBUG_ENTER("replace_db_table");
 
@@ -1076,7 +1108,7 @@ static int replace_db_table(TABLE *table, const char *db,
 		      combo.user.str,combo.host.str);
       goto abort;
     }
-    ima = 0; // no row
+    old_row_exists = 0;
     restore_record(table,2);			// cp empty row from record[2]
     table->field[0]->store(combo.host.str,combo.host.length);
     table->field[1]->store(db,(uint) strlen(db));
@@ -1084,7 +1116,7 @@ static int replace_db_table(TABLE *table, const char *db,
   }
   else
   {
-    ima = 1;
+    old_row_exists = 1;
     store_record(table,1);
   }
 
@@ -1097,8 +1129,9 @@ static int replace_db_table(TABLE *table, const char *db,
   rights=get_access(table,3);
   rights=fix_rights_for_db(rights);
 
-  if (ima) // there is a row, therefore go update, else insert
+  if (old_row_exists)
   {
+    // update old existing row
     if (rights)
     {
       if ((error=table->file->update_row(table->record[1],table->record[0])))
@@ -1117,7 +1150,7 @@ static int replace_db_table(TABLE *table, const char *db,
   }
 
   acl_cache->clear(1);				// Clear privilege cache
-  if (ima)
+  if (old_row_exists)
     acl_update_db(combo.user.str,combo.host.str,db,rights);
   else
     acl_insert_db(combo.user.str,combo.host.str,db,rights);
@@ -1324,7 +1357,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
   while ((xx=iter++))
   {
     uint privileges = xx->rights;
-    bool ima=0;
+    bool old_row_exists=0;
     key_restore(table,key,0,key_length);
     table->field[4]->store(xx->column.ptr(),xx->column.length());
 
@@ -1339,7 +1372,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
 	result= -1; /* purecov: inspected */
 	continue; /* purecov: inspected */
       }
-      ima = 0;
+      old_row_exists = 0;
       restore_record(table,2);			// Get empty record
       key_restore(table,key,0,key_length);
       table->field[4]->store(xx->column.ptr(),xx->column.length());
@@ -1353,13 +1386,13 @@ static int replace_column_table(GRANT_TABLE *g_t,
 	privileges = tmp & ~(privileges | rights);
       else
 	privileges |= tmp;
-      ima = 1;
+      old_row_exists = 1;
       store_record(table,1);			// copy original row
     }
 
     table->field[6]->store((longlong) get_rights_for_column(privileges));
 
-    if (ima) // there is a row, therefore go update, else insert
+    if (old_row_exists)
     {
       if (privileges)
 	error=table->file->update_row(table->record[1],table->record[0]);
@@ -1465,7 +1498,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
 			       uint rights, uint kolone, bool revoke_grant)
 {
   char grantor[HOSTNAME_LENGTH+1+USERNAME_LENGTH];
-  int ima = 1;
+  int old_row_exists = 1;
   int error=0;
   uint store_table_rights,store_col_rights;
   DBUG_ENTER("replace_table_table");
@@ -1505,13 +1538,13 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
 		      table_name);		/* purecov: deadcode */
       DBUG_RETURN(-1);				/* purecov: deadcode */
     }
-    ima = 0;					// no row
+    old_row_exists = 0;
     restore_record(table,1);			// Get saved record
   }
 
   store_table_rights=get_rights_for_table(rights);
   store_col_rights=get_rights_for_column(kolone);
-  if (ima)
+  if (old_row_exists)
   {
     uint j,k;
     store_record(table,1);
@@ -1536,7 +1569,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
   rights=fix_rights_for_table(store_table_rights);
   kolone=fix_rights_for_column(store_col_rights);
 
-  if (ima) // there is a row, therefore go update, else insert
+  if (old_row_exists)
   {
     if (store_table_rights || store_col_rights)
     {
@@ -1668,10 +1701,12 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
       continue;
     }
     /* Create user if needed */
-    if ((replace_user_table(tables[0].table,
+    if (replace_user_table(tables[0].table,
 			    *Str,
 			    0,
-			    revoke_grant ? 'N' : 'Y')))
+			   revoke_grant ? 'N' : 'Y',
+			   (revoke_grant ? 0 :
+			    test_if_create_new_users(thd))))
     {
       result= -1;				// Remember error
       continue;					// Add next user
@@ -1773,6 +1808,7 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
   List_iterator <LEX_USER> str_list (list);
   LEX_USER *Str;
   char what;
+  bool create_new_users=0;
   TABLE_LIST tables[2];
   DBUG_ENTER("mysql_grant");
 
@@ -1799,8 +1835,10 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
     DBUG_RETURN(-1);				/* purecov: deadcode */
   }
 
- // go through users in user_list
+  if (!revoke_grant)
+    create_new_users= test_if_create_new_users(thd);
 
+  // go through users in user_list
   pthread_mutex_lock(&LOCK_grant);
   VOID(pthread_mutex_lock(&acl_cache->lock));
   grant_version++;
@@ -1822,11 +1860,14 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
     }
     if ((replace_user_table(tables[0].table,
 			    *Str,
-			    (!db ? rights : 0), what)))
-      result= -1;
-    if (db && replace_db_table(tables[1].table, db, *Str, rights & DB_ACLS,
-			       what))
+			    (!db ? rights : 0), what, create_new_users)))
       result= -1;
+    else
+    {
+      if (db && replace_db_table(tables[1].table, db, *Str, rights & DB_ACLS,
+				 what))
+	result= -1;
+    }
   }
   VOID(pthread_mutex_unlock(&acl_cache->lock));
   pthread_mutex_unlock(&LOCK_grant);
@@ -1978,7 +2019,7 @@ void grant_reload(void)
 ****************************************************************************/
 
 bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
-		 uint show_table)
+		 uint show_table, bool no_errors)
 {
   TABLE_LIST *table;
   char *user = thd->priv_user;
@@ -2026,7 +2067,7 @@ bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
 
  err:
   pthread_mutex_unlock(&LOCK_grant);
-  if (show_table != 1)				// Not a silent skip of table
+  if (!no_errors)				// Not a silent skip of table
   {
     const char *command="";
     if (want_access & SELECT_ACL)
diff --git a/sql/sql_acl.h b/sql/sql_acl.h
index ff9a105d76b..cf9696d51e7 100644
--- a/sql/sql_acl.h
+++ b/sql/sql_acl.h
@@ -74,7 +74,7 @@ int  grant_init(void);
 void grant_free(void);
 void grant_reload(void);
 bool check_grant(THD *thd, uint want_access, TABLE_LIST *tables,
-		 uint show_command=0);
+		 uint show_command=0, bool dont_print_error=0);
 bool check_grant_column (THD *thd,TABLE *table, const char *name,uint length,
 			 uint show_command=0);
 bool check_grant_all_columns(THD *thd, uint want_access, TABLE *table);
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 1486502148f..1e1b3a612e6 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -27,8 +27,15 @@ class Sql_alloc
 public:
   static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
   static void operator delete(void *ptr, size_t size) {} /*lint -e715 */
-  inline Sql_alloc() {};
-  inline ~Sql_alloc() {};
+#ifdef HAVE_purify
+  bool dummy;
+  inline Sql_alloc() :dummy(0) {}
+  inline ~Sql_alloc() {}
+#else
+  inline Sql_alloc() {}
+  inline ~Sql_alloc() {}
+#endif
+
 };
 
 /*
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 1655d54e9fc..00e0bdefc0c 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2116,7 +2116,7 @@ mysql_execute_command(void)
        else
 	 res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
 			   lex->sql_command == SQLCOM_REVOKE);
-       if(!res)
+       if (!res)
        {
 	 mysql_update_log.write(thd, thd->query,thd->query_length);
 	 if (mysql_bin_log.is_open())
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 3a1d36796b2..0f87eaccd51 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1413,24 +1413,27 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
 
   if (cond->type() == Item::FUNC_ITEM)
   {
-    Item_func *func=(Item_func *)cond,
-              *arg0=(Item_func *)(func->arguments()[0]),
-              *arg1=(Item_func *)(func->arguments()[1]);
-
-    if (func->functype() == Item_func::FT_FUNC)
+    Item_func *func=(Item_func *)cond;
+    Item_func::Functype functype=  func->functype();
+    if (functype == Item_func::FT_FUNC)
       cond_func=(Item_func_match *)cond;
-    else if ((func->functype() == Item_func::GE_FUNC ||
-              func->functype() == Item_func::GT_FUNC)  &&
-              arg0->type() == Item::FUNC_ITEM          &&
-              arg0->functype() == Item_func::FT_FUNC   &&
-              arg1->const_item() && arg1->val()>=0)
-      cond_func=(Item_func_match *)arg0;
-    else if ((func->functype() == Item_func::LE_FUNC ||
-              func->functype() == Item_func::LT_FUNC)  &&
-              arg1->type() == Item::FUNC_ITEM          &&
-              arg1->functype() == Item_func::FT_FUNC   &&
-              arg0->const_item() && arg0->val()>=0)
-      cond_func=(Item_func_match *)arg1;
+    else if (func->arg_count == 2)
+    {
+      Item_func *arg0=(Item_func *)(func->arguments()[0]),
+                *arg1=(Item_func *)(func->arguments()[1]);
+      if ((functype == Item_func::GE_FUNC ||
+           functype == Item_func::GT_FUNC)  &&
+     	   arg0->type() == Item::FUNC_ITEM          &&
+           arg0->functype() == Item_func::FT_FUNC   &&
+           arg1->const_item() && arg1->val()>=0)
+        cond_func=(Item_func_match *) arg0;
+      else if ((functype == Item_func::LE_FUNC ||
+                functype == Item_func::LT_FUNC)  &&
+                arg1->type() == Item::FUNC_ITEM          &&
+                arg1->functype() == Item_func::FT_FUNC   &&
+                arg0->const_item() && arg0->val()>=0)
+        cond_func=(Item_func_match *) arg1;
+    }
   }
   else if (cond->type() == Item::COND_ITEM)
   {
@@ -1439,18 +1442,21 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
     if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
     {
       Item *item;
-      /* I'm too lazy to implement proper recursive descent here,
+      /*
+         I', (Sergei) too lazy to implement proper recursive descent here,
          and anyway, nobody will use such a stupid queries
          that will require it :-)
          May be later...
-       */
+      */
       while ((item=li++))
+      {
         if (item->type() == Item::FUNC_ITEM &&
             ((Item_func *)item)->functype() == Item_func::FT_FUNC)
         {
           cond_func=(Item_func_match *)item;
           break;
         }
+      }
     }
   }
 
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 2bd6e383eac..1409897a7f2 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -217,7 +217,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path,
       table_list.db= (char*) db;
       table_list.real_name=file->name;
       table_list.grant.privilege=col_access;
-      if (check_grant(thd,TABLE_ACLS,&table_list,1))
+      if (check_grant(thd,TABLE_ACLS,&table_list,1,1))
         continue;
     }
     if (files->push_back(thd->strdup(file->name)))
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 8dbb9710cda..f8c3aa59d65 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1128,11 +1128,15 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
   {
     strmov(new_name_buff,new_name);
     fn_same(new_name_buff,table_name,3);
-    // Check if name changed
 #ifdef FN_LOWER_CASE
-    if (!strcmp(db,new_db) && !my_strcasecmp(new_name_buff,table_name))
+    if (lower_case_table_names)
+      casedn_str(new_name);
+    if ((lower_case_table_names &&
+	 !my_strcasecmp(new_name_buff,table_name)) ||
+	(!lower_case_table_names &&
+	 !strcmp(new_name_buff,table_name)))
 #else
-    if (!strcmp(db,new_db) && !strcmp(new_name_buff,table_name))
+    if (!strcmp(new_name_buff,table_name))	// Check if name changed
 #endif
       new_name=table_name;			// No. Make later check easier
     else