From 3221600e62166fa9ba1d49c6daea537c86137d9a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jul 2001 16:48:33 +0200 Subject: [PATCH 01/18] fulltext_update.result BitKeeper file /usr/home/serg/Abk/mysql/mysql-test/r/fulltext_update.result fulltext_update.test BitKeeper file /usr/home/serg/Abk/mysql/mysql-test/t/fulltext_update.test --- mysql-test/r/fulltext_update.result | 2 ++ mysql-test/t/fulltext_update.test | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 mysql-test/r/fulltext_update.result create mode 100644 mysql-test/t/fulltext_update.test 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/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; From 9d5a520730a8136633f8aa81e5f3ede2a1412033 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 01:04:43 +0300 Subject: [PATCH 02/18] acinclude.m4: Paste the libtool.m4 from libtool version 1.3.4 into aclinclude.m4; this should make our configure work even when the user has libtool version 1.4 installed. This should be removed, and everyone should upgrade to libtool 1.4; until then, this is a quick hack to make things work. acinclude.m4: Paste the libtool.m4 from libtool version 1.3.4 into aclinclude.m4; this should make our configure work even when the user has libtool version 1.4 installed. This should be removed, and everyone should upgrade to libtool 1.4; until then, this is a quick hack to make things work. BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + acinclude.m4 | 432 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 433 insertions(+) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index fbf9c3702a3..ce08f235c9d 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -14,3 +14,4 @@ tim@white.box jcole@tetra.spaceapes.com davida@isil.mysql.com tonu@x153.internalnet +tim@bitch.mysql.fi diff --git a/acinclude.m4 b/acinclude.m4 index 59b6e909225..8fb3e986b11 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1154,3 +1154,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 , 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 &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 From 51bc6118a4ba799b059046bd4bb3c5e065b8d846 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Aug 2001 22:58:45 -0500 Subject: [PATCH 03/18] DocTOC Chapter 9 Complete! (Chapter 8 Skipped, will be next.) --- Docs/manual.texi | 4986 +++++++++++++++++++++++----------------------- 1 file changed, 2540 insertions(+), 2446 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 685933b67af..b07e9a889de 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -115,15 +115,11 @@ distribution for that version. * MySQL Optimization:: * Reference:: @strong{MySQL} language reference * Table types:: @strong{MySQL} table types -* Maintenance:: Maintaining a @strong{MySQL} installation -* Adding functions:: Adding new functions to @strong{MySQL} -* Adding procedures:: Adding new procedures to @strong{MySQL} +* Extending MySQL:: * ODBC:: @strong{MySQL} ODBC Support * Common programs:: Using @strong{MySQL} with some common programs -* Problems:: Problems -* Common problems:: Solving some common problems with @strong{MySQL} * Clients:: @strong{MySQL} client tools and APIs -* MySQL internals:: @strong{MySQL} internals +* Problems:: Problems * Environment variables:: @strong{MySQL} environment variables * Users:: Some @strong{MySQL} users * MySQL customer usage:: @@ -746,7 +742,8 @@ memory leakage detector. @item Includes @code{myisamchk}, a very fast utility for table checking, optimization, and repair. All of the functionality of @code{myisamchk} -is also available through the SQL interface as well. @xref{Maintenance}. +is also available through the SQL interface as well. +@xref{MySQL Database Administration}. @item Full support for several different character sets, including @@ -2569,7 +2566,7 @@ upgrading to a newer version of @strong{MySQL}. @xref{News}. If you have a problem such that your data appears corrupt or you get errors when you access some particular table, you should first check and then try repairing your tables with @code{myisamchk} or @code{CHECK TABLE} and -@code{REPAIR TABLE}. @xref{Maintenance}. +@code{REPAIR TABLE}. @xref{MySQL Database Administration}. @item If you often get corrupted tables you should try to find out when and why this @@ -20573,7 +20570,7 @@ The list below briefly describes the @strong{MySQL} programs: @item myisamchk Utility to describe, check, optimize, and repair @strong{MySQL} tables. Because @code{myisamchk} has many functions, it is described in its own -chapter. @xref{Maintenance}. +chapter. @xref{MySQL Database Administration}. @cindex @code{make_binary_distribution} @item make_binary_distribution @@ -21435,6 +21432,7 @@ binaries includes: * Client-Side Overview:: * mysql:: * mysqladmin:: +* Using mysqlcheck:: * mysqldump:: * mysqlhotcopy:: * mysqlimport:: @@ -21501,7 +21499,7 @@ The list below briefly describes the @strong{MySQL} programs: @item myisamchk Utility to describe, check, optimize, and repair @strong{MySQL} tables. Because @code{myisamchk} has many functions, it is described in its own -chapter. @xref{Maintenance}. +chapter. @xref{MySQL Database Administration}. @cindex @code{make_binary_distribution} @item make_binary_distribution @@ -21924,7 +21922,7 @@ file, but want to be able to turn the feature off sometimes. @end itemize -@node mysqladmin, mysqldump, mysql, Client-Side Scripts +@node mysqladmin, Using mysqlcheck, mysql, Client-Side Scripts @subsection mysqladmin, Administrating a MySQL Server @cindex administration, server @@ -22044,7 +22042,131 @@ wait until the @strong{MySQL} @code{pid-file} is removed to ensure that the @code{mysqld} server has stopped properly. -@node mysqldump, mysqlhotcopy, mysqladmin, Client-Side Scripts +@node Using mysqlcheck, mysqldump, mysqladmin, Client-Side Scripts +@subsection Using @code{mysqlcheck} for Table Maintenance and Crash Recovery + +Since @strong{MySQL} version 3.23.38 you will be able to use a new +checking and repairing tool for @code{MyISAM} tables. The difference to +@code{myisamchk} is that @code{mysqlcheck} should be used when the +@code{mysqld} server is running, where as @code{myisamchk} should be used +when it is not. The benefit is that you no longer have to take the +server down for checking or repairing your tables. + +@code{mysqlcheck} uses @strong{MySQL} server commands @code{CHECK}, +@code{REPAIR}, @code{ANALYZE} and @code{OPTIMIZE} in a convenient way +for the user. + +There are three alternative ways to invoke @code{mysqlcheck}: + +@example +shell> mysqlcheck [OPTIONS] database [tables] +shell> mysqlcheck [OPTIONS] --databases DB1 [DB2 DB3...] +shell> mysqlcheck [OPTIONS] --all-databases +@end example + +So it can be used in a similar way as @code{mysqldump} when it +comes to what databases and tables you want to choose. + +@code{mysqlcheck} does have a special feature compared to the other +clients; the default behavior, checking tables (-c), can be changed by +renaming the binary. So if you want to have a tool that repairs tables +by default, you should just copy @code{mysqlcheck} to your harddrive +with a new name, @code{mysqlrepair}, or alternatively make a symbolic +link to @code{mysqlrepair} and name the symbolic link as +@code{mysqlrepair}. If you invoke @code{mysqlrepair} now, it will repair +tables by default. + +The names that you can use to change @code{mysqlcheck} default behavior +are here: + +@example +mysqlrepair: The default option will be -r +mysqlanalyze: The default option will be -a +mysqloptimize: The default option will be -o +@end example + +The options available for @code{mysqlcheck} are listed here, please +check what your version supports with @code{mysqlcheck --help}. + +@table @code +@item -A, --all-databases +Check all the databases. This will be same as --databases with all +databases selected +@item -1, --all-in-1 +Instead of making one query for each table, execute all queries in 1 +query separately for each database. Table names will be in a comma +separated list. +@item -a, --analyze +Analyze given tables. +@item --auto-repair +If a checked table is corrupted, automatically fix it. Repairing will be +done after all tables have been checked, if corrupted ones were found. +@item -#, --debug=... +Output debug log. Often this is 'd:t:o,filename' +@item --character-sets-dir=... +Directory where character sets are +@item -c, --check +Check table for errors +@item -C, --check-only-changed +Check only tables that have changed since last check or haven't been +closed properly. +@item --compress +Use compression in server/client protocol. +@item -?, --help +Display this help message and exit. +@item -B, --databases +To check several databases. Note the difference in usage; In this case +no tables are given. All name arguments are regarded as database names. +@item --default-character-set=... +Set the default character set +@item -F, --fast +Check only tables that hasn't been closed properly +@item -f, --force +Continue even if we get an sql-error. +@item -e, --extended +If you are using this option with CHECK TABLE, it will ensure that the +table is 100 percent consistent, but will take a long time. + +If you are using this option with REPAIR TABLE, it will run an extended +repair on the table, which may not only take a long time to execute, but +may produce a lot of garbage rows also! +@item -h, --host=... +Connect to host. +@item -m, --medium-check +Faster than extended-check, but only finds 99.99 percent of all +errors. Should be good enough for most cases. +@item -o, --optimize +Optimize table +@item -p, --password[=...] +Password to use when connecting to server. If password is not given +it's solicited on the tty. +@item -P, --port=... +Port number to use for connection. +@item -q, --quick +If you are using this option with CHECK TABLE, it prevents the check +from scanning the rows to check for wrong links. This is the fastest +check. + +If you are using this option with REPAIR TABLE, it will try to repair +only the index tree. This is the fastest repair method for a table. +@item -r, --repair +Can fix almost anything except unique keys that aren't unique. +@item -s, --silent +Print only error messages. +@item -S, --socket=... +Socket file to use for connection. +@item --tables +Overrides option --databases (-B). +@item -u, --user=# +User for login if not current user. +@item -v, --verbose +Print info about the various stages. +@item -V, --version +Output version information and exit. +@end table + + +@node mysqldump, mysqlhotcopy, Using mysqlcheck, Client-Side Scripts @subsection mysqldump, Dumping Table Structure and Data @cindex dumping, databases @@ -22911,9 +23033,6 @@ the new updates. Note that if you are replicating a database, all updates to this database should be done through the master! -On older servers one can use the update log to do simple replication. -@xref{Log Replication}. - Another benefit of using replication is that one can get live backups of the system by doing a backup on a slave instead of doing it on the master. @xref{Backup}. @@ -34613,7 +34732,9 @@ parameters to @code{FULLTEXT} in @code{CREATE/ALTER TABLE}). @end itemize -@node Table types, Maintenance, Reference, Top + + +@node Table types, Extending MySQL, Reference, Top @chapter MySQL Table Types @cindex table types, choosing @@ -34696,10 +34817,11 @@ of both worlds. * MERGE:: MERGE tables * ISAM:: ISAM tables * HEAP:: HEAP tables -* InnoDB:: InnoDB tables * BDB:: BDB or Berkeley_db tables +* InnoDB:: InnoDB tables @end menu + @node MyISAM, MERGE, Table types, Table types @section MyISAM Tables @@ -34877,10 +34999,12 @@ backup media. * MyISAM table problems:: @end menu -@cindex key space, MyISAM + @node Key space, MyISAM table formats, MyISAM, MyISAM @subsection Space Needed for Keys +@cindex key space, MyISAM + @strong{MySQL} can support different index types, but the normal type is ISAM or MyISAM. These use a B-tree index, and you can roughly calculate the size for the index file as @code{(key_length+4)/0.67}, summed over @@ -34900,6 +35024,7 @@ In @code{MyISAM} tables, you can also prefix compress numbers by specifying many integer keys that have an identical prefix when the numbers are stored high-byte first. + @node MyISAM table formats, MyISAM table problems, Key space, MyISAM @subsection MyISAM Table Formats @@ -34913,6 +35038,7 @@ compressed tables, can only be created with the @code{myisampack} tool. * Compressed format:: Compressed table characteristics @end menu + @node Static format, Dynamic format, MyISAM table formats, MyISAM table formats @subsubsection Static (Fixed-length) Table Characteristics @@ -34952,11 +35078,13 @@ system. Usually requires more disk space than dynamic tables. @end itemize -@cindex dynamic table characteristics -@cindex tables, dynamic + @node Dynamic format, Compressed format, Static format, MyISAM table formats @subsubsection Dynamic Table Characteristics +@cindex dynamic table characteristics +@cindex tables, dynamic + This format is used if the table contains any @code{VARCHAR}, @code{BLOB}, or @code{TEXT} columns or if the table was created with @code{ROW_FORMAT=dynamic}. @@ -35016,10 +35144,12 @@ If not, there will be another link. You may check how many links there are with @code{myisamchk -ed}. All links may be removed with @code{myisamchk -r}. @end itemize -@cindex tables, compressed format + @node Compressed format, , Dynamic format, MyISAM table formats @subsubsection Compressed Table Characteristics +@cindex tables, compressed format + This is a read-only type that is generated with the optional @code{myisampack} tool (@code{pack_isam} for @code{ISAM} tables): @@ -35062,6 +35192,7 @@ columns. Can be uncompressed with @code{myisamchk}. @end itemize + @node MyISAM table problems, , MyISAM table formats, MyISAM @subsection MyISAM table problems. @@ -35074,6 +35205,7 @@ to become corrupted. * MyISAM table close:: @end menu + @node Corrupted MyISAM tables, MyISAM table close, MyISAM table problems, MyISAM table problems @subsubsection Corrupted MyISAM tables. @@ -35121,6 +35253,7 @@ checking if there is a recent row @code{restarted mysqld} in the mysqld error file). If this isn't the case, then you should try to make a test case of this. @xref{Reproduceable test case}. + @node MyISAM table close, , Corrupted MyISAM tables, MyISAM table problems @subsubsection Clients is using or hasn't closed the table properly @@ -35179,11 +35312,13 @@ be avoided as it currently replaces the data file with a new one, which is not signaled to the other servers. @end itemize -@cindex tables, merging -@cindex MERGE tables, defined + @node MERGE, ISAM, MyISAM, Table types @section MERGE Tables +@cindex tables, merging +@cindex MERGE tables, defined + @code{MERGE} tables are new in @strong{MySQL} Version 3.23.25. The code is still in gamma, but should be resonable stable. @@ -35332,10 +35467,12 @@ Change the @code{.MRG} file and issue a @code{FLUSH TABLE} on the read the new definition file. @end itemize -@cindex tables, ISAM + @node ISAM, HEAP, MERGE, Table types @section ISAM Tables +@cindex tables, ISAM + You can also use the deprecated ISAM table type. This will disappear rather soon because @code{MyISAM} is a better implementation of the same thing. ISAM uses a @code{B-tree} index. The index is stored in a file @@ -35374,10 +35511,12 @@ TABLE} statement: mysql> ALTER TABLE tbl_name TYPE = MYISAM; @end example -@cindex tables, @code{HEAP} -@node HEAP, InnoDB, ISAM, Table types + +@node HEAP, BDB, ISAM, Table types @section HEAP Tables +@cindex tables, @code{HEAP} + @code{HEAP} tables use a hashed index and are stored in memory. This makes them very fast, but if @strong{MySQL} crashes you will lose all data stored in them. @code{HEAP} is very useful for temporary tables! @@ -35452,7 +35591,303 @@ SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2) @code{sizeof(char*)} is 4 on 32-bit machines and 8 on 64-bit machines. -@node InnoDB, BDB, HEAP, Table types + +@node BDB, InnoDB, HEAP, Table types +@section BDB or Berkeley_DB Tables + +@cindex tables, @code{BDB} +@cindex tables, @code{Berkeley DB} + +@menu +* BDB overview:: Overview of BDB Tables +* BDB install:: Installing BDB +* BDB start:: BDB startup options +* BDB characteristic:: Some characteristic of @code{BDB} tables: +* BDB TODO:: Some things we need to fix for BDB in the near future: +* BDB portability:: Operating systems supported by @strong{BDB} +* BDB errors:: Errors You May Get When Using BDB Tables +@end menu + +@node BDB overview, BDB install, BDB, BDB +@subsection Overview of BDB Tables + +Support for BDB tables is included in the @strong{MySQL} source distribution +starting from Version 3.23.34 and is activated in the @strong{MySQL}-Max +binary. + +BerkeleyDB, available at @uref{http://www.sleepycat.com/} has provided +@strong{MySQL} with a transactional table handler. By using BerkeleyDB +tables, your tables may have a greater chance of surviving crashes, and also +provides @code{COMMIT} and @code{ROLLBACK} on transactions. The +@strong{MySQL} source distribution comes with a BDB distribution that has a +couple of small patches to make it work more smoothly with @strong{MySQL}. +You can't use a non-patched @code{BDB} version with @strong{MySQL}. + +We at @strong{MySQL AB} are working in close cooperation with Sleepycat to +keep the quality of the @strong{MySQL}/BDB interface high. + +When it comes to supporting BDB tables, we are committed to help our +users to locate the problem and help creating a reproducable test case +for any problems involving BDB tables. Any such test case will be +forwarded to Sleepycat who in turn will help us find and fix the +problem. As this is a two stage operation, any problems with BDB tables +may take a little longer for us to fix than for other table handlers. +However, as the BerkeleyDB code itself has been used by many other +applications than @strong{MySQL}, we don't envision any big problems with +this. @xref{Table handler support}. + + +@node BDB install, BDB start, BDB overview, BDB +@subsection Installing BDB + +If you have downloaded a binary version of @strong{MySQL} that includes +support for BerkeleyDB, simply follow the instructions for installing a +binary version of @strong{MySQL}. +@xref{Installing binary}. @xref{mysqld-max, , @code{mysqld-max}}. + +To compile @strong{MySQL} with Berkeley DB support, download @strong{MySQL} +Version 3.23.34 or newer and configure @code{MySQL} with the +@code{--with-berkeley-db} option. @xref{Installing source}. + +@example +cd /path/to/source/of/mysql-3.23.34 +./configure --with-berkeley-db +@end example + +Please refer to the manual provided with the @code{BDB} distribution for +more updated information. + +Even though Berkeley DB is in itself very tested and reliable, +the @strong{MySQL} interface is still considered beta quality. +We are actively improving and optimizing it to get it stable very +soon. + + +@node BDB start, BDB characteristic, BDB install, BDB +@subsection BDB startup options + +If you are running with @code{AUTOCOMMIT=0} then your changes in @code{BDB} +tables will not be updated until you execute @code{COMMIT}. Instead of commit +you can execute @code{ROLLBACK} to forget your changes. @xref{COMMIT}. + +If you are running with @code{AUTOCOMMIT=1} (the default), your changes +will be committed immediately. You can start an extended transaction with +the @code{BEGIN WORK} SQL command, after which your changes will not be +committed until you execute @code{COMMIT} (or decide to @code{ROLLBACK} +the changes). + +The following options to @code{mysqld} can be used to change the behavior of +BDB tables: + +@multitable @columnfractions .30 .70 +@item @strong{Option} @tab @strong{Meaning} +@item @code{--bdb-home=directory} @tab Base directory for BDB tables. This should be the same directory you use for --datadir. +@item @code{--bdb-lock-detect=#} @tab Berkeley lock detect. One of (DEFAULT, OLDEST, RANDOM, or YOUNGEST). +@item @code{--bdb-logdir=directory} @tab Berkeley DB log file directory. +@item @code{--bdb-no-sync} @tab Don't synchronously flush logs. +@item @code{--bdb-no-recover} @tab Don't start Berkeley DB in recover mode. +@item @code{--bdb-shared-data} @tab Start Berkeley DB in multi-process mode (Don't use @code{DB_PRIVATE} when initializing Berkeley DB) +@item @code{--bdb-tmpdir=directory} @tab Berkeley DB tempfile name. +@item @code{--skip-bdb} @tab Don't use berkeley db. +@item @code{-O bdb_max_lock=1000} @tab Set the maximum number of locks possible. @xref{SHOW VARIABLES}. +@end multitable + +If you use @code{--skip-bdb}, @strong{MySQL} will not initialize the +Berkeley DB library and this will save a lot of memory. Of course, +you cannot use @code{BDB} tables if you are using this option. + +Normally you should start @code{mysqld} without @code{--bdb-no-recover} if you +intend to use BDB tables. This may, however, give you problems when you +try to start @code{mysqld} if the BDB log files are corrupted. @xref{Starting +server}. + +With @code{bdb_max_lock} you can specify the maximum number of locks +(10000 by default) you can have active on a BDB table. You should +increase this if you get errors of type @code{bdb: Lock table is out of +available locks} or @code{Got error 12 from ...} when you have do long +transactions or when @code{mysqld} has to examine a lot of rows to +calculate the query. + +You may also want to change @code{binlog_cache_size} and +@code{max_binlog_cache_size} if you are using big multi-line transactions. +@xref{COMMIT}. + + +@node BDB characteristic, BDB TODO, BDB start, BDB +@subsection Some characteristic of @code{BDB} tables: + +@itemize @bullet +@item +To be able to rollback transactions BDB maintain log files. For maximum +performance you should place these on another disk than your databases +by using the @code{--bdb_log_dir} options. +@item +@strong{MySQL} performs a checkpoint each time a new BDB log +file is started, and removes any log files that are not needed for +current transactions. One can also run @code{FLUSH LOGS} at any time +to checkpoint the Berkeley DB tables. + +For disaster recovery, one should use table backups plus +@strong{MySQL}'s binary log. @xref{Backup}. + +@strong{Warning}: If you delete old log files that are in use, BDB will +not be able to do recovery at all and you may lose data if something +goes wrong. +@item +@strong{MySQL} requires a @code{PRIMARY KEY} in each BDB table to be +able to refer to previously read rows. If you don't create one, +@strong{MySQL} will create an maintain a hidden @code{PRIMARY KEY} for +you. The hidden key has a length of 5 bytes and is incremented for each +insert attempt. +@item +If all columns you access in a @code{BDB} table are part of the same index or +part of the primary key, then @strong{MySQL} can execute the query +without having to access the actual row. In a @code{MyISAM} table the +above holds only if the columns are part of the same index. +@item +The @code{PRIMARY KEY} will be faster than any other key, as the +@code{PRIMARY KEY} is stored together with the row data. As the other keys are +stored as the key data + the @code{PRIMARY KEY}, it's important to keep the +@code{PRIMARY KEY} as short as possible to save disk and get better speed. +@item +@code{LOCK TABLES} works on @code{BDB} tables as with other tables. If +you don't use @code{LOCK TABLE}, @strong{MYSQL} will issue an internal +multiple-write lock on the table to ensure that the table will be +properly locked if another thread issues a table lock. +@item +Internal locking in @code{BDB} tables is done on page level. +@item +@code{SELECT COUNT(*) FROM table_name} is slow as @code{BDB} tables doesn't +maintain a count of the number of rows in the table. +@item +Scanning is slower than with @code{MyISAM} tables as one has data in BDB +tables stored in B-trees and not in a separate data file. +@item +The application must always be prepared to handle cases where +any change of a @code{BDB} table may make an automatic rollback and any +read may fail with a deadlock error. +@item +Keys are not compressed to previous keys as with ISAM or MyISAM +tables. In other words, the key information will take a little more +space in @code{BDB} tables compared to MyISAM tables which don't use +@code{PACK_KEYS=0}. +@item +There is often holes in the BDB table to allow you to insert new rows in +the middle of the key tree. This makes BDB tables somewhat larger than +MyISAM tables. +@item +The optimizer needs to know an approximation of the number of rows in +the table. @strong{MySQL} solves this by counting inserts and +maintaining this in a separate segment in each BDB table. If you don't +do a lot of @code{DELETE} or @code{ROLLBACK}:s this number should be +accurate enough for the @strong{MySQL} optimizer, but as @strong{MySQL} +only store the number on close, it may be wrong if @strong{MySQL} dies +unexpectedly. It should not be fatal even if this number is not 100 % +correct. One can update the number of rows by executing @code{ANALYZE +TABLE} or @code{OPTIMIZE TABLE}. @xref{ANALYZE TABLE} . @xref{OPTIMIZE +TABLE}. +@item +If you get full disk with a @code{BDB} table, you will get an error +(probably error 28) and the transaction should roll back. This is in +contrast with @code{MyISAM} and @code{ISAM} tables where @code{mysqld} will +wait for enough free disk before continuing. +@end itemize + + +@node BDB TODO, BDB portability, BDB characteristic, BDB +@subsection Some things we need to fix for BDB in the near future: + +@itemize @bullet +@item +It's very slow to open many BDB tables at the same time. If you are +going to use BDB tables, you should not have a very big table cache (> +256 ?) and you should use @code{--no-auto-rehash} with the @code{mysql} +client. We plan to partly fix this in 4.0. +@item +@code{SHOW TABLE STATUS} doesn't yet provide that much information for BDB +tables. +@item +Optimize performance. +@item +Change to not use page locks at all when we are scanning tables. +@end itemize + + +@node BDB portability, BDB errors, BDB TODO, BDB +@subsection Operating systems supported by @strong{BDB} + +If you after having built @strong{MySQL} with support for BDB tables get +the following error in the log file when you start @code{mysqld}: + +@example +bdb: architecture lacks fast mutexes: applications cannot be threaded +Can't init dtabases +@end example + +This means that @code{BDB} tables are not supported for your architecture. +In this case you have to rebuild @strong{MySQL} without BDB table support. + +NOTE: The following list is not complete; We will update this as we get +more information about this. + +Currently we know that BDB tables works with the following operating +system. + +@itemize @bullet +@item +Linux 2.x intel +@item +Solaris sparc +@item +SCO OpenServer +@item +SCO UnixWare 7.0.1 +@end itemize + +It doesn't work with the following operating systems: + +@itemize @bullet +@item +Linux 2.x Alpha +@item +Max OS X +@end itemize + + +@node BDB errors, , BDB portability, BDB +@subsection Errors You May Get When Using BDB Tables + +@itemize @bullet +@item +If you get the following error in the @code{hostname.err log} when +starting @code{mysqld}: + +@example +bdb: Ignoring log file: .../log.XXXXXXXXXX: unsupported log version # +@end example +it means that the new @code{BDB} version doesn't support the old log +file format. In this case you have to delete all @code{BDB} log BDB +from your database directory (the files that has the format +@code{log.XXXXXXXXXX} ) and restart @code{mysqld}. We would also +recommend you to do a @code{mysqldump --opt} of your old @code{BDB} +tables, delete the old table and restore the dump. +@item +If you are running in not @code{auto_commit} mode and delete a table you +are using by another thread you may get the following error messages in +the @strong{MySQL} error file: + +@example +001119 23:43:56 bdb: Missing log fileid entry +001119 23:43:56 bdb: txn_abort: Log undo failed for LSN: 1 3644744: Invalid +@end example + +This is not fatal but we don't recommend that you delete tables if you are +not in @code{auto_commit} mode, until this problem is fixed (the fix is +not trivial). +@end itemize + + +@node InnoDB, , BDB, Table types @section InnoDB Tables @menu @@ -35472,6 +35907,7 @@ SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2) * InnoDB contact information:: InnoDB contact information. @end menu + @node InnoDB overview, InnoDB start, InnoDB, InnoDB @subsection InnoDB tables overview @@ -35518,6 +35954,7 @@ may consist of several files. This is different from, for example, InnoDB is distributed under the GNU GPL License Version 2 (of June 1991). In the source distribution of @strong{MySQL}, InnoDB appears as a subdirectory. + @node InnoDB start, InnoDB init, InnoDB overview, InnoDB @subsection InnoDB startup options @@ -35671,6 +36108,7 @@ performance it is wisest not to specify this parameter at all, in which case it will get the default value. @end multitable + @node InnoDB init, Using InnoDB tables, InnoDB start, InnoDB @subsection Creating InnoDB table space @@ -35736,6 +36174,7 @@ mysqld: ready for connections * Error creating InnoDB:: @end menu + @node Error creating InnoDB, , InnoDB init, InnoDB init @subsubsection If something goes wrong in database creation @@ -35746,6 +36185,7 @@ create some InnoDB tables, delete also the corresponding @file{.frm} files for these tables from the @strong{MySQL} database directories. Then you can try the InnoDB database creation again. + @node Using InnoDB tables, Adding and removing, InnoDB init, InnoDB @subsection Creating InnoDB tables @@ -35829,6 +36269,7 @@ it is better that you kill the database process and delete all InnoDB data and log files and all InnoDB table @file{.frm} files, and start your job again, rather than wait for millions of disk i/os to complete. + @node Adding and removing, Backing up, Using InnoDB tables, InnoDB @subsection Adding and removing InnoDB data and log files @@ -35851,6 +36292,7 @@ database. Delete then the old log files from the log file directory, edit @file{my.cnf}, and start @strong{MySQL} again. InnoDB will tell you at the startup that it is creating new log files. + @node Backing up, Moving, Adding and removing, InnoDB @subsection Backing up and recovering an InnoDB database @@ -35937,6 +36379,7 @@ MySQL manual. * InnoDB checkpoints:: @end menu + @node InnoDB checkpoints, , Backing up, Backing up @subsubsection Checkpoints @@ -35968,6 +36411,7 @@ the total size of the log files as big as the buffer pool or even bigger. The drawback in big log files is that crash recovery can last longer because there will be more log to apply to the database. + @node Moving, InnoDB transaction model, Backing up, InnoDB @subsection Moving an InnoDB database to another machine @@ -35988,6 +36432,7 @@ the big rollback segment the big import transaction will generate. Do the commit only after importing a whole table or a segment of a table. + @node InnoDB transaction model, Implementation, Moving, InnoDB @subsection InnoDB transaction model @@ -36022,6 +36467,7 @@ transaction. * InnoDB Deadlock detection:: @end menu + @node InnoDB consistent read, InnoDB locking reads, InnoDB transaction model, InnoDB transaction model @subsubsection Consistent read @@ -36047,6 +36493,7 @@ on the tables it accesses, and therefore other users are free to modify those tables at the same time a consistent read is being performed on the table. + @node InnoDB locking reads, InnoDB Next-key locking, InnoDB consistent read, InnoDB transaction model @subsubsection Locking reads @@ -36104,6 +36551,7 @@ available data setting exclusive locks on each row it reads. Thus it sets the same locks a searched SQL @code{UPDATE} would set on the rows. + @node InnoDB Next-key locking, InnoDB Locks set, InnoDB locking reads, InnoDB transaction model @subsubsection Next-key locking: avoiding the phantom problem @@ -36158,6 +36606,7 @@ anyone meanwhile inserting a duplicate for your row. Thus the next-key locking allows you to 'lock' the non-existence of something in your table. + @node InnoDB Locks set, InnoDB Deadlock detection, InnoDB Next-key locking, InnoDB transaction model @subsubsection Locks set by different SQL statements in InnoDB @@ -36210,6 +36659,7 @@ get a table lock on a table where another user currently has row level locks. But that does not put transaction integerity into danger. @end itemize + @node InnoDB Deadlock detection, , InnoDB Locks set, InnoDB transaction model @subsubsection Deadlock detection and rollback @@ -36326,6 +36776,7 @@ INSERT INTO yourtable VALUES (1, 2), (5, 5); This tip is of course valid for inserts into any table type, not just InnoDB. + @node Implementation, Table and index, InnoDB transaction model, InnoDB @subsection Implementation of multiversioning @@ -36375,6 +36826,7 @@ its index records from the database. This removal operation is called a purge, and it is quite fast, usually taking the same order of time as the SQL statement which did the deletion. + @node Table and index, File space management, Implementation, InnoDB @subsection Table and index structures @@ -36410,6 +36862,7 @@ will use more space. * InnoDB Physical record:: @end menu + @node InnoDB physical structure, InnoDB Insert buffering, Table and index, Table and index @subsubsection Physical structure of an index @@ -36425,6 +36878,7 @@ If records are inserted in a random order, then the pages will be 1/2 - 15/16 full. If the fillfactor of an index page drops below 1/2, InnoDB will try to contract the index tree to free the page. + @node InnoDB Insert buffering, InnoDB Adaptive hash, InnoDB physical structure, Table and index @subsubsection Insert buffering @@ -36452,6 +36906,7 @@ same page in of the index tree, and hence save disk i/o's. It has been measured that the insert buffer can speed up insertions to a table up to 15 times. + @node InnoDB Adaptive hash, InnoDB Physical record, InnoDB Insert buffering, Table and index @subsubsection Adaptive hash indexes @@ -36475,6 +36930,7 @@ In a sense, through the adaptive hash index mechanism InnoDB adapts itself to ample main memory, coming closer to the architecture of main memory databases. + @node InnoDB Physical record, , InnoDB Adaptive hash, Table and index @subsubsection Physical record structure @@ -36532,6 +36988,7 @@ The behavior of auto-increment is not defined if a user gives a negative value to the column or if the value becomes bigger than the maximum integer that can be stored in the specified integer type. + @node File space management, Error handling, Table and index, InnoDB @subsection File space management and disk i/o @@ -36541,6 +36998,7 @@ integer that can be stored in the specified integer type. * InnoDB File Defragmenting:: @end menu + @node InnoDB Disk i/o, InnoDB File space, File space management, File space management @subsubsection Disk i/o @@ -36572,6 +37030,7 @@ in a tablespace seems to be in the process of being fully read into the buffer pool. Then InnoDB posts the remaining reads to the i/o system. + @node InnoDB File space, InnoDB File Defragmenting, InnoDB Disk i/o, File space management @subsubsection File space management @@ -36619,6 +37078,7 @@ but remember that deleted rows can be physically removed only in a purge operation after they are no longer needed in transaction rollback or consistent read. + @node InnoDB File Defragmenting, , InnoDB File space, File space management @subsubsection Defragmenting a table @@ -36642,6 +37102,7 @@ records are deleted only from the end, then the the file space management algorithm of InnoDB guarantees that fragmentation in the index will not occur. + @node Error handling, InnoDB restrictions, File space management, InnoDB @subsection Error handling @@ -36674,6 +37135,7 @@ Other errors are mostly detected by the @strong{MySQL} layer of code, and they roll back the corresponding SQL statement. @end itemize + @node InnoDB restrictions, InnoDB contact information, Error handling, InnoDB @subsection Some restrictions on InnoDB tables @@ -36734,6 +37196,7 @@ The maximum tablespace size is 4 billion database pages. This is also the maximum size for a table. The minimum tablespace size is 10 MB. @end itemize + @node InnoDB contact information, , InnoDB restrictions, InnoDB @subsection InnoDB contact information @@ -36751,449 +37214,27 @@ P.O.Box 800 Finland @end example -@cindex tables, @code{BDB} -@cindex tables, @code{Berkeley DB} -@node BDB, , InnoDB, Table types -@section BDB or Berkeley_DB Tables + + + +@node Extending MySQL, ODBC, Table types, Top +@chapter Extending MySQL @menu -* BDB overview:: Overview of BDB Tables -* BDB install:: Installing BDB -* BDB start:: BDB startup options -* BDB characteristic:: Some characteristic of @code{BDB} tables: -* BDB TODO:: Some things we need to fix for BDB in the near future: -* BDB portability:: Operating systems supported by @strong{BDB} -* BDB errors:: Errors You May Get When Using BDB Tables +* Adding functions:: +* Adding procedures:: +* MySQL internals:: @end menu -@node BDB overview, BDB install, BDB, BDB -@subsection Overview of BDB Tables - -Support for BDB tables is included in the @strong{MySQL} source distribution -starting from Version 3.23.34 and is activated in the @strong{MySQL}-Max -binary. - -BerkeleyDB, available at @uref{http://www.sleepycat.com/} has provided -@strong{MySQL} with a transactional table handler. By using BerkeleyDB -tables, your tables may have a greater chance of surviving crashes, and also -provides @code{COMMIT} and @code{ROLLBACK} on transactions. The -@strong{MySQL} source distribution comes with a BDB distribution that has a -couple of small patches to make it work more smoothly with @strong{MySQL}. -You can't use a non-patched @code{BDB} version with @strong{MySQL}. - -We at @strong{MySQL AB} are working in close cooperation with Sleepycat to -keep the quality of the @strong{MySQL}/BDB interface high. - -When it comes to supporting BDB tables, we are committed to help our -users to locate the problem and help creating a reproducable test case -for any problems involving BDB tables. Any such test case will be -forwarded to Sleepycat who in turn will help us find and fix the -problem. As this is a two stage operation, any problems with BDB tables -may take a little longer for us to fix than for other table handlers. -However, as the BerkeleyDB code itself has been used by many other -applications than @strong{MySQL}, we don't envision any big problems with -this. @xref{Table handler support}. - -@node BDB install, BDB start, BDB overview, BDB -@subsection Installing BDB - -If you have downloaded a binary version of @strong{MySQL} that includes -support for BerkeleyDB, simply follow the instructions for installing a -binary version of @strong{MySQL}. -@xref{Installing binary}. @xref{mysqld-max, , @code{mysqld-max}}. - -To compile @strong{MySQL} with Berkeley DB support, download @strong{MySQL} -Version 3.23.34 or newer and configure @code{MySQL} with the -@code{--with-berkeley-db} option. @xref{Installing source}. - -@example -cd /path/to/source/of/mysql-3.23.34 -./configure --with-berkeley-db -@end example - -Please refer to the manual provided with the @code{BDB} distribution for -more updated information. - -Even though Berkeley DB is in itself very tested and reliable, -the @strong{MySQL} interface is still considered beta quality. -We are actively improving and optimizing it to get it stable very -soon. - -@node BDB start, BDB characteristic, BDB install, BDB -@subsection BDB startup options - -If you are running with @code{AUTOCOMMIT=0} then your changes in @code{BDB} -tables will not be updated until you execute @code{COMMIT}. Instead of commit -you can execute @code{ROLLBACK} to forget your changes. @xref{COMMIT}. - -If you are running with @code{AUTOCOMMIT=1} (the default), your changes -will be committed immediately. You can start an extended transaction with -the @code{BEGIN WORK} SQL command, after which your changes will not be -committed until you execute @code{COMMIT} (or decide to @code{ROLLBACK} -the changes). - -The following options to @code{mysqld} can be used to change the behavior of -BDB tables: - -@multitable @columnfractions .30 .70 -@item @strong{Option} @tab @strong{Meaning} -@item @code{--bdb-home=directory} @tab Base directory for BDB tables. This should be the same directory you use for --datadir. -@item @code{--bdb-lock-detect=#} @tab Berkeley lock detect. One of (DEFAULT, OLDEST, RANDOM, or YOUNGEST). -@item @code{--bdb-logdir=directory} @tab Berkeley DB log file directory. -@item @code{--bdb-no-sync} @tab Don't synchronously flush logs. -@item @code{--bdb-no-recover} @tab Don't start Berkeley DB in recover mode. -@item @code{--bdb-shared-data} @tab Start Berkeley DB in multi-process mode (Don't use @code{DB_PRIVATE} when initializing Berkeley DB) -@item @code{--bdb-tmpdir=directory} @tab Berkeley DB tempfile name. -@item @code{--skip-bdb} @tab Don't use berkeley db. -@item @code{-O bdb_max_lock=1000} @tab Set the maximum number of locks possible. @xref{SHOW VARIABLES}. -@end multitable - -If you use @code{--skip-bdb}, @strong{MySQL} will not initialize the -Berkeley DB library and this will save a lot of memory. Of course, -you cannot use @code{BDB} tables if you are using this option. - -Normally you should start @code{mysqld} without @code{--bdb-no-recover} if you -intend to use BDB tables. This may, however, give you problems when you -try to start @code{mysqld} if the BDB log files are corrupted. @xref{Starting -server}. - -With @code{bdb_max_lock} you can specify the maximum number of locks -(10000 by default) you can have active on a BDB table. You should -increase this if you get errors of type @code{bdb: Lock table is out of -available locks} or @code{Got error 12 from ...} when you have do long -transactions or when @code{mysqld} has to examine a lot of rows to -calculate the query. - -You may also want to change @code{binlog_cache_size} and -@code{max_binlog_cache_size} if you are using big multi-line transactions. -@xref{COMMIT}. - -@node BDB characteristic, BDB TODO, BDB start, BDB -@subsection Some characteristic of @code{BDB} tables: - -@itemize @bullet -@item -To be able to rollback transactions BDB maintain log files. For maximum -performance you should place these on another disk than your databases -by using the @code{--bdb_log_dir} options. -@item -@strong{MySQL} performs a checkpoint each time a new BDB log -file is started, and removes any log files that are not needed for -current transactions. One can also run @code{FLUSH LOGS} at any time -to checkpoint the Berkeley DB tables. - -For disaster recovery, one should use table backups plus -@strong{MySQL}'s binary log. @xref{Backup}. - -@strong{Warning}: If you delete old log files that are in use, BDB will -not be able to do recovery at all and you may lose data if something -goes wrong. -@item -@strong{MySQL} requires a @code{PRIMARY KEY} in each BDB table to be -able to refer to previously read rows. If you don't create one, -@strong{MySQL} will create an maintain a hidden @code{PRIMARY KEY} for -you. The hidden key has a length of 5 bytes and is incremented for each -insert attempt. -@item -If all columns you access in a @code{BDB} table are part of the same index or -part of the primary key, then @strong{MySQL} can execute the query -without having to access the actual row. In a @code{MyISAM} table the -above holds only if the columns are part of the same index. -@item -The @code{PRIMARY KEY} will be faster than any other key, as the -@code{PRIMARY KEY} is stored together with the row data. As the other keys are -stored as the key data + the @code{PRIMARY KEY}, it's important to keep the -@code{PRIMARY KEY} as short as possible to save disk and get better speed. -@item -@code{LOCK TABLES} works on @code{BDB} tables as with other tables. If -you don't use @code{LOCK TABLE}, @strong{MYSQL} will issue an internal -multiple-write lock on the table to ensure that the table will be -properly locked if another thread issues a table lock. -@item -Internal locking in @code{BDB} tables is done on page level. -@item -@code{SELECT COUNT(*) FROM table_name} is slow as @code{BDB} tables doesn't -maintain a count of the number of rows in the table. -@item -Scanning is slower than with @code{MyISAM} tables as one has data in BDB -tables stored in B-trees and not in a separate data file. -@item -The application must always be prepared to handle cases where -any change of a @code{BDB} table may make an automatic rollback and any -read may fail with a deadlock error. -@item -Keys are not compressed to previous keys as with ISAM or MyISAM -tables. In other words, the key information will take a little more -space in @code{BDB} tables compared to MyISAM tables which don't use -@code{PACK_KEYS=0}. -@item -There is often holes in the BDB table to allow you to insert new rows in -the middle of the key tree. This makes BDB tables somewhat larger than -MyISAM tables. -@item -The optimizer needs to know an approximation of the number of rows in -the table. @strong{MySQL} solves this by counting inserts and -maintaining this in a separate segment in each BDB table. If you don't -do a lot of @code{DELETE} or @code{ROLLBACK}:s this number should be -accurate enough for the @strong{MySQL} optimizer, but as @strong{MySQL} -only store the number on close, it may be wrong if @strong{MySQL} dies -unexpectedly. It should not be fatal even if this number is not 100 % -correct. One can update the number of rows by executing @code{ANALYZE -TABLE} or @code{OPTIMIZE TABLE}. @xref{ANALYZE TABLE} . @xref{OPTIMIZE -TABLE}. -@item -If you get full disk with a @code{BDB} table, you will get an error -(probably error 28) and the transaction should roll back. This is in -contrast with @code{MyISAM} and @code{ISAM} tables where @code{mysqld} will -wait for enough free disk before continuing. -@end itemize - -@node BDB TODO, BDB portability, BDB characteristic, BDB -@subsection Some things we need to fix for BDB in the near future: - -@itemize @bullet -@item -It's very slow to open many BDB tables at the same time. If you are -going to use BDB tables, you should not have a very big table cache (> -256 ?) and you should use @code{--no-auto-rehash} with the @code{mysql} -client. We plan to partly fix this in 4.0. -@item -@code{SHOW TABLE STATUS} doesn't yet provide that much information for BDB -tables. -@item -Optimize performance. -@item -Change to not use page locks at all when we are scanning tables. -@end itemize - -@node BDB portability, BDB errors, BDB TODO, BDB -@subsection Operating systems supported by @strong{BDB} - -If you after having built @strong{MySQL} with support for BDB tables get -the following error in the log file when you start @code{mysqld}: - -@example -bdb: architecture lacks fast mutexes: applications cannot be threaded -Can't init dtabases -@end example - -This means that @code{BDB} tables are not supported for your architecture. -In this case you have to rebuild @strong{MySQL} without BDB table support. - -NOTE: The following list is not complete; We will update this as we get -more information about this. - -Currently we know that BDB tables works with the following operating -system. - -@itemize @bullet -@item -Linux 2.x intel -@item -Solaris sparc -@item -SCO OpenServer -@item -SCO UnixWare 7.0.1 -@end itemize - -It doesn't work with the following operating systems: - -@itemize @bullet -@item -Linux 2.x Alpha -@item -Max OS X -@end itemize - -@node BDB errors, , BDB portability, BDB -@subsection Errors You May Get When Using BDB Tables - -@itemize @bullet -@item -If you get the following error in the @code{hostname.err log} when -starting @code{mysqld}: - -@example -bdb: Ignoring log file: .../log.XXXXXXXXXX: unsupported log version # -@end example -it means that the new @code{BDB} version doesn't support the old log -file format. In this case you have to delete all @code{BDB} log BDB -from your database directory (the files that has the format -@code{log.XXXXXXXXXX} ) and restart @code{mysqld}. We would also -recommend you to do a @code{mysqldump --opt} of your old @code{BDB} -tables, delete the old table and restore the dump. -@item -If you are running in not @code{auto_commit} mode and delete a table you -are using by another thread you may get the following error messages in -the @strong{MySQL} error file: - -@example -001119 23:43:56 bdb: Missing log fileid entry -001119 23:43:56 bdb: txn_abort: Log undo failed for LSN: 1 3644744: Invalid -@end example - -This is not fatal but we don't recommend that you delete tables if you are -not in @code{auto_commit} mode, until this problem is fixed (the fix is -not trivial). -@end itemize - - - - -@node Maintenance, Adding functions, Table types, Top -@chapter Maintaining a MySQL Installation - -@cindex installation maintenance -@cindex maintaining, tables -@cindex tables, maintaining -@cindex databases, maintaining -@cindex @code{myisamchk} -@cindex @code{mysqlcheck} -@cindex crash, recovery -@cindex recovery, from crash - - -@menu -* Using mysqlcheck:: Using mysqlcheck for maintenance and recovery -@end menu - -This chapter covers what you should know about maintaining a @strong{MySQL} -distribution. You will learn how to care for your tables on a regular -basis, and what to do when disaster strikes. - -@node Using mysqlcheck, , Maintenance, Maintenance -@section Using @code{mysqlcheck} for Table Maintenance and Crash Recovery - -Since @strong{MySQL} version 3.23.38 you will be able to use a new -checking and repairing tool for @code{MyISAM} tables. The difference to -@code{myisamchk} is that @code{mysqlcheck} should be used when the -@code{mysqld} server is running, where as @code{myisamchk} should be used -when it is not. The benefit is that you no longer have to take the -server down for checking or repairing your tables. - -@code{mysqlcheck} uses @strong{MySQL} server commands @code{CHECK}, -@code{REPAIR}, @code{ANALYZE} and @code{OPTIMIZE} in a convenient way -for the user. - -There are three alternative ways to invoke @code{mysqlcheck}: - -@example -shell> mysqlcheck [OPTIONS] database [tables] -shell> mysqlcheck [OPTIONS] --databases DB1 [DB2 DB3...] -shell> mysqlcheck [OPTIONS] --all-databases -@end example - -So it can be used in a similar way as @code{mysqldump} when it -comes to what databases and tables you want to choose. - -@code{mysqlcheck} does have a special feature compared to the other -clients; the default behavior, checking tables (-c), can be changed by -renaming the binary. So if you want to have a tool that repairs tables -by default, you should just copy @code{mysqlcheck} to your harddrive -with a new name, @code{mysqlrepair}, or alternatively make a symbolic -link to @code{mysqlrepair} and name the symbolic link as -@code{mysqlrepair}. If you invoke @code{mysqlrepair} now, it will repair -tables by default. - -The names that you can use to change @code{mysqlcheck} default behavior -are here: - -@example -mysqlrepair: The default option will be -r -mysqlanalyze: The default option will be -a -mysqloptimize: The default option will be -o -@end example - -The options available for @code{mysqlcheck} are listed here, please -check what your version supports with @code{mysqlcheck --help}. - -@table @code -@item -A, --all-databases -Check all the databases. This will be same as --databases with all -databases selected -@item -1, --all-in-1 -Instead of making one query for each table, execute all queries in 1 -query separately for each database. Table names will be in a comma -separated list. -@item -a, --analyze -Analyze given tables. -@item --auto-repair -If a checked table is corrupted, automatically fix it. Repairing will be -done after all tables have been checked, if corrupted ones were found. -@item -#, --debug=... -Output debug log. Often this is 'd:t:o,filename' -@item --character-sets-dir=... -Directory where character sets are -@item -c, --check -Check table for errors -@item -C, --check-only-changed -Check only tables that have changed since last check or haven't been -closed properly. -@item --compress -Use compression in server/client protocol. -@item -?, --help -Display this help message and exit. -@item -B, --databases -To check several databases. Note the difference in usage; In this case -no tables are given. All name arguments are regarded as database names. -@item --default-character-set=... -Set the default character set -@item -F, --fast -Check only tables that hasn't been closed properly -@item -f, --force -Continue even if we get an sql-error. -@item -e, --extended -If you are using this option with CHECK TABLE, it will ensure that the -table is 100 percent consistent, but will take a long time. - -If you are using this option with REPAIR TABLE, it will run an extended -repair on the table, which may not only take a long time to execute, but -may produce a lot of garbage rows also! -@item -h, --host=... -Connect to host. -@item -m, --medium-check -Faster than extended-check, but only finds 99.99 percent of all -errors. Should be good enough for most cases. -@item -o, --optimize -Optimize table -@item -p, --password[=...] -Password to use when connecting to server. If password is not given -it's solicited on the tty. -@item -P, --port=... -Port number to use for connection. -@item -q, --quick -If you are using this option with CHECK TABLE, it prevents the check -from scanning the rows to check for wrong links. This is the fastest -check. - -If you are using this option with REPAIR TABLE, it will try to repair -only the index tree. This is the fastest repair method for a table. -@item -r, --repair -Can fix almost anything except unique keys that aren't unique. -@item -s, --silent -Print only error messages. -@item -S, --socket=... -Socket file to use for connection. -@item --tables -Overrides option --databases (-B). -@item -u, --user=# -User for login if not current user. -@item -v, --verbose -Print info about the various stages. -@item -V, --version -Output version information and exit. -@end table - +@node Adding functions, Adding procedures, Extending MySQL, Extending MySQL +@section Adding New Functions to MySQL @cindex functions, new @cindex adding, new functions @cindex user-defined functions, adding @cindex UDFs, defined @cindex functions, user-defined -@node Adding functions, Adding procedures, Maintenance, Top -@chapter Adding New Functions to MySQL There are two ways to add new functions to @strong{MySQL}: @@ -37228,15 +37269,60 @@ Whichever method you use to add new functions, they may be used just like native functions such as @code{ABS()} or @code{SOUNDEX()}. @menu +* CREATE FUNCTION:: * Adding UDF:: Adding a new user-definable function * Adding native function:: Adding a new native function @end menu + +@node CREATE FUNCTION, Adding UDF, Adding functions, Adding functions +@subsection @code{CREATE FUNCTION/DROP FUNCTION} Syntax + +@findex CREATE FUNCTION +@findex DROP FUNCTION +@findex UDF functions +@findex User-defined functions +@findex Functions, user-defined + +@example +CREATE [AGGREGATE] FUNCTION function_name RETURNS @{STRING|REAL|INTEGER@} + SONAME shared_library_name + +DROP FUNCTION function_name +@end example + +A user-definable function (UDF) is a way to extend @strong{MySQL} with a new +function that works like native (built in) @strong{MySQL} functions such as +@code{ABS()} and @code{CONCAT()}. + +@code{AGGREGATE} is a new option for @strong{MySQL} Version 3.23. An +@code{AGGREGATE} function works exactly like a native @strong{MySQL} +@code{GROUP} function like @code{SUM} or @code{COUNT()}. + +@code{CREATE FUNCTION} saves the function's name, type, and shared library +name in the @code{mysql.func} system table. You must have the +@strong{insert} and @strong{delete} privileges for the @code{mysql} database +to create and drop functions. + +All active functions are reloaded each time the server starts, unless +you start @code{mysqld} with the @code{--skip-grant-tables} option. In +this case, UDF initialization is skipped and UDFs are unavailable. +(An active function is one that has been loaded with @code{CREATE FUNCTION} +and not removed with @code{DROP FUNCTION}.) + +For instructions on writing user-definable functions, see @ref{Adding +functions}. For the UDF mechanism to work, functions must be written in C or +C++, your operating system must support dynamic loading and you must have +compiled @code{mysqld} dynamically (not statically). + + + +@node Adding UDF, Adding native function, CREATE FUNCTION, Adding functions +@subsection Adding a New User-definable Function + @cindex adding, user-definable functions @cindex user-defined functions, adding @cindex functions, user-definable, adding -@node Adding UDF, Adding native function, Adding functions, Adding functions -@section Adding a New User-definable Function @menu * UDF calling sequences:: UDF calling sequences @@ -37245,6 +37331,7 @@ native functions such as @code{ABS()} or @code{SOUNDEX()}. * UDF compiling:: Compiling and installing user-definable functions @end menu + For the UDF mechanism to work, functions must be written in C or C++ and your operating system must support dynamic loading. The @strong{MySQL} source distribution includes a file @file{sql/udf_example.cc} that defines 5 new @@ -37322,9 +37409,11 @@ that you are not allowed to allocate any global or static variables that change! If you need memory, you should allocate it in @code{xxx_init()} and free it in @code{xxx_deinit()}. -@cindex calling sequences, UDF + @node UDF calling sequences, UDF arguments, Adding UDF, Adding UDF -@subsection UDF Calling Sequences +@subsubsection UDF Calling Sequences + +@cindex calling sequences, UDF The main function should be declared as shown below. Note that the return type and parameters differ, depending on whether you will declare the SQL @@ -37404,10 +37493,12 @@ In @code{xxx()} and @code{xxx_deinit()}, refer to @code{initid->ptr} to use or deallocate the memory. @end table + +@node UDF arguments, UDF return values, UDF calling sequences, Adding UDF +@subsubsection Argument Processing + @cindex argument processing @cindex processing, arguments -@node UDF arguments, UDF return values, UDF calling sequences, Adding UDF -@subsection Argument Processing The @code{args} parameter points to a @code{UDF_ARGS} structure that thas the members listed below: @@ -37508,12 +37599,14 @@ types @code{INT_RESULT} or @code{REAL_RESULT}, @code{lengths} still contains the maximum length of the argument (as for the initialization function). @end table + +@node UDF return values, UDF compiling, UDF arguments, Adding UDF +@subsubsection Return Values and Error Handling + @cindex UDFs, return values @cindex return values, UDFs @cindex errors, handling for UDFs @cindex handling, errors -@node UDF return values, UDF compiling, UDF arguments, Adding UDF -@subsection Return Values and Error Handling The initialization function should return @code{0} if no error occurred and @code{1} otherwise. If an error occurs, @code{xxx_init()} should store a @@ -37567,11 +37660,13 @@ and @code{*is_null}: *is_null = 1; @end example + +@node UDF compiling, , UDF return values, Adding UDF +@subsubsection Compiling and Installing User-definable Functions + @cindex compiling, user-defined functions @cindex UDFs, compiling @cindex installing, user-defined functions -@node UDF compiling, , UDF return values, Adding UDF -@subsection Compiling and Installing User-definable Functions Files implementing UDFs must be compiled and installed on the host where the server runs. This process is described below for the example UDF file @@ -37669,11 +37764,13 @@ initialization is skipped and UDFs are unavailable. (An active function is one that has been loaded with @code{CREATE FUNCTION} and not removed with @code{DROP FUNCTION}.) + +@node Adding native function, , Adding UDF, Adding functions +@subsection Adding a New Native Function + @cindex adding, native functions @cindex native functions, adding @cindex functions, native, adding -@node Adding native function, , Adding UDF, Adding functions -@section Adding a New Native Function The procedure for adding a new native function is described below. Note that you cannot add native functions to a binary distribution because @@ -37760,11 +37857,13 @@ All current string functions try to avoid allocating any memory unless absolutely necessary! @end itemize + +@node Adding procedures, MySQL internals, Adding functions, Extending MySQL +@section Adding New Procedures to MySQL + @cindex procedures, adding @cindex adding, procedures @cindex new procedures, adding -@node Adding procedures, ODBC, Adding functions, Top -@chapter Adding New Procedures to MySQL In @strong{MySQL}, you can define a procedure in C++ that can access and modify the data in a query before it is sent to the client. The modification @@ -37781,8 +37880,9 @@ language to load a procedure at runtime into @code{mysqld}. * Writing a procedure:: Writing a procedure. @end menu + @node procedure analyse, Writing a procedure, Adding procedures, Adding procedures -@section Procedure Analyse +@subsection Procedure Analyse @code{analyse([max elements,[max memory]])} @@ -37804,8 +37904,9 @@ allocate per column while trying to find all distinct values. SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]]) @end example + @node Writing a procedure, , procedure analyse, Adding procedures -@section Writing a Procedure +@subsection Writing a Procedure For the moment, the only documentation for this is the source. @@ -37818,11 +37919,298 @@ You can find all information about procedures by examining the following files: @item @file{sql/sql_select.cc} @end itemize + +@node MySQL internals, , Adding procedures, Extending MySQL +@section MySQL Internals + +@cindex internals +@cindex threads + +This chapter describes a lot of things that you need to know when +working on the @strong{MySQL} code. If you plan to contribute to MySQL +development, want to have access to the bleeding-edge in-between +versions code, or just want to keep track of development, follow the +instructions in @xref{Installing source tree}. If you are interested in MySQL +internals, you should also subscribe to @email{internals@@lists.mysql.com}. +This is a relatively low traffic list, in comparison with +@email{mysql@@lists.mysql.com}. + +@menu +* MySQL threads:: MySQL threads +* MySQL test suite:: MySQL test suite +@end menu + + +@node MySQL threads, MySQL test suite, MySQL internals, MySQL internals +@subsection MySQL Threads + +The @strong{MySQL} server creates the following threads: + +@itemize @bullet + +@item +The TCP/IP connection thread handles all connection requests and +creates a new dedicated thread to handle the authentication and +and SQL query processing for each connection. + +@item +On Windows NT there is a named pipe handler thread that does the same work as +the TCP/IP connection thread on named pipe connect requests. + +@item +The signal thread handles all signals. This thread also normally handles +alarms and calls @code{process_alarm()} to force timeouts on connections +that have been idle too long. + +@item +If @code{mysqld} is compiled with @code{-DUSE_ALARM_THREAD}, a dedicated +thread that handles alarms is created. This is only used on some systems where +there are problems with @code{sigwait()} or if one wants to use the +@code{thr_alarm()} code in ones application without a dedicated signal +handling thread. + +@item +If one uses the @code{--flush_time=#} option, a dedicated thread is created +to flush all tables at the given interval. + +@item +Every connection has its own thread. + +@item +Every different table on which one uses @code{INSERT DELAYED} gets its +own thread. + +@item +If you use @code{--master-host}, a slave replication thread will be +started to read and apply updates from the master. +@end itemize + +@code{mysqladmin processlist} only shows the connection, @code{INSERT DELAYED}, +and replication threads. + + +@node MySQL test suite, , MySQL threads, MySQL internals +@subsection MySQL Test Suite + +@cindex mysqltest, MySQL Test Suite +@cindex testing mysqld, mysqltest + +Until recently, our main full-coverage test suite was based on proprietary +customer data and for that reason has not been publicly available. The only +publicly available part of our testing process consisted of the @code{crash-me} +test, a Perl DBI/DBD benchmark found in the @code{sql-bench} directory, and +miscellaneous tests located in @code{tests} directory. The lack of a +standardized publicly available test suite has made it difficult for our users, +as well developers, to do regression tests on the @strong{MySQL} code. To +address this problem, we have created a new test system that is included in +the source and binary distributions starting in Version 3.23.29. + +The current set of test cases doesn't test everything in @strong{MySQL}, but it +should catch most obvious bugs in the SQL processing code, OS/library +issues, and is quite thorough in testing replication. Our eventual goal +is to have the tests cover 100% of the code. We welcome contributions +to our test suite. You may especially want to contribute tests that +examine the functionality critical to your system, as this will ensure +that all future @strong{MySQL} releases will work well with your +applications. + +@menu +* running mysqltest:: +* extending mysqltest:: +* Reporting mysqltest bugs:: +@end menu + + +@node running mysqltest, extending mysqltest, MySQL test suite, MySQL test suite +@subsubsection Running the MySQL Test Suite + +The test system consist of a test language interpreter +(@code{mysqltest}), a shell script to run all +tests(@code{mysql-test-run}), the actual test cases written in a special +test language, and their expected results. To run the test suite on +your system after a build, type @code{make test} or +@code{mysql-test/mysql-test-run} from the source root. If you have +installed a binary distribution, @code{cd} to the install root +(eg. @code{/usr/local/mysql}), and do @code{scripts/mysql-test-run}. +All tests should succeed. If not, you should try to find out why and +report the problem if this is a bug in @strong{MySQL}. +@xref{Reporting mysqltest bugs}. + +If you have a copy of @code{mysqld} running on the machine where you want to +run the test suite you do not have to stop it, as long as it is not using +ports @code{9306} and @code{9307}. If one of those ports is taken, you should +edit @code{mysql-test-run} and change the values of the master and/or slave +port to one that is available. + +You can run one individual test case with +@code{mysql-test/mysql-test-run test_name}. + +If one test fails, you should test running @code{mysql-test-run} with +the @code{--force} option to check if any other tests fails. + + +@node extending mysqltest, Reporting mysqltest bugs, running mysqltest, MySQL test suite +@subsubsection Extending the MySQL Test Suite + +You can use the @code{mysqltest} language to write your own test cases. +Unfortunately, we have not yet written full documentation for it - we plan to +do this shortly. You can, however, look at our current test cases and use +them as an example. The following points should help you get started: + +@itemize +@item +The tests are located in @code{mysql-test/t/*.test} + +@item +A test case consists of @code{;} terminated statements and is similar to the +input of @code{mysql} command line client. A statement by default is a query +to be sent to @strong{MySQL} server, unless it is recognized as internal +command ( eg. @code{sleep} ). + +@item +All queries that produce results, e.g. @code{SELECT}, @code{SHOW}, +@code{EXPLAIN}, etc., must be preceded with @code{@@/path/to/result/file}. The +file must contain the expected results. An easy way to generate the result +file is to run @code{mysqltest -r < t/test-case-name.test} from +@code{mysql-test} directory, and then edit the generated result files, if +needed, to adjust them to the expected output. In that case, be very careful +about not adding or deleting any invisible characters - make sure to only +change the text and/or delete lines. If you have to insert a line, make sure +the fields are separated with a hard tab, and there is a hard tab at the end. +You may want to use @code{od -c} to make sure your text editor has not messed +anything up during edit. We, of course, hope that you will never have to edit +the output of @code{mysqltest -r} as you only have to do it when you find a +bug. + +@item +To be consistent with our setup, you should put your result files in +@code{mysql-test/r} directory and name them @code{test_name.result}. If the +test produces more than one result, you should use @code{test_name.a.result}, +@code{test_name.b.result}, etc. + +@item +If a statement returns an error, you should on the line before the statement +specify with the @code{--error error-number}. The error number can be +a list of possible error numbers separated with @code{','}. + +@item +If you are writing a replication test case, you should on the first line of +the test file, put @code{source include/master-slave.inc;}. To switch between +master and slave, use @code{connection master;} and @code{connection slave;}. +If you need to do something on an alternate connection, you can do +@code{connection master1;} for the master, and @code{connection slave1;} for +the slave. + +@item +If you need to do something in a loop, you can use something like this: +@example +let $1=1000; +while ($1) +@{ + # do your queries here + dec $1; +@} +@end example + +@item +To sleep between queries, use the @code{sleep} command. It supports fractions +of a second, so you can do @code{sleep 1.3;}, for example, to sleep 1.3 +seconds. + +@item +To run the slave with additional options for your test case, put them +in the command-line format in @code{mysql-test/t/test_name-slave.opt}. For +the master, put them in @code{mysql-test/t/test_name-master.opt}. + +@item +If you have a question about the test suite, or have a test case to contribute, +e-mail to @email{internals@@lists.mysql.com}. As the list does not accept +attachments, you should ftp all the relevant files to: +@url{ftp://support.mysql.com/pub/mysql/Incoming} + +@end itemize + + +@node Reporting mysqltest bugs, , extending mysqltest, MySQL test suite +@subsubsection Reporting Bugs in the MySQL Test Suite + +If your @strong{MySQL} version doesn't pass the test suite you should +do the following: + +@itemize @bullet +@item +Don't send a bug report before you have found out as much as possible of +what when wrong! When you do it, please use the @code{mysqlbug} script +so that we can get information about your system and @code{MySQL} +version. @xref{Bug reports}. +@item +Make sure to include the output of @code{mysql-test-run}, as well as +contents of all @code{.reject} files in @code{mysql-test/r} directory. +@item +If a test in the test suite fails, check if the test fails also when run +by its own: + +@example +cd mysql-test +mysql-test-run --local test-name +@end example + +If this fails, then you should configure @strong{MySQL} with +@code{--with-debug} and run @code{mysql-test-run} with the +@code{--debug} option. If this also fails send the trace file +@file{var/tmp/master.trace} to ftp://support.mysql.com/pub/mysql/secret +so that we can examine it. Please remember to also include a full +description of your system, the version of the mysqld binary and how you +compiled it. + +@item +Try also to run @code{mysql-test-run} with the @code{--force} option to +see if there is any other test that fails. + +@item +If you have compiled @strong{MySQL} yourself, check our manual for how +to compile @strong{MySQL} on your platform or, preferable, use one of +the binaries we have compiled for you at +@uref{http://www.mysql.com/downloads/}. All our standard binaries should +pass the test suite ! + +@item +If you get an error, like @code{Result length mismatch} or @code{Result +content mismatch} it means that the output of the test didn't match +exactly the expected output. This could be a bug in @strong{MySQL} or +that your mysqld version produces slight different results under some +circumstances. + +Failed test results are put in a file with the same base name as the +result file with the @code{.reject} extension. If your test case is +failing, you should do a diff on the two files. If you cannot see how +they are different, examine both with @code{od -c} and also check their +lengths. + +@item +If a test fails totally, you should check the logs file in the +@code{mysql-test/var/log} directory for hints of what went wrong. + +@item +If you have compiled @strong{MySQL} with debugging you can try to debug this +by running @code{mysql-test-run} with the @code{--gdb} and/or @code{--debug} +options. +@xref{Making trace files}. + +If you have not compiled @strong{MySQL} for debugging you should probably +do that. Just specify the @code{--with-debug} options to @code{configure}! +@xref{Installing source}. +@end itemize + + + + +@node ODBC, Common programs, Extending MySQL, Top +@chapter MySQL ODBC Support + @cindex ODBC @cindex Windows @cindex MyODBC -@node ODBC, Common programs, Adding procedures, Top -@chapter MySQL ODBC Support @menu * Installing MyODBC:: How to install MyODBC @@ -37834,11 +38222,13 @@ You can find all information about procedures by examining the following files: * MyODBC bug report:: Reporting problems with MyODBC @end menu + @strong{MySQL} provides support for ODBC by means of the @strong{MyODBC} program. This chapter will teach you how to install @strong{MyODBC}, and how to use it. Here, you will also find a list of common programs that are known to work with @strong{MyODBC}. + @node Installing MyODBC, ODBC administrator, ODBC, ODBC @section How To Install MyODBC @@ -37927,10 +38317,12 @@ Notice that there are other configuration options on the screen of @strong{MySQL} (trace, don't prompt on connect, etc) that you can try if you run into problems. -@cindex ODBC, administrator + @node ODBC administrator, MyODBC connect parameters, Installing MyODBC, ODBC @section How to Fill in the Various Fields in the ODBC Administrator Program +@cindex ODBC, administrator + There are three possibilities for specifying the server name on Windows95: @@ -37982,6 +38374,7 @@ If you specify the option @code{Read options from C:\my.cnf}, the groups You can use all options that are usable by @code{mysql_options()}. @xref{mysql_options, , @code{mysql_options}}. + @node MyODBC connect parameters, ODBC Problems, ODBC administrator, ODBC @section Connect parameters for MyODBC @@ -38039,6 +38432,7 @@ you want to to debug @strong{MyODBC} (for example to enable tracing), you should instead use @code{MYODBCD.DLL}. To install this file, copy @file{MYODBCD.DLL} over the installed @code{MYODBC.DLL} file. + @node ODBC Problems, MyODBC clients, MyODBC connect parameters, ODBC @section How to Report Problems with MyODBC @@ -38069,6 +38463,7 @@ single floats. If the above doesn't help, you should do a @code{MyODBC} trace file and try to figure out why things go wrong. + @node MyODBC clients, ODBC and last_insert_id, ODBC Problems, ODBC @section Programs Known to Work with MyODBC @@ -38357,10 +38752,12 @@ columns to INT} option in the MyODBC connect screen. You should use the option flag @code{Don't optimize column widths}. @end table -@cindex AUTO-INCREMENT, ODBC + @node ODBC and last_insert_id, MyODBC bug report, MyODBC clients, ODBC @section How to Get the Value of an @code{AUTO_INCREMENT} Column in ODBC +@cindex AUTO-INCREMENT, ODBC + A common problem is how to get the value of an automatically generated ID from an @code{INSERT}. With ODBC, you can do something like this (assuming that @code{auto} is an @code{AUTO_INCREMENT} field): @@ -38385,11 +38782,13 @@ the following query can be used to find a newly inserted row: SELECT * FROM tbl_name WHERE auto IS NULL; @end example + +@node MyODBC bug report, , ODBC and last_insert_id, ODBC +@section Reporting Problems with MyODBC + @cindex reporting, MyODBC problems @cindex problems, ODBC @cindex MyODBC, reporting problems -@node MyODBC bug report, , ODBC and last_insert_id, ODBC -@section Reporting Problems with MyODBC If you encounter difficulties with @strong{MyODBC}, you should start by making a log file from the ODBC manager (the log you get when requesting @@ -38444,7 +38843,8 @@ file where you do exactly the same thing in the other SQL server. Remember that the more information you can supply to us, the more likely it is that we can fix the problem! -@node Common programs, Problems, ODBC, Top + +@node Common programs, Clients, ODBC, Top @chapter Using MySQL with Some Common Programs @menu @@ -38488,1711 +38888,10 @@ Only call @code{mysql_init()} with @code{NULL} as an argument, not a pre-allocated MYSQL struct. @end itemize -@cindex problems, common errors -@cindex errors, common -@node Problems, Common problems, Common programs, Top -@chapter Problems and Common Errors -@menu -* What is crashing:: How to determine what is causing problems -* Crashing:: What to do if @strong{MySQL} keeps crashing -* Link errors:: Problems when linking with the @strong{MySQL} client library -* Common errors:: Some common errors when using @strong{MySQL} -* Full disk:: How @strong{MySQL} handles a full disk -* Temporary files:: Where @strong{MySQL} stores temporary files -* Problems with mysql.sock:: How to protect @file{/tmp/mysql.sock} -* Changing MySQL user:: How to run @strong{MySQL} as a normal user -* Resetting permissions:: How to reset a forgotten password. -* File permissions :: Problems with file permissions -* Not enough file handles:: File not found -* Using DATE:: Problems using @code{DATE} columns -* Timezone problems:: Timezone problems -* Case sensitivity:: Case sensitivity in searches -* Problems with NULL:: Problems with @code{NULL} values -* Problems with alias:: Problems with @code{alias} -* Deleting from related tables:: Deleting rows from related tables -* No matching rows:: Solving problems with no matching rows -* ALTER TABLE problems:: Problems with @code{ALTER TABLE}. -* Change column order:: How to change the order of columns in a table -* Temporary table problems:: -@end menu -This chapter lists some common problems and error messages that users have -run into. You will learn how to figure out what the problem is, and what -to do to solve it. You will also find proper solutions to some common -problems. -@node What is crashing, Crashing, Problems, Problems -@section How to Determine What Is Causing Problems - -When you run into problems, the first thing you should do is to find out -which program / piece of equipment is causing problems: - -@itemize @bullet -@item -If you have one of the following symptoms, then it is probably a hardware -(like memory, motherboard, CPU, or hard disk) or kernel problem: -@itemize @minus -@item -The keyboard doesn't work. This can normally be checked by pressing -Caps Lock. If the Caps Lock light doesn't change you have to replace -your keyboard. (Before doing this, you should try to reboot -your computer and check all cables to the keyboard.) -@item -The mouse pointer doesn't move. -@item -The machine doesn't answer to a remote machine's pings. -@item -Different, unrelated programs don't behave correctly. -@item -If your system rebooted unexpectedly (a faulty user level program should -NEVER be able to take down your system). -@end itemize - -In this case you should start by checking all your cables and run some -diagnostic tool to check your hardware! -You should also check if there are any patches, updates, or service -packs for your operating system that could likely solve your problems. -Check also that all your libraries (like glibc) are up to date. - -It's always good to use a machine with ECC memory to discover -memory problems early! -@item -If your keyboard is locked up, you may be able to fix this by -logging into your machine from another machine and execute -@code{kbd_mode -a} on it. - -@item -Please examine your system log file (/var/log/messages or similar) for -reasons for your problems. If you think the problem is in @strong{MySQL} -then you should also examine @strong{MySQL}'s log files. @xref{Update log}. - -@item -If you don't think you have hardware problems, you should try to find -out which program is causing problems. - -Try using @code{top}, @code{ps}, @code{taskmanager}, or some similar program, -to check which program is taking all CPU or is locking the machine. - -@item -Check with @code{top}, @code{df}, or a similar program if you are out of -memory, disk space, open files, or some other critical resource. - -@item -If the problem is some runaway process, you can always try to kill it. If it -doesn't want to die, there is probably a bug in the operating system. -@end itemize - -If after you have examined all other possibilities and you have -concluded that it's the @strong{MySQL} server or a @strong{MySQL} client -that is causing the problem, it's time to do a bug report for our -mailing list or our support team. In the bug report, try to give a -very detailed description of how the system is behaving and what you think is -happening. You should also state why you think it's @strong{MySQL} that -is causing the problems. Take into consideration all the situations in -this chapter. State any problems exactly how they appear when you -examine your system. Use the 'cut and paste' method for any output -and/or error messages from programs and/or log files! - -Try to describe in detail which program is not working and all -symptoms you see! We have in the past received many bug reports that just -state "the system doesn't work". This doesn't provide us with any -information about what could be the problem. - -If a program fails, it's always useful to know: - -@itemize @bullet -@item -Has the program in question made a segmentation fault (core dumped)? -@item -Is the program taking the whole CPU? Check with @code{top}. Let the -program run for a while, it may be evaluating something heavy. -@item -If it's the @code{mysqld} server that is causing problems, can you -do @code{mysqladmin -u root ping} or @code{mysqladmin -u root processlist}? -@item -What does a client program say (try with @code{mysql}, for example) -when you try to connect to the @strong{MySQL} server? -Does the client jam? Do you get any output from the program? -@end itemize - -When sending a bug report, you should of follow the outlines -described in this manual. @xref{Asking questions}. - -@cindex crash, repeated -@node Crashing, Link errors, What is crashing, Problems -@section What to Do if MySQL Keeps Crashing - -All @strong{MySQL} versions are tested on many platforms before they are -released. This doesn't mean that there aren't any bugs in -@strong{MySQL}, but it means if there are bugs, they are very few and can be -hard to find. If you have a problem, it will always help if you try to -find out exactly what crashes your system, as you will have a much better -chance of getting this fixed quickly. - -First, you should try to find out whether the problem is that the -@code{mysqld} daemon dies or whether your problem has to do with your -client. You can check how long your @code{mysqld} server has been up by -executing @code{mysqladmin version}. If @code{mysqld} has died, you may -find the reason for this in the file -@file{mysql-data-directory/`hostname`.err}. @xref{Error log}. - -Many crashes of @strong{MySQL} are caused by corrupted index / data -files. @strong{MySQL} will update the data on disk, with the -@code{write()} system call, after every SQL statement and before the -client is notified about the result. (This is not true if you are running -with @code{delayed_key_writes}, in which case only the data is written.) -This means that the data is safe even if @code{mysqld} crashes, as the OS will -ensure that the not flushed data is written to disk. You can force -@strong{MySQL} to sync everything to disk after every SQL command by -starting @code{mysqld} with @code{--flush}. - -The above means that normally you shouldn't get corrupted tables unless: - -@itemize @bullet -@item -Someone/something killed @code{mysqld} or the machine in the middle -of an update. -@item -You have found a bug in @code{mysqld} that caused it to die in the -middle of an update. -@item -Someone is manipulating the data/index files outside of @strong{mysqld} -without locking the table properly. -@item -If you are running many @code{mysqld} servers on the same data on a -system that doesn't support good file system locks (normally handled by -the @code{lockd} daemon ) or if you are running -multiple servers with @code{--skip-locking} -@item -You have a crashed index/data file that contains very wrong data that -got @code{mysqld} confused. -@item -You have found a bug in the data storage code. This isn't that likely, -but it's at least possible. In this case you can try to change the file -type to another database handler by using @code{ALTER TABLE} on a -repaired copy of the table! -@end itemize - -Because it is very difficult to know why something is crashing, first try to -check whether or not things that work for others crash for you. Please try -the following things: - -@itemize @bullet -@item -Take down the @code{mysqld} daemon with @code{mysqladmin shutdown}, run -@code{myisamchk --silent --force */*.MYI} on all tables, and restart the -@code{mysqld} daemon. This will ensure that you are running from a clean -state. @xref{Maintenance}. - -@item -Use @code{mysqld --log} and try to determine from the information in the log -whether or not some specific query kills the server. About 95% of all bugs are -related to a particular query! Normally this is one of the last queries in -the log file just before @strong{MySQL} restarted. @xref{Query log}. -If you can repeatadly kill @strong{MySQL} with one of the queries, even -when you have checked all tables just before doing the query, then you -have been able to locate the bug and should do a bug report for this! -@xref{Bug reports}. - -@item -Try to make a test case that we can use to reproduce the problem. -@xref{Reproduceable test case}. - -@item -Try running the included mysql-test test and the @strong{MySQL} -benchmarks. @xref{MySQL test suite}. They should test @strong{MySQL} -rather well. You can also add code that to the benchmarks to simulates -your application! The benchmarks can be found in the @file{bench} -directory in the source distribution or, for a binary distribution, in -the @file{sql-bench} directory under your @strong{MySQL} installation -directory. - -@item -Try @code{fork_test.pl} and @code{fork2_test.pl}. - -@item -If you configure @strong{MySQL} for debugging, it will be much easier to -gather information about possible errors if something goes wrong. -Reconfigure @strong{MySQL} with the @code{--with-debug} option or -@code{--with-debug=full} to @code{configure} and then recompile. -@xref{Debugging server}. - -@item -Configuring @strong{MySQL} for debugging causes a safe memory allocator to be -included that can find some errors. It also provides a lot of output about -what is happening. - -@item -Have you applied the latest patches for your operating system? - -@item -Use the @code{--skip-locking} option to @code{mysqld}. On some systems, the -@code{lockd} lock manager does not work properly; the @code{--skip-locking} -option tells @code{mysqld} not to use external locking. (This means that you -cannot run 2 @code{mysqld} servers on the same data and that you must be -careful if you use @code{myisamchk}, but it may be instructive to try the -option as a test.) - -@item -Have you tried @code{mysqladmin -u root processlist} when @code{mysqld} -appears to be running but not responding? Sometimes @code{mysqld} is not -comatose even though you might think so. The problem may be that all -connections are in use, or there may be some internal lock problem. -@code{mysqladmin processlist} will usually be able to make a connection even -in these cases, and can provide useful information about the current number -of connections and their status. - -@item -Run the command @code{mysqladmin -i 5 status} or @code{mysqladmin -i 5 --r status} or in a separate window to produce statistics while you run -your other queries. - -@item -Try the following: -@enumerate -@item -Start @code{mysqld} from @code{gdb} (or in another debugger). -@xref{Using gdb on mysqld}. - -@item -Run your test scripts. - -@item -Print the backtrace and the local variables at the 3 lowest levels. In gdb you -can do this with the following commands when @code{mysqld} has crashed inside -gdb: - -@example -backtrace -info local -up -info local -up -info local -@end example - -With gdb you can also examine which threads exist with @code{info -threads} and switch to a specific thread with @code{thread #}, where -@code{#} is the thread id. -@end enumerate - -@item -Try to simulate your application with a Perl script to force -@strong{MySQL} to crash or misbehave. - -@item -Send a normal bug report. @xref{Bug reports}. Be even more detailed -than usual. Because @strong{MySQL} works for many people, it may be that the -crash results from something that exists only on your computer (for example, -an error that is related to your particular system libraries). -@item -If you have a problem with tables with dynamic-length rows and you are -not using @code{BLOB/TEXT} columns (but only @code{VARCHAR} columns), you -can try to change all @code{VARCHAR} to @code{CHAR} with @code{ALTER -TABLE}. This will force @strong{MySQL} to use fixed-size rows. -Fixed-size rows take a little extra space, but are much more tolerant to -corruption! - -The current dynamic row code has been in use at @strong{MySQL AB} for at -least 3 years without any problems, but by nature dynamic-length rows are -more prone to errors, so it may be a good idea to try the above to see if -it helps! -@end itemize - -@cindex linking, errors -@cindex errors, linking -@cindex problems, linking -@node Link errors, Common errors, Crashing, Problems -@section Problems When Linking with the MySQL Client Library - -If you are linking your program and you get errors for unreferenced -symbols that start with @code{mysql_}, like the following: - -@example -/tmp/ccFKsdPa.o: In function `main': -/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init' -/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect' -/tmp/ccFKsdPa.o(.text+0x57): undefined reference to `mysql_real_connect' -/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error' -/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close' -@end example - -you should be able to solve this by adding @code{-Lpath-to-the-mysql-library --lmysqlclient} @strong{LAST} on your link line. - -If you get @code{undefined reference} errors for the @code{uncompress} -or @code{compress} function, add @code{-lz} @strong{LAST} on your link -line and try again! - -If you get @code{undefined reference} errors for functions that should -exist on your system, like @code{connect}, check the man page for the -function in question, for which libraries you should add to the link -line! - -If you get @code{undefined reference} errors for functions that don't -exist on your system, like the following: - -@example -mf_format.o(.text+0x201): undefined reference to `__lxstat' -@end example - -it usually means that your library is compiled on a system that is not -100 % compatible with yours. In this case you should download the -latest @strong{MySQL} source distribution and compile this yourself. -@xref{Installing source}. - -If you are trying to run a program and you then get errors for -unreferenced symbols that start with @code{mysql_} or that the -@code{mysqlclient} library can't be found, this means that your system -can't find the share @code{libmysqlclient.so} library. - -The fix for this is to tell your system to search after shared -libraries where the library is located by one of the following methods: - -@itemize @bullet -@item -Add the path to the directory where you have @code{libmysqlclient.so} the -@code{LD_LIBRARY_PATH} environment variable. -@item -Add the path to the directory where you have @code{libmysqlclient.so} the -@code{LD_LIBRARY} environment variable. -@item -Copy @code{libmysqlclient.so} to some place that is searched by your system, -like @file{/lib}, and update the shared library information by executing -@code{ldconfig}. -@end itemize - -Another way to solve this problem is to link your program statically, with -@code{-static}, or by removing the dynamic @strong{MySQL} libraries -before linking your code. In the second case you should be -sure that no other programs are using the dynamic libraries! - -@cindex errors, list of -@node Common errors, Full disk, Link errors, Problems -@section Some Common Errors When Using MySQL - -@menu -* Error Access denied:: @code{Access denied} Error -* Gone away:: @code{MySQL server has gone away} error -* Can not connect to server:: @code{Can't connect to [local] MySQL server} error -* Blocked host:: @code{Host '...' is blocked} error -* Too many connections:: @code{Too many connections} error -* Non-transactional tables:: @code{Some non-transactional changed tables couldn't be rolled back} Error -* Out of memory:: @code{Out of memory} error -* Packet too large:: @code{Packet too large} error -* Communication errors:: Communication errors / Aborted connection -* Full table:: @code{The table is full} error -* Cannot create:: @code{Can't create/write to file} Error -* Commands out of sync:: @code{Commands out of sync} error in client -* Ignoring user:: @code{Ignoring user} error -* Cannot find table:: @code{Table 'xxx' doesn't exist} error -* Cannot initialize character set:: -@end menu - -This section lists some errors that users frequently get. You will find -descriptions of the errors, and how to solve the problem here. - -@cindex errors, access denied -@cindex problems, access denied errors -@cindex access denied errors -@node Error Access denied, Gone away, Common errors, Common errors -@subsection @code{Access denied} Error - -@xref{Privileges}, and especially. @xref{Access denied}. - -@node Gone away, Can not connect to server, Error Access denied, Common errors -@subsection @code{MySQL server has gone away} Error - -This section also covers the related @code{Lost connection to server -during query} error. - -The most common reason for the @code{MySQL server has gone away} error -is that the server timed out and closed the connection. By default, the -server closes the connection after 8 hours if nothing has happened. You -can change the time limit by setting the @code{wait_timeout} variable when -you start @code{mysqld}. - -Another common reason to receive the @code{MySQL server has gone away} error -is because you have issued a ``close'' on your @strong{MySQL} connection -and then tried to run a query on the closed connection. - -You can check that the @strong{MySQL} hasn't died by executing -@code{mysqladmin version} and examining the uptime. - -If you have a script, you just have to issue the query again for the client -to do an automatic reconnection. - -You normally can get the following error codes in this case -(which one you get is OS-dependent): - -@multitable @columnfractions .3 .7 -@item @code{CR_SERVER_GONE_ERROR} @tab The client couldn't send a question to the -server. -@item @code{CR_SERVER_LOST} @tab The client didn't get an error when writing -to the server, but it didn't get a full answer (or any answer) to the question. -@end multitable - -You can also get these errors if you send a query to the server that is -incorrect or too large. If @code{mysqld} gets a packet that is too large -or out of order, it assumes that something has gone wrong with the client and -closes the connection. If you need big queries (for example, if you are -working with big @code{BLOB} columns), you can increase the query limit by -starting @code{mysqld} with the @code{-O max_allowed_packet=#} option -(default 1M). The extra memory is allocated on demand, so @code{mysqld} will -use more memory only when you issue a big query or when @code{mysqld} must -return a big result row! - -@node Can not connect to server, Blocked host, Gone away, Common errors -@subsection @code{Can't connect to [local] MySQL server} error - -A @strong{MySQL} client on Unix can connect to the @code{mysqld} server in two -different ways: Unix sockets, which connect through a file in the file -system (default @file{/tmp/mysqld.sock}) or TCP/IP, which connects -through a port number. Unix sockets are faster than TCP/IP but can only -be used when connecting to a server on the same computer. Unix sockets -are used if you don't specify a hostname or if you specify the special -hostname @code{localhost}. - -On Windows you can connect only with TCP/IP if the @code{mysqld} server -is running on Win95/Win98. If it's running on NT, you can also connect -with named pipes. The name of the named pipe is @strong{MySQL}. If you -don't give a hostname when connecting to @code{mysqld}, a @strong{MySQL} client -will first try to connect to the named pipe, and if this doesn't work it -will connect to the TCP/IP port. You can force the use of named pipes -on Windows by using @code{.} as the hostname. - -The error (2002) @code{Can't connect to ...} normally means that there -isn't a @strong{MySQL} server running on the system or that you are -using a wrong socket file or TCP/IP port when trying to connect to the -@code{mysqld} server. - -Start by checking (using @code{ps} or the task manager on Windows) that -there is a process running named @code{mysqld} on your server! If there -isn't any @code{mysqld} process, you should start one. @xref{Starting -server}. - -If a @code{mysqld} process is running, you can check the server by -trying these different connections (the port number and socket pathname -might be different in your setup, of course): - -@example -shell> mysqladmin version -shell> mysqladmin variables -shell> mysqladmin -h `hostname` version variables -shell> mysqladmin -h `hostname` --port=3306 version -shell> mysqladmin -h 'ip for your host' version -shell> mysqladmin --socket=/tmp/mysql.sock version -@end example - -Note the use of backquotes rather than forward quotes with the @code{hostname} -command; these cause the output of @code{hostname} (that is, the current -hostname) to be substituted into the @code{mysqladmin} command. - -Here are some reasons the @code{Can't connect to local MySQL server} -error might occur: - -@itemize @bullet -@item -@code{mysqld} is not running. -@item -You are running on a system that uses MIT-pthreads. -If you are running on a system that doesn't have native threads, -@code{mysqld} uses the MIT-pthreads package. @xref{Which OS}. However, -all MIT-pthreads versions doesn't support Unix sockets. On a system -without sockets support you must always specify the hostname explicitly -when connecting to the server. Try using this command to check the -connection to the server: -@example -shell> mysqladmin -h `hostname` version -@end example -@item -Someone has removed the Unix socket that @code{mysqld} uses (default -@file{/tmp/mysqld.sock}). You might have a @code{cron} job that removes -the @strong{MySQL} socket (for example, a job that removes old files -from the @file{/tmp} directory). You can always run @code{mysqladmin -version} and check that the socket @code{mysqladmin} is trying to use -really exists. The fix in this case is to change the @code{cron} job to -not remove @file{mysqld.sock} or to place the socket somewhere else. You -can specify a different socket location at @strong{MySQL} configuration -time with this command: -@example -shell> ./configure --with-unix-socket-path=/path/to/socket -@end example -You can also start @code{safe_mysqld} with the -@code{--socket=/path/to/socket} option and set the environment variable -@code{MYSQL_UNIX_PORT} to the socket pathname before starting your -@strong{MySQL} clients. -@item -You have started the @code{mysqld} server with -the @code{--socket=/path/to/socket} option. If you change the socket -pathname for the server, you must also notify the @strong{MySQL} clients -about the new path. You can do this by setting the environment variable -@code{MYSQL_UNIX_PORT} to the socket pathname or by providing the socket path -as an argument to the clients. You can test the socket with this command: - -@example -shell> mysqladmin --socket=/path/to/socket version -@end example -@item -You are using Linux and one thread has died (core dumped). In this case -you must kill the other @code{mysqld} threads (for example, with the -@code{mysql_zap} script before you can start a new @strong{MySQL} -server. @xref{Crashing}. -@item -You may not have read and write privilege to either the directory that holds -the socket file or privilege to the socket file itself. In this case you -have to either change the privilege for the directory / file or restart -@code{mysqld} so that it uses a directory that you can access. -@end itemize - -If you get the error message @code{Can't connect to MySQL server on -some_hostname}, you can try the following things to find out what the -problem is : - -@itemize @bullet -@item -Check if the server is up by doing @code{telnet your-host-name -tcp-ip-port-number} and press @code{RETURN} a couple of times. If there -is a @strong{MySQL} server running on this port you should get a -responses that includes the version number of the running @strong{MySQL} -server. If you get an error like @code{telnet: Unable to connect to -remote host: Connection refused}, then there is no server running on the -given port. -@item -Try connecting to the @code{mysqld} daemon on the local machine and check -the TCP/IP port that @code{mysqld} it's configured to use (variable @code{port}) with -@code{mysqladmin variables}. -@item -Check that your @code{mysqld} server is not started with the -@code{--skip-networking} option. -@end itemize - -@node Blocked host, Too many connections, Can not connect to server, Common errors -@subsection @code{Host '...' is blocked} Error - -If you get an error like this: - -@example -Host 'hostname' is blocked because of many connection errors. -Unblock with 'mysqladmin flush-hosts' -@end example - -this means that @code{mysqld} has gotten a lot (@code{max_connect_errors}) -of connect requests from the host @code{'hostname'} that have been interrupted -in the middle. After @code{max_connect_errors} failed requests, @code{mysqld} -assumes that something is wrong (like an attack from a cracker), and -blocks the site from further connections until someone executes the command -@code{mysqladmin flush-hosts}. - -By default, @code{mysqld} blocks a host after 10 connection errors. -You can easily adjust this by starting the server like this: - -@example -shell> safe_mysqld -O max_connect_errors=10000 & -@end example - -Note that if you get this error message for a given host, you should first -check that there isn't anything wrong with TCP/IP connections from that -host. If your TCP/IP connections aren't working, it won't do you any good to -increase the value of the @code{max_connect_errors} variable! - -@node Too many connections, Non-transactional tables, Blocked host, Common errors -@subsection @code{Too many connections} Error - -If you get the error @code{Too many connections} when you try to connect -to @strong{MySQL}, this means that there is already @code{max_connections} -clients connected to the @code{mysqld} server. - -If you need more connections than the default (100), then you should restart -@code{mysqld} with a bigger value for the @code{max_connections} variable. - -Note that @code{mysqld} actually allows (@code{max_connections}+1) -clients to connect. The last connection is reserved for a user with the -@strong{process} privilege. By not giving this privilege to normal -users (they shouldn't need this), an administrator with this privilege -can log in and use @code{SHOW PROCESSLIST} to find out what could be -wrong. @xref{SHOW}. - -The maximum number of connects @strong{MySQL} is depending on how good -the thread library is on a given platform. Linux or Solaris should be -able to support 500-1000 simultaneous connections, depending on how much -RAM you have and what your clients are doing. - -@cindex Non-transactional tables -@node Non-transactional tables, Out of memory, Too many connections, Common errors -@subsection @code{Some non-transactional changed tables couldn't be rolled back} Error - -If you get the error/warning: @code{Warning: Some non-transactional -changed tables couldn't be rolled back} when trying to do a -@code{ROLLBACK}, this means that some of the tables you used in the -transaction didn't support transactions. These non-transactional tables -will not be affected by the @code{ROLLBACK} statement. - -The most typical case when this happens is when you have tried to create -a table of a type that is not supported by your @code{mysqld} binary. -If @code{mysqld} doesn't support a table type (or if the table type is -disabled by a startup option) , it will instead create the table type -with the table type that is most resembles to the one you requested, -probably @code{MyISAM}. - -You can check the table type for a table by doing: - -@code{SHOW TABLE STATUS LIKE 'table_name'}. @xref{SHOW TABLE STATUS}. - -You can check the extensions your @code{mysqld} binary supports by doing: - -@code{show variables like 'have_%'}. @xref{SHOW VARIABLES}. - -@node Out of memory, Packet too large, Non-transactional tables, Common errors -@subsection @code{Out of memory} Error - -If you issue a query and get something like the following error: - -@example -mysql: Out of memory at line 42, 'malloc.c' -mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k) -ERROR 2008: MySQL client ran out of memory -@end example - -note that the error refers to the @strong{MySQL} client @code{mysql}. The -reason for this error is simply that the client does not have enough memory to -store the whole result. - -To remedy the problem, first check that your query is correct. Is it -reasonable that it should return so many rows? If so, -you can use @code{mysql --quick}, which uses @code{mysql_use_result()} -to retrieve the result set. This places less of a load on the client (but -more on the server). - -@node Packet too large, Communication errors, Out of memory, Common errors -@subsection @code{Packet too large} Error - -When a @strong{MySQL} client or the @code{mysqld} server gets a packet bigger -than @code{max_allowed_packet} bytes, it issues a @code{Packet too large} -error and closes the connection. - -If you are using the @code{mysql} client, you may specify a bigger buffer by -starting the client with @code{mysql --set-variable=max_allowed_packet=8M}. - -If you are using other clients that do not allow you to specify the maximum -packet size (such as @code{DBI}), you need to set the packet size when you -start the server. You cau use a command-line option to @code{mysqld} to set -@code{max_allowed_packet} to a larger size. For example, if you are -expecting to store the full length of a @code{BLOB} into a table, you'll need -to start the server with the @code{--set-variable=max_allowed_packet=16M} -option. - -@cindex aborted clients -@cindex aborted connection -@cindex connection, aborted -@node Communication errors, Full table, Packet too large, Common errors -@subsection Communication Errors / Aborted Connection - -Starting with @code{MySQL 3.23.40} you only get the @code{Aborted -connection} error of you start @code{mysqld} with @code{--warnings}. - -If you find errors like the following in your error log. - -@example -010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh' -@end example - -@xref{Error log}. - -This means that something of the following has happened: - -@itemize @bullet -@item -The client program did not call @code{mysql_close()} before exit. -@item -The client had been sleeping more than @code{wait_timeout} or -@code{interactive_timeout} without doing any requests. @xref{SHOW -VARIABLES}. -@item -The client program ended abruptly in the middle of the transfer. -@end itemize - -When the above happens, the server variable @code{Aborted_clients} is -incremented. - -The server variable @code{Aborted_connects} is incremented when: - -@itemize @bullet -@item -When a connection packet doesn't contain the right information. -@item -When the user didn't have privileges to connect to a database. -@item -When a user uses a wrong password. -@item -When it takes more than @code{connect_timeout} seconds to get -a connect package. -@end itemize - -Note that the above could indicate that someone is trying to break into -your database! - -@xref{SHOW VARIABLES}. - -Other reasons for problems with Aborted clients / Aborted connections. -@itemize @bullet -@item -Usage of duplex Ethernet protocol, both half and full with -Linux. Many Linux Ethernet drivers have this bug. You should test -for this bug by transferring a huge file via ftp between these two -machines. If a transfer goes in burst-pause-burst-pause ... mode then -you are experiencing a Linux duplex syndrome. The only solution to -this problem is switching of both half and full duplexing on hubs -and switches. -@item -Some problem with the thread library that causes interrupts on reads. -@item -Badly configured TCP/IP. -@item -Faulty Ethernets or hubs or switches, cables ... This can be diagnosed -properly only by replacing hardware. -@end itemize - - -@cindex table is full -@node Full table, Cannot create, Communication errors, Common errors -@subsection @code{The table is full} Error - -This error occurs in older @strong{MySQL} versions when an in-memory temporary -table becomes larger than @code{tmp_table_size} bytes. To avoid this -problem, you can use the @code{-O tmp_table_size=#} option to -@code{mysqld} to increase the temporary table size or use the SQL -option @code{SQL_BIG_TABLES} before you issue the problematic -query. @xref{SET OPTION, , @code{SET OPTION}}. - -You can also start @code{mysqld} with the @code{--big-tables} option. -This is exactly the same as using @code{SQL_BIG_TABLES} for all queries. - -In @strong{MySQL} Version 3.23, in-memory temporary tables will automatically be -converted to a disk-based @code{MyISAM} table after the table size gets -bigger than @code{tmp_table_size}. - -@cindex can't create/write to file -@node Cannot create, Commands out of sync, Full table, Common errors -@subsection @code{Can't create/write to file} Error - -If you get an error for some queries of type: - -@example -Can't create/write to file '\\sqla3fe_0.ism'. -@end example - -this means that @strong{MySQL} can't create a temporary file for the -result set in the given temporary directory. (The above error is a -typical error message on Windows, and the Unix error message is similar.) -The fix is to start @code{mysqld} with @code{--tmpdir=path} or to add to your option -file: - -@example -[mysqld] -tmpdir=C:/temp -@end example - -assuming that the @file{c:\\temp} directory exists. @xref{Option files}. - -Check also the error code that you get with @code{perror}. One reason -may also be a disk full error; - -@example -shell> perror 28 -Error code 28: No space left on device -@end example - -@cindex commands out of sync -@node Commands out of sync, Ignoring user, Cannot create, Common errors -@subsection @code{Commands out of sync} Error in Client - -If you get @code{Commands out of sync; You can't run this command now} -in your client code, you are calling client functions in the wrong order! - -This can happen, for example, if you are using @code{mysql_use_result()} and -try to execute a new query before you have called @code{mysql_free_result()}. -It can also happen if you try to execute two queries that return data without -a @code{mysql_use_result()} or @code{mysql_store_result()} in between. - -@node Ignoring user, Cannot find table, Commands out of sync, Common errors -@subsection @code{Ignoring user} Error - -If you get the following error: - -@code{Found wrong password for user: 'some_user@@some_host'; Ignoring user} - -this means that when @code{mysqld} was started or when it reloaded the -permissions tables, it found an entry in the @code{user} table with -an invalid password. As a result, the entry is simply ignored by the -permission system. - -Possible causes of and fixes for this problem: - -@itemize @bullet -@item -You may be running a new version of @code{mysqld} with an old -@code{user} table. -You can check this by executing @code{mysqlshow mysql user} to see if -the password field is shorter than 16 characters. If so, you can correct this -condition by running the @code{scripts/add_long_password} script. - -@item -The user has an old password (8 characters long) and you didn't start -@code{mysqld} with the @code{--old-protocol} option. -Update the user in the @code{user} table with a new password or -restart @code{mysqld} with @code{--old-protocol}. - -@item -@findex PASSWORD() -You have specified a password in the @code{user} table without using the -@code{PASSWORD()} function. Use @code{mysql} to update the user in the -@code{user} table with a new password. Make sure to use the @code{PASSWORD()} -function: - -@example -mysql> update user set password=PASSWORD('your password') - where user='XXX'; -@end example -@end itemize - -@node Cannot find table, Cannot initialize character set, Ignoring user, Common errors -@subsection @code{Table 'xxx' doesn't exist} Error - -If you get the error @code{Table 'xxx' doesn't exist} or @code{Can't -find file: 'xxx' (errno: 2)}, this means that no table exists -in the current database with the name @code{xxx}. - -Note that as @strong{MySQL} uses directories and files to store databases and -tables, the database and table names are @strong{case sensitive}! -(On Windows the databases and tables names are not case sensitive, but all -references to a given table within a query must use the same case!) - -You can check which tables you have in the current database with -@code{SHOW TABLES}. @xref{SHOW, , @code{SHOW}}. - -@cindex multibyte character sets -@node Cannot initialize character set, , Cannot find table, Common errors -@subsection @code{Can@'t initialize character set xxx} error. - -If you get an error like: - -@example -MySQL Connection Failed: Can't initialize character set xxx -@end example - -This means one of the following things: - -@itemize @bullet -@item -The character set is a multi-byte character set and you have not support -for the character set in the client. - -In this case you need to recompile the client with -@code{--with-charset=xxx} or with @code{--with-extra-charsets=xxx}. -@xref{configure options}. - -All standard @strong{MySQL} binaries are compiled with -@code{--with-extra-character-sets=complex} which will enable support for -all multi-byte character sets. @xref{Character sets}. - -@item -The character set is a simple character set which is not compiled into -@code{mysqld} and the character set definition files is not in the place -where the client expect to find them. - -In this case you need to: - -@itemize @bullet -@item -Recompile the client with support for the character set. -@xref{configure options}. -@item -Specify to the client where the character set definition files are. For many -client you can do this with the -@code{--character-sets-dir=path-to-charset-dir} option. -@item -Copy the character definition files to the path where the client expect them -to be. -@end itemize -@end itemize - -@cindex full disk -@cindex disk full -@node Full disk, Temporary files, Common errors, Problems -@section How MySQL Handles a Full Disk - -@noindent -When a disk-full condition occurs, @strong{MySQL} does the following: - -@itemize @bullet -@item -It checks once every minute to see whether or not there is enough space to -write the current row. If there is enough space, it continues as if nothing had -happened. -@item -Every 6 minutes it writes an entry to the log file warning about the disk -full condition. -@end itemize - -@noindent -To alleviate the problem, you can take the following actions: - -@itemize @bullet -@item -To continue, you only have to free enough disk space to insert all records. -@item -To abort the thread, you must send a @code{mysqladmin kill} to the thread. -The thread will be aborted the next time it checks the disk (in 1 minute). -@item -Note that other threads may be waiting for the table that caused the disk -full condition. If you have several ``locked'' threads, killing the one -thread that is waiting on the disk-full condition will allow the other -threads to continue. -@end itemize - -Exceptions to the above behaveour is when you use @code{REPAIR} or -@code{OPTIMIZE} or when the indexes are created in a batch after an -@code{LOAD DATA INFILE} or after an @code{ALTER TABLE} statement. - -All of the above commands may use big temporary files that left to -themself would cause big problems for the rest of the system. If -@strong{MySQL} gets disk full while doing any of the above operations, -it will remove the big temporary files and mark the table as crashed -(except for @code{ALTER TABLE}, in which the old table will be left -unchanged). - - -@node Temporary files, Problems with mysql.sock, Full disk, Problems -@section Where MySQL Stores Temporary Files - -@strong{MySQL} uses the value of the @code{TMPDIR} environment variable as -the pathname of the directory in which to store temporary files. If you don't -have @code{TMPDIR} set, @strong{MySQL} uses the system default, which is -normally @file{/tmp} or @file{/usr/tmp}. If the file system containing your -temporary file directory is too small, you should edit @code{safe_mysqld} to -set @code{TMPDIR} to point to a directory in a file system where you have -enough space! You can also set the temporary directory using the -@code{--tmpdir} option to @code{mysqld}. - -@strong{MySQL} creates all temporary files as hidden files. This ensures -that the temporary files will be removed if @code{mysqld} is terminated. The -disadvantage of using hidden files is that you will not see a big temporary -file that fills up the file system in which the temporary file directory is -located. - -When sorting (@code{ORDER BY} or @code{GROUP BY}), @strong{MySQL} normally -uses one or two temporary files. The maximum disk-space needed is: - -@example -(length of what is sorted + sizeof(database pointer)) -* number of matched rows -* 2 -@end example - -@code{sizeof(database pointer)} is usually 4, but may grow in the future for -really big tables. - -For some @code{SELECT} queries, @strong{MySQL} also creates temporary SQL -tables. These are not hidden and have names of the form @file{SQL_*}. - -@code{ALTER TABLE} creates a temporary table in the same directory as -the original table. - -@cindex @code{mysql.sock}, protection -@cindex deletion, @code{mysql.sock} -@node Problems with mysql.sock, Changing MySQL user, Temporary files, Problems -@section How to Protect @file{/tmp/mysql.sock} from Being Deleted - -If you have problems with the fact that anyone can delete the -@strong{MySQL} communication socket @file{/tmp/mysql.sock}, you can, -on most versions of Unix, protect your @file{/tmp} file system by setting -the @code{sticky} bit on it. Log in as @code{root} and do the following: - -@example -shell> chmod +t /tmp -@end example - -This will protect your @file{/tmp} file system so that files can be deleted -only by their owners or the superuser (@code{root}). - -You can check if the @code{sticky} bit is set by executing @code{ls -ld /tmp}. -If the last permission bit is @code{t}, the bit is set. - -@cindex starting, @code{mysqld} -@cindex @code{mysqld}, starting -@node Changing MySQL user, Resetting permissions, Problems with mysql.sock, Problems -@section How to Run MySQL As a Normal User - -The @strong{MySQL} server @code{mysqld} can be started and run by any user. -In order to change @code{mysqld} to run as a Unix user @code{user_name}, you must -do the following: - -@enumerate -@item -Stop the server if it's running (use @code{mysqladmin shutdown}). - -@item -Change the database directories and files so that @code{user_name} has -privileges to read and write files in them (you may need to do this as -the Unix @code{root} user): - -@example -shell> chown -R user_name /path/to/mysql/datadir -@end example - -If directories or files within the @strong{MySQL} data directory are -symlinks, you'll also need to follow those links and change the directories -and files they point to. @code{chown -R} may not follow symlinks for -you. - -@item -Start the server as user @code{user_name}, or, if you are using -@strong{MySQL} Version 3.22 or later, start @code{mysqld} as the Unix @code{root} -user and use the @code{--user=user_name} option. @code{mysqld} will switch -to run as the Unix user @code{user_name} before accepting any connections. - -@item -To start the server as the given user name automatically at system -startup time, add a @code{user} line that specifies the user name to -the @code{[mysqld]} group of the @file{/etc/my.cnf} option file or the -@file{my.cnf} option file in the server's data directory. For example: - -@example -[mysqld] -user=user_name -@end example -@end enumerate - -At this point, your @code{mysqld} process should be running fine and dandy as -the Unix user @code{user_name}. One thing hasn't changed, though: the -contents of the permissions tables. By default (right after running the -permissions table install script @code{mysql_install_db}), the @strong{MySQL} -user @code{root} is the only user with permission to access the @code{mysql} -database or to create or drop databases. Unless you have changed those -permissions, they still hold. This shouldn't stop you from accessing -@strong{MySQL} as the @strong{MySQL} @code{root} user when you're logged in -as a Unix user other than @code{root}; just specify the @code{-u root} option -to the client program. - -Note that accessing @strong{MySQL} as @code{root}, by supplying @code{-u -root} on the command line, has @emph{nothing} to do with @strong{MySQL} running -as the Unix @code{root} user, or, indeed, as another Unix user. The access -permissions and user names of @strong{MySQL} are completely separate from -Unix user names. The only connection with Unix user names is that if you -don't provide a @code{-u} option when you invoke a client program, the client -will try to connect using your Unix login name as your @strong{MySQL} user -name. - -If your Unix box itself isn't secured, you should probably at least put a -password on the @strong{MySQL} @code{root} users in the access tables. -Otherwise, any user with an account on that machine can run @code{mysql -u -root db_name} and do whatever he likes. - -@cindex passwords, forgotten -@cindex passwords, resetting -@cindex root user, password resetting -@node Resetting permissions, File permissions , Changing MySQL user, Problems -@section How to Reset a Forgotten Password - -If you have forgotten the @code{root} user password for @strong{MySQL}, you -can restore it with the following procedure: - -@enumerate -@item -Take down the @code{mysqld} server by sending a @code{kill} (not @code{kill --9}) to the @code{mysqld} server. The pid is stored in a @code{.pid} -file, which is normally in the @strong{MySQL} database directory: - -@example -kill `cat /mysql-data-directory/hostname.pid` -@end example - -You must be either the Unix @code{root} user or the same user the server -runs as to do this. - -@item -Restart @code{mysqld} with the @code{--skip-grant-tables} option. -@item -Connect to the @code{mysqld} server with @code{mysql -h hostname mysql} and change -the password with a @code{GRANT} command. @xref{GRANT,,@code{GRANT}}. -You can also do this with -@code{mysqladmin -h hostname -u user password 'new password'} -@item -Load the privilege tables with: @code{mysqladmin -h hostname -flush-privileges} or with the SQL command @code{FLUSH PRIVILEGES}. -@end enumerate - -Note that after you started @code{mysqld} with @code{--skip-grant-tables}, -any usage of @code{GRANT} commands will give you an @code{Unknown command} -error until you have executed @code{FLUSH PRIVILEGES}. - -@cindex files, permissions -@cindex error mesaages, can't find file -@cindex files, not found message -@node File permissions , Not enough file handles, Resetting permissions, Problems -@section Problems with File Permissions - -If you have problems with file permissions, for example, if @code{mysql} -issues the following error message when you create a table: - -@example -ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13) -@end example - -@tindex UMASK environment variable -@tindex Environment variable, UMASK -then the environment variable @code{UMASK} might be set incorrectly when -@code{mysqld} starts up. The default umask value is @code{0660}. You can -change this behavior by starting @code{safe_mysqld} as follows: - -@example -shell> UMASK=384 # = 600 in octal -shell> export UMASK -shell> /path/to/safe_mysqld & -@end example - -@tindex UMASK_DIR environment variable -@tindex Environment variable, UMASK_DIR -By default @strong{MySQL} will create database and @code{RAID} -directories with permission type 0700. You can modify this behavior by -setting the @code{UMASK_DIR} variable. If you set this, new -directories are created with the combined @code{UMASK} and -@code{UMASK_DIR}. For example, if you want to give group access to -all new directories, you can do: - -@example -shell> UMASK_DIR=504 # = 770 in octal -shell> export UMASK_DIR -shell> /path/to/safe_mysqld & -@end example - -In @strong{MySQL} Version 3.23.25 and above, @strong{MySQL} assumes that the -value for @code{UMASK} and @code{UMASK_DIR} is in octal if it starts -with a zero. - -@xref{Environment variables}. - -@node Not enough file handles, Using DATE, File permissions , Problems -@section File Not Found - -If you get @code{ERROR '...' not found (errno: 23)}, @code{Can't open -file: ... (errno: 24)}, or any other error with @code{errno 23} or -@code{errno 24} from @strong{MySQL}, it means that you haven't allocated -enough file descriptors for @strong{MySQL}. You can use the -@code{perror} utility to get a description of what the error number -means: - -@example -shell> perror 23 -File table overflow -shell> perror 24 -Too many open files -shell> perror 11 -Resource temporarily unavailable -@end example - -The problem here is that @code{mysqld} is trying to keep open too many -files simultaneously. You can either tell @code{mysqld} not to open so -many files at once or increase the number of file descriptors -available to @code{mysqld}. - -To tell @code{mysqld} to keep open fewer files at a time, you can make -the table cache smaller by using the @code{-O table_cache=32} option to -@code{safe_mysqld} (the default value is 64). Reducing the value of -@code{max_connections} will also reduce the number of open files (the -default value is 90). - -@tindex ulimit -To change the number of file descriptors available to @code{mysqld}, you -can use the option @code{--open-files-limit=#} to @code{safe_mysqld} or -@code{-O open-files-limit=#} to @code{mysqld}. @xref{SHOW VARIABLES}. -The easiest way to do that is to add the option to your option file. -@xref{Option files}. If you have an old @code{mysqld} version that -doesn't support this, you can edit the @code{safe_mysqld} script. There -is a commented-out line @code{ulimit -n 256} in the script. You can -remove the @code{'#'} character to uncomment this line, and change the -number 256 to affect the number of file descriptors available to -@code{mysqld}. - -@code{ulimit} (and @code{open-files-limit}) can increase the number of -file descriptors, but only up to the limit imposed by the operating -system. There is also a 'hard' limit that can only be overrided if you -start @code{safe_mysqld} or @code{mysqld} as root (Just remember that -you need to also use the @code{--user=..} option in this case). If you -need to increase the OS limit on the number of file descriptors -available to each process, consult the documentation for your operating -system. - -Note that if you run the @code{tcsh} shell, @code{ulimit} will not work! -@code{tcsh} will also report incorrect values when you ask for the current -limits! In this case you should start @code{safe_mysqld} with @code{sh}! - -@findex DATE -@cindex DATE columns, problems -@cindex problems, @code{DATE} columns -@node Using DATE, Timezone problems, Not enough file handles, Problems -@section Problems Using @code{DATE} Columns - -The format of a @code{DATE} value is @code{'YYYY-MM-DD'}. According to ANSI -SQL, no other format is allowed. You should use this format in @code{UPDATE} -expressions and in the WHERE clause of @code{SELECT} statements. For -example: - -@example -mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05'; -@end example - -As a convenience, @strong{MySQL} automatically converts a date to a number if -the date is used in a numeric context (and vice versa). It is also smart -enough to allow a ``relaxed'' string form when updating and in a @code{WHERE} -clause that compares a date to a @code{TIMESTAMP}, @code{DATE}, or a -@code{DATETIME} column. (Relaxed form means that any punctuation character -may be used as the separator between parts. For example, @code{'1998-08-15'} -and @code{'1998#08#15'} are equivalent.) @strong{MySQL} can also convert a -string containing no separators (such as @code{'19980815'}), provided it -makes sense as a date. - -The special date @code{'0000-00-00'} can be stored and retrieved as -@code{'0000-00-00'.} When using a @code{'0000-00-00'} date through -@strong{MyODBC}, it will automatically be converted to @code{NULL} in -@strong{MyODBC} Version 2.50.12 and above, because ODBC can't handle this kind of -date. - -Because @strong{MySQL} performs the conversions described above, the following -statements work: - -@example -mysql> INSERT INTO tbl_name (idate) VALUES (19970505); -mysql> INSERT INTO tbl_name (idate) VALUES ('19970505'); -mysql> INSERT INTO tbl_name (idate) VALUES ('97-05-05'); -mysql> INSERT INTO tbl_name (idate) VALUES ('1997.05.05'); -mysql> INSERT INTO tbl_name (idate) VALUES ('1997 05 05'); -mysql> INSERT INTO tbl_name (idate) VALUES ('0000-00-00'); - -mysql> SELECT idate FROM tbl_name WHERE idate >= '1997-05-05'; -mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505; -mysql> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505; -mysql> SELECT idate FROM tbl_name WHERE idate >= '19970505'; -@end example - -@noindent -However, the following will not work: - -@example -mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0; -@end example - -@code{STRCMP()} is a string function, so it converts @code{idate} to -a string and performs a string comparison. It does not convert -@code{'19970505'} to a date and perform a date comparison. - -Note that @strong{MySQL} does no checking whether or not the date is -correct. If you store an incorrect date, such as @code{'1998-2-31'}, the -wrong date will be stored. If the date cannot be converted to any reasonable -value, a @code{0} is stored in the @code{DATE} field. This is mainly a speed -issue and we think it is up to the application to check the dates, and not -the server. - -@cindex timezone problems -@cindex problems, timezone -@tindex TZ environment variable -@tindex Environment variable, TZ -@node Timezone problems, Case sensitivity, Using DATE, Problems -@section Time Zone Problems - -If you have a problem with @code{SELECT NOW()} returning values in GMT and -not your local time, you have to set the @code{TZ} environment variable to -your current time zone. This should be done for the environment in which -the server runs, for example, in @code{safe_mysqld} or @code{mysql.server}. -@xref{Environment variables}. - -@node Case sensitivity, Problems with NULL, Timezone problems, Problems -@section Case Sensitivity in Searches - -@cindex case sensitivity, in searches -@cindex searching, and case-sensitivity -@cindex Chinese -@cindex Big5 Chinese character encoding - -By default, @strong{MySQL} searches are case-insensitive (although there are -some character sets that are never case insensitive, such as @code{czech}). -That means that if you search with @code{col_name LIKE 'a%'}, you will get all -column values that start with @code{A} or @code{a}. If you want to make this -search case-sensitive, use something like @code{INDEX(col_name, "A")=0} to -check a prefix. Or use @code{STRCMP(col_name, "A") = 0} if the column value -must be exactly @code{"A"}. - -Simple comparison operations (@code{>=, >, = , < , <=}, sorting and -grouping) are based on each character's ``sort value''. Characters with -the same sort value (like E, e and é) are treated as the same character! - -In older @strong{MySQL} versions @code{LIKE} comparisons where done on -the uppercase value of each character (E == e but E <> é). In newer -@strong{MySQL} versions @code{LIKE} works just like the other comparison -operators. - -If you want a column always to be treated in case-sensitive fashion, -declare it as @code{BINARY}. @xref{CREATE TABLE, , @code{CREATE TABLE}}. - -If you are using Chinese data in the so-called big5 encoding, you want to -make all character columns @code{BINARY}. This works because the sorting -order of big5 encoding characters is based on the order of ASCII codes. - -@cindex @code{NULL} values, vs. empty values -@tindex NULL -@node Problems with NULL, Problems with alias, Case sensitivity, Problems -@section Problems with @code{NULL} Values - -The concept of the @code{NULL} value is a common source of confusion for -newcomers to SQL, who often think that @code{NULL} is the same thing as an -empty string @code{''}. This is not the case! For example, the following -statements are completely different: - -@example -mysql> INSERT INTO my_table (phone) VALUES (NULL); -mysql> INSERT INTO my_table (phone) VALUES (""); -@end example - -Both statements insert a value into the @code{phone} column, but the first -inserts a @code{NULL} value and the second inserts an empty string. The -meaning of the first can be regarded as ``phone number is not known'' and the -meaning of the second can be regarded as ``she has no phone''. - -In SQL, the @code{NULL} value is always false in comparison to any -other value, even @code{NULL}. An expression that contains @code{NULL} -always produces a @code{NULL} value unless otherwise indicated in -the documentation for the operators and functions involved in the -expression. All columns in the following example return @code{NULL}: - -@example -mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL); -@end example - -If you want to search for column values that are @code{NULL}, you -cannot use the @code{=NULL} test. The following statement returns no -rows, because @code{expr = NULL} is FALSE, for any expression: - -@example -mysql> SELECT * FROM my_table WHERE phone = NULL; -@end example - -To look for @code{NULL} values, you must use the @code{IS NULL} test. -The following shows how to find the @code{NULL} phone number and the -empty phone number: - -@example -mysql> SELECT * FROM my_table WHERE phone IS NULL; -mysql> SELECT * FROM my_table WHERE phone = ""; -@end example - -In @strong{MySQL}, as in many other SQL servers, you can't index -columns that can have @code{NULL} values. You must declare such columns -@code{NOT NULL}. Conversely, you cannot insert @code{NULL} into an indexed -column. - -@findex LOAD DATA INFILE -When reading data with @code{LOAD DATA INFILE}, empty columns are updated -with @code{''}. If you want a @code{NULL} value in a column, you should use -@code{\N} in the text file. The literal word @code{'NULL'} may also be used -under some circumstances. -@xref{LOAD DATA, , @code{LOAD DATA}}. - -When using @code{ORDER BY}, @code{NULL} values are presented first. If you -sort in descending order using @code{DESC}, @code{NULL} values are presented -last. When using @code{GROUP BY}, all @code{NULL} values are regarded as -equal. - -To help with @code{NULL} handling, you can use the @code{IS NULL} and -@code{IS NOT NULL} operators and the @code{IFNULL()} function. - -@cindex @code{TIMESTAMP}, and @code{NULL} values -@cindex @code{AUTO_INCREMENT}, and @code{NULL} values -@cindex @code{NULL} values, and @code{TIMESTAMP} columns -@cindex @code{NULL} values, and @code{AUTO_INCREMENT} columns -For some column types, @code{NULL} values are handled specially. If you -insert @code{NULL} into the first @code{TIMESTAMP} column of a table, the -current date and time is inserted. If you insert @code{NULL} into an -@code{AUTO_INCREMENT} column, the next number in the sequence is inserted. - -@tindex alias -@node Problems with alias, Deleting from related tables, Problems with NULL, Problems -@section Problems with @code{alias} - -You can use an alias to refer to a column in the @code{GROUP BY}, -@code{ORDER BY}, or in the @code{HAVING} part. Aliases can also be used -to give columns better names: - -@example -SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0; -SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0; -SELECT id AS "Customer identity" FROM table_name; -@end example - -Note that ANSI SQL doesn't allow you to refer to an alias in a -@code{WHERE} clause. This is because when the @code{WHERE} code is -executed the column value may not yet be determined. For example, the -following query is @strong{illegal}: - -@example -SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id; -@end example - -The @code{WHERE} statement is executed to determine which rows should -be included in the @code{GROUP BY} part while @code{HAVING} is used to -decide which rows from the result set should be used. - -@cindex deleting, rows -@cindex rows, deleting -@cindex tables, deleting rows -@node Deleting from related tables, No matching rows, Problems with alias, Problems -@section Deleting Rows from Related Tables - -As @strong{MySQL} doesn't support sub-selects or use of more than one table -in the @code{DELETE} statement, you should use the following approach to -delete rows from 2 related tables: - -@enumerate -@item -@code{SELECT} the rows based on some @code{WHERE} condition in the main table. -@item -@code{DELETE} the rows in the main table based on the same condition. -@item -@code{DELETE FROM related_table WHERE related_column IN (selected_rows)}. -@end enumerate - -If the total number of characters in the query with -@code{related_column} is more than 1,048,576 (the default value of -@code{max_allowed_packet}, you should split it into smaller parts and -execute multiple @code{DELETE} statements. You will probably get the -fastest @code{DELETE} by only deleting 100-1000 @code{related_column} -id's per query if the @code{related_column} is an index. If the -@code{related_column} isn't an index, the speed is independent of the -number of arguments in the @code{IN} clause. - -@cindex no matching rows -@cindex rows, matching problems -@node No matching rows, ALTER TABLE problems, Deleting from related tables, Problems -@section Solving Problems with No Matching Rows - -If you have a complicated query that has many tables and that doesn't -return any rows, you should use the following procedure to find out what -is wrong with your query: - -@enumerate -@item -Test the query with @code{EXPLAIN} and check if you can find something that is -obviously wrong. @xref{EXPLAIN, , @code{EXPLAIN}}. - -@item -Select only those fields that are used in the @code{WHERE} clause. - -@item -Remove one table at a time from the query until it returns some rows. -If the tables are big, it's a good idea to use @code{LIMIT 10} with the query. - -@item -Do a @code{SELECT} for the column that should have matched a row against -the table that was last removed from the query. - -@item -If you are comparing @code{FLOAT} or @code{DOUBLE} columns with numbers that -have decimals, you can't use @code{=}! This problem is common in most -computer languages because floating-point values are not exact values: - -@example -mysql> SELECT * FROM table_name WHERE float_column=3.5; - -> -mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55; -@end example - -In most cases, changing the @code{FLOAT} to a @code{DOUBLE} will fix this! - -@item -If you still can't figure out what's wrong, create a minimal test that can -be run with @code{mysql test < query.sql} that shows your problems. -You can create a test file with @code{mysqldump --quick database tables > query.sql}. Open the file in an editor, remove some insert lines (if there are -too many of these), and add your select statement at the end of the file. - -Test that you still have your problem by doing: - -@example -shell> mysqladmin create test2 -shell> mysql test2 < query.sql -@end example - -Post the test file using @code{mysqlbug} to @email{mysql@@lists.mysql.com}. -@end enumerate - -@tindex ALTER TABLE -@node ALTER TABLE problems, Change column order, No matching rows, Problems -@section Problems with @code{ALTER TABLE}. - -@code{ALTER TABLE} changes a table to the current character set. -If you during @code{ALTER TABLE} get a duplicate key error, then the cause -is either that the new character sets maps to keys to the same value -or that the table is corrupted, in which case you should run -@code{REPAIR TABLE} on the table. - -If @code{ALTER TABLE} dies with an error like this: - -@example -Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17) -@end example - -the problem may be that @strong{MySQL} has crashed in a previous @code{ALTER -TABLE} and there is an old table named @file{A-something} or -@file{B-something} lying around. In this case, go to the @strong{MySQL} data -directory and delete all files that have names starting with @code{A-} or -@code{B-}. (You may want to move them elsewhere instead of deleting them.) - -@code{ALTER TABLE} works the following way: - -@itemize @bullet -@item Create a new table named @file{A-xxx} with the requested changes. -@item All rows from the old table are copied to @file{A-xxx}. -@item The old table is renamed @file{B-xxx}. -@item @file{A-xxx} is renamed to your old table name. -@item @file{B-xxx} is deleted. -@end itemize - -If something goes wrong with the renaming operation, @strong{MySQL} tries to -undo the changes. If something goes seriously wrong (this shouldn't happen, -of course), @strong{MySQL} may leave the old table as @file{B-xxx}, but a -simple rename on the system level should get your data back. - -@cindex reordering, columns -@cindex columns, changing -@cindex changing, column order -@cindex tables, changing column order -@node Change column order, Temporary table problems, ALTER TABLE problems, Problems -@section How To Change the Order of Columns in a Table - -The whole point of SQL is to abstract the application from the data -storage format. You should always specify the order in which you wish to -retrieve your data. For example: - -@example -SELECT col_name1, col_name2, col_name3 FROM tbl_name; -@end example - -will return columns in the order @code{col_name1}, @code{col_name2}, @code{col_name3}, whereas: - -@example -SELECT col_name1, col_name3, col_name2 FROM tbl_name; -@end example - -will return columns in the order @code{col_name1}, @code{col_name3}, @code{col_name2}. - -You should @strong{NEVER}, in an application, use @code{SELECT *} and -retrieve the columns based on their position, because the order in which -columns are returned @strong{CANNOT} be guaranteed over time. A simple -change to your database may cause your application to fail rather -dramatically. - -If you want to change the order of columns anyway, you can do it as follows: - -@enumerate -@item -Create a new table with the columns in the right order. -@item -Execute -@code{INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table}. -@item -Drop or rename @code{old_table}. -@item -@code{ALTER TABLE new_table RENAME old_table}. -@end enumerate - -@cindex temporary tables, problems -@node Temporary table problems, , Change column order, Problems -@section TEMPORARY TABLE problems - -The following are a list of the limitations with @code{TEMPORARY TABLES}. - -@itemize @bullet -@item -A temporary table can only be of type @code{HEAP}, @code{ISAM} or -@code{MyISAM}. -@item -You can't use temporary tables more than once in the same query. -For example, the following doesn't work. - -@example -select * from temporary_table, temporary_table as t2; -@end example - -We plan to fix the above in 4.0. -@item -You can't use @code{RENAME} on a @code{TEMPORARY} table. -Note that @code{ALTER TABLE org_name RENAME new_name} works! - -We plan to fix the above in 4.0. -@end itemize - -@cindex problems, solving -@cindex solving, problems -@cindex databases, replicating -@node Common problems, Clients, Problems, Top -@chapter Solving Some Common Problems with MySQL - -@cindex replication -@menu -* Log Replication:: Database replication with update log -@end menu - -In this chapter, you will find information to solve some of the more common -tasks with @strong{MySQL}. This includes making backups, running more than -one @strong{MySQL} server daemon on a single machine, and replicating a -database using the update or binary logs. - -@cindex database replication -@cindex replication, database -@node Log Replication, , Common problems, Common problems -@section Database Replication with Update Log - -Now that master-slave internal replication is available starting in -Version 3.23.15, using the update log to implement replications is not -recommended. @xref{Replication}. - -However, it is still possible to replicate a database by using the -update log or the binary log. @xref{Update log}. This requires one -database that acts as a master (to which data changes are made) and one -or more other databases that act as slaves. To update a slave, just run -@code{mysql < update_log.*} or @code{mysqlbinlog binary_log.* | mysql}. -Supply host, user, and password options that are appropriate for the -slave database, and use the update log from the master database as -input. - -If you never delete anything from a table, you can use a @code{TIMESTAMP} -column to find out which rows have been inserted or changed in the table -since the last replication (by comparing the time when you did the -replication last time) and only copy these rows to the mirror. - -It is possible to make a two-way updating system using both the update -log (for deletes) and timestamps (on both sides). But in that case you -must be able to handle conflicts when the same data have been changed in -both ends. You probably want to keep the old version to help with -deciding what has been updated. - -Because replication in this case is done with SQL statements, you should not -use the following functions in statements that update the database; they may -not return the same value as in the original database: - -@itemize @bullet -@item @code{DATABASE()} -@item @code{GET_LOCK()} and @code{RELEASE_LOCK()} -@item @code{RAND()} -@item @code{USER()}, @code{SYSTEM_USER()} or @code{SESSION_USER()} -@item @code{VERSION()}, @code{CONNECT_ID()} -@end itemize - -All time functions are safe to use, as the timestamp is sent to the -mirror if needed. @code{LAST_INSERT_ID()} is also safe to use. - - -@node Clients, MySQL internals, Common problems, Top +@node Clients, Problems, Common programs, Top @chapter MySQL APIs @cindex client tools @@ -43661,284 +42360,1718 @@ interface that is based on msqltcl 1.50. -@cindex internals -@cindex threads -@node MySQL internals, Environment variables, Clients, Top -@chapter MySQL Internals -This chapter describes a lot of things that you need to know when -working on the @strong{MySQL} code. If you plan to contribute to MySQL -development, want to have access to the bleeding-edge in-between -versions code, or just want to keep track of development, follow the -instructions in @xref{Installing source tree}. If you are interested in MySQL -internals, you should also subscribe to @email{internals@@lists.mysql.com}. -This is a relatively low traffic list, in comparison with -@email{mysql@@lists.mysql.com}. +@node Problems, Environment variables, Clients, Top +@appendix Problems and Common Errors + +@cindex problems, common errors +@cindex errors, common @menu -* MySQL threads:: MySQL threads -* MySQL test suite:: MySQL test suite +* What is crashing:: How to determine what is causing problems +* Crashing:: What to do if @strong{MySQL} keeps crashing +* Link errors:: Problems when linking with the @strong{MySQL} client library +* Common errors:: Some common errors when using @strong{MySQL} +* Full disk:: How @strong{MySQL} handles a full disk +* Temporary files:: Where @strong{MySQL} stores temporary files +* Problems with mysql.sock:: How to protect @file{/tmp/mysql.sock} +* Changing MySQL user:: How to run @strong{MySQL} as a normal user +* Resetting permissions:: How to reset a forgotten password. +* File permissions :: Problems with file permissions +* Not enough file handles:: File not found +* Using DATE:: Problems using @code{DATE} columns +* Timezone problems:: Timezone problems +* Case sensitivity:: Case sensitivity in searches +* Problems with NULL:: Problems with @code{NULL} values +* Problems with alias:: Problems with @code{alias} +* Deleting from related tables:: Deleting rows from related tables +* No matching rows:: Solving problems with no matching rows +* ALTER TABLE problems:: Problems with @code{ALTER TABLE}. +* Change column order:: How to change the order of columns in a table +* Temporary table problems:: @end menu -@node MySQL threads, MySQL test suite, MySQL internals, MySQL internals -@section MySQL Threads +This chapter lists some common problems and error messages that users have +run into. You will learn how to figure out what the problem is, and what +to do to solve it. You will also find proper solutions to some common +problems. -The @strong{MySQL} server creates the following threads: + +@node What is crashing, Crashing, Problems, Problems +@appendixsec How to Determine What Is Causing Problems + +When you run into problems, the first thing you should do is to find out +which program / piece of equipment is causing problems: @itemize @bullet - @item -The TCP/IP connection thread handles all connection requests and -creates a new dedicated thread to handle the authentication and -and SQL query processing for each connection. - +If you have one of the following symptoms, then it is probably a hardware +(like memory, motherboard, CPU, or hard disk) or kernel problem: +@itemize @minus @item -On Windows NT there is a named pipe handler thread that does the same work as -the TCP/IP connection thread on named pipe connect requests. - +The keyboard doesn't work. This can normally be checked by pressing +Caps Lock. If the Caps Lock light doesn't change you have to replace +your keyboard. (Before doing this, you should try to reboot +your computer and check all cables to the keyboard.) @item -The signal thread handles all signals. This thread also normally handles -alarms and calls @code{process_alarm()} to force timeouts on connections -that have been idle too long. - +The mouse pointer doesn't move. @item -If @code{mysqld} is compiled with @code{-DUSE_ALARM_THREAD}, a dedicated -thread that handles alarms is created. This is only used on some systems where -there are problems with @code{sigwait()} or if one wants to use the -@code{thr_alarm()} code in ones application without a dedicated signal -handling thread. - +The machine doesn't answer to a remote machine's pings. @item -If one uses the @code{--flush_time=#} option, a dedicated thread is created -to flush all tables at the given interval. - +Different, unrelated programs don't behave correctly. @item -Every connection has its own thread. - -@item -Every different table on which one uses @code{INSERT DELAYED} gets its -own thread. - -@item -If you use @code{--master-host}, a slave replication thread will be -started to read and apply updates from the master. +If your system rebooted unexpectedly (a faulty user level program should +NEVER be able to take down your system). @end itemize -@code{mysqladmin processlist} only shows the connection, @code{INSERT DELAYED}, -and replication threads. +In this case you should start by checking all your cables and run some +diagnostic tool to check your hardware! +You should also check if there are any patches, updates, or service +packs for your operating system that could likely solve your problems. +Check also that all your libraries (like glibc) are up to date. -@cindex mysqltest, MySQL Test Suite -@cindex testing mysqld, mysqltest -@node MySQL test suite, , MySQL threads, MySQL internals -@section MySQL Test Suite - -Until recently, our main full-coverage test suite was based on proprietary -customer data and for that reason has not been publicly available. The only -publicly available part of our testing process consisted of the @code{crash-me} -test, a Perl DBI/DBD benchmark found in the @code{sql-bench} directory, and -miscellaneous tests located in @code{tests} directory. The lack of a -standardized publicly available test suite has made it difficult for our users, -as well developers, to do regression tests on the @strong{MySQL} code. To -address this problem, we have created a new test system that is included in -the source and binary distributions starting in Version 3.23.29. - -The current set of test cases doesn't test everything in @strong{MySQL}, but it -should catch most obvious bugs in the SQL processing code, OS/library -issues, and is quite thorough in testing replication. Our eventual goal -is to have the tests cover 100% of the code. We welcome contributions -to our test suite. You may especially want to contribute tests that -examine the functionality critical to your system, as this will ensure -that all future @strong{MySQL} releases will work well with your -applications. - -@menu -* running mysqltest:: -* extending mysqltest:: -* Reporting mysqltest bugs:: -@end menu - -@node running mysqltest, extending mysqltest, MySQL test suite, MySQL test suite -@subsection Running the MySQL Test Suite - -The test system consist of a test language interpreter -(@code{mysqltest}), a shell script to run all -tests(@code{mysql-test-run}), the actual test cases written in a special -test language, and their expected results. To run the test suite on -your system after a build, type @code{make test} or -@code{mysql-test/mysql-test-run} from the source root. If you have -installed a binary distribution, @code{cd} to the install root -(eg. @code{/usr/local/mysql}), and do @code{scripts/mysql-test-run}. -All tests should succeed. If not, you should try to find out why and -report the problem if this is a bug in @strong{MySQL}. -@xref{Reporting mysqltest bugs}. - -If you have a copy of @code{mysqld} running on the machine where you want to -run the test suite you do not have to stop it, as long as it is not using -ports @code{9306} and @code{9307}. If one of those ports is taken, you should -edit @code{mysql-test-run} and change the values of the master and/or slave -port to one that is available. - -You can run one individual test case with -@code{mysql-test/mysql-test-run test_name}. - -If one test fails, you should test running @code{mysql-test-run} with -the @code{--force} option to check if any other tests fails. - -@node extending mysqltest, Reporting mysqltest bugs, running mysqltest, MySQL test suite -@subsection Extending the MySQL Test Suite - -You can use the @code{mysqltest} language to write your own test cases. -Unfortunately, we have not yet written full documentation for it - we plan to -do this shortly. You can, however, look at our current test cases and use -them as an example. The following points should help you get started: - -@itemize +It's always good to use a machine with ECC memory to discover +memory problems early! @item -The tests are located in @code{mysql-test/t/*.test} +If your keyboard is locked up, you may be able to fix this by +logging into your machine from another machine and execute +@code{kbd_mode -a} on it. @item -A test case consists of @code{;} terminated statements and is similar to the -input of @code{mysql} command line client. A statement by default is a query -to be sent to @strong{MySQL} server, unless it is recognized as internal -command ( eg. @code{sleep} ). +Please examine your system log file (/var/log/messages or similar) for +reasons for your problems. If you think the problem is in @strong{MySQL} +then you should also examine @strong{MySQL}'s log files. @xref{Update log}. @item -All queries that produce results, e.g. @code{SELECT}, @code{SHOW}, -@code{EXPLAIN}, etc., must be preceded with @code{@@/path/to/result/file}. The -file must contain the expected results. An easy way to generate the result -file is to run @code{mysqltest -r < t/test-case-name.test} from -@code{mysql-test} directory, and then edit the generated result files, if -needed, to adjust them to the expected output. In that case, be very careful -about not adding or deleting any invisible characters - make sure to only -change the text and/or delete lines. If you have to insert a line, make sure -the fields are separated with a hard tab, and there is a hard tab at the end. -You may want to use @code{od -c} to make sure your text editor has not messed -anything up during edit. We, of course, hope that you will never have to edit -the output of @code{mysqltest -r} as you only have to do it when you find a -bug. +If you don't think you have hardware problems, you should try to find +out which program is causing problems. + +Try using @code{top}, @code{ps}, @code{taskmanager}, or some similar program, +to check which program is taking all CPU or is locking the machine. @item -To be consistent with our setup, you should put your result files in -@code{mysql-test/r} directory and name them @code{test_name.result}. If the -test produces more than one result, you should use @code{test_name.a.result}, -@code{test_name.b.result}, etc. +Check with @code{top}, @code{df}, or a similar program if you are out of +memory, disk space, open files, or some other critical resource. @item -If a statement returns an error, you should on the line before the statement -specify with the @code{--error error-number}. The error number can be -a list of possible error numbers separated with @code{','}. +If the problem is some runaway process, you can always try to kill it. If it +doesn't want to die, there is probably a bug in the operating system. +@end itemize + +If after you have examined all other possibilities and you have +concluded that it's the @strong{MySQL} server or a @strong{MySQL} client +that is causing the problem, it's time to do a bug report for our +mailing list or our support team. In the bug report, try to give a +very detailed description of how the system is behaving and what you think is +happening. You should also state why you think it's @strong{MySQL} that +is causing the problems. Take into consideration all the situations in +this chapter. State any problems exactly how they appear when you +examine your system. Use the 'cut and paste' method for any output +and/or error messages from programs and/or log files! + +Try to describe in detail which program is not working and all +symptoms you see! We have in the past received many bug reports that just +state "the system doesn't work". This doesn't provide us with any +information about what could be the problem. + +If a program fails, it's always useful to know: + +@itemize @bullet +@item +Has the program in question made a segmentation fault (core dumped)? +@item +Is the program taking the whole CPU? Check with @code{top}. Let the +program run for a while, it may be evaluating something heavy. +@item +If it's the @code{mysqld} server that is causing problems, can you +do @code{mysqladmin -u root ping} or @code{mysqladmin -u root processlist}? +@item +What does a client program say (try with @code{mysql}, for example) +when you try to connect to the @strong{MySQL} server? +Does the client jam? Do you get any output from the program? +@end itemize + +When sending a bug report, you should of follow the outlines +described in this manual. @xref{Asking questions}. + + +@node Crashing, Link errors, What is crashing, Problems +@appendixsec What to Do if MySQL Keeps Crashing + +@cindex crash, repeated + +All @strong{MySQL} versions are tested on many platforms before they are +released. This doesn't mean that there aren't any bugs in +@strong{MySQL}, but it means if there are bugs, they are very few and can be +hard to find. If you have a problem, it will always help if you try to +find out exactly what crashes your system, as you will have a much better +chance of getting this fixed quickly. + +First, you should try to find out whether the problem is that the +@code{mysqld} daemon dies or whether your problem has to do with your +client. You can check how long your @code{mysqld} server has been up by +executing @code{mysqladmin version}. If @code{mysqld} has died, you may +find the reason for this in the file +@file{mysql-data-directory/`hostname`.err}. @xref{Error log}. + +Many crashes of @strong{MySQL} are caused by corrupted index / data +files. @strong{MySQL} will update the data on disk, with the +@code{write()} system call, after every SQL statement and before the +client is notified about the result. (This is not true if you are running +with @code{delayed_key_writes}, in which case only the data is written.) +This means that the data is safe even if @code{mysqld} crashes, as the OS will +ensure that the not flushed data is written to disk. You can force +@strong{MySQL} to sync everything to disk after every SQL command by +starting @code{mysqld} with @code{--flush}. + +The above means that normally you shouldn't get corrupted tables unless: + +@itemize @bullet +@item +Someone/something killed @code{mysqld} or the machine in the middle +of an update. +@item +You have found a bug in @code{mysqld} that caused it to die in the +middle of an update. +@item +Someone is manipulating the data/index files outside of @strong{mysqld} +without locking the table properly. +@item +If you are running many @code{mysqld} servers on the same data on a +system that doesn't support good file system locks (normally handled by +the @code{lockd} daemon ) or if you are running +multiple servers with @code{--skip-locking} +@item +You have a crashed index/data file that contains very wrong data that +got @code{mysqld} confused. +@item +You have found a bug in the data storage code. This isn't that likely, +but it's at least possible. In this case you can try to change the file +type to another database handler by using @code{ALTER TABLE} on a +repaired copy of the table! +@end itemize + +Because it is very difficult to know why something is crashing, first try to +check whether or not things that work for others crash for you. Please try +the following things: + +@itemize @bullet +@item +Take down the @code{mysqld} daemon with @code{mysqladmin shutdown}, run +@code{myisamchk --silent --force */*.MYI} on all tables, and restart the +@code{mysqld} daemon. This will ensure that you are running from a clean +state. @xref{MySQL Database Administration}. @item -If you are writing a replication test case, you should on the first line of -the test file, put @code{source include/master-slave.inc;}. To switch between -master and slave, use @code{connection master;} and @code{connection slave;}. -If you need to do something on an alternate connection, you can do -@code{connection master1;} for the master, and @code{connection slave1;} for -the slave. +Use @code{mysqld --log} and try to determine from the information in the log +whether or not some specific query kills the server. About 95% of all bugs are +related to a particular query! Normally this is one of the last queries in +the log file just before @strong{MySQL} restarted. @xref{Query log}. +If you can repeatadly kill @strong{MySQL} with one of the queries, even +when you have checked all tables just before doing the query, then you +have been able to locate the bug and should do a bug report for this! +@xref{Bug reports}. @item -If you need to do something in a loop, you can use something like this: +Try to make a test case that we can use to reproduce the problem. +@xref{Reproduceable test case}. + +@item +Try running the included mysql-test test and the @strong{MySQL} +benchmarks. @xref{MySQL test suite}. They should test @strong{MySQL} +rather well. You can also add code that to the benchmarks to simulates +your application! The benchmarks can be found in the @file{bench} +directory in the source distribution or, for a binary distribution, in +the @file{sql-bench} directory under your @strong{MySQL} installation +directory. + +@item +Try @code{fork_test.pl} and @code{fork2_test.pl}. + +@item +If you configure @strong{MySQL} for debugging, it will be much easier to +gather information about possible errors if something goes wrong. +Reconfigure @strong{MySQL} with the @code{--with-debug} option or +@code{--with-debug=full} to @code{configure} and then recompile. +@xref{Debugging server}. + +@item +Configuring @strong{MySQL} for debugging causes a safe memory allocator to be +included that can find some errors. It also provides a lot of output about +what is happening. + +@item +Have you applied the latest patches for your operating system? + +@item +Use the @code{--skip-locking} option to @code{mysqld}. On some systems, the +@code{lockd} lock manager does not work properly; the @code{--skip-locking} +option tells @code{mysqld} not to use external locking. (This means that you +cannot run 2 @code{mysqld} servers on the same data and that you must be +careful if you use @code{myisamchk}, but it may be instructive to try the +option as a test.) + +@item +Have you tried @code{mysqladmin -u root processlist} when @code{mysqld} +appears to be running but not responding? Sometimes @code{mysqld} is not +comatose even though you might think so. The problem may be that all +connections are in use, or there may be some internal lock problem. +@code{mysqladmin processlist} will usually be able to make a connection even +in these cases, and can provide useful information about the current number +of connections and their status. + +@item +Run the command @code{mysqladmin -i 5 status} or @code{mysqladmin -i 5 +-r status} or in a separate window to produce statistics while you run +your other queries. + +@item +Try the following: +@enumerate +@item +Start @code{mysqld} from @code{gdb} (or in another debugger). +@xref{Using gdb on mysqld}. + +@item +Run your test scripts. + +@item +Print the backtrace and the local variables at the 3 lowest levels. In gdb you +can do this with the following commands when @code{mysqld} has crashed inside +gdb: + @example -let $1=1000; -while ($1) -@{ - # do your queries here - dec $1; -@} +backtrace +info local +up +info local +up +info local @end example -@item -To sleep between queries, use the @code{sleep} command. It supports fractions -of a second, so you can do @code{sleep 1.3;}, for example, to sleep 1.3 -seconds. +With gdb you can also examine which threads exist with @code{info +threads} and switch to a specific thread with @code{thread #}, where +@code{#} is the thread id. +@end enumerate @item -To run the slave with additional options for your test case, put them -in the command-line format in @code{mysql-test/t/test_name-slave.opt}. For -the master, put them in @code{mysql-test/t/test_name-master.opt}. +Try to simulate your application with a Perl script to force +@strong{MySQL} to crash or misbehave. @item -If you have a question about the test suite, or have a test case to contribute, -e-mail to @email{internals@@lists.mysql.com}. As the list does not accept -attachments, you should ftp all the relevant files to: -@url{ftp://support.mysql.com/pub/mysql/Incoming} +Send a normal bug report. @xref{Bug reports}. Be even more detailed +than usual. Because @strong{MySQL} works for many people, it may be that the +crash results from something that exists only on your computer (for example, +an error that is related to your particular system libraries). +@item +If you have a problem with tables with dynamic-length rows and you are +not using @code{BLOB/TEXT} columns (but only @code{VARCHAR} columns), you +can try to change all @code{VARCHAR} to @code{CHAR} with @code{ALTER +TABLE}. This will force @strong{MySQL} to use fixed-size rows. +Fixed-size rows take a little extra space, but are much more tolerant to +corruption! +The current dynamic row code has been in use at @strong{MySQL AB} for at +least 3 years without any problems, but by nature dynamic-length rows are +more prone to errors, so it may be a good idea to try the above to see if +it helps! @end itemize -@node Reporting mysqltest bugs, , extending mysqltest, MySQL test suite -@subsection Reporting bugs in the MySQL Test Suite -If your @strong{MySQL} version doesn't pass the test suite you should +@node Link errors, Common errors, Crashing, Problems +@appendixsec Problems When Linking with the MySQL Client Library + +@cindex linking, errors +@cindex errors, linking +@cindex problems, linking + +If you are linking your program and you get errors for unreferenced +symbols that start with @code{mysql_}, like the following: + +@example +/tmp/ccFKsdPa.o: In function `main': +/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init' +/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect' +/tmp/ccFKsdPa.o(.text+0x57): undefined reference to `mysql_real_connect' +/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error' +/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close' +@end example + +you should be able to solve this by adding @code{-Lpath-to-the-mysql-library +-lmysqlclient} @strong{LAST} on your link line. + +If you get @code{undefined reference} errors for the @code{uncompress} +or @code{compress} function, add @code{-lz} @strong{LAST} on your link +line and try again! + +If you get @code{undefined reference} errors for functions that should +exist on your system, like @code{connect}, check the man page for the +function in question, for which libraries you should add to the link +line! + +If you get @code{undefined reference} errors for functions that don't +exist on your system, like the following: + +@example +mf_format.o(.text+0x201): undefined reference to `__lxstat' +@end example + +it usually means that your library is compiled on a system that is not +100 % compatible with yours. In this case you should download the +latest @strong{MySQL} source distribution and compile this yourself. +@xref{Installing source}. + +If you are trying to run a program and you then get errors for +unreferenced symbols that start with @code{mysql_} or that the +@code{mysqlclient} library can't be found, this means that your system +can't find the share @code{libmysqlclient.so} library. + +The fix for this is to tell your system to search after shared +libraries where the library is located by one of the following methods: + +@itemize @bullet +@item +Add the path to the directory where you have @code{libmysqlclient.so} the +@code{LD_LIBRARY_PATH} environment variable. +@item +Add the path to the directory where you have @code{libmysqlclient.so} the +@code{LD_LIBRARY} environment variable. +@item +Copy @code{libmysqlclient.so} to some place that is searched by your system, +like @file{/lib}, and update the shared library information by executing +@code{ldconfig}. +@end itemize + +Another way to solve this problem is to link your program statically, with +@code{-static}, or by removing the dynamic @strong{MySQL} libraries +before linking your code. In the second case you should be +sure that no other programs are using the dynamic libraries! + + +@node Common errors, Full disk, Link errors, Problems +@appendixsec Some Common Errors When Using MySQL + +@cindex errors, list of + +@menu +* Error Access denied:: @code{Access denied} Error +* Gone away:: @code{MySQL server has gone away} error +* Can not connect to server:: @code{Can't connect to [local] MySQL server} error +* Blocked host:: @code{Host '...' is blocked} error +* Too many connections:: @code{Too many connections} error +* Non-transactional tables:: @code{Some non-transactional changed tables couldn't be rolled back} Error +* Out of memory:: @code{Out of memory} error +* Packet too large:: @code{Packet too large} error +* Communication errors:: Communication errors / Aborted connection +* Full table:: @code{The table is full} error +* Cannot create:: @code{Can't create/write to file} Error +* Commands out of sync:: @code{Commands out of sync} error in client +* Ignoring user:: @code{Ignoring user} error +* Cannot find table:: @code{Table 'xxx' doesn't exist} error +* Cannot initialize character set:: +@end menu + + +This section lists some errors that users frequently get. You will find +descriptions of the errors, and how to solve the problem here. + + +@node Error Access denied, Gone away, Common errors, Common errors +@appendixsubsec @code{Access denied} Error + +@cindex errors, access denied +@cindex problems, access denied errors +@cindex access denied errors + +@xref{Privileges}, and especially. @xref{Access denied}. + + +@node Gone away, Can not connect to server, Error Access denied, Common errors +@appendixsubsec @code{MySQL server has gone away} Error + +This section also covers the related @code{Lost connection to server +during query} error. + +The most common reason for the @code{MySQL server has gone away} error +is that the server timed out and closed the connection. By default, the +server closes the connection after 8 hours if nothing has happened. You +can change the time limit by setting the @code{wait_timeout} variable when +you start @code{mysqld}. + +Another common reason to receive the @code{MySQL server has gone away} error +is because you have issued a ``close'' on your @strong{MySQL} connection +and then tried to run a query on the closed connection. + +You can check that the @strong{MySQL} hasn't died by executing +@code{mysqladmin version} and examining the uptime. + +If you have a script, you just have to issue the query again for the client +to do an automatic reconnection. + +You normally can get the following error codes in this case +(which one you get is OS-dependent): + +@multitable @columnfractions .3 .7 +@item @code{CR_SERVER_GONE_ERROR} @tab The client couldn't send a question to the +server. +@item @code{CR_SERVER_LOST} @tab The client didn't get an error when writing +to the server, but it didn't get a full answer (or any answer) to the question. +@end multitable + +You can also get these errors if you send a query to the server that is +incorrect or too large. If @code{mysqld} gets a packet that is too large +or out of order, it assumes that something has gone wrong with the client and +closes the connection. If you need big queries (for example, if you are +working with big @code{BLOB} columns), you can increase the query limit by +starting @code{mysqld} with the @code{-O max_allowed_packet=#} option +(default 1M). The extra memory is allocated on demand, so @code{mysqld} will +use more memory only when you issue a big query or when @code{mysqld} must +return a big result row! + + +@node Can not connect to server, Blocked host, Gone away, Common errors +@appendixsubsec @code{Can't connect to [local] MySQL server} error + +A @strong{MySQL} client on Unix can connect to the @code{mysqld} server in two +different ways: Unix sockets, which connect through a file in the file +system (default @file{/tmp/mysqld.sock}) or TCP/IP, which connects +through a port number. Unix sockets are faster than TCP/IP but can only +be used when connecting to a server on the same computer. Unix sockets +are used if you don't specify a hostname or if you specify the special +hostname @code{localhost}. + +On Windows you can connect only with TCP/IP if the @code{mysqld} server +is running on Win95/Win98. If it's running on NT, you can also connect +with named pipes. The name of the named pipe is @strong{MySQL}. If you +don't give a hostname when connecting to @code{mysqld}, a @strong{MySQL} client +will first try to connect to the named pipe, and if this doesn't work it +will connect to the TCP/IP port. You can force the use of named pipes +on Windows by using @code{.} as the hostname. + +The error (2002) @code{Can't connect to ...} normally means that there +isn't a @strong{MySQL} server running on the system or that you are +using a wrong socket file or TCP/IP port when trying to connect to the +@code{mysqld} server. + +Start by checking (using @code{ps} or the task manager on Windows) that +there is a process running named @code{mysqld} on your server! If there +isn't any @code{mysqld} process, you should start one. @xref{Starting +server}. + +If a @code{mysqld} process is running, you can check the server by +trying these different connections (the port number and socket pathname +might be different in your setup, of course): + +@example +shell> mysqladmin version +shell> mysqladmin variables +shell> mysqladmin -h `hostname` version variables +shell> mysqladmin -h `hostname` --port=3306 version +shell> mysqladmin -h 'ip for your host' version +shell> mysqladmin --socket=/tmp/mysql.sock version +@end example + +Note the use of backquotes rather than forward quotes with the @code{hostname} +command; these cause the output of @code{hostname} (that is, the current +hostname) to be substituted into the @code{mysqladmin} command. + +Here are some reasons the @code{Can't connect to local MySQL server} +error might occur: + +@itemize @bullet +@item +@code{mysqld} is not running. +@item +You are running on a system that uses MIT-pthreads. +If you are running on a system that doesn't have native threads, +@code{mysqld} uses the MIT-pthreads package. @xref{Which OS}. However, +all MIT-pthreads versions doesn't support Unix sockets. On a system +without sockets support you must always specify the hostname explicitly +when connecting to the server. Try using this command to check the +connection to the server: +@example +shell> mysqladmin -h `hostname` version +@end example +@item +Someone has removed the Unix socket that @code{mysqld} uses (default +@file{/tmp/mysqld.sock}). You might have a @code{cron} job that removes +the @strong{MySQL} socket (for example, a job that removes old files +from the @file{/tmp} directory). You can always run @code{mysqladmin +version} and check that the socket @code{mysqladmin} is trying to use +really exists. The fix in this case is to change the @code{cron} job to +not remove @file{mysqld.sock} or to place the socket somewhere else. You +can specify a different socket location at @strong{MySQL} configuration +time with this command: +@example +shell> ./configure --with-unix-socket-path=/path/to/socket +@end example +You can also start @code{safe_mysqld} with the +@code{--socket=/path/to/socket} option and set the environment variable +@code{MYSQL_UNIX_PORT} to the socket pathname before starting your +@strong{MySQL} clients. +@item +You have started the @code{mysqld} server with +the @code{--socket=/path/to/socket} option. If you change the socket +pathname for the server, you must also notify the @strong{MySQL} clients +about the new path. You can do this by setting the environment variable +@code{MYSQL_UNIX_PORT} to the socket pathname or by providing the socket path +as an argument to the clients. You can test the socket with this command: + +@example +shell> mysqladmin --socket=/path/to/socket version +@end example +@item +You are using Linux and one thread has died (core dumped). In this case +you must kill the other @code{mysqld} threads (for example, with the +@code{mysql_zap} script before you can start a new @strong{MySQL} +server. @xref{Crashing}. +@item +You may not have read and write privilege to either the directory that holds +the socket file or privilege to the socket file itself. In this case you +have to either change the privilege for the directory / file or restart +@code{mysqld} so that it uses a directory that you can access. +@end itemize + +If you get the error message @code{Can't connect to MySQL server on +some_hostname}, you can try the following things to find out what the +problem is : + +@itemize @bullet +@item +Check if the server is up by doing @code{telnet your-host-name +tcp-ip-port-number} and press @code{RETURN} a couple of times. If there +is a @strong{MySQL} server running on this port you should get a +responses that includes the version number of the running @strong{MySQL} +server. If you get an error like @code{telnet: Unable to connect to +remote host: Connection refused}, then there is no server running on the +given port. +@item +Try connecting to the @code{mysqld} daemon on the local machine and check +the TCP/IP port that @code{mysqld} it's configured to use (variable @code{port}) with +@code{mysqladmin variables}. +@item +Check that your @code{mysqld} server is not started with the +@code{--skip-networking} option. +@end itemize + + +@node Blocked host, Too many connections, Can not connect to server, Common errors +@appendixsubsec @code{Host '...' is blocked} Error + +If you get an error like this: + +@example +Host 'hostname' is blocked because of many connection errors. +Unblock with 'mysqladmin flush-hosts' +@end example + +this means that @code{mysqld} has gotten a lot (@code{max_connect_errors}) +of connect requests from the host @code{'hostname'} that have been interrupted +in the middle. After @code{max_connect_errors} failed requests, @code{mysqld} +assumes that something is wrong (like an attack from a cracker), and +blocks the site from further connections until someone executes the command +@code{mysqladmin flush-hosts}. + +By default, @code{mysqld} blocks a host after 10 connection errors. +You can easily adjust this by starting the server like this: + +@example +shell> safe_mysqld -O max_connect_errors=10000 & +@end example + +Note that if you get this error message for a given host, you should first +check that there isn't anything wrong with TCP/IP connections from that +host. If your TCP/IP connections aren't working, it won't do you any good to +increase the value of the @code{max_connect_errors} variable! + + +@node Too many connections, Non-transactional tables, Blocked host, Common errors +@appendixsubsec @code{Too many connections} Error + +If you get the error @code{Too many connections} when you try to connect +to @strong{MySQL}, this means that there is already @code{max_connections} +clients connected to the @code{mysqld} server. + +If you need more connections than the default (100), then you should restart +@code{mysqld} with a bigger value for the @code{max_connections} variable. + +Note that @code{mysqld} actually allows (@code{max_connections}+1) +clients to connect. The last connection is reserved for a user with the +@strong{process} privilege. By not giving this privilege to normal +users (they shouldn't need this), an administrator with this privilege +can log in and use @code{SHOW PROCESSLIST} to find out what could be +wrong. @xref{SHOW}. + +The maximum number of connects @strong{MySQL} is depending on how good +the thread library is on a given platform. Linux or Solaris should be +able to support 500-1000 simultaneous connections, depending on how much +RAM you have and what your clients are doing. + +@node Non-transactional tables, Out of memory, Too many connections, Common errors +@appendixsubsec @code{Some non-transactional changed tables couldn't be rolled back} Error + +@cindex Non-transactional tables + +If you get the error/warning: @code{Warning: Some non-transactional +changed tables couldn't be rolled back} when trying to do a +@code{ROLLBACK}, this means that some of the tables you used in the +transaction didn't support transactions. These non-transactional tables +will not be affected by the @code{ROLLBACK} statement. + +The most typical case when this happens is when you have tried to create +a table of a type that is not supported by your @code{mysqld} binary. +If @code{mysqld} doesn't support a table type (or if the table type is +disabled by a startup option) , it will instead create the table type +with the table type that is most resembles to the one you requested, +probably @code{MyISAM}. + +You can check the table type for a table by doing: + +@code{SHOW TABLE STATUS LIKE 'table_name'}. @xref{SHOW TABLE STATUS}. + +You can check the extensions your @code{mysqld} binary supports by doing: + +@code{show variables like 'have_%'}. @xref{SHOW VARIABLES}. + + +@node Out of memory, Packet too large, Non-transactional tables, Common errors +@appendixsubsec @code{Out of memory} Error + +If you issue a query and get something like the following error: + +@example +mysql: Out of memory at line 42, 'malloc.c' +mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k) +ERROR 2008: MySQL client ran out of memory +@end example + +note that the error refers to the @strong{MySQL} client @code{mysql}. The +reason for this error is simply that the client does not have enough memory to +store the whole result. + +To remedy the problem, first check that your query is correct. Is it +reasonable that it should return so many rows? If so, +you can use @code{mysql --quick}, which uses @code{mysql_use_result()} +to retrieve the result set. This places less of a load on the client (but +more on the server). + + +@node Packet too large, Communication errors, Out of memory, Common errors +@appendixsubsec @code{Packet too large} Error + +When a @strong{MySQL} client or the @code{mysqld} server gets a packet bigger +than @code{max_allowed_packet} bytes, it issues a @code{Packet too large} +error and closes the connection. + +If you are using the @code{mysql} client, you may specify a bigger buffer by +starting the client with @code{mysql --set-variable=max_allowed_packet=8M}. + +If you are using other clients that do not allow you to specify the maximum +packet size (such as @code{DBI}), you need to set the packet size when you +start the server. You cau use a command-line option to @code{mysqld} to set +@code{max_allowed_packet} to a larger size. For example, if you are +expecting to store the full length of a @code{BLOB} into a table, you'll need +to start the server with the @code{--set-variable=max_allowed_packet=16M} +option. + + +@node Communication errors, Full table, Packet too large, Common errors +@appendixsubsec Communication Errors / Aborted Connection + +@cindex aborted clients +@cindex aborted connection +@cindex connection, aborted + +Starting with @code{MySQL 3.23.40} you only get the @code{Aborted +connection} error of you start @code{mysqld} with @code{--warnings}. + +If you find errors like the following in your error log. + +@example +010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh' +@end example + +@xref{Error log}. + +This means that something of the following has happened: + +@itemize @bullet +@item +The client program did not call @code{mysql_close()} before exit. +@item +The client had been sleeping more than @code{wait_timeout} or +@code{interactive_timeout} without doing any requests. @xref{SHOW +VARIABLES}. +@item +The client program ended abruptly in the middle of the transfer. +@end itemize + +When the above happens, the server variable @code{Aborted_clients} is +incremented. + +The server variable @code{Aborted_connects} is incremented when: + +@itemize @bullet +@item +When a connection packet doesn't contain the right information. +@item +When the user didn't have privileges to connect to a database. +@item +When a user uses a wrong password. +@item +When it takes more than @code{connect_timeout} seconds to get +a connect package. +@end itemize + +Note that the above could indicate that someone is trying to break into +your database! + +@xref{SHOW VARIABLES}. + +Other reasons for problems with Aborted clients / Aborted connections. +@itemize @bullet +@item +Usage of duplex Ethernet protocol, both half and full with +Linux. Many Linux Ethernet drivers have this bug. You should test +for this bug by transferring a huge file via ftp between these two +machines. If a transfer goes in burst-pause-burst-pause ... mode then +you are experiencing a Linux duplex syndrome. The only solution to +this problem is switching of both half and full duplexing on hubs +and switches. +@item +Some problem with the thread library that causes interrupts on reads. +@item +Badly configured TCP/IP. +@item +Faulty Ethernets or hubs or switches, cables ... This can be diagnosed +properly only by replacing hardware. +@end itemize + + +@node Full table, Cannot create, Communication errors, Common errors +@appendixsubsec @code{The table is full} Error + +@cindex table is full + +This error occurs in older @strong{MySQL} versions when an in-memory temporary +table becomes larger than @code{tmp_table_size} bytes. To avoid this +problem, you can use the @code{-O tmp_table_size=#} option to +@code{mysqld} to increase the temporary table size or use the SQL +option @code{SQL_BIG_TABLES} before you issue the problematic +query. @xref{SET OPTION, , @code{SET OPTION}}. + +You can also start @code{mysqld} with the @code{--big-tables} option. +This is exactly the same as using @code{SQL_BIG_TABLES} for all queries. + +In @strong{MySQL} Version 3.23, in-memory temporary tables will automatically be +converted to a disk-based @code{MyISAM} table after the table size gets +bigger than @code{tmp_table_size}. + + +@node Cannot create, Commands out of sync, Full table, Common errors +@appendixsubsec @code{Can't create/write to file} Error + +@cindex can't create/write to file + +If you get an error for some queries of type: + +@example +Can't create/write to file '\\sqla3fe_0.ism'. +@end example + +this means that @strong{MySQL} can't create a temporary file for the +result set in the given temporary directory. (The above error is a +typical error message on Windows, and the Unix error message is similar.) +The fix is to start @code{mysqld} with @code{--tmpdir=path} or to add to your option +file: + +@example +[mysqld] +tmpdir=C:/temp +@end example + +assuming that the @file{c:\\temp} directory exists. @xref{Option files}. + +Check also the error code that you get with @code{perror}. One reason +may also be a disk full error; + +@example +shell> perror 28 +Error code 28: No space left on device +@end example + + +@node Commands out of sync, Ignoring user, Cannot create, Common errors +@appendixsubsec @code{Commands out of sync} Error in Client + +@cindex commands out of sync + +If you get @code{Commands out of sync; You can't run this command now} +in your client code, you are calling client functions in the wrong order! + +This can happen, for example, if you are using @code{mysql_use_result()} and +try to execute a new query before you have called @code{mysql_free_result()}. +It can also happen if you try to execute two queries that return data without +a @code{mysql_use_result()} or @code{mysql_store_result()} in between. + + +@node Ignoring user, Cannot find table, Commands out of sync, Common errors +@appendixsubsec @code{Ignoring user} Error + +If you get the following error: + +@code{Found wrong password for user: 'some_user@@some_host'; Ignoring user} + +this means that when @code{mysqld} was started or when it reloaded the +permissions tables, it found an entry in the @code{user} table with +an invalid password. As a result, the entry is simply ignored by the +permission system. + +Possible causes of and fixes for this problem: + +@itemize @bullet +@item +You may be running a new version of @code{mysqld} with an old +@code{user} table. +You can check this by executing @code{mysqlshow mysql user} to see if +the password field is shorter than 16 characters. If so, you can correct this +condition by running the @code{scripts/add_long_password} script. + +@item +The user has an old password (8 characters long) and you didn't start +@code{mysqld} with the @code{--old-protocol} option. +Update the user in the @code{user} table with a new password or +restart @code{mysqld} with @code{--old-protocol}. + +@item +@findex PASSWORD() +You have specified a password in the @code{user} table without using the +@code{PASSWORD()} function. Use @code{mysql} to update the user in the +@code{user} table with a new password. Make sure to use the @code{PASSWORD()} +function: + +@example +mysql> update user set password=PASSWORD('your password') + where user='XXX'; +@end example +@end itemize + + +@node Cannot find table, Cannot initialize character set, Ignoring user, Common errors +@appendixsubsec @code{Table 'xxx' doesn't exist} Error + +If you get the error @code{Table 'xxx' doesn't exist} or @code{Can't +find file: 'xxx' (errno: 2)}, this means that no table exists +in the current database with the name @code{xxx}. + +Note that as @strong{MySQL} uses directories and files to store databases and +tables, the database and table names are @strong{case sensitive}! +(On Windows the databases and tables names are not case sensitive, but all +references to a given table within a query must use the same case!) + +You can check which tables you have in the current database with +@code{SHOW TABLES}. @xref{SHOW, , @code{SHOW}}. + + +@node Cannot initialize character set, , Cannot find table, Common errors +@appendixsubsec @code{Can@'t initialize character set xxx} error. + +@cindex multibyte character sets + +If you get an error like: + +@example +MySQL Connection Failed: Can't initialize character set xxx +@end example + +This means one of the following things: + +@itemize @bullet +@item +The character set is a multi-byte character set and you have not support +for the character set in the client. + +In this case you need to recompile the client with +@code{--with-charset=xxx} or with @code{--with-extra-charsets=xxx}. +@xref{configure options}. + +All standard @strong{MySQL} binaries are compiled with +@code{--with-extra-character-sets=complex} which will enable support for +all multi-byte character sets. @xref{Character sets}. + +@item +The character set is a simple character set which is not compiled into +@code{mysqld} and the character set definition files is not in the place +where the client expect to find them. + +In this case you need to: + +@itemize @bullet +@item +Recompile the client with support for the character set. +@xref{configure options}. +@item +Specify to the client where the character set definition files are. For many +client you can do this with the +@code{--character-sets-dir=path-to-charset-dir} option. +@item +Copy the character definition files to the path where the client expect them +to be. +@end itemize +@end itemize + + +@node Full disk, Temporary files, Common errors, Problems +@appendixsec How MySQL Handles a Full Disk + +@cindex full disk +@cindex disk full + +@noindent +When a disk-full condition occurs, @strong{MySQL} does the following: + +@itemize @bullet +@item +It checks once every minute to see whether or not there is enough space to +write the current row. If there is enough space, it continues as if nothing had +happened. +@item +Every 6 minutes it writes an entry to the log file warning about the disk +full condition. +@end itemize + +@noindent +To alleviate the problem, you can take the following actions: + +@itemize @bullet +@item +To continue, you only have to free enough disk space to insert all records. +@item +To abort the thread, you must send a @code{mysqladmin kill} to the thread. +The thread will be aborted the next time it checks the disk (in 1 minute). +@item +Note that other threads may be waiting for the table that caused the disk +full condition. If you have several ``locked'' threads, killing the one +thread that is waiting on the disk-full condition will allow the other +threads to continue. +@end itemize + +Exceptions to the above behaveour is when you use @code{REPAIR} or +@code{OPTIMIZE} or when the indexes are created in a batch after an +@code{LOAD DATA INFILE} or after an @code{ALTER TABLE} statement. + +All of the above commands may use big temporary files that left to +themself would cause big problems for the rest of the system. If +@strong{MySQL} gets disk full while doing any of the above operations, +it will remove the big temporary files and mark the table as crashed +(except for @code{ALTER TABLE}, in which the old table will be left +unchanged). + + +@node Temporary files, Problems with mysql.sock, Full disk, Problems +@appendixsec Where MySQL Stores Temporary Files + +@strong{MySQL} uses the value of the @code{TMPDIR} environment variable as +the pathname of the directory in which to store temporary files. If you don't +have @code{TMPDIR} set, @strong{MySQL} uses the system default, which is +normally @file{/tmp} or @file{/usr/tmp}. If the file system containing your +temporary file directory is too small, you should edit @code{safe_mysqld} to +set @code{TMPDIR} to point to a directory in a file system where you have +enough space! You can also set the temporary directory using the +@code{--tmpdir} option to @code{mysqld}. + +@strong{MySQL} creates all temporary files as hidden files. This ensures +that the temporary files will be removed if @code{mysqld} is terminated. The +disadvantage of using hidden files is that you will not see a big temporary +file that fills up the file system in which the temporary file directory is +located. + +When sorting (@code{ORDER BY} or @code{GROUP BY}), @strong{MySQL} normally +uses one or two temporary files. The maximum disk-space needed is: + +@example +(length of what is sorted + sizeof(database pointer)) +* number of matched rows +* 2 +@end example + +@code{sizeof(database pointer)} is usually 4, but may grow in the future for +really big tables. + +For some @code{SELECT} queries, @strong{MySQL} also creates temporary SQL +tables. These are not hidden and have names of the form @file{SQL_*}. + +@code{ALTER TABLE} creates a temporary table in the same directory as +the original table. + + +@node Problems with mysql.sock, Changing MySQL user, Temporary files, Problems +@appendixsec How to Protect @file{/tmp/mysql.sock} from Being Deleted + +@cindex @code{mysql.sock}, protection +@cindex deletion, @code{mysql.sock} + +If you have problems with the fact that anyone can delete the +@strong{MySQL} communication socket @file{/tmp/mysql.sock}, you can, +on most versions of Unix, protect your @file{/tmp} file system by setting +the @code{sticky} bit on it. Log in as @code{root} and do the following: + +@example +shell> chmod +t /tmp +@end example + +This will protect your @file{/tmp} file system so that files can be deleted +only by their owners or the superuser (@code{root}). + +You can check if the @code{sticky} bit is set by executing @code{ls -ld /tmp}. +If the last permission bit is @code{t}, the bit is set. + + +@node Changing MySQL user, Resetting permissions, Problems with mysql.sock, Problems +@appendixsec How to Run MySQL As a Normal User + +@cindex starting, @code{mysqld} +@cindex @code{mysqld}, starting + +The @strong{MySQL} server @code{mysqld} can be started and run by any user. +In order to change @code{mysqld} to run as a Unix user @code{user_name}, you must do the following: -@itemize @bullet +@enumerate @item -Don't send a bug report before you have found out as much as possible of -what when wrong! When you do it, please use the @code{mysqlbug} script -so that we can get information about your system and @code{MySQL} -version. @xref{Bug reports}. +Stop the server if it's running (use @code{mysqladmin shutdown}). + @item -Make sure to include the output of @code{mysql-test-run}, as well as -contents of all @code{.reject} files in @code{mysql-test/r} directory. -@item -If a test in the test suite fails, check if the test fails also when run -by its own: +Change the database directories and files so that @code{user_name} has +privileges to read and write files in them (you may need to do this as +the Unix @code{root} user): @example -cd mysql-test -mysql-test-run --local test-name +shell> chown -R user_name /path/to/mysql/datadir @end example -If this fails, then you should configure @strong{MySQL} with -@code{--with-debug} and run @code{mysql-test-run} with the -@code{--debug} option. If this also fails send the trace file -@file{var/tmp/master.trace} to ftp://support.mysql.com/pub/mysql/secret -so that we can examine it. Please remember to also include a full -description of your system, the version of the mysqld binary and how you -compiled it. +If directories or files within the @strong{MySQL} data directory are +symlinks, you'll also need to follow those links and change the directories +and files they point to. @code{chown -R} may not follow symlinks for +you. @item -Try also to run @code{mysql-test-run} with the @code{--force} option to -see if there is any other test that fails. +Start the server as user @code{user_name}, or, if you are using +@strong{MySQL} Version 3.22 or later, start @code{mysqld} as the Unix @code{root} +user and use the @code{--user=user_name} option. @code{mysqld} will switch +to run as the Unix user @code{user_name} before accepting any connections. @item -If you have compiled @strong{MySQL} yourself, check our manual for how -to compile @strong{MySQL} on your platform or, preferable, use one of -the binaries we have compiled for you at -@uref{http://www.mysql.com/downloads/}. All our standard binaries should -pass the test suite ! +To start the server as the given user name automatically at system +startup time, add a @code{user} line that specifies the user name to +the @code{[mysqld]} group of the @file{/etc/my.cnf} option file or the +@file{my.cnf} option file in the server's data directory. For example: + +@example +[mysqld] +user=user_name +@end example +@end enumerate + +At this point, your @code{mysqld} process should be running fine and dandy as +the Unix user @code{user_name}. One thing hasn't changed, though: the +contents of the permissions tables. By default (right after running the +permissions table install script @code{mysql_install_db}), the @strong{MySQL} +user @code{root} is the only user with permission to access the @code{mysql} +database or to create or drop databases. Unless you have changed those +permissions, they still hold. This shouldn't stop you from accessing +@strong{MySQL} as the @strong{MySQL} @code{root} user when you're logged in +as a Unix user other than @code{root}; just specify the @code{-u root} option +to the client program. + +Note that accessing @strong{MySQL} as @code{root}, by supplying @code{-u +root} on the command line, has @emph{nothing} to do with @strong{MySQL} running +as the Unix @code{root} user, or, indeed, as another Unix user. The access +permissions and user names of @strong{MySQL} are completely separate from +Unix user names. The only connection with Unix user names is that if you +don't provide a @code{-u} option when you invoke a client program, the client +will try to connect using your Unix login name as your @strong{MySQL} user +name. + +If your Unix box itself isn't secured, you should probably at least put a +password on the @strong{MySQL} @code{root} users in the access tables. +Otherwise, any user with an account on that machine can run @code{mysql -u +root db_name} and do whatever he likes. + + +@node Resetting permissions, File permissions , Changing MySQL user, Problems +@appendixsec How to Reset a Forgotten Password + +@cindex passwords, forgotten +@cindex passwords, resetting +@cindex root user, password resetting + +If you have forgotten the @code{root} user password for @strong{MySQL}, you +can restore it with the following procedure: + +@enumerate +@item +Take down the @code{mysqld} server by sending a @code{kill} (not @code{kill +-9}) to the @code{mysqld} server. The pid is stored in a @code{.pid} +file, which is normally in the @strong{MySQL} database directory: + +@example +kill `cat /mysql-data-directory/hostname.pid` +@end example + +You must be either the Unix @code{root} user or the same user the server +runs as to do this. @item -If you get an error, like @code{Result length mismatch} or @code{Result -content mismatch} it means that the output of the test didn't match -exactly the expected output. This could be a bug in @strong{MySQL} or -that your mysqld version produces slight different results under some -circumstances. +Restart @code{mysqld} with the @code{--skip-grant-tables} option. +@item +Connect to the @code{mysqld} server with @code{mysql -h hostname mysql} and change +the password with a @code{GRANT} command. @xref{GRANT,,@code{GRANT}}. +You can also do this with +@code{mysqladmin -h hostname -u user password 'new password'} +@item +Load the privilege tables with: @code{mysqladmin -h hostname +flush-privileges} or with the SQL command @code{FLUSH PRIVILEGES}. +@end enumerate -Failed test results are put in a file with the same base name as the -result file with the @code{.reject} extension. If your test case is -failing, you should do a diff on the two files. If you cannot see how -they are different, examine both with @code{od -c} and also check their -lengths. +Note that after you started @code{mysqld} with @code{--skip-grant-tables}, +any usage of @code{GRANT} commands will give you an @code{Unknown command} +error until you have executed @code{FLUSH PRIVILEGES}. + + +@node File permissions , Not enough file handles, Resetting permissions, Problems +@appendixsec Problems with File Permissions + +@cindex files, permissions +@cindex error mesaages, can't find file +@cindex files, not found message + +If you have problems with file permissions, for example, if @code{mysql} +issues the following error message when you create a table: + +@example +ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13) +@end example + +@tindex UMASK environment variable +@tindex Environment variable, UMASK +then the environment variable @code{UMASK} might be set incorrectly when +@code{mysqld} starts up. The default umask value is @code{0660}. You can +change this behavior by starting @code{safe_mysqld} as follows: + +@example +shell> UMASK=384 # = 600 in octal +shell> export UMASK +shell> /path/to/safe_mysqld & +@end example + +@tindex UMASK_DIR environment variable +@tindex Environment variable, UMASK_DIR +By default @strong{MySQL} will create database and @code{RAID} +directories with permission type 0700. You can modify this behavior by +setting the @code{UMASK_DIR} variable. If you set this, new +directories are created with the combined @code{UMASK} and +@code{UMASK_DIR}. For example, if you want to give group access to +all new directories, you can do: + +@example +shell> UMASK_DIR=504 # = 770 in octal +shell> export UMASK_DIR +shell> /path/to/safe_mysqld & +@end example + +In @strong{MySQL} Version 3.23.25 and above, @strong{MySQL} assumes that the +value for @code{UMASK} and @code{UMASK_DIR} is in octal if it starts +with a zero. + +@xref{Environment variables}. + + +@node Not enough file handles, Using DATE, File permissions , Problems +@appendixsec File Not Found + +If you get @code{ERROR '...' not found (errno: 23)}, @code{Can't open +file: ... (errno: 24)}, or any other error with @code{errno 23} or +@code{errno 24} from @strong{MySQL}, it means that you haven't allocated +enough file descriptors for @strong{MySQL}. You can use the +@code{perror} utility to get a description of what the error number +means: + +@example +shell> perror 23 +File table overflow +shell> perror 24 +Too many open files +shell> perror 11 +Resource temporarily unavailable +@end example + +The problem here is that @code{mysqld} is trying to keep open too many +files simultaneously. You can either tell @code{mysqld} not to open so +many files at once or increase the number of file descriptors +available to @code{mysqld}. + +To tell @code{mysqld} to keep open fewer files at a time, you can make +the table cache smaller by using the @code{-O table_cache=32} option to +@code{safe_mysqld} (the default value is 64). Reducing the value of +@code{max_connections} will also reduce the number of open files (the +default value is 90). + +@tindex ulimit +To change the number of file descriptors available to @code{mysqld}, you +can use the option @code{--open-files-limit=#} to @code{safe_mysqld} or +@code{-O open-files-limit=#} to @code{mysqld}. @xref{SHOW VARIABLES}. +The easiest way to do that is to add the option to your option file. +@xref{Option files}. If you have an old @code{mysqld} version that +doesn't support this, you can edit the @code{safe_mysqld} script. There +is a commented-out line @code{ulimit -n 256} in the script. You can +remove the @code{'#'} character to uncomment this line, and change the +number 256 to affect the number of file descriptors available to +@code{mysqld}. + +@code{ulimit} (and @code{open-files-limit}) can increase the number of +file descriptors, but only up to the limit imposed by the operating +system. There is also a 'hard' limit that can only be overrided if you +start @code{safe_mysqld} or @code{mysqld} as root (Just remember that +you need to also use the @code{--user=..} option in this case). If you +need to increase the OS limit on the number of file descriptors +available to each process, consult the documentation for your operating +system. + +Note that if you run the @code{tcsh} shell, @code{ulimit} will not work! +@code{tcsh} will also report incorrect values when you ask for the current +limits! In this case you should start @code{safe_mysqld} with @code{sh}! + + +@node Using DATE, Timezone problems, Not enough file handles, Problems +@appendixsec Problems Using @code{DATE} Columns + +@findex DATE + +@cindex DATE columns, problems +@cindex problems, @code{DATE} columns + +The format of a @code{DATE} value is @code{'YYYY-MM-DD'}. According to ANSI +SQL, no other format is allowed. You should use this format in @code{UPDATE} +expressions and in the WHERE clause of @code{SELECT} statements. For +example: + +@example +mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05'; +@end example + +As a convenience, @strong{MySQL} automatically converts a date to a number if +the date is used in a numeric context (and vice versa). It is also smart +enough to allow a ``relaxed'' string form when updating and in a @code{WHERE} +clause that compares a date to a @code{TIMESTAMP}, @code{DATE}, or a +@code{DATETIME} column. (Relaxed form means that any punctuation character +may be used as the separator between parts. For example, @code{'1998-08-15'} +and @code{'1998#08#15'} are equivalent.) @strong{MySQL} can also convert a +string containing no separators (such as @code{'19980815'}), provided it +makes sense as a date. + +The special date @code{'0000-00-00'} can be stored and retrieved as +@code{'0000-00-00'.} When using a @code{'0000-00-00'} date through +@strong{MyODBC}, it will automatically be converted to @code{NULL} in +@strong{MyODBC} Version 2.50.12 and above, because ODBC can't handle this kind of +date. + +Because @strong{MySQL} performs the conversions described above, the following +statements work: + +@example +mysql> INSERT INTO tbl_name (idate) VALUES (19970505); +mysql> INSERT INTO tbl_name (idate) VALUES ('19970505'); +mysql> INSERT INTO tbl_name (idate) VALUES ('97-05-05'); +mysql> INSERT INTO tbl_name (idate) VALUES ('1997.05.05'); +mysql> INSERT INTO tbl_name (idate) VALUES ('1997 05 05'); +mysql> INSERT INTO tbl_name (idate) VALUES ('0000-00-00'); + +mysql> SELECT idate FROM tbl_name WHERE idate >= '1997-05-05'; +mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505; +mysql> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505; +mysql> SELECT idate FROM tbl_name WHERE idate >= '19970505'; +@end example + +@noindent +However, the following will not work: + +@example +mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0; +@end example + +@code{STRCMP()} is a string function, so it converts @code{idate} to +a string and performs a string comparison. It does not convert +@code{'19970505'} to a date and perform a date comparison. + +Note that @strong{MySQL} does no checking whether or not the date is +correct. If you store an incorrect date, such as @code{'1998-2-31'}, the +wrong date will be stored. If the date cannot be converted to any reasonable +value, a @code{0} is stored in the @code{DATE} field. This is mainly a speed +issue and we think it is up to the application to check the dates, and not +the server. + + +@node Timezone problems, Case sensitivity, Using DATE, Problems +@appendixsec Time Zone Problems + +@cindex timezone problems +@cindex problems, timezone + +@tindex TZ environment variable +@tindex Environment variable, TZ + +If you have a problem with @code{SELECT NOW()} returning values in GMT and +not your local time, you have to set the @code{TZ} environment variable to +your current time zone. This should be done for the environment in which +the server runs, for example, in @code{safe_mysqld} or @code{mysql.server}. +@xref{Environment variables}. + + +@node Case sensitivity, Problems with NULL, Timezone problems, Problems +@appendixsec Case Sensitivity in Searches + +@cindex case sensitivity, in searches +@cindex searching, and case-sensitivity +@cindex Chinese +@cindex Big5 Chinese character encoding + +By default, @strong{MySQL} searches are case-insensitive (although there are +some character sets that are never case insensitive, such as @code{czech}). +That means that if you search with @code{col_name LIKE 'a%'}, you will get all +column values that start with @code{A} or @code{a}. If you want to make this +search case-sensitive, use something like @code{INDEX(col_name, "A")=0} to +check a prefix. Or use @code{STRCMP(col_name, "A") = 0} if the column value +must be exactly @code{"A"}. + +Simple comparison operations (@code{>=, >, = , < , <=}, sorting and +grouping) are based on each character's ``sort value''. Characters with +the same sort value (like E, e and é) are treated as the same character! + +In older @strong{MySQL} versions @code{LIKE} comparisons where done on +the uppercase value of each character (E == e but E <> é). In newer +@strong{MySQL} versions @code{LIKE} works just like the other comparison +operators. + +If you want a column always to be treated in case-sensitive fashion, +declare it as @code{BINARY}. @xref{CREATE TABLE, , @code{CREATE TABLE}}. + +If you are using Chinese data in the so-called big5 encoding, you want to +make all character columns @code{BINARY}. This works because the sorting +order of big5 encoding characters is based on the order of ASCII codes. + + +@node Problems with NULL, Problems with alias, Case sensitivity, Problems +@appendixsec Problems with @code{NULL} Values + +@cindex @code{NULL} values, vs. empty values + +@tindex NULL + +The concept of the @code{NULL} value is a common source of confusion for +newcomers to SQL, who often think that @code{NULL} is the same thing as an +empty string @code{''}. This is not the case! For example, the following +statements are completely different: + +@example +mysql> INSERT INTO my_table (phone) VALUES (NULL); +mysql> INSERT INTO my_table (phone) VALUES (""); +@end example + +Both statements insert a value into the @code{phone} column, but the first +inserts a @code{NULL} value and the second inserts an empty string. The +meaning of the first can be regarded as ``phone number is not known'' and the +meaning of the second can be regarded as ``she has no phone''. + +In SQL, the @code{NULL} value is always false in comparison to any +other value, even @code{NULL}. An expression that contains @code{NULL} +always produces a @code{NULL} value unless otherwise indicated in +the documentation for the operators and functions involved in the +expression. All columns in the following example return @code{NULL}: + +@example +mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL); +@end example + +If you want to search for column values that are @code{NULL}, you +cannot use the @code{=NULL} test. The following statement returns no +rows, because @code{expr = NULL} is FALSE, for any expression: + +@example +mysql> SELECT * FROM my_table WHERE phone = NULL; +@end example + +To look for @code{NULL} values, you must use the @code{IS NULL} test. +The following shows how to find the @code{NULL} phone number and the +empty phone number: + +@example +mysql> SELECT * FROM my_table WHERE phone IS NULL; +mysql> SELECT * FROM my_table WHERE phone = ""; +@end example + +In @strong{MySQL}, as in many other SQL servers, you can't index +columns that can have @code{NULL} values. You must declare such columns +@code{NOT NULL}. Conversely, you cannot insert @code{NULL} into an indexed +column. + +@findex LOAD DATA INFILE +When reading data with @code{LOAD DATA INFILE}, empty columns are updated +with @code{''}. If you want a @code{NULL} value in a column, you should use +@code{\N} in the text file. The literal word @code{'NULL'} may also be used +under some circumstances. +@xref{LOAD DATA, , @code{LOAD DATA}}. + +When using @code{ORDER BY}, @code{NULL} values are presented first. If you +sort in descending order using @code{DESC}, @code{NULL} values are presented +last. When using @code{GROUP BY}, all @code{NULL} values are regarded as +equal. + +To help with @code{NULL} handling, you can use the @code{IS NULL} and +@code{IS NOT NULL} operators and the @code{IFNULL()} function. + +@cindex @code{TIMESTAMP}, and @code{NULL} values +@cindex @code{AUTO_INCREMENT}, and @code{NULL} values +@cindex @code{NULL} values, and @code{TIMESTAMP} columns +@cindex @code{NULL} values, and @code{AUTO_INCREMENT} columns +For some column types, @code{NULL} values are handled specially. If you +insert @code{NULL} into the first @code{TIMESTAMP} column of a table, the +current date and time is inserted. If you insert @code{NULL} into an +@code{AUTO_INCREMENT} column, the next number in the sequence is inserted. + + +@node Problems with alias, Deleting from related tables, Problems with NULL, Problems +@appendixsec Problems with @code{alias} + +@tindex alias + +You can use an alias to refer to a column in the @code{GROUP BY}, +@code{ORDER BY}, or in the @code{HAVING} part. Aliases can also be used +to give columns better names: + +@example +SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0; +SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0; +SELECT id AS "Customer identity" FROM table_name; +@end example + +Note that ANSI SQL doesn't allow you to refer to an alias in a +@code{WHERE} clause. This is because when the @code{WHERE} code is +executed the column value may not yet be determined. For example, the +following query is @strong{illegal}: + +@example +SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id; +@end example + +The @code{WHERE} statement is executed to determine which rows should +be included in the @code{GROUP BY} part while @code{HAVING} is used to +decide which rows from the result set should be used. + + +@node Deleting from related tables, No matching rows, Problems with alias, Problems +@appendixsec Deleting Rows from Related Tables + +@cindex deleting, rows +@cindex rows, deleting +@cindex tables, deleting rows + +As @strong{MySQL} doesn't support sub-selects or use of more than one table +in the @code{DELETE} statement, you should use the following approach to +delete rows from 2 related tables: + +@enumerate +@item +@code{SELECT} the rows based on some @code{WHERE} condition in the main table. +@item +@code{DELETE} the rows in the main table based on the same condition. +@item +@code{DELETE FROM related_table WHERE related_column IN (selected_rows)}. +@end enumerate + +If the total number of characters in the query with +@code{related_column} is more than 1,048,576 (the default value of +@code{max_allowed_packet}, you should split it into smaller parts and +execute multiple @code{DELETE} statements. You will probably get the +fastest @code{DELETE} by only deleting 100-1000 @code{related_column} +id's per query if the @code{related_column} is an index. If the +@code{related_column} isn't an index, the speed is independent of the +number of arguments in the @code{IN} clause. + +@node No matching rows, ALTER TABLE problems, Deleting from related tables, Problems +@appendixsec Solving Problems with No Matching Rows + +@cindex no matching rows +@cindex rows, matching problems + +If you have a complicated query that has many tables and that doesn't +return any rows, you should use the following procedure to find out what +is wrong with your query: + +@enumerate +@item +Test the query with @code{EXPLAIN} and check if you can find something that is +obviously wrong. @xref{EXPLAIN, , @code{EXPLAIN}}. @item -If a test fails totally, you should check the logs file in the -@code{mysql-test/var/log} directory for hints of what went wrong. +Select only those fields that are used in the @code{WHERE} clause. @item -If you have compiled @strong{MySQL} with debugging you can try to debug this -by running @code{mysql-test-run} with the @code{--gdb} and/or @code{--debug} -options. -@xref{Making trace files}. +Remove one table at a time from the query until it returns some rows. +If the tables are big, it's a good idea to use @code{LIMIT 10} with the query. -If you have not compiled @strong{MySQL} for debugging you should probably -do that. Just specify the @code{--with-debug} options to @code{configure}! -@xref{Installing source}. +@item +Do a @code{SELECT} for the column that should have matched a row against +the table that was last removed from the query. + +@item +If you are comparing @code{FLOAT} or @code{DOUBLE} columns with numbers that +have decimals, you can't use @code{=}! This problem is common in most +computer languages because floating-point values are not exact values: + +@example +mysql> SELECT * FROM table_name WHERE float_column=3.5; + -> +mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55; +@end example + +In most cases, changing the @code{FLOAT} to a @code{DOUBLE} will fix this! + +@item +If you still can't figure out what's wrong, create a minimal test that can +be run with @code{mysql test < query.sql} that shows your problems. +You can create a test file with @code{mysqldump --quick database tables > query.sql}. Open the file in an editor, remove some insert lines (if there are +too many of these), and add your select statement at the end of the file. + +Test that you still have your problem by doing: + +@example +shell> mysqladmin create test2 +shell> mysql test2 < query.sql +@end example + +Post the test file using @code{mysqlbug} to @email{mysql@@lists.mysql.com}. +@end enumerate + + +@node ALTER TABLE problems, Change column order, No matching rows, Problems +@appendixsec Problems with @code{ALTER TABLE}. + +@tindex ALTER TABLE + +@code{ALTER TABLE} changes a table to the current character set. +If you during @code{ALTER TABLE} get a duplicate key error, then the cause +is either that the new character sets maps to keys to the same value +or that the table is corrupted, in which case you should run +@code{REPAIR TABLE} on the table. + +If @code{ALTER TABLE} dies with an error like this: + +@example +Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17) +@end example + +the problem may be that @strong{MySQL} has crashed in a previous @code{ALTER +TABLE} and there is an old table named @file{A-something} or +@file{B-something} lying around. In this case, go to the @strong{MySQL} data +directory and delete all files that have names starting with @code{A-} or +@code{B-}. (You may want to move them elsewhere instead of deleting them.) + +@code{ALTER TABLE} works the following way: + +@itemize @bullet +@item Create a new table named @file{A-xxx} with the requested changes. +@item All rows from the old table are copied to @file{A-xxx}. +@item The old table is renamed @file{B-xxx}. +@item @file{A-xxx} is renamed to your old table name. +@item @file{B-xxx} is deleted. @end itemize +If something goes wrong with the renaming operation, @strong{MySQL} tries to +undo the changes. If something goes seriously wrong (this shouldn't happen, +of course), @strong{MySQL} may leave the old table as @file{B-xxx}, but a +simple rename on the system level should get your data back. + + +@node Change column order, Temporary table problems, ALTER TABLE problems, Problems +@appendixsec How To Change the Order of Columns in a Table + +@cindex reordering, columns +@cindex columns, changing +@cindex changing, column order +@cindex tables, changing column order + +The whole point of SQL is to abstract the application from the data +storage format. You should always specify the order in which you wish to +retrieve your data. For example: + +@example +SELECT col_name1, col_name2, col_name3 FROM tbl_name; +@end example + +will return columns in the order @code{col_name1}, @code{col_name2}, @code{col_name3}, whereas: + +@example +SELECT col_name1, col_name3, col_name2 FROM tbl_name; +@end example + +will return columns in the order @code{col_name1}, @code{col_name3}, @code{col_name2}. + +You should @strong{NEVER}, in an application, use @code{SELECT *} and +retrieve the columns based on their position, because the order in which +columns are returned @strong{CANNOT} be guaranteed over time. A simple +change to your database may cause your application to fail rather +dramatically. + +If you want to change the order of columns anyway, you can do it as follows: + +@enumerate +@item +Create a new table with the columns in the right order. +@item +Execute +@code{INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table}. +@item +Drop or rename @code{old_table}. +@item +@code{ALTER TABLE new_table RENAME old_table}. +@end enumerate + + +@node Temporary table problems, , Change column order, Problems +@appendixsec TEMPORARY TABLE problems + +@cindex temporary tables, problems + +The following are a list of the limitations with @code{TEMPORARY TABLES}. + +@itemize @bullet +@item +A temporary table can only be of type @code{HEAP}, @code{ISAM} or +@code{MyISAM}. +@item +You can't use temporary tables more than once in the same query. +For example, the following doesn't work. + +@example +select * from temporary_table, temporary_table as t2; +@end example + +We plan to fix the above in 4.0. +@item +You can't use @code{RENAME} on a @code{TEMPORARY} table. +Note that @code{ALTER TABLE org_name RENAME new_name} works! + +We plan to fix the above in 4.0. +@end itemize + + + + + @page @cindex environment variables, list of -@node Environment variables, Users, MySQL internals, Top +@node Environment variables, Users, Problems, Top @appendix Environment Variables Here is a list of all the environment variables that are used directly or @@ -51104,8 +51237,8 @@ information even if you haven't compiled @strong{MySQL} for debugging! If the problem is that some tables are getting slower and slower you should try to optimize the table with @code{OPTIMIZE TABLE} or -@code{myisamchk}. @xref{Maintenance}. You should also check the slow -queries with @code{EXPLAIN}. +@code{myisamchk}. @xref{MySQL Database Administration}. You should also +check the slow queries with @code{EXPLAIN}. You should also read the OS-specific section in this manual for problems that may be unique to your environment. @@ -51362,7 +51495,8 @@ repeat the problem! @xref{Bug reports}. @appendixsubsec Using log files to find cause of errors in mysqld Note that before starting @code{mysqld} with @code{--log} you should -check all your tables with @code{myisamchk}. @xref{Maintenance}. +check all your tables with @code{myisamchk}. +@xref{MySQL Database Administration}. If @code{mysqld} dies or hangs, you should start @code{mysqld} with @code{--log}. When @code{mysqld} dies again, you can examine the end of @@ -51385,11 +51519,11 @@ You can find the queries that take a long time to execute by starting If you find the text @code{mysqld restarted} in the error log file (normally named @file{hostname.err}) you have probably found a query that causes @code{mysqld} to fail. If this happens you should check all -your tables with @code{myisamchk} (@pxref{Maintenance}), and test the -queries in the @strong{MySQL} log files to see if one doesn't work. If -you find such a query, try first upgrading to the newest @strong{MySQL} -version. If this doesn't help and you can't find anything in the -@code{mysql} mail archive, you should report the bug to +your tables with @code{myisamchk} (@pxref{MySQL Database Administration}), +and test the queries in the @strong{MySQL} log files to see if one doesn't +work. If you find such a query, try first upgrading to the newest +@strong{MySQL} version. If this doesn't help and you can't find anything +in the @code{mysql} mail archive, you should report the bug to @email{mysql@@lists.mysql.com}. Links to mail archives are available online at the @uref{http://www.mysql.com/documentation/, @strong{MySQL} documentation page}. @@ -53044,7 +53178,6 @@ That's all there is to it! * Building clients:: * Perl support:: * Group by functions:: -* CREATE FUNCTION:: @end menu @node Installing binary, Building clients, Placeholder, Placeholder @@ -53577,7 +53710,7 @@ Finally, you should install this new Perl. Again, the output of @code{make perl} indicates the command to use. -@node Group by functions, CREATE FUNCTION, Perl support, Placeholder +@node Group by functions, , Perl support, Placeholder @appendixsec Functions for Use with @code{GROUP BY} Clauses @findex GROUP BY functions @@ -53734,45 +53867,6 @@ mysql> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND(); @end example -@node CREATE FUNCTION, , Group by functions, Placeholder -@appendixsec @code{CREATE FUNCTION/DROP FUNCTION} Syntax - -@findex CREATE FUNCTION -@findex DROP FUNCTION -@findex UDF functions -@findex User-defined functions -@findex Functions, user-defined - -@example -CREATE [AGGREGATE] FUNCTION function_name RETURNS @{STRING|REAL|INTEGER@} - SONAME shared_library_name - -DROP FUNCTION function_name -@end example - -A user-definable function (UDF) is a way to extend @strong{MySQL} with a new -function that works like native (built in) @strong{MySQL} functions such as -@code{ABS()} and @code{CONCAT()}. - -@code{AGGREGATE} is a new option for @strong{MySQL} Version 3.23. An -@code{AGGREGATE} function works exactly like a native @strong{MySQL} -@code{GROUP} function like @code{SUM} or @code{COUNT()}. - -@code{CREATE FUNCTION} saves the function's name, type, and shared library -name in the @code{mysql.func} system table. You must have the -@strong{insert} and @strong{delete} privileges for the @code{mysql} database -to create and drop functions. - -All active functions are reloaded each time the server starts, unless -you start @code{mysqld} with the @code{--skip-grant-tables} option. In -this case, UDF initialization is skipped and UDFs are unavailable. -(An active function is one that has been loaded with @code{CREATE FUNCTION} -and not removed with @code{DROP FUNCTION}.) - -For instructions on writing user-definable functions, see @ref{Adding -functions}. For the UDF mechanism to work, functions must be written in C or -C++, your operating system must support dynamic loading and you must have -compiled @code{mysqld} dynamically (not statically). From cd62fdf6d0794f6d71ffa6f38e1213dca27b3e9a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Aug 2001 23:40:37 -0500 Subject: [PATCH 04/18] DocTOC Chapter 8 Complete! --- Docs/manual.texi | 8492 +++++++++++++++++++++++----------------------- 1 file changed, 4307 insertions(+), 4185 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index b07e9a889de..135600104da 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -115,10 +115,8 @@ distribution for that version. * MySQL Optimization:: * Reference:: @strong{MySQL} language reference * Table types:: @strong{MySQL} table types -* Extending MySQL:: -* ODBC:: @strong{MySQL} ODBC Support -* Common programs:: Using @strong{MySQL} with some common programs * Clients:: @strong{MySQL} client tools and APIs +* Extending MySQL:: * Problems:: Problems * Environment variables:: @strong{MySQL} environment variables * Users:: Some @strong{MySQL} users @@ -26965,7 +26963,6 @@ Things that are not yet supported: - @node Reference, Table types, MySQL Optimization, Top @chapter MySQL Language Reference @@ -34734,7 +34731,7 @@ parameters to @code{FULLTEXT} in @code{CREATE/ALTER TABLE}). -@node Table types, Extending MySQL, Reference, Top +@node Table types, Clients, Reference, Top @chapter MySQL Table Types @cindex table types, choosing @@ -37217,7 +37214,4308 @@ Finland -@node Extending MySQL, ODBC, Table types, Top +@node Clients, Extending MySQL, Table types, Top +@chapter MySQL APIs + +@cindex client tools +@cindex APIs +@cindex @code{mysqlclient} library +@cindex buffer sizes, client +@cindex library, @code{mysqlclient} + +@menu +* PHP:: @strong{MySQL} PHP API +* Perl:: @strong{MySQL} Perl API +* ODBC:: +* C:: @strong{MySQL} C API +* Cplusplus:: @strong{MySQL} C++ APIs +* Java:: @strong{MySQL} Java connectivity (JDBC) +* Python:: @strong{MySQL} Python APIs +* Tcl:: @strong{MySQL} Tcl APIs +* Eiffel:: @strong{MySQL} Eiffel wrapper +@end menu + +This chapter describes the APIs available for @strong{MySQL}, where to get +them, and how to use them. The C API is the most extensively covered, as it +was developed by the @strong{MySQL} team, and is the basis for most of the +other APIs. + + +@node PHP, Perl, Clients, Clients +@section MySQL PHP API + +@cindex PHP API + +PHP is a server-side, HTML-embedded scripting language that may be used to +create dynamic Web pages. It contains support for accessing several +databases, including @strong{MySQL}. PHP may be run as a separate program +or compiled as a module for use with the Apache Web server. + +The distribution and documentation are available at the +@uref{http://www.php.net/, PHP web site}. + +@menu +* PHP problems:: Common problems with MySQL and PHP +@end menu + +@node PHP problems, , PHP, PHP +@subsection Common Problems with MySQL and PHP + +@itemize @bullet +@item Error: "Maximum Execution Time Exceeded" +This is a PHP limit; Go into the @file{php3.ini} file and set the maximum +execution time up from 30 seconds to something higher, as needed. +It is also not a bad idea to double the ram allowed per script to 16MB instead of +8 MB. +@item Error: "Fatal error: Call to unsupported or undefined function mysql_connect() in .." +This means that your PHP version isn't compiled with @strong{MySQL} support. +You can either compile a dynamic @strong{MySQL} module and load it into PHP or +recompile PHP with built-in @strong{MySQL} support. This is described in +detail in the PHP manual. +@item Error: "undefined reference to `uncompress'" +This means that the client library is compiled with support for a compressed +client/server protocol. The fix is to add @code{-lz} last when linking +with @code{-lmysqlclient}. +@end itemize + + +@node Perl, ODBC, PHP, Clients +@section MySQL Perl API + +@cindex APIs, Perl +@cindex Perl API + +This section documents the Perl @code{DBI} interface. The former interface +was called @code{mysqlperl}. @code{DBI}/@code{DBD} now is the +recommended Perl interface, so @code{mysqlperl} is obsolete and is not +documented here. + +@menu +* DBI with DBD:: @code{DBI} with @code{DBD::mysql} +* Perl DBI Class:: The @code{DBI} interface +* DBI-info:: More @code{DBI}/@code{DBD} information +@end menu + + +@node DBI with DBD, Perl DBI Class, Perl, Perl +@subsection @code{DBI} with @code{DBD::mysql} + +@cindex @code{DBI} interface + +@code{DBI} is a generic interface for many databases. That means that +you can write a script that works with many different database engines +without change. You need a DataBase Driver (DBD) defined for each +database type. For @strong{MySQL}, this driver is called +@code{DBD::mysql}. + +For more information on the Perl5 DBI, please visit the @code{DBI} Web +page and read the documentation: +@example +@uref{http://www.symbolstone.org/technology/perl/DBI/index.html} +@end example +For more information on Object Oriented Programming +(OOP) as defined in Perl5, see the Perl OOP page: +@example +@uref{http://language.perl.com/info/documentation.html} +@end example + +Note that if you want to use transactions with Perl, you need to have +@code{Msql-Mysql-modules} version 1.2216 or newer. + +Installation instructions for @strong{MySQL} Perl support are given in +@ref{Perl support}. + + +@node Perl DBI Class, DBI-info, DBI with DBD, Perl +@subsection The @code{DBI} Interface + +@cindex @code{DBI} Perl module + +@noindent +@strong{Portable DBI Methods} + +@multitable @columnfractions .3 .7 +@item @code{connect} @tab Establishes a connection to a database server. +@item @code{disconnect} @tab Disconnects from the database server. +@item @code{prepare} @tab Prepares a SQL statement for execution. +@item @code{execute} @tab Executes prepared statements. +@item @code{do} @tab Prepares and executes a SQL statement. +@item @code{quote} @tab Quotes string or @code{BLOB} values to be inserted. +@item @code{fetchrow_array} @tab Fetches the next row as an array of fields. +@item @code{fetchrow_arrayref} @tab Fetches next row as a reference array of fields. +@item @code{fetchrow_hashref} @tab Fetches next row as a reference to a hashtable. +@item @code{fetchall_arrayref} @tab Fetches all data as an array of arrays. +@item @code{finish} @tab Finishes a statement and lets the system free resources. +@item @code{rows} @tab Returns the number of rows affected. +@item @code{data_sources} @tab Returns an array of databases available on localhost. +@item @code{ChopBlanks} @tab Controls whether @code{fetchrow_*} methods trim spaces. +@item @code{NUM_OF_PARAMS} @tab The number of placeholders in the prepared statement. +@item @code{NULLABLE} @tab Which columns can be @code{NULL}. +@item @code{trace} @tab Perform tracing for debugging. +@end multitable + +@noindent +@strong{MySQL-specific Methods} + +@multitable @columnfractions .3 .7 +@item @code{insertid} @tab The latest @code{AUTO_INCREMENT} value. +@item @code{is_blob} @tab Which columns are @code{BLOB} values. +@item @code{is_key} @tab Which columns are keys. +@item @code{is_num} @tab Which columns are numeric. +@item @code{is_pri_key} @tab Which columns are primary keys. +@item @code{is_not_null} @tab Which columns CANNOT be @code{NULL}. See @code{NULLABLE}. +@item @code{length} @tab Maximum possible column sizes. +@item @code{max_length} @tab Maximum column sizes actually present in result. +@item @code{NAME} @tab Column names. +@item @code{NUM_OF_FIELDS} @tab Number of fields returned. +@item @code{table} @tab Table names in returned set. +@item @code{type} @tab All column types. +@end multitable + +The Perl methods are described in more detail in the following sections. +Variables used for method return values have these meanings: + +@table @code +@item $dbh +Database handle + +@item $sth +Statement handle + +@item $rc +Return code (often a status) + +@item $rv +Return value (often a row count) +@end table + +@noindent +@strong{Portable DBI Methods} + +@table @code + +@findex DBI->connect() +@findex connect() DBI method +@item connect($data_source, $username, $password) +Use the @code{connect} method to make a database connection to the data +source. The @code{$data_source} value should begin with +@code{DBI:driver_name:}. +Example uses of @code{connect} with the @code{DBD::mysql} driver: +@example +$dbh = DBI->connect("DBI:mysql:$database", $user, $password); +$dbh = DBI->connect("DBI:mysql:$database:$hostname", + $user, $password); +$dbh = DBI->connect("DBI:mysql:$database:$hostname:$port", + $user, $password); +@end example +If the user name and/or password are undefined, @code{DBI} uses the +values of the @code{DBI_USER} and @code{DBI_PASS} environment variables, +respectively. If you don't specify a hostname, it defaults to +@code{'localhost'}. If you don't specify a port number, it defaults to the +default @strong{MySQL} port (@value{default_port}). + +As of @code{Msql-Mysql-modules} Version 1.2009, +the @code{$data_source} value allows certain modifiers: + +@table @code +@item mysql_read_default_file=file_name +Read @file{filename} as an option file. For information on option files, +see @ref{Option files}. + +@item mysql_read_default_group=group_name +The default group when reading an option file is normally the +@code{[client]} group. By specifying the @code{mysql_read_default_group} +option, the default group becomes the @code{[group_name]} group. + +@item mysql_compression=1 +Use compressed communication between the client and server (@strong{MySQL} +Version 3.22.3 or later). + +@item mysql_socket=/path/to/socket +Specify the pathname of the Unix socket that is used to connect +to the server (@strong{MySQL} Version 3.21.15 or later). +@end table + +Multiple modifiers may be given; each must be preceded by a semicolon. + +For example, if you want to avoid hardcoding the user name and password into +a @code{DBI} script, you can take them from the user's @file{~/.my.cnf} +option file instead by writing your @code{connect} call like this: + +@example +$dbh = DBI->connect("DBI:mysql:$database" + . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf", + $user, $password); +@end example + +This call will read options defined for the @code{[client]} group in the +option file. If you wanted to do the same thing but use options specified +for the @code{[perl]} group as well, you could use this: + +@example +$dbh = DBI->connect("DBI:mysql:$database" + . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf" + . ";mysql_read_default_group=perl", + $user, $password); +@end example + +@findex DBI->disconnect +@findex disconnect DBI method +@item disconnect +The @code{disconnect} method disconnects the database handle from the database. +This is typically called right before you exit from the program. +Example: +@example +$rc = $dbh->disconnect; +@end example + +@findex DBI->prepare() +@findex prepare() DBI method +@item prepare($statement) +Prepares a SQL statement for execution by the database engine +and returns a statement handle @code{($sth)}, which you can use to invoke +the @code{execute} method. +Typically you handle @code{SELECT} statements (and @code{SELECT}-like statements +such as @code{SHOW}, @code{DESCRIBE}, and @code{EXPLAIN}) by means of +@code{prepare} and @code{execute}. +Example: +@example +$sth = $dbh->prepare($statement) + or die "Can't prepare $statement: $dbh->errstr\n"; +@end example + +@findex DBI->execute +@findex execute DBI method +@item execute +The @code{execute} method executes a prepared statement. For +non-@code{SELECT} statements, @code{execute} returns the number of rows +affected. If no rows are affected, @code{execute} returns @code{"0E0"}, +which Perl treats as zero but regards as true. If an error occurs, +@code{execute} returns @code{undef}. For @code{SELECT} statements, +@code{execute} only starts the SQL query in the database; you need to use one +of the @code{fetch_*} methods described below to retrieve the data. +Example: +@example +$rv = $sth->execute + or die "can't execute the query: $sth->errstr; +@end example + +@findex DBI->do() +@findex do() DBI method +@item do($statement) +The @code{do} method prepares and executes a SQL statement and returns the +number of rows affected. If no rows are affected, @code{do} returns +@code{"0E0"}, which Perl treats as zero but regards as true. This method is +generally used for non-@code{SELECT} statements that cannot be prepared in +advance (due to driver limitations) or that do not need to be executed more +than once (inserts, deletes, etc.). Example: +@example +$rv = $dbh->do($statement) + or die "Can't execute $statement: $dbh- >errstr\n"; +@end example + +Generally the 'do' statement is MUCH faster (and is preferable) +than prepare/execute for statements that don't contain parameters. + +@findex DBI->quote() +@findex quote() DBI method +@cindex quoting strings +@cindex strings, quoting +@item quote($string) +The @code{quote} method is used to "escape" any special characters contained in +the string and to add the required outer quotation marks. +Example: +@example +$sql = $dbh->quote($string) +@end example + +@findex DBI->fetchrow_array +@findex fetchrow_array DBI method +@item fetchrow_array +This method fetches the next row of data and returns it as an array of +field values. Example: +@example +while(@@row = $sth->fetchrow_array) @{ + print qw($row[0]\t$row[1]\t$row[2]\n); +@} +@end example + +@findex DBI->fetchrow_arrayref +@findex fetchrow_arrayref DBI method +@item fetchrow_arrayref +This method fetches the next row of data and returns it as a reference +to an array of field values. Example: +@example +while($row_ref = $sth->fetchrow_arrayref) @{ + print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n); +@} +@end example + +@findex DBI->fetchrow_hashref +@findex fetchrow_hashref DBI method +@item fetchrow_hashref +This method fetches a row of data and returns a reference to a hash +table containing field name/value pairs. This method is not nearly as +efficient as using array references as demonstrated above. Example: +@example +while($hash_ref = $sth->fetchrow_hashref) @{ + print qw($hash_ref->@{firstname@}\t$hash_ref->@{lastname@}\t\ + $hash_ref- > title@}\n); +@} +@end example + +@findex DBI->fetchall_arrayref +@findex fetchall_arrayref DBI method +@item fetchall_arrayref +This method is used to get all the data (rows) to be returned from the +SQL statement. It returns a reference to an array of references to arrays +for each row. You access or print the data by using a nested +loop. Example: +@example +my $table = $sth->fetchall_arrayref + or die "$sth->errstr\n"; +my($i, $j); +for $i ( 0 .. $#@{$table@} ) @{ + for $j ( 0 .. $#@{$table->[$i]@} ) @{ + print "$table->[$i][$j]\t"; + @} + print "\n"; +@} +@end example + +@findex DBI->finish +@findex finish DBI method +@item finish +Indicates that no more data will be fetched from this statement +handle. You call this method to free up the statement handle and any +system resources associated with it. Example: +@example +$rc = $sth->finish; +@end example + +@findex DBI->rows +@findex rows DBI method +@item rows +Returns the number of rows changed (updated, deleted, etc.) by the last +command. This is usually used after a non-@code{SELECT} @code{execute} +statement. Example: +@example +$rv = $sth->rows; +@end example + +@findex DBI->@{NULLABLE@} +@findex NULLABLE DBI method +@item NULLABLE +Returns a reference to an array of boolean values; for each element of +the array, a value of TRUE indicates that this +column may contain @code{NULL} values. +Example: +@example +$null_possible = $sth->@{NULLABLE@}; +@end example + +@findex DBI->@{NUM_OF_FIELDS@} +@findex NUM_OF_FIELDS DBI method +@item NUM_OF_FIELDS +This attribute indicates +the number of fields returned by a @code{SELECT} or @code{SHOW FIELDS} +statement. You may use this for checking whether a statement returned a +result: A zero value indicates a non-@code{SELECT} statement like +@code{INSERT}, @code{DELETE}, or @code{UPDATE}. +Example: +@example +$nr_of_fields = $sth->@{NUM_OF_FIELDS@}; +@end example + +@findex DBI->data_sources() +@findex data_sources() DBI method +@item data_sources($driver_name) +This method returns an array containing names of databases available to the +@strong{MySQL} server on the host @code{'localhost'}. +Example: +@example +@@dbs = DBI->data_sources("mysql"); +@end example + +@findex DBI->@{ChopBlanks@} +@findex ChopBlanks DBI method +@item ChopBlanks +This attribute determines whether the @code{fetchrow_*} methods will chop +leading and trailing blanks from the returned values. +Example: +@example +$sth->@{'ChopBlanks'@} =1; +@end example + +@findex DBI->trace +@findex trace DBI method +@item trace($trace_level) +@itemx trace($trace_level, $trace_filename) +The @code{trace} method enables or disables tracing. When invoked as a +@code{DBI} class method, it affects tracing for all handles. When invoked as +a database or statement handle method, it affects tracing for the given +handle (and any future children of the handle). Setting @code{$trace_level} +to 2 provides detailed trace information. Setting @code{$trace_level} to 0 +disables tracing. Trace output goes to the standard error output by +default. If @code{$trace_filename} is specified, the file is opened in +append mode and output for @emph{all} traced handles is written to that +file. Example: +@example +DBI->trace(2); # trace everything +DBI->trace(2,"/tmp/dbi.out"); # trace everything to + # /tmp/dbi.out +$dth->trace(2); # trace this database handle +$sth->trace(2); # trace this statement handle +@end example + +@tindex DBI_TRACE environment variable +@tindex Environment variable, DBI_TRACE +You can also enable @code{DBI} tracing by setting the @code{DBI_TRACE} +environment variable. Setting it to a numeric value is equivalent to calling +@code{DBI->(value)}. Setting it to a pathname is equivalent to calling +@code{DBI->(2,value)}. + +@end table + +@noindent +@strong{MySQL-specific Methods} + +The methods shown below are @strong{MySQL}-specific and not part of the +@code{DBI} standard. Several of them are now deprecated: +@code{is_blob}, @code{is_key}, @code{is_num}, @code{is_pri_key}, +@code{is_not_null}, @code{length}, @code{max_length}, and @code{table}. +Where @code{DBI}-standard alternatives exist, they are noted below: + +@table @code +@findex DBI->@{insertid@} +@findex insertid DBI method +@tindex AUTO_INCREMENT, using with DBI +@item insertid +If you use the @code{AUTO_INCREMENT} feature of @strong{MySQL}, the new +auto-incremented values will be stored here. +Example: +@example +$new_id = $sth->@{insertid@}; +@end example + +As an alternative, you can use @code{$dbh->@{'mysql_insertid'@}}. + +@findex DBI->@{is_blob@} +@findex is_blob DBI method +@item is_blob +Returns a reference to an array of boolean values; for each element of the +array, a value of TRUE indicates that the +respective column is a @code{BLOB}. +Example: +@example +$keys = $sth->@{is_blob@}; +@end example + +@findex DBI->@{is_key@} +@findex is_key DBI method +@item is_key +Returns a reference to an array of boolean values; for each element of the +array, a value of TRUE indicates that the +respective column is a key. +Example: +@example +$keys = $sth->@{is_key@}; +@end example + +@findex DBI->@{is_num@} +@findex is_num DBI method +@item is_num +Returns a reference to an array of boolean values; for each element of the +array, a value of TRUE indicates that the +respective column contains numeric values. +Example: +@example +$nums = $sth->@{is_num@}; +@end example + +@findex DBI->@{is_pri_key@} +@findex is_pri_key DBI method +@item is_pri_key +Returns a reference to an array of boolean values; for each element of the +array, a value of TRUE indicates that the respective column is a primary key. +Example: +@example +$pri_keys = $sth->@{is_pri_key@}; +@end example + +@findex DBI->@{is_not_null@} +@findex is_not_null DBI method +@item is_not_null +Returns a reference to an array of boolean values; for each element of the +array, a value of FALSE indicates that this column may contain @code{NULL} +values. +Example: +@example +$not_nulls = $sth->@{is_not_null@}; +@end example + +@code{is_not_null} is deprecated; it is preferable to use the +@code{NULLABLE} attribute (described above), because that is a DBI standard. + +@findex DBI->@{length@} +@findex length DBI method +@findex DBI->@{max_length@} +@findex max_length DBI method +@item length +@itemx max_length +Each of these methods returns a reference to an array of column sizes. The +@code{length} array indicates the maximum possible sizes that each column may +be (as declared in the table description). The @code{max_length} array +indicates the maximum sizes actually present in the result table. Example: + +@example +$lengths = $sth->@{length@}; +$max_lengths = $sth->@{max_length@}; +@end example + +@findex DBI->@{NAME@} +@findex NAME DBI method +@item NAME +Returns a reference to an array of column names. +Example: +@example +$names = $sth->@{NAME@}; +@end example + +@findex DBI->@{table@} +@findex table DBI method +@item table +Returns a reference to an array of table names. +Example: +@example +$tables = $sth->@{table@}; +@end example + +@findex DBI->@{type@} +@findex type DBI method +@item type +Returns a reference to an array of column types. +Example: +@example +$types = $sth->@{type@}; +@end example + +@end table + + +@node DBI-info, , Perl DBI Class, Perl +@subsection More @code{DBI}/@code{DBD} Information + +@cindex @code{DBI/DBD} + +You can use the @code{perldoc} command to get more information about +@code{DBI}. + +@example +perldoc DBI +perldoc DBI::FAQ +perldoc DBD::mysql +@end example + +You can also use the @code{pod2man}, @code{pod2html}, etc., tools to +translate to other formats. + +You can find the latest @code{DBI} information at +the @code{DBI} Web page: +@example +@uref{http://www.symbolstone.org/technology/perl/DBI/index.html} +@end example + + +@node ODBC, C, Perl, Clients +@section MySQL ODBC Support + +@cindex ODBC +@cindex Windows +@cindex MyODBC + +@menu +* Installing MyODBC:: How to install MyODBC +* ODBC administrator:: How to fill in the various fields in the ODBC administrator program +* MyODBC connect parameters:: +* ODBC Problems:: How to report problems with @strong{MySQL} ODBC +* MyODBC clients:: Programs known to work with @strong{MyODBC} +* ODBC and last_insert_id:: How to get the value of an @code{AUTO_INCREMENT} column in ODBC +* MyODBC bug report:: Reporting problems with MyODBC +@end menu + + +@strong{MySQL} provides support for ODBC by means of the @strong{MyODBC} +program. This chapter will teach you how to install @strong{MyODBC}, +and how to use it. Here, you will also find a list of common programs that +are known to work with @strong{MyODBC}. + + +@node Installing MyODBC, ODBC administrator, ODBC, ODBC +@subsection How To Install MyODBC + +@strong{MyODBC} is a 32-bit ODBC (2.50) level 0 (with level 1 and level +2 features) driver for connecting an ODBC-aware application to +@strong{MySQL}. @strong{MyODBC} works on Windows95, Windows98, NT, and +on most Unix platforms. + +@strong{MyODBC} is in public domain, and you can find the newest version +at @uref{http://www.mysql.com/downloads/api-myodbc.html}. + +If you have problem with @strong{MyODBC} and your program also works +with OLEDB, you should try the OLEDB driver that you can find in the +Contrib section. @xref{Contrib}. + +Normally you only need to install @strong{MyODBC} on Windows machines. +You only need @strong{MyODBC} for Unix if you have a program like +ColdFusion that is running on the Unix machine and uses ODBC to connect +to the databases. + +If you want to install @strong{MyODBC} on a Unix box, you will also need +an @strong{ODBC} manager. @strong{MyODBC} is known to work with +most of the Unix ODBC managers. You can find a list at these in the +@strong{ODBC}-related links section on the @strong{MySQL} useful links page. +@xref{Useful Links}. + +To install @strong{MyODBC} on Windows, you should download the +appropriate @strong{MyODBC} .zip file (for Windows or NT/Win2000), +unpack it with @code{WINZIP}, or some similar program, and execute the +@code{SETUP.EXE} file. + +On Windows/NT you may get the following error when trying to install +@strong{MyODBC}: + +@example +An error occurred while copying C:\WINDOWS\SYSTEM\MFC30.DLL. Restart +Windows and try installing again (before running any applications which +use ODBC) +@end example + +The problem in this case is that some other program is using ODBC and +because of how Windows is designed, you may not in this case be able to +install a new ODBC drivers with Microsoft's ODBC setup program. In most +cases you can continue by just pressing @code{Ignore} to copy the rest +of the MyODBC files and the final installation should still work. If +this doesn't work, the solution is to reboot your computer in ``safe +mode`` (Choose this by pressing F8 just before your machine starts +Windows during rebooting), install @strong{MyODBC}, and reboot to normal +mode. + +@itemize @bullet +@item +To make a connection to a Unix box from a Windows box, with an ODBC +application (one that doesn't support @strong{MySQL} natively), you must +first install @strong{MyODBC} on the Windows machine. +@item +The user and Windows machine must have the access privileges to the +@strong{MySQL} server on the Unix machine. This is set up with the +@code{GRANT} command. @xref{GRANT,,@code{GRANT}}. +@item +You must create an ODBC DSN entry as follows: + +@itemize @minus +@item +Open the Control Panel on the Windows machine. +@item +Double-click the ODBC Data Sources 32 bits icon. +@item +Click the tab User DSN. +@item +Click the button Add. +@item +Select @strong{MySQL} in the screen Create New Data Source and click +the Finish button. +@item +The @strong{MySQL} Driver default configuration screen is shown. +@xref{ODBC administrator}. +@end itemize + +@item +Now start your application and select the ODBC driver with the DSN you +specified in the ODBC administrator. +@end itemize + +Notice that there are other configuration options on the screen of +@strong{MySQL} (trace, don't prompt on connect, etc) that you can try if +you run into problems. + + +@node ODBC administrator, MyODBC connect parameters, Installing MyODBC, ODBC +@subsection How to Fill in the Various Fields in the ODBC Administrator Program + +@cindex ODBC, administrator + +There are three possibilities for specifying the server name on +Windows95: + +@itemize @bullet +@item +Use the IP address of the server. +@item +Add a file @file{\windows\lmhosts} with the following information: + +@example +ip hostname +@end example + +For example: + +@example +194.216.84.21 my_hostname +@end example + +@item +Configure the PC to use DNS. +@end itemize + +Example of how to fill in the @code{ODBC setup}: +@example +Windows DSN name: test +Description: This is my test database +MySql Database: test +Server: 194.216.84.21 +User: monty +Password: my_password +Port: +@end example + +The value for the @code{Windows DSN name} field is any name that is unique +in your Windows ODBC setup. + +You don't have to specify values for the @code{Server}, @code{User}, +@code{Password}, or @code{Port} fields in the ODBC setup screen. +However, if you do, the values will be used as the defaults later when +you attempt to make a connection. You have the option of changing the +values at that time. + +If the port number is not given, the default port (@value{default_port}) +is used. + +If you specify the option @code{Read options from C:\my.cnf}, the groups +@code{client} and @code{odbc} will be read from the @file{C:\my.cnf} file. +You can use all options that are usable by @code{mysql_options()}. +@xref{mysql_options, , @code{mysql_options}}. + + +@node MyODBC connect parameters, ODBC Problems, ODBC administrator, ODBC +@subsection Connect parameters for MyODBC + +One can specify the following parameters for @strong{MyODBC} on +the @code{[Servername]} section of an @code{ODBC.INI} file or +through the @code{InConnectionString} argument in the +@code{SQLDriverConnect()} call. + +@multitable @columnfractions .2 .2 .6 +@item @strong{Parameter} @tab @strong{Default value} @tab @strong{Comment} +@item user @tab ODBC (on Windows) @tab The username used to connect to @strong{MySQL}. +@item server @tab localhost @tab The hostname of the @strong{MySQL} server. +@item database @tab @tab The default database +@item option @tab 0 @tab A integer by which you can specify how @strong{MyODBC} should work. See below. +@item port @tab 3306 @tab The TCP/IP port to use if @code{server} is not @code{localhost}. +@item stmt @tab @tab A statement that will be executed when connection to @code{MySQL}. +@item password @tab @tab The password for the @code{server} @code{user} combination. +@item socket @tab @tab The socket or Windows pipe to connect to. +@end multitable + +The option argument is used to tell @strong{MyODBC} that the client isn't 100% +ODBC compliant. On Windows, one normally sets the option flag by +toggling the different options on the connection screen but one can also +set this in the opton argument. The following options are listed in the +same order as they appear in the @strong{MyODBC} connect screen: + +@multitable @columnfractions .1 .9 +@item @strong{Bit} @tab @strong{Meaning} +@item 1 @tab The client can't handle that @strong{MyODBC} returns the real width of a column. +@item 2 @tab The client can't handle that MySQL returns the true value of affected rows. If this flag is set then MySQL returns 'found rows' instead. One must have MySQL 3.21.14 or newer to get this to work. +@item 4 @tab Make a debug log in c:\myodbc.log. This is the same as putting @code{MYSQL_DEBUG=d:t:O,c::\myodbc.log} in @file{AUTOEXEC.BAT} +@item 8 @tab Don't set any packet limit for results and parameters. +@item 16 @tab Don't prompt for questions even if driver would like to prompt +@item 32 @tab Simulate a ODBC 1.0 driver in some context. +@item 64 @tab Ignore use of database name in 'database.table.column'. +@item 128 @tab Force use of ODBC manager cursors (experimental). +@item 256 @tab Disable the use of extended fetch (experimental) +@item 512 @tab Pad CHAR fields to full column length. +@item 1024 @tab SQLDescribeCol() will return fully qualifed column names +@item 2048 @tab Use the compressed server/client protocol +@item 4096 @tab Tell server to ignore space after function name and before @code{'('} (needed by PowerBuilder). This will make all function names keywords! +@item 8192 @tab Connect with named pipes to a @code{mysqld} server running on NT. +@item 16384 @tab Change LONGLONG columns to INT columns (Some applications can't handle LONGLONG). +@item 32768 @tab Return 'user' as Table_qualifier and Table_owner from SQLTables (experimental) +@item 65536 @tab Read parameters from the @code{client} and @code{odbc} groups from @file{my.cnf} +@item 131072 @tab Add some extra safety checks (should not bee needed but...) +@end multitable + +If you want to have many options, you should add the above flags! For +example setting option to 12 (4+8) gives you debugging without package +limits! + +The default @file{MYODBC.DLL} is compiled for optimal performance. If +you want to to debug @strong{MyODBC} (for example to enable tracing), +you should instead use @code{MYODBCD.DLL}. To install this file, copy +@file{MYODBCD.DLL} over the installed @code{MYODBC.DLL} file. + + +@node ODBC Problems, MyODBC clients, MyODBC connect parameters, ODBC +@subsection How to Report Problems with MyODBC + +@strong{MyODBC} has been tested with Access, Admndemo.exe, C++-Builder, +Borland Builder 4, Centura Team Developer (formerly Gupta SQL/Windows), +ColdFusion (on Solaris and NT with svc pack 5), Crystal Reports, +DataJunction, Delphi, ERwin, Excel, iHTML, FileMaker Pro, FoxPro, Notes +4.5/4.6, SBSS, Perl DBD-ODBC, Paradox, Powerbuilder, Powerdesigner 32 +bit, VC++, and Visual Basic. + +If you know of any other applications that work with @strong{MyODBC}, please +send mail to @email{myodbc@@lists.mysql.com} about this! + +With some programs you may get an error like: +@code{Another user has modifies the record that you have modified}. In most +cases this can be solved by doing one of the following things: + +@itemize @bullet +@item +Add a primary key for the table if there isn't one already. +@item +Add a timestamp column if there isn't one already. +@item +Only use double float fields. Some programs may fail when they compare +single floats. +@end itemize + +If the above doesn't help, you should do a @code{MyODBC} trace file and +try to figure out why things go wrong. + + +@node MyODBC clients, ODBC and last_insert_id, ODBC Problems, ODBC +@subsection Programs Known to Work with MyODBC + +Most programs should work with @strong{MyODBC}, but for each of those +listed below, we have tested it ourselves or received confirmation from +some user that it works: + +@table @asis +@item @strong{Program} +@strong{Comment} +@cindex Access program + +@item Access +To make Access work: +@itemize @bullet +@item +If you are using Access 2000, you should get and install the newest +Microsoft MDAC (@code{Microsoft Data Access Components}) from +@uref{http://www.microsoft.com/data}. This will fix the following bug +in Access: when you export data to @strong{MySQL}, the table and column +names aren't specified. Another way to around this bug is to upgrade to +MyODBC Version 2.50.33 and @strong{MySQL} Version 3.23.x, which together +provide a workaround for this bug! + +Note that if you are using @strong{MySQL} Version 3.22, you must to apply the +MDAC patch and use MyODBC 2.50.32 or 2.50.34 and above to go around +this problem. +@item +Set the ``Return matching rows'' MyODBC option field when connecting to +@strong{MySQL}. +@item +You should have a primary key in the table. If not, new or updated rows +may show up as @code{#Deleted#}. +@item +You should have a timestamp in all tables you want to be able to update. +For maximum portability @code{TIMESTAMP(14)} or simple @code{TIMESTAMP} +is recommended instead of other @code{TIMESTAMP(X)} variations. +@item +Only use double float fields. Access fails when comparing with single floats. +The symptom usually is that new or updated rows may show up as @code{#Deleted#} +or that you can't find or update rows. +@item +If you still get the error @code{Another user has changed your data} after +adding a @code{TIMESTAMP} column, the following trick may help you: + +Don't use @code{table} data sheet view. Create instead a form with the +fields you want, and use that @code{form} data sheet view. You should +set the @code{DefaultValue} property for the @code{TIMESTAMP} column to +@code{NOW()}. It may be a good idea to hide the @code{TIMESTAMP} column +from view so your users are not confused. +@item +Access on NT will report @code{BLOB} columns as @code{OLE OBJECTS}. If +you want to have @code{MEMO} columns instead, you should change the +column to @code{TEXT} with @code{ALTER TABLE}. +@item +Access can't always handle @code{DATE} columns properly. If you have a problem +with these, change the columns to @code{DATETIME}. +@item +In some cases, Access may generate illegal SQL queries that +@strong{MySQL} can't understand. You can fix this by selecting +@code{"Query|SQLSpecific|Pass-Through"} from the Access menu. +@item +If you have in Access a column defined as BYTE, Access will try to export this +as @code{TINYINT} instead of @code{TINYINT UNSIGNED}. This will give you +problems if you have values > 127 in the column! +@item +If you are using Access 7.0, You should use the option flag @code{Return +matching rows}. +@item +If you are using Access 2.0, You should use the option flags @code{Return +matching rows} and @code{Simulate ODBC 1.0}. +@end itemize + +@cindex ADO program +@item ADO +When you are coding with the ADO API and @strong{MyODBC} you need to put +attention in some default properties that aren't supported by the +@strong{MySQL} server. For example, using the @code{CursorLocation +Property} as @code{adUseServer} will return for the @code{RecordCount +Property} a result of -1. To have the right value, you need to set this +property to @code{adUseClient}, like is showing in the VB code below: + +@example +Dim myconn As New ADODB.Connection +Dim myrs As New Recordset +Dim mySQL As String +Dim myrows As Long + +myconn.Open "DSN=MyODBCsample" +mySQL = "SELECT * from user" +myrs.Source = mySQL +Set myrs.ActiveConnection = myconn +myrs.CursorLocation = adUseClient +myrs.Open +myrows = myrs.RecordCount + +myrs.Close +myconn.Close +@end example + +Another workaround is to use a @code{SELECT COUNT(*)} statement +for a similar query to get the correct row count. + +@item Active server pages (ASP) +You should use the option flag @code{Return matching rows}. + +@item BDE applications +To get these to work, you should set the option flags +@code{Don't optimize column widths} and @code{Return matching rows}. + +@cindex Borland Buidler 4 program +@item Borland Builder 4 +When you start a query you can use the property @code{Active} or use the +method @code{Open}. Note that @code{Active} will start by automatically +issuing a @code{SELECT * FROM ...} query that may not be a good thing if +your tables are big! +@item ColdFusion (On Unix) +The following information is taken from the ColdFusion documentation: + +Use the following information to configure ColdFusion Server for Linux +to use the unixODBC driver with @strong{MyODBC} for @strong{MySQL} data +sources. Allaire has verified that @strong{MyODBC} Version 2.50.26 +works with @strong{MySQL} Version 3.22.27 and ColdFusion for Linux. (Any +newer version should also work.) You can download @strong{MyODBC} at +@uref{http://www.mysql.com/downloads/api-myodbc.html} + +@cindex ColdFusion program +ColdFusion Version 4.5.1 allows you to us the ColdFusion Administrator +to add the @strong{MySQL} data source. However, the driver is not +included with ColdFusion Version 4.5.1. Before the @strong{MySQL} driver +will appear in the ODBC datasources drop-down list, you must build and +copy the @strong{MyODBC} driver to +@file{/opt/coldfusion/lib/libmyodbc.so}. + +The Contrib directory contains the program mydsn-xxx.zip which allows +you to build and remove the DSN registry file for the MyODBC driver +on Coldfusion applications. + +@cindex DataJunction +@item DataJunction +You have to change it to output @code{VARCHAR} rather than @code{ENUM}, as +it exports the latter in a manner that causes @strong{MySQL} grief. +@cindex Excel +@item Excel +Works. Some tips: +@itemize @bullet +@item +If you have problems with dates, try to select them as strings using the +@code{CONCAT()} function. For example: +@example +select CONCAT(rise_time), CONCAT(set_time) + from sunrise_sunset; +@end example +Values retrieved as strings this way should be correctly recognized +as time values by Excel97. + +The purpose of @code{CONCAT()} in this example is to fool ODBC into thinking +the column is of ``string type''. Without the @code{CONCAT()}, ODBC knows the +column is of time type, and Excel does not understand that. + +Note that this is a bug in Excel, because it automatically converts a +string to a time. This would be great if the source was a text file, but +is plain stupid when the source is an ODBC connection that reports +exact types for each column. +@end itemize +@cindex Word program +@item Word + +To retrieve data from @strong{MySQL} to Word/Excel documents, you need to +use the @code{MyODBC} driver and the Add-in Microsoft Query help. + +For example, create a db with a table containing 2 columns of text: + +@itemize @bullet +@item +Insert rows using the @code{mysql} client command-line tool. +@item +Create a DSN file using the MyODBC driver, for example, my for the db above. +@item +Open the Word application. +@item +Create a blank new documentation. +@item +Using the tool bar called Database, press the button insert database. +@item +Press the button Get Data. +@item +At the right hand of the screen Get Data, press the button Ms Query. +@item +In the Ms Query create a New Data Source using the DSN file my. +@item +Select the new query. +@item +Select the columns that you want. +@item +Make a filter if you want. +@item +Make a Sort if you want. +@item +Select Return Data to Microsoft Word. +@item +Click Finish. +@item +Click Insert data and select the records. +@item +Click OK and you see the rows in your Word document. +@end itemize + +@cindex odbcadmin program +@item odbcadmin +Test program for ODBC. +@cindex Delphi program +@item Delphi +You must use BDE Version 3.2 or newer. Set the `Don't optimize column width' +option field when connecting to @strong{MySQL}. + +Also, here is some potentially useful Delphi code that sets up both an +ODBC entry and a BDE entry for @strong{MyODBC} (the BDE entry requires a BDE +Alias Editor that is free at a Delphi Super Page near +you. (Thanks to Bryan Brunton @email{bryan@@flesherfab.com} for this): + +@example +fReg:= TRegistry.Create; + fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True); + fReg.WriteString('Database', 'Documents'); + fReg.WriteString('Description', ' '); + fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll'); + fReg.WriteString('Flag', '1'); + fReg.WriteString('Password', ''); + fReg.WriteString('Port', ' '); + fReg.WriteString('Server', 'xmark'); + fReg.WriteString('User', 'winuser'); + fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True); + fReg.WriteString('DocumentsFab', 'MySQL'); + fReg.CloseKey; + fReg.Free; + + Memo1.Lines.Add('DATABASE NAME='); + Memo1.Lines.Add('USER NAME='); + Memo1.Lines.Add('ODBC DSN=DocumentsFab'); + Memo1.Lines.Add('OPEN MODE=READ/WRITE'); + Memo1.Lines.Add('BATCH COUNT=200'); + Memo1.Lines.Add('LANGDRIVER='); + Memo1.Lines.Add('MAX ROWS=-1'); + Memo1.Lines.Add('SCHEMA CACHE DIR='); + Memo1.Lines.Add('SCHEMA CACHE SIZE=8'); + Memo1.Lines.Add('SCHEMA CACHE TIME=-1'); + Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT'); + Memo1.Lines.Add('SQLQRYMODE='); + Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE'); + Memo1.Lines.Add('ENABLE BCD=FALSE'); + Memo1.Lines.Add('ROWSET SIZE=20'); + Memo1.Lines.Add('BLOBS TO CACHE=64'); + Memo1.Lines.Add('BLOB SIZE=32'); + + AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines); +@end example + +@cindex C++Builder +@item C++Builder +Tested with BDE Version 3.0. The only known problem is that when the table +schema changes, query fields are not updated. BDE, however, does not seem +to recognize primary keys, only the index PRIMARY, though this has not +been a problem. + +@item Vision +You should use the option flag @code{Return matching rows}. + +@cindex Visual Basic +@item Visual Basic +To be able to update a table, you must define a primary key for the table. + +Visual Basic with ADO can't handle big integers. This means that some queries +like @code{SHOW PROCESSLIST} will not work properly. The fix is to set +add the option @code{OPTION=16834} in the ODBC connect string or set +the @code{Change BIGINT columns to INT} option in the MyODBC connect screen. +You may also want to set the @code{Return matching rows} option. + +@item VisualInterDev +If you get the error @code{[Microsoft][ODBC Driver Manager] Driver does +not support this parameter} the reason may be that you have a +@code{BIGINT} in your result. Try setting the @code{Change BIGINT +columns to INT} option in the MyODBC connect screen. + +@item Visual Objects +You should use the option flag @code{Don't optimize column widths}. +@end table + + +@node ODBC and last_insert_id, MyODBC bug report, MyODBC clients, ODBC +@subsection How to Get the Value of an @code{AUTO_INCREMENT} Column in ODBC + +@cindex AUTO-INCREMENT, ODBC + +A common problem is how to get the value of an automatically generated ID +from an @code{INSERT}. With ODBC, you can do something like this (assuming +that @code{auto} is an @code{AUTO_INCREMENT} field): + +@example +INSERT INTO foo (auto,text) VALUES(NULL,'text'); +SELECT LAST_INSERT_ID(); +@end example + +Or, if you are just going to insert the ID into another table, you can do this: + +@example +INSERT INTO foo (auto,text) VALUES(NULL,'text'); +INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text'); +@end example + +@xref{Getting unique ID}. + +For the benefit of some ODBC applications (at least Delphi and Access), +the following query can be used to find a newly inserted row: +@example +SELECT * FROM tbl_name WHERE auto IS NULL; +@end example + + +@node MyODBC bug report, , ODBC and last_insert_id, ODBC +@subsection Reporting Problems with MyODBC + +@cindex reporting, MyODBC problems +@cindex problems, ODBC +@cindex MyODBC, reporting problems + +If you encounter difficulties with @strong{MyODBC}, you should start by +making a log file from the ODBC manager (the log you get when requesting +logs from ODBCADMIN) and a @strong{MyODBC} log. + +To get a @strong{MyODBC} log, you need to do the following: + +@enumerate +@item +Ensure that you are using @code{myodbcd.dll} and not @code{myodbc.dll}. +The easiest way to do this is to get @code{myodbcd.dll} from the MyODBC +distribution and copy it over the @code{myodbc.dll}, which is probably +in your @code{C:\windows\system32} or @code{C:\winnt\system32} directory. + +Note that you probably want to restore the old myodbc.dll file when you +have finished testing, as this is a lot faster than @code{myodbcd.dll}. +@item +Tag the `Trace MyODBC' option flag in the @strong{MyODBC} connect/configure +screen. The log will be written to file @file{C:\myodbc.log}. + +If the trace option is not remembered when you are going back to the +above screen, it means that you are not using the @code{myodbcd.dll} +driver (see above). +@item +Start your application and try to get it to fail. +@end enumerate + +Check the @code{MyODBC trace file}, to find out what could be wrong. +You should be able to find out the issued queries by searching after +the string @code{>mysql_real_query} in the @file{myodbc.log} file. + +You should also try duplicating the queries in the @code{mysql} monitor +or @code{admndemo} to find out if the error is MyODBC or @strong{MySQL}. + +If you find out something is wrong, please only send the relevant rows +(max 40 rows) to @email{myodbc@@lists.mysql.com}. Please never +send the whole MyODBC or ODBC log file! + +If you are unable to find out what's wrong, the last option is to +make an archive (tar or zip) that contains a MyODBC trace file, the ODBC +log file, and a README file that explains the problem. You can send this +to @uref{ftp://support.mysql.com/pub/mysql/secret}. Only we at +@strong{MySQL AB} will have access to the files you upload, and we will +be very discrete with the data! + +If you can create a program that also shows this problem, please +upload this too! + +If the program works with some other SQL server, you should make an ODBC log +file where you do exactly the same thing in the other SQL server. + +Remember that the more information you can supply to us, the more +likely it is that we can fix the problem! + + +@node C, Cplusplus, ODBC, Clients +@section MySQL C API + +@cindex C API, datatypes +@cindex datatypes, C API + +@menu +* C API datatypes:: C API Datatypes +* C API function overview:: C API Function Overview +* C API functions:: C API Function Descriptions +* C API problems:: +* Building clients:: +* Thread-safe clients:: +@end menu + +The C API code is distributed with @strong{MySQL}. It is included in the +@code{mysqlclient} library and allows C programs to access a database. + +Many of the clients in the @strong{MySQL} source distribution are +written in C. If you are looking for examples that demonstrate how to +use the C API, take a look at these clients. You can find these in the +@code{clients} directory in the @strong{MySQL} source distribution. + +Most of the other client APIs (all except Java) use the @code{mysqlclient} +library to communicate with the @strong{MySQL} server. This means that, for +example, you can take advantage of many of the same environment variables +that are used by other client programs, because they are referenced from the +library. See @ref{Client-Side Scripts}, for a list of these variables. + +The client has a maximum communication buffer size. The size of the buffer +that is allocated initially (16K bytes) is automatically increased up to the +maximum size (the maximum is 16M). Because buffer sizes are increased +only as demand warrants, simply increasing the default maximum limit does not +in itself cause more resources to be used. This size check is mostly a check +for erroneous queries and communication packets. + +The communication buffer must be large enough to contain a single SQL +statement (for client-to-server traffic) and one row of returned data (for +server-to-client traffic). Each thread's communication buffer is dynamically +enlarged to handle any query or row up to the maximum limit. For example, if +you have @code{BLOB} values that contain up to 16M of data, you must have a +communication buffer limit of at least 16M (in both server and client). The +client's default maximum is 16M, but the default maximum in the server is +1M. You can increase this by changing the value of the +@code{max_allowed_packet} parameter when the server is started. @xref{Server +parameters}. + +The @strong{MySQL} server shrinks each communication buffer to +@code{net_buffer_length} bytes after each query. For clients, the size of +the buffer associated with a connection is not decreased until the connection +is closed, at which time client memory is reclaimed. + +For programming with threads, consult the 'how to make a thread-safe +client' chapter. @xref{Thread-safe clients}. + + +@node C API datatypes, C API function overview, C, C +@subsection C API Datatypes + +@table @code +@tindex MYSQL C type +@item MYSQL +This structure represents a handle to one database connection. It is +used for almost all @strong{MySQL} functions. + +@tindex MYSQL_RES C type +@item MYSQL_RES +This structure represents the result of a query that returns rows +(@code{SELECT}, @code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}). The +information returned from a query is called the @emph{result set} in the +remainder of this section. + +@tindex MYSQL_ROW C type +@item MYSQL_ROW +This is a type-safe representation of one row of data. It is currently +implemented as an array of counted byte strings. (You cannot treat these as +null-terminated strings if field values may contain binary data, because such +values may contain null bytes internally.) Rows are obtained by calling +@code{mysql_fetch_row()}. + +@tindex MYSQL_FIELD C type +@item MYSQL_FIELD +This structure contains information about a field, such as the field's +name, type, and size. Its members are described in more detail below. +You may obtain the @code{MYSQL_FIELD} structures for each field by +calling @code{mysql_fetch_field()} repeatedly. Field values are not part of +this structure; they are contained in a @code{MYSQL_ROW} structure. + + +@tindex MYSQL_FIELD_OFFSET C type +@item MYSQL_FIELD_OFFSET +This is a type-safe representation of an offset into a @strong{MySQL} field +list. (Used by @code{mysql_field_seek()}.) Offsets are field numbers +within a row, beginning at zero. + +@tindex my_ulonglong C type +@tindex my_ulonglong values, printing +@item my_ulonglong +The type used for the number of rows and for @code{mysql_affected_rows()}, +@code{mysql_num_rows()}, and @code{mysql_insert_id()}. This type provides a +range of @code{0} to @code{1.84e19}. + +On some systems, attempting to print a value of type @code{my_ulonglong} +will not work. To print such a value, convert it to @code{unsigned long} +and use a @code{%lu} print format. Example: +@example +printf (Number of rows: %lu\n", (unsigned long) mysql_num_rows(result)); +@end example +@end table + +@noindent +The @code{MYSQL_FIELD} structure contains the members listed below: + +@table @code +@item char * name +The name of the field, as a null-terminated string. + +@item char * table +The name of the table containing this field, if it isn't a calculated field. +For calculated fields, the @code{table} value is an empty string. + +@item char * def +The default value of this field, as a null-terminated string. This is set +only if you use @code{mysql_list_fields()}. + +@item enum enum_field_types type +The type of the field. +The @code{type} value may be one of the following: + +@multitable @columnfractions .3 .55 +@item @strong{Type value} @tab @strong{Type meaning} +@item @code{FIELD_TYPE_TINY} @tab @code{TINYINT} field +@item @code{FIELD_TYPE_SHORT} @tab @code{SMALLINT} field +@item @code{FIELD_TYPE_LONG} @tab @code{INTEGER} field +@item @code{FIELD_TYPE_INT24} @tab @code{MEDIUMINT} field +@item @code{FIELD_TYPE_LONGLONG} @tab @code{BIGINT} field +@item @code{FIELD_TYPE_DECIMAL} @tab @code{DECIMAL} or @code{NUMERIC} field +@item @code{FIELD_TYPE_FLOAT} @tab @code{FLOAT} field +@item @code{FIELD_TYPE_DOUBLE} @tab @code{DOUBLE} or @code{REAL} field +@item @code{FIELD_TYPE_TIMESTAMP} @tab @code{TIMESTAMP} field +@item @code{FIELD_TYPE_DATE} @tab @code{DATE} field +@item @code{FIELD_TYPE_TIME} @tab @code{TIME} field +@item @code{FIELD_TYPE_DATETIME} @tab @code{DATETIME} field +@item @code{FIELD_TYPE_YEAR} @tab @code{YEAR} field +@item @code{FIELD_TYPE_STRING} @tab String (@code{CHAR} or @code{VARCHAR}) field +@item @code{FIELD_TYPE_BLOB} @tab @code{BLOB} or @code{TEXT} field (use @code{max_length} to determine the maximum length) +@item @code{FIELD_TYPE_SET} @tab @code{SET} field +@item @code{FIELD_TYPE_ENUM} @tab @code{ENUM} field +@item @code{FIELD_TYPE_NULL} @tab @code{NULL}-type field +@item @code{FIELD_TYPE_CHAR} @tab Deprecated; use @code{FIELD_TYPE_TINY} instead +@end multitable + +You can use the @code{IS_NUM()} macro to test whether or not a field has a +numeric type. Pass the @code{type} value to @code{IS_NUM()} and it +will evaluate to TRUE if the field is numeric: + +@example +if (IS_NUM(field->type)) + printf("Field is numeric\n"); +@end example + +@item unsigned int length +The width of the field, as specified in the table definition. + +@item unsigned int max_length +The maximum width of the field for the result set (the length of the longest +field value for the rows actually in the result set). If you use +@code{mysql_store_result()} or @code{mysql_list_fields()}, this contains the +maximum length for the field. If you use @code{mysql_use_result()}, the +value of this variable is zero. + +@item unsigned int flags +Different bit-flags for the field. The @code{flags} value may have zero +or more of the following bits set: + +@multitable @columnfractions .3 .55 +@item @strong{Flag value} @tab @strong{Flag meaning} +@item @code{NOT_NULL_FLAG} @tab Field can't be @code{NULL} +@item @code{PRI_KEY_FLAG} @tab Field is part of a primary key +@item @code{UNIQUE_KEY_FLAG} @tab Field is part of a unique key +@item @code{MULTIPLE_KEY_FLAG} @tab Field is part of a non-unique key +@item @code{UNSIGNED_FLAG} @tab Field has the @code{UNSIGNED} attribute +@item @code{ZEROFILL_FLAG} @tab Field has the @code{ZEROFILL} attribute +@item @code{BINARY_FLAG} @tab Field has the @code{BINARY} attribute +@item @code{AUTO_INCREMENT_FLAG} @tab Field has the @code{AUTO_INCREMENT} +attribute +@item @code{ENUM_FLAG} @tab Field is an @code{ENUM} (deprecated) +@item @code{BLOB_FLAG} @tab Field is a @code{BLOB} or @code{TEXT} (deprecated) +@item @code{TIMESTAMP_FLAG} @tab Field is a @code{TIMESTAMP} (deprecated) +@end multitable + +Use of the @code{BLOB_FLAG}, @code{ENUM_FLAG}, and @code{TIMESTAMP_FLAG} +flags is deprecated because they indicate the type of a field rather +than an attribute of its type. It is preferable to test +@code{field->type} against @code{FIELD_TYPE_BLOB}, +@code{FIELD_TYPE_ENUM}, or @code{FIELD_TYPE_TIMESTAMP} instead. + +@noindent +The example below illustrates a typical use of the @code{flags} value: + +@example +if (field->flags & NOT_NULL_FLAG) + printf("Field can't be null\n"); +@end example + +You may use the following convenience macros to determine the boolean +status of the @code{flags} value: + +@multitable @columnfractions .3 .5 +@item @code{IS_NOT_NULL(flags)} @tab True if this field is defined as @code{NOT NULL} +@item @code{IS_PRI_KEY(flags)} @tab True if this field is a primary key +@item @code{IS_BLOB(flags)} @tab True if this field is a @code{BLOB} or @code{TEXT} (deprecated; test @code{field->type} instead) +@end multitable + +@item unsigned int decimals +The number of decimals for numeric fields. +@end table + + +@node C API function overview, C API functions, C API datatypes, C +@subsection C API Function Overview + +@cindex C API, functions +@cindex functions, C API + +The functions available in the C API are listed below and are described in +greater detail in the next section. +@xref{C API functions}. + +@multitable @columnfractions .3 .7 +@item @strong{mysql_affected_rows()} @tab +Returns the number of rows changed/deleted/inserted by the last @code{UPDATE}, +@code{DELETE}, or @code{INSERT} query. + +@item @strong{mysql_close()} @tab +Closes a server connection. + +@item @strong{mysql_connect()} @tab +Connects to a @strong{MySQL} server. This function is deprecated; use +@code{mysql_real_connect()} instead. + +@item @strong{mysql_change_user()} @tab +Changes user and database on an open connection. + +@item @strong{mysql_character_set_name()} @tab +Returns the name of the default character set for the connection. + +@item @strong{mysql_create_db()} @tab +Creates a database. This function is deprecated; use the SQL command +@code{CREATE DATABASE} instead. + +@item @strong{mysql_data_seek()} @tab +Seeks to an arbitrary row in a query result set. + +@item @strong{mysql_debug()} @tab +Does a @code{DBUG_PUSH} with the given string. + +@item @strong{mysql_drop_db()} @tab +Drops a database. This function is deprecated; use the SQL command +@code{DROP DATABASE} instead. + +@item @strong{mysql_dump_debug_info()} @tab +Makes the server write debug information to the log. + +@item @strong{mysql_eof()} @tab +Determines whether or not the last row of a result set has been read. +This function is deprecated; @code{mysql_errno()} or @code{mysql_error()} +may be used instead. + +@item @strong{mysql_errno()} @tab +Returns the error number for the most recently invoked @strong{MySQL} function. + +@item @strong{mysql_error()} @tab +Returns the error message for the most recently invoked @strong{MySQL} function. + +@item @strong{mysql_real_escape_string()} @tab +Escapes special characters in a string for use in a SQL statement taking +into account the current charset of the connection. + +@item @strong{mysql_escape_string()} @tab +Escapes special characters in a string for use in a SQL statement. + +@item @strong{mysql_fetch_field()} @tab +Returns the type of the next table field. + +@item @strong{mysql_fetch_field_direct()} @tab +Returns the type of a table field, given a field number. + +@item @strong{mysql_fetch_fields()} @tab +Returns an array of all field structures. + +@item @strong{mysql_fetch_lengths()} @tab +Returns the lengths of all columns in the current row. + +@item @strong{mysql_fetch_row()} @tab +Fetches the next row from the result set. + +@item @strong{mysql_field_seek()} @tab +Puts the column cursor on a specified column. + +@item @strong{mysql_field_count()} @tab +Returns the number of result columns for the most recent query. + +@item @strong{mysql_field_tell()} @tab +Returns the position of the field cursor used for the last +@code{mysql_fetch_field()}. + +@item @strong{mysql_free_result()} @tab +Frees memory used by a result set. + +@item @strong{mysql_get_client_info()} @tab +Returns client version information. + +@item @strong{mysql_get_host_info()} @tab +Returns a string describing the connection. + +@item @strong{mysql_get_proto_info()} @tab +Returns the protocol version used by the connection. + +@item @strong{mysql_get_server_info()} @tab +Returns the server version number. + +@item @strong{mysql_info()} @tab +Returns information about the most recently executed query. + +@item @strong{mysql_init()} @tab +Gets or initializes a @code{MYSQL} structure. + +@item @strong{mysql_insert_id()} @tab +Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous +query. + +@item @strong{mysql_kill()} @tab +Kills a given thread. + +@item @strong{mysql_list_dbs()} @tab +Returns database names matching a simple regular expression. + +@item @strong{mysql_list_fields()} @tab +Returns field names matching a simple regular expression. + +@item @strong{mysql_list_processes()} @tab +Returns a list of the current server threads. + +@item @strong{mysql_list_tables()} @tab +Returns table names matching a simple regular expression. + +@item @strong{mysql_num_fields()} @tab +Returns the number of columns in a result set. + +@item @strong{mysql_num_rows()} @tab +Returns the number of rows in a result set. + +@item @strong{mysql_options()} @tab +Sets connect options for @code{mysql_connect()}. + +@item @strong{mysql_ping()} @tab +Checks whether or not the connection to the server is working, reconnecting +as necessary. + +@item @strong{mysql_query()} @tab +Executes a SQL query specified as a null-terminated string. + +@item @strong{mysql_real_connect()} @tab +Connects to a @strong{MySQL} server. + +@item @strong{mysql_real_query()} @tab +Executes a SQL query specified as a counted string. + +@item @strong{mysql_reload()} @tab +Tells the server to reload the grant tables. + +@item @strong{mysql_row_seek()} @tab +Seeks to a row in a result set, using value returned from +@code{mysql_row_tell()}. + +@item @strong{mysql_row_tell()} @tab +Returns the row cursor position. + +@item @strong{mysql_select_db()} @tab +Selects a database. + +@item @strong{mysql_shutdown()} @tab +Shuts down the database server. + +@item @strong{mysql_stat()} @tab +Returns the server status as a string. + +@item @strong{mysql_store_result()} @tab +Retrieves a complete result set to the client. + +@item @strong{mysql_thread_id()} @tab +Returns the current thread ID. + +@item @strong{mysql_thread_save()} @tab +Returns 1 if the clients are compiled as thread-safe. + +@item @strong{mysql_use_result()} @tab +Initiates a row-by-row result set retrieval. +@end multitable + +To connect to the server, call @code{mysql_init()} to initialize a +connection handler, then call @code{mysql_real_connect()} with that +handler (along with other information such as the hostname, user name, +and password). Upon connection, @code{mysql_real_connect()} sets the +@code{reconnect} flag (part of the MYSQL structure) to a value of +@code{1}. This flag indicates, in the event that a query cannot be +performed because of a lost connection, to try reconnecting to the +server before giving up. When you are done with the connection, call +@code{mysql_close()} to terminate it. + +While a connection is active, the client may send SQL queries to the server +using @code{mysql_query()} or @code{mysql_real_query()}. The difference +between the two is that @code{mysql_query()} expects the query to be +specified as a null-terminated string whereas @code{mysql_real_query()} +expects a counted string. If the string contains binary data (which may +include null bytes), you must use @code{mysql_real_query()}. + +For each non-@code{SELECT} query (for example, @code{INSERT}, @code{UPDATE}, +@code{DELETE}), you can find out how many rows were changed (affected) +by calling @code{mysql_affected_rows()}. + +For @code{SELECT} queries, you retrieve the selected rows as a result set. +(Note that some statements are @code{SELECT}-like in that they return rows. +These include @code{SHOW}, @code{DESCRIBE}, and @code{EXPLAIN}. They should +be treated the same way as @code{SELECT} statements.) + +There are two ways for a client to process result sets. One way is to +retrieve the entire result set all at once by calling +@code{mysql_store_result()}. This function acquires from the server all the +rows returned by the query and stores them in the client. The second way is +for the client to initiate a row-by-row result set retrieval by calling +@code{mysql_use_result()}. This function initializes the retrieval, but does +not actually get any rows from the server. + +In both cases, you access rows by calling @code{mysql_fetch_row()}. With +@code{mysql_store_result()}, @code{mysql_fetch_row()} accesses rows that have +already been fetched from the server. With @code{mysql_use_result()}, +@code{mysql_fetch_row()} actually retrieves the row from the server. +Information about the size of the data in each row is available by +calling @code{mysql_fetch_lengths()}. + +After you are done with a result set, call @code{mysql_free_result()} +to free the memory used for it. + +The two retrieval mechanisms are complementary. Client programs should +choose the approach that is most appropriate for their requirements. +In practice, clients tend to use @code{mysql_store_result()} more +commonly. + +An advantage of @code{mysql_store_result()} is that because the rows have all +been fetched to the client, you not only can access rows sequentially, you +can move back and forth in the result set using @code{mysql_data_seek()} or +@code{mysql_row_seek()} to change the current row position within the result +set. You can also find out how many rows there are by calling +@code{mysql_num_rows()}. On the other hand, the memory requirements for +@code{mysql_store_result()} may be very high for large result sets and you +are more likely to encounter out-of-memory conditions. + +An advantage of @code{mysql_use_result()} is that the client requires less +memory for the result set because it maintains only one row at a time (and +because there is less allocation overhead, @code{mysql_use_result()} can be +faster). Disadvantages are that you must process each row quickly to avoid +tying up the server, you don't have random access to rows within the result +set (you can only access rows sequentially), and you don't know how many rows +are in the result set until you have retrieved them all. Furthermore, you +@emph{must} retrieve all the rows even if you determine in mid-retrieval that +you've found the information you were looking for. + +The API makes it possible for clients to respond appropriately to +queries (retrieving rows only as necessary) without knowing whether or +not the query is a @code{SELECT}. You can do this by calling +@code{mysql_store_result()} after each @code{mysql_query()} (or +@code{mysql_real_query()}). If the result set call succeeds, the query +was a @code{SELECT} and you can read the rows. If the result set call +fails, call @code{mysql_field_count()} to determine whether or not a +result was actually to be expected. If @code{mysql_field_count()} +returns zero, the query returned no data (indicating that it was an +@code{INSERT}, @code{UPDATE}, @code{DELETE}, etc.), and was not +expected to return rows. If @code{mysql_field_count()} is non-zero, the +query should have returned rows, but didn't. This indicates that the +query was a @code{SELECT} that failed. See the description for +@code{mysql_field_count()} for an example of how this can be done. + +Both @code{mysql_store_result()} and @code{mysql_use_result()} allow you to +obtain information about the fields that make up the result set (the number +of fields, their names and types, etc.). You can access field information +sequentially within the row by calling @code{mysql_fetch_field()} repeatedly, +or by field number within the row by calling +@code{mysql_fetch_field_direct()}. The current field cursor position may be +changed by calling @code{mysql_field_seek()}. Setting the field cursor +affects subsequent calls to @code{mysql_fetch_field()}. You can also get +information for fields all at once by calling @code{mysql_fetch_fields()}. + +For detecting and reporting errors, @strong{MySQL} provides access to error +information by means of the @code{mysql_errno()} and @code{mysql_error()} +functions. These return the error code or error message for the most +recently invoked function that can succeed or fail, allowing you to determine +when an error occurred and what it was. + + +@node C API functions, C API problems, C API function overview, C +@subsection C API Function Descriptions + +@menu +* mysql_affected_rows:: @code{mysql_affected_rows()} +* mysql_close:: @code{mysql_close()} +* mysql_connect:: @code{mysql_connect()} +* mysql_change_user:: @code{mysql_change_user()} +* mysql_character_set_name:: @code{mysql_character_set_name()} +* mysql_create_db:: @code{mysql_create_db()} +* mysql_data_seek:: @code{mysql_data_seek()} +* mysql_debug:: @code{mysql_debug()} +* mysql_drop_db:: @code{mysql_drop_db()} +* mysql_dump_debug_info:: @code{mysql_dump_debug_info()} +* mysql_eof:: @code{mysql_eof()} +* mysql_errno:: @code{mysql_errno()} +* mysql_error:: @code{mysql_error()} +* mysql_escape_string:: @code{mysql_escape_string()} +* mysql_fetch_field:: @code{mysql_fetch_field()} +* mysql_fetch_fields:: @code{mysql_fetch_fields()} +* mysql_fetch_field_direct:: @code{mysql_fetch_field_direct()} +* mysql_fetch_lengths:: @code{mysql_fetch_lengths()} +* mysql_fetch_row:: @code{mysql_fetch_row()} +* mysql_field_count:: @code{mysql_field_count()} +* mysql_field_seek:: @code{mysql_field_seek()} +* mysql_field_tell:: @code{mysql_field_tell()} +* mysql_free_result:: @code{mysql_free_result()} +* mysql_get_client_info:: @code{mysql_get_client_info()} +* mysql_get_host_info:: @code{mysql_get_host_info()} +* mysql_get_proto_info:: @code{mysql_get_proto_info()} +* mysql_get_server_info:: @code{mysql_get_server_info()} +* mysql_info:: @code{mysql_info()} +* mysql_init:: @code{mysql_init()} +* mysql_insert_id:: @code{mysql_insert_id()} +* mysql_kill:: @code{mysql_kill()} +* mysql_list_dbs:: @code{mysql_list_dbs()} +* mysql_list_fields:: @code{mysql_list_fields()} +* mysql_list_processes:: @code{mysql_list_processes()} +* mysql_list_tables:: @code{mysql_list_tables()} +* mysql_num_fields:: @code{mysql_num_fields()} +* mysql_num_rows:: @code{mysql_num_rows()} +* mysql_options:: @code{mysql_options()} +* mysql_ping:: @code{mysql_ping()} +* mysql_query:: @code{mysql_query()} +* mysql_real_connect:: @code{mysql_real_connect()} +* mysql_real_escape_string:: @code{mysql_real_escape_string()} +* mysql_real_query:: @code{mysql_real_query()} +* mysql_reload:: @code{mysql_reload()} +* mysql_row_seek:: @code{mysql_row_seek()} +* mysql_row_tell:: @code{mysql_row_tell()} +* mysql_select_db:: @code{mysql_select_db()} +* mysql_shutdown:: @code{mysql_shutdown()} +* mysql_stat:: @code{mysql_stat()} +* mysql_store_result:: @code{mysql_store_result()} +* mysql_thread_id:: @code{mysql_thread_id()} +* mysql_use_result:: @code{mysql_use_result()} +@end menu + +In the descriptions below, a parameter or return value of @code{NULL} means +@code{NULL} in the sense of the C programming language, not a +@strong{MySQL} @code{NULL} value. + +Functions that return a value generally return a pointer or an integer. +Unless specified otherwise, functions returning a pointer return a +non-@code{NULL} value to indicate success or a @code{NULL} value to indicate +an error, and functions returning an integer return zero to indicate success +or non-zero to indicate an error. Note that ``non-zero'' means just that. +Unless the function description says otherwise, do not test against a value +other than zero: + +@example +if (result) /* correct */ + ... error ... + +if (result < 0) /* incorrect */ + ... error ... + +if (result == -1) /* incorrect */ + ... error ... +@end example + +When a function returns an error, the @strong{Errors} subsection of the +function description lists the possible types of errors. You can +find out which of these occurred by calling @code{mysql_errno()}. +A string representation of the error may be obtained by calling +@code{mysql_error()}. + + +@node mysql_affected_rows, mysql_close, C API functions, C API functions +@subsubsection @code{mysql_affected_rows()} + +@findex @code{mysql_affected_rows()} + +@code{my_ulonglong mysql_affected_rows(MYSQL *mysql)} + +@subsubheading Description + +Returns the number of rows changed by the last @code{UPDATE}, deleted by +the last @code{DELETE} or inserted by the last @code{INSERT} +statement. May be called immediately after @code{mysql_query()} for +@code{UPDATE}, @code{DELETE}, or @code{INSERT} statements. For +@code{SELECT} statements, @code{mysql_affected_rows()} works like +@code{mysql_num_rows()}. + +@subsubheading Return Values + +An integer greater than zero indicates the number of rows affected or +retrieved. Zero indicates that no records where updated for an +@code{UPDATE} statement, no rows matched the @code{WHERE} clause in the +query or that no query has yet been executed. -1 indicates that the +query returned an error or that, for a @code{SELECT} query, +@code{mysql_affected_rows()} was called prior to calling +@code{mysql_store_result()}. + +@subsubheading Errors + +None. + +@subsubheading Example + +@example +mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10"); +printf("%ld products updated",(long) mysql_affected_rows(&mysql)); +@end example + +If one specifies the flag @code{CLIENT_FOUND_ROWS} when connecting to +@code{mysqld}, @code{mysql_affected_rows()} will return the number of +rows matched by the @code{WHERE} statement for @code{UPDATE} statements. + +Note that when one uses a @code{REPLACE} command, +@code{mysql_affected_rows()} will return 2 if the new row replaced and +old row. This is because in this case one row was inserted and then the +duplicate was deleted. + + +@node mysql_close, mysql_connect, mysql_affected_rows, C API functions +@subsubsection @code{mysql_close()} + +@findex @code{mysql_close()} + +@code{void mysql_close(MYSQL *mysql)} + +@subsubheading Description +Closes a previously opened connection. @code{mysql_close()} also deallocates +the connection handle pointed to by @code{mysql} if the handle was allocated +automatically by @code{mysql_init()} or @code{mysql_connect()}. + +@subsubheading Return Values + +None. + +@subsubheading Errors + +None. + + +@node mysql_connect, mysql_change_user, mysql_close, C API functions +@subsubsection @code{mysql_connect()} + +@findex @code{mysql_connect()} + +@code{MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)} + +@subsubheading Description + +This function is deprecated. It is preferable to use +@code{mysql_real_connect()} instead. + +@code{mysql_connect()} attempts to establish a connection to a @strong{MySQL} +database engine running on @code{host}. @code{mysql_connect()} must complete +successfully before you can execute any of the other API functions, with the +exception of @code{mysql_get_client_info()}. + +The meanings of the parameters are the same as for the corresponding +parameters for @code{mysql_real_connect()} with the difference that the +connection parameter may be @code{NULL}. In this case the C API +allocates memory for the connection structure automatically and frees it +when you call @code{mysql_close()}. The disadvantage of this approach is +that you can't retrieve an error message if the connection fails. (To +get error information from @code{mysql_errno()} or @code{mysql_error()}, +you must provide a valid @code{MYSQL} pointer.) + +@subsubheading Return Values + +Same as for @code{mysql_real_connect()}. + +@subsubheading Errors + +Same as for @code{mysql_real_connect()}. + + +@node mysql_change_user, mysql_character_set_name, mysql_connect, C API functions +@subsubsection @code{mysql_change_user()} + +@findex @code{mysql_change_user()} + +@code{my_bool mysql_change_user(MYSQL *mysql, const char *user, const +char *password, const char *db)} + +@subsubheading Description + +Changes the user and causes the database specified by @code{db} to +become the default (current) database on the connection specified by +@code{mysql}. In subsequent queries, this database is the default for +table references that do not include an explicit database specifier. + +This function was introduced in @strong{MySQL} Version 3.23.3. + +@code{mysql_change_user()} fails unless the connected user can be +authenticated or if he doesn't have permission to use the database. In +this case the user and database are not changed + +The @code{db} parameter may be set to @code{NULL} if you don't want to have a +default database. + +@subsubheading Return values + +Zero for success. Non-zero if an error occurred. + +@subsubheading Errors + +The same that you can get from @code{mysql_real_connect()}. + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@item ER_UNKNOWN_COM_ERROR +The @strong{MySQL} server doesn't implement this command (probably an old server) +@item ER_ACCESS_DENIED_ERROR +The user or password was wrong. +@item ER_BAD_DB_ERROR +The database didn't exist. +@item ER_DBACCESS_DENIED_ERROR +The user did not have access rights to the database. +@item ER_WRONG_DB_NAME +The database name was too long. +@end table + +@subsubheading Example + +@example +if (mysql_change_user(&mysql, "user", "password", "new_database")) +@{ + fprintf(stderr, "Failed to change user. Error: %s\n", + mysql_error(&mysql)); +@} +@end example + + +@node mysql_character_set_name, mysql_create_db, mysql_change_user, C API functions +@subsubsection @code{mysql_character_set_name()} + +@findex @code{mysql_character_set_name()} + +@code{const char *mysql_character_set_name(MYSQL *mysql)} + +@subsubheading Description + +Returns the default character set for the current connection. + +@subsubheading Return Values + +The default character set + +@subsubheading Errors +None. + + +@node mysql_create_db, mysql_data_seek, mysql_character_set_name, C API functions +@subsubsection @code{mysql_create_db()} + +@findex @code{mysql_create_db()} + +@code{int mysql_create_db(MYSQL *mysql, const char *db)} + +@subsubheading Description +Creates the database named by the @code{db} parameter. + +This function is deprecated. It is preferable to use @code{mysql_query()} +to issue a SQL @code{CREATE DATABASE} statement instead. + +@subsubheading Return Values + +Zero if the database was created successfully. Non-zero if an error +occurred. + +@subsubheading Errors +@table @code + +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. + +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. + +@item CR_SERVER_LOST +The connection to the server was lost during the query. + +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + +@subsubheading Example + +@example +if(mysql_create_db(&mysql, "my_database")) +@{ + fprintf(stderr, "Failed to create new database. Error: %s\n", + mysql_error(&mysql)); +@} +@end example + + +@node mysql_data_seek, mysql_debug, mysql_create_db, C API functions +@subsubsection @code{mysql_data_seek()} + +@findex @code{mysql_data_seek()} + +@code{void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)} + +@subsubheading Description +Seeks to an arbitrary row in a query result set. This requires that the +result set structure contains the entire result of the query, so +@code{mysql_data_seek()} may be used in conjunction only with +@code{mysql_store_result()}, not with @code{mysql_use_result()}. + +The offset should be a value in the range from 0 to +@code{mysql_num_rows(result)-1}. + +@subsubheading Return Values + +None. + +@subsubheading Errors +None. + + +@node mysql_debug, mysql_drop_db, mysql_data_seek, C API functions +@subsubsection @code{mysql_debug()} + +@findex @code{mysql_debug()} + +@code{void mysql_debug(char *debug)} + +@subsubheading Description +Does a @code{DBUG_PUSH} with the given string. @code{mysql_debug()} uses the +Fred Fish debug library. To use this function, you must compile the client +library to support debugging. +@xref{Debugging server}. @xref{Debugging client}. + +@subsubheading Return Values + +None. + +@subsubheading Errors +None. + +@subsubheading Example + +The call shown below causes the client library to generate a trace file in +@file{/tmp/client.trace} on the client machine: + +@example +mysql_debug("d:t:O,/tmp/client.trace"); +@end example + + +@node mysql_drop_db, mysql_dump_debug_info, mysql_debug, C API functions +@subsubsection @code{mysql_drop_db()} + +@findex @code{mysql_drop_db()} + +@code{int mysql_drop_db(MYSQL *mysql, const char *db)} + +@subsubheading Description +Drops the database named by the @code{db} parameter. + +This function is deprecated. It is preferable to use @code{mysql_query()} +to issue a SQL @code{DROP DATABASE} statement instead. + +@subsubheading Return Values + +Zero if the database was dropped successfully. Non-zero if an error +occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + +@subsubheading Example + +@example +if(mysql_drop_db(&mysql, "my_database")) + fprintf(stderr, "Failed to drop the database: Error: %s\n", + mysql_error(&mysql)); +@end example + + +@node mysql_dump_debug_info, mysql_eof, mysql_drop_db, C API functions +@subsubsection @code{mysql_dump_debug_info()} + +@findex @code{mysql_dump_debug_info()} + +@code{int mysql_dump_debug_info(MYSQL *mysql)} + +@subsubheading Description + +Instructs the server to write some debug information to the log. The +connected user must have the @strong{process} privilege for this to work. + +@subsubheading Return values + +Zero if the command was successful. Non-zero if an error occurred. + +@subsubheading Errors +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_eof, mysql_errno, mysql_dump_debug_info, C API functions +@subsubsection @code{mysql_eof()} + +@findex @code{mysql_eof()} + +@code{my_bool mysql_eof(MYSQL_RES *result)} + +@subsubheading Description + +This function is deprecated. @code{mysql_errno()} or @code{mysql_error()} +may be used instead. + +@code{mysql_eof()} determines whether or not the last row of a result +set has been read. + +If you acquire a result set from a successful call to +@code{mysql_store_result()}, the client receives the entire set in one +operation. In this case, a @code{NULL} return from @code{mysql_fetch_row()} +always means the end of the result set has been reached and it is +unnecessary to call @code{mysql_eof()}. + +On the other hand, if you use @code{mysql_use_result()} to initiate a result +set retrieval, the rows of the set are obtained from the server one by one as +you call @code{mysql_fetch_row()} repeatedly. Because an error may occur on +the connection during this process, a @code{NULL} return value from +@code{mysql_fetch_row()} does not necessarily mean the end of the result set +was reached normally. In this case, you can use @code{mysql_eof()} to +determine what happened. @code{mysql_eof()} returns a non-zero value if the +end of the result set was reached and zero if an error occurred. + +Historically, @code{mysql_eof()} predates the standard @strong{MySQL} error +functions @code{mysql_errno()} and @code{mysql_error()}. Because those error +functions provide the same information, their use is preferred over +@code{mysql_eof()}, which is now deprecated. (In fact, they provide more +information, because @code{mysql_eof()} returns only a boolean value whereas +the error functions indicate a reason for the error when one occurs.) + +@subsubheading Return Values + +Zero if no error occurred. Non-zero if the end of the result set has been +reached. + +@subsubheading Errors +None. + +@subsubheading Example + +The following example shows how you might use @code{mysql_eof()}: + +@example +mysql_query(&mysql,"SELECT * FROM some_table"); +result = mysql_use_result(&mysql); +while((row = mysql_fetch_row(result))) +@{ + // do something with data +@} +if(!mysql_eof(result)) // mysql_fetch_row() failed due to an error +@{ + fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); +@} +@end example + +However, you can achieve the same effect with the standard @strong{MySQL} +error functions: + +@example +mysql_query(&mysql,"SELECT * FROM some_table"); +result = mysql_use_result(&mysql); +while((row = mysql_fetch_row(result))) +@{ + // do something with data +@} +if(mysql_errno(&mysql)) // mysql_fetch_row() failed due to an error +@{ + fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); +@} +@end example + + +@node mysql_errno, mysql_error, mysql_eof, C API functions +@subsubsection @code{mysql_errno()} + +@findex @code{mysql_errno()} + +@code{unsigned int mysql_errno(MYSQL *mysql)} + +@subsubheading Description + +For the connection specified by @code{mysql}, @code{mysql_errno()} returns +the error code for the most recently invoked API function that can succeed +or fail. A return value of zero means that no error occurred. Client error +message numbers are listed in the @strong{MySQL} @file{errmsg.h} header file. +Server error message numbers are listed in @file{mysqld_error.h}. In the +@strong{MySQL} source distribution you can find a complete list of +error messages and error numbers in the file @file{Docs/mysqld_error.txt}. + +@subsubheading Return Values + +An error code value. Zero if no error occurred. + +@subsubheading Errors +None. + + +@node mysql_error, mysql_escape_string, mysql_errno, C API functions +@subsubsection @code{mysql_error()} + +@findex @code{mysql_error()} + +@code{char *mysql_error(MYSQL *mysql)} + +@subsubheading Description + +For the connection specified by @code{mysql}, @code{mysql_error()} returns +the error message for the most recently invoked API function that can succeed +or fail. An empty string (@code{""}) is returned if no error occurred. +This means the following two tests are equivalent: + +@example +if(mysql_errno(&mysql)) +@{ + // an error occurred +@} + +if(mysql_error(&mysql)[0] != '\0') +@{ + // an error occurred +@} +@end example + +The language of the client error messages may be changed by +recompiling the @strong{MySQL} client library. Currently you can choose +error messages in several different languages. +@xref{Languages}. + +@subsubheading Return Values + +A character string that describes the error. An empty string if no error +occurred. + +@subsubheading Errors +None. + + +@node mysql_escape_string, mysql_fetch_field, mysql_error, C API functions +@subsubsection @code{mysql_escape_string()} + +@findex @code{mysql_escape_string()} + +You should use @code{mysql_real_escape_string()} instead! + +This is identical to @code{mysql_real_escape_string()} except that it +takes the connection as the first +argument. @code{mysql_real_escape_string()} will escape the string +according to the current character set while +@code{mysql_escape_string()} does not respect the current charset +setting. + + +@node mysql_fetch_field, mysql_fetch_fields, mysql_escape_string, C API functions +@subsubsection @code{mysql_fetch_field()} + +@findex @code{mysql_fetch_field()} + +@code{MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)} + +@subsubheading Description + +Returns the definition of one column of a result set as a @code{MYSQL_FIELD} +structure. Call this function repeatedly to retrieve information about all +columns in the result set. @code{mysql_fetch_field()} returns @code{NULL} +when no more fields are left. + +@code{mysql_fetch_field()} is reset to return information about the first +field each time you execute a new @code{SELECT} query. The field returned by +@code{mysql_fetch_field()} is also affected by calls to +@code{mysql_field_seek()}. + +If you've called @code{mysql_query()} to perform a @code{SELECT} on a table +but have not called @code{mysql_store_result()}, @strong{MySQL} returns the +default blob length (8K bytes) if you call @code{mysql_fetch_field()} to ask +for the length of a @code{BLOB} field. (The 8K size is chosen because +@strong{MySQL} doesn't know the maximum length for the @code{BLOB}. This +should be made configurable sometime.) Once you've retrieved the result set, +@code{field->max_length} contains the length of the largest value for this +column in the specific query. + +@subsubheading Return Values + +The @code{MYSQL_FIELD} structure for the current column. @code{NULL} +if no columns are left. + +@subsubheading Errors +None. + +@subsubheading Example + +@example +MYSQL_FIELD *field; + +while((field = mysql_fetch_field(result))) +@{ + printf("field name %s\n", field->name); +@} +@end example + + +@node mysql_fetch_fields, mysql_fetch_field_direct, mysql_fetch_field, C API functions +@subsubsection @code{mysql_fetch_fields()} + +@findex @code{mysql_fetch_fields()} + +@code{MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)} + +@subsubheading Description + +Returns an array of all @code{MYSQL_FIELD} structures for a result set. +Each structure provides the field definition for one column of the result +set. + +@subsubheading Return Values + +An array of @code{MYSQL_FIELD} structures for all columns of a result set. + +@subsubheading Errors +None. + +@subsubheading Example + +@example +unsigned int num_fields; +unsigned int i; +MYSQL_FIELD *fields; + +num_fields = mysql_num_fields(result); +fields = mysql_fetch_fields(result); +for(i = 0; i < num_fields; i++) +@{ + printf("Field %u is %s\n", i, fields[i].name); +@} +@end example + + +@node mysql_fetch_field_direct, mysql_fetch_lengths, mysql_fetch_fields, C API functions +@subsubsection @code{mysql_fetch_field_direct()} + +@findex @code{mysql_fetch_field_direct()} + +@code{MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)} + +@subsubheading Description + +Given a field number @code{fieldnr} for a column within a result set, returns +that column's field definition as a @code{MYSQL_FIELD} structure. You may use +this function to retrieve the definition for an arbitrary column. The value +of @code{fieldnr} should be in the range from 0 to +@code{mysql_num_fields(result)-1}. + +@subsubheading Return Values + +The @code{MYSQL_FIELD} structure for the specified column. + +@subsubheading Errors +None. + +@subsubheading Example + +@example +unsigned int num_fields; +unsigned int i; +MYSQL_FIELD *field; + +num_fields = mysql_num_fields(result); +for(i = 0; i < num_fields; i++) +@{ + field = mysql_fetch_field_direct(result, i); + printf("Field %u is %s\n", i, field->name); +@} +@end example + + +@node mysql_fetch_lengths, mysql_fetch_row, mysql_fetch_field_direct, C API functions +@subsubsection @code{mysql_fetch_lengths()} + +@findex @code{mysql_fetch_lengths()} + +@code{unsigned long *mysql_fetch_lengths(MYSQL_RES *result)} + +@subsubheading Description + +Returns the lengths of the columns of the current row within a result set. +If you plan to copy field values, this length information is also useful for +optimization, because you can avoid calling @code{strlen()}. In addition, if +the result set contains binary data, you @emph{must} use this function to +determine the size of the data, because @code{strlen()} returns incorrect +results for any field containing null characters. + +The length for empty columns and for columns containing @code{NULL} values is +zero. To see how to distinguish these two cases, see the description for +@code{mysql_fetch_row()}. + +@subsubheading Return Values + +An array of unsigned long integers representing the size of each column (not +including any terminating null characters). +@code{NULL} if an error occurred. + +@subsubheading Errors +@code{mysql_fetch_lengths()} is valid only for the current row of the result +set. It returns @code{NULL} if you call it before calling +@code{mysql_fetch_row()} or after retrieving all rows in the result. + +@subsubheading Example + +@example +MYSQL_ROW row; +unsigned long *lengths; +unsigned int num_fields; +unsigned int i; + +row = mysql_fetch_row(result); +if (row) +@{ + num_fields = mysql_num_fields(result); + lengths = mysql_fetch_lengths(result); + for(i = 0; i < num_fields; i++) + @{ + printf("Column %u is %lu bytes in length.\n", i, lengths[i]); + @} +@} +@end example + + +@node mysql_fetch_row, mysql_field_count, mysql_fetch_lengths, C API functions +@subsubsection @code{mysql_fetch_row()} + +@findex @code{mysql_fetch_row()} + +@code{MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)} + +@subsubheading Description + +Retrieves the next row of a result set. When used after +@code{mysql_store_result()}, @code{mysql_fetch_row()} returns @code{NULL} +when there are no more rows to retrieve. When used after +@code{mysql_use_result()}, @code{mysql_fetch_row()} returns @code{NULL} when +there are no more rows to retrieve or if an error occurred. + +The number of values in the row is given by @code{mysql_num_fields(result)}. +If @code{row} holds the return value from a call to @code{mysql_fetch_row()}, +pointers to the values are accessed as @code{row[0]} to +@code{row[mysql_num_fields(result)-1]}. @code{NULL} values in the row are +indicated by @code{NULL} pointers. + +The lengths of the field values in the row may be obtained by calling +@code{mysql_fetch_lengths()}. Empty fields and fields containing +@code{NULL} both have length 0; you can distinguish these by checking +the pointer for the field value. If the pointer is @code{NULL}, the field +is @code{NULL}; otherwise the field is empty. + +@subsubheading Return Values + +A @code{MYSQL_ROW} structure for the next row. @code{NULL} if +there are no more rows to retrieve or if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + +@subsubheading Example + +@example +MYSQL_ROW row; +unsigned int num_fields; +unsigned int i; + +num_fields = mysql_num_fields(result); +while ((row = mysql_fetch_row(result))) +@{ + unsigned long *lengths; + lengths = mysql_fetch_lengths(result); + for(i = 0; i < num_fields; i++) + @{ + printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL"); + @} + printf("\n"); +@} +@end example + + +@node mysql_field_count, mysql_field_seek, mysql_fetch_row, C API functions +@subsubsection @code{mysql_field_count()} + +@findex @code{mysql_field_count()} + +@code{unsigned int mysql_field_count(MYSQL *mysql)} + +If you are using a version of @strong{MySQL} earlier than Version 3.22.24, you +should use @code{unsigned int mysql_num_fields(MYSQL *mysql)} instead. + +@subsubheading Description + +Returns the number of columns for the most recent query on the connection. + +The normal use of this function is when @code{mysql_store_result()} +returned @code{NULL} (and thus you have no result set pointer). +In this case, you can call @code{mysql_field_count()} to +determine whether or not @code{mysql_store_result()} should have produced a +non-empty result. This allows the client program to take proper action +without knowing whether or not the query was a @code{SELECT} (or +@code{SELECT}-like) statement. The example shown below illustrates how this +may be done. + +@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. + +@subsubheading Return Values + +An unsigned integer representing the number of fields in a result set. + +@subsubheading Errors +None. + +@subsubheading Example + +@example +MYSQL_RES *result; +unsigned int num_fields; +unsigned int num_rows; + +if (mysql_query(&mysql,query_string)) +@{ + // error +@} +else // query succeeded, process any data returned by it +@{ + result = mysql_store_result(&mysql); + if (result) // there are rows + @{ + num_fields = mysql_num_fields(result); + // retrieve rows, then call mysql_free_result(result) + @} + else // mysql_store_result() returned nothing; should it have? + @{ + if(mysql_field_count(&mysql) == 0) + @{ + // query does not return data + // (it was not a SELECT) + num_rows = mysql_affected_rows(&mysql); + @} + else // mysql_store_result() should have returned data + @{ + fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); + @} + @} +@} +@end example + +An alternative is to replace the @code{mysql_field_count(&mysql)} call with +@code{mysql_errno(&mysql)}. In this case, you are checking directly for an +error from @code{mysql_store_result()} rather than inferring from the value +of @code{mysql_field_count()} whether or not the statement was a +@code{SELECT}. + + +@node mysql_field_seek, mysql_field_tell, mysql_field_count, C API functions +@subsubsection @code{mysql_field_seek()} + +@findex @code{mysql_field_seek()} + +@code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)} + +@subsubheading Description + +Sets the field cursor to the given offset. The next call to +@code{mysql_fetch_field()} will retrieve the field definition of the column +associated with that offset. + +To seek to the beginning of a row, pass an @code{offset} value of zero. + +@subsubheading Return Values + +The previous value of the field cursor. + +@subsubheading Errors +None. + + +@node mysql_field_tell, mysql_free_result, mysql_field_seek, C API functions +@subsubsection @code{mysql_field_tell()} + +@findex @code{mysql_field_tell()} + +@code{MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)} + +@subsubheading Description + +Returns the position of the field cursor used for the last +@code{mysql_fetch_field()}. This value can be used as an argument to +@code{mysql_field_seek()}. + +@subsubheading Return Values + +The current offset of the field cursor. + +@subsubheading Errors +None. + + +@node mysql_free_result, mysql_get_client_info, mysql_field_tell, C API functions +@subsubsection @code{mysql_free_result()} + +@findex @code{mysql_free_result()} + +@code{void mysql_free_result(MYSQL_RES *result)} + +@subsubheading Description + +Frees the memory allocated for a result set by @code{mysql_store_result()}, +@code{mysql_use_result()}, @code{mysql_list_dbs()}, etc. When you are done +with a result set, you must free the memory it uses by calling +@code{mysql_free_result()}. + +@subsubheading Return Values + +None. + +@subsubheading Errors +None. + + +@node mysql_get_client_info, mysql_get_host_info, mysql_free_result, C API functions +@subsubsection @code{mysql_get_client_info()} + +@findex @code{mysql_get_client_info()} + +@code{char *mysql_get_client_info(void)} + +@subsubheading Description + +Returns a string that represents the client library version. + +@subsubheading Return Values + +A character string that represents the @strong{MySQL} client library version. + +@subsubheading Errors +None. + + +@node mysql_get_host_info, mysql_get_proto_info, mysql_get_client_info, C API functions +@subsubsection @code{mysql_get_host_info()} + +@findex @code{mysql_get_host_info()} + +@code{char *mysql_get_host_info(MYSQL *mysql)} + +@subsubheading Description + +Returns a string describing the type of connection in use, including the +server host name. + +@subsubheading Return Values + +A character string representing the server host name and the connection type. + +@subsubheading Errors +None. + + +@node mysql_get_proto_info, mysql_get_server_info, mysql_get_host_info, C API functions +@subsubsection @code{mysql_get_proto_info()} + +@findex @code{mysql_get_proto_info()} + +@code{unsigned int mysql_get_proto_info(MYSQL *mysql)} + +@subsubheading Description + +Returns the protocol version used by current connection. + +@subsubheading Return Values + +An unsigned integer representing the protocol version used by the current +connection. + +@subsubheading Errors +None. + + +@node mysql_get_server_info, mysql_info, mysql_get_proto_info, C API functions +@subsubsection @code{mysql_get_server_info()} + +@findex @code{mysql_get_server_info()} + +@code{char *mysql_get_server_info(MYSQL *mysql)} + +@subsubheading Description + +Returns a string that represents the server version number. + +@subsubheading Return Values + +A character string that represents the server version number. + +@subsubheading Errors +None. + + +@node mysql_info, mysql_init, mysql_get_server_info, C API functions +@subsubsection @code{mysql_info()} + +@findex @code{mysql_info()} + +@code{char *mysql_info(MYSQL *mysql)} + +@subsubheading Description + +Retrieves a string providing information about the most recently executed +query, but only for the statements listed below. For other statements, +@code{mysql_info()} returns @code{NULL}. The format of the string varies +depending on the type of query, as described below. The numbers are +illustrative only; the string will contain values appropriate for the query. + +@table @code +@item INSERT INTO ... SELECT ... +String format: @code{Records: 100 Duplicates: 0 Warnings: 0} +@item INSERT INTO ... VALUES (...),(...),(...)... +String format: @code{Records: 3 Duplicates: 0 Warnings: 0} +@item LOAD DATA INFILE ... +String format: @code{Records: 1 Deleted: 0 Skipped: 0 Warnings: 0} +@item ALTER TABLE +String format: @code{Records: 3 Duplicates: 0 Warnings: 0} +@item UPDATE +String format: @code{Rows matched: 40 Changed: 40 Warnings: 0} +@end table + +Note that @code{mysql_info()} returns a non-@code{NULL} value for the +@code{INSERT ... VALUES} statement only if multiple value lists are +specified in the statement. + +@subsubheading Return Values + +A character string representing additional information about the most +recently executed query. @code{NULL} if no information is available for the +query. + +@subsubheading Errors +None. + + +@node mysql_init, mysql_insert_id, mysql_info, C API functions +@subsubsection @code{mysql_init()} + +@findex @code{mysql_init()} + +@code{MYSQL *mysql_init(MYSQL *mysql)} + +@subsubheading Description + +Allocates or initializes a @code{MYSQL} object suitable for +@code{mysql_real_connect()}. If @code{mysql} is a @code{NULL} pointer, the +function allocates, initializes, and returns a new object. Otherwise the +object is initialized and the address of the object is returned. If +@code{mysql_init()} allocates a new object, it will be freed when +@code{mysql_close()} is called to close the connection. + +@subsubheading Return Values + +An initialized @code{MYSQL*} handle. @code{NULL} if there was +insufficient memory to allocate a new object. + +@subsubheading Errors +In case of insufficient memory, @code{NULL} is returned. + + +@node mysql_insert_id, mysql_kill, mysql_init, C API functions +@subsubsection @code{mysql_insert_id()} + +@findex @code{mysql_insert_id()} + +@code{my_ulonglong mysql_insert_id(MYSQL *mysql)} + +@subsubheading Description + +Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous +query. Use this function after you have performed an @code{INSERT} query +into a table that contains an @code{AUTO_INCREMENT} field. + +Note that @code{mysql_insert_id()} returns @code{0} if the previous query +does not generate an @code{AUTO_INCREMENT} value. If you need to save +the value for later, be sure to call @code{mysql_insert_id()} immediately +after the query that generates the value. + +Also note that the value of the SQL @code{LAST_INSERT_ID()} function always +contains the most recently generated @code{AUTO_INCREMENT} value, and is +not reset between queries because the value of that function is maintained +in the server. + +@subsubheading Return Values + +The value of the @code{AUTO_INCREMENT} field that was updated by the previous +query. Returns zero if there was no previous query on the connection or if +the query did not update an @code{AUTO_INCREMENT} value. + +@subsubheading Errors +None. + + +@node mysql_kill, mysql_list_dbs, mysql_insert_id, C API functions +@subsubsection @code{mysql_kill()} + +@findex @code{mysql_kill()} + +@code{int mysql_kill(MYSQL *mysql, unsigned long pid)} + +@subsubheading Description + +Asks the server to kill the thread specified by @code{pid}. + +@subsubheading Return Values + +Zero for success. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_list_dbs, mysql_list_fields, mysql_kill, C API functions +@subsubsection @code{mysql_list_dbs()} + +@findex @code{mysql_list_dbs()} + +@code{MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)} + +@subsubheading Description + +Returns a result set consisting of database names on the server that match +the simple regular expression specified by the @code{wild} parameter. +@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may +be a @code{NULL} pointer to match all databases. Calling +@code{mysql_list_dbs()} is similar to executing the query @code{SHOW +databases [LIKE wild]}. + +You must free the result set with @code{mysql_free_result()}. + +@subsubheading Return Values + +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_OUT_OF_MEMORY +Out of memory. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_list_fields, mysql_list_processes, mysql_list_dbs, C API functions +@subsubsection @code{mysql_list_fields()} + +@findex @code{mysql_list_fields()} + +@code{MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)} + +@subsubheading Description + +Returns a result set consisting of field names in the given table that match +the simple regular expression specified by the @code{wild} parameter. +@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may +be a @code{NULL} pointer to match all fields. Calling +@code{mysql_list_fields()} is similar to executing the query @code{SHOW +COLUMNS FROM tbl_name [LIKE wild]}. + +Note that it's recommended that you use @code{SHOW COLUMNS FROM tbl_name} +instead of @code{mysql_list_fields()}. + +You must free the result set with @code{mysql_free_result()}. + +@subsubheading Return Values + +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_list_processes, mysql_list_tables, mysql_list_fields, C API functions +@subsubsection @code{mysql_list_processes()} + +@findex @code{mysql_list_processes()} + +@code{MYSQL_RES *mysql_list_processes(MYSQL *mysql)} + +@subsubheading Description + +Returns a result set describing the current server threads. This is the same +kind of information as that reported by @code{mysqladmin processlist} or +a @code{SHOW PROCESSLIST} query. + +You must free the result set with @code{mysql_free_result()}. + +@subsubheading Return Values + +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_list_tables, mysql_num_fields, mysql_list_processes, C API functions +@subsubsection @code{mysql_list_tables()} + +@findex @code{mysql_list_tables()} + +@code{MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)} + +@subsubheading Description + +Returns a result set consisting of table names in the current database that +match the simple regular expression specified by the @code{wild} parameter. +@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may +be a @code{NULL} pointer to match all tables. Calling +@code{mysql_list_tables()} is similar to executing the query @code{SHOW +tables [LIKE wild]}. + +You must free the result set with @code{mysql_free_result()}. + +@subsubheading Return Values + +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_num_fields, mysql_num_rows, mysql_list_tables, C API functions +@subsubsection @code{mysql_num_fields()} + +@findex @code{mysql_num_fields()} +@findex @code{mysql_field_count()} + +@code{unsigned int mysql_num_fields(MYSQL_RES *result)} + +or + +@code{unsigned int mysql_num_fields(MYSQL *mysql)} + +The second form doesn't work on @strong{MySQL} Version 3.22.24 or newer. To pass a +@code{MYSQL*} argument, you must use +@code{unsigned int mysql_field_count(MYSQL *mysql)} instead. + +@subsubheading Description + +Returns the number of columns in a result set. + +Note that you can get the number of columns either from a pointer to a result +set or to a connection handle. You would use the connection handle if +@code{mysql_store_result()} or @code{mysql_use_result()} returned +@code{NULL} (and thus you have no result set pointer). In this case, you can +call @code{mysql_field_count()} to determine whether or not +@code{mysql_store_result()} should have produced a non-empty result. This +allows the client program to take proper action without knowing whether or +not the query was a @code{SELECT} (or @code{SELECT}-like) statement. The +example shown below illustrates how this may be done. + +@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. + +@subsubheading Return Values + +An unsigned integer representing the number of fields in a result set. + +@subsubheading Errors +None. + +@subsubheading Example + +@example +MYSQL_RES *result; +unsigned int num_fields; +unsigned int num_rows; + +if (mysql_query(&mysql,query_string)) +@{ + // error +@} +else // query succeeded, process any data returned by it +@{ + result = mysql_store_result(&mysql); + if (result) // there are rows + @{ + num_fields = mysql_num_fields(result); + // retrieve rows, then call mysql_free_result(result) + @} + else // mysql_store_result() returned nothing; should it have? + @{ + if (mysql_errno(&mysql)) + @{ + fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); + @} + else if (mysql_field_count(&mysql) == 0) + @{ + // query does not return data + // (it was not a SELECT) + num_rows = mysql_affected_rows(&mysql); + @} + @} +@} +@end example + +An alternative (if you KNOW that your query should have returned a result set) +is to replace the @code{mysql_errno(&mysql)} call with a check if +@code{mysql_field_count(&mysql)} is = 0. This will only happen if something +went wrong. + + +@node mysql_num_rows, mysql_options, mysql_num_fields, C API functions +@subsubsection @code{mysql_num_rows()} + +@findex @code{mysql_num_rows()} + +@code{my_ulonglong mysql_num_rows(MYSQL_RES *result)} + +@subsubheading Description + +Returns the number of rows in the result set. + +The use of @code{mysql_num_rows()} depends on whether you use +@code{mysql_store_result()} or @code{mysql_use_result()} to return the result +set. If you use @code{mysql_store_result()}, @code{mysql_num_rows()} may be +called immediately. If you use @code{mysql_use_result()}, +@code{mysql_num_rows()} will not return the correct value until all the rows +in the result set have been retrieved. + +@subsubheading Return Values + +The number of rows in the result set. + +@subsubheading Errors +None. + + +@node mysql_options, mysql_ping, mysql_num_rows, C API functions +@subsubsection @code{mysql_options()} + +@findex @code{mysql_options()} + +@code{int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)} + +@subsubheading Description + +Can be used to set extra connect options and affect behavior for a connection. +This function may be called multiple times to set several options. + +@code{mysql_options()} should be called after @code{mysql_init()} and before +@code{mysql_connect()} or @code{mysql_real_connect()}. + +The @code{option} argument is the option that you want to set; the @code{arg} +argument is the value for the option. If the option is an integer, then +@code{arg} should point to the value of the integer. + +Possible options values: + +@multitable @columnfractions .25 .25 .5 +@item @strong{Option} @tab @strong{Argument type} @tab @strong{Function} +@item @code{MYSQL_OPT_CONNECT_TIMEOUT} @tab @code{unsigned int *} @tab Connect timeout in seconds. +@item @code{MYSQL_OPT_COMPRESS} @tab Not used @tab Use the compressed client/server protocol. +@item @code{MYSQL_OPT_NAMED_PIPE} @tab Not used @tab Use named pipes to connect to a @strong{MySQL} server on NT. +@item @code{MYSQL_INIT_COMMAND} @tab @code{char *} @tab Command to execute when connecting to the @strong{MySQL} server. Will automatically be re-executed when reconnecting. +@item @code{MYSQL_READ_DEFAULT_FILE} @tab @code{char *} @tab Read options from the named option file instead of from @file{my.cnf}. +@item @code{MYSQL_READ_DEFAULT_GROUP} @tab @code{char *} @tab Read options from the named group from @file{my.cnf} or the file specified with @code{MYSQL_READ_DEFAULT_FILE}. +@end multitable + +Note that the group @code{client} is always read if you use +@code{MYSQL_READ_DEFAULT_FILE} or @code{MYSQL_READ_DEFAULT_GROUP}. + +The specified group in the option file may contain the following options: + +@multitable @columnfractions .3 .7 +@item @code{connect_timeout} @tab Connect timeout in seconds. On Linux this timeout is also used for waiting for the first answer from the server. +@item @code{compress} @tab Use the compressed client/server protocol. +@item @code{database} @tab Connect to this database if no database was specified in the connect command. +@item @code{debug} @tab Debug options. +@item @code{host} @tab Default host name. +@item @code{init-command} @tab Command to execute when connecting to @strong{MySQL} server. Will automatically be re-executed when reconnecting. +@item @code{interactive-timeout} @tab Same as specifying @code{CLIENT_INTERACTIVE} to @code{mysql_real_connect()}. @xref{mysql_real_connect}. +@item @code{password} @tab Default password. +@item @code{pipe} @tab Use named pipes to connect to a @strong{MySQL} server on NT. +@item @code{port} @tab Default port number. +@item @code{return-found-rows} @tab Tell @code{mysql_info()} to return found rows instead of updated rows when using @code{UPDATE}. +@item @code{socket} @tab Default socket number. +@item +@item @code{user} @tab Default user. +@end multitable + +Note that @code{timeout} has been replaced by @code{connect_timeout}, but +@code{timeout} will still work for a while. + +For more information about option files, see @ref{Option files}. + +@subsubheading Return Values + +Zero for success. Non-zero if you used an unknown option. + +@subsubheading Example + +@example +MYSQL mysql; + +mysql_init(&mysql); +mysql_options(&mysql,MYSQL_OPT_COMPRESS,0); +mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc"); +if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) +@{ + fprintf(stderr, "Failed to connect to database: Error: %s\n", + mysql_error(&mysql)); +@} +@end example + +The above requests the client to use the compressed client/server protocol and +read the additional options from the @code{odbc} section in the @code{my.cnf} +file. + + +@node mysql_ping, mysql_query, mysql_options, C API functions +@subsubsection @code{mysql_ping()} + +@findex @code{mysql_ping()} + +@code{int mysql_ping(MYSQL *mysql)} + +@subsubheading Description + +Checks whether or not the connection to the server is working. If it has gone +down, an automatic reconnection is attempted. + +This function can be used by clients that remain idle for a long while, +to check whether or not the server has closed the connection and reconnect +if necessary. + +@subsubheading Return Values + +Zero if the server is alive. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_query, mysql_real_connect, mysql_ping, C API functions +@subsubsection @code{mysql_query()} + +@findex @code{mysql_query()} + +@code{int mysql_query(MYSQL *mysql, const char *query)} + +@subsubheading Description +Executes the SQL query pointed to by the null-terminated string @code{query}. +The query must consist of a single SQL statement. You should not add +a terminating semicolon (@samp{;}) or @code{\g} to the statement. + +@code{mysql_query()} cannot be used for queries that contain binary data; you +should use @code{mysql_real_query()} instead. (Binary data may contain the +@samp{\0} character, which @code{mysql_query()} interprets as the end of the +query string.) + +If you want to know if the query should return a result set or not, you can +use @code{mysql_field_count()} to check for this. +@xref{mysql_field_count, , @code{mysql_field_count}}. + +@subsubheading Return Values + +Zero if the query was successful. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_real_connect, mysql_real_escape_string, mysql_query, C API functions +@subsubsection @code{mysql_real_connect()} + +@findex @code{mysql_real_connect()} + +@code{MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, + const char *user, const char *passwd, const char *db, + unsigned int port, const char *unix_socket, + unsigned int client_flag)} + +@subsubheading Description + +@code{mysql_real_connect()} attempts to establish a connection to a +@strong{MySQL} database engine running on @code{host}. +@code{mysql_real_connect()} must complete successfully before you can execute +any of the other API functions, with the exception of +@code{mysql_get_client_info()}. + +The parameters are specified as follows: + +@itemize @bullet +@item +The first parameter should be the address of an existing @code{MYSQL} +structure. Before calling @code{mysql_real_connect()} you must call +@code{mysql_init()} to initialize the @code{MYSQL} structure. You can +change a lot of connect options with the @code{mysql_options()} +call. @xref{mysql_options}. + +@item +The value of @code{host} may be either a hostname or an IP address. If +@code{host} is @code{NULL} or the string @code{"localhost"}, a connection to +the local host is assumed. If the OS supports sockets (Unix) or named pipes +(Windows), they are used instead of TCP/IP to connect to the server. + +@item +The @code{user} parameter contains the user's @strong{MySQL} login ID. If +@code{user} is @code{NULL}, the current user is assumed. Under Unix, this is +the current login name. Under Windows ODBC, the current user name must be +specified explicitly. +@xref{ODBC administrator}. + +@item +The @code{passwd} parameter contains the password for @code{user}. If +@code{passwd} is @code{NULL}, only entries in the @code{user} table for the +user that have a blank (empty) password field will be checked for a match. This +allows the database administrator to set up the @strong{MySQL} privilege +system in such a way that users get different privileges depending on whether +or not they have specified a password. + +NOTE: Do not attempt to encrypt the password before calling +@code{mysql_real_connect()}; password encryption is handled automatically by +the client API. + +@item +@code{db} is the database name. +If @code{db} is not @code{NULL}, the connection will set the default +database to this value. + +@item +If @code{port} is not 0, the value will be used as the port number +for the TCP/IP connection. Note that the @code{host} parameter +determines the type of the connection. + +@item +If @code{unix_socket} is not @code{NULL}, the string specifies the +socket or named pipe that should be used. Note that the @code{host} +parameter determines the type of the connection. + +@item +The value of @code{client_flag} is usually 0, but can be set to a combination +of the following flags in very special circumstances: + +@multitable @columnfractions .25 .7 +@item @strong{Flag name} @tab @strong{Flag meaning} +@code{mysqld} to be more ODBC-friendly. +@item @code{CLIENT_COMPRESS} @tab Use compression protocol. +@item @code{CLIENT_FOUND_ROWS} @tab Return the number of found (matched) rows, not the number of affected rows. +@item @code{CLIENT_IGNORE_SPACE} @tab Allow spaces after function names. Makes all functions names reserved words. +@item @code{CLIENT_INTERACTIVE} @tab Allow @code{interactive_timeout} seconds (instead of @code{wait_timeout} seconds) of inactivity before closing the connection. +@item @code{CLIENT_NO_SCHEMA} @tab Don't allow the @code{db_name.tbl_name.col_name} syntax. This is for ODBC. It causes the parser to generate an error if you use that syntax, which is useful for trapping bugs in some ODBC programs. +@item @code{CLIENT_ODBC} @tab The client is an ODBC client. This changes +@item @code{CLIENT_SSL} @tab Use SSL (encrypted protocol). +@end multitable +@end itemize + +@subsubheading Return Values + +A @code{MYSQL*} connection handle if the connection was successful, +@code{NULL} if the connection was unsuccessful. For a successful connection, +the return value is the same as the value of the first parameter, unless you +pass @code{NULL} for that parameter. + +@subsubheading Errors + +@table @code +@item CR_CONN_HOST_ERROR +Failed to connect to the @strong{MySQL} server. + +@item CR_CONNECTION_ERROR +Failed to connect to the local @strong{MySQL} server. + +@item CR_IPSOCK_ERROR +Failed to create an IP socket. + +@item CR_OUT_OF_MEMORY +Out of memory. + +@item CR_SOCKET_CREATE_ERROR +Failed to create a Unix socket. + +@item CR_UNKNOWN_HOST +Failed to find the IP address for the hostname. + +@item CR_VERSION_ERROR +A protocol mismatch resulted from attempting to connect to a server with a +client library that uses a different protocol version. This can happen if you +use a very old client library to connect to a new server that wasn't started +with the @code{--old-protocol} option. + +@item CR_NAMEDPIPEOPEN_ERROR +Failed to create a named pipe on Windows. + +@item CR_NAMEDPIPEWAIT_ERROR +Failed to wait for a named pipe on Windows. + +@item CR_NAMEDPIPESETSTATE_ERROR +Failed to get a pipe handler on Windows. + +@item CR_SERVER_LOST +If @code{connect_timeout} > 0 and it took longer then @code{connect_timeout} +seconds to connect to the server or if the server died while executing the +@code{init-command}. + +@end table + +@subsubheading Example + +@example +MYSQL mysql; + +mysql_init(&mysql); +mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name"); +if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) +@{ + fprintf(stderr, "Failed to connect to database: Error: %s\n", + mysql_error(&mysql)); +@} +@end example + +By using @code{mysql_options()} the @strong{MySQL} library will read the +@code{[client]} and @code{your_prog_name} sections in the @code{my.cnf} +file which will ensure that your program will work, even if someone has +set up @strong{MySQL} in some non-standard way. + +Note that upon connection, @code{mysql_real_connect()} sets the @code{reconnect} +flag (part of the MYSQL structure) to a value of @code{1}. This flag indicates, +in the event that a query cannot be performed because of a lost connection, to +try reconnecting to the server before giving up. + + +@node mysql_real_escape_string, mysql_real_query, mysql_real_connect, C API functions +@subsubsection @code{mysql_real_escape_string()} + +@findex @code{mysql_real_escape_string()} + +@code{unsigned int mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned int length)} + +@subsubheading Description + +This function is used to create a legal SQL string that you can use in a +SQL statement. @xref{String syntax}. + +The string in @code{from} is encoded to an escaped SQL string, taking +into account the current character set of the connection. The result is placed +in @code{to} and a terminating null byte is appended. Characters +encoded are @code{NUL} (ASCII 0), @samp{\n}, @samp{\r}, @samp{\}, +@samp{'}, @samp{"}, and Control-Z (@pxref{Literals}). + +The string pointed to by @code{from} must be @code{length} bytes long. You +must allocate the @code{to} buffer to be at least @code{length*2+1} bytes +long. (In the worse case, each character may need to be encoded as using two +bytes, and you need room for the terminating null byte.) When +@code{mysql_escape_string()} returns, the contents of @code{to} will be a +null-terminated string. The return value is the length of the encoded +string, not including the terminating null character. + +@subsubheading Example + +@example +char query[1000],*end; + +end = strmov(query,"INSERT INTO test_table values("); +*end++ = '\''; +end += mysql_real_escape_string(&mysql, end,"What's this",11); +*end++ = '\''; +*end++ = ','; +*end++ = '\''; +end += mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16); +*end++ = '\''; +*end++ = ')'; + +if (mysql_real_query(&mysql,query,(unsigned int) (end - query))) +@{ + fprintf(stderr, "Failed to insert row, Error: %s\n", + mysql_error(&mysql)); +@} +@end example + +The @code{strmov()} function used in the example is included in the +@code{mysqlclient} library and works like @code{strcpy()} but returns a +pointer to the terminating null of the first parameter. + +@subsubheading Return Values + +The length of the value placed into @code{to}, not including the +terminating null character. + +@subsubheading Errors +None. + + +@node mysql_real_query, mysql_reload, mysql_real_escape_string, C API functions +@subsubsection @code{mysql_real_query()} + +@findex @code{mysql_real_query()} + +@code{int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)} + +@subsubheading Description + +Executes the SQL query pointed to by @code{query}, which should be a string +@code{length} bytes long. The query must consist of a single SQL statement. +You should not add a terminating semicolon (@samp{;}) or @code{\g} to the +statement. + +You @emph{must} use @code{mysql_real_query()} rather than +@code{mysql_query()} for queries that contain binary data, because binary data +may contain the @samp{\0} character. In addition, @code{mysql_real_query()} +is faster than @code{mysql_query()} because it does not call @code{strlen()} on +the query string. + +If you want to know if the query should return a result set or not, you can +use @code{mysql_field_count()} to check for this. +@xref{mysql_field_count, @code{mysql_field_count}}. + +@subsubheading Return Values + +Zero if the query was successful. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_reload, mysql_row_seek, mysql_real_query, C API functions +@subsubsection @code{mysql_reload()} + +@findex @code{mysql_reload()} + +@code{int mysql_reload(MYSQL *mysql)} + +@subsubheading Description + +Asks the @strong{MySQL} server to reload the grant tables. The +connected user must have the @strong{reload} privilege. + +This function is deprecated. It is preferable to use @code{mysql_query()} +to issue a SQL @code{FLUSH PRIVILEGES} statement instead. + +@subsubheading Return Values + +Zero for success. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_row_seek, mysql_row_tell, mysql_reload, C API functions +@subsubsection @code{mysql_row_seek()} + +@findex @code{mysql_row_seek()} + +@code{MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)} + +@subsubheading Description +Sets the row cursor to an arbitrary row in a query result set. This requires +that the result set structure contains the entire result of the query, so +@code{mysql_row_seek()} may be used in conjunction only with +@code{mysql_store_result()}, not with @code{mysql_use_result()}. + +The offset should be a value returned from a call to @code{mysql_row_tell()} +or to @code{mysql_row_seek()}. This value is not simply a row number; if you +want to seek to a row within a result set using a row number, use +@code{mysql_data_seek()} instead. + +@subsubheading Return Values + +The previous value of the row cursor. This value may be passed to a +subsequent call to @code{mysql_row_seek()}. + +@subsubheading Errors +None. + + +@node mysql_row_tell, mysql_select_db, mysql_row_seek, C API functions +@subsubsection @code{mysql_row_tell()} + +@findex @code{mysql_row_tell()} + +@code{MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)} + +@subsubheading Description + +Returns the current position of the row cursor for the last +@code{mysql_fetch_row()}. This value can be used as an argument to +@code{mysql_row_seek()}. + +You should use @code{mysql_row_tell()} only after @code{mysql_store_result()}, +not after @code{mysql_use_result()}. + +@subsubheading Return Values + +The current offset of the row cursor. + +@subsubheading Errors +None. + + +@node mysql_select_db, mysql_shutdown, mysql_row_tell, C API functions +@subsubsection @code{mysql_select_db()} + +@findex @code{mysql_select_db()} + +@code{int mysql_select_db(MYSQL *mysql, const char *db)} + +@subsubheading Description + +Causes the database specified by @code{db} to become the default (current) +database on the connection specified by @code{mysql}. In subsequent queries, +this database is the default for table references that do not include an +explicit database specifier. + +@code{mysql_select_db()} fails unless the connected user can be authenticated +as having permission to use the database. + +@subsubheading Return Values + +Zero for success. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_shutdown, mysql_stat, mysql_select_db, C API functions +@subsubsection @code{mysql_shutdown()} + +@findex @code{mysql_shutdown()} + +@code{int mysql_shutdown(MYSQL *mysql)} + +@subsubheading Description + +Asks the database server to shut down. The connected user must have +@strong{shutdown} privileges. + +@subsubheading Return Values + +Zero for success. Non-zero if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_stat, mysql_store_result, mysql_shutdown, C API functions +@subsubsection @code{mysql_stat()} + +@findex @code{mysql_stat()} + +@code{char *mysql_stat(MYSQL *mysql)} + +@subsubheading Description + +Returns a character string containing information similar to that provided by +the @code{mysqladmin status} command. This includes uptime in seconds and +the number of running threads, questions, reloads, and open tables. + +@subsubheading Return Values + +A character string describing the server status. @code{NULL} if an +error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_store_result, mysql_thread_id, mysql_stat, C API functions +@subsubsection @code{mysql_store_result()} + +@findex @code{mysql_store_result()} + +@code{MYSQL_RES *mysql_store_result(MYSQL *mysql)} + +@subsubheading Description + +You must call @code{mysql_store_result()} or @code{mysql_use_result()} +for every query that successfully retrieves data (@code{SELECT}, +@code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}). + +You don't have to call @code{mysql_store_result()} or +@code{mysql_use_result()} for other queries, but it will not do any +harm or cause any notable performance if you call @code{mysql_store_result()} +in all cases. You can detect if the query didn't have a result set by +checking if @code{mysql_store_result()} returns 0 (more about this later one). + +If you want to know if the query should return a result set or not, you can +use @code{mysql_field_count()} to check for this. +@xref{mysql_field_count, @code{mysql_field_count}}. + +@code{mysql_store_result()} reads the entire result of a query to the client, +allocates a @code{MYSQL_RES} structure, and places the result into this +structure. + +@code{mysql_store_results()} returns a null pointer if the query didn't return +a result set (if the query was, for example, an @code{INSERT} statement). + +@code{mysql_store_results()} also returns a null pointer if reading of the +result set failed. You can check if you got an error by checking if +@code{mysql_error()} doesn't return a null pointer, if +@code{mysql_errno()} returns <> 0, or if @code{mysql_field_count()} +returns <> 0. + +An empty result set is returned if there are no rows returned. (An empty +result set differs from a null pointer as a return value.) + +Once you have called @code{mysql_store_result()} and got a result back +that isn't a null pointer, you may call @code{mysql_num_rows()} to find +out how many rows are in the result set. + +You can call @code{mysql_fetch_row()} to fetch rows from the result set, +or @code{mysql_row_seek()} and @code{mysql_row_tell()} to obtain or +set the current row position within the result set. + +You must call @code{mysql_free_result()} once you are done with the result +set. + +@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. + +@subsubheading Return Values + +A @code{MYSQL_RES} result structure with the results. @code{NULL} if +an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_OUT_OF_MEMORY +Out of memory. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node mysql_thread_id, mysql_use_result, mysql_store_result, C API functions +@subsubsection @code{mysql_thread_id()} + +@findex @code{mysql_thread_id()} + +@code{unsigned long mysql_thread_id(MYSQL *mysql)} + +@subsubheading Description + +Returns the thread ID of the current connection. This value can be used as +an argument to @code{mysql_kill()} to kill the thread. + +If the connection is lost and you reconnect with @code{mysql_ping()}, the +thread ID will change. This means you should not get the thread ID and store +it for later. You should get it when you need it. + +@subsubheading Return Values + +The thread ID of the current connection. + +@subsubheading Errors +None. + + +@node mysql_use_result, , mysql_thread_id, C API functions +@subsubsection @code{mysql_use_result()} + +@findex @code{mysql_use_result()} + +@code{MYSQL_RES *mysql_use_result(MYSQL *mysql)} + +@subsubheading Description + +You must call @code{mysql_store_result()} or @code{mysql_use_result()} for +every query that successfully retrieves data (@code{SELECT}, @code{SHOW}, +@code{DESCRIBE}, @code{EXPLAIN}). + +@code{mysql_use_result()} initiates a result set retrieval but does not +actually read the result set into the client like @code{mysql_store_result()} +does. Instead, each row must be retrieved individually by making calls to +@code{mysql_fetch_row()}. This reads the result of a query directly from the +server without storing it in a temporary table or local buffer, which is +somewhat faster and uses much less memory than @code{mysql_store_result()}. +The client will only allocate memory for the current row and a communication +buffer that may grow up to @code{max_allowed_packet} bytes. + +On the other hand, you shouldn't use @code{mysql_use_result()} if you are +doing a lot of processing for each row on the client side, or if the output +is sent to a screen on which the user may type a @code{^S} (stop scroll). +This will tie up the server and prevent other threads from updating any +tables from which the data is being fetched. + +When using @code{mysql_use_result()}, you must execute +@code{mysql_fetch_row()} until a @code{NULL} value is returned, otherwise the +unfetched rows will be returned as part of the result set for your next +query. The C API will give the error @code{Commands out of sync; You can't +run this command now} if you forget to do this! + +You may not use @code{mysql_data_seek()}, @code{mysql_row_seek()}, +@code{mysql_row_tell()}, @code{mysql_num_rows()}, or +@code{mysql_affected_rows()} with a result returned from +@code{mysql_use_result()}, nor may you issue other queries until the +@code{mysql_use_result()} has finished. (However, after you have fetched all +the rows, @code{mysql_num_rows()} will accurately return the number of rows +fetched.) + +You must call @code{mysql_free_result()} once you are done with the result +set. + +@subsubheading Return Values + +A @code{MYSQL_RES} result structure. @code{NULL} if an error occurred. + +@subsubheading Errors + +@table @code +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. +@item CR_OUT_OF_MEMORY +Out of memory. +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. +@item CR_SERVER_LOST +The connection to the server was lost during the query. +@item CR_UNKNOWN_ERROR +An unknown error occurred. +@end table + + +@node C API problems, Building clients, C API functions, C +@subsection Common questions and problems when using the C API + +@tindex @code{mysql_query()} +@tindex @code{mysql_store_result()} + +@menu +* NULL mysql_store_result:: +* Query results:: +* Getting unique ID:: +* C API linking problems:: +@end menu + + +@node NULL mysql_store_result, Query results, C API problems, C API problems +@subsubsection Why Is It that After @code{mysql_query()} Returns Success, @code{mysql_store_result()} Sometimes Returns @code{NULL?} + +It is possible for @code{mysql_store_result()} to return @code{NULL} +following a successful call to @code{mysql_query()}. When this happens, it +means one of the following conditions occurred: + +@itemize @bullet +@item +There was a @code{malloc()} failure (for example, if the result set was too +large). + +@item +The data couldn't be read (an error occurred on the connection). + +@item +The query returned no data (for example, it was an @code{INSERT}, +@code{UPDATE}, or @code{DELETE}). +@end itemize + +You can always check whether or not the statement should have produced a +non-empty result by calling @code{mysql_field_count()}. If +@code{mysql_field_count()} returns zero, the result is empty and the last +query was a statement that does not return values (for example, an +@code{INSERT} or a @code{DELETE}). If @code{mysql_field_count()} returns a +non-zero value, the statement should have produced a non-empty result. +See the description of the @code{mysql_field_count()} function for an +example. + +You can test for an error by calling @code{mysql_error()} or +@code{mysql_errno()}. + +@cindex queries, C API results +@menu +* Query results:: +* Getting unique ID:: +* C API linking problems:: +@end menu + + +@node Query results, Getting unique ID, NULL mysql_store_result, C API problems +@subsubsection What Results Can I Get From a Query? + +In addition to the result set returned by a query, you can also get the +following information: + +@itemize @bullet +@item +@code{mysql_affected_rows()} returns the number of rows affected by the last +query when doing an @code{INSERT}, @code{UPDATE}, or @code{DELETE}. An +exception is that if @code{DELETE} is used without a @code{WHERE} clause, the +table is re-created empty, which is much faster! In this case, +@code{mysql_affected_rows()} returns zero for the number of records +affected. + +@item +@code{mysql_num_rows()} returns the number of rows in a result set. With +@code{mysql_store_result()}, @code{mysql_num_rows()} may be called as soon as +@code{mysql_store_result()} returns. With @code{mysql_use_result()}, +@code{mysql_num_rows()} may be called only after you have fetched all the +rows with @code{mysql_fetch_row()}. + +@item +@code{mysql_insert_id()} returns the ID generated by the last +query that inserted a row into a table with an @code{AUTO_INCREMENT} index. +@xref{mysql_insert_id, , @code{mysql_insert_id()}}. + +@item +Some queries (@code{LOAD DATA INFILE ...}, @code{INSERT INTO +... SELECT ...}, @code{UPDATE}) return additional information. The result is +returned by @code{mysql_info()}. See the description for @code{mysql_info()} +for the format of the string that it returns. @code{mysql_info()} returns a +@code{NULL} pointer if there is no additional information. +@end itemize + + +@node Getting unique ID, C API linking problems, Query results, C API problems +@subsubsection How Can I Get the Unique ID for the Last Inserted Row? + +@cindex unique ID +@cindex last row, unique ID +@cindex ID, unique +@cindex tables, unique ID for last row + +If you insert a record in a table containing a column that has the +@code{AUTO_INCREMENT} attribute, you can get the most recently generated +ID by calling the @code{mysql_insert_id()} function. + +You can also retrieve the ID by using the @code{LAST_INSERT_ID()} function in +a query string that you pass to @code{mysql_query()}. + +You can check if an @code{AUTO_INCREMENT} index is used by executing +the following code. This also checks if the query was an @code{INSERT} with +an @code{AUTO_INCREMENT} index: + +@example +if (mysql_error(&mysql)[0] == 0 && + mysql_num_fields(result) == 0 && + mysql_insert_id(&mysql) != 0) +@{ + used_id = mysql_insert_id(&mysql); +@} +@end example + +The most recently generated ID is maintained in the server on a +per-connection basis. It will not be changed by another client. It will not +even be changed if you update another @code{AUTO_INCREMENT} column with a +non-magic value (that is, a value that is not @code{NULL} and not @code{0}). + +If you want to use the ID that was generated for one table and insert +it into a second table, you can use SQL statements like this: + +@example +INSERT INTO foo (auto,text) + VALUES(NULL,'text'); # generate ID by inserting NULL +INSERT INTO foo2 (id,text) + VALUES(LAST_INSERT_ID(),'text'); # use ID in second table +@end example + + +@node C API linking problems, , Getting unique ID, C API problems +@subsubsection Problems Linking with the C API + +@cindex linking, problems +@cindex C API, linking problems + +When linking with the C API, the following errors may occur on some systems: + +@example +gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl + +Undefined first referenced + symbol in file +floor /usr/local/lib/mysql/libmysqlclient.a(password.o) +ld: fatal: Symbol referencing errors. No output written to client +@end example + +If this happens on your system, you must include the math library by +adding @code{-lm} to the end of the compile/link line. + + +@node Building clients, Thread-safe clients, C API problems, C +@subsection Building Client Programs + +@cindex client programs, building +@cindex linking +@cindex building, client programs +@cindex programs, client + +If you compile @strong{MySQL} clients that you've written yourself or that +you obtain from a third party, they must be linked using the +@code{-lmysqlclient -lz} option on the link command. You may also need to +specify a @code{-L} option to tell the linker where to find the library. For +example, if the library is installed in @file{/usr/local/mysql/lib}, use +@code{-L/usr/local/mysql/lib -lmysqlclient -lz} on the link command. + +For clients that use @strong{MySQL} header files, you may need to specify a +@code{-I} option when you compile them (for example, +@code{-I/usr/local/mysql/include}), so the compiler can find the header +files. + + +@node Thread-safe clients, , Building clients, C +@subsection How to Make a Thread-safe Client + +@cindex clients, thread-safe +@cindex thread-safe clients + +The client library is almost thread safe. The biggest problem is +that the subroutines in @file{net.c} that read from sockets are not +interrupt safe. This was done with the thought that you might want to +have your own alarm that can break a long read to a server. If you +install interrupt handlers for the @code{SIGPIPE} interrupt, +the socket handling should be thread safe. + +In the older binaries we distribute on our Web site, the client +libraries are not normally compiled with the thread-safe option (the +Windows binaries are by default compiled to be thread safe). +Newer binary distributions should have both a normal and a +thread-safe client library. + +To get a really thread-safe client where you can interrupt the client +from other threads and set timeouts when talking with the @strong{MySQL} +server, you should use the @code{-lmysys}, @code{-lstring}, and @code{-ldbug} +libraries and the @code{net_serv.o} code that the server uses. + +If you don't need interrupts or timeouts, you can just compile a thread +safe client library @code{(mysqlclient_r)} and use this. @xref{C,, +MySQL C API}. In this case you don't have to worry about the +@code{net_serv.o} object file or the other @strong{MySQL} libraries. + +When using a threaded client and you want to use timeouts and interrupts, +you can make great use of the routines in the @file{thr_alarm.c} file. +If you are using routines from the @code{mysys} library, the only thing +you must remember is to call @code{my_init()} first! + +All functions except @code{mysql_real_connect()} are by default +thread safe. The following notes describe how to compile a thread safe +client library and use it in a thread-safe manner. (The notes below for +@code{mysql_real_connect()} actually apply to @code{mysql_connect()} as +well, but because @code{mysql_connect()} is deprecated, you should be +using @code{mysql_real_connect()} anyway.) + +To make @code{mysql_real_connect()} thread safe, you must recompile the +client library with this command: + +@example +shell> ./configure --with-thread-safe-client +@end example + +This will create a thread-safe client library @code{libmysqlclient_r}. +@code{--with-thread-safe-client}. This library is thread safe per +connection. You can let two threads share the same connection as long +as you do the following: + +@itemize @bullet +@item +Two threads can't send a query to the @strong{MySQL} at the same time on +the same connection. In particular, you have to ensure that between a +@code{mysql_query()} and @code{mysql_store_result()} no other thread is using +the same connection. +@item +Many threads can access different result sets that are retrieved with +@code{mysql_store_result()}. +@item +If you use @code{mysql_use_result}, you have to ensure that no other thread +is asking anything on the same connection until the result set is closed. +However, it really is best for threaded clients that share the same +connection to use @code{mysql_use_result()}. +@item +If you want to use multiple threads on the same connection, you must +have a mutex lock around your @code{mysql_query()} and +@code{mysql_store_result()} call combination. Once +@code{mysql_store_result()} is ready, the lock can be released and other +threads may query the same connection. +@item +If you program with POSIX threads, you can use +@code{pthread_mutex_lock()} and @code{pthread_mutex_unlock()} to +establish and release a mutex lock. +@end itemize + +You may get some errors because of undefined symbols when linking your +client with @code{mysqlclient_r}. In most cases this is because you haven't +included the thread libraries on the link/compile line. + + +@node Cplusplus, Java, C, Clients +@section MySQL C++ APIs + +@menu +* Borland C++:: +@end menu + + +@cindex C++ APIs + +Two APIs are available in the @strong{MySQL} +@uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory}. + + +@node Borland C++, , Cplusplus, Cplusplus +@subsection Borland C++ + +@cindex Borland C++ compiler + +You can compile the @strong{MySQL} Windows source with Borland C++ 5.02. +(The Windows source includes only projects for Microsoft VC++, for +Borland C++ you have to do the project files yourself). + +One known problem with Borland C++ is that it uses a different structure +alignment than VC++. This means that you will run into problems if you +try to use the default @code{libmysql.dll} libraries (that was compiled +with VC++) with Borland C++. You can do one of the following to avoid +this problem. + +@itemize @bullet +@item +You can use the static @strong{MySQL} libraries for Borland C++ that you +can find on @uref{http://www.mysql.com/downloads/os-win32.html}. +@item +Only call @code{mysql_init()} with @code{NULL} as an argument, not a +pre-allocated MYSQL struct. +@end itemize + + +@node Java, Python, Cplusplus, Clients +@section MySQL Java Connectivity (JDBC) + +@cindex Java connectivity +@cindex JDBC + +There are 2 supported JDBC drivers for @strong{MySQL} (the mm driver and +the Reisin JDBC driver). You can find a copy of the mm driver at +@uref{http://mmmysql.sourceforge.net/} or +@uref{http://www.mysql.com/Downloads/Contrib/} and the Reisin driver at +@uref{http://www.caucho.com/projects/jdbc-mysql/index.xtp} For +documentation consult any JDBC documentation and the driver's own +documentation for @strong{MySQL}-specific features. + + +@node Python, Tcl, Java, Clients +@section MySQL Python APIs + +@cindex Python APIs + +The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} +contains a Python interface written by Joseph Skinner. + +You can also use the Python interface to iODBC to access a +@strong{MySQL} server. +@uref{http://starship.skyport.net/~lemburg/,mxODBC} + + +@node Tcl, Eiffel, Python, Clients +@section MySQL Tcl APIs + +@cindex Tcl APIs + +@uref{http://www.binevolve.com/~tdarugar/tcl-sql/, Tcl at binevolve}. +The +@uref{http://www.mysql.com/Downloads/Contrib,Contrib directory} contains a Tcl +interface that is based on msqltcl 1.50. + + +@node Eiffel, , Tcl, Clients +@section MySQL Eiffel wrapper + +@cindex Eiffel Wrapper +@cindex wrappers, Eiffel + +The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} +contains an Eiffel wrapper written by Michael Ravits. + +You can also find this at: +@url{http://www.netpedia.net/hosting/newplayer/} + + + + +@node Extending MySQL, Problems, Clients, Top @chapter Extending MySQL @menu @@ -38205,4163 +42503,7 @@ do that. Just specify the @code{--with-debug} options to @code{configure}! -@node ODBC, Common programs, Extending MySQL, Top -@chapter MySQL ODBC Support - -@cindex ODBC -@cindex Windows -@cindex MyODBC - -@menu -* Installing MyODBC:: How to install MyODBC -* ODBC administrator:: How to fill in the various fields in the ODBC administrator program -* MyODBC connect parameters:: -* ODBC Problems:: How to report problems with @strong{MySQL} ODBC -* MyODBC clients:: Programs known to work with @strong{MyODBC} -* ODBC and last_insert_id:: How to get the value of an @code{AUTO_INCREMENT} column in ODBC -* MyODBC bug report:: Reporting problems with MyODBC -@end menu - - -@strong{MySQL} provides support for ODBC by means of the @strong{MyODBC} -program. This chapter will teach you how to install @strong{MyODBC}, -and how to use it. Here, you will also find a list of common programs that -are known to work with @strong{MyODBC}. - - -@node Installing MyODBC, ODBC administrator, ODBC, ODBC -@section How To Install MyODBC - -@strong{MyODBC} is a 32-bit ODBC (2.50) level 0 (with level 1 and level -2 features) driver for connecting an ODBC-aware application to -@strong{MySQL}. @strong{MyODBC} works on Windows95, Windows98, NT, and -on most Unix platforms. - -@strong{MyODBC} is in public domain, and you can find the newest version -at @uref{http://www.mysql.com/downloads/api-myodbc.html}. - -If you have problem with @strong{MyODBC} and your program also works -with OLEDB, you should try the OLEDB driver that you can find in the -Contrib section. @xref{Contrib}. - -Normally you only need to install @strong{MyODBC} on Windows machines. -You only need @strong{MyODBC} for Unix if you have a program like -ColdFusion that is running on the Unix machine and uses ODBC to connect -to the databases. - -If you want to install @strong{MyODBC} on a Unix box, you will also need -an @strong{ODBC} manager. @strong{MyODBC} is known to work with -most of the Unix ODBC managers. You can find a list at these in the -@strong{ODBC}-related links section on the @strong{MySQL} useful links page. -@xref{Useful Links}. - -To install @strong{MyODBC} on Windows, you should download the -appropriate @strong{MyODBC} .zip file (for Windows or NT/Win2000), -unpack it with @code{WINZIP}, or some similar program, and execute the -@code{SETUP.EXE} file. - -On Windows/NT you may get the following error when trying to install -@strong{MyODBC}: - -@example -An error occurred while copying C:\WINDOWS\SYSTEM\MFC30.DLL. Restart -Windows and try installing again (before running any applications which -use ODBC) -@end example - -The problem in this case is that some other program is using ODBC and -because of how Windows is designed, you may not in this case be able to -install a new ODBC drivers with Microsoft's ODBC setup program. In most -cases you can continue by just pressing @code{Ignore} to copy the rest -of the MyODBC files and the final installation should still work. If -this doesn't work, the solution is to reboot your computer in ``safe -mode`` (Choose this by pressing F8 just before your machine starts -Windows during rebooting), install @strong{MyODBC}, and reboot to normal -mode. - -@itemize @bullet -@item -To make a connection to a Unix box from a Windows box, with an ODBC -application (one that doesn't support @strong{MySQL} natively), you must -first install @strong{MyODBC} on the Windows machine. -@item -The user and Windows machine must have the access privileges to the -@strong{MySQL} server on the Unix machine. This is set up with the -@code{GRANT} command. @xref{GRANT,,@code{GRANT}}. -@item -You must create an ODBC DSN entry as follows: - -@itemize @minus -@item -Open the Control Panel on the Windows machine. -@item -Double-click the ODBC Data Sources 32 bits icon. -@item -Click the tab User DSN. -@item -Click the button Add. -@item -Select @strong{MySQL} in the screen Create New Data Source and click -the Finish button. -@item -The @strong{MySQL} Driver default configuration screen is shown. -@xref{ODBC administrator}. -@end itemize - -@item -Now start your application and select the ODBC driver with the DSN you -specified in the ODBC administrator. -@end itemize - -Notice that there are other configuration options on the screen of -@strong{MySQL} (trace, don't prompt on connect, etc) that you can try if -you run into problems. - - -@node ODBC administrator, MyODBC connect parameters, Installing MyODBC, ODBC -@section How to Fill in the Various Fields in the ODBC Administrator Program - -@cindex ODBC, administrator - -There are three possibilities for specifying the server name on -Windows95: - -@itemize @bullet -@item -Use the IP address of the server. -@item -Add a file @file{\windows\lmhosts} with the following information: - -@example -ip hostname -@end example - -For example: - -@example -194.216.84.21 my_hostname -@end example - -@item -Configure the PC to use DNS. -@end itemize - -Example of how to fill in the @code{ODBC setup}: -@example -Windows DSN name: test -Description: This is my test database -MySql Database: test -Server: 194.216.84.21 -User: monty -Password: my_password -Port: -@end example - -The value for the @code{Windows DSN name} field is any name that is unique -in your Windows ODBC setup. - -You don't have to specify values for the @code{Server}, @code{User}, -@code{Password}, or @code{Port} fields in the ODBC setup screen. -However, if you do, the values will be used as the defaults later when -you attempt to make a connection. You have the option of changing the -values at that time. - -If the port number is not given, the default port (@value{default_port}) -is used. - -If you specify the option @code{Read options from C:\my.cnf}, the groups -@code{client} and @code{odbc} will be read from the @file{C:\my.cnf} file. -You can use all options that are usable by @code{mysql_options()}. -@xref{mysql_options, , @code{mysql_options}}. - - -@node MyODBC connect parameters, ODBC Problems, ODBC administrator, ODBC -@section Connect parameters for MyODBC - -One can specify the following parameters for @strong{MyODBC} on -the @code{[Servername]} section of an @code{ODBC.INI} file or -through the @code{InConnectionString} argument in the -@code{SQLDriverConnect()} call. - -@multitable @columnfractions .2 .2 .6 -@item @strong{Parameter} @tab @strong{Default value} @tab @strong{Comment} -@item user @tab ODBC (on Windows) @tab The username used to connect to @strong{MySQL}. -@item server @tab localhost @tab The hostname of the @strong{MySQL} server. -@item database @tab @tab The default database -@item option @tab 0 @tab A integer by which you can specify how @strong{MyODBC} should work. See below. -@item port @tab 3306 @tab The TCP/IP port to use if @code{server} is not @code{localhost}. -@item stmt @tab @tab A statement that will be executed when connection to @code{MySQL}. -@item password @tab @tab The password for the @code{server} @code{user} combination. -@item socket @tab @tab The socket or Windows pipe to connect to. -@end multitable - -The option argument is used to tell @strong{MyODBC} that the client isn't 100% -ODBC compliant. On Windows, one normally sets the option flag by -toggling the different options on the connection screen but one can also -set this in the opton argument. The following options are listed in the -same order as they appear in the @strong{MyODBC} connect screen: - -@multitable @columnfractions .1 .9 -@item @strong{Bit} @tab @strong{Meaning} -@item 1 @tab The client can't handle that @strong{MyODBC} returns the real width of a column. -@item 2 @tab The client can't handle that MySQL returns the true value of affected rows. If this flag is set then MySQL returns 'found rows' instead. One must have MySQL 3.21.14 or newer to get this to work. -@item 4 @tab Make a debug log in c:\myodbc.log. This is the same as putting @code{MYSQL_DEBUG=d:t:O,c::\myodbc.log} in @file{AUTOEXEC.BAT} -@item 8 @tab Don't set any packet limit for results and parameters. -@item 16 @tab Don't prompt for questions even if driver would like to prompt -@item 32 @tab Simulate a ODBC 1.0 driver in some context. -@item 64 @tab Ignore use of database name in 'database.table.column'. -@item 128 @tab Force use of ODBC manager cursors (experimental). -@item 256 @tab Disable the use of extended fetch (experimental) -@item 512 @tab Pad CHAR fields to full column length. -@item 1024 @tab SQLDescribeCol() will return fully qualifed column names -@item 2048 @tab Use the compressed server/client protocol -@item 4096 @tab Tell server to ignore space after function name and before @code{'('} (needed by PowerBuilder). This will make all function names keywords! -@item 8192 @tab Connect with named pipes to a @code{mysqld} server running on NT. -@item 16384 @tab Change LONGLONG columns to INT columns (Some applications can't handle LONGLONG). -@item 32768 @tab Return 'user' as Table_qualifier and Table_owner from SQLTables (experimental) -@item 65536 @tab Read parameters from the @code{client} and @code{odbc} groups from @file{my.cnf} -@item 131072 @tab Add some extra safety checks (should not bee needed but...) -@end multitable - -If you want to have many options, you should add the above flags! For -example setting option to 12 (4+8) gives you debugging without package -limits! - -The default @file{MYODBC.DLL} is compiled for optimal performance. If -you want to to debug @strong{MyODBC} (for example to enable tracing), -you should instead use @code{MYODBCD.DLL}. To install this file, copy -@file{MYODBCD.DLL} over the installed @code{MYODBC.DLL} file. - - -@node ODBC Problems, MyODBC clients, MyODBC connect parameters, ODBC -@section How to Report Problems with MyODBC - -@strong{MyODBC} has been tested with Access, Admndemo.exe, C++-Builder, -Borland Builder 4, Centura Team Developer (formerly Gupta SQL/Windows), -ColdFusion (on Solaris and NT with svc pack 5), Crystal Reports, -DataJunction, Delphi, ERwin, Excel, iHTML, FileMaker Pro, FoxPro, Notes -4.5/4.6, SBSS, Perl DBD-ODBC, Paradox, Powerbuilder, Powerdesigner 32 -bit, VC++, and Visual Basic. - -If you know of any other applications that work with @strong{MyODBC}, please -send mail to @email{myodbc@@lists.mysql.com} about this! - -With some programs you may get an error like: -@code{Another user has modifies the record that you have modified}. In most -cases this can be solved by doing one of the following things: - -@itemize @bullet -@item -Add a primary key for the table if there isn't one already. -@item -Add a timestamp column if there isn't one already. -@item -Only use double float fields. Some programs may fail when they compare -single floats. -@end itemize - -If the above doesn't help, you should do a @code{MyODBC} trace file and -try to figure out why things go wrong. - - -@node MyODBC clients, ODBC and last_insert_id, ODBC Problems, ODBC -@section Programs Known to Work with MyODBC - -Most programs should work with @strong{MyODBC}, but for each of those -listed below, we have tested it ourselves or received confirmation from -some user that it works: - -@table @asis -@item @strong{Program} -@strong{Comment} -@cindex Access program - -@item Access -To make Access work: -@itemize @bullet -@item -If you are using Access 2000, you should get and install the newest -Microsoft MDAC (@code{Microsoft Data Access Components}) from -@uref{http://www.microsoft.com/data}. This will fix the following bug -in Access: when you export data to @strong{MySQL}, the table and column -names aren't specified. Another way to around this bug is to upgrade to -MyODBC Version 2.50.33 and @strong{MySQL} Version 3.23.x, which together -provide a workaround for this bug! - -Note that if you are using @strong{MySQL} Version 3.22, you must to apply the -MDAC patch and use MyODBC 2.50.32 or 2.50.34 and above to go around -this problem. -@item -Set the ``Return matching rows'' MyODBC option field when connecting to -@strong{MySQL}. -@item -You should have a primary key in the table. If not, new or updated rows -may show up as @code{#Deleted#}. -@item -You should have a timestamp in all tables you want to be able to update. -For maximum portability @code{TIMESTAMP(14)} or simple @code{TIMESTAMP} -is recommended instead of other @code{TIMESTAMP(X)} variations. -@item -Only use double float fields. Access fails when comparing with single floats. -The symptom usually is that new or updated rows may show up as @code{#Deleted#} -or that you can't find or update rows. -@item -If you still get the error @code{Another user has changed your data} after -adding a @code{TIMESTAMP} column, the following trick may help you: - -Don't use @code{table} data sheet view. Create instead a form with the -fields you want, and use that @code{form} data sheet view. You should -set the @code{DefaultValue} property for the @code{TIMESTAMP} column to -@code{NOW()}. It may be a good idea to hide the @code{TIMESTAMP} column -from view so your users are not confused. -@item -Access on NT will report @code{BLOB} columns as @code{OLE OBJECTS}. If -you want to have @code{MEMO} columns instead, you should change the -column to @code{TEXT} with @code{ALTER TABLE}. -@item -Access can't always handle @code{DATE} columns properly. If you have a problem -with these, change the columns to @code{DATETIME}. -@item -In some cases, Access may generate illegal SQL queries that -@strong{MySQL} can't understand. You can fix this by selecting -@code{"Query|SQLSpecific|Pass-Through"} from the Access menu. -@item -If you have in Access a column defined as BYTE, Access will try to export this -as @code{TINYINT} instead of @code{TINYINT UNSIGNED}. This will give you -problems if you have values > 127 in the column! -@item -If you are using Access 7.0, You should use the option flag @code{Return -matching rows}. -@item -If you are using Access 2.0, You should use the option flags @code{Return -matching rows} and @code{Simulate ODBC 1.0}. -@end itemize - -@cindex ADO program -@item ADO -When you are coding with the ADO API and @strong{MyODBC} you need to put -attention in some default properties that aren't supported by the -@strong{MySQL} server. For example, using the @code{CursorLocation -Property} as @code{adUseServer} will return for the @code{RecordCount -Property} a result of -1. To have the right value, you need to set this -property to @code{adUseClient}, like is showing in the VB code below: - -@example -Dim myconn As New ADODB.Connection -Dim myrs As New Recordset -Dim mySQL As String -Dim myrows As Long - -myconn.Open "DSN=MyODBCsample" -mySQL = "SELECT * from user" -myrs.Source = mySQL -Set myrs.ActiveConnection = myconn -myrs.CursorLocation = adUseClient -myrs.Open -myrows = myrs.RecordCount - -myrs.Close -myconn.Close -@end example - -Another workaround is to use a @code{SELECT COUNT(*)} statement -for a similar query to get the correct row count. - -@item Active server pages (ASP) -You should use the option flag @code{Return matching rows}. - -@item BDE applications -To get these to work, you should set the option flags -@code{Don't optimize column widths} and @code{Return matching rows}. - -@cindex Borland Buidler 4 program -@item Borland Builder 4 -When you start a query you can use the property @code{Active} or use the -method @code{Open}. Note that @code{Active} will start by automatically -issuing a @code{SELECT * FROM ...} query that may not be a good thing if -your tables are big! -@item ColdFusion (On Unix) -The following information is taken from the ColdFusion documentation: - -Use the following information to configure ColdFusion Server for Linux -to use the unixODBC driver with @strong{MyODBC} for @strong{MySQL} data -sources. Allaire has verified that @strong{MyODBC} Version 2.50.26 -works with @strong{MySQL} Version 3.22.27 and ColdFusion for Linux. (Any -newer version should also work.) You can download @strong{MyODBC} at -@uref{http://www.mysql.com/downloads/api-myodbc.html} - -@cindex ColdFusion program -ColdFusion Version 4.5.1 allows you to us the ColdFusion Administrator -to add the @strong{MySQL} data source. However, the driver is not -included with ColdFusion Version 4.5.1. Before the @strong{MySQL} driver -will appear in the ODBC datasources drop-down list, you must build and -copy the @strong{MyODBC} driver to -@file{/opt/coldfusion/lib/libmyodbc.so}. - -The Contrib directory contains the program mydsn-xxx.zip which allows -you to build and remove the DSN registry file for the MyODBC driver -on Coldfusion applications. - -@cindex DataJunction -@item DataJunction -You have to change it to output @code{VARCHAR} rather than @code{ENUM}, as -it exports the latter in a manner that causes @strong{MySQL} grief. -@cindex Excel -@item Excel -Works. Some tips: -@itemize @bullet -@item -If you have problems with dates, try to select them as strings using the -@code{CONCAT()} function. For example: -@example -select CONCAT(rise_time), CONCAT(set_time) - from sunrise_sunset; -@end example -Values retrieved as strings this way should be correctly recognized -as time values by Excel97. - -The purpose of @code{CONCAT()} in this example is to fool ODBC into thinking -the column is of ``string type''. Without the @code{CONCAT()}, ODBC knows the -column is of time type, and Excel does not understand that. - -Note that this is a bug in Excel, because it automatically converts a -string to a time. This would be great if the source was a text file, but -is plain stupid when the source is an ODBC connection that reports -exact types for each column. -@end itemize -@cindex Word program -@item Word - -To retrieve data from @strong{MySQL} to Word/Excel documents, you need to -use the @code{MyODBC} driver and the Add-in Microsoft Query help. - -For example, create a db with a table containing 2 columns of text: - -@itemize @bullet -@item -Insert rows using the @code{mysql} client command-line tool. -@item -Create a DSN file using the MyODBC driver, for example, my for the db above. -@item -Open the Word application. -@item -Create a blank new documentation. -@item -Using the tool bar called Database, press the button insert database. -@item -Press the button Get Data. -@item -At the right hand of the screen Get Data, press the button Ms Query. -@item -In the Ms Query create a New Data Source using the DSN file my. -@item -Select the new query. -@item -Select the columns that you want. -@item -Make a filter if you want. -@item -Make a Sort if you want. -@item -Select Return Data to Microsoft Word. -@item -Click Finish. -@item -Click Insert data and select the records. -@item -Click OK and you see the rows in your Word document. -@end itemize - -@cindex odbcadmin program -@item odbcadmin -Test program for ODBC. -@cindex Delphi program -@item Delphi -You must use BDE Version 3.2 or newer. Set the `Don't optimize column width' -option field when connecting to @strong{MySQL}. - -Also, here is some potentially useful Delphi code that sets up both an -ODBC entry and a BDE entry for @strong{MyODBC} (the BDE entry requires a BDE -Alias Editor that is free at a Delphi Super Page near -you. (Thanks to Bryan Brunton @email{bryan@@flesherfab.com} for this): - -@example -fReg:= TRegistry.Create; - fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True); - fReg.WriteString('Database', 'Documents'); - fReg.WriteString('Description', ' '); - fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll'); - fReg.WriteString('Flag', '1'); - fReg.WriteString('Password', ''); - fReg.WriteString('Port', ' '); - fReg.WriteString('Server', 'xmark'); - fReg.WriteString('User', 'winuser'); - fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True); - fReg.WriteString('DocumentsFab', 'MySQL'); - fReg.CloseKey; - fReg.Free; - - Memo1.Lines.Add('DATABASE NAME='); - Memo1.Lines.Add('USER NAME='); - Memo1.Lines.Add('ODBC DSN=DocumentsFab'); - Memo1.Lines.Add('OPEN MODE=READ/WRITE'); - Memo1.Lines.Add('BATCH COUNT=200'); - Memo1.Lines.Add('LANGDRIVER='); - Memo1.Lines.Add('MAX ROWS=-1'); - Memo1.Lines.Add('SCHEMA CACHE DIR='); - Memo1.Lines.Add('SCHEMA CACHE SIZE=8'); - Memo1.Lines.Add('SCHEMA CACHE TIME=-1'); - Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT'); - Memo1.Lines.Add('SQLQRYMODE='); - Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE'); - Memo1.Lines.Add('ENABLE BCD=FALSE'); - Memo1.Lines.Add('ROWSET SIZE=20'); - Memo1.Lines.Add('BLOBS TO CACHE=64'); - Memo1.Lines.Add('BLOB SIZE=32'); - - AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines); -@end example - -@cindex C++Builder -@item C++Builder -Tested with BDE Version 3.0. The only known problem is that when the table -schema changes, query fields are not updated. BDE, however, does not seem -to recognize primary keys, only the index PRIMARY, though this has not -been a problem. - -@item Vision -You should use the option flag @code{Return matching rows}. - -@cindex Visual Basic -@item Visual Basic -To be able to update a table, you must define a primary key for the table. - -Visual Basic with ADO can't handle big integers. This means that some queries -like @code{SHOW PROCESSLIST} will not work properly. The fix is to set -add the option @code{OPTION=16834} in the ODBC connect string or set -the @code{Change BIGINT columns to INT} option in the MyODBC connect screen. -You may also want to set the @code{Return matching rows} option. - -@item VisualInterDev -If you get the error @code{[Microsoft][ODBC Driver Manager] Driver does -not support this parameter} the reason may be that you have a -@code{BIGINT} in your result. Try setting the @code{Change BIGINT -columns to INT} option in the MyODBC connect screen. - -@item Visual Objects -You should use the option flag @code{Don't optimize column widths}. -@end table - - -@node ODBC and last_insert_id, MyODBC bug report, MyODBC clients, ODBC -@section How to Get the Value of an @code{AUTO_INCREMENT} Column in ODBC - -@cindex AUTO-INCREMENT, ODBC - -A common problem is how to get the value of an automatically generated ID -from an @code{INSERT}. With ODBC, you can do something like this (assuming -that @code{auto} is an @code{AUTO_INCREMENT} field): - -@example -INSERT INTO foo (auto,text) VALUES(NULL,'text'); -SELECT LAST_INSERT_ID(); -@end example - -Or, if you are just going to insert the ID into another table, you can do this: - -@example -INSERT INTO foo (auto,text) VALUES(NULL,'text'); -INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text'); -@end example - -@xref{Getting unique ID}. - -For the benefit of some ODBC applications (at least Delphi and Access), -the following query can be used to find a newly inserted row: -@example -SELECT * FROM tbl_name WHERE auto IS NULL; -@end example - - -@node MyODBC bug report, , ODBC and last_insert_id, ODBC -@section Reporting Problems with MyODBC - -@cindex reporting, MyODBC problems -@cindex problems, ODBC -@cindex MyODBC, reporting problems - -If you encounter difficulties with @strong{MyODBC}, you should start by -making a log file from the ODBC manager (the log you get when requesting -logs from ODBCADMIN) and a @strong{MyODBC} log. - -To get a @strong{MyODBC} log, you need to do the following: - -@enumerate -@item -Ensure that you are using @code{myodbcd.dll} and not @code{myodbc.dll}. -The easiest way to do this is to get @code{myodbcd.dll} from the MyODBC -distribution and copy it over the @code{myodbc.dll}, which is probably -in your @code{C:\windows\system32} or @code{C:\winnt\system32} directory. - -Note that you probably want to restore the old myodbc.dll file when you -have finished testing, as this is a lot faster than @code{myodbcd.dll}. -@item -Tag the `Trace MyODBC' option flag in the @strong{MyODBC} connect/configure -screen. The log will be written to file @file{C:\myodbc.log}. - -If the trace option is not remembered when you are going back to the -above screen, it means that you are not using the @code{myodbcd.dll} -driver (see above). -@item -Start your application and try to get it to fail. -@end enumerate - -Check the @code{MyODBC trace file}, to find out what could be wrong. -You should be able to find out the issued queries by searching after -the string @code{>mysql_real_query} in the @file{myodbc.log} file. - -You should also try duplicating the queries in the @code{mysql} monitor -or @code{admndemo} to find out if the error is MyODBC or @strong{MySQL}. - -If you find out something is wrong, please only send the relevant rows -(max 40 rows) to @email{myodbc@@lists.mysql.com}. Please never -send the whole MyODBC or ODBC log file! - -If you are unable to find out what's wrong, the last option is to -make an archive (tar or zip) that contains a MyODBC trace file, the ODBC -log file, and a README file that explains the problem. You can send this -to @uref{ftp://support.mysql.com/pub/mysql/secret}. Only we at -@strong{MySQL AB} will have access to the files you upload, and we will -be very discrete with the data! - -If you can create a program that also shows this problem, please -upload this too! - -If the program works with some other SQL server, you should make an ODBC log -file where you do exactly the same thing in the other SQL server. - -Remember that the more information you can supply to us, the more -likely it is that we can fix the problem! - - -@node Common programs, Clients, ODBC, Top -@chapter Using MySQL with Some Common Programs - -@menu -* Borland C++:: -@end menu - -This chapter describes how to use @strong{MySQL} with some common programs. - -In this chapter you will: - -@itemize @bullet -@item -Learn how to easily store your Apache log files in a @strong{MySQL} -database. -@item -Find some tips on how to compile @strong{MySQL} and @strong{MySQL}-based -programs using Borland C++. -@end itemize - - -@cindex Borland C++ compiler -@node Borland C++, , Common programs, Common programs -@section Borland C++ - -You can compile the @strong{MySQL} Windows source with Borland C++ 5.02. -(The Windows source includes only projects for Microsoft VC++, for -Borland C++ you have to do the project files yourself). - -One known problem with Borland C++ is that it uses a different structure -alignment than VC++. This means that you will run into problems if you -try to use the default @code{libmysql.dll} libraries (that was compiled -with VC++) with Borland C++. You can do one of the following to avoid -this problem. - -@itemize @bullet -@item -You can use the static @strong{MySQL} libraries for Borland C++ that you -can find on @uref{http://www.mysql.com/downloads/os-win32.html}. -@item -Only call @code{mysql_init()} with @code{NULL} as an argument, not a -pre-allocated MYSQL struct. -@end itemize - - - - -@node Clients, Problems, Common programs, Top -@chapter MySQL APIs - -@cindex client tools -@cindex APIs -@cindex @code{mysqlclient} library -@cindex buffer sizes, client -@cindex library, @code{mysqlclient} - -@menu -* C:: @strong{MySQL} C API -* Perl:: @strong{MySQL} Perl API -* Eiffel:: @strong{MySQL} Eiffel wrapper -* Java:: @strong{MySQL} Java connectivity (JDBC) -* PHP:: @strong{MySQL} PHP API -* Cplusplus:: @strong{MySQL} C++ APIs -* Python:: @strong{MySQL} Python APIs -* Tcl:: @strong{MySQL} Tcl APIs -@end menu - -This chapter describes the APIs available for @strong{MySQL}, where to get -them, and how to use them. The C API is the most extensively covered, as it -was developed by the @strong{MySQL} team, and is the basis for most of the -other APIs. - -@cindex C API, datatypes -@cindex datatypes, C API -@node C, Perl, Clients, Clients -@section MySQL C API - -@menu -* C API datatypes:: C API Datatypes -* C API function overview:: C API Function Overview -* C API functions:: C API Function Descriptions -* C API problems:: -* Thread-safe clients:: -@end menu - -The C API code is distributed with @strong{MySQL}. It is included in the -@code{mysqlclient} library and allows C programs to access a database. - -Many of the clients in the @strong{MySQL} source distribution are -written in C. If you are looking for examples that demonstrate how to -use the C API, take a look at these clients. You can find these in the -@code{clients} directory in the @strong{MySQL} source distribution. - -Most of the other client APIs (all except Java) use the @code{mysqlclient} -library to communicate with the @strong{MySQL} server. This means that, for -example, you can take advantage of many of the same environment variables -that are used by other client programs, because they are referenced from the -library. See @ref{Client-Side Scripts}, for a list of these variables. - -The client has a maximum communication buffer size. The size of the buffer -that is allocated initially (16K bytes) is automatically increased up to the -maximum size (the maximum is 16M). Because buffer sizes are increased -only as demand warrants, simply increasing the default maximum limit does not -in itself cause more resources to be used. This size check is mostly a check -for erroneous queries and communication packets. - -The communication buffer must be large enough to contain a single SQL -statement (for client-to-server traffic) and one row of returned data (for -server-to-client traffic). Each thread's communication buffer is dynamically -enlarged to handle any query or row up to the maximum limit. For example, if -you have @code{BLOB} values that contain up to 16M of data, you must have a -communication buffer limit of at least 16M (in both server and client). The -client's default maximum is 16M, but the default maximum in the server is -1M. You can increase this by changing the value of the -@code{max_allowed_packet} parameter when the server is started. @xref{Server -parameters}. - -The @strong{MySQL} server shrinks each communication buffer to -@code{net_buffer_length} bytes after each query. For clients, the size of -the buffer associated with a connection is not decreased until the connection -is closed, at which time client memory is reclaimed. - -For programming with threads, consult the 'how to make a thread-safe -client' chapter. @xref{Thread-safe clients}. - -@node C API datatypes, C API function overview, C, C -@subsection C API Datatypes -@table @code - -@tindex MYSQL C type -@item MYSQL -This structure represents a handle to one database connection. It is -used for almost all @strong{MySQL} functions. - -@tindex MYSQL_RES C type -@item MYSQL_RES -This structure represents the result of a query that returns rows -(@code{SELECT}, @code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}). The -information returned from a query is called the @emph{result set} in the -remainder of this section. - -@tindex MYSQL_ROW C type -@item MYSQL_ROW -This is a type-safe representation of one row of data. It is currently -implemented as an array of counted byte strings. (You cannot treat these as -null-terminated strings if field values may contain binary data, because such -values may contain null bytes internally.) Rows are obtained by calling -@code{mysql_fetch_row()}. - -@tindex MYSQL_FIELD C type -@item MYSQL_FIELD -This structure contains information about a field, such as the field's -name, type, and size. Its members are described in more detail below. -You may obtain the @code{MYSQL_FIELD} structures for each field by -calling @code{mysql_fetch_field()} repeatedly. Field values are not part of -this structure; they are contained in a @code{MYSQL_ROW} structure. - - -@tindex MYSQL_FIELD_OFFSET C type -@item MYSQL_FIELD_OFFSET -This is a type-safe representation of an offset into a @strong{MySQL} field -list. (Used by @code{mysql_field_seek()}.) Offsets are field numbers -within a row, beginning at zero. - -@tindex my_ulonglong C type -@tindex my_ulonglong values, printing -@item my_ulonglong -The type used for the number of rows and for @code{mysql_affected_rows()}, -@code{mysql_num_rows()}, and @code{mysql_insert_id()}. This type provides a -range of @code{0} to @code{1.84e19}. - -On some systems, attempting to print a value of type @code{my_ulonglong} -will not work. To print such a value, convert it to @code{unsigned long} -and use a @code{%lu} print format. Example: -@example -printf (Number of rows: %lu\n", (unsigned long) mysql_num_rows(result)); -@end example -@end table - -@noindent -The @code{MYSQL_FIELD} structure contains the members listed below: - -@table @code -@item char * name -The name of the field, as a null-terminated string. - -@item char * table -The name of the table containing this field, if it isn't a calculated field. -For calculated fields, the @code{table} value is an empty string. - -@item char * def -The default value of this field, as a null-terminated string. This is set -only if you use @code{mysql_list_fields()}. - -@item enum enum_field_types type -The type of the field. -The @code{type} value may be one of the following: - -@multitable @columnfractions .3 .55 -@item @strong{Type value} @tab @strong{Type meaning} -@item @code{FIELD_TYPE_TINY} @tab @code{TINYINT} field -@item @code{FIELD_TYPE_SHORT} @tab @code{SMALLINT} field -@item @code{FIELD_TYPE_LONG} @tab @code{INTEGER} field -@item @code{FIELD_TYPE_INT24} @tab @code{MEDIUMINT} field -@item @code{FIELD_TYPE_LONGLONG} @tab @code{BIGINT} field -@item @code{FIELD_TYPE_DECIMAL} @tab @code{DECIMAL} or @code{NUMERIC} field -@item @code{FIELD_TYPE_FLOAT} @tab @code{FLOAT} field -@item @code{FIELD_TYPE_DOUBLE} @tab @code{DOUBLE} or @code{REAL} field -@item @code{FIELD_TYPE_TIMESTAMP} @tab @code{TIMESTAMP} field -@item @code{FIELD_TYPE_DATE} @tab @code{DATE} field -@item @code{FIELD_TYPE_TIME} @tab @code{TIME} field -@item @code{FIELD_TYPE_DATETIME} @tab @code{DATETIME} field -@item @code{FIELD_TYPE_YEAR} @tab @code{YEAR} field -@item @code{FIELD_TYPE_STRING} @tab String (@code{CHAR} or @code{VARCHAR}) field -@item @code{FIELD_TYPE_BLOB} @tab @code{BLOB} or @code{TEXT} field (use @code{max_length} to determine the maximum length) -@item @code{FIELD_TYPE_SET} @tab @code{SET} field -@item @code{FIELD_TYPE_ENUM} @tab @code{ENUM} field -@item @code{FIELD_TYPE_NULL} @tab @code{NULL}-type field -@item @code{FIELD_TYPE_CHAR} @tab Deprecated; use @code{FIELD_TYPE_TINY} instead -@end multitable - -You can use the @code{IS_NUM()} macro to test whether or not a field has a -numeric type. Pass the @code{type} value to @code{IS_NUM()} and it -will evaluate to TRUE if the field is numeric: - -@example -if (IS_NUM(field->type)) - printf("Field is numeric\n"); -@end example - -@item unsigned int length -The width of the field, as specified in the table definition. - -@item unsigned int max_length -The maximum width of the field for the result set (the length of the longest -field value for the rows actually in the result set). If you use -@code{mysql_store_result()} or @code{mysql_list_fields()}, this contains the -maximum length for the field. If you use @code{mysql_use_result()}, the -value of this variable is zero. - -@item unsigned int flags -Different bit-flags for the field. The @code{flags} value may have zero -or more of the following bits set: - -@multitable @columnfractions .3 .55 -@item @strong{Flag value} @tab @strong{Flag meaning} -@item @code{NOT_NULL_FLAG} @tab Field can't be @code{NULL} -@item @code{PRI_KEY_FLAG} @tab Field is part of a primary key -@item @code{UNIQUE_KEY_FLAG} @tab Field is part of a unique key -@item @code{MULTIPLE_KEY_FLAG} @tab Field is part of a non-unique key -@item @code{UNSIGNED_FLAG} @tab Field has the @code{UNSIGNED} attribute -@item @code{ZEROFILL_FLAG} @tab Field has the @code{ZEROFILL} attribute -@item @code{BINARY_FLAG} @tab Field has the @code{BINARY} attribute -@item @code{AUTO_INCREMENT_FLAG} @tab Field has the @code{AUTO_INCREMENT} -attribute -@item @code{ENUM_FLAG} @tab Field is an @code{ENUM} (deprecated) -@item @code{BLOB_FLAG} @tab Field is a @code{BLOB} or @code{TEXT} (deprecated) -@item @code{TIMESTAMP_FLAG} @tab Field is a @code{TIMESTAMP} (deprecated) -@end multitable - -Use of the @code{BLOB_FLAG}, @code{ENUM_FLAG}, and @code{TIMESTAMP_FLAG} -flags is deprecated because they indicate the type of a field rather -than an attribute of its type. It is preferable to test -@code{field->type} against @code{FIELD_TYPE_BLOB}, -@code{FIELD_TYPE_ENUM}, or @code{FIELD_TYPE_TIMESTAMP} instead. - -@noindent -The example below illustrates a typical use of the @code{flags} value: - -@example -if (field->flags & NOT_NULL_FLAG) - printf("Field can't be null\n"); -@end example - -You may use the following convenience macros to determine the boolean -status of the @code{flags} value: - -@multitable @columnfractions .3 .5 -@item @code{IS_NOT_NULL(flags)} @tab True if this field is defined as @code{NOT NULL} -@item @code{IS_PRI_KEY(flags)} @tab True if this field is a primary key -@item @code{IS_BLOB(flags)} @tab True if this field is a @code{BLOB} or @code{TEXT} (deprecated; test @code{field->type} instead) -@end multitable - -@item unsigned int decimals -The number of decimals for numeric fields. -@end table - -@cindex C API, functions -@cindex functions, C API -@node C API function overview, C API functions, C API datatypes, C -@subsection C API Function Overview - -The functions available in the C API are listed below and are described in -greater detail in the next section. -@xref{C API functions}. - -@multitable @columnfractions .3 .7 -@item @strong{mysql_affected_rows()} @tab -Returns the number of rows changed/deleted/inserted by the last @code{UPDATE}, -@code{DELETE}, or @code{INSERT} query. - -@item @strong{mysql_close()} @tab -Closes a server connection. - -@item @strong{mysql_connect()} @tab -Connects to a @strong{MySQL} server. This function is deprecated; use -@code{mysql_real_connect()} instead. - -@item @strong{mysql_change_user()} @tab -Changes user and database on an open connection. - -@item @strong{mysql_character_set_name()} @tab -Returns the name of the default character set for the connection. - -@item @strong{mysql_create_db()} @tab -Creates a database. This function is deprecated; use the SQL command -@code{CREATE DATABASE} instead. - -@item @strong{mysql_data_seek()} @tab -Seeks to an arbitrary row in a query result set. - -@item @strong{mysql_debug()} @tab -Does a @code{DBUG_PUSH} with the given string. - -@item @strong{mysql_drop_db()} @tab -Drops a database. This function is deprecated; use the SQL command -@code{DROP DATABASE} instead. - -@item @strong{mysql_dump_debug_info()} @tab -Makes the server write debug information to the log. - -@item @strong{mysql_eof()} @tab -Determines whether or not the last row of a result set has been read. -This function is deprecated; @code{mysql_errno()} or @code{mysql_error()} -may be used instead. - -@item @strong{mysql_errno()} @tab -Returns the error number for the most recently invoked @strong{MySQL} function. - -@item @strong{mysql_error()} @tab -Returns the error message for the most recently invoked @strong{MySQL} function. - -@item @strong{mysql_real_escape_string()} @tab -Escapes special characters in a string for use in a SQL statement taking -into account the current charset of the connection. - -@item @strong{mysql_escape_string()} @tab -Escapes special characters in a string for use in a SQL statement. - -@item @strong{mysql_fetch_field()} @tab -Returns the type of the next table field. - -@item @strong{mysql_fetch_field_direct()} @tab -Returns the type of a table field, given a field number. - -@item @strong{mysql_fetch_fields()} @tab -Returns an array of all field structures. - -@item @strong{mysql_fetch_lengths()} @tab -Returns the lengths of all columns in the current row. - -@item @strong{mysql_fetch_row()} @tab -Fetches the next row from the result set. - -@item @strong{mysql_field_seek()} @tab -Puts the column cursor on a specified column. - -@item @strong{mysql_field_count()} @tab -Returns the number of result columns for the most recent query. - -@item @strong{mysql_field_tell()} @tab -Returns the position of the field cursor used for the last -@code{mysql_fetch_field()}. - -@item @strong{mysql_free_result()} @tab -Frees memory used by a result set. - -@item @strong{mysql_get_client_info()} @tab -Returns client version information. - -@item @strong{mysql_get_host_info()} @tab -Returns a string describing the connection. - -@item @strong{mysql_get_proto_info()} @tab -Returns the protocol version used by the connection. - -@item @strong{mysql_get_server_info()} @tab -Returns the server version number. - -@item @strong{mysql_info()} @tab -Returns information about the most recently executed query. - -@item @strong{mysql_init()} @tab -Gets or initializes a @code{MYSQL} structure. - -@item @strong{mysql_insert_id()} @tab -Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous -query. - -@item @strong{mysql_kill()} @tab -Kills a given thread. - -@item @strong{mysql_list_dbs()} @tab -Returns database names matching a simple regular expression. - -@item @strong{mysql_list_fields()} @tab -Returns field names matching a simple regular expression. - -@item @strong{mysql_list_processes()} @tab -Returns a list of the current server threads. - -@item @strong{mysql_list_tables()} @tab -Returns table names matching a simple regular expression. - -@item @strong{mysql_num_fields()} @tab -Returns the number of columns in a result set. - -@item @strong{mysql_num_rows()} @tab -Returns the number of rows in a result set. - -@item @strong{mysql_options()} @tab -Sets connect options for @code{mysql_connect()}. - -@item @strong{mysql_ping()} @tab -Checks whether or not the connection to the server is working, reconnecting -as necessary. - -@item @strong{mysql_query()} @tab -Executes a SQL query specified as a null-terminated string. - -@item @strong{mysql_real_connect()} @tab -Connects to a @strong{MySQL} server. - -@item @strong{mysql_real_query()} @tab -Executes a SQL query specified as a counted string. - -@item @strong{mysql_reload()} @tab -Tells the server to reload the grant tables. - -@item @strong{mysql_row_seek()} @tab -Seeks to a row in a result set, using value returned from -@code{mysql_row_tell()}. - -@item @strong{mysql_row_tell()} @tab -Returns the row cursor position. - -@item @strong{mysql_select_db()} @tab -Selects a database. - -@item @strong{mysql_shutdown()} @tab -Shuts down the database server. - -@item @strong{mysql_stat()} @tab -Returns the server status as a string. - -@item @strong{mysql_store_result()} @tab -Retrieves a complete result set to the client. - -@item @strong{mysql_thread_id()} @tab -Returns the current thread ID. - -@item @strong{mysql_thread_save()} @tab -Returns 1 if the clients are compiled as thread-safe. - -@item @strong{mysql_use_result()} @tab -Initiates a row-by-row result set retrieval. -@end multitable - -To connect to the server, call @code{mysql_init()} to initialize a -connection handler, then call @code{mysql_real_connect()} with that -handler (along with other information such as the hostname, user name, -and password). Upon connection, @code{mysql_real_connect()} sets the -@code{reconnect} flag (part of the MYSQL structure) to a value of -@code{1}. This flag indicates, in the event that a query cannot be -performed because of a lost connection, to try reconnecting to the -server before giving up. When you are done with the connection, call -@code{mysql_close()} to terminate it. - -While a connection is active, the client may send SQL queries to the server -using @code{mysql_query()} or @code{mysql_real_query()}. The difference -between the two is that @code{mysql_query()} expects the query to be -specified as a null-terminated string whereas @code{mysql_real_query()} -expects a counted string. If the string contains binary data (which may -include null bytes), you must use @code{mysql_real_query()}. - -For each non-@code{SELECT} query (for example, @code{INSERT}, @code{UPDATE}, -@code{DELETE}), you can find out how many rows were changed (affected) -by calling @code{mysql_affected_rows()}. - -For @code{SELECT} queries, you retrieve the selected rows as a result set. -(Note that some statements are @code{SELECT}-like in that they return rows. -These include @code{SHOW}, @code{DESCRIBE}, and @code{EXPLAIN}. They should -be treated the same way as @code{SELECT} statements.) - -There are two ways for a client to process result sets. One way is to -retrieve the entire result set all at once by calling -@code{mysql_store_result()}. This function acquires from the server all the -rows returned by the query and stores them in the client. The second way is -for the client to initiate a row-by-row result set retrieval by calling -@code{mysql_use_result()}. This function initializes the retrieval, but does -not actually get any rows from the server. - -In both cases, you access rows by calling @code{mysql_fetch_row()}. With -@code{mysql_store_result()}, @code{mysql_fetch_row()} accesses rows that have -already been fetched from the server. With @code{mysql_use_result()}, -@code{mysql_fetch_row()} actually retrieves the row from the server. -Information about the size of the data in each row is available by -calling @code{mysql_fetch_lengths()}. - -After you are done with a result set, call @code{mysql_free_result()} -to free the memory used for it. - -The two retrieval mechanisms are complementary. Client programs should -choose the approach that is most appropriate for their requirements. -In practice, clients tend to use @code{mysql_store_result()} more -commonly. - -An advantage of @code{mysql_store_result()} is that because the rows have all -been fetched to the client, you not only can access rows sequentially, you -can move back and forth in the result set using @code{mysql_data_seek()} or -@code{mysql_row_seek()} to change the current row position within the result -set. You can also find out how many rows there are by calling -@code{mysql_num_rows()}. On the other hand, the memory requirements for -@code{mysql_store_result()} may be very high for large result sets and you -are more likely to encounter out-of-memory conditions. - -An advantage of @code{mysql_use_result()} is that the client requires less -memory for the result set because it maintains only one row at a time (and -because there is less allocation overhead, @code{mysql_use_result()} can be -faster). Disadvantages are that you must process each row quickly to avoid -tying up the server, you don't have random access to rows within the result -set (you can only access rows sequentially), and you don't know how many rows -are in the result set until you have retrieved them all. Furthermore, you -@emph{must} retrieve all the rows even if you determine in mid-retrieval that -you've found the information you were looking for. - -The API makes it possible for clients to respond appropriately to -queries (retrieving rows only as necessary) without knowing whether or -not the query is a @code{SELECT}. You can do this by calling -@code{mysql_store_result()} after each @code{mysql_query()} (or -@code{mysql_real_query()}). If the result set call succeeds, the query -was a @code{SELECT} and you can read the rows. If the result set call -fails, call @code{mysql_field_count()} to determine whether or not a -result was actually to be expected. If @code{mysql_field_count()} -returns zero, the query returned no data (indicating that it was an -@code{INSERT}, @code{UPDATE}, @code{DELETE}, etc.), and was not -expected to return rows. If @code{mysql_field_count()} is non-zero, the -query should have returned rows, but didn't. This indicates that the -query was a @code{SELECT} that failed. See the description for -@code{mysql_field_count()} for an example of how this can be done. - -Both @code{mysql_store_result()} and @code{mysql_use_result()} allow you to -obtain information about the fields that make up the result set (the number -of fields, their names and types, etc.). You can access field information -sequentially within the row by calling @code{mysql_fetch_field()} repeatedly, -or by field number within the row by calling -@code{mysql_fetch_field_direct()}. The current field cursor position may be -changed by calling @code{mysql_field_seek()}. Setting the field cursor -affects subsequent calls to @code{mysql_fetch_field()}. You can also get -information for fields all at once by calling @code{mysql_fetch_fields()}. - -For detecting and reporting errors, @strong{MySQL} provides access to error -information by means of the @code{mysql_errno()} and @code{mysql_error()} -functions. These return the error code or error message for the most -recently invoked function that can succeed or fail, allowing you to determine -when an error occurred and what it was. - -@node C API functions, C API problems, C API function overview, C -@subsection C API Function Descriptions - -@menu -* mysql_affected_rows:: @code{mysql_affected_rows()} -* mysql_close:: @code{mysql_close()} -* mysql_connect:: @code{mysql_connect()} -* mysql_change_user:: @code{mysql_change_user()} -* mysql_character_set_name:: @code{mysql_character_set_name()} -* mysql_create_db:: @code{mysql_create_db()} -* mysql_data_seek:: @code{mysql_data_seek()} -* mysql_debug:: @code{mysql_debug()} -* mysql_drop_db:: @code{mysql_drop_db()} -* mysql_dump_debug_info:: @code{mysql_dump_debug_info()} -* mysql_eof:: @code{mysql_eof()} -* mysql_errno:: @code{mysql_errno()} -* mysql_error:: @code{mysql_error()} -* mysql_escape_string:: @code{mysql_escape_string()} -* mysql_fetch_field:: @code{mysql_fetch_field()} -* mysql_fetch_fields:: @code{mysql_fetch_fields()} -* mysql_fetch_field_direct:: @code{mysql_fetch_field_direct()} -* mysql_fetch_lengths:: @code{mysql_fetch_lengths()} -* mysql_fetch_row:: @code{mysql_fetch_row()} -* mysql_field_count:: @code{mysql_field_count()} -* mysql_field_seek:: @code{mysql_field_seek()} -* mysql_field_tell:: @code{mysql_field_tell()} -* mysql_free_result:: @code{mysql_free_result()} -* mysql_get_client_info:: @code{mysql_get_client_info()} -* mysql_get_host_info:: @code{mysql_get_host_info()} -* mysql_get_proto_info:: @code{mysql_get_proto_info()} -* mysql_get_server_info:: @code{mysql_get_server_info()} -* mysql_info:: @code{mysql_info()} -* mysql_init:: @code{mysql_init()} -* mysql_insert_id:: @code{mysql_insert_id()} -* mysql_kill:: @code{mysql_kill()} -* mysql_list_dbs:: @code{mysql_list_dbs()} -* mysql_list_fields:: @code{mysql_list_fields()} -* mysql_list_processes:: @code{mysql_list_processes()} -* mysql_list_tables:: @code{mysql_list_tables()} -* mysql_num_fields:: @code{mysql_num_fields()} -* mysql_num_rows:: @code{mysql_num_rows()} -* mysql_options:: @code{mysql_options()} -* mysql_ping:: @code{mysql_ping()} -* mysql_query:: @code{mysql_query()} -* mysql_real_connect:: @code{mysql_real_connect()} -* mysql_real_escape_string:: @code{mysql_real_escape_string()} -* mysql_real_query:: @code{mysql_real_query()} -* mysql_reload:: @code{mysql_reload()} -* mysql_row_seek:: @code{mysql_row_seek()} -* mysql_row_tell:: @code{mysql_row_tell()} -* mysql_select_db:: @code{mysql_select_db()} -* mysql_shutdown:: @code{mysql_shutdown()} -* mysql_stat:: @code{mysql_stat()} -* mysql_store_result:: @code{mysql_store_result()} -* mysql_thread_id:: @code{mysql_thread_id()} -* mysql_use_result:: @code{mysql_use_result()} -@end menu - -In the descriptions below, a parameter or return value of @code{NULL} means -@code{NULL} in the sense of the C programming language, not a -@strong{MySQL} @code{NULL} value. - -Functions that return a value generally return a pointer or an integer. -Unless specified otherwise, functions returning a pointer return a -non-@code{NULL} value to indicate success or a @code{NULL} value to indicate -an error, and functions returning an integer return zero to indicate success -or non-zero to indicate an error. Note that ``non-zero'' means just that. -Unless the function description says otherwise, do not test against a value -other than zero: - -@example -if (result) /* correct */ - ... error ... - -if (result < 0) /* incorrect */ - ... error ... - -if (result == -1) /* incorrect */ - ... error ... -@end example - -When a function returns an error, the @strong{Errors} subsection of the -function description lists the possible types of errors. You can -find out which of these occurred by calling @code{mysql_errno()}. -A string representation of the error may be obtained by calling -@code{mysql_error()}. - -@findex @code{mysql_affected_rows()} -@node mysql_affected_rows, mysql_close, C API functions, C API functions -@subsubsection @code{mysql_affected_rows()} - -@code{my_ulonglong mysql_affected_rows(MYSQL *mysql)} - -@subsubheading Description - -Returns the number of rows changed by the last @code{UPDATE}, deleted by -the last @code{DELETE} or inserted by the last @code{INSERT} -statement. May be called immediately after @code{mysql_query()} for -@code{UPDATE}, @code{DELETE}, or @code{INSERT} statements. For -@code{SELECT} statements, @code{mysql_affected_rows()} works like -@code{mysql_num_rows()}. - -@subsubheading Return Values - -An integer greater than zero indicates the number of rows affected or -retrieved. Zero indicates that no records where updated for an -@code{UPDATE} statement, no rows matched the @code{WHERE} clause in the -query or that no query has yet been executed. -1 indicates that the -query returned an error or that, for a @code{SELECT} query, -@code{mysql_affected_rows()} was called prior to calling -@code{mysql_store_result()}. - -@subsubheading Errors - -None. - -@subsubheading Example - -@example -mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10"); -printf("%ld products updated",(long) mysql_affected_rows(&mysql)); -@end example - -If one specifies the flag @code{CLIENT_FOUND_ROWS} when connecting to -@code{mysqld}, @code{mysql_affected_rows()} will return the number of -rows matched by the @code{WHERE} statement for @code{UPDATE} statements. - -Note that when one uses a @code{REPLACE} command, -@code{mysql_affected_rows()} will return 2 if the new row replaced and -old row. This is because in this case one row was inserted and then the -duplicate was deleted. - -@findex @code{mysql_close()} -@node mysql_close, mysql_connect, mysql_affected_rows, C API functions -@subsubsection @code{mysql_close()} - -@code{void mysql_close(MYSQL *mysql)} - -@subsubheading Description -Closes a previously opened connection. @code{mysql_close()} also deallocates -the connection handle pointed to by @code{mysql} if the handle was allocated -automatically by @code{mysql_init()} or @code{mysql_connect()}. - -@subsubheading Return Values - -None. - -@subsubheading Errors - -None. - -@findex @code{mysql_connect()} -@node mysql_connect, mysql_change_user, mysql_close, C API functions -@subsubsection @code{mysql_connect()} - -@code{MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)} - -@subsubheading Description - -This function is deprecated. It is preferable to use -@code{mysql_real_connect()} instead. - -@code{mysql_connect()} attempts to establish a connection to a @strong{MySQL} -database engine running on @code{host}. @code{mysql_connect()} must complete -successfully before you can execute any of the other API functions, with the -exception of @code{mysql_get_client_info()}. - -The meanings of the parameters are the same as for the corresponding -parameters for @code{mysql_real_connect()} with the difference that the -connection parameter may be @code{NULL}. In this case the C API -allocates memory for the connection structure automatically and frees it -when you call @code{mysql_close()}. The disadvantage of this approach is -that you can't retrieve an error message if the connection fails. (To -get error information from @code{mysql_errno()} or @code{mysql_error()}, -you must provide a valid @code{MYSQL} pointer.) - -@subsubheading Return Values - -Same as for @code{mysql_real_connect()}. - -@subsubheading Errors - -Same as for @code{mysql_real_connect()}. - -@findex @code{mysql_change_user()} -@node mysql_change_user, mysql_character_set_name, mysql_connect, C API functions -@subsubsection @code{mysql_change_user()} - -@code{my_bool mysql_change_user(MYSQL *mysql, const char *user, const -char *password, const char *db)} - -@subsubheading Description - -Changes the user and causes the database specified by @code{db} to -become the default (current) database on the connection specified by -@code{mysql}. In subsequent queries, this database is the default for -table references that do not include an explicit database specifier. - -This function was introduced in @strong{MySQL} Version 3.23.3. - -@code{mysql_change_user()} fails unless the connected user can be -authenticated or if he doesn't have permission to use the database. In -this case the user and database are not changed - -The @code{db} parameter may be set to @code{NULL} if you don't want to have a -default database. - -@subsubheading Return values - -Zero for success. Non-zero if an error occurred. - -@subsubheading Errors - -The same that you can get from @code{mysql_real_connect()}. - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@item ER_UNKNOWN_COM_ERROR -The @strong{MySQL} server doesn't implement this command (probably an old server) -@item ER_ACCESS_DENIED_ERROR -The user or password was wrong. -@item ER_BAD_DB_ERROR -The database didn't exist. -@item ER_DBACCESS_DENIED_ERROR -The user did not have access rights to the database. -@item ER_WRONG_DB_NAME -The database name was too long. -@end table - -@subsubheading Example - -@example -if (mysql_change_user(&mysql, "user", "password", "new_database")) -@{ - fprintf(stderr, "Failed to change user. Error: %s\n", - mysql_error(&mysql)); -@} -@end example - -@findex @code{mysql_character_set_name()} -@node mysql_character_set_name, mysql_create_db, mysql_change_user, C API functions -@subsubsection @code{mysql_character_set_name()} - -@code{const char *mysql_character_set_name(MYSQL *mysql)} - -@subsubheading Description - -Returns the default character set for the current connection. - -@subsubheading Return Values - -The default character set - -@subsubheading Errors -None. - - -@findex @code{mysql_create_db()} -@node mysql_create_db, mysql_data_seek, mysql_character_set_name, C API functions -@subsubsection @code{mysql_create_db()} - -@code{int mysql_create_db(MYSQL *mysql, const char *db)} - -@subsubheading Description -Creates the database named by the @code{db} parameter. - -This function is deprecated. It is preferable to use @code{mysql_query()} -to issue a SQL @code{CREATE DATABASE} statement instead. - -@subsubheading Return Values - -Zero if the database was created successfully. Non-zero if an error -occurred. - -@subsubheading Errors -@table @code - -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. - -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. - -@item CR_SERVER_LOST -The connection to the server was lost during the query. - -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@subsubheading Example - -@example -if(mysql_create_db(&mysql, "my_database")) -@{ - fprintf(stderr, "Failed to create new database. Error: %s\n", - mysql_error(&mysql)); -@} -@end example - -@findex @code{mysql_data_seek()} -@node mysql_data_seek, mysql_debug, mysql_create_db, C API functions -@subsubsection @code{mysql_data_seek()} - -@code{void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)} - -@subsubheading Description -Seeks to an arbitrary row in a query result set. This requires that the -result set structure contains the entire result of the query, so -@code{mysql_data_seek()} may be used in conjunction only with -@code{mysql_store_result()}, not with @code{mysql_use_result()}. - -The offset should be a value in the range from 0 to -@code{mysql_num_rows(result)-1}. - -@subsubheading Return Values - -None. - -@subsubheading Errors -None. - -@findex @code{mysql_debug()} -@node mysql_debug, mysql_drop_db, mysql_data_seek, C API functions -@subsubsection @code{mysql_debug()} - -@code{void mysql_debug(char *debug)} - -@subsubheading Description -Does a @code{DBUG_PUSH} with the given string. @code{mysql_debug()} uses the -Fred Fish debug library. To use this function, you must compile the client -library to support debugging. -@xref{Debugging server}. @xref{Debugging client}. - -@subsubheading Return Values - -None. - -@subsubheading Errors -None. - -@subsubheading Example - -The call shown below causes the client library to generate a trace file in -@file{/tmp/client.trace} on the client machine: - -@example -mysql_debug("d:t:O,/tmp/client.trace"); -@end example - -@findex @code{mysql_drop_db()} -@node mysql_drop_db, mysql_dump_debug_info, mysql_debug, C API functions -@subsubsection @code{mysql_drop_db()} - -@code{int mysql_drop_db(MYSQL *mysql, const char *db)} - -@subsubheading Description -Drops the database named by the @code{db} parameter. - -This function is deprecated. It is preferable to use @code{mysql_query()} -to issue a SQL @code{DROP DATABASE} statement instead. - -@subsubheading Return Values - -Zero if the database was dropped successfully. Non-zero if an error -occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@subsubheading Example - -@example -if(mysql_drop_db(&mysql, "my_database")) - fprintf(stderr, "Failed to drop the database: Error: %s\n", - mysql_error(&mysql)); -@end example - -@findex @code{mysql_dump_debug_info()} -@node mysql_dump_debug_info, mysql_eof, mysql_drop_db, C API functions -@subsubsection @code{mysql_dump_debug_info()} - -@code{int mysql_dump_debug_info(MYSQL *mysql)} - -@subsubheading Description - -Instructs the server to write some debug information to the log. The -connected user must have the @strong{process} privilege for this to work. - -@subsubheading Return values - -Zero if the command was successful. Non-zero if an error occurred. - -@subsubheading Errors -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_eof()} -@node mysql_eof, mysql_errno, mysql_dump_debug_info, C API functions -@subsubsection @code{mysql_eof()} - -@code{my_bool mysql_eof(MYSQL_RES *result)} - -@subsubheading Description - -This function is deprecated. @code{mysql_errno()} or @code{mysql_error()} -may be used instead. - -@code{mysql_eof()} determines whether or not the last row of a result -set has been read. - -If you acquire a result set from a successful call to -@code{mysql_store_result()}, the client receives the entire set in one -operation. In this case, a @code{NULL} return from @code{mysql_fetch_row()} -always means the end of the result set has been reached and it is -unnecessary to call @code{mysql_eof()}. - -On the other hand, if you use @code{mysql_use_result()} to initiate a result -set retrieval, the rows of the set are obtained from the server one by one as -you call @code{mysql_fetch_row()} repeatedly. Because an error may occur on -the connection during this process, a @code{NULL} return value from -@code{mysql_fetch_row()} does not necessarily mean the end of the result set -was reached normally. In this case, you can use @code{mysql_eof()} to -determine what happened. @code{mysql_eof()} returns a non-zero value if the -end of the result set was reached and zero if an error occurred. - -Historically, @code{mysql_eof()} predates the standard @strong{MySQL} error -functions @code{mysql_errno()} and @code{mysql_error()}. Because those error -functions provide the same information, their use is preferred over -@code{mysql_eof()}, which is now deprecated. (In fact, they provide more -information, because @code{mysql_eof()} returns only a boolean value whereas -the error functions indicate a reason for the error when one occurs.) - -@subsubheading Return Values - -Zero if no error occurred. Non-zero if the end of the result set has been -reached. - -@subsubheading Errors -None. - -@subsubheading Example - -The following example shows how you might use @code{mysql_eof()}: - -@example -mysql_query(&mysql,"SELECT * FROM some_table"); -result = mysql_use_result(&mysql); -while((row = mysql_fetch_row(result))) -@{ - // do something with data -@} -if(!mysql_eof(result)) // mysql_fetch_row() failed due to an error -@{ - fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); -@} -@end example - -However, you can achieve the same effect with the standard @strong{MySQL} -error functions: - -@example -mysql_query(&mysql,"SELECT * FROM some_table"); -result = mysql_use_result(&mysql); -while((row = mysql_fetch_row(result))) -@{ - // do something with data -@} -if(mysql_errno(&mysql)) // mysql_fetch_row() failed due to an error -@{ - fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); -@} -@end example - -@findex @code{mysql_errno()} -@node mysql_errno, mysql_error, mysql_eof, C API functions -@subsubsection @code{mysql_errno()} - -@code{unsigned int mysql_errno(MYSQL *mysql)} - -@subsubheading Description - -For the connection specified by @code{mysql}, @code{mysql_errno()} returns -the error code for the most recently invoked API function that can succeed -or fail. A return value of zero means that no error occurred. Client error -message numbers are listed in the @strong{MySQL} @file{errmsg.h} header file. -Server error message numbers are listed in @file{mysqld_error.h}. In the -@strong{MySQL} source distribution you can find a complete list of -error messages and error numbers in the file @file{Docs/mysqld_error.txt}. - -@subsubheading Return Values - -An error code value. Zero if no error occurred. - -@subsubheading Errors -None. - -@findex @code{mysql_error()} -@node mysql_error, mysql_escape_string, mysql_errno, C API functions -@subsubsection @code{mysql_error()} - -@code{char *mysql_error(MYSQL *mysql)} - -@subsubheading Description - -For the connection specified by @code{mysql}, @code{mysql_error()} returns -the error message for the most recently invoked API function that can succeed -or fail. An empty string (@code{""}) is returned if no error occurred. -This means the following two tests are equivalent: - -@example -if(mysql_errno(&mysql)) -@{ - // an error occurred -@} - -if(mysql_error(&mysql)[0] != '\0') -@{ - // an error occurred -@} -@end example - -The language of the client error messages may be changed by -recompiling the @strong{MySQL} client library. Currently you can choose -error messages in several different languages. -@xref{Languages}. - -@subsubheading Return Values - -A character string that describes the error. An empty string if no error -occurred. - -@subsubheading Errors -None. - -@findex @code{mysql_escape_string()} -@node mysql_escape_string, mysql_fetch_field, mysql_error, C API functions -@subsubsection @code{mysql_escape_string()} - -You should use @code{mysql_real_escape_string()} instead! - -This is identical to @code{mysql_real_escape_string()} except that it -takes the connection as the first -argument. @code{mysql_real_escape_string()} will escape the string -according to the current character set while -@code{mysql_escape_string()} does not respect the current charset -setting. - -@findex @code{mysql_fetch_field()} -@node mysql_fetch_field, mysql_fetch_fields, mysql_escape_string, C API functions -@subsubsection @code{mysql_fetch_field()} - -@code{MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)} - -@subsubheading Description - -Returns the definition of one column of a result set as a @code{MYSQL_FIELD} -structure. Call this function repeatedly to retrieve information about all -columns in the result set. @code{mysql_fetch_field()} returns @code{NULL} -when no more fields are left. - -@code{mysql_fetch_field()} is reset to return information about the first -field each time you execute a new @code{SELECT} query. The field returned by -@code{mysql_fetch_field()} is also affected by calls to -@code{mysql_field_seek()}. - -If you've called @code{mysql_query()} to perform a @code{SELECT} on a table -but have not called @code{mysql_store_result()}, @strong{MySQL} returns the -default blob length (8K bytes) if you call @code{mysql_fetch_field()} to ask -for the length of a @code{BLOB} field. (The 8K size is chosen because -@strong{MySQL} doesn't know the maximum length for the @code{BLOB}. This -should be made configurable sometime.) Once you've retrieved the result set, -@code{field->max_length} contains the length of the largest value for this -column in the specific query. - -@subsubheading Return Values - -The @code{MYSQL_FIELD} structure for the current column. @code{NULL} -if no columns are left. - -@subsubheading Errors -None. - -@subsubheading Example - -@example -MYSQL_FIELD *field; - -while((field = mysql_fetch_field(result))) -@{ - printf("field name %s\n", field->name); -@} -@end example - -@findex @code{mysql_fetch_fields()} -@node mysql_fetch_fields, mysql_fetch_field_direct, mysql_fetch_field, C API functions -@subsubsection @code{mysql_fetch_fields()} - -@code{MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)} - -@subsubheading Description - -Returns an array of all @code{MYSQL_FIELD} structures for a result set. -Each structure provides the field definition for one column of the result -set. - -@subsubheading Return Values - -An array of @code{MYSQL_FIELD} structures for all columns of a result set. - -@subsubheading Errors -None. - -@subsubheading Example - -@example -unsigned int num_fields; -unsigned int i; -MYSQL_FIELD *fields; - -num_fields = mysql_num_fields(result); -fields = mysql_fetch_fields(result); -for(i = 0; i < num_fields; i++) -@{ - printf("Field %u is %s\n", i, fields[i].name); -@} -@end example - -@findex @code{mysql_fetch_field_direct()} -@node mysql_fetch_field_direct, mysql_fetch_lengths, mysql_fetch_fields, C API functions -@subsubsection @code{mysql_fetch_field_direct()} - -@code{MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)} - -@subsubheading Description - -Given a field number @code{fieldnr} for a column within a result set, returns -that column's field definition as a @code{MYSQL_FIELD} structure. You may use -this function to retrieve the definition for an arbitrary column. The value -of @code{fieldnr} should be in the range from 0 to -@code{mysql_num_fields(result)-1}. - -@subsubheading Return Values - -The @code{MYSQL_FIELD} structure for the specified column. - -@subsubheading Errors -None. - -@subsubheading Example - -@example -unsigned int num_fields; -unsigned int i; -MYSQL_FIELD *field; - -num_fields = mysql_num_fields(result); -for(i = 0; i < num_fields; i++) -@{ - field = mysql_fetch_field_direct(result, i); - printf("Field %u is %s\n", i, field->name); -@} -@end example - -@findex @code{mysql_fetch_lengths()} -@node mysql_fetch_lengths, mysql_fetch_row, mysql_fetch_field_direct, C API functions -@subsubsection @code{mysql_fetch_lengths()} - -@code{unsigned long *mysql_fetch_lengths(MYSQL_RES *result)} - -@subsubheading Description - -Returns the lengths of the columns of the current row within a result set. -If you plan to copy field values, this length information is also useful for -optimization, because you can avoid calling @code{strlen()}. In addition, if -the result set contains binary data, you @emph{must} use this function to -determine the size of the data, because @code{strlen()} returns incorrect -results for any field containing null characters. - -The length for empty columns and for columns containing @code{NULL} values is -zero. To see how to distinguish these two cases, see the description for -@code{mysql_fetch_row()}. - -@subsubheading Return Values - -An array of unsigned long integers representing the size of each column (not -including any terminating null characters). -@code{NULL} if an error occurred. - -@subsubheading Errors -@code{mysql_fetch_lengths()} is valid only for the current row of the result -set. It returns @code{NULL} if you call it before calling -@code{mysql_fetch_row()} or after retrieving all rows in the result. - -@subsubheading Example - -@example -MYSQL_ROW row; -unsigned long *lengths; -unsigned int num_fields; -unsigned int i; - -row = mysql_fetch_row(result); -if (row) -@{ - num_fields = mysql_num_fields(result); - lengths = mysql_fetch_lengths(result); - for(i = 0; i < num_fields; i++) - @{ - printf("Column %u is %lu bytes in length.\n", i, lengths[i]); - @} -@} -@end example - -@findex @code{mysql_fetch_row()} -@node mysql_fetch_row, mysql_field_count, mysql_fetch_lengths, C API functions -@subsubsection @code{mysql_fetch_row()} - -@code{MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)} - -@subsubheading Description - -Retrieves the next row of a result set. When used after -@code{mysql_store_result()}, @code{mysql_fetch_row()} returns @code{NULL} -when there are no more rows to retrieve. When used after -@code{mysql_use_result()}, @code{mysql_fetch_row()} returns @code{NULL} when -there are no more rows to retrieve or if an error occurred. - -The number of values in the row is given by @code{mysql_num_fields(result)}. -If @code{row} holds the return value from a call to @code{mysql_fetch_row()}, -pointers to the values are accessed as @code{row[0]} to -@code{row[mysql_num_fields(result)-1]}. @code{NULL} values in the row are -indicated by @code{NULL} pointers. - -The lengths of the field values in the row may be obtained by calling -@code{mysql_fetch_lengths()}. Empty fields and fields containing -@code{NULL} both have length 0; you can distinguish these by checking -the pointer for the field value. If the pointer is @code{NULL}, the field -is @code{NULL}; otherwise the field is empty. - -@subsubheading Return Values - -A @code{MYSQL_ROW} structure for the next row. @code{NULL} if -there are no more rows to retrieve or if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@subsubheading Example - -@example -MYSQL_ROW row; -unsigned int num_fields; -unsigned int i; - -num_fields = mysql_num_fields(result); -while ((row = mysql_fetch_row(result))) -@{ - unsigned long *lengths; - lengths = mysql_fetch_lengths(result); - for(i = 0; i < num_fields; i++) - @{ - printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL"); - @} - printf("\n"); -@} -@end example - -@findex @code{mysql_field_count()} -@node mysql_field_count, mysql_field_seek, mysql_fetch_row, C API functions -@subsubsection @code{mysql_field_count()} - -@code{unsigned int mysql_field_count(MYSQL *mysql)} - -If you are using a version of @strong{MySQL} earlier than Version 3.22.24, you -should use @code{unsigned int mysql_num_fields(MYSQL *mysql)} instead. - -@subsubheading Description - -Returns the number of columns for the most recent query on the connection. - -The normal use of this function is when @code{mysql_store_result()} -returned @code{NULL} (and thus you have no result set pointer). -In this case, you can call @code{mysql_field_count()} to -determine whether or not @code{mysql_store_result()} should have produced a -non-empty result. This allows the client program to take proper action -without knowing whether or not the query was a @code{SELECT} (or -@code{SELECT}-like) statement. The example shown below illustrates how this -may be done. - -@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. - -@subsubheading Return Values - -An unsigned integer representing the number of fields in a result set. - -@subsubheading Errors -None. - -@subsubheading Example - -@example -MYSQL_RES *result; -unsigned int num_fields; -unsigned int num_rows; - -if (mysql_query(&mysql,query_string)) -@{ - // error -@} -else // query succeeded, process any data returned by it -@{ - result = mysql_store_result(&mysql); - if (result) // there are rows - @{ - num_fields = mysql_num_fields(result); - // retrieve rows, then call mysql_free_result(result) - @} - else // mysql_store_result() returned nothing; should it have? - @{ - if(mysql_field_count(&mysql) == 0) - @{ - // query does not return data - // (it was not a SELECT) - num_rows = mysql_affected_rows(&mysql); - @} - else // mysql_store_result() should have returned data - @{ - fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); - @} - @} -@} -@end example - -An alternative is to replace the @code{mysql_field_count(&mysql)} call with -@code{mysql_errno(&mysql)}. In this case, you are checking directly for an -error from @code{mysql_store_result()} rather than inferring from the value -of @code{mysql_field_count()} whether or not the statement was a -@code{SELECT}. - -@findex @code{mysql_field_seek()} -@node mysql_field_seek, mysql_field_tell, mysql_field_count, C API functions -@subsubsection @code{mysql_field_seek()} - -@code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)} - -@subsubheading Description - -Sets the field cursor to the given offset. The next call to -@code{mysql_fetch_field()} will retrieve the field definition of the column -associated with that offset. - -To seek to the beginning of a row, pass an @code{offset} value of zero. - -@subsubheading Return Values - -The previous value of the field cursor. - -@subsubheading Errors -None. - -@findex @code{mysql_field_tell()} -@node mysql_field_tell, mysql_free_result, mysql_field_seek, C API functions -@subsubsection @code{mysql_field_tell()} - -@code{MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)} - -@subsubheading Description - -Returns the position of the field cursor used for the last -@code{mysql_fetch_field()}. This value can be used as an argument to -@code{mysql_field_seek()}. - -@subsubheading Return Values - -The current offset of the field cursor. - -@subsubheading Errors -None. - -@findex @code{mysql_free_result()} -@node mysql_free_result, mysql_get_client_info, mysql_field_tell, C API functions -@subsubsection @code{mysql_free_result()} - -@code{void mysql_free_result(MYSQL_RES *result)} - -@subsubheading Description - -Frees the memory allocated for a result set by @code{mysql_store_result()}, -@code{mysql_use_result()}, @code{mysql_list_dbs()}, etc. When you are done -with a result set, you must free the memory it uses by calling -@code{mysql_free_result()}. - -@subsubheading Return Values - -None. - -@subsubheading Errors -None. - -@findex @code{mysql_get_client_info()} -@node mysql_get_client_info, mysql_get_host_info, mysql_free_result, C API functions -@subsubsection @code{mysql_get_client_info()} - -@code{char *mysql_get_client_info(void)} - -@subsubheading Description - -Returns a string that represents the client library version. - -@subsubheading Return Values - -A character string that represents the @strong{MySQL} client library version. - -@subsubheading Errors -None. - -@findex @code{mysql_get_host_info()} -@node mysql_get_host_info, mysql_get_proto_info, mysql_get_client_info, C API functions -@subsubsection @code{mysql_get_host_info()} - -@code{char *mysql_get_host_info(MYSQL *mysql)} - -@subsubheading Description - -Returns a string describing the type of connection in use, including the -server host name. - -@subsubheading Return Values - -A character string representing the server host name and the connection type. - -@subsubheading Errors -None. - -@findex @code{mysql_get_proto_info()} -@node mysql_get_proto_info, mysql_get_server_info, mysql_get_host_info, C API functions -@subsubsection @code{mysql_get_proto_info()} - -@code{unsigned int mysql_get_proto_info(MYSQL *mysql)} - -@subsubheading Description - -Returns the protocol version used by current connection. - -@subsubheading Return Values - -An unsigned integer representing the protocol version used by the current -connection. - -@subsubheading Errors -None. - -@findex @code{mysql_get_server_info()} -@node mysql_get_server_info, mysql_info, mysql_get_proto_info, C API functions -@subsubsection @code{mysql_get_server_info()} - -@code{char *mysql_get_server_info(MYSQL *mysql)} - -@subsubheading Description - -Returns a string that represents the server version number. - -@subsubheading Return Values - -A character string that represents the server version number. - -@subsubheading Errors -None. - -@findex @code{mysql_info()} -@node mysql_info, mysql_init, mysql_get_server_info, C API functions -@subsubsection @code{mysql_info()} - -@code{char *mysql_info(MYSQL *mysql)} - -@subsubheading Description - -Retrieves a string providing information about the most recently executed -query, but only for the statements listed below. For other statements, -@code{mysql_info()} returns @code{NULL}. The format of the string varies -depending on the type of query, as described below. The numbers are -illustrative only; the string will contain values appropriate for the query. - -@table @code -@item INSERT INTO ... SELECT ... -String format: @code{Records: 100 Duplicates: 0 Warnings: 0} -@item INSERT INTO ... VALUES (...),(...),(...)... -String format: @code{Records: 3 Duplicates: 0 Warnings: 0} -@item LOAD DATA INFILE ... -String format: @code{Records: 1 Deleted: 0 Skipped: 0 Warnings: 0} -@item ALTER TABLE -String format: @code{Records: 3 Duplicates: 0 Warnings: 0} -@item UPDATE -String format: @code{Rows matched: 40 Changed: 40 Warnings: 0} -@end table - -Note that @code{mysql_info()} returns a non-@code{NULL} value for the -@code{INSERT ... VALUES} statement only if multiple value lists are -specified in the statement. - -@subsubheading Return Values - -A character string representing additional information about the most -recently executed query. @code{NULL} if no information is available for the -query. - -@subsubheading Errors -None. - -@findex @code{mysql_init()} -@node mysql_init, mysql_insert_id, mysql_info, C API functions -@subsubsection @code{mysql_init()} - -@code{MYSQL *mysql_init(MYSQL *mysql)} - -@subsubheading Description - -Allocates or initializes a @code{MYSQL} object suitable for -@code{mysql_real_connect()}. If @code{mysql} is a @code{NULL} pointer, the -function allocates, initializes, and returns a new object. Otherwise the -object is initialized and the address of the object is returned. If -@code{mysql_init()} allocates a new object, it will be freed when -@code{mysql_close()} is called to close the connection. - -@subsubheading Return Values - -An initialized @code{MYSQL*} handle. @code{NULL} if there was -insufficient memory to allocate a new object. - -@subsubheading Errors -In case of insufficient memory, @code{NULL} is returned. - -@findex @code{mysql_insert_id()} -@node mysql_insert_id, mysql_kill, mysql_init, C API functions -@subsubsection @code{mysql_insert_id()} - -@code{my_ulonglong mysql_insert_id(MYSQL *mysql)} - -@subsubheading Description - -Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous -query. Use this function after you have performed an @code{INSERT} query -into a table that contains an @code{AUTO_INCREMENT} field. - -Note that @code{mysql_insert_id()} returns @code{0} if the previous query -does not generate an @code{AUTO_INCREMENT} value. If you need to save -the value for later, be sure to call @code{mysql_insert_id()} immediately -after the query that generates the value. - -Also note that the value of the SQL @code{LAST_INSERT_ID()} function always -contains the most recently generated @code{AUTO_INCREMENT} value, and is -not reset between queries because the value of that function is maintained -in the server. - -@subsubheading Return Values - -The value of the @code{AUTO_INCREMENT} field that was updated by the previous -query. Returns zero if there was no previous query on the connection or if -the query did not update an @code{AUTO_INCREMENT} value. - -@subsubheading Errors -None. - -@findex @code{mysql_kill()} -@node mysql_kill, mysql_list_dbs, mysql_insert_id, C API functions -@subsubsection @code{mysql_kill()} - -@code{int mysql_kill(MYSQL *mysql, unsigned long pid)} - -@subsubheading Description - -Asks the server to kill the thread specified by @code{pid}. - -@subsubheading Return Values - -Zero for success. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_list_dbs()} -@node mysql_list_dbs, mysql_list_fields, mysql_kill, C API functions -@subsubsection @code{mysql_list_dbs()} - -@code{MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)} - -@subsubheading Description - -Returns a result set consisting of database names on the server that match -the simple regular expression specified by the @code{wild} parameter. -@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may -be a @code{NULL} pointer to match all databases. Calling -@code{mysql_list_dbs()} is similar to executing the query @code{SHOW -databases [LIKE wild]}. - -You must free the result set with @code{mysql_free_result()}. - -@subsubheading Return Values - -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_OUT_OF_MEMORY -Out of memory. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_list_fields()} -@node mysql_list_fields, mysql_list_processes, mysql_list_dbs, C API functions -@subsubsection @code{mysql_list_fields()} - -@code{MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)} - -@subsubheading Description - -Returns a result set consisting of field names in the given table that match -the simple regular expression specified by the @code{wild} parameter. -@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may -be a @code{NULL} pointer to match all fields. Calling -@code{mysql_list_fields()} is similar to executing the query @code{SHOW -COLUMNS FROM tbl_name [LIKE wild]}. - -Note that it's recommended that you use @code{SHOW COLUMNS FROM tbl_name} -instead of @code{mysql_list_fields()}. - -You must free the result set with @code{mysql_free_result()}. - -@subsubheading Return Values - -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_list_processes()} -@node mysql_list_processes, mysql_list_tables, mysql_list_fields, C API functions -@subsubsection @code{mysql_list_processes()} - -@code{MYSQL_RES *mysql_list_processes(MYSQL *mysql)} - -@subsubheading Description - -Returns a result set describing the current server threads. This is the same -kind of information as that reported by @code{mysqladmin processlist} or -a @code{SHOW PROCESSLIST} query. - -You must free the result set with @code{mysql_free_result()}. - -@subsubheading Return Values - -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_list_tables()} -@node mysql_list_tables, mysql_num_fields, mysql_list_processes, C API functions -@subsubsection @code{mysql_list_tables()} - -@code{MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)} - -@subsubheading Description - -Returns a result set consisting of table names in the current database that -match the simple regular expression specified by the @code{wild} parameter. -@code{wild} may contain the wild-card characters @samp{%} or @samp{_}, or may -be a @code{NULL} pointer to match all tables. Calling -@code{mysql_list_tables()} is similar to executing the query @code{SHOW -tables [LIKE wild]}. - -You must free the result set with @code{mysql_free_result()}. - -@subsubheading Return Values - -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_num_fields()} -@findex @code{mysql_field_count()} -@node mysql_num_fields, mysql_num_rows, mysql_list_tables, C API functions -@subsubsection @code{mysql_num_fields()} - -@code{unsigned int mysql_num_fields(MYSQL_RES *result)} - -or - -@code{unsigned int mysql_num_fields(MYSQL *mysql)} - -The second form doesn't work on @strong{MySQL} Version 3.22.24 or newer. To pass a -@code{MYSQL*} argument, you must use -@code{unsigned int mysql_field_count(MYSQL *mysql)} instead. - -@subsubheading Description - -Returns the number of columns in a result set. - -Note that you can get the number of columns either from a pointer to a result -set or to a connection handle. You would use the connection handle if -@code{mysql_store_result()} or @code{mysql_use_result()} returned -@code{NULL} (and thus you have no result set pointer). In this case, you can -call @code{mysql_field_count()} to determine whether or not -@code{mysql_store_result()} should have produced a non-empty result. This -allows the client program to take proper action without knowing whether or -not the query was a @code{SELECT} (or @code{SELECT}-like) statement. The -example shown below illustrates how this may be done. - -@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. - -@subsubheading Return Values - -An unsigned integer representing the number of fields in a result set. - -@subsubheading Errors -None. - -@subsubheading Example - -@example -MYSQL_RES *result; -unsigned int num_fields; -unsigned int num_rows; - -if (mysql_query(&mysql,query_string)) -@{ - // error -@} -else // query succeeded, process any data returned by it -@{ - result = mysql_store_result(&mysql); - if (result) // there are rows - @{ - num_fields = mysql_num_fields(result); - // retrieve rows, then call mysql_free_result(result) - @} - else // mysql_store_result() returned nothing; should it have? - @{ - if (mysql_errno(&mysql)) - @{ - fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); - @} - else if (mysql_field_count(&mysql) == 0) - @{ - // query does not return data - // (it was not a SELECT) - num_rows = mysql_affected_rows(&mysql); - @} - @} -@} -@end example - -An alternative (if you KNOW that your query should have returned a result set) -is to replace the @code{mysql_errno(&mysql)} call with a check if -@code{mysql_field_count(&mysql)} is = 0. This will only happen if something -went wrong. - -@findex @code{mysql_num_rows()} -@node mysql_num_rows, mysql_options, mysql_num_fields, C API functions -@subsubsection @code{mysql_num_rows()} - -@code{my_ulonglong mysql_num_rows(MYSQL_RES *result)} - -@subsubheading Description - -Returns the number of rows in the result set. - -The use of @code{mysql_num_rows()} depends on whether you use -@code{mysql_store_result()} or @code{mysql_use_result()} to return the result -set. If you use @code{mysql_store_result()}, @code{mysql_num_rows()} may be -called immediately. If you use @code{mysql_use_result()}, -@code{mysql_num_rows()} will not return the correct value until all the rows -in the result set have been retrieved. - -@subsubheading Return Values - -The number of rows in the result set. - -@subsubheading Errors -None. - -@findex @code{mysql_options()} -@node mysql_options, mysql_ping, mysql_num_rows, C API functions -@subsubsection @code{mysql_options()} - -@code{int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)} - -@subsubheading Description - -Can be used to set extra connect options and affect behavior for a connection. -This function may be called multiple times to set several options. - -@code{mysql_options()} should be called after @code{mysql_init()} and before -@code{mysql_connect()} or @code{mysql_real_connect()}. - -The @code{option} argument is the option that you want to set; the @code{arg} -argument is the value for the option. If the option is an integer, then -@code{arg} should point to the value of the integer. - -Possible options values: - -@multitable @columnfractions .25 .25 .5 -@item @strong{Option} @tab @strong{Argument type} @tab @strong{Function} -@item @code{MYSQL_OPT_CONNECT_TIMEOUT} @tab @code{unsigned int *} @tab Connect timeout in seconds. -@item @code{MYSQL_OPT_COMPRESS} @tab Not used @tab Use the compressed client/server protocol. -@item @code{MYSQL_OPT_NAMED_PIPE} @tab Not used @tab Use named pipes to connect to a @strong{MySQL} server on NT. -@item @code{MYSQL_INIT_COMMAND} @tab @code{char *} @tab Command to execute when connecting to the @strong{MySQL} server. Will automatically be re-executed when reconnecting. -@item @code{MYSQL_READ_DEFAULT_FILE} @tab @code{char *} @tab Read options from the named option file instead of from @file{my.cnf}. -@item @code{MYSQL_READ_DEFAULT_GROUP} @tab @code{char *} @tab Read options from the named group from @file{my.cnf} or the file specified with @code{MYSQL_READ_DEFAULT_FILE}. -@end multitable - -Note that the group @code{client} is always read if you use -@code{MYSQL_READ_DEFAULT_FILE} or @code{MYSQL_READ_DEFAULT_GROUP}. - -The specified group in the option file may contain the following options: - -@multitable @columnfractions .3 .7 -@item @code{connect_timeout} @tab Connect timeout in seconds. On Linux this timeout is also used for waiting for the first answer from the server. -@item @code{compress} @tab Use the compressed client/server protocol. -@item @code{database} @tab Connect to this database if no database was specified in the connect command. -@item @code{debug} @tab Debug options. -@item @code{host} @tab Default host name. -@item @code{init-command} @tab Command to execute when connecting to @strong{MySQL} server. Will automatically be re-executed when reconnecting. -@item @code{interactive-timeout} @tab Same as specifying @code{CLIENT_INTERACTIVE} to @code{mysql_real_connect()}. @xref{mysql_real_connect}. -@item @code{password} @tab Default password. -@item @code{pipe} @tab Use named pipes to connect to a @strong{MySQL} server on NT. -@item @code{port} @tab Default port number. -@item @code{return-found-rows} @tab Tell @code{mysql_info()} to return found rows instead of updated rows when using @code{UPDATE}. -@item @code{socket} @tab Default socket number. -@item -@item @code{user} @tab Default user. -@end multitable - -Note that @code{timeout} has been replaced by @code{connect_timeout}, but -@code{timeout} will still work for a while. - -For more information about option files, see @ref{Option files}. - -@subsubheading Return Values - -Zero for success. Non-zero if you used an unknown option. - -@subsubheading Example - -@example -MYSQL mysql; - -mysql_init(&mysql); -mysql_options(&mysql,MYSQL_OPT_COMPRESS,0); -mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc"); -if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) -@{ - fprintf(stderr, "Failed to connect to database: Error: %s\n", - mysql_error(&mysql)); -@} -@end example - -The above requests the client to use the compressed client/server protocol and -read the additional options from the @code{odbc} section in the @code{my.cnf} -file. - -@findex @code{mysql_ping()} -@node mysql_ping, mysql_query, mysql_options, C API functions -@subsubsection @code{mysql_ping()} - -@code{int mysql_ping(MYSQL *mysql)} - -@subsubheading Description - -Checks whether or not the connection to the server is working. If it has gone -down, an automatic reconnection is attempted. - -This function can be used by clients that remain idle for a long while, -to check whether or not the server has closed the connection and reconnect -if necessary. - -@subsubheading Return Values - -Zero if the server is alive. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_query()} -@node mysql_query, mysql_real_connect, mysql_ping, C API functions -@subsubsection @code{mysql_query()} - -@code{int mysql_query(MYSQL *mysql, const char *query)} - -@subsubheading Description -Executes the SQL query pointed to by the null-terminated string @code{query}. -The query must consist of a single SQL statement. You should not add -a terminating semicolon (@samp{;}) or @code{\g} to the statement. - -@code{mysql_query()} cannot be used for queries that contain binary data; you -should use @code{mysql_real_query()} instead. (Binary data may contain the -@samp{\0} character, which @code{mysql_query()} interprets as the end of the -query string.) - -If you want to know if the query should return a result set or not, you can -use @code{mysql_field_count()} to check for this. -@xref{mysql_field_count, , @code{mysql_field_count}}. - -@subsubheading Return Values - -Zero if the query was successful. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_real_connect()} -@node mysql_real_connect, mysql_real_escape_string, mysql_query, C API functions -@subsubsection @code{mysql_real_connect()} - -@code{MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, - const char *user, const char *passwd, const char *db, - unsigned int port, const char *unix_socket, - unsigned int client_flag)} - -@subsubheading Description - -@code{mysql_real_connect()} attempts to establish a connection to a -@strong{MySQL} database engine running on @code{host}. -@code{mysql_real_connect()} must complete successfully before you can execute -any of the other API functions, with the exception of -@code{mysql_get_client_info()}. - -The parameters are specified as follows: - -@itemize @bullet -@item -The first parameter should be the address of an existing @code{MYSQL} -structure. Before calling @code{mysql_real_connect()} you must call -@code{mysql_init()} to initialize the @code{MYSQL} structure. You can -change a lot of connect options with the @code{mysql_options()} -call. @xref{mysql_options}. - -@item -The value of @code{host} may be either a hostname or an IP address. If -@code{host} is @code{NULL} or the string @code{"localhost"}, a connection to -the local host is assumed. If the OS supports sockets (Unix) or named pipes -(Windows), they are used instead of TCP/IP to connect to the server. - -@item -The @code{user} parameter contains the user's @strong{MySQL} login ID. If -@code{user} is @code{NULL}, the current user is assumed. Under Unix, this is -the current login name. Under Windows ODBC, the current user name must be -specified explicitly. -@xref{ODBC administrator}. - -@item -The @code{passwd} parameter contains the password for @code{user}. If -@code{passwd} is @code{NULL}, only entries in the @code{user} table for the -user that have a blank (empty) password field will be checked for a match. This -allows the database administrator to set up the @strong{MySQL} privilege -system in such a way that users get different privileges depending on whether -or not they have specified a password. - -NOTE: Do not attempt to encrypt the password before calling -@code{mysql_real_connect()}; password encryption is handled automatically by -the client API. - -@item -@code{db} is the database name. -If @code{db} is not @code{NULL}, the connection will set the default -database to this value. - -@item -If @code{port} is not 0, the value will be used as the port number -for the TCP/IP connection. Note that the @code{host} parameter -determines the type of the connection. - -@item -If @code{unix_socket} is not @code{NULL}, the string specifies the -socket or named pipe that should be used. Note that the @code{host} -parameter determines the type of the connection. - -@item -The value of @code{client_flag} is usually 0, but can be set to a combination -of the following flags in very special circumstances: - -@multitable @columnfractions .25 .7 -@item @strong{Flag name} @tab @strong{Flag meaning} -@code{mysqld} to be more ODBC-friendly. -@item @code{CLIENT_COMPRESS} @tab Use compression protocol. -@item @code{CLIENT_FOUND_ROWS} @tab Return the number of found (matched) rows, not the number of affected rows. -@item @code{CLIENT_IGNORE_SPACE} @tab Allow spaces after function names. Makes all functions names reserved words. -@item @code{CLIENT_INTERACTIVE} @tab Allow @code{interactive_timeout} seconds (instead of @code{wait_timeout} seconds) of inactivity before closing the connection. -@item @code{CLIENT_NO_SCHEMA} @tab Don't allow the @code{db_name.tbl_name.col_name} syntax. This is for ODBC. It causes the parser to generate an error if you use that syntax, which is useful for trapping bugs in some ODBC programs. -@item @code{CLIENT_ODBC} @tab The client is an ODBC client. This changes -@item @code{CLIENT_SSL} @tab Use SSL (encrypted protocol). -@end multitable -@end itemize - -@subsubheading Return Values - -A @code{MYSQL*} connection handle if the connection was successful, -@code{NULL} if the connection was unsuccessful. For a successful connection, -the return value is the same as the value of the first parameter, unless you -pass @code{NULL} for that parameter. - -@subsubheading Errors - -@table @code -@item CR_CONN_HOST_ERROR -Failed to connect to the @strong{MySQL} server. - -@item CR_CONNECTION_ERROR -Failed to connect to the local @strong{MySQL} server. - -@item CR_IPSOCK_ERROR -Failed to create an IP socket. - -@item CR_OUT_OF_MEMORY -Out of memory. - -@item CR_SOCKET_CREATE_ERROR -Failed to create a Unix socket. - -@item CR_UNKNOWN_HOST -Failed to find the IP address for the hostname. - -@item CR_VERSION_ERROR -A protocol mismatch resulted from attempting to connect to a server with a -client library that uses a different protocol version. This can happen if you -use a very old client library to connect to a new server that wasn't started -with the @code{--old-protocol} option. - -@item CR_NAMEDPIPEOPEN_ERROR -Failed to create a named pipe on Windows. - -@item CR_NAMEDPIPEWAIT_ERROR -Failed to wait for a named pipe on Windows. - -@item CR_NAMEDPIPESETSTATE_ERROR -Failed to get a pipe handler on Windows. - -@item CR_SERVER_LOST -If @code{connect_timeout} > 0 and it took longer then @code{connect_timeout} -seconds to connect to the server or if the server died while executing the -@code{init-command}. - -@end table - -@subsubheading Example - -@example -MYSQL mysql; - -mysql_init(&mysql); -mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name"); -if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) -@{ - fprintf(stderr, "Failed to connect to database: Error: %s\n", - mysql_error(&mysql)); -@} -@end example - -By using @code{mysql_options()} the @strong{MySQL} library will read the -@code{[client]} and @code{your_prog_name} sections in the @code{my.cnf} -file which will ensure that your program will work, even if someone has -set up @strong{MySQL} in some non-standard way. - -Note that upon connection, @code{mysql_real_connect()} sets the @code{reconnect} -flag (part of the MYSQL structure) to a value of @code{1}. This flag indicates, -in the event that a query cannot be performed because of a lost connection, to -try reconnecting to the server before giving up. - -@findex @code{mysql_real_escape_string()} -@node mysql_real_escape_string, mysql_real_query, mysql_real_connect, C API functions -@subsubsection @code{mysql_real_escape_string()} - -@code{unsigned int mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned int length)} - -@subsubheading Description - -This function is used to create a legal SQL string that you can use in a -SQL statement. @xref{String syntax}. - -The string in @code{from} is encoded to an escaped SQL string, taking -into account the current character set of the connection. The result is placed -in @code{to} and a terminating null byte is appended. Characters -encoded are @code{NUL} (ASCII 0), @samp{\n}, @samp{\r}, @samp{\}, -@samp{'}, @samp{"}, and Control-Z (@pxref{Literals}). - -The string pointed to by @code{from} must be @code{length} bytes long. You -must allocate the @code{to} buffer to be at least @code{length*2+1} bytes -long. (In the worse case, each character may need to be encoded as using two -bytes, and you need room for the terminating null byte.) When -@code{mysql_escape_string()} returns, the contents of @code{to} will be a -null-terminated string. The return value is the length of the encoded -string, not including the terminating null character. - -@subsubheading Example - -@example -char query[1000],*end; - -end = strmov(query,"INSERT INTO test_table values("); -*end++ = '\''; -end += mysql_real_escape_string(&mysql, end,"What's this",11); -*end++ = '\''; -*end++ = ','; -*end++ = '\''; -end += mysql_real_escape_string(&mysql, end,"binary data: \0\r\n",16); -*end++ = '\''; -*end++ = ')'; - -if (mysql_real_query(&mysql,query,(unsigned int) (end - query))) -@{ - fprintf(stderr, "Failed to insert row, Error: %s\n", - mysql_error(&mysql)); -@} -@end example - -The @code{strmov()} function used in the example is included in the -@code{mysqlclient} library and works like @code{strcpy()} but returns a -pointer to the terminating null of the first parameter. - -@subsubheading Return Values - -The length of the value placed into @code{to}, not including the -terminating null character. - -@subsubheading Errors -None. - -@findex @code{mysql_real_query()} -@node mysql_real_query, mysql_reload, mysql_real_escape_string, C API functions -@subsubsection @code{mysql_real_query()} - -@code{int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)} - -@subsubheading Description - -Executes the SQL query pointed to by @code{query}, which should be a string -@code{length} bytes long. The query must consist of a single SQL statement. -You should not add a terminating semicolon (@samp{;}) or @code{\g} to the -statement. - -You @emph{must} use @code{mysql_real_query()} rather than -@code{mysql_query()} for queries that contain binary data, because binary data -may contain the @samp{\0} character. In addition, @code{mysql_real_query()} -is faster than @code{mysql_query()} because it does not call @code{strlen()} on -the query string. - -If you want to know if the query should return a result set or not, you can -use @code{mysql_field_count()} to check for this. -@xref{mysql_field_count, @code{mysql_field_count}}. - -@subsubheading Return Values - -Zero if the query was successful. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_reload()} -@node mysql_reload, mysql_row_seek, mysql_real_query, C API functions -@subsubsection @code{mysql_reload()} - -@code{int mysql_reload(MYSQL *mysql)} - -@subsubheading Description - -Asks the @strong{MySQL} server to reload the grant tables. The -connected user must have the @strong{reload} privilege. - -This function is deprecated. It is preferable to use @code{mysql_query()} -to issue a SQL @code{FLUSH PRIVILEGES} statement instead. - -@subsubheading Return Values - -Zero for success. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_row_seek()} -@node mysql_row_seek, mysql_row_tell, mysql_reload, C API functions -@subsubsection @code{mysql_row_seek()} - -@code{MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)} - -@subsubheading Description -Sets the row cursor to an arbitrary row in a query result set. This requires -that the result set structure contains the entire result of the query, so -@code{mysql_row_seek()} may be used in conjunction only with -@code{mysql_store_result()}, not with @code{mysql_use_result()}. - -The offset should be a value returned from a call to @code{mysql_row_tell()} -or to @code{mysql_row_seek()}. This value is not simply a row number; if you -want to seek to a row within a result set using a row number, use -@code{mysql_data_seek()} instead. - -@subsubheading Return Values - -The previous value of the row cursor. This value may be passed to a -subsequent call to @code{mysql_row_seek()}. - -@subsubheading Errors -None. - -@findex @code{mysql_row_tell()} -@node mysql_row_tell, mysql_select_db, mysql_row_seek, C API functions -@subsubsection @code{mysql_row_tell()} - -@code{MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)} - -@subsubheading Description - -Returns the current position of the row cursor for the last -@code{mysql_fetch_row()}. This value can be used as an argument to -@code{mysql_row_seek()}. - -You should use @code{mysql_row_tell()} only after @code{mysql_store_result()}, -not after @code{mysql_use_result()}. - -@subsubheading Return Values - -The current offset of the row cursor. - -@subsubheading Errors -None. - -@findex @code{mysql_select_db()} -@node mysql_select_db, mysql_shutdown, mysql_row_tell, C API functions -@subsubsection @code{mysql_select_db()} - -@code{int mysql_select_db(MYSQL *mysql, const char *db)} - -@subsubheading Description - -Causes the database specified by @code{db} to become the default (current) -database on the connection specified by @code{mysql}. In subsequent queries, -this database is the default for table references that do not include an -explicit database specifier. - -@code{mysql_select_db()} fails unless the connected user can be authenticated -as having permission to use the database. - -@subsubheading Return Values - -Zero for success. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_shutdown()} -@node mysql_shutdown, mysql_stat, mysql_select_db, C API functions -@subsubsection @code{mysql_shutdown()} - -@code{int mysql_shutdown(MYSQL *mysql)} - -@subsubheading Description - -Asks the database server to shut down. The connected user must have -@strong{shutdown} privileges. - -@subsubheading Return Values - -Zero for success. Non-zero if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_stat()} -@node mysql_stat, mysql_store_result, mysql_shutdown, C API functions -@subsubsection @code{mysql_stat()} - -@code{char *mysql_stat(MYSQL *mysql)} - -@subsubheading Description - -Returns a character string containing information similar to that provided by -the @code{mysqladmin status} command. This includes uptime in seconds and -the number of running threads, questions, reloads, and open tables. - -@subsubheading Return Values - -A character string describing the server status. @code{NULL} if an -error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_store_result()} -@node mysql_store_result, mysql_thread_id, mysql_stat, C API functions -@subsubsection @code{mysql_store_result()} - -@code{MYSQL_RES *mysql_store_result(MYSQL *mysql)} - -@subsubheading Description - -You must call @code{mysql_store_result()} or @code{mysql_use_result()} -for every query that successfully retrieves data (@code{SELECT}, -@code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}). - -You don't have to call @code{mysql_store_result()} or -@code{mysql_use_result()} for other queries, but it will not do any -harm or cause any notable performance if you call @code{mysql_store_result()} -in all cases. You can detect if the query didn't have a result set by -checking if @code{mysql_store_result()} returns 0 (more about this later one). - -If you want to know if the query should return a result set or not, you can -use @code{mysql_field_count()} to check for this. -@xref{mysql_field_count, @code{mysql_field_count}}. - -@code{mysql_store_result()} reads the entire result of a query to the client, -allocates a @code{MYSQL_RES} structure, and places the result into this -structure. - -@code{mysql_store_results()} returns a null pointer if the query didn't return -a result set (if the query was, for example, an @code{INSERT} statement). - -@code{mysql_store_results()} also returns a null pointer if reading of the -result set failed. You can check if you got an error by checking if -@code{mysql_error()} doesn't return a null pointer, if -@code{mysql_errno()} returns <> 0, or if @code{mysql_field_count()} -returns <> 0. - -An empty result set is returned if there are no rows returned. (An empty -result set differs from a null pointer as a return value.) - -Once you have called @code{mysql_store_result()} and got a result back -that isn't a null pointer, you may call @code{mysql_num_rows()} to find -out how many rows are in the result set. - -You can call @code{mysql_fetch_row()} to fetch rows from the result set, -or @code{mysql_row_seek()} and @code{mysql_row_tell()} to obtain or -set the current row position within the result set. - -You must call @code{mysql_free_result()} once you are done with the result -set. - -@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. - -@subsubheading Return Values - -A @code{MYSQL_RES} result structure with the results. @code{NULL} if -an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_OUT_OF_MEMORY -Out of memory. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@findex @code{mysql_thread_id()} -@node mysql_thread_id, mysql_use_result, mysql_store_result, C API functions -@subsubsection @code{mysql_thread_id()} - -@code{unsigned long mysql_thread_id(MYSQL *mysql)} - -@subsubheading Description - -Returns the thread ID of the current connection. This value can be used as -an argument to @code{mysql_kill()} to kill the thread. - -If the connection is lost and you reconnect with @code{mysql_ping()}, the -thread ID will change. This means you should not get the thread ID and store -it for later. You should get it when you need it. - -@subsubheading Return Values - -The thread ID of the current connection. - -@subsubheading Errors -None. - -@findex @code{mysql_use_result()} -@node mysql_use_result, , mysql_thread_id, C API functions -@subsubsection @code{mysql_use_result()} - -@code{MYSQL_RES *mysql_use_result(MYSQL *mysql)} - -@subsubheading Description - -You must call @code{mysql_store_result()} or @code{mysql_use_result()} for -every query that successfully retrieves data (@code{SELECT}, @code{SHOW}, -@code{DESCRIBE}, @code{EXPLAIN}). - -@code{mysql_use_result()} initiates a result set retrieval but does not -actually read the result set into the client like @code{mysql_store_result()} -does. Instead, each row must be retrieved individually by making calls to -@code{mysql_fetch_row()}. This reads the result of a query directly from the -server without storing it in a temporary table or local buffer, which is -somewhat faster and uses much less memory than @code{mysql_store_result()}. -The client will only allocate memory for the current row and a communication -buffer that may grow up to @code{max_allowed_packet} bytes. - -On the other hand, you shouldn't use @code{mysql_use_result()} if you are -doing a lot of processing for each row on the client side, or if the output -is sent to a screen on which the user may type a @code{^S} (stop scroll). -This will tie up the server and prevent other threads from updating any -tables from which the data is being fetched. - -When using @code{mysql_use_result()}, you must execute -@code{mysql_fetch_row()} until a @code{NULL} value is returned, otherwise the -unfetched rows will be returned as part of the result set for your next -query. The C API will give the error @code{Commands out of sync; You can't -run this command now} if you forget to do this! - -You may not use @code{mysql_data_seek()}, @code{mysql_row_seek()}, -@code{mysql_row_tell()}, @code{mysql_num_rows()}, or -@code{mysql_affected_rows()} with a result returned from -@code{mysql_use_result()}, nor may you issue other queries until the -@code{mysql_use_result()} has finished. (However, after you have fetched all -the rows, @code{mysql_num_rows()} will accurately return the number of rows -fetched.) - -You must call @code{mysql_free_result()} once you are done with the result -set. - -@subsubheading Return Values - -A @code{MYSQL_RES} result structure. @code{NULL} if an error occurred. - -@subsubheading Errors - -@table @code -@item CR_COMMANDS_OUT_OF_SYNC -Commands were executed in an improper order. -@item CR_OUT_OF_MEMORY -Out of memory. -@item CR_SERVER_GONE_ERROR -The @strong{MySQL} server has gone away. -@item CR_SERVER_LOST -The connection to the server was lost during the query. -@item CR_UNKNOWN_ERROR -An unknown error occurred. -@end table - -@node C API problems, Thread-safe clients, C API functions, C -@subsection Common questions and problems when using the C API - -@tindex @code{mysql_query()} -@tindex @code{mysql_store_result()} -@menu -* NULL mysql_store_result:: -* Query results:: -* Getting unique ID:: -* C API linking problems:: -@end menu - -@node NULL mysql_store_result, Query results, C API problems, C API problems -@subsubsection Why Is It that After @code{mysql_query()} Returns Success, @code{mysql_store_result()} Sometimes Returns @code{NULL?} - -It is possible for @code{mysql_store_result()} to return @code{NULL} -following a successful call to @code{mysql_query()}. When this happens, it -means one of the following conditions occurred: - -@itemize @bullet -@item -There was a @code{malloc()} failure (for example, if the result set was too -large). - -@item -The data couldn't be read (an error occurred on the connection). - -@item -The query returned no data (for example, it was an @code{INSERT}, -@code{UPDATE}, or @code{DELETE}). -@end itemize - -You can always check whether or not the statement should have produced a -non-empty result by calling @code{mysql_field_count()}. If -@code{mysql_field_count()} returns zero, the result is empty and the last -query was a statement that does not return values (for example, an -@code{INSERT} or a @code{DELETE}). If @code{mysql_field_count()} returns a -non-zero value, the statement should have produced a non-empty result. -See the description of the @code{mysql_field_count()} function for an -example. - -You can test for an error by calling @code{mysql_error()} or -@code{mysql_errno()}. - -@cindex queries, C API results -@menu -* Query results:: -* Getting unique ID:: -* C API linking problems:: -@end menu - -@node Query results, Getting unique ID, NULL mysql_store_result, C API problems -@subsubsection What Results Can I Get From a Query? - -In addition to the result set returned by a query, you can also get the -following information: - -@itemize @bullet -@item -@code{mysql_affected_rows()} returns the number of rows affected by the last -query when doing an @code{INSERT}, @code{UPDATE}, or @code{DELETE}. An -exception is that if @code{DELETE} is used without a @code{WHERE} clause, the -table is re-created empty, which is much faster! In this case, -@code{mysql_affected_rows()} returns zero for the number of records -affected. - -@item -@code{mysql_num_rows()} returns the number of rows in a result set. With -@code{mysql_store_result()}, @code{mysql_num_rows()} may be called as soon as -@code{mysql_store_result()} returns. With @code{mysql_use_result()}, -@code{mysql_num_rows()} may be called only after you have fetched all the -rows with @code{mysql_fetch_row()}. - -@item -@code{mysql_insert_id()} returns the ID generated by the last -query that inserted a row into a table with an @code{AUTO_INCREMENT} index. -@xref{mysql_insert_id, , @code{mysql_insert_id()}}. - -@item -Some queries (@code{LOAD DATA INFILE ...}, @code{INSERT INTO -... SELECT ...}, @code{UPDATE}) return additional information. The result is -returned by @code{mysql_info()}. See the description for @code{mysql_info()} -for the format of the string that it returns. @code{mysql_info()} returns a -@code{NULL} pointer if there is no additional information. -@end itemize - -@cindex unique ID -@cindex last row, unique ID -@cindex ID, unique -@cindex tables, unique ID for last row -@node Getting unique ID, C API linking problems, Query results, C API problems -@subsubsection How Can I Get the Unique ID for the Last Inserted Row? - -If you insert a record in a table containing a column that has the -@code{AUTO_INCREMENT} attribute, you can get the most recently generated -ID by calling the @code{mysql_insert_id()} function. - -You can also retrieve the ID by using the @code{LAST_INSERT_ID()} function in -a query string that you pass to @code{mysql_query()}. - -You can check if an @code{AUTO_INCREMENT} index is used by executing -the following code. This also checks if the query was an @code{INSERT} with -an @code{AUTO_INCREMENT} index: - -@example -if (mysql_error(&mysql)[0] == 0 && - mysql_num_fields(result) == 0 && - mysql_insert_id(&mysql) != 0) -@{ - used_id = mysql_insert_id(&mysql); -@} -@end example - -The most recently generated ID is maintained in the server on a -per-connection basis. It will not be changed by another client. It will not -even be changed if you update another @code{AUTO_INCREMENT} column with a -non-magic value (that is, a value that is not @code{NULL} and not @code{0}). - -If you want to use the ID that was generated for one table and insert -it into a second table, you can use SQL statements like this: - -@example -INSERT INTO foo (auto,text) - VALUES(NULL,'text'); # generate ID by inserting NULL -INSERT INTO foo2 (id,text) - VALUES(LAST_INSERT_ID(),'text'); # use ID in second table -@end example - -@cindex linking, problems -@cindex C API, linking problems -@node C API linking problems, , Getting unique ID, C API problems -@subsubsection Problems Linking with the C API - -When linking with the C API, the following errors may occur on some systems: - -@example -gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl - -Undefined first referenced - symbol in file -floor /usr/local/lib/mysql/libmysqlclient.a(password.o) -ld: fatal: Symbol referencing errors. No output written to client -@end example - -If this happens on your system, you must include the math library by -adding @code{-lm} to the end of the compile/link line. - -@cindex clients, thread-safe -@cindex thread-safe clients -@node Thread-safe clients, , C API problems, C -@subsection How to Make a Thread-safe Client - -The client library is almost thread safe. The biggest problem is -that the subroutines in @file{net.c} that read from sockets are not -interrupt safe. This was done with the thought that you might want to -have your own alarm that can break a long read to a server. If you -install interrupt handlers for the @code{SIGPIPE} interrupt, -the socket handling should be thread safe. - -In the older binaries we distribute on our Web site, the client -libraries are not normally compiled with the thread-safe option (the -Windows binaries are by default compiled to be thread safe). -Newer binary distributions should have both a normal and a -thread-safe client library. - -To get a really thread-safe client where you can interrupt the client -from other threads and set timeouts when talking with the @strong{MySQL} -server, you should use the @code{-lmysys}, @code{-lstring}, and @code{-ldbug} -libraries and the @code{net_serv.o} code that the server uses. - -If you don't need interrupts or timeouts, you can just compile a thread -safe client library @code{(mysqlclient_r)} and use this. @xref{C,, -MySQL C API}. In this case you don't have to worry about the -@code{net_serv.o} object file or the other @strong{MySQL} libraries. - -When using a threaded client and you want to use timeouts and interrupts, -you can make great use of the routines in the @file{thr_alarm.c} file. -If you are using routines from the @code{mysys} library, the only thing -you must remember is to call @code{my_init()} first! - -All functions except @code{mysql_real_connect()} are by default -thread safe. The following notes describe how to compile a thread safe -client library and use it in a thread-safe manner. (The notes below for -@code{mysql_real_connect()} actually apply to @code{mysql_connect()} as -well, but because @code{mysql_connect()} is deprecated, you should be -using @code{mysql_real_connect()} anyway.) - -To make @code{mysql_real_connect()} thread safe, you must recompile the -client library with this command: - -@example -shell> ./configure --with-thread-safe-client -@end example - -This will create a thread-safe client library @code{libmysqlclient_r}. -@code{--with-thread-safe-client}. This library is thread safe per -connection. You can let two threads share the same connection as long -as you do the following: - -@itemize @bullet -@item -Two threads can't send a query to the @strong{MySQL} at the same time on -the same connection. In particular, you have to ensure that between a -@code{mysql_query()} and @code{mysql_store_result()} no other thread is using -the same connection. -@item -Many threads can access different result sets that are retrieved with -@code{mysql_store_result()}. -@item -If you use @code{mysql_use_result}, you have to ensure that no other thread -is asking anything on the same connection until the result set is closed. -However, it really is best for threaded clients that share the same -connection to use @code{mysql_use_result()}. -@item -If you want to use multiple threads on the same connection, you must -have a mutex lock around your @code{mysql_query()} and -@code{mysql_store_result()} call combination. Once -@code{mysql_store_result()} is ready, the lock can be released and other -threads may query the same connection. -@item -If you program with POSIX threads, you can use -@code{pthread_mutex_lock()} and @code{pthread_mutex_unlock()} to -establish and release a mutex lock. -@end itemize - -You may get some errors because of undefined symbols when linking your -client with @code{mysqlclient_r}. In most cases this is because you haven't -included the thread libraries on the link/compile line. - -@cindex APIs, Perl -@cindex Perl API -@node Perl, Eiffel, C, Clients -@section MySQL Perl API - -This section documents the Perl @code{DBI} interface. The former interface -was called @code{mysqlperl}. @code{DBI}/@code{DBD} now is the -recommended Perl interface, so @code{mysqlperl} is obsolete and is not -documented here. - -@menu -* DBI with DBD:: @code{DBI} with @code{DBD::mysql} -* Perl DBI Class:: The @code{DBI} interface -* DBI-info:: More @code{DBI}/@code{DBD} information -@end menu - -@cindex @code{DBI} interface -@node DBI with DBD, Perl DBI Class, Perl, Perl -@subsection @code{DBI} with @code{DBD::mysql} - -@code{DBI} is a generic interface for many databases. That means that -you can write a script that works with many different database engines -without change. You need a DataBase Driver (DBD) defined for each -database type. For @strong{MySQL}, this driver is called -@code{DBD::mysql}. - -For more information on the Perl5 DBI, please visit the @code{DBI} Web -page and read the documentation: -@example -@uref{http://www.symbolstone.org/technology/perl/DBI/index.html} -@end example -For more information on Object Oriented Programming -(OOP) as defined in Perl5, see the Perl OOP page: -@example -@uref{http://language.perl.com/info/documentation.html} -@end example - -Note that if you want to use transactions with Perl, you need to have -@code{Msql-Mysql-modules} version 1.2216 or newer. - -Installation instructions for @strong{MySQL} Perl support are given in -@ref{Perl support}. - -@cindex @code{DBI} Perl module -@node Perl DBI Class, DBI-info, DBI with DBD, Perl -@subsection The @code{DBI} Interface - -@noindent -@strong{Portable DBI Methods} - -@multitable @columnfractions .3 .7 -@item @code{connect} @tab Establishes a connection to a database server. -@item @code{disconnect} @tab Disconnects from the database server. -@item @code{prepare} @tab Prepares a SQL statement for execution. -@item @code{execute} @tab Executes prepared statements. -@item @code{do} @tab Prepares and executes a SQL statement. -@item @code{quote} @tab Quotes string or @code{BLOB} values to be inserted. -@item @code{fetchrow_array} @tab Fetches the next row as an array of fields. -@item @code{fetchrow_arrayref} @tab Fetches next row as a reference array of fields. -@item @code{fetchrow_hashref} @tab Fetches next row as a reference to a hashtable. -@item @code{fetchall_arrayref} @tab Fetches all data as an array of arrays. -@item @code{finish} @tab Finishes a statement and lets the system free resources. -@item @code{rows} @tab Returns the number of rows affected. -@item @code{data_sources} @tab Returns an array of databases available on localhost. -@item @code{ChopBlanks} @tab Controls whether @code{fetchrow_*} methods trim spaces. -@item @code{NUM_OF_PARAMS} @tab The number of placeholders in the prepared statement. -@item @code{NULLABLE} @tab Which columns can be @code{NULL}. -@item @code{trace} @tab Perform tracing for debugging. -@end multitable - -@noindent -@strong{MySQL-specific Methods} - -@multitable @columnfractions .3 .7 -@item @code{insertid} @tab The latest @code{AUTO_INCREMENT} value. -@item @code{is_blob} @tab Which columns are @code{BLOB} values. -@item @code{is_key} @tab Which columns are keys. -@item @code{is_num} @tab Which columns are numeric. -@item @code{is_pri_key} @tab Which columns are primary keys. -@item @code{is_not_null} @tab Which columns CANNOT be @code{NULL}. See @code{NULLABLE}. -@item @code{length} @tab Maximum possible column sizes. -@item @code{max_length} @tab Maximum column sizes actually present in result. -@item @code{NAME} @tab Column names. -@item @code{NUM_OF_FIELDS} @tab Number of fields returned. -@item @code{table} @tab Table names in returned set. -@item @code{type} @tab All column types. -@end multitable - -The Perl methods are described in more detail in the following sections. -Variables used for method return values have these meanings: - -@table @code -@item $dbh -Database handle - -@item $sth -Statement handle - -@item $rc -Return code (often a status) - -@item $rv -Return value (often a row count) -@end table - -@noindent -@strong{Portable DBI Methods} - -@table @code - -@findex DBI->connect() -@findex connect() DBI method -@item connect($data_source, $username, $password) -Use the @code{connect} method to make a database connection to the data -source. The @code{$data_source} value should begin with -@code{DBI:driver_name:}. -Example uses of @code{connect} with the @code{DBD::mysql} driver: -@example -$dbh = DBI->connect("DBI:mysql:$database", $user, $password); -$dbh = DBI->connect("DBI:mysql:$database:$hostname", - $user, $password); -$dbh = DBI->connect("DBI:mysql:$database:$hostname:$port", - $user, $password); -@end example -If the user name and/or password are undefined, @code{DBI} uses the -values of the @code{DBI_USER} and @code{DBI_PASS} environment variables, -respectively. If you don't specify a hostname, it defaults to -@code{'localhost'}. If you don't specify a port number, it defaults to the -default @strong{MySQL} port (@value{default_port}). - -As of @code{Msql-Mysql-modules} Version 1.2009, -the @code{$data_source} value allows certain modifiers: - -@table @code -@item mysql_read_default_file=file_name -Read @file{filename} as an option file. For information on option files, -see @ref{Option files}. - -@item mysql_read_default_group=group_name -The default group when reading an option file is normally the -@code{[client]} group. By specifying the @code{mysql_read_default_group} -option, the default group becomes the @code{[group_name]} group. - -@item mysql_compression=1 -Use compressed communication between the client and server (@strong{MySQL} -Version 3.22.3 or later). - -@item mysql_socket=/path/to/socket -Specify the pathname of the Unix socket that is used to connect -to the server (@strong{MySQL} Version 3.21.15 or later). -@end table - -Multiple modifiers may be given; each must be preceded by a semicolon. - -For example, if you want to avoid hardcoding the user name and password into -a @code{DBI} script, you can take them from the user's @file{~/.my.cnf} -option file instead by writing your @code{connect} call like this: - -@example -$dbh = DBI->connect("DBI:mysql:$database" - . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf", - $user, $password); -@end example - -This call will read options defined for the @code{[client]} group in the -option file. If you wanted to do the same thing but use options specified -for the @code{[perl]} group as well, you could use this: - -@example -$dbh = DBI->connect("DBI:mysql:$database" - . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf" - . ";mysql_read_default_group=perl", - $user, $password); -@end example - -@findex DBI->disconnect -@findex disconnect DBI method -@item disconnect -The @code{disconnect} method disconnects the database handle from the database. -This is typically called right before you exit from the program. -Example: -@example -$rc = $dbh->disconnect; -@end example - -@findex DBI->prepare() -@findex prepare() DBI method -@item prepare($statement) -Prepares a SQL statement for execution by the database engine -and returns a statement handle @code{($sth)}, which you can use to invoke -the @code{execute} method. -Typically you handle @code{SELECT} statements (and @code{SELECT}-like statements -such as @code{SHOW}, @code{DESCRIBE}, and @code{EXPLAIN}) by means of -@code{prepare} and @code{execute}. -Example: -@example -$sth = $dbh->prepare($statement) - or die "Can't prepare $statement: $dbh->errstr\n"; -@end example - -@findex DBI->execute -@findex execute DBI method -@item execute -The @code{execute} method executes a prepared statement. For -non-@code{SELECT} statements, @code{execute} returns the number of rows -affected. If no rows are affected, @code{execute} returns @code{"0E0"}, -which Perl treats as zero but regards as true. If an error occurs, -@code{execute} returns @code{undef}. For @code{SELECT} statements, -@code{execute} only starts the SQL query in the database; you need to use one -of the @code{fetch_*} methods described below to retrieve the data. -Example: -@example -$rv = $sth->execute - or die "can't execute the query: $sth->errstr; -@end example - -@findex DBI->do() -@findex do() DBI method -@item do($statement) -The @code{do} method prepares and executes a SQL statement and returns the -number of rows affected. If no rows are affected, @code{do} returns -@code{"0E0"}, which Perl treats as zero but regards as true. This method is -generally used for non-@code{SELECT} statements that cannot be prepared in -advance (due to driver limitations) or that do not need to be executed more -than once (inserts, deletes, etc.). Example: -@example -$rv = $dbh->do($statement) - or die "Can't execute $statement: $dbh- >errstr\n"; -@end example - -Generally the 'do' statement is MUCH faster (and is preferable) -than prepare/execute for statements that don't contain parameters. - -@findex DBI->quote() -@findex quote() DBI method -@cindex quoting strings -@cindex strings, quoting -@item quote($string) -The @code{quote} method is used to "escape" any special characters contained in -the string and to add the required outer quotation marks. -Example: -@example -$sql = $dbh->quote($string) -@end example - -@findex DBI->fetchrow_array -@findex fetchrow_array DBI method -@item fetchrow_array -This method fetches the next row of data and returns it as an array of -field values. Example: -@example -while(@@row = $sth->fetchrow_array) @{ - print qw($row[0]\t$row[1]\t$row[2]\n); -@} -@end example - -@findex DBI->fetchrow_arrayref -@findex fetchrow_arrayref DBI method -@item fetchrow_arrayref -This method fetches the next row of data and returns it as a reference -to an array of field values. Example: -@example -while($row_ref = $sth->fetchrow_arrayref) @{ - print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n); -@} -@end example - -@findex DBI->fetchrow_hashref -@findex fetchrow_hashref DBI method -@item fetchrow_hashref -This method fetches a row of data and returns a reference to a hash -table containing field name/value pairs. This method is not nearly as -efficient as using array references as demonstrated above. Example: -@example -while($hash_ref = $sth->fetchrow_hashref) @{ - print qw($hash_ref->@{firstname@}\t$hash_ref->@{lastname@}\t\ - $hash_ref- > title@}\n); -@} -@end example - -@findex DBI->fetchall_arrayref -@findex fetchall_arrayref DBI method -@item fetchall_arrayref -This method is used to get all the data (rows) to be returned from the -SQL statement. It returns a reference to an array of references to arrays -for each row. You access or print the data by using a nested -loop. Example: -@example -my $table = $sth->fetchall_arrayref - or die "$sth->errstr\n"; -my($i, $j); -for $i ( 0 .. $#@{$table@} ) @{ - for $j ( 0 .. $#@{$table->[$i]@} ) @{ - print "$table->[$i][$j]\t"; - @} - print "\n"; -@} -@end example - -@findex DBI->finish -@findex finish DBI method -@item finish -Indicates that no more data will be fetched from this statement -handle. You call this method to free up the statement handle and any -system resources associated with it. Example: -@example -$rc = $sth->finish; -@end example - -@findex DBI->rows -@findex rows DBI method -@item rows -Returns the number of rows changed (updated, deleted, etc.) by the last -command. This is usually used after a non-@code{SELECT} @code{execute} -statement. Example: -@example -$rv = $sth->rows; -@end example - -@findex DBI->@{NULLABLE@} -@findex NULLABLE DBI method -@item NULLABLE -Returns a reference to an array of boolean values; for each element of -the array, a value of TRUE indicates that this -column may contain @code{NULL} values. -Example: -@example -$null_possible = $sth->@{NULLABLE@}; -@end example - -@findex DBI->@{NUM_OF_FIELDS@} -@findex NUM_OF_FIELDS DBI method -@item NUM_OF_FIELDS -This attribute indicates -the number of fields returned by a @code{SELECT} or @code{SHOW FIELDS} -statement. You may use this for checking whether a statement returned a -result: A zero value indicates a non-@code{SELECT} statement like -@code{INSERT}, @code{DELETE}, or @code{UPDATE}. -Example: -@example -$nr_of_fields = $sth->@{NUM_OF_FIELDS@}; -@end example - -@findex DBI->data_sources() -@findex data_sources() DBI method -@item data_sources($driver_name) -This method returns an array containing names of databases available to the -@strong{MySQL} server on the host @code{'localhost'}. -Example: -@example -@@dbs = DBI->data_sources("mysql"); -@end example - -@findex DBI->@{ChopBlanks@} -@findex ChopBlanks DBI method -@item ChopBlanks -This attribute determines whether the @code{fetchrow_*} methods will chop -leading and trailing blanks from the returned values. -Example: -@example -$sth->@{'ChopBlanks'@} =1; -@end example - -@findex DBI->trace -@findex trace DBI method -@item trace($trace_level) -@itemx trace($trace_level, $trace_filename) -The @code{trace} method enables or disables tracing. When invoked as a -@code{DBI} class method, it affects tracing for all handles. When invoked as -a database or statement handle method, it affects tracing for the given -handle (and any future children of the handle). Setting @code{$trace_level} -to 2 provides detailed trace information. Setting @code{$trace_level} to 0 -disables tracing. Trace output goes to the standard error output by -default. If @code{$trace_filename} is specified, the file is opened in -append mode and output for @emph{all} traced handles is written to that -file. Example: -@example -DBI->trace(2); # trace everything -DBI->trace(2,"/tmp/dbi.out"); # trace everything to - # /tmp/dbi.out -$dth->trace(2); # trace this database handle -$sth->trace(2); # trace this statement handle -@end example - -@tindex DBI_TRACE environment variable -@tindex Environment variable, DBI_TRACE -You can also enable @code{DBI} tracing by setting the @code{DBI_TRACE} -environment variable. Setting it to a numeric value is equivalent to calling -@code{DBI->(value)}. Setting it to a pathname is equivalent to calling -@code{DBI->(2,value)}. - -@end table - -@noindent -@strong{MySQL-specific Methods} - -The methods shown below are @strong{MySQL}-specific and not part of the -@code{DBI} standard. Several of them are now deprecated: -@code{is_blob}, @code{is_key}, @code{is_num}, @code{is_pri_key}, -@code{is_not_null}, @code{length}, @code{max_length}, and @code{table}. -Where @code{DBI}-standard alternatives exist, they are noted below: - -@table @code -@findex DBI->@{insertid@} -@findex insertid DBI method -@tindex AUTO_INCREMENT, using with DBI -@item insertid -If you use the @code{AUTO_INCREMENT} feature of @strong{MySQL}, the new -auto-incremented values will be stored here. -Example: -@example -$new_id = $sth->@{insertid@}; -@end example - -As an alternative, you can use @code{$dbh->@{'mysql_insertid'@}}. - -@findex DBI->@{is_blob@} -@findex is_blob DBI method -@item is_blob -Returns a reference to an array of boolean values; for each element of the -array, a value of TRUE indicates that the -respective column is a @code{BLOB}. -Example: -@example -$keys = $sth->@{is_blob@}; -@end example - -@findex DBI->@{is_key@} -@findex is_key DBI method -@item is_key -Returns a reference to an array of boolean values; for each element of the -array, a value of TRUE indicates that the -respective column is a key. -Example: -@example -$keys = $sth->@{is_key@}; -@end example - -@findex DBI->@{is_num@} -@findex is_num DBI method -@item is_num -Returns a reference to an array of boolean values; for each element of the -array, a value of TRUE indicates that the -respective column contains numeric values. -Example: -@example -$nums = $sth->@{is_num@}; -@end example - -@findex DBI->@{is_pri_key@} -@findex is_pri_key DBI method -@item is_pri_key -Returns a reference to an array of boolean values; for each element of the -array, a value of TRUE indicates that the respective column is a primary key. -Example: -@example -$pri_keys = $sth->@{is_pri_key@}; -@end example - -@findex DBI->@{is_not_null@} -@findex is_not_null DBI method -@item is_not_null -Returns a reference to an array of boolean values; for each element of the -array, a value of FALSE indicates that this column may contain @code{NULL} -values. -Example: -@example -$not_nulls = $sth->@{is_not_null@}; -@end example - -@code{is_not_null} is deprecated; it is preferable to use the -@code{NULLABLE} attribute (described above), because that is a DBI standard. - -@findex DBI->@{length@} -@findex length DBI method -@findex DBI->@{max_length@} -@findex max_length DBI method -@item length -@itemx max_length -Each of these methods returns a reference to an array of column sizes. The -@code{length} array indicates the maximum possible sizes that each column may -be (as declared in the table description). The @code{max_length} array -indicates the maximum sizes actually present in the result table. Example: - -@example -$lengths = $sth->@{length@}; -$max_lengths = $sth->@{max_length@}; -@end example - -@findex DBI->@{NAME@} -@findex NAME DBI method -@item NAME -Returns a reference to an array of column names. -Example: -@example -$names = $sth->@{NAME@}; -@end example - -@findex DBI->@{table@} -@findex table DBI method -@item table -Returns a reference to an array of table names. -Example: -@example -$tables = $sth->@{table@}; -@end example - -@findex DBI->@{type@} -@findex type DBI method -@item type -Returns a reference to an array of column types. -Example: -@example -$types = $sth->@{type@}; -@end example - -@end table - -@cindex @code{DBI/DBD} -@node DBI-info, , Perl DBI Class, Perl -@subsection More @code{DBI}/@code{DBD} Information - -You can use the @code{perldoc} command to get more information about -@code{DBI}. - -@example -perldoc DBI -perldoc DBI::FAQ -perldoc DBD::mysql -@end example - -You can also use the @code{pod2man}, @code{pod2html}, etc., tools to -translate to other formats. - -You can find the latest @code{DBI} information at -the @code{DBI} Web page: -@example -@uref{http://www.symbolstone.org/technology/perl/DBI/index.html} -@end example - -@cindex Eiffel Wrapper -@cindex wrappers, Eiffel -@node Eiffel, Java, Perl, Clients -@section MySQL Eiffel wrapper - -The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} -contains an Eiffel wrapper written by Michael Ravits. - -You can also find this at: -@url{http://www.netpedia.net/hosting/newplayer/} - -@cindex Java connectivity -@cindex JDBC -@node Java, PHP, Eiffel, Clients -@section MySQL Java Connectivity (JDBC) - -There are 2 supported JDBC drivers for @strong{MySQL} (the mm driver and -the Reisin JDBC driver). You can find a copy of the mm driver at -@uref{http://mmmysql.sourceforge.net/} or -@uref{http://www.mysql.com/Downloads/Contrib/} and the Reisin driver at -@uref{http://www.caucho.com/projects/jdbc-mysql/index.xtp} For -documentation consult any JDBC documentation and the driver's own -documentation for @strong{MySQL}-specific features. - -@cindex PHP API -@node PHP, Cplusplus, Java, Clients -@section MySQL PHP API - -PHP is a server-side, HTML-embedded scripting language that may be used to -create dynamic Web pages. It contains support for accessing several -databases, including @strong{MySQL}. PHP may be run as a separate program -or compiled as a module for use with the Apache Web server. - -The distribution and documentation are available at the -@uref{http://www.php.net/, PHP web site}. - -@menu -* PHP problems:: Common problems with MySQL and PHP -@end menu - -@node PHP problems, , PHP, PHP -@subsection Common Problems with MySQL and PHP - -@itemize @bullet -@item Error: "Maximum Execution Time Exceeded" -This is a PHP limit; Go into the @file{php3.ini} file and set the maximum -execution time up from 30 seconds to something higher, as needed. -It is also not a bad idea to double the ram allowed per script to 16MB instead of -8 MB. -@item Error: "Fatal error: Call to unsupported or undefined function mysql_connect() in .." -This means that your PHP version isn't compiled with @strong{MySQL} support. -You can either compile a dynamic @strong{MySQL} module and load it into PHP or -recompile PHP with built-in @strong{MySQL} support. This is described in -detail in the PHP manual. -@item Error: "undefined reference to `uncompress'" -This means that the client library is compiled with support for a compressed -client/server protocol. The fix is to add @code{-lz} last when linking -with @code{-lmysqlclient}. -@end itemize - -@cindex C++ APIs -@node Cplusplus, Python, PHP, Clients -@section MySQL C++ APIs - -Two APIs are available in the @strong{MySQL} -@uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory}. - -@cindex Python APIs -@node Python, Tcl, Cplusplus, Clients -@section MySQL Python APIs - -The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} -contains a Python interface written by Joseph Skinner. - -You can also use the Python interface to iODBC to access a -@strong{MySQL} server. -@uref{http://starship.skyport.net/~lemburg/,mxODBC} - -@cindex Tcl APIs -@node Tcl, , Python, Clients -@section MySQL Tcl APIs - -@uref{http://www.binevolve.com/~tdarugar/tcl-sql/, Tcl at binevolve}. -The -@uref{http://www.mysql.com/Downloads/Contrib,Contrib directory} contains a Tcl -interface that is based on msqltcl 1.50. - - - - -@node Problems, Environment variables, Clients, Top +@node Problems, Environment variables, Extending MySQL, Top @appendix Problems and Common Errors @cindex problems, common errors @@ -53175,12 +53317,11 @@ That's all there is to it! @menu * Installing binary:: -* Building clients:: * Perl support:: * Group by functions:: @end menu -@node Installing binary, Building clients, Placeholder, Placeholder +@node Installing binary, Perl support, Placeholder, Placeholder @appendixsec Installing a MySQL Binary Distribution @cindex installing, binary distribution @@ -53397,31 +53538,12 @@ shell> bin/safe_mysqld --user=mysql & @xref{Post-installation}. -@node Building clients, Perl support, Installing binary, Placeholder -@appendixsec Building Client Programs - -@cindex client programs, building -@cindex linking -@cindex building, client programs -@cindex programs, client - -If you compile @strong{MySQL} clients that you've written yourself or that -you obtain from a third party, they must be linked using the -@code{-lmysqlclient -lz} option on the link command. You may also need to -specify a @code{-L} option to tell the linker where to find the library. For -example, if the library is installed in @file{/usr/local/mysql/lib}, use -@code{-L/usr/local/mysql/lib -lmysqlclient -lz} on the link command. - -For clients that use @strong{MySQL} header files, you may need to specify a -@code{-I} option when you compile them (for example, -@code{-I/usr/local/mysql/include}), so the compiler can find the header -files. -@node Perl support, Group by functions, Building clients, Placeholder +@node Perl support, Group by functions, Installing binary, Placeholder @appendixsec Perl Installation Comments @cindex Perl, installing From f73b05fff8aefc9d92489918cef9643b541e7f2e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 04:11:34 -0500 Subject: [PATCH 05/18] Fixed stupid node name in manual.texi. Docs/manual.texi: Fixed stupid node name. --- Docs/manual.texi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 135600104da..8bb22202055 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -30179,10 +30179,10 @@ a binary string. This only affects comparisons. @menu * String comparison functions:: -* Case Sensitivity:: +* Case Sensitivity Operators:: @end menu -@node String comparison functions, Case Sensitivity, String functions, String functions +@node String comparison functions, Case Sensitivity Operators, String functions, String functions @subsubsection String Comparison Functions @findex string comparison functions @@ -30333,7 +30333,7 @@ must be created first. @xref{CREATE TABLE, , @code{CREATE TABLE}}. @end table -@node Case Sensitivity, , String comparison functions, String functions +@node Case Sensitivity Operators, , String comparison functions, String functions @subsubsection Case Sensitivity @findex casts From e24443b04bda0ca59db61a016637e7ab644fff8c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 12:40:49 +0300 Subject: [PATCH 06/18] changed variable display from string to int (bits) for myisam-recover and sql-mode options. sql/mysqld.cc: Changed the sql-mode to be shown as a number (bits) instead of a string. --- sql/mysqld.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 36ee127580c..2d7d53919a6 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2850,7 +2850,7 @@ struct show_var_st init_vars[]= { {"max_user_connections", (char*) &max_user_connections, SHOW_LONG}, {"max_tmp_tables", (char*) &max_tmp_tables, SHOW_LONG}, {"max_write_lock_count", (char*) &max_write_lock_count, SHOW_LONG}, - {"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR}, + {"myisam_recover_options", (char*) &myisam_recover_options, SHOW_LONG}, {"myisam_max_extra_sort_file_size", (char*) &myisam_max_extra_sort_file_size, SHOW_LONG}, {"myisam_max_sort_file_size",(char*) &myisam_max_sort_file_size, SHOW_LONG}, @@ -2874,7 +2874,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}, From d84ef9d9498e62190da02b32ab733b78ffd36c2b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 13:01:42 +0300 Subject: [PATCH 07/18] New dutch error message file. sql/share/dutch/errmsg.txt: New dutch error messages. --- sql/share/dutch/errmsg.txt | 244 +++++++++++++++++++------------------ 1 file changed, 124 insertions(+), 120 deletions(-) diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index df3d35600ba..7a77d7c7ddf 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -1,17 +1,23 @@ /* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ + This file is public domain and comes with NO WARRANTY of any kind + + Dutch error messages (share/dutch/errmsg.txt) + Arjen G. Lentz (agl@bitbike.com) + Completed earlier partial translation; worked on consistency and spelling. + Version: 02-08-2001 +*/ "hashchk", "isamchk", "NEE", "JA", -"Kan file '%-.64s' niet aanmaken. (Errcode: %d)", -"Kan tabel '%-.64s' niet aanmaken. (Errcode: %d)", -"Kan database '%-.64s' niet aanmaken. Error %d", -"Kan database '%-.64s' niet aanmaken. Database bestaat al", +"Kan file '%-.64s' niet aanmaken (Errcode: %d)", +"Kan tabel '%-.64s' niet aanmaken (Errcode: %d)", +"Kan database '%-.64s' niet aanmaken (Errcode: %d)", +"Kan database '%-.64s' niet aanmaken. Database bestaat reeds", "Kan database '%-.64s' niet verwijderen. Database bestaat niet", -"Error verwijderen database (kan '%-.64s' niet verwijderen, error %d)", -"Error verwijderen database (kan rmdir '%-.64s' niet uitvoeren, error %d)", +"Error verwijderen database (kan '%-.64s' niet verwijderen, Errcode: %d)", +"Error verwijderen database (kan rmdir '%-.64s' niet uitvoeren, Errcode: %d)", "Error bij het verwijderen van '%-.64s' (Errcode: %d)", "Kan record niet lezen in de systeem tabel", "Kan de status niet krijgen van '%-.64s' (Errcode: %d)", @@ -23,27 +29,27 @@ "Kan de directory niet veranderen naar '%-.64s' (Errcode: %d)", "Record is veranderd sinds de laatste lees activiteit in de tabel '%-.64s'", "Schijf vol (%s). Aan het wachten totdat er ruimte vrij wordt gemaakt...", -"Kan niet schrijven, dubbele key in tabel '%-.64s'", +"Kan niet schrijven, dubbele zoeksleutel in tabel '%-.64s'", "Fout bij het sluiten van '%-.64s' (Errcode: %d)", "Fout bij het lezen van file '%-.64s' (Errcode: %d)", "Fout bij het hernoemen van '%-.64s' naar '%-.64s' (Errcode: %d)", "Fout bij het wegschrijven van file '%-.64s' (Errcode: %d)", "'%-.64s' is geblokeerd tegen veranderingen", "Sorteren afgebroken", -"View '%-.64s' bestaat niet voorr '%-.64s'", +"View '%-.64s' bestaat niet voor '%-.64s'", "Fout %d van tabel handler", "Tabel handler voor '%-.64s' heeft deze optie niet", "Kan record niet vinden in '%-.64s'", "Verkeerde info in file: '%-.64s'", -"Verkeerde key file voor tabel: '%-.64s'. Probeer het te repareren", -"Oude key file voor tabel '%-.64s'; Repareer het!", +"Verkeerde zoeksleutel file voor tabel: '%-.64s'. Probeer het te repareren", +"Oude zoeksleutel file voor tabel '%-.64s'; Repareer het!", "'%-.64s' is alleen leesbaar", "Geen geheugen meer. Herstart server en probeer opnieuw (%d bytes nodig)", "Geen geheugen om te sorteren. Verhoog de server sort buffer size", "Onverwachte eof gevonden tijdens het lezen van file '%-.64s' (Errcode: %d)", "Te veel verbindingen", -"Geen thread geheugen meer", -"Kan de hostname niet krijgen van jou adres", +"Geen thread geheugen meer; controleer of mysqld of andere processen al het beschikbare geheugen gebruikt. Zo niet, dan moet u wellicht 'ulimit' gebruiken om mysqld toe te laten meer geheugen te benutten, of u kunt extra swap ruimte toevoegen", +"Kan de hostname niet krijgen van uw adres", "Verkeerde handshake", "Toegang geweigerd voor gebruiker: '%-.32s@%-.64s' naar database '%-.64s'", "Toegang geweigerd voor gebruiker: '%-.32s@%-.64s' (Wachtwoord gebruikt: %s)", @@ -53,30 +59,30 @@ "Onbekende database '%-.64s'", "Tabel '%-.64s' bestaat al", "Onbekende tabel '%-.64s'", -"Kolom: '%-.64s' in %s is ambiguous", +"Kolom: '%-.64s' in %s is niet eenduidig", "Bezig met het stoppen van de server", "Onbekende kolom '%-.64s' in %s", -"Opdracht gebruikt '%-.64s' dat niet in de group by voorkomt", +"Opdracht gebruikt '%-.64s' dat niet in de GROUP BY voorkomt", "Kan '%-.64s' niet groeperen", "Opdracht heeft totaliseer functies en kolommen in dezelfde opdracht", "Het aantal kolommen komt niet overeen met het aantal opgegeven waardes", "Naam voor herkenning '%-.64s' is te lang", "Dubbele kolom naam '%-.64s'", -"Dubbele sleutel naam '%-.64s'", -"Dubbele ingang '%-.64s' voor sleutel %d", +"Dubbele zoeksleutel naam '%-.64s'", +"Dubbele ingang '%-.64s' voor zoeksleutel %d", "Verkeerde kolom specificatie voor kolom '%-.64s'", "%s bij '%-.64s' in regel %d", "Query was leeg", "Niet unieke waarde tabel/alias: '%-.64s'", "Foutieve standaard waarde voor '%-.64s'", -"Meerdere primaire sleutels gedefinieerd", -"Teveel sleutels gedifinieerd. Maximaal zijn %d sleutels toegestaan", -"Teveel sleutel onderdelen gespecificeerd. Maximaal %d onderdelen toegestaan", -"Gespecificeerde sleutel was te lang. De maximale lengte is %d", -"Sleutel kolom '%-.64s' bestaat niet in tabel", -"Blob kolom '%-.64s' kan niet gebruikt worden bij key specificatie", +"Meerdere primaire zoeksleutels gedefinieerd", +"Teveel zoeksleutels gedefinieerd. Maximaal zijn %d zoeksleutels toegestaan", +"Teveel zoeksleutel onderdelen gespecificeerd. Maximaal %d onderdelen toegestaan", +"Gespecificeerde zoeksleutel was te lang. De maximale lengte is %d", +"Zoeksleutel kolom '%-.64s' bestaat niet in tabel", +"BLOB kolom '%-.64s' kan niet gebruikt worden bij zoeksleutel specificatie", "Te grote kolomlengte voor '%-.64s' (max = %d). Maak hiervoor gebruik van het type BLOB", -"Er kan slechts 1 autofield zijn en deze moet als sleutel worden gedefinieerd.", +"Er kan slechts 1 autofield zijn en deze moet als zoeksleutel worden gedefinieerd.", "%s: klaar voor verbindingen\n", "%s: Normaal afgesloten \n", "%s: Signaal %d. Systeem breekt af!\n", @@ -84,15 +90,15 @@ "%s: Afsluiten afgedwongen van thread %ld gebruiker: '%-.64s'\n", "Kan IP-socket niet openen", "Tabel '%-.64s' heeft geen INDEX zoals deze gemaakt worden met CREATE INDEX. Maak de tabel opnieuw", -"De argumenten om velden te scheiden zijn anders dan verwacht. Controleer de handleiding", +"De argumenten om velden te scheiden zijn anders dan verwacht. Raadpleeg de handleiding", "Bij het gebruik van BLOBs is het niet mogelijk om vaste rijlengte te gebruiken. Maak s.v.p. gebruik van 'fields terminated by'.", "Het bestand '%-.64s' dient in de database directory voor the komen of leesbaar voor iedereen te zijn.", "Het bestand '%-.64s' bestaat reeds", "Records: %ld Verwijderd: %ld Overgeslagen: %ld Waarschuwingen: %ld", "Records: %ld Dubbel: %ld", -"Foutief sub-gedeelte van de sleutel. De gebruikte sleutel is geen onderdeel van een string of of de gebruikte lengte is langer dan de sleutel", +"Foutief sub-gedeelte van de zoeksleutel. De gebruikte zoeksleutel is geen onderdeel van een string of of de gebruikte lengte is langer dan de zoeksleutel", "Het is niet mogelijk alle velden te verwijderen met ALTER TABLE. Gebruik a.u.b. DROP TABLE hiervoor!", -"Kan '%-.64s' niet weggooien. Controleer of het veld of de sleutel daadwerkelijk bestaat.", +"Kan '%-.64s' niet weggooien. Controleer of het veld of de zoeksleutel daadwerkelijk bestaat.", "Records: %ld Dubbel: %ld Waarschuwing: %ld", "INSERT TABLE '%-.64s' is niet toegestaan in de FROM tabel-lijst", "Onbekend thread id: %lu", @@ -101,7 +107,7 @@ "Teveel strings voor kolom %s en SET", "Het is niet mogelijk een unieke naam te maken voor de logfile %s.(1-999)\n", "Tabel '%-.64s' was gelocked met een lock om te lezen. Derhalve kunnen geen wijzigingen worden opgeslagen.", -"Table '%-.64s' was niet gelocked met LOCK TABLES", +"Tabel '%-.64s' was niet gelocked met LOCK TABLES", "Blob veld '%-.64s' can geen standaardwaarde bevatten", "Databasenaam '%-.64s' is niet getoegestaan", "Niet toegestane tabelnaam '%-.64s'", @@ -120,95 +126,93 @@ "Teveel tabellen. MySQL kan slechts %d tabellen in een join bevatten", "Te veel velden", "Rij-grootte is groter dan toegestaan. Maximale rij grootte, blobs niet meegeteld, is %d. U dient sommige velden in blobs te veranderen.", -"Thread stapel overrun: Gebruikte: %ld van een %ld stack. Gebruik 'mysqld -O thread_stack=#' om een grotere stapel te definieren (indien noodzakelijk).", -"Gekruiste afhankelijkheid gevonden in OUTER JOIN. Controleer uw ON-conditions", -"Column '%-.64s' is used with UNIQUE or INDEX but is not defined as NOT NULL", -"Can't load function '%-.64s'", -"Can't initialize function '%-.64s'; %-.80s", -"No paths allowed for shared library", -"Function '%-.64s' already exist", -"Can't open shared library '%-.64s' (errno: %d %s)", -"Can't find function '%-.64s' in library'", -"Function '%-.64s' is not defined", -"Host '%-.64s' is blocked because of many connection errors. Unblock with 'mysqladmin flush-hosts'", -"Host '%-.64s' is not allowed to connect to this MySQL server", -"You are using MySQL as an anonymous users and anonymous users are not allowed to change passwords", -"You must have privileges to update tables in the mysql database to be able to change passwords for others", -"Can't find any matching row in the user table", -"Rows matched: %ld Changed: %ld Warnings: %ld", -"Can't create a new thread (errno %d). If you are not out of available memory you can consult the manual for any possible OS dependent bug", -"Column count doesn't match value count at row %ld", -"Can't reopen table: '%-.64s', -"Invalid use of NULL value", -"Got error '%-.64s' from regexp", -"Mixing of GROUP columns (MIN(),MAX(),COUNT()...) with no GROUP columns is illegal if there is no GROUP BY clause", -"There is no such grant defined for user '%-.32s' on host '%-.64s'", -"%-.16s command denied to user: '%-.32s@%-.64s' for table '%-.64s'", -"%-.16s command denied to user: '%-.32s@%-.64s' for column '%-.64s' in table '%-.64s'", -"Illegal GRANT/REVOKE command. Please consult the manual which privleges can be used.", -"The host or user argument to GRANT is too long", -"Table '%-64s.%s' doesn't exist", -"There is no such grant defined for user '%-.32s' on host '%-.64s' on table '%-.64s'", -"The used command is not allowed with this MySQL version", -"Something is wrong in your syntax", -"Delayed insert thread couldn't get requested lock for table %-.64s", -"Too many delayed threads in use", -"Aborted connection %ld to db: '%-.64s' user: '%-.64s' (%s)", -"Got a packet bigger than 'max_allowed_packet'", -"Got a read error from the connection pipe", -"Got an error from fcntl()", -"Got packets out of order", -"Couldn't uncompress communication packet", -"Got an error reading communication packets" -"Got timeout reading communication packets", -"Got an error writing communication packets", -"Got timeout writing communication packets", -"Result string is longer than max_allowed_packet", -"The used table type doesn't support BLOB/TEXT columns", -"The used table type doesn't support AUTO_INCREMENT columns", -"INSERT DELAYED can't be used with table '%-.64s', because it is locked with LOCK TABLES", -"Incorrect column name '%-.100s'", -"The used table handler can't index column '%-.64s'", -"All tables in the MERGE table are not defined identically", -"Can't write, because of unique constraint, to table '%-.64s'", -"BLOB column '%-.64s' used in key specification without a key length", -"All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead", -"Result consisted of more than one row", -"This table type requires a primary key", -"This version of MySQL is not compiled with RAID support", -"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column", -"Key '%-.64s' doesn't exist in table '%-.64s'", -"Can't open table", -"The handler for the table doesn't support check/repair", -"You are not allowed to execute this command in a transaction", -"Got error %d during COMMIT", -"Got error %d during ROLLBACK", -"Got error %d during FLUSH_LOGS", -"Got error %d during CHECKPOINT", -"Aborted connection %ld to db: '%-.64s' user: '%-.32s' host: `%-.64s' (%-.64s)", -"The handler for the table does not support binary table dump", -"Binlog closed while trying to FLUSH MASTER", -"Failed rebuilding the index of dumped table '%-.64s'", -"Error from master: '%-.64s'", -"Net error reading from master", -"Net error writing to master", -"Can't find FULLTEXT index matching the column list", -"Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", -"Table '%-.64s' is marked as crashed and should be repaired", -"Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", -"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', -"This operation cannot be performed with a running slave, run SLAVE STOP first", -"This operation requires a running slave, configure slave and do SLAVE START", -"The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", -"Could not create slave thread, check system resources", -"User %-.64s has already more than 'max_user_connections' active connections", -"You may only use constant expressions with SET", -"Lock wait timeout exceeded", -"The total number of locks exceeds the lock table size", -"Update locks cannot be acquired during a READ UNCOMMITTED transaction", -"DROP DATABASE not allowed while thread is holding global read lock", -"CREATE DATABASE not allowed while thread is holding global read lock", -"Wrong arguments to %s", +"Thread stapel overrun: Gebruikte: %ld van een %ld stack. Gebruik 'mysqld -O thread_stack=#' om een grotere stapel te definieren (indien noodzakelijk).", +"Gekruiste afhankelijkheid gevonden in OUTER JOIN. Controleer uw ON-conditions", +"Kolom '%-.64s' wordt gebruikt met UNIQUE of INDEX maar is niet gedefinieerd als NOT NULL", +"Kan functie '%-.64s' niet laden", +"Kan functie '%-.64s' niet initialiseren; %-.80s", +"Geen pad toegestaan voor shared library", +"Functie '%-.64s' bestaat reeds", +"Kan shared library '%-.64s' niet openen (Errcode: %d %s)", +"Kan functie '%-.64s' niet in library vinden", +"Functie '%-.64s' is niet gedefinieerd", +"Host '%-.64s' is geblokkeeerd vanwege te veel verbindings fouten. Deblokkeer met 'mysqladmin flush-hosts'", +"Het is host '%-.64s' is niet toegestaan verbinding te maken met deze MySQL server", +"U gebruikt MySQL als anonieme gebruiker en deze mogen geen wachtwoorden wijzigen", +"U moet tabel update priveleges hebben in de mysql database om wachtwoorden voor anderen te mogen wijzigen", +"Kan geen enkele passende rij vinden in de gebruikers tabel", +"Passende rijen: %ld Gewijzigd: %ld Waarschuwingen: %ld", +"Kan geen nieuwe thread aanmaken (Errcode: %d). Indien er geen tekort aan geheugen is kunt u de handleiding consulteren over een mogelijke OS afhankelijke fout", +"Kolom aantal komt niet overeen met waarde aantal in rij %ld", +"Kan tabel niet opnieuw openen: '%-.64s', +"Foutief gebruik van de NULL waarde", +"Fout '%-.64s' ontvangen van regexp", +"Het mixen van GROUP kolommen (MIN(),MAX(),COUNT()...) met no-GROUP kolommen is foutief indien er geen GROUP BY clausule is", +"Deze toegang (GRANT) is niet toegekend voor gebruiker '%-.32s' op host '%-.64s'", +"%-.16s commando geweigerd voor gebruiker: '%-.32s@%-.64s' voor tabel '%-.64s'", +"%-.16s commando geweigerd voor gebruiker: '%-.32s@%-.64s' voor kolom '%-.64s' in tabel '%-.64s'", +"Foutief GRANT/REVOKE commando. Raadpleeg de handleiding welke priveleges gebruikt kunnen worden.", +"De host of gebruiker parameter voor GRANT is te lang", +"Tabel '%-64s.%s' bestaat niet", +"Deze toegang (GRANT) is niet toegekend voor gebruiker '%-.32s' op host '%-.64s' op tabel '%-.64s'", +"Het used commando is niet toegestaan in deze MySQL versie", +"Er is iets fout in de gebruikte syntax", +"'Delayed insert' thread kon de aangevraagde 'lock' niet krijgen voor tabel %-.64s", +"Te veel 'delayed' threads in gebruik", +"Afgebroken verbinding %ld naar db: '%-.64s' gebruiker: '%-.64s' (%s)", +"Groter pakket ontvangen dan 'max_allowed_packet'", +"Kreeg leesfout van de verbindings pipe", +"Kreeg fout van fcntl()", +"Pakketten in verkeerde volgorde ontvangen", +"Communicatiepakket kon niet worden gedecomprimeerd", +"Fout bij het lezen van communicatiepakketten" +"Timeout bij het lezen van communicatiepakketten", +"Resultaat string is langer dan max_allowed_packet", +"Het gebruikte tabel type ondersteunt geen BLOB/TEXT kolommen", +"Het gebruikte tabel type ondersteunt geen AUTO_INCREMENT kolommen", +"INSERT DELAYED kan niet worden gebruikt bij table '%-.64s', vanwege een 'lock met LOCK TABLES", +"Incorrecte kolom naam '%-.100s'", +"De gebruikte tabel 'handler' kan kolom '%-.64s' niet indexeren", +"Niet alle tabellen in de MERGE tabel hebben identieke gedefinities", +"Kan niet opslaan naar table '%-.64s' vanwege 'unique' beperking", +"BLOB kolom '%-.64s' gebruikt in zoeksleutel specificatie zonder zoeksleutel lengte", +"Alle delen van een PRIMARY KEY moeten NOT NULL zijn; Indien u NULL in een zoeksleutel nodig heeft kunt u UNIQUE gebruiken", +"Resultaat bevatte meer dan een rij", +"Dit tabel type heeft een primaire zoeksleutel nodig", +"Deze versie van MySQL is niet gecompileerd met RAID ondersteuning", +"U gebruikt 'safe update mode' en u probeerde een tabel te updaten zonder een WHERE met een KEY kolom", +"Zoeksleutel '%-.64s' bestaat niet in tabel '%-.64s'", +"Kan tabel niet openen", +"De 'handler' voor de tabel ondersteund geen check/repair", +"Het is u niet toegestaan dit commando uit te voeren binnen een transactie", +"Kreeg fout %d tijdens COMMIT", +"Kreeg fout %d tijdens ROLLBACK", +"Kreeg fout %d tijdens FLUSH_LOGS", +"Kreeg fout %d tijdens CHECKPOINT", +"Afgebroken verbinding %ld naar db: '%-.64s' gebruiker: '%-.32s' host: `%-.64s' (%-.64s)", +"De 'handler' voor de tabel ondersteund geen binaire tabel dump", +"Binlog gesloten tijdens FLUSH MASTER poging", +"Gefaald tijdens heropbouw index van gedumpte tabel '%-.64s'", +"Fout van master: '%-.64s'", +"Net fout tijdens lezen van master", +"Net fout tijdens schrijven naar master", +"Kan geen FULLTEXT index vinden passend bij de kolom lijst", +"Kan het gegeven commando niet uitvoeren, want u heeft actieve gelockte tabellen of een actieve transactie", +"Onbekende systeem variabele '%-.64'", +"Tabel '%-.64s' staat als gecrashed gemarkeerd en dient te worden gerepareerd", +"Tabel '%-.64s' staat als gecrashed gemarkeerd en de laatste (automatische?) reparatie poging mislukte", +"Waarschuwing: Roll back mislukt voor sommige buiten transacties gewijzigde tabellen", +"Multi-statement transactie vereist meer dan 'max_binlog_cache_size' bytes opslag. Verhoog deze mysqld variabele en probeer opnieuw', +"Deze operatie kan niet worden uitgevoerd met een actieve slave, doe eerst SLAVE STOP", +"Deze operatie vereist een actieve slave, configureer slave en doe dan SLAVE START", +"De server is niet geconfigureerd als slave, fix in configuratie bestand of met CHANGE MASTER TO", +"Kon master info structuur niet initialiseren, controleer permissies in master.info", +"Kon slave thread niet aanmaken, controleer systeem resources", +"Gebruiker %-.64s heeft reeds meer dan 'max_user_connections' actieve verbindingen", +"U mag alleen constante expressies gebruiken bij SET", +"Lock wacht tijd overschreden", +"Het totale aantal locks overschrijdt de lock tabel grootte", +"Update locks kunnen niet worden verkregen tijdens een READ UNCOMMITTED transactie", +"DROP DATABASE niet toegestaan terwijl thread een globale 'read lock' bezit", +"CREATE DATABASE niet toegestaan terwijl thread een globale 'read lock' bezit", +"Foutieve parameters voor %s" From 16108af1d31ba9901c71654699511ecf76bb67f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 13:47:27 +0300 Subject: [PATCH 08/18] Fixed bug in show variables, it didn't show whether slow-query was enabled or not. sql/mysqld.cc: Added notification to "show variables" whether slow-query-log is enabled or not. --- sql/mysqld.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2d7d53919a6..cb37c569d3e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2835,6 +2835,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}, From 0f670051e4c6a222cc1b5d5fec7c88d88147e170 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 12:51:16 +0200 Subject: [PATCH 09/18] manual.texi PASSWORD() issue clarified Docs/manual.texi: PASSWORD() issue clarified --- Docs/manual.texi | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 8bb22202055..c495e72a266 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -17406,10 +17406,13 @@ mysql> FLUSH PRIVILEGES; The result is that the plaintext value @code{'biscuit'} is stored as the password in the @code{user} table. When the user @code{jeffrey} attempts to connect to the server using this password, the @code{mysql} client encrypts -it with @code{PASSWORD()} and sends the result to the server. The server -compares the value in the @code{user} table (the encrypted value of -@code{'biscuit'}) to the encrypted password (which is @emph{not} -@code{'biscuit'}). The comparison fails and the server rejects the +it with @code{PASSWORD()}, generates an authentification vector +based on @strong{encrypted} password and a random number, +obtained from server, and sends the result to the server. +The server uses the @code{password} value in the @code{user} table +(that is @strong{not encrypted} value @code{'biscuit'}) +to perform the same calculations, and compares results. +The comparison fails and the server rejects the connection: @example From bffebc8e0be4772e7988b6b23570bd1197c7214a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 17:05:54 +0300 Subject: [PATCH 10/18] Fixed bug in ALTER TABLE for MERGE tables Portability fixes Fixed problem when giving wrong arguments to myisam_recover Fix to remove warnings when using purify BUILD/compile-solaris-sparc-purify: Added innodb and berkeleydb to test mysql-test/install_test_db.sh: Portability fix. sql/ha_myisam.cc: Fixed problem when giving wrong arguments to myisam_recover sql/ha_myisammrg.cc: Fixed bug in ALTER TABLE for MERGE tables sql/sql_list.h: Fix to remove warnings when using purify sql/sql_select.cc: Fix to remove warnings from purify BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BUILD/compile-solaris-sparc-purify | 4 ++- BitKeeper/etc/logging_ok | 1 + mysql-test/install_test_db.sh | 2 +- sql/ha_myisam.cc | 2 +- sql/ha_myisammrg.cc | 2 ++ sql/sql_list.h | 11 ++++++-- sql/sql_select.cc | 44 +++++++++++++++++------------- 7 files changed, 42 insertions(+), 24 deletions(-) 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 ce08f235c9d..d39597b1718 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -15,3 +15,4 @@ jcole@tetra.spaceapes.com davida@isil.mysql.com tonu@x153.internalnet tim@bitch.mysql.fi +monty@bitch.mysql.fi diff --git a/mysql-test/install_test_db.sh b/mysql-test/install_test_db.sh index 049ac6b1cd7..6fe736644d3 100644 --- a/mysql-test/install_test_db.sh +++ b/mysql-test/install_test_db.sh @@ -59,7 +59,7 @@ else basedir=. rm -rf share mkdir share -ln -sf ../../sql/share share/mysql +ln -f -s ../../sql/share share/mysql fi # Initialize variables diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 6409ec5d019..8be62920308 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -35,7 +35,7 @@ ulong myisam_recover_options= HA_RECOVER_NONE; /* bits in myisam_recover_options */ const char *myisam_recover_names[] = -{ "DEFAULT", "BACKUP", "FORCE", "QUICK"}; +{ "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS}; TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"", myisam_recover_names}; diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index b842c15cce0..866fd1e69f9 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/sql_list.h b/sql/sql_list.h index b86250f70b6..d21f2e658dc 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_select.cc b/sql/sql_select.cc index d23a7edd37e..14640e8387e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1368,24 +1368,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) { @@ -1394,18 +1397,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; } + } } } From aa3c4306754c3db0c2ea3a6db0cffcb6bc1ed0f7 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 17:37:37 +0300 Subject: [PATCH 11/18] Portability fixes Added record_rnd_buffer Added --safe-user-create Fix for ALTER TABLE RENAME on windows Docs/manual.texi: Changelog and documentation of new features. More information about using threaded client libraries include/mysql_com.h: Added prototype for my_thread_init() include/mysqld_error.h: New error for --safe-create-user innobase/buf/buf0flu.c: Portability fix innobase/include/univ.i: Portability fix mysql-test/t/distinct.test: Test for distinct bug sql/mysql_priv.h: Added record_rnd_buffer sql/mysqld.cc: Added record_rnd_buffer sql/records.cc: Added record_rnd_buffer sql/share/czech/errmsg.txt: New error message for --safe-user-create sql/share/danish/errmsg.txt: New error message for --safe-user-create sql/share/dutch/errmsg.txt: New error message for --safe-user-create sql/share/english/errmsg.txt: New error message for --safe-user-create sql/share/estonian/errmsg.txt: New error message for --safe-user-create sql/share/french/errmsg.txt: New error message for --safe-user-create sql/share/german/errmsg.txt: New error message for --safe-user-create sql/share/greek/errmsg.txt: New error message for --safe-user-create sql/share/hungarian/errmsg.txt: New error message for --safe-user-create sql/share/italian/errmsg.txt: New error message for --safe-user-create sql/share/japanese/errmsg.txt: New error message for --safe-user-create sql/share/korean/errmsg.txt: New error message for --safe-user-create sql/share/norwegian-ny/errmsg.txt: New error message for --safe-user-create sql/share/norwegian/errmsg.txt: New error message for --safe-user-create sql/share/polish/errmsg.txt: New error message for --safe-user-create sql/share/portuguese/errmsg.txt: New error message for --safe-user-create sql/share/romanian/errmsg.txt: New error message for --safe-user-create sql/share/russian/errmsg.txt: New error message for --safe-user-create sql/share/slovak/errmsg.txt: New error message for --safe-user-create sql/share/spanish/errmsg.txt: New error message for --safe-user-create sql/share/swedish/errmsg.txt: New error message for --safe-user-create sql/sql_acl.cc: Checking of privileges for --safe-user-create sql/sql_acl.h: --safe-user-create sql/sql_base.cc: --safe-user-create sql/sql_parse.cc: --safe-user-create sql/sql_show.cc: --safe-user-create sql/sql_table.cc: Fix for ALTER TABLE RENAME on windows --- Docs/manual.texi | 161 +++++++++++++++++++------- include/mysql_com.h | 8 +- include/mysqld_error.h | 3 +- innobase/buf/buf0flu.c | 1 + innobase/include/univ.i | 4 +- mysql-test/t/distinct.test | 9 ++ sql/mysql_priv.h | 7 +- sql/mysqld.cc | 30 ++++- sql/records.cc | 4 +- sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 181 +++++++++++++++--------------- sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/sql_acl.cc | 103 ++++++++++++----- sql/sql_acl.h | 2 +- sql/sql_base.cc | 2 +- sql/sql_parse.cc | 5 +- sql/sql_show.cc | 2 +- sql/sql_table.cc | 11 +- 36 files changed, 367 insertions(+), 186 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index 86a4b92f304..058e62e6234 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -14522,15 +14522,10 @@ Skip some optimize stages. Implies @code{--skip-delay-key-write}. @item --safe-show-database Don't show databases for which the user doesn't have any privileges. -@item --secure -IP numbers returned by the @code{gethostbyname()} system call are -checked to make sure they resolve back to the original hostname. This -makes it harder for someone on the outside to get access by pretending -to be another host. This option also adds some sanity checks of -hostnames. The option is turned off by default in @strong{MySQL} Version 3.21 -because sometimes it takes a long time to perform backward resolutions. -@strong{MySQL} Version 3.22 caches hostnames (unless @code{--skip-host-cache} -is used) and has this option enabled by default. +@item --safe-user-create +If this is enabled, a user can't create new users with the GRANT +command, if the user doesn't have @code{INSERT} privilege to the +@code{mysql.user} table or any column in this table. @item --skip-concurrent-insert Turn off the ability to select and insert at the same time on @code{MyISAM} @@ -15313,11 +15308,10 @@ by using @code{LOAD DATA} to load @file{/etc/passwd} into a table, which can then be read with @code{SELECT}. @item -If you don't trust your DNS, you should use IP numbers instead of hostnames -in the grant tables. In principle, the @code{--secure} option to -@code{mysqld} should make hostnames safe. In any case, you should be very -careful about creating grant table entries using hostname values that -contain wild cards! +If you don't trust your DNS, you should use IP numbers instead of +hostnames in the grant tables. In any case, you should be very careful +about creating grant table entries using hostname values that contain +wild cards! @item If you want to restrict the number of connections for a single user, you @@ -15325,21 +15319,31 @@ can do this by setting the @code{max_user_connections} variable in @code{mysqld}. @end itemize + @node Privileges options, What Privileges, Security, Privilege system @subsection Startup Options for @code{mysqld} Concerning Security -The following @code{mysqld} options affect networking security: +The following @code{mysqld} options affect security: @table @code -@item --secure -IP numbers returned by the @code{gethostbyname()} system call are -checked to make sure they resolve back to the original hostname. This -makes it harder for someone on the outside to get access by pretending -to be another host. This option also adds some sanity checks of -hostnames. The option is turned off by default in @strong{MySQL} Version -3.21 because sometimes it takes a long time to perform backward resolutions. -@strong{MySQL} Version 3.22 caches hostnames and has this option enabled by -default. +@item --safe-show-database +With this option, +@code{SHOW DATABASES} returns only those databases for which the user has +some kind of privilege. + +@item @code{--safe-user-create} +If this is enabled, an user can't create new users with the @code{GRANT} +command, if the user doesn't have @code{INSERT} privilege to the +@code{mysql.user} table. If you want to give a user access to just create +new users with those privileges that the user has right to grant, you should +give the user the following privilege: + +@example +GRANT INSERT(user) on mysql.user to 'user'@'hostname'; +@end example + +This will ensure that the user can't change any privilege columns directly, +but has to use the @code{GRANT} command to give privileges to other users. @item --skip-grant-tables This option causes the server not to use the privilege system at all. This @@ -15361,11 +15365,6 @@ support Unix sockets. With this option, the @code{SHOW DATABASES} statement doesn't return anything. -@item --safe-show-database -With this option, -@code{SHOW DATABASES} returns only those databases for which the user has -some kind of privilege. - @end table @@ -19812,6 +19811,11 @@ Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value. +@item @code{record_rnd_buffer} +When reading rows in sorted order after a sort, the rows are read through this +buffer to avoid a disk seeks. If not set, then it's set to the value of +@code{record_buffer}. + @item @code{query_buffer_size} The initial allocation of the query buffer. If most of your queries are long (like when inserting blobs), you should increase this! @@ -25946,6 +25950,7 @@ net_read_timeout current value: 30 net_write_timeout current value: 60 query_buffer_size current value: 0 record_buffer current value: 131072 +record_rnd_buffer current value: 131072 slow_launch_time current value: 2 sort_buffer current value: 2097116 table_cache current value: 64 @@ -26006,6 +26011,11 @@ shell> safe_mysqld -O key_buffer=512k -O sort_buffer=16k \ -O table_cache=32 -O record_buffer=8k -O net_buffer=1K & @end example +If you are doing a @code{GROUP BY} or @code{ORDER BY} on files that are +much bigger than your available memory you should increase the value of +@code{record_rnd_buffer} to speed up the reading of rows after the sorting +is done. + When you have installed @strong{MySQL}, the @file{support-files} directory will contain some different @code{my.cnf} example files, @file{my-huge.cnf}, @file{my-large.cnf}, @file{my-medium.cnf}, and @file{my-small.cnf}, you can @@ -26167,6 +26177,11 @@ common we may add general support for memory mapping. Each request doing a sequential scan over a table allocates a read buffer (variable @code{record_buffer}). +@item +When reading rows in 'random' order (for example after a sort) a +random-read buffer is allocated to avoid disk seeks. +(variable @code{record_rnd_buffer}). + @item All joins are done in one pass, and most joins can be done without even using a temporary table. Most temporary tables are memory-based (HEAP) @@ -27642,7 +27657,7 @@ significant decimal digits that will be stored for values, and @code{2} (@code{scale}) represents the number of digits that will be stored following the decimal point. In this case, therefore, the range of values that can be stored in the @code{salary} column is from -@code{-9999999.99} to @code{9999999.99}. In ANSI/ISO SQL92, the syntax +@code{-999999.99} to @code{9999999.99}. In ANSI/ISO SQL92, the syntax @code{DECIMAL(p)} is equivalent to @code{DECIMAL(p,0)}. Similarly, the syntax @code{DECIMAL} is equivalent to @code{DECIMAL(p,0)}, where the implementation is allowed to decide the value of @code{p}. @@ -29145,6 +29160,15 @@ mysql> select INTERVAL(22, 23, 30, 44, 200); Normally, if any expression in a string comparison is case sensitive, the comparison is performed in case-sensitive fashion. +If you are comparing case sensitive string with any of the standard +operators (@code{=}, @code{<>}..., but not @code{LIKE}) end space will +be ignored. + +@example +mysql> select "a" ="A "; + -> 1 +@end example + @table @code @findex LIKE @item expr LIKE pat [ESCAPE 'escape-char'] @@ -37893,12 +37917,16 @@ To make Access work: @itemize @bullet @item If you are using Access 2000, you should get and install the newest -Microsoft MDAC (@code{Microsoft Data Access Components}) from -@uref{http://www.microsoft.com/data}. This will fix the following bug -in Access: when you export data to @strong{MySQL}, the table and column -names aren't specified. Another way to around this bug is to upgrade to -MyODBC Version 2.50.33 and @strong{MySQL} Version 3.23.x, which together -provide a workaround for this bug! +(version 2.6 or above) Microsoft MDAC (@code{Microsoft Data Access +Components}) from @uref{http://www.microsoft.com/data}. This will fix +the following bug in Access: when you export data to @strong{MySQL}, the +table and column names aren't specified. Another way to around this bug +is to upgrade to MyODBC Version 2.50.33 and @strong{MySQL} Version +3.23.x, which together provide a workaround for this bug! + +You should also get and apply the Microsoft Jet 4.0 Service Pack 5 (SP5) +which can be found here +@uref{http://support.microsoft.com/support/kb/articles/Q 239/1/14.ASP}. Note that if you are using @strong{MySQL} Version 3.22, you must to apply the MDAC patch and use MyODBC 2.50.32 or 2.50.34 and above to go around @@ -40033,7 +40061,7 @@ other APIs. * C API function overview:: C API Function Overview * C API functions:: C API Function Descriptions * C API problems:: -* Thread-safe clients:: +* Thread-safe clients:: How to Make a Thread-safe Client @end menu The C API code is distributed with @strong{MySQL}. It is included in the @@ -42834,6 +42862,34 @@ If you program with POSIX threads, you can use establish and release a mutex lock. @end itemize +You need to know the following if you have a thread that is calling +MySQL functions, but that thread has not created the connection to the +MySQL database: + +When you call @code{mysql_init()} or @code{mysql_connect()}, MySQL will +create a thread specific variable for the thread that is used by the +debug library (among other things). + +If you have in a thread call a MySQL function, before a thread has +called @code{mysql_init()} or @code{mysql_connect()}, the thread will +not have the necessary thread specific variables in place and you are +likely to end up with a core dump sooner or later. + +The get things to work smoothly you have to do the following: + +@enumerate +@item +Call @code{my_init()} at the start of your program if it calls +any other MySQL function before calling @code{mysql_real_connect()}. +@item +Call @code{my_thread_init()} in the thread handler before calling +any MySQL function. +@item +In the thread, call @code{my_thread_end()} before calling +@code{pthread_exit()}. This will free the memory used by MySQL thread +specific variables. +@end enumerate + You may get some errors because of undefined symbols when linking your client with @code{mysqlclient_r}. In most cases this is because you haven't included the thread libraries on the link/compile line. @@ -45434,6 +45490,8 @@ Romanian error messages. Hungarian error messages. @item Roberto M. Serqueira Portugise error messages. +@item Carsten H. Pedersen +Danish error messages @item David Sacerdote @email{davids@@secnet.com} Ideas for secure checking of DNS hostnames. @item Wei-Jou Chen @email{jou@@nematic.ieo.nctu.edu.tw} @@ -45672,7 +45730,7 @@ users use this code as the rest of the code and because of this we are not yet 100% confident in this code. @menu -* News-3.23.41:: +* News-3.23.41:: Changes in release 3.23.41 * News-3.23.40:: Changes in release 3.23.40 * News-3.23.39:: Changes in release 3.23.39 * News-3.23.38:: Changes in release 3.23.38 @@ -45721,8 +45779,35 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.41 @itemize @bullet @item +InnoDB now supports < 4 GB rows. The former limit was 8000 bytes. +@item +The @code{doublewrite} file flush method is used in InnoDB. +It reduces the need for Unix fsync calls to a fraction and +improves performance on most Unix flavors. +@item +You can now use the InnoDB Monitor to print a lot of InnoDB state +information, including locks, to the standard output; useful in +performance tuning. +@item +Several bugs which could cause hangs in InnoDB have been fixed. +@item +Split @code{record_buffer} to @code{record_buffer} and +@code{record_rnd_buffer}. To make things compatible to previous MySQL +versions, if @code{record_rnd_buffer} is not set, then it takes the +value of @code{record_buffer}. +@item Fixed optimizing bug in @code{ORDER BY} where some @code{ORDER BY} parts where wrongly removed. +@item +Fixed overflow bug with @code{ALTER TABLE} and @code{MERGE} tables. +@item +Added prototypes for @code{my_thread_init()} and @code{my_thread_end()} to +@file{mysql_com.h} +@item +Added option @code{--safe-user-create} to @code{mysqld}. +@item +Added options to the @code{--ansi} startup options to let the user +decide which @code{ansi} options one to enable. @end itemize @node News-3.23.40, News-3.23.39, News-3.23.41, News-3.23.x diff --git a/include/mysql_com.h b/include/mysql_com.h index 5b22d58150d..82eb34060a9 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -218,17 +218,19 @@ my_bool check_scramble(const char *, const char *message, unsigned long *salt,my_bool old_ver); char *get_tty_password(char *opt_message); void hash_password(unsigned long *result, const char *password); -#ifdef __cplusplus -} -#endif /* Some other useful functions */ 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 +} +#endif + #define NULL_LENGTH ((unsigned long) ~0) /* For net_store_length */ #ifdef __WIN__ diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 32967931eac..758c74fc122 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -211,4 +211,5 @@ #define ER_DROP_DB_WITH_READ_LOCK 1208 #define ER_CREATE_DB_WITH_READ_LOCK 1209 #define ER_WRONG_ARGUMENTS 1210 -#define ER_ERROR_MESSAGES 211 +#define ER_NO_PERMISSON_TO_CREATE_USER 1211 +#define ER_ERROR_MESSAGES 212 diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index 0f27cee45a5..3abb3702191 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 -#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/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/sql/mysql_priv.h b/sql/mysql_priv.h index f21c635dbdf..e039cf1d925 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -251,6 +251,7 @@ void kill_mysql(void); void close_connection(NET *net,uint errcode=0,bool lock=1); bool check_access(THD *thd,uint access,const char *db=0,uint *save_priv=0, bool no_grant=0); +bool check_table_access(THD *thd,uint want_access,TABLE_LIST *tables); bool check_process_priv(THD *thd=0); int generate_table(THD *thd, TABLE_LIST *table_list, @@ -530,10 +531,10 @@ extern ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size, what_to_log,flush_time, max_tmp_tables,max_heap_table_size,query_buff_size, lower_case_table_names,thread_stack,thread_stack_min, - binlog_cache_size, max_binlog_cache_size; + binlog_cache_size, max_binlog_cache_size, record_rnd_cache_size; extern ulong specialflag, current_pid; -extern bool low_priority_updates, using_update_log; -extern bool opt_sql_bin_update, opt_safe_show_db, opt_warnings; +extern bool low_priority_updates, using_update_log,opt_warnings; +extern bool opt_sql_bin_update, opt_safe_show_db, opt_safe_user_create; extern char language[LIBLEN],reg_ext[FN_EXTLEN],blob_newline; extern const char **errmesg; /* Error messages */ extern const char *default_tx_isolation_name; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a9771184b4b..9e86207bf69 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -213,7 +213,8 @@ static bool opt_log,opt_update_log,opt_bin_log,opt_slow_log,opt_noacl, opt_disable_networking=0, opt_bootstrap=0,opt_skip_show_db=0, opt_ansi_mode=0,opt_myisam_log=0, opt_large_files=sizeof(my_off_t) > 4; -bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0; +bool opt_sql_bin_update = 0, opt_log_slave_updates = 0, opt_safe_show_db=0, + opt_safe_user_create=0; FILE *bootstrap_file=0; int segfaulted = 0; // ensure we do not enter SIGSEGV handler twice extern MASTER_INFO glob_mi; @@ -261,7 +262,7 @@ ulong keybuff_size,sortbuff_size,max_item_sort_length,table_cache_size, query_buff_size, lower_case_table_names, mysqld_net_retry_count, net_interactive_timeout, slow_launch_time = 2L, net_read_timeout,net_write_timeout,slave_open_temp_tables=0, - open_files_limit=0, max_binlog_size; + open_files_limit=0, max_binlog_size, record_rnd_cache_size; ulong slave_net_timeout; ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0; volatile ulong cached_thread_count=0; @@ -1481,9 +1482,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); } @@ -2471,7 +2476,8 @@ enum options { OPT_GEMINI_FLUSH_LOG, OPT_GEMINI_RECOVER, OPT_GEMINI_UNBUFFERED_IO, OPT_SKIP_SAFEMALLOC, OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS, - OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL + OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, + OPT_SAFE_USER_CREATE }; static struct option long_options[] = { @@ -2583,7 +2589,7 @@ static struct option long_options[] = { (int) OPT_REPLICATE_REWRITE_DB}, {"safe-mode", no_argument, 0, (int) OPT_SAFE}, {"safe-show-database", no_argument, 0, (int) OPT_SAFE_SHOW_DB}, - {"socket", required_argument, 0, (int) OPT_SOCKET}, + {"safe-user-create", no_argument, 0, (int) OPT_SAFE_USER_CREATE}, {"server-id", required_argument, 0, (int) OPT_SERVER_ID}, {"set-variable", required_argument, 0, 'O'}, {"skip-bdb", no_argument, 0, (int) OPT_BDB_SKIP}, @@ -2603,6 +2609,7 @@ static struct option long_options[] = { {"skip-stack-trace", no_argument, 0, (int) OPT_SKIP_STACK_TRACE}, {"skip-symlink", no_argument, 0, (int) OPT_SKIP_SYMLINKS}, {"skip-thread-priority", no_argument, 0, (int) OPT_SKIP_PRIOR}, + {"socket", required_argument, 0, (int) OPT_SOCKET}, {"sql-bin-update-same", no_argument, 0, (int) OPT_SQL_BIN_UPDATE_SAME}, #include "sslopt-longopts.h" #ifdef __WIN__ @@ -2741,6 +2748,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, @@ -2856,6 +2865,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}, @@ -3030,6 +3040,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\ @@ -3747,6 +3759,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; @@ -3770,6 +3785,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; } 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/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index a0540bfe270..f67496da923 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -221,3 +221,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 73fa8b79f0f..34c3d8ed95d 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -2,29 +2,29 @@ This file is public domain and comes with NO WARRANTY of any kind */ /* Knud Riishøjgård knudriis@post.tele.dk 99 && - Carsten H. Pedersen, carsten.pedersen@bitbybit.dk oct. 1999 */ + Carsten H. Pedersen, carsten.pedersen@bitbybit.dk oct. 1999 / aug. 2001. */ "hashchk", "isamchk", "NEJ", "JA", "Kan ikke oprette filen '%-.64s' (Fejlkode: %d)", -"Kan ikke opprette tabellen '%-.64s' (Fejlkode: %d)", +"Kan ikke oprette tabellen '%-.64s' (Fejlkode: %d)", "Kan ikke oprette databasen '%-.64s'. Fejl %d", "Kan ikke oprette databasen '%-.64s'. Databasen eksisterer", "Kan ikke slette (droppe) '%-.64s'. Databasen eksisterer ikke", "Fejl ved sletning (drop) af databasen (kan ikke slette '%-.64s', Fejl %d)", -"Fejl ved sletting af database (kan ikke slette biblioteket '%-.64s', Fejl %d)", +"Fejl ved sletting af database (kan ikke slette folderen '%-.64s', Fejl %d)", "Fejl ved sletning af '%-.64s' (Fejlkode: %d)", -"Kan ikke læse posten i systembiblioteket", +"Kan ikke læse posten i systemfolderen", "Kan ikke læse status af '%-.64s' (Fejlkode: %d)", -"Kan ikke læse aktive bibliotek (Fejlkode: %d)", +"Kan ikke læse aktive folder (Fejlkode: %d)", "Kan ikke låse fil (Fejlkode: %d)", "Kan ikke åbne fil: '%-.64s'. (Fejlkode: %d)", "Kan ikke finde fila: '%-.64s' (Fejlkode: %d)", -"Kan ikke læse bibliotek '%-.64s' (Fejlkode: %d)", -"Kan ikke skifte bibliotek til '%-.64s' (Fejlkode: %d)", -"Posten erændret siden sidst læst '%-.64s'", +"Kan ikke læse folder '%-.64s' (Fejlkode: %d)", +"Kan ikke skifte folder til '%-.64s' (Fejlkode: %d)", +"Posten er ændret siden sidste læsning '%-.64s'", "Ikke mere diskplads (%s). Venter på at få frigjort plads....", "Kan ikke skrive, flere ens nøgler i tabellen '%-.64s'", "Fejl ved lukning af '%-.64s' (Fejlkode: %d)", @@ -32,10 +32,10 @@ "Fejl ved omdøbning af '%-.64s' til '%-.64s' (Fejlkode: %d)", "Fejl ved skriving av filen '%-.64s' (Fejlkode: %d)", "'%-.64s' er låst mod opdateringer", -"Sortering afbrutt", +"Sortering afbrudt", "View '%-.64s' eksisterer ikke for '%-.64s'", -"Modtog fejl %d fra tabel håndterer", -"Tabel håndtereren for '%-.64s' har ikke denne mulighed", +"Modtog fejl %d fra tabel håndteringen", +"Denne mulighed eksisterer ikke for tabeltypen '%-.64s'", "Kan ikke finde posten i '%-.64s'", "Forkert indhold i: '%-.64s'", "Fejl i indeksfilen til tabellen '%-.64s', prøv at reparere den", @@ -43,95 +43,95 @@ "'%-.64s' er skrivebeskyttet", "Ikke mere hukommelse. Genstart serveren og prøv igen (mangler %d bytes)", "Ikke mere sorteringshukommelse. Øg sorteringshukommelse (sort buffer size) for serveren", -"Uventet sluttning af fil (eof) ved læsning af filen '%-.64s' (Fejlkode: %d)", -"For mange tilkoblinger (connections)", +"Uventet afslutning på fil (eof) ved læsning af filen '%-.64s' (Fejlkode: %d)", +"For mange forbindelser (connections)", "Udgået for tråde/hukommelse", "Kan ikke få værtsnavn for din adresse", "Forkert håndtryk (handshake)", "Adgang nægtet bruger: '%-.32s@%-.64s' til databasen '%-.64s'", -"Adgang nægtet bruger: '%-.32s@%-.64s' (Bruger password: %s)", +"Adgang nægtet bruger: '%-.32s@%-.64s' (Bruger adgangskode: %s)", "Ingen database valgt", "Ukendt kommando", -"Kolonne '%-.64s' kan ikke være nul", +"Kolonne '%-.64s' kan ikke være NULL", "Ukendt database '%-.64s'", -"Tabellen '%-.64s' eksisterer allerede", +"Tabellen '%-.64s' findes allerede", "Ukendt tabel '%-.64s'", "Felt: '%-.64s' i tabel %s er ikke entydigt", -"Database nedkobling er i gang", +"Database nedlukning er i gang", "Ukendt kolonne '%-.64s' i tabel %s", -"Grugte '%-.64s' som ikke var i group by", +"Brugte '%-.64s' som ikke var i group by", "Kan ikke gruppere på '%-.64s'", "Udtrykket har summer (sum) funktioner og kolonner i samme udtryk", -"Kolonne tæller stemmer ikke med værditæller", -"Identifikationen '%-.64s' er for lang", -"Feltnavnet '%-.64s' eksisterer allerede", -"Indeksnavnet '%-.64s' eksisterer allerede", +"Kolonne tæller stemmer ikke med antallet af værdier", +"Navnet '%-.64s' er for langt", +"Feltnavnet '%-.64s' findes allerede", +"Indeksnavnet '%-.64s' findes allerede", "Ens værdier '%-.64s' for indeks %d", "Forkert kolonnespecifikaton for felt '%-.64s'", "%s nær '%-.64s' på linje %d", "Forespørgsel var tom", -"Ikke unikt tabel/alias: '%-.64s'", +"Tabellen/aliaset: '%-.64s' er ikke unikt", "Ugyldig standardværdi for '%-.64s'", -"Flere primærindekser specificeret", -"For mange indekser specificeret. Maks %d indekser tillatt", -"For mange indeksdele specificeret. Maks %d dele tillatt", -"Specificeret indeks var for langt. Maks indekslængde er %d", -"Indeks felt '%-.64s' eksiterer ikke i tabellen", -"Blob felt '%-.64s' kan ikke bruges ved specifikation af indeks", +"Flere primærnøgler specificeret", +"For mange nøgler specificeret. Kun %d nøgler må bruges", +"For mange nøgledele specificeret. Kun %d dele må bruges", +"Specificeret nøgle var for lang. Maksimal nøglelængde er %d", +"Nøglefeltet '%-.64s' eksisterer ikke i tabellen", +"BLOB feltet '%-.64s' kan ikke bruges ved specifikation af indeks", "For stor feltlængde for kolonne '%-.64s' (maks = %d). Brug BLOB i stedet", -"Der kan kun bruges eet AUTO-felt og det skal være indekseret", -"%s: klar for tilslutninger\n", +"Der kan kun specificeres eet AUTO_INCREMENT-felt, og det skal være indekseret", +"%s: klar til tilslutninger\n", "%s: Normal nedlukning\n", -"%s: Opdaget signal %d. Afslutter!!\n", +"%s: Fangede signal %d. Afslutter!!\n", "%s: Server lukket\n", "%s: Forceret nedlukning af tråd: %ld bruger: '%-.64s'\n", "Kan ikke oprette IP socket", -"Tabellen '%-.64s' har intet indeks som det der er brugt i CREATE INDEX. Genopret tabellen", +"Tabellen '%-.64s' har ikke den nøgle, som blev brugt i CREATE INDEX. Genopret tabellen", "Felt adskiller er ikke som forventet, se dokumentationen", "Man kan ikke bruge faste feltlængder med BLOB. Brug i stedet 'fields terminated by'.", -"Filen '%-.64s' skal være i database-biblioteket for at kunne læses af alle", +"Filen '%-.64s' skal være i database-folderen og kunne læses af alle", "Filen '%-.64s' eksisterer allerede", "Poster: %ld Fjernet: %ld Sprunget over: %ld Advarsler: %ld", "Poster: %ld Ens: %ld", -"Forkert indeksdel. Den anvendte indeksdel er ikke en streng eller den længden er større end indekslængden", +"Forkert indeksdel. Den anvendte nøgledel er ikke en streng eller længden er større end nøglelængden", "Man kan ikke slette alle felter med ALTER TABLE. Brug DROP TABLE i stedet.", -"Kan ikke DROP '%-.64s'. Undersøg om felt/indeks eksisterer.", +"Kan ikke udføre DROP '%-.64s'. Undersøg om feltet/nøglen eksisterer.", "Poster: %ld Ens: %ld Advarsler: %ld", "INSERT TABLE '%-.64s' er ikke tilladt i FROM tabel liste", "Ukendt tråd id: %lu", -"Du er ikke ejer av tråden %lu", +"Du er ikke ejer af tråden %lu", "Ingen tabeller i brug", -"For mange tekststrenge kolonne %s og SET", -"Kan ikke lave unikt loggfilnavn %s.(1-999)\n", +"For mange tekststrenge til specifikationen af SET i kolonne %-.64s", +"Kan ikke lave unikt log-filnavn %s.(1-999)\n", "Tabellen '%-.64s' var låst med READ lås og kan ikke opdateres", "Tabellen '%-.64s' var ikke låst med LOCK TABLES", -"Blob feltet '%-.64s' kan ikke have en standard værdi", +"BLOB feltet '%-.64s' kan ikke have en standard værdi", "Ugyldigt database navn '%-.64s'", "Ugyldigt tabel navn '%-.64s'", -"SELECT ville undersøge for mange poster og ville sannsynligvis tage meget lang tid. Undersøg WHERE delen og brug SET OPTION SQL_BIG_SELECTS=1 hvis SELECTen er korrekt" +"SELECT ville undersøge for mange poster og ville sandsynligvis tage meget lang tid. Undersøg WHERE delen og brug SET OPTION SQL_BIG_SELECTS=1 hvis udtrykket er korrekt" "Ukendt fejl", "Ukendt procedure %s", "Forkert antal parametre til proceduren %s", "Forkert(e) parametre til proceduren %s", "Ukendt tabel '%-.64s' i %s", -"Feltet '%-.64s' er anvendt to ganger", -"Forkert brug af gruppe-funktion", -"Tabellen '%-.64s' bruger et efternavn som ikke findes i denne MySQL version", +"Feltet '%-.64s' er anvendt to gange", +"Forkert brug af grupperings-funktion", +"Tabellen '%-.64s' bruger et filtypenavn som ikke findes i denne MySQL version", "En tabel skal have mindst een kolonne", "Tabellen '%-.64s' er fuld", -"Ukendt karaktersæt: '%-.64s'", +"Ukendt tegnsæt: '%-.64s'", "For mange tabeller. MySQL kan kun bruge %d tabeller i et join", "For mange felter", -"For store poster. Max post størrelse, unde BOLB's, er %d. Du må lave nogle felter til BLOB's", +"For store poster. Max post størrelse, uden BLOB's, er %d. Du må lave nogle felter til BLOB's", "Thread stack brugt: Brugt: %ld af en %ld stak. Brug 'mysqld -O thread_stack=#' for at allokere en større stak om nødvendigt", "Krydsreferencer fundet i OUTER JOIN. Check dine ON conditions", "Kolonne '%-.32s' bruges som UNIQUE eller INDEX men er ikke defineret som NOT NULL", "Kan ikke læse funktionen '%-.64s'", "Kan ikke starte funktionen '%-.64s'; %-.80s", -"Ingen sti tilladte for delt bibliotek", +"Angivelse af sti ikke tilladt for delt bibliotek", "Funktionen '%-.64s' findes allerede", "Kan ikke åbne delt bibliotek '%-.64s' (errno: %d %s)", -"Kan ikke finde funktionen '%-.64s' in bibliotek'", +"Kan ikke finde funktionen '%-.64s' i bibliotek'", "Funktionen '%-.64s' er ikke defineret", "Værten er blokeret på grund af mange fejlforespørgsler. Lås op med 'mysqladmin flush-hosts'", "Værten '%-.64s' kan ikke tilkoble denne MySQL-server", @@ -139,7 +139,7 @@ "Du skal have tilladelse til at opdatere tabeller i MySQL databasen for at ændre andres adgangskoder", "Kan ikke finde nogen tilsvarende poster i bruger tabellen", "Poster fundet: %ld Ændret: %ld Advarsler: %ld", -"Kan ikke danne en ny tråd (thread) (errno %d). Hvis computeren ikke er løbet tør for hukommelse, kan du se i brugervejledningen for en mulig operativ-system - afhængig fejl", +"Kan ikke danne en ny tråd (fejl nr. %d). Hvis computeren ikke er løbet tør for hukommelse, kan du se i brugervejledningen for en mulig operativ-system - afhængig fejl", "Kolonne antallet stemmer ikke overens med antallet af værdier i post %ld", "Kan ikke genåbne tabel '%-.64s', "Forkert brug af nulværdi (NULL)", @@ -171,47 +171,48 @@ "Denne tabeltype understøtter ikke brug af AUTO_INCREMENT kolonner", "INSERT DELAYED kan ikke bruges med tabellen '%-.64s', fordi tabellen er låst med LOCK TABLES", "Forkert kolonnenavn '%-.100s'", -"Den brugte tabel styrer kan ikke indeksere kolonnen '%-.64s'", +"Den brugte tabeltype kan ikke indeksere kolonnen '%-.64s'", "Tabellerne i MERGE er ikke defineret ens", "Kan ikke skrive til tabellen '%-.64s' fordi det vil bryde CONSTRAINT regler", -"BLOB column '%-.64s' used in key specification without a key length", -"All parts of a PRIMARY KEY must be NOT NULL; If you need NULL in a key, use UNIQUE instead", -"Result consisted of more than one row", -"This table type requires a primary key", -"This version of MySQL is not compiled with RAID support", -"You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column", -"Key '%-.64s' doesn't exist in table '%-.64s'", -"Can't open table", -"The handler for the table doesn't support check/repair", -"You are not allowed to execute this command in a transaction", -"Got error %d during COMMIT", -"Got error %d during ROLLBACK", -"Got error %d during FLUSH_LOGS", -"Got error %d during CHECKPOINT", -"Aborted connection %ld to db: '%-.64s' user: '%-.32s' host: `%-.64s' (%-.64s)", -"The handler for the table does not support binary table dump", -"Binlog closed while trying to FLUSH MASTER", -"Failed rebuilding the index of dumped table '%-.64s'", -"Error from master: '%-.64s'", -"Net error reading from master", -"Net error writing to master", -"Can't find FULLTEXT index matching the column list", -"Can't execute the given command because you have active locked tables or an active transaction", -"Unknown system variable '%-.64'", -"Table '%-.64s' is marked as crashed and should be repaired", -"Table '%-.64s' is marked as crashed and last (automatic?) repair failed", -"Warning: Some non-transactional changed tables couldn't be rolled back", -"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage. Increase this mysqld variable and try again', -"This operation cannot be performed with a running slave, run SLAVE STOP first", -"This operation requires a running slave, configure slave and do SLAVE START", -"The server is not configured as slave, fix in config file or with CHANGE MASTER TO", -"Could not initialize master info structure, check permisions on master.info", -"Could not create slave thread, check system resources", -"User %-.64s has already more than 'max_user_connections' active connections", -"You may only use constant expressions with SET", -"Lock wait timeout exceeded", -"The total number of locks exceeds the lock table size", -"Update locks cannot be acquired during a READ UNCOMMITTED transaction", -"DROP DATABASE not allowed while thread is holding global read lock", -"CREATE DATABASE not allowed while thread is holding global read lock", +"BLOB kolonnen '%-.64s' brugt i nøglespecifikation uden nøglelængde", +"Alle dele af en PRIMARY KEY skal være NOT NULL; Hvis du skal bruge NULL i nøglen, brug UNIQUE istedet", +"Resultatet bestod af mere end een række", +"Denne tabeltype kræver en primærnøgle", +"Denne udgave af MySQL er ikke oversat med understøttelse af RAID", +"Du bruger sikker opdaterings modus ('safe update mode') og du forsøgte at opdatere en tabel uden en WHERE klausul, der gør brug af et KEY felt", +"Nøglen '%-.64s' eksisterer ikke i tabellen '%-.64s'", +"Kan ikke åbne tabellen", +"Denne tabeltype understøtter ikke CHECK/REPAIR", +"Du må ikke bruge denne kommando i en transaktion", +"Modtog fejl %d mens kommandoen COMMIT blev udført", +"Modtog fejl %d mens kommandoen ROLLBACK blev udført", +"Modtog fejl %d mens kommandoen FLUSH_LOGS blev udført", +"Modtog fejl %d mens kommandoen CHECKPOINT blev udført", +"Afbrød forbindelsen %ld til databasen '%-.64s' bruger: '%-.32s' vært: `%-.64s' (%-.64s)", +"Denne tabeltype unserstøtter ikke binært tabeldump", +"Binlog blev lukket mens kommandoen FLUSH MASTER blev udført", +"Kunne ikke genopbygge indekset for den dumpede tabel '%-.64s'", +"Fejl fra master: '%-.64s'", +"Netværksfejl ved læsning fra master", +"Netværksfejl ved skrivning til master", +"Kan ikke finde en FULLTEXT nøgle som svarer til kolonne listen", +"Kan ikke udføre den givne kommando fordi der findes aktive, låste tabeller eller fordi der udføres en transaktion", +"Ukendt systemvariabel '%-.64'", +"Tabellen '%-.64s' er markeret med fejl og bør repareres", +"Tabellen '%-.64s' er markeret med fejl og sidste (automatiske?) REPAIR fejlede", +"Advarsel: Visse data i tabeller der ikke understøtter transaktioner kunne ikke tilbagestilles", +"Fler-udtryks transaktion krævede mere plads en 'max_binlog_cache_size' bytes. Forhøj værdien af denne variabel og prøv igen', +"Denne handling kunne ikke udføres med kørende slave, brug først kommandoen SLAVE STOP", +"Denne handling kræver en kørende slave. Konfigurer en slave og brug kommandoen SLAVE START", +"Denne server er ikke konfigureret som slave. Ret in config-filen eller brug kommandoen CHANGE MASTER TO", +"Kunne ikke initialisere master info-struktur. Check om rettigheder i master.info", +"Kunne ikke danne en slave-tråd. Check systemressourcerne", +"Brugeren %-.64s har allerede mere end 'max_user_connections' aktive forbindelser", +"Du må kun bruge konstantudtryk med SET", +"Lock wait timeout overskredet", +"Det totale antal låse overstiger størrelsen på låse-tabellen", +"Update lås kan ikke opnås under en READ UNCOMMITTED transaktion", +"DROP DATABASE er ikke tilladt mens en tråd holder på globalt read lock", +"CREATE DATABASE er ikke tilladt mens en tråd holder på globalt read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index df3d35600ba..4eb31cb1d45 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -212,3 +212,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index f6ab398e92f..80b99c58940 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -212,3 +212,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 8686b7e17a4..816997f5266 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -216,3 +216,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index fb181535764..98902e847b9 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -212,3 +212,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index eabbff043f3..1d9e770ea8d 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -215,3 +215,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 2dcbad5ffba..f879c281422 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -212,3 +212,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index edeaec62590..303032d73b2 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -214,3 +214,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 434fb2fc7a0..c927eceb163 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -212,3 +212,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 306fe22ab1d..a177fcf81a8 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -214,3 +214,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 89e3abd9680..5c12cbf7d42 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -212,3 +212,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index dd9b153acff..05562e675bb 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -214,3 +214,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 87c25bd933f..8d973a57137 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -214,3 +214,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 2bb0dbb9802..705eb7f86ef 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -216,3 +216,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index a8a7b0a565f..ae36c738606 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -212,3 +212,4 @@ "DROP DATABASE não permitido enquanto uma 'thread' está assegurando um travamento global de leitura", "CREATE DATABASE não permitido enquanto uma 'thread' está assegurando um travamento global de leitura", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 9a964780398..2364bbb6d7d 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -216,3 +216,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 6d4fd4bcea6..0d778d67f11 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -215,3 +215,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index de12b57638f..e990e00722b 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -220,3 +220,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 3bb80df41a9..35788a72935 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -213,3 +213,4 @@ "DROP DATABASE no permitido mientras un thread está ejerciendo un bloqueo de lectura global", "CREATE DATABASE no permitido mientras un thread está ejerciendo un bloqueo de lectura global", "Wrong arguments to %s", +"%-.32s@%-.64s is not allowed to create new users", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 0451e4fe6eb..79380cbc501 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -212,3 +212,4 @@ "DROP DATABASE not allowed while thread is holding global read lock", "CREATE DATABASE not allowed while thread is holding global read lock", "Felaktiga argument till %s", +"%-.32s@%-.64s is not allowed to create new users", 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 &list, uint rights, List_iterator 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 &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 &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_base.cc b/sql/sql_base.cc index fd7945cb5bf..a38829f3605 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -133,7 +133,7 @@ int list_open_tables(THD *thd,List *tables, const char *db, table_list.db= (char*) db; table_list.real_name= entry->real_name;/*real 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; } /* need to check if he have't already listed it */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 87fbed47ef1..030d4743105 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -36,7 +36,6 @@ extern "C" int gethostname(char *name, int namelen); static int check_for_max_user_connections(const char *user, int u_length, const char *host); static void decrease_user_connections(const char *user, const char *host); -static bool check_table_access(THD *thd,uint want_access, TABLE_LIST *tables); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); static bool check_dup(THD *thd,const char *db,const char *name, @@ -1956,7 +1955,7 @@ mysql_execute_command(void) else res = mysql_grant(thd, 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()) @@ -2116,7 +2115,7 @@ bool check_process_priv(THD *thd) ** in the table list for GRANT checking */ -static bool +bool check_table_access(THD *thd,uint want_access,TABLE_LIST *tables) { uint found=0,found_access=0; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 637ab4fe7e9..71ee60e1eca 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -220,7 +220,7 @@ mysql_find_files(THD *thd,List *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 207f9dd324d..44372ad4800 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -59,9 +59,9 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) VOID(pthread_mutex_lock(&LOCK_open)); pthread_mutex_unlock(&thd->mysys_var->mutex); - if(global_read_lock) + if (global_read_lock) { - if(thd->global_read_lock) + if (thd->global_read_lock) { my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0), tables->real_name); @@ -1126,7 +1126,12 @@ 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); #ifdef FN_LOWER_CASE - if (!my_strcasecmp(new_name_buff,table_name))// Check if name changed + 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(new_name_buff,table_name)) // Check if name changed #endif From 1ddd584a23bac9ab78933113f16eb8bf4dc589e0 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 19:02:23 +0300 Subject: [PATCH 12/18] Allow myisam-recover="" and --sql-mode="" Docs/manual.texi: Changelog mysql-test/r/distinct.result: new test case mysql-test/r/innodb.result: Fixed result --- Docs/manual.texi | 185 ++++++++++++++++++++++++++--------- mysql-test/r/distinct.result | 6 ++ mysql-test/r/innodb.result | 2 +- sql/mysqld.cc | 14 +-- 4 files changed, 154 insertions(+), 53 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index c495e72a266..f9e492ca910 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -3668,8 +3668,8 @@ extra conditions in this case. @cindex running, ANSI mode @cindex ANSI mode, running -If you start @code{mysqld} with the @code{--ansi} option, the following behavior -of @strong{MySQL} changes: +If you start @code{mysqld} with the @code{--ansi} option, the following +behavior of @strong{MySQL} changes: @itemize @bullet @item @@ -3688,6 +3688,7 @@ The default transaction isolation level is @code{SERIALIZABLE}. @xref{SET TRANSACTION}. @end itemize +This is the same as using @code{--sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,SERIALIZE,ONLY_FULL_GROUP_BY}. @node Missing functions, Standards, ANSI mode, Compatibility @subsection Functionality Missing from MySQL @@ -14619,12 +14620,15 @@ system supports the @code{mlockall()} system call (like Solaris). This may help if you have a problem where the operating system is causing @code{mysqld} to swap on disk. -@item --myisam-recover [=option[,option...]]] where option is one of DEFAULT, BACKUP, FORCE or QUICK. -If this option is used, @code{mysqld} will on open check if the table is -marked as crashed or if if the table wasn't closed properly. (The last -option only works if you are running with @code{--skip-locking}). If this -is the case @code{mysqld} will run check on the table. If the table was corrupted, -@code{mysqld} will attempt to repair it. +@item --myisam-recover [=option[,option...]]] where option is any combination +of @code{DEFAULT}, @code{BACKUP}, @code{FORCE} or @code{QUICK}. You can +also set this explicitely to @code{""} if you want to disable this +option. If this option is used, @code{mysqld} will on open check if the +table is marked as crashed or if if the table wasn't closed properly. +(The last option only works if you are running with +@code{--skip-locking}). If this is the case @code{mysqld} will run +check on the table. If the table was corrupted, @code{mysqld} will +attempt to repair it. The following options affects how the repair works. @@ -14672,15 +14676,10 @@ Skip some optimize stages. Implies @code{--skip-delay-key-write}. @item --safe-show-database Don't show databases for which the user doesn't have any privileges. -@item --secure -IP numbers returned by the @code{gethostbyname()} system call are -checked to make sure they resolve back to the original hostname. This -makes it harder for someone on the outside to get access by pretending -to be another host. This option also adds some sanity checks of -hostnames. The option is turned off by default in @strong{MySQL} Version 3.21 -because sometimes it takes a long time to perform backward resolutions. -@strong{MySQL} Version 3.22 caches hostnames (unless @code{--skip-host-cache} -is used) and has this option enabled by default. +@item --safe-user-create +If this is enabled, a user can't create new users with the GRANT +command, if the user doesn't have @code{INSERT} privilege to the +@code{mysql.user} table or any column in this table. @item --skip-concurrent-insert Turn off the ability to select and insert at the same time on @code{MyISAM} @@ -14746,8 +14745,10 @@ Socket file to use for local connections instead of default @code{/tmp/mysql.sock}. @item --sql-mode=option[,option[,option...]] -Option can be one of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, -IGNORE_SPACE, SERIALIZE, ONLY_FULL_GROUP_BY. +Option can be any combination of: @code{REAL_AS_FLOAT}, +@code{PIPES_AS_CONCAT}, @code{ANSI_QUOTES}, @code{IGNORE_SPACE}, +@code{SERIALIZE}, @code{ONLY_FULL_GROUP_BY}. It can also be empty +(@code{""}) if you want to reset this. By specifying all of the above options is same as using --ansi. With this option one can turn on only needed SQL modes. @xref{ANSI mode}. @@ -15471,11 +15472,10 @@ by using @code{LOAD DATA} to load @file{/etc/passwd} into a table, which can then be read with @code{SELECT}. @item -If you don't trust your DNS, you should use IP numbers instead of hostnames -in the grant tables. In principle, the @code{--secure} option to -@code{mysqld} should make hostnames safe. In any case, you should be very -careful about creating grant table entries using hostname values that -contain wild cards! +If you don't trust your DNS, you should use IP numbers instead of +hostnames in the grant tables. In any case, you should be very careful +about creating grant table entries using hostname values that contain +wild cards! @item If you want to restrict the number of connections for a single user, you @@ -15484,21 +15484,31 @@ can do this by setting the @code{max_user_connections} variable in @end itemize + @node Privileges options, What Privileges, Security, Privilege system @subsection Startup Options for @code{mysqld} Concerning Security -The following @code{mysqld} options affect networking security: +The following @code{mysqld} options affect security: @table @code -@item --secure -IP numbers returned by the @code{gethostbyname()} system call are -checked to make sure they resolve back to the original hostname. This -makes it harder for someone on the outside to get access by pretending -to be another host. This option also adds some sanity checks of -hostnames. The option is turned off by default in @strong{MySQL} Version -3.21 because sometimes it takes a long time to perform backward resolutions. -@strong{MySQL} Version 3.22 caches hostnames and has this option enabled by -default. +@item --safe-show-database +With this option, +@code{SHOW DATABASES} returns only those databases for which the user has +some kind of privilege. + +@item @code{--safe-user-create} +If this is enabled, an user can't create new users with the @code{GRANT} +command, if the user doesn't have @code{INSERT} privilege to the +@code{mysql.user} table. If you want to give a user access to just create +new users with those privileges that the user has right to grant, you should +give the user the following privilege: + +@example +GRANT INSERT(user) on mysql.user to 'user'@'hostname'; +@end example + +This will ensure that the user can't change any privilege columns directly, +but has to use the @code{GRANT} command to give privileges to other users. @item --skip-grant-tables This option causes the server not to use the privilege system at all. This @@ -15520,11 +15530,6 @@ support Unix sockets. With this option, the @code{SHOW DATABASES} statement doesn't return anything. -@item --safe-show-database -With this option, -@code{SHOW DATABASES} returns only those databases for which the user has -some kind of privilege. - @end table @@ -19979,6 +19984,11 @@ Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value. +@item @code{record_rnd_buffer} +When reading rows in sorted order after a sort, the rows are read through this +buffer to avoid a disk seeks. If not set, then it's set to the value of +@code{record_buffer}. + @item @code{query_buffer_size} The initial allocation of the query buffer. If most of your queries are long (like when inserting blobs), you should increase this! @@ -26246,6 +26256,7 @@ net_read_timeout current value: 30 net_write_timeout current value: 60 query_buffer_size current value: 0 record_buffer current value: 131072 +record_rnd_buffer current value: 131072 slow_launch_time current value: 2 sort_buffer current value: 2097116 table_cache current value: 64 @@ -26306,6 +26317,11 @@ shell> safe_mysqld -O key_buffer=512k -O sort_buffer=16k \ -O table_cache=32 -O record_buffer=8k -O net_buffer=1K & @end example +If you are doing a @code{GROUP BY} or @code{ORDER BY} on files that are +much bigger than your available memory you should increase the value of +@code{record_rnd_buffer} to speed up the reading of rows after the sorting +is done. + When you have installed @strong{MySQL}, the @file{support-files} directory will contain some different @code{my.cnf} example files, @file{my-huge.cnf}, @file{my-large.cnf}, @file{my-medium.cnf}, and @file{my-small.cnf}, you can @@ -26467,6 +26483,11 @@ common we may add general support for memory mapping. Each request doing a sequential scan over a table allocates a read buffer (variable @code{record_buffer}). +@item +When reading rows in 'random' order (for example after a sort) a +random-read buffer is allocated to avoid disk seeks. +(variable @code{record_rnd_buffer}). + @item All joins are done in one pass, and most joins can be done without even using a temporary table. Most temporary tables are memory-based (HEAP) @@ -28000,7 +28021,7 @@ significant decimal digits that will be stored for values, and @code{2} (@code{scale}) represents the number of digits that will be stored following the decimal point. In this case, therefore, the range of values that can be stored in the @code{salary} column is from -@code{-9999999.99} to @code{9999999.99}. In ANSI/ISO SQL92, the syntax +@code{-999999.99} to @code{9999999.99}. In ANSI/ISO SQL92, the syntax @code{DECIMAL(p)} is equivalent to @code{DECIMAL(p,0)}. Similarly, the syntax @code{DECIMAL} is equivalent to @code{DECIMAL(p,0)}, where the implementation is allowed to decide the value of @code{p}. @@ -29449,6 +29470,15 @@ mysql> select INTERVAL(22, 23, 30, 44, 200); @end example @end table +If you are comparing case sensitive string with any of the standard +operators (@code{=}, @code{<>}..., but not @code{LIKE}) end space will +be ignored. + +@example +mysql> select "a" ="A "; + -> 1 +@end example + @node Logical Operators, Control flow functions, Comparison Operators, Non-typed Operators @subsubsection Logical Operators @@ -38106,12 +38136,16 @@ To make Access work: @itemize @bullet @item If you are using Access 2000, you should get and install the newest -Microsoft MDAC (@code{Microsoft Data Access Components}) from -@uref{http://www.microsoft.com/data}. This will fix the following bug -in Access: when you export data to @strong{MySQL}, the table and column -names aren't specified. Another way to around this bug is to upgrade to -MyODBC Version 2.50.33 and @strong{MySQL} Version 3.23.x, which together -provide a workaround for this bug! +(version 2.6 or above) Microsoft MDAC (@code{Microsoft Data Access +Components}) from @uref{http://www.microsoft.com/data}. This will fix +the following bug in Access: when you export data to @strong{MySQL}, the +table and column names aren't specified. Another way to around this bug +is to upgrade to MyODBC Version 2.50.33 and @strong{MySQL} Version +3.23.x, which together provide a workaround for this bug! + +You should also get and apply the Microsoft Jet 4.0 Service Pack 5 (SP5) +which can be found here +@uref{http://support.microsoft.com/support/kb/articles/Q 239/1/14.ASP}. Note that if you are using @strong{MySQL} Version 3.22, you must to apply the MDAC patch and use MyODBC 2.50.32 or 2.50.34 and above to go around @@ -39888,6 +39922,7 @@ of @code{mysql_field_count()} whether or not the statement was a @code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)} +* Thread-safe clients:: How to Make a Thread-safe Client @subsubheading Description Sets the field cursor to the given offset. The next call to @@ -43501,6 +43536,34 @@ thread that is waiting on the disk-full condition will allow the other threads to continue. @end itemize +You need to know the following if you have a thread that is calling +MySQL functions, but that thread has not created the connection to the +MySQL database: + +When you call @code{mysql_init()} or @code{mysql_connect()}, MySQL will +create a thread specific variable for the thread that is used by the +debug library (among other things). + +If you have in a thread call a MySQL function, before a thread has +called @code{mysql_init()} or @code{mysql_connect()}, the thread will +not have the necessary thread specific variables in place and you are +likely to end up with a core dump sooner or later. + +The get things to work smoothly you have to do the following: + +@enumerate +@item +Call @code{my_init()} at the start of your program if it calls +any other MySQL function before calling @code{mysql_real_connect()}. +@item +Call @code{my_thread_init()} in the thread handler before calling +any MySQL function. +@item +In the thread, call @code{my_thread_end()} before calling +@code{pthread_exit()}. This will free the memory used by MySQL thread +specific variables. +@end enumerate + Exceptions to the above behaveour is when you use @code{REPAIR} or @code{OPTIMIZE} or when the indexes are created in a batch after an @code{LOAD DATA INFILE} or after an @code{ALTER TABLE} statement. @@ -45906,6 +45969,8 @@ Romanian error messages. Hungarian error messages. @item Roberto M. Serqueira Portugise error messages. +@item Carsten H. Pedersen +Danish error messages @item David Sacerdote @email{davids@@secnet.com} Ideas for secure checking of DNS hostnames. @item Wei-Jou Chen @email{jou@@nematic.ieo.nctu.edu.tw} @@ -46145,6 +46210,7 @@ not yet 100% confident in this code. @menu * News-3.23.41:: Changes in release 3.23.41 +* News-3.23.41:: Changes in release 3.23.41 * News-3.23.40:: Changes in release 3.23.40 * News-3.23.39:: Changes in release 3.23.39 * News-3.23.38:: Changes in release 3.23.38 @@ -46195,9 +46261,36 @@ not yet 100% confident in this code. @item Added option @code{--sql-mode=option[,option[,option]]}. Please see @code{mysqld --help} for legal modes. @item +InnoDB now supports < 4 GB rows. The former limit was 8000 bytes. +@item +The @code{doublewrite} file flush method is used in InnoDB. +It reduces the need for Unix fsync calls to a fraction and +improves performance on most Unix flavors. +@item +You can now use the InnoDB Monitor to print a lot of InnoDB state +information, including locks, to the standard output; useful in +performance tuning. +@item +Several bugs which could cause hangs in InnoDB have been fixed. +@item +Split @code{record_buffer} to @code{record_buffer} and +@code{record_rnd_buffer}. To make things compatible to previous MySQL +versions, if @code{record_rnd_buffer} is not set, then it takes the +value of @code{record_buffer}. +@item Fixed optimizing bug in @code{ORDER BY} where some @code{ORDER BY} parts where wrongly removed. @item +Fixed overflow bug with @code{ALTER TABLE} and @code{MERGE} tables. +@item +Added prototypes for @code{my_thread_init()} and @code{my_thread_end()} to +@file{mysql_com.h} +@item +Added option @code{--safe-user-create} to @code{mysqld}. +@item +Added options to the @code{--ansi} startup options to let the user +decide which @code{ansi} options one to enable. +@item Fixed bug in @code{SELECT DISTINCT ... HAVING} that casued error message @code{Can't find record in '#...} @end itemize 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/innodb.result b/mysql-test/r/innodb.result index 52251e8f87a..fd7900af13b 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/sql/mysqld.cc b/sql/mysqld.cc index c9711fcf78e..99d05fa73e4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3733,7 +3733,7 @@ static void get_options(int argc,char **argv) #endif /* HAVE_INNOBASE_DB */ case OPT_MYISAM_RECOVER: { - if (!optarg || !optarg[0]) + if (!optarg) { myisam_recover_options= HA_RECOVER_DEFAULT; myisam_recover_options_str= myisam_recover_typelib.type_names[0]; @@ -3760,8 +3760,9 @@ static void get_options(int argc,char **argv) fprintf(stderr, "Unknown option to sql-mode: %s\n", optarg); exit(1); } - if (opt_sql_mode & MODE_SERIALIZABLE) - default_tx_isolation= ISO_SERIALIZABLE; + default_tx_isolation= ((opt_sql_mode & MODE_SERIALIZABLE) ? + ISO_SERIALIZABLE : + ISO_READ_COMMITTED); break; } case OPT_MASTER_HOST: @@ -4393,9 +4394,10 @@ static ulong find_bit_type(const char *x, TYPELIB *bit_lib) DBUG_PRINT("enter",("x: '%s'",x)); 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 */ { @@ -4428,7 +4430,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); From 49a3cea4e09a14bc0c198d6acfc3316a4957dd23 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 01:42:34 +0300 Subject: [PATCH 13/18] Fixed handling of strings in mysqldumpslow scripts/mysqldumpslow.sh: Handling of strings with \ and double '' sql/mysqlbinlog.cc: Fixed type --- scripts/mysqldumpslow.sh | 5 +++-- sql/mysqlbinlog.cc | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) 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/mysqlbinlog.cc b/sql/mysqlbinlog.cc index 5edfe6e0591..c2ea73008e1 100644 --- a/sql/mysqlbinlog.cc +++ b/sql/mysqlbinlog.cc @@ -108,7 +108,7 @@ static void die(const char* fmt, ...) static void print_version() { - printf("%s Ver 1.4 for %s at %s\n",my_progname,SYSTEM_TYPE, MACHINE_TYPE); + printf("%s Ver 1.5 for %s at %s\n",my_progname,SYSTEM_TYPE, MACHINE_TYPE); } @@ -133,7 +133,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\ From 11b0c8322bf3ac57c73fe1c891c0dd331152b299 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 02:16:13 +0300 Subject: [PATCH 14/18] Changed to use standard 'install' syntax --- sql-bench/Makefile.am | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/sql-bench/Makefile.am b/sql-bench/Makefile.am index 673a36852e9..80806f35418 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 From cb1c0b08187ba3b7bea7db158ad4d42329fd1162 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 11:24:43 +0300 Subject: [PATCH 15/18] Made SIGTERM safer for Solaris BitKeeper/etc/ignore: added */*_pure_*warnings BUILD/compile-solaris-sparc: Optimized build for ultrasparc sql/mysqld.cc: Made SIGTERM safer for Solaris as it sometimes delivered a not catched signal during shutdown --- .bzrignore | 2 ++ BUILD/compile-solaris-sparc | 19 +++++++++++++------ sql/mysqld.cc | 22 +++++++++++----------- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/.bzrignore b/.bzrignore index e18c49af87c..56411f9b53f 100644 --- a/.bzrignore +++ b/.bzrignore @@ -291,3 +291,5 @@ myisam/test1.MYD myisam/test1.MYI .gdbinit .vimrc +*/.pure +*/*_pure_*warnings 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/sql/mysqld.cc b/sql/mysqld.cc index 99d05fa73e4..49c8be0f363 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -576,16 +576,16 @@ void kill_mysql(void) // CloseHandle(hEvent); } #elif defined(HAVE_PTHREAD_KILL) - if (pthread_kill(signal_thread,SIGTERM)) /* End everything nicely */ - { - DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */ - } + if (pthread_kill(signal_thread,MYSQL_KILL_SIGNAL))// End everything nicely + { + DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */ + } #else - kill(current_pid,SIGTERM); + kill(current_pid,MYSQL_KILL_SIGNAL); #endif - DBUG_PRINT("quit",("After pthread_kill")); - shutdown_in_progress=1; // Safety if kill didn't work - DBUG_VOID_RETURN; + DBUG_PRINT("quit",("After pthread_kill")); + shutdown_in_progress=1; // Safety if kill didn't work + DBUG_VOID_RETURN; } @@ -1248,8 +1248,8 @@ static void init_signals(void) sigaddset(&set,SIGQUIT); sigaddset(&set,SIGTERM); sigaddset(&set,SIGHUP); - signal(SIGTERM,SIG_DFL); // If it's blocked by parent - signal(SIGHUP,SIG_DFL); // If it's blocked by parent + sigset(SIGTERM,print_signal_warning); // If it's blocked by parent + signal(SIGHUP,print_signal_warning); // If it's blocked by parent #ifdef SIGTSTP sigaddset(&set,SIGTSTP); #endif @@ -1344,7 +1344,7 @@ static void *signal_hand(void *arg __attribute__((unused))) int error; // Used when debugging if (shutdown_in_progress && !abort_loop) { - sig=SIGTERM; + sig= MYSQL_KILL_SIGNAL; error=0; } else From 1e5b7a20fe917577aacdaa0ff434881accdb7e3d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 11:43:45 +0300 Subject: [PATCH 16/18] ignore generated include file BitKeeper/etc/ignore: added include/widec.h --- .bzrignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.bzrignore b/.bzrignore index 56411f9b53f..895e3bbb044 100644 --- a/.bzrignore +++ b/.bzrignore @@ -293,3 +293,4 @@ myisam/test1.MYI .vimrc */.pure */*_pure_*warnings +include/widec.h From cc32440ce94cc313e0c9ff2556a0db5ea7cebe2b Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 11:53:50 +0300 Subject: [PATCH 17/18] delete generated files BitKeeper/deleted/.del-rpc_server_ext.h~952741fb85de2b80: Delete: bdb/include/rpc_server_ext.h BitKeeper/deleted/.del-rpc_client_ext.h~85436ca9b5691338: Delete: bdb/include/rpc_client_ext.h BitKeeper/etc/ignore: added bdb/include/rpc_client_ext.h --- .bzrignore | 2 ++ bdb/include/rpc_client_ext.h | 19 ------------------- bdb/include/rpc_server_ext.h | 21 --------------------- 3 files changed, 2 insertions(+), 40 deletions(-) delete mode 100644 bdb/include/rpc_client_ext.h delete mode 100644 bdb/include/rpc_server_ext.h diff --git a/.bzrignore b/.bzrignore index e18c49af87c..af6c28edcdf 100644 --- a/.bzrignore +++ b/.bzrignore @@ -291,3 +291,5 @@ myisam/test1.MYD myisam/test1.MYI .gdbinit .vimrc +bdb/include/rpc_server_ext.h +bdb/include/rpc_client_ext.h 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/bdb/include/rpc_server_ext.h b/bdb/include/rpc_server_ext.h deleted file mode 100644 index 4abb0768134..00000000000 --- a/bdb/include/rpc_server_ext.h +++ /dev/null @@ -1,21 +0,0 @@ -/* DO NOT EDIT: automatically built by dist/s_include. */ -#ifndef _rpc_server_ext_h_ -#define _rpc_server_ext_h_ -#if defined(__cplusplus) -extern "C" { -#endif -void __db_stats_freelist __P((__db_stat_statsreplist **)); -void __dbsrv_settimeout __P((ct_entry *, u_int32_t)); -void __dbsrv_timeout __P((int)); -void __dbclear_ctp __P((ct_entry *)); -void __dbdel_ctp __P((ct_entry *)); -ct_entry *new_ct_ent __P((u_int32_t *)); -ct_entry *get_tableent __P((long)); -void __dbsrv_active __P((ct_entry *)); -int __dbc_close_int __P((ct_entry *)); -int __dbenv_close_int __P((long, int)); -char *get_home __P((char *)); -#if defined(__cplusplus) -} -#endif -#endif /* _rpc_server_ext_h_ */ From f6751dd8db31161f6eaa0a80aa8cf1b8f9c930c3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 14:10:27 +0300 Subject: [PATCH 18/18] Portability fix for windows Docs/manual.texi: Changelog --- Docs/manual.texi | 9 ++++++--- sql/mysqlbinlog.cc | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index f9e492ca910..59d9e44a6cf 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -46210,7 +46210,6 @@ not yet 100% confident in this code. @menu * News-3.23.41:: Changes in release 3.23.41 -* News-3.23.41:: Changes in release 3.23.41 * News-3.23.40:: Changes in release 3.23.40 * News-3.23.39:: Changes in release 3.23.39 * News-3.23.38:: Changes in release 3.23.38 @@ -46258,8 +46257,12 @@ not yet 100% confident in this code. @node News-3.23.41, News-3.23.40, News-3.23.x, News-3.23.x @appendixsubsec Changes in release 3.23.41 @itemize @bullet -@item Added option @code{--sql-mode=option[,option[,option]]}. Please see -@code{mysqld --help} for legal modes. +@item +Added option @code{--sql-mode=option[,option[,option]]}. +@xref{Command-line options}. +@item +Fixed possible problem with @code{shutdown} on Solaris where the +@code{.pid} file wasn't deleted. @item InnoDB now supports < 4 GB rows. The former limit was 8000 bytes. @item diff --git a/sql/mysqlbinlog.cc b/sql/mysqlbinlog.cc index c2ea73008e1..637115fe2f4 100644 --- a/sql/mysqlbinlog.cc +++ b/sql/mysqlbinlog.cc @@ -466,4 +466,8 @@ int main(int argc, char** argv) the server */ +#ifdef __WIN__ +#include "log_event.cpp" +#else #include "log_event.cc" +#endif