From bf2ccade41684c773e67cc66b67b84a0c2777656 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Jul 2001 16:48:33 +0200 Subject: 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; -- cgit v1.2.1 From 29b3ef30267ebc58017d6dede783eb35bcdc295c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 01:04:43 +0300 Subject: 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 -- cgit v1.2.1 From 70f97c8647965bed225c7e50f4e7481dc94e7d70 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Aug 2001 22:58:45 -0500 Subject: DocTOC Chapter 9 Complete! (Chapter 8 Skipped, will be next.) --- Docs/manual.texi | 9560 +++++++++++++++++++++++++++--------------------------- 1 file changed, 4827 insertions(+), 4733 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 - -@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 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 +@node Extending MySQL, ODBC, Table types, Top +@chapter Extending MySQL @menu -* Using mysqlcheck:: Using mysqlcheck for maintenance and recovery +* Adding functions:: +* Adding procedures:: +* MySQL internals:: @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,5457 +38888,5190 @@ 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 +@node Clients, Problems, Common programs, Top +@chapter MySQL APIs -When you run into problems, the first thing you should do is to find out -which program / piece of equipment is causing problems: +@cindex client tools +@cindex APIs +@cindex @code{mysqlclient} library +@cindex buffer sizes, client +@cindex library, @code{mysqlclient} -@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 +@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 -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. +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. -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. +@cindex C API, datatypes +@cindex datatypes, C API +@node C, Perl, Clients, Clients +@section MySQL C API -@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}. +@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 -@item -If you don't think you have hardware problems, you should try to find -out which program is causing problems. +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. -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. +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. -@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. +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. -@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 +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. -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! +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}. -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. +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. -If a program fails, it's always useful to know: +For programming with threads, consult the 'how to make a thread-safe +client' chapter. @xref{Thread-safe clients}. -@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 +@node C API datatypes, C API function overview, C, C +@subsection C API Datatypes +@table @code -When sending a bug report, you should of follow the outlines -described in this manual. @xref{Asking questions}. +@tindex MYSQL C type +@item MYSQL +This structure represents a handle to one database connection. It is +used for almost all @strong{MySQL} functions. -@cindex crash, repeated -@node Crashing, Link errors, What is crashing, Problems -@section What to Do if MySQL Keeps Crashing +@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. -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. +@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()}. -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}. +@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. -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: +@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. -@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 +@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}. -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: +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 -@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}. +@noindent +The @code{MYSQL_FIELD} structure contains the members listed below: -@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}. +@table @code +@item char * name +The name of the field, as a null-terminated string. -@item -Try to make a test case that we can use to reproduce the problem. -@xref{Reproduceable test case}. +@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 -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 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 -Try @code{fork_test.pl} and @code{fork2_test.pl}. +@item enum enum_field_types type +The type of the field. +The @code{type} value may be one of the following: -@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}. +@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 -@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. +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: -@item -Have you applied the latest patches for your operating system? +@example +if (IS_NUM(field->type)) + printf("Field is numeric\n"); +@end example -@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 unsigned int length +The width of the field, as specified in the table definition. -@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 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 -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 unsigned int flags +Different bit-flags for the field. The @code{flags} value may have zero +or more of the following bits set: -@item -Try the following: -@enumerate -@item -Start @code{mysqld} from @code{gdb} (or in another debugger). -@xref{Using gdb on mysqld}. +@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 -@item -Run your test scripts. +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. -@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: +@noindent +The example below illustrates a typical use of the @code{flags} value: @example -backtrace -info local -up -info local -up -info local +if (field->flags & NOT_NULL_FLAG) + printf("Field can't be null\n"); @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 +You may use the following convenience macros to determine the boolean +status of the @code{flags} value: -@item -Try to simulate your application with a Perl script to force -@strong{MySQL} to crash or misbehave. +@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 -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! +@item unsigned int decimals +The number of decimals for numeric fields. +@end table -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 C API, functions +@cindex functions, C API +@node C API function overview, C API functions, C API datatypes, C +@subsection C API Function Overview -@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 +The functions available in the C API are listed below and are described in +greater detail in the next section. +@xref{C API functions}. -If you are linking your program and you get errors for unreferenced -symbols that start with @code{mysql_}, like the following: +@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. -@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 +@item @strong{mysql_close()} @tab +Closes a server connection. -you should be able to solve this by adding @code{-Lpath-to-the-mysql-library --lmysqlclient} @strong{LAST} on your link line. +@item @strong{mysql_connect()} @tab +Connects to a @strong{MySQL} server. This function is deprecated; use +@code{mysql_real_connect()} instead. -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! +@item @strong{mysql_change_user()} @tab +Changes user and database on an open connection. -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 +@item @strong{mysql_character_set_name()} @tab +Returns the name of the default character set for the connection. -@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 +@item @strong{mysql_create_db()} @tab +Creates a database. This function is deprecated; use the SQL command +@code{CREATE DATABASE} instead. -This section lists some errors that users frequently get. You will find -descriptions of the errors, and how to solve the problem here. +@item @strong{mysql_data_seek()} @tab +Seeks to an arbitrary row in a query result set. -@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 +@item @strong{mysql_debug()} @tab +Does a @code{DBUG_PUSH} with the given string. -@xref{Privileges}, and especially. @xref{Access denied}. +@item @strong{mysql_drop_db()} @tab +Drops a database. This function is deprecated; use the SQL command +@code{DROP DATABASE} instead. -@node Gone away, Can not connect to server, Error Access denied, Common errors -@subsection @code{MySQL server has gone away} Error +@item @strong{mysql_dump_debug_info()} @tab +Makes the server write debug information to the log. -This section also covers the related @code{Lost connection to server -during query} error. +@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. -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}. +@item @strong{mysql_errno()} @tab +Returns the error number for the most recently invoked @strong{MySQL} function. -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. +@item @strong{mysql_error()} @tab +Returns the error message for the most recently invoked @strong{MySQL} function. -You can check that the @strong{MySQL} hasn't died by executing -@code{mysqladmin version} and examining the uptime. +@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. -If you have a script, you just have to issue the query again for the client -to do an automatic reconnection. +@item @strong{mysql_escape_string()} @tab +Escapes special characters in a string for use in a SQL statement. -You normally can get the following error codes in this case -(which one you get is OS-dependent): +@item @strong{mysql_fetch_field()} @tab +Returns the type of the next table field. -@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 +@item @strong{mysql_fetch_field_direct()} @tab +Returns the type of a table field, given a field number. -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! +@item @strong{mysql_fetch_fields()} @tab +Returns an array of all field structures. -@node Can not connect to server, Blocked host, Gone away, Common errors -@subsection @code{Can't connect to [local] MySQL server} error +@item @strong{mysql_fetch_lengths()} @tab +Returns the lengths of all columns in the current row. -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}. +@item @strong{mysql_fetch_row()} @tab +Fetches the next row from the result set. -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. +@item @strong{mysql_field_seek()} @tab +Puts the column cursor on a specified column. -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. +@item @strong{mysql_field_count()} @tab +Returns the number of result columns for the most recent query. -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}. +@item @strong{mysql_field_tell()} @tab +Returns the position of the field cursor used for the last +@code{mysql_fetch_field()}. -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): +@item @strong{mysql_free_result()} @tab +Frees memory used by a result set. -@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 +@item @strong{mysql_get_client_info()} @tab +Returns client version information. -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. +@item @strong{mysql_get_host_info()} @tab +Returns a string describing the connection. -Here are some reasons the @code{Can't connect to local MySQL server} -error might occur: +@item @strong{mysql_get_proto_info()} @tab +Returns the protocol version used by the connection. -@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: +@item @strong{mysql_get_server_info()} @tab +Returns the server version number. -@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 +@item @strong{mysql_info()} @tab +Returns information about the most recently executed query. -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 : +@item @strong{mysql_init()} @tab +Gets or initializes a @code{MYSQL} structure. -@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 +@item @strong{mysql_insert_id()} @tab +Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous +query. -@node Blocked host, Too many connections, Can not connect to server, Common errors -@subsection @code{Host '...' is blocked} Error +@item @strong{mysql_kill()} @tab +Kills a given thread. -If you get an error like this: +@item @strong{mysql_list_dbs()} @tab +Returns database names matching a simple regular expression. -@example -Host 'hostname' is blocked because of many connection errors. -Unblock with 'mysqladmin flush-hosts' -@end example +@item @strong{mysql_list_fields()} @tab +Returns field names matching a simple regular expression. -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}. +@item @strong{mysql_list_processes()} @tab +Returns a list of the current server threads. -By default, @code{mysqld} blocks a host after 10 connection errors. -You can easily adjust this by starting the server like this: +@item @strong{mysql_list_tables()} @tab +Returns table names matching a simple regular expression. -@example -shell> safe_mysqld -O max_connect_errors=10000 & -@end example +@item @strong{mysql_num_fields()} @tab +Returns the number of columns in a result set. -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! +@item @strong{mysql_num_rows()} @tab +Returns the number of rows in a result set. -@node Too many connections, Non-transactional tables, Blocked host, Common errors -@subsection @code{Too many connections} Error +@item @strong{mysql_options()} @tab +Sets connect options for @code{mysql_connect()}. -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. +@item @strong{mysql_ping()} @tab +Checks whether or not the connection to the server is working, reconnecting +as necessary. -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. +@item @strong{mysql_query()} @tab +Executes a SQL query specified as a null-terminated string. -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}. +@item @strong{mysql_real_connect()} @tab +Connects to a @strong{MySQL} server. -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. +@item @strong{mysql_real_query()} @tab +Executes a SQL query specified as a counted string. -@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 +@item @strong{mysql_reload()} @tab +Tells the server to reload the grant 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. +@item @strong{mysql_row_seek()} @tab +Seeks to a row in a result set, using value returned from +@code{mysql_row_tell()}. -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}. +@item @strong{mysql_row_tell()} @tab +Returns the row cursor position. -You can check the table type for a table by doing: +@item @strong{mysql_select_db()} @tab +Selects a database. -@code{SHOW TABLE STATUS LIKE 'table_name'}. @xref{SHOW TABLE STATUS}. +@item @strong{mysql_shutdown()} @tab +Shuts down the database server. -You can check the extensions your @code{mysqld} binary supports by doing: +@item @strong{mysql_stat()} @tab +Returns the server status as a string. -@code{show variables like 'have_%'}. @xref{SHOW VARIABLES}. +@item @strong{mysql_store_result()} @tab +Retrieves a complete result set to the client. -@node Out of memory, Packet too large, Non-transactional tables, Common errors -@subsection @code{Out of memory} Error +@item @strong{mysql_thread_id()} @tab +Returns the current thread ID. -If you issue a query and get something like the following error: +@item @strong{mysql_thread_save()} @tab +Returns 1 if the clients are compiled as thread-safe. -@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 +@item @strong{mysql_use_result()} @tab +Initiates a row-by-row result set retrieval. +@end multitable -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 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. -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). +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()}. -@node Packet too large, Communication errors, Out of memory, Common errors -@subsection @code{Packet too large} Error +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()}. -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. +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.) -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}. +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. -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. +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()}. -@cindex aborted clients -@cindex aborted connection -@cindex connection, aborted -@node Communication errors, Full table, Packet too large, Common errors -@subsection Communication Errors / Aborted Connection +After you are done with a result set, call @code{mysql_free_result()} +to free the memory used for it. -Starting with @code{MySQL 3.23.40} you only get the @code{Aborted -connection} error of you start @code{mysqld} with @code{--warnings}. +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. -If you find errors like the following in your error log. +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. -@example -010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh' -@end example +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. -@xref{Error log}. +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. -This means that something of the following has happened: +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()}. -@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 +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. -When the above happens, the server variable @code{Aborted_clients} is -incremented. +@node C API functions, C API problems, C API function overview, C +@subsection C API Function Descriptions -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 +@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 -Note that the above could indicate that someone is trying to break into -your database! +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. -@xref{SHOW VARIABLES}. +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: -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 +@example +if (result) /* correct */ + ... error ... +if (result < 0) /* incorrect */ + ... error ... -@cindex table is full -@node Full table, Cannot create, Communication errors, Common errors -@subsection @code{The table is full} Error +if (result == -1) /* incorrect */ + ... error ... +@end example -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}}. +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()}. -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. +@findex @code{mysql_affected_rows()} +@node mysql_affected_rows, mysql_close, C API functions, C API functions +@subsubsection @code{mysql_affected_rows()} -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}. +@code{my_ulonglong mysql_affected_rows(MYSQL *mysql)} -@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 +@subsubheading Description -If you get an error for some queries of type: +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()}. -@example -Can't create/write to file '\\sqla3fe_0.ism'. -@end example +@subsubheading Return Values -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: +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()}. -@example -[mysqld] -tmpdir=C:/temp -@end example +@subsubheading Errors -assuming that the @file{c:\\temp} directory exists. @xref{Option files}. +None. -Check also the error code that you get with @code{perror}. One reason -may also be a disk full error; +@subsubheading Example @example -shell> perror 28 -Error code 28: No space left on device +mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10"); +printf("%ld products updated",(long) mysql_affected_rows(&mysql)); @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 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. -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! +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. -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. +@findex @code{mysql_close()} +@node mysql_close, mysql_connect, mysql_affected_rows, C API functions +@subsubsection @code{mysql_close()} -@node Ignoring user, Cannot find table, Commands out of sync, Common errors -@subsection @code{Ignoring user} Error +@code{void mysql_close(MYSQL *mysql)} -If you get the following error: +@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()}. -@code{Found wrong password for user: 'some_user@@some_host'; Ignoring user} +@subsubheading Return Values -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. +None. -Possible causes of and fixes for this problem: +@subsubheading Errors -@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. +None. -@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}. +@findex @code{mysql_connect()} +@node mysql_connect, mysql_change_user, mysql_close, C API functions +@subsubsection @code{mysql_connect()} -@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: +@code{MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)} -@example -mysql> update user set password=PASSWORD('your password') - where user='XXX'; -@end example -@end itemize +@subsubheading Description -@node Cannot find table, Cannot initialize character set, Ignoring user, Common errors -@subsection @code{Table 'xxx' doesn't exist} Error +This function is deprecated. It is preferable to use +@code{mysql_real_connect()} instead. -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}. +@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()}. -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!) +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.) -You can check which tables you have in the current database with -@code{SHOW TABLES}. @xref{SHOW, , @code{SHOW}}. +@subsubheading Return Values -@cindex multibyte character sets -@node Cannot initialize character set, , Cannot find table, Common errors -@subsection @code{Can@'t initialize character set xxx} error. +Same as for @code{mysql_real_connect()}. -If you get an error like: +@subsubheading Errors -@example -MySQL Connection Failed: Can't initialize character set xxx -@end example +Same as for @code{mysql_real_connect()}. -This means one of the following things: +@findex @code{mysql_change_user()} +@node mysql_change_user, mysql_character_set_name, mysql_connect, C API functions +@subsubsection @code{mysql_change_user()} -@itemize @bullet -@item -The character set is a multi-byte character set and you have not support -for the character set in the client. +@code{my_bool mysql_change_user(MYSQL *mysql, const char *user, const +char *password, const char *db)} -In this case you need to recompile the client with -@code{--with-charset=xxx} or with @code{--with-extra-charsets=xxx}. -@xref{configure options}. +@subsubheading Description -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}. +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. -@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. +This function was introduced in @strong{MySQL} Version 3.23.3. -In this case you need to: +@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 -@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 +The @code{db} parameter may be set to @code{NULL} if you don't want to have a +default database. -@cindex full disk -@cindex disk full -@node Full disk, Temporary files, Common errors, Problems -@section How MySQL Handles a Full Disk +@subsubheading Return values -@noindent -When a disk-full condition occurs, @strong{MySQL} does the following: +Zero for success. Non-zero if an error occurred. -@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 +@subsubheading Errors -@noindent -To alleviate the problem, you can take the following actions: +The same that you can get from @code{mysql_real_connect()}. -@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 +@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 -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. +@subsubheading Example -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). +@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()} -@node Temporary files, Problems with mysql.sock, Full disk, Problems -@section Where MySQL Stores Temporary Files +@code{const char *mysql_character_set_name(MYSQL *mysql)} -@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}. +@subsubheading Description -@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. +Returns the default character set for the current connection. -When sorting (@code{ORDER BY} or @code{GROUP BY}), @strong{MySQL} normally -uses one or two temporary files. The maximum disk-space needed is: +@subsubheading Return Values -@example -(length of what is sorted + sizeof(database pointer)) -* number of matched rows -* 2 -@end example +The default character set -@code{sizeof(database pointer)} is usually 4, but may grow in the future for -really big tables. +@subsubheading Errors +None. -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. +@findex @code{mysql_create_db()} +@node mysql_create_db, mysql_data_seek, mysql_character_set_name, C API functions +@subsubsection @code{mysql_create_db()} -@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 +@code{int mysql_create_db(MYSQL *mysql, const char *db)} -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: +@subsubheading Description +Creates the database named by the @code{db} parameter. -@example -shell> chmod +t /tmp -@end example +This function is deprecated. It is preferable to use @code{mysql_query()} +to issue a SQL @code{CREATE DATABASE} statement instead. -This will protect your @file{/tmp} file system so that files can be deleted -only by their owners or the superuser (@code{root}). +@subsubheading Return Values -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. +Zero if the database was created successfully. Non-zero if an error +occurred. -@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 +@subsubheading Errors +@table @code -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: +@item CR_COMMANDS_OUT_OF_SYNC +Commands were executed in an improper order. -@enumerate -@item -Stop the server if it's running (use @code{mysqladmin shutdown}). +@item CR_SERVER_GONE_ERROR +The @strong{MySQL} server has gone away. -@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): +@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 -shell> chown -R user_name /path/to/mysql/datadir +if(mysql_create_db(&mysql, "my_database")) +@{ + fprintf(stderr, "Failed to create new database. Error: %s\n", + mysql_error(&mysql)); +@} @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. +@findex @code{mysql_data_seek()} +@node mysql_data_seek, mysql_debug, mysql_create_db, C API functions +@subsubsection @code{mysql_data_seek()} -@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. +@code{void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)} -@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: +@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()}. -@example -[mysqld] -user=user_name -@end example -@end enumerate +The offset should be a value in the range from 0 to +@code{mysql_num_rows(result)-1}. -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. +@subsubheading Return Values -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. +None. -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. +@subsubheading Errors +None. -@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 +@findex @code{mysql_debug()} +@node mysql_debug, mysql_drop_db, mysql_data_seek, C API functions +@subsubsection @code{mysql_debug()} -If you have forgotten the @code{root} user password for @strong{MySQL}, you -can restore it with the following procedure: +@code{void mysql_debug(char *debug)} -@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: +@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 -kill `cat /mysql-data-directory/hostname.pid` +mysql_debug("d:t:O,/tmp/client.trace"); @end example -You must be either the Unix @code{root} user or the same user the server -runs as to do this. +@findex @code{mysql_drop_db()} +@node mysql_drop_db, mysql_dump_debug_info, mysql_debug, C API functions +@subsubsection @code{mysql_drop_db()} -@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 +@code{int mysql_drop_db(MYSQL *mysql, const char *db)} -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}. +@subsubheading Description +Drops the database named by the @code{db} parameter. -@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 +This function is deprecated. It is preferable to use @code{mysql_query()} +to issue a SQL @code{DROP DATABASE} statement instead. -If you have problems with file permissions, for example, if @code{mysql} -issues the following error message when you create a table: +@subsubheading Return Values -@example -ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13) -@end example +Zero if the database was dropped successfully. Non-zero if an error +occurred. -@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: +@subsubheading Errors -@example -shell> UMASK=384 # = 600 in octal -shell> export UMASK -shell> /path/to/safe_mysqld & -@end example +@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 -@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: +@subsubheading Example @example -shell> UMASK_DIR=504 # = 770 in octal -shell> export UMASK_DIR -shell> /path/to/safe_mysqld & +if(mysql_drop_db(&mysql, "my_database")) + fprintf(stderr, "Failed to drop the database: Error: %s\n", + mysql_error(&mysql)); @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. +@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()} -@xref{Environment variables}. +@code{int mysql_dump_debug_info(MYSQL *mysql)} -@node Not enough file handles, Using DATE, File permissions , Problems -@section File Not Found +@subsubheading Description -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: +Instructs the server to write some debug information to the log. The +connected user must have the @strong{process} privilege for this to work. -@example -shell> perror 23 -File table overflow -shell> perror 24 -Too many open files -shell> perror 11 -Resource temporarily unavailable -@end example +@subsubheading Return values -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}. +Zero if the command was successful. Non-zero if an error occurred. -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). +@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 -@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}. +@findex @code{mysql_eof()} +@node mysql_eof, mysql_errno, mysql_dump_debug_info, C API functions +@subsubsection @code{mysql_eof()} -@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. +@code{my_bool mysql_eof(MYSQL_RES *result)} -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}! +@subsubheading Description -@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 +This function is deprecated. @code{mysql_errno()} or @code{mysql_error()} +may be used instead. -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: +@code{mysql_eof()} determines whether or not the last row of a result +set has been read. -@example -mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05'; -@end example +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()}. -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. +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. -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. +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.) -Because @strong{MySQL} performs the conversions described above, the following -statements work: +@subsubheading Return Values -@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'); +Zero if no error occurred. Non-zero if the end of the result set has been +reached. -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 +@subsubheading Errors +None. -@noindent -However, the following will not work: +@subsubheading Example + +The following example shows how you might use @code{mysql_eof()}: @example -mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0; +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 -@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. +However, you can achieve the same effect with the standard @strong{MySQL} +error functions: -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. +@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 -@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 +@findex @code{mysql_errno()} +@node mysql_errno, mysql_error, mysql_eof, C API functions +@subsubsection @code{mysql_errno()} -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}. +@code{unsigned int mysql_errno(MYSQL *mysql)} -@node Case sensitivity, Problems with NULL, Timezone problems, Problems -@section Case Sensitivity in Searches +@subsubheading Description -@cindex case sensitivity, in searches -@cindex searching, and case-sensitivity -@cindex Chinese -@cindex Big5 Chinese character encoding +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}. -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"}. +@subsubheading Return Values -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! +An error code value. Zero if no error occurred. -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. +@subsubheading Errors +None. -If you want a column always to be treated in case-sensitive fashion, -declare it as @code{BINARY}. @xref{CREATE TABLE, , @code{CREATE TABLE}}. +@findex @code{mysql_error()} +@node mysql_error, mysql_escape_string, mysql_errno, C API functions +@subsubsection @code{mysql_error()} -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. +@code{char *mysql_error(MYSQL *mysql)} -@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 +@subsubheading Description -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: +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 -mysql> INSERT INTO my_table (phone) VALUES (NULL); -mysql> INSERT INTO my_table (phone) VALUES (""); +if(mysql_errno(&mysql)) +@{ + // an error occurred +@} + +if(mysql_error(&mysql)[0] != '\0') +@{ + // an error occurred +@} @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''. +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}. -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}: +@subsubheading Return Values -@example -mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL); -@end example +A character string that describes the error. An empty string if no error +occurred. -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: +@subsubheading Errors +None. -@example -mysql> SELECT * FROM my_table WHERE phone = NULL; -@end example +@findex @code{mysql_escape_string()} +@node mysql_escape_string, mysql_fetch_field, mysql_error, C API functions +@subsubsection @code{mysql_escape_string()} -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: +You should use @code{mysql_real_escape_string()} instead! -@example -mysql> SELECT * FROM my_table WHERE phone IS NULL; -mysql> SELECT * FROM my_table WHERE phone = ""; -@end example +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. -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 @code{mysql_fetch_field()} +@node mysql_fetch_field, mysql_fetch_fields, mysql_escape_string, C API functions +@subsubsection @code{mysql_fetch_field()} -@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}}. +@code{MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)} -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. +@subsubheading Description -To help with @code{NULL} handling, you can use the @code{IS NULL} and -@code{IS NOT NULL} operators and the @code{IFNULL()} function. +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. -@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. +@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()}. -@tindex alias -@node Problems with alias, Deleting from related tables, Problems with NULL, Problems -@section Problems with @code{alias} +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. -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: +@subsubheading Return Values -@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 +The @code{MYSQL_FIELD} structure for the current column. @code{NULL} +if no columns are left. -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}: +@subsubheading Errors +None. + +@subsubheading Example @example -SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id; +MYSQL_FIELD *field; + +while((field = mysql_fetch_field(result))) +@{ + printf("field name %s\n", field->name); +@} @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. +@findex @code{mysql_fetch_fields()} +@node mysql_fetch_fields, mysql_fetch_field_direct, mysql_fetch_field, C API functions +@subsubsection @code{mysql_fetch_fields()} -@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 +@code{MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)} -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: +@subsubheading Description -@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 +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. -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. +@subsubheading Return Values -@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 +An array of @code{MYSQL_FIELD} structures for all columns of a result set. -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: +@subsubheading Errors +None. -@enumerate -@item -Test the query with @code{EXPLAIN} and check if you can find something that is -obviously wrong. @xref{EXPLAIN, , @code{EXPLAIN}}. +@subsubheading Example -@item -Select only those fields that are used in the @code{WHERE} clause. +@example +unsigned int num_fields; +unsigned int i; +MYSQL_FIELD *fields; -@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. +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 -@item -Do a @code{SELECT} for the column that should have matched a row against -the table that was last removed from the query. +@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()} -@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: +@code{MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)} -@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 +@subsubheading Description -In most cases, changing the @code{FLOAT} to a @code{DOUBLE} will fix this! +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}. -@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. +@subsubheading Return Values -Test that you still have your problem by doing: +The @code{MYSQL_FIELD} structure for the specified column. + +@subsubheading Errors +None. + +@subsubheading Example @example -shell> mysqladmin create test2 -shell> mysql test2 < query.sql +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 -Post the test file using @code{mysqlbug} to @email{mysql@@lists.mysql.com}. -@end enumerate +@findex @code{mysql_fetch_lengths()} +@node mysql_fetch_lengths, mysql_fetch_row, mysql_fetch_field_direct, C API functions +@subsubsection @code{mysql_fetch_lengths()} -@tindex ALTER TABLE -@node ALTER TABLE problems, Change column order, No matching rows, Problems -@section Problems with @code{ALTER TABLE}. +@code{unsigned long *mysql_fetch_lengths(MYSQL_RES *result)} -@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. +@subsubheading Description -If @code{ALTER TABLE} dies with an error like this: +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 -Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17) +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 -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.) +@findex @code{mysql_fetch_row()} +@node mysql_fetch_row, mysql_field_count, mysql_fetch_lengths, C API functions +@subsubsection @code{mysql_fetch_row()} -@code{ALTER TABLE} works the following way: +@code{MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)} -@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 +@subsubheading Description -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. +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. -@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 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 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: +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. -@example -SELECT col_name1, col_name2, col_name3 FROM tbl_name; -@end example +@subsubheading Return Values -will return columns in the order @code{col_name1}, @code{col_name2}, @code{col_name3}, whereas: +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 -SELECT col_name1, col_name3, col_name2 FROM tbl_name; +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 -will return columns in the order @code{col_name1}, @code{col_name3}, @code{col_name2}. +@findex @code{mysql_field_count()} +@node mysql_field_count, mysql_field_seek, mysql_fetch_row, C API functions +@subsubsection @code{mysql_field_count()} -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. +@code{unsigned int mysql_field_count(MYSQL *mysql)} -If you want to change the order of columns anyway, you can do it as follows: +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. -@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 +@subsubheading Description -@cindex temporary tables, problems -@node Temporary table problems, , Change column order, Problems -@section TEMPORARY TABLE problems +Returns the number of columns for the most recent query on the connection. -The following are a list of the limitations with @code{TEMPORARY TABLES}. +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. -@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. +@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. -@example -select * from temporary_table, temporary_table as t2; -@end example +@subsubheading Return Values -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! +An unsigned integer representing the number of fields in a result set. -We plan to fix the above in 4.0. -@end itemize +@subsubheading Errors +None. -@cindex problems, solving -@cindex solving, problems -@cindex databases, replicating -@node Common problems, Clients, Problems, Top -@chapter Solving Some Common Problems with MySQL +@subsubheading Example -@cindex replication -@menu -* Log Replication:: Database replication with update log -@end menu +@example +MYSQL_RES *result; +unsigned int num_fields; +unsigned int num_rows; -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. +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 -@cindex database replication -@cindex replication, database -@node Log Replication, , Common problems, Common problems -@section Database Replication with Update Log +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}. -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}. +@findex @code{mysql_field_seek()} +@node mysql_field_seek, mysql_field_tell, mysql_field_count, C API functions +@subsubsection @code{mysql_field_seek()} -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. +@code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)} -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. +@subsubheading Description -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. +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. -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: +To seek to the beginning of a row, pass an @code{offset} value of zero. -@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 +@subsubheading Return Values -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. +The previous value of the field cursor. +@subsubheading Errors +None. -@node Clients, MySQL internals, Common problems, Top -@chapter MySQL APIs +@findex @code{mysql_field_tell()} +@node mysql_field_tell, mysql_free_result, mysql_field_seek, C API functions +@subsubsection @code{mysql_field_tell()} -@cindex client tools -@cindex APIs -@cindex @code{mysqlclient} library -@cindex buffer sizes, client -@cindex library, @code{mysqlclient} +@code{MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)} -@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 +@subsubheading Description -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. +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()}. -@cindex C API, datatypes -@cindex datatypes, C API -@node C, Perl, Clients, Clients -@section MySQL C API +@subsubheading Return Values -@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 current offset of the field cursor. -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. +@subsubheading Errors +None. -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. +@findex @code{mysql_free_result()} +@node mysql_free_result, mysql_get_client_info, mysql_field_tell, C API functions +@subsubsection @code{mysql_free_result()} -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. +@code{void mysql_free_result(MYSQL_RES *result)} -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. +@subsubheading Description -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}. +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()}. -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. +@subsubheading Return Values -For programming with threads, consult the 'how to make a thread-safe -client' chapter. @xref{Thread-safe clients}. +None. -@node C API datatypes, C API function overview, C, C -@subsection C API Datatypes -@table @code +@subsubheading Errors +None. -@tindex MYSQL C type -@item MYSQL -This structure represents a handle to one database connection. It is -used for almost all @strong{MySQL} functions. +@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()} -@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. +@code{char *mysql_get_client_info(void)} -@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()}. +@subsubheading Description -@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. +Returns a string that represents the client library version. +@subsubheading Return Values -@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. +A character string that represents the @strong{MySQL} client library version. -@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}. +@subsubheading Errors +None. -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 +@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()} -@noindent -The @code{MYSQL_FIELD} structure contains the members listed below: +@code{char *mysql_get_host_info(MYSQL *mysql)} -@table @code -@item char * name -The name of the field, as a null-terminated string. +@subsubheading Description -@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. +Returns a string describing the type of connection in use, including the +server host name. -@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()}. +@subsubheading Return Values -@item enum enum_field_types type -The type of the field. -The @code{type} value may be one of the following: +A character string representing the server host name and the connection type. -@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 +@subsubheading Errors +None. -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: +@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()} -@example -if (IS_NUM(field->type)) - printf("Field is numeric\n"); -@end example +@code{unsigned int mysql_get_proto_info(MYSQL *mysql)} -@item unsigned int length -The width of the field, as specified in the table definition. +@subsubheading Description -@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. +Returns the protocol version used by current connection. -@item unsigned int flags -Different bit-flags for the field. The @code{flags} value may have zero -or more of the following bits set: +@subsubheading Return Values -@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 +An unsigned integer representing the protocol version used by the current +connection. -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. +@subsubheading Errors +None. -@noindent -The example below illustrates a typical use of the @code{flags} value: +@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()} -@example -if (field->flags & NOT_NULL_FLAG) - printf("Field can't be null\n"); -@end example +@code{char *mysql_get_server_info(MYSQL *mysql)} -You may use the following convenience macros to determine the boolean -status of the @code{flags} value: +@subsubheading Description -@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 +Returns a string that represents the server version number. -@item unsigned int decimals -The number of decimals for numeric fields. -@end table +@subsubheading Return Values -@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 +A character string that represents the server version number. -The functions available in the C API are listed below and are described in -greater detail in the next section. -@xref{C API functions}. +@subsubheading Errors +None. -@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. +@findex @code{mysql_info()} +@node mysql_info, mysql_init, mysql_get_server_info, C API functions +@subsubsection @code{mysql_info()} -@item @strong{mysql_close()} @tab -Closes a server connection. +@code{char *mysql_info(MYSQL *mysql)} -@item @strong{mysql_connect()} @tab -Connects to a @strong{MySQL} server. This function is deprecated; use -@code{mysql_real_connect()} instead. +@subsubheading Description -@item @strong{mysql_change_user()} @tab -Changes user and database on an open connection. +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. -@item @strong{mysql_character_set_name()} @tab -Returns the name of the default character set for the connection. +@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 -@item @strong{mysql_create_db()} @tab -Creates a database. This function is deprecated; use the SQL command -@code{CREATE DATABASE} instead. +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. -@item @strong{mysql_data_seek()} @tab -Seeks to an arbitrary row in a query result set. +@subsubheading Return Values -@item @strong{mysql_debug()} @tab -Does a @code{DBUG_PUSH} with the given string. +A character string representing additional information about the most +recently executed query. @code{NULL} if no information is available for the +query. -@item @strong{mysql_drop_db()} @tab -Drops a database. This function is deprecated; use the SQL command -@code{DROP DATABASE} instead. +@subsubheading Errors +None. -@item @strong{mysql_dump_debug_info()} @tab -Makes the server write debug information to the log. +@findex @code{mysql_init()} +@node mysql_init, mysql_insert_id, mysql_info, C API functions +@subsubsection @code{mysql_init()} -@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. +@code{MYSQL *mysql_init(MYSQL *mysql)} -@item @strong{mysql_errno()} @tab -Returns the error number for the most recently invoked @strong{MySQL} function. +@subsubheading Description -@item @strong{mysql_error()} @tab -Returns the error message for the most recently invoked @strong{MySQL} function. +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. -@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. +@subsubheading Return Values -@item @strong{mysql_escape_string()} @tab -Escapes special characters in a string for use in a SQL statement. +An initialized @code{MYSQL*} handle. @code{NULL} if there was +insufficient memory to allocate a new object. -@item @strong{mysql_fetch_field()} @tab -Returns the type of the next table field. +@subsubheading Errors +In case of insufficient memory, @code{NULL} is returned. -@item @strong{mysql_fetch_field_direct()} @tab -Returns the type of a table field, given a field number. +@findex @code{mysql_insert_id()} +@node mysql_insert_id, mysql_kill, mysql_init, C API functions +@subsubsection @code{mysql_insert_id()} -@item @strong{mysql_fetch_fields()} @tab -Returns an array of all field structures. +@code{my_ulonglong mysql_insert_id(MYSQL *mysql)} -@item @strong{mysql_fetch_lengths()} @tab -Returns the lengths of all columns in the current row. +@subsubheading Description -@item @strong{mysql_fetch_row()} @tab -Fetches the next row from the result set. +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. -@item @strong{mysql_field_seek()} @tab -Puts the column cursor on a specified column. +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. -@item @strong{mysql_field_count()} @tab -Returns the number of result columns for the most recent query. +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. -@item @strong{mysql_field_tell()} @tab -Returns the position of the field cursor used for the last -@code{mysql_fetch_field()}. +@subsubheading Return Values -@item @strong{mysql_free_result()} @tab -Frees memory used by a result set. +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. -@item @strong{mysql_get_client_info()} @tab -Returns client version information. +@subsubheading Errors +None. -@item @strong{mysql_get_host_info()} @tab -Returns a string describing the connection. +@findex @code{mysql_kill()} +@node mysql_kill, mysql_list_dbs, mysql_insert_id, C API functions +@subsubsection @code{mysql_kill()} -@item @strong{mysql_get_proto_info()} @tab -Returns the protocol version used by the connection. +@code{int mysql_kill(MYSQL *mysql, unsigned long pid)} -@item @strong{mysql_get_server_info()} @tab -Returns the server version number. +@subsubheading Description -@item @strong{mysql_info()} @tab -Returns information about the most recently executed query. +Asks the server to kill the thread specified by @code{pid}. -@item @strong{mysql_init()} @tab -Gets or initializes a @code{MYSQL} structure. +@subsubheading Return Values -@item @strong{mysql_insert_id()} @tab -Returns the ID generated for an @code{AUTO_INCREMENT} column by the previous -query. +Zero for success. Non-zero if an error occurred. -@item @strong{mysql_kill()} @tab -Kills a given thread. +@subsubheading Errors -@item @strong{mysql_list_dbs()} @tab -Returns database names matching a simple regular expression. +@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 -@item @strong{mysql_list_fields()} @tab -Returns field names matching a simple regular expression. +@findex @code{mysql_list_dbs()} +@node mysql_list_dbs, mysql_list_fields, mysql_kill, C API functions +@subsubsection @code{mysql_list_dbs()} -@item @strong{mysql_list_processes()} @tab -Returns a list of the current server threads. +@code{MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)} -@item @strong{mysql_list_tables()} @tab -Returns table names matching a simple regular expression. +@subsubheading Description -@item @strong{mysql_num_fields()} @tab -Returns the number of columns in a result set. +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]}. -@item @strong{mysql_num_rows()} @tab -Returns the number of rows in a result set. +You must free the result set with @code{mysql_free_result()}. -@item @strong{mysql_options()} @tab -Sets connect options for @code{mysql_connect()}. +@subsubheading Return Values -@item @strong{mysql_ping()} @tab -Checks whether or not the connection to the server is working, reconnecting -as necessary. +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. -@item @strong{mysql_query()} @tab -Executes a SQL query specified as a null-terminated string. +@subsubheading Errors -@item @strong{mysql_real_connect()} @tab -Connects to a @strong{MySQL} server. +@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 -@item @strong{mysql_real_query()} @tab -Executes a SQL query specified as a counted string. +@findex @code{mysql_list_fields()} +@node mysql_list_fields, mysql_list_processes, mysql_list_dbs, C API functions +@subsubsection @code{mysql_list_fields()} -@item @strong{mysql_reload()} @tab -Tells the server to reload the grant tables. +@code{MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)} -@item @strong{mysql_row_seek()} @tab -Seeks to a row in a result set, using value returned from -@code{mysql_row_tell()}. +@subsubheading Description -@item @strong{mysql_row_tell()} @tab -Returns the row cursor position. +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]}. -@item @strong{mysql_select_db()} @tab -Selects a database. +Note that it's recommended that you use @code{SHOW COLUMNS FROM tbl_name} +instead of @code{mysql_list_fields()}. -@item @strong{mysql_shutdown()} @tab -Shuts down the database server. +You must free the result set with @code{mysql_free_result()}. -@item @strong{mysql_stat()} @tab -Returns the server status as a string. +@subsubheading Return Values -@item @strong{mysql_store_result()} @tab -Retrieves a complete result set to the client. +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. -@item @strong{mysql_thread_id()} @tab -Returns the current thread ID. +@subsubheading Errors -@item @strong{mysql_thread_save()} @tab -Returns 1 if the clients are compiled as thread-safe. +@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 -@item @strong{mysql_use_result()} @tab -Initiates a row-by-row result set retrieval. -@end multitable +@findex @code{mysql_list_processes()} +@node mysql_list_processes, mysql_list_tables, mysql_list_fields, C API functions +@subsubsection @code{mysql_list_processes()} -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. +@code{MYSQL_RES *mysql_list_processes(MYSQL *mysql)} -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()}. +@subsubheading Description -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()}. +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. -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.) +You must free the result set with @code{mysql_free_result()}. -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. +@subsubheading Return Values -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()}. +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. -After you are done with a result set, call @code{mysql_free_result()} -to free the memory used for it. +@subsubheading Errors -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. +@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 -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. +@findex @code{mysql_list_tables()} +@node mysql_list_tables, mysql_num_fields, mysql_list_processes, C API functions +@subsubsection @code{mysql_list_tables()} -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. +@code{MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)} -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. +@subsubheading Description -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()}. +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]}. -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. +You must free the result set with @code{mysql_free_result()}. -@node C API functions, C API problems, C API function overview, C -@subsection C API Function Descriptions +@subsubheading Return Values -@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. +A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. -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: +@subsubheading Errors -@example -if (result) /* correct */ - ... error ... +@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 -if (result < 0) /* incorrect */ - ... error ... +@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()} -if (result == -1) /* incorrect */ - ... error ... -@end example +@code{unsigned int mysql_num_fields(MYSQL_RES *result)} -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()}. +or -@findex @code{mysql_affected_rows()} -@node mysql_affected_rows, mysql_close, C API functions, C API functions -@subsubsection @code{mysql_affected_rows()} +@code{unsigned int mysql_num_fields(MYSQL *mysql)} -@code{my_ulonglong mysql_affected_rows(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 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()}. +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 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()}. +An unsigned integer representing the number of fields in a result set. @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 +MYSQL_RES *result; +unsigned int num_fields; +unsigned int num_rows; -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. +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 -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. +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_close()} -@node mysql_close, mysql_connect, mysql_affected_rows, C API functions -@subsubsection @code{mysql_close()} +@findex @code{mysql_num_rows()} +@node mysql_num_rows, mysql_options, mysql_num_fields, C API functions +@subsubsection @code{mysql_num_rows()} -@code{void mysql_close(MYSQL *mysql)} +@code{my_ulonglong mysql_num_rows(MYSQL_RES *result)} @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()}. + +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 -None. +The number of rows in the result set. @subsubheading Errors - None. -@findex @code{mysql_connect()} -@node mysql_connect, mysql_change_user, mysql_close, C API functions -@subsubsection @code{mysql_connect()} +@findex @code{mysql_options()} +@node mysql_options, mysql_ping, mysql_num_rows, C API functions +@subsubsection @code{mysql_options()} -@code{MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)} +@code{int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)} @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()} +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{my_bool mysql_change_user(MYSQL *mysql, const char *user, const -char *password, const char *db)} +@code{mysql_options()} should be called after @code{mysql_init()} and before +@code{mysql_connect()} or @code{mysql_real_connect()}. -@subsubheading Description +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. -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. +Possible options values: -This function was introduced in @strong{MySQL} Version 3.23.3. +@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 -@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 +Note that the group @code{client} is always read if you use +@code{MYSQL_READ_DEFAULT_FILE} or @code{MYSQL_READ_DEFAULT_GROUP}. -The @code{db} parameter may be set to @code{NULL} if you don't want to have a -default database. +The specified group in the option file may contain the following options: -@subsubheading Return values +@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 -Zero for success. Non-zero if an error occurred. +Note that @code{timeout} has been replaced by @code{connect_timeout}, but +@code{timeout} will still work for a while. -@subsubheading Errors +For more information about option files, see @ref{Option files}. -The same that you can get from @code{mysql_real_connect()}. +@subsubheading Return Values -@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 +Zero for success. Non-zero if you used an unknown option. @subsubheading Example @example -if (mysql_change_user(&mysql, "user", "password", "new_database")) +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 change user. Error: %s\n", - mysql_error(&mysql)); + fprintf(stderr, "Failed to connect to database: 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()} +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. -@code{const char *mysql_character_set_name(MYSQL *mysql)} +@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 -Returns the default character set for the current connection. +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 -The default character set +Zero if the server is alive. Non-zero if an error occurred. @subsubheading Errors -None. +@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_create_db()} -@node mysql_create_db, mysql_data_seek, mysql_character_set_name, C API functions -@subsubsection @code{mysql_create_db()} +@findex @code{mysql_query()} +@node mysql_query, mysql_real_connect, mysql_ping, C API functions +@subsubsection @code{mysql_query()} -@code{int mysql_create_db(MYSQL *mysql, const char *db)} +@code{int mysql_query(MYSQL *mysql, const char *query)} @subsubheading Description -Creates the database named by the @code{db} parameter. +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. -This function is deprecated. It is preferable to use @code{mysql_query()} -to issue a SQL @code{CREATE DATABASE} statement instead. +@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 database was created successfully. Non-zero if an error -occurred. +Zero if the query was successful. Non-zero if an error occurred. @subsubheading Errors -@table @code +@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 +@findex @code{mysql_real_connect()} +@node mysql_real_connect, mysql_real_escape_string, mysql_query, C API functions +@subsubsection @code{mysql_real_connect()} -@example -if(mysql_create_db(&mysql, "my_database")) -@{ - fprintf(stderr, "Failed to create new database. Error: %s\n", - mysql_error(&mysql)); -@} -@end example +@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)} -@findex @code{mysql_data_seek()} -@node mysql_data_seek, mysql_debug, mysql_create_db, C API functions -@subsubsection @code{mysql_data_seek()} +@subsubheading Description -@code{void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)} +@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()}. -@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 parameters are specified as follows: -The offset should be a value in the range from 0 to -@code{mysql_num_rows(result)-1}. +@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}. -@subsubheading Return Values +@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. -None. +@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}. -@subsubheading Errors -None. +@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. -@findex @code{mysql_debug()} -@node mysql_debug, mysql_drop_db, mysql_data_seek, C API functions -@subsubsection @code{mysql_debug()} +NOTE: Do not attempt to encrypt the password before calling +@code{mysql_real_connect()}; password encryption is handled automatically by +the client API. -@code{void mysql_debug(char *debug)} +@item +@code{db} is the database name. +If @code{db} is not @code{NULL}, the connection will set the default +database to this value. -@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}. +@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 -None. +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 -None. -@subsubheading Example +@table @code +@item CR_CONN_HOST_ERROR +Failed to connect to the @strong{MySQL} server. -The call shown below causes the client library to generate a trace file in -@file{/tmp/client.trace} on the client machine: +@item CR_CONNECTION_ERROR +Failed to connect to the local @strong{MySQL} server. -@example -mysql_debug("d:t:O,/tmp/client.trace"); -@end example +@item CR_IPSOCK_ERROR +Failed to create an IP socket. -@findex @code{mysql_drop_db()} -@node mysql_drop_db, mysql_dump_debug_info, mysql_debug, C API functions -@subsubsection @code{mysql_drop_db()} +@item CR_OUT_OF_MEMORY +Out of memory. -@code{int mysql_drop_db(MYSQL *mysql, const char *db)} +@item CR_SOCKET_CREATE_ERROR +Failed to create a Unix socket. -@subsubheading Description -Drops the database named by the @code{db} parameter. +@item CR_UNKNOWN_HOST +Failed to find the IP address for the hostname. -This function is deprecated. It is preferable to use @code{mysql_query()} -to issue a SQL @code{DROP DATABASE} statement instead. +@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. -@subsubheading Return Values +@item CR_NAMEDPIPEOPEN_ERROR +Failed to create a named pipe on Windows. -Zero if the database was dropped successfully. Non-zero if an error -occurred. +@item CR_NAMEDPIPEWAIT_ERROR +Failed to wait for a named pipe on Windows. -@subsubheading Errors +@item CR_NAMEDPIPESETSTATE_ERROR +Failed to get a pipe handler on Windows. -@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. +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 -if(mysql_drop_db(&mysql, "my_database")) - fprintf(stderr, "Failed to drop the database: Error: %s\n", +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 -@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. +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. -@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 +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_eof()} -@node mysql_eof, mysql_errno, mysql_dump_debug_info, C API functions -@subsubsection @code{mysql_eof()} +@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{my_bool mysql_eof(MYSQL_RES *result)} +@code{unsigned int mysql_real_escape_string(MYSQL *mysql, char *to, const char *from, unsigned int length)} @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 +This function is used to create a legal SQL string that you can use in a +SQL statement. @xref{String syntax}. -Zero if no error occurred. Non-zero if the end of the result set has been -reached. +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}). -@subsubheading Errors -None. +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 -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 +char query[1000],*end; -However, you can achieve the same effect with the standard @strong{MySQL} -error functions: +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++ = ')'; -@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 +if (mysql_real_query(&mysql,query,(unsigned int) (end - query))) @{ - fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); + fprintf(stderr, "Failed to insert row, 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}. +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 -An error code value. Zero if no error occurred. +The length of the value placed into @code{to}, not including the +terminating null character. @subsubheading Errors None. -@findex @code{mysql_error()} -@node mysql_error, mysql_escape_string, mysql_errno, C API functions -@subsubsection @code{mysql_error()} +@findex @code{mysql_real_query()} +@node mysql_real_query, mysql_reload, mysql_real_escape_string, C API functions +@subsubsection @code{mysql_real_query()} -@code{char *mysql_error(MYSQL *mysql)} +@code{int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)} @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 -@} +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. -if(mysql_error(&mysql)[0] != '\0') -@{ - // an error occurred -@} -@end example +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. -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}. +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 -A character string that describes the error. An empty string if no error -occurred. +Zero if the query was successful. Non-zero if an 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. +@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_fetch_field()} -@node mysql_fetch_field, mysql_fetch_fields, mysql_escape_string, C API functions -@subsubsection @code{mysql_fetch_field()} +@findex @code{mysql_reload()} +@node mysql_reload, mysql_row_seek, mysql_real_query, C API functions +@subsubsection @code{mysql_reload()} -@code{MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)} +@code{int mysql_reload(MYSQL *mysql)} @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()}. +Asks the @strong{MySQL} server to reload the grant tables. The +connected user must have the @strong{reload} privilege. -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. +This function is deprecated. It is preferable to use @code{mysql_query()} +to issue a SQL @code{FLUSH PRIVILEGES} statement instead. @subsubheading Return Values -The @code{MYSQL_FIELD} structure for the current column. @code{NULL} -if no columns are left. +Zero for success. Non-zero if an error occurred. @subsubheading Errors -None. - -@subsubheading Example - -@example -MYSQL_FIELD *field; -while((field = mysql_fetch_field(result))) -@{ - printf("field name %s\n", field->name); -@} -@end example +@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_fetch_fields()} -@node mysql_fetch_fields, mysql_fetch_field_direct, mysql_fetch_field, C API functions -@subsubsection @code{mysql_fetch_fields()} +@findex @code{mysql_row_seek()} +@node mysql_row_seek, mysql_row_tell, mysql_reload, C API functions +@subsubsection @code{mysql_row_seek()} -@code{MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)} +@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()}. -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. +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 -An array of @code{MYSQL_FIELD} structures for all columns of a result set. +The previous value of the row cursor. This value may be passed to a +subsequent call to @code{mysql_row_seek()}. @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()} +@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_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)} +@code{MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)} @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}. +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 @code{MYSQL_FIELD} structure for the specified column. +The current offset of the row cursor. @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()} +@findex @code{mysql_select_db()} +@node mysql_select_db, mysql_shutdown, mysql_row_tell, C API functions +@subsubsection @code{mysql_select_db()} -@code{unsigned long *mysql_fetch_lengths(MYSQL_RES *result)} +@code{int mysql_select_db(MYSQL *mysql, const char *db)} @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. +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. -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()}. +@code{mysql_select_db()} fails unless the connected user can be authenticated +as having permission to use the database. @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. +Zero for success. Non-zero 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 +@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_fetch_row()} -@node mysql_fetch_row, mysql_field_count, mysql_fetch_lengths, C API functions -@subsubsection @code{mysql_fetch_row()} +@findex @code{mysql_shutdown()} +@node mysql_shutdown, mysql_stat, mysql_select_db, C API functions +@subsubsection @code{mysql_shutdown()} -@code{MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)} +@code{int mysql_shutdown(MYSQL *mysql)} @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. +Asks the database server to shut down. The connected user must have +@strong{shutdown} privileges. @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. +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 -@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)} +@findex @code{mysql_stat()} +@node mysql_stat, mysql_store_result, mysql_shutdown, C API functions +@subsubsection @code{mysql_stat()} -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. +@code{char *mysql_stat(MYSQL *mysql)} @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()}}. +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 -An unsigned integer representing the number of fields in a result set. +A character string describing the server status. @code{NULL} if an +error occurred. @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}. +@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_field_seek()} -@node mysql_field_seek, mysql_field_tell, mysql_field_count, C API functions -@subsubsection @code{mysql_field_seek()} +@findex @code{mysql_store_result()} +@node mysql_store_result, mysql_thread_id, mysql_stat, C API functions +@subsubsection @code{mysql_store_result()} -@code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)} +@code{MYSQL_RES *mysql_store_result(MYSQL *mysql)} @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. +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}). -To seek to the beginning of a row, pass an @code{offset} value of zero. +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). -@subsubheading Return Values +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}}. -The previous value of the field cursor. +@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. -@subsubheading Errors -None. +@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). -@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_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. -@code{MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)} +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.) -@subsubheading Description +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. -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()}. +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 -The current offset of the field cursor. +A @code{MYSQL_RES} result structure with the results. @code{NULL} if +an error occurred. @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()} +@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 -@code{void mysql_free_result(MYSQL_RES *result)} +@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 -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()}. +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 -None. +The thread ID of the current connection. @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()} +@findex @code{mysql_use_result()} +@node mysql_use_result, , mysql_thread_id, C API functions +@subsubsection @code{mysql_use_result()} -@code{char *mysql_get_client_info(void)} +@code{MYSQL_RES *mysql_use_result(MYSQL *mysql)} @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. +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}). -@subsubheading Errors -None. +@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. -@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()} +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. -@code{char *mysql_get_host_info(MYSQL *mysql)} +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! -@subsubheading Description +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.) -Returns a string describing the type of connection in use, including the -server host name. +You must call @code{mysql_free_result()} once you are done with the result +set. @subsubheading Return Values -A character string representing the server host name and the connection type. +A @code{MYSQL_RES} result structure. @code{NULL} if an error occurred. @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()} +@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 -@code{unsigned int mysql_get_proto_info(MYSQL *mysql)} +@node C API problems, Thread-safe clients, C API functions, C +@subsection Common questions and problems when using the C API -@subsubheading Description +@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 -Returns the protocol version used by current connection. +@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?} -@subsubheading Return Values +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: -An unsigned integer representing the protocol version used by the current -connection. +@itemize @bullet +@item +There was a @code{malloc()} failure (for example, if the result set was too +large). -@subsubheading Errors -None. +@item +The data couldn't be read (an error occurred on the connection). -@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()} +@item +The query returned no data (for example, it was an @code{INSERT}, +@code{UPDATE}, or @code{DELETE}). +@end itemize -@code{char *mysql_get_server_info(MYSQL *mysql)} +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. -@subsubheading Description +You can test for an error by calling @code{mysql_error()} or +@code{mysql_errno()}. -Returns a string that represents the server version number. +@cindex queries, C API results +@menu +* Query results:: +* Getting unique ID:: +* C API linking problems:: +@end menu -@subsubheading Return Values +@node Query results, Getting unique ID, NULL mysql_store_result, C API problems +@subsubsection What Results Can I Get From a Query? -A character string that represents the server version number. +In addition to the result set returned by a query, you can also get the +following information: -@subsubheading Errors -None. +@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. -@findex @code{mysql_info()} -@node mysql_info, mysql_init, mysql_get_server_info, C API functions -@subsubsection @code{mysql_info()} +@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()}. -@code{char *mysql_info(MYSQL *mysql)} +@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()}}. -@subsubheading Description +@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 -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. +@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? -@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 +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. -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. +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()}. -@subsubheading Return Values +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: -A character string representing additional information about the most -recently executed query. @code{NULL} if no information is available for the -query. +@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 -@subsubheading Errors -None. +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}). -@findex @code{mysql_init()} -@node mysql_init, mysql_insert_id, mysql_info, C API functions -@subsubsection @code{mysql_init()} +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: -@code{MYSQL *mysql_init(MYSQL *mysql)} +@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 -@subsubheading Description +@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 -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. +When linking with the C API, the following errors may occur on some systems: -@subsubheading Return Values +@example +gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl -An initialized @code{MYSQL*} handle. @code{NULL} if there was -insufficient memory to allocate a new object. +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 -@subsubheading Errors -In case of insufficient memory, @code{NULL} is returned. +If this happens on your system, you must include the math library by +adding @code{-lm} to the end of the compile/link line. -@findex @code{mysql_insert_id()} -@node mysql_insert_id, mysql_kill, mysql_init, C API functions -@subsubsection @code{mysql_insert_id()} +@cindex clients, thread-safe +@cindex thread-safe clients +@node Thread-safe clients, , C API problems, C +@subsection How to Make a Thread-safe Client -@code{my_ulonglong mysql_insert_id(MYSQL *mysql)} +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. -@subsubheading Description +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. -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. +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. -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. +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. -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. +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! -@subsubheading Return Values +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.) -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. +To make @code{mysql_real_connect()} thread safe, you must recompile the +client library with this command: -@subsubheading Errors -None. +@example +shell> ./configure --with-thread-safe-client +@end example -@findex @code{mysql_kill()} -@node mysql_kill, mysql_list_dbs, mysql_insert_id, C API functions -@subsubsection @code{mysql_kill()} +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: -@code{int mysql_kill(MYSQL *mysql, unsigned long pid)} +@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 -@subsubheading Description +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. -Asks the server to kill the thread specified by @code{pid}. +@cindex APIs, Perl +@cindex Perl API +@node Perl, Eiffel, C, Clients +@section MySQL Perl API -@subsubheading Return Values +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. -Zero for success. Non-zero if an error occurred. +@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 -@subsubheading Errors +@cindex @code{DBI} interface +@node DBI with DBD, Perl DBI Class, Perl, Perl +@subsection @code{DBI} with @code{DBD::mysql} -@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 +@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}. -@findex @code{mysql_list_dbs()} -@node mysql_list_dbs, mysql_list_fields, mysql_kill, C API functions -@subsubsection @code{mysql_list_dbs()} +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 -@code{MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)} +Note that if you want to use transactions with Perl, you need to have +@code{Msql-Mysql-modules} version 1.2216 or newer. -@subsubheading Description +Installation instructions for @strong{MySQL} Perl support are given in +@ref{Perl support}. -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]}. +@cindex @code{DBI} Perl module +@node Perl DBI Class, DBI-info, DBI with DBD, Perl +@subsection The @code{DBI} Interface -You must free the result set with @code{mysql_free_result()}. +@noindent +@strong{Portable DBI Methods} -@subsubheading Return Values +@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 -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. +@noindent +@strong{MySQL-specific Methods} -@subsubheading Errors +@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 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 +@item $dbh +Database handle -@findex @code{mysql_list_fields()} -@node mysql_list_fields, mysql_list_processes, mysql_list_dbs, C API functions -@subsubsection @code{mysql_list_fields()} +@item $sth +Statement handle -@code{MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)} +@item $rc +Return code (often a status) -@subsubheading Description +@item $rv +Return value (often a row count) +@end table -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]}. +@noindent +@strong{Portable DBI Methods} -Note that it's recommended that you use @code{SHOW COLUMNS FROM tbl_name} -instead of @code{mysql_list_fields()}. +@table @code -You must free the result set with @code{mysql_free_result()}. +@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}). -@subsubheading Return Values +As of @code{Msql-Mysql-modules} Version 1.2009, +the @code{$data_source} value allows certain modifiers: -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. +@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}. -@subsubheading Errors +@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. -@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 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 -@findex @code{mysql_list_processes()} -@node mysql_list_processes, mysql_list_tables, mysql_list_fields, C API functions -@subsubsection @code{mysql_list_processes()} +Multiple modifiers may be given; each must be preceded by a semicolon. -@code{MYSQL_RES *mysql_list_processes(MYSQL *mysql)} +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: -@subsubheading Description +@example +$dbh = DBI->connect("DBI:mysql:$database" + . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf", + $user, $password); +@end example -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. +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: -You must free the result set with @code{mysql_free_result()}. +@example +$dbh = DBI->connect("DBI:mysql:$database" + . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf" + . ";mysql_read_default_group=perl", + $user, $password); +@end example -@subsubheading Return Values +@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 -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. +@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 -@subsubheading Errors +@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 -@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 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 -@findex @code{mysql_list_tables()} -@node mysql_list_tables, mysql_num_fields, mysql_list_processes, C API functions -@subsubsection @code{mysql_list_tables()} +Generally the 'do' statement is MUCH faster (and is preferable) +than prepare/execute for statements that don't contain parameters. -@code{MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)} +@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 -@subsubheading Description +@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 -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]}. +@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 -You must free the result set with @code{mysql_free_result()}. +@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 -@subsubheading Return Values +@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 -A @code{MYSQL_RES} result set for success. @code{NULL} if an error occurred. +@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 -@subsubheading Errors +@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)}. -@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()} +@noindent +@strong{MySQL-specific Methods} -@code{unsigned int mysql_num_fields(MYSQL_RES *result)} +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: -or +@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 -@code{unsigned int mysql_num_fields(MYSQL *mysql)} +As an alternative, you can use @code{$dbh->@{'mysql_insertid'@}}. -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. +@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 -@subsubheading Description +@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 -Returns the number of columns in a result set. +@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 -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. +@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 -@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. +@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 -@subsubheading Return Values +@code{is_not_null} is deprecated; it is preferable to use the +@code{NULLABLE} attribute (described above), because that is a DBI standard. -An unsigned integer representing the number of fields in a result set. +@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: -@subsubheading Errors -None. +@example +$lengths = $sth->@{length@}; +$max_lengths = $sth->@{max_length@}; +@end example -@subsubheading 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 -MYSQL_RES *result; -unsigned int num_fields; -unsigned int num_rows; +$tables = $sth->@{table@}; +@end example -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); - @} - @} -@} +@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 -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. +@end table -@findex @code{mysql_num_rows()} -@node mysql_num_rows, mysql_options, mysql_num_fields, C API functions -@subsubsection @code{mysql_num_rows()} +@cindex @code{DBI/DBD} +@node DBI-info, , Perl DBI Class, Perl +@subsection More @code{DBI}/@code{DBD} Information -@code{my_ulonglong mysql_num_rows(MYSQL_RES *result)} +You can use the @code{perldoc} command to get more information about +@code{DBI}. -@subsubheading Description +@example +perldoc DBI +perldoc DBI::FAQ +perldoc DBD::mysql +@end example -Returns the number of rows in the result set. +You can also use the @code{pod2man}, @code{pod2html}, etc., tools to +translate to other formats. -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. +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 -@subsubheading Return Values +@cindex Eiffel Wrapper +@cindex wrappers, Eiffel +@node Eiffel, Java, Perl, Clients +@section MySQL Eiffel wrapper -The number of rows in the result set. +The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} +contains an Eiffel wrapper written by Michael Ravits. -@subsubheading Errors -None. +You can also find this at: +@url{http://www.netpedia.net/hosting/newplayer/} -@findex @code{mysql_options()} -@node mysql_options, mysql_ping, mysql_num_rows, C API functions -@subsubsection @code{mysql_options()} +@cindex Java connectivity +@cindex JDBC +@node Java, PHP, Eiffel, Clients +@section MySQL Java Connectivity (JDBC) -@code{int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)} +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. -@subsubheading Description +@cindex PHP API +@node PHP, Cplusplus, Java, Clients +@section MySQL PHP API -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. +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. -@code{mysql_options()} should be called after @code{mysql_init()} and before -@code{mysql_connect()} or @code{mysql_real_connect()}. +The distribution and documentation are available at the +@uref{http://www.php.net/, PHP web site}. -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. +@menu +* PHP problems:: Common problems with MySQL and PHP +@end menu -Possible options values: +@node PHP problems, , PHP, PHP +@subsection Common Problems with MySQL and PHP -@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 +@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 -Note that the group @code{client} is always read if you use -@code{MYSQL_READ_DEFAULT_FILE} or @code{MYSQL_READ_DEFAULT_GROUP}. +@cindex C++ APIs +@node Cplusplus, Python, PHP, Clients +@section MySQL C++ APIs -The specified group in the option file may contain the following options: +Two APIs are available in the @strong{MySQL} +@uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory}. -@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 +@cindex Python APIs +@node Python, Tcl, Cplusplus, Clients +@section MySQL Python APIs -Note that @code{timeout} has been replaced by @code{connect_timeout}, but -@code{timeout} will still work for a while. +The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} +contains a Python interface written by Joseph Skinner. -For more information about option files, see @ref{Option files}. +You can also use the Python interface to iODBC to access a +@strong{MySQL} server. +@uref{http://starship.skyport.net/~lemburg/,mxODBC} -@subsubheading Return Values +@cindex Tcl APIs +@node Tcl, , Python, Clients +@section MySQL Tcl APIs -Zero for success. Non-zero if you used an unknown option. +@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. -@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 Problems, Environment variables, Clients, Top +@appendix Problems and Common Errors -@findex @code{mysql_ping()} -@node mysql_ping, mysql_query, mysql_options, C API functions -@subsubsection @code{mysql_ping()} +@cindex problems, common errors +@cindex errors, common -@code{int mysql_ping(MYSQL *mysql)} +@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 -@subsubheading Description +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. -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. +@node What is crashing, Crashing, Problems, Problems +@appendixsec How to Determine What Is Causing Problems -@subsubheading Return Values +When you run into problems, the first thing you should do is to find out +which program / piece of equipment is causing problems: -Zero if the server is alive. Non-zero if an error occurred. +@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 -@subsubheading Errors +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. -@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 +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. -@findex @code{mysql_query()} -@node mysql_query, mysql_real_connect, mysql_ping, C API functions -@subsubsection @code{mysql_query()} +@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}. -@code{int mysql_query(MYSQL *mysql, const char *query)} +@item +If you don't think you have hardware problems, you should try to find +out which program is causing problems. -@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. +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. -@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.) +@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 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}}. +If a program fails, it's always useful to know: -@subsubheading Return Values +@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 -Zero if the query was successful. Non-zero if an error occurred. +When sending a bug report, you should of follow the outlines +described in this manual. @xref{Asking questions}. -@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 Crashing, Link errors, What is crashing, Problems +@appendixsec What to Do if MySQL Keeps Crashing -@findex @code{mysql_real_connect()} -@node mysql_real_connect, mysql_real_escape_string, mysql_query, C API functions -@subsubsection @code{mysql_real_connect()} +@cindex crash, repeated -@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)} +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. -@subsubheading Description +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}. -@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()}. +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 parameters are specified as follows: +The above means that normally you shouldn't get corrupted tables unless: @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}. - +Someone/something killed @code{mysqld} or the machine in the middle +of an update. @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. - +You have found a bug in @code{mysqld} that caused it to die in the +middle of an update. @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}. +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 -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. +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}. -NOTE: Do not attempt to encrypt the password before calling -@code{mysql_real_connect()}; password encryption is handled automatically by -the client API. +@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 -@code{db} is the database name. -If @code{db} is not @code{NULL}, the connection will set the default -database to this value. +Try to make a test case that we can use to reproduce the problem. +@xref{Reproduceable test case}. @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. +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 -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. +Try @code{fork_test.pl} and @code{fork2_test.pl}. @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: +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}. -@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 +@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. -@subsubheading Return Values +@item +Have you applied the latest patches for your operating system? -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. +@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.) -@subsubheading Errors +@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. -@table @code -@item CR_CONN_HOST_ERROR -Failed to connect to the @strong{MySQL} server. +@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 CR_CONNECTION_ERROR -Failed to connect to the local @strong{MySQL} server. +@item +Try the following: +@enumerate +@item +Start @code{mysqld} from @code{gdb} (or in another debugger). +@xref{Using gdb on mysqld}. -@item CR_IPSOCK_ERROR -Failed to create an IP socket. +@item +Run your test scripts. -@item CR_OUT_OF_MEMORY -Out of memory. +@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: -@item CR_SOCKET_CREATE_ERROR -Failed to create a Unix socket. +@example +backtrace +info local +up +info local +up +info local +@end example -@item CR_UNKNOWN_HOST -Failed to find the IP address for the hostname. +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 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 +Try to simulate your application with a Perl script to force +@strong{MySQL} to crash or misbehave. -@item CR_NAMEDPIPEOPEN_ERROR -Failed to create a named pipe on Windows. +@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! -@item CR_NAMEDPIPEWAIT_ERROR -Failed to wait for a named pipe on Windows. +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 -@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}. +@node Link errors, Common errors, Crashing, Problems +@appendixsec Problems When Linking with the MySQL Client Library -@end table +@cindex linking, errors +@cindex errors, linking +@cindex problems, linking -@subsubheading Example +If you are linking your program and you get errors for unreferenced +symbols that start with @code{mysql_}, like the following: @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)); -@} +/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 -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}. +you should be able to solve this by adding @code{-Lpath-to-the-mysql-library +-lmysqlclient} @strong{LAST} on your link line. -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}). +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! -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. +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! -@subsubheading Example +If you get @code{undefined reference} errors for functions that don't +exist on your system, like the following: @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)); -@} +mf_format.o(.text+0x201): undefined reference to `__lxstat' @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. +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}. -@subsubheading Return Values +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 length of the value placed into @code{to}, not including the -terminating null character. +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: -@subsubheading Errors -None. +@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 -@findex @code{mysql_real_query()} -@node mysql_real_query, mysql_reload, mysql_real_escape_string, C API functions -@subsubsection @code{mysql_real_query()} +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! -@code{int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)} -@subsubheading Description +@node Common errors, Full disk, Link errors, Problems +@appendixsec Some Common Errors When Using MySQL -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. +@cindex errors, list of -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. +@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 -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 +This section lists some errors that users frequently get. You will find +descriptions of the errors, and how to solve the problem here. -Zero if the query was successful. Non-zero if an error occurred. -@subsubheading Errors +@node Error Access denied, Gone away, Common errors, Common errors +@appendixsubsec @code{Access denied} Error -@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 +@cindex errors, access denied +@cindex problems, access denied errors +@cindex access denied errors -@findex @code{mysql_reload()} -@node mysql_reload, mysql_row_seek, mysql_real_query, C API functions -@subsubsection @code{mysql_reload()} +@xref{Privileges}, and especially. @xref{Access denied}. -@code{int mysql_reload(MYSQL *mysql)} -@subsubheading Description +@node Gone away, Can not connect to server, Error Access denied, Common errors +@appendixsubsec @code{MySQL server has gone away} Error -Asks the @strong{MySQL} server to reload the grant tables. The -connected user must have the @strong{reload} privilege. +This section also covers the related @code{Lost connection to server +during query} error. -This function is deprecated. It is preferable to use @code{mysql_query()} -to issue a SQL @code{FLUSH PRIVILEGES} statement instead. +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}. -@subsubheading Return Values +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. -Zero for success. Non-zero if an error occurred. +You can check that the @strong{MySQL} hasn't died by executing +@code{mysqladmin version} and examining the uptime. -@subsubheading Errors +If you have a script, you just have to issue the query again for the client +to do an automatic reconnection. -@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 +You normally can get the following error codes in this case +(which one you get is OS-dependent): -@findex @code{mysql_row_seek()} -@node mysql_row_seek, mysql_row_tell, mysql_reload, C API functions -@subsubsection @code{mysql_row_seek()} +@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 -@code{MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)} +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! -@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. +@node Can not connect to server, Blocked host, Gone away, Common errors +@appendixsubsec @code{Can't connect to [local] MySQL server} error -@subsubheading Return Values +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}. -The previous value of the row cursor. This value may be passed to a -subsequent call to @code{mysql_row_seek()}. +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. -@subsubheading Errors -None. +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. -@findex @code{mysql_row_tell()} -@node mysql_row_tell, mysql_select_db, mysql_row_seek, C API functions -@subsubsection @code{mysql_row_tell()} +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}. -@code{MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)} +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): -@subsubheading Description +@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 -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()}. +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. -You should use @code{mysql_row_tell()} only after @code{mysql_store_result()}, -not after @code{mysql_use_result()}. +Here are some reasons the @code{Can't connect to local MySQL server} +error might occur: -@subsubheading Return Values +@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: -The current offset of the row cursor. +@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 -@subsubheading Errors -None. +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 : -@findex @code{mysql_select_db()} -@node mysql_select_db, mysql_shutdown, mysql_row_tell, C API functions -@subsubsection @code{mysql_select_db()} +@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 -@code{int mysql_select_db(MYSQL *mysql, const char *db)} -@subsubheading Description +@node Blocked host, Too many connections, Can not connect to server, Common errors +@appendixsubsec @code{Host '...' is blocked} Error -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. +If you get an error like this: -@code{mysql_select_db()} fails unless the connected user can be authenticated -as having permission to use the database. +@example +Host 'hostname' is blocked because of many connection errors. +Unblock with 'mysqladmin flush-hosts' +@end example -@subsubheading Return Values +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}. -Zero for success. Non-zero if an error occurred. +By default, @code{mysqld} blocks a host after 10 connection errors. +You can easily adjust this by starting the server like this: -@subsubheading Errors +@example +shell> safe_mysqld -O max_connect_errors=10000 & +@end example -@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 +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! -@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)} +@node Too many connections, Non-transactional tables, Blocked host, Common errors +@appendixsubsec @code{Too many connections} Error -@subsubheading Description +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. -Asks the database server to shut down. The connected user must have -@strong{shutdown} privileges. +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. -@subsubheading Return Values +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}. -Zero for success. Non-zero if an error occurred. +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. -@subsubheading Errors +@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 -@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 +@cindex Non-transactional tables -@findex @code{mysql_stat()} -@node mysql_stat, mysql_store_result, mysql_shutdown, C API functions -@subsubsection @code{mysql_stat()} +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. -@code{char *mysql_stat(MYSQL *mysql)} +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}. -@subsubheading Description +You can check the table type for a table by doing: -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. +@code{SHOW TABLE STATUS LIKE 'table_name'}. @xref{SHOW TABLE STATUS}. -@subsubheading Return Values +You can check the extensions your @code{mysqld} binary supports by doing: -A character string describing the server status. @code{NULL} if an -error occurred. +@code{show variables like 'have_%'}. @xref{SHOW VARIABLES}. -@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 Out of memory, Packet too large, Non-transactional tables, Common errors +@appendixsubsec @code{Out of memory} Error -@findex @code{mysql_store_result()} -@node mysql_store_result, mysql_thread_id, mysql_stat, C API functions -@subsubsection @code{mysql_store_result()} +If you issue a query and get something like the following error: -@code{MYSQL_RES *mysql_store_result(MYSQL *mysql)} +@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 -@subsubheading Description +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. -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}). +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). -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}}. +@node Packet too large, Communication errors, Out of memory, Common errors +@appendixsubsec @code{Packet too large} Error -@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. +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. -@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). +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}. -@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. +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. -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. +@node Communication errors, Full table, Packet too large, Common errors +@appendixsubsec Communication Errors / Aborted Connection -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. +@cindex aborted clients +@cindex aborted connection +@cindex connection, aborted -You must call @code{mysql_free_result()} once you are done with the result -set. +Starting with @code{MySQL 3.23.40} you only get the @code{Aborted +connection} error of you start @code{mysqld} with @code{--warnings}. -@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}. +If you find errors like the following in your error log. -@subsubheading Return Values +@example +010301 14:38:23 Aborted connection 854 to db: 'users' user: 'josh' +@end example -A @code{MYSQL_RES} result structure with the results. @code{NULL} if -an error occurred. +@xref{Error log}. -@subsubheading Errors +This means that something of the following has happened: -@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 +@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 -@findex @code{mysql_thread_id()} -@node mysql_thread_id, mysql_use_result, mysql_store_result, C API functions -@subsubsection @code{mysql_thread_id()} +When the above happens, the server variable @code{Aborted_clients} is +incremented. -@code{unsigned long mysql_thread_id(MYSQL *mysql)} +The server variable @code{Aborted_connects} is incremented when: -@subsubheading Description +@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 -Returns the thread ID of the current connection. This value can be used as -an argument to @code{mysql_kill()} to kill the thread. +Note that the above could indicate that someone is trying to break into +your database! -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. +@xref{SHOW VARIABLES}. -@subsubheading Return Values +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 -The thread ID of the current connection. -@subsubheading Errors -None. +@node Full table, Cannot create, Communication errors, Common errors +@appendixsubsec @code{The table is full} Error -@findex @code{mysql_use_result()} -@node mysql_use_result, , mysql_thread_id, C API functions -@subsubsection @code{mysql_use_result()} +@cindex table is full -@code{MYSQL_RES *mysql_use_result(MYSQL *mysql)} +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}}. -@subsubheading Description +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. -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}). +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}. -@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. +@node Cannot create, Commands out of sync, Full table, Common errors +@appendixsubsec @code{Can't create/write to file} Error -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! +@cindex can't create/write to file -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.) +If you get an error for some queries of type: -You must call @code{mysql_free_result()} once you are done with the result -set. +@example +Can't create/write to file '\\sqla3fe_0.ism'. +@end example -@subsubheading Return Values +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: -A @code{MYSQL_RES} result structure. @code{NULL} if an error occurred. +@example +[mysqld] +tmpdir=C:/temp +@end example -@subsubheading Errors +assuming that the @file{c:\\temp} directory exists. @xref{Option files}. -@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 +Check also the error code that you get with @code{perror}. One reason +may also be a disk full error; -@node C API problems, Thread-safe clients, C API functions, C -@subsection Common questions and problems when using the C API +@example +shell> perror 28 +Error code 28: No space left on device +@end example -@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?} +@node Commands out of sync, Ignoring user, Cannot create, Common errors +@appendixsubsec @code{Commands out of sync} Error in Client -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: +@cindex commands out of sync -@itemize @bullet -@item -There was a @code{malloc()} failure (for example, if the result set was too -large). +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! -@item -The data couldn't be read (an error occurred on the connection). +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. -@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. +@node Ignoring user, Cannot find table, Commands out of sync, Common errors +@appendixsubsec @code{Ignoring user} Error -You can test for an error by calling @code{mysql_error()} or -@code{mysql_errno()}. +If you get the following error: -@cindex queries, C API results -@menu -* Query results:: -* Getting unique ID:: -* C API linking problems:: -@end menu +@code{Found wrong password for user: 'some_user@@some_host'; Ignoring user} -@node Query results, Getting unique ID, NULL mysql_store_result, C API problems -@subsubsection What Results Can I Get From a Query? +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. -In addition to the result set returned by a query, you can also get the -following information: +Possible causes of and fixes for this problem: @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. +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 -@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()}. +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 -@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()}}. +@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: -@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. +@example +mysql> update user set password=PASSWORD('your password') + where user='XXX'; +@end example @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()}. +@node Cannot find table, Cannot initialize character set, Ignoring user, Common errors +@appendixsubsec @code{Table 'xxx' doesn't exist} Error -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: +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}. -@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 +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!) -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}). +You can check which tables you have in the current database with +@code{SHOW TABLES}. @xref{SHOW, , @code{SHOW}}. -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 Cannot initialize character set, , Cannot find table, Common errors +@appendixsubsec @code{Can@'t initialize character set xxx} error. -@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 +@cindex multibyte character sets -When linking with the C API, the following errors may occur on some systems: +If you get an error like: @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 +MySQL Connection Failed: Can't initialize character set xxx @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. +This means one of the following things: -@cindex clients, thread-safe -@cindex thread-safe clients -@node Thread-safe clients, , C API problems, C -@subsection How to Make a Thread-safe Client +@itemize @bullet +@item +The character set is a multi-byte character set and you have not support +for the character set in the 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 this case you need to recompile the client with +@code{--with-charset=xxx} or with @code{--with-extra-charsets=xxx}. +@xref{configure options}. -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. +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}. -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. +@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. -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. +In this case you need to: -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! +@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 -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: +@node Full disk, Temporary files, Common errors, Problems +@appendixsec How MySQL Handles a Full Disk -@example -shell> ./configure --with-thread-safe-client -@end example +@cindex full disk +@cindex disk full -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: +@noindent +When a disk-full condition occurs, @strong{MySQL} does 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. +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 -Many threads can access different result sets that are retrieved with -@code{mysql_store_result()}. +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 -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()}. +To continue, you only have to free enough disk space to insert all records. @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. +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 -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. +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 -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. +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. -@cindex APIs, Perl -@cindex Perl API -@node Perl, Eiffel, C, Clients -@section MySQL Perl API +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). -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 Temporary files, Problems with mysql.sock, Full disk, Problems +@appendixsec Where MySQL Stores Temporary Files -@cindex @code{DBI} interface -@node DBI with DBD, Perl DBI Class, Perl, Perl -@subsection @code{DBI} with @code{DBD::mysql} +@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}. -@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}. +@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: -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} +(length of what is sorted + sizeof(database pointer)) +* number of matched rows +* 2 @end example -For more information on Object Oriented Programming -(OOP) as defined in Perl5, see the Perl OOP page: + +@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 -@uref{http://language.perl.com/info/documentation.html} +shell> chmod +t /tmp @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. +This will protect your @file{/tmp} file system so that files can be deleted +only by their owners or the superuser (@code{root}). -Installation instructions for @strong{MySQL} Perl support are given in -@ref{Perl support}. +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 @code{DBI} Perl module -@node Perl DBI Class, DBI-info, DBI with DBD, Perl -@subsection The @code{DBI} Interface -@noindent -@strong{Portable DBI Methods} +@node Changing MySQL user, Resetting permissions, Problems with mysql.sock, Problems +@appendixsec How to Run MySQL As a Normal User -@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 +@cindex starting, @code{mysqld} +@cindex @code{mysqld}, starting -@noindent -@strong{MySQL-specific Methods} +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: -@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 +@enumerate +@item +Stop the server if it's running (use @code{mysqladmin shutdown}). -The Perl methods are described in more detail in the following sections. -Variables used for method return values have these meanings: +@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): -@table @code -@item $dbh -Database handle +@example +shell> chown -R user_name /path/to/mysql/datadir +@end example -@item $sth -Statement handle +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 $rc -Return code (often a status) +@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 $rv -Return value (often a row count) -@end table +@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: -@noindent -@strong{Portable DBI Methods} +@example +[mysqld] +user=user_name +@end example +@end enumerate -@table @code +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: -@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); +kill `cat /mysql-data-directory/hostname.pid` @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}. +You must be either the Unix @code{root} user or the same user the server +runs as to do this. -@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 +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 -@item mysql_compression=1 -Use compressed communication between the client and server (@strong{MySQL} -Version 3.22.3 or later). +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}. -@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. +@node File permissions , Not enough file handles, Resetting permissions, Problems +@appendixsec Problems with File Permissions -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: +@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 -$dbh = DBI->connect("DBI:mysql:$database" - . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf", - $user, $password); +ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13) @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: +@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 -$dbh = DBI->connect("DBI:mysql:$database" - . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf" - . ";mysql_read_default_group=perl", - $user, $password); +shell> UMASK=384 # = 600 in octal +shell> export UMASK +shell> /path/to/safe_mysqld & @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 +@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: -@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"; +shell> UMASK_DIR=504 # = 770 in octal +shell> export UMASK_DIR +shell> /path/to/safe_mysqld & @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 +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. -@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 +@xref{Environment variables}. -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 +@node Not enough file handles, Using DATE, File permissions , Problems +@appendixsec File Not Found -@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 +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: -@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); -@} +shell> perror 23 +File table overflow +shell> perror 24 +Too many open files +shell> perror 11 +Resource temporarily unavailable @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 +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}. -@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 +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). -@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 +@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}. -@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 +@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. -@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 +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 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: +@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 -@@dbs = DBI->data_sources("mysql"); +mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05'; @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: +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 -$sth->@{'ChopBlanks'@} =1; +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 -@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: +@noindent +However, the following will not work: + @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 +mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0; @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)}. +@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. -@end table +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. -@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: +@node Timezone problems, Case sensitivity, Using DATE, Problems +@appendixsec Time Zone Problems -@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 +@cindex timezone problems +@cindex problems, timezone -As an alternative, you can use @code{$dbh->@{'mysql_insertid'@}}. +@tindex TZ environment variable +@tindex Environment variable, TZ -@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 +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}. -@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 +@node Case sensitivity, Problems with NULL, Timezone problems, Problems +@appendixsec Case Sensitivity in Searches -@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 +@cindex case sensitivity, in searches +@cindex searching, and case-sensitivity +@cindex Chinese +@cindex Big5 Chinese character encoding -@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 +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"}. -@code{is_not_null} is deprecated; it is preferable to use the -@code{NULLABLE} attribute (described above), because that is a DBI standard. +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! -@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: +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. -@example -$lengths = $sth->@{length@}; -$max_lengths = $sth->@{max_length@}; -@end example +If you want a column always to be treated in case-sensitive fashion, +declare it as @code{BINARY}. @xref{CREATE TABLE, , @code{CREATE TABLE}}. -@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 +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. -@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: +@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 -$types = $sth->@{type@}; +mysql> INSERT INTO my_table (phone) VALUES (NULL); +mysql> INSERT INTO my_table (phone) VALUES (""); @end example -@end table - -@cindex @code{DBI/DBD} -@node DBI-info, , Perl DBI Class, Perl -@subsection More @code{DBI}/@code{DBD} Information +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''. -You can use the @code{perldoc} command to get more information about -@code{DBI}. +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 -perldoc DBI -perldoc DBI::FAQ -perldoc DBD::mysql +mysql> SELECT NULL,1+NULL,CONCAT('Invisible',NULL); @end example -You can also use the @code{pod2man}, @code{pod2html}, etc., tools to -translate to other formats. +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: -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} +mysql> SELECT * FROM my_table WHERE phone = NULL; @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/} +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: -@cindex Java connectivity -@cindex JDBC -@node Java, PHP, Eiffel, Clients -@section MySQL Java Connectivity (JDBC) +@example +mysql> SELECT * FROM my_table WHERE phone IS NULL; +mysql> SELECT * FROM my_table WHERE phone = ""; +@end example -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. +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. -@cindex PHP API -@node PHP, Cplusplus, Java, Clients -@section MySQL PHP API +@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}}. -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. +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. -The distribution and documentation are available at the -@uref{http://www.php.net/, PHP web site}. +To help with @code{NULL} handling, you can use the @code{IS NULL} and +@code{IS NOT NULL} operators and the @code{IFNULL()} function. -@menu -* PHP problems:: Common problems with MySQL and PHP -@end menu +@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 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 Problems with alias, Deleting from related tables, Problems with NULL, Problems +@appendixsec Problems with @code{alias} -@cindex C++ APIs -@node Cplusplus, Python, PHP, Clients -@section MySQL C++ APIs +@tindex alias -Two APIs are available in the @strong{MySQL} -@uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory}. +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: -@cindex Python APIs -@node Python, Tcl, Cplusplus, Clients -@section MySQL Python APIs +@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 -The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} -contains a Python interface written by Joseph Skinner. +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}: -You can also use the Python interface to iODBC to access a -@strong{MySQL} server. -@uref{http://starship.skyport.net/~lemburg/,mxODBC} +@example +SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id; +@end example -@cindex Tcl APIs -@node Tcl, , Python, Clients -@section MySQL Tcl APIs +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. -@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 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 -@cindex internals -@cindex threads -@node MySQL internals, Environment variables, Clients, Top -@chapter MySQL Internals +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: -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}. +@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 -@menu -* MySQL threads:: MySQL threads -* MySQL test suite:: MySQL test suite -@end menu +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 MySQL threads, MySQL test suite, MySQL internals, MySQL internals -@section MySQL Threads +@node No matching rows, ALTER TABLE problems, Deleting from related tables, Problems +@appendixsec Solving Problems with No Matching Rows -The @strong{MySQL} server creates the following threads: +@cindex no matching rows +@cindex rows, matching problems -@itemize @bullet +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 -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. +Test the query with @code{EXPLAIN} and check if you can find something that is +obviously wrong. @xref{EXPLAIN, , @code{EXPLAIN}}. @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. +Select only those fields that are used in the @code{WHERE} clause. @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. +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 -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. +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 one uses the @code{--flush_time=#} option, a dedicated thread is created -to flush all tables at the given interval. +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: -@item -Every connection has its own thread. +@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 -@item -Every different table on which one uses @code{INSERT DELAYED} gets its -own thread. +In most cases, changing the @code{FLOAT} to a @code{DOUBLE} will fix this! @item -If you use @code{--master-host}, a slave replication thread will be -started to read and apply updates from the master. -@end itemize +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. -@code{mysqladmin processlist} only shows the connection, @code{INSERT DELAYED}, -and replication threads. +Test that you still have your problem by doing: -@cindex mysqltest, MySQL Test Suite -@cindex testing mysqld, mysqltest -@node MySQL test suite, , MySQL threads, MySQL internals -@section MySQL Test Suite +@example +shell> mysqladmin create test2 +shell> mysql test2 < query.sql +@end example -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. +Post the test file using @code{mysqlbug} to @email{mysql@@lists.mysql.com}. +@end enumerate -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 ALTER TABLE problems, Change column order, No matching rows, Problems +@appendixsec Problems with @code{ALTER TABLE}. -@node running mysqltest, extending mysqltest, MySQL test suite, MySQL test suite -@subsection Running the MySQL Test Suite +@tindex ALTER TABLE -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}. +@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 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. +If @code{ALTER TABLE} dies with an error like this: -You can run one individual test case with -@code{mysql-test/mysql-test-run test_name}. +@example +Error on rename of './database/name.frm' to './database/B-a.frm' (Errcode: 17) +@end example -If one test fails, you should test running @code{mysql-test-run} with -the @code{--force} option to check if any other tests fails. +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.) -@node extending mysqltest, Reporting mysqltest bugs, running mysqltest, MySQL test suite -@subsection Extending the MySQL Test Suite +@code{ALTER TABLE} works the following way: -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 @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 -@itemize -@item -The tests are located in @code{mysql-test/t/*.test} +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. -@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. +@node Change column order, Temporary table problems, ALTER TABLE problems, Problems +@appendixsec How To Change the Order of Columns in a Table -@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. +@cindex reordering, columns +@cindex columns, changing +@cindex changing, column order +@cindex tables, changing column order -@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{','}. +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: -@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. +@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: -@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; -@} +SELECT col_name1, col_name3, col_name2 FROM tbl_name; @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. +will return columns in the order @code{col_name1}, @code{col_name3}, @code{col_name2}. -@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}. +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 -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} +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 -@end itemize -@node Reporting mysqltest bugs, , extending mysqltest, MySQL test suite -@subsection Reporting bugs in the MySQL Test Suite +@node Temporary table problems, , Change column order, Problems +@appendixsec TEMPORARY TABLE problems -If your @strong{MySQL} version doesn't pass the test suite you should -do the following: +@cindex temporary tables, problems + +The following are a list of the limitations with @code{TEMPORARY TABLES}. @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. +A temporary table can only be of type @code{HEAP}, @code{ISAM} or +@code{MyISAM}. @item -If a test in the test suite fails, check if the test fails also when run -by its own: +You can't use temporary tables more than once in the same query. +For example, the following doesn't work. @example -cd mysql-test -mysql-test-run --local test-name +select * from temporary_table, temporary_table as t2; @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. - +We plan to fix the above in 4.0. @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 ! +You can't use @code{RENAME} on a @code{TEMPORARY} table. +Note that @code{ALTER TABLE org_name RENAME new_name} works! -@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. +We plan to fix the above in 4.0. +@end itemize -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 @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). -- cgit v1.2.1 From df0ae66008fa960478e4fbf8befc90cd5d4e9564 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Aug 2001 23:40:37 -0500 Subject: DocTOC Chapter 8 Complete! --- Docs/manual.texi | 3284 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 1703 insertions(+), 1581 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,1037 +37214,662 @@ Finland -@node Extending MySQL, ODBC, Table types, Top -@chapter Extending MySQL +@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 -* Adding functions:: -* Adding procedures:: -* MySQL internals:: +* 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 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 PHP, Perl, Clients, Clients +@section MySQL PHP API -There are two ways to add new functions to @strong{MySQL}: +@cindex PHP API -@itemize @bullet -@item You can add the function through the user-definable function (UDF) -interface. User-definable functions are added and removed dynamically using -the @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements. -@xref{CREATE FUNCTION, , @code{CREATE FUNCTION}}. +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. -@item You can add the function as a native (built in) @strong{MySQL} function. -Native functions are compiled into the @code{mysqld} server and become -available on a permanent basis. -@end itemize +The distribution and documentation are available at the +@uref{http://www.php.net/, PHP web site}. -Each method has advantages and disadvantages: +@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 -If you write a user-definable function, you must install the object file -in addition to the server itself. If you compile your function into the -server, you don't need to do that. -@item -You can add UDFs to a binary @strong{MySQL} distribution. Native functions -require you to modify a source distribution. -@item -If you upgrade your @strong{MySQL} distribution, you can continue to use your -previously installed UDFs. For native functions, you must repeat your -modifications each time you upgrade. +@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 -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 Perl, ODBC, PHP, Clients +@section MySQL Perl API +@cindex APIs, Perl +@cindex Perl API -@node CREATE FUNCTION, Adding UDF, Adding functions, Adding functions -@subsection @code{CREATE FUNCTION/DROP FUNCTION} Syntax +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. -@findex CREATE FUNCTION -@findex DROP FUNCTION -@findex UDF functions -@findex User-defined functions -@findex Functions, user-defined +@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 -@example -CREATE [AGGREGATE] FUNCTION function_name RETURNS @{STRING|REAL|INTEGER@} - SONAME shared_library_name -DROP FUNCTION function_name -@end example +@node DBI with DBD, Perl DBI Class, Perl, Perl +@subsection @code{DBI} with @code{DBD::mysql} -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()}. +@cindex @code{DBI} interface -@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{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}. -@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. +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 -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}.) +Note that if you want to use transactions with Perl, you need to have +@code{Msql-Mysql-modules} version 1.2216 or newer. -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). +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 -@node Adding UDF, Adding native function, CREATE FUNCTION, Adding functions -@subsection Adding a New User-definable Function +@cindex @code{DBI} Perl module -@cindex adding, user-definable functions -@cindex user-defined functions, adding -@cindex functions, user-definable, adding +@noindent +@strong{Portable DBI Methods} -@menu -* UDF calling sequences:: UDF calling sequences -* UDF arguments:: Argument processing -* UDF return values:: Return values and error handling -* UDF compiling:: Compiling and installing user-definable functions -@end menu +@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} -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 -functions. Consult this file to see how UDF calling conventions work. +@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 -For @code{mysqld} to be able to use UDF functions, you should configure MySQL -with @code{--with-mysqld-ldflags=-rdynamic} The reason is that to on -many platforms (including Linux) you can load a dynamic library (with -@code{dlopen()}) from a static linked program, which you would get if -you are using @code{--with-mysqld-ldflags=-all-static} If you want to -use an UDF that needs to access symbols from @code{mysqld} (like the -@code{methaphone} example in @file{sql/udf_example.cc} that uses -@code{default_charset_info}), you must link the program with -@code{-rdynamic}. (see @code{man dlopen}). +The Perl methods are described in more detail in the following sections. +Variables used for method return values have these meanings: -For each function that you want to use in SQL statements, you should define -corresponding C (or C++) functions. In the discussion below, the name -``xxx'' is used for an example function name. To distinquish between SQL and -C/C++ usage, @code{XXX()} (uppercase) indicates a SQL function call, and -@code{xxx()} (lowercase) indicates a C/C++ function call. +@table @code +@item $dbh +Database handle -The C/C++ functions that you write to implement the interface for -@code{XXX()} are: +@item $sth +Statement handle -@table @asis -@item @code{xxx()} (required) -The main function. This is where the function result is computed. -The correspondence between the SQL type and return type of your C/C++ -function is shown below: +@item $rc +Return code (often a status) -@multitable @columnfractions .2 .8 -@item @strong{SQL type} @tab @strong{C/C++ type} -@item @code{STRING} @tab @code{char *} -@item @code{INTEGER} @tab @code{long long} -@item @code{REAL} @tab @code{double} -@end multitable +@item $rv +Return value (often a row count) +@end table -@item @code{xxx_init()} (optional) -The initialization function for @code{xxx()}. It can be used to: +@noindent +@strong{Portable DBI Methods} -@itemize @bullet -@item -Check the number of arguments to @code{XXX()}. -@item -Check that the arguments are of a required type or, alternatively, -tell @strong{MySQL} to coerce arguments to the types you want when -the main function is called. -@item -Allocate any memory required by the main function. -@item -Specify the maximum length of the result. -@item -Specify (for @code{REAL} functions) the maximum number of decimals. -@item -Specify whether or not the result can be @code{NULL}. -@end itemize +@table @code -@item @code{xxx_deinit()} (optional) -The deinitialization function for @code{xxx()}. It should deallocate any -memory allocated by the initialization function. -@end table +@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}). -When a SQL statement invokes @code{XXX()}, @strong{MySQL} calls the -initialization function @code{xxx_init()} to let it perform any required -setup, such as argument checking or memory allocation. If @code{xxx_init()} -returns an error, the SQL statement is aborted with an error message and the -main and deinitialization functions are not called. Otherwise, the main -function @code{xxx()} is called once for each row. After all rows have been -processed, the deinitialization function @code{xxx_deinit()} is called so it -can perform any required cleanup. +As of @code{Msql-Mysql-modules} Version 1.2009, +the @code{$data_source} value allows certain modifiers: -All functions must be thread safe (not just the main function, -but the initialization and deinitialization functions as well). This means -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()}. +@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. -@node UDF calling sequences, UDF arguments, Adding UDF, Adding UDF -@subsubsection UDF Calling Sequences +@item mysql_compression=1 +Use compressed communication between the client and server (@strong{MySQL} +Version 3.22.3 or later). -@cindex calling sequences, UDF +@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 -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 -function @code{XXX()} to return @code{STRING}, @code{INTEGER}, or @code{REAL} -in the @code{CREATE FUNCTION} statement: +Multiple modifiers may be given; each must be preceded by a semicolon. -@noindent -For @code{STRING} functions: +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 -char *xxx(UDF_INIT *initid, UDF_ARGS *args, - char *result, unsigned long *length, - char *is_null, char *error); +$dbh = DBI->connect("DBI:mysql:$database" + . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf", + $user, $password); @end example -@noindent -For @code{INTEGER} functions: +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 -long long xxx(UDF_INIT *initid, UDF_ARGS *args, - char *is_null, char *error); +$dbh = DBI->connect("DBI:mysql:$database" + . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf" + . ";mysql_read_default_group=perl", + $user, $password); @end example -@noindent -For @code{REAL} functions: - +@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 -double xxx(UDF_INIT *initid, UDF_ARGS *args, - char *is_null, char *error); +$rc = $dbh->disconnect; @end example -The initialization and deinitialization functions are declared like this: - +@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 -my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); - -void xxx_deinit(UDF_INIT *initid); +$sth = $dbh->prepare($statement) + or die "Can't prepare $statement: $dbh->errstr\n"; @end example -The @code{initid} parameter is passed to all three functions. It points to a -@code{UDF_INIT} structure that is used to communicate information between -functions. The @code{UDF_INIT} structure members are listed below. The -initialization function should fill in any members that it wishes to change. -(To use the default for a member, leave it unchanged.): - -@table @code -@item my_bool maybe_null -@code{xxx_init()} should set @code{maybe_null} to @code{1} if @code{xxx()} -can return @code{NULL}. The default value is @code{1} if any of the -arguments are declared @code{maybe_null}. - -@item unsigned int decimals -Number of decimals. The default value is the maximum number of decimals in -the arguments passed to the main function. (For example, if the function is -passed @code{1.34}, @code{1.345}, and @code{1.3}, the default would be 3, -because @code{1.345} has 3 decimals. - -@item unsigned int max_length -The maximum length of the string result. The default value differs depending -on the result type of the function. For string functions, the default is the -length of the longest argument. For integer functions, the default is 21 -digits. For real functions, the default is 13 plus the number of decimals -indicated by @code{initid->decimals}. (For numeric functions, the length -includes any sign or decimal point characters.) - -@item char *ptr -A pointer that the function can use for its own purposes. For example, -functions can use @code{initid->ptr} to communicate allocated memory -between functions. In @code{xxx_init()}, allocate the memory and assign it -to this pointer: - +@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 -initid->ptr = allocated_memory; +$rv = $sth->execute + or die "can't execute the query: $sth->errstr; @end example -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 +@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 -The @code{args} parameter points to a @code{UDF_ARGS} structure that thas the -members listed below: +Generally the 'do' statement is MUCH faster (and is preferable) +than prepare/execute for statements that don't contain parameters. -@table @code -@item unsigned int arg_count -The number of arguments. Check this value in the initialization function -if you want your function to be called with a particular number of arguments. -For example: +@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 -if (args->arg_count != 2) -@{ - strcpy(message,"XXX() requires two arguments"); - return 1; +while(@@row = $sth->fetchrow_array) @{ + print qw($row[0]\t$row[1]\t$row[2]\n); @} @end example - -@item enum Item_result *arg_type -The types for each argument. The possible type values are -@code{STRING_RESULT}, @code{INT_RESULT}, and @code{REAL_RESULT}. - -To make sure that arguments are of a given type and return an -error if they are not, check the @code{arg_type} array in the initialization -function. For 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 -if (args->arg_type[0] != STRING_RESULT || - args->arg_type[1] != INT_RESULT) -@{ - strcpy(message,"XXX() requires a string and an integer"); - return 1; +while($row_ref = $sth->fetchrow_arrayref) @{ + print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n); @} @end example -As an alternative to requiring your function's arguments to be of particular -types, you can use the initialization function to set the @code{arg_type} -elements to the types you want. This causes @strong{MySQL} to coerce -arguments to those types for each call to @code{xxx()}. For example, to -specify coercion of the first two arguments to string and integer, do this in -@code{xxx_init()}: - -@example -args->arg_type[0] = STRING_RESULT; -args->arg_type[1] = INT_RESULT; +@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 -@item char **args -@code{args->args} communicates information to the initialization function -about the general nature of the arguments your function was called with. For a -constant argument @code{i}, @code{args->args[i]} points to the argument -value. (See below for instructions on how to access the value properly.) -For a non-constant argument, @code{args->args[i]} is @code{0}. -A constant argument is an expression that uses only constants, such as -@code{3} or @code{4*7-2} or @code{SIN(3.14)}. A non-constant argument is an -expression that refers to values that may change from row to row, such as -column names or functions that are called with non-constant arguments. - -For each invocation of the main function, @code{args->args} contains the -actual arguments that are passed for the row currently being processed. - -Functions can refer to an argument @code{i} as follows: +@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 -@itemize @bullet -@item -An argument of type @code{STRING_RESULT} is given as a string pointer plus a -length, to allow handling of binary data or data of arbitrary length. The -string contents are available as @code{args->args[i]} and the string length -is @code{args->lengths[i]}. You should not assume that strings are -null-terminated. +@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 -@item -For an argument of type @code{INT_RESULT}, you must cast -@code{args->args[i]} to a @code{long long} value: +@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 -long long int_val; -int_val = *((long long*) args->args[i]); +$null_possible = $sth->@{NULLABLE@}; @end example -@item -For an argument of type @code{REAL_RESULT}, you must cast -@code{args->args[i]} to a @code{double} value: +@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 -double real_val; -real_val = *((double*) args->args[i]); +@@dbs = DBI->data_sources("mysql"); @end example -@end itemize -@item unsigned long *lengths -For the initialization function, the @code{lengths} array indicates the -maximum string length for each argument. For each invocation of the main -function, @code{lengths} contains the actual lengths of any string arguments -that are passed for the row currently being processed. For arguments of -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 +@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 -@node UDF return values, UDF compiling, UDF arguments, Adding UDF -@subsubsection Return Values and Error Handling +@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)}. -@cindex UDFs, return values -@cindex return values, UDFs -@cindex errors, handling for UDFs -@cindex handling, errors +@end table -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 -null-terminated error message in the @code{message} parameter. The message -will be returned to the client. The message buffer is -@code{MYSQL_ERRMSG_SIZE} characters long, but you should try to keep the -message to less than 80 characters so that it fits the width of a standard -terminal screen. +@noindent +@strong{MySQL-specific Methods} -The return value of the main function @code{xxx()} is the function value, for -@code{long long} and @code{double} functions. A string functions should -return a pointer to the result and store the length of the string in the -@code{length} arguments. @code{result} is a buffer at least 255 bytes long. -Set these to the contents and length of the return value. For example: +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 -memcpy(result, "result string", 13); -*length = 13; +$new_id = $sth->@{insertid@}; @end example -If your string functions that needs to return a string longer than 255 -bytes, you must allocate the space for it with @code{malloc()} in your -@code{xxx_init()} function or your @code{xxx()} function and free it in -your @code{xxx_deinit()} function. You can store the allocated memory -in the @code{ptr} slot in the @code{UDF_INIT} structure for reuse by -future @code{xxx()} calls. @xref{UDF calling sequences}. - -To indicate a return value of @code{NULL} in the main function, set -@code{is_null} to @code{1}: +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 -*is_null = 1; +$keys = $sth->@{is_blob@}; @end example -To indicate an error return in the main function, set the @code{error} -parameter to @code{1}: - +@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 -*error = 1; +$keys = $sth->@{is_key@}; @end example -If @code{xxx()} sets @code{*error} to @code{1} for any row, the function -value is @code{NULL} for the current row and for any subsequent rows -processed by the statement in which @code{XXX()} was invoked. (@code{xxx()} -will not even be called for subsequent rows.) @strong{NOTE:} In -@strong{MySQL} versions prior to 3.22.10, you should set both @code{*error} -and @code{*is_null}: - +@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 -*error = 1; -*is_null = 1; +$nums = $sth->@{is_num@}; @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 - -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 -@file{udf_example.cc} that is included in the @strong{MySQL} source -distribution. This file contains the following functions: - -@itemize @bullet -@item -@code{metaphon()} returns a metaphon string of the string argument. -This is something like a soundex string, but it's more tuned for English. -@item -@code{myfunc_double()} returns the sum of the ASCII values of the -characters in its arguments, divided by the sum of the length of its arguments. -@item -@code{myfunc_int()} returns the sum of the length of its arguments. -@item -@code{sequence([const int])} returns an sequence starting from the given -number or 1 if no number has been given. -@item -@code{lookup()} returns the IP number for a hostname. -@item -@code{reverse_lookup()} returns the hostname for an IP number. -The function may be called with a string @code{"xxx.xxx.xxx.xxx"} or -four numbers. -@end itemize - -A dynamically loadable file should be compiled as a sharable object file, -using a command something like this: - +@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 -shell> gcc -shared -o udf_example.so myfunc.cc +$pri_keys = $sth->@{is_pri_key@}; @end example -You can easily find out the correct compiler options for your system by -running this command in the @file{sql} directory of your @strong{MySQL} -source tree: - +@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 -shell> make udf_example.o +$not_nulls = $sth->@{is_not_null@}; @end example -You should run a compile command similar to the one that @code{make} displays, -except that you should remove the @code{-c} option near the end of the line -and add @code{-o udf_example.so} to the end of the line. (On some systems, -you may need to leave the @code{-c} on the command.) - -Once you compile a shared object containing UDFs, you must install it -and tell @strong{MySQL} about it. Compiling a shared object from -@file{udf_example.cc} produces a file named something like -@file{udf_example.so} (the exact name may vary from platform to platform). -Copy this file to some directory searched by @code{ld}, such as -@file{/usr/lib}. On many systems, you can set the @code{LD_LIBRARY} or -@code{LD_LIBRARY_PATH} environment variable to point at the directory where -you have your UDF function files. The @code{dlopen} manual page tells you -which variable you should use on your system. You should set this in -@code{mysql.server} or @code{safe_mysqld} and restart @code{mysqld}. +@code{is_not_null} is deprecated; it is preferable to use the +@code{NULLABLE} attribute (described above), because that is a DBI standard. -After the library is installed, notify @code{mysqld} about the new -functions with these commands: +@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 -mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; -mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; -mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; -mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; -mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so"; +$lengths = $sth->@{length@}; +$max_lengths = $sth->@{max_length@}; @end example -Functions can be deleted using @code{DROP FUNCTION}: - +@findex DBI->@{NAME@} +@findex NAME DBI method +@item NAME +Returns a reference to an array of column names. +Example: @example -mysql> DROP FUNCTION metaphon; -mysql> DROP FUNCTION myfunc_double; -mysql> DROP FUNCTION myfunc_int; -mysql> DROP FUNCTION lookup; -mysql> DROP FUNCTION reverse_lookup; +$names = $sth->@{NAME@}; @end example -The @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements update the -system table @code{func} in the @code{mysql} database. The function's name, -type and shared library name are saved in the table. You must have the -@strong{insert} and @strong{delete} privileges for the @code{mysql} database -to create and drop functions. - -You should not use @code{CREATE FUNCTION} to add a function that has already -been created. If you need to reinstall a function, you should remove it with -@code{DROP FUNCTION} and then reinstall it with @code{CREATE FUNCTION}. You -would need to do this, for example, if you recompile a new version of your -function, so that @code{mysqld} gets the new version. Otherwise the server -will continue to use the old version. - -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}.) +@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 -@node Adding native function, , Adding UDF, Adding functions -@subsection Adding a New Native Function +@end table -@cindex adding, native functions -@cindex native functions, adding -@cindex functions, native, adding -The procedure for adding a new native function is described below. Note -that you cannot add native functions to a binary distribution because -the procedure involves modifying @strong{MySQL} source code. You must -compile @strong{MySQL} yourself from a source distribution. Also note -that if you migrate to another version of @strong{MySQL} (for example, -when a new version is released), you will need to repeat the procedure -with the new version. +@node DBI-info, , Perl DBI Class, Perl +@subsection More @code{DBI}/@code{DBD} Information -To add a new native @strong{MySQL} function, follow these steps: +@cindex @code{DBI/DBD} -@enumerate -@item -Add one line to @file{lex.h} that defines the function name in the -@code{sql_functions[]} array. -@item -If the function prototype is simple (just takes zero, one, two or three -arguments), you should in lex.h specify SYM(FUNC_ARG#) (where # is the -number of arguments) as the second argument in the -@code{sql_functions[]} array and add a function that creates a function -object in @file{item_create.cc}. Take a look at @code{"ABS"} and -@code{create_funcs_abs()} for an example of this. +You can use the @code{perldoc} command to get more information about +@code{DBI}. -If the function prototype is complicated (for example takes a variable number -of arguments), you should add two lines to @file{sql_yacc.yy}. One -indicates the preprocessor symbol that @code{yacc} should define (this -should be added at the beginning of the file). Then define the function -parameters and add an ``item'' with these parameters to the -@code{simple_expr} parsing rule. For an example, check all occurrences -of @code{ATAN} in @file{sql_yacc.yy} to see how this is done. -@item -In @file{item_func.h}, declare a class inheriting from @code{Item_num_func} or -@code{Item_str_func}, depending on whether your function returns a number or a -string. -@item -In @file{item_func.cc}, add one of the following declarations, depending -on whether you are defining a numeric or string function: @example -double Item_func_newname::val() -longlong Item_func_newname::val_int() -String *Item_func_newname::Str(String *str) +perldoc DBI +perldoc DBI::FAQ +perldoc DBD::mysql @end example -If you inherit your object from any of the standard items (like -@code{Item_num_func} you probably only have to define one of the above -functions and let the parent object take care of the other functions. -For example, the @code{Item_str_func} class defines a @code{val()} function -that executes @code{atof()} on the value returned by @code{::str()}. +You can also use the @code{pod2man}, @code{pod2html}, etc., tools to +translate to other formats. -@item -You should probably also define the following object function: +You can find the latest @code{DBI} information at +the @code{DBI} Web page: @example -void Item_func_newname::fix_length_and_dec() +@uref{http://www.symbolstone.org/technology/perl/DBI/index.html} @end example -This function should at least calculate @code{max_length} based on the -given arguments. @code{max_length} is the maximum number of characters -the function may return. This function should also set @code{maybe_null -= 0} if the main function can't return a @code{NULL} value. The -function can check if any of the function arguments can return -@code{NULL} by checking the arguments @code{maybe_null} variable. You -can take a look at @code{Item_func_mod::fix_length_and_dec} for a -typical example of how to do this. -@end enumerate -All functions must be thread safe (In other words, don't use any global or -static variables in the functions without protecting them with mutexes). -If you want to return @code{NULL}, from @code{::val()}, @code{::val_int()} -or @code{::str()} you should set @code{null_value} to 1 and return 0. +@node ODBC, C, Perl, Clients +@section MySQL ODBC Support -For @code{::str()} object functions, there are some additional -considerations to be aware of: +@cindex ODBC +@cindex Windows +@cindex MyODBC -@itemize @bullet -@item -The @code{String *str} argument provides a string buffer that may be -used to hold the result. (For more information about the @code{String} type, -take a look at the @file{sql_string.h} file.) -@item -The @code{::str()} function should return the string that holds the result or -@code{(char*) 0} if the result is @code{NULL}. -@item -All current string functions try to avoid allocating any memory unless -absolutely necessary! -@end itemize +@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 -@node Adding procedures, MySQL internals, Adding functions, Extending MySQL -@section Adding New Procedures to MySQL +@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}. -@cindex procedures, adding -@cindex adding, procedures -@cindex new procedures, adding -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 -can be done on row-by-row or @code{GROUP BY} level. +@node Installing MyODBC, ODBC administrator, ODBC, ODBC +@subsection How To Install MyODBC -We have created an example procedure in @strong{MySQL} Version 3.23 to -show you what can be done. +@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. -Additionally we recommend you to take a look at 'mylua', which you can find in the Contrib directory. @xref{Contrib}. Which this you can use the LUA -language to load a procedure at runtime into @code{mysqld}. +@strong{MyODBC} is in public domain, and you can find the newest version +at @uref{http://www.mysql.com/downloads/api-myodbc.html}. -@menu -* procedure analyse:: Procedure analyse -* Writing a procedure:: Writing a procedure. -@end menu +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}. - -@node procedure analyse, Writing a procedure, Adding procedures, Adding procedures -@subsection Procedure Analyse - -@code{analyse([max elements,[max memory]])} - -This procedure is defined in the @file{sql/sql_analyse.cc}. This -examines the result from your query and returns an analysis of the -results: - -@itemize @bullet -@item -@code{max elements} (default 256) is the maximum number of distinct values -@code{analyse} will notice per column. This is used by @code{analyse} to check if -the optimal column type should be of type @code{ENUM}. -@item -@code{max memory} (default 8192) is the maximum memory @code{analyse} should -allocate per column while trying to find all distinct values. -@end itemize - -@example -SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]]) -@end example - - -@node Writing a procedure, , procedure analyse, Adding procedures -@subsection Writing a Procedure - -For the moment, the only documentation for this is the source. - -You can find all information about procedures by examining the following files: - -@itemize @bullet -@item @file{sql/sql_analyse.cc} -@item @file{sql/procedure.h} -@item @file{sql/procedure.cc} -@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 - -@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. +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 @@ -38319,7 +37941,7 @@ 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 +@subsection How to Fill in the Various Fields in the ODBC Administrator Program @cindex ODBC, administrator @@ -38376,7 +37998,7 @@ You can use all options that are usable by @code{mysql_options()}. @node MyODBC connect parameters, ODBC Problems, ODBC administrator, ODBC -@section Connect parameters for MyODBC +@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 @@ -38434,7 +38056,7 @@ you should instead use @code{MYODBCD.DLL}. To install this file, copy @node ODBC Problems, MyODBC clients, MyODBC connect parameters, ODBC -@section How to Report Problems with MyODBC +@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), @@ -38465,7 +38087,7 @@ 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 +@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 @@ -38754,7 +38376,7 @@ You should use the option flag @code{Don't optimize column widths}. @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 +@subsection How to Get the Value of an @code{AUTO_INCREMENT} Column in ODBC @cindex AUTO-INCREMENT, ODBC @@ -38784,7 +38406,7 @@ SELECT * FROM tbl_name WHERE auto IS NULL; @node MyODBC bug report, , ODBC and last_insert_id, ODBC -@section Reporting Problems with MyODBC +@subsection Reporting Problems with MyODBC @cindex reporting, MyODBC problems @cindex problems, ODBC @@ -38844,88 +38466,18 @@ 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. +@node C, Cplusplus, ODBC, Clients +@section MySQL C API @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:: +* Building clients:: * Thread-safe clients:: @end menu @@ -38969,10 +38521,11 @@ 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 +@table @code @tindex MYSQL C type @item MYSQL This structure represents a handle to one database connection. It is @@ -39131,11 +38684,13 @@ status of the @code{flags} value: 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 +@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}. @@ -39411,6 +38966,7 @@ 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 @@ -39498,10 +39054,12 @@ 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()} +@findex @code{mysql_affected_rows()} + @code{my_ulonglong mysql_affected_rows(MYSQL *mysql)} @subsubheading Description @@ -39543,10 +39101,12 @@ Note that when one uses a @code{REPLACE} command, 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()} +@findex @code{mysql_close()} + @code{void mysql_close(MYSQL *mysql)} @subsubheading Description @@ -39562,10 +39122,12 @@ None. None. -@findex @code{mysql_connect()} + @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 @@ -39595,10 +39157,12 @@ Same as for @code{mysql_real_connect()}. 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()} +@findex @code{mysql_change_user()} + @code{my_bool mysql_change_user(MYSQL *mysql, const char *user, const char *password, const char *db)} @@ -39657,10 +39221,12 @@ if (mysql_change_user(&mysql, "user", "password", "new_database")) @} @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()} +@findex @code{mysql_character_set_name()} + @code{const char *mysql_character_set_name(MYSQL *mysql)} @subsubheading Description @@ -39675,10 +39241,11 @@ The default character set 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()} +@findex @code{mysql_create_db()} + @code{int mysql_create_db(MYSQL *mysql, const char *db)} @subsubheading Description @@ -39718,10 +39285,12 @@ if(mysql_create_db(&mysql, "my_database")) @} @end example -@findex @code{mysql_data_seek()} + @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 @@ -39740,10 +39309,12 @@ None. @subsubheading Errors None. -@findex @code{mysql_debug()} + @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 @@ -39768,10 +39339,12 @@ The call shown below causes the client library to generate a trace file in 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()} +@findex @code{mysql_drop_db()} + @code{int mysql_drop_db(MYSQL *mysql, const char *db)} @subsubheading Description @@ -39806,10 +39379,12 @@ if(mysql_drop_db(&mysql, "my_database")) 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()} +@findex @code{mysql_dump_debug_info()} + @code{int mysql_dump_debug_info(MYSQL *mysql)} @subsubheading Description @@ -39833,10 +39408,12 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_eof()} + @code{my_bool mysql_eof(MYSQL_RES *result)} @subsubheading Description @@ -39910,10 +39487,12 @@ if(mysql_errno(&mysql)) // mysql_fetch_row() failed due to an error @} @end example -@findex @code{mysql_errno()} + @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 @@ -39933,10 +39512,12 @@ 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()} +@findex @code{mysql_error()} + @code{char *mysql_error(MYSQL *mysql)} @subsubheading Description @@ -39971,10 +39552,12 @@ 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()} +@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 @@ -39984,10 +39567,12 @@ 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()} +@findex @code{mysql_fetch_field()} + @code{MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)} @subsubheading Description @@ -40030,10 +39615,12 @@ while((field = mysql_fetch_field(result))) @} @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()} +@findex @code{mysql_fetch_fields()} + @code{MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)} @subsubheading Description @@ -40064,10 +39651,12 @@ for(i = 0; i < num_fields; i++) @} @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()} +@findex @code{mysql_fetch_field_direct()} + @code{MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr)} @subsubheading Description @@ -40100,10 +39689,12 @@ for(i = 0; i < num_fields; i++) @} @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()} +@findex @code{mysql_fetch_lengths()} + @code{unsigned long *mysql_fetch_lengths(MYSQL_RES *result)} @subsubheading Description @@ -40150,10 +39741,12 @@ if (row) @} @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()} +@findex @code{mysql_fetch_row()} + @code{MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)} @subsubheading Description @@ -40210,10 +39803,12 @@ while ((row = mysql_fetch_row(result))) @} @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()} +@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 @@ -40282,10 +39877,12 @@ 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()} +@findex @code{mysql_field_seek()} + @code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)} @subsubheading Description @@ -40303,10 +39900,12 @@ 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()} +@findex @code{mysql_field_tell()} + @code{MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)} @subsubheading Description @@ -40322,10 +39921,12 @@ 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()} +@findex @code{mysql_free_result()} + @code{void mysql_free_result(MYSQL_RES *result)} @subsubheading Description @@ -40342,10 +39943,12 @@ 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()} +@findex @code{mysql_get_client_info()} + @code{char *mysql_get_client_info(void)} @subsubheading Description @@ -40359,10 +39962,12 @@ 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()} +@findex @code{mysql_get_host_info()} + @code{char *mysql_get_host_info(MYSQL *mysql)} @subsubheading Description @@ -40377,10 +39982,12 @@ 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()} +@findex @code{mysql_get_proto_info()} + @code{unsigned int mysql_get_proto_info(MYSQL *mysql)} @subsubheading Description @@ -40395,10 +40002,12 @@ 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()} +@findex @code{mysql_get_server_info()} + @code{char *mysql_get_server_info(MYSQL *mysql)} @subsubheading Description @@ -40412,10 +40021,12 @@ 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()} +@findex @code{mysql_info()} + @code{char *mysql_info(MYSQL *mysql)} @subsubheading Description @@ -40452,10 +40063,12 @@ query. @subsubheading Errors None. -@findex @code{mysql_init()} + @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 @@ -40475,10 +40088,12 @@ 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()} +@findex @code{mysql_insert_id()} + @code{my_ulonglong mysql_insert_id(MYSQL *mysql)} @subsubheading Description @@ -40506,10 +40121,12 @@ 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()} +@findex @code{mysql_kill()} + @code{int mysql_kill(MYSQL *mysql, unsigned long pid)} @subsubheading Description @@ -40533,10 +40150,12 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_list_dbs()} + @code{MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)} @subsubheading Description @@ -40569,10 +40188,12 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_list_fields()} + @code{MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)} @subsubheading Description @@ -40606,10 +40227,12 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_list_processes()} + @code{MYSQL_RES *mysql_list_processes(MYSQL *mysql)} @subsubheading Description @@ -40637,10 +40260,12 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_list_tables()} + @code{MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)} @subsubheading Description @@ -40671,11 +40296,13 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_num_fields()} +@findex @code{mysql_field_count()} + @code{unsigned int mysql_num_fields(MYSQL_RES *result)} or @@ -40749,10 +40376,12 @@ 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()} +@findex @code{mysql_num_rows()} + @code{my_ulonglong mysql_num_rows(MYSQL_RES *result)} @subsubheading Description @@ -40773,10 +40402,12 @@ 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()} +@findex @code{mysql_options()} + @code{int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)} @subsubheading Description @@ -40853,10 +40484,12 @@ 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()} +@findex @code{mysql_ping()} + @code{int mysql_ping(MYSQL *mysql)} @subsubheading Description @@ -40883,10 +40516,12 @@ The @strong{MySQL} server has gone away. 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()} +@findex @code{mysql_query()} + @code{int mysql_query(MYSQL *mysql, const char *query)} @subsubheading Description @@ -40920,10 +40555,12 @@ The connection to the server was lost during the query. 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()} +@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, @@ -41078,10 +40715,12 @@ 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()} +@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 @@ -41137,10 +40776,12 @@ 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()} +@findex @code{mysql_real_query()} + @code{int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length)} @subsubheading Description @@ -41177,10 +40818,12 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_reload()} + @code{int mysql_reload(MYSQL *mysql)} @subsubheading Description @@ -41208,10 +40851,12 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_row_seek()} + @code{MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset)} @subsubheading Description @@ -41233,10 +40878,12 @@ 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()} +@findex @code{mysql_row_tell()} + @code{MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result)} @subsubheading Description @@ -41255,10 +40902,12 @@ 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()} +@findex @code{mysql_select_db()} + @code{int mysql_select_db(MYSQL *mysql, const char *db)} @subsubheading Description @@ -41288,10 +40937,12 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_shutdown()} + @code{int mysql_shutdown(MYSQL *mysql)} @subsubheading Description @@ -41316,10 +40967,12 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_stat()} + @code{char *mysql_stat(MYSQL *mysql)} @subsubheading Description @@ -41346,10 +40999,12 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_store_result()} + @code{MYSQL_RES *mysql_store_result(MYSQL *mysql)} @subsubheading Description @@ -41417,10 +41072,12 @@ The connection to the server was lost during the query. 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()} +@findex @code{mysql_thread_id()} + @code{unsigned long mysql_thread_id(MYSQL *mysql)} @subsubheading Description @@ -41439,10 +41096,12 @@ 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()} +@findex @code{mysql_use_result()} + @code{MYSQL_RES *mysql_use_result(MYSQL *mysql)} @subsubheading Description @@ -41502,11 +41161,13 @@ The connection to the server was lost during the query. An unknown error occurred. @end table -@node C API problems, Thread-safe clients, C API functions, C + +@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:: @@ -41514,6 +41175,7 @@ An unknown error occurred. * 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?} @@ -41553,6 +41215,7 @@ You can test for an error by calling @code{mysql_error()} or * 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? @@ -41588,12 +41251,14 @@ 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 -@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 @@ -41630,11 +41295,13 @@ 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 +@cindex linking, problems +@cindex C API, linking problems + When linking with the C API, the following errors may occur on some systems: @example @@ -41649,10 +41316,33 @@ ld: fatal: Symbol referencing errors. No output written to client 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 -@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 @@ -41731,637 +41421,1089 @@ 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. +@node Cplusplus, Java, C, Clients +@section MySQL C++ APIs @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 +* Borland C++:: @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}. +@cindex C++ APIs -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 +Two APIs are available in the @strong{MySQL} +@uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory}. -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 Borland C++, , Cplusplus, Cplusplus +@subsection Borland C++ -@cindex @code{DBI} Perl module -@node Perl DBI Class, DBI-info, DBI with DBD, Perl -@subsection The @code{DBI} Interface +@cindex Borland C++ compiler -@noindent -@strong{Portable DBI Methods} +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). -@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 +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. -@noindent -@strong{MySQL-specific Methods} +@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 -@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: +@node Java, Python, Cplusplus, Clients +@section MySQL Java Connectivity (JDBC) -@table @code -@item $dbh -Database handle +@cindex Java connectivity +@cindex JDBC -@item $sth -Statement handle +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. -@item $rc -Return code (often a status) -@item $rv -Return value (often a row count) -@end table +@node Python, Tcl, Java, Clients +@section MySQL Python APIs -@noindent -@strong{Portable DBI Methods} +@cindex Python APIs -@table @code +The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} +contains a Python interface written by Joseph Skinner. -@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}). +You can also use the Python interface to iODBC to access a +@strong{MySQL} server. +@uref{http://starship.skyport.net/~lemburg/,mxODBC} -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}. +@node Tcl, Eiffel, Python, Clients +@section MySQL Tcl APIs -@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. +@cindex Tcl APIs -@item mysql_compression=1 -Use compressed communication between the client and server (@strong{MySQL} -Version 3.22.3 or later). +@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. -@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. +@node Eiffel, , Tcl, Clients +@section MySQL Eiffel wrapper -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: +@cindex Eiffel Wrapper +@cindex wrappers, Eiffel -@example -$dbh = DBI->connect("DBI:mysql:$database" - . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf", - $user, $password); -@end example +The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} +contains an Eiffel wrapper written by Michael Ravits. -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: +You can also find this at: +@url{http://www.netpedia.net/hosting/newplayer/} -@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 +@node Extending MySQL, Problems, Clients, Top +@chapter Extending MySQL -@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 +@menu +* Adding functions:: +* Adding procedures:: +* MySQL internals:: +@end menu -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 +@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 + +There are two ways to add new functions to @strong{MySQL}: + +@itemize @bullet +@item You can add the function through the user-definable function (UDF) +interface. User-definable functions are added and removed dynamically using +the @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements. +@xref{CREATE FUNCTION, , @code{CREATE FUNCTION}}. + +@item You can add the function as a native (built in) @strong{MySQL} function. +Native functions are compiled into the @code{mysqld} server and become +available on a permanent basis. +@end itemize + +Each method has advantages and disadvantages: + +@itemize @bullet +@item +If you write a user-definable function, you must install the object file +in addition to the server itself. If you compile your function into the +server, you don't need to do that. +@item +You can add UDFs to a binary @strong{MySQL} distribution. Native functions +require you to modify a source distribution. +@item +If you upgrade your @strong{MySQL} distribution, you can continue to use your +previously installed UDFs. For native functions, you must repeat your +modifications each time you upgrade. +@end itemize + +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 -@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); -@} +CREATE [AGGREGATE] FUNCTION function_name RETURNS @{STRING|REAL|INTEGER@} + SONAME shared_library_name + +DROP FUNCTION function_name @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: +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 + +@menu +* UDF calling sequences:: UDF calling sequences +* UDF arguments:: Argument processing +* UDF return values:: Return values and error handling +* 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 +functions. Consult this file to see how UDF calling conventions work. + +For @code{mysqld} to be able to use UDF functions, you should configure MySQL +with @code{--with-mysqld-ldflags=-rdynamic} The reason is that to on +many platforms (including Linux) you can load a dynamic library (with +@code{dlopen()}) from a static linked program, which you would get if +you are using @code{--with-mysqld-ldflags=-all-static} If you want to +use an UDF that needs to access symbols from @code{mysqld} (like the +@code{methaphone} example in @file{sql/udf_example.cc} that uses +@code{default_charset_info}), you must link the program with +@code{-rdynamic}. (see @code{man dlopen}). + +For each function that you want to use in SQL statements, you should define +corresponding C (or C++) functions. In the discussion below, the name +``xxx'' is used for an example function name. To distinquish between SQL and +C/C++ usage, @code{XXX()} (uppercase) indicates a SQL function call, and +@code{xxx()} (lowercase) indicates a C/C++ function call. + +The C/C++ functions that you write to implement the interface for +@code{XXX()} are: + +@table @asis +@item @code{xxx()} (required) +The main function. This is where the function result is computed. +The correspondence between the SQL type and return type of your C/C++ +function is shown below: + +@multitable @columnfractions .2 .8 +@item @strong{SQL type} @tab @strong{C/C++ type} +@item @code{STRING} @tab @code{char *} +@item @code{INTEGER} @tab @code{long long} +@item @code{REAL} @tab @code{double} +@end multitable + +@item @code{xxx_init()} (optional) +The initialization function for @code{xxx()}. It can be used to: + +@itemize @bullet +@item +Check the number of arguments to @code{XXX()}. +@item +Check that the arguments are of a required type or, alternatively, +tell @strong{MySQL} to coerce arguments to the types you want when +the main function is called. +@item +Allocate any memory required by the main function. +@item +Specify the maximum length of the result. +@item +Specify (for @code{REAL} functions) the maximum number of decimals. +@item +Specify whether or not the result can be @code{NULL}. +@end itemize + +@item @code{xxx_deinit()} (optional) +The deinitialization function for @code{xxx()}. It should deallocate any +memory allocated by the initialization function. +@end table + +When a SQL statement invokes @code{XXX()}, @strong{MySQL} calls the +initialization function @code{xxx_init()} to let it perform any required +setup, such as argument checking or memory allocation. If @code{xxx_init()} +returns an error, the SQL statement is aborted with an error message and the +main and deinitialization functions are not called. Otherwise, the main +function @code{xxx()} is called once for each row. After all rows have been +processed, the deinitialization function @code{xxx_deinit()} is called so it +can perform any required cleanup. + +All functions must be thread safe (not just the main function, +but the initialization and deinitialization functions as well). This means +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()}. + + +@node UDF calling sequences, UDF arguments, Adding UDF, Adding UDF +@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 +function @code{XXX()} to return @code{STRING}, @code{INTEGER}, or @code{REAL} +in the @code{CREATE FUNCTION} statement: + +@noindent +For @code{STRING} functions: + @example -while($row_ref = $sth->fetchrow_arrayref) @{ - print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n); -@} +char *xxx(UDF_INIT *initid, UDF_ARGS *args, + char *result, unsigned long *length, + char *is_null, char *error); @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: +@noindent +For @code{INTEGER} functions: + @example -while($hash_ref = $sth->fetchrow_hashref) @{ - print qw($hash_ref->@{firstname@}\t$hash_ref->@{lastname@}\t\ - $hash_ref- > title@}\n); +long long xxx(UDF_INIT *initid, UDF_ARGS *args, + char *is_null, char *error); +@end example + +@noindent +For @code{REAL} functions: + +@example +double xxx(UDF_INIT *initid, UDF_ARGS *args, + char *is_null, char *error); +@end example + +The initialization and deinitialization functions are declared like this: + +@example +my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); + +void xxx_deinit(UDF_INIT *initid); +@end example + +The @code{initid} parameter is passed to all three functions. It points to a +@code{UDF_INIT} structure that is used to communicate information between +functions. The @code{UDF_INIT} structure members are listed below. The +initialization function should fill in any members that it wishes to change. +(To use the default for a member, leave it unchanged.): + +@table @code +@item my_bool maybe_null +@code{xxx_init()} should set @code{maybe_null} to @code{1} if @code{xxx()} +can return @code{NULL}. The default value is @code{1} if any of the +arguments are declared @code{maybe_null}. + +@item unsigned int decimals +Number of decimals. The default value is the maximum number of decimals in +the arguments passed to the main function. (For example, if the function is +passed @code{1.34}, @code{1.345}, and @code{1.3}, the default would be 3, +because @code{1.345} has 3 decimals. + +@item unsigned int max_length +The maximum length of the string result. The default value differs depending +on the result type of the function. For string functions, the default is the +length of the longest argument. For integer functions, the default is 21 +digits. For real functions, the default is 13 plus the number of decimals +indicated by @code{initid->decimals}. (For numeric functions, the length +includes any sign or decimal point characters.) + +@item char *ptr +A pointer that the function can use for its own purposes. For example, +functions can use @code{initid->ptr} to communicate allocated memory +between functions. In @code{xxx_init()}, allocate the memory and assign it +to this pointer: + +@example +initid->ptr = allocated_memory; +@end example + +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 + +The @code{args} parameter points to a @code{UDF_ARGS} structure that thas the +members listed below: + +@table @code +@item unsigned int arg_count +The number of arguments. Check this value in the initialization function +if you want your function to be called with a particular number of arguments. +For example: + +@example +if (args->arg_count != 2) +@{ + strcpy(message,"XXX() requires two arguments"); + return 1; @} @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: + +@item enum Item_result *arg_type +The types for each argument. The possible type values are +@code{STRING_RESULT}, @code{INT_RESULT}, and @code{REAL_RESULT}. + +To make sure that arguments are of a given type and return an +error if they are not, check the @code{arg_type} array in the initialization +function. For 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"; +if (args->arg_type[0] != STRING_RESULT || + args->arg_type[1] != INT_RESULT) +@{ + strcpy(message,"XXX() requires a string and an integer"); + return 1; @} @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 +As an alternative to requiring your function's arguments to be of particular +types, you can use the initialization function to set the @code{arg_type} +elements to the types you want. This causes @strong{MySQL} to coerce +arguments to those types for each call to @code{xxx()}. For example, to +specify coercion of the first two arguments to string and integer, do this in +@code{xxx_init()}: + +@example +args->arg_type[0] = STRING_RESULT; +args->arg_type[1] = INT_RESULT; +@end example + +@item char **args +@code{args->args} communicates information to the initialization function +about the general nature of the arguments your function was called with. For a +constant argument @code{i}, @code{args->args[i]} points to the argument +value. (See below for instructions on how to access the value properly.) +For a non-constant argument, @code{args->args[i]} is @code{0}. +A constant argument is an expression that uses only constants, such as +@code{3} or @code{4*7-2} or @code{SIN(3.14)}. A non-constant argument is an +expression that refers to values that may change from row to row, such as +column names or functions that are called with non-constant arguments. + +For each invocation of the main function, @code{args->args} contains the +actual arguments that are passed for the row currently being processed. + +Functions can refer to an argument @code{i} as follows: + +@itemize @bullet +@item +An argument of type @code{STRING_RESULT} is given as a string pointer plus a +length, to allow handling of binary data or data of arbitrary length. The +string contents are available as @code{args->args[i]} and the string length +is @code{args->lengths[i]}. You should not assume that strings are +null-terminated. + +@item +For an argument of type @code{INT_RESULT}, you must cast +@code{args->args[i]} to a @code{long long} value: + +@example +long long int_val; +int_val = *((long long*) args->args[i]); +@end example + +@item +For an argument of type @code{REAL_RESULT}, you must cast +@code{args->args[i]} to a @code{double} value: + +@example +double real_val; +real_val = *((double*) args->args[i]); +@end example +@end itemize + +@item unsigned long *lengths +For the initialization function, the @code{lengths} array indicates the +maximum string length for each argument. For each invocation of the main +function, @code{lengths} contains the actual lengths of any string arguments +that are passed for the row currently being processed. For arguments of +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 + +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 +null-terminated error message in the @code{message} parameter. The message +will be returned to the client. The message buffer is +@code{MYSQL_ERRMSG_SIZE} characters long, but you should try to keep the +message to less than 80 characters so that it fits the width of a standard +terminal screen. + +The return value of the main function @code{xxx()} is the function value, for +@code{long long} and @code{double} functions. A string functions should +return a pointer to the result and store the length of the string in the +@code{length} arguments. @code{result} is a buffer at least 255 bytes long. +Set these to the contents and length of the return value. For example: + +@example +memcpy(result, "result string", 13); +*length = 13; +@end example + +If your string functions that needs to return a string longer than 255 +bytes, you must allocate the space for it with @code{malloc()} in your +@code{xxx_init()} function or your @code{xxx()} function and free it in +your @code{xxx_deinit()} function. You can store the allocated memory +in the @code{ptr} slot in the @code{UDF_INIT} structure for reuse by +future @code{xxx()} calls. @xref{UDF calling sequences}. + +To indicate a return value of @code{NULL} in the main function, set +@code{is_null} to @code{1}: + +@example +*is_null = 1; +@end example + +To indicate an error return in the main function, set the @code{error} +parameter to @code{1}: + +@example +*error = 1; +@end example + +If @code{xxx()} sets @code{*error} to @code{1} for any row, the function +value is @code{NULL} for the current row and for any subsequent rows +processed by the statement in which @code{XXX()} was invoked. (@code{xxx()} +will not even be called for subsequent rows.) @strong{NOTE:} In +@strong{MySQL} versions prior to 3.22.10, you should set both @code{*error} +and @code{*is_null}: + +@example +*error = 1; +*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 + +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 +@file{udf_example.cc} that is included in the @strong{MySQL} source +distribution. This file contains the following functions: + +@itemize @bullet +@item +@code{metaphon()} returns a metaphon string of the string argument. +This is something like a soundex string, but it's more tuned for English. +@item +@code{myfunc_double()} returns the sum of the ASCII values of the +characters in its arguments, divided by the sum of the length of its arguments. +@item +@code{myfunc_int()} returns the sum of the length of its arguments. +@item +@code{sequence([const int])} returns an sequence starting from the given +number or 1 if no number has been given. +@item +@code{lookup()} returns the IP number for a hostname. +@item +@code{reverse_lookup()} returns the hostname for an IP number. +The function may be called with a string @code{"xxx.xxx.xxx.xxx"} or +four numbers. +@end itemize + +A dynamically loadable file should be compiled as a sharable object file, +using a command something like this: + +@example +shell> gcc -shared -o udf_example.so myfunc.cc +@end example + +You can easily find out the correct compiler options for your system by +running this command in the @file{sql} directory of your @strong{MySQL} +source tree: + +@example +shell> make udf_example.o +@end example + +You should run a compile command similar to the one that @code{make} displays, +except that you should remove the @code{-c} option near the end of the line +and add @code{-o udf_example.so} to the end of the line. (On some systems, +you may need to leave the @code{-c} on the command.) + +Once you compile a shared object containing UDFs, you must install it +and tell @strong{MySQL} about it. Compiling a shared object from +@file{udf_example.cc} produces a file named something like +@file{udf_example.so} (the exact name may vary from platform to platform). +Copy this file to some directory searched by @code{ld}, such as +@file{/usr/lib}. On many systems, you can set the @code{LD_LIBRARY} or +@code{LD_LIBRARY_PATH} environment variable to point at the directory where +you have your UDF function files. The @code{dlopen} manual page tells you +which variable you should use on your system. You should set this in +@code{mysql.server} or @code{safe_mysqld} and restart @code{mysqld}. + +After the library is installed, notify @code{mysqld} about the new +functions with these commands: + +@example +mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; +mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; +mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; +mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; +mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so"; +@end example + +Functions can be deleted using @code{DROP FUNCTION}: + +@example +mysql> DROP FUNCTION metaphon; +mysql> DROP FUNCTION myfunc_double; +mysql> DROP FUNCTION myfunc_int; +mysql> DROP FUNCTION lookup; +mysql> DROP FUNCTION reverse_lookup; +@end example + +The @code{CREATE FUNCTION} and @code{DROP FUNCTION} statements update the +system table @code{func} in the @code{mysql} database. The function's name, +type and shared library name are saved in the table. You must have the +@strong{insert} and @strong{delete} privileges for the @code{mysql} database +to create and drop functions. + +You should not use @code{CREATE FUNCTION} to add a function that has already +been created. If you need to reinstall a function, you should remove it with +@code{DROP FUNCTION} and then reinstall it with @code{CREATE FUNCTION}. You +would need to do this, for example, if you recompile a new version of your +function, so that @code{mysqld} gets the new version. Otherwise the server +will continue to use the old version. + +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}.) + + +@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 + +The procedure for adding a new native function is described below. Note +that you cannot add native functions to a binary distribution because +the procedure involves modifying @strong{MySQL} source code. You must +compile @strong{MySQL} yourself from a source distribution. Also note +that if you migrate to another version of @strong{MySQL} (for example, +when a new version is released), you will need to repeat the procedure +with the new version. + +To add a new native @strong{MySQL} function, follow these steps: + +@enumerate +@item +Add one line to @file{lex.h} that defines the function name in the +@code{sql_functions[]} array. +@item +If the function prototype is simple (just takes zero, one, two or three +arguments), you should in lex.h specify SYM(FUNC_ARG#) (where # is the +number of arguments) as the second argument in the +@code{sql_functions[]} array and add a function that creates a function +object in @file{item_create.cc}. Take a look at @code{"ABS"} and +@code{create_funcs_abs()} for an example of this. + +If the function prototype is complicated (for example takes a variable number +of arguments), you should add two lines to @file{sql_yacc.yy}. One +indicates the preprocessor symbol that @code{yacc} should define (this +should be added at the beginning of the file). Then define the function +parameters and add an ``item'' with these parameters to the +@code{simple_expr} parsing rule. For an example, check all occurrences +of @code{ATAN} in @file{sql_yacc.yy} to see how this is done. +@item +In @file{item_func.h}, declare a class inheriting from @code{Item_num_func} or +@code{Item_str_func}, depending on whether your function returns a number or a +string. +@item +In @file{item_func.cc}, add one of the following declarations, depending +on whether you are defining a numeric or string function: +@example +double Item_func_newname::val() +longlong Item_func_newname::val_int() +String *Item_func_newname::Str(String *str) +@end example + +If you inherit your object from any of the standard items (like +@code{Item_num_func} you probably only have to define one of the above +functions and let the parent object take care of the other functions. +For example, the @code{Item_str_func} class defines a @code{val()} function +that executes @code{atof()} on the value returned by @code{::str()}. + +@item +You should probably also define the following object function: +@example +void Item_func_newname::fix_length_and_dec() +@end example +This function should at least calculate @code{max_length} based on the +given arguments. @code{max_length} is the maximum number of characters +the function may return. This function should also set @code{maybe_null += 0} if the main function can't return a @code{NULL} value. The +function can check if any of the function arguments can return +@code{NULL} by checking the arguments @code{maybe_null} variable. You +can take a look at @code{Item_func_mod::fix_length_and_dec} for a +typical example of how to do this. +@end enumerate + +All functions must be thread safe (In other words, don't use any global or +static variables in the functions without protecting them with mutexes). + +If you want to return @code{NULL}, from @code{::val()}, @code{::val_int()} +or @code{::str()} you should set @code{null_value} to 1 and return 0. + +For @code{::str()} object functions, there are some additional +considerations to be aware of: + +@itemize @bullet +@item +The @code{String *str} argument provides a string buffer that may be +used to hold the result. (For more information about the @code{String} type, +take a look at the @file{sql_string.h} file.) +@item +The @code{::str()} function should return the string that holds the result or +@code{(char*) 0} if the result is @code{NULL}. +@item +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 + +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 +can be done on row-by-row or @code{GROUP BY} level. + +We have created an example procedure in @strong{MySQL} Version 3.23 to +show you what can be done. + +Additionally we recommend you to take a look at 'mylua', which you can find in the Contrib directory. @xref{Contrib}. Which this you can use the LUA +language to load a procedure at runtime into @code{mysqld}. + +@menu +* procedure analyse:: Procedure analyse +* Writing a procedure:: Writing a procedure. +@end menu + + +@node procedure analyse, Writing a procedure, Adding procedures, Adding procedures +@subsection Procedure Analyse + +@code{analyse([max elements,[max memory]])} + +This procedure is defined in the @file{sql/sql_analyse.cc}. This +examines the result from your query and returns an analysis of the +results: + +@itemize @bullet +@item +@code{max elements} (default 256) is the maximum number of distinct values +@code{analyse} will notice per column. This is used by @code{analyse} to check if +the optimal column type should be of type @code{ENUM}. +@item +@code{max memory} (default 8192) is the maximum memory @code{analyse} should +allocate per column while trying to find all distinct values. +@end itemize + +@example +SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]]) +@end example + + +@node Writing a procedure, , procedure analyse, Adding procedures +@subsection Writing a Procedure + +For the moment, the only documentation for this is the source. + +You can find all information about procedures by examining the following files: + +@itemize @bullet +@item @file{sql/sql_analyse.cc} +@item @file{sql/procedure.h} +@item @file{sql/procedure.cc} +@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 -@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 +@node MySQL threads, MySQL test suite, MySQL internals, MySQL internals +@subsection MySQL Threads -@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 +The @strong{MySQL} server creates the following threads: -@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 +@itemize @bullet -@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 +@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. -@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 +@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. -@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)}. +@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. -@end table +@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. -@noindent -@strong{MySQL-specific Methods} +@item +If one uses the @code{--flush_time=#} option, a dedicated thread is created +to flush all tables at the given interval. -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: +@item +Every connection has its own thread. -@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 +@item +Every different table on which one uses @code{INSERT DELAYED} gets its +own thread. -As an alternative, you can use @code{$dbh->@{'mysql_insertid'@}}. +@item +If you use @code{--master-host}, a slave replication thread will be +started to read and apply updates from the master. +@end itemize -@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 +@code{mysqladmin processlist} only shows the connection, @code{INSERT DELAYED}, +and replication threads. -@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 +@node MySQL test suite, , MySQL threads, MySQL internals +@subsection MySQL Test Suite -@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 +@cindex mysqltest, MySQL Test Suite +@cindex testing mysqld, mysqltest -@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 +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. -@code{is_not_null} is deprecated; it is preferable to use the -@code{NULLABLE} attribute (described above), because that is a DBI standard. +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. -@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: +@menu +* running mysqltest:: +* extending mysqltest:: +* Reporting mysqltest bugs:: +@end menu -@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 +@node running mysqltest, extending mysqltest, MySQL test suite, MySQL test suite +@subsubsection Running the MySQL Test Suite -@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 +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}. -@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 +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. -@end table +You can run one individual test case with +@code{mysql-test/mysql-test-run test_name}. -@cindex @code{DBI/DBD} -@node DBI-info, , Perl DBI Class, Perl -@subsection More @code{DBI}/@code{DBD} Information +If one test fails, you should test running @code{mysql-test-run} with +the @code{--force} option to check if any other tests fails. -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 +@node extending mysqltest, Reporting mysqltest bugs, running mysqltest, MySQL test suite +@subsubsection Extending the MySQL Test Suite -You can also use the @code{pod2man}, @code{pod2html}, etc., tools to -translate to other formats. +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: -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 +@itemize +@item +The tests are located in @code{mysql-test/t/*.test} -@cindex Eiffel Wrapper -@cindex wrappers, Eiffel -@node Eiffel, Java, Perl, Clients -@section MySQL Eiffel wrapper +@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} ). -The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} -contains an Eiffel wrapper written by Michael Ravits. +@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. -You can also find this at: -@url{http://www.netpedia.net/hosting/newplayer/} +@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. -@cindex Java connectivity -@cindex JDBC -@node Java, PHP, Eiffel, Clients -@section MySQL Java Connectivity (JDBC) +@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{','}. -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. +@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. -@cindex PHP API -@node PHP, Cplusplus, Java, Clients -@section MySQL PHP API +@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 -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. +@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. -The distribution and documentation are available at the -@uref{http://www.php.net/, PHP web site}. +@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}. -@menu -* PHP problems:: Common problems with MySQL and PHP -@end menu +@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 PHP problems, , PHP, PHP -@subsection Common Problems with MySQL and PHP + +@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 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 +@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: -@cindex C++ APIs -@node Cplusplus, Python, PHP, Clients -@section MySQL C++ APIs +@example +cd mysql-test +mysql-test-run --local test-name +@end example -Two APIs are available in the @strong{MySQL} -@uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory}. +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. -@cindex Python APIs -@node Python, Tcl, Cplusplus, Clients -@section MySQL Python APIs +@item +Try also to run @code{mysql-test-run} with the @code{--force} option to +see if there is any other test that fails. -The @strong{MySQL} @uref{http://www.mysql.com/Downloads/Contrib/,Contrib directory} -contains a Python interface written by Joseph Skinner. +@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 ! -You can also use the Python interface to iODBC to access a -@strong{MySQL} server. -@uref{http://starship.skyport.net/~lemburg/,mxODBC} +@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. -@cindex Tcl APIs -@node Tcl, , Python, Clients -@section MySQL Tcl APIs +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. -@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. +@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 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 -- cgit v1.2.1 From 94063bf9adfe77394d3ab4a9cb9deae2aa1da3e8 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 04:11:34 -0500 Subject: 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 -- cgit v1.2.1 From e25a3f856f2e969b56e259efd8c3ece96e716cd0 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 12:40:49 +0300 Subject: 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}, -- cgit v1.2.1 From 11136859f597842e8b2519e7cf8f8e4bddf0ddff Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 13:01:42 +0300 Subject: 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" -- cgit v1.2.1 From 572a95e1d3baeeee27fc9b3e1acb164ffddd04e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 13:47:27 +0300 Subject: 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}, -- cgit v1.2.1 From e1b8a18a02fa0eb2faac3d5cc0d17c6a6ec7b0f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 12:51:16 +0200 Subject: 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 -- cgit v1.2.1 From 8700c5636529d4ac68afeb6ab5333c6b660e8a2f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 17:05:54 +0300 Subject: 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; } + } } } -- cgit v1.2.1 From e835ab56983ab925661c135b3394eda128836ee6 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 17:37:37 +0300 Subject: 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 -- cgit v1.2.1 From d9b03fb215f7319dff8d659e110f19b08c2238ac Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Aug 2001 19:02:23 +0300 Subject: 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); -- cgit v1.2.1 From 68ab6b59adce63c6f31fd1e2a5a7c6e24d140613 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 01:42:34 +0300 Subject: 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\ -- cgit v1.2.1 From c65e21a4b3a10339123369fb83e8f40050620573 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 02:16:13 +0300 Subject: 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 -- cgit v1.2.1 From 120c77af524845d15f0923e44c557e3c19b4f6a6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 11:24:43 +0300 Subject: 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 -- cgit v1.2.1 From baa1e44ce517b3763f45c7672d97dd4fbccc93d6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 11:43:45 +0300 Subject: 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 -- cgit v1.2.1 From 34f87d9d90b5db5ae7ec4f8f7beccdaeab8dad85 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 11:53:50 +0300 Subject: 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_ */ -- cgit v1.2.1 From 12a5c3513f738116bbf5d507ef86ad5cb74ffeed Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 11 Aug 2001 14:10:27 +0300 Subject: 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 -- cgit v1.2.1