1
0
mirror of https://github.com/MariaDB/server.git synced 2025-09-02 09:41:40 +03:00

Merge with base MySQL-5.1-maria

This commit is contained in:
Michael Widenius
2009-01-12 13:12:00 +02:00
2338 changed files with 697600 additions and 342170 deletions

View File

@@ -330,6 +330,9 @@ client/readline.cpp
client/rpl_constants.h client/rpl_constants.h
client/rpl_record_old.cc client/rpl_record_old.cc
client/rpl_record_old.h client/rpl_record_old.h
client/rpl_tblmap.h
client/rpl_tblmap.cc
client/rpl_utility.h
client/select_test client/select_test
client/sql_string.cpp client/sql_string.cpp
client/ssl_test client/ssl_test
@@ -746,6 +749,8 @@ mysql-test/funcs_1.log
mysql-test/funcs_1.tar mysql-test/funcs_1.tar
mysql-test/install_test_db mysql-test/install_test_db
mysql-test/lib/init_db.sql mysql-test/lib/init_db.sql
mysql-test/linux_sys_vars.inc
mysql-test/load_sysvars.inc
mysql-test/mtr mysql-test/mtr
mysql-test/mysql-test-run mysql-test/mysql-test-run
mysql-test/mysql-test-run-shell mysql-test/mysql-test-run-shell
@@ -781,6 +786,7 @@ mysql-test/r/im_client_port.log
mysql-test/r/index_merge_load.result mysql-test/r/index_merge_load.result
mysql-test/r/isam.err mysql-test/r/isam.err
mysql-test/r/lowercase_table2.err mysql-test/r/lowercase_table2.err
mysql-test/r/max_allowed_packet_func.result
mysql-test/r/multi_update.err mysql-test/r/multi_update.err
mysql-test/r/mysql_protocols.err mysql-test/r/mysql_protocols.err
mysql-test/r/mysqlbinlog.err mysql-test/r/mysqlbinlog.err
@@ -858,6 +864,7 @@ mysql-test/t/index_merge.load
mysql-test/t/tmp.test mysql-test/t/tmp.test
mysql-test/var mysql-test/var
mysql-test/var/* mysql-test/var/*
mysql-test/windows_sys_vars.inc
mysql.kdevprj mysql.kdevprj
mysql.proj mysql.proj
mysql_priv.h mysql_priv.h
@@ -1860,3 +1867,33 @@ win/vs8cache.txt
ylwrap ylwrap
zlib/*.ds? zlib/*.ds?
zlib/*.vcproj zlib/*.vcproj
mysql-test/bug36522-64.tar
mysql-test/bug36522.tar
mysql-test/t.log
mysql-test/tps.log
libmysqld/event_parse_data.cc
autom4te.cache
sql/share/czech
sql/share/danish
sql/share/dutch
sql/share/english
sql/share/estonian
sql/share/french
sql/share/german
sql/share/greek
sql/share/hungarian
sql/share/italian
sql/share/japanese
sql/share/japanese-sjis
sql/share/korean
sql/share/norwegian
sql/share/norwegian-ny
sql/share/polish
sql/share/portuguese
sql/share/romanian
sql/share/russian
sql/share/serbian
sql/share/slovak
sql/share/spanish
sql/share/swedish
sql/share/ukrainian

View File

@@ -20,6 +20,7 @@
EXTRA_DIST = FINISH.sh \ EXTRA_DIST = FINISH.sh \
SETUP.sh \ SETUP.sh \
autorun.sh \ autorun.sh \
build_mccge.sh \
check-cpu \ check-cpu \
cleanup \ cleanup \
compile-alpha \ compile-alpha \
@@ -27,8 +28,12 @@ EXTRA_DIST = FINISH.sh \
compile-alpha-cxx \ compile-alpha-cxx \
compile-alpha-debug \ compile-alpha-debug \
compile-amd64-debug-max \ compile-amd64-debug-max \
compile-amd64-debug-max-no-ndb \
compile-amd64-gcov \
compile-amd64-gprof \
compile-amd64-max \ compile-amd64-max \
compile-amd64-max-sci \ compile-amd64-max-sci \
compile-amd64-valgrind-max \
compile-darwin-mwcc \ compile-darwin-mwcc \
compile-dist \ compile-dist \
compile-hpux11-parisc2-aCC \ compile-hpux11-parisc2-aCC \
@@ -51,8 +56,12 @@ EXTRA_DIST = FINISH.sh \
compile-pentium-mysqlfs-debug \ compile-pentium-mysqlfs-debug \
compile-pentium-pgcc \ compile-pentium-pgcc \
compile-pentium-valgrind-max \ compile-pentium-valgrind-max \
compile-pentium64 \
compile-pentium64-debug \ compile-pentium64-debug \
compile-pentium64-debug-max \ compile-pentium64-debug-max \
compile-pentium64-gcov \
compile-pentium64-gprof \
compile-pentium64-max \
compile-pentium64-max-sci \ compile-pentium64-max-sci \
compile-pentium64-valgrind-max \ compile-pentium64-valgrind-max \
compile-ppc \ compile-ppc \
@@ -60,6 +69,10 @@ EXTRA_DIST = FINISH.sh \
compile-ppc-debug-max \ compile-ppc-debug-max \
compile-ppc-debug-max-no-ndb \ compile-ppc-debug-max-no-ndb \
compile-ppc-max \ compile-ppc-max \
compile-solaris-amd64 \
compile-solaris-amd64-debug \
compile-solaris-amd64-forte \
compile-solaris-amd64-forte-debug \
compile-solaris-sparc \ compile-solaris-sparc \
compile-solaris-sparc-debug \ compile-solaris-sparc-debug \
compile-solaris-sparc-forte \ compile-solaris-sparc-forte \

View File

@@ -80,7 +80,7 @@ path=`dirname $0`
. "$path/check-cpu" . "$path/check-cpu"
export AM_MAKEFLAGS export AM_MAKEFLAGS
AM_MAKEFLAGS="-j 4" AM_MAKEFLAGS="-j 6"
# SSL library to use.--with-ssl will select our bundled yaSSL # SSL library to use.--with-ssl will select our bundled yaSSL
# implementation of SSL. To use openSSl you will nee too point out # implementation of SSL. To use openSSl you will nee too point out
@@ -105,7 +105,7 @@ if [ "x$warning_mode" != "xpedantic" ]; then
cxx_warnings="$cxx_warnings -Wreorder" cxx_warnings="$cxx_warnings -Wreorder"
cxx_warnings="$cxx_warnings -Wctor-dtor-privacy -Wnon-virtual-dtor" cxx_warnings="$cxx_warnings -Wctor-dtor-privacy -Wnon-virtual-dtor"
# Added unless --with-debug=full # Added unless --with-debug=full
debug_extra_cflags="-O1 -Wuninitialized" debug_extra_cflags="-O0 -g3 -gdwarf-2" #1 -Wuninitialized"
else else
warnings="-W -Wall -ansi -pedantic -Wno-long-long -Wno-unused -D_POSIX_SOURCE" warnings="-W -Wall -ansi -pedantic -Wno-long-long -Wno-unused -D_POSIX_SOURCE"
c_warnings="$warnings" c_warnings="$warnings"

View File

@@ -176,7 +176,7 @@ check_cpu () {
fi fi
cc_ver=`$cc --version | sed 1q` cc_ver=`$cc --version | sed 1q`
cc_verno=`echo $cc_ver | sed -e 's/^.*gcc/gcc/g; s/[^0-9. ]//g; s/^ *//g; s/ .*//g'` cc_verno=`echo $cc_ver | sed -e 's/^.*(GCC)//g; s/[^0-9. ]//g; s/^ *//g; s/ .*//g'`
set -- `echo $cc_verno | tr '.' ' '` set -- `echo $cc_verno | tr '.' ' '`
cc_major=$1 cc_major=$1
cc_minor=$2 cc_minor=$2

View File

@@ -13,35 +13,52 @@ path=`dirname $0`
# Default to gcc for CC and CXX # Default to gcc for CC and CXX
if test -z "$CXX" ; then if test -z "$CXX" ; then
export CXX=gcc CXX=gcc
# Set some required compile options # Set some required compile options
if test -z "$CXXFLAGS" ; then if test -z "$CXXFLAGS" ; then
export CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti"
fi fi
fi fi
if test -z "$CC" ; then if test -z "$CC" ; then
export CC=gcc CC=gcc
fi fi
# Use ccache, if available # Use ccache, if available
if ccache -V > /dev/null 2>&1 if ccache -V > /dev/null 2>&1
then then
if ! (echo "$CC" | grep "ccache" > /dev/null) if echo "$CC" | grep "ccache" > /dev/null
then then
export CC="ccache $CC" :
else
CC="ccache $CC"
fi fi
if ! (echo "$CXX" | grep "ccache" > /dev/null) if echo "$CXX" | grep "ccache" > /dev/null
then then
export CXX="ccache $CXX" :
else
CXX="ccache $CXX"
fi fi
fi fi
if test -z "$MAKE"
then
if gmake -v > /dev/null 2>&1
then
MAKE="gmake"
else
MAKE="make"
fi
fi
export CC CXX MAKE
# Make sure to enable all features that affect "make dist" # Make sure to enable all features that affect "make dist"
# Remember that configure restricts the man pages to the configured features ! # Remember that configure restricts the man pages to the configured features !
./configure \ ./configure \
--with-maria-storage-engine \ --with-maria-storage-engine \
--with-embedded-server \ --with-embedded-server \
--with-ndbcluster --with-ndbcluster
make $MAKE

View File

@@ -0,0 +1,24 @@
#! /bin/sh
path=`dirname $0`
. "$path/SETUP.sh"
extra_flags="$pentium_cflags $debug_cflags $valgrind_flags"
extra_configs="$pentium_configs $debug_configs $max_no_ndb_configs"
. "$path/FINISH.sh"
if test -z "$just_print"
then
set +v +x
echo "\
******************************************************************************
Note that by default BUILD/compile-pentium-valgrind-max calls 'configure' with
--enable-assembler. When Valgrind detects an error involving an assembly
function (for example an uninitialized value used as an argument of an
assembly function), Valgrind will not print the stacktrace and 'valgrind
--gdb-attach=yes' will not work either. If you need a stacktrace in those
cases, you have to run BUILD/compile-pentium-valgrind-max with the
--disable-assembler argument.
******************************************************************************"
fi

7
BUILD/compile-solaris-amd64-forte Normal file → Executable file
View File

@@ -7,22 +7,23 @@ path=`dirname $0`
. "$path/autorun.sh" . "$path/autorun.sh"
# For "optimal" code for this computer add -fast to EXTRA # For "optimal" code for this computer add -fast to EXTRA
# To compile 64 bit, add -xarch=v9 to EXTRA_64_BIT # To compile 64 bit, add -m64 to EXTRA_64_BIT
EXTRA_64_BIT="-xarch=amd64" EXTRA_64_BIT="-m64"
EXTRA="-fast" EXTRA="-fast"
# #
# The following should not need to be touched # The following should not need to be touched
# #
export CC CXX CFLAGS CXXFLAGS export CC CXX CFLAGS CXXFLAGS LIBS
STD="-g -mt -D_FORTEC_ $EXTRA $EXTRA_64_BIT" STD="-g -mt -D_FORTEC_ $EXTRA $EXTRA_64_BIT"
ASFLAGS="$EXTRA_64_BIT" ASFLAGS="$EXTRA_64_BIT"
CC=cc-5.0 CC=cc-5.0
CFLAGS="-Xa -xstrconst $STD" CFLAGS="-Xa -xstrconst $STD"
CXX=CC CXX=CC
CXXFLAGS="-noex $STD" CXXFLAGS="-noex $STD"
LIBS=-lmtmalloc
./configure \ ./configure \
--prefix=/usr/local/mysql \ --prefix=/usr/local/mysql \
--localstatedir=/usr/local/mysql/data \ --localstatedir=/usr/local/mysql/data \

View File

@@ -6,8 +6,8 @@ gmake -k clean || true
path=`dirname $0` path=`dirname $0`
. "$path/autorun.sh" . "$path/autorun.sh"
# To compile 64 bit, add -xarch=amd64 to EXTRA_64_BIT # To compile 64 bit, add -m64 to EXTRA_64_BIT
EXTRA_64_BIT="-xarch=amd64" EXTRA_64_BIT="-m64"
# For "optimal" code for this computer add -fast to EXTRA. Note that # For "optimal" code for this computer add -fast to EXTRA. Note that
# this causes problem with debugging the program since -fast implies # this causes problem with debugging the program since -fast implies

View File

@@ -9,6 +9,6 @@ PATH=$PATH:/usr/ccs/bin:/usr/local/bin
path=`dirname $0` path=`dirname $0`
. "$path/autorun.sh" . "$path/autorun.sh"
CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -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 CFLAGS="-g -Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Wunused -O3 -fno-omit-frame-pointer -mcpu=v8 -Wa,-xarch=v8plusa" CXX=gcc CXXFLAGS="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings -Woverloaded-virtual -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" LIBS="-lmtmalloc" ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client
make -j 4 make -j 4

View File

@@ -29,7 +29,7 @@ EXTRA="-fast" # Remove comment to target current machine
STD="-mt -D_FORTEC_ $EXTRA $EXTRA_64_BIT" STD="-mt -D_FORTEC_ $EXTRA $EXTRA_64_BIT"
CC=cc-5.0 CFLAGS="-Xa -xstrconst $STD" \ CC=cc-5.0 CFLAGS="-Xa -xstrconst $STD" \
CXX=CC CXXFLAGS="-noex $STD" \ CXX=CC CXXFLAGS="-noex $STD" LIBS="-lmtmalloc" \
./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --prefix=$PREFIX ./configure --prefix=/usr/local/mysql --enable-assembler --with-extra-charsets=complex --enable-thread-safe-client --prefix=$PREFIX
make -j 4 make -j 4

View File

@@ -115,18 +115,18 @@ SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DDBUG_OFF")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800 /wd4805") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800 /wd4805")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4800 /wd4805") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4800 /wd4805")
IF(CMAKE_GENERATOR MATCHES "Visual Studio 8") # Disable warnings in Visual Studio 8 and above
IF(MSVC AND NOT CMAKE_GENERATOR MATCHES "Visual Studio 7")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /wd4996") SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /wd4996")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /wd4996") SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /wd4996")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /wd4996") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /wd4996")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /wd4996") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /wd4996")
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /wd4996") SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /wd4996")
SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /wd4996") SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /wd4996")
ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 8") ENDIF(MSVC AND NOT CMAKE_GENERATOR MATCHES "Visual Studio 7")
IF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR
CMAKE_GENERATOR MATCHES "Visual Studio 8")
# Settings for Visual Studio 7 and above.
IF(MSVC)
# replace /MDd with /MTd # replace /MDd with /MTd
STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE}) STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO}) STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO})
@@ -156,9 +156,7 @@ IF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR
IF(NOT tmp_manifest) IF(NOT tmp_manifest)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
ENDIF(NOT tmp_manifest) ENDIF(NOT tmp_manifest)
ENDIF(MSVC)
ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR
CMAKE_GENERATOR MATCHES "Visual Studio 8")
IF(WIN32) IF(WIN32)
ADD_DEFINITIONS("-D_WINDOWS -D__WIN__ -D_CRT_SECURE_NO_DEPRECATE") ADD_DEFINITIONS("-D_WINDOWS -D__WIN__ -D_CRT_SECURE_NO_DEPRECATE")

View File

@@ -19,11 +19,24 @@ EXTRA_DIST = mysql.info INSTALL-BINARY @extra_docs@
# automake only seems to take care of this automatically, # automake only seems to take care of this automatically,
# if we're building the info page from texi directly. # if we're building the info page from texi directly.
install-data-hook: $(srcdir)/mysql.info install-data-hook: $(srcdir)/mysql.info
$(mkinstalldirs) $(DESTDIR)$(infodir) if test `basename $(prefix)` = "mysql" ; then \
$(INSTALL_DATA) $(srcdir)/mysql.info $(DESTDIR)$(infodir) $(mkinstalldirs) $(DESTDIR)$(prefix)/docs ; \
$(INSTALL_DATA) $(srcdir)/mysql.info $(DESTDIR)$(prefix)/docs ; \
test ! -f $(top_srcdir)/ChangeLog || $(INSTALL_DATA) $(top_srcdir)/ChangeLog $(DESTDIR)$(prefix)/docs ; \
else \
$(mkinstalldirs) $(DESTDIR)$(infodir) $(DESTDIR)$(pkgdatadir) ; \
$(INSTALL_DATA) $(srcdir)/mysql.info $(DESTDIR)$(infodir) ; \
test ! -f $(top_srcdir)/ChangeLog || $(INSTALL_DATA) $(top_srcdir)/ChangeLog $(DESTDIR)$(pkgdatadir) ; \
fi
uninstall-local: uninstall-local:
@RM@ -f $(DESTDIR)$(infodir)/mysql.info if test `basename $(prefix)` = "mysql" ; then \
@RM@ -f $(DESTDIR)$(prefix)/docs/mysql.info ; \
@RM@ -f $(DESTDIR)$(prefix)/docs/ChangeLog ; \
else \
@RM@ -f $(DESTDIR)$(infodir)/mysql.info ; \
@RM@ -f $(DESTDIR)$(pkgdatadir)/ChangeLog ; \
fi
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%

View File

@@ -20,14 +20,29 @@ If you have found a bug that is not listed here, please add it to
http://bugs.mysql.com/ so that we can either fix it for next release http://bugs.mysql.com/ so that we can either fix it for next release
or in the worst case add it here for others to know! or in the worst case add it here for others to know!
IMPORTANT:
If you have been using a MySQL-5.1-Maria-alpha build and upgrading to
MySQL-5.1-Maria-beta you MUST run maria_chk --recover on all your
Maria tables. This is because we made an incompatible change of how
transaction id is stored and old transaction id's must be reset!
cd mysql-data-directory
maria_chk --recover */*.MAI
As the Maria-1.5 engine is now in beta we will do our best to not
introduce any incompatible changes in the data format for the Maria
tables; If this would be ever be needed, we will, if possible, support
both the old and the new version to make upgrades as easy as possible.
Known bugs that we are working on and will be fixed shortly Known bugs that we are working on and will be fixed shortly
=========================================================== ===========================================================
- We have some instabilities in log writing that is under investigatation - We have some time ago some instabilities in log writing that is was
under investigation but we haven't been able to repeat in a while.
This causes mainly assert to triggers in the code and sometimes This causes mainly assert to triggers in the code and sometimes
the log handler doesn't start up after restart. the log handler doesn't start up after restart.
Most of this should now be fixed... Most of this should now be fixed.
- INSERT on a duplicate key against a key inserted by another connection - INSERT on a duplicate key against a key inserted by another connection
that has not yet ended will give a duplicate key error instead of that has not yet ended will give a duplicate key error instead of

View File

@@ -49,7 +49,7 @@ bin-dist: all
$(top_builddir)/scripts/make_binary_distribution @MAKE_BINARY_DISTRIBUTION_OPTIONS@ $(top_builddir)/scripts/make_binary_distribution @MAKE_BINARY_DISTRIBUTION_OPTIONS@
# Remove BK's "SCCS" subdirectories from source distribution # Remove BK's "SCCS" subdirectories from source distribution
# Create initial database files for Windows installations. # Create initial database files for Windows installations and check them.
dist-hook: dist-hook:
rm -rf `find $(distdir) -type d -name SCCS -print` rm -rf `find $(distdir) -type d -name SCCS -print`
mkdir -p $(distdir)/win mkdir -p $(distdir)/win
@@ -57,6 +57,9 @@ dist-hook:
--builddir=$(top_builddir) \ --builddir=$(top_builddir) \
--datadir=$(distdir)/win/data \ --datadir=$(distdir)/win/data \
--srcdir=$(top_srcdir) --srcdir=$(top_srcdir)
storage/myisam/myisamchk --silent --fast $(distdir)/win/data/mysql/*.MYI
all-local: @ABI_CHECK@
tags: tags:
support-files/build-tags support-files/build-tags
@@ -66,7 +69,7 @@ tags:
test-pl test-force-pl test-full-pl test-force-full-pl test-force-pl-mem \ test-pl test-force-pl test-full-pl test-force-full-pl test-force-pl-mem \
test-unit test-unit-big test-ps test-nr test-pr test-ns test-binlog-statement \ test-unit test-unit-big test-ps test-nr test-pr test-ns test-binlog-statement \
test-ext-funcs test-ext-rpl test-ext-partitions test-ext-jp \ test-ext-funcs test-ext-rpl test-ext-partitions test-ext-jp \
test-ext-stress test-ext test-embedded \ test-ext-stress test-ext test-embedded test-reprepare \
test-fast test-fast-cursor test-fast-view test-fast-prepare \ test-fast test-fast-cursor test-fast-view test-fast-prepare \
test-full-qa test-full-qa
@@ -112,9 +115,14 @@ test-embedded:
--embedded-server --skip-rpl --skip-ndbcluster ; \ --embedded-server --skip-rpl --skip-ndbcluster ; \
else \ else \
echo "no program found for 'embedded' tests - skipped testing" ; \ echo "no program found for 'embedded' tests - skipped testing" ; \
fi fi
test: test-ns test-pr test-reprepare:
cd mysql-test ; \
@PERL@ ./mysql-test-run.pl $(force) $(mem) --ps-protocol \
--mysqld=--debug=+d,reprepare_each_statement
test: test-ns test-pr
test-full: test test-nr test-ps test-full: test test-nr test-ps
@@ -135,15 +143,33 @@ test-bt:
-cd mysql-test ; MTR_BUILD_THREAD=auto \ -cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=ps --force --timer \ @PERL@ ./mysql-test-run.pl --comment=ps --force --timer \
--skip-ndbcluster --ps-protocol --skip-ndbcluster --ps-protocol
-if [ -e bin/ndbd -o -e storage/ndb/src/kernel/ndbd ] ; then \
cd mysql-test ; \
MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=ndb+rpl_ndb+ps --force --timer \
--ps-protocol --mysqld=--binlog-format=row --suite=ndb,rpl_ndb ; \
MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=ndb --force --timer \
--with-ndbcluster-only ; \
else \
echo "no program found for 'ndbcluster' tests - skipped testing" ; \
fi
-cd mysql-test ; MTR_BUILD_THREAD=auto \ -cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=normal+rowrepl --force --timer \ @PERL@ ./mysql-test-run.pl --force --comment=funcs1+ps --ps-protocol --reorder --suite=funcs_1
--skip-ndbcluster --mysqld=--binlog-format=row
-cd mysql-test ; MTR_BUILD_THREAD=auto \ -cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=ps+rowrepl+NDB --force --timer \ @PERL@ ./mysql-test-run.pl --force --comment=funcs2 --suite=funcs_2
--ps-protocol --mysqld=--binlog-format=row
-cd mysql-test ; MTR_BUILD_THREAD=auto \ -cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=NDB --force --timer \ @PERL@ ./mysql-test-run.pl --force --comment=partitions --suite=parts
--with-ndbcluster-only -cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --force --comment=stress --suite=stress
-if [ -d mysql-test/suite/nist ] ; then \
cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=nist --force --suite=nist ; \
fi
-if [ -d mysql-test/suite/nist ] ; then \
cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=nist+ps --force --suite=nist --ps-protocol ; \
fi
-if [ -e bin/mysqltest_embedded -o -e libmysqld/examples/mysqltest_embedded ] ; then \ -if [ -e bin/mysqltest_embedded -o -e libmysqld/examples/mysqltest_embedded ] ; then \
cd mysql-test ; MTR_BUILD_THREAD=auto \ cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=embedded --force --timer \ @PERL@ ./mysql-test-run.pl --comment=embedded --force --timer \
@@ -151,24 +177,6 @@ test-bt:
else \ else \
echo "no program found for 'embedded' tests - skipped testing" ; \ echo "no program found for 'embedded' tests - skipped testing" ; \
fi fi
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --force --comment=funcs1_ps --ps-protocol --suite=funcs_1
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --force --comment=funcs2 --suite=funcs_2
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --force --comment=rpl --suite=rpl
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --force --comment=partitions --suite=parts
-if [ -d mysql-test/suite/nist ] ; then \
cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=NIST+normal --force --suite=nist ; \
fi
-if [ -d mysql-test/suite/nist ] ; then \
cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --comment=NIST+ps --force --suite=nist --ps-protocol ; \
fi
-cd mysql-test ; MTR_BUILD_THREAD=auto \
@PERL@ ./mysql-test-run.pl --force --comment=stress --suite=stress
# Re-enable the "jp" suite when bug#28563 is fixed # Re-enable the "jp" suite when bug#28563 is fixed
# -cd mysql-test ; MTR_BUILD_THREAD=auto \ # -cd mysql-test ; MTR_BUILD_THREAD=auto \
@@ -188,7 +196,7 @@ test-force-full-pl: test-force-full
test-ext-funcs: test-ext-funcs:
cd mysql-test ; \ cd mysql-test ; \
@PERL@ ./mysql-test-run.pl --force --suite=funcs_1 ; \ @PERL@ ./mysql-test-run.pl --force --reorder --suite=funcs_1 ; \
@PERL@ ./mysql-test-run.pl --force --suite=funcs_2 @PERL@ ./mysql-test-run.pl --force --suite=funcs_2
test-ext-rpl: test-ext-rpl:
@@ -229,5 +237,81 @@ test-full-qa:
test-binlog-statement test-ext test-fast-view \ test-binlog-statement test-ext test-fast-view \
test-fast-cursor test-unit test-fast-cursor test-unit
#
# Headers which need to be checked for abi/api compatibility.
# API_PREPROCESSOR_HEADER will be used until mysql_priv.h stablizes
# after which TEST_PREPROCESSOR_HEADER will be used.
#
API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin.h \
$(top_srcdir)/include/mysql.h
TEST_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin.h \
$(top_srcdir)/sql/mysql_priv.h \
$(top_srcdir)/include/mysql.h
#
# Rules for checking that the abi/api has not changed.
#
# The following steps are followed in the do_abi_check rule below
#
# 1) Generate preprocessor output for the files that need to
# be tested for abi/api changes. use -nostdinc to prevent
# generation of preprocessor output for system headers. This
# results in messages in stderr saying that these headers
# were not found. Redirect the stderr output to /dev/null
# to prevent seeing these messages.
# 2) sed the output to
# 2.1) remove blank lines and lines that begin with "# "
# 2.2) When gcc -E is run on the Mac OS and solaris sparc platforms it
# introduces a line of output that shows up as a difference between
# the .pp and .out files. Remove these OS specific preprocessor text
# inserted by the preprocessor.
# 3) diff the generated file and the canons (.pp files already in
# the repository).
# 4) delete the .out file that is generated.
#
# If the diff fails, the generated file is not removed. This will
# be useful for analysis of ABI differences (e.g. using a visual
# diff tool).
#
# A ABI change that causes a build to fail will always be accompanied
# by new canons (.out files). The .out files that are not removed will
# be replaced as the new .pp files.
#
# e.g. If include/mysql/plugin.h has an ABI change then this rule would
# leave a <build directory>/abi_check.out file.
#
# A developer with a justified API change will then do a
# mv <build directory>/abi_check.out include/mysql/plugin.pp
# to replace the old canons with the new ones.
#
abi_check: $(API_PREPROCESSOR_HEADER)
$(MAKE) abi_headers="$^" do_abi_check
abi_check_all: $(TEST_PREPROCESSOR_HEADER)
$(MAKE) abi_headers="$^" do_abi_check
do_abi_check:
set -ex; \
for file in $(abi_headers); do \
@CC@ -E -nostdinc -dI \
-I$(top_srcdir)/include \
-I$(top_srcdir)/include/mysql \
-I$(top_srcdir)/sql \
-I$(top_builddir)/include \
-I$(top_builddir)/include/mysql \
-I$(top_builddir)/sql \
$$file 2>/dev/null | \
@SED@ -e '/^# /d' \
-e '/^[ ]*$$/d' \
-e '/^#pragma GCC set_debug_pwd/d' \
-e '/^#ident/d' > \
$(top_builddir)/abi_check.out; \
@DIFF@ -w $$file.pp $(top_builddir)/abi_check.out; \
@RM@ $(top_builddir)/abi_check.out; \
done
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%

View File

@@ -15,7 +15,7 @@
INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake") INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake")
# We use the "mysqlclient_notls" library here just as safety, in case # We use the "mysqlclient_notls" library here just as safety, in case
# any of the clients here would go beond the client API and access the # any of the clients here would go beyond the client API and access the
# Thread Local Storage directly. # Thread Local Storage directly.
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
@@ -32,9 +32,9 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c) ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c)
TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32) TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32)
ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c ADD_EXECUTABLE(mysqltest mysqltest.c)
../mysys/my_copy.c ../mysys/my_mkdir.c) SET_SOURCE_FILES_PROPERTIES(mysqltest.c PROPERTIES COMPILE_FLAGS "-DTHREADS")
TARGET_LINK_LIBRARIES(mysqltest mysqlclient_notls regex wsock32) TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex wsock32 dbug)
ADD_EXECUTABLE(mysqlcheck mysqlcheck.c) ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)
TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32) TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32)

View File

@@ -86,11 +86,14 @@ mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
$(LIBMYSQLCLIENT_LA) \ $(LIBMYSQLCLIENT_LA) \
$(top_builddir)/mysys/libmysys.a $(top_builddir)/mysys/libmysys.a
mysqltest_SOURCES= mysqltest.c \ mysqltest_SOURCES= mysqltest.c
$(top_srcdir)/mysys/my_getsystime.c \ mysqltest_CFLAGS= -DTHREAD -UUNDEF_THREADS_HACK
$(top_srcdir)/mysys/my_copy.c \ mysqltest_LDADD = $(CXXLDFLAGS) \
$(top_srcdir)/mysys/my_mkdir.c @CLIENT_EXTRA_LDFLAGS@ \
mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) $(LIBMYSQLCLIENT_LA) \
$(top_builddir)/mysys/libmysys.a \
$(top_builddir)/regex/libregex.a \
$(CLIENT_THREAD_LIBS)
mysql_upgrade_SOURCES= mysql_upgrade.c \ mysql_upgrade_SOURCES= mysql_upgrade.c \
$(top_srcdir)/mysys/my_getpagesize.c $(top_srcdir)/mysys/my_getpagesize.c
@@ -101,6 +104,7 @@ DEFS = -DUNDEF_THREADS_HACK \
-DDATADIR="\"$(localstatedir)\"" -DDATADIR="\"$(localstatedir)\""
sql_src=log_event.h mysql_priv.h rpl_constants.h \ sql_src=log_event.h mysql_priv.h rpl_constants.h \
rpl_utility.h rpl_tblmap.h rpl_tblmap.cc \
log_event.cc my_decimal.h my_decimal.cc \ log_event.cc my_decimal.h my_decimal.cc \
log_event_old.h log_event_old.cc \ log_event_old.h log_event_old.cc \
rpl_record_old.h rpl_record_old.cc rpl_record_old.h rpl_record_old.cc

View File

@@ -1631,8 +1631,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_nopager= 1; opt_nopager= 1;
break; break;
case OPT_MYSQL_PROTOCOL: case OPT_MYSQL_PROTOCOL:
#ifndef EMBEDDED_LIBRARY
opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib,
opt->name); opt->name);
#endif
break; break;
case OPT_SERVER_ARG: case OPT_SERVER_ARG:
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
@@ -1828,7 +1830,7 @@ static int read_and_execute(bool interactive)
the very beginning of a text file when the very beginning of a text file when
you save the file using "Unicode UTF-8" format. you save the file using "Unicode UTF-8" format.
*/ */
if (!line_number && if (line && !line_number &&
(uchar) line[0] == 0xEF && (uchar) line[0] == 0xEF &&
(uchar) line[1] == 0xBB && (uchar) line[1] == 0xBB &&
(uchar) line[2] == 0xBF) (uchar) line[2] == 0xBF)
@@ -2183,7 +2185,14 @@ static bool add_line(String &buffer,char *line,char *in_string,
} }
else if (!*ml_comment && (!*in_string && (inchar == '#' || else if (!*ml_comment && (!*in_string && (inchar == '#' ||
inchar == '-' && pos[1] == '-' && inchar == '-' && pos[1] == '-' &&
my_isspace(charset_info,pos[2])))) /*
The third byte is either whitespace or is the
end of the line -- which would occur only
because of the user sending newline -- which is
itself whitespace and should also match.
*/
(my_isspace(charset_info,pos[2]) ||
!pos[2]))))
{ {
// Flush previously accepted characters // Flush previously accepted characters
if (out != line) if (out != line)

View File

@@ -43,6 +43,8 @@ static DYNAMIC_STRING ds_args;
static char *opt_password= 0; static char *opt_password= 0;
static my_bool tty_password= 0; static my_bool tty_password= 0;
static char opt_tmpdir[FN_REFLEN];
#ifndef DBUG_OFF #ifndef DBUG_OFF
static char *default_dbug_option= (char*) "d:t:O,/tmp/mysql_upgrade.trace"; static char *default_dbug_option= (char*) "d:t:O,/tmp/mysql_upgrade.trace";
#endif #endif
@@ -113,6 +115,8 @@ static struct my_option my_long_options[]=
#endif #endif
{"socket", 'S', "Socket file to use for connection.", {"socket", 'S', "Socket file to use for connection.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"tmpdir", 't', "Directory for temporary files",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"user", 'u', "User for login if not current user.", (uchar**) &opt_user, {"user", 'u', "User for login if not current user.", (uchar**) &opt_user,
(uchar**) &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, (uchar**) &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#include <sslopt-longopts.h> #include <sslopt-longopts.h>
@@ -239,6 +243,11 @@ get_one_option(int optid, const struct my_option *opt,
} }
break; break;
case 't':
strnmov(opt_tmpdir, argument, sizeof(opt_tmpdir));
add_option= FALSE;
break;
case 'b': /* --basedir */ case 'b': /* --basedir */
case 'v': /* --verbose */ case 'v': /* --verbose */
case 'd': /* --datadir */ case 'd': /* --datadir */
@@ -260,6 +269,10 @@ get_one_option(int optid, const struct my_option *opt,
} }
/**
Run a command using the shell, storing its output in the supplied dynamic
string.
*/
static int run_command(char* cmd, static int run_command(char* cmd,
DYNAMIC_STRING *ds_res) DYNAMIC_STRING *ds_res)
{ {
@@ -332,37 +345,15 @@ static int run_tool(char *tool_path, DYNAMIC_STRING *ds_res, ...)
} }
/* /**
Try to get the full path to this exceutable Look for the filename of given tool, with the presumption that it is in the
same directory as mysql_upgrade and that the same executable-searching
Return 0 if path found mechanism will be used when we run our sub-shells with popen() later.
*/ */
static void find_tool(char *tool_executable_name, const char *tool_name,
static my_bool get_full_path_to_executable(char* path) const char *self_name)
{ {
my_bool ret; char *last_fn_libchar;
DBUG_ENTER("get_full_path_to_executable");
#ifdef __WIN__
ret= (GetModuleFileName(NULL, path, FN_REFLEN) == 0);
#else
/* my_readlink returns 0 if a symlink was read */
ret= (my_readlink(path, "/proc/self/exe", MYF(0)) != 0);
/* Might also want to try with /proc/$$/exe if the above fails */
#endif
DBUG_PRINT("exit", ("path: %s", path));
DBUG_RETURN(ret);
}
/*
Look for the tool in the same directory as mysql_upgrade.
*/
static void find_tool(char *tool_path, const char *tool_name)
{
size_t path_len;
char path[FN_REFLEN];
DYNAMIC_STRING ds_tmp; DYNAMIC_STRING ds_tmp;
DBUG_ENTER("find_tool"); DBUG_ENTER("find_tool");
DBUG_PRINT("enter", ("progname: %s", my_progname)); DBUG_PRINT("enter", ("progname: %s", my_progname));
@@ -370,77 +361,59 @@ static void find_tool(char *tool_path, const char *tool_name)
if (init_dynamic_string(&ds_tmp, "", 32, 32)) if (init_dynamic_string(&ds_tmp, "", 32, 32))
die("Out of memory"); die("Out of memory");
/* Initialize path with the full path to this program */ last_fn_libchar= strrchr(self_name, FN_LIBCHAR);
if (get_full_path_to_executable(path))
if (last_fn_libchar == NULL)
{ {
/* /*
Easy way to get full executable path failed, try mysql_upgrade was found by the shell searching the path. A sibling
other methods next to us should be found the same way.
*/ */
if (my_progname[0] == FN_LIBCHAR) strncpy(tool_executable_name, tool_name, FN_REFLEN);
{
/* 1. my_progname contains full path */
strmake(path, my_progname, FN_REFLEN);
}
else if (my_progname[0] == '.')
{
/* 2. my_progname contains relative path, prepend wd */
char buf[FN_REFLEN];
my_getwd(buf, FN_REFLEN, MYF(0));
my_snprintf(path, FN_REFLEN, "%s%s", buf, my_progname);
}
else
{
/* 3. Just go for it and hope tool is in path */
path[0]= 0;
}
} }
else
DBUG_PRINT("info", ("path: '%s'", path));
/* Chop off binary name (i.e mysql-upgrade) from path */
dirname_part(path, path, &path_len);
/*
When running in a not yet installed build and using libtool,
the program(mysql_upgrade) will be in .libs/ and executed
through a libtool wrapper in order to use the dynamic libraries
from this build. The same must be done for the tools(mysql and
mysqlcheck). Thus if path ends in .libs/, step up one directory
and execute the tools from there
*/
path[max(path_len-1, 0)]= 0; /* Chop off last / */
if (strncmp(path + dirname_length(path), ".libs", 5) == 0)
{ {
DBUG_PRINT("info", ("Chopping off .libs from '%s'", path)); int len;
/* Chop off .libs */ /*
dirname_part(path, path, &path_len); mysql_upgrade was run absolutely or relatively. We can find a sibling
by replacing our name after the LIBCHAR with the new tool name.
*/
/*
When running in a not yet installed build and using libtool,
the program(mysql_upgrade) will be in .libs/ and executed
through a libtool wrapper in order to use the dynamic libraries
from this build. The same must be done for the tools(mysql and
mysqlcheck). Thus if path ends in .libs/, step up one directory
and execute the tools from there
*/
if (((last_fn_libchar - 6) >= self_name) &&
(strncmp(last_fn_libchar - 5, ".libs", 5) == 0) &&
(*(last_fn_libchar - 6) == FN_LIBCHAR))
{
DBUG_PRINT("info", ("Chopping off \".libs\" from end of path"));
last_fn_libchar -= 6;
}
len= last_fn_libchar - self_name;
my_snprintf(tool_executable_name, FN_REFLEN, "%.*s%c%s",
len, self_name, FN_LIBCHAR, tool_name);
} }
verbose("Looking for '%s' as: %s", tool_name, tool_executable_name);
DBUG_PRINT("info", ("path: '%s'", path));
/* Format name of the tool to search for */
fn_format(tool_path, tool_name,
path, "", MYF(MY_REPLACE_DIR));
verbose("Looking for '%s' in: %s", tool_name, tool_path);
/* Make sure the tool exists */
if (my_access(tool_path, F_OK) != 0)
die("Can't find '%s'", tool_path);
/* /*
Make sure it can be executed Make sure it can be executed
*/ */
if (run_tool(tool_path, if (run_tool(tool_executable_name,
&ds_tmp, /* Get output from command, discard*/ &ds_tmp, /* Get output from command, discard*/
"--help", "--help",
"2>&1", "2>&1",
IF_WIN("> NUL", "> /dev/null"), IF_WIN("> NUL", "> /dev/null"),
NULL)) NULL))
die("Can't execute '%s'", tool_path); die("Can't execute '%s'", tool_executable_name);
dynstr_free(&ds_tmp); dynstr_free(&ds_tmp);
@@ -460,7 +433,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
char query_file_path[FN_REFLEN]; char query_file_path[FN_REFLEN];
DBUG_ENTER("run_query"); DBUG_ENTER("run_query");
DBUG_PRINT("enter", ("query: %s", query)); DBUG_PRINT("enter", ("query: %s", query));
if ((fd= create_temp_file(query_file_path, NULL, if ((fd= create_temp_file(query_file_path, opt_tmpdir,
"sql", O_CREAT | O_SHARE | O_RDWR, "sql", O_CREAT | O_SHARE | O_RDWR,
MYF(MY_WME))) < 0) MYF(MY_WME))) < 0)
die("Failed to create temporary file for defaults"); die("Failed to create temporary file for defaults");
@@ -750,11 +723,20 @@ static const char *load_default_groups[]=
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
char self_name[FN_REFLEN];
MY_INIT(argv[0]); MY_INIT(argv[0]);
#ifdef __NETWARE__ #ifdef __NETWARE__
setscreenmode(SCR_AUTOCLOSE_ON_EXIT); setscreenmode(SCR_AUTOCLOSE_ON_EXIT);
#endif #endif
#if __WIN__
if (GetModuleFileName(NULL, self_name, FN_REFLEN) == 0)
#endif
{
strncpy(self_name, argv[0], FN_REFLEN);
}
if (init_dynamic_string(&ds_args, "", 512, 256)) if (init_dynamic_string(&ds_args, "", 512, 256))
die("Out of memory"); die("Out of memory");
@@ -780,10 +762,10 @@ int main(int argc, char **argv)
dynstr_append(&ds_args, " "); dynstr_append(&ds_args, " ");
/* Find mysql */ /* Find mysql */
find_tool(mysql_path, IF_WIN("mysql.exe", "mysql")); find_tool(mysql_path, IF_WIN("mysql.exe", "mysql"), self_name);
/* Find mysqlcheck */ /* Find mysqlcheck */
find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck")); find_tool(mysqlcheck_path, IF_WIN("mysqlcheck.exe", "mysqlcheck"), self_name);
/* /*
Read the mysql_upgrade_info file to check if mysql_upgrade Read the mysql_upgrade_info file to check if mysql_upgrade

View File

@@ -64,7 +64,8 @@ static void warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0; static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0;
static bool opt_hexdump= 0; static bool opt_hexdump= 0;
const char *base64_output_mode_names[]= {"NEVER", "AUTO", "ALWAYS", NullS}; const char *base64_output_mode_names[]=
{"NEVER", "AUTO", "ALWAYS", "UNSPEC", "DECODE-ROWS", NullS};
TYPELIB base64_output_mode_typelib= TYPELIB base64_output_mode_typelib=
{ array_elements(base64_output_mode_names) - 1, "", { array_elements(base64_output_mode_names) - 1, "",
base64_output_mode_names, NULL }; base64_output_mode_names, NULL };
@@ -83,6 +84,8 @@ static const char* user = 0;
static char* pass = 0; static char* pass = 0;
static char *charset= 0; static char *charset= 0;
static uint verbose= 0;
static ulonglong start_position, stop_position; static ulonglong start_position, stop_position;
#define start_position_mot ((my_off_t)start_position) #define start_position_mot ((my_off_t)start_position)
#define stop_position_mot ((my_off_t)stop_position) #define stop_position_mot ((my_off_t)stop_position)
@@ -1063,6 +1066,9 @@ that may lead to an endless loop.",
{"user", 'u', "Connect to the remote server as username.", {"user", 'u', "Connect to the remote server as username.",
(uchar**) &user, (uchar**) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, (uchar**) &user, (uchar**) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0,
0, 0}, 0, 0},
{"verbose", 'v', "Reconstruct SQL statements out of row events. "
"-v -v adds comments on column data types",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, {"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
0, 0, 0, 0, 0}, 0, 0, 0, 0, 0},
{"open_files_limit", OPT_OPEN_FILES_LIMIT, {"open_files_limit", OPT_OPEN_FILES_LIMIT,
@@ -1258,6 +1264,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
(find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1); (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1);
} }
break; break;
case 'v':
if (argument == disabled_my_option)
verbose= 0;
else
verbose++;
break;
case 'V': case 'V':
print_version(); print_version();
exit(0); exit(0);
@@ -1343,6 +1355,8 @@ static Exit_status dump_log_entries(const char* logname)
*/ */
fprintf(result_file, "DELIMITER /*!*/;\n"); fprintf(result_file, "DELIMITER /*!*/;\n");
strmov(print_event_info.delimiter, "/*!*/;"); strmov(print_event_info.delimiter, "/*!*/;");
print_event_info.verbose= short_form ? 0 : verbose;
rc= (remote_opt ? dump_remote_log_entries(&print_event_info, logname) : rc= (remote_opt ? dump_remote_log_entries(&print_event_info, logname) :
dump_local_log_entries(&print_event_info, logname)); dump_local_log_entries(&print_event_info, logname));
@@ -1926,7 +1940,7 @@ int main(int argc, char** argv)
DBUG_ENTER("main"); DBUG_ENTER("main");
DBUG_PROCESS(argv[0]); DBUG_PROCESS(argv[0]);
init_time(); // for time functions my_init_time(); // for time functions
parse_args(&argc, (char***)&argv); parse_args(&argc, (char***)&argv);
defaults_argv=argv; defaults_argv=argv;

View File

@@ -517,9 +517,14 @@ static int process_all_tables_in_db(char *database)
LINT_INIT(res); LINT_INIT(res);
if (use_db(database)) if (use_db(database))
return 1; return 1;
if (mysql_query(sock, "SHOW /*!50002 FULL*/ TABLES") || if ((mysql_query(sock, "SHOW /*!50002 FULL*/ TABLES") &&
!((res= mysql_store_result(sock)))) mysql_query(sock, "SHOW TABLES")) ||
!(res= mysql_store_result(sock)))
{
my_printf_error(0, "Error: Couldn't get table list for database %s: %s",
MYF(0), database, mysql_error(sock));
return 1; return 1;
}
num_columns= mysql_num_fields(res); num_columns= mysql_num_fields(res);

View File

@@ -2396,8 +2396,15 @@ static uint get_table_structure(char *table, char *db, char *table_type,
fprintf(sql_file, ",\n %s %s", fprintf(sql_file, ",\n %s %s",
quote_name(row[0], name_buff, 0), row[1]); quote_name(row[0], name_buff, 0), row[1]);
} }
/*
Stand-in tables are always MyISAM tables as the default
engine might have a column-limit that's lower than the
number of columns in the view, and MyISAM support is
guaranteed to be in the server anyway.
*/
fprintf(sql_file, fprintf(sql_file,
"\n) */;\n" "\n) ENGINE=MyISAM */;\n"
"SET character_set_client = @saved_cs_client;\n"); "SET character_set_client = @saved_cs_client;\n");
check_io(sql_file); check_io(sql_file);
@@ -4347,7 +4354,10 @@ static int do_flush_tables_read_lock(MYSQL *mysql_con)
update starts between the two FLUSHes, we have that bad stall. update starts between the two FLUSHes, we have that bad stall.
*/ */
return return
( mysql_query_with_error_report(mysql_con, 0, "FLUSH TABLES") || ( mysql_query_with_error_report(mysql_con, 0,
((opt_master_data != 0) ?
"FLUSH /*!40101 LOCAL */ TABLES" :
"FLUSH TABLES")) ||
mysql_query_with_error_report(mysql_con, 0, mysql_query_with_error_report(mysql_con, 0,
"FLUSH TABLES WITH READ LOCK") ); "FLUSH TABLES WITH READ LOCK") );
} }

View File

@@ -1886,10 +1886,17 @@ limit_not_met:
{ {
if (mysql_field_count(mysql)) if (mysql_field_count(mysql))
{ {
result= mysql_store_result(mysql); if ((result= mysql_store_result(mysql)))
while ((row = mysql_fetch_row(result))) {
counter++; while ((row = mysql_fetch_row(result)))
mysql_free_result(result); counter++;
mysql_free_result(result);
}
else
{
fprintf(stderr,"%s: Error in mysql_store_result(): %d %s\n",
my_progname, mysql_errno(mysql), mysql_error(mysql));
}
} }
} while(mysql_next_result(mysql) == 0); } while(mysql_next_result(mysql) == 0);
queries++; queries++;

View File

@@ -48,7 +48,15 @@
#ifdef __WIN__ #ifdef __WIN__
#include <direct.h> #include <direct.h>
#endif #endif
#include <signal.h>
#include <my_stacktrace.h>
#ifdef __WIN__
#include <crtdbg.h>
#define SIGNAL_FMT "exception 0x%x"
#else
#define SIGNAL_FMT "signal %d"
#endif
/* Use cygwin for --exec and --system before 5.0 */ /* Use cygwin for --exec and --system before 5.0 */
#if MYSQL_VERSION_ID < 50000 #if MYSQL_VERSION_ID < 50000
@@ -167,6 +175,8 @@ static ulonglong timer_now(void);
static ulonglong progress_start= 0; static ulonglong progress_start= 0;
static ulong connection_retry_sleep= 100000; /* Microseconds */
/* Precompiled re's */ /* Precompiled re's */
static my_regex_t ps_re; /* the query can be run using PS protocol */ static my_regex_t ps_re; /* the query can be run using PS protocol */
static my_regex_t sp_re; /* the query can be run as a SP */ static my_regex_t sp_re; /* the query can be run as a SP */
@@ -222,6 +232,7 @@ struct st_connection
/* Used when creating views and sp, to avoid implicit commit */ /* Used when creating views and sp, to avoid implicit commit */
MYSQL* util_mysql; MYSQL* util_mysql;
char *name; char *name;
size_t name_len;
MYSQL_STMT* stmt; MYSQL_STMT* stmt;
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
@@ -275,7 +286,8 @@ enum enum_commands {
Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST,
Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP, Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP,
Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES, Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES,
Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, Q_LIST_FILES,
Q_LIST_FILES_WRITE_FILE, Q_LIST_FILES_APPEND_FILE,
Q_UNKNOWN, /* Unknown command. */ Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */ Q_COMMENT, /* Comments, ignored. */
@@ -367,6 +379,9 @@ const char *command_names[]=
"change_user", "change_user",
"mkdir", "mkdir",
"rmdir", "rmdir",
"list_files",
"list_files_write_file",
"list_files_append_file",
0 0
}; };
@@ -490,6 +505,9 @@ void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val); void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val);
void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input); void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING* ds_input);
static int match_expected_error(struct st_command *command,
unsigned int err_errno,
const char *err_sqlstate);
void handle_error(struct st_command*, void handle_error(struct st_command*,
unsigned int err_errno, const char *err_error, unsigned int err_errno, const char *err_error,
const char *err_sqlstate, DYNAMIC_STRING *ds); const char *err_sqlstate, DYNAMIC_STRING *ds);
@@ -843,29 +861,25 @@ void check_command_args(struct st_command *command,
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
void handle_command_error(struct st_command *command, uint error) void handle_command_error(struct st_command *command, uint error)
{ {
DBUG_ENTER("handle_command_error"); DBUG_ENTER("handle_command_error");
DBUG_PRINT("enter", ("error: %d", error)); DBUG_PRINT("enter", ("error: %d", error));
if (error != 0) if (error != 0)
{ {
uint i; int i;
if (command->abort_on_error) if (command->abort_on_error)
die("command \"%.*s\" failed with error %d", die("command \"%.*s\" failed with error %d",
command->first_word_len, command->query, error); command->first_word_len, command->query, error);
for (i= 0; i < command->expected_errors.count; i++)
i= match_expected_error(command, error, NULL);
if (i >= 0)
{ {
DBUG_PRINT("info", ("expected error: %d", DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d",
command->expected_errors.err[i].code.errnum)); command->first_word_len, command->query, error));
if ((command->expected_errors.err[i].type == ERR_ERRNO) && DBUG_VOID_RETURN;
(command->expected_errors.err[i].code.errnum == error))
{
DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d",
command->first_word_len, command->query, error));
DBUG_VOID_RETURN;
}
} }
die("command \"%.*s\" failed with wrong error: %d", die("command \"%.*s\" failed with wrong error: %d",
command->first_word_len, command->query, error); command->first_word_len, command->query, error);
@@ -1528,7 +1542,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
DBUG_ENTER("dyn_string_cmp"); DBUG_ENTER("dyn_string_cmp");
DBUG_PRINT("enter", ("fname: %s", fname)); DBUG_PRINT("enter", ("fname: %s", fname));
if ((fd= create_temp_file(temp_file_path, NULL, if ((fd= create_temp_file(temp_file_path, TMPDIR,
"tmp", O_CREAT | O_SHARE | O_RDWR, "tmp", O_CREAT | O_SHARE | O_RDWR,
MYF(MY_WME))) < 0) MYF(MY_WME))) < 0)
die("Failed to create temporary file for ds"); die("Failed to create temporary file for ds");
@@ -2486,8 +2500,8 @@ void do_exec(struct st_command *command)
error= pclose(res_file); error= pclose(res_file);
if (error > 0) if (error > 0)
{ {
uint status= WEXITSTATUS(error), i; uint status= WEXITSTATUS(error);
my_bool ok= 0; int i;
if (command->abort_on_error) if (command->abort_on_error)
{ {
@@ -2499,19 +2513,13 @@ void do_exec(struct st_command *command)
DBUG_PRINT("info", DBUG_PRINT("info",
("error: %d, status: %d", error, status)); ("error: %d, status: %d", error, status));
for (i= 0; i < command->expected_errors.count; i++)
{ i= match_expected_error(command, status, NULL);
DBUG_PRINT("info", ("expected error: %d",
command->expected_errors.err[i].code.errnum)); if (i >= 0)
if ((command->expected_errors.err[i].type == ERR_ERRNO) && DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d",
(command->expected_errors.err[i].code.errnum == status)) command->first_argument, status));
{ else
ok= 1;
DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d",
command->first_argument, status));
}
}
if (!ok)
{ {
dynstr_free(&ds_cmd); dynstr_free(&ds_cmd);
die("command \"%s\" failed with wrong error: %d", die("command \"%s\" failed with wrong error: %d",
@@ -2815,7 +2823,7 @@ void do_mkdir(struct st_command *command)
int error; int error;
static DYNAMIC_STRING ds_dirname; static DYNAMIC_STRING ds_dirname;
const struct command_arg mkdir_args[] = { const struct command_arg mkdir_args[] = {
"dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to create" {"dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to create"}
}; };
DBUG_ENTER("do_mkdir"); DBUG_ENTER("do_mkdir");
@@ -2845,7 +2853,7 @@ void do_rmdir(struct st_command *command)
int error; int error;
static DYNAMIC_STRING ds_dirname; static DYNAMIC_STRING ds_dirname;
const struct command_arg rmdir_args[] = { const struct command_arg rmdir_args[] = {
"dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to remove" { "dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to remove" }
}; };
DBUG_ENTER("do_rmdir"); DBUG_ENTER("do_rmdir");
@@ -2861,6 +2869,126 @@ void do_rmdir(struct st_command *command)
} }
/*
SYNOPSIS
get_list_files
ds output
ds_dirname dir to list
ds_wild wild-card file pattern (can be empty)
DESCRIPTION
list all entries in directory (matching ds_wild if given)
*/
static int get_list_files(DYNAMIC_STRING *ds, const DYNAMIC_STRING *ds_dirname,
const DYNAMIC_STRING *ds_wild)
{
uint i;
MY_DIR *dir_info;
FILEINFO *file;
DBUG_ENTER("get_list_files");
DBUG_PRINT("info", ("listing directory: %s", ds_dirname->str));
/* Note that my_dir sorts the list if not given any flags */
if (!(dir_info= my_dir(ds_dirname->str, MYF(0))))
DBUG_RETURN(1);
for (i= 0; i < (uint) dir_info->number_off_files; i++)
{
file= dir_info->dir_entry + i;
if (file->name[0] == '.' &&
(file->name[1] == '\0' ||
(file->name[1] == '.' && file->name[2] == '\0')))
continue; /* . or .. */
if (ds_wild && ds_wild->length &&
wild_compare(file->name, ds_wild->str, 0))
continue;
dynstr_append(ds, file->name);
dynstr_append(ds, "\n");
}
my_dirend(dir_info);
DBUG_RETURN(0);
}
/*
SYNOPSIS
do_list_files
command called command
DESCRIPTION
list_files <dir_name> [<file_name>]
List files and directories in directory <dir_name> (like `ls`)
[Matching <file_name>, where wild-cards are allowed]
*/
static void do_list_files(struct st_command *command)
{
int error;
static DYNAMIC_STRING ds_dirname;
static DYNAMIC_STRING ds_wild;
const struct command_arg list_files_args[] = {
{"dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to list"},
{"file", ARG_STRING, FALSE, &ds_wild, "Filename (incl. wildcard)"}
};
DBUG_ENTER("do_list_files");
check_command_args(command, command->first_argument,
list_files_args,
sizeof(list_files_args)/sizeof(struct command_arg), ' ');
error= get_list_files(&ds_res, &ds_dirname, &ds_wild);
handle_command_error(command, error);
dynstr_free(&ds_dirname);
dynstr_free(&ds_wild);
DBUG_VOID_RETURN;
}
/*
SYNOPSIS
do_list_files_write_file_command
command called command
append append file, or create new
DESCRIPTION
list_files_{write|append}_file <filename> <dir_name> [<match_file>]
List files and directories in directory <dir_name> (like `ls`)
[Matching <match_file>, where wild-cards are allowed]
Note: File will be truncated if exists and append is not true.
*/
static void do_list_files_write_file_command(struct st_command *command,
my_bool append)
{
int error;
static DYNAMIC_STRING ds_content;
static DYNAMIC_STRING ds_filename;
static DYNAMIC_STRING ds_dirname;
static DYNAMIC_STRING ds_wild;
const struct command_arg list_files_args[] = {
{"filename", ARG_STRING, TRUE, &ds_filename, "Filename for write"},
{"dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to list"},
{"file", ARG_STRING, FALSE, &ds_wild, "Filename (incl. wildcard)"}
};
DBUG_ENTER("do_list_files_write_file");
check_command_args(command, command->first_argument,
list_files_args,
sizeof(list_files_args)/sizeof(struct command_arg), ' ');
init_dynamic_string(&ds_content, "", 1024, 1024);
error= get_list_files(&ds_content, &ds_dirname, &ds_wild);
handle_command_error(command, error);
str_to_file2(ds_filename.str, ds_content.str, ds_content.length, append);
dynstr_free(&ds_content);
dynstr_free(&ds_filename);
dynstr_free(&ds_dirname);
dynstr_free(&ds_wild);
DBUG_VOID_RETURN;
}
/* /*
Read characters from line buffer or file. This is needed to allow Read characters from line buffer or file. This is needed to allow
my_ungetc() to buffer MAX_DELIMITER_LENGTH characters for a file my_ungetc() to buffer MAX_DELIMITER_LENGTH characters for a file
@@ -4191,7 +4319,6 @@ void safe_connect(MYSQL* mysql, const char *name, const char *host,
int port, const char *sock) int port, const char *sock)
{ {
int failed_attempts= 0; int failed_attempts= 0;
static ulong connection_retry_sleep= 100000; /* Microseconds */
DBUG_ENTER("safe_connect"); DBUG_ENTER("safe_connect");
while(!mysql_real_connect(mysql, host,user, pass, db, port, sock, while(!mysql_real_connect(mysql, host,user, pass, db, port, sock,
@@ -4258,6 +4385,7 @@ int connect_n_handle_errors(struct st_command *command,
const char* db, int port, const char* sock) const char* db, int port, const char* sock)
{ {
DYNAMIC_STRING *ds; DYNAMIC_STRING *ds;
int failed_attempts= 0;
ds= &ds_res; ds= &ds_res;
@@ -4286,9 +4414,41 @@ int connect_n_handle_errors(struct st_command *command,
dynstr_append_mem(ds, delimiter, delimiter_length); dynstr_append_mem(ds, delimiter, delimiter_length);
dynstr_append_mem(ds, "\n", 1); dynstr_append_mem(ds, "\n", 1);
} }
if (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0, while (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0,
CLIENT_MULTI_STATEMENTS)) CLIENT_MULTI_STATEMENTS))
{ {
/*
If we have used up all our connections check whether this
is expected (by --error). If so, handle the error right away.
Otherwise, give it some extra time to rule out race-conditions.
If extra-time doesn't help, we have an unexpected error and
must abort -- just proceeding to handle_error() when second
and third chances are used up will handle that for us.
There are various user-limits of which only max_user_connections
and max_connections_per_hour apply at connect time. For the
the second to create a race in our logic, we'd need a limits
test that runs without a FLUSH for longer than an hour, so we'll
stay clear of trying to work out which exact user-limit was
exceeded.
*/
if (((mysql_errno(con) == ER_TOO_MANY_USER_CONNECTIONS) ||
(mysql_errno(con) == ER_USER_LIMIT_REACHED)) &&
(failed_attempts++ < opt_max_connect_retries))
{
int i;
i= match_expected_error(command, mysql_errno(con), mysql_sqlstate(con));
if (i >= 0)
goto do_handle_error; /* expected error, handle */
my_sleep(connection_retry_sleep); /* unexpected error, wait */
continue; /* and give it 1 more chance */
}
do_handle_error:
var_set_errno(mysql_errno(con)); var_set_errno(mysql_errno(con));
handle_error(command, mysql_errno(con), mysql_error(con), handle_error(command, mysql_errno(con), mysql_error(con),
mysql_sqlstate(con), ds); mysql_sqlstate(con), ds);
@@ -4470,6 +4630,7 @@ void do_connect(struct st_command *command)
ds_connection_name.str)); ds_connection_name.str));
if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME)))) if (!(con_slot->name= my_strdup(ds_connection_name.str, MYF(MY_WME))))
die("Out of memory"); die("Out of memory");
con_slot->name_len= strlen(con_slot->name);
cur_con= con_slot; cur_con= con_slot;
if (con_slot == next_con) if (con_slot == next_con)
@@ -5539,6 +5700,7 @@ void init_win_path_patterns()
const char* paths[] = { "$MYSQL_TEST_DIR", const char* paths[] = { "$MYSQL_TEST_DIR",
"$MYSQL_TMP_DIR", "$MYSQL_TMP_DIR",
"$MYSQLTEST_VARDIR", "$MYSQLTEST_VARDIR",
"$MASTER_MYSOCK",
"./test/" }; "./test/" };
int num_paths= sizeof(paths)/sizeof(char*); int num_paths= sizeof(paths)/sizeof(char*);
int i; int i;
@@ -5643,8 +5805,10 @@ void fix_win_paths(const char *val, int len)
*/ */
void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field, void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field,
const char* val, ulonglong len, my_bool is_null) char* val, ulonglong len, my_bool is_null)
{ {
char null[]= "NULL";
if (col_idx < max_replace_column && replace_column[col_idx]) if (col_idx < max_replace_column && replace_column[col_idx])
{ {
val= replace_column[col_idx]; val= replace_column[col_idx];
@@ -5652,7 +5816,7 @@ void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field,
} }
else if (is_null) else if (is_null)
{ {
val= "NULL"; val= null;
len= 4; len= 4;
} }
#ifdef __WIN__ #ifdef __WIN__
@@ -5666,9 +5830,18 @@ void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field,
(start[1] == '-' || start[1] == '+') && start[2] == '0') (start[1] == '-' || start[1] == '+') && start[2] == '0')
{ {
start+=2; /* Now points at first '0' */ start+=2; /* Now points at first '0' */
/* Move all chars after the first '0' one step left */ if (field->flags & ZEROFILL_FLAG)
memmove(start, start + 1, strlen(start)); {
len--; /* Move all chars before the first '0' one step right */
memmove(val + 1, val, start - val);
*val= '0';
}
else
{
/* Move all chars after the first '0' one step left */
memmove(start, start + 1, strlen(start));
len--;
}
} }
} }
#endif #endif
@@ -5707,7 +5880,7 @@ void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
lengths = mysql_fetch_lengths(res); lengths = mysql_fetch_lengths(res);
for (i = 0; i < num_fields; i++) for (i = 0; i < num_fields; i++)
append_field(ds, i, &fields[i], append_field(ds, i, &fields[i],
(const char*)row[i], lengths[i], !row[i]); row[i], lengths[i], !row[i]);
if (!display_result_vertically) if (!display_result_vertically)
dynstr_append_mem(ds, "\n", 1); dynstr_append_mem(ds, "\n", 1);
} }
@@ -5756,7 +5929,7 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
while (mysql_stmt_fetch(stmt) == 0) while (mysql_stmt_fetch(stmt) == 0)
{ {
for (i= 0; i < num_fields; i++) for (i= 0; i < num_fields; i++)
append_field(ds, i, &fields[i], (const char *) my_bind[i].buffer, append_field(ds, i, &fields[i], my_bind[i].buffer,
*my_bind[i].length, *my_bind[i].is_null); *my_bind[i].length, *my_bind[i].is_null);
if (!display_result_vertically) if (!display_result_vertically)
dynstr_append_mem(ds, "\n", 1); dynstr_append_mem(ds, "\n", 1);
@@ -6052,6 +6225,56 @@ end:
} }
/*
Check whether given error is in list of expected errors
SYNOPSIS
match_expected_error()
PARAMETERS
command the current command (and its expect-list)
err_errno error number of the error that actually occurred
err_sqlstate SQL-state that was thrown, or NULL for impossible
(file-ops, diff, etc.)
RETURNS
-1 for not in list, index in list of expected errors otherwise
NOTE
If caller needs to know whether the list was empty, they should
check command->expected_errors.count.
*/
static int match_expected_error(struct st_command *command,
unsigned int err_errno,
const char *err_sqlstate)
{
uint i;
for (i= 0 ; (uint) i < command->expected_errors.count ; i++)
{
if ((command->expected_errors.err[i].type == ERR_ERRNO) &&
(command->expected_errors.err[i].code.errnum == err_errno))
return i;
if (command->expected_errors.err[i].type == ERR_SQLSTATE)
{
/*
NULL is quite likely, but not in conjunction with a SQL-state expect!
*/
if (unlikely(err_sqlstate == NULL))
die("expecting a SQL-state (%s) from query '%s' which cannot produce one...",
command->expected_errors.err[i].code.sqlstate, command->query);
if (strncmp(command->expected_errors.err[i].code.sqlstate,
err_sqlstate, SQLSTATE_LENGTH) == 0)
return i;
}
}
return -1;
}
/* /*
Handle errors which occurred during execution Handle errors which occurred during execution
@@ -6072,7 +6295,7 @@ void handle_error(struct st_command *command,
unsigned int err_errno, const char *err_error, unsigned int err_errno, const char *err_error,
const char *err_sqlstate, DYNAMIC_STRING *ds) const char *err_sqlstate, DYNAMIC_STRING *ds)
{ {
uint i; int i;
DBUG_ENTER("handle_error"); DBUG_ENTER("handle_error");
@@ -6098,34 +6321,30 @@ void handle_error(struct st_command *command,
DBUG_PRINT("info", ("expected_errors.count: %d", DBUG_PRINT("info", ("expected_errors.count: %d",
command->expected_errors.count)); command->expected_errors.count));
for (i= 0 ; (uint) i < command->expected_errors.count ; i++)
i= match_expected_error(command, err_errno, err_sqlstate);
if (i >= 0)
{ {
if (((command->expected_errors.err[i].type == ERR_ERRNO) && if (!disable_result_log)
(command->expected_errors.err[i].code.errnum == err_errno)) ||
((command->expected_errors.err[i].type == ERR_SQLSTATE) &&
(strncmp(command->expected_errors.err[i].code.sqlstate,
err_sqlstate, SQLSTATE_LENGTH) == 0)))
{ {
if (!disable_result_log) if (command->expected_errors.count == 1)
{ {
if (command->expected_errors.count == 1) /* Only log error if there is one possible error */
{ dynstr_append_mem(ds, "ERROR ", 6);
/* Only log error if there is one possible error */ replace_dynstr_append(ds, err_sqlstate);
dynstr_append_mem(ds, "ERROR ", 6); dynstr_append_mem(ds, ": ", 2);
replace_dynstr_append(ds, err_sqlstate); replace_dynstr_append(ds, err_error);
dynstr_append_mem(ds, ": ", 2); dynstr_append_mem(ds,"\n",1);
replace_dynstr_append(ds, err_error);
dynstr_append_mem(ds,"\n",1);
}
/* Don't log error if we may not get an error */
else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
(command->expected_errors.err[0].type == ERR_ERRNO &&
command->expected_errors.err[0].code.errnum != 0))
dynstr_append(ds,"Got one of the listed errors\n");
} }
/* OK */ /* Don't log error if we may not get an error */
DBUG_VOID_RETURN; else if (command->expected_errors.err[0].type == ERR_SQLSTATE ||
(command->expected_errors.err[0].type == ERR_ERRNO &&
command->expected_errors.err[0].code.errnum != 0))
dynstr_append(ds,"Got one of the listed errors\n");
} }
/* OK */
DBUG_VOID_RETURN;
} }
DBUG_PRINT("info",("i: %d expected_errors: %d", i, DBUG_PRINT("info",("i: %d expected_errors: %d", i,
@@ -6140,7 +6359,7 @@ void handle_error(struct st_command *command,
dynstr_append_mem(ds, "\n", 1); dynstr_append_mem(ds, "\n", 1);
} }
if (i) if (command->expected_errors.count > 0)
{ {
if (command->expected_errors.err[0].type == ERR_ERRNO) if (command->expected_errors.err[0].type == ERR_ERRNO)
die("query '%s' failed with wrong errno %d: '%s', instead of %d...", die("query '%s' failed with wrong errno %d: '%s', instead of %d...",
@@ -6875,6 +7094,104 @@ void mark_progress(struct st_command* command __attribute__((unused)),
} }
#ifdef HAVE_STACKTRACE
static void dump_backtrace(void)
{
struct st_connection *conn= cur_con;
my_safe_print_str("read_command_buf", read_command_buf,
sizeof(read_command_buf));
if (conn)
{
my_safe_print_str("conn->name", conn->name, conn->name_len);
#ifdef EMBEDDED_LIBRARY
my_safe_print_str("conn->cur_query", conn->cur_query, conn->cur_query_len);
#endif
}
fputs("Attempting backtrace...\n", stderr);
my_print_stacktrace(NULL, my_thread_stack_size);
}
#else
static void dump_backtrace(void)
{
fputs("Backtrace not available.\n", stderr);
}
#endif
static sig_handler signal_handler(int sig)
{
fprintf(stderr, "mysqltest got " SIGNAL_FMT "\n", sig);
dump_backtrace();
}
#ifdef __WIN__
LONG WINAPI exception_filter(EXCEPTION_POINTERS *exp)
{
__try
{
my_set_exception_pointers(exp);
signal_handler(exp->ExceptionRecord->ExceptionCode);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
fputs("Got exception in exception handler!\n", stderr);
}
return EXCEPTION_CONTINUE_SEARCH;
}
static void init_signal_handling(void)
{
UINT mode;
/* Set output destination of messages to the standard error stream. */
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
/* Do not not display the a error message box. */
mode= SetErrorMode(0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX;
SetErrorMode(mode);
SetUnhandledExceptionFilter(exception_filter);
}
#else /* __WIN__ */
static void init_signal_handling(void)
{
struct sigaction sa;
DBUG_ENTER("init_signal_handling");
#ifdef HAVE_STACKTRACE
my_init_stacktrace();
#endif
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
sigemptyset(&sa.sa_mask);
sigprocmask(SIG_SETMASK, &sa.sa_mask, NULL);
sa.sa_handler= signal_handler;
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGABRT, &sa, NULL);
#ifdef SIGBUS
sigaction(SIGBUS, &sa, NULL);
#endif
sigaction(SIGILL, &sa, NULL);
sigaction(SIGFPE, &sa, NULL);
}
#endif /* !__WIN__ */
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
@@ -6888,6 +7205,8 @@ int main(int argc, char **argv)
save_file[0]= 0; save_file[0]= 0;
TMPDIR[0]= 0; TMPDIR[0]= 0;
init_signal_handling();
/* Init expected errors */ /* Init expected errors */
memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));
@@ -7074,6 +7393,13 @@ int main(int argc, char **argv)
case Q_REMOVE_FILE: do_remove_file(command); break; case Q_REMOVE_FILE: do_remove_file(command); break;
case Q_MKDIR: do_mkdir(command); break; case Q_MKDIR: do_mkdir(command); break;
case Q_RMDIR: do_rmdir(command); break; case Q_RMDIR: do_rmdir(command); break;
case Q_LIST_FILES: do_list_files(command); break;
case Q_LIST_FILES_WRITE_FILE:
do_list_files_write_file_command(command, FALSE);
break;
case Q_LIST_FILES_APPEND_FILE:
do_list_files_write_file_command(command, TRUE);
break;
case Q_FILE_EXIST: do_file_exist(command); break; case Q_FILE_EXIST: do_file_exist(command); break;
case Q_WRITE_FILE: do_write_file(command); break; case Q_WRITE_FILE: do_write_file(command); break;
case Q_APPEND_FILE: do_append_file(command); break; case Q_APPEND_FILE: do_append_file(command); break;
@@ -8143,8 +8469,6 @@ uint replace_len(char * str)
uint len=0; uint len=0;
while (*str) while (*str)
{ {
if (str[0] == '\\' && str[1])
str++;
str++; str++;
len++; len++;
} }
@@ -8157,7 +8481,6 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
char * word_end_chars) char * word_end_chars)
{ {
static const int SPACE_CHAR= 256; static const int SPACE_CHAR= 256;
static const int START_OF_LINE= 257;
static const int END_OF_LINE= 258; static const int END_OF_LINE= 258;
uint i,j,states,set_nr,len,result_len,max_length,found_end,bits_set,bit_nr; uint i,j,states,set_nr,len,result_len,max_length,found_end,bits_set,bit_nr;
@@ -8243,35 +8566,7 @@ REPLACE *init_replace(char * *from, char * *to,uint count,
} }
for (pos=from[i], len=0; *pos ; pos++) for (pos=from[i], len=0; *pos ; pos++)
{ {
if (*pos == '\\' && *(pos+1)) follow_ptr->chr= (uchar) *pos;
{
pos++;
switch (*pos) {
case 'b':
follow_ptr->chr = SPACE_CHAR;
break;
case '^':
follow_ptr->chr = START_OF_LINE;
break;
case '$':
follow_ptr->chr = END_OF_LINE;
break;
case 'r':
follow_ptr->chr = '\r';
break;
case 't':
follow_ptr->chr = '\t';
break;
case 'v':
follow_ptr->chr = '\v';
break;
default:
follow_ptr->chr = (uchar) *pos;
break;
}
}
else
follow_ptr->chr= (uchar) *pos;
follow_ptr->table_offset=i; follow_ptr->table_offset=i;
follow_ptr->len= ++len; follow_ptr->len= ++len;
follow_ptr++; follow_ptr++;

View File

@@ -343,8 +343,8 @@ case $default_charset in
default_charset_default_collation="ucs2_general_ci" default_charset_default_collation="ucs2_general_ci"
define(UCSC1, ucs2_general_ci ucs2_bin) define(UCSC1, ucs2_general_ci ucs2_bin)
define(UCSC2, ucs2_czech_ci ucs2_danish_ci) define(UCSC2, ucs2_czech_ci ucs2_danish_ci)
define(UCSC3, ucs2_esperanto_ci ucs2_estonian_ci ucs2_icelandic_ci) define(UCSC3, ucs2_esperanto_ci ucs2_estonian_ci ucs2_hungarian_ci)
define(UCSC4, ucs2_latvian_ci ucs2_lithuanian_ci) define(UCSC4, ucs2_icelandic_ci ucs2_latvian_ci ucs2_lithuanian_ci)
define(UCSC5, ucs2_persian_ci ucs2_polish_ci ucs2_romanian_ci) define(UCSC5, ucs2_persian_ci ucs2_polish_ci ucs2_romanian_ci)
define(UCSC6, ucs2_slovak_ci ucs2_slovenian_ci) define(UCSC6, ucs2_slovak_ci ucs2_slovenian_ci)
define(UCSC7, ucs2_spanish2_ci ucs2_spanish_ci) define(UCSC7, ucs2_spanish2_ci ucs2_spanish_ci)
@@ -367,8 +367,8 @@ case $default_charset in
else else
define(UTFC1, utf8_general_ci utf8_bin) define(UTFC1, utf8_general_ci utf8_bin)
define(UTFC2, utf8_czech_ci utf8_danish_ci) define(UTFC2, utf8_czech_ci utf8_danish_ci)
define(UTFC3, utf8_esperanto_ci utf8_estonian_ci utf8_icelandic_ci) define(UTFC3, utf8_esperanto_ci utf8_estonian_ci utf8_hungarian_ci)
define(UTFC4, utf8_latvian_ci utf8_lithuanian_ci) define(UTFC4, utf8_icelandic_ci utf8_latvian_ci utf8_lithuanian_ci)
define(UTFC5, utf8_persian_ci utf8_polish_ci utf8_romanian_ci) define(UTFC5, utf8_persian_ci utf8_polish_ci utf8_romanian_ci)
define(UTFC6, utf8_slovak_ci utf8_slovenian_ci) define(UTFC6, utf8_slovak_ci utf8_slovenian_ci)
define(UTFC7, utf8_spanish2_ci utf8_spanish_ci) define(UTFC7, utf8_spanish2_ci utf8_spanish_ci)

View File

@@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM
# #
# When changing major version number please also check switch statement # When changing major version number please also check switch statement
# in mysqlbinlog::check_master_version(). # in mysqlbinlog::check_master_version().
AM_INIT_AUTOMAKE(mysql, 5.1.25-maria-alpha) AM_INIT_AUTOMAKE(mysql, 5.1.31-maria-alpha)
AM_CONFIG_HEADER([include/config.h:config.h.in]) AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10 PROTOCOL_VERSION=10
@@ -250,8 +250,6 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
# Not critical since the generated file is distributed # Not critical since the generated file is distributed
AC_CHECK_PROGS(YACC, ['bison -y -p MYSQL']) AC_CHECK_PROGS(YACC, ['bison -y -p MYSQL'])
AC_CHECK_PROG(PDFMANUAL, pdftex, manual.pdf)
AC_CHECK_PROG(DVIS, tex, manual.dvi)
#check the return type of sprintf #check the return type of sprintf
AC_MSG_CHECKING("return type of sprintf") AC_MSG_CHECKING("return type of sprintf")
@@ -405,12 +403,15 @@ dnl Find paths to some shell programs
AC_PATH_PROG(LN, ln, ln) AC_PATH_PROG(LN, ln, ln)
# This must be able to take a -f flag like normal unix ln. # This must be able to take a -f flag like normal unix ln.
AC_PATH_PROG(LN_CP_F, ln, ln) AC_PATH_PROG(LN_CP_F, ln, ln)
if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then case $SYSTEM_TYPE in
# If ln -f does not exists use -s (AFS systems) *netware*) ;;
if test -n "$LN_CP_F"; then *)
LN_CP_F="$LN_CP_F -s" # If ln -f does not exists use -s (AFS systems)
fi if test -n "$LN_CP_F"; then
fi LN_CP_F="$LN_CP_F -s"
fi
;;
esac
AC_PATH_PROG(MV, mv, mv) AC_PATH_PROG(MV, mv, mv)
AC_PATH_PROG(RM, rm, rm) AC_PATH_PROG(RM, rm, rm)
@@ -419,6 +420,7 @@ AC_PATH_PROG(SED, sed, sed)
AC_PATH_PROG(CMP, cmp, cmp) AC_PATH_PROG(CMP, cmp, cmp)
AC_PATH_PROG(CHMOD, chmod, chmod) AC_PATH_PROG(CHMOD, chmod, chmod)
AC_PATH_PROG(HOSTNAME, hostname, hostname) AC_PATH_PROG(HOSTNAME, hostname, hostname)
AC_PATH_PROG(DIFF, diff, diff)
# Check for a GNU tar named 'gtar', or 'gnutar' (MacOS X) and # Check for a GNU tar named 'gtar', or 'gnutar' (MacOS X) and
# fall back to 'tar' otherwise and hope that it's a GNU tar as well # fall back to 'tar' otherwise and hope that it's a GNU tar as well
AC_CHECK_PROGS(TAR, gnutar gtar tar) AC_CHECK_PROGS(TAR, gnutar gtar tar)
@@ -443,66 +445,61 @@ AC_SUBST(HOSTNAME)
AC_SUBST(PERL) AC_SUBST(PERL)
AC_SUBST(PERL5) AC_SUBST(PERL5)
# icheck, used for ABI check # Enable the abi_check rule only if gcc is available
AC_PATH_PROG(ICHECK, icheck, no)
# "icheck" is also the name of a file system check program on Tru64.
# Verify the program found is really the interface checker.
if test "x$ICHECK" != "xno"
then
AC_MSG_CHECKING(if $ICHECK works as expected)
echo "int foo;" > conftest.h
$ICHECK --canonify -o conftest.ic conftest.h 2>/dev/null
if test -f "conftest.ic"
then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
ICHECK=no
fi
rm -f conftest.ic conftest.h
fi
AC_SUBST(ICHECK)
# Lock for PS if expr "$CC" : ".*gcc.*"
then
ABI_CHECK="abi_check"
else
ABI_CHECK=""
fi
AC_SUBST(ABI_CHECK)
# Look for PS usage. We use double dollar-signs in FIND_PROC because this
# value is written to a makefile, which interprets away one level of
# dollar-signs. So, interpretation stages are m4 and then shell in autoconf,
# then Make, then shell. The autoconf substitution uses single quotes, so
# no unprotected single quotes should appear in the expression.
AC_PATH_PROG(PS, ps, ps) AC_PATH_PROG(PS, ps, ps)
AC_MSG_CHECKING("how to check if pid exists") AC_MSG_CHECKING("how to check if pid exists")
PS=$ac_cv_path_PS PS=$ac_cv_path_PS
# Linux style # Linux style
if $PS p $$ 2> /dev/null | grep `echo $0 | sed s/\-//` > /dev/null if $PS wwwp $$ 2> /dev/null | grep -- "$0" > /dev/null
then then
FIND_PROC="$PS p \$\$PID | grep -v grep | grep \$\$MYSQLD > /dev/null" FIND_PROC="$PS wwwp \$\$PID | grep -v \" grep\" | grep -v mysqld_safe | grep -- \"\$\$MYSQLD\" > /dev/null"
# Solaris # Solaris
elif $PS -fp $$ 2> /dev/null | grep $0 > /dev/null elif $PS -fp $$ 2> /dev/null | grep -- $0 > /dev/null
then then
FIND_PROC="$PS -p \$\$PID | grep -v grep | grep \$\$MYSQLD > /dev/null" FIND_PROC="$PS -p \$\$PID | grep -v \" grep\" | grep -v mysqld_safe | grep -- \"\$\$MYSQLD\" > /dev/null"
# BSD style # BSD style
elif $PS -uaxww 2> /dev/null | grep $0 > /dev/null elif $PS -uaxww 2> /dev/null | grep -- $0 > /dev/null
then then
FIND_PROC="$PS -uaxww | grep -v grep | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" FIND_PROC="$PS -uaxww | grep -v \" grep\" | grep -v mysqld_safe | grep -- \"\$\$MYSQLD\" | grep \" \$\$PID \" > /dev/null"
# SysV style # SysV style
elif $PS -ef 2> /dev/null | grep $0 > /dev/null elif $PS -ef 2> /dev/null | grep -- $0 > /dev/null
then then
FIND_PROC="$PS -ef | grep -v grep | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" FIND_PROC="$PS -ef | grep -v \" grep\" | grep -v mysqld_safe | grep -- \"\$\$MYSQLD\" | grep \" \$\$PID \" > /dev/null"
# Do anybody use this? # Do anybody use this?
elif $PS $$ 2> /dev/null | grep $0 > /dev/null elif $PS $$ 2> /dev/null | grep -- $0 > /dev/null
then then
FIND_PROC="$PS \$\$PID | grep -v grep | grep \$\$MYSQLD > /dev/null" FIND_PROC="$PS \$\$PID | grep -v \" grep\" | grep -v mysqld_safe | grep -- \"\$\$MYSQLD\" > /dev/null"
else else
case $SYSTEM_TYPE in case $SYSTEM_TYPE in
*freebsd*|*dragonfly*) *freebsd*|*dragonfly*)
FIND_PROC="$PS p \$\$PID | grep -v grep | grep \$\$MYSQLD > /dev/null" FIND_PROC="$PS p \$\$PID | grep -v \" grep\" | grep -v mysqld_safe | grep -- \"\$\$MYSQLD\" > /dev/null"
;; ;;
*darwin*) *darwin*)
FIND_PROC="$PS -uaxww | grep -v grep | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" FIND_PROC="$PS -uaxww | grep -v \" grep\" | grep -v mysqld_safe | grep -- \"\$\$MYSQLD\" | grep \" \$\$PID \" > /dev/null"
;; ;;
*cygwin*) *cygwin*)
FIND_PROC="$PS -e | grep -v grep | grep \$\$MYSQLD | grep \" \$\$PID \" > /dev/null" FIND_PROC="$PS -e | grep -v \" grep\" | grep -v mysqld_safe | grep -- \"\$\$MYSQLD\" | grep \" \$\$PID \" > /dev/null"
;; ;;
*netware*) *netware*)
FIND_PROC= FIND_PROC=
;; ;;
*) *)
AC_MSG_ERROR([Could not find the right ps switches. Which OS is this ?. See the Installation chapter in the Reference Manual.]) AC_MSG_ERROR([Could not find the right ps and/or grep switches. Which OS is this? See the Installation chapter in the Reference Manual.])
esac esac
fi fi
AC_SUBST(FIND_PROC) AC_SUBST(FIND_PROC)
@@ -617,19 +614,19 @@ fi
AC_MSG_CHECKING(whether features provided by the user community should be included.) AC_MSG_CHECKING(whether features provided by the user community should be included.)
AC_ARG_ENABLE(community-features, AC_ARG_ENABLE(community-features,
AC_HELP_STRING( AC_HELP_STRING(
[--enable-community-features], [--disable-community-features],
[Enable additional features provided by the user community.]), [Disable additional features provided by the user community.]),
[ ENABLE_COMMUNITY_FEATURES=$enableval ], [ ENABLE_COMMUNITY_FEATURES=$enableval ],
[ ENABLE_COMMUNITY_FEATURES=no ] [ ENABLE_COMMUNITY_FEATURES=yes ]
) )
if test "$ENABLE_COMMUNITY_FEATURES" = "yes" if test "$ENABLE_COMMUNITY_FEATURES" = "yes"
then then
AC_DEFINE([COMMUNITY_SERVER], [1], AC_DEFINE([COMMUNITY_SERVER], [1],
[Whether features provided by the user community should be included]) [Whether features provided by the user community should be included])
AC_MSG_RESULT([yes, community server]) AC_MSG_RESULT([yes])
else else
AC_MSG_RESULT([no, enterprise server]) AC_MSG_RESULT([no])
fi fi
AC_ARG_WITH(server-suffix, AC_ARG_WITH(server-suffix,
@@ -1646,14 +1643,16 @@ else
OPTIMIZE_CXXFLAGS="-O" OPTIMIZE_CXXFLAGS="-O"
fi fi
if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null; then case $SYSTEM_TYPE in
DEBUG_CFLAGS="-g -DDEBUG -sym internal,codeview4" *netware*)
DEBUG_CXXFLAGS="-g -DDEBUG -sym internal,codeview4" DEBUG_CFLAGS="-g -DDEBUG -sym internal,codeview4"
DEBUG_OPTIMIZE_CC="-DDEBUG" DEBUG_CXXFLAGS="-g -DDEBUG -sym internal,codeview4"
DEBUG_OPTIMIZE_CXX="-DDEBUG" DEBUG_OPTIMIZE_CC="-DDEBUG"
OPTIMIZE_CFLAGS="-O3 -DNDEBUG" DEBUG_OPTIMIZE_CXX="-DDEBUG"
OPTIMIZE_CXXFLAGS="-O3 -DNDEBUG" OPTIMIZE_CFLAGS="-O3 -DNDEBUG"
fi OPTIMIZE_CXXFLAGS="-O3 -DNDEBUG"
;;
esac
# If the user specified CFLAGS, we won't add any optimizations # If the user specified CFLAGS, we won't add any optimizations
if test -n "$SAVE_CFLAGS" if test -n "$SAVE_CFLAGS"
@@ -1726,41 +1725,43 @@ fi
AC_ARG_WITH([atomic-ops], AC_ARG_WITH([atomic-ops],
AC_HELP_STRING([--with-atomic-ops=rwlocks|smp|up], AC_HELP_STRING([--with-atomic-ops=rwlocks|smp|up],
[Implement atomic operations using pthread rwlocks or atomic CPU [Implement atomic operations using pthread rwlocks or atomic CPU
instructions for multi-processor (default) or uniprocessor instructions for multi-processor or uniprocessor
configuration]), , [with_atomic_ops=smp]) configuration. By default gcc built-in sync functions are used,
if available and 'smp' configuration otherwise.]))
case "$with_atomic_ops" in case "$with_atomic_ops" in
"up") AC_DEFINE([MY_ATOMIC_MODE_DUMMY], [1], "up") AC_DEFINE([MY_ATOMIC_MODE_DUMMY], [1],
[Assume single-CPU mode, no concurrency]) ;; [Assume single-CPU mode, no concurrency]) ;;
"rwlocks") AC_DEFINE([MY_ATOMIC_MODE_RWLOCKS], [1], "rwlocks") AC_DEFINE([MY_ATOMIC_MODE_RWLOCKS], [1],
[Use pthread rwlocks for atomic ops]) ;; [Use pthread rwlocks for atomic ops]) ;;
"smp") ;; "smp") ;;
"")
AC_CACHE_CHECK([whether the compiler provides atomic builtins],
[mysql_cv_gcc_atomic_builtins], [AC_TRY_RUN([
int main()
{
int foo= -10; int bar= 10;
if (!__sync_fetch_and_add(&foo, bar) || foo)
return -1;
bar= __sync_lock_test_and_set(&foo, bar);
if (bar || foo != 10)
return -1;
bar= __sync_val_compare_and_swap(&bar, foo, 15);
if (bar)
return -1;
return 0;
}
], [mysql_cv_gcc_atomic_builtins=yes_but_disabled],
[mysql_cv_gcc_atomic_builtins=no],
[mysql_cv_gcc_atomic_builtins=no])])
if test "x$mysql_cv_gcc_atomic_builtins" = xyes; then
AC_DEFINE(HAVE_GCC_ATOMIC_BUILTINS, 1,
[Define to 1 if compiler provides atomic builtins.])
fi
;;
*) AC_MSG_ERROR(["$with_atomic_ops" is not a valid value for --with-atomic-ops]) ;; *) AC_MSG_ERROR(["$with_atomic_ops" is not a valid value for --with-atomic-ops]) ;;
esac esac
AC_CACHE_CHECK([whether the compiler provides atomic builtins],
[mysql_cv_gcc_atomic_builtins], [AC_TRY_RUN([
int main()
{
int foo= -10; int bar= 10;
if (!__sync_fetch_and_add(&foo, bar) || foo)
return -1;
bar= __sync_lock_test_and_set(&foo, bar);
if (bar || foo != 10)
return -1;
bar= __sync_val_compare_and_swap(&bar, foo, 15);
if (bar)
return -1;
return 0;
}
], [mysql_cv_gcc_atomic_builtins=yes],
[mysql_cv_gcc_atomic_builtins=no],
[mysql_cv_gcc_atomic_builtins=no])])
if test "x$mysql_cv_gcc_atomic_builtins" = disabled_xyes; then
AC_DEFINE(HAVE_GCC_ATOMIC_BUILTINS, 1,
[Define to 1 if compiler provides atomic builtins.])
fi
# Force static compilation to avoid linking problems/get more speed # Force static compilation to avoid linking problems/get more speed
AC_ARG_WITH(mysqld-ldflags, AC_ARG_WITH(mysqld-ldflags,
[ --with-mysqld-ldflags Extra linking arguments for mysqld], [ --with-mysqld-ldflags Extra linking arguments for mysqld],
@@ -1919,15 +1920,18 @@ MYSQL_TZNAME
# Do the c++ compiler have a bool type # Do the c++ compiler have a bool type
MYSQL_CXX_BOOL MYSQL_CXX_BOOL
# Check some common bugs with gcc 2.8.# on sparc # Check some common bugs with gcc 2.8.# on sparc
if ! ( expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null ); then case $SYSTEM_TYPE in
MYSQL_CHECK_LONGLONG_TO_FLOAT *netware*) ;;
if test "$ac_cv_conv_longlong_to_float" != "yes" *)
then MYSQL_CHECK_LONGLONG_TO_FLOAT
AC_MSG_ERROR([Your compiler cannot convert a longlong value to a float! if test "$ac_cv_conv_longlong_to_float" != "yes"
If you are using gcc 2.8.# you should upgrade to egcs 1.0.3 or newer and try then
again]) AC_MSG_ERROR([Your compiler cannot convert a longlong value to a float!
fi If you are using gcc 2.8.# you should upgrade to egcs 1.0.3 or newer and try
fi again])
fi
;;
esac
AC_CHECK_TYPES([sigset_t, off_t], [], [], [#include <sys/types.h>]) AC_CHECK_TYPES([sigset_t, off_t], [], [], [#include <sys/types.h>])
AC_CHECK_TYPES([size_t], [], [], [#include <stdio.h>]) AC_CHECK_TYPES([size_t], [], [], [#include <stdio.h>])
AC_CHECK_TYPES([u_int32_t]) AC_CHECK_TYPES([u_int32_t])
@@ -2044,7 +2048,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \
mkstemp mlockall perror poll pread pthread_attr_create mmap mmap64 getpagesize \ mkstemp mlockall perror poll pread pthread_attr_create mmap mmap64 getpagesize \
pthread_attr_getstacksize pthread_attr_setprio pthread_attr_setschedparam \ pthread_attr_getstacksize pthread_attr_setprio pthread_attr_setschedparam \
pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \ pthread_attr_setstacksize pthread_condattr_create pthread_getsequence_np \
pthread_key_delete pthread_rwlock_rdlock pthread_setprio \ pthread_key_delete pthread_rwlock_rdlock pthread_setprio pthread_setschedprio \
pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \ pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \
realpath rename rint rwlock_init setupterm \ realpath rename rint rwlock_init setupterm \
shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \ shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \
@@ -2341,10 +2345,31 @@ then
fi fi
AC_MSG_RESULT("$netinet_inc") AC_MSG_RESULT("$netinet_inc")
AC_CACHE_CHECK([support for weak symbols], mysql_cv_weak_symbol,
[AC_TRY_LINK([],[
extern void __attribute__((weak)) foo(void);
], [mysql_cv_weak_symbol=yes], [mysql_cv_weak_symbol=no])])
if test "x$mysql_cv_weak_symbol" = xyes; then
AC_DEFINE(HAVE_WEAK_SYMBOL, 1,
[Define to 1 if compiler supports weak symbol attribute.])
fi
AC_CACHE_CHECK([whether __bss_start is defined], mysql_cv_bss_start,
[AC_TRY_LINK([],[
extern char *__bss_start;
return __bss_start ? 1 : 0;
], [mysql_cv_bss_start=yes], [mysql_cv_bss_start=no])])
if test "x$mysql_cv_bss_start" = xyes; then
AC_DEFINE(HAVE_BSS_START, 1,
[Define to 1 if compiler defines __bss_start.])
fi
AC_LANG_SAVE AC_LANG_SAVE
AC_LANG_CPLUSPLUS AC_LANG_CPLUSPLUS
AC_CHECK_HEADERS(cxxabi.h) AC_CHECK_HEADERS(cxxabi.h)
AC_CACHE_CHECK([checking for abi::__cxa_demangle], mysql_cv_cxa_demangle, AC_CACHE_CHECK([for abi::__cxa_demangle], mysql_cv_cxa_demangle,
[AC_TRY_LINK([#include <cxxabi.h>], [ [AC_TRY_LINK([#include <cxxabi.h>], [
char *foo= 0; int bar= 0; char *foo= 0; int bar= 0;
foo= abi::__cxa_demangle(foo, foo, 0, &bar); foo= abi::__cxa_demangle(foo, foo, 0, &bar);
@@ -2543,11 +2568,12 @@ readline_h_ln_cmd=""
readline_link="" readline_link=""
want_to_use_readline="no" want_to_use_readline="no"
if expr "$SYSTEM_TYPE" : ".*netware.*" > /dev/null case $SYSTEM_TYPE in
then *netware*)
# For NetWare, do not need readline # For NetWare, do not need readline
echo "Skipping readline" echo "Skipping readline"
else ;;
*)
if [test "$with_libedit" = "yes"] || [test "$with_libedit" = "undefined"] && [test "$with_readline" = "undefined"] if [test "$with_libedit" = "yes"] || [test "$with_libedit" = "undefined"] && [test "$with_readline" = "undefined"]
then then
readline_topdir="cmd-line-utils" readline_topdir="cmd-line-utils"
@@ -2600,7 +2626,8 @@ else
be built with libreadline. Please use --with-libedit to use be built with libreadline. Please use --with-libedit to use
the bundled version of libedit instead.]) the bundled version of libedit instead.])
fi fi
fi ;;
esac
AC_SUBST(readline_dir) AC_SUBST(readline_dir)
AC_SUBST(readline_topdir) AC_SUBST(readline_topdir)
@@ -2701,14 +2728,15 @@ if test "$with_server" = "yes" -o "$THREAD_SAFE_CLIENT" != "no"
then then
AC_DEFINE([THREAD], [1], AC_DEFINE([THREAD], [1],
[Define if you want to have threaded code. This may be undef on client code]) [Define if you want to have threaded code. This may be undef on client code])
# Avoid _PROGRAMS names
THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o mf_keycache.o"
AC_SUBST(THREAD_LOBJECTS)
server_scripts="mysqld_safe mysql_install_db" server_scripts="mysqld_safe mysql_install_db"
sql_server_dirs="strings mysys dbug extra regex" sql_server_dirs="strings mysys dbug extra regex"
sql_server="vio sql" sql_server="vio sql"
fi fi
AM_CONDITIONAL(THREAD, test "$with_server" = "yes" -o "$THREAD_SAFE_CLIENT" != "no")
# "innochecksum" is not in the "innobase/" subdirectory, but should be switched
AM_CONDITIONAL([BUILD_INNODB_TOOLS], [test X"$with_plugin_innobase" = Xyes])
# IMPORTANT - do not modify LIBS past this line - this hack is the only way # IMPORTANT - do not modify LIBS past this line - this hack is the only way
# I know to add the static NSS magic if we have static NSS libraries with # I know to add the static NSS magic if we have static NSS libraries with

View File

@@ -177,7 +177,11 @@
static void perror(); /* Fake system/library error print routine */ static void perror(); /* Fake system/library error print routine */
#endif #endif
#ifdef SAFEMALLOC
IMPORT int _sanity(const char *file,uint line); /* safemalloc sanity checker */ IMPORT int _sanity(const char *file,uint line); /* safemalloc sanity checker */
#else
#define _sanity(X,Y) (1)
#endif
/* /*
* The user may specify a list of functions to trace or * The user may specify a list of functions to trace or
@@ -287,7 +291,7 @@ static void PushState(CODE_STATE *cs);
/* Free memory associated with debug state. */ /* Free memory associated with debug state. */
static void FreeState (CODE_STATE *cs, struct settings *state, int free_state); static void FreeState (CODE_STATE *cs, struct settings *state, int free_state);
/* Test for tracing enabled */ /* Test for tracing enabled */
static int DoTrace(CODE_STATE *cs, int tracing); static int DoTrace(CODE_STATE *cs);
/* /*
return values of DoTrace. return values of DoTrace.
Can also be used as bitmask: ret & DO_TRACE Can also be used as bitmask: ret & DO_TRACE
@@ -533,7 +537,7 @@ int DbugParse(CODE_STATE *cs, const char *control)
} }
end= DbugStrTok(control); end= DbugStrTok(control);
while (1) while (control < end)
{ {
int c, sign= (*control == '+') ? 1 : (*control == '-') ? -1 : 0; int c, sign= (*control == '+') ? 1 : (*control == '-') ? -1 : 0;
if (sign) control++; if (sign) control++;
@@ -726,7 +730,7 @@ void FixTraceFlags_helper(CODE_STATE *cs, const char *func,
It's ok, because cs->framep may only affect DO_TRACE/DONT_TRACE return It's ok, because cs->framep may only affect DO_TRACE/DONT_TRACE return
values, but we ignore them here anyway values, but we ignore them here anyway
*/ */
switch(DoTrace(cs, 1)) { switch(DoTrace(cs)) {
case ENABLE_TRACE: case ENABLE_TRACE:
framep->level|= TRACE_ON; framep->level|= TRACE_ON;
break; break;
@@ -1153,18 +1157,23 @@ void _db_enter_(const char *_func_, const char *_file_,
(void) fflush(cs->stack->prof_file); (void) fflush(cs->stack->prof_file);
} }
#endif #endif
switch (DoTrace(cs, TRACING)) { switch (DoTrace(cs)) {
case ENABLE_TRACE: case ENABLE_TRACE:
cs->framep->level|= TRACE_ON; cs->framep->level|= TRACE_ON;
if (!TRACING) break; if (!TRACING) break;
/* fall through */ /* fall through */
case DO_TRACE: case DO_TRACE:
if (!cs->locked) if ((cs->stack->flags & SANITY_CHECK_ON) && _sanity(_file_,_line_))
pthread_mutex_lock(&THR_LOCK_dbug); cs->stack->flags &= ~SANITY_CHECK_ON;
DoPrefix(cs, _line_); if (TRACING)
Indent(cs, cs->level); {
(void) fprintf(cs->stack->out_file, ">%s\n", cs->func); if (!cs->locked)
DbugFlush(cs); /* This does a unlock */ pthread_mutex_lock(&THR_LOCK_dbug);
DoPrefix(cs, _line_);
Indent(cs, cs->level);
(void) fprintf(cs->stack->out_file, ">%s\n", cs->func);
DbugFlush(cs); /* This does a unlock */
}
break; break;
case DISABLE_TRACE: case DISABLE_TRACE:
cs->framep->level&= ~TRACE_ON; cs->framep->level&= ~TRACE_ON;
@@ -1172,11 +1181,6 @@ void _db_enter_(const char *_func_, const char *_file_,
case DONT_TRACE: case DONT_TRACE:
break; break;
} }
#ifdef SAFEMALLOC
if (cs->stack->flags & SANITY_CHECK_ON)
if (_sanity(_file_,_line_)) /* Check of safemalloc */
cs->stack->flags &= ~SANITY_CHECK_ON;
#endif
errno=save_errno; errno=save_errno;
} }
@@ -1218,25 +1222,24 @@ void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_)
} }
else else
{ {
#ifdef SAFEMALLOC
if (cs->stack->flags & SANITY_CHECK_ON)
{
if (_sanity(_stack_frame_->file,_line_))
cs->stack->flags &= ~SANITY_CHECK_ON;
}
#endif
#ifndef THREAD #ifndef THREAD
if (DoProfile(cs)) if (DoProfile(cs))
(void) fprintf(cs->stack->prof_file, PROF_XFMT, Clock(), cs->func); (void) fprintf(cs->stack->prof_file, PROF_XFMT, Clock(), cs->func);
#endif #endif
if (TRACING && DoTrace(cs, 1) & DO_TRACE) if (DoTrace(cs) & DO_TRACE)
{ {
if (!cs->locked) if ((cs->stack->flags & SANITY_CHECK_ON) &&
pthread_mutex_lock(&THR_LOCK_dbug); _sanity(_stack_frame_->file,_line_))
DoPrefix(cs, _line_); cs->stack->flags &= ~SANITY_CHECK_ON;
Indent(cs, cs->level); if (TRACING)
(void) fprintf(cs->stack->out_file, "<%s\n", cs->func); {
DbugFlush(cs); if (!cs->locked)
pthread_mutex_lock(&THR_LOCK_dbug);
DoPrefix(cs, _line_);
Indent(cs, cs->level);
(void) fprintf(cs->stack->out_file, "<%s\n", cs->func);
DbugFlush(cs);
}
} }
} }
/* /*
@@ -1694,28 +1697,24 @@ void _db_end_()
* *
* DoTrace check to see if tracing is current enabled * DoTrace check to see if tracing is current enabled
* *
* tracing is the value of TRACING to check if the tracing is enabled
* or 1 to check if the function is enabled (in _db_keyword_)
*
* DESCRIPTION * DESCRIPTION
* *
* Checks to see if tracing is enabled based on whether the * Checks to see if dbug in this function is enabled based on
* user has specified tracing, the maximum trace depth has * whether the maximum trace depth has been reached, the current
* not yet been reached, the current function is selected, * function is selected, and the current process is selected.
* and the current process is selected.
* *
*/ */
static int DoTrace(CODE_STATE *cs, int tracing) static int DoTrace(CODE_STATE *cs)
{ {
if ((cs->stack->maxdepth == 0 || cs->level <= cs->stack->maxdepth) && if ((cs->stack->maxdepth == 0 || cs->level <= cs->stack->maxdepth) &&
InList(cs->stack->processes, cs->process) & (MATCHED|INCLUDE)) InList(cs->stack->processes, cs->process) & (MATCHED|INCLUDE))
switch(InList(cs->stack->functions, cs->func)) { switch(InList(cs->stack->functions, cs->func)) {
case INCLUDE|SUBDIR: return ENABLE_TRACE; case INCLUDE|SUBDIR: return ENABLE_TRACE;
case INCLUDE: return tracing ? DO_TRACE : DONT_TRACE; case INCLUDE: return DO_TRACE;
case MATCHED|SUBDIR: case MATCHED|SUBDIR:
case NOT_MATCHED|SUBDIR: case NOT_MATCHED|SUBDIR:
case MATCHED: return tracing && framep_trace_flag(cs, cs->framep) ? case MATCHED: return framep_trace_flag(cs, cs->framep) ?
DO_TRACE : DONT_TRACE; DO_TRACE : DONT_TRACE;
case EXCLUDE: case EXCLUDE:
case NOT_MATCHED: return DONT_TRACE; case NOT_MATCHED: return DONT_TRACE;
@@ -1786,7 +1785,7 @@ BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword, int strict)
get_code_state_if_not_set_or_return FALSE; get_code_state_if_not_set_or_return FALSE;
strict=strict ? INCLUDE : INCLUDE|MATCHED; strict=strict ? INCLUDE : INCLUDE|MATCHED;
return DEBUGGING && DoTrace(cs, 1) & DO_TRACE && return DEBUGGING && DoTrace(cs) & DO_TRACE &&
InList(cs->stack->keywords, keyword) & strict; InList(cs->stack->keywords, keyword) & strict;
} }

View File

@@ -44,7 +44,12 @@ $(top_builddir)/include/mysqld_ername.h: $(top_builddir)/include/mysqld_error.h
$(top_builddir)/include/sql_state.h: $(top_builddir)/include/mysqld_error.h $(top_builddir)/include/sql_state.h: $(top_builddir)/include/mysqld_error.h
bin_PROGRAMS = replace perror resolveip my_print_defaults \ bin_PROGRAMS = replace perror resolveip my_print_defaults \
resolve_stack_dump mysql_waitpid innochecksum resolve_stack_dump mysql_waitpid
# "innochecksum" should be switched
if BUILD_INNODB_TOOLS
bin_PROGRAMS += innochecksum
endif
noinst_PROGRAMS = charset2html noinst_PROGRAMS = charset2html
EXTRA_DIST = CMakeLists.txt EXTRA_DIST = CMakeLists.txt

View File

@@ -185,11 +185,36 @@ static const char *get_ha_error_msg(int code)
} }
#if defined(__WIN__)
static my_bool print_win_error_msg(DWORD error, my_bool verbose)
{
LPTSTR s;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, 0, (LPTSTR)&s, 0,
NULL))
{
if (verbose)
printf("Win32 error code %d: %s", error, s);
else
puts(s);
LocalFree(s);
return 0;
}
return 1;
}
#endif
int main(int argc,char *argv[]) int main(int argc,char *argv[])
{ {
int error,code,found; int error,code,found;
const char *msg; const char *msg;
char *unknown_error = 0; char *unknown_error = 0;
#if defined(__WIN__)
my_bool skip_win_message= 0;
#endif
MY_INIT(argv[0]); MY_INIT(argv[0]);
if (get_options(&argc,&argv)) if (get_options(&argc,&argv))
@@ -293,9 +318,20 @@ int main(int argc,char *argv[])
} }
if (!found) if (!found)
{ {
fprintf(stderr,"Illegal error code: %d\n", code); #if defined(__WIN__)
error= 1; if (!(skip_win_message= !print_win_error_msg((DWORD)code, verbose)))
{
#endif
fprintf(stderr,"Illegal error code: %d\n",code);
error=1;
#if defined(__WIN__)
}
#endif
} }
#if defined(__WIN__)
if (!skip_win_message)
print_win_error_msg((DWORD)code, verbose);
#endif
} }
} }

View File

@@ -1,6 +1,5 @@
SUBDIRS = taocrypt src testsuite SUBDIRS = taocrypt src testsuite
EXTRA_DIST = yassl.dsp yassl.dsw yassl.vcproj \ EXTRA_DIST = CMakeLists.txt
CMakeLists.txt
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%

View File

@@ -34,6 +34,7 @@
#include "yassl_types.hpp" // SignatureAlgorithm #include "yassl_types.hpp" // SignatureAlgorithm
#include "buffer.hpp" // input_buffer #include "buffer.hpp" // input_buffer
#include "asn.hpp" // SignerList #include "asn.hpp" // SignerList
#include "openssl/ssl.h" // internal and external use
#include STL_LIST_FILE #include STL_LIST_FILE
#include STL_ALGORITHM_FILE #include STL_ALGORITHM_FILE
@@ -87,6 +88,7 @@ class CertManager {
bool verifyNone_; // no error if verify fails bool verifyNone_; // no error if verify fails
bool failNoCert_; bool failNoCert_;
bool sendVerify_; bool sendVerify_;
VerifyCallback verifyCallback_; // user verify callback
public: public:
CertManager(); CertManager();
~CertManager(); ~CertManager();
@@ -118,6 +120,7 @@ public:
void setFailNoCert(); void setFailNoCert();
void setSendVerify(); void setSendVerify();
void setPeerX509(X509*); void setPeerX509(X509*);
void setVerifyCallback(VerifyCallback);
private: private:
CertManager(const CertManager&); // hide copy CertManager(const CertManager&); // hide copy
CertManager& operator=(const CertManager&); // and assign CertManager& operator=(const CertManager&); // and assign

View File

@@ -52,6 +52,7 @@
#define SSL_load_error_strings yaSSL_load_error_strings #define SSL_load_error_strings yaSSL_load_error_strings
#define SSL_set_session yaSSL_set_session #define SSL_set_session yaSSL_set_session
#define SSL_get_session yaSSL_get_session #define SSL_get_session yaSSL_get_session
#define SSL_flush_sessions yaSSL_flush_sessions
#define SSL_SESSION_set_timeout yaSSL_SESSION_set_timeout #define SSL_SESSION_set_timeout yaSSL_SESSION_set_timeout
#define SSL_CTX_set_session_cache_mode yaSSL_CTX_set_session_cache_mode #define SSL_CTX_set_session_cache_mode yaSSL_CTX_set_session_cache_mode
#define SSL_get_peer_certificate yaSSL_get_peer_certificate #define SSL_get_peer_certificate yaSSL_get_peer_certificate

View File

@@ -170,8 +170,9 @@ enum { /* X509 Constants */
X509_V_ERR_CRL_SIGNATURE_FAILURE = 10, X509_V_ERR_CRL_SIGNATURE_FAILURE = 10,
X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 11, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD = 11,
X509_V_ERR_CRL_HAS_EXPIRED = 12, X509_V_ERR_CRL_HAS_EXPIRED = 12,
X509_V_ERR_CERT_REVOKED = 13 X509_V_ERR_CERT_REVOKED = 13,
X509_V_FLAG_CRL_CHECK = 14,
X509_V_FLAG_CRL_CHECK_ALL = 15
}; };
@@ -202,7 +203,8 @@ SSL_CTX* SSL_CTX_new(SSL_METHOD*);
SSL* SSL_new(SSL_CTX*); SSL* SSL_new(SSL_CTX*);
int SSL_set_fd (SSL*, YASSL_SOCKET_T); int SSL_set_fd (SSL*, YASSL_SOCKET_T);
YASSL_SOCKET_T SSL_get_fd(const SSL*); YASSL_SOCKET_T SSL_get_fd(const SSL*);
int SSL_connect(SSL*); int SSL_connect(SSL*); // if you get an error from connect
// see note at top of REAMDE
int SSL_write(SSL*, const void*, int); int SSL_write(SSL*, const void*, int);
int SSL_read(SSL*, void*, int); int SSL_read(SSL*, void*, int);
int SSL_accept(SSL*); int SSL_accept(SSL*);
@@ -227,6 +229,7 @@ void SSL_load_error_strings(void);
int SSL_set_session(SSL *ssl, SSL_SESSION *session); int SSL_set_session(SSL *ssl, SSL_SESSION *session);
SSL_SESSION* SSL_get_session(SSL* ssl); SSL_SESSION* SSL_get_session(SSL* ssl);
void SSL_flush_sessions(SSL_CTX *ctx, long tm);
long SSL_SESSION_set_timeout(SSL_SESSION*, long); long SSL_SESSION_set_timeout(SSL_SESSION*, long);
long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode); long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode);
X509* SSL_get_peer_certificate(SSL*); X509* SSL_get_peer_certificate(SSL*);

View File

@@ -667,10 +667,12 @@ struct Parameters {
Cipher suites_[MAX_SUITE_SZ]; Cipher suites_[MAX_SUITE_SZ];
char cipher_name_[MAX_SUITE_NAME]; char cipher_name_[MAX_SUITE_NAME];
char cipher_list_[MAX_CIPHERS][MAX_SUITE_NAME]; char cipher_list_[MAX_CIPHERS][MAX_SUITE_NAME];
bool removeDH_; // for server's later use
Parameters(ConnectionEnd, const Ciphers&, ProtocolVersion, bool haveDH); Parameters(ConnectionEnd, const Ciphers&, ProtocolVersion, bool haveDH);
void SetSuites(ProtocolVersion pv, bool removeDH = false); void SetSuites(ProtocolVersion pv, bool removeDH = false,
bool removeRSA = false, bool removeDSA = false);
void SetCipherNames(); void SetCipherNames();
private: private:
Parameters(const Parameters&); // hide copy Parameters(const Parameters&); // hide copy

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (C) 2000-2007 MySQL AB Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -268,12 +268,14 @@ class Sessions {
STL::list<SSL_SESSION*> list_; STL::list<SSL_SESSION*> list_;
RandomPool random_; // for session cleaning RandomPool random_; // for session cleaning
Mutex mutex_; // no-op for single threaded Mutex mutex_; // no-op for single threaded
int count_; // flush counter
Sessions() {} // only GetSessions can create Sessions() : count_(0) {} // only GetSessions can create
public: public:
SSL_SESSION* lookup(const opaque*, SSL_SESSION* copy = 0); SSL_SESSION* lookup(const opaque*, SSL_SESSION* copy = 0);
void add(const SSL&); void add(const SSL&);
void remove(const opaque*); void remove(const opaque*);
void Flush();
~Sessions(); ~Sessions();
@@ -425,8 +427,10 @@ private:
pem_password_cb passwordCb_; pem_password_cb passwordCb_;
void* userData_; void* userData_;
bool sessionCacheOff_; bool sessionCacheOff_;
bool sessionCacheFlushOff_;
Stats stats_; Stats stats_;
Mutex mutex_; // for Stats Mutex mutex_; // for Stats
VerifyCallback verifyCallback_;
public: public:
explicit SSL_CTX(SSL_METHOD* meth); explicit SSL_CTX(SSL_METHOD* meth);
~SSL_CTX(); ~SSL_CTX();
@@ -437,18 +441,22 @@ public:
const Ciphers& GetCiphers() const; const Ciphers& GetCiphers() const;
const DH_Parms& GetDH_Parms() const; const DH_Parms& GetDH_Parms() const;
const Stats& GetStats() const; const Stats& GetStats() const;
const VerifyCallback getVerifyCallback() const;
pem_password_cb GetPasswordCb() const; pem_password_cb GetPasswordCb() const;
void* GetUserData() const; void* GetUserData() const;
bool GetSessionCacheOff() const; bool GetSessionCacheOff() const;
bool GetSessionCacheFlushOff() const;
void setVerifyPeer(); void setVerifyPeer();
void setVerifyNone(); void setVerifyNone();
void setFailNoCert(); void setFailNoCert();
void setVerifyCallback(VerifyCallback);
bool SetCipherList(const char*); bool SetCipherList(const char*);
bool SetDH(const DH&); bool SetDH(const DH&);
void SetPasswordCb(pem_password_cb cb); void SetPasswordCb(pem_password_cb cb);
void SetUserData(void*); void SetUserData(void*);
void SetSessionCacheOff(); void SetSessionCacheOff();
void SetSessionCacheFlushOff();
void IncrementStats(StatsField); void IncrementStats(StatsField);
void AddCA(x509* ca); void AddCA(x509* ca);

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (C) 2000-2007 MySQL AB Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -29,6 +29,13 @@
#include "type_traits.hpp" #include "type_traits.hpp"
#ifdef _MSC_VER
// disable conversion warning
// 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy
#pragma warning(disable:4244 4996)
#endif
namespace yaSSL { namespace yaSSL {
#define YASSL_LIB #define YASSL_LIB
@@ -163,7 +170,7 @@ const int RMD_LEN = 20; // RIPEMD-160 digest length
const int PREFIX = 3; // up to 3 prefix letters for secret rounds const int PREFIX = 3; // up to 3 prefix letters for secret rounds
const int KEY_PREFIX = 7; // up to 7 prefix letters for key rounds const int KEY_PREFIX = 7; // up to 7 prefix letters for key rounds
const int FORTEZZA_MAX = 128; // Maximum Fortezza Key length const int FORTEZZA_MAX = 128; // Maximum Fortezza Key length
const int MAX_SUITE_SZ = 64; // 32 max suites * sizeof(suite) const int MAX_SUITE_SZ = 128; // 64 max suites * sizeof(suite)
const int MAX_SUITE_NAME = 48; // max length of suite name const int MAX_SUITE_NAME = 48; // max length of suite name
const int MAX_CIPHERS = 32; // max supported ciphers for cipher list const int MAX_CIPHERS = 32; // max supported ciphers for cipher list
const int SIZEOF_ENUM = 1; // SSL considers an enum 1 byte, not 4 const int SIZEOF_ENUM = 1; // SSL considers an enum 1 byte, not 4
@@ -205,6 +212,7 @@ const int SEED_LEN = RAN_LEN * 2; // TLS seed, client + server random
const int DEFAULT_TIMEOUT = 500; // Default Session timeout in seconds const int DEFAULT_TIMEOUT = 500; // Default Session timeout in seconds
const int MAX_RECORD_SIZE = 16384; // 2^14, max size by standard const int MAX_RECORD_SIZE = 16384; // 2^14, max size by standard
const int COMPRESS_EXTRA = 1024; // extra compression possible addition const int COMPRESS_EXTRA = 1024; // extra compression possible addition
const int SESSION_FLUSH_COUNT = 256; // when to flush session cache
typedef uint8 Cipher; // first byte is always 0x00 for SSLv3 & TLS typedef uint8 Cipher; // first byte is always 0x00 for SSLv3 & TLS

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (C) 2000-2007 MySQL AB Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
#include "runtime.hpp" #include "runtime.hpp"
#include "cert_wrapper.hpp" #include "cert_wrapper.hpp"
#include "yassl_int.hpp" #include "yassl_int.hpp"
#include "error.hpp"
#if defined(USE_CML_LIB) #if defined(USE_CML_LIB)
#include "cmapi_cpp.h" #include "cmapi_cpp.h"
@@ -90,7 +91,7 @@ opaque* x509::use_buffer()
//CertManager //CertManager
CertManager::CertManager() CertManager::CertManager()
: peerX509_(0), verifyPeer_(false), verifyNone_(false), failNoCert_(false), : peerX509_(0), verifyPeer_(false), verifyNone_(false), failNoCert_(false),
sendVerify_(false) sendVerify_(false), verifyCallback_(0)
{} {}
@@ -154,6 +155,12 @@ void CertManager::setSendVerify()
} }
void CertManager::setVerifyCallback(VerifyCallback vc)
{
verifyCallback_ = vc;
}
void CertManager::AddPeerCert(x509* x) void CertManager::AddPeerCert(x509* x)
{ {
peerList_.push_back(x); // take ownership peerList_.push_back(x); // take ownership
@@ -236,7 +243,7 @@ uint CertManager::get_privateKeyLength() const
int CertManager::Validate() int CertManager::Validate()
{ {
CertList::reverse_iterator last = peerList_.rbegin(); CertList::reverse_iterator last = peerList_.rbegin();
int count = peerList_.size(); size_t count = peerList_.size();
while ( count > 1 ) { while ( count > 1 ) {
TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length()); TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length());
@@ -257,7 +264,8 @@ int CertManager::Validate()
TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length()); TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length());
TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_); TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_);
if (int err = cert.GetError().What()) int err = cert.GetError().What();
if ( err )
return err; return err;
uint sz = cert.GetPublicKey().size(); uint sz = cert.GetPublicKey().size();
@@ -269,13 +277,25 @@ int CertManager::Validate()
else else
peerKeyType_ = dsa_sa_algo; peerKeyType_ = dsa_sa_algo;
int iSz = strlen(cert.GetIssuer()) + 1; size_t iSz = strlen(cert.GetIssuer()) + 1;
int sSz = strlen(cert.GetCommonName()) + 1; size_t sSz = strlen(cert.GetCommonName()) + 1;
int bSz = strlen(cert.GetBeforeDate()) + 1; int bSz = (int)strlen(cert.GetBeforeDate()) + 1;
int aSz = strlen(cert.GetAfterDate()) + 1; int aSz = (int)strlen(cert.GetAfterDate()) + 1;
peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(), peerX509_ = NEW_YS X509(cert.GetIssuer(), iSz, cert.GetCommonName(),
sSz, cert.GetBeforeDate(), bSz, sSz, cert.GetBeforeDate(), bSz,
cert.GetAfterDate(), aSz); cert.GetAfterDate(), aSz);
if (err == TaoCrypt::SIG_OTHER_E && verifyCallback_) {
X509_STORE_CTX store;
store.error = err;
store.error_depth = static_cast<int>(count) - 1;
store.current_cert = peerX509_;
int ok = verifyCallback_(0, &store);
if (ok) return 0;
}
if (err == TaoCrypt::SIG_OTHER_E) return err;
} }
return 0; return 0;
} }

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (C) 2000-2007 MySQL AB Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -245,6 +245,7 @@ YASSL_SOCKET_T SSL_get_fd(const SSL* ssl)
} }
// if you get an error from connect see note at top of README
int SSL_connect(SSL* ssl) int SSL_connect(SSL* ssl)
{ {
if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ)) if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ))
@@ -447,6 +448,9 @@ long SSL_CTX_set_session_cache_mode(SSL_CTX* ctx, long mode)
if (mode == SSL_SESS_CACHE_OFF) if (mode == SSL_SESS_CACHE_OFF)
ctx->SetSessionCacheOff(); ctx->SetSessionCacheOff();
if (mode == SSL_SESS_CACHE_NO_AUTO_CLEAR)
ctx->SetSessionCacheFlushOff();
return SSL_SUCCESS; return SSL_SUCCESS;
} }
@@ -493,6 +497,15 @@ long SSL_get_default_timeout(SSL* /*ssl*/)
} }
void SSL_flush_sessions(SSL_CTX *ctx, long /* tm */)
{
if (ctx->GetSessionCacheOff())
return;
GetSessions().Flush();
}
const char* SSL_get_cipher_name(SSL* ssl) const char* SSL_get_cipher_name(SSL* ssl)
{ {
return SSL_get_cipher(ssl); return SSL_get_cipher(ssl);
@@ -560,7 +573,7 @@ int SSL_get_error(SSL* ssl, int /*previous*/)
only need to turn on for client, becuase server on by default if built in only need to turn on for client, becuase server on by default if built in
but calling for server will tell you whether it's available or not but calling for server will tell you whether it's available or not
*/ */
int SSL_set_compression(SSL* ssl) int SSL_set_compression(SSL* ssl) /* Chad didn't rename to ya~ because it is prob. bug. */
{ {
return ssl->SetCompression(); return ssl->SetCompression();
} }
@@ -604,7 +617,7 @@ char* X509_NAME_oneline(X509_NAME* name, char* buffer, int sz)
{ {
if (!name->GetName()) return buffer; if (!name->GetName()) return buffer;
int len = strlen(name->GetName()) + 1; int len = (int)strlen(name->GetName()) + 1;
int copySz = min(len, sz); int copySz = min(len, sz);
if (!buffer) { if (!buffer) {
@@ -693,7 +706,7 @@ int SSL_CTX_use_PrivateKey_file(SSL_CTX* ctx, const char* file, int format)
} }
void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback /*vc*/) void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback vc)
{ {
if (mode & SSL_VERIFY_PEER) if (mode & SSL_VERIFY_PEER)
ctx->setVerifyPeer(); ctx->setVerifyPeer();
@@ -703,6 +716,8 @@ void SSL_CTX_set_verify(SSL_CTX* ctx, int mode, VerifyCallback /*vc*/)
if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) if (mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
ctx->setFailNoCert(); ctx->setFailNoCert();
ctx->setVerifyCallback(vc);
} }
@@ -1450,6 +1465,8 @@ unsigned long err_helper(bool peek = false)
default : default :
return 0; return 0;
} }
return 0; // shut up compiler
} }

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (C) 2000-2007 MySQL AB Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -26,6 +26,11 @@
#include "openssl/ssl.h" // SSL_ERROR_WANT_READ #include "openssl/ssl.h" // SSL_ERROR_WANT_READ
#include <string.h> // strncpy #include <string.h> // strncpy
#ifdef _MSC_VER
// 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy
#pragma warning(disable: 4996)
#endif
namespace yaSSL { namespace yaSSL {

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (C) 2000-2007 MySQL AB Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -136,9 +136,19 @@ void DH_Server::build(SSL& ssl)
const CertManager& cert = ssl.getCrypto().get_certManager(); const CertManager& cert = ssl.getCrypto().get_certManager();
if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo) if (ssl.getSecurity().get_parms().sig_algo_ == rsa_sa_algo)
{
if (cert.get_keyType() != rsa_sa_algo) {
ssl.SetError(privateKey_error);
return;
}
auth.reset(NEW_YS RSA(cert.get_privateKey(), auth.reset(NEW_YS RSA(cert.get_privateKey(),
cert.get_privateKeyLength(), false)); cert.get_privateKeyLength(), false));
}
else { else {
if (cert.get_keyType() != dsa_sa_algo) {
ssl.SetError(privateKey_error);
return;
}
auth.reset(NEW_YS DSS(cert.get_privateKey(), auth.reset(NEW_YS DSS(cert.get_privateKey(),
cert.get_privateKeyLength(), false)); cert.get_privateKeyLength(), false));
sigSz += DSS_ENCODED_EXTRA; sigSz += DSS_ENCODED_EXTRA;
@@ -436,18 +446,21 @@ Parameters::Parameters(ConnectionEnd ce, const Ciphers& ciphers,
pending_ = true; // suite not set yet pending_ = true; // suite not set yet
strncpy(cipher_name_, "NONE", 5); strncpy(cipher_name_, "NONE", 5);
removeDH_ = !haveDH; // only use on server side for set suites
if (ciphers.setSuites_) { // use user set list if (ciphers.setSuites_) { // use user set list
suites_size_ = ciphers.suiteSz_; suites_size_ = ciphers.suiteSz_;
memcpy(suites_, ciphers.suites_, ciphers.suiteSz_); memcpy(suites_, ciphers.suites_, ciphers.suiteSz_);
SetCipherNames(); SetCipherNames();
} }
else else
SetSuites(pv, ce == server_end && !haveDH); // defaults SetSuites(pv, ce == server_end && removeDH_); // defaults
} }
void Parameters::SetSuites(ProtocolVersion pv, bool removeDH) void Parameters::SetSuites(ProtocolVersion pv, bool removeDH, bool removeRSA,
bool removeDSA)
{ {
int i = 0; int i = 0;
// available suites, best first // available suites, best first
@@ -456,67 +469,87 @@ void Parameters::SetSuites(ProtocolVersion pv, bool removeDH)
if (isTLS(pv)) { if (isTLS(pv)) {
if (!removeDH) { if (!removeDH) {
suites_[i++] = 0x00; if (!removeRSA) {
suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA; suites_[i++] = 0x00;
suites_[i++] = 0x00; suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA; }
if (!removeDSA) {
suites_[i++] = 0x00;
suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA;
}
} }
suites_[i++] = 0x00; if (!removeRSA) {
suites_[i++] = TLS_RSA_WITH_AES_256_CBC_SHA; suites_[i++] = 0x00;
suites_[i++] = TLS_RSA_WITH_AES_256_CBC_SHA;
if (!removeDH) {
suites_[i++] = 0x00;
suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
suites_[i++] = 0x00;
suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA;
} }
suites_[i++] = 0x00;
suites_[i++] = TLS_RSA_WITH_AES_128_CBC_SHA;
suites_[i++] = 0x00;
suites_[i++] = TLS_RSA_WITH_AES_256_CBC_RMD160;
suites_[i++] = 0x00;
suites_[i++] = TLS_RSA_WITH_AES_128_CBC_RMD160;
suites_[i++] = 0x00;
suites_[i++] = TLS_RSA_WITH_3DES_EDE_CBC_RMD160;
if (!removeDH) { if (!removeDH) {
suites_[i++] = 0x00; if (!removeRSA) {
suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_RMD160; suites_[i++] = 0x00;
suites_[i++] = 0x00; suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_RMD160; }
suites_[i++] = 0x00; if (!removeDSA) {
suites_[i++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160; suites_[i++] = 0x00;
suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA;
suites_[i++] = 0x00; }
suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_RMD160; }
suites_[i++] = 0x00; if (!removeRSA) {
suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_RMD160; suites_[i++] = 0x00;
suites_[i++] = 0x00; suites_[i++] = TLS_RSA_WITH_AES_128_CBC_SHA;
suites_[i++] = TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160; suites_[i++] = 0x00;
} suites_[i++] = TLS_RSA_WITH_AES_256_CBC_RMD160;
suites_[i++] = 0x00;
suites_[i++] = TLS_RSA_WITH_AES_128_CBC_RMD160;
suites_[i++] = 0x00;
suites_[i++] = TLS_RSA_WITH_3DES_EDE_CBC_RMD160;
}
if (!removeDH) {
if (!removeRSA) {
suites_[i++] = 0x00;
suites_[i++] = TLS_DHE_RSA_WITH_AES_256_CBC_RMD160;
suites_[i++] = 0x00;
suites_[i++] = TLS_DHE_RSA_WITH_AES_128_CBC_RMD160;
suites_[i++] = 0x00;
suites_[i++] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD160;
}
if (!removeDSA) {
suites_[i++] = 0x00;
suites_[i++] = TLS_DHE_DSS_WITH_AES_256_CBC_RMD160;
suites_[i++] = 0x00;
suites_[i++] = TLS_DHE_DSS_WITH_AES_128_CBC_RMD160;
suites_[i++] = 0x00;
suites_[i++] = TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD160;
}
}
} }
suites_[i++] = 0x00; if (!removeRSA) {
suites_[i++] = SSL_RSA_WITH_RC4_128_SHA; suites_[i++] = 0x00;
suites_[i++] = 0x00; suites_[i++] = SSL_RSA_WITH_RC4_128_SHA;
suites_[i++] = SSL_RSA_WITH_RC4_128_MD5; suites_[i++] = 0x00;
suites_[i++] = SSL_RSA_WITH_RC4_128_MD5;
suites_[i++] = 0x00;
suites_[i++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
suites_[i++] = 0x00;
suites_[i++] = SSL_RSA_WITH_DES_CBC_SHA;
suites_[i++] = 0x00;
suites_[i++] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
suites_[i++] = 0x00;
suites_[i++] = SSL_RSA_WITH_DES_CBC_SHA;
}
if (!removeDH) { if (!removeDH) {
suites_[i++] = 0x00; if (!removeRSA) {
suites_[i++] = SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA; suites_[i++] = 0x00;
suites_[i++] = 0x00; suites_[i++] = SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
suites_[i++] = SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA; }
if (!removeDSA) {
suites_[i++] = 0x00; suites_[i++] = 0x00;
suites_[i++] = SSL_DHE_RSA_WITH_DES_CBC_SHA; suites_[i++] = SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA;
suites_[i++] = 0x00; }
suites_[i++] = SSL_DHE_DSS_WITH_DES_CBC_SHA; if (!removeRSA) {
suites_[i++] = 0x00;
suites_[i++] = SSL_DHE_RSA_WITH_DES_CBC_SHA;
}
if (!removeDSA) {
suites_[i++] = 0x00;
suites_[i++] = SSL_DHE_DSS_WITH_DES_CBC_SHA;
}
} }
suites_size_ = i; suites_size_ = i;
@@ -532,7 +565,7 @@ void Parameters::SetCipherNames()
for (int j = 0; j < suites; j++) { for (int j = 0; j < suites; j++) {
int index = suites_[j*2 + 1]; // every other suite is suite id int index = suites_[j*2 + 1]; // every other suite is suite id
int len = strlen(cipher_names[index]) + 1; size_t len = strlen(cipher_names[index]) + 1;
strncpy(cipher_list_[pos++], cipher_names[index], len); strncpy(cipher_list_[pos++], cipher_names[index], len);
} }
cipher_list_[pos][0] = 0; cipher_list_[pos][0] = 0;
@@ -1469,7 +1502,19 @@ void ClientHello::Process(input_buffer&, SSL& ssl)
// downgrade to SSLv3 // downgrade to SSLv3
ssl.useSecurity().use_connection().TurnOffTLS(); ssl.useSecurity().use_connection().TurnOffTLS();
ProtocolVersion pv = ssl.getSecurity().get_connection().version_; ProtocolVersion pv = ssl.getSecurity().get_connection().version_;
ssl.useSecurity().use_parms().SetSuites(pv); // reset w/ SSL suites bool removeDH = ssl.getSecurity().get_parms().removeDH_;
bool removeRSA = false;
bool removeDSA = false;
const CertManager& cm = ssl.getCrypto().get_certManager();
if (cm.get_keyType() == rsa_sa_algo)
removeDSA = true;
else
removeRSA = true;
// reset w/ SSL suites
ssl.useSecurity().use_parms().SetSuites(pv, removeDH, removeRSA,
removeDSA);
} }
else if (ssl.isTLSv1_1() && client_version_.minor_ == 1) else if (ssl.isTLSv1_1() && client_version_.minor_ == 1)
// downgrade to TLSv1, but use same suites // downgrade to TLSv1, but use same suites
@@ -1515,6 +1560,7 @@ void ClientHello::Process(input_buffer&, SSL& ssl)
return; return;
} }
ssl.matchSuite(cipher_suites_, suite_len_); ssl.matchSuite(cipher_suites_, suite_len_);
if (ssl.GetError()) return;
ssl.set_pending(ssl.getSecurity().get_parms().suite_[1]); ssl.set_pending(ssl.getSecurity().get_parms().suite_[1]);
if (compression_methods_ == zlib) if (compression_methods_ == zlib)

View File

@@ -1,5 +1,5 @@
/* /*
Copyright (C) 2000-2007 MySQL AB Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@@ -40,28 +40,28 @@
void* operator new(size_t sz, yaSSL::new_t) void* operator new(size_t sz, yaSSL::new_t)
{ {
void* ptr = malloc(sz ? sz : 1); void* ptr = malloc(sz ? sz : 1);
if (!ptr) abort(); if (!ptr) abort();
return ptr; return ptr;
} }
void operator delete(void* ptr, yaSSL::new_t) void operator delete(void* ptr, yaSSL::new_t)
{ {
if (ptr) free(ptr); if (ptr) free(ptr);
} }
void* operator new[](size_t sz, yaSSL::new_t nt) void* operator new[](size_t sz, yaSSL::new_t nt)
{ {
return ::operator new(sz, nt); return ::operator new(sz, nt);
} }
void operator delete[](void* ptr, yaSSL::new_t nt) void operator delete[](void* ptr, yaSSL::new_t nt)
{ {
::operator delete(ptr, nt); ::operator delete(ptr, nt);
} }
namespace yaSSL { namespace yaSSL {
@@ -308,6 +308,20 @@ SSL::SSL(SSL_CTX* ctx)
SetError(YasslError(err)); SetError(YasslError(err));
return; return;
} }
else if (serverSide) {
// remove RSA or DSA suites depending on cert key type
ProtocolVersion pv = secure_.get_connection().version_;
bool removeDH = secure_.use_parms().removeDH_;
bool removeRSA = false;
bool removeDSA = false;
if (cm.get_keyType() == rsa_sa_algo)
removeDSA = true;
else
removeRSA = true;
secure_.use_parms().SetSuites(pv, removeDH, removeRSA, removeDSA);
}
} }
else if (serverSide) { else if (serverSide) {
SetError(no_key_file); SetError(no_key_file);
@@ -320,6 +334,7 @@ SSL::SSL(SSL_CTX* ctx)
cm.setVerifyNone(); cm.setVerifyNone();
if (ctx->getMethod()->failNoCert()) if (ctx->getMethod()->failNoCert())
cm.setFailNoCert(); cm.setFailNoCert();
cm.setVerifyCallback(ctx->getVerifyCallback());
if (serverSide) if (serverSide)
crypto_.SetDH(ctx->GetDH_Parms()); crypto_.SetDH(ctx->GetDH_Parms());
@@ -1034,12 +1049,12 @@ void SSL::fillData(Data& data)
{ {
if (GetError()) return; if (GetError()) return;
uint dataSz = data.get_length(); // input, data size to fill uint dataSz = data.get_length(); // input, data size to fill
uint elements = buffers_.getData().size(); size_t elements = buffers_.getData().size();
data.set_length(0); // output, actual data filled data.set_length(0); // output, actual data filled
dataSz = min(dataSz, bufferedData()); dataSz = min(dataSz, bufferedData());
for (uint i = 0; i < elements; i++) { for (size_t i = 0; i < elements; i++) {
input_buffer* front = buffers_.getData().front(); input_buffer* front = buffers_.getData().front();
uint frontSz = front->get_remaining(); uint frontSz = front->get_remaining();
uint readSz = min(dataSz - data.get_length(), frontSz); uint readSz = min(dataSz - data.get_length(), frontSz);
@@ -1063,8 +1078,8 @@ void SSL::fillData(Data& data)
void SSL::PeekData(Data& data) void SSL::PeekData(Data& data)
{ {
if (GetError()) return; if (GetError()) return;
uint dataSz = data.get_length(); // input, data size to fill uint dataSz = data.get_length(); // input, data size to fill
uint elements = buffers_.getData().size(); size_t elements = buffers_.getData().size();
data.set_length(0); // output, actual data filled data.set_length(0); // output, actual data filled
dataSz = min(dataSz, bufferedData()); dataSz = min(dataSz, bufferedData());
@@ -1098,9 +1113,9 @@ void SSL::flushBuffer()
buffers_.getHandShake().end(), buffers_.getHandShake().end(),
SumBuffer()).total_; SumBuffer()).total_;
output_buffer out(sz); output_buffer out(sz);
uint elements = buffers_.getHandShake().size(); size_t elements = buffers_.getHandShake().size();
for (uint i = 0; i < elements; i++) { for (size_t i = 0; i < elements; i++) {
output_buffer* front = buffers_.getHandShake().front(); output_buffer* front = buffers_.getHandShake().front();
out.write(front->get_buffer(), front->get_size()); out.write(front->get_buffer(), front->get_size());
@@ -1276,6 +1291,7 @@ void SSL::matchSuite(const opaque* peer, uint length)
if (secure_.use_parms().suites_[i] == peer[j]) { if (secure_.use_parms().suites_[i] == peer[j]) {
secure_.use_parms().suite_[0] = 0x00; secure_.use_parms().suite_[0] = 0x00;
secure_.use_parms().suite_[1] = peer[j]; secure_.use_parms().suite_[1] = peer[j];
return; return;
} }
@@ -1284,7 +1300,7 @@ void SSL::matchSuite(const opaque* peer, uint length)
void SSL::set_session(SSL_SESSION* s) void SSL::set_session(SSL_SESSION* s)
{ {
if (getSecurity().GetContext()->GetSessionCacheOff()) if (getSecurity().GetContext()->GetSessionCacheOff())
return; return;
@@ -1565,13 +1581,19 @@ Errors& GetErrors()
typedef Mutex::Lock Lock; typedef Mutex::Lock Lock;
void Sessions::add(const SSL& ssl) void Sessions::add(const SSL& ssl)
{ {
if (ssl.getSecurity().get_connection().sessionID_Set_) { if (ssl.getSecurity().get_connection().sessionID_Set_) {
Lock guard(mutex_); Lock guard(mutex_);
list_.push_back(NEW_YS SSL_SESSION(ssl, random_)); list_.push_back(NEW_YS SSL_SESSION(ssl, random_));
count_++;
} }
if (count_ > SESSION_FLUSH_COUNT)
if (!ssl.getSecurity().GetContext()->GetSessionCacheFlushOff())
Flush();
} }
@@ -1660,6 +1682,25 @@ void Sessions::remove(const opaque* id)
} }
// flush expired sessions from cache
void Sessions::Flush()
{
Lock guard(mutex_);
sess_iterator next = list_.begin();
uint current = lowResTimer();
while (next != list_.end()) {
sess_iterator si = next;
++next;
if ( ((*si)->GetBornOn() + (*si)->GetTimeOut()) < current) {
del_ptr_zero()(*si);
list_.erase(si);
}
}
count_ = 0; // reset flush counter
}
// remove a self thread error // remove a self thread error
void Errors::Remove() void Errors::Remove()
{ {
@@ -1764,7 +1805,8 @@ bool SSL_METHOD::multipleProtocol() const
SSL_CTX::SSL_CTX(SSL_METHOD* meth) SSL_CTX::SSL_CTX(SSL_METHOD* meth)
: method_(meth), certificate_(0), privateKey_(0), passwordCb_(0), : method_(meth), certificate_(0), privateKey_(0), passwordCb_(0),
userData_(0), sessionCacheOff_(false) userData_(0), sessionCacheOff_(false), sessionCacheFlushOff_(false),
verifyCallback_(0)
{} {}
@@ -1791,6 +1833,12 @@ SSL_CTX::GetCA_List() const
} }
const VerifyCallback SSL_CTX::getVerifyCallback() const
{
return verifyCallback_;
}
const x509* SSL_CTX::getCert() const const x509* SSL_CTX::getCert() const
{ {
return certificate_; return certificate_;
@@ -1851,6 +1899,12 @@ bool SSL_CTX::GetSessionCacheOff() const
} }
bool SSL_CTX::GetSessionCacheFlushOff() const
{
return sessionCacheFlushOff_;
}
void SSL_CTX::SetUserData(void* data) void SSL_CTX::SetUserData(void* data)
{ {
userData_ = data; userData_ = data;
@@ -1863,6 +1917,12 @@ void SSL_CTX::SetSessionCacheOff()
} }
void SSL_CTX::SetSessionCacheFlushOff()
{
sessionCacheFlushOff_ = true;
}
void SSL_CTX::setVerifyPeer() void SSL_CTX::setVerifyPeer()
{ {
method_->setVerifyPeer(); method_->setVerifyPeer();
@@ -1881,6 +1941,12 @@ void SSL_CTX::setFailNoCert()
} }
void SSL_CTX::setVerifyCallback(VerifyCallback vc)
{
verifyCallback_ = vc;
}
bool SSL_CTX::SetDH(const DH& dh) bool SSL_CTX::SetDH(const DH& dh)
{ {
dhParms_.p_ = dh.p->int_; dhParms_.p_ = dh.p->int_;
@@ -1906,7 +1972,7 @@ bool SSL_CTX::SetCipherList(const char* list)
int idx = 0; int idx = 0;
for(;;) { for(;;) {
int len; size_t len;
prev = haystack; prev = haystack;
haystack = strstr(haystack, needle); haystack = strstr(haystack, needle);
@@ -2316,7 +2382,7 @@ X509::X509(const char* i, size_t iSz, const char* s, size_t sSz,
: issuer_(i, iSz), subject_(s, sSz), : issuer_(i, iSz), subject_(s, sSz),
beforeDate_(b, bSz), afterDate_(a, aSz) beforeDate_(b, bSz), afterDate_(a, aSz)
{} {}
X509_NAME* X509::GetIssuer() X509_NAME* X509::GetIssuer()
{ {
@@ -2354,10 +2420,10 @@ ASN1_STRING* X509_NAME::GetEntry(int i)
memcpy(entry_.data, &name_[i], sz_ - i); memcpy(entry_.data, &name_[i], sz_ - i);
if (entry_.data[sz_ -i - 1]) { if (entry_.data[sz_ -i - 1]) {
entry_.data[sz_ - i] = 0; entry_.data[sz_ - i] = 0;
entry_.length = sz_ - i; entry_.length = int(sz_) - i;
} }
else else
entry_.length = sz_ - i - 1; entry_.length = int(sz_) - i - 1;
entry_.type = 0; entry_.type = 0;
return &entry_; return &entry_;

View File

@@ -1,5 +1,5 @@
SUBDIRS = src test benchmark SUBDIRS = src test benchmark
EXTRA_DIST = taocrypt.dsw taocrypt.dsp taocrypt.vcproj CMakeLists.txt $(wildcard mySTL/*.hpp) EXTRA_DIST = CMakeLists.txt $(wildcard mySTL/*.hpp)
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%

View File

@@ -1,268 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="taocrypt"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\debug_obj"
IntermediateDirectory=".\debug_obj"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="include,mySTL"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
ExceptionHandling="FALSE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\debug_obj/taocrypt.pch"
AssemblerListingLocation=".\debug_obj/"
ObjectFile=".\debug_obj/"
ProgramDataBaseFileName=".\debug_obj/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile=".\debug_obj\taocrypt.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\release_obj"
IntermediateDirectory=".\release_obj"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="include,mySTL"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="TRUE"
ExceptionHandling="FALSE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\release_obj/taocrypt.pch"
AssemblerListingLocation=".\release_obj/"
ObjectFile=".\release_obj/"
ProgramDataBaseFileName=".\release_obj/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile=".\release_obj\taocrypt.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="src\aes.cpp">
</File>
<File
RelativePath="src\aestables.cpp">
</File>
<File
RelativePath="src\algebra.cpp">
</File>
<File
RelativePath="src\arc4.cpp">
</File>
<File
RelativePath="src\asn.cpp">
</File>
<File
RelativePath="src\coding.cpp">
</File>
<File
RelativePath="src\des.cpp">
</File>
<File
RelativePath="src\dh.cpp">
</File>
<File
RelativePath="src\dsa.cpp">
</File>
<File
RelativePath="src\file.cpp">
</File>
<File
RelativePath="src\hash.cpp">
</File>
<File
RelativePath="src\integer.cpp">
</File>
<File
RelativePath="src\md2.cpp">
</File>
<File
RelativePath="src\md4.cpp">
</File>
<File
RelativePath="src\md5.cpp">
</File>
<File
RelativePath="src\misc.cpp">
</File>
<File
RelativePath="src\random.cpp">
</File>
<File
RelativePath="src\ripemd.cpp">
</File>
<File
RelativePath="src\rsa.cpp">
</File>
<File
RelativePath="src\sha.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="include\aes.hpp">
</File>
<File
RelativePath="include\algebra.hpp">
</File>
<File
RelativePath="include\arc4.hpp">
</File>
<File
RelativePath="include\asn.hpp">
</File>
<File
RelativePath="include\block.hpp">
</File>
<File
RelativePath="include\coding.hpp">
</File>
<File
RelativePath="include\des.hpp">
</File>
<File
RelativePath="include\dh.hpp">
</File>
<File
RelativePath="include\dsa.hpp">
</File>
<File
RelativePath="include\error.hpp">
</File>
<File
RelativePath="include\file.hpp">
</File>
<File
RelativePath="include\hash.hpp">
</File>
<File
RelativePath="include\hmac.hpp">
</File>
<File
RelativePath="include\integer.hpp">
</File>
<File
RelativePath="include\md2.hpp">
</File>
<File
RelativePath="include\md4.hpp">
</File>
<File
RelativePath="include\md5.hpp">
</File>
<File
RelativePath="include\misc.hpp">
</File>
<File
RelativePath="include\modarith.hpp">
</File>
<File
RelativePath="include\modes.hpp">
</File>
<File
RelativePath="include\random.hpp">
</File>
<File
RelativePath="include\ripemd.hpp">
</File>
<File
RelativePath="include\rsa.hpp">
</File>
<File
RelativePath="include\sha.hpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -1,211 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="yassl"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\debug_obj"
IntermediateDirectory=".\debug_obj"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="include,taocrypt\include,taocrypt\mySTL"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;YASSL_PREFIX"
ExceptionHandling="FALSE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\debug_obj/yassl.pch"
AssemblerListingLocation=".\debug_obj/"
ObjectFile=".\debug_obj/"
ProgramDataBaseFileName=".\debug_obj/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile=".\debug_obj\yassl.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\release_obj"
IntermediateDirectory=".\release_obj"
ConfigurationType="4"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
OptimizeForProcessor="2"
AdditionalIncludeDirectories="include,taocrypt\include,taocrypt\mySTL"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;YASSL_PREFIX"
StringPooling="TRUE"
ExceptionHandling="FALSE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\release_obj/yassl.pch"
AssemblerListingLocation=".\release_obj/"
ObjectFile=".\release_obj/"
ProgramDataBaseFileName=".\release_obj/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLibrarianTool"
OutputFile=".\release_obj\yassl.lib"
SuppressStartupBanner="TRUE"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="src\buffer.cpp">
</File>
<File
RelativePath="src\cert_wrapper.cpp">
</File>
<File
RelativePath="src\crypto_wrapper.cpp">
</File>
<File
RelativePath="src\handshake.cpp">
</File>
<File
RelativePath="src\lock.cpp">
</File>
<File
RelativePath="src\log.cpp">
</File>
<File
RelativePath="src\socket_wrapper.cpp">
</File>
<File
RelativePath="src\ssl.cpp">
</File>
<File
RelativePath="src\timer.cpp">
</File>
<File
RelativePath="src\yassl_error.cpp">
</File>
<File
RelativePath="src\yassl_imp.cpp">
</File>
<File
RelativePath="src\yassl_int.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="include\buffer.hpp">
</File>
<File
RelativePath="include\cert_wrapper.hpp">
</File>
<File
RelativePath="include\crypto_wrapper.hpp">
</File>
<File
RelativePath="include\factory.hpp">
</File>
<File
RelativePath="include\handshake.hpp">
</File>
<File
RelativePath="include\lock.hpp">
</File>
<File
RelativePath="include\log.hpp">
</File>
<File
RelativePath="include\socket_wrapper.hpp">
</File>
<File
RelativePath="include\timer.hpp">
</File>
<File
RelativePath="include\yassl_error.hpp">
</File>
<File
RelativePath="include\yassl_imp.hpp">
</File>
<File
RelativePath="include\yassl_int.hpp">
</File>
<File
RelativePath="include\yassl_types.hpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -15,8 +15,9 @@
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, # Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA # MA 02111-1307, USA
BUILT_SOURCES = $(HEADERS_GEN) link_sources BUILT_SOURCES = $(HEADERS_GEN_MAKE) link_sources
HEADERS_GEN = mysql_version.h my_config.h HEADERS_GEN_CONFIGURE = mysql_version.h
HEADERS_GEN_MAKE = my_config.h
HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \ HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
my_list.h my_alloc.h typelib.h mysql/plugin.h my_list.h my_alloc.h typelib.h mysql/plugin.h
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \ pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
@@ -25,7 +26,9 @@ pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
decimal.h errmsg.h my_global.h my_net.h \ decimal.h errmsg.h my_global.h my_net.h \
my_getopt.h sslopt-longopts.h my_dir.h \ my_getopt.h sslopt-longopts.h my_dir.h \
sslopt-vars.h sslopt-case.h sql_common.h keycache.h \ sslopt-vars.h sslopt-case.h sql_common.h keycache.h \
m_ctype.h my_attribute.h $(HEADERS_GEN) m_ctype.h my_attribute.h $(HEADERS_GEN_CONFIGURE) \
$(HEADERS_GEN_MAKE)
noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \ noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \
heap.h maria.h myisamchk.h my_bitmap.h my_uctype.h \ heap.h maria.h myisamchk.h my_bitmap.h my_uctype.h \
myisam.h myisampack.h myisammrg.h ft_global.h\ myisam.h myisampack.h myisammrg.h ft_global.h\
@@ -33,18 +36,19 @@ noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \
my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \
my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \ my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \
thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \
mysql_version.h.in my_handler.h my_time.h \ my_handler.h my_time.h \
my_vle.h my_user.h my_atomic.h atomic/nolock.h \ my_vle.h my_user.h my_atomic.h atomic/nolock.h \
atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \ atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \
atomic/gcc_builtins.h my_libwrap.h wqueue.h atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \
wqueue.h waiting_threads.h
EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp
# Remove built files and the symlinked directories # Remove built files and the symlinked directories
CLEANFILES = $(BUILT_SOURCES) readline openssl CLEANFILES = $(BUILT_SOURCES) readline openssl
EXTRA_DIST = mysql_h.ic
# Some include files that may be moved and patched by configure # Some include files that may be moved and patched by configure
DISTCLEANFILES = sched.h $(CLEANFILES) DISTCLEANFILES = sched.h $(CLEANFILES) $(HEADERS_GEN_CONFIGURE)
link_sources: link_sources:
-$(RM) -f readline openssl -$(RM) -f readline openssl
@@ -63,18 +67,5 @@ my_config.h: config.h
dist-hook: dist-hook:
$(RM) -f $(distdir)/mysql_version.h $(distdir)/my_config.h $(RM) -f $(distdir)/mysql_version.h $(distdir)/my_config.h
#
# Rules for checking that ABI has not changed
#
# Create a icheck file and compare it to the reference
abi_check: $(HEADERS_ABI) mysql_version.h mysql_h.ic
@set -ex; \
if [ @ICHECK@ != no ] ; then \
@ICHECK@ --canonify --skip-from-re /usr/ -o $@ $(HEADERS_ABI); \
@ICHECK@ --compare mysql_h.ic $@; \
fi; \
touch abi_check;
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%

View File

@@ -52,8 +52,8 @@ LONG _InterlockedExchangeAdd (LONG volatile *Addend, LONG Value);
#endif /*_M_IX86*/ #endif /*_M_IX86*/
#define MY_ATOMIC_MODE "msvc-intrinsics" #define MY_ATOMIC_MODE "msvc-intrinsics"
#define IL_EXCHG_ADD32 InterlockedExchangeAdd #define IL_EXCHG_ADD32(X,Y) InterlockedExchangeAdd((volatile LONG *)(X),(Y))
#define IL_COMP_EXCHG32 InterlockedCompareExchange #define IL_COMP_EXCHG32(X,Y,Z) InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z))
#define IL_COMP_EXCHGptr InterlockedCompareExchangePointer #define IL_COMP_EXCHGptr InterlockedCompareExchangePointer
#define IL_EXCHG32 InterlockedExchange #define IL_EXCHG32 InterlockedExchange
#define IL_EXCHGptr InterlockedExchangePointer #define IL_EXCHGptr InterlockedExchangePointer

View File

@@ -96,6 +96,7 @@ extern const char *client_errors[]; /* Error messages */
#define CR_NOT_IMPLEMENTED 2054 #define CR_NOT_IMPLEMENTED 2054
#define CR_SERVER_LOST_EXTENDED 2055 #define CR_SERVER_LOST_EXTENDED 2055
#define CR_STMT_CLOSED 2056 #define CR_STMT_CLOSED 2056
#define CR_ERROR_LAST /*Copy last error nr:*/ 2056 #define CR_NEW_STMT_METADATA 2057
#define CR_ERROR_LAST /*Copy last error nr:*/ 2057
/* Add error numbers before CR_ERROR_LAST and change it accordingly. */ /* Add error numbers before CR_ERROR_LAST and change it accordingly. */

View File

@@ -21,6 +21,40 @@
extern "C" { extern "C" {
#endif #endif
/*
There was a problem on MacOSX with a shared object ha_example.so.
It used hash_search(). During build of ha_example.so no libmysys
was specified. Since MacOSX had a hash_search() in the system
library, it built the shared object so that the dynamic linker
linked hash_search() to the system library, which caused a crash
when called. To come around this, we renamed hash_search() to
my_hash_search(), as we did long ago with hash_insert() and
hash_reset(). However, this time we made the move complete with
all names. To keep compatibility, we redefine the old names.
Since every C and C++ file, that uses HASH, needs to include
this file, the change is complete. Both names could be used
in the code, but the my_* versions are recommended now.
*/
#define hash_get_key my_hash_get_key
#define hash_free_key my_hash_free_key
#define hash_init my_hash_init
#define hash_init2 my_hash_init2
#define _hash_init _my_hash_init
#define hash_free my_hash_free
#define hash_reset my_hash_reset
#define hash_element my_hash_element
#define hash_search my_hash_search
#define hash_first my_hash_first
#define hash_next my_hash_next
#define hash_insert my_hash_insert
#define hash_delete my_hash_delete
#define hash_update my_hash_update
#define hash_replace my_hash_replace
#define hash_check my_hash_check
#define hash_clear my_hash_clear
#define hash_inited my_hash_inited
#define hash_init_opt my_hash_init_opt
/* /*
Overhead to store an element in hash Overhead to store an element in hash
Can be used to approximate memory consumption for a hash Can be used to approximate memory consumption for a hash
@@ -30,8 +64,9 @@ extern "C" {
/* flags for hash_init */ /* flags for hash_init */
#define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */ #define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */
typedef uchar *(*hash_get_key)(const uchar *,size_t*,my_bool); typedef uchar *(*my_hash_get_key)(const uchar *,size_t*,my_bool);
typedef void (*hash_free_key)(void *); typedef void (*my_hash_free_key)(void *);
typedef my_bool (*my_hash_walk_action)(void *,void *);
typedef struct st_hash { typedef struct st_hash {
size_t key_offset,key_length; /* Length of key if const length */ size_t key_offset,key_length; /* Length of key if const length */
@@ -39,7 +74,7 @@ typedef struct st_hash {
ulong records; ulong records;
uint flags; uint flags;
DYNAMIC_ARRAY array; /* Place for hash_keys */ DYNAMIC_ARRAY array; /* Place for hash_keys */
hash_get_key get_key; my_hash_get_key get_key;
void (*free)(void *); void (*free)(void *);
CHARSET_INFO *charset; CHARSET_INFO *charset;
} HASH; } HASH;
@@ -47,30 +82,35 @@ typedef struct st_hash {
/* A search iterator state */ /* A search iterator state */
typedef uint HASH_SEARCH_STATE; typedef uint HASH_SEARCH_STATE;
#define hash_init(A,B,C,D,E,F,G,H) _hash_init(A,0,B,C,D,E,F,G,H CALLER_INFO) #define my_hash_init(A,B,C,D,E,F,G,H) \
#define hash_init2(A,B,C,D,E,F,G,H,I) _hash_init(A,B,C,D,E,F,G,H,I CALLER_INFO) _my_hash_init(A,0,B,C,D,E,F,G,H CALLER_INFO)
my_bool _hash_init(HASH *hash, uint growth_size,CHARSET_INFO *charset, #define my_hash_init2(A,B,C,D,E,F,G,H,I) \
ulong default_array_elements, size_t key_offset, _my_hash_init(A,B,C,D,E,F,G,H,I CALLER_INFO)
size_t key_length, hash_get_key get_key, my_bool _my_hash_init(HASH *hash, uint growth_size, CHARSET_INFO *charset,
void (*free_element)(void*), uint flags CALLER_INFO_PROTO); ulong default_array_elements, size_t key_offset,
void hash_free(HASH *tree); size_t key_length, my_hash_get_key get_key,
void (*free_element)(void*),
uint flags CALLER_INFO_PROTO);
void my_hash_free(HASH *tree);
void my_hash_reset(HASH *hash); void my_hash_reset(HASH *hash);
uchar *hash_element(HASH *hash,ulong idx); uchar *my_hash_element(HASH *hash, ulong idx);
uchar *hash_search(const HASH *info, const uchar *key, size_t length); uchar *my_hash_search(const HASH *info, const uchar *key, size_t length);
uchar *hash_first(const HASH *info, const uchar *key, size_t length, uchar *my_hash_first(const HASH *info, const uchar *key, size_t length,
HASH_SEARCH_STATE *state); HASH_SEARCH_STATE *state);
uchar *hash_next(const HASH *info, const uchar *key, size_t length, uchar *my_hash_next(const HASH *info, const uchar *key, size_t length,
HASH_SEARCH_STATE *state); HASH_SEARCH_STATE *state);
my_bool my_hash_insert(HASH *info,const uchar *data); my_bool my_hash_insert(HASH *info, const uchar *data);
my_bool hash_delete(HASH *hash,uchar *record); my_bool my_hash_delete(HASH *hash, uchar *record);
my_bool hash_update(HASH *hash,uchar *record,uchar *old_key,size_t old_key_length); my_bool my_hash_update(HASH *hash, uchar *record, uchar *old_key,
void hash_replace(HASH *hash, HASH_SEARCH_STATE *state, uchar *new_row); size_t old_key_length);
my_bool hash_check(HASH *hash); /* Only in debug library */ void my_hash_replace(HASH *hash, HASH_SEARCH_STATE *state, uchar *new_row);
my_bool my_hash_check(HASH *hash); /* Only in debug library */
my_bool my_hash_iterate(HASH *hash, my_hash_walk_action action, void *argument);
#define hash_clear(H) bzero((char*) (H),sizeof(*(H))) #define my_hash_clear(H) bzero((char*) (H), sizeof(*(H)))
#define hash_inited(H) ((H)->array.buffer != 0) #define my_hash_inited(H) ((H)->array.buffer != 0)
#define hash_init_opt(A,B,C,D,E,F,G,H) \ #define my_hash_init_opt(A,B,C,D,E,F,G,H) \
(!hash_inited(A) && _hash_init(A,0,B,C,D,E,F,G, H CALLER_INFO)) (!my_hash_inited(A) && _my_hash_init(A,0,B,C,D,E,F,G, H CALLER_INFO))
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -110,7 +110,7 @@ typedef struct {
typedef struct { typedef struct {
void * volatile pin[LF_PINBOX_PINS]; void * volatile pin[LF_PINBOX_PINS];
LF_PINBOX *pinbox; LF_PINBOX *pinbox;
void *stack_ends_here; void **stack_ends_here;
void *purgatory; void *purgatory;
uint32 purgatory_count; uint32 purgatory_count;
uint32 volatile link; uint32 volatile link;
@@ -166,8 +166,8 @@ void lf_pinbox_init(LF_PINBOX *pinbox, uint free_ptr_offset,
void lf_pinbox_destroy(LF_PINBOX *pinbox); void lf_pinbox_destroy(LF_PINBOX *pinbox);
lock_wrap(lf_pinbox_get_pins, LF_PINS *, lock_wrap(lf_pinbox_get_pins, LF_PINS *,
(LF_PINBOX *pinbox, void *stack_end), (LF_PINBOX *pinbox),
(pinbox, stack_end), (pinbox),
&pinbox->pinarray.lock) &pinbox->pinarray.lock)
lock_wrap_void(lf_pinbox_put_pins, lock_wrap_void(lf_pinbox_put_pins,
(LF_PINS *pins), (LF_PINS *pins),
@@ -182,15 +182,13 @@ lock_wrap_void(lf_pinbox_free,
memory allocator, lf_alloc-pin.c memory allocator, lf_alloc-pin.c
*/ */
struct st_lf_alloc_node {
struct st_lf_alloc_node *next;
};
typedef struct st_lf_allocator { typedef struct st_lf_allocator {
LF_PINBOX pinbox; LF_PINBOX pinbox;
struct st_lf_alloc_node * volatile top; uchar * volatile top;
uint element_size; uint element_size;
uint32 volatile mallocs; uint32 volatile mallocs;
void (*constructor)(uchar *);
void (*destructor)(uchar *);
} LF_ALLOCATOR; } LF_ALLOCATOR;
void lf_alloc_init(LF_ALLOCATOR *allocator, uint size, uint free_ptr_offset); void lf_alloc_init(LF_ALLOCATOR *allocator, uint size, uint free_ptr_offset);
@@ -202,8 +200,8 @@ uint lf_alloc_pool_count(LF_ALLOCATOR *allocator);
*/ */
#define _lf_alloc_free(PINS, PTR) _lf_pinbox_free((PINS), (PTR)) #define _lf_alloc_free(PINS, PTR) _lf_pinbox_free((PINS), (PTR))
#define lf_alloc_free(PINS, PTR) lf_pinbox_free((PINS), (PTR)) #define lf_alloc_free(PINS, PTR) lf_pinbox_free((PINS), (PTR))
#define _lf_alloc_get_pins(A, ST) _lf_pinbox_get_pins(&(A)->pinbox, (ST)) #define _lf_alloc_get_pins(A) _lf_pinbox_get_pins(&(A)->pinbox)
#define lf_alloc_get_pins(A, ST) lf_pinbox_get_pins(&(A)->pinbox, (ST)) #define lf_alloc_get_pins(A) lf_pinbox_get_pins(&(A)->pinbox)
#define _lf_alloc_put_pins(PINS) _lf_pinbox_put_pins(PINS) #define _lf_alloc_put_pins(PINS) _lf_pinbox_put_pins(PINS)
#define lf_alloc_put_pins(PINS) lf_pinbox_put_pins(PINS) #define lf_alloc_put_pins(PINS) lf_pinbox_put_pins(PINS)
#define lf_alloc_direct_free(ALLOC, ADDR) my_free((uchar*)(ADDR), MYF(0)) #define lf_alloc_direct_free(ALLOC, ADDR) my_free((uchar*)(ADDR), MYF(0))
@@ -220,13 +218,17 @@ lock_wrap(lf_alloc_new, void *,
#define LF_HASH_UNIQUE 1 #define LF_HASH_UNIQUE 1
/* lf_hash overhead per element (that is, sizeof(LF_SLIST) */
#define LF_HASH_OVERHEAD (sizeof(int*)*4)
typedef struct { typedef struct {
LF_DYNARRAY array; /* hash itself */ LF_DYNARRAY array; /* hash itself */
LF_ALLOCATOR alloc; /* allocator for elements */ LF_ALLOCATOR alloc; /* allocator for elements */
hash_get_key get_key; /* see HASH */ hash_get_key get_key; /* see HASH */
CHARSET_INFO *charset; /* see HASH */ CHARSET_INFO *charset; /* see HASH */
uint key_offset, key_length; /* see HASH */ uint key_offset, key_length; /* see HASH */
uint element_size, flags; /* LF_HASH_UNIQUE, etc */ uint element_size; /* size of memcpy'ed area on insert */
uint flags; /* LF_HASH_UNIQUE, etc */
int32 volatile size; /* size of array */ int32 volatile size; /* size of array */
int32 volatile count; /* number of elements in the hash */ int32 volatile count; /* number of elements in the hash */
} LF_HASH; } LF_HASH;
@@ -242,8 +244,8 @@ int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen);
shortcut macros to access underlying pinbox functions from an LF_HASH shortcut macros to access underlying pinbox functions from an LF_HASH
see _lf_pinbox_get_pins() and _lf_pinbox_put_pins() see _lf_pinbox_get_pins() and _lf_pinbox_put_pins()
*/ */
#define _lf_hash_get_pins(HASH, ST) _lf_alloc_get_pins(&(HASH)->alloc, (ST)) #define _lf_hash_get_pins(HASH) _lf_alloc_get_pins(&(HASH)->alloc)
#define lf_hash_get_pins(HASH, ST) lf_alloc_get_pins(&(HASH)->alloc, (ST)) #define lf_hash_get_pins(HASH) lf_alloc_get_pins(&(HASH)->alloc)
#define _lf_hash_put_pins(PINS) _lf_pinbox_put_pins(PINS) #define _lf_hash_put_pins(PINS) _lf_pinbox_put_pins(PINS)
#define lf_hash_put_pins(PINS) lf_pinbox_put_pins(PINS) #define lf_hash_put_pins(PINS) lf_pinbox_put_pins(PINS)
#define lf_hash_search_unpin(PINS) lf_unpin((PINS), 2) #define lf_hash_search_unpin(PINS) lf_unpin((PINS), 2)

View File

@@ -43,7 +43,6 @@ extern "C" {
#define MARIA_MAX_KEY MAX_INDEXES /* Max allowed keys */ #define MARIA_MAX_KEY MAX_INDEXES /* Max allowed keys */
#endif #endif
#define MARIA_MAX_MSG_BUF 1024 /* used in CHECK TABLE, REPAIR TABLE */
#define MARIA_NAME_IEXT ".MAI" #define MARIA_NAME_IEXT ".MAI"
#define MARIA_NAME_DEXT ".MAD" #define MARIA_NAME_DEXT ".MAD"
/* Max extra space to use when sorting keys */ /* Max extra space to use when sorting keys */
@@ -274,6 +273,12 @@ extern my_off_t maria_max_temp_length;
extern ulong maria_bulk_insert_tree_size, maria_data_pointer_size; extern ulong maria_bulk_insert_tree_size, maria_data_pointer_size;
extern PAGECACHE maria_pagecache_var, *maria_pagecache; extern PAGECACHE maria_pagecache_var, *maria_pagecache;
extern MY_TMPDIR *maria_tmpdir; extern MY_TMPDIR *maria_tmpdir;
/*
This is used to check if a symlink points into the mysql data home,
which is normally forbidden as it can be used to get access to
not privileged data
*/
extern int (*maria_test_invalid_symlink)(const char *filename);
/* Prototypes for maria-functions */ /* Prototypes for maria-functions */

View File

@@ -39,12 +39,12 @@ typedef struct st_mem_root
/* if block have less memory it will be put in 'used' list */ /* if block have less memory it will be put in 'used' list */
size_t min_malloc; size_t min_malloc;
size_t block_size; /* initial block size */ size_t block_size; /* initial block size */
unsigned long block_num; /* allocated blocks counter */ unsigned int block_num; /* allocated blocks counter */
/* /*
first free block in queue test counter (if it exceed first free block in queue test counter (if it exceed
MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list) MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list)
*/ */
unsigned long first_block_usage; unsigned int first_block_usage;
void (*error_handler)(void); void (*error_handler)(void);
} MEM_ROOT; } MEM_ROOT;

View File

@@ -195,7 +195,9 @@ enum ha_extra_function {
begin and end of a statement. begin and end of a statement.
*/ */
HA_EXTRA_ATTACH_CHILDREN, HA_EXTRA_ATTACH_CHILDREN,
HA_EXTRA_DETACH_CHILDREN HA_EXTRA_DETACH_CHILDREN,
/* Inform handler we will force a close as part of flush */
HA_EXTRA_PREPARE_FOR_FORCED_CLOSE
}; };
/* Compatible option, to be deleted in 6.0 */ /* Compatible option, to be deleted in 6.0 */

View File

@@ -18,11 +18,6 @@
#ifndef _global_h #ifndef _global_h
#define _global_h #define _global_h
#ifndef EMBEDDED_LIBRARY
#define HAVE_REPLICATION
#define HAVE_EXTERNAL_CLIENT
#endif
/* /*
InnoDB depends on some MySQL internals which other plugins should not InnoDB depends on some MySQL internals which other plugins should not
need. This is because of InnoDB's foreign key support, "safe" binlog need. This is because of InnoDB's foreign key support, "safe" binlog
@@ -101,6 +96,11 @@
#endif #endif
#endif /* !EMBEDDED_LIBRARY */ #endif /* !EMBEDDED_LIBRARY */
#ifndef EMBEDDED_LIBRARY
#define HAVE_REPLICATION
#define HAVE_EXTERNAL_CLIENT
#endif
/* Some defines to avoid ifdefs in the code */ /* Some defines to avoid ifdefs in the code */
#ifndef NETWARE_YIELD #ifndef NETWARE_YIELD
#define NETWARE_YIELD #define NETWARE_YIELD
@@ -478,14 +478,13 @@ C_MODE_END
#include <assert.h> #include <assert.h>
/* an assert that works at compile-time. only for constant expression */ /* an assert that works at compile-time. only for constant expression */
#ifndef __GNUC__ #ifdef _some_old_compiler_that_does_not_understand_the_construct_below_
#define compile_time_assert(X) do { } while(0) #define compile_time_assert(X) do { } while(0)
#else #else
#define compile_time_assert(X) \ #define compile_time_assert(X) \
do \ do \
{ \ { \
char compile_time_assert[(X) ? 1 : -1] \ typedef char compile_time_assert[(X) ? 1 : -1]; \
__attribute__ ((unused)); \
} while(0) } while(0)
#endif #endif
@@ -579,7 +578,7 @@ typedef unsigned short ushort;
#define CMP_NUM(a,b) (((a) < (b)) ? -1 : ((a) == (b)) ? 0 : 1) #define CMP_NUM(a,b) (((a) < (b)) ? -1 : ((a) == (b)) ? 0 : 1)
#define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0) #define sgn(a) (((a) < 0) ? -1 : ((a) > 0) ? 1 : 0)
#define swap_variables(t, a, b) { register t swap_dummy; swap_dummy= a; a= b; b= swap_dummy; } #define swap_variables(t, a, b) { t swap_dummy; swap_dummy= a; a= b; b= swap_dummy; }
#define test(a) ((a) ? 1 : 0) #define test(a) ((a) ? 1 : 0)
#define set_if_bigger(a,b) do { if ((a) < (b)) (a)=(b); } while(0) #define set_if_bigger(a,b) do { if ((a) < (b)) (a)=(b); } while(0)
#define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0) #define set_if_smaller(a,b) do { if ((a) > (b)) (a)=(b); } while(0)
@@ -1518,17 +1517,45 @@ inline void operator delete[](void*, void*) { /* Do nothing */ }
#if !defined(max) #if !defined(max)
#define max(a, b) ((a) > (b) ? (a) : (b)) #define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b))
#endif #endif
/* /*
Only Linux is known to need an explicit sync of the directory to make sure a Only Linux is known to need an explicit sync of the directory to make sure a
file creation/deletion/renaming in(from,to) this directory durable. file creation/deletion/renaming in(from,to) this directory durable.
*/ */
#ifdef TARGET_OS_LINUX #ifdef TARGET_OS_LINUX
#define NEED_EXPLICIT_SYNC_DIR 1 #define NEED_EXPLICIT_SYNC_DIR 1
#else
/*
On linux default rwlock scheduling policy is good enough for
waiting_threads.c, on other systems use our special implementation
(which is slower).
QQ perhaps this should be tested in configure ? how ?
*/
#define WT_RWLOCKS_USE_MUTEXES 1
#endif #endif
#if !defined(__cplusplus) && !defined(bool) #if !defined(__cplusplus) && !defined(bool)
#define bool In_C_you_should_use_my_bool_instead() #define bool In_C_you_should_use_my_bool_instead()
#endif #endif
/* Provide __func__ macro definition for platforms that miss it. */
#if __STDC_VERSION__ < 199901L
# if __GNUC__ >= 2
# define __func__ __FUNCTION__
# else
# define __func__ "<unknown>"
# endif
#elif defined(_MSC_VER)
# if _MSC_VER < 1300
# define __func__ "<unknown>"
# else
# define __func__ __FUNCTION__
# endif
#elif defined(__BORLANDC__)
# define __func__ __FUNC__
#else
# define __func__ "<unknown>"
#endif
#endif /* my_global_h */ #endif /* my_global_h */

View File

@@ -45,6 +45,7 @@ extern "C" {
#define HA_MAX_POSSIBLE_KEY_BUFF (HA_MAX_KEY_LENGTH + 24+ 6+6) #define HA_MAX_POSSIBLE_KEY_BUFF (HA_MAX_KEY_LENGTH + 24+ 6+6)
#define HA_MAX_KEY_BUFF (HA_MAX_KEY_LENGTH+HA_MAX_KEY_SEG*6+8+8) #define HA_MAX_KEY_BUFF (HA_MAX_KEY_LENGTH+HA_MAX_KEY_SEG*6+8+8)
#define HA_MAX_MSG_BUF 1024 /* used in CHECK TABLE, REPAIR TABLE */
typedef struct st_HA_KEYSEG /* Key-portion */ typedef struct st_HA_KEYSEG /* Key-portion */
{ {

View File

@@ -79,25 +79,27 @@ typedef void * (__cdecl *pthread_handler)(void *);
so it can be used directly as a 64 bit value. The value so it can be used directly as a 64 bit value. The value
stored is in 100ns units. stored is in 100ns units.
*/ */
union ft64 { union ft64 {
FILETIME ft; FILETIME ft;
__int64 i64; __int64 i64;
}; };
struct timespec { struct timespec {
union ft64 tv; union ft64 tv;
/* The max timeout value in millisecond for pthread_cond_timedwait */ /* The max timeout value in millisecond for pthread_cond_timedwait */
long max_timeout_msec; long max_timeout_msec;
}; };
#define set_timespec(ABSTIME,SEC) { \
GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \ #define set_timespec_time_nsec(ABSTIME,TIME,NSEC) do { \
(ABSTIME).tv.i64+= (__int64)(SEC)*10000000; \ (ABSTIME).tv.i64= (TIME)+(__int64)(NSEC)/100; \
(ABSTIME).max_timeout_msec= (long)((SEC)*1000); \ (ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
} } while(0)
#define set_timespec_nsec(ABSTIME,NSEC) { \
GetSystemTimeAsFileTime(&((ABSTIME).tv.ft)); \ #define set_timespec_nsec(ABSTIME,NSEC) do { \
(ABSTIME).tv.i64+= (__int64)(NSEC)/100; \ union ft64 tv; \
(ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \ GetSystemTimeAsFileTime(&tv.ft); \
} set_timespec_time_nsec((ABSTIME), tv.i64, (NSEC)); \
} while(0)
void win_pthread_init(void); void win_pthread_init(void);
int win_pthread_setspecific(void *A,void *B,uint length); int win_pthread_setspecific(void *A,void *B,uint length);
@@ -237,13 +239,13 @@ int my_sigwait(const sigset_t *set,int *sig);
#ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT #ifdef HAVE_NONPOSIX_PTHREAD_MUTEX_INIT
#ifndef SAFE_MUTEX #ifndef SAFE_MUTEX
#define pthread_mutex_init(a,b) my_pthread_mutex_init((a),(b)) #define pthread_mutex_init(a,b) my_pthread_mutex_noposix_init((a),(b))
extern int my_pthread_mutex_init(pthread_mutex_t *mp, extern int my_pthread_mutex_noposix_init(pthread_mutex_t *mp,
const pthread_mutexattr_t *attr); const pthread_mutexattr_t *attr);
#endif /* SAFE_MUTEX */ #endif /* SAFE_MUTEX */
#define pthread_cond_init(a,b) my_pthread_cond_init((a),(b)) #define pthread_cond_init(a,b) my_pthread_cond_noposix_init((a),(b))
extern int my_pthread_cond_init(pthread_cond_t *mp, extern int my_pthread_cond_noposix_init(pthread_cond_t *mp,
const pthread_condattr_t *attr); const pthread_condattr_t *attr);
#endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */ #endif /* HAVE_NONPOSIX_PTHREAD_MUTEX_INIT */
#if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK) #if defined(HAVE_SIGTHREADMASK) && !defined(HAVE_PTHREAD_SIGMASK)
@@ -282,6 +284,8 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */
#define my_pthread_setprio(A,B) pthread_setprio_np((A),(B)) #define my_pthread_setprio(A,B) pthread_setprio_np((A),(B))
#elif defined(HAVE_PTHREAD_SETPRIO) #elif defined(HAVE_PTHREAD_SETPRIO)
#define my_pthread_setprio(A,B) pthread_setprio((A),(B)) #define my_pthread_setprio(A,B) pthread_setprio((A),(B))
#elif defined(HAVE_PTHREAD_SETSCHEDPRIO)
#define my_pthread_setprio(A,B) pthread_setschedprio((A),(B))
#else #else
extern void my_pthread_setprio(pthread_t thread_id,int prior); extern void my_pthread_setprio(pthread_t thread_id,int prior);
#endif #endif
@@ -416,59 +420,64 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
for calculating an absolute time at which for calculating an absolute time at which
pthread_cond_timedwait should timeout pthread_cond_timedwait should timeout
*/ */
#define set_timespec(ABSTIME,SEC) set_timespec_nsec((ABSTIME),(SEC)*1000000000ULL)
#ifndef set_timespec_nsec
#define set_timespec_nsec(ABSTIME,NSEC) \
set_timespec_time_nsec((ABSTIME),my_getsystime(),(NSEC))
#endif /* !set_timespec_nsec */
/* adapt for two different flavors of struct timespec */
#ifdef HAVE_TIMESPEC_TS_SEC #ifdef HAVE_TIMESPEC_TS_SEC
#ifndef set_timespec #define TV_sec ts_sec
#define set_timespec(ABSTIME,SEC) \ #define TV_nsec ts_nsec
{ \
(ABSTIME).ts_sec=time(0) + (time_t) (SEC); \
(ABSTIME).ts_nsec=0; \
}
#endif /* !set_timespec */
#ifndef set_timespec_nsec
#define set_timespec_nsec(ABSTIME,NSEC) \
{ \
ulonglong now= my_getsystime() + (NSEC/100); \
(ABSTIME).ts_sec= (now / ULL(10000000)); \
(ABSTIME).ts_nsec= (now % ULL(10000000) * 100 + ((NSEC) % 100)); \
}
#endif /* !set_timespec_nsec */
#else #else
#ifndef set_timespec #define TV_sec tv_sec
#define set_timespec(ABSTIME,SEC) \ #define TV_nsec tv_nsec
{\
struct timeval tv;\
gettimeofday(&tv,0);\
(ABSTIME).tv_sec=tv.tv_sec+(time_t) (SEC);\
(ABSTIME).tv_nsec=tv.tv_usec*1000;\
}
#endif /* !set_timespec */
#ifndef set_timespec_nsec
#define set_timespec_nsec(ABSTIME,NSEC) \
{\
ulonglong now= my_getsystime() + (NSEC/100); \
(ABSTIME).tv_sec= (time_t) (now / ULL(10000000)); \
(ABSTIME).tv_nsec= (long) (now % ULL(10000000) * 100 + ((NSEC) % 100)); \
}
#endif /* !set_timespec_nsec */
#endif /* HAVE_TIMESPEC_TS_SEC */ #endif /* HAVE_TIMESPEC_TS_SEC */
/* safe_mutex adds checking to mutex for easier debugging */ #ifndef set_timespec_time_nsec
#define set_timespec_time_nsec(ABSTIME,TIME,NSEC) do { \
ulonglong nsec= (NSEC); \
ulonglong now= (TIME) + (nsec/100); \
(ABSTIME).TV_sec= (now / ULL(10000000)); \
(ABSTIME).TV_nsec= (now % ULL(10000000) * 100 + (nsec % 100)); \
} while(0)
#endif /* !set_timespec_time_nsec */
/* safe_mutex adds checking to mutex for easier debugging */
#if defined(__NETWARE__) && !defined(SAFE_MUTEX_DETECT_DESTROY) #if defined(__NETWARE__) && !defined(SAFE_MUTEX_DETECT_DESTROY)
#define SAFE_MUTEX_DETECT_DESTROY #define SAFE_MUTEX_DETECT_DESTROY
#endif #endif
struct st_hash;
typedef struct st_safe_mutex_t typedef struct st_safe_mutex_t
{ {
pthread_mutex_t global,mutex; pthread_mutex_t global,mutex;
const char *file, *name; const char *file, *name;
uint line,count; uint line,count;
myf create_flags, active_flags;
ulong id;
pthread_t thread; pthread_t thread;
struct st_hash *locked_mutex, *used_mutex;
struct st_safe_mutex_t *prev, *next;
#ifdef SAFE_MUTEX_DETECT_DESTROY #ifdef SAFE_MUTEX_DETECT_DESTROY
struct st_safe_mutex_info_t *info; /* to track destroying of mutexes */ struct st_safe_mutex_info_t *info; /* to track destroying of mutexes */
#endif #endif
} safe_mutex_t; } safe_mutex_t;
typedef struct st_safe_mutex_deadlock_t
{
const char *file, *name;
safe_mutex_t *mutex;
uint line;
ulong count;
ulong id;
my_bool warning_only;
} safe_mutex_deadlock_t;
#ifdef SAFE_MUTEX_DETECT_DESTROY #ifdef SAFE_MUTEX_DETECT_DESTROY
/* /*
Used to track the destroying of mutexes. This needs to be a seperate Used to track the destroying of mutexes. This needs to be a seperate
@@ -486,8 +495,10 @@ typedef struct st_safe_mutex_info_t
#endif /* SAFE_MUTEX_DETECT_DESTROY */ #endif /* SAFE_MUTEX_DETECT_DESTROY */
int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr, int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
const char *file, uint line, const char *name); const char *name, myf my_flags,
int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line); const char *file, uint line);
int safe_mutex_lock(safe_mutex_t *mp, myf my_flags, const char *file,
uint line);
int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line); int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line);
int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line); int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line);
int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file, int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file,
@@ -496,8 +507,12 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
struct timespec *abstime, const char *file, uint line); struct timespec *abstime, const char *file, uint line);
void safe_mutex_global_init(void); void safe_mutex_global_init(void);
void safe_mutex_end(FILE *file); void safe_mutex_end(FILE *file);
void safe_mutex_free_deadlock_data(safe_mutex_t *mp);
/* Wrappers if safe mutex is actually used */ /* Wrappers if safe mutex is actually used */
#define MYF_TRY_LOCK 1
#define MYF_NO_DEADLOCK_DETECTION 2
#ifdef SAFE_MUTEX #ifdef SAFE_MUTEX
#undef pthread_mutex_init #undef pthread_mutex_init
#undef pthread_mutex_lock #undef pthread_mutex_lock
@@ -509,13 +524,15 @@ void safe_mutex_end(FILE *file);
#undef pthread_cond_wait #undef pthread_cond_wait
#undef pthread_cond_timedwait #undef pthread_cond_timedwait
#undef pthread_mutex_trylock #undef pthread_mutex_trylock
#define pthread_mutex_init(A,B) safe_mutex_init((A),(B),__FILE__,__LINE__,#A) #define my_pthread_mutex_init(A,B,C,D) safe_mutex_init((A),(B),(C),(D),__FILE__,__LINE__)
#define pthread_mutex_lock(A) safe_mutex_lock((A), FALSE, __FILE__, __LINE__) #define pthread_mutex_init(A,B) safe_mutex_init((A),(B),#A,0,__FILE__,__LINE__)
#define pthread_mutex_lock(A) safe_mutex_lock((A), 0, __FILE__, __LINE__)
#define my_pthread_mutex_lock(A,B) safe_mutex_lock((A), (B), __FILE__, __LINE__)
#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__) #define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__)
#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__) #define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__)
#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__) #define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__)
#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__) #define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__)
#define pthread_mutex_trylock(A) safe_mutex_lock((A), TRUE, __FILE__, __LINE__) #define pthread_mutex_trylock(A) safe_mutex_lock((A), MYF_TRY_LOCK, __FILE__, __LINE__)
#define pthread_mutex_t safe_mutex_t #define pthread_mutex_t safe_mutex_t
#define safe_mutex_assert_owner(mp) \ #define safe_mutex_assert_owner(mp) \
DBUG_ASSERT((mp)->count > 0 && \ DBUG_ASSERT((mp)->count > 0 && \
@@ -524,8 +541,11 @@ void safe_mutex_end(FILE *file);
DBUG_ASSERT(! (mp)->count || \ DBUG_ASSERT(! (mp)->count || \
! pthread_equal(pthread_self(), (mp)->thread)) ! pthread_equal(pthread_self(), (mp)->thread))
#else #else
#define my_pthread_mutex_init(A,B,C,D) pthread_mutex_init((A),(B))
#define my_pthread_mutex_lock(A,B) pthread_mutex_lock(A)
#define safe_mutex_assert_owner(mp) #define safe_mutex_assert_owner(mp)
#define safe_mutex_assert_not_owner(mp) #define safe_mutex_assert_not_owner(mp)
#define safe_mutex_free_deadlock_data(mp)
#endif /* SAFE_MUTEX */ #endif /* SAFE_MUTEX */
#if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) #if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
@@ -533,6 +553,7 @@ typedef struct st_my_pthread_fastmutex_t
{ {
pthread_mutex_t mutex; pthread_mutex_t mutex;
uint spins; uint spins;
uint rng_state;
} my_pthread_fastmutex_t; } my_pthread_fastmutex_t;
void fastmutex_global_init(void); void fastmutex_global_init(void);
@@ -692,6 +713,8 @@ struct st_my_thread_var
struct st_my_thread_var *next,**prev; struct st_my_thread_var *next,**prev;
void *opt_info; void *opt_info;
uint lock_type; /* used by conditional release the queue */ uint lock_type; /* used by conditional release the queue */
void *stack_ends_here;
safe_mutex_t *mutex_in_use;
#ifndef DBUG_OFF #ifndef DBUG_OFF
void *dbug; void *dbug;
char name[THREAD_NAME_SIZE+1]; char name[THREAD_NAME_SIZE+1];
@@ -700,7 +723,9 @@ struct st_my_thread_var
extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const)); extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
extern void **my_thread_var_dbug(); extern void **my_thread_var_dbug();
extern safe_mutex_t **my_thread_var_mutex_in_use();
extern uint my_thread_end_wait_time; extern uint my_thread_end_wait_time;
extern my_bool safe_mutex_deadlock_detector;
#define my_thread_var (_my_thread_var()) #define my_thread_var (_my_thread_var())
#define my_errno my_thread_var->thr_errno #define my_errno my_thread_var->thr_errno
/* /*

66
include/my_stacktrace.h Normal file
View File

@@ -0,0 +1,66 @@
/* Copyright (C) 2000 MySQL AB
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; version 2 of the License.
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 */
#ifndef _my_stacktrace_h_
#define _my_stacktrace_h_
#include <my_global.h>
#ifdef TARGET_OS_LINUX
#if defined (__x86_64__) || defined (__i386__) || \
(defined(__alpha__) && defined(__GNUC__))
#define HAVE_STACKTRACE 1
#endif
#elif defined(__WIN__)
#define HAVE_STACKTRACE 1
#endif
#if HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
#undef HAVE_STACKTRACE
#define HAVE_STACKTRACE 1
#endif
#if !defined(__NETWARE__)
#define HAVE_WRITE_CORE
#endif
#if HAVE_BACKTRACE && HAVE_BACKTRACE_SYMBOLS && \
HAVE_CXXABI_H && HAVE_ABI_CXA_DEMANGLE && \
HAVE_WEAK_SYMBOL
#define BACKTRACE_DEMANGLE 1
#endif
C_MODE_START
#if defined(HAVE_STACKTRACE) || defined(HAVE_BACKTRACE)
void my_init_stacktrace();
void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack);
void my_safe_print_str(const char* name, const char* val, int max_len);
void my_write_core(int sig);
#if BACKTRACE_DEMANGLE
char *my_demangle(const char *mangled_name, int *status);
#endif
#ifdef __WIN__
void my_set_exception_pointers(EXCEPTION_POINTERS *ep);
#endif
#endif
#ifdef HAVE_WRITE_CORE
void my_write_core(int sig);
#endif
C_MODE_END
#endif /* _my_stacktrace_h_ */

View File

@@ -94,6 +94,9 @@ extern int NEAR my_errno; /* Last error in mysys */
#define ME_COLOUR3 ((3 << ME_HIGHBYTE)) #define ME_COLOUR3 ((3 << ME_HIGHBYTE))
#define ME_JUST_INFO 1024 /**< not error but just info */ #define ME_JUST_INFO 1024 /**< not error but just info */
#define ME_JUST_WARNING 2048 /**< not error but just warning */ #define ME_JUST_WARNING 2048 /**< not error but just warning */
#define ME_FATALERROR 4096 /* Fatal statement error */
#define ME_NO_WARNING_FOR_ERROR 8192 /* Don't push a warning for error */
#define ME_NO_SP_HANDLER 16384 /* Don't call stored routine error handlers */
/* Bits in last argument to fn_format */ /* Bits in last argument to fn_format */
#define MY_REPLACE_DIR 1 /* replace dir in name with 'dir' */ #define MY_REPLACE_DIR 1 /* replace dir in name with 'dir' */
@@ -220,6 +223,9 @@ extern int (*fatal_error_handler_hook)(uint my_err, const char *str,
extern uint my_file_limit; extern uint my_file_limit;
extern ulong my_thread_stack_size; extern ulong my_thread_stack_size;
extern const char *(*proc_info_hook)(void *, const char *, const char *,
const char *, const unsigned int);
#ifdef HAVE_LARGE_PAGES #ifdef HAVE_LARGE_PAGES
extern my_bool my_use_large_pages; extern my_bool my_use_large_pages;
extern uint my_large_page_size; extern uint my_large_page_size;
@@ -248,7 +254,7 @@ extern int NEAR my_umask, /* Default creation mask */
NEAR my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */ NEAR my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */
NEAR my_dont_interrupt; /* call remember_intr when set */ NEAR my_dont_interrupt; /* call remember_intr when set */
extern my_bool NEAR mysys_uses_curses, my_use_symdir; extern my_bool NEAR mysys_uses_curses, my_use_symdir;
extern ulong sf_malloc_cur_memory, sf_malloc_max_memory; extern size_t sf_malloc_cur_memory, sf_malloc_max_memory;
extern ulong my_default_record_cache_size; extern ulong my_default_record_cache_size;
extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io, extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
@@ -586,6 +592,7 @@ extern int my_close(File Filedes,myf MyFlags);
extern File my_dup(File file, myf MyFlags); extern File my_dup(File file, myf MyFlags);
extern int my_mkdir(const char *dir, int Flags, myf MyFlags); extern int my_mkdir(const char *dir, int Flags, myf MyFlags);
extern int my_readlink(char *to, const char *filename, myf MyFlags); extern int my_readlink(char *to, const char *filename, myf MyFlags);
extern int my_is_symlink(const char *filename);
extern int my_realpath(char *to, const char *filename, myf MyFlags); extern int my_realpath(char *to, const char *filename, myf MyFlags);
extern File my_create_with_symlink(const char *linkname, const char *filename, extern File my_create_with_symlink(const char *linkname, const char *filename,
int createflags, int access_flags, int createflags, int access_flags,
@@ -705,6 +712,7 @@ extern char * fn_format(char * to,const char *name,const char *dir,
const char *form, uint flag); const char *form, uint flag);
extern size_t strlength(const char *str); extern size_t strlength(const char *str);
extern void pack_dirname(char * to,const char *from); extern void pack_dirname(char * to,const char *from);
extern size_t normalize_dirname(char * to, const char *from);
extern size_t unpack_dirname(char * to,const char *from); extern size_t unpack_dirname(char * to,const char *from);
extern size_t cleanup_dirname(char * to,const char *from); extern size_t cleanup_dirname(char * to,const char *from);
extern size_t system_filename(char * to,const char *from); extern size_t system_filename(char * to,const char *from);

View File

@@ -95,7 +95,7 @@ long calc_daynr(uint year,uint month,uint day);
uint calc_days_in_year(uint year); uint calc_days_in_year(uint year);
uint year_2000_handling(uint year); uint year_2000_handling(uint year);
void init_time(void); void my_init_time(void);
/* /*

View File

@@ -46,7 +46,6 @@ extern "C" {
#define MI_MAX_POSSIBLE_KEY_BUFF HA_MAX_POSSIBLE_KEY_BUFF #define MI_MAX_POSSIBLE_KEY_BUFF HA_MAX_POSSIBLE_KEY_BUFF
#define MI_MAX_MSG_BUF 1024 /* used in CHECK TABLE, REPAIR TABLE */
#define MI_NAME_IEXT ".MYI" #define MI_NAME_IEXT ".MYI"
#define MI_NAME_DEXT ".MYD" #define MI_NAME_DEXT ".MYD"
/* Max extra space to use when sorting keys */ /* Max extra space to use when sorting keys */
@@ -249,6 +248,10 @@ extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user;
extern my_off_t myisam_max_temp_length; extern my_off_t myisam_max_temp_length;
extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size; extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size;
/* usually used to check if a symlink points into the mysql data home */
/* which is normally forbidden */
extern int (*myisam_test_invalid_symlink)(const char *filename);
/* Prototypes for myisam-functions */ /* Prototypes for myisam-functions */
extern int mi_close(struct st_myisam_info *file); extern int mi_close(struct st_myisam_info *file);

View File

@@ -112,6 +112,7 @@ extern int myrg_reset(MYRG_INFO *info);
extern void myrg_extrafunc(MYRG_INFO *info,invalidator_by_filename inv); extern void myrg_extrafunc(MYRG_INFO *info,invalidator_by_filename inv);
extern ha_rows myrg_records_in_range(MYRG_INFO *info, int inx, extern ha_rows myrg_records_in_range(MYRG_INFO *info, int inx,
key_range *min_key, key_range *max_key); key_range *min_key, key_range *max_key);
extern ha_rows myrg_records(MYRG_INFO *info);
extern ulonglong myrg_position(MYRG_INFO *info); extern ulonglong myrg_position(MYRG_INFO *info);
#ifdef __cplusplus #ifdef __cplusplus

671
include/mysql.h.pp Normal file
View File

@@ -0,0 +1,671 @@
#include <sys/types.h>
typedef char my_bool;
typedef int my_socket;
#include "mysql_version.h"
#include "mysql_com.h"
enum enum_server_command
{
COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST,
COM_CREATE_DB, COM_DROP_DB, COM_REFRESH, COM_SHUTDOWN, COM_STATISTICS,
COM_PROCESS_INFO, COM_CONNECT, COM_PROCESS_KILL, COM_DEBUG, COM_PING,
COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP,
COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE,
COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA, COM_STMT_CLOSE,
COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON,
COM_END
};
struct st_vio;
typedef struct st_vio Vio;
typedef struct st_net {
Vio *vio;
unsigned char *buff,*buff_end,*write_pos,*read_pos;
my_socket fd;
unsigned long remain_in_buf,length, buf_length, where_b;
unsigned long max_packet,max_packet_size;
unsigned int pkt_nr,compress_pkt_nr;
unsigned int write_timeout, read_timeout, retry_count;
int fcntl;
unsigned int *return_status;
unsigned char reading_or_writing;
char save_char;
my_bool unused0;
my_bool unused;
my_bool compress;
my_bool unused1;
unsigned char *query_cache_query;
unsigned int last_errno;
unsigned char error;
my_bool unused2;
my_bool return_errno;
char last_error[512];
char sqlstate[5 +1];
void *extension;
} NET;
enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
MYSQL_TYPE_SHORT, MYSQL_TYPE_LONG,
MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE,
MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP,
MYSQL_TYPE_LONGLONG,MYSQL_TYPE_INT24,
MYSQL_TYPE_DATE, MYSQL_TYPE_TIME,
MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
MYSQL_TYPE_BIT,
MYSQL_TYPE_NEWDECIMAL=246,
MYSQL_TYPE_ENUM=247,
MYSQL_TYPE_SET=248,
MYSQL_TYPE_TINY_BLOB=249,
MYSQL_TYPE_MEDIUM_BLOB=250,
MYSQL_TYPE_LONG_BLOB=251,
MYSQL_TYPE_BLOB=252,
MYSQL_TYPE_VAR_STRING=253,
MYSQL_TYPE_STRING=254,
MYSQL_TYPE_GEOMETRY=255
};
enum mysql_enum_shutdown_level {
SHUTDOWN_DEFAULT = 0,
SHUTDOWN_WAIT_CONNECTIONS= (unsigned char)(1 << 0),
SHUTDOWN_WAIT_TRANSACTIONS= (unsigned char)(1 << 1),
SHUTDOWN_WAIT_UPDATES= (unsigned char)(1 << 3),
SHUTDOWN_WAIT_ALL_BUFFERS= ((unsigned char)(1 << 3) << 1),
SHUTDOWN_WAIT_CRITICAL_BUFFERS= ((unsigned char)(1 << 3) << 1) + 1,
KILL_QUERY= 254,
KILL_CONNECTION= 255
};
enum enum_cursor_type
{
CURSOR_TYPE_NO_CURSOR= 0,
CURSOR_TYPE_READ_ONLY= 1,
CURSOR_TYPE_FOR_UPDATE= 2,
CURSOR_TYPE_SCROLLABLE= 4
};
enum enum_mysql_set_option
{
MYSQL_OPTION_MULTI_STATEMENTS_ON,
MYSQL_OPTION_MULTI_STATEMENTS_OFF
};
my_bool my_net_init(NET *net, Vio* vio);
void my_net_local_init(NET *net);
void net_end(NET *net);
void net_clear(NET *net, my_bool clear_buffer);
my_bool net_realloc(NET *net, size_t length);
my_bool net_flush(NET *net);
my_bool my_net_write(NET *net,const unsigned char *packet, size_t len);
my_bool net_write_command(NET *net,unsigned char command,
const unsigned char *header, size_t head_len,
const unsigned char *packet, size_t len);
int net_real_write(NET *net,const unsigned char *packet, size_t len);
unsigned long my_net_read(NET *net);
struct sockaddr;
int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen,
unsigned int timeout);
struct my_rnd_struct;
enum Item_result
{
STRING_RESULT=0, REAL_RESULT, INT_RESULT, ROW_RESULT, DECIMAL_RESULT
};
typedef struct st_udf_args
{
unsigned int arg_count;
enum Item_result *arg_type;
char **args;
unsigned long *lengths;
char *maybe_null;
char **attributes;
unsigned long *attribute_lengths;
void *extension;
} UDF_ARGS;
typedef struct st_udf_init
{
my_bool maybe_null;
unsigned int decimals;
unsigned long max_length;
char *ptr;
my_bool const_item;
void *extension;
} UDF_INIT;
void create_random_string(char *to, unsigned int length,
struct my_rnd_struct *rand_st);
void hash_password(unsigned long *to, const char *password, unsigned int password_len);
void make_scrambled_password_323(char *to, const char *password);
void scramble_323(char *to, const char *message, const char *password);
my_bool check_scramble_323(const char *, const char *message,
unsigned long *salt);
void get_salt_from_password_323(unsigned long *res, const char *password);
void make_password_from_salt_323(char *to, const unsigned long *salt);
void make_scrambled_password(char *to, const char *password);
void scramble(char *to, const char *message, const char *password);
my_bool check_scramble(const char *reply, const char *message,
const unsigned char *hash_stage2);
void get_salt_from_password(unsigned char *res, const char *password);
void make_password_from_salt(char *to, const unsigned char *hash_stage2);
char *octet2hex(char *to, const char *str, unsigned int len);
char *get_tty_password(const char *opt_message);
const char *mysql_errno_to_sqlstate(unsigned int mysql_errno);
my_bool my_thread_init(void);
void my_thread_end(void);
#include "mysql_time.h"
enum enum_mysql_timestamp_type
{
MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
MYSQL_TIMESTAMP_DATE= 0, MYSQL_TIMESTAMP_DATETIME= 1, MYSQL_TIMESTAMP_TIME= 2
};
typedef struct st_mysql_time
{
unsigned int year, month, day, hour, minute, second;
unsigned long second_part;
my_bool neg;
enum enum_mysql_timestamp_type time_type;
} MYSQL_TIME;
#include "my_list.h"
typedef struct st_list {
struct st_list *prev,*next;
void *data;
} LIST;
typedef int (*list_walk_action)(void *,void *);
extern LIST *list_add(LIST *root,LIST *element);
extern LIST *list_delete(LIST *root,LIST *element);
extern LIST *list_cons(void *data,LIST *root);
extern LIST *list_reverse(LIST *root);
extern void list_free(LIST *root,unsigned int free_data);
extern unsigned int list_length(LIST *);
extern int list_walk(LIST *,list_walk_action action,unsigned char * argument);
extern unsigned int mysql_port;
extern char *mysql_unix_port;
typedef struct st_mysql_field {
char *name;
char *org_name;
char *table;
char *org_table;
char *db;
char *catalog;
char *def;
unsigned long length;
unsigned long max_length;
unsigned int name_length;
unsigned int org_name_length;
unsigned int table_length;
unsigned int org_table_length;
unsigned int db_length;
unsigned int catalog_length;
unsigned int def_length;
unsigned int flags;
unsigned int decimals;
unsigned int charsetnr;
enum enum_field_types type;
void *extension;
} MYSQL_FIELD;
typedef char **MYSQL_ROW;
typedef unsigned int MYSQL_FIELD_OFFSET;
typedef unsigned long long my_ulonglong;
#include "typelib.h"
#include "my_alloc.h"
typedef struct st_used_mem
{
struct st_used_mem *next;
size_t left;
size_t size;
} USED_MEM;
typedef struct st_mem_root
{
USED_MEM *free;
USED_MEM *used;
USED_MEM *pre_alloc;
size_t min_malloc;
size_t block_size;
unsigned int block_num;
unsigned int first_block_usage;
void (*error_handler)(void);
} MEM_ROOT;
typedef struct st_typelib {
unsigned int count;
const char *name;
const char **type_names;
unsigned int *type_lengths;
} TYPELIB;
extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
extern int find_type_or_exit(const char *x, TYPELIB *typelib,
const char *option);
extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name);
extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
extern const char *get_type(TYPELIB *typelib,unsigned int nr);
extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
extern TYPELIB sql_protocol_typelib;
typedef struct st_mysql_rows {
struct st_mysql_rows *next;
MYSQL_ROW data;
unsigned long length;
} MYSQL_ROWS;
typedef MYSQL_ROWS *MYSQL_ROW_OFFSET;
#include "my_alloc.h"
typedef struct embedded_query_result EMBEDDED_QUERY_RESULT;
typedef struct st_mysql_data {
MYSQL_ROWS *data;
struct embedded_query_result *embedded_info;
MEM_ROOT alloc;
my_ulonglong rows;
unsigned int fields;
void *extension;
} MYSQL_DATA;
enum mysql_option
{
MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE,
MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE,
MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
MYSQL_OPT_SSL_VERIFY_SERVER_CERT
};
struct st_mysql_options {
unsigned int connect_timeout, read_timeout, write_timeout;
unsigned int port, protocol;
unsigned long client_flag;
char *host,*user,*password,*unix_socket,*db;
struct st_dynamic_array *init_commands;
char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name;
char *ssl_key;
char *ssl_cert;
char *ssl_ca;
char *ssl_capath;
char *ssl_cipher;
char *shared_memory_base_name;
unsigned long max_allowed_packet;
my_bool use_ssl;
my_bool compress,named_pipe;
my_bool rpl_probe;
my_bool rpl_parse;
my_bool no_master_reads;
my_bool separate_thread;
enum mysql_option methods_to_use;
char *client_ip;
my_bool secure_auth;
my_bool report_data_truncation;
int (*local_infile_init)(void **, const char *, void *);
int (*local_infile_read)(void *, char *, unsigned int);
void (*local_infile_end)(void *);
int (*local_infile_error)(void *, char *, unsigned int);
void *local_infile_userdata;
void *extension;
};
enum mysql_status
{
MYSQL_STATUS_READY,MYSQL_STATUS_GET_RESULT,MYSQL_STATUS_USE_RESULT
};
enum mysql_protocol_type
{
MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET,
MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY
};
enum mysql_rpl_type
{
MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN
};
typedef struct character_set
{
unsigned int number;
unsigned int state;
const char *csname;
const char *name;
const char *comment;
const char *dir;
unsigned int mbminlen;
unsigned int mbmaxlen;
} MY_CHARSET_INFO;
struct st_mysql_methods;
struct st_mysql_stmt;
typedef struct st_mysql
{
NET net;
unsigned char *connector_fd;
char *host,*user,*passwd,*unix_socket,*server_version,*host_info;
char *info, *db;
struct charset_info_st *charset;
MYSQL_FIELD *fields;
MEM_ROOT field_alloc;
my_ulonglong affected_rows;
my_ulonglong insert_id;
my_ulonglong extra_info;
unsigned long thread_id;
unsigned long packet_length;
unsigned int port;
unsigned long client_flag,server_capabilities;
unsigned int protocol_version;
unsigned int field_count;
unsigned int server_status;
unsigned int server_language;
unsigned int warning_count;
struct st_mysql_options options;
enum mysql_status status;
my_bool free_me;
my_bool reconnect;
char scramble[20 +1];
my_bool rpl_pivot;
struct st_mysql* master, *next_slave;
struct st_mysql* last_used_slave;
struct st_mysql* last_used_con;
LIST *stmts;
const struct st_mysql_methods *methods;
void *thd;
my_bool *unbuffered_fetch_owner;
char *info_buffer;
void *extension;
} MYSQL;
typedef struct st_mysql_res {
my_ulonglong row_count;
MYSQL_FIELD *fields;
MYSQL_DATA *data;
MYSQL_ROWS *data_cursor;
unsigned long *lengths;
MYSQL *handle;
const struct st_mysql_methods *methods;
MYSQL_ROW row;
MYSQL_ROW current_row;
MEM_ROOT field_alloc;
unsigned int field_count, current_field;
my_bool eof;
my_bool unbuffered_fetch_cancelled;
void *extension;
} MYSQL_RES;
typedef struct st_mysql_manager
{
NET net;
char *host, *user, *passwd;
char *net_buf, *net_buf_pos, *net_data_end;
unsigned int port;
int cmd_status;
int last_errno;
int net_buf_size;
my_bool free_me;
my_bool eof;
char last_error[256];
void *extension;
} MYSQL_MANAGER;
typedef struct st_mysql_parameters
{
unsigned long *p_max_allowed_packet;
unsigned long *p_net_buffer_length;
void *extension;
} MYSQL_PARAMETERS;
int mysql_server_init(int argc, char **argv, char **groups);
void mysql_server_end(void);
MYSQL_PARAMETERS * mysql_get_parameters(void);
my_bool mysql_thread_init(void);
void mysql_thread_end(void);
my_ulonglong mysql_num_rows(MYSQL_RES *res);
unsigned int mysql_num_fields(MYSQL_RES *res);
my_bool mysql_eof(MYSQL_RES *res);
MYSQL_FIELD * mysql_fetch_field_direct(MYSQL_RES *res,
unsigned int fieldnr);
MYSQL_FIELD * mysql_fetch_fields(MYSQL_RES *res);
MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *res);
MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *res);
unsigned int mysql_field_count(MYSQL *mysql);
my_ulonglong mysql_affected_rows(MYSQL *mysql);
my_ulonglong mysql_insert_id(MYSQL *mysql);
unsigned int mysql_errno(MYSQL *mysql);
const char * mysql_error(MYSQL *mysql);
const char * mysql_sqlstate(MYSQL *mysql);
unsigned int mysql_warning_count(MYSQL *mysql);
const char * mysql_info(MYSQL *mysql);
unsigned long mysql_thread_id(MYSQL *mysql);
const char * mysql_character_set_name(MYSQL *mysql);
int mysql_set_character_set(MYSQL *mysql, const char *csname);
MYSQL * mysql_init(MYSQL *mysql);
my_bool mysql_ssl_set(MYSQL *mysql, const char *key,
const char *cert, const char *ca,
const char *capath, const char *cipher);
const char * mysql_get_ssl_cipher(MYSQL *mysql);
my_bool mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db);
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 long clientflag);
int mysql_select_db(MYSQL *mysql, const char *db);
int mysql_query(MYSQL *mysql, const char *q);
int mysql_send_query(MYSQL *mysql, const char *q,
unsigned long length);
int mysql_real_query(MYSQL *mysql, const char *q,
unsigned long length);
MYSQL_RES * mysql_store_result(MYSQL *mysql);
MYSQL_RES * mysql_use_result(MYSQL *mysql);
my_bool mysql_master_query(MYSQL *mysql, const char *q,
unsigned long length);
my_bool mysql_master_send_query(MYSQL *mysql, const char *q,
unsigned long length);
my_bool mysql_slave_query(MYSQL *mysql, const char *q,
unsigned long length);
my_bool mysql_slave_send_query(MYSQL *mysql, const char *q,
unsigned long length);
void mysql_get_character_set_info(MYSQL *mysql,
MY_CHARSET_INFO *charset);
void
mysql_set_local_infile_handler(MYSQL *mysql,
int (*local_infile_init)(void **, const char *,
void *),
int (*local_infile_read)(void *, char *,
unsigned int),
void (*local_infile_end)(void *),
int (*local_infile_error)(void *, char*,
unsigned int),
void *);
void
mysql_set_local_infile_default(MYSQL *mysql);
void mysql_enable_rpl_parse(MYSQL* mysql);
void mysql_disable_rpl_parse(MYSQL* mysql);
int mysql_rpl_parse_enabled(MYSQL* mysql);
void mysql_enable_reads_from_master(MYSQL* mysql);
void mysql_disable_reads_from_master(MYSQL* mysql);
my_bool mysql_reads_from_master_enabled(MYSQL* mysql);
enum mysql_rpl_type mysql_rpl_query_type(const char* q, int len);
my_bool mysql_rpl_probe(MYSQL* mysql);
int mysql_set_master(MYSQL* mysql, const char* host,
unsigned int port,
const char* user,
const char* passwd);
int mysql_add_slave(MYSQL* mysql, const char* host,
unsigned int port,
const char* user,
const char* passwd);
int mysql_shutdown(MYSQL *mysql,
enum mysql_enum_shutdown_level
shutdown_level);
int mysql_dump_debug_info(MYSQL *mysql);
int mysql_refresh(MYSQL *mysql,
unsigned int refresh_options);
int mysql_kill(MYSQL *mysql,unsigned long pid);
int mysql_set_server_option(MYSQL *mysql,
enum enum_mysql_set_option
option);
int mysql_ping(MYSQL *mysql);
const char * mysql_stat(MYSQL *mysql);
const char * mysql_get_server_info(MYSQL *mysql);
const char * mysql_get_client_info(void);
unsigned long mysql_get_client_version(void);
const char * mysql_get_host_info(MYSQL *mysql);
unsigned long mysql_get_server_version(MYSQL *mysql);
unsigned int mysql_get_proto_info(MYSQL *mysql);
MYSQL_RES * mysql_list_dbs(MYSQL *mysql,const char *wild);
MYSQL_RES * mysql_list_tables(MYSQL *mysql,const char *wild);
MYSQL_RES * mysql_list_processes(MYSQL *mysql);
int mysql_options(MYSQL *mysql,enum mysql_option option,
const void *arg);
void mysql_free_result(MYSQL_RES *result);
void mysql_data_seek(MYSQL_RES *result,
my_ulonglong offset);
MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result,
MYSQL_ROW_OFFSET offset);
MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result,
MYSQL_FIELD_OFFSET offset);
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
unsigned long * mysql_fetch_lengths(MYSQL_RES *result);
MYSQL_FIELD * mysql_fetch_field(MYSQL_RES *result);
MYSQL_RES * mysql_list_fields(MYSQL *mysql, const char *table,
const char *wild);
unsigned long mysql_escape_string(char *to,const char *from,
unsigned long from_length);
unsigned long mysql_hex_string(char *to,const char *from,
unsigned long from_length);
unsigned long mysql_real_escape_string(MYSQL *mysql,
char *to,const char *from,
unsigned long length);
void mysql_debug(const char *debug);
void myodbc_remove_escape(MYSQL *mysql,char *name);
unsigned int mysql_thread_safe(void);
my_bool mysql_embedded(void);
MYSQL_MANAGER* mysql_manager_init(MYSQL_MANAGER* con);
MYSQL_MANAGER* mysql_manager_connect(MYSQL_MANAGER* con,
const char* host,
const char* user,
const char* passwd,
unsigned int port);
void mysql_manager_close(MYSQL_MANAGER* con);
int mysql_manager_command(MYSQL_MANAGER* con,
const char* cmd, int cmd_len);
int mysql_manager_fetch_line(MYSQL_MANAGER* con,
char* res_buf,
int res_buf_size);
my_bool mysql_read_query_result(MYSQL *mysql);
enum enum_mysql_stmt_state
{
MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE,
MYSQL_STMT_FETCH_DONE
};
typedef struct st_mysql_bind
{
unsigned long *length;
my_bool *is_null;
void *buffer;
my_bool *error;
unsigned char *row_ptr;
void (*store_param_func)(NET *net, struct st_mysql_bind *param);
void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *,
unsigned char **row);
void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *,
unsigned char **row);
unsigned long buffer_length;
unsigned long offset;
unsigned long length_value;
unsigned int param_number;
unsigned int pack_length;
enum enum_field_types buffer_type;
my_bool error_value;
my_bool is_unsigned;
my_bool long_data_used;
my_bool is_null_value;
void *extension;
} MYSQL_BIND;
typedef struct st_mysql_stmt
{
MEM_ROOT mem_root;
LIST list;
MYSQL *mysql;
MYSQL_BIND *params;
MYSQL_BIND *bind;
MYSQL_FIELD *fields;
MYSQL_DATA result;
MYSQL_ROWS *data_cursor;
int (*read_row_func)(struct st_mysql_stmt *stmt,
unsigned char **row);
my_ulonglong affected_rows;
my_ulonglong insert_id;
unsigned long stmt_id;
unsigned long flags;
unsigned long prefetch_rows;
unsigned int server_status;
unsigned int last_errno;
unsigned int param_count;
unsigned int field_count;
enum enum_mysql_stmt_state state;
char last_error[512];
char sqlstate[5 +1];
my_bool send_types_to_server;
my_bool bind_param_done;
unsigned char bind_result_done;
my_bool unbuffered_fetch_cancelled;
my_bool update_max_length;
void *extension;
} MYSQL_STMT;
enum enum_stmt_attr_type
{
STMT_ATTR_UPDATE_MAX_LENGTH,
STMT_ATTR_CURSOR_TYPE,
STMT_ATTR_PREFETCH_ROWS
};
typedef struct st_mysql_methods
{
my_bool (*read_query_result)(MYSQL *mysql);
my_bool (*advanced_command)(MYSQL *mysql,
enum enum_server_command command,
const unsigned char *header,
unsigned long header_length,
const unsigned char *arg,
unsigned long arg_length,
my_bool skip_check,
MYSQL_STMT *stmt);
MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
unsigned int fields);
MYSQL_RES * (*use_result)(MYSQL *mysql);
void (*fetch_lengths)(unsigned long *to,
MYSQL_ROW column, unsigned int field_count);
void (*flush_use_result)(MYSQL *mysql);
MYSQL_FIELD * (*list_fields)(MYSQL *mysql);
my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt);
int (*stmt_execute)(MYSQL_STMT *stmt);
int (*read_binary_rows)(MYSQL_STMT *stmt);
int (*unbuffered_fetch)(MYSQL *mysql, char **row);
void (*free_embedded_thd)(MYSQL *mysql);
const char *(*read_statistics)(MYSQL *mysql);
my_bool (*next_result)(MYSQL *mysql);
int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
} MYSQL_METHODS;
MYSQL_STMT * mysql_stmt_init(MYSQL *mysql);
int mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query,
unsigned long length);
int mysql_stmt_execute(MYSQL_STMT *stmt);
int mysql_stmt_fetch(MYSQL_STMT *stmt);
int mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind_arg,
unsigned int column,
unsigned long offset);
int mysql_stmt_store_result(MYSQL_STMT *stmt);
unsigned long mysql_stmt_param_count(MYSQL_STMT * stmt);
my_bool mysql_stmt_attr_set(MYSQL_STMT *stmt,
enum enum_stmt_attr_type attr_type,
const void *attr);
my_bool mysql_stmt_attr_get(MYSQL_STMT *stmt,
enum enum_stmt_attr_type attr_type,
void *attr);
my_bool mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
my_bool mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd);
my_bool mysql_stmt_close(MYSQL_STMT * stmt);
my_bool mysql_stmt_reset(MYSQL_STMT * stmt);
my_bool mysql_stmt_free_result(MYSQL_STMT *stmt);
my_bool mysql_stmt_send_long_data(MYSQL_STMT *stmt,
unsigned int param_number,
const char *data,
unsigned long length);
MYSQL_RES * mysql_stmt_result_metadata(MYSQL_STMT *stmt);
MYSQL_RES * mysql_stmt_param_metadata(MYSQL_STMT *stmt);
unsigned int mysql_stmt_errno(MYSQL_STMT * stmt);
const char * mysql_stmt_error(MYSQL_STMT * stmt);
const char * mysql_stmt_sqlstate(MYSQL_STMT * stmt);
MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT *stmt,
MYSQL_ROW_OFFSET offset);
MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT *stmt);
void mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset);
my_ulonglong mysql_stmt_num_rows(MYSQL_STMT *stmt);
my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT *stmt);
my_ulonglong mysql_stmt_insert_id(MYSQL_STMT *stmt);
unsigned int mysql_stmt_field_count(MYSQL_STMT *stmt);
my_bool mysql_commit(MYSQL * mysql);
my_bool mysql_rollback(MYSQL * mysql);
my_bool mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
my_bool mysql_more_results(MYSQL *mysql);
int mysql_next_result(MYSQL *mysql);
void mysql_close(MYSQL *sock);

140
include/mysql/plugin.h.pp Normal file
View File

@@ -0,0 +1,140 @@
struct st_mysql_lex_string
{
char *str;
unsigned int length;
};
typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
struct st_mysql_xid {
long formatID;
long gtrid_length;
long bqual_length;
char data[128];
};
typedef struct st_mysql_xid MYSQL_XID;
enum enum_mysql_show_type
{
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE
};
struct st_mysql_show_var {
const char *name;
char *value;
enum enum_mysql_show_type type;
};
typedef int (*mysql_show_var_func)(void*, struct st_mysql_show_var*, char *);
struct st_mysql_sys_var;
struct st_mysql_value;
typedef int (*mysql_var_check_func)(void* thd,
struct st_mysql_sys_var *var,
void *save, struct st_mysql_value *value);
typedef void (*mysql_var_update_func)(void* thd,
struct st_mysql_sys_var *var,
void *var_ptr, const void *save);
struct st_mysql_plugin
{
int type;
void *info;
const char *name;
const char *author;
const char *descr;
int license;
int (*init)(void *);
int (*deinit)(void *);
unsigned int version;
struct st_mysql_show_var *status_vars;
struct st_mysql_sys_var **system_vars;
void * __reserved1;
};
enum enum_ftparser_mode
{
MYSQL_FTPARSER_SIMPLE_MODE= 0,
MYSQL_FTPARSER_WITH_STOPWORDS= 1,
MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
};
enum enum_ft_token_type
{
FT_TOKEN_EOF= 0,
FT_TOKEN_WORD= 1,
FT_TOKEN_LEFT_PAREN= 2,
FT_TOKEN_RIGHT_PAREN= 3,
FT_TOKEN_STOPWORD= 4
};
typedef struct st_mysql_ftparser_boolean_info
{
enum enum_ft_token_type type;
int yesno;
int weight_adjust;
char wasign;
char trunc;
char prev;
char *quot;
} MYSQL_FTPARSER_BOOLEAN_INFO;
typedef struct st_mysql_ftparser_param
{
int (*mysql_parse)(struct st_mysql_ftparser_param *,
char *doc, int doc_len);
int (*mysql_add_word)(struct st_mysql_ftparser_param *,
char *word, int word_len,
MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
void *ftparser_state;
void *mysql_ftparam;
struct charset_info_st *cs;
char *doc;
int length;
int flags;
enum enum_ftparser_mode mode;
} MYSQL_FTPARSER_PARAM;
struct st_mysql_ftparser
{
int interface_version;
int (*parse)(MYSQL_FTPARSER_PARAM *param);
int (*init)(MYSQL_FTPARSER_PARAM *param);
int (*deinit)(MYSQL_FTPARSER_PARAM *param);
};
struct st_mysql_storage_engine
{
int interface_version;
};
struct handlerton;
struct st_mysql_daemon
{
int interface_version;
};
struct st_mysql_information_schema
{
int interface_version;
};
struct st_mysql_value
{
int (*value_type)(struct st_mysql_value *);
const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
int (*val_real)(struct st_mysql_value *, double *realbuf);
int (*val_int)(struct st_mysql_value *, long long *intbuf);
};
int thd_in_lock_tables(const void* thd);
int thd_tablespace_op(const void* thd);
long long thd_test_options(const void* thd, long long test_options);
int thd_sql_command(const void* thd);
void **thd_ha_data(const void* thd, const struct handlerton *hton);
int thd_tx_isolation(const void* thd);
char *thd_security_context(void* thd, char *buffer, unsigned int length,
unsigned int max_query_len);
void thd_inc_row_count(void* thd);
const char *set_thd_proc_info(void*, const char * info, const char *func,
const char *file, const unsigned int line);
int mysql_tmpfile(const char *prefix);
int thd_killed(const void* thd);
unsigned long thd_get_thread_id(const void* thd);
void *thd_alloc(void* thd, unsigned int size);
void *thd_calloc(void* thd, unsigned int size);
char *thd_strdup(void* thd, const char *str);
char *thd_strmake(void* thd, const char *str, unsigned int size);
void *thd_memdup(void* thd, const void* str, unsigned int size);
MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
const char *str, unsigned int size,
int allocate_lex_string);
void thd_get_xid(const void* thd, MYSQL_XID *xid);
void mysql_query_cache_invalidate4(void* thd,
const char *key, unsigned int key_length,
int using_trx);

View File

@@ -184,19 +184,38 @@ enum enum_server_command
#define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */ #define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */
#define SERVER_QUERY_NO_GOOD_INDEX_USED 16 #define SERVER_QUERY_NO_GOOD_INDEX_USED 16
#define SERVER_QUERY_NO_INDEX_USED 32 #define SERVER_QUERY_NO_INDEX_USED 32
/* /**
The server was able to fulfill the clients request and opened a The server was able to fulfill the clients request and opened a
read-only non-scrollable cursor for a query. This flag comes read-only non-scrollable cursor for a query. This flag comes
in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands. in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands.
*/ */
#define SERVER_STATUS_CURSOR_EXISTS 64 #define SERVER_STATUS_CURSOR_EXISTS 64
/* /**
This flag is sent when a read-only cursor is exhausted, in reply to This flag is sent when a read-only cursor is exhausted, in reply to
COM_STMT_FETCH command. COM_STMT_FETCH command.
*/ */
#define SERVER_STATUS_LAST_ROW_SENT 128 #define SERVER_STATUS_LAST_ROW_SENT 128
#define SERVER_STATUS_DB_DROPPED 256 /* A database was dropped */ #define SERVER_STATUS_DB_DROPPED 256 /* A database was dropped */
#define SERVER_STATUS_NO_BACKSLASH_ESCAPES 512 #define SERVER_STATUS_NO_BACKSLASH_ESCAPES 512
/**
Sent to the client if after a prepared statement reprepare
we discovered that the new statement returns a different
number of result set columns.
*/
#define SERVER_STATUS_METADATA_CHANGED 1024
/**
Server status flags that must be cleared when starting
execution of a new SQL statement.
Flags from this set are only added to the
current server status by the execution engine, but
never removed -- the execution engine expects them
to disappear automagically by the next command.
*/
#define SERVER_STATUS_CLEAR_SET (SERVER_QUERY_NO_GOOD_INDEX_USED| \
SERVER_QUERY_NO_INDEX_USED|\
SERVER_MORE_RESULTS_EXISTS|\
SERVER_STATUS_METADATA_CHANGED)
#define MYSQL_ERRMSG_SIZE 512 #define MYSQL_ERRMSG_SIZE 512
#define NET_READ_TIMEOUT 30 /* Timeout on read */ #define NET_READ_TIMEOUT 30 /* Timeout on read */
@@ -205,6 +224,7 @@ enum enum_server_command
#define ONLY_KILL_QUERY 1 #define ONLY_KILL_QUERY 1
struct st_vio; /* Only C */ struct st_vio; /* Only C */
typedef struct st_vio Vio; typedef struct st_vio Vio;

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,14 @@ extern ulong locks_immediate,locks_waited ;
enum thr_lock_type { TL_IGNORE=-1, enum thr_lock_type { TL_IGNORE=-1,
TL_UNLOCK, /* UNLOCK ANY LOCK */ TL_UNLOCK, /* UNLOCK ANY LOCK */
/*
Parser only! At open_tables() becomes TL_READ or
TL_READ_NO_INSERT depending on the binary log format
(SBR/RBR) and on the table category (log table).
Used for tables that are read by statements which
modify tables.
*/
TL_READ_DEFAULT,
TL_READ, /* Read lock */ TL_READ, /* Read lock */
TL_READ_WITH_SHARED_LOCKS, TL_READ_WITH_SHARED_LOCKS,
/* High prior. than TL_WRITE. Allow concurrent insert */ /* High prior. than TL_WRITE. Allow concurrent insert */

202
include/waiting_threads.h Normal file
View File

@@ -0,0 +1,202 @@
/* Copyright (C) 2008 MySQL AB
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; version 2 of the License.
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 */
#ifndef _waiting_threads_h
#define _waiting_threads_h
#include <my_global.h>
#include <my_sys.h>
#include <lf.h>
C_MODE_START
typedef struct st_wt_resource_id WT_RESOURCE_ID;
typedef struct st_wt_resource_type {
int (*compare)(void *a, void *b);
const void *(*make_key)(WT_RESOURCE_ID *id, uint *len);
} WT_RESOURCE_TYPE;
struct st_wt_resource_id {
ulonglong value;
WT_RESOURCE_TYPE *type;
};
#define sizeof_WT_RESOURCE_ID (sizeof(ulonglong)+sizeof(void*))
#define WT_WAIT_STATS 24
#define WT_CYCLE_STATS 32
extern ulonglong wt_wait_table[WT_WAIT_STATS];
extern uint32 wt_wait_stats[WT_WAIT_STATS+1];
extern uint32 wt_cycle_stats[2][WT_CYCLE_STATS+1];
extern uint32 wt_success_stats;
/*
'lock' protects 'owners', 'state', and 'waiter_count'
'id' is read-only
a resource is picked up from a hash in a lock-free manner
it's returned pinned, so it cannot be freed at once
but it may be freed right after the pin is removed
to free a resource it should be
1. have no owners
2. have no waiters
two ways to access a resource:
1. find it in a hash
- it's returned pinned.
a) take a lock in exclusive mode
b) check the state, it should be ACTIVE
c) unpin
2. by a direct reference
- could only used if a resource cannot be freed
e.g. accessing a resource by thd->waiting_for is safe,
a resource cannot be freed as there's a thread waiting for it
*/
typedef struct st_wt_resource {
WT_RESOURCE_ID id;
uint waiter_count;
enum { ACTIVE, FREE } state;
#ifndef DBUG_OFF
pthread_mutex_t *mutex;
#endif
/*
before the 'lock' all elements are mutable, after (and including) -
immutable in the sense that lf_hash_insert() won't memcpy() over them.
See wt_init().
*/
#ifdef WT_RWLOCKS_USE_MUTEXES
/*
we need a special rwlock-like 'lock' to allow readers bypass
waiting writers, otherwise readers can deadlock. For example:
A waits on resource x, owned by B, B waits on resource y, owned
by A, we have a cycle (A->x->B->y->A)
Both A and B start deadlock detection:
A locks x B locks y
A goes deeper B goes deeper
A locks y B locks x
with mutexes it would deadlock. With rwlocks it won't, as long
as both A and B are taking read locks (and they do).
But other threads may take write locks. Assume there's
C who wants to start waiting on x, and D who wants to start
waiting on y.
A read-locks x B read-locks y
A goes deeper B goes deeper
=> C write-locks x (to add a new edge) D write-locks y
.. C is blocked D is blocked
A read-locks y B read-locks x
Now, if a read lock can bypass a pending wrote lock request, we're fine.
If it can not, we have a deadlock.
writer starvation is technically possible, but unlikely, because
the contention is expected to be low.
*/
struct {
pthread_cond_t cond;
pthread_mutex_t mutex;
uint readers: 16;
uint pending_writers: 15;
uint write_locked: 1;
} lock;
#else
rw_lock_t lock;
#endif
pthread_cond_t cond;
DYNAMIC_ARRAY owners;
} WT_RESOURCE;
typedef struct st_wt_thd {
/*
XXX
there's no protection (mutex) against concurrent access of
the dynarray below. it is assumed that a caller will have it
automatically (not to protect this array but to protect its
own - caller's - data structures, and we'll get it for free.
If not, we'll need to add a mutex
*/
DYNAMIC_ARRAY my_resources;
/*
'waiting_for' is modified under waiting_for->lock, and only by thd itself
'waiting_for' is read lock-free (using pinning protocol), but a thd object
can read its own 'waiting_for' without any locks or tricks.
*/
WT_RESOURCE *waiting_for;
LF_PINS *pins;
/* pointers to values */
ulong *timeout_short, *deadlock_search_depth_short;
ulong *timeout_long, *deadlock_search_depth_long;
/*
weight relates to the desirability of a transaction being killed if it's
part of a deadlock. In a deadlock situation transactions with lower weights
are killed first.
Examples of using the weight to implement different selection strategies:
1. Latest
Keep all weights equal.
2. Random
Assight weights at random.
(variant: modify a weight randomly before every lock request)
3. Youngest
Set weight to -NOW()
4. Minimum locks
count locks granted in your lock manager, store the value as a weight
5. Minimum work
depends on the definition of "work". For example, store the number
of rows modifies in this transaction (or a length of REDO log for a
transaction) as a weight.
It is only statistically relevant and is not protected by any locks.
*/
ulong volatile weight;
/*
'killed' is indirectly protected by waiting_for->lock -
a killed thread needs to clear its 'waiting_for', and thus needs a lock.
That is a thread needs an exclusive lock to read 'killed' reliably.
But other threads may change 'killed' from 0 to 1, a shared
lock is enough for that.
*/
my_bool volatile killed;
#ifndef DBUG_OFF
const char *name;
#endif
} WT_THD;
#define WT_TIMEOUT ETIMEDOUT
#define WT_OK 0
#define WT_DEADLOCK -1
#define WT_DEPTH_EXCEEDED -2
#define WT_FREE_TO_GO -3
void wt_init(void);
void wt_end(void);
void wt_thd_lazy_init(WT_THD *, ulong *, ulong *, ulong *, ulong *);
void wt_thd_destroy(WT_THD *);
int wt_thd_will_wait_for(WT_THD *, WT_THD *, WT_RESOURCE_ID *);
int wt_thd_cond_timedwait(WT_THD *, pthread_mutex_t *);
void wt_thd_release(WT_THD *, WT_RESOURCE_ID *);
#define wt_thd_release_all(THD) wt_thd_release((THD), 0)
int wt_resource_id_memcmp(void *, void *);
C_MODE_END
#endif

View File

@@ -89,9 +89,20 @@ BOOL APIENTRY LibMain(HANDLE hInst,DWORD ul_reason_being_called,
UNREFERENCED_PARAMETER(lpReserved); UNREFERENCED_PARAMETER(lpReserved);
} /* LibMain */ } /* LibMain */
static BOOL do_libmain;
int __stdcall DllMain(HANDLE hInst,DWORD ul_reason_being_called,LPVOID lpReserved) int __stdcall DllMain(HANDLE hInst,DWORD ul_reason_being_called,LPVOID lpReserved)
{ {
return LibMain(hInst,ul_reason_being_called,lpReserved); /*
Unless environment variable LIBMYSQL_DLLINIT is set, do nothing.
The environment variable is checked once, during the first call to DllMain()
(in DLL_PROCESS_ATTACH hook).
*/
if (ul_reason_being_called == DLL_PROCESS_ATTACH)
do_libmain = (getenv("LIBMYSQL_DLLINIT") != NULL);
if (do_libmain)
return LibMain(hInst,ul_reason_being_called,lpReserved);
return TRUE;
} }
#elif defined(WINDOWS) #elif defined(WINDOWS)

View File

@@ -84,6 +84,7 @@ const char *client_errors[]=
"This feature is not implemented yet", "This feature is not implemented yet",
"Lost connection to MySQL server at '%s', system error: %d", "Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call", "Statement closed indirectly because of a preceeding %s() call",
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
"" ""
}; };
@@ -149,6 +150,7 @@ const char *client_errors[]=
"This feature is not implemented yet", "This feature is not implemented yet",
"Lost connection to MySQL server at '%s', system error: %d", "Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call", "Statement closed indirectly because of a preceeding %s() call",
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
"" ""
}; };
@@ -212,6 +214,7 @@ const char *client_errors[]=
"This feature is not implemented yet", "This feature is not implemented yet",
"Lost connection to MySQL server at '%s', system error: %d", "Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call", "Statement closed indirectly because of a preceeding %s() call",
"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again",
"" ""
}; };
#endif #endif

View File

@@ -207,9 +207,7 @@ void STDCALL mysql_server_end()
/* If library called my_init(), free memory allocated by it */ /* If library called my_init(), free memory allocated by it */
if (!org_my_init_done) if (!org_my_init_done)
{ {
my_end(MY_DONT_FREE_DBUG); my_end(0);
/* Remove TRACING, if enabled by mysql_debug() */
DBUG_POP();
} }
else else
{ {
@@ -1706,6 +1704,7 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *, MYSQL_FIELD *field);
#define RESET_SERVER_SIDE 1 #define RESET_SERVER_SIDE 1
#define RESET_LONG_DATA 2 #define RESET_LONG_DATA 2
#define RESET_STORE_RESULT 4 #define RESET_STORE_RESULT 4
#define RESET_CLEAR_ERROR 8
static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags); static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags);
@@ -2090,7 +2089,7 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
To be removed when all commands will fully support prepared mode. To be removed when all commands will fully support prepared mode.
*/ */
static unsigned int alloc_stmt_fields(MYSQL_STMT *stmt) static void alloc_stmt_fields(MYSQL_STMT *stmt)
{ {
MYSQL_FIELD *fields, *field, *end; MYSQL_FIELD *fields, *field, *end;
MEM_ROOT *alloc= &stmt->mem_root; MEM_ROOT *alloc= &stmt->mem_root;
@@ -2108,7 +2107,10 @@ static unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
!(stmt->bind= (MYSQL_BIND *) alloc_root(alloc, !(stmt->bind= (MYSQL_BIND *) alloc_root(alloc,
sizeof(MYSQL_BIND) * sizeof(MYSQL_BIND) *
stmt->field_count))) stmt->field_count)))
return 0; {
set_stmt_error(stmt, CR_OUT_OF_MEMORY, unknown_sqlstate, NULL);
return;
}
for (fields= mysql->fields, end= fields+stmt->field_count, for (fields= mysql->fields, end= fields+stmt->field_count,
field= stmt->fields; field= stmt->fields;
@@ -2127,13 +2129,15 @@ static unsigned int alloc_stmt_fields(MYSQL_STMT *stmt)
field->def = fields->def ? strdup_root(alloc,fields->def): 0; field->def = fields->def ? strdup_root(alloc,fields->def): 0;
field->max_length= 0; field->max_length= 0;
} }
return stmt->field_count;
} }
/* /**
Update result set columns metadata if it was sent again in Update result set columns metadata if it was sent again in
reply to COM_STMT_EXECUTE. reply to COM_STMT_EXECUTE.
@note If the new field count is different from the original one,
an error is set and no update is performed.
*/ */
static void update_stmt_fields(MYSQL_STMT *stmt) static void update_stmt_fields(MYSQL_STMT *stmt)
@@ -2143,7 +2147,22 @@ static void update_stmt_fields(MYSQL_STMT *stmt)
MYSQL_FIELD *stmt_field= stmt->fields; MYSQL_FIELD *stmt_field= stmt->fields;
MYSQL_BIND *my_bind= stmt->bind_result_done ? stmt->bind : 0; MYSQL_BIND *my_bind= stmt->bind_result_done ? stmt->bind : 0;
DBUG_ASSERT(stmt->field_count == stmt->mysql->field_count); if (stmt->field_count != stmt->mysql->field_count)
{
/*
The tables used in the statement were altered,
and the query now returns a different number of columns.
There is no way to continue without reallocating the bind
array:
- if the number of columns increased, mysql_stmt_fetch()
will write beyond allocated memory
- if the number of columns decreased, some user-bound
buffers will be left unassigned without user knowing
that.
*/
set_stmt_error(stmt, CR_NEW_STMT_METADATA, unknown_sqlstate, NULL);
return;
}
for (; field < field_end; ++field, ++stmt_field) for (; field < field_end; ++field, ++stmt_field)
{ {
@@ -2792,6 +2811,50 @@ my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt,
} }
/**
Update statement result set metadata from with the new field
information sent during statement execute.
@pre mysql->field_count is not zero
@retval TRUE if error: out of memory or the new
result set has a different number of columns
@retval FALSE success
*/
static void reinit_result_set_metadata(MYSQL_STMT *stmt)
{
/* Server has sent result set metadata */
if (stmt->field_count == 0)
{
/*
This is 'SHOW'/'EXPLAIN'-like query. Current implementation of
prepared statements can't send result set metadata for these queries
on prepare stage. Read it now.
*/
alloc_stmt_fields(stmt);
}
else
{
/*
Update result set metadata if it for some reason changed between
prepare and execute, i.e.:
- in case of 'SELECT ?' we don't know column type unless data was
supplied to mysql_stmt_execute, so updated column type is sent
now.
- if data dictionary changed between prepare and execute, for
example a table used in the query was altered.
Note, that now (4.1.3) we always send metadata in reply to
COM_STMT_EXECUTE (even if it is not necessary), so either this or
previous branch always works.
TODO: send metadata only when it's really necessary and add a warning
'Metadata changed' when it's sent twice.
*/
update_stmt_fields(stmt);
}
}
/* /*
Send placeholders data to server (if there are placeholders) Send placeholders data to server (if there are placeholders)
and execute prepared statement. and execute prepared statement.
@@ -2847,7 +2910,7 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (reset_stmt_handle(stmt, RESET_STORE_RESULT)) if (reset_stmt_handle(stmt, RESET_STORE_RESULT | RESET_CLEAR_ERROR))
DBUG_RETURN(1); DBUG_RETURN(1);
/* /*
No need to check for stmt->state: if the statement wasn't No need to check for stmt->state: if the statement wasn't
@@ -2855,40 +2918,10 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
*/ */
if (mysql->methods->stmt_execute(stmt)) if (mysql->methods->stmt_execute(stmt))
DBUG_RETURN(1); DBUG_RETURN(1);
stmt->state= MYSQL_STMT_EXECUTE_DONE;
if (mysql->field_count) if (mysql->field_count)
{ {
/* Server has sent result set metadata */ reinit_result_set_metadata(stmt);
if (stmt->field_count == 0)
{
/*
This is 'SHOW'/'EXPLAIN'-like query. Current implementation of
prepared statements can't send result set metadata for these queries
on prepare stage. Read it now.
*/
alloc_stmt_fields(stmt);
}
else
{
/*
Update result set metadata if it for some reason changed between
prepare and execute, i.e.:
- in case of 'SELECT ?' we don't know column type unless data was
supplied to mysql_stmt_execute, so updated column type is sent
now.
- if data dictionary changed between prepare and execute, for
example a table used in the query was altered.
Note, that now (4.1.3) we always send metadata in reply to
COM_STMT_EXECUTE (even if it is not necessary), so either this or
previous branch always works.
TODO: send metadata only when it's really necessary and add a warning
'Metadata changed' when it's sent twice.
*/
update_stmt_fields(stmt);
}
}
stmt->state= MYSQL_STMT_EXECUTE_DONE;
if (stmt->field_count)
{
if (stmt->server_status & SERVER_STATUS_CURSOR_EXISTS) if (stmt->server_status & SERVER_STATUS_CURSOR_EXISTS)
{ {
mysql->status= MYSQL_STATUS_READY; mysql->status= MYSQL_STATUS_READY;
@@ -2903,7 +2936,7 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
network or b) is more efficient if all (few) result set rows are network or b) is more efficient if all (few) result set rows are
precached on client and server's resources are freed. precached on client and server's resources are freed.
*/ */
DBUG_RETURN(mysql_stmt_store_result(stmt)); mysql_stmt_store_result(stmt);
} }
else else
{ {
@@ -2912,7 +2945,7 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
stmt->read_row_func= stmt_read_row_unbuffered; stmt->read_row_func= stmt_read_row_unbuffered;
} }
} }
DBUG_RETURN(0); DBUG_RETURN(test(stmt->last_errno));
} }
@@ -4765,6 +4798,12 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (stmt->last_errno)
{
/* An attempt to use an invalid statement handle. */
DBUG_RETURN(1);
}
if (mysql->status == MYSQL_STATUS_READY && if (mysql->status == MYSQL_STATUS_READY &&
stmt->server_status & SERVER_STATUS_CURSOR_EXISTS) stmt->server_status & SERVER_STATUS_CURSOR_EXISTS)
{ {
@@ -4972,9 +5011,10 @@ static my_bool reset_stmt_handle(MYSQL_STMT *stmt, uint flags)
stmt->state= MYSQL_STMT_INIT_DONE; stmt->state= MYSQL_STMT_INIT_DONE;
return 1; return 1;
} }
stmt_clear_error(stmt);
} }
} }
if (flags & RESET_CLEAR_ERROR)
stmt_clear_error(stmt);
stmt->state= MYSQL_STMT_PREPARE_DONE; stmt->state= MYSQL_STMT_PREPARE_DONE;
} }
return 0; return 0;
@@ -4985,7 +5025,8 @@ my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt)
DBUG_ENTER("mysql_stmt_free_result"); DBUG_ENTER("mysql_stmt_free_result");
/* Free the client side and close the server side cursor if there is one */ /* Free the client side and close the server side cursor if there is one */
DBUG_RETURN(reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT)); DBUG_RETURN(reset_stmt_handle(stmt, RESET_LONG_DATA | RESET_STORE_RESULT |
RESET_CLEAR_ERROR));
} }
/******************************************************************** /********************************************************************
@@ -5066,7 +5107,9 @@ my_bool STDCALL mysql_stmt_reset(MYSQL_STMT *stmt)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
/* Reset the client and server sides of the prepared statement */ /* Reset the client and server sides of the prepared statement */
DBUG_RETURN(reset_stmt_handle(stmt, RESET_SERVER_SIDE | RESET_LONG_DATA)); DBUG_RETURN(reset_stmt_handle(stmt,
RESET_SERVER_SIDE | RESET_LONG_DATA |
RESET_CLEAR_ERROR));
} }
/* /*

View File

@@ -154,14 +154,12 @@ ENDIF(WITH_MARIA_STORAGE_ENGINE)
SET(SOURCE_SUBLIBS FALSE) SET(SOURCE_SUBLIBS FALSE)
SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../libmysql/libmysql.c ../libmysql/errmsg.c ../client/get_password.c ../libmysql/libmysql.c ../libmysql/errmsg.c ../client/get_password.c
../sql-common/client.c ../sql-common/my_time.c ../sql-common/client.c ../sql-common/my_time.c
../sql-common/my_user.c ../sql-common/pack.c ../sql-common/my_user.c ../sql-common/pack.c
../sql/password.c ../sql/discover.cc ../sql/derror.cc ../sql/password.c ../sql/discover.cc ../sql/derror.cc
../sql/event_scheduler.cc ../sql/events.cc ../sql/field.cc ../sql/field_conv.cc
../sql/event_data_objects.cc ../sql/event_queue.cc
../sql/event_db_repository.cc ../sql/field.cc ../sql/field_conv.cc
../sql/filesort.cc ../sql/gstream.cc ../sql/ha_partition.cc ../sql/filesort.cc ../sql/gstream.cc ../sql/ha_partition.cc
../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc ../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc
../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc ../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc
@@ -194,7 +192,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc ../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc
../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc ../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
../sql/partition_info.cc ../sql/sql_connect.cc ../sql/partition_info.cc ../sql/sql_connect.cc
../sql/scheduler.cc ../sql/scheduler.cc ../sql/event_parse_data.cc
${GEN_SOURCES} ${GEN_SOURCES}
${LIB_SOURCES}) ${LIB_SOURCES})

View File

@@ -69,16 +69,14 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
sql_select.cc sql_do.cc sql_show.cc set_var.cc \ sql_select.cc sql_do.cc sql_show.cc set_var.cc \
sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \ sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
unireg.cc uniques.cc stacktrace.c sql_union.cc hash_filo.cc \ unireg.cc uniques.cc sql_union.cc hash_filo.cc \
spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \ spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \ sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
event_scheduler.cc events.cc event_data_objects.cc \
event_queue.cc event_db_repository.cc \
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \ rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
sql_tablespace.cc \ sql_tablespace.cc \
rpl_injector.cc my_user.c partition_info.cc \ rpl_injector.cc my_user.c partition_info.cc \
sql_servers.cc sql_servers.cc event_parse_data.cc
libmysqld_int_a_SOURCES= $(libmysqld_sources) libmysqld_int_a_SOURCES= $(libmysqld_sources)
nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources) nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources)

View File

@@ -447,7 +447,8 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
if (thd->protocol == &thd->protocol_binary) if (thd->protocol == &thd->protocol_binary)
{ {
uint length; uint length;
row= (MYSQL_ROWS *)alloc_root(&data->alloc, rows * sizeof(MYSQL_ROWS)); row= (MYSQL_ROWS *)alloc_root(&data->alloc,
(size_t) (rows * sizeof(MYSQL_ROWS)));
end_row= row + rows; end_row= row + rows;
data->data= row; data->data= row;

View File

@@ -29,13 +29,13 @@ ADD_DEFINITIONS(-DEMBEDDED_LIBRARY)
ADD_EXECUTABLE(mysql_embedded ../../client/completion_hash.cc ADD_EXECUTABLE(mysql_embedded ../../client/completion_hash.cc
../../client/mysql.cc ../../client/readline.cc ../../client/mysql.cc ../../client/readline.cc
../../client/sql_string.cc) ../../client/sql_string.cc)
TARGET_LINK_LIBRARIES(mysql_embedded mysys yassl taocrypt zlib debug dbug regex strings wsock32) TARGET_LINK_LIBRARIES(mysql_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32)
ADD_DEPENDENCIES(mysql_embedded libmysqld) ADD_DEPENDENCIES(mysql_embedded libmysqld)
ADD_EXECUTABLE(mysqltest_embedded ../../client/mysqltest.c) ADD_EXECUTABLE(mysqltest_embedded ../../client/mysqltest.c)
TARGET_LINK_LIBRARIES(mysqltest_embedded mysys yassl taocrypt zlib debug dbug regex strings wsock32) TARGET_LINK_LIBRARIES(mysqltest_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32)
ADD_DEPENDENCIES(mysqltest_embedded libmysqld) ADD_DEPENDENCIES(mysqltest_embedded libmysqld)
ADD_EXECUTABLE(mysql_client_test_embedded ../../tests/mysql_client_test.c) ADD_EXECUTABLE(mysql_client_test_embedded ../../tests/mysql_client_test.c)
TARGET_LINK_LIBRARIES(mysql_client_test_embedded debug dbug mysys yassl taocrypt zlib strings wsock32) TARGET_LINK_LIBRARIES(mysql_client_test_embedded debug dbug strings mysys vio yassl taocrypt regex ws2_32)
ADD_DEPENDENCIES(mysql_client_test_embedded libmysqld) ADD_DEPENDENCIES(mysql_client_test_embedded libmysqld)

View File

@@ -79,6 +79,15 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
my_bool result= 1; my_bool result= 1;
THD *thd=(THD *) mysql->thd; THD *thd=(THD *) mysql->thd;
NET *net= &mysql->net; NET *net= &mysql->net;
my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE;
if (!thd)
{
/* Do "reconnect" if possible */
if (mysql_reconnect(mysql) || stmt_skip)
return 1;
thd= (THD *) mysql->thd;
}
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER) #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
thd->profiling.start_new_query(); thd->profiling.start_new_query();
@@ -285,7 +294,7 @@ static int emb_stmt_execute(MYSQL_STMT *stmt)
my_bool res; my_bool res;
int4store(header, stmt->stmt_id); int4store(header, stmt->stmt_id);
header[4]= stmt->flags; header[4]= (uchar) stmt->flags;
thd= (THD*)stmt->mysql->thd; thd= (THD*)stmt->mysql->thd;
thd->client_param_count= stmt->param_count; thd->client_param_count= stmt->param_count;
thd->client_params= stmt->params; thd->client_params= stmt->params;
@@ -375,7 +384,9 @@ static void emb_free_embedded_thd(MYSQL *mysql)
thd->clear_data_list(); thd->clear_data_list();
thread_count--; thread_count--;
thd->store_globals(); thd->store_globals();
thd->unlink();
delete thd; delete thd;
my_pthread_setspecific_ptr(THR_THD, 0);
mysql->thd=0; mysql->thd=0;
} }
@@ -529,12 +540,7 @@ int init_embedded_server(int argc, char **argv, char **groups)
(void) thr_setconcurrency(concurrency); // 10 by default (void) thr_setconcurrency(concurrency); // 10 by default
if (flush_time && flush_time != ~(ulong) 0L) start_handle_manager();
{
pthread_t hThread;
if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
sql_print_error("Warning: Can't create thread to manage maintenance");
}
// FIXME initialize binlog_filter and rpl_filter if not already done // FIXME initialize binlog_filter and rpl_filter if not already done
// corresponding delete is in clean_up() // corresponding delete is in clean_up()
@@ -618,6 +624,7 @@ void *create_embedded_thd(int client_flag)
bzero((char*) &thd->net, sizeof(thd->net)); bzero((char*) &thd->net, sizeof(thd->net));
thread_count++; thread_count++;
threads.append(thd);
return thd; return thd;
err: err:
delete(thd); delete(thd);
@@ -848,7 +855,7 @@ void Protocol_text::remove_last_row()
{ {
MYSQL_DATA *data= thd->cur_data; MYSQL_DATA *data= thd->cur_data;
MYSQL_ROWS **last_row_hook= &data->data; MYSQL_ROWS **last_row_hook= &data->data;
uint count= data->rows; my_ulonglong count= data->rows;
DBUG_ENTER("Protocol_text::remove_last_row"); DBUG_ENTER("Protocol_text::remove_last_row");
while (--count) while (--count)
last_row_hook= &(*last_row_hook)->next; last_row_hook= &(*last_row_hook)->next;
@@ -1094,6 +1101,9 @@ void Protocol_text::prepare_for_resend()
data->embedded_info->prev_ptr= &cur->next; data->embedded_info->prev_ptr= &cur->next;
next_field=cur->data; next_field=cur->data;
next_mysql_field= data->embedded_info->fields_list; next_mysql_field= data->embedded_info->fields_list;
#ifndef DBUG_OFF
field_pos= 0;
#endif
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@@ -1124,6 +1134,9 @@ bool Protocol::net_store_data(const uchar *from, size_t length)
return FALSE; return FALSE;
} }
#if defined(_MSC_VER) && _MSC_VER < 1400
#define vsnprintf _vsnprintf
#endif
int vprint_msg_to_log(enum loglevel level __attribute__((unused)), int vprint_msg_to_log(enum loglevel level __attribute__((unused)),
const char *format, va_list argsi) const char *format, va_list argsi)

View File

@@ -2,34 +2,6 @@ LIBRARY LIBMYSQLD
DESCRIPTION 'MySQL 5.1 Embedded Server Library' DESCRIPTION 'MySQL 5.1 Embedded Server Library'
VERSION 5.1 VERSION 5.1
EXPORTS EXPORTS
_dig_vec_upper
_dig_vec_lower
bmove_upp
delete_dynamic
free_defaults
getopt_compare_strings
getopt_ull_limit_value
handle_options
init_dynamic_array
insert_dynamic
int2str
is_prefix
list_add
list_delete
load_defaults
max_allowed_packet
my_cgets
my_end
my_getopt_print_errors
my_init
my_malloc
my_memdup
my_no_flags_free
my_path
my_print_help
my_print_variables
my_realloc
my_strdup
mysql_thread_end mysql_thread_end
mysql_thread_init mysql_thread_init
myodbc_remove_escape myodbc_remove_escape
@@ -102,47 +74,13 @@ EXPORTS
mysql_thread_safe mysql_thread_safe
mysql_use_result mysql_use_result
mysql_warning_count mysql_warning_count
set_dynamic
strcend
strcont
strdup_root
strfill
strinstr
strmake
strmov
strxmov
mysql_server_end mysql_server_end
mysql_server_init mysql_server_init
get_tty_password get_tty_password
sql_protocol_typelib
mysql_get_server_version mysql_get_server_version
mysql_set_character_set mysql_set_character_set
mysql_sqlstate mysql_sqlstate
charsets_dir
disabled_my_option
my_charset_latin1
init_alloc_root
my_progname
get_charset_name
get_charset_by_csname
print_defaults
find_type
strxnmov
strend
my_fopen
my_fclose
unpack_filename
str2int
int10_to_str
longlong10_to_str
my_snprintf_8bit
alloc_root
free_root
my_read
llstr
mysql_get_parameters mysql_get_parameters
mysql_thread_init
mysql_thread_end
mysql_stmt_bind_param mysql_stmt_bind_param
mysql_stmt_bind_result mysql_stmt_bind_result
mysql_stmt_execute mysql_stmt_execute
@@ -170,7 +108,3 @@ EXPORTS
mysql_stmt_attr_get mysql_stmt_attr_get
mysql_stmt_attr_set mysql_stmt_attr_set
mysql_stmt_field_count mysql_stmt_field_count
get_defaults_options
my_charset_bin
my_charset_same
modify_defaults_file

View File

@@ -21,5 +21,9 @@ man1_MANS = @man1_files@
man8_MANS = @man8_files@ man8_MANS = @man8_files@
EXTRA_DIST = $(man1_MANS) $(man8_MANS) EXTRA_DIST = $(man1_MANS) $(man8_MANS)
# "make_win_*" are not needed in Unix binary packages,
install-data-hook:
rm -f $(DESTDIR)$(manlibdir)/man1/make_win_*
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%

View File

@@ -46,6 +46,7 @@ dist-hook:
$(distdir)/std_data/ndb_backup51_data_le \ $(distdir)/std_data/ndb_backup51_data_le \
$(distdir)/std_data/parts \ $(distdir)/std_data/parts \
$(distdir)/lib \ $(distdir)/lib \
$(distdir)/std_data/funcs_1 \
$(distdir)/lib/My $(distdir)/lib/My
-$(INSTALL_DATA) $(srcdir)/t/*.def $(distdir)/t -$(INSTALL_DATA) $(srcdir)/t/*.def $(distdir)/t
$(INSTALL_DATA) $(srcdir)/t/*.test $(distdir)/t $(INSTALL_DATA) $(srcdir)/t/*.test $(distdir)/t
@@ -70,11 +71,14 @@ dist-hook:
$(INSTALL_DATA) $(srcdir)/std_data/*.frm $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.frm $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(distdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.txt $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup50/BACKUP* $(distdir)/std_data/ndb_backup50 $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup50/BACKUP* $(distdir)/std_data/ndb_backup50
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51/BACKUP* $(distdir)/std_data/ndb_backup51 $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51/BACKUP* $(distdir)/std_data/ndb_backup51
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_be/BACKUP* $(distdir)/std_data/ndb_backup51_data_be $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_be/BACKUP* $(distdir)/std_data/ndb_backup51_data_be
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_le/BACKUP* $(distdir)/std_data/ndb_backup51_data_le $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_le/BACKUP* $(distdir)/std_data/ndb_backup51_data_le
$(INSTALL_DATA) $(srcdir)/std_data/parts/part_* $(distdir)/std_data/parts $(INSTALL_DATA) $(srcdir)/std_data/parts/part_* $(distdir)/std_data/parts
$(INSTALL_DATA) $(srcdir)/std_data/parts/*.MY* $(distdir)/std_data/parts
$(INSTALL_DATA) $(srcdir)/std_data/funcs_1/* $(distdir)/std_data/funcs_1
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(distdir)/lib $(INSTALL_DATA) $(srcdir)/lib/*.pl $(distdir)/lib
$(INSTALL_DATA) $(srcdir)/lib/My/*.pm $(distdir)/lib/My $(INSTALL_DATA) $(srcdir)/lib/My/*.pm $(distdir)/lib/My
-rm -rf `find $(distdir)/suite -type d -name SCCS` $(distdir)/suite/row_lock -rm -rf `find $(distdir)/suite -type d -name SCCS` $(distdir)/suite/row_lock
@@ -93,6 +97,7 @@ install-data-local:
$(DESTDIR)$(testdir)/std_data/ndb_backup51_data_le \ $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_le \
$(DESTDIR)$(testdir)/std_data/parts \ $(DESTDIR)$(testdir)/std_data/parts \
$(DESTDIR)$(testdir)/lib \ $(DESTDIR)$(testdir)/lib \
$(DESTDIR)$(testdir)/std_data/funcs_1 \
$(DESTDIR)$(testdir)/lib/My $(DESTDIR)$(testdir)/lib/My
$(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(testdir) $(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(testdir)
-$(INSTALL_DATA) $(srcdir)/t/*.def $(DESTDIR)$(testdir)/t -$(INSTALL_DATA) $(srcdir)/t/*.def $(DESTDIR)$(testdir)/t
@@ -122,11 +127,14 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/std_data/*.frm $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.frm $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.MY* $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.txt $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup50/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup50 $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup50/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup50
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51 $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_be/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_be $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_be/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_be
$(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_le/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_le $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_le/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_le
$(INSTALL_DATA) $(srcdir)/std_data/parts/part_* $(DESTDIR)$(testdir)/std_data/parts $(INSTALL_DATA) $(srcdir)/std_data/parts/part_* $(DESTDIR)$(testdir)/std_data/parts
$(INSTALL_DATA) $(srcdir)/std_data/parts/*.MY* $(DESTDIR)$(testdir)/std_data/parts
$(INSTALL_DATA) $(srcdir)/std_data/funcs_1/* $(DESTDIR)$(testdir)/std_data/funcs_1
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib $(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib
$(INSTALL_DATA) $(srcdir)/lib/My/*.pm $(DESTDIR)$(testdir)/lib/My $(INSTALL_DATA) $(srcdir)/lib/My/*.pm $(DESTDIR)$(testdir)/lib/My
for f in `(cd $(srcdir); find suite -type f | egrep -v 'SCCS|row_lock')`; \ for f in `(cd $(srcdir); find suite -type f | egrep -v 'SCCS|row_lock')`; \

View File

@@ -125,6 +125,45 @@ drop table t1;
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/ --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /Server ver: [^,]*,/Server version,/
show binlog events from 0; show binlog events from 0;
#
# Bug #39182: Binary log producing incompatible character set query from
# stored procedure.
#
reset master;
CREATE DATABASE bug39182 DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
USE bug39182;
CREATE TABLE t1 (a VARCHAR(255) COLLATE utf8_unicode_ci)
DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
DELIMITER //;
CREATE PROCEDURE p1()
BEGIN
DECLARE s1 VARCHAR(255);
SET s1= "test";
CREATE TEMPORARY TABLE tmp1
SELECT * FROM t1 WHERE a LIKE CONCAT("%", s1, "%");
SELECT
COLLATION(NAME_CONST('s1', _utf8'test')) c1,
COLLATION(NAME_CONST('s1', _utf8'test' COLLATE utf8_unicode_ci)) c2,
COLLATION(s1) c3,
COERCIBILITY(NAME_CONST('s1', _utf8'test')) d1,
COERCIBILITY(NAME_CONST('s1', _utf8'test' COLLATE utf8_unicode_ci)) d2,
COERCIBILITY(s1) d3;
DROP TEMPORARY TABLE tmp1;
END//
DELIMITER ;//
CALL p1();
source include/show_binlog_events.inc;
DROP PROCEDURE p1;
DROP TABLE t1;
DROP DATABASE bug39182;
USE test;
--echo End of 5.0 tests --echo End of 5.0 tests
# Test of a too big SET INSERT_ID: see if the truncated value goes # Test of a too big SET INSERT_ID: see if the truncated value goes

View File

@@ -1,17 +1,43 @@
# Test of binlogging of INSERT_ID with INSERT DELAYED # ==== Purpose ====
#
# Verify that INSERT DELAYED in mixed or row mode writes events to the
# binlog, and that AUTO_INCREMENT works correctly.
#
# ==== Method ====
#
# Insert both single and multiple rows into an autoincrement column,
# both with specified value and with NULL.
#
# With INSERT DELAYED, the rows do not show up in the table
# immediately, so we must do source include/wait_until_rows_count.inc
# between any two INSERT DELAYED statements. Moreover, if mixed or
# row-based logging is used, there is also a delay between when rows
# show up in the table and when they show up in the binlog. To ensure
# that the rows show up in the binlog, we call FLUSH TABLES, which
# waits until the delayed_insert thread has finished.
#
# We cannot read the binlog after executing INSERT DELAYED statements
# that insert multiple rows, because that is nondeterministic. More
# precisely, rows may be written in batches to the binlog, where each
# batch has one Table_map_log_event and one or more
# Write_rows_log_event. The number of rows included in each batch is
# nondeterministic.
#
# ==== Related bugs ====
#
# BUG#20627: INSERT DELAYED does not honour auto_increment_* variables
# Bug in this test: BUG#38068: binlog_stm_binlog fails sporadically in pushbuild
create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
# First, avoid BUG#20627:
set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
# Verify that only one INSERT_ID event is binlogged.
# Note, that because of WL#3368 mixed mode binlog records RBR events for the delayed
let $table=t1; let $table=t1;
let $rows_inserted=11; # total number of inserted rows in this test let $count=0;
insert delayed into t1 values (207); insert delayed into t1 values (207);
let $count=1; inc $count;
# use this macro instead of sleeps.
--source include/wait_until_rows_count.inc --source include/wait_until_rows_count.inc
insert delayed into t1 values (null); insert delayed into t1 values (null);
inc $count; inc $count;
--source include/wait_until_rows_count.inc --source include/wait_until_rows_count.inc
@@ -20,9 +46,10 @@ insert delayed into t1 values (300);
inc $count; inc $count;
--source include/wait_until_rows_count.inc --source include/wait_until_rows_count.inc
# moving binlog check affront of multi-rows queries which work is indeterministic (extra table_maps) # It is not enough to wait until all rows have been inserted into the
# todo: better check is to substitute SHOW BINLOG with reading from binlog, probably bug#19459 is in # table. FLUSH TABLES ensures that they are in the binlog too. See
# the way # comment above.
FLUSH TABLES;
source include/show_binlog_events.inc; source include/show_binlog_events.inc;
insert delayed into t1 values (null),(null),(null),(null); insert delayed into t1 values (null),(null),(null),(null);
@@ -33,8 +60,5 @@ insert delayed into t1 values (null),(null),(400),(null);
inc $count; inc $count; inc $count; inc $count; inc $count; inc $count; inc $count; inc $count;
--source include/wait_until_rows_count.inc --source include/wait_until_rows_count.inc
#check this assertion about $count calculation
--echo $count == $rows_inserted
select * from t1; select * from t1;
drop table t1; drop table t1;

View File

@@ -139,15 +139,6 @@ drop table t1,t2,t3;
# table # table
# #
CREATE TABLE t1(a INT) ENGINE=BLACKHOLE; CREATE TABLE t1(a INT) ENGINE=BLACKHOLE;
# NOTE: After exchanging open_ltable() by open_and_lock_tables() in
# handle_delayed_insert() to fix problems with MERGE tables (Bug#26379),
# problems with INSERT DELAYED and BLACKHOLE popped up. open_ltable()
# does not check if the binlogging capabilities of the statement and the
# table match. So the below used to succeed. But since INSERT DELAYED
# switches to row-based logging in mixed-mode and BLACKHOLE cannot do
# row-based logging, it could not really work. Until this problem is
# correctly fixed, we have that error here.
--error ER_BINLOG_LOGGING_IMPOSSIBLE
INSERT DELAYED INTO t1 VALUES(1); INSERT DELAYED INTO t1 VALUES(1);
DROP TABLE t1; DROP TABLE t1;

View File

@@ -13,3 +13,18 @@ create trigger tr1 before insert on t1 for each row insert into t2 values (2*new
create procedure sp1 (a int) insert into t1 values(a); create procedure sp1 (a int) insert into t1 values(a);
drop database testing_1; drop database testing_1;
source include/show_binlog_events.inc; source include/show_binlog_events.inc;
# BUG#38773: DROP DATABASE cause switch to stmt-mode when there are
# temporary tables open
use test;
reset master;
create temporary table tt1 (a int);
create table t1 (a int);
insert into t1 values (1);
disable_warnings;
drop database if exists mysqltest1;
enable_warnings;
insert into t1 values (1);
drop table tt1, t1;
source include/show_binlog_events.inc;

View File

@@ -7,6 +7,7 @@
# Actually this test has nothing to do with innodb per se, it just requires # Actually this test has nothing to do with innodb per se, it just requires
# transactional table. # transactional table.
# #
flush status;
show status like "binlog_cache_use"; show status like "binlog_cache_use";
show status like "binlog_cache_disk_use"; show status like "binlog_cache_disk_use";
--disable_warnings --disable_warnings
@@ -38,12 +39,3 @@ commit;
show status like "binlog_cache_use"; show status like "binlog_cache_use";
show status like "binlog_cache_disk_use"; show status like "binlog_cache_disk_use";
drop table t1; drop table t1;
# Test for testable InnoDB status variables. This test
# uses previous ones(pages_created, rows_deleted, ...).
show status like "Innodb_buffer_pool_pages_total";
show status like "Innodb_page_size";
show status like "Innodb_rows_deleted";
show status like "Innodb_rows_inserted";
show status like "Innodb_rows_updated";

View File

@@ -20,7 +20,7 @@
eval create table t1 (a int) engine=$engine_type; eval create table t1 (a int) engine=$engine_type;
flush tables; flush tables;
system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ; remove_file $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
drop table if exists t1; drop table if exists t1;
save_master_pos; save_master_pos;
connection slave; connection slave;

View File

@@ -0,0 +1,32 @@
# Check replication of one statement assuming that the engine on the
# slave is a blackhole engine.
# Input:
# $statement Statement to evaluate, it is assumed to change t1
# 1. Evaluate statement on master, it is assumed to change t1
# 2. Wait for statement to be processed on slave
# 3. SELECT from table t1 to see what was written
# 4. Compare position on slave before executing statement and after
# executing statement. If difference is >0, then something was
# written to the binary log on the slave.
connection slave;
let $before = query_get_value("SHOW MASTER STATUS", Position, 1);
--echo [on master]
connection master;
eval $statement;
--echo [on slave]
sync_slave_with_master;
--echo # Expect 0
SELECT COUNT(*) FROM t1;
let $after = query_get_value("SHOW MASTER STATUS", Position, 1);
let $something_written = `select $after - $before != 0`;
if ($something_written) {
--echo >>> Something was written to binary log <<<
}
if (!$something_written) {
--echo >>> Nothing was written to binary log <<<
}

View File

@@ -151,6 +151,20 @@ DROP DATABASE IF EXISTS mysqltest3;
CREATE DATABASE mysqltest1; CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2; CREATE DATABASE mysqltest2;
eval CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE=$engine_type; eval CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE=$engine_type;
# Prevent Bug#26687 rpl_ddl test fails if run with --innodb option
# The testscript (suite/rpl/rpl_ddl.test) + the expected result need that the
# slave uses MyISAM for the table mysqltest.t1.
# This is not valid in case of suite/rpl_ndb/rpl_ndb_ddl.test which sources
# also this script.
sync_slave_with_master;
connection slave;
if (`SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mysqltest1' AND TABLE_NAME = 't1'
AND ENGINE <> 'MyISAM' AND '$engine_type' <> 'NDB'`)
{
skip This test needs on slave side: InnoDB disabled, default engine: MyISAM;
}
connection master;
INSERT INTO mysqltest1.t1 SET f1= 0; INSERT INTO mysqltest1.t1 SET f1= 0;
eval CREATE TABLE mysqltest1.t2 (f1 BIGINT) ENGINE=$engine_type; eval CREATE TABLE mysqltest1.t2 (f1 BIGINT) ENGINE=$engine_type;
eval CREATE TABLE mysqltest1.t3 (f1 BIGINT) ENGINE=$engine_type; eval CREATE TABLE mysqltest1.t3 (f1 BIGINT) ENGINE=$engine_type;

View File

@@ -28,9 +28,17 @@ drop table if exists t1, t2, t3;
-- source include/master-slave.inc -- source include/master-slave.inc
#should work for both SBR and RBR #should work for both SBR and RBR
# If concurrent inserts are on, it is not guaranteed that the rows
# inserted by INSERT are immediately accessible by SELECT in another
# thread. This would cause problems near the line 'connection master1'
# below. So we turn off concurrent inserts.
connection master; connection master;
create table t1(a int auto_increment, key(a)); SET @old_concurrent_insert= @@global.concurrent_insert;
create table t2(b int auto_increment, c int, key(b)); SET @@global.concurrent_insert= 0;
connection master;
eval create table t1(a int auto_increment, key(a)) engine=$engine_type;
eval create table t2(b int auto_increment, c int, key(b)) engine=$engine_type;
insert into t1 values (1),(2),(3); insert into t1 values (1),(2),(3);
insert into t1 values (null); insert into t1 values (null);
insert into t2 values (null,last_insert_id()); insert into t2 values (null,last_insert_id());
@@ -68,8 +76,8 @@ connection master;
drop table t2; drop table t2;
drop table t1; drop table t1;
create table t1(a int auto_increment, key(a)); eval create table t1(a int auto_increment, key(a)) engine=$engine_type;
create table t2(b int auto_increment, c int, key(b)); eval create table t2(b int auto_increment, c int, key(b)) engine=$engine_type;
insert into t1 values (10); insert into t1 values (10);
insert into t1 values (null),(null),(null); insert into t1 values (null),(null),(null);
insert into t2 values (5,0); insert into t2 values (5,0);
@@ -94,7 +102,7 @@ sync_with_master;
connection master; connection master;
SET TIMESTAMP=1000000000; SET TIMESTAMP=1000000000;
CREATE TABLE t1 ( a INT UNIQUE ); eval CREATE TABLE t1 ( a INT UNIQUE ) engine=$engine_type;
SET FOREIGN_KEY_CHECKS=0; SET FOREIGN_KEY_CHECKS=0;
# Duplicate Key Errors # Duplicate Key Errors
--error 1022, ER_DUP_ENTRY --error 1022, ER_DUP_ENTRY
@@ -109,8 +117,8 @@ sync_slave_with_master;
--echo # --echo #
connection master; connection master;
create table t1(a int auto_increment, key(a)); eval create table t1(a int auto_increment, key(a)) engine=$engine_type;
create table t2(a int); eval create table t2(a int) engine=$engine_type;
insert into t1 (a) values (null); insert into t1 (a) values (null);
insert into t2 (a) select a from t1 where a is null; insert into t2 (a) select a from t1 where a is null;
insert into t2 (a) select a from t1 where a is null; insert into t2 (a) select a from t1 where a is null;
@@ -139,11 +147,11 @@ drop function if exists bug15728_insert;
drop table if exists t1, t2; drop table if exists t1, t2;
--enable_warnings --enable_warnings
create table t1 ( eval create table t1 (
id int not null auto_increment, id int not null auto_increment,
last_id int, last_id int,
primary key (id) primary key (id)
); ) engine=$engine_type;
create function bug15728() returns int(11) create function bug15728() returns int(11)
return last_insert_id(); return last_insert_id();
@@ -152,11 +160,11 @@ insert into t1 (last_id) values (last_insert_id());
insert into t1 (last_id) values (bug15728()); insert into t1 (last_id) values (bug15728());
# Check that nested call replicates too. # Check that nested call replicates too.
create table t2 ( eval create table t2 (
id int not null auto_increment, id int not null auto_increment,
last_id int, last_id int,
primary key (id) primary key (id)
); ) engine=$engine_type;
delimiter |; delimiter |;
create function bug15728_insert() returns int(11) modifies sql data create function bug15728_insert() returns int(11) modifies sql data
begin begin
@@ -215,8 +223,8 @@ drop procedure foo;
# test of BUG#20188 REPLACE or ON DUPLICATE KEY UPDATE in # test of BUG#20188 REPLACE or ON DUPLICATE KEY UPDATE in
# auto_increment breaks binlog # auto_increment breaks binlog
create table t1 (n int primary key auto_increment not null, eval create table t1 (n int primary key auto_increment not null,
b int, unique(b)); b int, unique(b)) engine=$engine_type;
# First, test that we do not call restore_auto_increment() too early # First, test that we do not call restore_auto_increment() too early
# in write_record(): # in write_record():
@@ -257,8 +265,8 @@ select * from t1 order by n;
# and now test for the bug: # and now test for the bug:
connection master; connection master;
drop table t1; drop table t1;
create table t1 (n int primary key auto_increment not null, eval create table t1 (n int primary key auto_increment not null,
b int, unique(b)); b int, unique(b)) engine=$engine_type;
insert into t1 values(null,100); insert into t1 values(null,100);
select * from t1 order by n; select * from t1 order by n;
sync_slave_with_master; sync_slave_with_master;
@@ -282,29 +290,29 @@ sync_slave_with_master;
connection master; connection master;
# testcase with INSERT VALUES # testcase with INSERT VALUES
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT, eval CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT,
UNIQUE(b)); UNIQUE(b)) ENGINE=$engine_type;
INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10; INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10;
SELECT * FROM t1; SELECT * FROM t1 ORDER BY a;
sync_slave_with_master; sync_slave_with_master;
SELECT * FROM t1; SELECT * FROM t1 ORDER BY a;
connection master; connection master;
drop table t1; drop table t1;
# tescase with INSERT SELECT # tescase with INSERT SELECT
CREATE TABLE t1 ( eval CREATE TABLE t1 (
id bigint(20) unsigned NOT NULL auto_increment, id bigint(20) unsigned NOT NULL auto_increment,
field_1 int(10) unsigned NOT NULL, field_1 int(10) unsigned NOT NULL,
field_2 varchar(255) NOT NULL, field_2 varchar(255) NOT NULL,
field_3 varchar(255) NOT NULL, field_3 varchar(255) NOT NULL,
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE KEY field_1 (field_1, field_2) UNIQUE KEY field_1 (field_1, field_2)
); ) ENGINE=$engine_type;
CREATE TABLE t2 ( eval CREATE TABLE t2 (
field_a int(10) unsigned NOT NULL, field_a int(10) unsigned NOT NULL,
field_b varchar(255) NOT NULL, field_b varchar(255) NOT NULL,
field_c varchar(255) NOT NULL field_c varchar(255) NOT NULL
); ) ENGINE=$engine_type;
INSERT INTO t2 (field_a, field_b, field_c) VALUES (1, 'a', '1a'); INSERT INTO t2 (field_a, field_b, field_c) VALUES (1, 'a', '1a');
INSERT INTO t2 (field_a, field_b, field_c) VALUES (2, 'b', '2b'); INSERT INTO t2 (field_a, field_b, field_c) VALUES (2, 'b', '2b');
INSERT INTO t2 (field_a, field_b, field_c) VALUES (3, 'c', '3c'); INSERT INTO t2 (field_a, field_b, field_c) VALUES (3, 'c', '3c');
@@ -324,9 +332,9 @@ SELECT t2.field_a, t2.field_b, t2.field_c
FROM t2 FROM t2
ON DUPLICATE KEY UPDATE ON DUPLICATE KEY UPDATE
t1.field_3 = t2.field_c; t1.field_3 = t2.field_c;
SELECT * FROM t1; SELECT * FROM t1 ORDER BY id;
sync_slave_with_master; sync_slave_with_master;
SELECT * FROM t1; SELECT * FROM t1 ORDER BY id;
connection master; connection master;
drop table t1, t2; drop table t1, t2;
@@ -348,17 +356,17 @@ DROP TABLE IF EXISTS t1, t2;
# Reset result of LAST_INSERT_ID(). # Reset result of LAST_INSERT_ID().
SELECT LAST_INSERT_ID(0); SELECT LAST_INSERT_ID(0);
CREATE TABLE t1 ( eval CREATE TABLE t1 (
id INT NOT NULL DEFAULT 0, id INT NOT NULL DEFAULT 0,
last_id INT, last_id INT,
PRIMARY KEY (id) PRIMARY KEY (id)
); ) ENGINE=$engine_type;
CREATE TABLE t2 ( eval CREATE TABLE t2 (
id INT NOT NULL AUTO_INCREMENT, id INT NOT NULL AUTO_INCREMENT,
last_id INT, last_id INT,
PRIMARY KEY (id) PRIMARY KEY (id)
); ) ENGINE=$engine_type;
delimiter |; delimiter |;
CREATE PROCEDURE p1() CREATE PROCEDURE p1()
@@ -369,12 +377,12 @@ END|
delimiter ;| delimiter ;|
CALL p1(); CALL p1();
SELECT * FROM t1; SELECT * FROM t1 ORDER BY id;
SELECT * FROM t2; SELECT * FROM t2 ORDER BY id;
sync_slave_with_master; sync_slave_with_master;
SELECT * FROM t1; SELECT * FROM t1 ORDER BY id;
SELECT * FROM t2; SELECT * FROM t2 ORDER BY id;
connection master; connection master;
@@ -394,11 +402,11 @@ DROP FUNCTION IF EXISTS f3;
DROP TABLE IF EXISTS t1, t2; DROP TABLE IF EXISTS t1, t2;
--enable_warnings --enable_warnings
CREATE TABLE t1 ( eval CREATE TABLE t1 (
i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, i INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
j INT DEFAULT 0 j INT DEFAULT 0
); ) ENGINE=$engine_type;
CREATE TABLE t2 (i INT); eval CREATE TABLE t2 (i INT) ENGINE=$engine_type;
delimiter |; delimiter |;
CREATE PROCEDURE p1() CREATE PROCEDURE p1()
@@ -434,8 +442,6 @@ SELECT f1();
INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()), INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()),
(NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2()); (NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2());
INSERT INTO t1 VALUES (NULL, f2()); INSERT INTO t1 VALUES (NULL, f2());
INSERT INTO t1 VALUES (NULL, LAST_INSERT_ID()), (NULL, LAST_INSERT_ID(5)),
(NULL, @@LAST_INSERT_ID);
# Test replication of substitution "IS NULL" -> "= LAST_INSERT_ID". # Test replication of substitution "IS NULL" -> "= LAST_INSERT_ID".
INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID()); INSERT INTO t1 VALUES (NULL, 0), (NULL, LAST_INSERT_ID());
UPDATE t1 SET j= -1 WHERE i IS NULL; UPDATE t1 SET j= -1 WHERE i IS NULL;
@@ -443,14 +449,16 @@ UPDATE t1 SET j= -1 WHERE i IS NULL;
# Test statement-based replication of function calls. # Test statement-based replication of function calls.
INSERT INTO t1 (i) VALUES (NULL); INSERT INTO t1 (i) VALUES (NULL);
# Here, we rely on having set @@concurrent_insert= 0 (see comment at
# the top of this file).
connection master1; connection master1;
INSERT INTO t1 (i) VALUES (NULL); INSERT INTO t1 (i) VALUES (NULL);
connection master; connection master;
SELECT f3(); SELECT f3();
SELECT * FROM t1; SELECT * FROM t1 ORDER BY i;
SELECT * FROM t2; SELECT * FROM t2 ORDER BY i;
sync_slave_with_master; sync_slave_with_master;
SELECT * FROM t1; SELECT * FROM t1;
@@ -472,11 +480,11 @@ sync_slave_with_master;
# Tests in this file are tightly bound together. Recreate t2. # Tests in this file are tightly bound together. Recreate t2.
connection master; connection master;
create table t2 ( eval create table t2 (
id int not null auto_increment, id int not null auto_increment,
last_id int, last_id int,
primary key (id) primary key (id)
); ) engine=$engine_type;
# Test for BUG#20341 "stored function inserting into one # Test for BUG#20341 "stored function inserting into one
@@ -484,7 +492,8 @@ create table t2 (
connection master; connection master;
truncate table t2; truncate table t2;
create table t1 (id tinyint primary key); # no auto_increment # no auto_increment
eval create table t1 (id tinyint primary key) engine=$engine_type;
delimiter |; delimiter |;
create function insid() returns int create function insid() returns int
@@ -504,20 +513,20 @@ insert into t2 (id) values(5),(6),(7);
delete from t2 where id>=5; delete from t2 where id>=5;
set sql_log_bin=1; set sql_log_bin=1;
insert into t1 select insid(); insert into t1 select insid();
select * from t1; select * from t1 order by id;
select * from t2; select * from t2 order by id;
sync_slave_with_master; sync_slave_with_master;
select * from t1; select * from t1 order by id;
select * from t2; select * from t2 order by id;
connection master; connection master;
drop table t1; drop table t1;
drop function insid; drop function insid;
truncate table t2; truncate table t2;
create table t1 (n int primary key auto_increment not null, eval create table t1 (n int primary key auto_increment not null,
b int, unique(b)); b int, unique(b)) engine=$engine_type;
delimiter |; delimiter |;
create procedure foo() create procedure foo()
begin begin
@@ -528,14 +537,15 @@ begin
end| end|
delimiter ;| delimiter ;|
call foo(); call foo();
select * from t1; select * from t1 order by n;
select * from t2; select * from t2 order by id;
sync_slave_with_master; sync_slave_with_master;
select * from t1; select * from t1 order by n;
select * from t2; select * from t2 order by id;
connection master; connection master;
drop table t1, t2; drop table t1, t2;
drop procedure foo; drop procedure foo;
SET @@global.concurrent_insert= @old_concurrent_insert;
sync_slave_with_master; sync_slave_with_master;

View File

@@ -13,22 +13,15 @@ save_master_pos;
connection slave; connection slave;
sync_with_master; sync_with_master;
stop slave; stop slave;
--source include/wait_for_slave_to_stop.inc
reset master; reset master;
reset slave; reset slave;
# We are going to read the slave's binlog which contains file_id (for some LOAD start slave;
# DATA INFILE); to make it repeatable (not influenced by other tests), we need --source include/wait_for_slave_to_start.inc
# to stop and start the slave, to be sure file_id will start from 1.
# This can be done with 'server_stop slave', but
# this would require the manager, so most of the time the test will be skipped
# :(
# To workaround this, I (Guilhem) add a (empty) rpl_log-slave.opt (because when
# mysql-test-run finds such a file it restarts the slave before doing the
# test). That's not very elegant but I could find no better way, sorry.
let $VERSION=`select version()`; let $VERSION=`select version()`;
connection master; connection master;
reset master;
eval create table t1(n int not null auto_increment primary key)ENGINE=$engine_type; eval create table t1(n int not null auto_increment primary key)ENGINE=$engine_type;
insert into t1 values (NULL); insert into t1 values (NULL);
drop table t1; drop table t1;
@@ -79,7 +72,6 @@ connection slave;
# Note that the above 'slave start' will cause a 3rd rotate event (a fake one) # Note that the above 'slave start' will cause a 3rd rotate event (a fake one)
# to go into the relay log (the master always sends a fake one when replication # to go into the relay log (the master always sends a fake one when replication
# starts). # starts).
start slave;
let $result_pattern= '%127.0.0.1%root%master-bin.000002%slave-relay-bin.000005%Yes%Yes%0%0%None%'; let $result_pattern= '%127.0.0.1%root%master-bin.000002%slave-relay-bin.000005%Yes%Yes%0%0%None%';
--source include/wait_slave_status.inc --source include/wait_slave_status.inc
sync_with_master; sync_with_master;
@@ -87,6 +79,7 @@ sync_with_master;
select * from t1 order by 1 asc; select * from t1 order by 1 asc;
flush logs; flush logs;
stop slave; stop slave;
--source include/wait_for_slave_to_stop.inc
connection master; connection master;
# Create some entries for second log # Create some entries for second log
@@ -95,6 +88,7 @@ eval create table t2 (n int)ENGINE=$engine_type;
insert into t2 values (1); insert into t2 values (1);
source include/show_binlog_events.inc; source include/show_binlog_events.inc;
--replace_result $VERSION VERSION --replace_result $VERSION VERSION
--replace_regex /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/ /infile '.+'/infile 'words.dat'/
--replace_column 2 # 5 # --replace_column 2 # 5 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
show binlog events in 'master-bin.000002'; show binlog events in 'master-bin.000002';
@@ -102,10 +96,12 @@ show binary logs;
save_master_pos; save_master_pos;
connection slave; connection slave;
start slave; start slave;
--source include/wait_for_slave_to_start.inc
sync_with_master; sync_with_master;
show binary logs; show binary logs;
--replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION --replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION
--replace_column 2 # 5 # --replace_column 2 # 5 #
--replace_regex /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/ /INFILE '.+'/INFILE 'words.dat'/
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
show binlog events in 'slave-bin.000001' from 4; show binlog events in 'slave-bin.000001' from 4;
--replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION --replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION

View File

@@ -259,12 +259,28 @@ DELETE FROM t1;
query_vertical SELECT COUNT(*) FROM t1 ORDER BY c1,c2; query_vertical SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
sync_slave_with_master; sync_slave_with_master;
set @@global.slave_exec_mode= default; set @@global.slave_exec_mode= default;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
disable_query_log; disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error; eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log; enable_query_log;
query_vertical SELECT COUNT(*) FROM t1 ORDER BY c1,c2; query_vertical SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
# BUG#37076: TIMESTAMP/DATETIME values are not replicated correctly
# between machines with mixed endiannes
# (regression test)
--echo **** Test for BUG#37076 ****
--echo **** On Master ****
connection master;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a TIMESTAMP, b DATETIME, c DATE);
INSERT INTO t1 VALUES(
'2005-11-14 01:01:01', '2005-11-14 01:01:02', '2005-11-14');
--echo **** On Slave ****
sync_slave_with_master slave;
SELECT * FROM t1;
# #
# cleanup # cleanup
# #
@@ -272,3 +288,367 @@ query_vertical SELECT COUNT(*) FROM t1 ORDER BY c1,c2;
connection master; connection master;
DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8; DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8;
sync_slave_with_master; sync_slave_with_master;
#
# BUG#37426: RBR breaks for CHAR() UTF8 fields > 85 chars
#
# We have 4 combinations to test with respect to the field length
# (i.e., the number of bytes) of the CHAR fields:
#
# 1. Replicating from CHAR<256 to CHAR<256
# 2. Replicating from CHAR<256 to CHAR>255
# 3. Replicating from CHAR>255 to CHAR<256
# 4. Replicating from CHAR>255 to CHAR>255
# We also make a special case of using the max size of a field on the
# master, i.e. CHAR(255) in UTF-8, giving another three cases.
#
# 5. Replicating UTF-8 CHAR(255) to CHAR(<256)
# 6. Replicating UTF-8 CHAR(255) to CHAR(>255)
# 7. Replicating UTF-8 CHAR(255) to CHAR(255) UTF-8
connection master;
eval CREATE TABLE t1 (i INT NOT NULL,
c CHAR(16) CHARACTER SET utf8 NOT NULL,
j INT NOT NULL) ENGINE = $type ;
eval CREATE TABLE t2 (i INT NOT NULL,
c CHAR(16) CHARACTER SET utf8 NOT NULL,
j INT NOT NULL) ENGINE = $type ;
sync_slave_with_master;
ALTER TABLE t2 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
connection master;
eval CREATE TABLE t3 (i INT NOT NULL,
c CHAR(128) CHARACTER SET utf8 NOT NULL,
j INT NOT NULL) ENGINE = $type ;
sync_slave_with_master;
ALTER TABLE t3 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
connection master;
eval CREATE TABLE t4 (i INT NOT NULL,
c CHAR(128) CHARACTER SET utf8 NOT NULL,
j INT NOT NULL) ENGINE = $type ;
eval CREATE TABLE t5 (i INT NOT NULL,
c CHAR(255) CHARACTER SET utf8 NOT NULL,
j INT NOT NULL) ENGINE = $type ;
sync_slave_with_master;
ALTER TABLE t5 MODIFY c CHAR(16) CHARACTER SET utf8 NOT NULL;
connection master;
eval CREATE TABLE t6 (i INT NOT NULL,
c CHAR(255) CHARACTER SET utf8 NOT NULL,
j INT NOT NULL) ENGINE = $type ;
sync_slave_with_master;
ALTER TABLE t6 MODIFY c CHAR(128) CHARACTER SET utf8 NOT NULL;
connection master;
eval CREATE TABLE t7 (i INT NOT NULL,
c CHAR(255) CHARACTER SET utf8 NOT NULL,
j INT NOT NULL) ENGINE = $type ;
--echo [expecting slave to replicate correctly]
connection master;
INSERT INTO t1 VALUES (1, "", 1);
INSERT INTO t1 VALUES (2, repeat(_utf8'a', 16), 2);
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
--echo [expecting slave to replicate correctly]
connection master;
INSERT INTO t2 VALUES (1, "", 1);
INSERT INTO t2 VALUES (2, repeat(_utf8'a', 16), 2);
sync_slave_with_master;
let $diff_table_1=master:test.t2;
let $diff_table_2=slave:test.t2;
source include/diff_tables.inc;
--echo [expecting slave to stop]
connection master;
INSERT INTO t3 VALUES (1, "", 1);
INSERT INTO t3 VALUES (2, repeat(_utf8'a', 128), 2);
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
connection master;
RESET MASTER;
connection slave;
STOP SLAVE;
RESET SLAVE;
START SLAVE;
source include/wait_for_slave_to_start.inc;
--echo [expecting slave to replicate correctly]
connection master;
INSERT INTO t4 VALUES (1, "", 1);
INSERT INTO t4 VALUES (2, repeat(_utf8'a', 128), 2);
sync_slave_with_master;
let $diff_table_1=master:test.t4;
let $diff_table_2=slave:test.t4;
source include/diff_tables.inc;
--echo [expecting slave to stop]
connection master;
INSERT INTO t5 VALUES (1, "", 1);
INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2);
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
connection master;
RESET MASTER;
connection slave;
STOP SLAVE;
RESET SLAVE;
START SLAVE;
source include/wait_for_slave_to_start.inc;
--echo [expecting slave to stop]
connection master;
INSERT INTO t6 VALUES (1, "", 1);
INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2);
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
connection master;
RESET MASTER;
connection slave;
STOP SLAVE;
RESET SLAVE;
START SLAVE;
source include/wait_for_slave_to_start.inc;
--echo [expecting slave to replicate correctly]
connection master;
INSERT INTO t7 VALUES (1, "", 1);
INSERT INTO t7 VALUES (2, repeat(_utf8'a', 255), 2);
sync_slave_with_master;
let $diff_table_1=master:test.t7;
let $diff_table_2=slave:test.t7;
source include/diff_tables.inc;
connection master;
drop table t1, t2, t3, t4, t5, t6, t7;
sync_slave_with_master;
#
# BUG#32709: Assertion failed: trx_data->empty(), file .\log.cc, line 1293
#
connection master;
eval CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=$type;
INSERT INTO t1 VALUES (1), (2), (3);
--error ER_DUP_ENTRY
UPDATE t1 SET a = 10;
INSERT INTO t1 VALUES (4);
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
connection master;
drop table t1;
sync_slave_with_master;
#
# Bug #38230 Differences between master and slave after
# UPDATE or DELETE with LIMIT with pk
#
# the regression test verifies consistency via selecting
--disable_abort_on_error
--connection master
--disable_warnings
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
eval CREATE TABLE t1 (
`pk` int(11) NOT NULL AUTO_INCREMENT,
`int_nokey` int(11) NOT NULL,
`int_key` int(11) NOT NULL,
`date_key` date NOT NULL,
`date_nokey` date NOT NULL,
`time_key` time NOT NULL,
`time_nokey` time NOT NULL,
`datetime_key` datetime NOT NULL,
`datetime_nokey` datetime NOT NULL,
`varchar_key` varchar(1) NOT NULL,
`varchar_nokey` varchar(1) NOT NULL,
PRIMARY KEY (`pk`),
KEY `int_key` (`int_key`),
KEY `date_key` (`date_key`),
KEY `time_key` (`time_key`),
KEY `datetime_key` (`datetime_key`),
KEY `varchar_key` (`varchar_key`)
) ENGINE=$type;
INSERT INTO t1 VALUES (1,8,5,'0000-00-00','0000-00-00','10:37:38','10:37:38','0000-00-00 00:00:00','0000-00-00 00:00:00','p','p'),(2,0,9,'0000-00-00','0000-00-00','00:00:00','00:00:00','2007-10-14 00:00:00','2007-10-14 00:00:00','d','d');
eval CREATE TABLE t2 (
`pk` int(11) NOT NULL AUTO_INCREMENT,
`int_nokey` int(11) NOT NULL,
`int_key` int(11) NOT NULL,
`date_key` date NOT NULL,
`date_nokey` date NOT NULL,
`time_key` time NOT NULL,
`time_nokey` time NOT NULL,
`datetime_key` datetime NOT NULL,
`datetime_nokey` datetime NOT NULL,
`varchar_key` varchar(1) NOT NULL,
`varchar_nokey` varchar(1) NOT NULL,
PRIMARY KEY (`pk`),
KEY `int_key` (`int_key`),
KEY `date_key` (`date_key`),
KEY `time_key` (`time_key`),
KEY `datetime_key` (`datetime_key`),
KEY `varchar_key` (`varchar_key`)
) ENGINE=$type;
INSERT INTO t2 VALUES (1,1,6,'2005-12-23','2005-12-23','02:24:28','02:24:28','0000-00-00 00:00:00','0000-00-00 00:00:00','g','g'),(2,0,3,'2009-09-14','2009-09-14','00:00:00','00:00:00','2000-01-30 16:39:40','2000-01-30 16:39:40','q','q'),(3,0,3,'0000-00-00','0000-00-00','00:00:00','00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','c','c'),(4,1,6,'2007-03-29','2007-03-29','15:49:00','15:49:00','0000-00-00 00:00:00','0000-00-00 00:00:00','m','m'),(5,4,0,'2002-12-04','2002-12-04','00:00:00','00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','o','o'),(6,9,0,'2005-01-28','2005-01-28','00:00:00','00:00:00','2001-05-18 00:00:00','2001-05-18 00:00:00','w','w'),(7,6,0,'0000-00-00','0000-00-00','06:57:25','06:57:25','0000-00-00 00:00:00','0000-00-00 00:00:00','m','m'),(8,0,0,'0000-00-00','0000-00-00','00:00:00','00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00','z','z'),(9,4,6,'2006-08-15','2006-08-15','00:00:00','00:00:00','2002-04-12 14:44:25','2002-04-12 14:44:25','j','j'),(10,0,5,'2006-12-20','2006-12-20','10:13:53','10:13:53','2008-07-22 00:00:00','2008-07-22 00:00:00','y','y'),(11,9,7,'0000-00-00','0000-00-00','00:00:00','00:00:00','2004-07-05 00:00:00','2004-07-05 00:00:00','{','{'),(12,4,3,'2007-01-26','2007-01-26','23:00:51','23:00:51','2001-05-16 00:00:00','2001-05-16 00:00:00','f','f'),(13,7,0,'2004-03-27','2004-03-27','00:00:00','00:00:00','2005-01-24 03:30:37','2005-01-24 03:30:37','',''),(14,6,0,'2006-07-26','2006-07-26','18:43:57','18:43:57','0000-00-00 00:00:00','0000-00-00 00:00:00','{','{'),(15,0,6,'2000-01-14','2000-01-14','00:00:00','00:00:00','2000-09-21 00:00:00','2000-09-21 00:00:00','o','o'),(16,9,8,'0000-00-00','0000-00-00','21:15:08','21:15:08','0000-00-00 00:00:00','0000-00-00 00:00:00','a','a'),(17,2,0,'2004-10-27','2004-10-27','00:00:00','00:00:00','2004-03-24 22:13:43','2004-03-24 22:13:43','',''),(18,7,4,'0000-00-00','0000-00-00','08:38:27','08:38:27','2002-03-18 19:51:44','2002-03-18 19:51:44','t','t'),(19,5,3,'2008-03-07','2008-03-07','03:29:07','03:29:07','2007-12-01 18:44:44','2007-12-01 18:44:44','t','t'),(20,0,0,'2002-04-09','2002-04-09','16:06:03','16:06:03','2009-04-22 00:00:00','2009-04-22 00:00:00','n','n');
DELETE FROM t2 WHERE `int_key` < 3 LIMIT 1;
UPDATE t1 SET `int_key` = 3 ORDER BY `pk` LIMIT 4;
DELETE FROM t2 WHERE `int_key` < 3 LIMIT 1;
DELETE FROM t2 WHERE `pk` < 6 LIMIT 1;
UPDATE t1 SET `int_key` = 6 ORDER BY `pk` LIMIT 3;
DELETE FROM t2 WHERE `pk` < 6 LIMIT 1;
UPDATE t1 SET `pk` = 6 ORDER BY `int_key` LIMIT 6;
DELETE FROM t2 WHERE `pk` < 7 LIMIT 1;
UPDATE t1 SET `int_key` = 4 ORDER BY `pk` LIMIT 6;
--sync_slave_with_master
--echo *** results: t2 must be consistent ****
let $diff_table_1=master:test.t2;
let $diff_table_2=master:test.t2;
source include/diff_tables.inc;
--connection master
DROP TABLE t1, t2;
--enable_abort_on_error
--echo EOF OF TESTS
#
# BUG#40004: Replication failure with no PK + no indexes
#
# The test cases are taken from the bug report. It is difficult to
# produce a test case that generates a HA_ERR_RECORD_DELETED, so we go
# with the test cases we have.
connection master;
eval CREATE TABLE t1 (a int) ENGINE=$type;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 2 );
INSERT INTO t1 ( a ) VALUES ( 9 );
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 5 WHERE a = 9;
DELETE FROM t1 WHERE a < 6;
UPDATE t1 SET a = 9 WHERE a < 3;
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a < 4;
UPDATE t1 SET a = 8 WHERE a < 5;
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
connection master;
drop table t1;
sync_slave_with_master;
#
# Bug #39752: Replication failure on RBR + MyISAM + no PK
#
# The test cases are taken from the bug report. It is difficult to
# produce a test case that generates a HA_ERR_RECORD_DELETED, so we go
# with the test cases we have.
connection master;
--disable_warnings
eval CREATE TABLE t1 (a bit) ENGINE=$type;
INSERT IGNORE INTO t1 VALUES (NULL);
INSERT INTO t1 ( a ) VALUES ( 0 );
UPDATE t1 SET a = 0 WHERE a = 1 LIMIT 3;
INSERT INTO t1 ( a ) VALUES ( 5 );
DELETE FROM t1 WHERE a < 2 LIMIT 4;
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 9 );
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 8 );
UPDATE t1 SET a = 0 WHERE a < 6 LIMIT 0;
INSERT INTO t1 ( a ) VALUES ( 4 );
INSERT INTO t1 ( a ) VALUES ( 3 );
UPDATE t1 SET a = 0 WHERE a = 7 LIMIT 6;
DELETE FROM t1 WHERE a = 4 LIMIT 7;
UPDATE t1 SET a = 9 WHERE a < 2 LIMIT 9;
UPDATE t1 SET a = 0 WHERE a < 9 LIMIT 2;
DELETE FROM t1 WHERE a < 0 LIMIT 5;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 4 WHERE a < 6 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 5 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 8;
DELETE FROM t1 WHERE a < 8 LIMIT 8;
INSERT INTO t1 ( a ) VALUES ( 6 );
DELETE FROM t1 WHERE a < 6 LIMIT 7;
UPDATE t1 SET a = 7 WHERE a = 3 LIMIT 7;
UPDATE t1 SET a = 8 WHERE a = 0 LIMIT 6;
INSERT INTO t1 ( a ) VALUES ( 7 );
DELETE FROM t1 WHERE a < 9 LIMIT 4;
INSERT INTO t1 ( a ) VALUES ( 7 );
INSERT INTO t1 ( a ) VALUES ( 6 );
UPDATE t1 SET a = 8 WHERE a = 3 LIMIT 4;
DELETE FROM t1 WHERE a = 2 LIMIT 9;
DELETE FROM t1 WHERE a = 1 LIMIT 4;
UPDATE t1 SET a = 4 WHERE a = 2 LIMIT 7;
INSERT INTO t1 ( a ) VALUES ( 0 );
DELETE FROM t1 WHERE a < 3 LIMIT 0;
UPDATE t1 SET a = 8 WHERE a = 5 LIMIT 2;
INSERT INTO t1 ( a ) VALUES ( 1 );
UPDATE t1 SET a = 9 WHERE a < 5 LIMIT 3;
--enable_warnings
sync_slave_with_master;
let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
connection master;
drop table t1;
sync_slave_with_master;

View File

@@ -0,0 +1,81 @@
#
# This auxiliary script is used by character set test cases.
#
--Error 0,ER_UNKNOWN_CHARACTER_SET
eval SET $charset_variable = big5;
eval SELECT $charset_variable;
eval SET $charset_variable = dec8;
eval SELECT $charset_variable;
eval SET $charset_variable = cp850;
eval SELECT $charset_variable;
eval SET $charset_variable = hp8;
eval SELECT $charset_variable;
eval SET $charset_variable = koi8r;
eval SELECT $charset_variable;
eval SET $charset_variable = latin1;
eval SELECT $charset_variable;
eval SET $charset_variable = latin2;
eval SELECT $charset_variable;
eval SET $charset_variable = swe7;
eval SELECT $charset_variable;
eval SET $charset_variable = ascii;
eval SELECT $charset_variable;
eval SET $charset_variable = ujis;
eval SELECT $charset_variable;
eval SET $charset_variable = sjis;
eval SELECT $charset_variable;
eval SET $charset_variable = hebrew;
eval SELECT $charset_variable;
eval SET $charset_variable = tis620;
eval SELECT $charset_variable;
eval SET $charset_variable = euckr;
eval SELECT $charset_variable;
eval SET $charset_variable = koi8u;
eval SELECT $charset_variable;
eval SET $charset_variable = gb2312;
eval SELECT $charset_variable;
eval SET $charset_variable = greek;
eval SELECT $charset_variable;
eval SET $charset_variable = cp1250;
eval SELECT $charset_variable;
eval SET $charset_variable = gbk;
eval SELECT $charset_variable;
eval SET $charset_variable = latin5;
eval SELECT $charset_variable;
eval SET $charset_variable = armscii8;
eval SELECT $charset_variable;
eval SET $charset_variable = utf8;
eval SELECT $charset_variable;
# Error with Linux
--error 0,ER_WRONG_VALUE_FOR_VAR
eval SET $charset_variable = ucs2;
eval SELECT $charset_variable;
eval SET $charset_variable = cp866;
eval SELECT $charset_variable;
eval SET $charset_variable = keybcs2;
eval SELECT $charset_variable;
eval SET $charset_variable = macce;
eval SELECT $charset_variable;
eval SET $charset_variable = macroman;
eval SELECT $charset_variable;
eval SET $charset_variable = cp852;
eval SELECT $charset_variable;
eval SET $charset_variable = latin7;
eval SELECT $charset_variable;
eval SET $charset_variable = cp1251;
eval SELECT $charset_variable;
eval SET $charset_variable = cp1256;
eval SELECT $charset_variable;
eval SET $charset_variable = cp1257;
eval SELECT $charset_variable;
eval SET $charset_variable = binary;
eval SELECT $charset_variable;
eval SET $charset_variable = geostd8;
eval SELECT $charset_variable;
eval SET $charset_variable = cp932;
eval SELECT $charset_variable;
eval SET $charset_variable = eucjpms;
eval SELECT $charset_variable;

View File

@@ -11,12 +11,12 @@
# #
# Dump all global variables # Dump all global variables
# #
show global variables; SHOW GLOBAL VARIABLES WHERE variable_name != 'timestamp';
# #
# Dump all databases # Dump all databases
# #
show databases; SHOW DATABASES;
# #
# Dump the "test" database, all it's tables and their data # Dump the "test" database, all it's tables and their data
@@ -29,23 +29,23 @@ show databases;
# #
--exec $MYSQL_DUMP --skip-comments --skip-lock-tables --no-data mysql --exec $MYSQL_DUMP --skip-comments --skip-lock-tables --no-data mysql
use mysql; use mysql;
select * from columns_priv; SELECT * FROM columns_priv;
select * from db order by host, db, user; SELECT * FROM db ORDER BY host, db, user;
select * from func; SELECT * FROM func;
select * from help_category; SELECT * FROM help_category;
select * from help_keyword; SELECT * FROM help_keyword;
select * from help_relation; SELECT * FROM help_relation;
select * from help_relation; SELECT * FROM help_relation;
select * from host; SELECT * FROM host;
select * from proc; SELECT * FROM proc;
select * from procs_priv; SELECT * FROM procs_priv;
select * from tables_priv; SELECT * FROM tables_priv;
select * from time_zone; SELECT * FROM time_zone;
select * from time_zone_leap_second; SELECT * FROM time_zone_leap_second;
select * from time_zone_name; SELECT * FROM time_zone_name;
select * from time_zone_transition; SELECT * FROM time_zone_transition;
select * from time_zone_transition_type; SELECT * FROM time_zone_transition_type;
select * from user; SELECT * FROM user;

View File

@@ -0,0 +1,258 @@
#
# This auxiliary file is used by collation variables
#
--Error 0,ER_UNKNOWN_CHARACTER_SET
eval SET $collation_variable = big5_chinese_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = big5_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = dec8_swedish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = dec8_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = cp850_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp850_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = hp8_english_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = hp8_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = koi8r_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = koi8r_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = latin1_german1_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = latin1_swedish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = latin1_danish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = latin1_german2_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = latin1_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = latin1_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = latin1_general_cs;
eval SELECT $collation_variable;
eval SET $collation_variable = latin1_spanish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = latin2_czech_cs;
eval SELECT $collation_variable;
eval SET $collation_variable = latin2_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = latin2_hungarian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = latin2_croatian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = latin2_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = swe7_swedish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = swe7_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = ascii_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ascii_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = ujis_japanese_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ujis_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = sjis_japanese_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = sjis_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = hebrew_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = hebrew_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = tis620_thai_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = tis620_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = euckr_korean_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = euckr_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = koi8u_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = koi8u_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = gb2312_chinese_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = gb2312_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = greek_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = greek_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1250_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1250_czech_cs;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1250_croatian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1250_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1250_polish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = gbk_chinese_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = gbk_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = latin5_turkish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = latin5_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = armscii8_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = armscii8_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_unicode_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_icelandic_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_latvian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_romanian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_slovenian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_polish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_estonian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_spanish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_swedish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_turkish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_czech_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_danish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_lithuanian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_slovak_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_spanish2_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_roman_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_persian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_esperanto_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = utf8_hungarian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_unicode_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_icelandic_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_latvian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_romanian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_slovenian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_polish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_estonian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_spanish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_swedish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_turkish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_czech_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_danish_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_lithuanian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_slovak_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_spanish2_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_roman_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_persian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_esperanto_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = ucs2_hungarian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp866_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp866_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = keybcs2_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = keybcs2_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = macce_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = macce_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = macroman_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = macroman_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = cp852_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp852_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = latin7_estonian_cs;
eval SELECT $collation_variable;
eval SET $collation_variable = latin7_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = latin7_general_cs;
eval SELECT $collation_variable;
eval SET $collation_variable = latin7_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1251_bulgarian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1251_ukrainian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1251_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1251_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1251_general_cs;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1256_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1256_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1257_lithuanian_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1257_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = cp1257_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = binary;
eval SELECT $collation_variable;
eval SET $collation_variable = geostd8_general_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = geostd8_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = cp932_japanese_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = cp932_bin;
eval SELECT $collation_variable;
eval SET $collation_variable = eucjpms_japanese_ci;
eval SELECT $collation_variable;
eval SET $collation_variable = eucjpms_bin;
eval SELECT $collation_variable;

View File

@@ -4,354 +4,641 @@
# Bug#3300 # Bug#3300
# Designed and tested by Sinisa Milivojevic, sinisa@mysql.com # Designed and tested by Sinisa Milivojevic, sinisa@mysql.com
# #
# two non-interfering UPDATE's not changing result set # These variables have to be set before sourcing this script:
# # TRANSACTION ISOLATION LEVEL REPEATABLE READ
# The variable # innodb_locks_unsafe_for_binlog 0 (default) or 1 (by
# $engine_type -- storage engine to be tested # --innodb_locks_unsafe_for_binlog)
# has to be set before sourcing this script. # $engine_type storage engine to be tested
# #
# Last update: # Last update:
# 2006-08-02 ML test refactored # 2006-08-02 ML test refactored
# old name was t/innodb_concurrent.test # old name was t/innodb_concurrent.test
# main code went into include/concurrent.inc # main code went into include/concurrent.inc
# 2008-06-03 KP test refactored; removed name locks, added comments.
# renamed wrapper t/concurrent_innodb.test ->
# t/concurrent_innodb_unsafelog.test
# new wrapper t/concurrent_innodb_safelog.test
# #
connection default; connection default;
eval SET SESSION STORAGE_ENGINE = $engine_type;
#
# Show prerequisites for this test.
#
SELECT @@global.tx_isolation;
SELECT @@global.innodb_locks_unsafe_for_binlog;
#
# When innodb_locks_unsafe_for_binlog is not set (zero), which is the
# default, InnoDB takes "next-key locks"/"gap locks". This means it
# locks the gap before the keys that it accessed to find the rows to
# use for a statement. In this case we have to expect some more lock
# wait timeouts in the tests below as if innodb_locks_unsafe_for_binlog
# is set (non-zero). In the latter case no "next-key locks"/"gap locks"
# are taken and locks on keys that do not match the WHERE conditon are
# released. Hence less lock collisions occur.
# We use the variable $keep_locks to set the expectations for
# lock wait timeouts accordingly.
#
let $keep_locks= `SELECT NOT @@global.innodb_locks_unsafe_for_binlog`;
--echo # keep_locks == $keep_locks
#
# Set up privileges and remove user level locks, if exist.
#
GRANT USAGE ON test.* TO mysqltest@localhost;
#
# Preparatory cleanup.
#
DO release_lock("hello");
DO release_lock("hello2");
--disable_warnings --disable_warnings
drop table if exists t1; drop table if exists t1;
--enable_warnings --enable_warnings
create table t1(eta int(11) not null, tipo int(11), c varchar(255));
connect (thread1, localhost, mysqltest,,);
connection thread1;
eval SET SESSION STORAGE_ENGINE = $engine_type;
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
select get_lock("hello",1);
connect (thread2, localhost, mysqltest,,);
connection thread2;
begin;
send update t1 set eta=1+get_lock("hello",1)*0 where tipo=11;
sleep 1;
connection thread1;
begin;
update t1 set eta=2 where tipo=22;
select release_lock("hello");
select * from t1;
connection thread2;
reap;
select * from t1;
send commit;
connection thread1;
select * from t1;
commit;
select * from t1;
connection thread2;
reap;
select * from t1;
connection thread1;
select * from t1;
connection default;
drop table t1;
#
# two UPDATE's running and one changing result set --echo
# --echo **
#connect (thread1, localhost, mysqltest,,); --echo ** two UPDATE's running and both changing distinct result sets
connection thread1; --echo **
create table t1(eta int(11) not null, tipo int(11), c varchar(255)); --echo ** connection thread1
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); connect (thread1, localhost, mysqltest,,);
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); connection thread1;
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc"); --echo ** Set up table
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd"); eval SET SESSION STORAGE_ENGINE = $engine_type;
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); create table t1(eta int(11) not null, tipo int(11), c varchar(255));
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff"); insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg"); insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"); insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"); insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj"); insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"); insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
select get_lock("hello",10); insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
#connect (thread2, localhost, mysqltest,,); insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
connection thread2; insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
begin; insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
send update t1 set eta=1+get_lock("hello",10)*0 where tipo=1; insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
sleep 1; --echo ** Get user level lock (ULL) for thread 1
connection thread1; select get_lock("hello",10);
begin;
update t1 set tipo=1 where tipo=2; --echo ** connection thread2
select release_lock("hello"); connect (thread2, localhost, mysqltest,,);
select * from t1; connection thread2;
connection thread2; --echo ** Start transaction for thread 2
reap; begin;
select * from t1; --echo ** Update will cause a table scan and a new ULL will
send commit; --echo ** be created and blocked on the first row where tipo=11.
connection thread1; send update t1 set eta=1+get_lock("hello",10)*0 where tipo=11;
select * from t1; sleep 1;
commit;
select * from t1; --echo ** connection thread1
connection thread2; connection thread1;
reap; --echo ** Start new transaction for thread 1
select * from t1; begin;
connection thread1; --echo ** Update on t1 will cause a table scan which will be blocked because
select * from t1; --echo ** the previously initiated table scan applied exclusive key locks on
--echo ** all primary keys.
--echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
--echo ** do not match the WHERE condition are released.
if ($keep_locks)
{
--error ER_LOCK_WAIT_TIMEOUT
update t1 set eta=2 where tipo=22;
}
if (!$keep_locks)
{
update t1 set eta=2 where tipo=22;
}
--echo ** Release user level name lock from thread 1. This will cause the ULL
--echo ** on thread 2 to end its wait.
select release_lock("hello");
--echo ** Table is now updated with a new eta on tipo=22 for thread 1.
select * from t1;
--echo ** connection thread2
connection thread2;
--echo ** Release the lock and collect result from update on thread 2
reap;
select release_lock("hello");
--echo ** Table should have eta updates where tipo=11 but updates made by
--echo ** thread 1 shouldn't be visible yet.
select * from t1;
--echo ** Sending commit on thread 2.
commit;
--echo ** connection thread1
connection thread1;
--echo ** Make sure table reads didn't change yet on thread 1.
select * from t1;
--echo ** And send final commit on thread 1.
commit;
--echo ** Table should now be updated by both updates in the order of
--echo ** thread 1,2.
select * from t1;
--echo ** connection thread2
connection thread2;
--echo ** Make sure the output is similar for t1.
select * from t1;
--echo ** connection thread1
connection thread1;
select * from t1;
--echo ** connection default
connection default; connection default;
drop table t1; drop table t1;
# --echo
# One UPDATE and one INSERT .... Monty's test --echo **
# --echo ** two UPDATE's running and one changing result set
--echo **
--echo ** connection thread1
#connect (thread1, localhost, mysqltest,,);
connection thread1;
--echo ** Set up table
eval SET SESSION STORAGE_ENGINE = $engine_type;
create table t1(eta int(11) not null, tipo int(11), c varchar(255));
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
--echo ** Get ULL "hello" on thread 1
select get_lock("hello",10);
#connect (thread1, localhost, mysqltest,,); --echo ** connection thread2
connection thread1; #connect (thread2, localhost, mysqltest,,);
create table t1 (a int not null, b int not null); connection thread2;
insert into t1 values (1,1),(2,1),(3,1),(4,1); --echo ** Start transaction on thread 2
select get_lock("hello2",1000); begin;
#connect (thread2, localhost, mysqltest,,); --echo ** Update will cause a table scan.
connection thread2; --echo ** This will cause a hang on the first row where tipo=1 until the
begin; --echo ** blocking ULL is released.
send update t1 set b=10+get_lock(concat("hello",a),1000)*0 where send update t1 set eta=1+get_lock("hello",10)*0 where tipo=1;
a=2; sleep 1;
sleep 1;
connection thread1;
insert into t1 values (1,1);
select release_lock("hello2");
select * from t1;
connection thread2;
reap;
select * from t1;
send commit;
connection thread1;
sleep 1;
connection thread2;
reap;
connection default;
drop table t1;
# --echo ** connection thread1
# one UPDATE changing result set and SELECT ... FOR UPDATE connection thread1;
# --echo ** Start transaction on thread 1
#connect (thread1, localhost, mysqltest,,); begin;
connection thread1; --echo ** Update on t1 will cause a table scan which will be blocked because
create table t1(eta int(11) not null, tipo int(11), c varchar(255)); --echo ** the previously initiated table scan applied exclusive key locks on
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); --echo ** all primary keys.
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); --echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc"); --echo ** do not match the WHERE condition are released.
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd"); if ($keep_locks)
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); {
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff"); --error ER_LOCK_WAIT_TIMEOUT
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg"); update t1 set tipo=1 where tipo=2;
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"); }
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"); if (!$keep_locks)
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj"); {
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"); update t1 set tipo=1 where tipo=2;
select get_lock("hello",10); }
#connect (thread2, localhost, mysqltest,,); --echo ** Release ULL. This will release the next waiting ULL on thread 2.
connection thread2; select release_lock("hello");
begin; --echo ** The table should still be updated with updates for thread 1 only:
send select * from t1 where tipo=2 FOR UPDATE; select * from t1;
sleep 1;
connection thread1;
begin;
select release_lock("hello");
--error 1205
update t1 set tipo=1+get_lock("hello",10)*0 where tipo=2;
select * from t1;
connection thread2;
reap;
select * from t1;
send commit;
connection thread1;
commit;
connection thread2;
reap;
select * from t1;
connection thread1;
select * from t1;
connection default;
drop table t1;
# --echo ** connection thread2
# one UPDATE not changing result set and SELECT ... FOR UPDATE connection thread2;
# --echo ** Release the lock and collect result from thread 2:
#connect (thread1, localhost, mysqltest,,); reap;
connection thread1; select release_lock("hello");
create table t1(eta int(11) not null, tipo int(11), c varchar(255)); --echo ** Seen from thread 2 the table should have been updated on four
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); --echo ** places.
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); select * from t1;
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc"); commit;
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
select get_lock("hello",10);
#connect (thread2, localhost, mysqltest,,);
connection thread2;
begin;
send select * from t1 where tipo=2 FOR UPDATE;
sleep 1;
connection thread1;
begin;
select release_lock("hello");
--error 1205
update t1 set tipo=11+get_lock("hello",10)*0 where tipo=22;
select * from t1;
connection thread2;
reap;
select * from t1;
send commit;
connection thread1;
commit;
connection thread2;
reap;
select * from t1;
connection thread1;
select * from t1;
connection default;
drop table t1;
# --echo ** connection thread1
# two SELECT ... FOR UPDATE connection thread1;
# --echo ** Thread 2 has committed but the result should remain the same for
#connect (thread1, localhost, mysqltest,,); --echo ** thread 1 (updated on three places):
connection thread1; select * from t1;
create table t1(eta int(11) not null, tipo int(11), c varchar(255)); commit;
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); --echo ** After a commit the table should be merged with the previous
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); --echo ** commit.
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc"); --echo ** This select should show both updates:
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd"); select * from t1;
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff"); --echo ** connection thread2
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg"); connection thread2;
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"); select * from t1;
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj"); --echo ** connection thread1
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"); connection thread1;
select get_lock("hello",10); select * from t1;
#connect (thread2, localhost, mysqltest,,);
connection thread2; --echo ** connection default
begin;
send select * from t1 where tipo=2 FOR UPDATE;
sleep 1;
connection thread1;
begin;
select release_lock("hello");
--error 1205
select * from t1 where tipo=1 FOR UPDATE;
connection thread2;
reap;
select * from t1;
send commit;
connection thread1;
commit;
connection thread2;
reap;
select * from t1;
connection thread1;
select * from t1;
connection default; connection default;
drop table t1; drop table t1;
# --echo
# one UPDATE changing result set and DELETE --echo **
# --echo ** One UPDATE and one INSERT .... Monty's test
#connect (thread1, localhost, mysqltest,,); --echo **
connection thread1; --echo ** connection thread1
create table t1(eta int(11) not null, tipo int(11), c varchar(255)); #connect (thread1, localhost, mysqltest,,);
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); connection thread1;
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); --echo ** Set up table
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc"); eval SET SESSION STORAGE_ENGINE = $engine_type;
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd"); create table t1 (a int not null, b int not null);
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); insert into t1 values (1,1),(2,1),(3,1),(4,1);
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff"); --echo ** Create ULL 'hello2'
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg"); select get_lock("hello2",10);
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"); --echo ** connection thread2
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj"); #connect (thread2, localhost, mysqltest,,);
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"); connection thread2;
select get_lock("hello",10); --echo ** Begin a new transaction on thread 2
#connect (thread2, localhost, mysqltest,,); begin;
connection thread2; --echo ** Update will create a table scan which creates a ULL where a=2;
begin; --echo ** this will hang waiting on thread 1.
send delete from t1 where tipo=2; send update t1 set b=10+get_lock(concat("hello",a),10)*0 where a=2;
sleep 1; sleep 1;
connection thread1;
begin; --echo ** connection thread1
select release_lock("hello"); connection thread1;
--error 1205 --echo ** Insert new values to t1 from thread 1; this created an implicit
update t1 set tipo=1+get_lock("hello",10)*0 where tipo=2; --echo ** commit since there are no on-going transactions.
select * from t1; insert into t1 values (1,1);
connection thread2; --echo ** Release the ULL (thread 2 updates will finish).
reap; select release_lock("hello2");
select * from t1; --echo ** ..but thread 1 will still see t1 as if nothing has happend:
send commit; select * from t1;
connection thread1;
commit; --echo ** connection thread2
connection thread2; connection thread2;
reap; --echo ** Collect results from thread 2 and release the lock.
select * from t1; reap;
connection thread1; select release_lock("hello2");
select * from t1; --echo ** The table should look like the original+updates for thread 2,
--echo ** and consist of new rows:
select * from t1;
--echo ** Commit changes from thread 2
commit;
--echo ** connection default
connection default; connection default;
drop table t1; drop table t1;
# --echo
# one UPDATE not changing result set and DELETE --echo **
# --echo ** one UPDATE changing result set and SELECT ... FOR UPDATE
#connect (thread1, localhost, mysqltest,,); --echo **
connection thread1; --echo ** connection thread1
create table t1(eta int(11) not null, tipo int(11), c varchar(255)); #connect (thread1, localhost, mysqltest,,);
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); connection thread1;
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"); --echo ** Set up table
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc"); eval SET SESSION STORAGE_ENGINE = $engine_type;
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd"); create table t1(eta int(11) not null, tipo int(11), c varchar(255));
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff"); insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg"); insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"); insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"); insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj"); insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"); insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
select get_lock("hello",10); insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
#connect (thread2, localhost, mysqltest,,); insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
connection thread2; insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
begin; insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
send delete from t1 where tipo=2;
sleep 1; --echo ** connection thread2
connection thread1; #connect (thread2, localhost, mysqltest,,);
begin; connection thread2;
select release_lock("hello"); --echo ** Begin a new transaction on thread 2
update t1 set tipo=1+get_lock("hello",10)*0 where tipo=22; begin;
select * from t1; --echo ** Select a range for update.
connection thread2; select * from t1 where tipo=2 FOR UPDATE;
reap;
select * from t1; --echo ** connection thread1
send commit; connection thread1;
connection thread1; --echo ** Begin a new transaction on thread 1
commit; begin;
connection thread2; --echo ** Update the same range which is marked for update on thread 2; this
reap; --echo ** will hang because of row locks.
select * from t1; --error ER_LOCK_WAIT_TIMEOUT
connection thread1; update t1 set tipo=1 where tipo=2;
select * from t1; --echo ** After the update the table will be unmodified because the previous
--echo ** transaction failed and was rolled back.
select * from t1;
--echo ** connection thread2
connection thread2;
--echo ** The table should look unmodified from thread 2.
select * from t1;
--echo ** Sending a commit should release the row locks and enable
--echo ** thread 1 to complete the transaction.
commit;
--echo ** connection thread1
connection thread1;
--echo ** Commit on thread 1.
commit;
--echo ** connection thread2
connection thread2;
--echo ** The table should not have been changed.
select * from t1;
--echo ** connection thread1
connection thread1;
--echo ** Even on thread 1:
select * from t1;
--echo ** connection default
connection default; connection default;
sleep 1;
drop table t1; drop table t1;
--echo
--echo **
--echo ** one UPDATE not changing result set and SELECT ... FOR UPDATE
--echo **
--echo ** connection thread1
#connect (thread1, localhost, mysqltest,,);
connection thread1;
--echo ** Set up table
eval SET SESSION STORAGE_ENGINE = $engine_type;
create table t1(eta int(11) not null, tipo int(11), c varchar(255));
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
--echo ** connection thread2
#connect (thread2, localhost, mysqltest,,);
connection thread2;
--echo ** Starting new transaction on thread 2.
begin;
--echo ** Starting SELECT .. FOR UPDATE
select * from t1 where tipo=2 FOR UPDATE;
--echo ** connection thread1
connection thread1;
--echo
--echo ** Starting new transaction on thread 1
begin;
--echo ** Updating single row using a table scan. This will time out
--echo ** because of ongoing transaction on thread 1 holding lock on
--echo ** all primary keys in the scan.
--echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
--echo ** do not match the WHERE condition are released.
if ($keep_locks)
{
--error ER_LOCK_WAIT_TIMEOUT
update t1 set tipo=11 where tipo=22;
}
if (!$keep_locks)
{
update t1 set tipo=11 where tipo=22;
}
--echo ** After the time out the transaction is aborted; no rows should
--echo ** have changed.
select * from t1;
--echo ** connection thread2
connection thread2;
--echo ** The same thing should hold true for the transaction on
--echo ** thread 2
select * from t1;
send commit;
--echo ** connection thread1
connection thread1;
commit;
--echo ** connection thread2
connection thread2;
--echo ** Even after committing:
reap;
select * from t1;
--echo ** connection thread1
connection thread1;
select * from t1;
--echo ** connection default
connection default;
drop table t1;
--echo
--echo **
--echo ** two SELECT ... FOR UPDATE
--echo **
--echo ** connection thread1
#connect (thread1, localhost, mysqltest,,);
connection thread1;
--echo ** Set up table
eval SET SESSION STORAGE_ENGINE = $engine_type;
create table t1(eta int(11) not null, tipo int(11), c varchar(255));
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
--echo ** connection thread2
#connect (thread2, localhost, mysqltest,,);
connection thread2;
--echo ** Begin a new transaction on thread 2
begin;
select * from t1 where tipo=2 FOR UPDATE;
--echo ** connection thread1
connection thread1;
--echo ** Begin a new transaction on thread 1
begin;
--echo ** Selecting a range for update by table scan will be blocked
--echo ** because of on-going transaction on thread 2.
--error ER_LOCK_WAIT_TIMEOUT
select * from t1 where tipo=1 FOR UPDATE;
--echo ** connection thread2
connection thread2;
--echo ** Table will be unchanged and the select command will not be
--echo ** blocked:
select * from t1;
--echo ** Commit transacton on thread 2.
commit;
--echo ** connection thread1
connection thread1;
--echo ** Commit transaction on thread 1.
commit;
--echo ** connection thread2
connection thread2;
--echo ** Make sure table isn't blocked on thread 2:
select * from t1;
--echo ** connection thread1
connection thread1;
--echo ** Make sure table isn't blocked on thread 1:
select * from t1;
--echo ** connection default
connection default;
drop table t1;
--echo
--echo **
--echo ** one UPDATE changing result set and DELETE
--echo **
--echo ** connection thread1
#connect (thread1, localhost, mysqltest,,);
connection thread1;
--echo ** Set up table
eval SET SESSION STORAGE_ENGINE = $engine_type;
create table t1(eta int(11) not null, tipo int(11), c varchar(255));
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
--echo ** connection thread2
#connect (thread2, localhost, mysqltest,,);
connection thread2;
begin;
send delete from t1 where tipo=2;
sleep 1;
--echo ** connection thread1
connection thread1;
begin;
--error ER_LOCK_WAIT_TIMEOUT
update t1 set tipo=1 where tipo=2;
select * from t1;
--echo ** connection thread2
connection thread2;
reap;
select * from t1;
send commit;
--echo ** connection thread1
connection thread1;
commit;
--echo ** connection thread2
connection thread2;
reap;
select * from t1;
--echo ** connection thread1
connection thread1;
select * from t1;
--echo ** connection default
connection default;
drop table t1;
--echo
--echo **
--echo ** one UPDATE not changing result set and DELETE
--echo **
--echo ** connection thread1
#connect (thread1, localhost, mysqltest,,);
connection thread1;
--echo ** Set up table
eval SET SESSION STORAGE_ENGINE = $engine_type;
create table t1(eta int(11) not null, tipo int(11), c varchar(255));
insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
--echo ** connection thread2
#connect (thread2, localhost, mysqltest,,);
connection thread2;
begin;
send delete from t1 where tipo=2;
sleep 1;
--echo ** connection thread1
connection thread1;
begin;
--echo ** Update on t1 will cause a table scan which will be blocked because
--echo ** the previously initiated table scan applied exclusive key locks on
--echo ** all primary keys.
--echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
--echo ** do not match the WHERE condition are released.
if ($keep_locks)
{
--error ER_LOCK_WAIT_TIMEOUT
update t1 set tipo=1 where tipo=22;
}
if (!$keep_locks)
{
update t1 set tipo=1 where tipo=22;
}
select * from t1;
--echo ** connection thread2
connection thread2;
reap;
select * from t1;
send commit;
--echo ** connection thread1
connection thread1;
commit;
--echo ** connection thread2
connection thread2;
reap;
select * from t1;
--echo ** connection thread1
connection thread1;
select * from t1;
--echo ** connection default
connection default;
drop table t1;
disconnect thread1; disconnect thread1;
disconnect thread2; disconnect thread2;

View File

@@ -136,7 +136,7 @@ connect (user3,localhost,mysqltest_3,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
connection user3; connection user3;
select "user3"; select "user3";
--replace_result 127.0.0.1 localhost --replace_result 127.0.0.1 localhost
--error ER_COLUMNACCESS_DENIED_ERROR --error ER_TABLEACCESS_DENIED_ERROR
select * from t1; select * from t1;
select a from t1; select a from t1;
--replace_result 127.0.0.1 localhost --replace_result 127.0.0.1 localhost

View File

@@ -0,0 +1,16 @@
# Created by Horst Hunger 2008-04-15
# see also have_64bit.inc
--disable_query_log
--disable_warnings
let $save = `SELECT @@global.sort_buffer_size`;
SET @@global.sort_buffer_size = 4294967296;
let $mach32 = `SELECT @@global.sort_buffer_size <= 4294967295`;
eval SET @@global.sort_buffer_size = $save;
--enable_warnings
--enable_query_log
if (!$mach32)
{
skip Need a 32 bit machine;
}

View File

@@ -0,0 +1,14 @@
# Created by Horst Hunger 2008-04-15
# see also have_32bit.inc
--disable_query_log
let $save = `SELECT @@session.sort_buffer_size`;
SET @@session.sort_buffer_size = 4294967296;
let $mach64 = `SELECT @@session.sort_buffer_size > 4294967295`;
eval SET @@session.sort_buffer_size = $save;
--enable_query_log
if (!$mach64)
{
skip Need a 64 bit machine;
}

View File

@@ -1,4 +1,4 @@
-- require r/have_big5.require -- require r/have_big5.require
disable_query_log; disable_query_log;
show collation like "big5_chinese_ci"; show collation like 'big5_chinese_ci';
enable_query_log; enable_query_log;

View File

@@ -2,5 +2,5 @@
-- require r/have_binlog_format_mixed.require -- require r/have_binlog_format_mixed.require
disable_query_log; disable_query_log;
show variables like "binlog_format"; show variables like 'binlog_format';
enable_query_log; enable_query_log;

View File

@@ -3,5 +3,5 @@
--require r/have_binlog_format_row.require --require r/have_binlog_format_row.require
--disable_query_log --disable_query_log
--replace_result MIXED ROW --replace_result MIXED ROW
show variables like "binlog_format"; show variables like 'binlog_format';
--enable_query_log --enable_query_log

View File

@@ -4,5 +4,5 @@ source include/have_log_bin.inc;
--require r/have_binlog_format_statement.require --require r/have_binlog_format_statement.require
--disable_query_log --disable_query_log
--replace_result MIXED STATEMENT --replace_result MIXED STATEMENT
show variables like "binlog_format"; show variables like 'binlog_format';
--enable_query_log --enable_query_log

View File

@@ -2,5 +2,5 @@
-- require r/have_binlog_format_row.require -- require r/have_binlog_format_row.require
disable_query_log; disable_query_log;
show variables like "binlog_format"; show variables like 'binlog_format';
enable_query_log; enable_query_log;

View File

@@ -3,5 +3,5 @@
-- require r/have_binlog_format_statement.require -- require r/have_binlog_format_statement.require
--disable_query_log --disable_query_log
--replace_result ROW STATEMENT --replace_result ROW STATEMENT
show variables like "binlog_format"; show variables like 'binlog_format';
--enable_query_log --enable_query_log

Some files were not shown because too many files have changed in this diff Show More