summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore4
-rwxr-xr-xBUILD/SETUP.sh12
-rwxr-xr-xBUILD/check-cpu375
-rwxr-xr-xBUILD/compile-ndb-autotest19
-rw-r--r--BitKeeper/etc/collapsed3
-rwxr-xr-xCMakeLists.txt132
-rw-r--r--Makefile.am4
-rw-r--r--VC++Files/mysql.sln29
-rwxr-xr-xbdb/CMakeLists.txt44
-rw-r--r--bdb/Makefile.in2
-rwxr-xr-xclient/CMakeLists.txt79
-rw-r--r--client/Makefile.am2
-rw-r--r--client/mysql.cc12
-rw-r--r--client/mysql_upgrade.c16
-rw-r--r--client/mysqlbinlog.cc5
-rw-r--r--client/mysqldump.c143
-rw-r--r--configure.in20
-rwxr-xr-xdbug/CMakeLists.txt5
-rw-r--r--dbug/Makefile.am3
-rw-r--r--dbug/dbug.c5
-rwxr-xr-xextra/CMakeLists.txt32
-rw-r--r--extra/Makefile.am1
-rw-r--r--extra/comp_err.c3
-rwxr-xr-xextra/yassl/CMakeLists.txt6
-rw-r--r--extra/yassl/Makefile.am2
-rwxr-xr-xextra/yassl/include/openssl/generate_prefix_files.pl2
-rw-r--r--extra/yassl/include/openssl/prefix_ssl.h9
-rwxr-xr-xextra/yassl/taocrypt/CMakeLists.txt10
-rw-r--r--extra/yassl/taocrypt/Makefile.am2
-rw-r--r--extra/yassl/taocrypt/src/misc.cpp3
-rwxr-xr-xheap/CMakeLists.txt8
-rw-r--r--heap/Makefile.am2
-rw-r--r--include/my_dbug.h1
-rw-r--r--include/mysql.h1
-rw-r--r--include/mysql_com.h17
-rwxr-xr-xinnobase/CMakeLists.txt35
-rw-r--r--innobase/Makefile.am1
-rwxr-xr-xlibmysql/CMakeLists.txt54
-rw-r--r--libmysql/Makefile.am2
-rw-r--r--libmysql/mytest.c175
-rw-r--r--libmysqld/libmysqld.def1
-rwxr-xr-xmyisam/CMakeLists.txt26
-rw-r--r--myisam/Makefile.am2
-rwxr-xr-xmyisammrg/CMakeLists.txt9
-rw-r--r--myisammrg/Makefile.am2
-rw-r--r--mysql-test/Makefile.am7
-rw-r--r--mysql-test/include/im_check_env.inc6
-rw-r--r--mysql-test/include/im_check_os.inc7
-rw-r--r--mysql-test/include/loaddata_autocom.inc21
-rw-r--r--mysql-test/lib/mtr_cases.pl58
-rw-r--r--mysql-test/lib/mtr_io.pl38
-rw-r--r--mysql-test/lib/mtr_process.pl839
-rwxr-xr-xmysql-test/mysql-test-run.pl294
-rw-r--r--mysql-test/r/ctype_recoding.result11
-rw-r--r--mysql-test/r/ctype_ucs.result40
-rw-r--r--mysql-test/r/ctype_utf8.result44
-rw-r--r--mysql-test/r/drop.result13
-rw-r--r--mysql-test/r/func_misc.result5
-rw-r--r--mysql-test/r/func_time.result12
-rw-r--r--mysql-test/r/grant.result27
-rw-r--r--mysql-test/r/heap_btree.result1
-rw-r--r--mysql-test/r/im_daemon_life_cycle.result1
-rw-r--r--mysql-test/r/im_life_cycle.result1
-rw-r--r--mysql-test/r/im_options_set.result1
-rw-r--r--mysql-test/r/im_options_unset.result1
-rw-r--r--mysql-test/r/im_utils.result1
-rw-r--r--mysql-test/r/limit.result14
-rw-r--r--mysql-test/r/loaddata_autocom_innodb.result21
-rw-r--r--mysql-test/r/loaddata_autocom_ndb.result23
-rw-r--r--mysql-test/r/mysql.result14
-rw-r--r--mysql-test/r/mysqldump.result296
-rw-r--r--mysql-test/r/ps.result15
-rw-r--r--mysql-test/r/query_cache.result6
-rw-r--r--mysql-test/r/range.result45
-rw-r--r--mysql-test/r/rpl_ndb_innodb_trans.result103
-rw-r--r--mysql-test/r/sp-error.result39
-rw-r--r--mysql-test/r/sp.result142
-rw-r--r--mysql-test/r/trigger.result86
-rw-r--r--mysql-test/r/type_varchar.result31
-rw-r--r--mysql-test/r/variables.result6
-rw-r--r--mysql-test/r/view.result38
-rw-r--r--mysql-test/std_data/14897.frmbin0 -> 8608 bytes
-rw-r--r--mysql-test/t/ctype_recoding.test14
-rw-r--r--mysql-test/t/ctype_ucs.test48
-rw-r--r--mysql-test/t/ctype_utf8.test35
-rw-r--r--mysql-test/t/drop.test41
-rw-r--r--mysql-test/t/func_misc.test12
-rw-r--r--mysql-test/t/func_time.test18
-rw-r--r--mysql-test/t/grant.test56
-rw-r--r--mysql-test/t/handler.test1
-rw-r--r--mysql-test/t/heap_btree.test1
-rw-r--r--mysql-test/t/im_daemon_life_cycle.imtest1
-rw-r--r--mysql-test/t/im_life_cycle.imtest1
-rw-r--r--mysql-test/t/im_options_set.imtest1
-rw-r--r--mysql-test/t/im_options_unset.imtest1
-rw-r--r--mysql-test/t/im_utils.imtest1
-rw-r--r--mysql-test/t/limit.test10
-rw-r--r--mysql-test/t/loaddata_autocom_innodb.test4
-rw-r--r--mysql-test/t/loaddata_autocom_ndb.test4
-rw-r--r--mysql-test/t/mysql.test4
-rw-r--r--mysql-test/t/mysqldump.test199
-rw-r--r--mysql-test/t/ps.test31
-rw-r--r--mysql-test/t/range.test29
-rw-r--r--mysql-test/t/rpl_ndb_innodb_trans-slave.opt1
-rw-r--r--mysql-test/t/rpl_ndb_innodb_trans.test66
-rw-r--r--mysql-test/t/sp-error.test39
-rw-r--r--mysql-test/t/sp.test134
-rw-r--r--mysql-test/t/system_mysql_db_fix.test3
-rw-r--r--mysql-test/t/trigger.test120
-rw-r--r--mysql-test/t/type_varchar.test41
-rw-r--r--mysql-test/t/variables.test11
-rw-r--r--mysql-test/t/view.test75
-rwxr-xr-xmysys/CMakeLists.txt29
-rw-r--r--mysys/Makefile.am3
-rw-r--r--mysys/my_read.c47
-rw-r--r--mysys/my_seek.c3
-rw-r--r--ndb/include/kernel/signaldata/CreateIndx.hpp1
-rw-r--r--ndb/include/kernel/signaldata/DropIndx.hpp1
-rw-r--r--ndb/include/ndbapi/NdbOperation.hpp2
-rw-r--r--ndb/src/kernel/blocks/ERROR_codes.txt3
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.cpp64
-rw-r--r--ndb/src/kernel/blocks/dbdict/Dbdict.cpp44
-rw-r--r--ndb/src/kernel/blocks/dbdict/Dbdict.hpp3
-rw-r--r--ndb/src/kernel/blocks/dbdih/DbdihMain.cpp21
-rw-r--r--ndb/src/kernel/blocks/dblqh/DblqhMain.cpp83
-rw-r--r--ndb/src/kernel/blocks/dbtc/Dbtc.hpp4
-rw-r--r--ndb/src/kernel/blocks/dbtc/DbtcMain.cpp159
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp10
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp30
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp4
-rw-r--r--ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp14
-rw-r--r--ndb/src/kernel/vm/DLHashTable2.hpp2
-rw-r--r--ndb/src/mgmapi/mgmapi.cpp11
-rw-r--r--ndb/src/mgmapi/ndb_logevent.cpp7
-rw-r--r--ndb/src/mgmclient/CommandInterpreter.cpp31
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.cpp11
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.hpp2
-rw-r--r--ndb/src/mgmsrv/Services.cpp1
-rw-r--r--ndb/src/ndbapi/ClusterMgr.cpp98
-rw-r--r--ndb/src/ndbapi/ClusterMgr.hpp10
-rw-r--r--ndb/src/ndbapi/NdbScanOperation.cpp13
-rw-r--r--ndb/test/include/NDBT_Tables.hpp2
-rw-r--r--ndb/test/ndbapi/testDict.cpp78
-rw-r--r--ndb/test/ndbapi/testIndex.cpp52
-rw-r--r--ndb/test/ndbapi/testSystemRestart.cpp47
-rw-r--r--ndb/test/run-test/daily-basic-tests.txt4
-rw-r--r--ndb/test/src/NDBT_Tables.cpp11
-rw-r--r--ndb/tools/ndb_config.cpp4
-rwxr-xr-xregex/CMakeLists.txt5
-rw-r--r--regex/Makefile.am2
-rw-r--r--scripts/Makefile.am3
-rwxr-xr-xscripts/make_win_bin_dist345
-rwxr-xr-xserver-tools/CMakeLists.txt18
-rw-r--r--server-tools/Makefile.am1
-rwxr-xr-xserver-tools/instance-manager/CMakeLists.txt17
-rw-r--r--server-tools/instance-manager/Makefile.am3
-rw-r--r--sql-common/client.c14
-rwxr-xr-xsql/CMakeLists.txt114
-rw-r--r--sql/Makefile.am8
-rwxr-xr-xsql/examples/CMakeLists.txt11
-rw-r--r--sql/field.cc27
-rw-r--r--sql/gen_lex_hash.cc21
-rw-r--r--sql/ha_archive.cc2
-rw-r--r--sql/ha_ndbcluster.cc20
-rw-r--r--sql/item.cc72
-rw-r--r--sql/item.h22
-rw-r--r--sql/item_cmpfunc.cc26
-rw-r--r--sql/item_func.cc9
-rw-r--r--sql/item_row.cc12
-rw-r--r--sql/item_strfunc.cc34
-rw-r--r--sql/item_strfunc.h35
-rw-r--r--sql/item_sum.cc4
-rw-r--r--sql/lock.cc7
-rw-r--r--sql/log.cc16
-rw-r--r--sql/message.mc8
-rw-r--r--sql/mysql_priv.h5
-rw-r--r--sql/mysqld.cc8
-rw-r--r--sql/net_serv.cc19
-rw-r--r--sql/opt_range.cc9
-rw-r--r--sql/protocol.cc40
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/share/errmsg.txt6
-rw-r--r--sql/slave.h2
-rw-r--r--sql/sp.cc29
-rw-r--r--sql/sp_head.cc12
-rw-r--r--sql/sp_head.h18
-rw-r--r--sql/sp_rcontext.cc59
-rw-r--r--sql/sp_rcontext.h6
-rw-r--r--sql/sql_acl.cc53
-rw-r--r--sql/sql_cache.cc582
-rw-r--r--sql/sql_cache.h17
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_error.cc8
-rw-r--r--sql/sql_lex.cc15
-rw-r--r--sql/sql_lex.h10
-rw-r--r--sql/sql_load.cc5
-rw-r--r--sql/sql_parse.cc55
-rw-r--r--sql/sql_prepare.cc6
-rw-r--r--sql/sql_repl.cc8
-rw-r--r--sql/sql_repl.h2
-rw-r--r--sql/sql_select.cc25
-rw-r--r--sql/sql_string.cc7
-rw-r--r--sql/sql_table.cc63
-rw-r--r--sql/sql_trigger.cc119
-rw-r--r--sql/sql_trigger.h6
-rw-r--r--sql/sql_view.cc52
-rw-r--r--sql/sql_yacc.yy67
-rw-r--r--sql/stacktrace.c55
-rw-r--r--sql/stacktrace.h8
-rw-r--r--sql/table.cc6
-rwxr-xr-xstrings/CMakeLists.txt12
-rw-r--r--strings/Makefile.am2
-rw-r--r--support-files/mysql.spec.sh3
-rwxr-xr-xtests/CMakeLists.txt9
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/mysql_client_test.c94
-rwxr-xr-xvio/CMakeLists.txt6
-rw-r--r--vio/Makefile.am2
-rw-r--r--vio/viosocket.c30
-rwxr-xr-xwin/Makefile.am21
-rw-r--r--win/README82
-rwxr-xr-xwin/build-vs71.bat7
-rwxr-xr-xwin/build-vs8.bat6
-rwxr-xr-xwin/build-vs8_x64.bat6
-rwxr-xr-xwin/configure.js166
-rwxr-xr-xzlib/CMakeLists.txt8
-rw-r--r--zlib/Makefile.am2
228 files changed, 6531 insertions, 1711 deletions
diff --git a/.bzrignore b/.bzrignore
index 5e6c7509354..555199fd166 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -671,6 +671,7 @@ mysql-test/*.ds?
mysql-test/*.vcproj
mysql-test/gmon.out
mysql-test/install_test_db
+mysql-test/mtr
mysql-test/mysql-test-run
mysql-test/mysql-test-run.log
mysql-test/mysql_test_run_new
@@ -913,6 +914,7 @@ ndb/src/common/mgmcommon/printConfig/*.d
ndb/src/common/portlib/libportlib.dsp
ndb/src/common/transporter/libtransporter.dsp
ndb/src/common/util/libgeneral.dsp
+ndb/src/common/util/testBitmask.cpp
ndb/src/cw/cpcd/ndb_cpcd
ndb/src/dummy.cpp
ndb/src/kernel/blocks/backup/libbackup.dsp
@@ -1138,6 +1140,7 @@ sql/*.ds?
sql/*.vcproj
sql/.gdbinit
sql/client.c
+sql/f.c
sql/gen_lex_hash
sql/gmon.out
sql/lex_hash.h
@@ -1296,4 +1299,3 @@ vio/viotest-sslconnect.cpp
vio/viotest.cpp
zlib/*.ds?
zlib/*.vcproj
-ndb/src/common/util/testBitmask.cpp
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 57061f3dbff..8055f337821 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-if ! test -f sql/mysqld.cc
+if test ! -f sql/mysqld.cc
then
echo "You must run this script from the MySQL top-level directory"
exit 1
@@ -122,12 +122,6 @@ fi
# (returns 0 if finds lines)
if ccache -V > /dev/null 2>&1
then
- if ! (echo "$CC" | grep "ccache" > /dev/null)
- then
- CC="ccache $CC"
- fi
- if ! (echo "$CXX" | grep "ccache" > /dev/null)
- then
- CXX="ccache $CXX"
- fi
+ echo "$CC" | grep "ccache" > /dev/null || CC="ccache $CC"
+ echo "$CXX" | grep "ccache" > /dev/null || CXX="ccache $CXX"
fi
diff --git a/BUILD/check-cpu b/BUILD/check-cpu
index d12a690eaa8..fb69fd0acae 100755
--- a/BUILD/check-cpu
+++ b/BUILD/check-cpu
@@ -3,213 +3,216 @@
# Check cpu of current machine and find the
# best compiler optimization flags for gcc
#
-#
-if test -r /proc/cpuinfo ; then
- # on Linux (and others?) we can get detailed CPU information out of /proc
- cpuinfo="cat /proc/cpuinfo"
+check_cpu () {
+ if test -r /proc/cpuinfo ; then
+ # on Linux (and others?) we can get detailed CPU information out of /proc
+ cpuinfo="cat /proc/cpuinfo"
- # detect CPU family
- cpu_family=`$cpuinfo | grep 'family' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
- if test -z "$cpu_family" ; then
- cpu_family=`$cpuinfo | grep 'cpu' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
- fi
+ # detect CPU family
+ cpu_family=`$cpuinfo | grep 'family' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
+ if test -z "$cpu_family" ; then
+ cpu_family=`$cpuinfo | grep 'cpu' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
+ fi
- # detect CPU vendor and model
- cpu_vendor=`$cpuinfo | grep 'vendor_id' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
- model_name=`$cpuinfo | grep 'model name' | cut -d ':' -f 2 | head -1`
- if test -z "$model_name" ; then
- model_name=`$cpuinfo | grep 'cpu model' | cut -d ':' -f 2 | head -1`
- fi
+ # detect CPU vendor and model
+ cpu_vendor=`$cpuinfo | grep 'vendor_id' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
+ model_name=`$cpuinfo | grep 'model name' | cut -d ':' -f 2 | head -1`
+ if test -z "$model_name" ; then
+ model_name=`$cpuinfo | grep 'cpu model' | cut -d ':' -f 2 | head -1`
+ fi
+
+ # fallback: get CPU model from uname output
+ if test -z "$model_name" ; then
+ model_name=`uname -m`
+ fi
- # fallback: get CPU model from uname output
- if test -z "$model_name" ; then
- model_name=`uname -m`
+ # parse CPU flags
+ for flag in `$cpuinfo | grep '^flags' | sed -e 's/^flags.*: //'`; do
+ eval cpu_flag_$flag=yes
+ done
+ else
+ # Fallback when there is no /proc/cpuinfo
+ case "`uname -s`" in
+ FreeBSD|OpenBSD)
+ cpu_family=`uname -m`;
+ model_name=`sysctl -n hw.model`
+ ;;
+ Darwin)
+ cpu_family=`uname -p`
+ model_name=`machine`
+ ;;
+ *)
+ cpu_family=`uname -m`;
+ model_name=`uname -p`;
+ ;;
+ esac
fi
- # parse CPU flags
- for flag in `$cpuinfo | grep '^flags' | sed -e 's/^flags.*: //'`; do
- eval cpu_flag_$flag=yes
- done
-else
- # Fallback when there is no /proc/cpuinfo
- case "`uname -s`" in
- FreeBSD|OpenBSD)
- cpu_family=`uname -m`;
- model_name=`sysctl -n hw.model`
- ;;
- Darwin)
- cpu_family=`uname -p`
- model_name=`machine`
+ # detect CPU shortname as used by gcc options
+ # this list is not complete, feel free to add further entries
+ cpu_arg=""
+ case "$cpu_family--$model_name" in
+ # DEC Alpha
+ Alpha*EV6*)
+ cpu_arg="ev6";
;;
- *)
- cpu_family=`uname -m`;
- model_name=`uname -p`;
+
+ # Intel ia32
+ *Xeon*)
+ # a Xeon is just another pentium4 ...
+ # ... unless it has the "lm" (long-mode) flag set,
+ # in that case it's a Xeon with EM64T support
+ if [ -z "$cpu_flag_lm" ]; then
+ cpu_arg="pentium4";
+ else
+ cpu_arg="nocona";
+ fi
;;
- esac
-fi
-
-# detect CPU shortname as used by gcc options
-# this list is not complete, feel free to add further entries
-cpu_arg=""
-case "$cpu_family--$model_name" in
- # DEC Alpha
- Alpha*EV6*)
- cpu_arg="ev6";
+ *Pentium*4*Mobile*)
+ cpu_arg="pentium4m";
;;
-
- # Intel ia32
- *Xeon*)
- # a Xeon is just another pentium4 ...
- # ... unless it has the "lm" (long-mode) flag set,
- # in that case it's a Xeon with EM64T support
- if [ -z "$cpu_flag_lm" ]; then
+ *Pentium*4*)
cpu_arg="pentium4";
- else
- cpu_arg="nocona";
- fi
- ;;
- *Pentium*4*Mobile*)
- cpu_arg="pentium4m";
- ;;
- *Pentium*4*)
- cpu_arg="pentium4";
- ;;
- *Pentium*III*Mobile*)
- cpu_arg="pentium3m";
- ;;
- *Pentium*III*)
- cpu_arg="pentium3";
- ;;
- *Pentium*M*pro*)
- cpu_arg="pentium-m";
- ;;
- *Athlon*64*)
- cpu_arg="athlon64";
- ;;
- *Athlon*)
- cpu_arg="athlon";
+ ;;
+ *Pentium*III*Mobile*)
+ cpu_arg="pentium3m";
;;
- *Opteron*)
- cpu_arg="opteron";
+ *Pentium*III*)
+ cpu_arg="pentium3";
;;
- # MacOSX / Intel
- *i386*i486*)
- cpu_arg="pentium-m";
+ *Pentium*M*pro*)
+ cpu_arg="pentium-m";
;;
+ *Athlon*64*)
+ cpu_arg="athlon64";
+ ;;
+ *Athlon*)
+ cpu_arg="athlon";
+ ;;
+ *Opteron*)
+ cpu_arg="opteron";
+ ;;
+ # MacOSX / Intel
+ *i386*i486*)
+ cpu_arg="pentium-m";
+ ;;
- # Intel ia64
- *Itanium*)
- # Don't need to set any flags for itanium(at the moment)
- cpu_arg="";
- ;;
+ # Intel ia64
+ *Itanium*)
+ # Don't need to set any flags for itanium(at the moment)
+ cpu_arg="";
+ ;;
- #
- *ppc*)
- cpu_arg='powerpc'
- ;;
-
- *powerpc*)
- cpu_arg='powerpc'
- ;;
+ #
+ *ppc*)
+ cpu_arg='powerpc'
+ ;;
+
+ *powerpc*)
+ cpu_arg='powerpc'
+ ;;
- # unknown
- *)
- cpu_arg="";
- ;;
-esac
-
-
-if test -z "$cpu_arg"; then
- echo "BUILD/check-cpu: Oops, could not find out what kind of cpu this machine is using."
- check_cpu_cflags=""
- return
-fi
-
-# different compiler versions have different option names
-# for CPU specific command line options
-if test -z "$CC" ; then
- cc="gcc";
-else
- cc=$CC
-fi
-
-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'`
-
-case "$cc_ver--$cc_verno" in
- *GCC*)
- # different gcc backends (and versions) have different CPU flags
- case `gcc -dumpmachine` in
- i?86-*)
- case "$cc_verno" in
- 3.4*|3.5*|4.*)
- check_cpu_args='-mtune=$cpu_arg -march=$cpu_arg'
- ;;
- *)
- check_cpu_args='-mcpu=$cpu_arg -march=$cpu_arg'
- ;;
- esac
- ;;
- ppc-*)
- check_cpu_args='-mcpu=$cpu_arg -mtune=$cpu_arg'
- ;;
- x86_64-*)
- check_cpu_args='-mtune=$cpu_arg'
- ;;
- *)
- check_cpu_cflags=""
- return
- ;;
- esac
- ;;
- 2.95.*)
- # GCC 2.95 doesn't expose its name in --version output
- check_cpu_args='-m$cpu_arg'
- ;;
- *)
+ # unknown
+ *)
+ cpu_arg="";
+ ;;
+ esac
+
+
+ if test -z "$cpu_arg"; then
+ echo "BUILD/check-cpu: Oops, could not find out what kind of cpu this machine is using." >&2
check_cpu_cflags=""
return
- ;;
-esac
-
-# now we check whether the compiler really understands the cpu type
-touch __test.c
-
-while [ "$cpu_arg" ] ; do
- echo -n testing $cpu_arg "... "
-
- # compile check
- check_cpu_cflags=`eval echo $check_cpu_args`
- if $cc -c $check_cpu_cflags __test.c 2>/dev/null; then
- echo ok
- break;
fi
- echo failed
- check_cpu_cflags=""
+ # different compiler versions have different option names
+ # for CPU specific command line options
+ if test -z "$CC" ; then
+ cc="gcc";
+ else
+ cc=$CC
+ fi
- # if compile failed: check whether it supports a predecessor of this CPU
- # this list is not complete, feel free to add further entries
- case "$cpu_arg" in
- # Intel ia32
- nocona) cpu_arg=pentium4 ;;
- prescott) cpu_arg=pentium4 ;;
- pentium4m) cpu_arg=pentium4 ;;
- pentium4) cpu_arg=pentium3 ;;
- pentium3m) cpu_arg=pentium3 ;;
- pentium3) cpu_arg=pentium2 ;;
- pentium2) cpu_arg=pentiumpro ;;
- pentiumpro) cpu_arg=pentium ;;
- pentium) cpu_arg=i486 ;;
- i486) cpu_arg=i386 ;;
-
- # power / powerPC
- 7450) cpu_arg=7400 ;;
-
- *) cpu_arg="" ;;
+ 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'`
+
+ case "$cc_ver--$cc_verno" in
+ *GCC*)
+ # different gcc backends (and versions) have different CPU flags
+ case `gcc -dumpmachine` in
+ i?86-*)
+ case "$cc_verno" in
+ 3.4*|3.5*|4.*)
+ check_cpu_args='-mtune=$cpu_arg -march=$cpu_arg'
+ ;;
+ *)
+ check_cpu_args='-mcpu=$cpu_arg -march=$cpu_arg'
+ ;;
+ esac
+ ;;
+ ppc-*)
+ check_cpu_args='-mcpu=$cpu_arg -mtune=$cpu_arg'
+ ;;
+ x86_64-*)
+ check_cpu_args='-mtune=$cpu_arg'
+ ;;
+ *)
+ check_cpu_cflags=""
+ return
+ ;;
+ esac
+ ;;
+ 2.95.*)
+ # GCC 2.95 doesn't expose its name in --version output
+ check_cpu_args='-m$cpu_arg'
+ ;;
+ *)
+ check_cpu_cflags=""
+ return
+ ;;
esac
-done
-rm __test.*
+ # now we check whether the compiler really understands the cpu type
+ touch __test.c
+
+ while [ "$cpu_arg" ] ; do
+ # FIXME: echo -n isn't portable - see contortions autoconf goes through
+ echo -n testing $cpu_arg "... " >&2
+
+ # compile check
+ check_cpu_cflags=`eval echo $check_cpu_args`
+ if $cc -c $check_cpu_cflags __test.c 2>/dev/null; then
+ echo ok >&2
+ break;
+ fi
+
+ echo failed >&2
+ check_cpu_cflags=""
+
+ # if compile failed: check whether it supports a predecessor of this CPU
+ # this list is not complete, feel free to add further entries
+ case "$cpu_arg" in
+ # Intel ia32
+ nocona) cpu_arg=pentium4 ;;
+ prescott) cpu_arg=pentium4 ;;
+ pentium4m) cpu_arg=pentium4 ;;
+ pentium4) cpu_arg=pentium3 ;;
+ pentium3m) cpu_arg=pentium3 ;;
+ pentium3) cpu_arg=pentium2 ;;
+ pentium2) cpu_arg=pentiumpro ;;
+ pentiumpro) cpu_arg=pentium ;;
+ pentium) cpu_arg=i486 ;;
+ i486) cpu_arg=i386 ;;
+
+ # power / powerPC
+ 7450) cpu_arg=7400 ;;
+
+ *) cpu_arg="" ;;
+ esac
+ done
+
+ rm __test.*
+}
+check_cpu
diff --git a/BUILD/compile-ndb-autotest b/BUILD/compile-ndb-autotest
new file mode 100755
index 00000000000..be28cc28346
--- /dev/null
+++ b/BUILD/compile-ndb-autotest
@@ -0,0 +1,19 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+extra_configs="$max_configs --with-ndb-test --with-ndb-ccflags='-DERROR_INSERT'"
+if [ "$full_debug" ]
+then
+ extra_flags="$debug_cflags"
+ c_warnings="$c_warnings $debug_extra_warnings"
+ cxx_warnings="$cxx_warnings $debug_extra_warnings"
+ extra_configs="$debug_configs $extra_configs"
+else
+ extra_flags="$fast_cflags"
+fi
+
+extra_flags="$extra_flags $max_cflags -g"
+
+. "$path/FINISH.sh"
diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed
index 8b90deae622..d4d681937a2 100644
--- a/BitKeeper/etc/collapsed
+++ b/BitKeeper/etc/collapsed
@@ -1 +1,4 @@
44d03f27qNdqJmARzBoP3Is_cN5e0w
+44ec850ac2k4y2Omgr92GiWPBAVKGQ
+44edb86b1iE5knJ97MbliK_3lCiAXA
+44f33f3aj5KW5qweQeekY1LU0E9ZCg
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755
index 00000000000..fd780ec6a13
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,132 @@
+PROJECT(MySql)
+
+# This reads user configuration, generated by configure.js.
+INCLUDE(win/configure.data)
+
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/include/mysql_version.h.in
+ ${CMAKE_SOURCE_DIR}/include/mysql_version.h @ONLY)
+
+# Set standard options
+ADD_DEFINITIONS(-D WITH_MYISAM_STORAGE_ENGINE)
+ADD_DEFINITIONS(-D CMAKE_BUILD)
+ADD_DEFINITIONS(-D HAVE_YASSL)
+
+SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_myisam_plugin")
+
+
+IF(WITH_ARCHIVE_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-D HAVE_ARCHIVE_DB)
+ENDIF(WITH_ARCHIVE_STORAGE_ENGINE)
+
+IF (WITH_HEAP_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-D WITH_HEAP_STORAGE_ENGINE)
+ SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_heap_plugin")
+ENDIF (WITH_HEAP_STORAGE_ENGINE)
+
+IF (WITH_MYISAMMRG_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-D WITH_MYISAMMRG_STORAGE_ENGINE)
+ SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_myisammrg_plugin")
+ENDIF (WITH_MYISAMMRG_STORAGE_ENGINE)
+
+IF(WITH_INNOBASE_STORAGE_ENGINE)
+ CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/innobase/ib_config.h.in
+ ${CMAKE_SOURCE_DIR}/innobase/ib_config.h @ONLY)
+ ADD_DEFINITIONS(-D HAVE_INNOBASE_DB)
+ ADD_DEFINITIONS(-D WITH_INNOBASE_STORAGE_ENGINE)
+ SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_innobase_plugin")
+ENDIF(WITH_INNOBASE_STORAGE_ENGINE)
+
+IF(WITH_FEDERATED_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-D HAVE_FEDERATED_DB)
+ ADD_DEFINITIONS(-D WITH_FEDERATED_STORAGE_ENGINE)
+ SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_federated_plugin")
+ENDIF(WITH_FEDERATED_STORAGE_ENGINE)
+
+IF(WITH_BERKELEY_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-D HAVE_BERKELEY_DB)
+ ADD_DEFINITIONS(-D WITH_BERKELEY_STORAGE_ENGINE)
+ SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_berkeley_plugin")
+ENDIF(WITH_BERKELEY_STORAGE_ENGINE)
+
+IF (WITH_BLACKHOLE_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-D HAVE_BLACKHOLE_DB)
+ENDIF (WITH_BLACKHOLE_STORAGE_ENGINE)
+
+SET(localstatedir "C:\\mysql\\data")
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-huge.cnf.sh
+ ${CMAKE_SOURCE_DIR}/support-files/my-huge.ini @ONLY)
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-innodb-heavy-4G.cnf.sh
+ ${CMAKE_SOURCE_DIR}/support-files/my-innodb-heavy-4G.ini @ONLY)
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-large.cnf.sh
+ ${CMAKE_SOURCE_DIR}/support-files/my-large.ini @ONLY)
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-medium.cnf.sh
+ ${CMAKE_SOURCE_DIR}/support-files/my-medium.ini @ONLY)
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-small.cnf.sh
+ ${CMAKE_SOURCE_DIR}/support-files/my-small.ini @ONLY)
+
+IF(__NT__)
+ ADD_DEFINITIONS(-D __NT__)
+ENDIF(__NT__)
+IF(CYBOZU)
+ ADD_DEFINITIONS(-D CYBOZU)
+ENDIF(CYBOZU)
+
+# in some places we use DBUG_OFF
+SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D DBUG_OFF")
+SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D DBUG_OFF")
+
+IF(CMAKE_GENERATOR MATCHES "Visual Studio 8")
+ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /wd4996")
+ SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /wd4996")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /wd4996")
+ SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /wd4996")
+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 8")
+
+IF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR
+ CMAKE_GENERATOR MATCHES "Visual Studio 8")
+ # replace /MDd with /MTd
+ STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG_INIT
+ ${CMAKE_CXX_FLAGS_DEBUG_INIT})
+ STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG_INIT
+ ${CMAKE_C_FLAGS_DEBUG_INIT})
+ STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE
+ ${CMAKE_C_FLAGS_RELEASE})
+ STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG
+ ${CMAKE_C_FLAGS_DEBUG})
+ STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE
+ ${CMAKE_CXX_FLAGS_RELEASE})
+ STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG
+ ${CMAKE_CXX_FLAGS_DEBUG})
+
+ # remove support for Exception handling
+ STRING(REPLACE "/GX" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+ STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+ STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS_INIT
+ ${CMAKE_CXX_FLAGS_INIT})
+ STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS_DEBUG_INIT
+ ${CMAKE_CXX_FLAGS_DEBUG_INIT})
+ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 7" OR
+ CMAKE_GENERATOR MATCHES "Visual Studio 8")
+
+ADD_DEFINITIONS("-D_WINDOWS -D__WIN__ -D _CRT_SECURE_NO_DEPRECATE")
+
+ADD_SUBDIRECTORY(vio)
+ADD_SUBDIRECTORY(dbug)
+ADD_SUBDIRECTORY(strings)
+ADD_SUBDIRECTORY(regex)
+ADD_SUBDIRECTORY(mysys)
+ADD_SUBDIRECTORY(extra/yassl)
+ADD_SUBDIRECTORY(extra/yassl/taocrypt)
+ADD_SUBDIRECTORY(extra)
+ADD_SUBDIRECTORY(zlib)
+ADD_SUBDIRECTORY(heap)
+ADD_SUBDIRECTORY(myisam)
+ADD_SUBDIRECTORY(myisammrg)
+ADD_SUBDIRECTORY(client)
+ADD_SUBDIRECTORY(bdb)
+ADD_SUBDIRECTORY(innobase)
+ADD_SUBDIRECTORY(sql)
+ADD_SUBDIRECTORY(sql/examples)
+ADD_SUBDIRECTORY(server-tools/instance-manager)
+ADD_SUBDIRECTORY(libmysql)
+ADD_SUBDIRECTORY(tests)
diff --git a/Makefile.am b/Makefile.am
index f0784a9baed..d48f0e24966 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,7 +20,7 @@ AUTOMAKE_OPTIONS = foreign
# These are built from source in the Docs directory
EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \
- README COPYING EXCEPTIONS-CLIENT
+ README COPYING EXCEPTIONS-CLIENT CMakeLists.txt
SUBDIRS = . include @docs_dirs@ @zlib_dir@ @yassl_dir@ \
@readline_topdir@ sql-common \
@thread_dirs@ pstack \
@@ -33,7 +33,7 @@ DIST_SUBDIRS = . include @docs_dirs@ zlib \
@thread_dirs@ pstack \
@sql_union_dirs@ scripts @man_dirs@ tests SSL\
BUILD netware os2 @libmysqld_dirs@ \
- @bench_dirs@ support-files @tools_dirs@
+ @bench_dirs@ support-files @tools_dirs@ win
# Run these targets before any others, also make part of clean target,
# to make sure we create new links after a clean.
diff --git a/VC++Files/mysql.sln b/VC++Files/mysql.sln
index bd0cae1d5d8..1e3a33b8eb4 100644
--- a/VC++Files/mysql.sln
+++ b/VC++Files/mysql.sln
@@ -174,7 +174,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlimport", "client\mysql
{44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_upgrade", "client\mysql_upgrade.vcproj", "{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysql_upgrade", "client\mysql_upgrade.vcproj", "{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}"
ProjectSection(ProjectDependencies) = postProject
{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB} = {BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}
{26383276-4843-494B-8BE0-8936ED3EBAAB} = {26383276-4843-494B-8BE0-8936ED3EBAAB}
@@ -990,6 +990,33 @@ Global
{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro nt.Build.0 = Release|Win32
{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.Release.ActiveCfg = Release|Win32
{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.Release.Build.0 = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.classic.ActiveCfg = classic|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.classic.Build.0 = classic|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.classic nt.ActiveCfg = classic|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.classic nt.Build.0 = classic|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Debug.ActiveCfg = Debug|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Debug.Build.0 = Debug|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Embedded_Classic.ActiveCfg = classic|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Embedded_Debug.ActiveCfg = Debug|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Embedded_Pro.ActiveCfg = classic|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Embedded_ProGPL.ActiveCfg = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Embedded_Release.ActiveCfg = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Max.ActiveCfg = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Max.Build.0 = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Max nt.ActiveCfg = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Max nt.Build.0 = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.nt.ActiveCfg = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.nt.Build.0 = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro.ActiveCfg = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro.Build.0 = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro gpl.ActiveCfg = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro gpl.Build.0 = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro gpl nt.ActiveCfg = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro gpl nt.Build.0 = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro nt.ActiveCfg = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.pro nt.Build.0 = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Release.ActiveCfg = Release|Win32
+ {AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3A}.Release.Build.0 = Release|Win32
{94B86159-C581-42CD-825D-C69CBC237E5C}.classic.ActiveCfg = Release|Win32
{94B86159-C581-42CD-825D-C69CBC237E5C}.classic.Build.0 = Release|Win32
{94B86159-C581-42CD-825D-C69CBC237E5C}.classic nt.ActiveCfg = Release|Win32
diff --git a/bdb/CMakeLists.txt b/bdb/CMakeLists.txt
new file mode 100755
index 00000000000..c5dd60852d4
--- /dev/null
+++ b/bdb/CMakeLists.txt
@@ -0,0 +1,44 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/bdb/build_win32
+ ${CMAKE_SOURCE_DIR}/bdb/dbinc
+ ${CMAKE_SOURCE_DIR}/bdb)
+
+# BDB needs a number of source files that are auto-generated by the unix
+# configure. So to build BDB, it is necessary to copy these over to the Windows
+# bitkeeper tree, or to use a source .tar.gz package which already has these
+# files.
+ADD_LIBRARY(bdb btree/bt_compare.c btree/bt_conv.c btree/bt_curadj.c btree/bt_cursor.c
+ btree/bt_delete.c btree/bt_method.c btree/bt_open.c btree/bt_put.c btree/bt_rec.c
+ btree/bt_reclaim.c btree/bt_recno.c btree/bt_rsearch.c btree/bt_search.c
+ btree/bt_split.c btree/bt_stat.c btree/bt_upgrade.c btree/bt_verify.c btree/btree_auto.c
+ db/crdel_auto.c db/crdel_rec.c db/db.c db/db_am.c db/db_auto.c common/db_byteorder.c
+ db/db_cam.c db/db_conv.c db/db_dispatch.c db/db_dup.c common/db_err.c common/db_getlong.c
+ common/db_idspace.c db/db_iface.c db/db_join.c common/db_log2.c db/db_meta.c
+ db/db_method.c db/db_open.c db/db_overflow.c db/db_pr.c db/db_rec.c db/db_reclaim.c
+ db/db_remove.c db/db_rename.c db/db_ret.c env/db_salloc.c env/db_shash.c db/db_truncate.c
+ db/db_upg.c db/db_upg_opd.c db/db_vrfy.c db/db_vrfyutil.c dbm/dbm.c dbreg/dbreg.c
+ dbreg/dbreg_auto.c dbreg/dbreg_rec.c dbreg/dbreg_util.c env/env_file.c env/env_method.c
+ env/env_open.c env/env_recover.c env/env_region.c fileops/fileops_auto.c fileops/fop_basic.c
+ fileops/fop_rec.c fileops/fop_util.c hash/hash.c hash/hash_auto.c hash/hash_conv.c
+ hash/hash_dup.c hash/hash_func.c hash/hash_meta.c hash/hash_method.c hash/hash_open.c
+ hash/hash_page.c hash/hash_rec.c hash/hash_reclaim.c hash/hash_stat.c hash/hash_upgrade.c
+ hash/hash_verify.c hmac/hmac.c hsearch/hsearch.c lock/lock.c lock/lock_deadlock.c
+ lock/lock_method.c lock/lock_region.c lock/lock_stat.c lock/lock_util.c log/log.c
+ log/log_archive.c log/log_compare.c log/log_get.c log/log_method.c log/log_put.c
+ mp/mp_alloc.c mp/mp_bh.c mp/mp_fget.c mp/mp_fopen.c mp/mp_fput.c
+ mp/mp_fset.c mp/mp_method.c mp/mp_region.c mp/mp_register.c mp/mp_stat.c mp/mp_sync.c
+ mp/mp_trickle.c mutex/mut_tas.c mutex/mut_win32.c mutex/mutex.c os_win32/os_abs.c
+ os/os_alloc.c os_win32/os_clock.c os_win32/os_config.c os_win32/os_dir.c os_win32/os_errno.c
+ os_win32/os_fid.c os_win32/os_fsync.c os_win32/os_handle.c os/os_id.c os_win32/os_map.c
+ os/os_method.c os/os_oflags.c os_win32/os_open.c os/os_region.c os_win32/os_rename.c
+ os/os_root.c os/os_rpath.c os_win32/os_rw.c os_win32/os_seek.c os_win32/os_sleep.c
+ os_win32/os_spin.c os_win32/os_stat.c os/os_tmpdir.c os_win32/os_type.c os/os_unlink.c
+ qam/qam.c qam/qam_auto.c qam/qam_conv.c qam/qam_files.c qam/qam_method.c qam/qam_open.c
+ qam/qam_rec.c qam/qam_stat.c qam/qam_upgrade.c qam/qam_verify.c rep/rep_method.c
+ rep/rep_record.c rep/rep_region.c rep/rep_util.c hmac/sha1.c
+ clib/strcasecmp.c txn/txn.c txn/txn_auto.c txn/txn_method.c txn/txn_rec.c
+ txn/txn_recover.c txn/txn_region.c txn/txn_stat.c txn/txn_util.c common/util_log.c
+ common/util_sig.c xa/xa.c xa/xa_db.c xa/xa_map.c)
+
diff --git a/bdb/Makefile.in b/bdb/Makefile.in
index c83d40ac8b2..d40fffed769 100644
--- a/bdb/Makefile.in
+++ b/bdb/Makefile.in
@@ -23,7 +23,7 @@ top_srcdir = @top_srcdir@
# distdir and top_distdir are set by the calling Makefile
bdb_build = build_unix
-files = LICENSE Makefile Makefile.in README
+files = LICENSE Makefile Makefile.in README CMakeLists.txt
subdirs = btree build_vxworks build_win32 clib common cxx db dbinc \
dbinc_auto db185 db_archive db_checkpoint db_deadlock db_dump \
db_dump185 db_load db_printlog db_recover db_stat db_upgrade \
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
new file mode 100755
index 00000000000..3e7f1a48c70
--- /dev/null
+++ b/client/CMakeLists.txt
@@ -0,0 +1,79 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+# The old Windows build method used renamed (.cc -> .cpp) source files, fails
+# in #include in mysqlbinlog.cc. So disable that using the USING_CMAKE define.
+ADD_DEFINITIONS(-DUSING_CMAKE)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_SOURCE_DIR}/zlib
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include
+ ${CMAKE_SOURCE_DIR}/libmysql
+ ${CMAKE_SOURCE_DIR}/regex
+ ${CMAKE_SOURCE_DIR}/mysys
+ ${CMAKE_SOURCE_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/strings)
+
+ADD_LIBRARY(mysqlclient ../mysys/array.c ../strings/bchange.c ../strings/bmove.c
+ ../strings/bmove_upp.c ../mysys/charset-def.c ../mysys/charset.c
+ ../sql-common/client.c ../strings/ctype-big5.c ../strings/ctype-bin.c
+ ../strings/ctype-cp932.c ../strings/ctype-czech.c ../strings/ctype-euc_kr.c
+ ../strings/ctype-eucjpms.c ../strings/ctype-extra.c ../strings/ctype-gb2312.c
+ ../strings/ctype-gbk.c ../strings/ctype-latin1.c ../strings/ctype-mb.c
+ ../strings/ctype-simple.c ../strings/ctype-sjis.c ../strings/ctype-tis620.c
+ ../strings/ctype-uca.c ../strings/ctype-ucs2.c ../strings/ctype-ujis.c
+ ../strings/ctype-utf8.c ../strings/ctype-win1250ch.c ../strings/ctype.c
+ ../mysys/default.c ../libmysql/errmsg.c ../mysys/errors.c
+ ../libmysql/get_password.c ../strings/int2str.c ../strings/is_prefix.c
+ ../libmysql/libmysql.c ../mysys/list.c ../strings/llstr.c
+ ../strings/longlong2str.c ../libmysql/manager.c ../mysys/mf_cache.c
+ ../mysys/mf_dirname.c ../mysys/mf_fn_ext.c ../mysys/mf_format.c
+ ../mysys/mf_iocache.c ../mysys/mf_iocache2.c ../mysys/mf_loadpath.c
+ ../mysys/mf_pack.c ../mysys/mf_path.c ../mysys/mf_tempfile.c ../mysys/mf_unixpath.c
+ ../mysys/mf_wcomp.c ../mysys/mulalloc.c ../mysys/my_access.c ../mysys/my_alloc.c
+ ../mysys/my_chsize.c ../mysys/my_compress.c ../mysys/my_create.c
+ ../mysys/my_delete.c ../mysys/my_div.c ../mysys/my_error.c ../mysys/my_file.c
+ ../mysys/my_fopen.c ../mysys/my_fstream.c ../mysys/my_gethostbyname.c
+ ../mysys/my_getopt.c ../mysys/my_getwd.c ../mysys/my_init.c ../mysys/my_lib.c
+ ../mysys/my_malloc.c ../mysys/my_messnc.c ../mysys/my_net.c ../mysys/my_once.c
+ ../mysys/my_open.c ../mysys/my_pread.c ../mysys/my_pthread.c ../mysys/my_read.c
+ ../mysys/my_realloc.c ../mysys/my_rename.c ../mysys/my_seek.c
+ ../mysys/my_static.c ../strings/my_strtoll10.c ../mysys/my_symlink.c
+ ../mysys/my_symlink2.c ../mysys/my_thr_init.c ../sql-common/my_time.c
+ ../strings/my_vsnprintf.c ../mysys/my_wincond.c ../mysys/my_winthread.c
+ ../mysys/my_write.c ../sql/net_serv.cc ../sql-common/pack.c ../sql/password.c
+ ../mysys/safemalloc.c ../mysys/sha1.c ../strings/str2int.c
+ ../strings/str_alloc.c ../strings/strcend.c ../strings/strcont.c ../strings/strend.c
+ ../strings/strfill.c ../mysys/string.c ../strings/strinstr.c ../strings/strmake.c
+ ../strings/strmov.c ../strings/strnlen.c ../strings/strnmov.c ../strings/strtod.c
+ ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c
+ ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c
+ ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c)
+
+ADD_DEPENDENCIES(mysqlclient GenError)
+ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc)
+LINK_DIRECTORIES(${MYSQL_BINARY_DIR}/mysys ${MYSQL_BINARY_DIR}/zlib)
+TARGET_LINK_LIBRARIES(mysql mysqlclient mysys yassl taocrypt zlib dbug wsock32)
+
+ADD_EXECUTABLE(mysqltest mysqltest.c)
+TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys yassl taocrypt zlib dbug regex wsock32)
+
+ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)
+TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient dbug yassl taocrypt zlib wsock32)
+
+ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c)
+TARGET_LINK_LIBRARIES(mysqldump mysqlclient mysys dbug yassl taocrypt zlib wsock32)
+
+ADD_EXECUTABLE(mysqlimport mysqlimport.c)
+TARGET_LINK_LIBRARIES(mysqlimport mysqlclient mysys dbug yassl taocrypt zlib wsock32)
+
+ADD_EXECUTABLE(mysqlshow mysqlshow.c)
+TARGET_LINK_LIBRARIES(mysqlshow mysqlclient mysys dbug yassl taocrypt zlib wsock32)
+
+ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc ../mysys/mf_tempdir.c ../mysys/my_new.cc
+ ../mysys/my_bit.c ../mysys/my_bitmap.c
+ ../mysys/base64.c)
+TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient dbug yassl taocrypt zlib wsock32)
+
+ADD_EXECUTABLE(mysqladmin mysqladmin.cc)
+TARGET_LINK_LIBRARIES(mysqladmin mysqlclient mysys dbug yassl taocrypt zlib wsock32)
+
diff --git a/client/Makefile.am b/client/Makefile.am
index b80357f68ea..d3c320db56c 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -60,6 +60,8 @@ DEFS = -DUNDEF_THREADS_HACK \
-DDEFAULT_MYSQL_HOME="\"$(prefix)\"" \
-DDATADIR="\"$(localstatedir)\""
+EXTRA_DIST = get_password.c CMakeLists.txt
+
link_sources:
for f in $(sql_src) ; do \
rm -f $$f; \
diff --git a/client/mysql.cc b/client/mysql.cc
index 6af9be965bb..2ba9e896747 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1974,6 +1974,9 @@ com_charset(String *buffer __attribute__((unused)), char *line)
if (new_cs)
{
charset_info= new_cs;
+ mysql_set_character_set(&mysql, charset_info->csname);
+ default_charset= (char *)charset_info->csname;
+ default_charset_used= 1;
put_info("Charset changed", INFO_INFO);
}
else put_info("Charset is not found", INFO_INFO);
@@ -2351,9 +2354,14 @@ print_table_data(MYSQL_RES *result)
(void) tee_fputs("|", PAGER);
for (uint off=0; (field = mysql_fetch_field(result)) ; off++)
{
- tee_fprintf(PAGER, " %-*s |",(int) min(field->max_length,
+ uint name_length= (uint) strlen(field->name);
+ uint numcells= charset_info->cset->numcells(charset_info,
+ field->name,
+ field->name + name_length);
+ uint display_length= field->max_length + name_length - numcells;
+ tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
MAX_COLUMN_LENGTH),
- field->name);
+ field->name);
num_flag[off]= IS_NUM(field->type);
not_null_flag[off]= IS_NOT_NULL(field->flags);
}
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index c68f8777624..9a73263f558 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -157,17 +157,29 @@ static int create_defaults_file(const char *path, const char *our_defaults_path)
File our_defaults_file, defaults_file;
char buffer[512];
char *buffer_end;
+ int failed_to_open_count= 0;
int error;
/* check if the defaults file is needed at all */
if (!opt_password)
return 0;
- defaults_file= my_open(path, O_BINARY | O_CREAT | O_WRONLY,
+retry_open:
+ defaults_file= my_open(path, O_BINARY | O_CREAT | O_WRONLY | O_EXCL,
MYF(MY_FAE | MY_WME));
if (defaults_file < 0)
- return 1;
+ {
+ if (failed_to_open_count == 0)
+ {
+ remove(path);
+ failed_to_open_count+= 1;
+ goto retry_open;
+ }
+ else
+ return 1;
+ }
+
upgrade_defaults_created= 1;
if (our_defaults_path)
{
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 9cecdb4eafc..c04c2ecabd6 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -1490,14 +1490,13 @@ int main(int argc, char** argv)
the server
*/
-#ifdef __WIN__
#include "my_decimal.h"
#include "decimal.c"
+
+#if defined(__WIN__) && !defined(CMAKE_BUILD)
#include "my_decimal.cpp"
#include "log_event.cpp"
#else
-#include "my_decimal.h"
-#include "decimal.c"
#include "my_decimal.cc"
#include "log_event.cc"
#endif
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 5ecf334c9f7..e774a07295b 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -417,7 +417,9 @@ static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row,
int string_value);
static int dump_selected_tables(char *db, char **table_names, int tables);
static int dump_all_tables_in_db(char *db);
-static int init_dumping(char *);
+static int init_dumping_views(char *);
+static int init_dumping_tables(char *);
+static int init_dumping(char *, int init_func(char*));
static int dump_databases(char **);
static int dump_all_databases();
static char *quote_name(const char *name, char *buff, my_bool force);
@@ -848,8 +850,9 @@ static int get_options(int *argc, char ***argv)
static void DB_error(MYSQL *mysql, const char *when)
{
DBUG_ENTER("DB_error");
- my_printf_error(0,"Got error: %d: %s %s", MYF(0),
- mysql_errno(mysql), mysql_error(mysql), when);
+ fprintf(stderr, "%s: Got error: %d: %s %s\n", my_progname,
+ mysql_errno(mysql), mysql_error(mysql), when);
+ fflush(stderr);
safe_exit(EX_MYSQLERR);
DBUG_VOID_RETURN;
} /* DB_error */
@@ -877,8 +880,9 @@ static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res,
if (mysql_query(mysql_con, query) ||
(res && !((*res)= mysql_store_result(mysql_con))))
{
- my_printf_error(0, "Couldn't execute '%s': %s (%d)", MYF(0),
- query, mysql_error(mysql_con), mysql_errno(mysql_con));
+ fprintf(stderr, "%s: Couldn't execute '%s': %s (%d)\n",
+ my_progname, query,
+ mysql_error(mysql_con), mysql_errno(mysql_con));
safe_exit(EX_MYSQLERR);
return 1;
}
@@ -2232,7 +2236,10 @@ static void dump_table(char *table, char *db)
check_io(md_result_file);
}
if (mysql_query_with_error_report(mysql, 0, query))
+ {
DB_error(mysql, "when retrieving data from server");
+ goto err;
+ }
if (quick)
res=mysql_use_result(mysql);
else
@@ -2635,7 +2642,76 @@ static int dump_databases(char **db_names)
} /* dump_databases */
-static int init_dumping(char *database)
+/*
+View Specific database initalization.
+
+SYNOPSIS
+ init_dumping_views
+ qdatabase quoted name of the database
+
+RETURN VALUES
+ 0 Success.
+ 1 Failure.
+*/
+int init_dumping_views(char *qdatabase)
+{
+ return 0;
+} /* init_dumping_views */
+
+
+/*
+Table Specific database initalization.
+
+SYNOPSIS
+ init_dumping_tables
+ qdatabase quoted name of the database
+
+RETURN VALUES
+ 0 Success.
+ 1 Failure.
+*/
+int init_dumping_tables(char *qdatabase)
+{
+ if (!opt_create_db)
+ {
+ char qbuf[256];
+ MYSQL_ROW row;
+ MYSQL_RES *dbinfo;
+
+ my_snprintf(qbuf, sizeof(qbuf),
+ "SHOW CREATE DATABASE IF NOT EXISTS %s",
+ qdatabase);
+
+ if (mysql_query(mysql, qbuf) || !(dbinfo = mysql_store_result(mysql)))
+ {
+ /* Old server version, dump generic CREATE DATABASE */
+ if (opt_drop_database)
+ fprintf(md_result_file,
+ "\n/*!40000 DROP DATABASE IF EXISTS %s;*/\n",
+ qdatabase);
+ fprintf(md_result_file,
+ "\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
+ qdatabase);
+ }
+ else
+ {
+ if (opt_drop_database)
+ fprintf(md_result_file,
+ "\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
+ qdatabase);
+ row = mysql_fetch_row(dbinfo);
+ if (row[1])
+ {
+ fprintf(md_result_file,"\n%s;\n",row[1]);
+ }
+ }
+ }
+
+ return 0;
+} /* init_dumping_tables */
+
+
+static int init_dumping(char *database, int init_func(char*))
{
if (mysql_get_server_version(mysql) >= 50003 &&
!my_strcasecmp(&my_charset_latin1, database, "information_schema"))
@@ -2660,40 +2736,10 @@ static int init_dumping(char *database)
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
check_io(md_result_file);
}
- if (!opt_create_db)
- {
- char qbuf[256];
- MYSQL_ROW row;
- MYSQL_RES *dbinfo;
- my_snprintf(qbuf, sizeof(qbuf),
- "SHOW CREATE DATABASE IF NOT EXISTS %s",
- qdatabase);
+ /* Call the view or table specific function */
+ init_func(qdatabase);
- if (mysql_query(mysql, qbuf) || !(dbinfo = mysql_store_result(mysql)))
- {
- /* Old server version, dump generic CREATE DATABASE */
- if (opt_drop_database)
- fprintf(md_result_file,
- "\n/*!40000 DROP DATABASE IF EXISTS %s;*/\n",
- qdatabase);
- fprintf(md_result_file,
- "\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
- qdatabase);
- }
- else
- {
- if (opt_drop_database)
- fprintf(md_result_file,
- "\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n",
- qdatabase);
- row = mysql_fetch_row(dbinfo);
- if (row[1])
- {
- fprintf(md_result_file,"\n%s;\n",row[1]);
- }
- }
- }
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
check_io(md_result_file);
}
@@ -2725,7 +2771,7 @@ static int dump_all_tables_in_db(char *database)
afterdot= strmov(hash_key, database);
*afterdot++= '.';
- if (init_dumping(database))
+ if (init_dumping(database, init_dumping_tables))
return 1;
if (opt_xml)
print_xml_tag1(md_result_file, "", "database name=", database, "\n");
@@ -2797,23 +2843,8 @@ static my_bool dump_all_views_in_db(char *database)
uint numrows;
char table_buff[NAME_LEN*2+3];
- if (mysql_select_db(mysql, database))
- {
- DB_error(mysql, "when selecting the database");
+ if (init_dumping(database, init_dumping_views))
return 1;
- }
- if (opt_databases || opt_alldbs)
- {
- char quoted_database_buf[NAME_LEN*2+3];
- char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
- if (opt_comments)
- {
- fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
- check_io(md_result_file);
- }
- fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
- check_io(md_result_file);
- }
if (opt_xml)
print_xml_tag1(md_result_file, "", "database name=", database, "\n");
if (lock_tables)
@@ -2908,7 +2939,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
char **dump_tables, **pos, **end;
DBUG_ENTER("dump_selected_tables");
- if (init_dumping(db))
+ if (init_dumping(db, init_dumping_tables))
return 1;
init_alloc_root(&root, 8192, 0);
diff --git a/configure.in b/configure.in
index 3430bd8a5b5..34d94b4f7da 100644
--- a/configure.in
+++ b/configure.in
@@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb
-AM_INIT_AUTOMAKE(mysql, 5.0.25)
+AM_INIT_AUTOMAKE(mysql, 5.0.26)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
@@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0
# ndb version
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
-NDB_VERSION_BUILD=25
+NDB_VERSION_BUILD=26
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
@@ -1655,20 +1655,17 @@ AC_ARG_WITH(debug,
if test "$with_debug" = "yes"
then
# Medium debug.
- AC_DEFINE([DBUG_ON], [1], [Use libdbug])
- CFLAGS="$DEBUG_CFLAGS $DEBUG_OPTIMIZE_CC -DSAFE_MUTEX $CFLAGS"
- CXXFLAGS="$DEBUG_CXXFLAGS $DEBUG_OPTIMIZE_CXX -DSAFE_MUTEX $CXXFLAGS"
+ CFLAGS="$DEBUG_CFLAGS $DEBUG_OPTIMIZE_CC -DDBUG_ON -DSAFE_MUTEX $CFLAGS"
+ CXXFLAGS="$DEBUG_CXXFLAGS $DEBUG_OPTIMIZE_CXX -DDBUG_ON -DSAFE_MUTEX $CXXFLAGS"
elif test "$with_debug" = "full"
then
# Full debug. Very slow in some cases
- AC_DEFINE([DBUG_ON], [1], [Use libdbug])
- CFLAGS="$DEBUG_CFLAGS -DSAFE_MUTEX -DSAFEMALLOC $CFLAGS"
- CXXFLAGS="$DEBUG_CXXFLAGS -DSAFE_MUTEX -DSAFEMALLOC $CXXFLAGS"
+ CFLAGS="$DEBUG_CFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC $CFLAGS"
+ CXXFLAGS="$DEBUG_CXXFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC $CXXFLAGS"
else
# Optimized version. No debug
- AC_DEFINE([DBUG_OFF], [1], [Don't use libdbug])
- CFLAGS="$OPTIMIZE_CFLAGS $CFLAGS"
- CXXFLAGS="$OPTIMIZE_CXXFLAGS $CXXFLAGS"
+ CFLAGS="$OPTIMIZE_CFLAGS -DDBUG_OFF $CFLAGS"
+ CXXFLAGS="$OPTIMIZE_CXXFLAGS -DDBUG_OFF $CXXFLAGS"
fi
# Force static compilation to avoid linking problems/get more speed
@@ -2829,6 +2826,7 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl
include/mysql_version.h dnl
cmd-line-utils/Makefile dnl
cmd-line-utils/libedit/Makefile dnl
+ win/Makefile dnl
zlib/Makefile dnl
cmd-line-utils/readline/Makefile)
AC_CONFIG_COMMANDS([default], , test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h)
diff --git a/dbug/CMakeLists.txt b/dbug/CMakeLists.txt
new file mode 100755
index 00000000000..fe20fdd3db6
--- /dev/null
+++ b/dbug/CMakeLists.txt
@@ -0,0 +1,5 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -D__WIN32__")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+ADD_LIBRARY(dbug dbug.c factorial.c sanity.c)
diff --git a/dbug/Makefile.am b/dbug/Makefile.am
index 38705e63847..57288d32431 100644
--- a/dbug/Makefile.am
+++ b/dbug/Makefile.am
@@ -22,7 +22,8 @@ noinst_HEADERS = dbug_long.h
libdbug_a_SOURCES = dbug.c sanity.c
EXTRA_DIST = example1.c example2.c example3.c \
user.r monty.doc readme.prof dbug_add_tags.pl \
- my_main.c main.c factorial.c dbug_analyze.c
+ my_main.c main.c factorial.c dbug_analyze.c \
+ CMakeLists.txt
NROFF_INC = example1.r example2.r example3.r main.r \
factorial.r output1.r output2.r output3.r \
output4.r output5.r
diff --git a/dbug/dbug.c b/dbug/dbug.c
index 575481305e7..c991daf3617 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -66,13 +66,10 @@
* Check of malloc on entry/exit (option "S")
*/
-#include <my_global.h>
-
-/* This file won't compile unless DBUG_OFF is undefined locally */
#ifdef DBUG_OFF
#undef DBUG_OFF
#endif
-
+#include <my_global.h>
#include <m_string.h>
#include <errno.h>
#if defined(MSDOS) || defined(__WIN__)
diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt
new file mode 100755
index 00000000000..50e0f04eb14
--- /dev/null
+++ b/extra/CMakeLists.txt
@@ -0,0 +1,32 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+
+ADD_EXECUTABLE(comp_err comp_err.c)
+TARGET_LINK_LIBRARIES(comp_err dbug mysys strings wsock32)
+
+GET_TARGET_PROPERTY(COMP_ERR_EXE comp_err LOCATION)
+
+ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/include/mysqld_error.h
+ COMMAND ${COMP_ERR_EXE}
+ --charset=${PROJECT_SOURCE_DIR}/sql/share/charsets
+ --out-dir=${PROJECT_SOURCE_DIR}/sql/share/
+ --header_file=${PROJECT_SOURCE_DIR}/include/mysqld_error.h
+ --name_file=${PROJECT_SOURCE_DIR}/include/mysqld_ername.h
+ --state_file=${PROJECT_SOURCE_DIR}/include/sql_state.h
+ --in_file=${PROJECT_SOURCE_DIR}/sql/share/errmsg.txt
+ DEPENDS comp_err ${PROJECT_SOURCE_DIR}/sql/share/errmsg.txt)
+
+ADD_CUSTOM_TARGET(GenError
+ ALL
+ DEPENDS ${PROJECT_SOURCE_DIR}/include/mysqld_error.h)
+
+ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+TARGET_LINK_LIBRARIES(my_print_defaults strings mysys dbug taocrypt odbc32 odbccp32 wsock32)
+
+ADD_EXECUTABLE(perror perror.c)
+TARGET_LINK_LIBRARIES(perror strings mysys dbug wsock32)
+
+ADD_EXECUTABLE(replace replace.c)
+TARGET_LINK_LIBRARIES(replace strings mysys dbug wsock32)
diff --git a/extra/Makefile.am b/extra/Makefile.am
index c0ad75059df..0de513ba15a 100644
--- a/extra/Makefile.am
+++ b/extra/Makefile.am
@@ -43,6 +43,7 @@ $(top_builddir)/include/sql_state.h: $(top_builddir)/include/mysqld_error.h
bin_PROGRAMS = replace comp_err perror resolveip my_print_defaults \
resolve_stack_dump mysql_waitpid innochecksum
noinst_PROGRAMS = charset2html
+EXTRA_DIST = CMakeLists.txt
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/extra/comp_err.c b/extra/comp_err.c
index 65fc131a5fc..14774c87a28 100644
--- a/extra/comp_err.c
+++ b/extra/comp_err.c
@@ -188,8 +188,9 @@ int main(int argc, char *argv[])
DBUG_RETURN(1);
}
clean_up(lang_head, error_head);
+ DBUG_LEAVE; /* we can't call my_end after DBUG_RETURN */
my_end(info_flag ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
- DBUG_RETURN(0);
+ return(0);
}
}
diff --git a/extra/yassl/CMakeLists.txt b/extra/yassl/CMakeLists.txt
new file mode 100755
index 00000000000..e5429876072
--- /dev/null
+++ b/extra/yassl/CMakeLists.txt
@@ -0,0 +1,6 @@
+ADD_DEFINITIONS("-DWIN32 -D_LIB -DYASSL_PREFIX")
+
+INCLUDE_DIRECTORIES(include taocrypt/include mySTL)
+ADD_LIBRARY(yassl src/buffer.cpp src/cert_wrapper.cpp src/crypto_wrapper.cpp src/handshake.cpp src/lock.cpp
+ src/log.cpp src/socket_wrapper.cpp src/ssl.cpp src/timer.cpp src/yassl_error.cpp
+ src/yassl_imp.cpp src/yassl_int.cpp)
diff --git a/extra/yassl/Makefile.am b/extra/yassl/Makefile.am
index d0415012767..12a7da1085b 100644
--- a/extra/yassl/Makefile.am
+++ b/extra/yassl/Makefile.am
@@ -1,2 +1,2 @@
SUBDIRS = taocrypt src testsuite
-EXTRA_DIST = yassl.dsp yassl.dsw $(wildcard mySTL/*.hpp)
+EXTRA_DIST = yassl.dsp yassl.dsw $(wildcard mySTL/*.hpp) CMakeLists.txt
diff --git a/extra/yassl/include/openssl/generate_prefix_files.pl b/extra/yassl/include/openssl/generate_prefix_files.pl
index b921ee11e9a..da591b31332 100755
--- a/extra/yassl/include/openssl/generate_prefix_files.pl
+++ b/extra/yassl/include/openssl/generate_prefix_files.pl
@@ -30,7 +30,7 @@ sub generate_prefix($$)
next;
}
- if ( /^\s*[a-zA-Z0-9*_ ]+\s+([_a-zA-Z0-9]+)\s*\(/ )
+ if ( /^\s*[a-zA-Z0-9*_ ]+\s+\*?([_a-zA-Z0-9]+)\s*\(/ )
{
print OUT "#define $1 ya$1\n";
}
diff --git a/extra/yassl/include/openssl/prefix_ssl.h b/extra/yassl/include/openssl/prefix_ssl.h
index 7f815156f47..aa3f799cf80 100644
--- a/extra/yassl/include/openssl/prefix_ssl.h
+++ b/extra/yassl/include/openssl/prefix_ssl.h
@@ -1,5 +1,6 @@
#define Copyright yaCopyright
#define yaSSL_CleanUp yayaSSL_CleanUp
+#define BN_bin2bn yaBN_bin2bn
#define DH_new yaDH_new
#define DH_free yaDH_free
#define RSA_free yaRSA_free
@@ -92,6 +93,12 @@
#define SSL_want_read yaSSL_want_read
#define SSL_want_write yaSSL_want_write
#define SSL_pending yaSSL_pending
+#define SSLv3_method yaSSLv3_method
+#define SSLv3_server_method yaSSLv3_server_method
+#define SSLv3_client_method yaSSLv3_client_method
+#define TLSv1_server_method yaTLSv1_server_method
+#define TLSv1_client_method yaTLSv1_client_method
+#define SSLv23_server_method yaSSLv23_server_method
#define SSL_CTX_use_certificate_file yaSSL_CTX_use_certificate_file
#define SSL_CTX_use_PrivateKey_file yaSSL_CTX_use_PrivateKey_file
#define SSL_CTX_set_cipher_list yaSSL_CTX_set_cipher_list
@@ -115,11 +122,13 @@
#define RAND_write_file yaRAND_write_file
#define RAND_load_file yaRAND_load_file
#define RAND_status yaRAND_status
+#define RAND_bytes yaRAND_bytes
#define DES_set_key yaDES_set_key
#define DES_set_odd_parity yaDES_set_odd_parity
#define DES_ecb_encrypt yaDES_ecb_encrypt
#define SSL_CTX_set_default_passwd_cb_userdata yaSSL_CTX_set_default_passwd_cb_userdata
#define SSL_SESSION_free yaSSL_SESSION_free
+#define SSL_peek yaSSL_peek
#define SSL_get_certificate yaSSL_get_certificate
#define SSL_get_privatekey yaSSL_get_privatekey
#define X509_get_pubkey yaX509_get_pubkey
diff --git a/extra/yassl/taocrypt/CMakeLists.txt b/extra/yassl/taocrypt/CMakeLists.txt
new file mode 100755
index 00000000000..0af0a242e5d
--- /dev/null
+++ b/extra/yassl/taocrypt/CMakeLists.txt
@@ -0,0 +1,10 @@
+INCLUDE_DIRECTORIES(../mySTL include)
+
+ADD_LIBRARY(taocrypt src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp src/asn.cpp src/coding.cpp
+ src/des.cpp src/dh.cpp src/dsa.cpp src/file.cpp src/hash.cpp src/integer.cpp src/md2.cpp
+ src/md4.cpp src/md5.cpp src/misc.cpp src/random.cpp src/ripemd.cpp src/rsa.cpp src/sha.cpp
+ include/aes.hpp include/algebra.hpp include/arc4.hpp include/asn.hpp include/block.hpp
+ include/coding.hpp include/des.hpp include/dh.hpp include/dsa.hpp include/dsa.hpp
+ include/error.hpp include/file.hpp include/hash.hpp include/hmac.hpp include/integer.hpp
+ include/md2.hpp include/md5.hpp include/misc.hpp include/modarith.hpp include/modes.hpp
+ include/random.hpp include/ripemd.hpp include/rsa.hpp include/sha.hpp)
diff --git a/extra/yassl/taocrypt/Makefile.am b/extra/yassl/taocrypt/Makefile.am
index ac0c1bc29dd..e232b499cc7 100644
--- a/extra/yassl/taocrypt/Makefile.am
+++ b/extra/yassl/taocrypt/Makefile.am
@@ -1,2 +1,2 @@
SUBDIRS = src test benchmark
-EXTRA_DIST = taocrypt.dsw taocrypt.dsp
+EXTRA_DIST = taocrypt.dsw taocrypt.dsp CMakeLists.txt
diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp
index b8095334789..a33ca4fa432 100644
--- a/extra/yassl/taocrypt/src/misc.cpp
+++ b/extra/yassl/taocrypt/src/misc.cpp
@@ -29,7 +29,7 @@
#include "runtime.hpp"
#include "misc.hpp"
-
+#if !defined(YASSL_MYSQL_COMPATIBLE)
extern "C" {
// for libcurl configure test, these are the signatures they use
@@ -37,6 +37,7 @@ extern "C" {
char CRYPTO_lock() { return 0;}
char CRYPTO_add_lock() { return 0;}
} // extern "C"
+#endif
#ifdef YASSL_PURE_C
diff --git a/heap/CMakeLists.txt b/heap/CMakeLists.txt
new file mode 100755
index 00000000000..db5fb8b2981
--- /dev/null
+++ b/heap/CMakeLists.txt
@@ -0,0 +1,8 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+ADD_LIBRARY(heap _check.c _rectest.c hp_block.c hp_clear.c hp_close.c hp_create.c
+ hp_delete.c hp_extra.c hp_hash.c hp_info.c hp_open.c hp_panic.c
+ hp_rename.c hp_rfirst.c hp_rkey.c hp_rlast.c hp_rnext.c hp_rprev.c
+ hp_rrnd.c hp_rsame.c hp_scan.c hp_static.c hp_update.c hp_write.c)
diff --git a/heap/Makefile.am b/heap/Makefile.am
index 567c7774751..a89c8a4a878 100644
--- a/heap/Makefile.am
+++ b/heap/Makefile.am
@@ -28,6 +28,6 @@ libheap_a_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \
hp_rnext.c hp_rlast.c hp_rprev.c hp_clear.c \
hp_rkey.c hp_block.c \
hp_hash.c _check.c _rectest.c hp_static.c
-
+EXTRA_DIST = CMakeLists.txt
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/include/my_dbug.h b/include/my_dbug.h
index 6e60b599f53..bf2e8d9969b 100644
--- a/include/my_dbug.h
+++ b/include/my_dbug.h
@@ -97,6 +97,7 @@ extern void _db_unlock_file(void);
#define DBUG_UNLOCK_FILE
#define DBUG_OUTPUT(A)
#define DBUG_ASSERT(A) {}
+#define DBUG_LEAVE
#endif
#ifdef __cplusplus
}
diff --git a/include/mysql.h b/include/mysql.h
index 72e5c457d5a..ae4a8222c5b 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -165,7 +165,6 @@ struct st_mysql_options {
char *ssl_ca; /* PEM CA file */
char *ssl_capath; /* PEM directory of CA-s? */
char *ssl_cipher; /* cipher to use */
- my_bool ssl_verify_server_cert; /* if to verify server cert */
char *shared_memory_base_name;
unsigned long max_allowed_packet;
my_bool use_ssl; /* if to use SSL or not */
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 60e726396cb..b1dd6152cf4 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -26,6 +26,9 @@
#define USERNAME_LENGTH 16
#define SERVER_VERSION_LENGTH 60
#define SQLSTATE_LENGTH 5
+#define SYSTEM_CHARSET_MBMAXLEN 3
+#define NAME_BYTE_LEN NAME_LEN*SYSTEM_CHARSET_MBMAXLEN
+#define USERNAME_BYTE_LENGTH USERNAME_LENGTH*SYSTEM_CHARSET_MBMAXLEN
/*
USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
@@ -33,7 +36,7 @@
MySQL standard format:
user_name_part@host_name_part\0
*/
-#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_LENGTH + 2
+#define USER_HOST_BUFF_SIZE HOSTNAME_LENGTH + USERNAME_BYTE_LENGTH + 2
#define LOCAL_HOST "localhost"
#define LOCAL_HOST_NAMEDPIPE "."
@@ -134,8 +137,10 @@ enum enum_server_command
#define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */
#define CLIENT_RESERVED 16384 /* Old flag for 4.1 protocol */
#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */
-#define CLIENT_MULTI_STATEMENTS 65536 /* Enable/disable multi-stmt support */
-#define CLIENT_MULTI_RESULTS 131072 /* Enable/disable multi-results */
+#define CLIENT_MULTI_STATEMENTS (((ulong) 1) << 16) /* Enable/disable multi-stmt support */
+#define CLIENT_MULTI_RESULTS (((ulong) 1) << 17) /* Enable/disable multi-results */
+
+#define CLIENT_SSL_VERIFY_SERVER_CERT (((ulong) 1) << 30)
#define CLIENT_REMEMBER_OPTIONS (((ulong) 1) << 31)
#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */
@@ -209,7 +214,13 @@ typedef struct st_net {
char last_error[MYSQL_ERRMSG_SIZE], sqlstate[SQLSTATE_LENGTH+1];
unsigned int last_errno;
unsigned char error;
+
+ /*
+ 'query_cache_query' should be accessed only via query cache
+ functions and methods to maintain proper locking.
+ */
gptr query_cache_query;
+
my_bool report_error; /* We should report error (we have unreported error) */
my_bool return_errno;
} NET;
diff --git a/innobase/CMakeLists.txt b/innobase/CMakeLists.txt
new file mode 100755
index 00000000000..f9661963d56
--- /dev/null
+++ b/innobase/CMakeLists.txt
@@ -0,0 +1,35 @@
+#SET(CMAKE_CXX_FLAGS_DEBUG "-DSAFEMALLOC -DSAFE_MUTEX")
+#SET(CMAKE_C_FLAGS_DEBUG "-DSAFEMALLOC -DSAFE_MUTEX")
+ADD_DEFINITIONS(-DMYSQL_SERVER -D_WIN32 -DWIN32 -D_LIB)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include include)
+ADD_LIBRARY(innobase btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
+ buf/buf0buf.c buf/buf0flu.c buf/buf0lru.c buf/buf0rea.c
+ data/data0data.c data/data0type.c
+ dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c dict/dict0load.c dict/dict0mem.c
+ dyn/dyn0dyn.c
+ eval/eval0eval.c eval/eval0proc.c
+ fil/fil0fil.c
+ fsp/fsp0fsp.c
+ fut/fut0fut.c fut/fut0lst.c
+ ha/ha0ha.c ha/hash0hash.c
+ ibuf/ibuf0ibuf.c
+ pars/lexyy.c pars/pars0grm.c pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c
+ lock/lock0lock.c
+ log/log0log.c log/log0recv.c
+ mach/mach0data.c
+ mem/mem0mem.c mem/mem0pool.c
+ mtr/mtr0log.c mtr/mtr0mtr.c
+ os/os0file.c os/os0proc.c os/os0sync.c os/os0thread.c
+ page/page0cur.c page/page0page.c
+ que/que0que.c
+ read/read0read.c
+ rem/rem0cmp.c rem/rem0rec.c
+ row/row0ins.c row/row0mysql.c row/row0purge.c row/row0row.c row/row0sel.c row/row0uins.c
+ row/row0umod.c row/row0undo.c row/row0upd.c row/row0vers.c
+ srv/srv0que.c srv/srv0srv.c srv/srv0start.c
+ sync/sync0arr.c sync/sync0rw.c sync/sync0sync.c
+ thr/thr0loc.c
+ trx/trx0purge.c trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c trx/trx0sys.c trx/trx0trx.c trx/trx0undo.c
+ usr/usr0sess.c
+ ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c )
diff --git a/innobase/Makefile.am b/innobase/Makefile.am
index 8ff90d16a2c..10e793396d8 100644
--- a/innobase/Makefile.am
+++ b/innobase/Makefile.am
@@ -25,6 +25,7 @@ noinst_HEADERS = ib_config.h
SUBDIRS = os ut btr buf data dict dyn eval fil fsp fut \
ha ibuf include lock log mach mem mtr page \
pars que read rem row srv sync thr trx usr
+EXTRA_DIST = CMakeLists.txt
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
new file mode 100755
index 00000000000..d12b6ca6c10
--- /dev/null
+++ b/libmysql/CMakeLists.txt
@@ -0,0 +1,54 @@
+# Need to set USE_TLS, since __declspec(thread) approach to thread local
+# storage does not work properly in DLLs.
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_SOURCE_DIR}/zlib
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include
+ ${CMAKE_SOURCE_DIR}/libmysql
+ ${CMAKE_SOURCE_DIR}/regex
+ ${CMAKE_SOURCE_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/strings)
+
+ADD_LIBRARY(libmysql SHARED dll.c libmysql.def
+ ../mysys/array.c ../strings/bchange.c ../strings/bmove.c
+ ../strings/bmove_upp.c ../mysys/charset-def.c ../mysys/charset.c
+ ../sql-common/client.c ../strings/ctype-big5.c ../strings/ctype-bin.c
+ ../strings/ctype-cp932.c ../strings/ctype-czech.c ../strings/ctype-euc_kr.c
+ ../strings/ctype-eucjpms.c ../strings/ctype-extra.c ../strings/ctype-gb2312.c
+ ../strings/ctype-gbk.c ../strings/ctype-latin1.c ../strings/ctype-mb.c
+ ../strings/ctype-simple.c ../strings/ctype-sjis.c ../strings/ctype-tis620.c
+ ../strings/ctype-uca.c ../strings/ctype-ucs2.c ../strings/ctype-ujis.c
+ ../strings/ctype-utf8.c ../strings/ctype-win1250ch.c ../strings/ctype.c
+ ../mysys/default.c ../libmysql/errmsg.c ../mysys/errors.c
+ ../libmysql/get_password.c ../strings/int2str.c ../strings/is_prefix.c
+ ../libmysql/libmysql.c ../mysys/list.c ../strings/llstr.c
+ ../strings/longlong2str.c ../libmysql/manager.c ../mysys/mf_cache.c
+ ../mysys/mf_dirname.c ../mysys/mf_fn_ext.c ../mysys/mf_format.c
+ ../mysys/mf_iocache.c ../mysys/mf_iocache2.c ../mysys/mf_loadpath.c
+ ../mysys/mf_pack.c ../mysys/mf_path.c ../mysys/mf_tempfile.c ../mysys/mf_unixpath.c
+ ../mysys/mf_wcomp.c ../mysys/mulalloc.c ../mysys/my_access.c ../mysys/my_alloc.c
+ ../mysys/my_chsize.c ../mysys/my_compress.c ../mysys/my_create.c
+ ../mysys/my_delete.c ../mysys/my_div.c ../mysys/my_error.c ../mysys/my_file.c
+ ../mysys/my_fopen.c ../mysys/my_fstream.c ../mysys/my_gethostbyname.c
+ ../mysys/my_getopt.c ../mysys/my_getwd.c ../mysys/my_init.c ../mysys/my_lib.c
+ ../mysys/my_malloc.c ../mysys/my_messnc.c ../mysys/my_net.c ../mysys/my_once.c
+ ../mysys/my_open.c ../mysys/my_pread.c ../mysys/my_pthread.c ../mysys/my_read.c
+ ../mysys/my_realloc.c ../mysys/my_rename.c ../mysys/my_seek.c
+ ../mysys/my_static.c ../strings/my_strtoll10.c ../mysys/my_symlink.c
+ ../mysys/my_symlink2.c ../mysys/my_thr_init.c ../sql-common/my_time.c
+ ../strings/my_vsnprintf.c ../mysys/my_wincond.c ../mysys/my_winthread.c
+ ../mysys/my_write.c ../sql/net_serv.cc ../sql-common/pack.c ../sql/password.c
+ ../mysys/safemalloc.c ../mysys/sha1.c ../strings/str2int.c
+ ../strings/str_alloc.c ../strings/strcend.c ../strings/strcont.c ../strings/strend.c
+ ../strings/strfill.c ../mysys/string.c ../strings/strinstr.c ../strings/strmake.c
+ ../strings/strmov.c ../strings/strnlen.c ../strings/strnmov.c ../strings/strtod.c
+ ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c
+ ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c
+ ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c)
+ADD_DEPENDENCIES(libmysql dbug vio mysys strings GenError zlib yassl taocrypt)
+TARGET_LINK_LIBRARIES(libmysql mysys strings wsock32)
+
+ADD_EXECUTABLE(myTest mytest.c)
+TARGET_LINK_LIBRARIES(myTest libmysql)
diff --git a/libmysql/Makefile.am b/libmysql/Makefile.am
index d089d56f38a..5e6c60a007b 100644
--- a/libmysql/Makefile.am
+++ b/libmysql/Makefile.am
@@ -31,7 +31,7 @@ include $(srcdir)/Makefile.shared
libmysqlclient_la_SOURCES = $(target_sources)
libmysqlclient_la_LIBADD = $(target_libadd) $(yassl_las)
libmysqlclient_la_LDFLAGS = $(target_ldflags)
-EXTRA_DIST = Makefile.shared libmysql.def
+EXTRA_DIST = Makefile.shared libmysql.def dll.c mytest.c CMakeLists.txt
noinst_HEADERS = client_settings.h
# This is called from the toplevel makefile
diff --git a/libmysql/mytest.c b/libmysql/mytest.c
new file mode 100644
index 00000000000..2d5c576b72a
--- /dev/null
+++ b/libmysql/mytest.c
@@ -0,0 +1,175 @@
+/*C4*/
+/****************************************************************/
+/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */
+/* Date: 02/18/1998 */
+/* mytest.c : do some testing of the libmySQL.DLL.... */
+/* */
+/* History: */
+/* 02/18/1998 jw3 also sprach zarathustra.... */
+/****************************************************************/
+
+
+#include <windows.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <mysql.h>
+
+#define DEFALT_SQL_STMT "SELECT * FROM db"
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+
+/********************************************************
+**
+** main :-
+**
+********************************************************/
+
+int
+main( int argc, char * argv[] )
+{
+
+ char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], szDB[ 50 ] ;
+ const char *pszT;
+ int i, j, k, l, x ;
+ MYSQL * myData ;
+ MYSQL_RES * res ;
+ MYSQL_FIELD * fd ;
+ MYSQL_ROW row ;
+
+ //....just curious....
+ printf( "sizeof( MYSQL ) == %d\n", (int) sizeof( MYSQL ) ) ;
+ if ( argc == 2 )
+ {
+ strcpy( szDB, argv[ 1 ] ) ;
+ strcpy( szSQL, DEFALT_SQL_STMT ) ;
+ if (!strcmp(szDB,"--debug"))
+ {
+ strcpy( szDB, "mysql" ) ;
+ printf("Some mysql struct information (size and offset):\n");
+ printf("net:\t%3d %3d\n",(int) sizeof(myData->net),
+ (int) offsetof(MYSQL,net));
+ printf("host:\t%3d %3d\n",(int) sizeof(myData->host),
+ (int) offsetof(MYSQL,host));
+ printf("port:\t%3d %3d\n", (int) sizeof(myData->port),
+ (int) offsetof(MYSQL,port));
+ printf("protocol_version:\t%3d %3d\n",
+ (int) sizeof(myData->protocol_version),
+ (int) offsetof(MYSQL,protocol_version));
+ printf("thread_id:\t%3d %3d\n",(int) sizeof(myData->thread_id),
+ (int) offsetof(MYSQL,thread_id));
+ printf("affected_rows:\t%3d %3d\n",(int) sizeof(myData->affected_rows),
+ (int) offsetof(MYSQL,affected_rows));
+ printf("packet_length:\t%3d %3d\n",(int) sizeof(myData->packet_length),
+ (int) offsetof(MYSQL,packet_length));
+ printf("status:\t%3d %3d\n",(int) sizeof(myData->status),
+ (int) offsetof(MYSQL,status));
+ printf("fields:\t%3d %3d\n",(int) sizeof(myData->fields),
+ (int) offsetof(MYSQL,fields));
+ printf("field_alloc:\t%3d %3d\n",(int) sizeof(myData->field_alloc),
+ (int) offsetof(MYSQL,field_alloc));
+ printf("free_me:\t%3d %3d\n",(int) sizeof(myData->free_me),
+ (int) offsetof(MYSQL,free_me));
+ printf("options:\t%3d %3d\n",(int) sizeof(myData->options),
+ (int) offsetof(MYSQL,options));
+ puts("");
+ }
+ }
+ else if ( argc > 2 ) {
+ strcpy( szDB, argv[ 1 ] ) ;
+ strcpy( szSQL, argv[ 2 ] ) ;
+ }
+ else {
+ strcpy( szDB, "mysql" ) ;
+ strcpy( szSQL, DEFALT_SQL_STMT ) ;
+ }
+ //....
+
+ if ( (myData = mysql_init((MYSQL*) 0)) &&
+ mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT,
+ NULL, 0 ) )
+ {
+ myData->reconnect= 1;
+ if ( mysql_select_db( myData, szDB ) < 0 ) {
+ printf( "Can't select the %s database !\n", szDB ) ;
+ mysql_close( myData ) ;
+ return 2 ;
+ }
+ }
+ else {
+ printf( "Can't connect to the mysql server on port %d !\n",
+ MYSQL_PORT ) ;
+ mysql_close( myData ) ;
+ return 1 ;
+ }
+ //....
+ if ( ! mysql_query( myData, szSQL ) ) {
+ res = mysql_store_result( myData ) ;
+ i = (int) mysql_num_rows( res ) ; l = 1 ;
+ printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ;
+ //....we can get the field-specific characteristics here....
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ //....
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Record #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ mysql_free_result( res ) ;
+ }
+ else printf( "Couldn't execute %s on the server !\n", szSQL ) ;
+ //....
+ puts( "==== Diagnostic info ====" ) ;
+ pszT = mysql_get_client_info() ;
+ printf( "Client info: %s\n", pszT ) ;
+ //....
+ pszT = mysql_get_host_info( myData ) ;
+ printf( "Host info: %s\n", pszT ) ;
+ //....
+ pszT = mysql_get_server_info( myData ) ;
+ printf( "Server info: %s\n", pszT ) ;
+ //....
+ res = mysql_list_processes( myData ) ; l = 1 ;
+ if (res)
+ {
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Process #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ }
+ else
+ {
+ printf("Got error %s when retreiving processlist\n",mysql_error(myData));
+ }
+ //....
+ res = mysql_list_tables( myData, "%" ) ; l = 1 ;
+ for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ )
+ strcpy( aszFlds[ x ], fd->name ) ;
+ while ( row = mysql_fetch_row( res ) ) {
+ j = mysql_num_fields( res ) ;
+ printf( "Table #%ld:-\n", l++ ) ;
+ for ( k = 0 ; k < j ; k++ )
+ printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ],
+ (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ;
+ puts( "==============================\n" ) ;
+ }
+ //....
+ pszT = mysql_stat( myData ) ;
+ puts( pszT ) ;
+ //....
+ mysql_close( myData ) ;
+ return 0 ;
+
+}
diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def
index 3895588e02c..0e80681700f 100644
--- a/libmysqld/libmysqld.def
+++ b/libmysqld/libmysqld.def
@@ -163,3 +163,4 @@ EXPORTS
my_charset_bin
my_charset_same
modify_defaults_file
+ mysql_set_server_option
diff --git a/myisam/CMakeLists.txt b/myisam/CMakeLists.txt
new file mode 100755
index 00000000000..3ba7aba4555
--- /dev/null
+++ b/myisam/CMakeLists.txt
@@ -0,0 +1,26 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+ADD_LIBRARY(myisam ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c ft_stem.c
+ ft_stopwords.c ft_update.c mi_cache.c mi_changed.c mi_check.c
+ mi_checksum.c mi_close.c mi_create.c mi_dbug.c mi_delete.c
+ mi_delete_all.c mi_delete_table.c mi_dynrec.c mi_extra.c mi_info.c
+ mi_key.c mi_keycache.c mi_locking.c mi_log.c mi_open.c
+ mi_packrec.c mi_page.c mi_panic.c mi_preload.c mi_range.c mi_rename.c
+ mi_rfirst.c mi_rlast.c mi_rnext.c mi_rnext_same.c mi_rprev.c mi_rrnd.c
+ mi_rsame.c mi_rsamepos.c mi_scan.c mi_search.c mi_static.c mi_statrec.c
+ mi_unique.c mi_update.c mi_write.c rt_index.c rt_key.c rt_mbr.c
+ rt_split.c sort.c sp_key.c ft_eval.h myisamdef.h rt_index.h mi_rkey.c)
+
+ADD_EXECUTABLE(myisam_ftdump myisam_ftdump.c)
+TARGET_LINK_LIBRARIES(myisam_ftdump myisam mysys dbug strings zlib wsock32)
+
+ADD_EXECUTABLE(myisamchk myisamchk.c)
+TARGET_LINK_LIBRARIES(myisamchk myisam mysys dbug strings zlib wsock32)
+
+ADD_EXECUTABLE(myisamlog myisamlog.c)
+TARGET_LINK_LIBRARIES(myisamlog myisam mysys dbug strings zlib wsock32)
+
+ADD_EXECUTABLE(myisampack myisampack.c)
+TARGET_LINK_LIBRARIES(myisampack myisam mysys dbug strings zlib wsock32)
diff --git a/myisam/Makefile.am b/myisam/Makefile.am
index e4327070997..081d7facf3a 100644
--- a/myisam/Makefile.am
+++ b/myisam/Makefile.am
@@ -14,7 +14,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-EXTRA_DIST = mi_test_all.sh mi_test_all.res
+EXTRA_DIST = mi_test_all.sh mi_test_all.res ft_stem.c CMakeLists.txt
pkgdata_DATA = mi_test_all mi_test_all.res
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
diff --git a/myisammrg/CMakeLists.txt b/myisammrg/CMakeLists.txt
new file mode 100755
index 00000000000..83168f6c60c
--- /dev/null
+++ b/myisammrg/CMakeLists.txt
@@ -0,0 +1,9 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+ADD_LIBRARY(myisammrg myrg_close.c myrg_create.c myrg_delete.c myrg_extra.c myrg_info.c
+ myrg_locking.c myrg_open.c myrg_panic.c myrg_queue.c myrg_range.c
+ myrg_rfirst.c myrg_rkey.c myrg_rlast.c myrg_rnext.c myrg_rnext_same.c
+ myrg_rprev.c myrg_rrnd.c myrg_rsame.c myrg_static.c myrg_update.c
+ myrg_write.c)
diff --git a/myisammrg/Makefile.am b/myisammrg/Makefile.am
index 14e3295c1ae..19543927fd2 100644
--- a/myisammrg/Makefile.am
+++ b/myisammrg/Makefile.am
@@ -23,6 +23,6 @@ libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \
myrg_rprev.c myrg_queue.c myrg_write.c myrg_range.c \
myrg_rnext_same.c
-
+EXTRA_DIST = CMakeLists.txt
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index 11bcef10fff..9f54b4fe192 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -34,7 +34,7 @@ benchdir_root= $(prefix)
testdir = $(benchdir_root)/mysql-test
EXTRA_SCRIPTS = mysql-test-run.sh install_test_db.sh valgrind.supp $(PRESCRIPTS)
EXTRA_DIST = $(EXTRA_SCRIPTS)
-GENSCRIPTS = mysql-test-run install_test_db
+GENSCRIPTS = mysql-test-run install_test_db mtr
PRESCRIPTS = mysql-test-run.pl
test_SCRIPTS = $(GENSCRIPTS) $(PRESCRIPTS)
test_DATA = std_data/client-key.pem std_data/client-cert.pem std_data/cacert.pem \
@@ -112,6 +112,11 @@ std_data/server-cert.pem: $(top_srcdir)/SSL/$(@F)
std_data/server-key.pem: $(top_srcdir)/SSL/$(@F)
@RM@ -f $@; @CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
+# mtr - a shortcut for executing mysql-test-run.pl
+mtr:
+ $(RM) -f mtr
+ $(LN_S) mysql-test-run.pl mtr
+
SUFFIXES = .sh
.sh:
diff --git a/mysql-test/include/im_check_env.inc b/mysql-test/include/im_check_env.inc
index 169edbac6b3..019e0984614 100644
--- a/mysql-test/include/im_check_env.inc
+++ b/mysql-test/include/im_check_env.inc
@@ -2,10 +2,6 @@
# that ensure that starting conditions (environment) for the IM-test are as
# expected.
-# Wait for mysqld1 (guarded instance) to start.
-
---exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started
-
# Check the running instances.
--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
@@ -14,6 +10,8 @@
SHOW VARIABLES LIKE 'server_id';
+--source include/not_windows.inc
+
--connection default
# Let IM detect that mysqld1 is online. This delay should be longer than
diff --git a/mysql-test/include/im_check_os.inc b/mysql-test/include/im_check_os.inc
deleted file mode 100644
index 9465115feb5..00000000000
--- a/mysql-test/include/im_check_os.inc
+++ /dev/null
@@ -1,7 +0,0 @@
---connect (dflt_server_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK)
---connection dflt_server_con
-
---source include/not_windows.inc
-
---connection default
---disconnect dflt_server_con
diff --git a/mysql-test/include/loaddata_autocom.inc b/mysql-test/include/loaddata_autocom.inc
new file mode 100644
index 00000000000..e5071c73c49
--- /dev/null
+++ b/mysql-test/include/loaddata_autocom.inc
@@ -0,0 +1,21 @@
+# Test if the engine does autocommit in LOAD DATA INFILE, or not
+# (NDB wants to do, others don't).
+
+eval SET SESSION STORAGE_ENGINE = $engine_type;
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t1 (a text, b text);
+start transaction;
+load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by '''';
+commit;
+select count(*) from t1;
+truncate table t1;
+start transaction;
+load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by '''';
+rollback;
+select count(*) from t1;
+
+drop table t1;
diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl
index ed0395abd9d..009269f382e 100644
--- a/mysql-test/lib/mtr_cases.pl
+++ b/mysql-test/lib/mtr_cases.pl
@@ -82,7 +82,7 @@ sub collect_test_cases ($) {
if ( $mysqld_test_exists and $im_test_exists )
{
- mtr_error("Ambiguos test case name ($tname)");
+ mtr_error("Ambiguous test case name ($tname)");
}
elsif ( ! $mysqld_test_exists and ! $im_test_exists )
{
@@ -154,34 +154,38 @@ sub collect_test_cases ($) {
if ( $::opt_reorder )
{
- @$cases = sort {
- if ( ! $a->{'master_restart'} and ! $b->{'master_restart'} )
- {
- return $a->{'name'} cmp $b->{'name'};
- }
- if ( $a->{'master_restart'} and $b->{'master_restart'} )
- {
- my $cmp= mtr_cmp_opts($a->{'master_opt'}, $b->{'master_opt'});
- if ( $cmp == 0 )
- {
- return $a->{'name'} cmp $b->{'name'};
- }
- else
- {
- return $cmp;
- }
- }
+ my %sort_criteria;
+ my $tinfo;
- if ( $a->{'master_restart'} )
- {
- return 1; # Is greater
- }
- else
- {
- return -1; # Is less
- }
- } @$cases;
+ # Make a mapping of test name to a string that represents how that test
+ # should be sorted among the other tests. Put the most important criterion
+ # first, then a sub-criterion, then sub-sub-criterion, et c.
+ foreach $tinfo (@$cases)
+ {
+ my @this_criteria = ();
+
+ # Append the criteria for sorting, in order of importance.
+ push(@this_criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~"); # Ending with "~" makes empty sort later than filled
+ push(@this_criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0"));
+ push(@this_criteria, "restart=" . ($tinfo->{'master_restart'} ? "1" : "0"));
+ push(@this_criteria, "big_test=" . ($tinfo->{'big_test'} ? "1" : "0"));
+ push(@this_criteria, join("|", sort keys %{$tinfo})); # Group similar things together. The values may differ substantially. FIXME?
+ push(@this_criteria, $tinfo->{'name'}); # Finally, order by the name
+
+ $sort_criteria{$tinfo->{"name"}} = join(" ", @this_criteria);
+ }
+
+ @$cases = sort { $sort_criteria{$a->{"name"}} cmp $sort_criteria{$b->{"name"}}; } @$cases;
+
+### For debugging the sort-order
+# foreach $tinfo (@$cases)
+# {
+# print $sort_criteria{$tinfo->{"name"}};
+# print " -> \t";
+# print $tinfo->{"name"};
+# print "\n";
+# }
}
return $cases;
diff --git a/mysql-test/lib/mtr_io.pl b/mysql-test/lib/mtr_io.pl
index b3da6d97664..bdf91212b59 100644
--- a/mysql-test/lib/mtr_io.pl
+++ b/mysql-test/lib/mtr_io.pl
@@ -19,13 +19,39 @@ sub mtr_tonewfile($@);
##############################################################################
sub mtr_get_pid_from_file ($) {
- my $file= shift;
+ my $pid_file_path= shift;
+ my $TOTAL_ATTEMPTS= 30;
+ my $timeout= 1;
- open(FILE,"<",$file) or mtr_error("can't open file \"$file\": $!");
- my $pid= <FILE>;
- chomp($pid);
- close FILE;
- return $pid;
+ # We should read from the file until we get correct pid. As it is
+ # stated in BUG#21884, pid file can be empty at some moment. So, we should
+ # read it until we get valid data.
+
+ for (my $cur_attempt= 1; $cur_attempt <= $TOTAL_ATTEMPTS; ++$cur_attempt)
+ {
+ mtr_debug("Reading pid file '$pid_file_path' " .
+ "($cur_attempt of $TOTAL_ATTEMPTS)...");
+
+ open(FILE, '<', $pid_file_path)
+ or mtr_error("can't open file \"$pid_file_path\": $!");
+
+ my $pid= <FILE>;
+
+ chomp($pid) if defined $pid;
+
+ close FILE;
+
+ return $pid if defined $pid && $pid ne '';
+
+ mtr_debug("Pid file '$pid_file_path' is empty. " .
+ "Sleeping $timeout second(s)...");
+
+ sleep(1);
+ }
+
+ mtr_error("Pid file '$pid_file_path' is corrupted. " .
+ "Can not retrieve PID in " .
+ ($timeout * $TOTAL_ATTEMPTS) . " seconds.");
}
sub mtr_get_opts_from_file ($) {
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index 0ca16b61fc2..bf869ca91c4 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -20,7 +20,29 @@ sub mtr_record_dead_children ();
sub mtr_exit ($);
sub sleep_until_file_created ($$$);
sub mtr_kill_processes ($);
-sub mtr_kill_process ($$$$);
+sub mtr_ping_mysqld_server ($);
+
+# Private IM-related operations.
+
+sub mtr_im_kill_process ($$$$);
+sub mtr_im_load_pids ($);
+sub mtr_im_terminate ($);
+sub mtr_im_check_alive ($);
+sub mtr_im_check_main_alive ($);
+sub mtr_im_check_angel_alive ($);
+sub mtr_im_check_mysqlds_alive ($);
+sub mtr_im_check_mysqld_alive ($$);
+sub mtr_im_cleanup ($);
+sub mtr_im_rm_file ($);
+sub mtr_im_errlog ($);
+sub mtr_im_kill ($);
+sub mtr_im_wait_for_connection ($$$);
+sub mtr_im_wait_for_mysqld($$$);
+
+# Public IM-related operations.
+
+sub mtr_im_start ($$);
+sub mtr_im_stop ($);
# static in C
sub spawn_impl ($$$$$$$$);
@@ -359,40 +381,54 @@ sub mtr_process_exit_status {
sub mtr_kill_leftovers () {
- # First, kill all masters and slaves that would conflict with
- # this run. Make sure to remove the PID file, if any.
- # FIXME kill IM manager first, else it will restart the servers, how?!
+ mtr_debug("mtr_kill_leftovers(): started.");
+
+ mtr_im_stop($::instance_manager);
+
+ # Kill mysqld servers (masters and slaves) that would conflict with this
+ # run. Make sure to remove the PID file, if any.
+ # Don't touch IM-managed mysqld instances -- they should be stopped by
+ # mtr_im_stop().
+
+ mtr_debug("Collecting mysqld-instances to shutdown...");
my @args;
- for ( my $idx; $idx < 2; $idx++ )
+ for ( my $idx= 0; $idx < 2; $idx++ )
{
- push(@args,{
- pid => 0, # We don't know the PID
- pidfile => $::instance_manager->{'instances'}->[$idx]->{'path_pid'},
- sockfile => $::instance_manager->{'instances'}->[$idx]->{'path_sock'},
- port => $::instance_manager->{'instances'}->[$idx]->{'port'},
- });
- }
+ my $pidfile= $::master->[$idx]->{'path_mypid'};
+ my $sockfile= $::master->[$idx]->{'path_mysock'};
+ my $port= $::master->[$idx]->{'path_myport'};
- for ( my $idx; $idx < 2; $idx++ )
- {
push(@args,{
pid => 0, # We don't know the PID
- pidfile => $::master->[$idx]->{'path_mypid'},
- sockfile => $::master->[$idx]->{'path_mysock'},
- port => $::master->[$idx]->{'path_myport'},
+ pidfile => $pidfile,
+ sockfile => $sockfile,
+ port => $port,
});
+
+ mtr_debug(" - Master mysqld " .
+ "(idx: $idx; pid: '$pidfile'; socket: '$sockfile'; port: $port)");
+ $::master->[$idx]->{'pid'}= 0; # Assume we are done with it
}
- for ( my $idx; $idx < 3; $idx++ )
+ for ( my $idx= 0; $idx < 3; $idx++ )
{
+ my $pidfile= $::slave->[$idx]->{'path_mypid'};
+ my $sockfile= $::slave->[$idx]->{'path_mysock'};
+ my $port= $::slave->[$idx]->{'path_myport'};
+
push(@args,{
pid => 0, # We don't know the PID
- pidfile => $::slave->[$idx]->{'path_mypid'},
- sockfile => $::slave->[$idx]->{'path_mysock'},
- port => $::slave->[$idx]->{'path_myport'},
+ pidfile => $pidfile,
+ sockfile => $sockfile,
+ port => $port,
});
+
+ mtr_debug(" - Slave mysqld " .
+ "(idx: $idx; pid: '$pidfile'; socket: '$sockfile'; port: $port)");
+
+ $::slave->[$idx]->{'pid'}= 0; # Assume we are done with it
}
mtr_mysqladmin_shutdown(\@args, 20);
@@ -413,6 +449,8 @@ sub mtr_kill_leftovers () {
# FIXME $path_run_dir or something
my $rundir= "$::opt_vardir/run";
+ mtr_debug("Processing PID files in directory '$rundir'...");
+
if ( -d $rundir )
{
opendir(RUNDIR, $rundir)
@@ -426,8 +464,12 @@ sub mtr_kill_leftovers () {
if ( -f $pidfile )
{
+ mtr_debug("Processing PID file: '$pidfile'...");
+
my $pid= mtr_get_pid_from_file($pidfile);
+ mtr_debug("Got pid: $pid from file '$pidfile'");
+
# Race, could have been removed between I tested with -f
# and the unlink() below, so I better check again with -f
@@ -438,14 +480,24 @@ sub mtr_kill_leftovers () {
if ( $::glob_cygwin_perl or kill(0, $pid) )
{
+ mtr_debug("There is process with pid $pid -- scheduling for kill.");
push(@pids, $pid); # We know (cygwin guess) it exists
}
+ else
+ {
+ mtr_debug("There is no process with pid $pid -- skipping.");
+ }
}
}
closedir(RUNDIR);
if ( @pids )
{
+ mtr_debug("Killing the following processes with PID files: " .
+ join(' ', @pids) . "...");
+
+ start_reap_all();
+
if ( $::glob_cygwin_perl )
{
# We have no (easy) way of knowing the Cygwin controlling
@@ -459,6 +511,7 @@ sub mtr_kill_leftovers () {
my $retries= 10; # 10 seconds
do
{
+ mtr_debug("Sending SIGKILL to pids: " . join(' ', @pids));
kill(9, @pids);
mtr_debug("Sleep 1 second waiting for processes to die");
sleep(1) # Wait one second
@@ -469,19 +522,29 @@ sub mtr_kill_leftovers () {
mtr_warning("can't kill process(es) " . join(" ", @pids));
}
}
+
+ stop_reap_all();
}
}
+ else
+ {
+ mtr_debug("Directory for PID files ($rundir) does not exist.");
+ }
# We may have failed everything, bug we now check again if we have
# the listen ports free to use, and if they are free, just go for it.
+ mtr_debug("Checking known mysqld servers...");
+
foreach my $srv ( @args )
{
- if ( mtr_ping_mysqld_server($srv->{'port'}, $srv->{'sockfile'}) )
+ if ( mtr_ping_mysqld_server($srv->{'port'}) )
{
mtr_warning("can't kill old mysqld holding port $srv->{'port'}");
}
}
+
+ mtr_debug("mtr_kill_leftovers(): finished.");
}
##############################################################################
@@ -653,10 +716,15 @@ sub mtr_mysqladmin_shutdown {
my %mysql_admin_pids;
my @to_kill_specs;
+ mtr_debug("mtr_mysqladmin_shutdown(): starting...");
+ mtr_debug("Collecting mysqld-instances to shutdown...");
+
foreach my $srv ( @$spec )
{
- if ( mtr_ping_mysqld_server($srv->{'port'}, $srv->{'sockfile'}) )
+ if ( mtr_ping_mysqld_server($srv->{'port'}) )
{
+ mtr_debug("Mysqld (port: $srv->{port}) needs to be stopped.");
+
push(@to_kill_specs, $srv);
}
}
@@ -688,6 +756,9 @@ sub mtr_mysqladmin_shutdown {
mtr_add_arg($args, "--shutdown_timeout=$adm_shutdown_tmo");
mtr_add_arg($args, "shutdown");
+ mtr_debug("Shutting down mysqld " .
+ "(port: $srv->{port}; socket: '$srv->{sockfile}')...");
+
my $path_mysqladmin_log= "$::opt_vardir/log/mysqladmin.log";
my $pid= mtr_spawn($::exe_mysqladmin, $args,
"", $path_mysqladmin_log, $path_mysqladmin_log, "",
@@ -719,14 +790,18 @@ sub mtr_mysqladmin_shutdown {
my $res= 1; # If we just fall through, we are done
# in the sense that the servers don't
# listen to their ports any longer
+
+ mtr_debug("Waiting for mysqld servers to stop...");
+
TIME:
while ( $timeout-- )
{
foreach my $srv ( @to_kill_specs )
{
$res= 1; # We are optimistic
- if ( mtr_ping_mysqld_server($srv->{'port'}, $srv->{'sockfile'}) )
+ if ( mtr_ping_mysqld_server($srv->{'port'}) )
{
+ mtr_debug("Mysqld (port: $srv->{port}) is still alive.");
mtr_debug("Sleep 1 second waiting for processes to stop using port");
sleep(1); # One second
$res= 0;
@@ -736,7 +811,14 @@ sub mtr_mysqladmin_shutdown {
last; # If we got here, we are done
}
- $timeout or mtr_debug("At least one server is still listening to its port");
+ if ($res)
+ {
+ mtr_debug("mtr_mysqladmin_shutdown(): All mysqld instances are down.");
+ }
+ else
+ {
+ mtr_debug("mtr_mysqladmin_shutdown(): At least one server is alive.");
+ }
return $res;
}
@@ -795,7 +877,7 @@ sub stop_reap_all {
$SIG{CHLD}= 'DEFAULT';
}
-sub mtr_ping_mysqld_server () {
+sub mtr_ping_mysqld_server ($) {
my $port= shift;
my $remote= "localhost";
@@ -810,13 +892,18 @@ sub mtr_ping_mysqld_server () {
{
mtr_error("can't create socket: $!");
}
+
+ mtr_debug("Pinging server (port: $port)...");
+
if ( connect(SOCK, $paddr) )
{
+ mtr_debug("Server (port: $port) is alive.");
close(SOCK); # FIXME check error?
return 1;
}
else
{
+ mtr_debug("Server (port: $port) is dead.");
return 0;
}
}
@@ -886,34 +973,6 @@ sub mtr_kill_processes ($) {
}
}
-
-sub mtr_kill_process ($$$$) {
- my $pid= shift;
- my $signal= shift;
- my $total_retries= shift;
- my $timeout= shift;
-
- for (my $cur_attempt= 1; $cur_attempt <= $total_retries; ++$cur_attempt)
- {
- mtr_debug("Sending $signal to $pid...");
-
- kill($signal, $pid);
-
- unless (kill (0, $pid))
- {
- mtr_debug("Process $pid died.");
- return;
- }
-
- mtr_debug("Sleeping $timeout second(s) waiting for processes to die...");
-
- sleep($timeout);
- }
-
- mtr_debug("Process $pid is still alive after $total_retries " .
- "of sending signal $signal.");
-}
-
##############################################################################
#
# When we exit, we kill off all children
@@ -943,4 +1002,676 @@ sub mtr_exit ($) {
exit($code);
}
+##############################################################################
+#
+# Instance Manager management routines.
+#
+##############################################################################
+
+sub mtr_im_kill_process ($$$$) {
+ my $pid_lst= shift;
+ my $signal= shift;
+ my $total_retries= shift;
+ my $timeout= shift;
+
+ my %pids;
+
+ foreach my $pid (@{$pid_lst})
+ {
+ $pids{$pid}= 1;
+ }
+
+ for (my $cur_attempt= 1; $cur_attempt <= $total_retries; ++$cur_attempt)
+ {
+ foreach my $pid (keys %pids)
+ {
+ mtr_debug("Sending $signal to $pid...");
+
+ kill($signal, $pid);
+
+ unless (kill (0, $pid))
+ {
+ mtr_debug("Process $pid died.");
+ delete $pids{$pid};
+ }
+ }
+
+ return if scalar keys %pids == 0;
+
+ mtr_debug("Sleeping $timeout second(s) waiting for processes to die...");
+
+ sleep($timeout);
+ }
+
+ mtr_debug("Process(es) " .
+ join(' ', keys %pids) .
+ " is still alive after $total_retries " .
+ "of sending signal $signal.");
+}
+
+###########################################################################
+
+sub mtr_im_load_pids($) {
+ my $instance_manager= shift;
+
+ mtr_debug("Loading PID files...");
+
+ # Obtain mysqld-process pids.
+
+ my $instances = $instance_manager->{'instances'};
+
+ for (my $idx= 0; $idx < 2; ++$idx)
+ {
+ mtr_debug("IM-guarded mysqld[$idx] PID file: '" .
+ $instances->[$idx]->{'path_pid'} . "'.");
+
+ my $mysqld_pid;
+
+ if (-r $instances->[$idx]->{'path_pid'})
+ {
+ $mysqld_pid= mtr_get_pid_from_file($instances->[$idx]->{'path_pid'});
+ mtr_debug("IM-guarded mysqld[$idx] PID: $mysqld_pid.");
+ }
+ else
+ {
+ $mysqld_pid= undef;
+ mtr_debug("IM-guarded mysqld[$idx]: no PID file.");
+ }
+
+ $instances->[$idx]->{'pid'}= $mysqld_pid;
+ }
+
+ # Re-read Instance Manager PIDs from the file, since during tests Instance
+ # Manager could have been restarted, so its PIDs could have been changed.
+
+ # - IM-main
+
+ mtr_debug("IM-main PID file: '$instance_manager->{path_pid}'.");
+
+ if (-f $instance_manager->{'path_pid'})
+ {
+ $instance_manager->{'pid'} =
+ mtr_get_pid_from_file($instance_manager->{'path_pid'});
+
+ mtr_debug("IM-main PID: $instance_manager->{pid}.");
+ }
+ else
+ {
+ mtr_debug("IM-main: no PID file.");
+ $instance_manager->{'pid'}= undef;
+ }
+
+ # - IM-angel
+
+ mtr_debug("IM-angel PID file: '$instance_manager->{path_angel_pid}'.");
+
+ if (-f $instance_manager->{'path_angel_pid'})
+ {
+ $instance_manager->{'angel_pid'} =
+ mtr_get_pid_from_file($instance_manager->{'path_angel_pid'});
+
+ mtr_debug("IM-angel PID: $instance_manager->{'angel_pid'}.");
+ }
+ else
+ {
+ mtr_debug("IM-angel: no PID file.");
+ $instance_manager->{'angel_pid'} = undef;
+ }
+}
+
+###########################################################################
+
+sub mtr_im_terminate($) {
+ my $instance_manager= shift;
+
+ # Load pids from pid-files. We should do it first of all, because IM deletes
+ # them on shutdown.
+
+ mtr_im_load_pids($instance_manager);
+
+ mtr_debug("Shutting Instance Manager down...");
+
+ # Ignoring SIGCHLD so that all children could rest in peace.
+
+ start_reap_all();
+
+ # Send SIGTERM to IM-main.
+
+ if (defined $instance_manager->{'pid'})
+ {
+ mtr_debug("IM-main pid: $instance_manager->{pid}.");
+ mtr_debug("Stopping IM-main...");
+
+ mtr_im_kill_process([ $instance_manager->{'pid'} ], 'TERM', 10, 1);
+ }
+ else
+ {
+ mtr_debug("IM-main pid: n/a.");
+ }
+
+ # If IM-angel was alive, wait for it to die.
+
+ if (defined $instance_manager->{'angel_pid'})
+ {
+ mtr_debug("IM-angel pid: $instance_manager->{'angel_pid'}.");
+ mtr_debug("Waiting for IM-angel to die...");
+
+ my $total_attempts= 10;
+
+ for (my $cur_attempt=1; $cur_attempt <= $total_attempts; ++$cur_attempt)
+ {
+ unless (kill (0, $instance_manager->{'angel_pid'}))
+ {
+ mtr_debug("IM-angel died.");
+ last;
+ }
+
+ sleep(1);
+ }
+ }
+ else
+ {
+ mtr_debug("IM-angel pid: n/a.");
+ }
+
+ stop_reap_all();
+
+ # Re-load PIDs.
+
+ mtr_im_load_pids($instance_manager);
+}
+
+###########################################################################
+
+sub mtr_im_check_alive($) {
+ my $instance_manager= shift;
+
+ mtr_debug("Checking whether IM-components are alive...");
+
+ return 1 if mtr_im_check_main_alive($instance_manager);
+
+ return 1 if mtr_im_check_angel_alive($instance_manager);
+
+ return 1 if mtr_im_check_mysqlds_alive($instance_manager);
+
+ return 0;
+}
+
+###########################################################################
+
+sub mtr_im_check_main_alive($) {
+ my $instance_manager= shift;
+
+ # Check that the process, that we know to be IM's, is dead.
+
+ if (defined $instance_manager->{'pid'})
+ {
+ if (kill (0, $instance_manager->{'pid'}))
+ {
+ mtr_debug("IM-main (PID: $instance_manager->{pid}) is alive.");
+ return 1;
+ }
+ else
+ {
+ mtr_debug("IM-main (PID: $instance_manager->{pid}) is dead.");
+ }
+ }
+ else
+ {
+ mtr_debug("No PID file for IM-main.");
+ }
+
+ # Check that IM does not accept client connections.
+
+ if (mtr_ping_mysqld_server($instance_manager->{'port'}))
+ {
+ mtr_debug("IM-main (port: $instance_manager->{port}) " .
+ "is accepting connections.");
+
+ mtr_im_errlog("IM-main is accepting connections on port " .
+ "$instance_manager->{port}, but there is no " .
+ "process information.");
+ return 1;
+ }
+ else
+ {
+ mtr_debug("IM-main (port: $instance_manager->{port}) " .
+ "does not accept connections.");
+ return 0;
+ }
+}
+
+###########################################################################
+
+sub mtr_im_check_angel_alive($) {
+ my $instance_manager= shift;
+
+ # Check that the process, that we know to be the Angel, is dead.
+
+ if (defined $instance_manager->{'angel_pid'})
+ {
+ if (kill (0, $instance_manager->{'angel_pid'}))
+ {
+ mtr_debug("IM-angel (PID: $instance_manager->{angel_pid}) is alive.");
+ return 1;
+ }
+ else
+ {
+ mtr_debug("IM-angel (PID: $instance_manager->{angel_pid}) is dead.");
+ return 0;
+ }
+ }
+ else
+ {
+ mtr_debug("No PID file for IM-angel.");
+ return 0;
+ }
+}
+
+###########################################################################
+
+sub mtr_im_check_mysqlds_alive($) {
+ my $instance_manager= shift;
+
+ mtr_debug("Checking for IM-guarded mysqld instances...");
+
+ my $instances = $instance_manager->{'instances'};
+
+ for (my $idx= 0; $idx < 2; ++$idx)
+ {
+ mtr_debug("Checking mysqld[$idx]...");
+
+ return 1
+ if mtr_im_check_mysqld_alive($instance_manager, $instances->[$idx]);
+ }
+}
+
+###########################################################################
+
+sub mtr_im_check_mysqld_alive($$) {
+ my $instance_manager= shift;
+ my $mysqld_instance= shift;
+
+ # Check that the process is dead.
+
+ if (defined $instance_manager->{'pid'})
+ {
+ if (kill (0, $instance_manager->{'pid'}))
+ {
+ mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is alive.");
+ return 1;
+ }
+ else
+ {
+ mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is dead.");
+ }
+ }
+ else
+ {
+ mtr_debug("No PID file for mysqld instance.");
+ }
+
+ # Check that mysqld does not accept client connections.
+
+ if (mtr_ping_mysqld_server($mysqld_instance->{'port'}))
+ {
+ mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " .
+ "is accepting connections.");
+
+ mtr_im_errlog("Mysqld is accepting connections on port " .
+ "$mysqld_instance->{port}, but there is no " .
+ "process information.");
+ return 1;
+ }
+ else
+ {
+ mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " .
+ "does not accept connections.");
+ return 0;
+ }
+}
+
+###########################################################################
+
+sub mtr_im_cleanup($) {
+ my $instance_manager= shift;
+
+ mtr_im_rm_file($instance_manager->{'path_pid'});
+ mtr_im_rm_file($instance_manager->{'path_sock'});
+
+ mtr_im_rm_file($instance_manager->{'path_angel_pid'});
+
+ for (my $idx= 0; $idx < 2; ++$idx)
+ {
+ mtr_im_rm_file($instance_manager->{'instances'}->[$idx]->{'path_pid'});
+ mtr_im_rm_file($instance_manager->{'instances'}->[$idx]->{'path_sock'});
+ }
+}
+
+###########################################################################
+
+sub mtr_im_rm_file($)
+{
+ my $file_path= shift;
+
+ if (-f $file_path)
+ {
+ mtr_debug("Removing '$file_path'...");
+
+ mtr_warning("Can not remove '$file_path'.")
+ unless unlink($file_path);
+ }
+ else
+ {
+ mtr_debug("File '$file_path' does not exist already.");
+ }
+}
+
+###########################################################################
+
+sub mtr_im_errlog($) {
+ my $msg= shift;
+
+ # Complain in error log so that a warning will be shown.
+ #
+ # TODO: unless BUG#20761 is fixed, we will print the warning to stdout, so
+ # that it can be seen on console and does not produce pushbuild error.
+
+ # my $errlog= "$opt_vardir/log/mysql-test-run.pl.err";
+ #
+ # open (ERRLOG, ">>$errlog") ||
+ # mtr_error("Can not open error log ($errlog)");
+ #
+ # my $ts= localtime();
+ # print ERRLOG
+ # "Warning: [$ts] $msg\n";
+ #
+ # close ERRLOG;
+
+ my $ts= localtime();
+ print "Warning: [$ts] $msg\n";
+}
+
+###########################################################################
+
+sub mtr_im_kill($) {
+ my $instance_manager= shift;
+
+ # Re-load PIDs. That can be useful because some processes could have been
+ # restarted.
+
+ mtr_im_load_pids($instance_manager);
+
+ # Ignoring SIGCHLD so that all children could rest in peace.
+
+ start_reap_all();
+
+ # Kill IM-angel first of all.
+
+ if (defined $instance_manager->{'angel_pid'})
+ {
+ mtr_debug("Killing IM-angel (PID: $instance_manager->{angel_pid})...");
+ mtr_im_kill_process([ $instance_manager->{'angel_pid'} ], 'KILL', 10, 1)
+ }
+ else
+ {
+ mtr_debug("IM-angel is dead.");
+ }
+
+ # Re-load PIDs again.
+
+ mtr_im_load_pids($instance_manager);
+
+ # Kill IM-main.
+
+ if (defined $instance_manager->{'pid'})
+ {
+ mtr_debug("Killing IM-main (PID: $instance_manager->pid})...");
+ mtr_im_kill_process([ $instance_manager->{'pid'} ], 'KILL', 10, 1);
+ }
+ else
+ {
+ mtr_debug("IM-main is dead.");
+ }
+
+ # Re-load PIDs again.
+
+ mtr_im_load_pids($instance_manager);
+
+ # Kill guarded mysqld instances.
+
+ my @mysqld_pids;
+
+ mtr_debug("Collecting PIDs of mysqld instances to kill...");
+
+ for (my $idx= 0; $idx < 2; ++$idx)
+ {
+ my $pid= $instance_manager->{'instances'}->[$idx]->{'pid'};
+
+ next unless defined $pid;
+
+ mtr_debug(" - IM-guarded mysqld[$idx] PID: $pid.");
+
+ push (@mysqld_pids, $pid);
+ }
+
+ if (scalar @mysqld_pids > 0)
+ {
+ mtr_debug("Killing IM-guarded mysqld instances...");
+ mtr_im_kill_process(\@mysqld_pids, 'KILL', 10, 1);
+ }
+
+ # That's all.
+
+ stop_reap_all();
+}
+
+##############################################################################
+
+sub mtr_im_wait_for_connection($$$) {
+ my $instance_manager= shift;
+ my $total_attempts= shift;
+ my $connect_timeout= shift;
+
+ mtr_debug("Waiting for IM on port $instance_manager->{port} " .
+ "to start accepting connections...");
+
+ for (my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt)
+ {
+ mtr_debug("Trying to connect to IM ($cur_attempt of $total_attempts)...");
+
+ if (mtr_ping_mysqld_server($instance_manager->{'port'}))
+ {
+ mtr_debug("IM is accepting connections " .
+ "on port $instance_manager->{port}.");
+ return 1;
+ }
+
+ mtr_debug("Sleeping $connect_timeout...");
+ sleep($connect_timeout);
+ }
+
+ mtr_debug("IM does not accept connections " .
+ "on port $instance_manager->{port} after " .
+ ($total_attempts * $connect_timeout) . " seconds.");
+
+ return 0;
+}
+
+##############################################################################
+
+sub mtr_im_wait_for_mysqld($$$) {
+ my $mysqld= shift;
+ my $total_attempts= shift;
+ my $connect_timeout= shift;
+
+ mtr_debug("Waiting for IM-guarded mysqld on port $mysqld->{port} " .
+ "to start accepting connections...");
+
+ for (my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt)
+ {
+ mtr_debug("Trying to connect to mysqld " .
+ "($cur_attempt of $total_attempts)...");
+
+ if (mtr_ping_mysqld_server($mysqld->{'port'}))
+ {
+ mtr_debug("Mysqld is accepting connections " .
+ "on port $mysqld->{port}.");
+ return 1;
+ }
+
+ mtr_debug("Sleeping $connect_timeout...");
+ sleep($connect_timeout);
+ }
+
+ mtr_debug("Mysqld does not accept connections " .
+ "on port $mysqld->{port} after " .
+ ($total_attempts * $connect_timeout) . " seconds.");
+
+ return 0;
+}
+
+##############################################################################
+
+sub mtr_im_start($$) {
+ my $instance_manager = shift;
+ my $opts = shift;
+
+ mtr_debug("Starting Instance Manager...");
+
+ my $args;
+ mtr_init_args(\$args);
+ mtr_add_arg($args, "--defaults-file=%s",
+ $instance_manager->{'defaults_file'});
+
+ foreach my $opt (@{$opts})
+ {
+ mtr_add_arg($args, $opt);
+ }
+
+ $instance_manager->{'pid'} =
+ mtr_spawn(
+ $::exe_im, # path to the executable
+ $args, # cmd-line args
+ '', # stdin
+ $instance_manager->{'path_log'}, # stdout
+ $instance_manager->{'path_err'}, # stderr
+ '', # pid file path (not used)
+ { append_log_file => 1 } # append log files
+ );
+
+ if ( ! $instance_manager->{'pid'} )
+ {
+ mtr_report('Could not start Instance Manager');
+ return;
+ }
+
+ # Instance Manager can be run in daemon mode. In this case, it creates
+ # several processes and the parent process, created by mtr_spawn(), exits just
+ # after start. So, we have to obtain Instance Manager PID from the PID file.
+
+ if ( ! sleep_until_file_created(
+ $instance_manager->{'path_pid'},
+ $instance_manager->{'start_timeout'},
+ -1)) # real PID is still unknown
+ {
+ mtr_report("Instance Manager PID file is missing");
+ return;
+ }
+
+ $instance_manager->{'pid'} =
+ mtr_get_pid_from_file($instance_manager->{'path_pid'});
+
+ mtr_debug("Instance Manager started. PID: $instance_manager->{pid}.");
+
+ # Wait until we can connect to IM.
+
+ my $IM_CONNECT_TIMEOUT= 30;
+
+ unless (mtr_im_wait_for_connection($instance_manager,
+ $IM_CONNECT_TIMEOUT, 1))
+ {
+ mtr_debug("Can not connect to Instance Manager " .
+ "in $IM_CONNECT_TIMEOUT seconds after start.");
+ mtr_debug("Aborting test suite...");
+
+ mtr_kill_leftovers();
+
+ mtr_error("Can not connect to Instance Manager " .
+ "in $IM_CONNECT_TIMEOUT seconds after start.");
+ }
+
+ # Wait until we can connect to guarded mysqld-instances
+ # (in other words -- wait for IM to start guarded instances).
+
+ for (my $idx= 0; $idx < 2; ++$idx)
+ {
+ my $mysqld= $instance_manager->{'instances'}->[$idx];
+
+ next if exists $mysqld->{'nonguarded'};
+
+ mtr_debug("Waiting for mysqld[$idx] to start...");
+
+ unless (mtr_im_wait_for_mysqld($mysqld, 30, 1))
+ {
+ mtr_debug("Can not connect to mysqld[$idx] " .
+ "in $IM_CONNECT_TIMEOUT seconds after start.");
+ mtr_debug("Aborting test suite...");
+
+ mtr_kill_leftovers();
+
+ mtr_error("Can not connect to mysqld[$idx] " .
+ "in $IM_CONNECT_TIMEOUT seconds after start.");
+ }
+
+ mtr_debug("mysqld[$idx] started.");
+ }
+
+ mtr_debug("Instance Manager started.");
+}
+
+##############################################################################
+
+sub mtr_im_stop($) {
+ my $instance_manager= shift;
+
+ mtr_debug("Stopping Instance Manager...");
+
+ # Try graceful shutdown.
+
+ mtr_im_terminate($instance_manager);
+
+ # Check that all processes died.
+
+ unless (mtr_im_check_alive($instance_manager))
+ {
+ mtr_debug("Instance Manager has been stopped successfully.");
+ mtr_im_cleanup($instance_manager);
+ return 1;
+ }
+
+ # Instance Manager don't want to die. We should kill it.
+
+ mtr_im_errlog("Instance Manager did not shutdown gracefully.");
+
+ mtr_im_kill($instance_manager);
+
+ # Check again that all IM-related processes have been killed.
+
+ my $im_is_alive= mtr_im_check_alive($instance_manager);
+
+ mtr_im_cleanup($instance_manager);
+
+ if ($im_is_alive)
+ {
+ mtr_error("Can not kill Instance Manager or its children.");
+ return 0;
+ }
+
+ mtr_debug("Instance Manager has been killed successfully.");
+ return 1;
+}
+
+###########################################################################
+
1;
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index afd79e9c887..7bca21e3ff6 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -336,7 +336,7 @@ sub snapshot_setup ();
sub executable_setup ();
sub environment_setup ();
sub kill_running_server ();
-sub kill_and_cleanup ();
+sub cleanup_stale_files ();
sub check_ssl_support ();
sub check_running_as_root();
sub check_ndbcluster_support ();
@@ -356,8 +356,6 @@ sub mysqld_arguments ($$$$$$);
sub stop_masters_slaves ();
sub stop_masters ();
sub stop_slaves ();
-sub im_start ($$);
-sub im_stop ($);
sub run_mysqltest ($);
sub usage ($);
@@ -499,7 +497,7 @@ sub command_line_setup () {
my $opt_master_myport= 9306;
my $opt_slave_myport= 9308;
$opt_ndbcluster_port= 9350;
- my $im_port= 9310;
+ my $im_port= 9311;
my $im_mysqld1_port= 9312;
my $im_mysqld2_port= 9314;
@@ -1044,20 +1042,30 @@ sub executable_setup () {
if ( $glob_win32 )
{
$path_client_bindir= mtr_path_exists("$glob_basedir/client_release",
- "$glob_basedir/client_debug",
+ "$glob_basedir/client_debug",
+ "$glob_basedir/client/release",
+ "$glob_basedir/client/debug",
"$glob_basedir/bin",);
$exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-max-nt",
"$path_client_bindir/mysqld-max",
"$path_client_bindir/mysqld-nt",
"$path_client_bindir/mysqld",
"$path_client_bindir/mysqld-debug",
- "$path_client_bindir/mysqld-max");
- $path_language= mtr_path_exists("$glob_basedir/share/english/");
- $path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets");
+ "$path_client_bindir/mysqld-max",
+ "$glob_basedir/sql/release/mysqld",
+ "$glob_basedir/sql/debug/mysqld");
+ $path_language= mtr_path_exists("$glob_basedir/share/english/",
+ "$glob_basedir/sql/share/english/");
+ $path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets",
+ "$glob_basedir/sql/share/charsets/");
$exe_my_print_defaults=
- mtr_exe_exists("$path_client_bindir/my_print_defaults");
+ mtr_exe_exists("$path_client_bindir/my_print_defaults",
+ "$glob_basedir/extra/release/my_print_defaults",
+ "$glob_basedir/extra/debug/my_print_defaults");
$exe_perror=
- mtr_exe_exists("$path_client_bindir/perror");
+ mtr_exe_exists("$path_client_bindir/perror",
+ "$glob_basedir/extra/release/perror",
+ "$glob_basedir/extra/debug/perror");
}
else
{
@@ -1088,6 +1096,9 @@ sub executable_setup () {
$exe_mysql_client_test=
mtr_exe_exists("$glob_basedir/tests/mysql_client_test",
"$path_client_bindir/mysql_client_test",
+ "$glob_basedir/tests/release/mysql_client_test",
+ "$glob_basedir/tests/debug/mysql_client_test",
+ "$path_client_bindir/mysql_client_test",
"/usr/bin/false");
}
$exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck");
@@ -1098,7 +1109,8 @@ sub executable_setup () {
$exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin");
$exe_mysql= mtr_exe_exists("$path_client_bindir/mysql");
$exe_mysql_fix_system_tables=
- mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables");
+ mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables",
+ "/usr/bin/false");
$path_ndb_tools_dir= mtr_path_exists("$glob_basedir/ndb/tools");
$exe_ndb_mgm= "$glob_basedir/ndb/src/mgmclient/ndb_mgm";
$lib_udf_example=
@@ -1116,7 +1128,8 @@ sub executable_setup () {
$exe_mysql= mtr_exe_exists("$path_client_bindir/mysql");
$exe_mysql_fix_system_tables=
mtr_script_exists("$path_client_bindir/mysql_fix_privilege_tables",
- "$glob_basedir/scripts/mysql_fix_privilege_tables");
+ "$glob_basedir/scripts/mysql_fix_privilege_tables",
+ "/usr/bin/false");
$exe_my_print_defaults=
mtr_exe_exists("$path_client_bindir/my_print_defaults");
$exe_perror=
@@ -1150,7 +1163,9 @@ sub executable_setup () {
}
else
{
- $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
+ $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest",
+ "$glob_basedir/client/release/mysqltest",
+ "$glob_basedir/client/debug/mysqltest");
$exe_mysql_client_test=
mtr_exe_exists("$path_client_bindir/mysql_client_test",
"/usr/bin/false"); # FIXME temporary
@@ -1303,6 +1318,7 @@ sub kill_running_server () {
mtr_report("Killing Possible Leftover Processes");
mkpath("$opt_vardir/log"); # Needed for mysqladmin log
+
mtr_kill_leftovers();
$using_ndbcluster_master= $opt_with_ndbcluster;
@@ -1311,9 +1327,7 @@ sub kill_running_server () {
}
}
-sub kill_and_cleanup () {
-
- kill_running_server ();
+sub cleanup_stale_files () {
mtr_report("Removing Stale Files");
@@ -1692,13 +1706,11 @@ sub run_suite () {
sub initialize_servers () {
if ( ! $glob_use_running_server )
{
- if ( $opt_start_dirty )
- {
- kill_running_server();
- }
- else
+ kill_running_server();
+
+ unless ( $opt_start_dirty )
{
- kill_and_cleanup();
+ cleanup_stale_files();
mysql_install_db();
if ( $opt_force )
{
@@ -2100,7 +2112,7 @@ sub run_testcase ($) {
im_create_defaults_file($instance_manager);
- im_start($instance_manager, $tinfo->{im_opts});
+ mtr_im_start($instance_manager, $tinfo->{im_opts});
}
# ----------------------------------------------------------------------
@@ -2195,10 +2207,9 @@ sub run_testcase ($) {
# Stop Instance Manager if we are processing an IM-test case.
# ----------------------------------------------------------------------
- if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' and
- $instance_manager->{'pid'} )
+ if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' )
{
- im_stop($instance_manager);
+ mtr_im_stop($instance_manager);
}
}
@@ -2726,11 +2737,8 @@ sub stop_masters_slaves () {
print "Ending Tests\n";
- if ( $instance_manager->{'pid'} )
- {
- print "Shutting-down Instance Manager\n";
- im_stop($instance_manager);
- }
+ print "Shutting-down Instance Manager\n";
+ mtr_im_stop($instance_manager);
print "Shutting-down MySQL daemon\n\n";
stop_masters();
@@ -2792,230 +2800,6 @@ sub stop_slaves () {
mtr_stop_mysqld_servers(\@args);
}
-##############################################################################
-#
-# Instance Manager management routines.
-#
-##############################################################################
-
-sub im_start($$) {
- my $instance_manager = shift;
- my $opts = shift;
-
- my $args;
- mtr_init_args(\$args);
- mtr_add_arg($args, "--defaults-file=%s",
- $instance_manager->{'defaults_file'});
-
- foreach my $opt (@{$opts})
- {
- mtr_add_arg($args, $opt);
- }
-
- $instance_manager->{'pid'} =
- mtr_spawn(
- $exe_im, # path to the executable
- $args, # cmd-line args
- '', # stdin
- $instance_manager->{'path_log'}, # stdout
- $instance_manager->{'path_err'}, # stderr
- '', # pid file path (not used)
- { append_log_file => 1 } # append log files
- );
-
- if ( ! $instance_manager->{'pid'} )
- {
- mtr_report('Could not start Instance Manager');
- return;
- }
-
- # Instance Manager can be run in daemon mode. In this case, it creates
- # several processes and the parent process, created by mtr_spawn(), exits just
- # after start. So, we have to obtain Instance Manager PID from the PID file.
-
- if ( ! sleep_until_file_created(
- $instance_manager->{'path_pid'},
- $instance_manager->{'start_timeout'},
- -1)) # real PID is still unknown
- {
- mtr_report("Instance Manager PID file is missing");
- return;
- }
-
- $instance_manager->{'pid'} =
- mtr_get_pid_from_file($instance_manager->{'path_pid'});
-}
-
-
-sub im_stop($) {
- my $instance_manager = shift;
-
- # Obtain mysqld-process pids before we start stopping IM (it can delete pid
- # files).
-
- my @mysqld_pids = ();
- my $instances = $instance_manager->{'instances'};
-
- push(@mysqld_pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'}))
- if -r $instances->[0]->{'path_pid'};
-
- push(@mysqld_pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'}))
- if -r $instances->[1]->{'path_pid'};
-
- # Re-read pid from the file, since during tests Instance Manager could have
- # been restarted, so its pid could have been changed.
-
- $instance_manager->{'pid'} =
- mtr_get_pid_from_file($instance_manager->{'path_pid'})
- if -f $instance_manager->{'path_pid'};
-
- if (-f $instance_manager->{'path_angel_pid'})
- {
- $instance_manager->{'angel_pid'} =
- mtr_get_pid_from_file($instance_manager->{'path_angel_pid'})
- }
- else
- {
- $instance_manager->{'angel_pid'} = undef;
- }
-
- # Inspired from mtr_stop_mysqld_servers().
-
- start_reap_all();
-
- # Try graceful shutdown.
-
- mtr_debug("IM-main pid: $instance_manager->{'pid'}");
- mtr_debug("Stopping IM-main...");
-
- mtr_kill_process($instance_manager->{'pid'}, 'TERM', 10, 1);
-
- # If necessary, wait for angel process to die.
-
- if (defined $instance_manager->{'angel_pid'})
- {
- mtr_debug("IM-angel pid: $instance_manager->{'angel_pid'}");
- mtr_debug("Waiting for IM-angel to die...");
-
- my $total_attempts= 10;
-
- for (my $cur_attempt=1; $cur_attempt <= $total_attempts; ++$cur_attempt)
- {
- unless (kill (0, $instance_manager->{'angel_pid'}))
- {
- mtr_debug("IM-angel died.");
- last;
- }
-
- sleep(1);
- }
- }
-
- # Check that all processes died.
-
- my $clean_shutdown= 0;
-
- while (1)
- {
- # Check that IM-main died.
-
- if (kill (0, $instance_manager->{'pid'}))
- {
- mtr_debug("IM-main is still alive.");
- last;
- }
-
- # Check that IM-angel died.
-
- if (defined $instance_manager->{'angel_pid'} &&
- kill (0, $instance_manager->{'angel_pid'}))
- {
- mtr_debug("IM-angel is still alive.");
- last;
- }
-
- # Check that all guarded mysqld-instances died.
-
- my $guarded_mysqlds_dead= 1;
-
- foreach my $pid (@mysqld_pids)
- {
- if (kill (0, $pid))
- {
- mtr_debug("Guarded mysqld ($pid) is still alive.");
- $guarded_mysqlds_dead= 0;
- last;
- }
- }
-
- last unless $guarded_mysqlds_dead;
-
- # Ok, all necessary processes are dead.
-
- $clean_shutdown= 1;
- last;
- }
-
- # Kill leftovers (the order is important).
-
- if ($clean_shutdown)
- {
- mtr_debug("IM-shutdown was clean -- all processed died.");
- }
- else
- {
- mtr_debug("IM failed to shutdown gracefully. We have to clean the mess...");
- }
-
- unless ($clean_shutdown)
- {
-
- if (defined $instance_manager->{'angel_pid'})
- {
- mtr_debug("Killing IM-angel...");
- mtr_kill_process($instance_manager->{'angel_pid'}, 'KILL', 10, 1)
- }
-
- mtr_debug("Killing IM-main...");
- mtr_kill_process($instance_manager->{'pid'}, 'KILL', 10, 1);
-
- # Shutdown managed mysqld-processes. Some of them may be nonguarded, so IM
- # will not stop them on shutdown. So, we should firstly try to end them
- # legally.
-
- mtr_debug("Killing guarded mysqld(s)...");
- mtr_kill_processes(\@mysqld_pids);
-
- # Complain in error log so that a warning will be shown.
- #
- # TODO: unless BUG#20761 is fixed, we will print the warning
- # to stdout, so that it can be seen on console and does not
- # produce pushbuild error.
-
- # my $errlog= "$opt_vardir/log/mysql-test-run.pl.err";
- #
- # open (ERRLOG, ">>$errlog") ||
- # mtr_error("Can not open error log ($errlog)");
- #
- # my $ts= localtime();
- # print ERRLOG
- # "Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
- #
- # close ERRLOG;
-
- my $ts= localtime();
- print "Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
- }
-
- # That's all.
-
- stop_reap_all();
-
- $instance_manager->{'pid'} = undef;
- $instance_manager->{'angel_pid'} = undef;
-}
-
-
#
# Run include/check-testcase.test
# Before a testcase, run in record mode, save result file to var
diff --git a/mysql-test/r/ctype_recoding.result b/mysql-test/r/ctype_recoding.result
index 996f6fa8645..4e145346081 100644
--- a/mysql-test/r/ctype_recoding.result
+++ b/mysql-test/r/ctype_recoding.result
@@ -248,3 +248,14 @@ select rpad(c1,3,'ö'), rpad('ö',3,c1) from t1;
rpad(c1,3,'ö') rpad('ö',3,c1)
ßöö ößß
drop table t1;
+set names koi8r;
+create table t1(a char character set cp1251 default _koi8r 0xFF);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(1) character set cp1251 default 'ÿ'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1(a char character set latin1 default _cp1251 0xFF);
+ERROR 42000: Invalid default value for 'a'
+End of 4.1 tests
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 890cdfd5cfc..3b6bfa6d776 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -730,6 +730,45 @@ id MIN(s)
1 ZZZ
2 ZZZ
DROP TABLE t1;
+drop table if exists bug20536;
+set names latin1;
+create table bug20536 (id bigint not null auto_increment primary key, name
+varchar(255) character set ucs2 not null);
+insert into `bug20536` (`id`,`name`) values (1, _latin1 x'7465737431'), (2, "'test\\_2'");
+select md5(name) from bug20536;
+md5(name)
+f4b7ce8b45a20e3c4e84bef515d1525c
+48d95db0d8305c2fe11548a3635c9385
+select sha1(name) from bug20536;
+sha1(name)
+e0b52f38deddb9f9e8d5336b153592794cb49baf
+677d4d505355eb5b0549b865fcae4b7f0c28aef5
+select make_set(3, name, upper(name)) from bug20536;
+make_set(3, name, upper(name))
+test1,TEST1
+'test\_2','TEST\_2'
+select export_set(5, name, upper(name)) from bug20536;
+export_set(5, name, upper(name))
+test1,TEST1,test1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1,TEST1
+'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2','TEST\_2'
+select export_set(5, name, upper(name), ",", 5) from bug20536;
+export_set(5, name, upper(name), ",", 5)
+test1,TEST1,test1,TEST1,TEST1
+'test\_2','TEST\_2','test\_2','TEST\_2','TEST\_2'
+select password(name) from bug20536;
+password(name)
+????????????????????
+????????????????????
+select old_password(name) from bug20536;
+old_password(name)
+????????
+????????
+select quote(name) from bug20536;
+quote(name)
+????????
+????????????????
+drop table bug20536;
+End of 4.1 tests
CREATE TABLE t1 (a varchar(64) character set ucs2, b decimal(10,3));
INSERT INTO t1 VALUES ("1.1", 0), ("2.1", 0);
update t1 set b=a;
@@ -765,3 +804,4 @@ blob 65535 65535
text 65535 65535
text 65535 32767
drop table t1;
+End of 5.0 tests
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index f78fe3521fa..51f361349e6 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -924,6 +924,37 @@ NULL
select ifnull(NULL, _utf8'string');
ifnull(NULL, _utf8'string')
string
+set names utf8;
+create table t1 (s1 char(5) character set utf8 collate utf8_lithuanian_ci);
+insert into t1 values ('I'),('K'),('Y');
+select * from t1 where s1 < 'K' and s1 = 'Y';
+s1
+I
+Y
+select * from t1 where 'K' > s1 and s1 = 'Y';
+s1
+I
+Y
+drop table t1;
+create table t1 (s1 char(5) character set utf8 collate utf8_czech_ci);
+insert into t1 values ('c'),('d'),('h'),('ch'),('CH'),('cH'),('Ch'),('i');
+select * from t1 where s1 > 'd' and s1 = 'CH';
+s1
+ch
+CH
+Ch
+select * from t1 where 'd' < s1 and s1 = 'CH';
+s1
+ch
+CH
+Ch
+select * from t1 where s1 = 'cH' and s1 <> 'ch';
+s1
+cH
+select * from t1 where 'cH' = s1 and s1 <> 'ch';
+s1
+cH
+drop table t1;
create table t1 (a varchar(255)) default character set utf8;
insert into t1 values (1.0);
drop table t1;
@@ -1309,6 +1340,19 @@ select a from t1 group by a;
a
e
drop table t1;
+set names utf8;
+grant select on test.* to юзер_юзер@localhost;
+user()
+юзер_юзер@localhost
+revoke all on test.* from юзер_юзер@localhost;
+drop user юзер_юзер@localhost;
+create database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
+use имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
+select database();
+database()
+имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45
+drop database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
+use test;
CREATE TABLE t1(id varchar(20) NOT NULL) DEFAULT CHARSET=utf8;
INSERT INTO t1 VALUES ('xxx'), ('aa'), ('yyy'), ('aa');
SELECT id FROM t1;
diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result
index 979e5d48871..d122dabc4ec 100644
--- a/mysql-test/r/drop.result
+++ b/mysql-test/r/drop.result
@@ -72,3 +72,16 @@ show tables;
Tables_in_test
t1
drop table t1;
+drop database if exists mysqltest;
+drop table if exists t1;
+create table t1 (i int);
+lock tables t1 read;
+create database mysqltest;
+ drop table t1;
+show open tables;
+ drop database mysqltest;
+select 1;
+1
+1
+unlock tables;
+End of 5.0 tests
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 33e642c74c4..f0262acd71e 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -87,6 +87,10 @@ SELECT IS_USED_LOCK('bug16501');
IS_USED_LOCK('bug16501')
NULL
DROP TABLE t1;
+select export_set(3, _latin1'foo', _utf8'bar', ',', 4);
+export_set(3, _latin1'foo', _utf8'bar', ',', 4)
+foo,foo,bar,bar
+End of 4.1 tests
create table t1 as select uuid(), length(uuid());
show create table t1;
Table Create Table
@@ -130,3 +134,4 @@ timediff(b, a) >= '00:00:03'
drop table t2;
drop table t1;
set global query_cache_size=default;
+End of 5.0 tests
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index b9533104b76..dc6a4561531 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -1053,3 +1053,15 @@ id day id day
3 2005-07-01 3 2005-07-15
DROP TABLE t1,t2;
set time_zone= @@global.time_zone;
+SET NAMES latin1;
+SET character_set_results = NULL;
+SHOW VARIABLES LIKE 'character_set_results';
+Variable_name Value
+character_set_results
+CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY);
+INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd');
+SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868;
+fmtddate field2
+Sep-4 12:00AM abcd
+DROP TABLE testBug8868;
+SET NAMES DEFAULT;
diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result
index 0b2cfd5ebb0..2f417a41652 100644
--- a/mysql-test/r/grant.result
+++ b/mysql-test/r/grant.result
@@ -943,6 +943,31 @@ DROP TABLE mysqltest3.t_nn;
DROP DATABASE mysqltest3;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'mysqltest_1'@'localhost';
DROP USER 'mysqltest_1'@'localhost';
+use test;
create user mysqltest1_thisisreallytoolong;
-ERROR HY000: Operation CREATE USER failed for 'mysqltest1_thisisreallytoolong'@'%'
+ERROR HY000: String 'mysqltest1_thisisreallytoolong' is too long for user name (should be no longer than 16)
+GRANT CREATE ON mysqltest.* TO 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16)
+GRANT CREATE ON mysqltest.* TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
+REVOKE CREATE ON mysqltest.* FROM 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16)
+REVOKE CREATE ON mysqltest.* FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
+GRANT CREATE ON t1 TO 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16)
+GRANT CREATE ON t1 TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
+REVOKE CREATE ON t1 FROM 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16)
+REVOKE CREATE ON t1 FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
+GRANT EXECUTE ON PROCEDURE p1 TO 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16)
+GRANT EXECUTE ON PROCEDURE p1 TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
+REVOKE EXECUTE ON PROCEDURE p1 FROM 1234567890abcdefGHIKL@localhost;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16)
+REVOKE EXECUTE ON PROCEDURE t1 FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
End of 5.0 tests
diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result
index c9d3db5e8e8..5b9c7f2244f 100644
--- a/mysql-test/r/heap_btree.result
+++ b/mysql-test/r/heap_btree.result
@@ -294,3 +294,4 @@ DROP TABLE t1;
CREATE TABLE t1 (a INT, UNIQUE USING BTREE(a)) ENGINE=MEMORY;
INSERT INTO t1 VALUES(NULL),(NULL);
DROP TABLE t1;
+End of 5.0 tests
diff --git a/mysql-test/r/im_daemon_life_cycle.result b/mysql-test/r/im_daemon_life_cycle.result
index 4f7dd77a88f..b805bdc9166 100644
--- a/mysql-test/r/im_daemon_life_cycle.result
+++ b/mysql-test/r/im_daemon_life_cycle.result
@@ -1,4 +1,3 @@
-Success: the process has been started.
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
diff --git a/mysql-test/r/im_life_cycle.result b/mysql-test/r/im_life_cycle.result
index 53737b64f28..69f6bb5a490 100644
--- a/mysql-test/r/im_life_cycle.result
+++ b/mysql-test/r/im_life_cycle.result
@@ -1,4 +1,3 @@
-Success: the process has been started.
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
diff --git a/mysql-test/r/im_options_set.result b/mysql-test/r/im_options_set.result
index c3035079b39..f7b7e8eaef7 100644
--- a/mysql-test/r/im_options_set.result
+++ b/mysql-test/r/im_options_set.result
@@ -1,4 +1,3 @@
-Success: the process has been started.
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
diff --git a/mysql-test/r/im_options_unset.result b/mysql-test/r/im_options_unset.result
index ba468c78a5b..2ab775e611a 100644
--- a/mysql-test/r/im_options_unset.result
+++ b/mysql-test/r/im_options_unset.result
@@ -1,4 +1,3 @@
-Success: the process has been started.
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
diff --git a/mysql-test/r/im_utils.result b/mysql-test/r/im_utils.result
index be696921812..f671089d31d 100644
--- a/mysql-test/r/im_utils.result
+++ b/mysql-test/r/im_utils.result
@@ -1,4 +1,3 @@
-Success: the process has been started.
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
diff --git a/mysql-test/r/limit.result b/mysql-test/r/limit.result
index 1e38f762dd1..be2776ef533 100644
--- a/mysql-test/r/limit.result
+++ b/mysql-test/r/limit.result
@@ -76,3 +76,17 @@ a
a
1
drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7);
+explain select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where; Using temporary
+select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3;
+c
+7
+explain select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where; Using temporary
+select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3;
+c
+28
diff --git a/mysql-test/r/loaddata_autocom_innodb.result b/mysql-test/r/loaddata_autocom_innodb.result
new file mode 100644
index 00000000000..10da6b5dde7
--- /dev/null
+++ b/mysql-test/r/loaddata_autocom_innodb.result
@@ -0,0 +1,21 @@
+SET SESSION STORAGE_ENGINE = InnoDB;
+drop table if exists t1;
+create table t1 (a text, b text);
+start transaction;
+load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by '''';
+Warnings:
+Warning 1261 Row 3 doesn't contain data for all columns
+commit;
+select count(*) from t1;
+count(*)
+4
+truncate table t1;
+start transaction;
+load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by '''';
+Warnings:
+Warning 1261 Row 3 doesn't contain data for all columns
+rollback;
+select count(*) from t1;
+count(*)
+0
+drop table t1;
diff --git a/mysql-test/r/loaddata_autocom_ndb.result b/mysql-test/r/loaddata_autocom_ndb.result
new file mode 100644
index 00000000000..94e5f825fa2
--- /dev/null
+++ b/mysql-test/r/loaddata_autocom_ndb.result
@@ -0,0 +1,23 @@
+SET SESSION STORAGE_ENGINE = ndbcluster;
+drop table if exists t1;
+create table t1 (a text, b text);
+start transaction;
+load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by '''';
+Warnings:
+Warning 1261 Row 3 doesn't contain data for all columns
+commit;
+select count(*) from t1;
+count(*)
+4
+truncate table t1;
+start transaction;
+load data infile '../std_data_ln/loaddata2.dat' into table t1 fields terminated by ',' enclosed by '''';
+Warnings:
+Warning 1261 Row 3 doesn't contain data for all columns
+rollback;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+select count(*) from t1;
+count(*)
+4
+drop table t1;
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index ba4e9daf7cb..99633f5e12a 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -59,16 +59,16 @@ database()
test
unlock tables;
drop table t1;
-ソ
-ソ
+ƒ\
+ƒ\
c_cp932
+ƒ\
+ƒ\
+ƒ\
ソ
ソ
-ソ
-ソ
-ソ
-ソ
-ソ
+ƒ\
+ƒ\
+----------------------+------------+--------+
| concat('>',col1,'<') | col2 | col3 |
+----------------------+------------+--------+
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 6669b33e1bb..1d131c67c73 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -1403,92 +1403,6 @@ UNLOCK TABLES;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
DROP TABLE t1;
-create database db1;
-use db1;
-CREATE TABLE t2 (
-a varchar(30) default NULL,
-KEY a (a(5))
-);
-INSERT INTO t2 VALUES ('alfred');
-INSERT INTO t2 VALUES ('angie');
-INSERT INTO t2 VALUES ('bingo');
-INSERT INTO t2 VALUES ('waffle');
-INSERT INTO t2 VALUES ('lemon');
-create view v2 as select * from t2 where a like 'a%' with check option;
-
-/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
-/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
-/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
-/*!40101 SET NAMES utf8 */;
-/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
-/*!40103 SET TIME_ZONE='+00:00' */;
-/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
-/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
-/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-DROP TABLE IF EXISTS `t2`;
-CREATE TABLE `t2` (
- `a` varchar(30) default NULL,
- KEY `a` (`a`(5))
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-
-LOCK TABLES `t2` WRITE;
-/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
-INSERT INTO `t2` VALUES ('alfred'),('angie'),('bingo'),('waffle'),('lemon');
-/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
-UNLOCK TABLES;
-DROP TABLE IF EXISTS `v2`;
-/*!50001 DROP VIEW IF EXISTS `v2`*/;
-/*!50001 CREATE TABLE `v2` (
- `a` varchar(30)
-) */;
-/*!50001 DROP TABLE IF EXISTS `v2`*/;
-/*!50001 DROP VIEW IF EXISTS `v2`*/;
-/*!50001 CREATE ALGORITHM=UNDEFINED */
-/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
-/*!50001 VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like _latin1'a%') */
-/*!50002 WITH CASCADED CHECK OPTION */;
-/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
-
-/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
-/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
-/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
-/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
-/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
-/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
-/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-
-drop table t2;
-drop view v2;
-drop database db1;
-create database db2;
-use db2;
-create table t1 (a int);
-create table t2 (a int, b varchar(10), primary key(a));
-insert into t2 values (1, "on"), (2, "off"), (10, "pol"), (12, "meg");
-insert into t1 values (289), (298), (234), (456), (789);
-create view v1 as select * from t2;
-create view v2 as select * from t1;
-drop table t1, t2;
-drop view v1, v2;
-drop database db2;
-create database db1;
-use db1;
-show tables;
-Tables_in_db1
-t1
-t2
-v1
-v2
-select * from t2 order by a;
-a b
-1 on
-2 off
-10 pol
-12 meg
-drop table t1, t2;
-drop database db1;
---fields-optionally-enclosed-by="
CREATE DATABASE mysqldump_test_db;
USE mysqldump_test_db;
CREATE TABLE t1 ( a INT );
@@ -1681,6 +1595,7 @@ select * from t1;
a b
Osnabrück Köln
drop table t1;
+--fields-optionally-enclosed-by="
create table `t1` (
t1_name varchar(255) default null,
t1_id int(10) unsigned not null auto_increment,
@@ -1718,7 +1633,162 @@ t1 CREATE TABLE `t1` (
KEY `t1_name` (`t1_name`)
) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1
drop table `t1`;
+create table t1(a int);
+create table t2(a int);
+create table t3(a int);
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+DROP TABLE IF EXISTS `t3`;
+CREATE TABLE `t3` (
+ `a` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+DROP TABLE IF EXISTS `t1`;
+CREATE TABLE `t1` (
+ `a` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+DROP TABLE IF EXISTS `t2`;
+CREATE TABLE `t2` (
+ `a` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+drop table t1, t2, t3;
+create table t1 (a int);
+mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ * FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064)
+mysqldump: Got error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 when retrieving data from server
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+DROP TABLE IF EXISTS `t1`;
+CREATE TABLE `t1` (
+ `a` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+drop table t1;
End of 4.1 tests
+create database db1;
+use db1;
+CREATE TABLE t2 (
+a varchar(30) default NULL,
+KEY a (a(5))
+);
+INSERT INTO t2 VALUES ('alfred');
+INSERT INTO t2 VALUES ('angie');
+INSERT INTO t2 VALUES ('bingo');
+INSERT INTO t2 VALUES ('waffle');
+INSERT INTO t2 VALUES ('lemon');
+create view v2 as select * from t2 where a like 'a%' with check option;
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+DROP TABLE IF EXISTS `t2`;
+CREATE TABLE `t2` (
+ `a` varchar(30) default NULL,
+ KEY `a` (`a`(5))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+LOCK TABLES `t2` WRITE;
+/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
+INSERT INTO `t2` VALUES ('alfred'),('angie'),('bingo'),('waffle'),('lemon');
+/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
+UNLOCK TABLES;
+DROP TABLE IF EXISTS `v2`;
+/*!50001 DROP VIEW IF EXISTS `v2`*/;
+/*!50001 CREATE TABLE `v2` (
+ `a` varchar(30)
+) */;
+/*!50001 DROP TABLE IF EXISTS `v2`*/;
+/*!50001 DROP VIEW IF EXISTS `v2`*/;
+/*!50001 CREATE ALGORITHM=UNDEFINED */
+/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
+/*!50001 VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like _latin1'a%') */
+/*!50002 WITH CASCADED CHECK OPTION */;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+drop table t2;
+drop view v2;
+drop database db1;
+use test;
+create database db2;
+use db2;
+create table t1 (a int);
+create table t2 (a int, b varchar(10), primary key(a));
+insert into t2 values (1, "on"), (2, "off"), (10, "pol"), (12, "meg");
+insert into t1 values (289), (298), (234), (456), (789);
+create view v1 as select * from t2;
+create view v2 as select * from t1;
+drop table t1, t2;
+drop view v1, v2;
+drop database db2;
+use test;
+create database db1;
+use db1;
+show tables;
+Tables_in_db1
+t1
+t2
+v1
+v2
+select * from t2 order by a;
+a b
+1 on
+2 off
+10 pol
+12 meg
+drop table t1, t2;
+drop database db1;
+use test;
create table t1(a int);
create view v1 as select * from t1;
@@ -2623,44 +2693,6 @@ UNLOCK TABLES;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
drop table t1;
-create table t1(a int);
-create table t2(a int);
-create table t3(a int);
-
-/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
-/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
-/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
-/*!40101 SET NAMES utf8 */;
-/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
-/*!40103 SET TIME_ZONE='+00:00' */;
-/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
-/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
-/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-DROP TABLE IF EXISTS `t3`;
-CREATE TABLE `t3` (
- `a` int(11) default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-DROP TABLE IF EXISTS `t1`;
-CREATE TABLE `t1` (
- `a` int(11) default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-DROP TABLE IF EXISTS `t2`;
-CREATE TABLE `t2` (
- `a` int(11) default NULL
-) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
-
-/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
-/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
-/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
-/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
-/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
-/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
-/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-
-drop table t1, t2, t3;
-End of 4.1 tests
create table t1 (a int);
insert into t1 values (289), (298), (234), (456), (789);
create definer = CURRENT_USER view v1 as select * from t1;
@@ -2892,3 +2924,19 @@ CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
drop table t1;
drop user mysqltest_1@localhost;
+create database mysqldump_myDB;
+use mysqldump_myDB;
+create user myDB_User;
+grant create view, select on mysqldump_myDB.* to myDB_User@localhost;
+create table t1 (c1 int);
+insert into t1 values (3);
+use mysqldump_myDB;
+create view v1 (c1) as select * from t1;
+use mysqldump_myDB;
+drop view v1;
+drop table t1;
+revoke all privileges on mysqldump_myDB.* from myDB_User@localhost;
+drop user myDB_User;
+drop database mysqldump_myDB;
+use test;
+End of 5.0 tests
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index d73dd03fc57..080187cfa7b 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -1297,3 +1297,18 @@ ERROR 3D000: No database selected
create temporary table t1 (i int);
ERROR 3D000: No database selected
use test;
+DROP TABLE IF EXISTS t1, t2, t3;
+CREATE TABLE t1 (i BIGINT, j BIGINT);
+CREATE TABLE t2 (i BIGINT);
+CREATE TABLE t3 (i BIGINT, j BIGINT);
+PREPARE stmt FROM "SELECT * FROM t1 JOIN t2 ON (t2.i = t1.i)
+ LEFT JOIN t3 ON ((t3.i, t3.j) = (t1.i, t1.j))
+ WHERE t1.i = ?";
+SET @a= 1;
+EXECUTE stmt USING @a;
+i j i i j
+EXECUTE stmt USING @a;
+i j i i j
+DEALLOCATE PREPARE stmt;
+DROP TABLE IF EXISTS t1, t2, t3;
+End of 5.0 tests.
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index 926a980f9c4..a735b52a26f 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -947,18 +947,24 @@ COUNT(*)
Warnings:
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
+Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid'
+Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid'
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050328 invalid';
COUNT(*)
0
Warnings:
Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1
Warning 1292 Incorrect datetime value: '20050328 invalid' for column 'date' at row 1
+Warning 1292 Truncated incorrect DOUBLE value: '20050328 invalid'
+Warning 1292 Truncated incorrect DOUBLE value: '20050328 invalid'
SELECT COUNT(*) FROM t1 WHERE date BETWEEN '20050326' AND '20050327 invalid';
COUNT(*)
0
Warnings:
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
Warning 1292 Incorrect datetime value: '20050327 invalid' for column 'date' at row 1
+Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid'
+Warning 1292 Truncated incorrect DOUBLE value: '20050327 invalid'
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 5c2c6e7e965..3edf56496fe 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -896,3 +896,48 @@ EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where
DROP TABLE t1;
+CREATE TABLE t1 (
+item char(20) NOT NULL default '',
+started datetime NOT NULL default '0000-00-00 00:00:00',
+price decimal(16,3) NOT NULL default '0.000',
+PRIMARY KEY (item,started)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+('A1','2005-11-01 08:00:00',1000),
+('A1','2005-11-15 00:00:00',2000),
+('A1','2005-12-12 08:00:00',3000),
+('A2','2005-12-01 08:00:00',1000);
+EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using where
+Warnings:
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+item started price
+A1 2005-11-01 08:00:00 1000.000
+A1 2005-11-15 00:00:00 2000.000
+Warnings:
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
+item started price
+A1 2005-11-01 08:00:00 1000.000
+A1 2005-11-15 00:00:00 2000.000
+DROP INDEX `PRIMARY` ON t1;
+EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+Warnings:
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+item started price
+A1 2005-11-01 08:00:00 1000.000
+A1 2005-11-15 00:00:00 2000.000
+Warnings:
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00' for column 'started' at row 1
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
+item started price
+A1 2005-11-01 08:00:00 1000.000
+A1 2005-11-15 00:00:00 2000.000
+DROP TABLE t1;
diff --git a/mysql-test/r/rpl_ndb_innodb_trans.result b/mysql-test/r/rpl_ndb_innodb_trans.result
new file mode 100644
index 00000000000..148e6247b03
--- /dev/null
+++ b/mysql-test/r/rpl_ndb_innodb_trans.result
@@ -0,0 +1,103 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1 (a int, unique(a)) engine=ndbcluster;
+create table t2 (a int, unique(a)) engine=innodb;
+begin;
+insert into t1 values(1);
+insert into t2 values(1);
+rollback;
+select count(*) from t1;
+count(*)
+0
+select count(*) from t2;
+count(*)
+0
+select count(*) from t1;
+count(*)
+0
+select count(*) from t2;
+count(*)
+0
+begin;
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t2;
+Warnings:
+Warning 1262 Row 1 was truncated; it contained more data than there were input columns
+Warning 1262 Row 2 was truncated; it contained more data than there were input columns
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t1;
+Warnings:
+Warning 1262 Row 1 was truncated; it contained more data than there were input columns
+Warning 1262 Row 2 was truncated; it contained more data than there were input columns
+rollback;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+select count(*) from t1;
+count(*)
+2
+select count(*) from t2;
+count(*)
+0
+select count(*) from t1;
+count(*)
+2
+select count(*) from t2;
+count(*)
+0
+delete from t1;
+delete from t2;
+begin;
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t2;
+Warnings:
+Warning 1262 Row 1 was truncated; it contained more data than there were input columns
+Warning 1262 Row 2 was truncated; it contained more data than there were input columns
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t1;
+Warnings:
+Warning 1262 Row 1 was truncated; it contained more data than there were input columns
+Warning 1262 Row 2 was truncated; it contained more data than there were input columns
+rollback;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+select count(*) from t1;
+count(*)
+2
+select count(*) from t2;
+count(*)
+0
+select count(*) from t1;
+count(*)
+2
+select count(*) from t2;
+count(*)
+0
+delete from t1;
+delete from t2;
+begin;
+insert into t2 values(3),(4);
+insert into t1 values(3),(4);
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t2;
+Warnings:
+Warning 1262 Row 1 was truncated; it contained more data than there were input columns
+Warning 1262 Row 2 was truncated; it contained more data than there were input columns
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t1;
+Warnings:
+Warning 1262 Row 1 was truncated; it contained more data than there were input columns
+Warning 1262 Row 2 was truncated; it contained more data than there were input columns
+rollback;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+select count(*) from t1;
+count(*)
+4
+select count(*) from t2;
+count(*)
+0
+select count(*) from t1;
+count(*)
+4
+select count(*) from t2;
+count(*)
+0
+drop table t1,t2;
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index da1fc58db57..85ea624ce2f 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -634,6 +634,45 @@ flush tables;
return 5;
end|
ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin reset query cache;
+return 1; end|
+ERROR 0A000: RESET is not allowed in stored function or trigger
+create function bug8409() returns int begin reset master;
+return 1; end|
+ERROR 0A000: RESET is not allowed in stored function or trigger
+create function bug8409() returns int begin reset slave;
+return 1; end|
+ERROR 0A000: RESET is not allowed in stored function or trigger
+create function bug8409() returns int begin flush hosts;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush privileges;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush tables with read lock;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush tables;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush logs;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush status;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush slave;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush master;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush des_key_file;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create function bug8409() returns int begin flush user_resources;
+return 1; end|
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
create procedure bug9529_901234567890123456789012345678901234567890123456789012345()
begin
end|
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 88a860d6c8a..854935b071b 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -4872,8 +4872,6 @@ declare continue handler for sqlexception begin end;
select no_such_function();
end|
call bug18787()|
-no_such_function()
-NULL
drop procedure bug18787|
create database bug18344_012345678901|
use bug18344_012345678901|
@@ -5222,6 +5220,126 @@ CHARSET(p3) COLLATION(p3)
greek greek_general_ci
use test|
DROP DATABASE mysqltest1|
+drop table if exists t3|
+drop table if exists t4|
+drop procedure if exists bug8153_subselect|
+drop procedure if exists bug8153_subselect_a|
+drop procedure if exists bug8153_subselect_b|
+drop procedure if exists bug8153_proc_a|
+drop procedure if exists bug8153_proc_b|
+create table t3 (a int)|
+create table t4 (a int)|
+insert into t3 values (1), (1), (2), (3)|
+insert into t4 values (1), (1)|
+create procedure bug8153_subselect()
+begin
+declare continue handler for sqlexception
+begin
+select 'statement failed';
+end;
+update t3 set a=a+1 where (select a from t4 where a=1) is null;
+select 'statement after update';
+end|
+call bug8153_subselect()|
+statement failed
+statement failed
+statement after update
+statement after update
+select * from t3|
+a
+1
+1
+2
+3
+call bug8153_subselect()|
+statement failed
+statement failed
+statement after update
+statement after update
+select * from t3|
+a
+1
+1
+2
+3
+drop procedure bug8153_subselect|
+create procedure bug8153_subselect_a()
+begin
+declare continue handler for sqlexception
+begin
+select 'in continue handler';
+end;
+select 'reachable code a1';
+call bug8153_subselect_b();
+select 'reachable code a2';
+end|
+create procedure bug8153_subselect_b()
+begin
+select 'reachable code b1';
+update t3 set a=a+1 where (select a from t4 where a=1) is null;
+select 'unreachable code b2';
+end|
+call bug8153_subselect_a()|
+reachable code a1
+reachable code a1
+reachable code b1
+reachable code b1
+in continue handler
+in continue handler
+reachable code a2
+reachable code a2
+select * from t3|
+a
+1
+1
+2
+3
+call bug8153_subselect_a()|
+reachable code a1
+reachable code a1
+reachable code b1
+reachable code b1
+in continue handler
+in continue handler
+reachable code a2
+reachable code a2
+select * from t3|
+a
+1
+1
+2
+3
+drop procedure bug8153_subselect_a|
+drop procedure bug8153_subselect_b|
+create procedure bug8153_proc_a()
+begin
+declare continue handler for sqlexception
+begin
+select 'in continue handler';
+end;
+select 'reachable code a1';
+call bug8153_proc_b();
+select 'reachable code a2';
+end|
+create procedure bug8153_proc_b()
+begin
+select 'reachable code b1';
+select no_such_function();
+select 'unreachable code b2';
+end|
+call bug8153_proc_a()|
+reachable code a1
+reachable code a1
+reachable code b1
+reachable code b1
+in continue handler
+in continue handler
+reachable code a2
+reachable code a2
+drop procedure bug8153_proc_a|
+drop procedure bug8153_proc_b|
+drop table t3|
+drop table t4|
drop procedure if exists bug19862|
CREATE TABLE t11 (a INT)|
CREATE TABLE t12 (a INT)|
@@ -5256,4 +5374,24 @@ a
1
use test|
drop table t3|
+DROP PROCEDURE IF EXISTS bug16899_p1|
+DROP FUNCTION IF EXISTS bug16899_f1|
+CREATE DEFINER=1234567890abcdefGHIKL@localhost PROCEDURE bug16899_p1()
+BEGIN
+SET @a = 1;
+END|
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16)
+CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+FUNCTION bug16899_f1() RETURNS INT
+BEGIN
+RETURN 1;
+END|
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
+drop procedure if exists bug21416|
+create procedure bug21416() show create procedure bug21416|
+call bug21416()|
+Procedure sql_mode Create Procedure
+bug21416 CREATE DEFINER=`root`@`localhost` PROCEDURE `bug21416`()
+show create procedure bug21416
+drop procedure bug21416|
drop table t1,t2;
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index f3e797d2344..c687d4c49c8 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -626,12 +626,51 @@ Trigger Event Table Statement Timing Created sql_mode Definer
t1_bi INSERT t1 set new.a = '2004-01-00' BEFORE # root@localhost
drop table t1;
create table t1 (id int);
+create trigger t1_ai after insert on t1 for each row reset query cache;
+ERROR 0A000: RESET is not allowed in stored function or trigger
+create trigger t1_ai after insert on t1 for each row reset master;
+ERROR 0A000: RESET is not allowed in stored function or trigger
+create trigger t1_ai after insert on t1 for each row reset slave;
+ERROR 0A000: RESET is not allowed in stored function or trigger
+create trigger t1_ai after insert on t1 for each row flush hosts;
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create trigger t1_ai after insert on t1 for each row flush tables with read lock;
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create trigger t1_ai after insert on t1 for each row flush logs;
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create trigger t1_ai after insert on t1 for each row flush status;
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create trigger t1_ai after insert on t1 for each row flush slave;
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create trigger t1_ai after insert on t1 for each row flush master;
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create trigger t1_ai after insert on t1 for each row flush des_key_file;
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+create trigger t1_ai after insert on t1 for each row flush user_resources;
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush tables;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush privileges;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
-create procedure p1() flush tables;
+drop procedure if exists p1;
create trigger t1_ai after insert on t1 for each row call p1();
+create procedure p1() flush tables;
+insert into t1 values (0);
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+drop procedure p1;
+create procedure p1() reset query cache;
+insert into t1 values (0);
+ERROR 0A000: RESET is not allowed in stored function or trigger
+drop procedure p1;
+create procedure p1() reset master;
+insert into t1 values (0);
+ERROR 0A000: RESET is not allowed in stored function or trigger
+drop procedure p1;
+create procedure p1() reset slave;
+insert into t1 values (0);
+ERROR 0A000: RESET is not allowed in stored function or trigger
+drop procedure p1;
+create procedure p1() flush hosts;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
@@ -639,6 +678,38 @@ create procedure p1() flush privileges;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
+create procedure p1() flush tables with read lock;
+insert into t1 values (0);
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+drop procedure p1;
+create procedure p1() flush tables;
+insert into t1 values (0);
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+drop procedure p1;
+create procedure p1() flush logs;
+insert into t1 values (0);
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+drop procedure p1;
+create procedure p1() flush status;
+insert into t1 values (0);
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+drop procedure p1;
+create procedure p1() flush slave;
+insert into t1 values (0);
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+drop procedure p1;
+create procedure p1() flush master;
+insert into t1 values (0);
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+drop procedure p1;
+create procedure p1() flush des_key_file;
+insert into t1 values (0);
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+drop procedure p1;
+create procedure p1() flush user_resources;
+insert into t1 values (0);
+ERROR 0A000: FLUSH is not allowed in stored function or trigger
+drop procedure p1;
drop table t1;
create table t1 (id int, data int, username varchar(16));
insert into t1 (id, data) values (1, 0);
@@ -1089,4 +1160,17 @@ begin
set @a:= 1;
end|
ERROR HY000: Triggers can not be created on system tables
+use test|
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1(c INT);
+CREATE TABLE t2(c INT);
+CREATE DEFINER=1234567890abcdefGHIKL@localhost
+TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16)
+CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW SET @a = 2;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
+DROP TABLE t1;
+DROP TABLE t2;
End of 5.0 tests
diff --git a/mysql-test/r/type_varchar.result b/mysql-test/r/type_varchar.result
index e74850bba33..1d707b83a4d 100644
--- a/mysql-test/r/type_varchar.result
+++ b/mysql-test/r/type_varchar.result
@@ -422,3 +422,34 @@ DROP TABLE IF EXISTS t1;
CREATE TABLE t1(f1 CHAR(100) DEFAULT 'test');
INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3));
DROP TABLE IF EXISTS t1;
+drop table if exists t1, t2, t3;
+create table t3 (
+id int(11),
+en varchar(255) character set utf8,
+cz varchar(255) character set utf8
+);
+truncate table t3;
+insert into t3 (id, en, cz) values
+(1,'en string 1','cz string 1'),
+(2,'en string 2','cz string 2'),
+(3,'en string 3','cz string 3');
+create table t1 (
+id int(11),
+name_id int(11)
+);
+insert into t1 (id, name_id) values (1,1), (2,3), (3,3);
+create table t2 (id int(11));
+insert into t2 (id) values (1), (2), (3);
+select t1.*, t2.id, t3.en, t3.cz from t1 left join t2 on t1.id=t2.id
+left join t3 on t1.id=t3.id order by t3.id;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def test t1 t1 id id 3 11 1 Y 32768 0 63
+def test t1 t1 name_id name_id 3 11 1 Y 32768 0 63
+def test t2 t2 id id 3 11 1 Y 32768 0 63
+def test t3 t3 en en 253 255 11 Y 0 0 8
+def test t3 t3 cz cz 253 255 11 Y 0 0 8
+id name_id id en cz
+1 1 1 en string 1 cz string 1
+2 3 2 en string 2 cz string 2
+3 3 3 en string 3 cz string 3
+drop table t1, t2, t3;
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index a0e516d2397..cd834a789bd 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -689,6 +689,12 @@ select @@log_queries_not_using_indexes;
show variables like 'log_queries_not_using_indexes';
Variable_name Value
log_queries_not_using_indexes OFF
+select @@"";
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '""' at line 1
+select @@&;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '&' at line 1
+select @@@;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@' at line 1
End of 5.0 tests
set global binlog_cache_size =@my_binlog_cache_size;
set global connect_timeout =@my_connect_timeout;
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index f9267b85134..f70547cd4a8 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -2879,3 +2879,41 @@ View Create View
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` where (`t1`.`f1` between now() and (now() + interval 1 minute))
drop view v1;
drop table t1;
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+DROP VIEW IF EXISTS v2;
+CREATE TABLE t1(a INT, b INT);
+CREATE DEFINER=1234567890abcdefGHIKL@localhost
+VIEW v1 AS SELECT a FROM t1;
+ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16)
+CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+VIEW v2 AS SELECT b FROM t1;
+ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
+DROP TABLE t1;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP VIEW IF EXISTS v1, v2;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (i INT);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+INSERT INTO v1 VALUES (0);
+RETURN 0;
+END |
+SELECT f1();
+f1()
+0
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t1;
+CREATE FUNCTION f2() RETURNS INT
+BEGIN
+INSERT INTO v2 VALUES (0);
+RETURN 0;
+END |
+SELECT f2();
+ERROR HY000: The target table v2 of the INSERT is not updatable
+DROP FUNCTION f1;
+DROP FUNCTION f2;
+DROP VIEW v1, v2;
+DROP TABLE t1;
+End of 5.0 tests.
diff --git a/mysql-test/std_data/14897.frm b/mysql-test/std_data/14897.frm
new file mode 100644
index 00000000000..aff11b467b0
--- /dev/null
+++ b/mysql-test/std_data/14897.frm
Binary files differ
diff --git a/mysql-test/t/ctype_recoding.test b/mysql-test/t/ctype_recoding.test
index 2d6b55600b1..c18c46b6b08 100644
--- a/mysql-test/t/ctype_recoding.test
+++ b/mysql-test/t/ctype_recoding.test
@@ -187,4 +187,16 @@ select rpad(c1,3,'ö'), rpad('ö',3,c1) from t1;
#select case c1 when 'ß' then 'ß' when 'ö' then 'ö' else 'c' end from t1;
#select export_set(5,c1,'ö'), export_set(5,'ö',c1) from t1;
drop table t1;
-# End of 4.1 tests
+
+#
+# Bug 20695: problem with field default value's character set
+#
+
+set names koi8r;
+create table t1(a char character set cp1251 default _koi8r 0xFF);
+show create table t1;
+drop table t1;
+--error 1067
+create table t1(a char character set latin1 default _cp1251 0xFF);
+
+--echo End of 4.1 tests
diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test
index eea0b06b224..8116d39e3db 100644
--- a/mysql-test/t/ctype_ucs.test
+++ b/mysql-test/t/ctype_ucs.test
@@ -465,7 +465,51 @@ INSERT INTO t1 VALUES (1, 'ZZZZZ'), (1, 'ZZZ'), (2, 'ZZZ'), (2, 'ZZZZZ');
SELECT id, MIN(s) FROM t1 GROUP BY id;
DROP TABLE t1;
-# End of 4.1 tests
+
+#
+# Bug #20536: md5() with GROUP BY and UCS2 return different results on myisam/innodb
+#
+
+--disable_warnings
+drop table if exists bug20536;
+--enable_warnings
+
+set names latin1;
+create table bug20536 (id bigint not null auto_increment primary key, name
+varchar(255) character set ucs2 not null);
+insert into `bug20536` (`id`,`name`) values (1, _latin1 x'7465737431'), (2, "'test\\_2'");
+select md5(name) from bug20536;
+select sha1(name) from bug20536;
+select make_set(3, name, upper(name)) from bug20536;
+select export_set(5, name, upper(name)) from bug20536;
+select export_set(5, name, upper(name), ",", 5) from bug20536;
+
+# Some broken functions: add these tests just to document current behavior.
+
+# PASSWORD and OLD_PASSWORD don't work with UCS2 strings, but to fix it would
+# not be backwards compatible in all cases, so it's best to leave it alone
+select password(name) from bug20536;
+select old_password(name) from bug20536;
+
+# Disable test case as encrypt relies on 'crypt' function.
+# "decrypt" is noramlly tested in func_crypt.test which have a
+# "have_crypt.inc" test
+--disable_parsing
+# ENCRYPT relies on OS function crypt() which takes a NUL-terminated string; it
+# doesn't return good results for strings with embedded 0 bytes. It won't be
+# fixed unless we choose to re-implement the crypt() function ourselves to take
+# an extra size_t string_length argument.
+select encrypt(name, 'SALT') from bug20536;
+--enable_parsing
+
+# QUOTE doesn't work with UCS2 data. It would require a total rewrite
+# of Item_func_quote::val_str(), which isn't worthwhile until UCS2 is
+# supported fully as a client character set.
+select quote(name) from bug20536;
+
+drop table bug20536;
+
+--echo End of 4.1 tests
#
# Conversion from an UCS2 string to a decimal column
@@ -497,3 +541,5 @@ create table t1(a blob, b text charset utf8, c text charset ucs2);
select data_type, character_octet_length, character_maximum_length
from information_schema.columns where table_name='t1';
drop table t1;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 365d0fab4bf..b6137d5f084 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -728,6 +728,24 @@ select repeat(_utf8'+',3) as h union select NULL;
select ifnull(NULL, _utf8'string');
#
+# Bug#9509 Optimizer: wrong result after AND with comparisons
+#
+set names utf8;
+create table t1 (s1 char(5) character set utf8 collate utf8_lithuanian_ci);
+insert into t1 values ('I'),('K'),('Y');
+select * from t1 where s1 < 'K' and s1 = 'Y';
+select * from t1 where 'K' > s1 and s1 = 'Y';
+drop table t1;
+
+create table t1 (s1 char(5) character set utf8 collate utf8_czech_ci);
+insert into t1 values ('c'),('d'),('h'),('ch'),('CH'),('cH'),('Ch'),('i');
+select * from t1 where s1 > 'd' and s1 = 'CH';
+select * from t1 where 'd' < s1 and s1 = 'CH';
+select * from t1 where s1 = 'cH' and s1 <> 'ch';
+select * from t1 where 'cH' = s1 and s1 <> 'ch';
+drop table t1;
+
+#
# Bug#10714: Inserting double value into utf8 column crashes server
#
create table t1 (a varchar(255)) default character set utf8;
@@ -1051,6 +1069,23 @@ explain select a from t1 group by a;
select a from t1 group by a;
drop table t1;
+#
+# Bug#20393: User name truncation in mysql client
+# Bug#21432: Database/Table name limited to 64 bytes, not chars, problems with multi-byte
+#
+set names utf8;
+#create user юзер_юзер@localhost;
+grant select on test.* to юзер_юзер@localhost;
+--exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()"
+revoke all on test.* from юзер_юзер@localhost;
+drop user юзер_юзер@localhost;
+
+create database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
+use имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
+select database();
+drop database имÑ_базы_в_кодировке_утф8_длиной_больше_чем_45;
+use test;
+
# End of 4.1 tests
#
diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test
index 7cd943d46da..a1451773e90 100644
--- a/mysql-test/t/drop.test
+++ b/mysql-test/t/drop.test
@@ -81,3 +81,44 @@ show tables;
drop table t1;
# End of 4.1 tests
+
+
+#
+# Test for bug#21216 "Simultaneous DROP TABLE and SHOW OPEN TABLES causes
+# server to crash". Crash (caused by failed assertion in 5.0 or by null
+# pointer dereference in 5.1) happened when one ran SHOW OPEN TABLES
+# while concurrently doing DROP TABLE (or RENAME TABLE, CREATE TABLE LIKE
+# or any other command that takes name-lock) in other connection.
+#
+# Also includes test for similar bug#12212 "Crash that happens during
+# removing of database name from cache" reappeared in 5.1 as bug#19403
+# In its case crash happened when one concurrently executed DROP DATABASE
+# and one of name-locking command.
+#
+--disable_warnings
+drop database if exists mysqltest;
+drop table if exists t1;
+--enable_warnings
+create table t1 (i int);
+lock tables t1 read;
+create database mysqltest;
+connect (addconroot1, localhost, root,,);
+--send drop table t1
+connect (addconroot2, localhost, root,,);
+# Server should not crash in any of the following statements
+--disable_result_log
+show open tables;
+--enable_result_log
+--send drop database mysqltest
+connection default;
+select 1;
+unlock tables;
+connection addconroot1;
+--reap
+connection addconroot2;
+--reap
+disconnect addconroot1;
+disconnect addconroot2;
+connection default;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
index 0475dd4bdb6..52a5512d070 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -78,7 +78,13 @@ connection default;
DROP TABLE t1;
-# End of 4.1 tests
+#
+# Bug #21531: EXPORT_SET() doesn't accept args with coercible character sets
+#
+select export_set(3, _latin1'foo', _utf8'bar', ',', 4);
+
+--echo End of 4.1 tests
+
#
# Test for BUG#9535
@@ -87,7 +93,9 @@ create table t1 as select uuid(), length(uuid());
show create table t1;
drop table t1;
+#
# Bug #6760: Add SLEEP() function
+#
create table t1 (a timestamp default '2005-05-05 01:01:01',
b timestamp default '2005-05-05 01:01:01');
insert into t1 set a = now();
@@ -117,4 +125,4 @@ drop table t2;
drop table t1;
set global query_cache_size=default;
-# End of 5.0 tests
+--echo End of 5.0 tests
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 0945c3ab33e..be09b00ad46 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -583,3 +583,21 @@ DROP TABLE t1,t2;
# Restore timezone to default
set time_zone= @@global.time_zone;
+
+#
+# 21913: DATE_FORMAT() Crashes mysql server if I use it through
+# mysql-connector-j driver.
+#
+
+SET NAMES latin1;
+SET character_set_results = NULL;
+SHOW VARIABLES LIKE 'character_set_results';
+
+CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY);
+INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd');
+
+SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868;
+
+DROP TABLE testBug8868;
+
+SET NAMES DEFAULT;
diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test
index cc66615039f..d3781d58780 100644
--- a/mysql-test/t/grant.test
+++ b/mysql-test/t/grant.test
@@ -682,8 +682,6 @@ drop table t2;
drop table t1;
-
-
#
# Bug#20214: Incorrect error when user calls SHOW CREATE VIEW on non
# privileged view
@@ -807,12 +805,62 @@ DROP DATABASE mysqltest3;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'mysqltest_1'@'localhost';
DROP USER 'mysqltest_1'@'localhost';
-
+# restore the original database
+use test;
#
# Bug #10668: CREATE USER does not enforce username length limit
#
---error ER_CANNOT_USER
+--error ER_WRONG_STRING_LENGTH
create user mysqltest1_thisisreallytoolong;
+#
+# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause.
+#
+# These checks are intended to ensure that appropriate errors are risen when
+# illegal user name or hostname is specified in user-clause of GRANT/REVOKE
+# statements.
+#
+
+# Working with database-level privileges.
+
+--error ER_WRONG_STRING_LENGTH
+GRANT CREATE ON mysqltest.* TO 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+GRANT CREATE ON mysqltest.* TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE CREATE ON mysqltest.* FROM 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE CREATE ON mysqltest.* FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+
+# Working with table-level privileges.
+
+--error ER_WRONG_STRING_LENGTH
+GRANT CREATE ON t1 TO 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+GRANT CREATE ON t1 TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE CREATE ON t1 FROM 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE CREATE ON t1 FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+
+# Working with routine-level privileges.
+
+--error ER_WRONG_STRING_LENGTH
+GRANT EXECUTE ON PROCEDURE p1 TO 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+GRANT EXECUTE ON PROCEDURE p1 TO some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE EXECUTE ON PROCEDURE p1 FROM 1234567890abcdefGHIKL@localhost;
+
+--error ER_WRONG_STRING_LENGTH
+REVOKE EXECUTE ON PROCEDURE t1 FROM some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY;
--echo End of 5.0 tests
diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test
index a7f1eeaa2cc..bf18b8da941 100644
--- a/mysql-test/t/handler.test
+++ b/mysql-test/t/handler.test
@@ -1,3 +1,4 @@
+-- source include/not_embedded.inc
#
# test of HANDLER ...
#
diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test
index e74e9723ca6..03ba8661a3c 100644
--- a/mysql-test/t/heap_btree.test
+++ b/mysql-test/t/heap_btree.test
@@ -204,3 +204,4 @@ CREATE TABLE t1 (a INT, UNIQUE USING BTREE(a)) ENGINE=MEMORY;
INSERT INTO t1 VALUES(NULL),(NULL);
DROP TABLE t1;
+--echo End of 5.0 tests
diff --git a/mysql-test/t/im_daemon_life_cycle.imtest b/mysql-test/t/im_daemon_life_cycle.imtest
index fe2345a9987..a07da161279 100644
--- a/mysql-test/t/im_daemon_life_cycle.imtest
+++ b/mysql-test/t/im_daemon_life_cycle.imtest
@@ -6,7 +6,6 @@
#
###########################################################################
---source include/im_check_os.inc
--source include/im_check_env.inc
###########################################################################
diff --git a/mysql-test/t/im_life_cycle.imtest b/mysql-test/t/im_life_cycle.imtest
index 16cf25a8f35..ddfb62d312e 100644
--- a/mysql-test/t/im_life_cycle.imtest
+++ b/mysql-test/t/im_life_cycle.imtest
@@ -6,7 +6,6 @@
#
###########################################################################
---source include/im_check_os.inc
--source include/im_check_env.inc
###########################################################################
diff --git a/mysql-test/t/im_options_set.imtest b/mysql-test/t/im_options_set.imtest
index 76e209b6a66..6a70c31c0a4 100644
--- a/mysql-test/t/im_options_set.imtest
+++ b/mysql-test/t/im_options_set.imtest
@@ -38,7 +38,6 @@
###########################################################################
---source include/im_check_os.inc
--source include/im_check_env.inc
###########################################################################
diff --git a/mysql-test/t/im_options_unset.imtest b/mysql-test/t/im_options_unset.imtest
index 06f59e79ffe..074c9a3b869 100644
--- a/mysql-test/t/im_options_unset.imtest
+++ b/mysql-test/t/im_options_unset.imtest
@@ -45,7 +45,6 @@
###########################################################################
---source include/im_check_os.inc
--source include/im_check_env.inc
###########################################################################
diff --git a/mysql-test/t/im_utils.imtest b/mysql-test/t/im_utils.imtest
index 4c05b342af5..52878f6c2b5 100644
--- a/mysql-test/t/im_utils.imtest
+++ b/mysql-test/t/im_utils.imtest
@@ -6,7 +6,6 @@
#
###########################################################################
---source include/im_check_os.inc
--source include/im_check_env.inc
###########################################################################
diff --git a/mysql-test/t/limit.test b/mysql-test/t/limit.test
index 6df865278f6..cf7789428b2 100644
--- a/mysql-test/t/limit.test
+++ b/mysql-test/t/limit.test
@@ -60,4 +60,14 @@ select 1 as a from t1 union all select 1 from dual limit 1;
(select 1 as a from t1) union all (select 1 from dual) limit 1;
drop table t1;
+#
+# Bug #21787: COUNT(*) + ORDER BY + LIMIT returns wrong result
+#
+create table t1 (a int);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7);
+explain select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3;
+select count(*) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3;
+explain select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3;
+select sum(a) c FROM t1 WHERE a > 0 ORDER BY c LIMIT 3;
+
# End of 4.1 tests
diff --git a/mysql-test/t/loaddata_autocom_innodb.test b/mysql-test/t/loaddata_autocom_innodb.test
new file mode 100644
index 00000000000..d7f152cb286
--- /dev/null
+++ b/mysql-test/t/loaddata_autocom_innodb.test
@@ -0,0 +1,4 @@
+--source include/have_innodb.inc
+let $engine_type= InnoDB;
+
+--source include/loaddata_autocom.inc
diff --git a/mysql-test/t/loaddata_autocom_ndb.test b/mysql-test/t/loaddata_autocom_ndb.test
new file mode 100644
index 00000000000..f4a6743aabe
--- /dev/null
+++ b/mysql-test/t/loaddata_autocom_ndb.test
@@ -0,0 +1,4 @@
+--source include/have_ndb.inc
+let $engine_type=ndbcluster;
+
+--source include/loaddata_autocom.inc
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index 385c59d1503..cf4e6f4047c 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -52,8 +52,8 @@ drop table t1;
--exec $MYSQL --default-character-set=cp932 test -e "charset utf8;"
# its usage to switch internally in mysql to requested charset
---exec $MYSQL --default-character-set=utf8 test -e "charset cp932; set @@session.character_set_client= cp932; select 'ƒ\'; create table t1 (c_cp932 TEXT CHARACTER SET cp932); insert into t1 values('ƒ\'); select * from t1; drop table t1;"
---exec $MYSQL --default-character-set=utf8 test -e "charset cp932; set character_set_client= cp932; select 'ƒ\'"
+--exec $MYSQL --default-character-set=utf8 test -e "charset cp932; select 'ƒ\'; create table t1 (c_cp932 TEXT CHARACTER SET cp932); insert into t1 values('ƒ\'); select * from t1; drop table t1;"
+--exec $MYSQL --default-character-set=utf8 test -e "charset cp932; select 'ƒ\'"
--exec $MYSQL --default-character-set=utf8 test -e "/*charset cp932 */; set character_set_client= cp932; select 'ƒ\'"
--exec $MYSQL --default-character-set=utf8 test -e "/*!\C cp932 */; set character_set_client= cp932; select 'ƒ\'"
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 848c5360db7..9766ee8d9c8 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -548,71 +548,6 @@ INSERT INTO t1 VALUES (1),(2),(3);
--exec $MYSQL_DUMP --add-drop-database --skip-comments --databases test
DROP TABLE t1;
-
-#
-# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X)
-#
-
-create database db1;
-use db1;
-
-CREATE TABLE t2 (
- a varchar(30) default NULL,
- KEY a (a(5))
-);
-
-INSERT INTO t2 VALUES ('alfred');
-INSERT INTO t2 VALUES ('angie');
-INSERT INTO t2 VALUES ('bingo');
-INSERT INTO t2 VALUES ('waffle');
-INSERT INTO t2 VALUES ('lemon');
-create view v2 as select * from t2 where a like 'a%' with check option;
---exec $MYSQL_DUMP --skip-comments db1
-drop table t2;
-drop view v2;
-drop database db1;
-
-#
-# Bug 10713 mysqldump includes database in create view and referenced tables
-#
-
-# create table and views in db2
-create database db2;
-use db2;
-create table t1 (a int);
-create table t2 (a int, b varchar(10), primary key(a));
-insert into t2 values (1, "on"), (2, "off"), (10, "pol"), (12, "meg");
-insert into t1 values (289), (298), (234), (456), (789);
-create view v1 as select * from t2;
-create view v2 as select * from t1;
-
-# dump tables and view from db2
---exec $MYSQL_DUMP db2 > $MYSQLTEST_VARDIR/tmp/bug10713.sql
-
-# drop the db, tables and views
-drop table t1, t2;
-drop view v1, v2;
-drop database db2;
-
-# create db1 and reload dump
-create database db1;
-use db1;
---exec $MYSQL db1 < $MYSQLTEST_VARDIR/tmp/bug10713.sql
-
-# check that all tables and views could be created
-show tables;
-select * from t2 order by a;
-
-drop table t1, t2;
-drop database db1;
-
-#
-# BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence
-#
-
---exec $MYSQL_MY_PRINT_DEFAULTS --config-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump
-
-
#
# Bug #9558 mysqldump --no-data db t1 t2 format still dumps data
#
@@ -720,6 +655,12 @@ select * from t1;
drop table t1;
#
+# BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence
+#
+
+--exec $MYSQL_MY_PRINT_DEFAULTS --config-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump
+
+#
# BUG #19025 mysqldump doesn't correctly dump "auto_increment = [int]"
#
create table `t1` (
@@ -748,9 +689,88 @@ show create table `t1`;
drop table `t1`;
+#
+# Bug #18536: wrong table order
+#
+
+create table t1(a int);
+create table t2(a int);
+create table t3(a int);
+--error 6
+--exec $MYSQL_DUMP --skip-comments --force --no-data test t3 t1 non_existing t2
+drop table t1, t2, t3;
+
+#
+# Bug #21288: mysqldump segmentation fault when using --where
+#
+create table t1 (a int);
+--error 2
+--exec $MYSQL_DUMP --skip-comments --force test t1 --where='xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 2>&1
+drop table t1;
+
--echo End of 4.1 tests
#
+# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X)
+#
+
+create database db1;
+use db1;
+
+CREATE TABLE t2 (
+ a varchar(30) default NULL,
+ KEY a (a(5))
+);
+
+INSERT INTO t2 VALUES ('alfred');
+INSERT INTO t2 VALUES ('angie');
+INSERT INTO t2 VALUES ('bingo');
+INSERT INTO t2 VALUES ('waffle');
+INSERT INTO t2 VALUES ('lemon');
+create view v2 as select * from t2 where a like 'a%' with check option;
+--exec $MYSQL_DUMP --skip-comments db1
+drop table t2;
+drop view v2;
+drop database db1;
+use test;
+
+#
+# Bug 10713 mysqldump includes database in create view and referenced tables
+#
+
+# create table and views in db2
+create database db2;
+use db2;
+create table t1 (a int);
+create table t2 (a int, b varchar(10), primary key(a));
+insert into t2 values (1, "on"), (2, "off"), (10, "pol"), (12, "meg");
+insert into t1 values (289), (298), (234), (456), (789);
+create view v1 as select * from t2;
+create view v2 as select * from t1;
+
+# dump tables and view from db2
+--exec $MYSQL_DUMP db2 > $MYSQLTEST_VARDIR/tmp/bug10713.sql
+
+# drop the db, tables and views
+drop table t1, t2;
+drop view v1, v2;
+drop database db2;
+use test;
+
+# create db1 and reload dump
+create database db1;
+use db1;
+--exec $MYSQL db1 < $MYSQLTEST_VARDIR/tmp/bug10713.sql
+
+# check that all tables and views could be created
+show tables;
+select * from t2 order by a;
+
+drop table t1, t2;
+drop database db1;
+use test;
+
+#
# dump of view
#
create table t1(a int);
@@ -813,6 +833,7 @@ select v3.a from v3, v1 where v1.a=v3.a and v3.b=3 limit 1;
drop view v1, v2, v3;
drop table t1;
+
#
# Test for dumping triggers
#
@@ -1073,19 +1094,6 @@ insert into t1 values ('','');
drop table t1;
#
-# Bug #18536: wrong table order
-#
-
-create table t1(a int);
-create table t2(a int);
-create table t3(a int);
---error 6
---exec $MYSQL_DUMP --skip-comments --force --no-data test t3 t1 non_existing t2
-drop table t1, t2, t3;
-
---echo End of 4.1 tests
-
-#
# Bug 14871 Invalid view dump output
#
@@ -1266,11 +1274,11 @@ use mysqldump_dbb;
drop view v1;
drop table t1;
drop database mysqldump_dbb;
+use test;
#
# Bug#21215 mysqldump creating incomplete backups without warning
#
-use test;
# Create user without sufficient privs to perform the requested operation
create user mysqltest_1@localhost;
@@ -1309,3 +1317,36 @@ grant REPLICATION CLIENT on *.* to mysqltest_1@localhost;
# Clean up
drop table t1;
drop user mysqltest_1@localhost;
+
+#
+# Bug #21527 mysqldump incorrectly tries to LOCK TABLES on the
+# information_schema database.
+#
+connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
+connection root;
+create database mysqldump_myDB;
+use mysqldump_myDB;
+create user myDB_User;
+grant create view, select on mysqldump_myDB.* to myDB_User@localhost;
+create table t1 (c1 int);
+insert into t1 values (3);
+
+connect (user1,localhost,myDB_User,,mysqldump_myDB,$MASTER_MYPORT,$MASTER_MYSOCK);
+connection user1;
+use mysqldump_myDB;
+create view v1 (c1) as select * from t1;
+
+# Backup should not fail.
+--exec $MYSQL_DUMP --all-databases --add-drop-table > $MYSQLTEST_VARDIR/tmp/bug21527.sql
+
+# Clean up
+connection root;
+use mysqldump_myDB;
+drop view v1;
+drop table t1;
+revoke all privileges on mysqldump_myDB.* from myDB_User@localhost;
+drop user myDB_User;
+drop database mysqldump_myDB;
+use test;
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index d0f31087c8f..5b2e37ecc94 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -1329,4 +1329,33 @@ create temporary table t1 (i int);
# Restore the old environemnt
#
use test;
-# End of 5.0 tests
+
+
+#
+# BUG#21166: Prepared statement causes signal 11 on second execution
+#
+# Changes in an item tree done by optimizer weren't properly
+# registered and went unnoticed, which resulted in preliminary freeing
+# of used memory.
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1, t2, t3;
+--enable_warnings
+
+CREATE TABLE t1 (i BIGINT, j BIGINT);
+CREATE TABLE t2 (i BIGINT);
+CREATE TABLE t3 (i BIGINT, j BIGINT);
+
+PREPARE stmt FROM "SELECT * FROM t1 JOIN t2 ON (t2.i = t1.i)
+ LEFT JOIN t3 ON ((t3.i, t3.j) = (t1.i, t1.j))
+ WHERE t1.i = ?";
+
+SET @a= 1;
+EXECUTE stmt USING @a;
+EXECUTE stmt USING @a;
+
+DEALLOCATE PREPARE stmt;
+DROP TABLE IF EXISTS t1, t2, t3;
+
+
+--echo End of 5.0 tests.
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 776c1a466ca..240851e6ac4 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -709,5 +709,34 @@ EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c;
DROP TABLE t1;
+#
+# Bug #16249: different results for a range with an without index
+# when a range condition use an invalid datetime constant
+#
+
+CREATE TABLE t1 (
+ item char(20) NOT NULL default '',
+ started datetime NOT NULL default '0000-00-00 00:00:00',
+ price decimal(16,3) NOT NULL default '0.000',
+ PRIMARY KEY (item,started)
+) ENGINE=MyISAM;
+
+INSERT INTO t1 VALUES
+('A1','2005-11-01 08:00:00',1000),
+('A1','2005-11-15 00:00:00',2000),
+('A1','2005-12-12 08:00:00',3000),
+('A2','2005-12-01 08:00:00',1000);
+
+EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
+
+DROP INDEX `PRIMARY` ON t1;
+
+EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
+
+DROP TABLE t1;
# End of 5.0 tests
diff --git a/mysql-test/t/rpl_ndb_innodb_trans-slave.opt b/mysql-test/t/rpl_ndb_innodb_trans-slave.opt
new file mode 100644
index 00000000000..627becdbfb5
--- /dev/null
+++ b/mysql-test/t/rpl_ndb_innodb_trans-slave.opt
@@ -0,0 +1 @@
+--innodb
diff --git a/mysql-test/t/rpl_ndb_innodb_trans.test b/mysql-test/t/rpl_ndb_innodb_trans.test
new file mode 100644
index 00000000000..127c2464570
--- /dev/null
+++ b/mysql-test/t/rpl_ndb_innodb_trans.test
@@ -0,0 +1,66 @@
+# Test of a transaction mixing the two engines
+
+-- source include/have_ndb.inc
+-- source include/have_innodb.inc
+-- source include/master-slave.inc
+
+create table t1 (a int, unique(a)) engine=ndbcluster;
+create table t2 (a int, unique(a)) engine=innodb;
+
+
+begin;
+insert into t1 values(1);
+insert into t2 values(1);
+rollback;
+
+select count(*) from t1;
+select count(*) from t2;
+sync_slave_with_master;
+select count(*) from t1;
+select count(*) from t2;
+connection master;
+
+begin;
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t2;
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t1;
+rollback;
+
+select count(*) from t1;
+select count(*) from t2;
+sync_slave_with_master;
+select count(*) from t1;
+select count(*) from t2;
+connection master;
+
+delete from t1;
+delete from t2;
+begin;
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t2;
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t1;
+rollback;
+
+select count(*) from t1;
+select count(*) from t2;
+sync_slave_with_master;
+select count(*) from t1;
+select count(*) from t2;
+connection master;
+
+delete from t1;
+delete from t2;
+begin;
+insert into t2 values(3),(4);
+insert into t1 values(3),(4);
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t2;
+load data infile '../std_data_ln/rpl_loaddata.dat' into table t1;
+rollback;
+
+select count(*) from t1;
+select count(*) from t2;
+sync_slave_with_master;
+select count(*) from t1;
+select count(*) from t2;
+connection master;
+
+drop table t1,t2;
+sync_slave_with_master;
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index 2abb923efbb..abb36f040d2 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -899,6 +899,45 @@ begin
flush tables;
return 5;
end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin reset query cache;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin reset master;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin reset slave;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin flush hosts;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin flush privileges;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin flush tables with read lock;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin flush tables;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin flush logs;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin flush status;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin flush slave;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin flush master;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin flush des_key_file;
+return 1; end|
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create function bug8409() returns int begin flush user_resources;
+return 1; end|
#
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index ba30699b1d0..4b0f463a9e3 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -6147,6 +6147,104 @@ use test|
DROP DATABASE mysqltest1|
#
+# BUG#8153: Stored procedure with subquery and continue handler, wrong result
+#
+
+--disable_warnings
+drop table if exists t3|
+drop table if exists t4|
+drop procedure if exists bug8153_subselect|
+drop procedure if exists bug8153_subselect_a|
+drop procedure if exists bug8153_subselect_b|
+drop procedure if exists bug8153_proc_a|
+drop procedure if exists bug8153_proc_b|
+--enable_warnings
+
+create table t3 (a int)|
+create table t4 (a int)|
+insert into t3 values (1), (1), (2), (3)|
+insert into t4 values (1), (1)|
+
+## Testing the use case reported in Bug#8153
+
+create procedure bug8153_subselect()
+begin
+ declare continue handler for sqlexception
+ begin
+ select 'statement failed';
+ end;
+ update t3 set a=a+1 where (select a from t4 where a=1) is null;
+ select 'statement after update';
+end|
+
+call bug8153_subselect()|
+select * from t3|
+
+call bug8153_subselect()|
+select * from t3|
+
+drop procedure bug8153_subselect|
+
+## Testing a subselect with a non local handler
+
+create procedure bug8153_subselect_a()
+begin
+ declare continue handler for sqlexception
+ begin
+ select 'in continue handler';
+ end;
+
+ select 'reachable code a1';
+ call bug8153_subselect_b();
+ select 'reachable code a2';
+end|
+
+create procedure bug8153_subselect_b()
+begin
+ select 'reachable code b1';
+ update t3 set a=a+1 where (select a from t4 where a=1) is null;
+ select 'unreachable code b2';
+end|
+
+call bug8153_subselect_a()|
+select * from t3|
+
+call bug8153_subselect_a()|
+select * from t3|
+
+drop procedure bug8153_subselect_a|
+drop procedure bug8153_subselect_b|
+
+## Testing extra use cases, found while investigating
+## This is related to BUG#18787, with a non local handler
+
+create procedure bug8153_proc_a()
+begin
+ declare continue handler for sqlexception
+ begin
+ select 'in continue handler';
+ end;
+
+ select 'reachable code a1';
+ call bug8153_proc_b();
+ select 'reachable code a2';
+end|
+
+create procedure bug8153_proc_b()
+begin
+ select 'reachable code b1';
+ select no_such_function();
+ select 'unreachable code b2';
+end|
+
+call bug8153_proc_a()|
+
+drop procedure bug8153_proc_a|
+drop procedure bug8153_proc_b|
+drop table t3|
+drop table t4|
+
+#
# BUG#19862: Sort with filesort by function evaluates function twice
#
--disable_warnings
@@ -6188,6 +6286,42 @@ select * from (select 1 as a) as t1 natural join (select * from test.t3) as t2|
use test|
drop table t3|
+
+#
+# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause.
+#
+
+# Prepare.
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS bug16899_p1|
+DROP FUNCTION IF EXISTS bug16899_f1|
+--enable_warnings
+
+--error ER_WRONG_STRING_LENGTH
+CREATE DEFINER=1234567890abcdefGHIKL@localhost PROCEDURE bug16899_p1()
+BEGIN
+ SET @a = 1;
+END|
+
+--error ER_WRONG_STRING_LENGTH
+CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+ FUNCTION bug16899_f1() RETURNS INT
+BEGIN
+ RETURN 1;
+END|
+
+
+#
+# BUG#21416: SP: Recursion level higher than zero needed for non-recursive call
+#
+--disable_warnings
+drop procedure if exists bug21416|
+--enable_warnings
+create procedure bug21416() show create procedure bug21416|
+call bug21416()|
+drop procedure bug21416|
+
#
# BUG#NNNN: New bug synopsis
#
diff --git a/mysql-test/t/system_mysql_db_fix.test b/mysql-test/t/system_mysql_db_fix.test
index 0a2ab180806..fa44b454b4f 100644
--- a/mysql-test/t/system_mysql_db_fix.test
+++ b/mysql-test/t/system_mysql_db_fix.test
@@ -1,6 +1,9 @@
# Embedded server doesn't support external clients
--source include/not_embedded.inc
+# Windows doesn't support execution of shell scripts (to fix!!)
+--source include/not_windows.inc
+
#
# This is the test for mysql_fix_privilege_tables
#
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index 95e8eaae83e..2a145e1eeaa 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -651,17 +651,105 @@ drop table t1;
# of functions and triggers.
create table t1 (id int);
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create trigger t1_ai after insert on t1 for each row reset query cache;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create trigger t1_ai after insert on t1 for each row reset master;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create trigger t1_ai after insert on t1 for each row reset slave;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create trigger t1_ai after insert on t1 for each row flush hosts;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create trigger t1_ai after insert on t1 for each row flush tables with read lock;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create trigger t1_ai after insert on t1 for each row flush logs;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create trigger t1_ai after insert on t1 for each row flush status;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create trigger t1_ai after insert on t1 for each row flush slave;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create trigger t1_ai after insert on t1 for each row flush master;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create trigger t1_ai after insert on t1 for each row flush des_key_file;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+create trigger t1_ai after insert on t1 for each row flush user_resources;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create trigger t1_ai after insert on t1 for each row flush tables;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
create trigger t1_ai after insert on t1 for each row flush privileges;
-create procedure p1() flush tables;
+--disable_warnings
+drop procedure if exists p1;
+--enable_warnings
+
create trigger t1_ai after insert on t1 for each row call p1();
+create procedure p1() flush tables;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() reset query cache;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() reset master;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() reset slave;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() flush hosts;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
drop procedure p1;
create procedure p1() flush privileges;
--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() flush tables with read lock;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() flush tables;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() flush logs;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() flush status;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() flush slave;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() flush master;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() flush des_key_file;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
+drop procedure p1;
+create procedure p1() flush user_resources;
+--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG
+insert into t1 values (0);
+
drop procedure p1;
drop table t1;
@@ -1301,6 +1389,36 @@ create trigger wont_work after update on event for each row
begin
set @a:= 1;
end|
+use test|
delimiter ;|
+
+#
+# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause.
+#
+
+# Prepare.
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1(c INT);
+CREATE TABLE t2(c INT);
+
+--error ER_WRONG_STRING_LENGTH
+CREATE DEFINER=1234567890abcdefGHIKL@localhost
+ TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1;
+
+--error ER_WRONG_STRING_LENGTH
+CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+ TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW SET @a = 2;
+
+# Cleanup.
+
+DROP TABLE t1;
+DROP TABLE t2;
+
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/type_varchar.test b/mysql-test/t/type_varchar.test
index e5614afe4f6..439e98471b2 100644
--- a/mysql-test/t/type_varchar.test
+++ b/mysql-test/t/type_varchar.test
@@ -146,3 +146,44 @@ DROP TABLE IF EXISTS t1;
CREATE TABLE t1(f1 CHAR(100) DEFAULT 'test');
INSERT INTO t1 VALUES(SUBSTR(f1, 1, 3));
DROP TABLE IF EXISTS t1;
+
+#
+# Bug#14897 "ResultSet.getString("table.column") sometimes doesn't find the
+# column"
+# Test that after upgrading an old 4.1 VARCHAR column to 5.0 VARCHAR we preserve
+# the original column metadata.
+#
+--disable_warnings
+drop table if exists t1, t2, t3;
+--enable_warnings
+
+create table t3 (
+ id int(11),
+ en varchar(255) character set utf8,
+ cz varchar(255) character set utf8
+);
+system cp $MYSQL_TEST_DIR/std_data/14897.frm $MYSQLTEST_VARDIR/master-data/test/t3.frm;
+truncate table t3;
+insert into t3 (id, en, cz) values
+(1,'en string 1','cz string 1'),
+(2,'en string 2','cz string 2'),
+(3,'en string 3','cz string 3');
+
+create table t1 (
+ id int(11),
+ name_id int(11)
+);
+insert into t1 (id, name_id) values (1,1), (2,3), (3,3);
+
+create table t2 (id int(11));
+insert into t2 (id) values (1), (2), (3);
+
+# max_length is different for varchar fields in ps-protocol and we can't
+# replace a single metadata column, disable PS protocol
+--disable_ps_protocol
+--enable_metadata
+select t1.*, t2.id, t3.en, t3.cz from t1 left join t2 on t1.id=t2.id
+left join t3 on t1.id=t3.id order by t3.id;
+--disable_metadata
+--enable_ps_protocol
+drop table t1, t2, t3;
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index 68efcafd1e0..d855b4d8266 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -585,6 +585,16 @@ show variables like 'ssl%';
select @@log_queries_not_using_indexes;
show variables like 'log_queries_not_using_indexes';
+#
+# Bug#20908: Crash if select @@""
+#
+--error ER_PARSE_ERROR
+select @@"";
+--error ER_PARSE_ERROR
+select @@&;
+--error ER_PARSE_ERROR
+select @@@;
+
--echo End of 5.0 tests
# This is at the very after the versioned tests, since it involves doing
@@ -620,3 +630,4 @@ set global server_id =@my_server_id;
set global slow_launch_time =@my_slow_launch_time;
set global storage_engine =@my_storage_engine;
set global thread_cache_size =@my_thread_cache_size;
+
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index fae3f856cb8..edff38274c4 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -2760,3 +2760,78 @@ create view v1 as select * from t1 where f1 between now() and now() + interval 1
show create view v1;
drop view v1;
drop table t1;
+#
+# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause.
+#
+
+# Prepare.
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP VIEW IF EXISTS v1;
+DROP VIEW IF EXISTS v2;
+--enable_warnings
+
+CREATE TABLE t1(a INT, b INT);
+
+--error ER_WRONG_STRING_LENGTH
+CREATE DEFINER=1234567890abcdefGHIKL@localhost
+ VIEW v1 AS SELECT a FROM t1;
+
+--error ER_WRONG_STRING_LENGTH
+CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
+ VIEW v2 AS SELECT b FROM t1;
+
+# Cleanup.
+
+DROP TABLE t1;
+
+
+#
+# BUG#17591: Updatable view not possible with trigger or stored
+# function
+#
+# During prelocking phase we didn't update lock type of view tables,
+# hence READ lock was always requested.
+#
+--disable_warnings
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP VIEW IF EXISTS v1, v2;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (i INT);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+delimiter |;
+CREATE FUNCTION f1() RETURNS INT
+BEGIN
+ INSERT INTO v1 VALUES (0);
+ RETURN 0;
+END |
+delimiter ;|
+
+SELECT f1();
+
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t1;
+
+delimiter |;
+CREATE FUNCTION f2() RETURNS INT
+BEGIN
+ INSERT INTO v2 VALUES (0);
+ RETURN 0;
+END |
+delimiter ;|
+
+--error ER_NON_UPDATABLE_TABLE
+SELECT f2();
+
+DROP FUNCTION f1;
+DROP FUNCTION f2;
+DROP VIEW v1, v2;
+DROP TABLE t1;
+
+
+--echo End of 5.0 tests.
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
new file mode 100755
index 00000000000..7926cb916c1
--- /dev/null
+++ b/mysys/CMakeLists.txt
@@ -0,0 +1,29 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+# Need to set USE_TLS, since mysys is linked into libmysql.dll and
+# libmysqld.dll, and __declspec(thread) approach to thread local storage does
+# not work properly in DLLs.
+# Currently, USE_TLS crashes in Debug builds, so until that is fixed Debug
+# .dlls cannot be loaded at runtime.
+SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DUSE_TLS")
+SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DUSE_TLS")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys )
+ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_modify.c
+ errors.c hash.c list.c md5.c mf_brkhant.c mf_cache.c mf_dirname.c mf_fn_ext.c
+ mf_format.c mf_getdate.c mf_iocache.c mf_iocache2.c mf_keycache.c
+ mf_keycaches.c mf_loadpath.c mf_pack.c mf_path.c mf_qsort.c mf_qsort2.c
+ mf_radix.c mf_same.c mf_sort.c mf_soundex.c mf_strip.c mf_tempdir.c
+ mf_tempfile.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_access.c
+ my_aes.c my_alarm.c my_alloc.c my_append.c my_bit.c my_bitmap.c my_chsize.c
+ my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c
+ my_div.c my_error.c my_file.c my_fopen.c my_fstream.c my_gethostbyname.c
+ my_gethwaddr.c my_getopt.c my_getsystime.c my_getwd.c my_handler.c my_init.c
+ my_lib.c my_lock.c my_lockmem.c my_lread.c my_lwrite.c my_malloc.c my_messnc.c
+ my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c
+ my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c
+ my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
+ my_windac.c my_winsem.c my_winthread.c my_write.c ptr_cmp.c queues.c
+ rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
+ thr_rwlock.c tree.c typelib.c base64.c my_memmem.c)
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index bc84f44cd29..041130fdf5c 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -58,7 +58,8 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
my_memmem.c \
my_windac.c my_access.c base64.c my_libwrap.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
- thr_mutex.c thr_rwlock.c
+ thr_mutex.c thr_rwlock.c mf_soundex.c my_conio.c \
+ my_wincond.c my_winsem.c my_winthread.c CMakeLists.txt
libmysys_a_LIBADD = @THREAD_LOBJECTS@
# test_dir_DEPENDENCIES= $(LIBRARIES)
# testhash_DEPENDENCIES= $(LIBRARIES)
diff --git a/mysys/my_read.c b/mysys/my_read.c
index 9de070e772d..2e23f2175f8 100644
--- a/mysys/my_read.c
+++ b/mysys/my_read.c
@@ -36,48 +36,51 @@
uint my_read(File Filedes, byte *Buffer, uint Count, myf MyFlags)
{
- uint readbytes,save_count;
+ uint readbytes, save_count;
DBUG_ENTER("my_read");
DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %u MyFlags: %d",
- Filedes, Buffer, Count, MyFlags));
- save_count=Count;
+ Filedes, Buffer, Count, MyFlags));
+ save_count= Count;
for (;;)
{
- errno=0; /* Linux doesn't reset this */
- if ((readbytes = (uint) read(Filedes, Buffer, Count)) != Count)
+ errno= 0; /* Linux doesn't reset this */
+ if ((readbytes= (uint) read(Filedes, Buffer, Count)) != Count)
{
- my_errno=errno ? errno : -1;
+ my_errno= errno ? errno : -1;
DBUG_PRINT("warning",("Read only %ld bytes off %ld from %d, errno: %d",
- readbytes,Count,Filedes,my_errno));
+ readbytes, Count, Filedes, my_errno));
#ifdef THREAD
- if (readbytes == 0 && errno == EINTR)
- continue; /* Interrupted */
+ if ((int) readbytes <= 0 && errno == EINTR)
+ {
+ DBUG_PRINT("debug", ("my_read() was interrupted and returned %d", (int) readbytes));
+ continue; /* Interrupted */
+ }
#endif
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
{
- if ((int) readbytes == -1)
- my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),my_errno);
- else if (MyFlags & (MY_NABP | MY_FNABP))
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),my_errno);
+ if ((int) readbytes == -1)
+ my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
+ my_filename(Filedes),my_errno);
+ else if (MyFlags & (MY_NABP | MY_FNABP))
+ my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
+ my_filename(Filedes),my_errno);
}
if ((int) readbytes == -1 ||
- ((MyFlags & (MY_FNABP | MY_NABP)) && !(MyFlags & MY_FULL_IO)))
- DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
+ ((MyFlags & (MY_FNABP | MY_NABP)) && !(MyFlags & MY_FULL_IO)))
+ DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
if (readbytes > 0 && (MyFlags & MY_FULL_IO))
{
- Buffer+=readbytes;
- Count-=readbytes;
- continue;
+ Buffer+= readbytes;
+ Count-= readbytes;
+ continue;
}
}
if (MyFlags & (MY_NABP | MY_FNABP))
- readbytes=0; /* Ok on read */
+ readbytes= 0; /* Ok on read */
else if (MyFlags & MY_FULL_IO)
- readbytes=save_count;
+ readbytes= save_count;
break;
}
DBUG_RETURN(readbytes);
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index 6af65d70fd0..8035312496d 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -29,7 +29,8 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
whence, MyFlags));
DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */
- newpos=lseek(fd, pos, whence);
+ if (-1 != fd)
+ newpos=lseek(fd, pos, whence);
if (newpos == (os_off_t) -1)
{
my_errno=errno;
diff --git a/ndb/include/kernel/signaldata/CreateIndx.hpp b/ndb/include/kernel/signaldata/CreateIndx.hpp
index a9dc653f349..4163583dbd2 100644
--- a/ndb/include/kernel/signaldata/CreateIndx.hpp
+++ b/ndb/include/kernel/signaldata/CreateIndx.hpp
@@ -192,6 +192,7 @@ public:
enum ErrorCode {
NoError = 0,
Busy = 701,
+ BusyWithNR = 711,
NotMaster = 702,
TriggerNotFound = 4238,
TriggerExists = 4239,
diff --git a/ndb/include/kernel/signaldata/DropIndx.hpp b/ndb/include/kernel/signaldata/DropIndx.hpp
index fd2ea7f0b7b..41ee50082f7 100644
--- a/ndb/include/kernel/signaldata/DropIndx.hpp
+++ b/ndb/include/kernel/signaldata/DropIndx.hpp
@@ -168,6 +168,7 @@ public:
NoError = 0,
InvalidIndexVersion = 241,
Busy = 701,
+ BusyWithNR = 711,
NotMaster = 702,
IndexNotFound = 4243,
BadRequestType = 4247,
diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp
index 4db541f7fe4..dbc343d2238 100644
--- a/ndb/include/ndbapi/NdbOperation.hpp
+++ b/ndb/include/ndbapi/NdbOperation.hpp
@@ -477,7 +477,7 @@ public:
/**
* Interpreted program instruction:
- * Substract RegSource1 from RegSource2 and put the result in RegDest.
+ * Substract RegSource2 from RegSource1 and put the result in RegDest.
*
* @param RegSource1 First register.
* @param RegSource2 Second register.
diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt
index 7fee2e92f2b..c8c9e82efc2 100644
--- a/ndb/src/kernel/blocks/ERROR_codes.txt
+++ b/ndb/src/kernel/blocks/ERROR_codes.txt
@@ -6,7 +6,7 @@ Next DBTUP 4014
Next DBLQH 5043
Next DBDICT 6007
Next DBDIH 7177
-Next DBTC 8037
+Next DBTC 8038
Next CMVMI 9000
Next BACKUP 10022
Next DBUTIL 11002
@@ -283,6 +283,7 @@ ABORT OF TCKEYREQ
8032: No free TC records any more
+8037 : Invalid schema version in TCINDXREQ
CMVMI
-----
diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp
index 43c1de5e2b3..10318e5f52d 100644
--- a/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -274,36 +274,48 @@ Backup::execCONTINUEB(Signal* signal)
BackupRecordPtr ptr;
c_backupPool.getPtr(ptr, ptr_I);
- TablePtr tabPtr;
- ptr.p->tables.getPtr(tabPtr, tabPtr_I);
- FragmentPtr fragPtr;
- tabPtr.p->fragments.getPtr(fragPtr, fragPtr_I);
- BackupFilePtr filePtr;
- ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
-
- const Uint32 sz = sizeof(BackupFormat::CtlFile::FragmentInfo) >> 2;
- Uint32 * dst;
- if (!filePtr.p->operation.dataBuffer.getWritePtr(&dst, sz))
+ if (tabPtr_I == RNIL)
{
- sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 4);
+ closeFiles(signal, ptr);
return;
}
+ jam();
+ TablePtr tabPtr;
+ ptr.p->tables.getPtr(tabPtr, tabPtr_I);
+ jam();
+ if(tabPtr.p->fragments.getSize())
+ {
+ FragmentPtr fragPtr;
+ tabPtr.p->fragments.getPtr(fragPtr, fragPtr_I);
- BackupFormat::CtlFile::FragmentInfo * fragInfo =
- (BackupFormat::CtlFile::FragmentInfo*)dst;
- fragInfo->SectionType = htonl(BackupFormat::FRAGMENT_INFO);
- fragInfo->SectionLength = htonl(sz);
- fragInfo->TableId = htonl(fragPtr.p->tableId);
- fragInfo->FragmentNo = htonl(fragPtr_I);
- fragInfo->NoOfRecordsLow = htonl(fragPtr.p->noOfRecords & 0xFFFFFFFF);
- fragInfo->NoOfRecordsHigh = htonl(fragPtr.p->noOfRecords >> 32);
- fragInfo->FilePosLow = htonl(0 & 0xFFFFFFFF);
- fragInfo->FilePosHigh = htonl(0 >> 32);
+ BackupFilePtr filePtr;
+ ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
- filePtr.p->operation.dataBuffer.updateWritePtr(sz);
+ const Uint32 sz = sizeof(BackupFormat::CtlFile::FragmentInfo) >> 2;
+ Uint32 * dst;
+ if (!filePtr.p->operation.dataBuffer.getWritePtr(&dst, sz))
+ {
+ sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 100, 4);
+ return;
+ }
+
+ BackupFormat::CtlFile::FragmentInfo * fragInfo =
+ (BackupFormat::CtlFile::FragmentInfo*)dst;
+ fragInfo->SectionType = htonl(BackupFormat::FRAGMENT_INFO);
+ fragInfo->SectionLength = htonl(sz);
+ fragInfo->TableId = htonl(fragPtr.p->tableId);
+ fragInfo->FragmentNo = htonl(fragPtr_I);
+ fragInfo->NoOfRecordsLow = htonl(fragPtr.p->noOfRecords & 0xFFFFFFFF);
+ fragInfo->NoOfRecordsHigh = htonl(fragPtr.p->noOfRecords >> 32);
+ fragInfo->FilePosLow = htonl(0 & 0xFFFFFFFF);
+ fragInfo->FilePosHigh = htonl(0 >> 32);
+
+ filePtr.p->operation.dataBuffer.updateWritePtr(sz);
+
+ fragPtr_I++;
+ }
- fragPtr_I++;
if (fragPtr_I == tabPtr.p->fragments.getSize())
{
signal->theData[0] = tabPtr.p->tableId;
@@ -4243,6 +4255,12 @@ Backup::execSTOP_BACKUP_REQ(Signal* signal)
TablePtr tabPtr;
ptr.p->tables.first(tabPtr);
+ if (tabPtr.i == RNIL)
+ {
+ closeFiles(signal, ptr);
+ return;
+ }
+
signal->theData[0] = BackupContinueB::BACKUP_FRAGMENT_INFO;
signal->theData[1] = ptr.i;
signal->theData[2] = tabPtr.i;
diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index efd519339f7..a79ddd05fae 100644
--- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -6520,9 +6520,18 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal)
}
if (signal->getLength() == CreateIndxReq::SignalLength) {
jam();
+ CreateIndxRef::ErrorCode tmperr = CreateIndxRef::NoError;
if (getOwnNodeId() != c_masterNodeId) {
jam();
-
+ tmperr = CreateIndxRef::NotMaster;
+ } else if (c_blockState == BS_NODE_RESTART) {
+ jam();
+ tmperr = CreateIndxRef::BusyWithNR;
+ } else if (c_blockState != BS_IDLE) {
+ jam();
+ tmperr = CreateIndxRef::Busy;
+ }
+ if (tmperr != CreateIndxRef::NoError) {
releaseSections(signal);
OpCreateIndex opBusy;
opPtr.p = &opBusy;
@@ -6530,13 +6539,12 @@ Dbdict::execCREATE_INDX_REQ(Signal* signal)
opPtr.p->m_isMaster = (senderRef == reference());
opPtr.p->key = 0;
opPtr.p->m_requestType = CreateIndxReq::RT_DICT_PREPARE;
- opPtr.p->m_errorCode = CreateIndxRef::NotMaster;
+ opPtr.p->m_errorCode = tmperr;
opPtr.p->m_errorLine = __LINE__;
opPtr.p->m_errorNode = c_masterNodeId;
createIndex_sendReply(signal, opPtr, true);
return;
}
-
// forward initial request plus operation key to all
req->setOpKey(++c_opRecordSequence);
NodeReceiverGroup rg(DBDICT, c_aliveNodes);
@@ -7082,10 +7090,19 @@ Dbdict::execDROP_INDX_REQ(Signal* signal)
jam();
if (signal->getLength() == DropIndxReq::SignalLength) {
jam();
+ DropIndxRef::ErrorCode tmperr = DropIndxRef::NoError;
if (getOwnNodeId() != c_masterNodeId) {
jam();
-
- err = DropIndxRef::NotMaster;
+ tmperr = DropIndxRef::NotMaster;
+ } else if (c_blockState == BS_NODE_RESTART) {
+ jam();
+ tmperr = DropIndxRef::BusyWithNR;
+ } else if (c_blockState != BS_IDLE) {
+ jam();
+ tmperr = DropIndxRef::Busy;
+ }
+ if (tmperr != DropIndxRef::NoError) {
+ err = tmperr;
goto error;
}
// forward initial request plus operation key to all
@@ -10130,6 +10147,17 @@ Dbdict::execDICT_LOCK_REQ(Signal* signal)
sendDictLockInfoEvent(lockPtr, "lock request by node");
}
+// only table and index ops are checked
+bool
+Dbdict::hasDictLockSchemaOp()
+{
+ return
+ ! c_opCreateTable.isEmpty() ||
+ ! c_opDropTable.isEmpty() ||
+ ! c_opCreateIndex.isEmpty() ||
+ ! c_opDropIndex.isEmpty();
+}
+
void
Dbdict::checkDictLockQueue(Signal* signal, bool poll)
{
@@ -10150,7 +10178,7 @@ Dbdict::checkDictLockQueue(Signal* signal, bool poll)
break;
}
- if (c_opRecordPool.getNoOfFree() != c_opRecordPool.getSize()) {
+ if (hasDictLockSchemaOp()) {
jam();
break;
}
@@ -10183,7 +10211,7 @@ Dbdict::execDICT_UNLOCK_ORD(Signal* signal)
if (lockPtr.p->locked) {
jam();
ndbrequire(c_blockState == lockPtr.p->lt->blockState);
- ndbrequire(c_opRecordPool.getNoOfFree() == c_opRecordPool.getSize());
+ ndbrequire(! hasDictLockSchemaOp());
ndbrequire(! c_dictLockQueue.hasPrev(lockPtr));
c_blockState = BS_IDLE;
@@ -10279,7 +10307,7 @@ Dbdict::removeStaleDictLocks(Signal* signal, const Uint32* theFailedNodes)
if (lockPtr.p->locked) {
jam();
ndbrequire(c_blockState == lockPtr.p->lt->blockState);
- ndbrequire(c_opRecordPool.getNoOfFree() == c_opRecordPool.getSize());
+ ndbrequire(! hasDictLockSchemaOp());
ndbrequire(! c_dictLockQueue.hasPrev(lockPtr));
c_blockState = BS_IDLE;
diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
index ed8b7e3b822..82644826d5b 100644
--- a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
+++ b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
@@ -1650,6 +1650,9 @@ private:
void sendDictLockInfoEvent(Uint32 pollCount);
void sendDictLockInfoEvent(DictLockPtr lockPtr, const char* text);
+ // check if any schema op exists (conflicting with dict lock)
+ bool hasDictLockSchemaOp();
+
void checkDictLockQueue(Signal* signal, bool poll);
void sendDictLockConf(Signal* signal, DictLockPtr lockPtr);
void sendDictLockRef(Signal* signal, DictLockReq req, Uint32 errorCode);
diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
index 491aa0849b9..1c1fdb41d51 100644
--- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -8252,11 +8252,21 @@ void Dbdih::openingTableErrorLab(Signal* signal, FileRecordPtr filePtr)
/* WE FAILED IN OPENING A FILE. IF THE FIRST FILE THEN TRY WITH THE */
/* DUPLICATE FILE, OTHERWISE WE REPORT AN ERROR IN THE SYSTEM RESTART. */
/* ---------------------------------------------------------------------- */
- ndbrequire(filePtr.i == tabPtr.p->tabFile[0]);
- filePtr.i = tabPtr.p->tabFile[1];
- ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
- openFileRw(signal, filePtr);
- filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
+ if (filePtr.i == tabPtr.p->tabFile[0])
+ {
+ filePtr.i = tabPtr.p->tabFile[1];
+ ptrCheckGuard(filePtr, cfileFileSize, fileRecord);
+ openFileRw(signal, filePtr);
+ filePtr.p->reqStatus = FileRecord::OPENING_TABLE;
+ }
+ else
+ {
+ char buf[256];
+ BaseString::snprintf(buf, sizeof(buf),
+ "Error opening DIH schema files for table: %d",
+ tabPtr.i);
+ progError(__LINE__, NDBD_EXIT_AFS_NO_SUCH_FILE, buf);
+ }
}//Dbdih::openingTableErrorLab()
void Dbdih::readingTableLab(Signal* signal, FileRecordPtr filePtr)
@@ -8422,6 +8432,7 @@ Dbdih::resetReplicaSr(TabRecordPtr tabPtr){
}
replicaPtr.i = nextReplicaPtrI;
}//while
+ updateNodeInfo(fragPtr);
}
}
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index 0ea49e47fc7..7286481002f 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -6470,6 +6470,7 @@ void Dblqh::execACC_ABORTCONF(Signal* signal)
* A NORMAL EVENT DURING CREATION OF A FRAGMENT. WE NOW NEED TO CONTINUE
* WITH NORMAL COMMIT PROCESSING.
* ---------------------------------------------------------------------- */
+ regTcPtr->totSendlenAi = regTcPtr->totReclenAi;
if (regTcPtr->currTupAiLen == regTcPtr->totReclenAi) {
jam();
regTcPtr->abortState = TcConnectionrec::ABORT_IDLE;
@@ -12579,19 +12580,17 @@ void Dblqh::lastWriteInFileLab(Signal* signal)
void Dblqh::writePageZeroLab(Signal* signal)
{
- if (false && logPartPtr.p->logPartState == LogPartRecord::FILE_CHANGE_PROBLEM)
+ if (logPartPtr.p->logPartState == LogPartRecord::FILE_CHANGE_PROBLEM)
{
if (logPartPtr.p->firstLogQueue == RNIL)
{
jam();
logPartPtr.p->logPartState = LogPartRecord::IDLE;
- ndbout_c("resetting logPartState to IDLE");
}
else
{
jam();
logPartPtr.p->logPartState = LogPartRecord::ACTIVE;
- ndbout_c("resetting logPartState to ACTIVE");
}
}
@@ -14623,6 +14622,8 @@ void Dblqh::execSr(Signal* signal)
LogFileRecordPtr nextLogFilePtr;
LogPageRecordPtr tmpLogPagePtr;
Uint32 logWord;
+ Uint32 line;
+ const char * crash_msg = 0;
jamEntry();
logPartPtr.i = signal->theData[0];
@@ -14833,8 +14834,14 @@ void Dblqh::execSr(Signal* signal)
/* PLACE THAN IN THE FIRST PAGE OF A NEW FILE IN THE FIRST POSITION AFTER THE*/
/* HEADER. */
/*---------------------------------------------------------------------------*/
- ndbrequire(logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] ==
- (ZPAGE_HEADER_SIZE + ZPOS_NO_FD));
+ if (unlikely(logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] !=
+ (ZPAGE_HEADER_SIZE + ZPOS_NO_FD)))
+ {
+ line = __LINE__;
+ logWord = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
+ crash_msg = "ZFD_TYPE at incorrect position!";
+ goto crash;
+ }
{
Uint32 noFdDescriptors =
logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_NO_FD];
@@ -14871,19 +14878,10 @@ void Dblqh::execSr(Signal* signal)
/*---------------------------------------------------------------------------*/
/* SEND A SIGNAL TO THE SIGNAL LOG AND THEN CRASH THE SYSTEM. */
/*---------------------------------------------------------------------------*/
- signal->theData[0] = RNIL;
- signal->theData[1] = logPartPtr.i;
- Uint32 tmp = logFilePtr.p->fileName[3];
- tmp = (tmp >> 8) & 0xff;// To get the Directory, DXX.
- signal->theData[2] = tmp;
- signal->theData[3] = logFilePtr.p->fileNo;
- signal->theData[4] = logFilePtr.p->currentFilepage;
- signal->theData[5] = logFilePtr.p->currentMbyte;
- signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- signal->theData[7] = ~0;
- signal->theData[8] = __LINE__;
- sendSignal(cownref, GSN_DEBUG_SIG, signal, 9, JBA);
- return;
+ line = __LINE__;
+ logWord = ZNEXT_MBYTE_TYPE;
+ crash_msg = "end of log wo/ having found last GCI";
+ goto crash;
}//if
}//if
/*---------------------------------------------------------------------------*/
@@ -14938,19 +14936,9 @@ void Dblqh::execSr(Signal* signal)
/*---------------------------------------------------------------------------*/
/* SEND A SIGNAL TO THE SIGNAL LOG AND THEN CRASH THE SYSTEM. */
/*---------------------------------------------------------------------------*/
- signal->theData[0] = RNIL;
- signal->theData[1] = logPartPtr.i;
- Uint32 tmp = logFilePtr.p->fileName[3];
- tmp = (tmp >> 8) & 0xff;// To get the Directory, DXX.
- signal->theData[2] = tmp;
- signal->theData[3] = logFilePtr.p->fileNo;
- signal->theData[4] = logFilePtr.p->currentMbyte;
- signal->theData[5] = logFilePtr.p->currentFilepage;
- signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
- signal->theData[7] = logWord;
- signal->theData[8] = __LINE__;
- sendSignal(cownref, GSN_DEBUG_SIG, signal, 9, JBA);
- return;
+ line = __LINE__;
+ crash_msg = "Invalid logword";
+ goto crash;
break;
}//switch
/*---------------------------------------------------------------------------*/
@@ -14958,6 +14946,35 @@ void Dblqh::execSr(Signal* signal)
// that we reach a new page.
/*---------------------------------------------------------------------------*/
} while (1);
+ return;
+
+crash:
+ signal->theData[0] = RNIL;
+ signal->theData[1] = logPartPtr.i;
+ Uint32 tmp = logFilePtr.p->fileName[3];
+ tmp = (tmp >> 8) & 0xff;// To get the Directory, DXX.
+ signal->theData[2] = tmp;
+ signal->theData[3] = logFilePtr.p->fileNo;
+ signal->theData[4] = logFilePtr.p->currentMbyte;
+ signal->theData[5] = logFilePtr.p->currentFilepage;
+ signal->theData[6] = logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX];
+ signal->theData[7] = logWord;
+ signal->theData[8] = line;
+
+ char buf[255];
+ BaseString::snprintf(buf, sizeof(buf),
+ "Error while reading REDO log. from %d\n"
+ "D=%d, F=%d Mb=%d FP=%d W1=%d W2=%d : %s",
+ signal->theData[8],
+ signal->theData[2],
+ signal->theData[3],
+ signal->theData[4],
+ signal->theData[5],
+ signal->theData[6],
+ signal->theData[7],
+ crash_msg ? crash_msg : "");
+
+ progError(__LINE__, NDBD_EXIT_SR_REDOLOG, buf);
}//Dblqh::execSr()
/*---------------------------------------------------------------------------*/
@@ -14973,8 +14990,8 @@ void Dblqh::execDEBUG_SIG(Signal* signal)
UintR tdebug;
jamEntry();
- logPagePtr.i = signal->theData[0];
- tdebug = logPagePtr.p->logPageWord[0];
+ //logPagePtr.i = signal->theData[0];
+ //tdebug = logPagePtr.p->logPageWord[0];
char buf[100];
BaseString::snprintf(buf, 100,
diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
index ac7fca9cf93..bf6ce7129ba 100644
--- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
+++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
@@ -720,7 +720,7 @@ public:
// Index data
- bool isIndexOp; // Used to mark on-going TcKeyReq as indx table access
+ Uint8 isIndexOp; // Used to mark on-going TcKeyReq as indx table access
bool indexOpReturn;
UintR noIndexOp; // No outstanding index ops
@@ -808,7 +808,7 @@ public:
UintR savedState[LqhKeyConf::SignalLength];
// Index data
- bool isIndexOp; // Used to mark on-going TcKeyReq as index table access
+ Uint8 isIndexOp; // Used to mark on-going TcKeyReq as index table access
UintR indexOp;
UintR currentIndexId;
UintR attrInfoLen;
diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index 71f3aff05d4..dda743616f4 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -1775,8 +1775,7 @@ void Dbtc::execKEYINFO(Signal* signal)
apiConnectptr.i = signal->theData[0];
tmaxData = 20;
if (apiConnectptr.i >= capiConnectFilesize) {
- jam();
- warningHandlerLab(signal, __LINE__);
+ TCKEY_abort(signal, 18);
return;
}//if
ptrAss(apiConnectptr, apiConnectRecord);
@@ -1785,9 +1784,7 @@ void Dbtc::execKEYINFO(Signal* signal)
compare_transid2 = apiConnectptr.p->transid[1] ^ signal->theData[2];
compare_transid1 = compare_transid1 | compare_transid2;
if (compare_transid1 != 0) {
- jam();
- printState(signal, 10);
- sendSignalErrorRefuseLab(signal);
+ TCKEY_abort(signal, 19);
return;
}//if
switch (apiConnectptr.p->apiConnectstate) {
@@ -2531,7 +2528,7 @@ void Dbtc::execTCKEYREQ(Signal* signal)
Uint32 TstartFlag = tcKeyReq->getStartFlag(Treqinfo);
Uint32 TexecFlag = TcKeyReq::getExecuteFlag(Treqinfo);
- bool isIndexOp = regApiPtr->isIndexOp;
+ Uint8 isIndexOp = regApiPtr->isIndexOp;
bool isIndexOpReturn = regApiPtr->indexOpReturn;
regApiPtr->isIndexOp = false; // Reset marker
regApiPtr->m_exec_flag |= TexecFlag;
@@ -3277,7 +3274,7 @@ void Dbtc::sendlqhkeyreq(Signal* signal,
sig1 = regCachePtr->fragmentid + (regTcPtr->tcNodedata[1] << 16);
sig2 = regApiPtr->transid[0];
sig3 = regApiPtr->transid[1];
- sig4 = regApiPtr->ndbapiBlockref;
+ sig4 = (regTcPtr->isIndexOp == 2) ? reference() : regApiPtr->ndbapiBlockref;
sig5 = regTcPtr->clientData;
sig6 = regCachePtr->scanInfo;
@@ -8619,6 +8616,7 @@ void Dbtc::execSCAN_TABREQ(Signal* signal)
// left over from simple/dirty read
} else {
jam();
+ jamLine(transP->apiConnectstate);
errCode = ZSTATE_ERROR;
goto SCAN_TAB_error_no_state_change;
}
@@ -12036,14 +12034,18 @@ void Dbtc::readIndexTable(Signal* signal,
opType == ZREAD ? ZREAD : ZREAD_EX);
TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, 1); // Allways send one AttrInfo
TcKeyReq::setExecutingTrigger(tcKeyRequestInfo, 0);
- BlockReference originalReceiver = regApiPtr->ndbapiBlockref;
- regApiPtr->ndbapiBlockref = reference(); // Send result to me
tcKeyReq->senderData = indexOp->indexOpId;
indexOp->indexOpState = IOS_INDEX_ACCESS;
regApiPtr->executingIndexOp = regApiPtr->accumulatingIndexOp;
regApiPtr->accumulatingIndexOp = RNIL;
- regApiPtr->isIndexOp = true;
+ regApiPtr->isIndexOp = 2;
+ if (ERROR_INSERTED(8037))
+ {
+ ndbout_c("shifting index version");
+ tcKeyReq->tableSchemaVersion = ~(Uint32)indexOp->tcIndxReq.tableSchemaVersion;
+ }
+
Uint32 remainingKey = indexOp->keyInfo.getSize();
bool moreKeyData = indexOp->keyInfo.first(keyIter);
// *********** KEYINFO in TCKEYREQ ***********
@@ -12062,21 +12064,13 @@ void Dbtc::readIndexTable(Signal* signal,
ndbassert(TcKeyReq::getDirtyFlag(tcKeyRequestInfo) == 0);
ndbassert(TcKeyReq::getSimpleFlag(tcKeyRequestInfo) == 0);
EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
-
- /**
- * "Fool" TC not to start commiting transaction since it always will
- * have one outstanding lqhkeyreq
- * This is later decreased when the index read is complete
- */
- regApiPtr->lqhkeyreqrec++;
+ jamEntry();
- /**
- * Remember ptr to index read operation
- * (used to set correct save point id on index operation later)
- */
- indexOp->indexReadTcConnect = regApiPtr->lastTcConnect;
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ goto err;
+ }
- jamEntry();
// *********** KEYINFO ***********
if (moreKeyData) {
jam();
@@ -12096,6 +12090,10 @@ void Dbtc::readIndexTable(Signal* signal,
EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ goto err;
+ }
dataPos = 0;
dataPtr = (Uint32 *) &keyInfo->keyData;
}
@@ -12106,10 +12104,32 @@ void Dbtc::readIndexTable(Signal* signal,
EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
KeyInfo::HeaderLength + dataPos);
jamEntry();
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ goto err;
+ }
}
}
- regApiPtr->ndbapiBlockref = originalReceiver; // reset original receiver
+ /**
+ * "Fool" TC not to start commiting transaction since it always will
+ * have one outstanding lqhkeyreq
+ * This is later decreased when the index read is complete
+ */
+ regApiPtr->lqhkeyreqrec++;
+
+ /**
+ * Remember ptr to index read operation
+ * (used to set correct save point id on index operation later)
+ */
+ indexOp->indexReadTcConnect = regApiPtr->lastTcConnect;
+
+done:
+ return;
+
+err:
+ jam();
+ goto done;
}
/**
@@ -12160,7 +12180,7 @@ void Dbtc::executeIndexOperation(Signal* signal,
tcKeyReq->transId2 = regApiPtr->transid[1];
tcKeyReq->senderData = tcIndxReq->senderData; // Needed for TRANSID_AI to API
indexOp->indexOpState = IOS_INDEX_OPERATION;
- regApiPtr->isIndexOp = true;
+ regApiPtr->isIndexOp = 1;
regApiPtr->executingIndexOp = indexOp->indexOpId;;
regApiPtr->noIndexOp++; // Increase count
@@ -12233,9 +12253,16 @@ void Dbtc::executeIndexOperation(Signal* signal,
const Uint32 currSavePointId = regApiPtr->currSavePointId;
regApiPtr->currSavePointId = tmp.p->savePointId;
EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
+ jamEntry();
+
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
regApiPtr->currSavePointId = currSavePointId;
- jamEntry();
// *********** KEYINFO ***********
if (moreKeyData) {
jam();
@@ -12256,6 +12283,13 @@ void Dbtc::executeIndexOperation(Signal* signal,
EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
+
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
dataPos = 0;
dataPtr = (Uint32 *) &keyInfo->keyData;
}
@@ -12266,6 +12300,12 @@ void Dbtc::executeIndexOperation(Signal* signal,
EXECUTE_DIRECT(DBTC, GSN_KEYINFO, signal,
KeyInfo::HeaderLength + dataPos);
jamEntry();
+
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
}
}
@@ -12295,6 +12335,13 @@ void Dbtc::executeIndexOperation(Signal* signal,
EXECUTE_DIRECT(DBTC, GSN_ATTRINFO, signal,
AttrInfo::HeaderLength + AttrInfo::DataLength);
jamEntry();
+
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
attrInfoPos = 0;
dataPtr = (Uint32 *) &attrInfo->attrData;
}
@@ -12694,9 +12741,16 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
const Uint32 currSavePointId = regApiPtr->currSavePointId;
regApiPtr->currSavePointId = opRecord->savePointId;
EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
+ jamEntry();
+
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
regApiPtr->currSavePointId = currSavePointId;
tcConnectptr.p->currentIndexId = indexData->indexId;
- jamEntry();
// *********** KEYINFO ***********
if (moreKeyData) {
@@ -12726,6 +12780,12 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
#endif
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
dataPtr = (Uint32 *) &keyInfo->keyData;
dataPos = 0;
}
@@ -12761,6 +12821,13 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
#endif
+
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
dataPtr = (Uint32 *) &keyInfo->keyData;
dataPos = 0;
}
@@ -12778,6 +12845,11 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
KeyInfo::HeaderLength + dataPos);
jamEntry();
#endif
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
}
}
@@ -12813,6 +12885,12 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
AttrInfo::HeaderLength + AttrInfo::DataLength);
jamEntry();
#endif
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
dataPtr = (Uint32 *) &attrInfo->attrData;
attrInfoPos = 0;
}
@@ -12849,6 +12927,12 @@ void Dbtc::insertIntoIndexTable(Signal* signal,
AttrInfo::HeaderLength + AttrInfo::DataLength);
jamEntry();
#endif
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
dataPtr = (Uint32 *) &attrInfo->attrData;
attrInfoPos = 0;
}
@@ -12994,9 +13078,16 @@ void Dbtc::deleteFromIndexTable(Signal* signal,
const Uint32 currSavePointId = regApiPtr->currSavePointId;
regApiPtr->currSavePointId = opRecord->savePointId;
EXECUTE_DIRECT(DBTC, GSN_TCKEYREQ, signal, tcKeyLength);
+ jamEntry();
+
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
regApiPtr->currSavePointId = currSavePointId;
tcConnectptr.p->currentIndexId = indexData->indexId;
- jamEntry();
// *********** KEYINFO ***********
if (moreKeyData) {
@@ -13027,6 +13118,12 @@ void Dbtc::deleteFromIndexTable(Signal* signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
#endif
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
dataPtr = (Uint32 *) &keyInfo->keyData;
dataPos = 0;
}
@@ -13063,6 +13160,12 @@ void Dbtc::deleteFromIndexTable(Signal* signal,
KeyInfo::HeaderLength + KeyInfo::DataLength);
jamEntry();
#endif
+ if (unlikely(regApiPtr->apiConnectstate == CS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
dataPtr = (Uint32 *) &keyInfo->keyData;
dataPos = 0;
}
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
index f83f21f14d8..13c0bad9c7a 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
@@ -1113,14 +1113,16 @@ Dbtup::updateStartLab(Signal* signal,
regOperPtr->pageOffset,
&cinBuffer[0],
regOperPtr->attrinbufLen);
- if (retValue == -1) {
- tupkeyErrorLab(signal);
- return -1;
- }//if
} else {
jam();
retValue = interpreterStartLab(signal, pagePtr, regOperPtr->pageOffset);
}//if
+
+ if (retValue == -1) {
+ tupkeyErrorLab(signal);
+ return -1;
+ }//if
+
ndbrequire(regOperPtr->tupVersion != ZNIL);
pagePtr->pageWord[regOperPtr->pageOffset + 1] = regOperPtr->tupVersion;
if (regTabPtr->checksumIndicator) {
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp b/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp
index 9722aa437c0..8a18fddae19 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp
@@ -184,24 +184,28 @@ void Dbtup::allocConsPages(Uint32 noOfPagesToAllocate,
/* PROPER AMOUNT OF PAGES WERE NOT FOUND. FIND AS MUCH AS */
/* POSSIBLE. */
/* ---------------------------------------------------------------- */
- for (Uint32 j = firstListToCheck; (Uint32)~j; j--) {
+ if (firstListToCheck)
+ {
ljam();
- if (cfreepageList[j] != RNIL) {
+ for (Uint32 j = firstListToCheck - 1; (Uint32)~j; j--) {
ljam();
+ if (cfreepageList[j] != RNIL) {
+ ljam();
/* ---------------------------------------------------------------- */
/* SOME AREA WAS FOUND, ALLOCATE ALL OF IT. */
/* ---------------------------------------------------------------- */
- allocPageRef = cfreepageList[j];
- removeCommonArea(allocPageRef, j);
- noOfPagesAllocated = 1 << j;
- findFreeLeftNeighbours(allocPageRef, noOfPagesAllocated,
- noOfPagesToAllocate);
- findFreeRightNeighbours(allocPageRef, noOfPagesAllocated,
- noOfPagesToAllocate);
-
- return;
- }//if
- }//for
+ allocPageRef = cfreepageList[j];
+ removeCommonArea(allocPageRef, j);
+ noOfPagesAllocated = 1 << j;
+ findFreeLeftNeighbours(allocPageRef, noOfPagesAllocated,
+ noOfPagesToAllocate);
+ findFreeRightNeighbours(allocPageRef, noOfPagesAllocated,
+ noOfPagesToAllocate);
+
+ return;
+ }//if
+ }//for
+ }
/* ---------------------------------------------------------------- */
/* NO FREE AREA AT ALL EXISTED. RETURN ZERO PAGES */
/* ---------------------------------------------------------------- */
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp b/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp
index acdb73704cb..0bb7c8a1e41 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp
@@ -397,12 +397,12 @@ void Dbtup::allocMoreFragPages(Fragrecord* const regFragPtr)
Uint32 noAllocPages = regFragPtr->noOfPagesToGrow >> 3; // 12.5%
noAllocPages += regFragPtr->noOfPagesToGrow >> 4; // 6.25%
noAllocPages += 2;
- regFragPtr->noOfPagesToGrow += noAllocPages;
/* -----------------------------------------------------------------*/
// We will grow by 18.75% plus two more additional pages to grow
// a little bit quicker in the beginning.
/* -----------------------------------------------------------------*/
- allocFragPages(regFragPtr, noAllocPages);
+ Uint32 allocated = allocFragPages(regFragPtr, noAllocPages);
+ regFragPtr->noOfPagesToGrow += allocated;
}//Dbtup::allocMoreFragPages()
Uint32 Dbtup::leafPageRangeFull(Fragrecord* const regFragPtr, PageRangePtr currPageRangePtr)
diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
index e6bb4d4f14f..fe6caf04d8c 100644
--- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
+++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
@@ -181,10 +181,9 @@ void Ndbcntr::execSYSTEM_ERROR(Signal* signal)
case SystemError::CopyFragRefError:
BaseString::snprintf(buf, sizeof(buf),
- "Node %d killed this node because "
- "it could not copy a fragment during node restart. "
- "Copy fragment error code: %u.",
- killingNode, data1);
+ "Killed by node %d as "
+ "copyfrag failed, error: %u",
+ killingNode, data1);
break;
default:
@@ -2043,6 +2042,11 @@ void Ndbcntr::execSET_VAR_REQ(Signal* signal) {
void Ndbcntr::updateNodeState(Signal* signal, const NodeState& newState) const{
NodeStateRep * const stateRep = (NodeStateRep *)&signal->theData[0];
+ if (newState.startLevel == NodeState::SL_STARTED)
+ {
+ CRASH_INSERTION(1000);
+ }
+
stateRep->nodeState = newState;
stateRep->nodeState.masterNodeId = cmasterNodeId;
stateRep->nodeState.setNodeGroup(c_nodeGroup);
@@ -2843,7 +2847,7 @@ void Ndbcntr::Missra::sendNextSTTOR(Signal* signal){
cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
}
}
-
+
signal->theData[0] = NDB_LE_NDBStartCompleted;
signal->theData[1] = NDB_VERSION;
cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
diff --git a/ndb/src/kernel/vm/DLHashTable2.hpp b/ndb/src/kernel/vm/DLHashTable2.hpp
index 6b166331631..1018b053e2a 100644
--- a/ndb/src/kernel/vm/DLHashTable2.hpp
+++ b/ndb/src/kernel/vm/DLHashTable2.hpp
@@ -147,6 +147,8 @@ public:
* @param iter - An "uninitialized" iterator
*/
bool next(Uint32 bucket, Iterator & iter) const;
+
+ inline bool isEmpty() const { Iterator iter; return ! first(iter); }
private:
Uint32 mask;
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index 4428b158b6b..9bf19dda3a4 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -1389,7 +1389,7 @@ ndb_mgm_listen_event_internal(NdbMgmHandle handle, const int filter[],
MGM_END()
};
CHECK_HANDLE(handle, -1);
-
+
const char *hostname= ndb_mgm_get_connected_host(handle);
int port= ndb_mgm_get_connected_port(handle);
SocketClient s(hostname, port);
@@ -1411,19 +1411,20 @@ ndb_mgm_listen_event_internal(NdbMgmHandle handle, const int filter[],
}
args.put("filter", tmp.c_str());
}
-
+
int tmp = handle->socket;
handle->socket = sockfd;
-
+
const Properties *reply;
reply = ndb_mgm_call(handle, stat_reply, "listen event", &args);
-
+
handle->socket = tmp;
-
+
if(reply == NULL) {
close(sockfd);
CHECK_REPLY(reply, -1);
}
+ delete reply;
return sockfd;
}
diff --git a/ndb/src/mgmapi/ndb_logevent.cpp b/ndb/src/mgmapi/ndb_logevent.cpp
index a90d5658506..2472a434590 100644
--- a/ndb/src/mgmapi/ndb_logevent.cpp
+++ b/ndb/src/mgmapi/ndb_logevent.cpp
@@ -68,6 +68,13 @@ ndb_mgm_create_logevent_handle(NdbMgmHandle mh,
}
extern "C"
+int
+ndb_logevent_get_fd(const NdbLogEventHandle h)
+{
+ return h->socket;
+}
+
+extern "C"
void ndb_mgm_destroy_logevent_handle(NdbLogEventHandle * h)
{
if( !h )
diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp
index 58b98671b14..ba68f6e4f0a 100644
--- a/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -173,8 +173,15 @@ private:
bool rep_connected;
#endif
struct NdbThread* m_event_thread;
+ NdbMutex *m_print_mutex;
};
+struct event_thread_param {
+ NdbMgmHandle *m;
+ NdbMutex **p;
+};
+
+NdbMutex* print_mutex;
/*
* Facade object for CommandInterpreter
@@ -395,6 +402,7 @@ CommandInterpreter::CommandInterpreter(const char *_host,int verbose)
m_connected= false;
m_event_thread= 0;
try_reconnect = 0;
+ m_print_mutex= NdbMutex_Create();
#ifdef HAVE_GLOBAL_REPLICATION
rep_host = NULL;
m_repserver = NULL;
@@ -408,6 +416,7 @@ CommandInterpreter::CommandInterpreter(const char *_host,int verbose)
CommandInterpreter::~CommandInterpreter()
{
disconnect();
+ NdbMutex_Destroy(m_print_mutex);
}
static bool
@@ -444,11 +453,13 @@ CommandInterpreter::printError()
static int do_event_thread;
static void*
-event_thread_run(void* m)
+event_thread_run(void* p)
{
DBUG_ENTER("event_thread_run");
- NdbMgmHandle handle= *(NdbMgmHandle*)m;
+ struct event_thread_param param= *(struct event_thread_param*)p;
+ NdbMgmHandle handle= *(param.m);
+ NdbMutex* printmutex= *(param.p);
int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP,
1, NDB_MGM_EVENT_CATEGORY_STARTUP,
@@ -466,7 +477,11 @@ event_thread_run(void* m)
{
const char ping_token[]= "<PING>";
if (memcmp(ping_token,tmp,sizeof(ping_token)-1))
- ndbout << tmp;
+ if(tmp && strlen(tmp))
+ {
+ Guard g(printmutex);
+ ndbout << tmp;
+ }
}
} while(do_event_thread);
NDB_CLOSE_SOCKET(fd);
@@ -519,8 +534,11 @@ CommandInterpreter::connect()
assert(m_event_thread == 0);
assert(do_event_thread == 0);
do_event_thread= 0;
+ struct event_thread_param p;
+ p.m= &m_mgmsrv2;
+ p.p= &m_print_mutex;
m_event_thread = NdbThread_Create(event_thread_run,
- (void**)&m_mgmsrv2,
+ (void**)&p,
32768,
"CommandInterpreted_event_thread",
NDB_THREAD_PRIO_LOW);
@@ -607,6 +625,7 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect,
int result= execute_impl(_line);
if (error)
*error= m_error;
+
return result;
}
@@ -686,6 +705,7 @@ CommandInterpreter::execute_impl(const char *_line)
DBUG_RETURN(true);
if (strcasecmp(firstToken, "SHOW") == 0) {
+ Guard g(m_print_mutex);
executeShow(allAfterFirstToken);
DBUG_RETURN(true);
}
@@ -920,6 +940,7 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun,
ndbout_c("Trying to start all nodes of system.");
ndbout_c("Use ALL STATUS to see the system start-up phases.");
} else {
+ Guard g(m_print_mutex);
struct ndb_mgm_cluster_state *cl= ndb_mgm_get_status(m_mgmsrv);
if(cl == 0){
ndbout_c("Unable get status from management server");
@@ -1224,6 +1245,7 @@ CommandInterpreter::executeShow(char* parameters)
if(it == 0){
ndbout_c("Unable to create config iterator");
+ ndb_mgm_destroy_configuration(conf);
return;
}
NdbAutoPtr<ndb_mgm_configuration_iterator> ptr(it);
@@ -1270,6 +1292,7 @@ CommandInterpreter::executeShow(char* parameters)
print_nodes(state, it, "ndb_mgmd", mgm_nodes, NDB_MGM_NODE_TYPE_MGM, 0);
print_nodes(state, it, "mysqld", api_nodes, NDB_MGM_NODE_TYPE_API, 0);
// ndbout << helpTextShow;
+ ndb_mgm_destroy_configuration(conf);
return;
} else if (strcasecmp(parameters, "PROPERTIES") == 0 ||
strcasecmp(parameters, "PROP") == 0) {
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index 69c0286a1de..5fabb84adb7 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -77,7 +77,6 @@
}\
}
-extern int global_flag_send_heartbeat_now;
extern int g_no_nodeid_checks;
extern my_bool opt_core;
@@ -1455,6 +1454,12 @@ MgmtSrvr::exitSingleUser(int * stopCount, bool abort)
#include <ClusterMgr.hpp>
+void
+MgmtSrvr::updateStatus()
+{
+ theFacade->theClusterMgr->forceHB();
+}
+
int
MgmtSrvr::status(int nodeId,
ndb_mgm_node_status * _status,
@@ -2153,7 +2158,7 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
if (found_matching_type && !found_free_node) {
// we have a temporary error which might be due to that
// we have got the latest connect status from db-nodes. Force update.
- global_flag_send_heartbeat_now= 1;
+ updateStatus();
}
BaseString type_string, type_c_string;
@@ -2507,7 +2512,7 @@ MgmtSrvr::Allocated_resources::~Allocated_resources()
if (!m_reserved_nodes.isclear()) {
m_mgmsrv.m_reserved_nodes.bitANDC(m_reserved_nodes);
// node has been reserved, force update signal to ndb nodes
- global_flag_send_heartbeat_now= 1;
+ m_mgmsrv.updateStatus();
char tmp_str[128];
m_mgmsrv.m_reserved_nodes.getText(tmp_str);
diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp
index 187f225470a..17debb19f50 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -490,6 +490,8 @@ public:
void get_connected_nodes(NodeBitmask &connected_nodes) const;
SocketServer *get_socket_server() { return m_socket_server; }
+ void updateStatus();
+
//**************************************************************************
private:
//**************************************************************************
diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp
index 0524aba4c32..7f5b0e29442 100644
--- a/ndb/src/mgmsrv/Services.cpp
+++ b/ndb/src/mgmsrv/Services.cpp
@@ -982,6 +982,7 @@ printNodeStatus(OutputStream *output,
MgmtSrvr &mgmsrv,
enum ndb_mgm_node_type type) {
NodeId nodeId = 0;
+ mgmsrv.updateStatus();
while(mgmsrv.getNextNodeId(&nodeId, type)) {
enum ndb_mgm_node_status status;
Uint32 startPhase = 0,
diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp
index fbff57d3168..475561af225 100644
--- a/ndb/src/ndbapi/ClusterMgr.cpp
+++ b/ndb/src/ndbapi/ClusterMgr.cpp
@@ -37,7 +37,7 @@
#include <mgmapi_configuration.hpp>
#include <mgmapi_config_parameters.h>
-int global_flag_send_heartbeat_now= 0;
+//#define DEBUG_REG
// Just a C wrapper for threadMain
extern "C"
@@ -67,6 +67,8 @@ ClusterMgr::ClusterMgr(TransporterFacade & _facade):
DBUG_ENTER("ClusterMgr::ClusterMgr");
ndbSetOwnVersion();
clusterMgrThreadMutex = NdbMutex_Create();
+ waitForHBCond= NdbCondition_Create();
+ waitingForHB= false;
noOfAliveNodes= 0;
noOfConnectedNodes= 0;
theClusterMgrThread= 0;
@@ -77,7 +79,8 @@ ClusterMgr::ClusterMgr(TransporterFacade & _facade):
ClusterMgr::~ClusterMgr()
{
DBUG_ENTER("ClusterMgr::~ClusterMgr");
- doStop();
+ doStop();
+ NdbCondition_Destroy(waitForHBCond);
NdbMutex_Destroy(clusterMgrThreadMutex);
DBUG_VOID_RETURN;
}
@@ -164,6 +167,70 @@ ClusterMgr::doStop( ){
}
void
+ClusterMgr::forceHB()
+{
+ theFacade.lock_mutex();
+
+ if(waitingForHB)
+ {
+ NdbCondition_WaitTimeout(waitForHBCond, theFacade.theMutexPtr, 1000);
+ theFacade.unlock_mutex();
+ return;
+ }
+
+ waitingForHB= true;
+
+ NodeBitmask ndb_nodes;
+ ndb_nodes.clear();
+ waitForHBFromNodes.clear();
+ for(Uint32 i = 0; i < MAX_NODES; i++)
+ {
+ if(!theNodes[i].defined)
+ continue;
+ if(theNodes[i].m_info.m_type == NodeInfo::DB)
+ {
+ ndb_nodes.set(i);
+ const ClusterMgr::Node &node= getNodeInfo(i);
+ waitForHBFromNodes.bitOR(node.m_state.m_connected_nodes);
+ }
+ }
+ waitForHBFromNodes.bitAND(ndb_nodes);
+
+#ifdef DEBUG_REG
+ char buf[128];
+ ndbout << "Waiting for HB from " << waitForHBFromNodes.getText(buf) << endl;
+#endif
+ NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId()));
+
+ signal.theVerId_signalNumber = GSN_API_REGREQ;
+ signal.theReceiversBlockNumber = QMGR;
+ signal.theTrace = 0;
+ signal.theLength = ApiRegReq::SignalLength;
+
+ ApiRegReq * req = CAST_PTR(ApiRegReq, signal.getDataPtrSend());
+ req->ref = numberToRef(API_CLUSTERMGR, theFacade.ownId());
+ req->version = NDB_VERSION;
+
+ int nodeId= 0;
+ for(int i=0;
+ NodeBitmask::NotFound!=(nodeId= waitForHBFromNodes.find(i));
+ i= nodeId+1)
+ {
+#ifdef DEBUG_REG
+ ndbout << "FORCE HB to " << nodeId << endl;
+#endif
+ theFacade.sendSignalUnCond(&signal, nodeId);
+ }
+
+ NdbCondition_WaitTimeout(waitForHBCond, theFacade.theMutexPtr, 1000);
+ waitingForHB= false;
+#ifdef DEBUG_REG
+ ndbout << "Still waiting for HB from " << waitForHBFromNodes.getText(buf) << endl;
+#endif
+ theFacade.unlock_mutex();
+}
+
+void
ClusterMgr::threadMain( ){
NdbApiSignal signal(numberToRef(API_CLUSTERMGR, theFacade.ownId()));
@@ -184,9 +251,6 @@ ClusterMgr::threadMain( ){
/**
* Start of Secure area for use of Transporter
*/
- int send_heartbeat_now= global_flag_send_heartbeat_now;
- global_flag_send_heartbeat_now= 0;
-
theFacade.lock_mutex();
for (int i = 1; i < MAX_NODES; i++){
/**
@@ -209,8 +273,7 @@ ClusterMgr::threadMain( ){
}
theNode.hbCounter += timeSlept;
- if (theNode.hbCounter >= theNode.hbFrequency ||
- send_heartbeat_now) {
+ if (theNode.hbCounter >= theNode.hbFrequency) {
/**
* It is now time to send a new Heartbeat
*/
@@ -226,7 +289,7 @@ ClusterMgr::threadMain( ){
if (theNode.m_info.m_type == NodeInfo::REP) {
signal.theReceiversBlockNumber = API_CLUSTERMGR;
}
-#if 0
+#ifdef DEBUG_REG
ndbout_c("ClusterMgr: Sending API_REGREQ to node %d", (int)nodeId);
#endif
theFacade.sendSignalUnCond(&signal, nodeId);
@@ -278,7 +341,7 @@ ClusterMgr::execAPI_REGREQ(const Uint32 * theData){
const ApiRegReq * const apiRegReq = (ApiRegReq *)&theData[0];
const NodeId nodeId = refToNode(apiRegReq->ref);
-#if 0
+#ifdef DEBUG_REG
ndbout_c("ClusterMgr: Recd API_REGREQ from node %d", nodeId);
#endif
@@ -319,7 +382,7 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){
const ApiRegConf * const apiRegConf = (ApiRegConf *)&theData[0];
const NodeId nodeId = refToNode(apiRegConf->qmgrRef);
-#if 0
+#ifdef DEBUG_REG
ndbout_c("ClusterMgr: Recd API_REGCONF from node %d", nodeId);
#endif
@@ -351,6 +414,17 @@ ClusterMgr::execAPI_REGCONF(const Uint32 * theData){
if (node.m_info.m_type != NodeInfo::REP) {
node.hbFrequency = (apiRegConf->apiHeartbeatFrequency * 10) - 50;
}
+
+ if(waitingForHB)
+ {
+ waitForHBFromNodes.clear(nodeId);
+
+ if(waitForHBFromNodes.isclear())
+ {
+ waitingForHB= false;
+ NdbCondition_Broadcast(waitForHBCond);
+ }
+ }
}
void
@@ -379,6 +453,10 @@ ClusterMgr::execAPI_REGREF(const Uint32 * theData){
default:
break;
}
+
+ waitForHBFromNodes.clear(nodeId);
+ if(waitForHBFromNodes.isclear())
+ NdbCondition_Signal(waitForHBCond);
}
void
diff --git a/ndb/src/ndbapi/ClusterMgr.hpp b/ndb/src/ndbapi/ClusterMgr.hpp
index 1a1e622a889..d2bcc52f7e8 100644
--- a/ndb/src/ndbapi/ClusterMgr.hpp
+++ b/ndb/src/ndbapi/ClusterMgr.hpp
@@ -49,7 +49,9 @@ public:
void doStop();
void startThread();
-
+
+ void forceHB();
+
private:
void threadMain();
@@ -85,7 +87,11 @@ private:
Uint32 noOfConnectedNodes;
Node theNodes[MAX_NODES];
NdbThread* theClusterMgrThread;
-
+
+ NodeBitmask waitForHBFromNodes; // used in forcing HBs
+ NdbCondition* waitForHBCond;
+ bool waitingForHB;
+
/**
* Used for controlling start/stop of the thread
*/
diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp
index 90e3a63c53d..c5a0ebbaf60 100644
--- a/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -475,6 +475,8 @@ int NdbScanOperation::nextResultImpl(bool fetchAllowed, bool forceSend)
idx = m_current_api_receiver;
last = m_api_receivers_count;
+
+ Uint32 timeout = tp->m_waitfor_timeout;
do {
if(theError.code){
@@ -502,7 +504,7 @@ int NdbScanOperation::nextResultImpl(bool fetchAllowed, bool forceSend)
*/
theNdb->theImpl->theWaiter.m_node = nodeId;
theNdb->theImpl->theWaiter.m_state = WAIT_SCAN;
- int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT);
+ int return_code = theNdb->receiveResponse(3*timeout);
if (return_code == 0 && seq == tp->getNodeSequence(nodeId)) {
continue;
} else {
@@ -1365,6 +1367,7 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed,
return -1;
Uint32 seq = theNdbCon->theNodeSequence;
Uint32 nodeId = theNdbCon->theDBnode;
+ Uint32 timeout = tp->m_waitfor_timeout;
if(seq == tp->getNodeSequence(nodeId) &&
!send_next_scan_ordered(s_idx, forceSend)){
Uint32 tmp = m_sent_receivers_count;
@@ -1372,7 +1375,7 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed,
while(m_sent_receivers_count > 0 && !theError.code){
theNdb->theImpl->theWaiter.m_node = nodeId;
theNdb->theImpl->theWaiter.m_state = WAIT_SCAN;
- int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT);
+ int return_code = theNdb->receiveResponse(3*timeout);
if (return_code == 0 && seq == tp->getNodeSequence(nodeId)) {
continue;
}
@@ -1513,6 +1516,8 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend){
return -1;
}
+ Uint32 timeout = tp->m_waitfor_timeout;
+
/**
* Wait for outstanding
*/
@@ -1520,7 +1525,7 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend){
{
theNdb->theImpl->theWaiter.m_node = nodeId;
theNdb->theImpl->theWaiter.m_state = WAIT_SCAN;
- int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT);
+ int return_code = theNdb->receiveResponse(3*timeout);
switch(return_code){
case 0:
break;
@@ -1590,7 +1595,7 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend){
{
theNdb->theImpl->theWaiter.m_node = nodeId;
theNdb->theImpl->theWaiter.m_state = WAIT_SCAN;
- int return_code = theNdb->receiveResponse(WAITFOR_SCAN_TIMEOUT);
+ int return_code = theNdb->receiveResponse(3*timeout);
switch(return_code){
case 0:
break;
diff --git a/ndb/test/include/NDBT_Tables.hpp b/ndb/test/include/NDBT_Tables.hpp
index fb0df8aa35b..a6973861af8 100644
--- a/ndb/test/include/NDBT_Tables.hpp
+++ b/ndb/test/include/NDBT_Tables.hpp
@@ -42,6 +42,8 @@ public:
static const NdbDictionary::Table* getTable(int _num);
static int getNumTables();
+ static const char** getIndexes(const char* table);
+
private:
static const NdbDictionary::Table* tableWithPkSize(const char* _nam, Uint32 pkSize);
};
diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp
index b992d492ad6..ba05bbad7bb 100644
--- a/ndb/test/ndbapi/testDict.cpp
+++ b/ndb/test/ndbapi/testDict.cpp
@@ -1022,8 +1022,8 @@ int verifyTablesAreEqual(const NdbDictionary::Table* pTab, const NdbDictionary::
if (!pTab->equal(*pTab2)){
g_err << "equal failed" << endl;
- g_info << *pTab;
- g_info << *pTab2;
+ g_info << *(NDBT_Table*)pTab; // gcc-4.1.2
+ g_info << *(NDBT_Table*)pTab2;
return NDBT_FAILED;
}
return NDBT_OK;
@@ -1033,7 +1033,7 @@ int runGetPrimaryKey(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
const NdbDictionary::Table* pTab = ctx->getTab();
ndbout << "|- " << pTab->getName() << endl;
- g_info << *pTab;
+ g_info << *(NDBT_Table*)pTab;
// Try to create table in db
if (pTab->createTableInDb(pNdb) != 0){
return NDBT_FAILED;
@@ -1890,6 +1890,52 @@ runDictOps(NDBT_Context* ctx, NDBT_Step* step)
// replace by the Retrieved table
pTab = pTab2;
+ // create indexes
+ const char** indlist = NDBT_Tables::getIndexes(tabName);
+ uint indnum = 0;
+ while (*indlist != 0) {
+ uint count = 0;
+ try_create_index:
+ count++;
+ if (count == 1)
+ g_info << "2: create index " << indnum << " " << *indlist << endl;
+ NdbDictionary::Index ind;
+ char indName[200];
+ sprintf(indName, "%s_X%u", tabName, indnum);
+ ind.setName(indName);
+ ind.setTable(tabName);
+ if (strcmp(*indlist, "UNIQUE") == 0) {
+ ind.setType(NdbDictionary::Index::UniqueHashIndex);
+ ind.setLogging(pTab->getLogging());
+ } else if (strcmp(*indlist, "ORDERED") == 0) {
+ ind.setType(NdbDictionary::Index::OrderedIndex);
+ ind.setLogging(false);
+ } else {
+ assert(false);
+ }
+ const char** indtemp = indlist;
+ while (*++indtemp != 0) {
+ ind.addColumn(*indtemp);
+ }
+ if (pDic->createIndex(ind) != 0) {
+ const NdbError err = pDic->getNdbError();
+ if (count == 1)
+ g_err << "2: " << indName << ": create failed: " << err << endl;
+ if (err.code != 711) {
+ result = NDBT_FAILED;
+ break;
+ }
+ NdbSleep_MilliSleep(myRandom48(maxsleep));
+ goto try_create_index;
+ }
+ indlist = ++indtemp;
+ indnum++;
+ }
+ if (result == NDBT_FAILED)
+ break;
+
+ uint indcount = indnum;
+
int records = myRandom48(ctx->getNumRecords());
g_info << "2: load " << records << " records" << endl;
HugoTransactions hugoTrans(*pTab);
@@ -1901,6 +1947,32 @@ runDictOps(NDBT_Context* ctx, NDBT_Step* step)
}
NdbSleep_MilliSleep(myRandom48(maxsleep));
+ // drop indexes
+ indnum = 0;
+ while (indnum < indcount) {
+ uint count = 0;
+ try_drop_index:
+ count++;
+ if (count == 1)
+ g_info << "2: drop index " << indnum << endl;
+ char indName[200];
+ sprintf(indName, "%s_X%u", tabName, indnum);
+ if (pDic->dropIndex(indName, tabName) != 0) {
+ const NdbError err = pDic->getNdbError();
+ if (count == 1)
+ g_err << "2: " << indName << ": drop failed: " << err << endl;
+ if (err.code != 711) {
+ result = NDBT_FAILED;
+ break;
+ }
+ NdbSleep_MilliSleep(myRandom48(maxsleep));
+ goto try_drop_index;
+ }
+ indnum++;
+ }
+ if (result == NDBT_FAILED)
+ break;
+
g_info << "2: drop" << endl;
{
uint count = 0;
diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp
index 5785db232c4..c25aae55897 100644
--- a/ndb/test/ndbapi/testIndex.cpp
+++ b/ndb/test/ndbapi/testIndex.cpp
@@ -1199,6 +1199,48 @@ int runLQHKEYREF(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK;
}
+int
+runBug21384(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* pNdb = GETNDB(step);
+ HugoTransactions hugoTrans(*ctx->getTab());
+ NdbRestarter restarter;
+
+ int loops = ctx->getNumLoops();
+ const int rows = ctx->getNumRecords();
+ const int batchsize = ctx->getProperty("BatchSize", 50);
+
+ while (loops--)
+ {
+ if(restarter.insertErrorInAllNodes(8037) != 0)
+ {
+ g_err << "Failed to error insert(8037)" << endl;
+ return NDBT_FAILED;
+ }
+
+ if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchsize) == 0)
+ {
+ g_err << "Index succeded (it should have failed" << endl;
+ return NDBT_FAILED;
+ }
+
+ if(restarter.insertErrorInAllNodes(0) != 0)
+ {
+ g_err << "Failed to error insert(0)" << endl;
+ return NDBT_FAILED;
+ }
+
+ if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchsize) != 0){
+ g_err << "Index read failed" << endl;
+ return NDBT_FAILED;
+ }
+ }
+
+ return NDBT_OK;
+}
+
+
+
NDBT_TESTSUITE(testIndex);
TESTCASE("CreateAll",
"Test that we can create all various indexes on each table\n"
@@ -1512,6 +1554,16 @@ TESTCASE("UniqueNull",
FINALIZER(createPkIndex_Drop);
FINALIZER(runClearTable);
}
+TESTCASE("Bug21384",
+ "Test that unique indexes and nulls"){
+ TC_PROPERTY("LoggedIndexes", (unsigned)0);
+ INITIALIZER(runClearTable);
+ INITIALIZER(createPkIndex);
+ INITIALIZER(runLoadTable);
+ STEP(runBug21384);
+ FINALIZER(createPkIndex_Drop);
+ FINALIZER(runClearTable);
+}
NDBT_TESTSUITE_END(testIndex);
int main(int argc, const char** argv){
diff --git a/ndb/test/ndbapi/testSystemRestart.cpp b/ndb/test/ndbapi/testSystemRestart.cpp
index 30f7aca9b06..8a0100ff3e4 100644
--- a/ndb/test/ndbapi/testSystemRestart.cpp
+++ b/ndb/test/ndbapi/testSystemRestart.cpp
@@ -1121,6 +1121,46 @@ int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK;
}
+int
+runBug21536(NDBT_Context* ctx, NDBT_Step* step)
+{
+ NdbRestarter restarter;
+ const Uint32 nodeCount = restarter.getNumDbNodes();
+ if(nodeCount != 2){
+ g_info << "Bug21536 - 2 nodes to test" << endl;
+ return NDBT_OK;
+ }
+
+ int node1 = restarter.getDbNodeId(rand() % nodeCount);
+ int node2 = restarter.getRandomNodeSameNodeGroup(node1, rand());
+
+ if (node1 == -1 || node2 == -1)
+ return NDBT_OK;
+
+ int result = NDBT_OK;
+ do {
+ CHECK(restarter.restartOneDbNode(node1, false, true, true) == 0);
+ CHECK(restarter.waitNodesNoStart(&node1, 1) == 0);
+ CHECK(restarter.insertErrorInNode(node1, 1000) == 0);
+ int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
+ CHECK(restarter.dumpStateOneNode(node1, val2, 2) == 0);
+ CHECK(restarter.startNodes(&node1, 1) == 0);
+ restarter.waitNodesStartPhase(&node1, 1, 3, 120);
+ CHECK(restarter.waitNodesNoStart(&node1, 1) == 0);
+
+ CHECK(restarter.restartOneDbNode(node2, true, true, true) == 0);
+ CHECK(restarter.waitNodesNoStart(&node2, 1) == 0);
+ CHECK(restarter.startNodes(&node1, 1) == 0);
+ CHECK(restarter.waitNodesStarted(&node1, 1) == 0);
+ CHECK(restarter.startNodes(&node2, 1) == 0);
+ CHECK(restarter.waitClusterStarted() == 0);
+
+ } while(0);
+
+ g_info << "Bug21536 finished" << endl;
+
+ return result;
+}
NDBT_TESTSUITE(testSystemRestart);
TESTCASE("SR1",
@@ -1287,6 +1327,13 @@ TESTCASE("Bug18385",
STEP(runBug18385);
FINALIZER(runClearTable);
}
+TESTCASE("Bug21536",
+ "Perform partition system restart with other nodes with higher GCI"){
+ INITIALIZER(runWaitStarted);
+ INITIALIZER(runClearTable);
+ STEP(runBug21536);
+ FINALIZER(runClearTable);
+}
NDBT_TESTSUITE_END(testSystemRestart);
int main(int argc, const char** argv){
diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt
index cbb8a9a2574..a2edc568426 100644
--- a/ndb/test/run-test/daily-basic-tests.txt
+++ b/ndb/test/run-test/daily-basic-tests.txt
@@ -449,6 +449,10 @@ max-time: 1000
cmd: testNodeRestart
args: -n Bug20185 T1
+max-time: 1000
+cmd: testIndex
+args: -n Bug21384
+
# OLD FLEX
max-time: 500
cmd: flexBench
diff --git a/ndb/test/src/NDBT_Tables.cpp b/ndb/test/src/NDBT_Tables.cpp
index 5a5fecd85c1..d72dfcc5031 100644
--- a/ndb/test/src/NDBT_Tables.cpp
+++ b/ndb/test/src/NDBT_Tables.cpp
@@ -799,6 +799,17 @@ NDBT_Tables::getNumTables(){
return numTestTables;
}
+const char**
+NDBT_Tables::getIndexes(const char* table)
+{
+ Uint32 i = 0;
+ for (i = 0; indexes[i].m_table != 0; i++) {
+ if (strcmp(indexes[i].m_table, table) == 0)
+ return indexes[i].m_indexes;
+ }
+ return 0;
+}
+
int
NDBT_Tables::createAllTables(Ndb* pNdb, bool _temp, bool existsOk){
diff --git a/ndb/tools/ndb_config.cpp b/ndb/tools/ndb_config.cpp
index 27ab6a182bb..135bec7ef72 100644
--- a/ndb/tools/ndb_config.cpp
+++ b/ndb/tools/ndb_config.cpp
@@ -145,7 +145,7 @@ struct Match
struct HostMatch : public Match
{
- virtual int eval(NdbMgmHandle, const Iter&);
+ virtual int eval(const Iter&);
};
struct Apply
@@ -402,7 +402,7 @@ Match::eval(const Iter& iter)
}
int
-HostMatch::eval(NdbMgmHandle h, const Iter& iter)
+HostMatch::eval(const Iter& iter)
{
const char* valc;
diff --git a/regex/CMakeLists.txt b/regex/CMakeLists.txt
new file mode 100755
index 00000000000..796481a62d5
--- /dev/null
+++ b/regex/CMakeLists.txt
@@ -0,0 +1,5 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys})
+ADD_LIBRARY(regex debug.c regcomp.c regerror.c regexec.c regfree.c reginit.c split.c)
diff --git a/regex/Makefile.am b/regex/Makefile.am
index 7e8478e8123..1f496fcec62 100644
--- a/regex/Makefile.am
+++ b/regex/Makefile.am
@@ -25,7 +25,7 @@ re_SOURCES = split.c debug.c main.c
re_LDFLAGS= @NOINST_LDFLAGS@
EXTRA_DIST = tests CHANGES COPYRIGHT WHATSNEW regexp.c \
debug.ih engine.ih main.ih regcomp.ih regerror.ih \
- regex.3 regex.7
+ regex.3 regex.7 CMakeLists.txt
test: re tests
./re < tests
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index a339ebc5b8f..dd4c133ff94 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -66,7 +66,8 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \
EXTRA_DIST = $(EXTRA_SCRIPTS) \
mysqlaccess.conf \
- mysqlbug
+ mysqlbug \
+ make_win_bin_dist
dist_pkgdata_DATA = fill_help_tables.sql mysql_fix_privilege_tables.sql
diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist
new file mode 100755
index 00000000000..cc75245e5d9
--- /dev/null
+++ b/scripts/make_win_bin_dist
@@ -0,0 +1,345 @@
+#!/bin/sh
+
+# Exit if failing to copy, we want exact specifications, not
+# just "what happen to be built".
+set -e
+
+# ----------------------------------------------------------------------
+# Read first argument that is the base name of the resulting TAR file.
+# See usage() function below for a description on the arguments.
+#
+# NOTE: We will read the rest of the command line later on.
+# NOTE: Pattern matching with "{..,..}" can't be used, not portable.
+# ----------------------------------------------------------------------
+
+# FIXME FIXME "debug", own build or handled here?
+# FIXME FIXME add way to copy from other builds executables
+
+usage()
+{
+ echo <<EOF
+Usage: make_win_bin_dist [ options ] package-base-name [ copy-defs... ]
+
+This is a script to run from the top of a source tree built on Windows.
+The "package-base-name" argument should be something like
+
+ mysql-noinstall-5.0.25-win32 (or winx64)
+
+and will be the name of the directory of the unpacked ZIP (stripping
+away the "noinstall" part of the ZIP file name if any) and the base
+for the resulting package name.
+
+Options are
+
+ --embedded Pack the embedded server and give error if not built.
+ The default is to pack it if it is built.
+
+ --no-embedded Don't pack the embedded server even if built
+
+ --debug Pack the debug binaries and give error if not built.
+
+ --no-debug Don't pack the debug binaries even if built
+
+ --only-debug The target for this build was "Debug", and we just
+ want to replace the normal binaries with debug
+ versions, i.e. no separate "debug" directories.
+
+ --exe-suffix=SUF Add a suffix to the "mysqld" binary.
+
+As you might want to include files of directories from other builds
+(like a "mysqld-max.exe" server), you can instruct this script do copy
+them in for you. This is the "copy-def" arguments, and they are of the
+form
+
+ relative-dest-name=source-name .....
+
+i.e. can be something like
+
+ bin/mysqld-max.exe=../my-max-build/sql/release/mysqld.exe
+
+If you specify a directory the whole directory will be copied.
+
+EOF
+ exit 1
+}
+
+# ----------------------------------------------------------------------
+# We need to be at the top of a source tree, check that we are
+# ----------------------------------------------------------------------
+
+if [ ! -d "sql" ] ; then
+ echo "You need to run this script from inside the source tree"
+ usage
+fi
+
+# ----------------------------------------------------------------------
+# Actual argument processing, first part
+# ----------------------------------------------------------------------
+
+NOINST_NAME=""
+TARGET="release"
+PACK_EMBEDDED="" # Could be "no", "yes" or empty
+PACK_DEBUG="" # Could be "no", "yes" or empty
+EXE_SUFFIX=""
+
+for arg do
+ shift
+ case "$arg" in
+ --embedded) PACK_EMBEDDED="yes" ;;
+ --no-embedded) PACK_EMBEDDED="no" ;;
+ --debug) PACK_DEBUG="yes" ;;
+ --no-debug) PACK_DEBUG="no" ;;
+ --only-debug) TARGET="debug" ; PACK_DEBUG="no" ;;
+ --exe-suffix=*) EXE_SUFFIX=`echo "$arg" | sed -e "s,--exe-suffix=,,"` ;;
+ -*)
+ echo "Unknown argument '$arg'"
+ usage
+ ;;
+ *)
+ NOINST_NAME="$arg"
+ break
+ esac
+done
+
+if [ x"$NOINST_NAME" = x"" ] ; then
+ echo "No base package name given"
+ usage
+fi
+DESTDIR=`echo $NOINST_NAME | sed 's/-noinstall-/-/'`
+
+if [ -e $DESTDIR ] ; then
+ echo "Please remove the old $DESTDIR before running this script"
+ usage
+fi
+
+# ----------------------------------------------------------------------
+# Copy executables, and client DLL (FIXME why?)
+# ----------------------------------------------------------------------
+
+trap 'echo "Clearning up and exiting..." ; rm -fr $DESTDIR; exit 1' ERR
+
+mkdir $DESTDIR
+mkdir $DESTDIR/bin
+cp client/$TARGET/*.exe $DESTDIR/bin/
+cp extra/$TARGET/*.exe $DESTDIR/bin/
+cp myisam/$TARGET/*.exe $DESTDIR/bin/
+cp server-tools/instance-manager/$TARGET/*.exe $DESTDIR/bin/
+cp tests/$TARGET/*.exe $DESTDIR/bin/
+cp libmysql/$TARGET/*.exe $DESTDIR/bin/
+cp libmysql/$TARGET/libmysql.dll $DESTDIR/bin/
+
+# FIXME really needed?!
+mv $DESTDIR/bin/comp_err.exe $DESTDIR/bin/comp-err.exe
+
+cp sql/$TARGET/mysqld.exe $DESTDIR/bin/mysqld$EXE_SUFFIX.exe
+
+if [ x"$PACK_DEBUG" = "" -a -f "sql/debug/mysqld.exe" -o \
+ x"$PACK_DEBUG" = "yes" ] ; then
+ cp sql/debug/mysqld.exe $DESTDIR/bin/mysqld-debug.exe
+ cp sql/debug/mysqld.pdb $DESTDIR/bin/mysqld-debug.pdb
+ cp sql/debug/mysqld.map $DESTDIR/bin/mysqld-debug.map
+fi
+
+# ----------------------------------------------------------------------
+# Copy data directory, readme files etc
+# ----------------------------------------------------------------------
+
+cp COPYING EXCEPTIONS-CLIENT $DESTDIR/
+
+# FIXME is there ever a data directory to copy?
+if [ -d win/data ] ; then
+ cp -pR win/data $DESTDIR/data
+fi
+
+# FIXME maybe a flag to define "release build", or do the
+# check from the calling script that all these are there,
+# and with the correct content.
+
+mkdir $DESTDIR/Docs
+cp Docs/INSTALL-BINARY $DESTDIR/Docs/
+cp Docs/manual.chm $DESTDIR/Docs/ || /bin/true
+cp ChangeLog $DESTDIR/Docs/ || /bin/true
+cp COPYING $DESTDIR/Docs/
+cp support-files/my-*.ini $DESTDIR/
+
+# ----------------------------------------------------------------------
+# These will be filled in when we enable embedded. Note that if no
+# argument is given, it is copied if exists, else a check is done.
+# ----------------------------------------------------------------------
+
+copy_embedded()
+{
+ mkdir -p $DESTDIR/Embedded/DLL/release \
+ $DESTDIR/Embedded/static/release
+ cp libmysqld/libmysqld.def $DESTDIR/include/
+ cp libmysqld/$TARGET/mysqlserver.lib $DESTDIR/Embedded/static/release/
+ cp libmysqld/$TARGET/libmysqld.dll $DESTDIR/Embedded/DLL/release/
+ cp libmysqld/$TARGET/libmysqld.exp $DESTDIR/Embedded/DLL/release/
+ cp libmysqld/$TARGET/libmysqld.lib $DESTDIR/Embedded/DLL/release/
+
+ if [ x"$PACK_DEBUG" = "" -a -f "libmysqld/debug/libmysqld.lib" -o \
+ x"$PACK_DEBUG" = "yes" ] ; then
+ mkdir -p $DESTDIR/Embedded/DLL/debug
+ cp libmysqld/debug/libmysqld.dll $DESTDIR/Embedded/DLL/debug/
+ cp libmysqld/debug/libmysqld.exp $DESTDIR/Embedded/DLL/debug/
+ cp libmysqld/debug/libmysqld.lib $DESTDIR/Embedded/DLL/debug/
+ fi
+}
+
+if [ x"$PACK_EMBEDDED" = "" -a \
+ -f "libmysqld/$TARGET/mysqlserver.lib" -a \
+ -f "libmysqld/$TARGET/libmysqld.lib" -o \
+ x"$PACK_EMBEDDED" = "yes" ] ; then
+ copy_embedded
+fi
+
+# ----------------------------------------------------------------------
+# FIXME test stuff that is useless garbage?
+# ----------------------------------------------------------------------
+
+mkdir -p $DESTDIR/examples/libmysqltest/release
+cp libmysql/mytest.c libmysql/myTest.vcproj libmysql/$TARGET/myTest.exe \
+ $DESTDIR/examples/libmysqltest/
+cp libmysql/$TARGET/myTest.exe $DESTDIR/examples/libmysqltest/release/
+
+if [ x"$PACK_DEBUG" = "" -a -f "libmysql/debug/myTest.exe" -o \
+ x"$PACK_DEBUG" = "yes" ] ; then
+ mkdir -p $DESTDIR/examples/libmysqltest/debug
+ cp libmysql/debug/myTest.exe $DESTDIR/examples/libmysqltest/debug/
+fi
+
+mkdir -p $DESTDIR/examples/tests
+cp tests/*.res tests/*.tst tests/*.pl tests/*.c $DESTDIR/examples/tests/
+
+# ----------------------------------------------------------------------
+# FIXME why not copy it all in "include"?!
+# ----------------------------------------------------------------------
+
+mkdir -p $DESTDIR/include
+cp include/conf*.h \
+ include/mysql*.h \
+ include/errmsg.h \
+ include/my_alloc.h \
+ include/my_getopt.h \
+ include/my_sys.h \
+ include/my_list.h \
+ include/my_pthread.h \
+ include/my_dbug.h \
+ include/m_string.h \
+ include/m_ctype.h \
+ include/my_global.h \
+ include/typelib.h $DESTDIR/include/
+cp libmysql/libmysql.def $DESTDIR/include/
+
+# ----------------------------------------------------------------------
+# Client libraries, and other libraries
+# FIXME why "libmysql.dll" installed both in "bin" and "lib/opt"?
+# ----------------------------------------------------------------------
+
+mkdir -p $DESTDIR/lib/opt
+cp libmysql/$TARGET/libmysql.dll \
+ libmysql/$TARGET/libmysql.lib \
+ client/$TARGET/mysqlclient.lib \
+ regex/$TARGET/regex.lib \
+ strings/$TARGET/strings.lib \
+ zlib/$TARGET/zlib.lib $DESTDIR/lib/opt/
+
+if [ x"$PACK_DEBUG" = "" -a -f "libmysql/debug/libmysql.lib" -o \
+ x"$PACK_DEBUG" = "yes" ] ; then
+ mkdir -p $DESTDIR/lib/debug
+ cp libmysql/debug/libmysql.dll \
+ libmysql/debug/libmysql.lib \
+ client/debug/mysqlclient.lib \
+ mysys/debug/mysys.lib \
+ regex/debug/regex.lib \
+ strings/debug/strings.lib \
+ zlib/debug/zlib.lib $DESTDIR/lib/debug/
+fi
+
+# FIXME sort this out...
+cp mysys/$TARGET/mysys.lib $DESTDIR/lib/opt/mysys_tls.lib
+
+# ----------------------------------------------------------------------
+# Copy the test directory
+# ----------------------------------------------------------------------
+
+mkdir -p $DESTDIR/mysql-test/include $DESTDIR/mysql-test/lib \
+ $DESTDIR/mysql-test/r $DESTDIR/mysql-test/std_data \
+ $DESTDIR/mysql-test/t
+cp mysql-test/mysql-test-run.pl $DESTDIR/mysql-test/
+cp mysql-test/README $DESTDIR/mysql-test/
+cp mysql-test/install_test_db.sh $DESTDIR/mysql-test/install_test_db
+cp mysql-test/include/*.inc $DESTDIR/mysql-test/include/
+cp mysql-test/lib/*.pl $DESTDIR/mysql-test/lib/
+cp mysql-test/lib/*.sql $DESTDIR/mysql-test/lib/
+cp mysql-test/r/*.require $DESTDIR/mysql-test/r/
+# Need this trick, or we get "argument list too long".
+ABS_DST=`pwd`/$DESTDIR
+(cd mysql-test/r/ && cp *.result $ABS_DST/mysql-test/r/)
+cp mysql-test/std_data/* $DESTDIR/mysql-test/std_data/
+cp mysql-test/t/*.opt $DESTDIR/mysql-test/t/
+cp mysql-test/t/*.sh $DESTDIR/mysql-test/t/
+cp mysql-test/t/*.slave-mi $DESTDIR/mysql-test/t/
+cp mysql-test/t/*.sql $DESTDIR/mysql-test/t/
+cp mysql-test/t/*.def $DESTDIR/mysql-test/t/
+(cd mysql-test/t/ && cp *.test $ABS_DST/mysql-test/t/)
+
+# Note that this will not copy "extra" if a soft link
+if [ -d mysql-test/extra ] ; then
+ mkdir -p $DESTDIR/mysql-test/extra
+ cp -pR mysql-test/extra/* $DESTDIR/mysql-test/extra/
+fi
+
+# ----------------------------------------------------------------------
+# Copy what could be usable in the "scripts" directory. Currently
+# only SQL files, others are bourne shell scripts or Perl scripts
+# not really usable on Windows.
+#
+# But to be nice to the few Cygwin users we might have in 5.0 we
+# continue to copy the stuff, but don't include it include it in
+# the WiX install.
+# ----------------------------------------------------------------------
+
+mkdir -p $DESTDIR/scripts
+
+# Uncomment and remove the for loop in 5.1
+#cp scripts/*.sql $DESTDIR/scripts/
+
+for i in `cd scripts && ls`; do \
+ if echo $i | grep -q '\.sh'; then \
+ cp scripts/$i $DESTDIR/scripts/`echo $i | sed -e 's/\.sh$//'`; \
+ elif [ $i = Makefile.am -o $i = Makefile.in -o -e scripts/$i.sh ] ; then \
+ : ; \
+ else \
+ cp scripts/$i $DESTDIR/scripts/$i; \
+ fi; \
+done
+
+cp -pR sql/share $DESTDIR/
+cp -pR sql-bench $DESTDIR/
+rm -f $DESTDIR/sql-bench/*.sh $DESTDIR/sql-bench/Makefile*
+
+# ----------------------------------------------------------------------
+# Copy other files specified on command line DEST=SOURCE
+# ----------------------------------------------------------------------
+
+for arg do
+ dst=`echo $arg | sed 's/=.*$//'`
+ src=`echo $arg | sed 's/^.*=//'`
+
+ if [ x"$dst" = x"" -o x"$src" = x"" ] ; then
+ echo "Invalid specification of what to copy"
+ usage
+ fi
+
+ mkdir -p `dirname $DESTDIR/$dst`
+ cp -pR "$src" $DESTDIR/$dst
+done
+
+# ----------------------------------------------------------------------
+# Finally creat the ZIP archive
+# ----------------------------------------------------------------------
+
+rm -f $NOINST_NAME.zip
+zip -r $NOINST_NAME.zip $DESTDIR
+rm -Rf $DESTDIR
diff --git a/server-tools/CMakeLists.txt b/server-tools/CMakeLists.txt
new file mode 100755
index 00000000000..1983d459ce2
--- /dev/null
+++ b/server-tools/CMakeLists.txt
@@ -0,0 +1,18 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+ADD_DEFINITIONS(-DMYSQL_SERVER -DMYSQL_INSTANCE_MANAGER)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/sql
+ ${PROJECT_SOURCE_DIR}/extra/yassl/include)
+
+ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instance.cc instance_map.cc
+ instance_options.cc listener.cc log.cc manager.cc messages.cc mysql_connection.cc
+ mysqlmanager.cc options.cc parse.cc parse_output.cc priv.cc protocol.cc
+ thread_registry.cc user_map.cc imservice.cpp windowsservice.cpp
+ user_management_commands.cc
+ ../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c
+ ../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
+ ../../libmysql/errmsg.c)
+
+ADD_DEPENDENCIES(mysqlmanager GenError)
+TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32)
diff --git a/server-tools/Makefile.am b/server-tools/Makefile.am
index ed316b9ac38..573bf07ccff 100644
--- a/server-tools/Makefile.am
+++ b/server-tools/Makefile.am
@@ -1 +1,2 @@
SUBDIRS= instance-manager
+DIST_SUBDIRS= instance-manager
diff --git a/server-tools/instance-manager/CMakeLists.txt b/server-tools/instance-manager/CMakeLists.txt
new file mode 100755
index 00000000000..fafc3df4108
--- /dev/null
+++ b/server-tools/instance-manager/CMakeLists.txt
@@ -0,0 +1,17 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+ADD_DEFINITIONS(-DMYSQL_SERVER -DMYSQL_INSTANCE_MANAGER)
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/sql
+ ${PROJECT_SOURCE_DIR}/extra/yassl/include)
+
+ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instance.cc instance_map.cc
+ instance_options.cc listener.cc log.cc manager.cc messages.cc mysql_connection.cc
+ mysqlmanager.cc options.cc parse.cc parse_output.cc priv.cc protocol.cc
+ thread_registry.cc user_map.cc IMService.cpp WindowsService.cpp
+ ../../sql/net_serv.cc ../../sql-common/pack.c ../../sql/password.c
+ ../../sql/sql_state.c ../../sql-common/client.c ../../libmysql/get_password.c
+ ../../libmysql/errmsg.c)
+
+ADD_DEPENDENCIES(mysqlmanager GenError)
+TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32)
diff --git a/server-tools/instance-manager/Makefile.am b/server-tools/instance-manager/Makefile.am
index 6b5d80a99af..b1d77506efa 100644
--- a/server-tools/instance-manager/Makefile.am
+++ b/server-tools/instance-manager/Makefile.am
@@ -18,7 +18,8 @@ INCLUDES= @ZLIB_INCLUDES@ -I$(top_srcdir)/include \
@openssl_includes@ -I$(top_builddir)/include
DEFS= -DMYSQL_INSTANCE_MANAGER -DMYSQL_SERVER
-
+EXTRA_DIST = IMService.cpp IMService.h WindowsService.cpp WindowsService.h \
+ CMakeLists.txt
# As all autoconf variables depend from ${prefix} and being resolved only when
# make is run, we can not put these defines to a header file (e.g. to
# default_options.h, generated from default_options.h.in)
diff --git a/sql-common/client.c b/sql-common/client.c
index 6819caddf35..fc483e7b4c7 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1514,7 +1514,6 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
mysql->options.ssl_ca= strdup_if_not_null(ca);
mysql->options.ssl_capath= strdup_if_not_null(capath);
mysql->options.ssl_cipher= strdup_if_not_null(cipher);
- mysql->options.ssl_verify_server_cert= FALSE; /* Off by default */
#endif /* HAVE_OPENSSL */
DBUG_RETURN(0);
}
@@ -1759,7 +1758,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db,
uint port, const char *unix_socket,ulong client_flag)
{
- char buff[NAME_LEN+USERNAME_LENGTH+100];
+ char buff[NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+100];
char *end,*host_info;
my_socket sock;
in_addr_t ip_addr;
@@ -2203,7 +2202,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
DBUG_PRINT("info", ("IO layer change done!"));
/* Verify server cert */
- if (mysql->options.ssl_verify_server_cert &&
+ if ((client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
ssl_verify_server_cert(mysql->net.vio, mysql->host))
{
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
@@ -2218,7 +2217,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
mysql->server_status, client_flag));
/* This needs to be changed as it's not useful with big packets */
if (user && user[0])
- strmake(end,user,USERNAME_LENGTH); /* Max user name */
+ strmake(end,user,USERNAME_BYTE_LENGTH); /* Max user name */
else
read_user_name((char*) end);
@@ -2248,7 +2247,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
/* Add database if needed */
if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB))
{
- end= strmake(end, db, NAME_LEN) + 1;
+ end= strmake(end, db, NAME_BYTE_LEN) + 1;
mysql->db= my_strdup(db,MYF(MY_WME));
db= 0;
}
@@ -2950,7 +2949,10 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
mysql->reconnect= *(my_bool *) arg;
break;
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
- mysql->options.ssl_verify_server_cert= *(my_bool *) arg;
+ if (!arg || test(*(uint*) arg))
+ mysql->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT;
+ else
+ mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
break;
default:
DBUG_RETURN(1);
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
new file mode 100755
index 00000000000..b01871872ce
--- /dev/null
+++ b/sql/CMakeLists.txt
@@ -0,0 +1,114 @@
+SET(CMAKE_CXX_FLAGS_DEBUG
+ "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi")
+SET(CMAKE_C_FLAGS_DEBUG
+ "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR /Zi")
+SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /MAP /MAPINFO:EXPORTS")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include
+ ${CMAKE_SOURCE_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/regex
+ ${CMAKE_SOURCE_DIR}/zlib
+ ${CMAKE_SOURCE_DIR}/bdb/build_win32
+ ${CMAKE_SOURCE_DIR}/bdb/dbinc)
+
+SET_SOURCE_FILES_PROPERTIES(${CMAKE_SOURCE_DIR}/sql/message.rc
+ ${CMAKE_SOURCE_DIR}/sql/message.h
+ ${CMAKE_SOURCE_DIR}/sql/sql_yacc.h
+ ${CMAKE_SOURCE_DIR}/sql/sql_yacc.cc
+ ${CMAKE_SOURCE_DIR}/include/mysql_version.h
+ ${CMAKE_SOURCE_DIR}/sql/lex_hash.h
+ ${PROJECT_SOURCE_DIR}/include/mysqld_error.h
+ ${PROJECT_SOURCE_DIR}/include/mysqld_ername.h
+ ${PROJECT_SOURCE_DIR}/include/sql_state.h
+ PROPERTIES GENERATED 1)
+
+ADD_DEFINITIONS(-DHAVE_INNOBASE -DMYSQL_SERVER
+ -D_CONSOLE -DHAVE_DLOPEN)
+
+ADD_EXECUTABLE(mysqld ../sql-common/client.c derror.cc des_key_file.cc
+ discover.cc ../libmysql/errmsg.c field.cc field_conv.cc
+ filesort.cc gstream.cc ha_blackhole.cc
+ ha_archive.cc ha_heap.cc ha_myisam.cc ha_myisammrg.cc
+ ha_innodb.cc ha_federated.cc ha_berkeley.cc ha_blackhole.cc
+ handler.cc hash_filo.cc hash_filo.h
+ hostname.cc init.cc item.cc item_buff.cc item_cmpfunc.cc
+ item_create.cc item_func.cc item_geofunc.cc item_row.cc
+ item_strfunc.cc item_subselect.cc item_sum.cc item_timefunc.cc
+ item_uniq.cc key.cc log.cc lock.cc log_event.cc message.rc
+ message.h mf_iocache.cc my_decimal.cc ../sql-common/my_time.c
+ ../myisammrg/myrg_rnext_same.c mysqld.cc net_serv.cc
+ nt_servc.cc nt_servc.h opt_range.cc opt_range.h opt_sum.cc
+ ../sql-common/pack.c parse_file.cc password.c procedure.cc
+ protocol.cc records.cc repl_failsafe.cc set_var.cc
+ slave.cc sp.cc sp_cache.cc sp_head.cc sp_pcontext.cc
+ sp_rcontext.cc spatial.cc sql_acl.cc sql_analyse.cc sql_base.cc
+ sql_cache.cc sql_class.cc sql_client.cc sql_crypt.cc sql_crypt.h
+ sql_cursor.cc sql_db.cc sql_delete.cc sql_derived.cc sql_do.cc
+ sql_error.cc sql_handler.cc sql_help.cc sql_insert.cc sql_lex.cc
+ sql_list.cc sql_load.cc sql_manager.cc sql_map.cc sql_parse.cc
+ sql_prepare.cc sql_rename.cc
+ sql_repl.cc sql_select.cc sql_show.cc sql_state.c sql_string.cc
+ sql_table.cc sql_test.cc sql_trigger.cc sql_udf.cc sql_union.cc
+ sql_update.cc sql_view.cc strfunc.cc table.cc thr_malloc.cc
+ time.cc tztime.cc uniques.cc unireg.cc
+ ../sql-common/my_user.c
+ sql_locale.cc
+ ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
+ ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
+ ${PROJECT_SOURCE_DIR}/include/mysqld_error.h
+ ${PROJECT_SOURCE_DIR}/include/mysqld_ername.h
+ ${PROJECT_SOURCE_DIR}/include/sql_state.h
+ ${PROJECT_SOURCE_DIR}/include/mysql_version.h
+ ${PROJECT_SOURCE_DIR}/sql/lex_hash.h)
+
+TARGET_LINK_LIBRARIES(mysqld heap myisam myisammrg mysys yassl zlib dbug yassl
+ taocrypt strings vio regex wsock32)
+
+IF(WITH_EXAMPLE_STORAGE_ENGINE)
+ TARGET_LINK_LIBRARIES(mysqld example)
+ENDIF(WITH_EXAMPLE_STORAGE_ENGINE)
+
+IF(WITH_INNOBASE_STORAGE_ENGINE)
+ TARGET_LINK_LIBRARIES(mysqld innobase)
+ENDIF(WITH_INNOBASE_STORAGE_ENGINE)
+
+IF(WITH_BERKELEY_STORAGE_ENGINE)
+ TARGET_LINK_LIBRARIES(mysqld bdb)
+ENDIF(WITH_BERKELEY_STORAGE_ENGINE)
+
+
+ADD_DEPENDENCIES(mysqld GenError)
+
+# Sql Parser custom command
+ADD_CUSTOM_COMMAND(
+ SOURCE ${PROJECT_SOURCE_DIR}/sql/sql_yacc.yy
+ OUTPUT ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
+ COMMAND bison.exe ARGS -y -p MYSQL --defines=sql_yacc.h
+ --output=sql_yacc.cc sql_yacc.yy
+ DEPENDS ${PROJECT_SOURCE_DIR}/sql/sql_yacc.yy)
+
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
+ COMMAND echo
+ DEPENDS ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
+)
+
+# Windows message file
+ADD_CUSTOM_COMMAND(
+ SOURCE ${PROJECT_SOURCE_DIR}/sql/message.mc
+ OUTPUT message.rc message.h
+ COMMAND mc ARGS ${PROJECT_SOURCE_DIR}/sql/message.mc
+ DEPENDS ${PROJECT_SOURCE_DIR}/sql/message.mc)
+
+# Gen_lex_hash
+ADD_EXECUTABLE(gen_lex_hash gen_lex_hash.cc)
+TARGET_LINK_LIBRARIES(gen_lex_hash dbug mysqlclient wsock32)
+GET_TARGET_PROPERTY(GEN_LEX_HASH_EXE gen_lex_hash LOCATION)
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${PROJECT_SOURCE_DIR}/sql/lex_hash.h
+ COMMAND ${GEN_LEX_HASH_EXE} ARGS > lex_hash.h
+ DEPENDS ${GEN_LEX_HASH_EXE}
+)
+
+ADD_DEPENDENCIES(mysqld gen_lex_hash)
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 8428d6401b5..98c8fe784eb 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -116,9 +116,11 @@ DEFS = -DMYSQL_SERVER \
@DEFS@
BUILT_SOURCES = sql_yacc.cc sql_yacc.h lex_hash.h
-EXTRA_DIST = $(BUILT_SOURCES)
-DISTCLEANFILES = lex_hash.h
-AM_YFLAGS = -d
+EXTRA_DIST = $(BUILT_SOURCES) nt_servc.cc nt_servc.h \
+ message.mc examples/CMakeLists.txt CMakeLists.txt
+DISTCLEANFILES = lex_hash.h sql_yacc.output
+
+AM_YFLAGS = -d --debug --verbose
mysql_tzinfo_to_sql.cc:
rm -f mysql_tzinfo_to_sql.cc
diff --git a/sql/examples/CMakeLists.txt b/sql/examples/CMakeLists.txt
new file mode 100755
index 00000000000..d3cc430ef40
--- /dev/null
+++ b/sql/examples/CMakeLists.txt
@@ -0,0 +1,11 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include
+ ${CMAKE_SOURCE_DIR}/regex)
+
+IF(WITH_EXAMPLE_STORAGE_ENGINE)
+ADD_LIBRARY(example ha_example.cc)
+ADD_DEPENDENCIES(example GenError)
+ENDIF(WITH_EXAMPLE_STORAGE_ENGINE)
diff --git a/sql/field.cc b/sql/field.cc
index 4fea6a085bb..4860f6ea3da 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6154,15 +6154,26 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table,
Field *new_field;
if (type() != MYSQL_TYPE_VAR_STRING || keep_type)
- return Field::new_field(root, new_table, keep_type);
+ new_field= Field::new_field(root, new_table, keep_type);
+ else
+ {
- /*
- Old VARCHAR field which should be modified to a VARCHAR on copy
- This is done to ensure that ALTER TABLE will convert old VARCHAR fields
- to now VARCHAR fields.
- */
- return new Field_varstring(field_length, maybe_null(),
- field_name, new_table, charset());
+ /*
+ Old VARCHAR field which should be modified to a VARCHAR on copy
+ This is done to ensure that ALTER TABLE will convert old VARCHAR fields
+ to now VARCHAR fields.
+ */
+ new_field= new Field_varstring(field_length, maybe_null(),
+ field_name, new_table, charset());
+ /*
+ Normally orig_table is different from table only if field was created
+ via ::new_field. Here we alter the type of field, so ::new_field is
+ not applicable. But we still need to preserve the original field
+ metadata for the client-server protocol.
+ */
+ new_field->orig_table= orig_table;
+ }
+ return new_field;
}
/****************************************************************************
diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc
index 7e0b178f7af..5a8bd48d699 100644
--- a/sql/gen_lex_hash.cc
+++ b/sql/gen_lex_hash.cc
@@ -442,13 +442,17 @@ int main(int argc,char **argv)
if (get_options(argc,(char **) argv))
exit(1);
+ /* Broken up to indicate that it's not advice to you, gentle reader. */
+ printf("/*\n\n Do " "not " "edit " "this " "file " "directly!\n\n*/\n");
+
printf("/* Copyright (C) 2001-2004 MySQL AB\n\
This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
and you are welcome to modify and redistribute it under the GPL license\n\
\n*/\n\n");
- printf("/* This code is generated by gen_lex_hash.cc that seeks for\
- a perfect\nhash function */\n\n");
+ /* Broken up to indicate that it's not advice to you, gentle reader. */
+ printf("/* Do " "not " "edit " "this " "file! This is generated by "
+ "gen_lex_hash.cc\nthat seeks for a perfect hash function */\n\n");
printf("#include \"lex.h\"\n\n");
calc_length();
@@ -468,6 +472,14 @@ static inline SYMBOL *get_hash_symbol(const char *s,\n\
{\n\
register uchar *hash_map;\n\
register const char *cur_str= s;\n\
+\n\
+ if (len == 0) {\n\
+ DBUG_PRINT(\"warning\", (\"get_hash_symbol() received a request for a zero-length symbol, which is probably a mistake.\"));\
+ return(NULL);\n\
+ }\n"
+);
+
+ printf("\
if (function){\n\
if (len>sql_functions_max_len) return 0;\n\
hash_map= sql_functions_map;\n\
@@ -498,7 +510,10 @@ static inline SYMBOL *get_hash_symbol(const char *s,\n\
cur_struct= uint4korr(hash_map+\n\
(((uint16)cur_struct + cur_char - first_char)*4));\n\
cur_str++;\n\
- }\n\
+ }\n"
+);
+
+ printf("\
}else{\n\
if (len>symbols_max_len) return 0;\n\
hash_map= symbols_map;\n\
diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc
index 0fb0bc9f791..bb94a99e700 100644
--- a/sql/ha_archive.cc
+++ b/sql/ha_archive.cc
@@ -614,7 +614,7 @@ int ha_archive::create(const char *name, TABLE *table_arg,
error= my_errno;
goto error;
}
- if ((archive= gzdopen(create_file, "wb")) == NULL)
+ if ((archive= gzdopen(dup(create_file), "wb")) == NULL)
{
error= errno;
goto error2;
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 5d6fe5f984f..9c4a2c20ca0 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -35,6 +35,7 @@
// options from from mysqld.cc
extern my_bool opt_ndb_optimized_node_selection;
extern const char *opt_ndbcluster_connectstring;
+extern ulong opt_ndb_cache_check_time;
// Default value for parallelism
static const int parallelism= 0;
@@ -3525,7 +3526,14 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
if (lock_type != F_UNLCK)
{
DBUG_PRINT("info", ("lock_type != F_UNLCK"));
- if (!thd->transaction.on)
+ if (thd->lex->sql_command == SQLCOM_LOAD)
+ {
+ m_transaction_on= FALSE;
+ /* Would be simpler if has_transactions() didn't always say "yes" */
+ thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
+ thd->no_trans_update= TRUE;
+ }
+ else if (!thd->transaction.on)
m_transaction_on= FALSE;
else
m_transaction_on= thd->variables.ndb_use_transactions;
@@ -4175,10 +4183,15 @@ static void ndb_set_fragmentation(NDBTAB &tab, TABLE *form, uint pk_length)
acc_row_size+= 4 + /*safety margin*/ 4;
#endif
ulonglong acc_fragment_size= 512*1024*1024;
+ /*
+ * if not --with-big-tables then max_rows is ulong
+ * the warning in this case is misleading though
+ */
+ ulonglong big_max_rows = (ulonglong)max_rows;
#if MYSQL_VERSION_ID >= 50100
- no_fragments= (max_rows*acc_row_size)/acc_fragment_size+1;
+ no_fragments= (big_max_rows*acc_row_size)/acc_fragment_size+1;
#else
- no_fragments= ((max_rows*acc_row_size)/acc_fragment_size+1
+ no_fragments= ((big_max_rows*acc_row_size)/acc_fragment_size+1
+1/*correct rounding*/)/2;
#endif
}
@@ -5238,6 +5251,7 @@ bool ndbcluster_init()
pthread_cond_init(&COND_ndb_util_thread, NULL);
+ ndb_cache_check_time = opt_ndb_cache_check_time;
// Create utility thread
pthread_t tmp;
if (pthread_create(&tmp, &connection_attrib, ndb_util_thread_func, 0))
diff --git a/sql/item.cc b/sql/item.cc
index 96b20d0f0bb..34e5e2da165 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -422,6 +422,49 @@ void Item::rename(char *new_name)
}
+/*
+ Traverse item tree possibly transforming it (replacing items).
+
+ SYNOPSIS
+ Item::transform()
+ transformer functor that performs transformation of a subtree
+ arg opaque argument passed to the functor
+
+ DESCRIPTION
+ This function is designed to ease transformation of Item trees.
+
+ Re-execution note: every such transformation is registered for
+ rollback by THD::change_item_tree() and is rolled back at the end
+ of execution by THD::rollback_item_tree_changes().
+
+ Therefore:
+
+ - this function can not be used at prepared statement prepare
+ (in particular, in fix_fields!), as only permanent
+ transformation of Item trees are allowed at prepare.
+
+ - the transformer function shall allocate new Items in execution
+ memory root (thd->mem_root) and not anywhere else: allocated
+ items will be gone in the end of execution.
+
+ If you don't need to transform an item tree, but only traverse
+ it, please use Item::walk() instead.
+
+
+ RETURN VALUE
+ Returns pointer to the new subtree root. THD::change_item_tree()
+ should be called for it if transformation took place, i.e. if a
+ pointer to newly allocated item is returned.
+*/
+
+Item* Item::transform(Item_transformer transformer, byte *arg)
+{
+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
+
+ return (this->*transformer)(arg);
+}
+
+
Item_ident::Item_ident(Name_resolution_context *context_arg,
const char *db_name_arg,const char *table_name_arg,
const char *field_name_arg)
@@ -3802,11 +3845,11 @@ Item *Item_field::equal_fields_propagator(byte *arg)
See comments in Arg_comparator::set_compare_func() for details
*/
-Item *Item_field::set_no_const_sub(byte *arg)
+bool Item_field::set_no_const_sub(byte *arg)
{
if (field->charset() != &my_charset_bin)
no_const_subst=1;
- return this;
+ return FALSE;
}
@@ -5308,6 +5351,31 @@ int Item_default_value::save_in_field(Field *field_arg, bool no_conversions)
}
+/*
+ This method like the walk method traverses the item tree, but at the
+ same time it can replace some nodes in the tree
+*/
+
+Item *Item_default_value::transform(Item_transformer transformer, byte *args)
+{
+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
+
+ Item *new_item= arg->transform(transformer, args);
+ if (!new_item)
+ return 0;
+
+ /*
+ THD::change_item_tree() should be called only if the tree was
+ really transformed, i.e. when a new item has been created.
+ Otherwise we'll be allocating a lot of unnecessary memory for
+ change records at each execution.
+ */
+ if (arg != new_item)
+ current_thd->change_item_tree(&arg, new_item);
+ return (this->*transformer)(args);
+}
+
+
bool Item_insert_value::eq(const Item *item, bool binary_cmp) const
{
return item->type() == INSERT_VALUE_ITEM &&
diff --git a/sql/item.h b/sql/item.h
index e3df0fdf389..58a3bfd0d75 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -734,10 +734,7 @@ public:
return (this->*processor)(arg);
}
- virtual Item* transform(Item_transformer transformer, byte *arg)
- {
- return (this->*transformer)(arg);
- }
+ virtual Item* transform(Item_transformer transformer, byte *arg);
virtual void traverse_cond(Cond_traverser traverser,
void *arg, traverse_order order)
@@ -755,7 +752,7 @@ public:
virtual bool is_expensive_processor(byte *arg) { return 0; }
virtual Item *equal_fields_propagator(byte * arg) { return this; }
- virtual Item *set_no_const_sub(byte *arg) { return this; }
+ virtual bool set_no_const_sub(byte *arg) { return FALSE; }
virtual Item *replace_equal_field(byte * arg) { return this; }
/*
@@ -1255,7 +1252,7 @@ public:
}
Item_equal *find_item_equal(COND_EQUAL *cond_equal);
Item *equal_fields_propagator(byte *arg);
- Item *set_no_const_sub(byte *arg);
+ bool set_no_const_sub(byte *arg);
Item *replace_equal_field(byte *arg);
inline uint32 max_disp_length() { return field->max_length(); }
Item_field *filed_for_view_update() { return this; }
@@ -2116,18 +2113,7 @@ public:
(this->*processor)(args);
}
- /*
- This method like the walk method traverses the item tree, but
- at the same time it can replace some nodes in the tree
- */
- Item *transform(Item_transformer transformer, byte *args)
- {
- Item *new_item= arg->transform(transformer, args);
- if (!new_item)
- return 0;
- arg= new_item;
- return (this->*transformer)(args);
- }
+ Item *transform(Item_transformer transformer, byte *args);
};
/*
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index dbf380232c4..919a23ed65d 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -511,8 +511,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
which would be transformed to:
WHERE col= 'j'
*/
- (*a)->transform(&Item::set_no_const_sub, (byte*) 0);
- (*b)->transform(&Item::set_no_const_sub, (byte*) 0);
+ (*a)->walk(&Item::set_no_const_sub, (byte*) 0);
+ (*b)->walk(&Item::set_no_const_sub, (byte*) 0);
}
break;
}
@@ -2765,6 +2765,8 @@ bool Item_cond::walk(Item_processor processor, byte *arg)
Item *Item_cond::transform(Item_transformer transformer, byte *arg)
{
+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
+
List_iterator<Item> li(list);
Item *item;
while ((item= li++))
@@ -2772,8 +2774,15 @@ Item *Item_cond::transform(Item_transformer transformer, byte *arg)
Item *new_item= item->transform(transformer, arg);
if (!new_item)
return 0;
+
+ /*
+ THD::change_item_tree() should be called only if the tree was
+ really transformed, i.e. when a new item has been created.
+ Otherwise we'll be allocating a lot of unnecessary memory for
+ change records at each execution.
+ */
if (new_item != item)
- li.replace(new_item);
+ current_thd->change_item_tree(li.ref(), new_item);
}
return Item_func::transform(transformer, arg);
}
@@ -4018,6 +4027,8 @@ bool Item_equal::walk(Item_processor processor, byte *arg)
Item *Item_equal::transform(Item_transformer transformer, byte *arg)
{
+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
+
List_iterator<Item_field> it(fields);
Item *item;
while ((item= it++))
@@ -4025,8 +4036,15 @@ Item *Item_equal::transform(Item_transformer transformer, byte *arg)
Item *new_item= item->transform(transformer, arg);
if (!new_item)
return 0;
+
+ /*
+ THD::change_item_tree() should be called only if the tree was
+ really transformed, i.e. when a new item has been created.
+ Otherwise we'll be allocating a lot of unnecessary memory for
+ change records at each execution.
+ */
if (new_item != item)
- it.replace((Item_field *) new_item);
+ current_thd->change_item_tree((Item **) it.ref(), new_item);
}
return Item_func::transform(transformer, arg);
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index e699669dcc5..579e7f88ee6 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -258,6 +258,8 @@ void Item_func::traverse_cond(Cond_traverser traverser,
Item *Item_func::transform(Item_transformer transformer, byte *argument)
{
+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
+
if (arg_count)
{
Item **arg,**arg_end;
@@ -266,6 +268,13 @@ Item *Item_func::transform(Item_transformer transformer, byte *argument)
Item *new_item= (*arg)->transform(transformer, argument);
if (!new_item)
return 0;
+
+ /*
+ THD::change_item_tree() should be called only if the tree was
+ really transformed, i.e. when a new item has been created.
+ Otherwise we'll be allocating a lot of unnecessary memory for
+ change records at each execution.
+ */
if (*arg != new_item)
current_thd->change_item_tree(arg, new_item);
}
diff --git a/sql/item_row.cc b/sql/item_row.cc
index f5c8d511025..d7591b9865d 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -154,12 +154,22 @@ bool Item_row::walk(Item_processor processor, byte *arg)
Item *Item_row::transform(Item_transformer transformer, byte *arg)
{
+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
+
for (uint i= 0; i < arg_count; i++)
{
Item *new_item= items[i]->transform(transformer, arg);
if (!new_item)
return 0;
- items[i]= new_item;
+
+ /*
+ THD::change_item_tree() should be called only if the tree was
+ really transformed, i.e. when a new item has been created.
+ Otherwise we'll be allocating a lot of unnecessary memory for
+ change records at each execution.
+ */
+ if (items[i] != new_item)
+ current_thd->change_item_tree(&items[i], new_item);
}
return (this->*transformer)(arg);
}
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 0cd0ffcc38b..2acd1371ce5 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -124,6 +124,7 @@ String *Item_func_md5::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
String * sptr= args[0]->val_str(str);
+ str->set_charset(&my_charset_bin);
if (sptr)
{
my_MD5_CTX context;
@@ -170,6 +171,7 @@ String *Item_func_sha::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
String * sptr= args[0]->val_str(str);
+ str->set_charset(&my_charset_bin);
if (sptr) /* If we got value different from NULL */
{
SHA1_CONTEXT context; /* Context used to generate SHA1 hash */
@@ -1605,7 +1607,7 @@ String *Item_func_encrypt::val_str(String *str)
null_value= 1;
return 0;
}
- str->set(tmp,(uint) strlen(tmp),res->charset());
+ str->set(tmp, (uint) strlen(tmp), &my_charset_bin);
str->copy();
pthread_mutex_unlock(&LOCK_crypt);
return str;
@@ -2041,7 +2043,7 @@ String *Item_func_make_set::val_str(String *str)
return &my_empty_string;
result= &tmp_str;
}
- if (tmp_str.append(',') || tmp_str.append(*res))
+ if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res))
return &my_empty_string;
}
}
@@ -2051,6 +2053,26 @@ String *Item_func_make_set::val_str(String *str)
}
+Item *Item_func_make_set::transform(Item_transformer transformer, byte *arg)
+{
+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
+
+ Item *new_item= item->transform(transformer, arg);
+ if (!new_item)
+ return 0;
+
+ /*
+ THD::change_item_tree() should be called only if the tree was
+ really transformed, i.e. when a new item has been created.
+ Otherwise we'll be allocating a lot of unnecessary memory for
+ change records at each execution.
+ */
+ if (item != new_item)
+ current_thd->change_item_tree(&item, new_item);
+ return Item_str_func::transform(transformer, arg);
+}
+
+
void Item_func_make_set::print(String *str)
{
str->append(STRING_WITH_LEN("make_set("));
@@ -2699,8 +2721,12 @@ String* Item_func_export_set::val_str(String* str)
}
break;
case 3:
- sep_buf.set(STRING_WITH_LEN(","), default_charset());
- sep = &sep_buf;
+ {
+ /* errors is not checked - assume "," can always be converted */
+ uint errors;
+ sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, collation.collation, &errors);
+ sep = &sep_buf;
+ }
break;
default:
DBUG_ASSERT(0); // cannot happen
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index eae7272835d..528180b803d 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -43,7 +43,10 @@ class Item_func_md5 :public Item_str_func
{
String tmp_value;
public:
- Item_func_md5(Item *a) :Item_str_func(a) {}
+ Item_func_md5(Item *a) :Item_str_func(a)
+ {
+ collation.set(&my_charset_bin);
+ }
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "md5"; }
@@ -53,7 +56,10 @@ public:
class Item_func_sha :public Item_str_func
{
public:
- Item_func_sha(Item *a) :Item_str_func(a) {}
+ Item_func_sha(Item *a) :Item_str_func(a)
+ {
+ collation.set(&my_charset_bin);
+ }
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "sha"; }
@@ -325,9 +331,21 @@ public:
class Item_func_encrypt :public Item_str_func
{
String tmp_value;
+
+ /* Encapsulate common constructor actions */
+ void constructor_helper()
+ {
+ collation.set(&my_charset_bin);
+ }
public:
- Item_func_encrypt(Item *a) :Item_str_func(a) {}
- Item_func_encrypt(Item *a, Item *b): Item_str_func(a,b) {}
+ Item_func_encrypt(Item *a) :Item_str_func(a)
+ {
+ constructor_helper();
+ }
+ Item_func_encrypt(Item *a, Item *b): Item_str_func(a,b)
+ {
+ constructor_helper();
+ }
String *val_str(String *);
void fix_length_and_dec() { maybe_null=1; max_length = 13; }
const char *func_name() const { return "encrypt"; }
@@ -475,14 +493,7 @@ public:
return item->walk(processor, arg) ||
Item_str_func::walk(processor, arg);
}
- Item *transform(Item_transformer transformer, byte *arg)
- {
- Item *new_item= item->transform(transformer, arg);
- if (!new_item)
- return 0;
- item= new_item;
- return Item_str_func::transform(transformer, arg);
- }
+ Item *transform(Item_transformer transformer, byte *arg);
void print(String *str);
};
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 0d2a5b3b080..bcd8270e52f 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -290,7 +290,9 @@ Item_sum::Item_sum(THD *thd, Item_sum *item):
void Item_sum::mark_as_sum_func()
{
- current_thd->lex->current_select->with_sum_func= 1;
+ SELECT_LEX *cur_select= current_thd->lex->current_select;
+ cur_select->n_sum_items++;
+ cur_select->with_sum_func= 1;
with_sum_func= 1;
}
diff --git a/sql/lock.cc b/sql/lock.cc
index 97a080c5634..90ddcc957a2 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -854,6 +854,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
TABLE *table;
char key[MAX_DBKEY_LENGTH];
char *db= table_list->db;
+ int table_in_key_offset;
uint key_length;
HASH_SEARCH_STATE state;
DBUG_ENTER("lock_table_name");
@@ -861,8 +862,9 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
safe_mutex_assert_owner(&LOCK_open);
- key_length=(uint) (strmov(strmov(key,db)+1,table_list->table_name)
- -key)+ 1;
+ table_in_key_offset= strmov(key, db) - key + 1;
+ key_length= (uint)(strmov(key + table_in_key_offset, table_list->table_name)
+ - key) + 1;
/* Only insert the table if we haven't insert it already */
@@ -883,6 +885,7 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
table->s= &table->share_not_to_be_used;
memcpy((table->s->table_cache_key= (char*) (table+1)), key, key_length);
table->s->db= table->s->table_cache_key;
+ table->s->table_name= table->s->table_cache_key + table_in_key_offset;
table->s->key_length=key_length;
table->in_use=thd;
table->locked_by_name=1;
diff --git a/sql/log.cc b/sql/log.cc
index ebd1d10d8b7..1cd01865f9f 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -723,13 +723,18 @@ shutdown the MySQL server and restart it.", name, errno);
int MYSQL_LOG::get_current_log(LOG_INFO* linfo)
{
pthread_mutex_lock(&LOCK_log);
+ int ret = raw_get_current_log(linfo);
+ pthread_mutex_unlock(&LOCK_log);
+ return ret;
+}
+
+int MYSQL_LOG::raw_get_current_log(LOG_INFO* linfo)
+{
strmake(linfo->log_file_name, log_file_name, sizeof(linfo->log_file_name)-1);
linfo->pos = my_b_tell(&log_file);
- pthread_mutex_unlock(&LOCK_log);
return 0;
}
-
/*
Move all data up in a file in an filename index file
@@ -2385,6 +2390,12 @@ void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
void
*/
+#ifdef EMBEDDED_LIBRARY
+void vprint_msg_to_log(enum loglevel level __attribute__((unused)),
+ const char *format __attribute__((unused)),
+ va_list argsi __attribute__((unused)))
+{}
+#else /*!EMBEDDED_LIBRARY*/
void vprint_msg_to_log(enum loglevel level, const char *format, va_list args)
{
char buff[1024];
@@ -2400,6 +2411,7 @@ void vprint_msg_to_log(enum loglevel level, const char *format, va_list args)
DBUG_VOID_RETURN;
}
+#endif /*EMBEDDED_LIBRARY*/
void sql_print_error(const char *format, ...)
diff --git a/sql/message.mc b/sql/message.mc
new file mode 100644
index 00000000000..a1a7c8cff7e
--- /dev/null
+++ b/sql/message.mc
@@ -0,0 +1,8 @@
+MessageId = 100
+Severity = Error
+Facility = Application
+SymbolicName = MSG_DEFAULT
+Language = English
+%1For more information, see Help and Support Center at http://www.mysql.com.
+
+
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 3178569abc6..d73b1f1aac0 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -566,6 +566,8 @@ void get_default_definer(THD *thd, LEX_USER *definer);
LEX_USER *create_default_definer(THD *thd);
LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
LEX_USER *get_current_user(THD *thd, LEX_USER *user);
+bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str,
+ const char *err_msg, uint max_length);
enum enum_mysql_completiontype {
ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
@@ -1511,6 +1513,9 @@ void free_list(I_List <i_string> *list);
/* sql_yacc.cc */
extern int MYSQLparse(void *thd);
+#ifndef DBUG_OFF
+extern void turn_parser_debug_on();
+#endif
/* frm_crypt.cc */
#ifdef HAVE_CRYPTED_FRM
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 5ef98eded95..075a3851dbd 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2392,10 +2392,8 @@ static int my_message_sql(uint error, const char *str, myf MyFlags)
if ((thd= current_thd))
{
if (thd->spcont &&
- thd->spcont->find_handler(error, MYSQL_ERROR::WARN_LEVEL_ERROR))
+ thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
{
- if (! thd->spcont->found_handler_here())
- thd->net.report_error= 1; /* Make "select" abort correctly */
DBUG_RETURN(0);
}
@@ -7045,10 +7043,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
}
switch (method-1) {
case 0:
- method_conv= MI_STATS_METHOD_NULLS_EQUAL;
+ method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
break;
case 1:
- method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
+ method_conv= MI_STATS_METHOD_NULLS_EQUAL;
break;
case 2:
method_conv= MI_STATS_METHOD_IGNORE_NULLS;
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index cf9dc6e3f60..1601f7e5177 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -96,8 +96,11 @@ extern uint test_flags;
extern ulong bytes_sent, bytes_received, net_big_packet_count;
extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
#ifndef MYSQL_INSTANCE_MANAGER
-extern void query_cache_insert(NET *net, const char *packet, ulong length);
+#ifdef HAVE_QUERY_CACHE
#define USE_QUERY_CACHE
+extern void query_cache_init_query(NET *net);
+extern void query_cache_insert(NET *net, const char *packet, ulong length);
+#endif // HAVE_QUERY_CACHE
#define update_statistics(A) A
#endif /* MYSQL_INSTANCE_MANGER */
#endif /* defined(MYSQL_SERVER) && !defined(MYSQL_INSTANCE_MANAGER) */
@@ -133,7 +136,11 @@ my_bool my_net_init(NET *net, Vio* vio)
net->compress=0; net->reading_or_writing=0;
net->where_b = net->remain_in_buf=0;
net->last_errno=0;
- net->query_cache_query=0;
+#ifdef USE_QUERY_CACHE
+ query_cache_init_query(net);
+#else
+ net->query_cache_query= 0;
+#endif
net->report_error= 0;
if (vio != 0) /* If real connection */
@@ -552,10 +559,8 @@ net_real_write(NET *net,const char *packet,ulong len)
my_bool net_blocking = vio_is_blocking(net->vio);
DBUG_ENTER("net_real_write");
-#if defined(MYSQL_SERVER) && defined(HAVE_QUERY_CACHE) \
- && !defined(MYSQL_INSTANCE_MANAGER)
- if (net->query_cache_query != 0)
- query_cache_insert(net, packet, len);
+#if defined(MYSQL_SERVER) && defined(USE_QUERY_CACHE)
+ query_cache_insert(net, packet, len);
#endif
if (net->error == 2)
@@ -855,7 +860,7 @@ my_real_read(NET *net, ulong *complen)
#endif /* EXTRA_DEBUG */
}
#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
- if (vio_should_retry(net->vio))
+ if (vio_errno(net->vio) == SOCKET_EINTR)
{
DBUG_PRINT("warning",("Interrupted read. Retrying..."));
continue;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 71ba63dcf98..6189d0412b3 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -4129,6 +4129,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
MEM_ROOT *alloc= param->mem_root;
char *str;
ulong orig_sql_mode;
+ int err;
DBUG_ENTER("get_mm_leaf");
/*
@@ -4280,7 +4281,13 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
(field->type() == FIELD_TYPE_DATE ||
field->type() == FIELD_TYPE_DATETIME))
field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
- if (value->save_in_field_no_warnings(field, 1) < 0)
+ err= value->save_in_field_no_warnings(field, 1);
+ if (err > 0 && field->cmp_type() != value->result_type())
+ {
+ tree= 0;
+ goto end;
+ }
+ if (err < 0)
{
field->table->in_use->variables.sql_mode= orig_sql_mode;
/* This happens when we try to insert a NULL field in a not null column */
diff --git a/sql/protocol.cc b/sql/protocol.cc
index f4efb8004ee..5de24ebdcb3 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -53,8 +53,18 @@ bool Protocol_prep::net_store_data(const char *from, uint length)
}
- /* Send a error string to client */
+/*
+ Send a error string to client
+
+ Design note:
+ net_printf_error and net_send_error are low-level functions
+ that shall be used only when a new connection is being
+ established or at server startup.
+ For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
+ critical that every error that can be intercepted is issued in one
+ place only, my_message_sql.
+*/
void net_send_error(THD *thd, uint sql_errno, const char *err)
{
NET *net= &thd->net;
@@ -64,19 +74,15 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
err ? err : net->last_error[0] ?
net->last_error : "NULL"));
+ DBUG_ASSERT(!thd->spcont);
+
if (net && net->no_send_error)
{
thd->clear_error();
DBUG_PRINT("info", ("sending error messages prohibited"));
DBUG_VOID_RETURN;
}
- if (thd->spcont && thd->spcont->find_handler(sql_errno,
- MYSQL_ERROR::WARN_LEVEL_ERROR))
- {
- if (! thd->spcont->found_handler_here())
- thd->net.report_error= 1; /* Make "select" abort correctly */
- DBUG_VOID_RETURN;
- }
+
thd->query_error= 1; // needed to catch query errors during replication
if (!err)
{
@@ -117,6 +123,15 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
Write error package and flush to client
It's a little too low level, but I don't want to use another buffer for
this
+
+ Design note:
+
+ net_printf_error and net_send_error are low-level functions
+ that shall be used only when a new connection is being
+ established or at server startup.
+ For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
+ critical that every error that can be intercepted is issued in one
+ place only, my_message_sql.
*/
void
@@ -136,6 +151,8 @@ net_printf_error(THD *thd, uint errcode, ...)
DBUG_ENTER("net_printf_error");
DBUG_PRINT("enter",("message: %u",errcode));
+ DBUG_ASSERT(!thd->spcont);
+
if (net && net->no_send_error)
{
thd->clear_error();
@@ -143,13 +160,6 @@ net_printf_error(THD *thd, uint errcode, ...)
DBUG_VOID_RETURN;
}
- if (thd->spcont && thd->spcont->find_handler(errcode,
- MYSQL_ERROR::WARN_LEVEL_ERROR))
- {
- if (! thd->spcont->found_handler_here())
- thd->net.report_error= 1; /* Make "select" abort correctly */
- DBUG_VOID_RETURN;
- }
thd->query_error= 1; // needed to catch query errors during replication
#ifndef EMBEDDED_LIBRARY
query_cache_abort(net); // Safety
diff --git a/sql/set_var.cc b/sql/set_var.cc
index b61f6d58347..c667e2f2bcc 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -870,8 +870,8 @@ struct show_var_st init_vars[]= {
{"have_geometry", (char*) &have_geometry, SHOW_HAVE},
{"have_innodb", (char*) &have_innodb, SHOW_HAVE},
{"have_isam", (char*) &have_isam, SHOW_HAVE},
- {"have_ndbcluster", (char*) &have_ndbcluster, SHOW_HAVE},
{"have_merge_engine", (char*) &have_merge_db, SHOW_HAVE},
+ {"have_ndbcluster", (char*) &have_ndbcluster, SHOW_HAVE},
{"have_openssl", (char*) &have_openssl, SHOW_HAVE},
{"have_query_cache", (char*) &have_query_cache, SHOW_HAVE},
{"have_raid", (char*) &have_raid, SHOW_HAVE},
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index e90f54608e1..d10f66e3878 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5623,3 +5623,9 @@ ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA
eng "Triggers can not be created on system tables"
ER_REMOVED_SPACES
eng "Leading spaces are removed from name '%s'"
+ER_USERNAME
+ eng "user name"
+ER_HOSTNAME
+ eng "host name"
+ER_WRONG_STRING_LENGTH
+ eng "String '%-.70s' is too long for %s (should be no longer than %d)"
diff --git a/sql/slave.h b/sql/slave.h
index c355f7172a9..dee134aaa0c 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -406,7 +406,7 @@ typedef struct st_master_info
/* the variables below are needed because we can change masters on the fly */
char master_log_name[FN_REFLEN];
char host[HOSTNAME_LENGTH+1];
- char user[USERNAME_LENGTH+1];
+ char user[USERNAME_BYTE_LENGTH+1];
char password[MAX_PASSWORD_LENGTH+1];
my_bool ssl; // enables use of SSL connection if true
char ssl_ca[FN_REFLEN], ssl_capath[FN_REFLEN], ssl_cert[FN_REFLEN];
diff --git a/sql/sp.cc b/sql/sp.cc
index b7bf049cb1d..63175b110fa 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -404,16 +404,16 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
{
LEX *old_lex= thd->lex, newlex;
String defstr;
- char old_db_buf[NAME_LEN+1];
+ char old_db_buf[NAME_BYTE_LEN+1];
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
bool dbchanged;
ulong old_sql_mode= thd->variables.sql_mode;
ha_rows old_select_limit= thd->variables.select_limit;
sp_rcontext *old_spcont= thd->spcont;
- char definer_user_name_holder[USERNAME_LENGTH + 1];
+ char definer_user_name_holder[USERNAME_BYTE_LENGTH + 1];
LEX_STRING_WITH_INIT definer_user_name(definer_user_name_holder,
- USERNAME_LENGTH);
+ USERNAME_BYTE_LENGTH);
char definer_host_name_holder[HOSTNAME_LENGTH + 1];
LEX_STRING_WITH_INIT definer_host_name(definer_host_name_holder,
@@ -511,7 +511,7 @@ db_create_routine(THD *thd, int type, sp_head *sp)
int ret;
TABLE *table;
char definer[USER_HOST_BUFF_SIZE];
- char old_db_buf[NAME_LEN+1];
+ char old_db_buf[NAME_BYTE_LEN+1];
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
bool dbchanged;
DBUG_ENTER("db_create_routine");
@@ -1006,6 +1006,12 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
}
DBUG_RETURN(sp->m_first_free_instance);
}
+ /*
+ Actually depth could be +1 than the actual value in case a SP calls
+ SHOW CREATE PROCEDURE. Hence, the linked list could hold up to one more
+ instance.
+ */
+
level= sp->m_last_cached_sp->m_recursion_level + 1;
if (level > depth)
{
@@ -1175,19 +1181,22 @@ sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics)
int
sp_show_create_procedure(THD *thd, sp_name *name)
{
+ int ret= SP_KEY_NOT_FOUND;
sp_head *sp;
DBUG_ENTER("sp_show_create_procedure");
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
+ /*
+ Increase the recursion limit for this statement. SHOW CREATE PROCEDURE
+ does not do actual recursion.
+ */
+ thd->variables.max_sp_recursion_depth++;
if ((sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name,
&thd->sp_proc_cache, FALSE)))
- {
- int ret= sp->show_create_procedure(thd);
+ ret= sp->show_create_procedure(thd);
- DBUG_RETURN(ret);
- }
-
- DBUG_RETURN(SP_KEY_NOT_FOUND);
+ thd->variables.max_sp_recursion_depth--;
+ DBUG_RETURN(ret);
}
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index eec6e0fc3cd..e5b0b1e606e 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -230,6 +230,12 @@ sp_get_flags_for_command(LEX *lex)
else
flags= sp_head::HAS_COMMIT_OR_ROLLBACK;
break;
+ case SQLCOM_FLUSH:
+ flags= sp_head::HAS_SQLCOM_FLUSH;
+ break;
+ case SQLCOM_RESET:
+ flags= sp_head::HAS_SQLCOM_RESET;
+ break;
case SQLCOM_CREATE_INDEX:
case SQLCOM_CREATE_DB:
case SQLCOM_CREATE_VIEW:
@@ -918,7 +924,7 @@ bool
sp_head::execute(THD *thd)
{
DBUG_ENTER("sp_head::execute");
- char old_db_buf[NAME_LEN+1];
+ char old_db_buf[NAME_BYTE_LEN+1];
LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) };
bool dbchanged;
sp_rcontext *ctx;
@@ -1951,8 +1957,8 @@ sp_head::set_info(longlong created, longlong modified,
void
sp_head::set_definer(const char *definer, uint definerlen)
{
- char user_name_holder[USERNAME_LENGTH + 1];
- LEX_STRING_WITH_INIT user_name(user_name_holder, USERNAME_LENGTH);
+ char user_name_holder[USERNAME_BYTE_LENGTH + 1];
+ LEX_STRING_WITH_INIT user_name(user_name_holder, USERNAME_BYTE_LENGTH);
char host_name_holder[HOSTNAME_LENGTH + 1];
LEX_STRING_WITH_INIT host_name(host_name_holder, HOSTNAME_LENGTH);
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 4cd34bc9e20..7f2da69aa0c 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -115,7 +115,9 @@ public:
IS_INVOKED= 32, // Is set if this sp_head is being used
HAS_SET_AUTOCOMMIT_STMT= 64,// Is set if a procedure with 'set autocommit'
/* Is set if a procedure with COMMIT (implicit or explicit) | ROLLBACK */
- HAS_COMMIT_OR_ROLLBACK= 128
+ HAS_COMMIT_OR_ROLLBACK= 128,
+ HAS_SQLCOM_RESET= 2048,
+ HAS_SQLCOM_FLUSH= 4096
};
/* TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */
@@ -335,14 +337,16 @@ public:
my_error(ER_SP_NO_RETSET, MYF(0), where);
else if (m_flags & HAS_SET_AUTOCOMMIT_STMT)
my_error(ER_SP_CANT_SET_AUTOCOMMIT, MYF(0));
- else if (m_type != TYPE_ENUM_PROCEDURE &&
- (m_flags & sp_head::HAS_COMMIT_OR_ROLLBACK))
- {
+ else if (m_flags & HAS_COMMIT_OR_ROLLBACK)
my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
- return TRUE;
- }
+ else if (m_flags & HAS_SQLCOM_RESET)
+ my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "RESET");
+ else if (m_flags & HAS_SQLCOM_FLUSH)
+ my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH");
+
return test(m_flags &
- (CONTAINS_DYNAMIC_SQL|MULTI_RESULTS|HAS_SET_AUTOCOMMIT_STMT));
+ (CONTAINS_DYNAMIC_SQL|MULTI_RESULTS|HAS_SET_AUTOCOMMIT_STMT|
+ HAS_COMMIT_OR_ROLLBACK|HAS_SQLCOM_RESET|HAS_SQLCOM_FLUSH));
}
#ifndef DBUG_OFF
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index 3bc27a029d0..67ee5459bb4 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -260,6 +260,65 @@ sp_rcontext::find_handler(uint sql_errno,
return TRUE;
}
+/*
+ Handle the error for a given errno.
+ The severity of the error is adjusted depending of the current sql_mode.
+ If an handler is present for the error (see find_handler()),
+ this function will return true.
+ If a handler is found and if the severity of the error indicate
+ that the current instruction executed should abort,
+ the flag thd->net.report_error is also set.
+ This will cause the execution of the current instruction in a
+ sp_instr* to fail, and give control to the handler code itself
+ in the sp_head::execute() loop.
+
+ SYNOPSIS
+ sql_errno The error code
+ level Warning level
+ thd The current thread
+ - thd->net.report_error is an optional output.
+
+ RETURN
+ TRUE if a handler was found.
+ FALSE if no handler was found.
+*/
+bool
+sp_rcontext::handle_error(uint sql_errno,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd)
+{
+ bool handled= FALSE;
+ MYSQL_ERROR::enum_warning_level elevated_level= level;
+
+
+ /* Depending on the sql_mode of execution,
+ warnings may be considered errors */
+ if ((level == MYSQL_ERROR::WARN_LEVEL_WARN) &&
+ thd->really_abort_on_warning())
+ {
+ elevated_level= MYSQL_ERROR::WARN_LEVEL_ERROR;
+ }
+
+ if (find_handler(sql_errno, elevated_level))
+ {
+ if (elevated_level == MYSQL_ERROR::WARN_LEVEL_ERROR)
+ {
+ /*
+ Forces to abort the current instruction execution.
+ NOTE: This code is altering the original meaning of
+ the net.report_error flag (send an error to the client).
+ In the context of stored procedures with error handlers,
+ the flag is reused to cause error propagation,
+ until the error handler is reached.
+ No messages will be sent to the client in that context.
+ */
+ thd->net.report_error= 1;
+ }
+ handled= TRUE;
+ }
+
+ return handled;
+}
void
sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h
index 30521f6da84..5e03aa60d23 100644
--- a/sql/sp_rcontext.h
+++ b/sql/sp_rcontext.h
@@ -128,6 +128,12 @@ class sp_rcontext : public Sql_alloc
bool
find_handler(uint sql_errno,MYSQL_ERROR::enum_warning_level level);
+ // If there is an error handler for this error, handle it and return TRUE.
+ bool
+ handle_error(uint sql_errno,
+ MYSQL_ERROR::enum_warning_level level,
+ THD *thd);
+
// Returns handler type and sets *ip to location if one was found
inline int
found_handler(uint *ip, uint *fp)
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index b8be4f47d82..010a5c33b96 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -54,7 +54,7 @@ static byte* acl_entry_get_key(acl_entry *entry,uint *length,
}
#define IP_ADDR_STRLEN (3+1+3+1+3+1+3)
-#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_LEN+1+USERNAME_LENGTH+1)
+#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_BYTE_LEN+1+USERNAME_BYTE_LENGTH+1)
static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs;
static MEM_ROOT mem, memex;
@@ -197,7 +197,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
READ_RECORD read_record_info;
my_bool return_val= 1;
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
- char tmp_name[NAME_LEN+1];
+ char tmp_name[NAME_BYTE_LEN+1];
int password_length;
DBUG_ENTER("acl_load");
@@ -2264,7 +2264,7 @@ static GRANT_NAME *name_hash_search(HASH *name_hash,
const char *user, const char *tname,
bool exact)
{
- char helping [NAME_LEN*2+USERNAME_LENGTH+3];
+ char helping [NAME_BYTE_LEN*2+USERNAME_BYTE_LENGTH+3];
uint len;
GRANT_NAME *grant_name,*found=0;
HASH_SEARCH_STATE state;
@@ -2903,14 +2903,6 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list,
result= TRUE;
continue;
}
- if (Str->host.length > HOSTNAME_LENGTH ||
- Str->user.length > USERNAME_LENGTH)
- {
- my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER),
- MYF(0));
- result= TRUE;
- continue;
- }
/* Create user if needed */
error=replace_user_table(thd, tables[0].table, *Str,
0, revoke_grant, create_new_users,
@@ -3115,15 +3107,6 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
result= TRUE;
continue;
}
- if (Str->host.length > HOSTNAME_LENGTH ||
- Str->user.length > USERNAME_LENGTH)
- {
- if (!no_error)
- my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER),
- MYF(0));
- result= TRUE;
- continue;
- }
/* Create user if needed */
error=replace_user_table(thd, tables[0].table, *Str,
0, revoke_grant, create_new_users,
@@ -3184,7 +3167,7 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
{
List_iterator <LEX_USER> str_list (list);
LEX_USER *Str, *tmp_Str;
- char tmp_db[NAME_LEN+1];
+ char tmp_db[NAME_BYTE_LEN+1];
bool create_new_users=0;
TABLE_LIST tables[2];
DBUG_ENTER("mysql_grant");
@@ -3249,14 +3232,6 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
result= TRUE;
continue;
}
- if (Str->host.length > HOSTNAME_LENGTH ||
- Str->user.length > USERNAME_LENGTH)
- {
- my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER),
- MYF(0));
- result= -1;
- continue;
- }
if (replace_user_table(thd, tables[0].table, *Str,
(!db ? rights : 0), revoke_grant, create_new_users,
test(thd->variables.sql_mode &
@@ -3892,7 +3867,7 @@ err2:
bool check_grant_db(THD *thd,const char *db)
{
Security_context *sctx= thd->security_ctx;
- char helping [NAME_LEN+USERNAME_LENGTH+2];
+ char helping [NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+2];
uint len;
bool error= 1;
@@ -4162,14 +4137,6 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
DBUG_RETURN(TRUE);
}
- if (lex_user->host.length > HOSTNAME_LENGTH ||
- lex_user->user.length > USERNAME_LENGTH)
- {
- my_message(ER_GRANT_WRONG_HOST_OR_USER, ER(ER_GRANT_WRONG_HOST_OR_USER),
- MYF(0));
- DBUG_RETURN(TRUE);
- }
-
rw_rdlock(&LOCK_grant);
VOID(pthread_mutex_lock(&acl_cache->lock));
@@ -5265,14 +5232,6 @@ bool mysql_create_user(THD *thd, List <LEX_USER> &list)
continue;
}
- if (user_name->host.length > HOSTNAME_LENGTH ||
- user_name->user.length > USERNAME_LENGTH)
- {
- append_user(&wrong_users, user_name);
- result= TRUE;
- continue;
- }
-
/*
Search all in-memory structures and grant tables
for a mention of the new user name.
@@ -5465,8 +5424,6 @@ bool mysql_revoke_all(THD *thd, List <LEX_USER> &list)
}
if (!find_acl_user(lex_user->host.str, lex_user->user.str, TRUE))
{
- sql_print_error("REVOKE ALL PRIVILEGES, GRANT: User '%s'@'%s' does not "
- "exists", lex_user->user.str, lex_user->host.str);
result= -1;
continue;
}
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index f8f7bde3a62..ff033b69f98 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -565,21 +565,62 @@ byte *query_cache_query_get_key(const byte *record, uint *length,
*****************************************************************************/
/*
+ Note on double-check locking (DCL) usage.
+
+ Below, in query_cache_insert(), query_cache_abort() and
+ query_cache_end_of_result() we use what is called double-check
+ locking (DCL) for NET::query_cache_query. I.e. we test it first
+ without a lock, and, if positive, test again under the lock.
+
+ This means that if we see 'NET::query_cache_query == 0' without a
+ lock we will skip the operation. But this is safe here: when we
+ started to cache a query, we called Query_cache::store_query(), and
+ NET::query_cache_query was set to non-zero in this thread (and the
+ thread always sees results of its memory operations, mutex or not).
+ If later we see 'NET::query_cache_query == 0' without locking a
+ mutex, that may only mean that some other thread have reset it by
+ invalidating the query. Skipping the operation in this case is the
+ right thing to do, as NET::query_cache_query won't get non-zero for
+ this query again.
+
+ See also comments in Query_cache::store_query() and
+ Query_cache::send_result_to_client().
+
+ NOTE, however, that double-check locking is not applicable in
+ 'invalidate' functions, as we may erroneously skip invalidation,
+ because the thread doing invalidation may never see non-zero
+ NET::query_cache_query.
+*/
+
+
+void query_cache_init_query(NET *net)
+{
+ /*
+ It is safe to initialize 'NET::query_cache_query' without a lock
+ here, because before it will be accessed from different threads it
+ will be set in this thread under a lock, and access from the same
+ thread is always safe.
+ */
+ net->query_cache_query= 0;
+}
+
+
+/*
Insert the packet into the query cache.
- This should only be called if net->query_cache_query != 0
*/
void query_cache_insert(NET *net, const char *packet, ulong length)
{
DBUG_ENTER("query_cache_insert");
+ /* See the comment on double-check locking usage above. */
+ if (net->query_cache_query == 0)
+ DBUG_VOID_RETURN;
+
STRUCT_LOCK(&query_cache.structure_guard_mutex);
- /*
- It is very unlikely that following condition is TRUE (it is possible
- only if other thread is resizing cache), so we check it only after guard
- mutex lock
- */
- if (unlikely(query_cache.query_cache_size == 0))
+
+ if (unlikely(query_cache.query_cache_size == 0 ||
+ query_cache.flush_in_progress))
{
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
DBUG_VOID_RETURN;
@@ -616,10 +657,10 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
header->result(result);
header->last_pkt_nr= net->pkt_nr;
BLOCK_UNLOCK_WR(query_block);
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
}
else
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
- DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
DBUG_VOID_RETURN;
}
@@ -628,33 +669,33 @@ void query_cache_abort(NET *net)
{
DBUG_ENTER("query_cache_abort");
- if (net->query_cache_query != 0) // Quick check on unlocked structure
+ /* See the comment on double-check locking usage above. */
+ if (net->query_cache_query == 0)
+ DBUG_VOID_RETURN;
+
+ STRUCT_LOCK(&query_cache.structure_guard_mutex);
+
+ if (unlikely(query_cache.query_cache_size == 0 ||
+ query_cache.flush_in_progress))
{
- STRUCT_LOCK(&query_cache.structure_guard_mutex);
- /*
- It is very unlikely that following condition is TRUE (it is possible
- only if other thread is resizing cache), so we check it only after guard
- mutex lock
- */
- if (unlikely(query_cache.query_cache_size == 0))
- {
- STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
- DBUG_VOID_RETURN;
- }
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+ DBUG_VOID_RETURN;
+ }
- Query_cache_block *query_block = ((Query_cache_block*)
- net->query_cache_query);
- if (query_block) // Test if changed by other thread
- {
- DUMP(&query_cache);
- BLOCK_LOCK_WR(query_block);
- // The following call will remove the lock on query_block
- query_cache.free_query(query_block);
- }
- net->query_cache_query=0;
+ Query_cache_block *query_block= ((Query_cache_block*)
+ net->query_cache_query);
+ if (query_block) // Test if changed by other thread
+ {
+ DUMP(&query_cache);
+ BLOCK_LOCK_WR(query_block);
+ // The following call will remove the lock on query_block
+ query_cache.free_query(query_block);
+ net->query_cache_query= 0;
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
- STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
}
+
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+
DBUG_VOID_RETURN;
}
@@ -663,60 +704,65 @@ void query_cache_end_of_result(THD *thd)
{
DBUG_ENTER("query_cache_end_of_result");
- if (thd->net.query_cache_query != 0) // Quick check on unlocked structure
- {
+ /* See the comment on double-check locking usage above. */
+ if (thd->net.query_cache_query == 0)
+ DBUG_VOID_RETURN;
+
#ifdef EMBEDDED_LIBRARY
- query_cache_insert(&thd->net, (char*)thd,
- emb_count_querycache_size(thd));
+ query_cache_insert(&thd->net, (char*)thd,
+ emb_count_querycache_size(thd));
#endif
- STRUCT_LOCK(&query_cache.structure_guard_mutex);
- /*
- It is very unlikely that following condition is TRUE (it is possible
- only if other thread is resizing cache), so we check it only after guard
- mutex lock
- */
- if (unlikely(query_cache.query_cache_size == 0))
- {
- STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
- DBUG_VOID_RETURN;
- }
- Query_cache_block *query_block = ((Query_cache_block*)
- thd->net.query_cache_query);
- if (query_block)
- {
- DUMP(&query_cache);
- BLOCK_LOCK_WR(query_block);
- Query_cache_query *header = query_block->query();
- Query_cache_block *last_result_block = header->result()->prev;
- ulong allign_size = ALIGN_SIZE(last_result_block->used);
- ulong len = max(query_cache.min_allocation_unit, allign_size);
- if (last_result_block->length >= query_cache.min_allocation_unit + len)
- query_cache.split_block(last_result_block,len);
- STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+ STRUCT_LOCK(&query_cache.structure_guard_mutex);
+
+ if (unlikely(query_cache.query_cache_size == 0 ||
+ query_cache.flush_in_progress))
+ {
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+ DBUG_VOID_RETURN;
+ }
+
+ Query_cache_block *query_block= ((Query_cache_block*)
+ thd->net.query_cache_query);
+ if (query_block)
+ {
+ DUMP(&query_cache);
+ BLOCK_LOCK_WR(query_block);
+ Query_cache_query *header= query_block->query();
+ Query_cache_block *last_result_block= header->result()->prev;
+ ulong allign_size= ALIGN_SIZE(last_result_block->used);
+ ulong len= max(query_cache.min_allocation_unit, allign_size);
+ if (last_result_block->length >= query_cache.min_allocation_unit + len)
+ query_cache.split_block(last_result_block,len);
#ifndef DBUG_OFF
- if (header->result() == 0)
- {
- DBUG_PRINT("error", ("end of data whith no result. query '%s'",
- header->query()));
- query_cache.wreck(__LINE__, "");
- DBUG_VOID_RETURN;
- }
-#endif
- header->found_rows(current_thd->limit_found_rows);
- header->result()->type = Query_cache_block::RESULT;
- header->writer(0);
- BLOCK_UNLOCK_WR(query_block);
- }
- else
+ if (header->result() == 0)
{
- // Cache was flushed or resized and query was deleted => do nothing
+ DBUG_PRINT("error", ("end of data whith no result. query '%s'",
+ header->query()));
+ query_cache.wreck(__LINE__, "");
+
STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+
+ DBUG_VOID_RETURN;
}
- thd->net.query_cache_query=0;
- DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
+#endif
+ header->found_rows(current_thd->limit_found_rows);
+ header->result()->type= Query_cache_block::RESULT;
+ header->writer(0);
+ thd->net.query_cache_query= 0;
+ DBUG_EXECUTE("check_querycache",query_cache.check_integrity(1););
+
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+
+ BLOCK_UNLOCK_WR(query_block);
+ }
+ else
+ {
+ // Cache was flushed or resized and query was deleted => do nothing
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
}
+
DBUG_VOID_RETURN;
}
@@ -762,8 +808,7 @@ ulong Query_cache::resize(ulong query_cache_size_arg)
query_cache_size_arg));
DBUG_ASSERT(initialized);
STRUCT_LOCK(&structure_guard_mutex);
- if (query_cache_size > 0)
- free_cache();
+ free_cache();
query_cache_size= query_cache_size_arg;
::query_cache_size= init_cache();
STRUCT_UNLOCK(&structure_guard_mutex);
@@ -784,7 +829,15 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used)
TABLE_COUNTER_TYPE local_tables;
ulong tot_length;
DBUG_ENTER("Query_cache::store_query");
- if (query_cache_size == 0 || thd->locked_tables)
+ /*
+ Testing 'query_cache_size' without a lock here is safe: the thing
+ we may loose is that the query won't be cached, but we save on
+ mutex locking in the case when query cache is disabled or the
+ query is uncachable.
+
+ See also a note on double-check locking usage above.
+ */
+ if (thd->locked_tables || query_cache_size == 0)
DBUG_VOID_RETURN;
uint8 tables_type= 0;
@@ -836,9 +889,9 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
acquiring the query cache mutex.
*/
ha_release_temporary_latches(thd);
- STRUCT_LOCK(&structure_guard_mutex);
- if (query_cache_size == 0)
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size == 0 || flush_in_progress)
{
STRUCT_UNLOCK(&structure_guard_mutex);
DBUG_VOID_RETURN;
@@ -912,11 +965,12 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
double_linked_list_simple_include(query_block, &queries_blocks);
inserts++;
queries_in_cache++;
- STRUCT_UNLOCK(&structure_guard_mutex);
-
net->query_cache_query= (gptr) query_block;
header->writer(net);
header->tables_type(tables_type);
+
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
// init_n_lock make query block locked
BLOCK_UNLOCK_WR(query_block);
}
@@ -970,12 +1024,16 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Query_cache_query_flags flags;
DBUG_ENTER("Query_cache::send_result_to_client");
- if (query_cache_size == 0 || thd->locked_tables ||
- thd->variables.query_cache_type == 0)
- goto err;
+ /*
+ Testing 'query_cache_size' without a lock here is safe: the thing
+ we may loose is that the query won't be served from cache, but we
+ save on mutex locking in the case when query cache is disabled.
- /* Check that we haven't forgot to reset the query cache variables */
- DBUG_ASSERT(thd->net.query_cache_query == 0);
+ See also a note on double-check locking usage above.
+ */
+ if (thd->locked_tables || thd->variables.query_cache_type == 0 ||
+ query_cache_size == 0)
+ goto err;
if (!thd->lex->safe_to_cache_query)
{
@@ -1011,11 +1069,15 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
}
STRUCT_LOCK(&structure_guard_mutex);
- if (query_cache_size == 0)
+ if (query_cache_size == 0 || flush_in_progress)
{
DBUG_PRINT("qcache", ("query cache disabled"));
goto err_unlock;
}
+
+ /* Check that we haven't forgot to reset the query cache variables */
+ DBUG_ASSERT(thd->net.query_cache_query == 0);
+
Query_cache_block *query_block;
tot_length= query_length + thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE;
@@ -1241,45 +1303,43 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
my_bool using_transactions)
{
DBUG_ENTER("Query_cache::invalidate (table list)");
- if (query_cache_size > 0)
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0 && !flush_in_progress)
{
- STRUCT_LOCK(&structure_guard_mutex);
- if (query_cache_size > 0)
- {
- DUMP(this);
+ DUMP(this);
- using_transactions = using_transactions &&
- (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
- for (; tables_used; tables_used= tables_used->next_local)
- {
- DBUG_ASSERT(!using_transactions || tables_used->table!=0);
- if (tables_used->derived)
- continue;
- if (using_transactions &&
- (tables_used->table->file->table_cache_type() ==
- HA_CACHE_TBL_TRANSACT))
- /*
- Tables_used->table can't be 0 in transaction.
- Only 'drop' invalidate not opened table, but 'drop'
- force transaction finish.
- */
- thd->add_changed_table(tables_used->table);
- else
- invalidate_table(tables_used);
- }
+ using_transactions= using_transactions &&
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ for (; tables_used; tables_used= tables_used->next_local)
+ {
+ DBUG_ASSERT(!using_transactions || tables_used->table!=0);
+ if (tables_used->derived)
+ continue;
+ if (using_transactions &&
+ (tables_used->table->file->table_cache_type() ==
+ HA_CACHE_TBL_TRANSACT))
+ /*
+ Tables_used->table can't be 0 in transaction.
+ Only 'drop' invalidate not opened table, but 'drop'
+ force transaction finish.
+ */
+ thd->add_changed_table(tables_used->table);
+ else
+ invalidate_table(tables_used);
}
- STRUCT_UNLOCK(&structure_guard_mutex);
}
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
DBUG_VOID_RETURN;
}
void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
{
DBUG_ENTER("Query_cache::invalidate (changed table list)");
- if (query_cache_size > 0 && tables_used)
+ if (tables_used)
{
STRUCT_LOCK(&structure_guard_mutex);
- if (query_cache_size > 0)
+ if (query_cache_size > 0 && !flush_in_progress)
{
DUMP(this);
for (; tables_used; tables_used= tables_used->next)
@@ -1309,10 +1369,10 @@ void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
void Query_cache::invalidate_locked_for_write(TABLE_LIST *tables_used)
{
DBUG_ENTER("Query_cache::invalidate_locked_for_write");
- if (query_cache_size > 0 && tables_used)
+ if (tables_used)
{
STRUCT_LOCK(&structure_guard_mutex);
- if (query_cache_size > 0)
+ if (query_cache_size > 0 && !flush_in_progress)
{
DUMP(this);
for (; tables_used; tables_used= tables_used->next_local)
@@ -1336,21 +1396,19 @@ void Query_cache::invalidate(THD *thd, TABLE *table,
{
DBUG_ENTER("Query_cache::invalidate (table)");
- if (query_cache_size > 0)
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0 && !flush_in_progress)
{
- STRUCT_LOCK(&structure_guard_mutex);
- if (query_cache_size > 0)
- {
- using_transactions = using_transactions &&
- (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
- if (using_transactions &&
- (table->file->table_cache_type() == HA_CACHE_TBL_TRANSACT))
- thd->add_changed_table(table);
- else
- invalidate_table(table);
- }
- STRUCT_UNLOCK(&structure_guard_mutex);
+ using_transactions= using_transactions &&
+ (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
+ if (using_transactions &&
+ (table->file->table_cache_type() == HA_CACHE_TBL_TRANSACT))
+ thd->add_changed_table(table);
+ else
+ invalidate_table(table);
}
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
DBUG_VOID_RETURN;
}
@@ -1359,20 +1417,18 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
{
DBUG_ENTER("Query_cache::invalidate (key)");
- if (query_cache_size > 0)
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0 && !flush_in_progress)
{
- using_transactions = using_transactions &&
+ using_transactions= using_transactions &&
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
if (using_transactions) // used for innodb => has_transactions() is TRUE
thd->add_changed_table(key, key_length);
else
- {
- STRUCT_LOCK(&structure_guard_mutex);
- if (query_cache_size > 0)
- invalidate_table((byte*)key, key_length);
- STRUCT_UNLOCK(&structure_guard_mutex);
- }
+ invalidate_table((byte*)key, key_length);
}
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
DBUG_VOID_RETURN;
}
@@ -1383,38 +1439,36 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
void Query_cache::invalidate(char *db)
{
DBUG_ENTER("Query_cache::invalidate (db)");
- if (query_cache_size > 0)
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0 && !flush_in_progress)
{
- STRUCT_LOCK(&structure_guard_mutex);
- if (query_cache_size > 0)
- {
- DUMP(this);
+ DUMP(this);
restart_search:
- if (tables_blocks)
+ if (tables_blocks)
+ {
+ Query_cache_block *curr= tables_blocks;
+ Query_cache_block *next;
+ do
{
- Query_cache_block *curr= tables_blocks;
- Query_cache_block *next;
- do
- {
- next= curr->next;
- if (strcmp(db, (char*)(curr->table()->db())) == 0)
- invalidate_table(curr);
- /*
- invalidate_table can freed block on which point 'next' (if
- table of this block used only in queries which was deleted
- by invalidate_table). As far as we do not allocate new blocks
- and mark all headers of freed blocks as 'FREE' (even if they are
- merged with other blocks) we can just test type of block
- to be sure that block is not deleted
- */
- if (next->type == Query_cache_block::FREE)
- goto restart_search;
- curr= next;
- } while (curr != tables_blocks);
- }
+ next= curr->next;
+ if (strcmp(db, (char*)(curr->table()->db())) == 0)
+ invalidate_table(curr);
+ /*
+ invalidate_table can freed block on which point 'next' (if
+ table of this block used only in queries which was deleted
+ by invalidate_table). As far as we do not allocate new blocks
+ and mark all headers of freed blocks as 'FREE' (even if they are
+ merged with other blocks) we can just test type of block
+ to be sure that block is not deleted
+ */
+ if (next->type == Query_cache_block::FREE)
+ goto restart_search;
+ curr= next;
+ } while (curr != tables_blocks);
}
- STRUCT_UNLOCK(&structure_guard_mutex);
}
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
DBUG_VOID_RETURN;
}
@@ -1422,23 +1476,22 @@ void Query_cache::invalidate(char *db)
void Query_cache::invalidate_by_MyISAM_filename(const char *filename)
{
DBUG_ENTER("Query_cache::invalidate_by_MyISAM_filename");
- if (query_cache_size > 0)
+
+ STRUCT_LOCK(&structure_guard_mutex);
+ if (query_cache_size > 0 && !flush_in_progress)
{
/* Calculate the key outside the lock to make the lock shorter */
char key[MAX_DBKEY_LENGTH];
uint32 db_length;
uint key_length= filename_2_table_key(key, filename, &db_length);
- STRUCT_LOCK(&structure_guard_mutex);
- if (query_cache_size > 0) // Safety if cache removed
- {
- Query_cache_block *table_block;
- if ((table_block = (Query_cache_block*) hash_search(&tables,
- (byte*) key,
- key_length)))
- invalidate_table(table_block);
- }
- STRUCT_UNLOCK(&structure_guard_mutex);
+ Query_cache_block *table_block;
+ if ((table_block = (Query_cache_block*) hash_search(&tables,
+ (byte*) key,
+ key_length)))
+ invalidate_table(table_block);
}
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
DBUG_VOID_RETURN;
}
@@ -1483,7 +1536,12 @@ void Query_cache::destroy()
}
else
{
+ /* Underlying code expects the lock. */
+ STRUCT_LOCK(&structure_guard_mutex);
free_cache();
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
+ pthread_cond_destroy(&COND_flush_finished);
pthread_mutex_destroy(&structure_guard_mutex);
initialized = 0;
}
@@ -1499,6 +1557,8 @@ void Query_cache::init()
{
DBUG_ENTER("Query_cache::init");
pthread_mutex_init(&structure_guard_mutex,MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&COND_flush_finished, NULL);
+ flush_in_progress= FALSE;
initialized = 1;
DBUG_VOID_RETURN;
}
@@ -1694,6 +1754,17 @@ void Query_cache::make_disabled()
}
+/*
+ free_cache() - free all resources allocated by the cache.
+
+ SYNOPSIS
+ free_cache()
+
+ DESCRIPTION
+ This function frees all resources allocated by the cache. You
+ have to call init_cache() before using the cache again.
+*/
+
void Query_cache::free_cache()
{
DBUG_ENTER("Query_cache::free_cache");
@@ -1728,17 +1799,51 @@ void Query_cache::free_cache()
Free block data
*****************************************************************************/
+
/*
- The following assumes we have a lock on the cache
+ flush_cache() - flush the cache.
+
+ SYNOPSIS
+ flush_cache()
+
+ DESCRIPTION
+ This function will flush cache contents. It assumes we have
+ 'structure_guard_mutex' locked. The function sets the
+ flush_in_progress flag and releases the lock, so other threads may
+ proceed skipping the cache as if it is disabled. Concurrent
+ flushes are performed in turn.
*/
void Query_cache::flush_cache()
{
+ /*
+ If there is flush in progress, wait for it to finish, and then do
+ our flush. This is necessary because something could be added to
+ the cache before we acquire the lock again, and some code (like
+ Query_cache::free_cache()) depends on the fact that after the
+ flush the cache is empty.
+ */
+ while (flush_in_progress)
+ pthread_cond_wait(&COND_flush_finished, &structure_guard_mutex);
+
+ /*
+ Setting 'flush_in_progress' will prevent other threads from using
+ the cache while we are in the middle of the flush, and we release
+ the lock so that other threads won't block.
+ */
+ flush_in_progress= TRUE;
+ STRUCT_UNLOCK(&structure_guard_mutex);
+
+ my_hash_reset(&queries);
while (queries_blocks != 0)
{
BLOCK_LOCK_WR(queries_blocks);
- free_query(queries_blocks);
+ free_query_internal(queries_blocks);
}
+
+ STRUCT_LOCK(&structure_guard_mutex);
+ flush_in_progress= FALSE;
+ pthread_cond_signal(&COND_flush_finished);
}
/*
@@ -1784,36 +1889,48 @@ my_bool Query_cache::free_old_query()
DBUG_RETURN(1); // Nothing to remove
}
+
/*
- Free query from query cache.
- query_block must be locked for writing.
- This function will remove (and destroy) the lock for the query.
+ free_query_internal() - free query from query cache.
+
+ SYNOPSIS
+ free_query_internal()
+ query_block Query_cache_block representing the query
+
+ DESCRIPTION
+ This function will remove the query from a cache, and place its
+ memory blocks to the list of free blocks. 'query_block' must be
+ locked for writing, this function will release (and destroy) this
+ lock.
+
+ NOTE
+ 'query_block' should be removed from 'queries' hash _before_
+ calling this method, as the lock will be destroyed here.
*/
-void Query_cache::free_query(Query_cache_block *query_block)
+void Query_cache::free_query_internal(Query_cache_block *query_block)
{
- DBUG_ENTER("Query_cache::free_query");
+ DBUG_ENTER("Query_cache::free_query_internal");
DBUG_PRINT("qcache", ("free query 0x%lx %lu bytes result",
(ulong) query_block,
query_block->query()->length() ));
queries_in_cache--;
- hash_delete(&queries,(byte *) query_block);
- Query_cache_query *query = query_block->query();
+ Query_cache_query *query= query_block->query();
if (query->writer() != 0)
{
/* Tell MySQL that this query should not be cached anymore */
- query->writer()->query_cache_query = 0;
+ query->writer()->query_cache_query= 0;
query->writer(0);
}
double_linked_list_exclude(query_block, &queries_blocks);
- Query_cache_block_table *table=query_block->table(0);
+ Query_cache_block_table *table= query_block->table(0);
- for (TABLE_COUNTER_TYPE i=0; i < query_block->n_tables; i++)
+ for (TABLE_COUNTER_TYPE i= 0; i < query_block->n_tables; i++)
unlink_table(table++);
- Query_cache_block *result_block = query->result();
+ Query_cache_block *result_block= query->result();
/*
The following is true when query destruction was called and no results
@@ -1827,11 +1944,11 @@ void Query_cache::free_query(Query_cache_block *query_block)
refused++;
inserts--;
}
- Query_cache_block *block = result_block;
+ Query_cache_block *block= result_block;
do
{
- Query_cache_block *current = block;
- block = block->next;
+ Query_cache_block *current= block;
+ block= block->next;
free_memory_block(current);
} while (block != result_block);
}
@@ -1848,6 +1965,32 @@ void Query_cache::free_query(Query_cache_block *query_block)
DBUG_VOID_RETURN;
}
+
+/*
+ free_query() - free query from query cache.
+
+ SYNOPSIS
+ free_query()
+ query_block Query_cache_block representing the query
+
+ DESCRIPTION
+ This function will remove 'query_block' from 'queries' hash, and
+ then call free_query_internal(), which see.
+*/
+
+void Query_cache::free_query(Query_cache_block *query_block)
+{
+ DBUG_ENTER("Query_cache::free_query");
+ DBUG_PRINT("qcache", ("free query 0x%lx %lu bytes result",
+ (ulong) query_block,
+ query_block->query()->length() ));
+
+ hash_delete(&queries,(byte *) query_block);
+ free_query_internal(query_block);
+
+ DBUG_VOID_RETURN;
+}
+
/*****************************************************************************
Query data creation
*****************************************************************************/
@@ -2431,12 +2574,8 @@ Query_cache::allocate_block(ulong len, my_bool not_less, ulong min,
if (!under_guard)
{
STRUCT_LOCK(&structure_guard_mutex);
- /*
- It is very unlikely that following condition is TRUE (it is possible
- only if other thread is resizing cache), so we check it only after
- guard mutex lock
- */
- if (unlikely(query_cache.query_cache_size == 0))
+
+ if (unlikely(query_cache.query_cache_size == 0 || flush_in_progress))
{
STRUCT_UNLOCK(&structure_guard_mutex);
DBUG_RETURN(0);
@@ -2892,11 +3031,9 @@ static TABLE_COUNTER_TYPE process_and_count_tables(TABLE_LIST *tables_used,
(query without tables are not cached)
*/
-TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len,
- char *query,
- LEX *lex,
- TABLE_LIST *tables_used,
- uint8 *tables_type)
+TABLE_COUNTER_TYPE
+Query_cache::is_cacheable(THD *thd, uint32 query_len, char *query, LEX *lex,
+ TABLE_LIST *tables_used, uint8 *tables_type)
{
TABLE_COUNTER_TYPE table_count;
DBUG_ENTER("Query_cache::is_cacheable");
@@ -2979,13 +3116,10 @@ my_bool Query_cache::ask_handler_allowance(THD *thd,
void Query_cache::pack_cache()
{
DBUG_ENTER("Query_cache::pack_cache");
+
STRUCT_LOCK(&structure_guard_mutex);
- /*
- It is very unlikely that following condition is TRUE (it is possible
- only if other thread is resizing cache), so we check it only after
- guard mutex lock
- */
- if (unlikely(query_cache_size == 0))
+
+ if (unlikely(query_cache_size == 0 || flush_in_progress))
{
STRUCT_UNLOCK(&structure_guard_mutex);
DBUG_VOID_RETURN;
@@ -3300,7 +3434,7 @@ my_bool Query_cache::join_results(ulong join_limit)
DBUG_ENTER("Query_cache::join_results");
STRUCT_LOCK(&structure_guard_mutex);
- if (queries_blocks != 0)
+ if (queries_blocks != 0 && !flush_in_progress)
{
DBUG_ASSERT(query_cache_size > 0);
Query_cache_block *block = queries_blocks;
@@ -3587,31 +3721,23 @@ void Query_cache::tables_dump()
}
-my_bool Query_cache::check_integrity(bool not_locked)
+my_bool Query_cache::check_integrity(bool locked)
{
my_bool result = 0;
uint i;
DBUG_ENTER("check_integrity");
- if (query_cache_size == 0)
+ if (!locked)
+ STRUCT_LOCK(&structure_guard_mutex);
+
+ if (unlikely(query_cache_size == 0 || flush_in_progress))
{
+ if (!locked)
+ STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
+
DBUG_PRINT("qcache", ("Query Cache not initialized"));
DBUG_RETURN(0);
}
- if (!not_locked)
- {
- STRUCT_LOCK(&structure_guard_mutex);
- /*
- It is very unlikely that following condition is TRUE (it is possible
- only if other thread is resizing cache), so we check it only after
- guard mutex lock
- */
- if (unlikely(query_cache_size == 0))
- {
- STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
- DBUG_RETURN(0);
- }
- }
if (hash_check(&queries))
{
@@ -3856,7 +3982,7 @@ my_bool Query_cache::check_integrity(bool not_locked)
}
}
DBUG_ASSERT(result == 0);
- if (!not_locked)
+ if (!locked)
STRUCT_UNLOCK(&structure_guard_mutex);
DBUG_RETURN(result);
}
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index 29d314d3c44..a66067159e2 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -195,7 +195,6 @@ extern "C"
byte *query_cache_table_get_key(const byte *record, uint *length,
my_bool not_used);
}
-void query_cache_insert(NET *thd, const char *packet, ulong length);
extern "C" void query_cache_invalidate_by_MyISAM_filename(const char* filename);
@@ -241,6 +240,12 @@ public:
ulong free_memory, queries_in_cache, hits, inserts, refused,
free_memory_blocks, total_blocks, lowmem_prunes;
+private:
+ pthread_cond_t COND_flush_finished;
+ bool flush_in_progress;
+
+ void free_query_internal(Query_cache_block *point);
+
protected:
/*
The following mutex is locked when searching or changing global
@@ -249,6 +254,12 @@ protected:
LOCK SEQUENCE (to prevent deadlocks):
1. structure_guard_mutex
2. query block (for operation inside query (query block/results))
+
+ Thread doing cache flush releases the mutex once it sets
+ flush_in_progress flag, so other threads may bypass the cache as
+ if it is disabled, not waiting for reset to finish. The exception
+ is other threads that were going to do cache flush---they'll wait
+ till the end of a flush operation.
*/
pthread_mutex_t structure_guard_mutex;
byte *cache; // cache memory
@@ -358,6 +369,7 @@ protected:
If query is cacheable return number tables in query
(query without tables not cached)
*/
+ static
TABLE_COUNTER_TYPE is_cacheable(THD *thd, uint32 query_len, char *query,
LEX *lex, TABLE_LIST *tables_used,
uint8 *tables_type);
@@ -410,6 +422,7 @@ protected:
void destroy();
+ friend void query_cache_init_query(NET *net);
friend void query_cache_insert(NET *net, const char *packet, ulong length);
friend void query_cache_end_of_result(THD *thd);
friend void query_cache_abort(NET *net);
@@ -435,6 +448,8 @@ protected:
extern Query_cache query_cache;
extern TYPELIB query_cache_type_typelib;
+void query_cache_init_query(NET *net);
+void query_cache_insert(NET *net, const char *packet, ulong length);
void query_cache_end_of_result(THD *thd);
void query_cache_abort(NET *net);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 759e3b1a60b..093173ab949 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -224,7 +224,7 @@ THD::THD()
#endif
client_capabilities= 0; // minimalistic client
net.last_error[0]=0; // If error on boot
- net.query_cache_query=0; // If error on boot
+ query_cache_init_query(&net); // If error on boot
ull=0;
system_thread= cleanup_done= abort_on_warning= no_warnings_for_error= 0;
peer_port= 0; // For SHOW PROCESSLIST
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 53a95a89b51..ed9f4b57f56 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -200,7 +200,7 @@ class MYSQL_LOG: public TC_LOG
IO_CACHE log_file;
IO_CACHE index_file;
char *name;
- char time_buff[20],db[NAME_LEN+1];
+ char time_buff[20],db[NAME_BYTE_LEN+1];
char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
/*
The max size before rotation (usable only if log_type == LOG_BIN: binary
@@ -342,6 +342,7 @@ public:
bool need_mutex);
int find_next_log(LOG_INFO* linfo, bool need_mutex);
int get_current_log(LOG_INFO* linfo);
+ int raw_get_current_log(LOG_INFO* linfo);
uint next_file_id();
inline bool is_open() { return log_type != LOG_CLOSED; }
inline char* get_index_fname() { return index_file_name;}
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 19811efbb12..ebd515bd209 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -139,14 +139,8 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
}
if (thd->spcont &&
- thd->spcont->find_handler(code,
- ((int) level >=
- (int) MYSQL_ERROR::WARN_LEVEL_WARN &&
- thd->really_abort_on_warning()) ?
- MYSQL_ERROR::WARN_LEVEL_ERROR : level))
+ thd->spcont->handle_error(code, level, thd))
{
- if (! thd->spcont->found_handler_here())
- thd->net.report_error= 1; /* Make "select" abort correctly */
DBUG_RETURN(NULL);
}
query_cache_abort(&thd->net);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 563ebce4ff7..43aeea2bf53 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -654,8 +654,9 @@ int MYSQLlex(void *arg, void *yythd)
*/
if ((yylval->lex_str.str[0]=='_') &&
- (lex->charset=get_charset_by_csname(yylval->lex_str.str+1,
- MY_CS_PRIMARY,MYF(0))))
+ (lex->underscore_charset=
+ get_charset_by_csname(yylval->lex_str.str + 1,
+ MY_CS_PRIMARY,MYF(0))))
return(UNDERSCORE_CHARSET);
return(result_state); // IDENT or IDENT_QUOTED
@@ -1040,6 +1041,8 @@ int MYSQLlex(void *arg, void *yythd)
if (c == '.')
lex->next_state=MY_LEX_IDENT_SEP;
length= (uint) (lex->ptr - lex->tok_start)-1;
+ if (length == 0)
+ return(ABORT_SYM); // Names must be nonempty.
if ((tokval= find_keyword(lex,length,0)))
{
yyUnget(); // Put back 'c'
@@ -1521,10 +1524,10 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
*/
Query_arena *arena= thd->stmt_arena;
return (ref_pointer_array=
- (Item **)arena->alloc(sizeof(Item*) *
- (item_list.elements +
- select_n_having_items +
- order_group_num)* 5)) == 0;
+ (Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items +
+ item_list.elements +
+ select_n_having_items +
+ order_group_num)*5)) == 0;
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 220d928ccf7..2e19c54cbfe 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -548,6 +548,12 @@ public:
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
/* TRUE when having fix field called in processing of this SELECT */
bool having_fix_field;
+
+ /* Number of Item_sum-derived objects in this SELECT */
+ uint n_sum_items;
+ /* Number of Item_sum-derived objects in children and descendant SELECTs */
+ uint n_child_sum_items;
+
/* explicit LIMIT clause was used */
bool explicit_limit;
/*
@@ -640,7 +646,7 @@ public:
bool test_limit();
friend void lex_start(THD *thd, uchar *buf, uint length);
- st_select_lex() {}
+ st_select_lex() : n_sum_items(0), n_child_sum_items(0) {}
void make_empty_select()
{
init_query();
@@ -834,7 +840,7 @@ typedef struct st_lex : public Query_tables_list
XID *xid;
gptr yacc_yyss,yacc_yyvs;
THD *thd;
- CHARSET_INFO *charset;
+ CHARSET_INFO *charset, *underscore_charset;
/* store original leaf_tables for INSERT SELECT and PS/SP */
TABLE_LIST *leaf_tables_insert;
/* Position (first character index) of SELECT of CREATE VIEW statement */
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index b1ba2e96651..d5faf6ee7e9 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -147,10 +147,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
MYF(0));
DBUG_RETURN(TRUE);
}
- /*
- This needs to be done before external_lock
- */
- ha_enable_transaction(thd, FALSE);
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
@@ -394,7 +390,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
table->next_number_field=0;
}
- ha_enable_transaction(thd, TRUE);
if (file >= 0)
my_close(file,MYF(0));
free_blobs(table); /* if pack_blob was used */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 905e8cdc71a..d809c1b2cb0 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1001,8 +1001,8 @@ static int check_connection(THD *thd)
char *passwd= strend(user)+1;
uint user_len= passwd - user - 1;
char *db= passwd;
- char db_buff[NAME_LEN+1]; // buffer to store db in utf8
- char user_buff[USERNAME_LENGTH+1]; // buffer to store user in utf8
+ char db_buff[NAME_BYTE_LEN + 1]; // buffer to store db in utf8
+ char user_buff[USERNAME_BYTE_LENGTH + 1]; // buffer to store user in utf8
uint dummy_errors;
/*
@@ -1662,7 +1662,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
password. New clients send the size (1 byte) + string (not null
terminated, so also '\0' for empty string).
*/
- char db_buff[NAME_LEN+1]; // buffer to store db in utf8
+ char db_buff[NAME_BYTE_LEN+1]; // buffer to store db in utf8
char *db= passwd;
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
*passwd++ : strlen(passwd);
@@ -5785,7 +5785,6 @@ void mysql_init_multi_delete(LEX *lex)
lex->query_tables_last= &lex->query_tables;
}
-
/*
When you modify mysql_parse(), you may need to mofify
mysql_test_parse_for_slave() in this same file.
@@ -5794,6 +5793,9 @@ void mysql_init_multi_delete(LEX *lex)
void mysql_parse(THD *thd, char *inBuf, uint length)
{
DBUG_ENTER("mysql_parse");
+
+ DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
+
mysql_init_query(thd, (uchar*) inBuf, length);
if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
{
@@ -6688,11 +6690,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
select_errors=0; /* Write if more errors */
bool tmp_write_to_binlog= 1;
- if (thd && thd->in_sub_stmt)
- {
- my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH");
- return 1;
- }
+ DBUG_ASSERT(!thd || !thd->in_sub_stmt);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (options & REFRESH_GRANT)
@@ -7540,16 +7538,35 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
LEX_USER *get_current_user(THD *thd, LEX_USER *user)
{
- LEX_USER *curr_user;
if (!user->user.str) // current_user
- {
- if (!(curr_user= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
- {
- my_error(ER_OUTOFMEMORY, MYF(0), sizeof(LEX_USER));
- return 0;
- }
- get_default_definer(thd, curr_user);
- return curr_user;
- }
+ return create_default_definer(thd);
+
return user;
}
+
+
+/*
+ Check that length of a string does not exceed some limit.
+
+ SYNOPSIS
+ check_string_length()
+ cs string charset
+ str string to be checked
+ err_msg error message to be displayed if the string is too long
+ max_length max length
+
+ RETURN
+ FALSE the passed string is not longer than max_length
+ TRUE the passed string is longer than max_length
+*/
+
+bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str,
+ const char *err_msg, uint max_length)
+{
+ if (cs->cset->charpos(cs, str->str, str->str + str->length,
+ max_length) >= str->length)
+ return FALSE;
+
+ my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_length);
+ return TRUE;
+}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 6d35c441368..32f0ca6859d 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1877,7 +1877,8 @@ void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length)
thd->stmt_map.erase(stmt);
}
else
- mysql_log.write(thd, COM_STMT_PREPARE, "[%lu] %s", stmt->id, packet);
+ mysql_log.write(thd, COM_STMT_PREPARE, "[%lu] %.*b", stmt->id,
+ stmt->query_length, stmt->query);
/* check_prepared_statemnt sends the metadata packet in case of success */
DBUG_VOID_RETURN;
@@ -2252,7 +2253,8 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
if (error == 0)
- mysql_log.write(thd, COM_STMT_EXECUTE, "[%lu] %s", stmt->id, thd->query);
+ mysql_log.write(thd, COM_STMT_EXECUTE, "[%lu] %.*b", stmt->id,
+ thd->query_length, thd->query);
DBUG_VOID_RETURN;
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index ccda69522c7..e1933d42f9e 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1494,10 +1494,14 @@ bool show_binlogs(THD* thd)
if (protocol->send_fields(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
+
+ pthread_mutex_lock(mysql_bin_log.get_log_lock());
mysql_bin_log.lock_index();
index_file=mysql_bin_log.get_index_file();
-
- mysql_bin_log.get_current_log(&cur);
+
+ mysql_bin_log.raw_get_current_log(&cur); // dont take mutex
+ pthread_mutex_unlock(mysql_bin_log.get_log_lock()); // lockdep, OK
+
cur_dir_len= dirname_length(cur.log_file_name);
reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 0);
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index 9eb6456ee20..6b1e5e6b447 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -22,7 +22,7 @@ typedef struct st_slave_info
uint32 server_id;
uint32 rpl_recovery_rank, master_id;
char host[HOSTNAME_LENGTH+1];
- char user[USERNAME_LENGTH+1];
+ char user[USERNAME_BYTE_LENGTH+1];
char password[MAX_PASSWORD_LENGTH+1];
uint16 port;
THD* thd;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 0ef4cb6da9d..e9d0e003f6d 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -7210,6 +7210,8 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
left_item->collation.collation == value->collation.collation))
{
Item *tmp=value->new_item();
+ tmp->collation.set(right_item->collation);
+
if (tmp)
{
thd->change_item_tree(args + 1, tmp);
@@ -7232,6 +7234,8 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
right_item->collation.collation == value->collation.collation))
{
Item *tmp=value->new_item();
+ tmp->collation.set(left_item->collation);
+
if (tmp)
{
thd->change_item_tree(args, tmp);
@@ -8990,11 +8994,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
keyinfo->key_length+= key_part_info->length;
}
}
- else
- {
- set_if_smaller(table->s->max_rows, rows_limit);
- param->end_write_records= rows_limit;
- }
if (distinct && field_count != param->hidden_field_count)
{
@@ -9009,8 +9008,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
null_pack_length-=hidden_null_pack_length;
keyinfo->key_parts= ((field_count-param->hidden_field_count)+
test(null_pack_length));
- set_if_smaller(table->s->max_rows, rows_limit);
- param->end_write_records= rows_limit;
table->distinct= 1;
table->s->keys= 1;
if (blob_count)
@@ -9062,6 +9059,20 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
0 : FIELDFLAG_BINARY;
}
}
+
+ /*
+ Push the LIMIT clause to the temporary table creation, so that we
+ materialize only up to 'rows_limit' records instead of all result records.
+ This optimization is not applicable when there is GROUP BY or there is
+ no GROUP BY, but there are aggregate functions, because both must be
+ computed for all result rows.
+ */
+ if (!group && !thd->lex->current_select->with_sum_func)
+ {
+ set_if_smaller(table->s->max_rows, rows_limit);
+ param->end_write_records= rows_limit;
+ }
+
if (thd->is_fatal_error) // If end of memory
goto err; /* purecov: inspected */
table->s->db_record_offset= 1;
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 79228be8a76..7aaca809113 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -248,6 +248,10 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
0 No conversion needed
1 Either character set conversion or adding leading zeros
(e.g. for UCS-2) must be done
+
+ NOTE
+ to_cs may be NULL for "no conversion" if the system variable
+ character_set_results is NULL.
*/
bool String::needs_conversion(uint32 arg_length,
@@ -256,7 +260,8 @@ bool String::needs_conversion(uint32 arg_length,
uint32 *offset)
{
*offset= 0;
- if ((to_cs == &my_charset_bin) ||
+ if (!to_cs ||
+ (to_cs == &my_charset_bin) ||
(to_cs == from_cs) ||
my_charset_same(from_cs, to_cs) ||
((from_cs == &my_charset_bin) &&
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index e065a32c2e8..a340c5ffc98 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -715,6 +715,40 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(-1);
}
+ /*
+ Convert the default value from client character
+ set into the column character set if necessary.
+ */
+ if (sql_field->def &&
+ save_cs != sql_field->def->collation.collation &&
+ (sql_field->sql_type == FIELD_TYPE_VAR_STRING ||
+ sql_field->sql_type == FIELD_TYPE_STRING ||
+ sql_field->sql_type == FIELD_TYPE_SET ||
+ sql_field->sql_type == FIELD_TYPE_ENUM))
+ {
+ Query_arena backup_arena;
+ bool need_to_change_arena= !thd->stmt_arena->is_conventional();
+ if (need_to_change_arena)
+ {
+ /* Asser that we don't do that at every PS execute */
+ DBUG_ASSERT(thd->stmt_arena->is_first_stmt_execute() ||
+ thd->stmt_arena->is_first_sp_execute());
+ thd->set_n_backup_active_arena(thd->stmt_arena, &backup_arena);
+ }
+
+ sql_field->def= sql_field->def->safe_charset_converter(save_cs);
+
+ if (need_to_change_arena)
+ thd->restore_active_arena(thd->stmt_arena, &backup_arena);
+
+ if (sql_field->def == NULL)
+ {
+ /* Could not convert */
+ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
+ DBUG_RETURN(-1);
+ }
+ }
+
if (sql_field->sql_type == FIELD_TYPE_SET ||
sql_field->sql_type == FIELD_TYPE_ENUM)
{
@@ -776,35 +810,6 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
sql_field->interval_list.empty(); // Don't need interval_list anymore
}
- /*
- Convert the default value from client character
- set into the column character set if necessary.
- */
- if (sql_field->def && cs != sql_field->def->collation.collation)
- {
- Query_arena backup_arena;
- bool need_to_change_arena= !thd->stmt_arena->is_conventional();
- if (need_to_change_arena)
- {
- /* Asser that we don't do that at every PS execute */
- DBUG_ASSERT(thd->stmt_arena->is_first_stmt_execute() ||
- thd->stmt_arena->is_first_sp_execute());
- thd->set_n_backup_active_arena(thd->stmt_arena, &backup_arena);
- }
-
- sql_field->def= sql_field->def->safe_charset_converter(cs);
-
- if (need_to_change_arena)
- thd->restore_active_arena(thd->stmt_arena, &backup_arena);
-
- if (sql_field->def == NULL)
- {
- /* Could not convert */
- my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
- DBUG_RETURN(-1);
- }
- }
-
if (sql_field->sql_type == FIELD_TYPE_SET)
{
uint32 field_length;
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index e806dd4a3f3..6bb50d602c3 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -158,11 +158,13 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
{
TABLE *table;
bool result= TRUE;
- LEX_STRING definer_user;
- LEX_STRING definer_host;
+ String stmt_query;
DBUG_ENTER("mysql_create_or_drop_trigger");
+ /* Charset of the buffer for statement must be system one. */
+ stmt_query.set_charset(system_charset_info);
+
/*
QQ: This function could be merged in mysql_alter_table() function
But do we want this ?
@@ -264,8 +266,8 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
}
result= (create ?
- table->triggers->create_trigger(thd, tables, &definer_user, &definer_host):
- table->triggers->drop_trigger(thd, tables));
+ table->triggers->create_trigger(thd, tables, &stmt_query):
+ table->triggers->drop_trigger(thd, tables, &stmt_query));
end:
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -277,32 +279,9 @@ end:
{
thd->clear_error();
- String log_query(thd->query, thd->query_length, system_charset_info);
-
- if (create)
- {
- log_query.set((char *) 0, 0, system_charset_info); /* reset log_query */
-
- log_query.append(STRING_WITH_LEN("CREATE "));
-
- if (definer_user.str && definer_host.str)
- {
- /*
- Append definer-clause if the trigger is SUID (a usual trigger in
- new MySQL versions).
- */
-
- append_definer(thd, &log_query, &definer_user, &definer_host);
- }
-
- log_query.append(thd->lex->stmt_definition_begin,
- (char *)thd->lex->sphead->m_body_begin -
- thd->lex->stmt_definition_begin +
- thd->lex->sphead->m_body.length);
- }
-
/* Such a statement can always go directly to binlog, no trans cache. */
- Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), 0, FALSE);
+ Query_log_event qinfo(thd, stmt_query.ptr(), stmt_query.length(), 0,
+ FALSE);
mysql_bin_log.write(&qinfo);
}
@@ -322,22 +301,8 @@ end:
LEX)
tables - table list containing one open table for which the
trigger is created.
- definer_user - [out] after a call it points to 0-terminated string or
- contains the NULL-string:
- - 0-terminated is returned if the trigger is SUID. The
- string contains user name part of the actual trigger
- definer.
- - NULL-string is returned if the trigger is non-SUID.
- Anyway, the caller is responsible to provide memory for
- storing LEX_STRING object.
- definer_host - [out] after a call it points to 0-terminated string or
- contains the NULL-string:
- - 0-terminated string is returned if the trigger is
- SUID. The string contains host name part of the
- actual trigger definer.
- - NULL-string is returned if the trigger is non-SUID.
- Anyway, the caller is responsible to provide memory for
- storing LEX_STRING object.
+ stmt_query - [OUT] after successful return, this string contains
+ well-formed statement for creation this trigger.
NOTE
- Assumes that trigger name is fully qualified.
@@ -352,8 +317,7 @@ end:
True - error
*/
bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
- LEX_STRING *definer_user,
- LEX_STRING *definer_host)
+ String *stmt_query)
{
LEX *lex= thd->lex;
TABLE *table= tables->table;
@@ -361,6 +325,8 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
trigname_path[FN_REFLEN];
LEX_STRING dir, file, trigname_file;
LEX_STRING *trg_def, *name;
+ LEX_STRING definer_user;
+ LEX_STRING definer_host;
ulonglong *trg_sql_mode;
char trg_definer_holder[USER_HOST_BUFF_SIZE];
LEX_STRING *trg_definer;
@@ -508,8 +474,6 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
definers_list.push_back(trg_definer, &table->mem_root))
goto err_with_cleanup;
- trg_def->str= thd->query;
- trg_def->length= thd->query_length;
*trg_sql_mode= thd->variables.sql_mode;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -529,27 +493,54 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
{
/* SUID trigger. */
- *definer_user= lex->definer->user;
- *definer_host= lex->definer->host;
+ definer_user= lex->definer->user;
+ definer_host= lex->definer->host;
trg_definer->str= trg_definer_holder;
- trg_definer->length= strxmov(trg_definer->str, definer_user->str, "@",
- definer_host->str, NullS) - trg_definer->str;
+ trg_definer->length= strxmov(trg_definer->str, definer_user.str, "@",
+ definer_host.str, NullS) - trg_definer->str;
}
else
{
/* non-SUID trigger. */
- definer_user->str= 0;
- definer_user->length= 0;
+ definer_user.str= 0;
+ definer_user.length= 0;
- definer_host->str= 0;
- definer_host->length= 0;
+ definer_host.str= 0;
+ definer_host.length= 0;
trg_definer->str= (char*) "";
trg_definer->length= 0;
}
+ /*
+ Create well-formed trigger definition query. Original query is not
+ appropriated, because definer-clause can be not truncated.
+ */
+
+ stmt_query->append(STRING_WITH_LEN("CREATE "));
+
+ if (trg_definer)
+ {
+ /*
+ Append definer-clause if the trigger is SUID (a usual trigger in
+ new MySQL versions).
+ */
+
+ append_definer(thd, stmt_query, &definer_user, &definer_host);
+ }
+
+ stmt_query->append(thd->lex->stmt_definition_begin,
+ (char *) thd->lex->sphead->m_body_begin -
+ thd->lex->stmt_definition_begin +
+ thd->lex->sphead->m_body.length);
+
+ trg_def->str= stmt_query->c_ptr();
+ trg_def->length= stmt_query->length();
+
+ /* Create trigger definition file. */
+
if (!sql_create_definition_file(&dir, &file, &triggers_file_type,
(gptr)this, triggers_file_parameters, 0))
return 0;
@@ -647,15 +638,19 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db,
SYNOPSIS
drop_trigger()
- thd - current thread context (including trigger definition in LEX)
- tables - table list containing one open table for which trigger is
- dropped.
+ thd - current thread context
+ (including trigger definition in LEX)
+ tables - table list containing one open table for which trigger
+ is dropped.
+ stmt_query - [OUT] after successful return, this string contains
+ well-formed statement for creation this trigger.
RETURN VALUE
False - success
True - error
*/
-bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables)
+bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables,
+ String *stmt_query)
{
LEX *lex= thd->lex;
LEX_STRING *name;
@@ -665,6 +660,8 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables)
List_iterator<LEX_STRING> it_definer(definers_list);
char path[FN_REFLEN];
+ stmt_query->append(thd->query, thd->query_length);
+
while ((name= it_name++))
{
it_def++;
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index e736c3e0e1a..521905a2c56 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -92,10 +92,8 @@ public:
}
~Table_triggers_list();
- bool create_trigger(THD *thd, TABLE_LIST *table,
- LEX_STRING *definer_user,
- LEX_STRING *definer_host);
- bool drop_trigger(THD *thd, TABLE_LIST *table);
+ bool create_trigger(THD *thd, TABLE_LIST *table, String *stmt_query);
+ bool drop_trigger(THD *thd, TABLE_LIST *table, String *stmt_query);
bool process_triggers(THD *thd, trg_event_type event,
trg_action_time_type time_type,
bool old_row_is_record1);
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index b4ee542ac39..4e2b48d9faf 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1060,6 +1060,31 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
table->next_global= view_tables;
}
+ bool view_is_mergeable= (table->algorithm != VIEW_ALGORITHM_TMPTABLE &&
+ lex->can_be_merged());
+ TABLE_LIST *view_main_select_tables;
+ if (view_is_mergeable)
+ {
+ /*
+ Currently 'view_main_select_tables' differs from 'view_tables'
+ only then view has CONVERT_TZ() function in its select list.
+ This may change in future, for example if we enable merging of
+ views with subqueries in select list.
+ */
+ view_main_select_tables=
+ (TABLE_LIST*)lex->select_lex.table_list.first;
+
+ /*
+ Let us set proper lock type for tables of the view's main
+ select since we may want to perform update or insert on
+ view. This won't work for view containing union. But this is
+ ok since we don't allow insert and update on such views
+ anyway.
+ */
+ for (tbl= view_main_select_tables; tbl; tbl= tbl->next_local)
+ tbl->lock_type= table->lock_type;
+ }
+
/*
If we are opening this view as part of implicit LOCK TABLES, then
this view serves as simple placeholder and we should not continue
@@ -1114,43 +1139,26 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
- VIEW SELECT allow merging
- VIEW used in subquery or command support MERGE algorithm
*/
- if (table->algorithm != VIEW_ALGORITHM_TMPTABLE &&
- lex->can_be_merged() &&
+ if (view_is_mergeable &&
(table->select_lex->master_unit() != &old_lex->unit ||
old_lex->can_use_merged()) &&
!old_lex->can_not_use_merged())
{
- List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list);
- /*
- Currently 'view_main_select_tables' differs from 'view_tables'
- only then view has CONVERT_TZ() function in its select list.
- This may change in future, for example if we enable merging
- of views with subqueries in select list.
- */
- TABLE_LIST *view_main_select_tables=
- (TABLE_LIST*)lex->select_lex.table_list.first;
/* lex should contain at least one table */
DBUG_ASSERT(view_main_select_tables != 0);
+ List_iterator_fast<TABLE_LIST> ti(view_select->top_join_list);
+
table->effective_algorithm= VIEW_ALGORITHM_MERGE;
DBUG_PRINT("info", ("algorithm: MERGE"));
table->updatable= (table->updatable_view != 0);
table->effective_with_check=
old_lex->get_effective_with_check(table);
table->merge_underlying_list= view_main_select_tables;
- /*
- Let us set proper lock type for tables of the view's main select
- since we may want to perform update or insert on view. This won't
- work for view containing union. But this is ok since we don't
- allow insert and update on such views anyway.
- Also we fill correct wanted privileges.
- */
- for (tbl= table->merge_underlying_list; tbl; tbl= tbl->next_local)
- {
- tbl->lock_type= table->lock_type;
+ /* Fill correct wanted privileges. */
+ for (tbl= view_main_select_tables; tbl; tbl= tbl->next_local)
tbl->grant.want_privilege= top_view->grant.orig_want_privilege;
- }
/* prepare view context */
lex->select_lex.context.resolve_in_table_list_only(view_main_select_tables);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d2aca27c836..30c7da220a6 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -68,6 +68,34 @@ inline Item *is_truth_value(Item *A, bool v1, bool v2)
new Item_int((char *) (v1 ? "FALSE" : "TRUE"),!v1, 1));
}
+#ifndef DBUG_OFF
+#define YYDEBUG 1
+#else
+#define YYDEBUG 0
+#endif
+
+#ifndef DBUG_OFF
+void turn_parser_debug_on()
+{
+ /*
+ MYSQLdebug is in sql/sql_yacc.cc, in bison generated code.
+ Turning this option on is **VERY** verbose, and should be
+ used when investigating a syntax error problem only.
+
+ The syntax to run with bison traces is as follows :
+ - Starting a server manually :
+ mysqld --debug="d,parser_debug" ...
+ - Running a test :
+ mysql-test-run.pl --mysqld="--debug=d,parser_debug" ...
+
+ The result will be in the process stderr (var/log/master.err)
+ */
+
+ extern int yydebug;
+ yydebug= 1;
+}
+#endif
+
%}
%union {
int num;
@@ -6759,17 +6787,8 @@ flush:
FLUSH_SYM opt_no_write_to_binlog
{
LEX *lex=Lex;
- if (lex->sphead && lex->sphead->m_type != TYPE_ENUM_PROCEDURE)
- {
- /*
- Note that both FLUSH TABLES and FLUSH PRIVILEGES will break
- execution in prelocked mode. So it is better to disable
- FLUSH in stored functions and triggers completely.
- */
- my_error(ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0), "FLUSH");
- YYABORT;
- }
- lex->sql_command= SQLCOM_FLUSH; lex->type=0;
+ lex->sql_command= SQLCOM_FLUSH;
+ lex->type= 0;
lex->no_write_to_binlog= $2;
}
flush_options
@@ -7050,7 +7069,7 @@ text_literal:
| NCHAR_STRING
{ $$= new Item_string($1.str,$1.length,national_charset_info); }
| UNDERSCORE_CHARSET TEXT_STRING
- { $$ = new Item_string($2.str,$2.length,Lex->charset); }
+ { $$ = new Item_string($2.str,$2.length,Lex->underscore_charset); }
| text_literal TEXT_STRING_literal
{ ((Item_string*) $1)->append($2.str,$2.length); }
;
@@ -7128,7 +7147,7 @@ literal:
(String*) 0;
$$= new Item_string(str ? str->ptr() : "",
str ? str->length() : 0,
- Lex->charset);
+ Lex->underscore_charset);
}
| UNDERSCORE_CHARSET BIN_NUM
{
@@ -7487,6 +7506,10 @@ user:
$$->user = $1;
$$->host.str= (char *) "%";
$$->host.length= 1;
+
+ if (check_string_length(system_charset_info, &$$->user,
+ ER(ER_USERNAME), USERNAME_LENGTH))
+ YYABORT;
}
| ident_or_text '@' ident_or_text
{
@@ -7494,6 +7517,12 @@ user:
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
YYABORT;
$$->user = $1; $$->host=$3;
+
+ if (check_string_length(system_charset_info, &$$->user,
+ ER(ER_USERNAME), USERNAME_LENGTH) ||
+ check_string_length(&my_charset_latin1, &$$->host,
+ ER(ER_HOSTNAME), HOSTNAME_LENGTH))
+ YYABORT;
}
| CURRENT_USER optional_braces
{
@@ -8927,8 +8956,10 @@ subselect_end:
{
LEX *lex=Lex;
lex->pop_context();
+ SELECT_LEX *child= lex->current_select;
lex->current_select = lex->current_select->return_after_parsing();
lex->nest_level--;
+ lex->current_select->n_child_sum_items += child->n_sum_items;
};
/**************************************************************************
@@ -8971,15 +9002,9 @@ definer:
*/
YYTHD->lex->definer= 0;
}
- | DEFINER_SYM EQ CURRENT_USER optional_braces
- {
- if (! (YYTHD->lex->definer= create_default_definer(YYTHD)))
- YYABORT;
- }
- | DEFINER_SYM EQ ident_or_text '@' ident_or_text
+ | DEFINER_SYM EQ user
{
- if (!(YYTHD->lex->definer= create_definer(YYTHD, &$3, &$5)))
- YYABORT;
+ YYTHD->lex->definer= get_current_user(YYTHD, $3);
}
;
diff --git a/sql/stacktrace.c b/sql/stacktrace.c
index 838f547dc02..43f35c452f7 100644
--- a/sql/stacktrace.c
+++ b/sql/stacktrace.c
@@ -21,6 +21,7 @@
#ifdef HAVE_STACKTRACE
#include <unistd.h>
+#include <strings.h>
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
@@ -44,7 +45,29 @@ void safe_print_str(const char* name, const char* val, int max_len)
}
#ifdef TARGET_OS_LINUX
-#define SIGRETURN_FRAME_COUNT 2
+
+#ifdef __i386__
+#define SIGRETURN_FRAME_OFFSET 17
+#endif
+
+#ifdef __x86_64__
+#define SIGRETURN_FRAME_OFFSET 23
+#endif
+
+static my_bool is_nptl;
+
+/* Check if we are using NPTL or LinuxThreads on Linux */
+void check_thread_lib(void)
+{
+ char buf[5];
+
+#ifdef _CS_GNU_LIBPTHREAD_VERSION
+ confstr(_CS_GNU_LIBPTHREAD_VERSION, buf, sizeof(buf));
+ is_nptl = !strncasecmp(buf, "NPTL", sizeof(buf));
+#else
+ is_nptl = 0;
+#endif
+}
#if defined(__alpha__) && defined(__GNUC__)
/*
@@ -90,7 +113,7 @@ inline uint32* find_prev_pc(uint32* pc, uchar** fp)
void print_stacktrace(gptr stack_bottom, ulong thread_stack)
{
uchar** fp;
- uint frame_count = 0;
+ uint frame_count = 0, sigreturn_frame_count;
#if defined(__alpha__) && defined(__GNUC__)
uint32* pc;
#endif
@@ -100,28 +123,27 @@ void print_stacktrace(gptr stack_bottom, ulong thread_stack)
Attempting backtrace. You can use the following information to find out\n\
where mysqld died. If you see no messages after this, something went\n\
terribly wrong...\n");
-#ifdef __i386__
+#ifdef __i386__
__asm __volatile__ ("movl %%ebp,%0"
:"=r"(fp)
:"r"(fp));
- if (!fp)
- {
- fprintf(stderr, "frame pointer (ebp) is NULL, did you compile with\n\
--fomit-frame-pointer? Aborting backtrace!\n");
- return;
- }
+#endif
+#ifdef __x86_64__
+ __asm __volatile__ ("movq %%rbp,%0"
+ :"=r"(fp)
+ :"r"(fp));
#endif
#if defined(__alpha__) && defined(__GNUC__)
__asm __volatile__ ("mov $30,%0"
:"=r"(fp)
:"r"(fp));
+#endif
if (!fp)
{
- fprintf(stderr, "frame pointer (fp) is NULL, did you compile with\n\
+ fprintf(stderr, "frame pointer is NULL, did you compile with\n\
-fomit-frame-pointer? Aborting backtrace!\n");
return;
}
-#endif /* __alpha__ */
if (!stack_bottom || (gptr) stack_bottom > (gptr) &fp)
{
@@ -151,13 +173,16 @@ terribly wrong...\n");
:"r"(pc));
#endif /* __alpha__ */
+ /* We are 1 frame above signal frame with NPTL and 2 frames above with LT */
+ sigreturn_frame_count = is_nptl ? 1 : 2;
+
while (fp < (uchar**) stack_bottom)
{
-#ifdef __i386__
+#if defined(__i386__) || defined(__x86_64__)
uchar** new_fp = (uchar**)*fp;
- fprintf(stderr, "%p\n", frame_count == SIGRETURN_FRAME_COUNT ?
- *(fp+17) : *(fp+1));
-#endif /* __386__ */
+ fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
+ *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
+#endif /* defined(__386__) || defined(__x86_64__) */
#if defined(__alpha__) && defined(__GNUC__)
uchar** new_fp = find_prev_fp(pc, fp);
diff --git a/sql/stacktrace.h b/sql/stacktrace.h
index d5d1e05ef0e..527d10d70a2 100644
--- a/sql/stacktrace.h
+++ b/sql/stacktrace.h
@@ -19,16 +19,20 @@ extern "C" {
#endif
#ifdef TARGET_OS_LINUX
-#if defined(HAVE_STACKTRACE) || (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
+#if defined(HAVE_STACKTRACE) || (defined (__x86_64__) || defined (__i386__) || (defined(__alpha__) && defined(__GNUC__)))
#undef HAVE_STACKTRACE
#define HAVE_STACKTRACE
extern char* __bss_start;
extern char* heap_start;
-#define init_stacktrace() { heap_start = (char*) &__bss_start; }
+#define init_stacktrace() do { \
+ heap_start = (char*) &__bss_start; \
+ check_thread_lib(); \
+ } while(0);
void print_stacktrace(gptr stack_bottom, ulong thread_stack);
void safe_print_str(const char* name, const char* val, int max_len);
+void check_thread_lib(void);
#endif /* (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */
#endif /* TARGET_OS_LINUX */
diff --git a/sql/table.cc b/sql/table.cc
index 0a95461cf06..054736401ff 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1592,7 +1592,7 @@ char *get_field(MEM_ROOT *mem, Field *field)
bool check_db_name(char *name)
{
- char *start=name;
+ uint name_length= 0; // name length in symbols
/* Used to catch empty names and names with end space */
bool last_char_is_space= TRUE;
@@ -1609,6 +1609,7 @@ bool check_db_name(char *name)
name+system_charset_info->mbmaxlen);
if (len)
{
+ name_length++;
name += len;
continue;
}
@@ -1616,12 +1617,13 @@ bool check_db_name(char *name)
#else
last_char_is_space= *name==' ';
#endif
+ name_length++;
if (*name == '/' || *name == '\\' || *name == FN_LIBCHAR ||
*name == FN_EXTCHAR)
return 1;
name++;
}
- return last_char_is_space || (uint) (name - start) > NAME_LEN;
+ return (last_char_is_space || name_length > NAME_LEN);
}
diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt
new file mode 100755
index 00000000000..0c65ce390b2
--- /dev/null
+++ b/strings/CMakeLists.txt
@@ -0,0 +1,12 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+ADD_LIBRARY(strings bchange.c bcmp.c bfill.c bmove512.c bmove_upp.c ctype-big5.c ctype-bin.c ctype-cp932.c
+ ctype-czech.c ctype-euc_kr.c ctype-eucjpms.c ctype-extra.c ctype-gb2312.c ctype-gbk.c
+ ctype-latin1.c ctype-mb.c ctype-simple.c ctype-sjis.c ctype-tis620.c ctype-uca.c
+ ctype-ucs2.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype.c decimal.c int2str.c
+ is_prefix.c llstr.c longlong2str.c my_strtoll10.c my_vsnprintf.c r_strinstr.c
+ str2int.c str_alloc.c strcend.c strend.c strfill.c strmake.c strmov.c strnmov.c
+ strtod.c strtol.c strtoll.c strtoul.c strtoull.c strxmov.c strxnmov.c xml.c
+ strcont.c strinstr.c)
diff --git a/strings/Makefile.am b/strings/Makefile.am
index 7ee115c09e5..255bc4e1518 100644
--- a/strings/Makefile.am
+++ b/strings/Makefile.am
@@ -53,7 +53,7 @@ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc
bmove_upp-sparc.s strappend-sparc.s strend-sparc.s \
strinstr-sparc.s strmake-sparc.s strmov-sparc.s \
strnmov-sparc.s strstr-sparc.s strxmov-sparc.s \
- t_ctype.h
+ t_ctype.h CMakeLists.txt
libmystrings_a_LIBADD=
conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c bcmp.c
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index b4942072e5d..eefc4f55d35 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -677,6 +677,9 @@ fi
%attr(755, root, root) %{_bindir}/ndb_show_tables
%attr(755, root, root) %{_bindir}/ndb_test_platform
%attr(755, root, root) %{_bindir}/ndb_config
+%attr(755, root, root) %{_bindir}/ndb_error_reporter
+%attr(755, root, root) %{_bindir}/ndb_size.pl
+%attr(-, root, root) %{_datadir}/mysql/ndb_size.tmpl
%files ndb-extra
%defattr(-,root,root,0755)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100755
index 00000000000..46c42d461f3
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,9 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+ADD_DEFINITIONS("-DMYSQL_CLIENT")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+
+ADD_EXECUTABLE(mysql_client_test mysql_client_test.c)
+TARGET_LINK_LIBRARIES(mysql_client_test dbug mysys mysqlclient yassl taocrypt zlib wsock32)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ab747d6e4ec..3eb3d39de1e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -29,7 +29,8 @@ EXTRA_DIST = auto_increment.res auto_increment.tst \
insert_and_repair.pl \
grant.pl grant.res test_delayed_insert.pl \
pmail.pl mail_to_db.pl table_types.pl \
- udf_test udf_test.res myisam-big-rows.tst
+ udf_test udf_test.res myisam-big-rows.tst \
+ CMakeLists.txt
bin_PROGRAMS = mysql_client_test
noinst_PROGRAMS = insert_test select_test thread_test
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 427994f832f..8a444590301 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -10444,8 +10444,9 @@ static void test_ps_i18n()
const char *stmt_text;
MYSQL_BIND bind_array[2];
- const char *koi8= "îÕ, ÚÁ ÒÙÂÁÌËÕ";
- const char *cp1251= "Íó, çà ðûáàëêó";
+ /* Represented as numbers to keep UTF8 tools from clobbering them. */
+ const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
+ const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
char buf1[16], buf2[16];
ulong buf1_len, buf2_len;
@@ -14912,22 +14913,31 @@ static void test_bug15613()
/*
Bug#17667: An attacker has the opportunity to bypass query logging.
+
+ Note! Also tests Bug#21813, where prepared statements are used to
+ run queries
*/
static void test_bug17667()
{
int rc;
+ MYSQL_STMT *stmt;
+ enum query_type { QT_NORMAL, QT_PREPARED};
struct buffer_and_length {
+ enum query_type qt;
const char *buffer;
const uint length;
} statements[]= {
- { "drop table if exists bug17667", 29 },
- { "create table bug17667 (c varchar(20))", 37 },
- { "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
- { "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
- { "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
- { "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
- { "drop table bug17667", 19 },
- { NULL, 0 } };
+ { QT_NORMAL, "drop table if exists bug17667", 29 },
+ { QT_NORMAL, "create table bug17667 (c varchar(20))", 37 },
+ { QT_NORMAL, "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
+ { QT_PREPARED,
+ "insert into bug17667 (c) values ('prepared') /* NUL=\0 with comment */", 69, },
+ { QT_NORMAL, "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
+ { QT_NORMAL, "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
+ { QT_PREPARED, "insert into bug17667 (c) values ('6 NULs=\0\0\0\0\0\0')", 50 },
+ { QT_NORMAL, "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
+ { QT_NORMAL, "drop table bug17667", 19 },
+ { QT_NORMAL, NULL, 0 } };
struct buffer_and_length *statement_cursor;
FILE *log_file;
@@ -14937,9 +14947,36 @@ static void test_bug17667()
for (statement_cursor= statements; statement_cursor->buffer != NULL;
statement_cursor++) {
- rc= mysql_real_query(mysql, statement_cursor->buffer,
- statement_cursor->length);
- myquery(rc);
+ if (statement_cursor->qt == QT_NORMAL)
+ {
+ /* Run statement as normal query */
+ rc= mysql_real_query(mysql, statement_cursor->buffer,
+ statement_cursor->length);
+ myquery(rc);
+ }
+ else if (statement_cursor->qt == QT_PREPARED)
+ {
+ /*
+ Run as prepared statement
+
+ NOTE! All these queries should be in the log twice,
+ one time for prepare and one time for execute
+ */
+ stmt= mysql_stmt_init(mysql);
+
+ rc= mysql_stmt_prepare(stmt, statement_cursor->buffer,
+ statement_cursor->length);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_execute(stmt);
+ check_execute(stmt, rc);
+
+ mysql_stmt_close(stmt);
+ }
+ else
+ {
+ assert(0==1);
+ }
}
/* Make sure the server has written the logs to disk before reading it */
@@ -14957,29 +14994,36 @@ static void test_bug17667()
for (statement_cursor= statements; statement_cursor->buffer != NULL;
statement_cursor++) {
+ int expected_hits= 1, hits= 0;
char line_buffer[MAX_TEST_QUERY_LENGTH*2];
/* more than enough room for the query and some marginalia. */
+ /* Prepared statments always occurs twice in log */
+ if (statement_cursor->qt == QT_PREPARED)
+ expected_hits++;
+
+ /* Loop until we found expected number of log entries */
do {
- memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
+ /* Loop until statement is found in log */
+ do {
+ memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
- if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
- {
- /* If fgets returned NULL, it indicates either error or EOF */
- if (feof(log_file))
- DIE("Found EOF before all statements where found");
- else
+ if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
{
+ /* If fgets returned NULL, it indicates either error or EOF */
+ if (feof(log_file))
+ DIE("Found EOF before all statements where found");
+
fprintf(stderr, "Got error %d while reading from file\n",
ferror(log_file));
DIE("Read error");
}
- }
- /* Print the line */
- printf("%s", line_buffer);
- } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
- statement_cursor->buffer, statement_cursor->length) == NULL);
+ } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
+ statement_cursor->buffer,
+ statement_cursor->length) == NULL);
+ hits++;
+ } while (hits < expected_hits);
printf("Found statement starting with \"%s\"\n",
statement_cursor->buffer);
diff --git a/vio/CMakeLists.txt b/vio/CMakeLists.txt
new file mode 100755
index 00000000000..a3cbb304289
--- /dev/null
+++ b/vio/CMakeLists.txt
@@ -0,0 +1,6 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX")
+
+ADD_DEFINITIONS(-DUSE_SYMDIR)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/extra/yassl/include)
+ADD_LIBRARY(vio vio.c viosocket.c viossl.c viosslfactories.c)
diff --git a/vio/Makefile.am b/vio/Makefile.am
index e89191d57cd..cb70501046e 100644
--- a/vio/Makefile.am
+++ b/vio/Makefile.am
@@ -38,6 +38,6 @@ test_sslclient_LDADD= @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \
../mysys/libmysys.a ../strings/libmystrings.a \
$(openssl_libs) $(yassl_libs)
libvio_a_SOURCES= vio.c viosocket.c viossl.c viosslfactories.c
-
+EXTRA_DIST= CMakeLists.txt
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/vio/viosocket.c b/vio/viosocket.c
index 710f7a93607..1f348c3313d 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -379,16 +379,30 @@ my_bool vio_poll_read(Vio *vio,uint timeout)
}
-void vio_timeout(Vio *vio __attribute__((unused)),
- uint which __attribute__((unused)),
- uint timeout __attribute__((unused)))
+void vio_timeout(Vio *vio, uint which, uint timeout)
{
+/* TODO: some action should be taken if socket timeouts are not supported. */
+#if defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)
+
#ifdef __WIN__
- ulong wait_timeout= (ulong) timeout * 1000;
- (void) setsockopt(vio->sd, SOL_SOCKET,
- which ? SO_SNDTIMEO : SO_RCVTIMEO, (char*) &wait_timeout,
- sizeof(wait_timeout));
-#endif /* __WIN__ */
+
+ /* Windows expects time in milliseconds as int. */
+ int wait_timeout= (int) timeout * 1000;
+
+#else /* ! __WIN__ */
+
+ /* POSIX specifies time as struct timeval. */
+ struct timeval wait_timeout;
+ wait_timeout.tv_sec= timeout;
+ wait_timeout.tv_usec= 0;
+
+#endif /* ! __WIN__ */
+
+ /* TODO: return value should be checked. */
+ (void) setsockopt(vio->sd, SOL_SOCKET, which ? SO_SNDTIMEO : SO_RCVTIMEO,
+ (char*) &wait_timeout, sizeof(wait_timeout));
+
+#endif /* defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO) */
}
diff --git a/win/Makefile.am b/win/Makefile.am
new file mode 100755
index 00000000000..05c01b61360
--- /dev/null
+++ b/win/Makefile.am
@@ -0,0 +1,21 @@
+# Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+## Process this file with automake to create Makefile.in
+EXTRA_DIST = build-vs71.bat build-vs8.bat build-vs8_x64.bat configure.js README
+
+# Don't update the files from bitkeeper
+%::SCCS/s.%
diff --git a/win/README b/win/README
new file mode 100644
index 00000000000..cbda33e1184
--- /dev/null
+++ b/win/README
@@ -0,0 +1,82 @@
+Windows building readme
+======================================
+
+----------------IMPORTANT----------------------------
+This readme outlines the instructions for building
+MySQL for Windows staring from version 5.0.
+This readme does not apply to MySQL versions 5.1
+or ealier.
+-----------------------------------------------------
+
+The Windows build system uses a tool named CMake to generate build files for
+a variety of project systems. This tool is combined with a set of jscript
+files to enable building of MySQL for Windows directly out of a bk clone.
+The steps required are below.
+
+Step 1
+------
+Download and install CMake. It can be downloaded from http://www.cmake.org.
+Once it is installed, modify your path to make sure you can execute
+the cmake binary.
+
+Step 2
+------
+Download and install bison for Windows. It can be downloaded from
+http://gnuwin32.sourceforge.net/packages/bison.htm. Please download using
+the link named "Complete package, excluding sources". This includes an
+installer that will install bison. After the installer finishes, modify
+your path so that you can execute bison.
+
+Step 3
+------
+Clone your bk tree to any location you like.
+
+Step 4
+------
+From the root of your bk clone, execute the command: win\configure <options>.
+The options right now are
+
+ WITH_INNOBASE_STORAGE_ENGINE Enable particular storage engines
+ WITH_PARTITION_STORAGE_ENGINE
+ WITH_ARCHIVE_STORAGE_ENGINE
+ WITH_BERKELEY_STORAGE_ENGINE
+ WITH_BLACKHOLE_STORAGE_ENGINE
+ WITH_EXAMPLE_STORAGE_ENGINE
+ WITH_FEDERATED_STORAGE_ENGINE
+ WITH_INNOBASE_STORAGE_ENGINE
+ __NT__ Enable named pipe support
+ MYSQL_SERVER_SUFFIX=<suffix> Server suffix, default none
+ COMPILATION_COMMENT=<comment> Server comment, default "Source distribution"
+ MYSQL_TCP_PORT=<port> Server port, default 3306
+ CYBOZU
+
+So the command line could look like:
+
+win\configure WITH_INNOBASE_STORAGE_ENGINE WITH_PARTITION_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-pro
+
+Step 5
+------
+From the root of your bk clone, execute one of the batch files to generate the type
+of project files you desire.
+
+For Visual Studio 8, do win\build-vs8.
+For Visual Studio 7.1, do win\build-vs71.
+
+We will support building with nmake in the near future.
+
+Step 6
+------
+From the root of your bk clone, start your build.
+
+For Visual Studio, simply execute mysql.sln. This will start the IDE and you can
+click the build solution menu option.
+
+Current issues
+--------------
+1. After changing configuration (eg. adding or removing a storage engine), it
+may be necessary to clean the build tree to remove any stale objects.
+
+2. To use Visual C++ Express Edition you also need to install the Platform SDK.
+Please see this link: http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/
+At step 4 you only need to add the libraries advapi32.lib and user32.lib to
+the file "corewin_express.vsprops" in order to avoid link errors.
diff --git a/win/build-vs71.bat b/win/build-vs71.bat
new file mode 100755
index 00000000000..959067695c5
--- /dev/null
+++ b/win/build-vs71.bat
@@ -0,0 +1,7 @@
+@echo off
+
+if exist cmakecache.txt del cmakecache.txt
+copy win\vs71cache.txt cmakecache.txt
+cmake -G "Visual Studio 7 .NET 2003"
+copy cmakecache.txt win\vs71cache.txt
+
diff --git a/win/build-vs8.bat b/win/build-vs8.bat
new file mode 100755
index 00000000000..d9c06241a9b
--- /dev/null
+++ b/win/build-vs8.bat
@@ -0,0 +1,6 @@
+@echo off
+
+if exist cmakecache.txt del cmakecache.txt
+copy win\vs8cache.txt cmakecache.txt
+cmake -G "Visual Studio 8 2005"
+copy cmakecache.txt win\vs8cache.txt
diff --git a/win/build-vs8_x64.bat b/win/build-vs8_x64.bat
new file mode 100755
index 00000000000..f1d96116390
--- /dev/null
+++ b/win/build-vs8_x64.bat
@@ -0,0 +1,6 @@
+@echo off
+
+if exist cmakecache.txt del cmakecache.txt
+copy win\vs8cache.txt cmakecache.txt
+cmake -G "Visual Studio 8 2005 Win64"
+copy cmakecache.txt win\vs8cache.txt
diff --git a/win/configure.js b/win/configure.js
new file mode 100755
index 00000000000..ef90ce982a6
--- /dev/null
+++ b/win/configure.js
@@ -0,0 +1,166 @@
+// Configure.js
+
+ForReading = 1;
+ForWriting = 2;
+ForAppending = 8;
+
+try
+{
+ var fso = new ActiveXObject("Scripting.FileSystemObject");
+
+ var args = WScript.Arguments
+
+ // read in the Unix configure.in file
+ var configureInTS = fso.OpenTextFile("configure.in", ForReading);
+ var configureIn = configureInTS.ReadAll();
+ configureInTS.Close();
+ var default_comment = "Source distribution";
+ var default_port = GetValue(configureIn, "MYSQL_TCP_PORT_DEFAULT");
+
+ var configfile = fso.CreateTextFile("win\\configure.data", true);
+ for (i=0; i < args.Count(); i++)
+ {
+ var parts = args.Item(i).split('=');
+ switch (parts[0])
+ {
+ case "WITH_ARCHIVE_STORAGE_ENGINE":
+ case "WITH_BERKELEY_STORAGE_ENGINE":
+ case "WITH_BLACKHOLE_STORAGE_ENGINE":
+ case "WITH_EXAMPLE_STORAGE_ENGINE":
+ case "WITH_FEDERATED_STORAGE_ENGINE":
+ case "WITH_INNOBASE_STORAGE_ENGINE":
+ case "WITH_PARTITION_STORAGE_ENGINE":
+ case "__NT__":
+ case "CYBOZU":
+ configfile.WriteLine("SET (" + args.Item(i) + " TRUE)");
+ break;
+ case "MYSQL_SERVER_SUFFIX":
+ configfile.WriteLine("SET (" + parts[0] + " \""
+ + parts[1] + "\")");
+ break;
+ case "COMPILATION_COMMENT":
+ default_comment = parts[1];
+ break;
+ case "MYSQL_TCP_PORT":
+ default_port = parts[1];
+ break;
+ }
+ }
+
+ configfile.WriteLine("SET (COMPILATION_COMMENT \"" +
+ default_comment + "\")");
+
+ configfile.WriteLine("SET (PROTOCOL_VERSION \"" +
+ GetValue(configureIn, "PROTOCOL_VERSION") + "\")");
+ configfile.WriteLine("SET (DOT_FRM_VERSION \"" +
+ GetValue(configureIn, "DOT_FRM_VERSION") + "\")");
+ configfile.WriteLine("SET (MYSQL_TCP_PORT \"" + default_port + "\")");
+ configfile.WriteLine("SET (MYSQL_UNIX_ADDR \"" +
+ GetValue(configureIn, "MYSQL_UNIX_ADDR_DEFAULT") + "\")");
+ var version = GetVersion(configureIn);
+ configfile.WriteLine("SET (VERSION \"" + version + "\")");
+ configfile.WriteLine("SET (MYSQL_BASE_VERSION \"" +
+ GetBaseVersion(version) + "\")");
+ configfile.WriteLine("SET (MYSQL_VERSION_ID \"" +
+ GetVersionId(version) + "\")");
+
+ configfile.Close();
+
+ //ConfigureBDB();
+
+ fso = null;
+
+ WScript.Echo("done!");
+}
+catch (e)
+{
+ WScript.Echo("Error: " + e.description);
+}
+
+function GetValue(str, key)
+{
+ var pos = str.indexOf(key+'=');
+ if (pos == -1) return null;
+ pos += key.length + 1;
+ var end = str.indexOf("\n", pos);
+ if (str.charAt(pos) == "\"")
+ pos++;
+ if (str.charAt(end-1) == "\"")
+ end--;
+ return str.substring(pos, end);
+}
+
+function GetVersion(str)
+{
+ var key = "AM_INIT_AUTOMAKE(mysql, ";
+ var pos = str.indexOf(key); //5.0.6-beta)
+ if (pos == -1) return null;
+ pos += key.length;
+ var end = str.indexOf(")", pos);
+ if (end == -1) return null;
+ return str.substring(pos, end);
+}
+
+function GetBaseVersion(version)
+{
+ var dot = version.indexOf(".");
+ if (dot == -1) return null;
+ dot = version.indexOf(".", dot+1);
+ if (dot == -1) dot = version.length;
+ return version.substring(0, dot);
+}
+
+function GetVersionId(version)
+{
+ var dot = version.indexOf(".");
+ if (dot == -1) return null;
+ var major = parseInt(version.substring(0, dot), 10);
+
+ dot++;
+ var nextdot = version.indexOf(".", dot);
+ if (nextdot == -1) return null;
+ var minor = parseInt(version.substring(dot, nextdot), 10);
+ dot = nextdot+1;
+
+ var stop = version.indexOf("-", dot);
+ if (stop == -1) stop = version.length;
+ var build = parseInt(version.substring(dot, stop), 10);
+
+ var id = major;
+ if (minor < 10)
+ id += '0';
+ id += minor;
+ if (build < 10)
+ id += '0';
+ id += build;
+ return id;
+}
+
+function ConfigureBDB()
+{
+ // read in the Unix configure.in file
+ var dbIncTS = fso.OpenTextFile("..\\bdb\\dbinc\\db.in", ForReading);
+ var dbIn = dbIncTS.ReadAll();
+ dbIncTS.Close();
+
+ dbIn = dbIn.replace("@DB_VERSION_MAJOR@", "$DB_VERSION_MAJOR");
+ dbIn = dbIn.replace("@DB_VERSION_MINOR@", "$DB_VERSION_MINOR");
+ dbIn = dbIn.replace("@DB_VERSION_PATCH@", "$DB_VERSION_PATCH");
+ dbIn = dbIn.replace("@DB_VERSION_STRING@", "$DB_VERSION_STRING");
+
+ dbIn = dbIn.replace("@u_int8_decl@", "typedef unsigned char u_int8_t;");
+ dbIn = dbIn.replace("@int16_decl@", "typedef short int16_t;");
+ dbIn = dbIn.replace("@u_int16_decl@", "typedef unsigned short u_int16_t;");
+ dbIn = dbIn.replace("@int32_decl@", "typedef int int32_t;");
+ dbIn = dbIn.replace("@u_int32_decl@", "typedef unsigned int u_int32_t;");
+
+ dbIn = dbIn.replace("@u_char_decl@", "{\r\n#if !defined(_WINSOCKAPI_)\r\n" +
+ "typedef unsigned char u_char;");
+ dbIn = dbIn.replace("@u_short_decl@", "typedef unsigned short u_short;");
+ dbIn = dbIn.replace("@u_int_decl@", "typedef unsigned int u_int;");
+ dbIn = dbIn.replace("@u_long_decl@", "typedef unsigned long u_long;");
+
+ dbIn = dbIn.replace("@ssize_t_decl@", "#endif\r\n#if defined(_WIN64)\r\n" +
+ "typedef __int64 ssize_t;\r\n#else\r\n" +
+ "typedef int ssize_t;\r\n#endif");
+}
diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt
new file mode 100755
index 00000000000..53560adf6d1
--- /dev/null
+++ b/zlib/CMakeLists.txt
@@ -0,0 +1,8 @@
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG")
+
+ADD_DEFINITIONS(-DUSE_TLS -DMYSQL_CLIENT -D__WIN32__)
+ADD_LIBRARY(zlib adler32.c compress.c crc32.c crc32.h deflate.c deflate.h gzio.c infback.c inffast.c inffast.h
+ inffixed.h inflate.c inflate.h inftrees.c inftrees.h trees.c trees.h uncompr.c zconf.h zlib.h
+ zutil.c zutil.h)
+ \ No newline at end of file
diff --git a/zlib/Makefile.am b/zlib/Makefile.am
index 71619ce40c1..0081c93a2ae 100644
--- a/zlib/Makefile.am
+++ b/zlib/Makefile.am
@@ -29,5 +29,5 @@ libz_la_SOURCES= adler32.c compress.c crc32.c deflate.c gzio.c \
infback.c inffast.c inflate.c inftrees.c trees.c \
uncompr.c zutil.c
-EXTRA_DIST= README FAQ INDEX ChangeLog algorithm.txt zlib.3
+EXTRA_DIST= README FAQ INDEX ChangeLog algorithm.txt zlib.3 CMakeLists.txt