summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xBUILD/SETUP.sh25
-rwxr-xr-xBUILD/compile-amd64-gcov17
-rwxr-xr-xBUILD/compile-amd64-gprof9
-rwxr-xr-xBUILD/compile-pentium-gcov13
-rwxr-xr-xBUILD/compile-pentium-gprof4
-rwxr-xr-xBUILD/compile-pentium64-gcov17
-rwxr-xr-xBUILD/compile-pentium64-gprof9
-rwxr-xr-xCMakeLists.txt116
-rwxr-xr-xclient/CMakeLists.txt114
-rw-r--r--client/mysql.cc54
-rw-r--r--client/mysql_upgrade.c72
-rw-r--r--client/mysqltest.c937
-rw-r--r--configure.in4
-rwxr-xr-xdbug/CMakeLists.txt12
-rwxr-xr-xextra/CMakeLists.txt8
-rwxr-xr-xextra/yassl/CMakeLists.txt12
-rw-r--r--extra/yassl/include/openssl/crypto.h1
-rw-r--r--extra/yassl/include/openssl/des_old.h1
-rw-r--r--extra/yassl/include/openssl/evp.h10
-rw-r--r--extra/yassl/include/openssl/hmac.h1
-rw-r--r--extra/yassl/include/openssl/objects.h1
-rw-r--r--extra/yassl/include/openssl/prefix_ssl.h3
-rw-r--r--extra/yassl/include/openssl/sha.h1
-rw-r--r--extra/yassl/include/openssl/ssl.h3
-rw-r--r--extra/yassl/include/yassl_int.hpp2
-rw-r--r--extra/yassl/src/handshake.cpp4
-rw-r--r--extra/yassl/src/socket_wrapper.cpp4
-rw-r--r--extra/yassl/src/ssl.cpp6
-rw-r--r--extra/yassl/src/yassl_int.cpp1
-rwxr-xr-xextra/yassl/taocrypt/CMakeLists.txt8
-rw-r--r--extra/yassl/taocrypt/src/coding.cpp5
-rw-r--r--extra/yassl/taocrypt/src/crypto.cpp5
-rw-r--r--include/my_pthread.h32
-rw-r--r--innobase/fsp/fsp0fsp.c7
-rw-r--r--innobase/include/fsp0fsp.h2
-rw-r--r--innobase/include/univ.i2
-rw-r--r--innobase/log/log0recv.c225
-rw-r--r--innobase/os/os0file.c3
-rw-r--r--innobase/srv/srv0srv.c2
-rw-r--r--innobase/trx/trx0trx.c12
-rwxr-xr-xlibmysql/CMakeLists.txt93
-rw-r--r--libmysql/libmysql.c10
-rwxr-xr-xmyisam/CMakeLists.txt8
-rw-r--r--myisam/mi_rkey.c81
-rwxr-xr-xmyisam/mi_test_all.sh256
-rw-r--r--myisam/myisamchk.c4
-rw-r--r--mysql-test/lib/mtr_misc.pl86
-rw-r--r--mysql-test/lib/mtr_process.pl21
-rw-r--r--mysql-test/lib/mtr_report.pl123
-rw-r--r--mysql-test/lib/mtr_timer.pl31
-rwxr-xr-xmysql-test/mysql-test-run.pl117
-rw-r--r--mysql-test/r/comments.result15
-rw-r--r--mysql-test/r/ctype_ascii.result177
-rw-r--r--mysql-test/r/federated.result14
-rw-r--r--mysql-test/r/handler.result20
-rw-r--r--mysql-test/r/information_schema.result26
-rw-r--r--mysql-test/r/information_schema_db.result2
-rw-r--r--mysql-test/r/innodb-deadlock.result11
-rw-r--r--mysql-test/r/innodb_mysql.result18
-rw-r--r--mysql-test/r/mysql.result2
-rw-r--r--mysql-test/r/mysqltest.result25
-rw-r--r--mysql-test/r/parser_precedence.result747
-rw-r--r--mysql-test/r/query_cache.result29
-rw-r--r--mysql-test/r/query_cache_with_views.result (renamed from mysql-test/r/view_query_cache.result)0
-rw-r--r--mysql-test/r/rpl_timezone.result18
-rw-r--r--mysql-test/r/select.result67
-rw-r--r--mysql-test/r/sp.result53
-rw-r--r--mysql-test/r/type_bit.result24
-rw-r--r--mysql-test/t/backup.test11
-rw-r--r--mysql-test/t/bootstrap.test7
-rw-r--r--mysql-test/t/comments.test33
-rw-r--r--mysql-test/t/ctype_ascii.test13
-rw-r--r--mysql-test/t/federated.test14
-rw-r--r--mysql-test/t/handler.test33
-rw-r--r--mysql-test/t/information_schema.test26
-rw-r--r--mysql-test/t/information_schema_chmod.test2
-rw-r--r--mysql-test/t/innodb-deadlock.test27
-rw-r--r--mysql-test/t/innodb_mysql.test28
-rw-r--r--mysql-test/t/loaddata.test22
-rw-r--r--mysql-test/t/myisam.test6
-rw-r--r--mysql-test/t/mysql.test8
-rw-r--r--mysql-test/t/mysqladmin.test3
-rw-r--r--mysql-test/t/mysqltest.test125
-rw-r--r--mysql-test/t/parser_precedence.test333
-rw-r--r--mysql-test/t/ps.test3
-rw-r--r--mysql-test/t/query_cache.test33
-rw-r--r--mysql-test/t/query_cache_with_views.test (renamed from mysql-test/t/view_query_cache.test)0
-rw-r--r--mysql-test/t/rpl_relayspace.test16
-rw-r--r--mysql-test/t/rpl_ssl.test15
-rw-r--r--mysql-test/t/rpl_timezone.test29
-rw-r--r--mysql-test/t/select.test90
-rw-r--r--mysql-test/t/sp-destruct.test1
-rw-r--r--mysql-test/t/sp.test55
-rw-r--r--mysql-test/t/type_bit.test19
-rwxr-xr-xmysys/CMakeLists.txt17
-rw-r--r--mysys/my_thr_init.c17
-rw-r--r--mysys/thr_lock.c40
-rwxr-xr-xnetware/BUILD/compile-netware-END11
-rw-r--r--netware/Makefile.am16
-rw-r--r--netware/isamchk.def12
-rw-r--r--netware/isamlog.def11
-rw-r--r--netware/pack_isam.def13
-rwxr-xr-xscripts/CMakeLists.txt2
-rw-r--r--scripts/Makefile.am6
-rwxr-xr-xscripts/make_win_bin_dist93
-rw-r--r--scripts/make_win_src_distribution_old.sh (renamed from scripts/make_win_src_distribution.sh)8
-rw-r--r--scripts/mysqlhotcopy.sh32
-rwxr-xr-xserver-tools/instance-manager/CMakeLists.txt2
-rwxr-xr-xsql/CMakeLists.txt7
-rw-r--r--sql/field.cc6
-rw-r--r--sql/field.h13
-rw-r--r--sql/ha_innodb.cc29
-rw-r--r--sql/handler.cc3
-rw-r--r--sql/item.cc4
-rw-r--r--sql/item_cmpfunc.h19
-rw-r--r--sql/lock.cc3
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/mysqld.cc10
-rw-r--r--sql/opt_range.cc3
-rw-r--r--sql/share/charsets/ascii.xml6
-rw-r--r--sql/share/errmsg.txt2
-rw-r--r--sql/sql_base.cc18
-rw-r--r--sql/sql_cache.cc103
-rw-r--r--sql/sql_cache.h8
-rw-r--r--sql/sql_handler.cc131
-rw-r--r--sql/sql_insert.cc11
-rw-r--r--sql/sql_lex.cc38
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_parse.cc32
-rw-r--r--sql/sql_select.cc57
-rw-r--r--sql/sql_show.cc17
-rw-r--r--sql/sql_table.cc5
-rw-r--r--sql/sql_trigger.cc2
-rw-r--r--sql/sql_view.cc6
-rw-r--r--sql/sql_yacc.yy247
-rw-r--r--sql/time.cc2
-rw-r--r--sql/unireg.h2
-rw-r--r--strings/ctype-extra.c6
-rwxr-xr-xtests/CMakeLists.txt10
-rw-r--r--tests/mysql_client_test.c128
-rw-r--r--vio/viossl.c142
-rw-r--r--win/README3
-rwxr-xr-xwin/configure.js1
-rwxr-xr-xzlib/CMakeLists.txt15
144 files changed, 4541 insertions, 1627 deletions
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 10324c22e56..532ea4eb0f1 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -138,3 +138,28 @@ then
echo "$CC" | grep "ccache" > /dev/null || CC="ccache $CC"
echo "$CXX" | grep "ccache" > /dev/null || CXX="ccache $CXX"
fi
+
+# gcov
+
+# The -fprofile-arcs and -ftest-coverage options cause GCC to instrument the
+# code with profiling information used by gcov.
+# The -DDISABLE_TAO_ASM is needed to avoid build failures in Yassl.
+# The -DHAVE_gcov enables code to write out coverage info even when crashing.
+
+gcov_compile_flags="-fprofile-arcs -ftest-coverage"
+gcov_compile_flags="$gcov_compile_flags -DDISABLE_TAO_ASM"
+gcov_compile_flags="$gcov_compile_flags -DMYSQL_SERVER_SUFFIX=-gcov -DHAVE_gcov"
+
+# GCC4 needs -fprofile-arcs -ftest-coverage on the linker command line (as well
+# as on the compiler command line), and this requires setting LDFLAGS for BDB.
+
+gcov_link_flags="-fprofile-arcs -ftest-coverage"
+
+gcov_configs="--disable-shared"
+
+# gprof
+
+gprof_compile_flags="-O2 -pg -g"
+
+gprof_link_flags="--disable-shared $static_link"
+
diff --git a/BUILD/compile-amd64-gcov b/BUILD/compile-amd64-gcov
new file mode 100755
index 00000000000..239a4aed0fb
--- /dev/null
+++ b/BUILD/compile-amd64-gcov
@@ -0,0 +1,17 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+# Need to disable ccache, or we loose the gcov-needed compiler output files.
+CCACHE_DISABLE=1
+export CCACHE_DISABLE
+
+export LDFLAGS="$gcov_link_flags"
+
+extra_flags="$amd64_cflags $debug_cflags $max_cflags $gcov_compile_flags"
+c_warnings="$c_warnings $debug_extra_warnings"
+cxx_warnings="$cxx_warnings $debug_extra_warnings"
+extra_configs="$amd64_configs $debug_configs $gcov_configs $max_configs"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-amd64-gprof b/BUILD/compile-amd64-gprof
new file mode 100755
index 00000000000..6cfb8a4302c
--- /dev/null
+++ b/BUILD/compile-amd64-gprof
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+extra_flags="$amd64_cflags $gprof_compile_flags"
+extra_configs="$amd64_configs $debug_configs $gprof_link_flags"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-gcov b/BUILD/compile-pentium-gcov
index 0d561d5b147..d4878dc591e 100755
--- a/BUILD/compile-pentium-gcov
+++ b/BUILD/compile-pentium-gcov
@@ -7,18 +7,11 @@ path=`dirname $0`
CCACHE_DISABLE=1
export CCACHE_DISABLE
-# GCC4 needs -fprofile-arcs -ftest-coverage on the linker command line (as well
-# as on the compiler command line), and this requires setting LDFLAGS for BDB.
-export LDFLAGS="-fprofile-arcs -ftest-coverage"
+export LDFLAGS="$gcov_link_flags"
-# The -fprofile-arcs and -ftest-coverage options cause GCC to instrument the
-# code with profiling information used by gcov.
-# The -DDISABLE_TAO_ASM is needed to avoid build failures in Yassl.
-# The -DHAVE_gcov enables code to write out coverage info even when crashing.
-extra_flags="$pentium_cflags -fprofile-arcs -ftest-coverage -DDISABLE_TAO_ASM $debug_cflags $max_cflags -DMYSQL_SERVER_SUFFIX=-gcov -DHAVE_gcov"
+extra_flags="$pentium_cflags $debug_cflags $max_cflags $gcov_compile_flags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
-extra_configs="$pentium_configs $debug_configs --disable-shared $static_link"
-extra_configs="$extra_configs $max_configs"
+extra_configs="$pentium_configs $debug_configs $gcov_configs $max_configs"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium-gprof b/BUILD/compile-pentium-gprof
index aa74de0b1b2..4aebc1d2e02 100755
--- a/BUILD/compile-pentium-gprof
+++ b/BUILD/compile-pentium-gprof
@@ -3,7 +3,7 @@
path=`dirname $0`
. "$path/SETUP.sh"
-extra_flags="$pentium_cflags -O2 -pg -g"
-extra_configs="$pentium_configs $debug_configs --disable-shared $static_link"
+extra_flags="$pentium_cflags $gprof_compile_flags"
+extra_configs="$pentium_configs $debug_configs $gprof_link_flags"
. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium64-gcov b/BUILD/compile-pentium64-gcov
new file mode 100755
index 00000000000..5a99b7f8796
--- /dev/null
+++ b/BUILD/compile-pentium64-gcov
@@ -0,0 +1,17 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+# Need to disable ccache, or we loose the gcov-needed compiler output files.
+CCACHE_DISABLE=1
+export CCACHE_DISABLE
+
+export LDFLAGS="$gcov_link_flags"
+
+extra_flags="$pentium64_cflags $debug_cflags $max_cflags $gcov_compile_flags"
+c_warnings="$c_warnings $debug_extra_warnings"
+cxx_warnings="$cxx_warnings $debug_extra_warnings"
+extra_configs="$pentium64_configs $debug_configs $gcov_configs $max_configs"
+
+. "$path/FINISH.sh"
diff --git a/BUILD/compile-pentium64-gprof b/BUILD/compile-pentium64-gprof
new file mode 100755
index 00000000000..f64dee6d196
--- /dev/null
+++ b/BUILD/compile-pentium64-gprof
@@ -0,0 +1,9 @@
+#! /bin/sh
+
+path=`dirname $0`
+. "$path/SETUP.sh"
+
+extra_flags="$pentium64_cflags $gprof_compile_flags"
+extra_configs="$pentium64_configs $debug_configs $gprof_link_flags"
+
+. "$path/FINISH.sh"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3703548ebc3..e2fb39fee9a 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,52 +22,37 @@ 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)
+ADD_DEFINITIONS(-DCMAKE_BUILD)
+ADD_DEFINITIONS(-DHAVE_YASSL)
# Set debug options
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DFORCE_INIT_OF_VARS")
-SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DFORCE_INIT_OF_VARS")
-
-SET (mysql_plugin_defs "${mysql_plugin_defs},builtin_myisam_plugin")
+# Note that some engines are always compiled in, MyISAM, MyISAMMRG, HEAP
IF(WITH_ARCHIVE_STORAGE_ENGINE)
- ADD_DEFINITIONS(-D HAVE_ARCHIVE_DB)
+ ADD_DEFINITIONS(-DHAVE_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_BERKELEY_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-DHAVE_BERKELEY_DB)
+ENDIF(WITH_BERKELEY_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_BLACKHOLE_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-DHAVE_BLACKHOLE_DB)
+ENDIF (WITH_BLACKHOLE_STORAGE_ENGINE)
-IF(WITH_INNOBASE_STORAGE_ENGINE)
- 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_EXAMPLE_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-DHAVE_EXAMPLE_DB)
+ENDIF(WITH_EXAMPLE_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")
+ ADD_DEFINITIONS(-DHAVE_FEDERATED_DB)
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)
+IF(WITH_INNOBASE_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-DHAVE_INNOBASE_DB)
+ENDIF(WITH_INNOBASE_STORAGE_ENGINE)
SET(localstatedir "C:\\mysql\\data")
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/support-files/my-huge.cnf.sh
@@ -82,14 +67,14 @@ 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__)
+ ADD_DEFINITIONS(-D__NT__)
ENDIF(__NT__)
# in some places we use DBUG_OFF
-SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D DBUG_OFF")
-SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -D DBUG_OFF")
-SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D DBUG_OFF")
-SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -D DBUG_OFF")
+SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDBUG_OFF")
+SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDBUG_OFF")
+SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DDBUG_OFF")
+SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DDBUG_OFF")
IF(CMAKE_GENERATOR MATCHES "Visual Studio 8")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /wd4996")
@@ -102,41 +87,32 @@ 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 "/MD" "/MT" CMAKE_C_FLAGS_RELWITHDEBINFO
- ${CMAKE_C_FLAGS_RELWITHDEBINFO})
- 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 "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO
- ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
- STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG
- ${CMAKE_CXX_FLAGS_DEBUG})
-
- # generate map files
- SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MAP /MAPINFO:EXPORTS")
-
- # set stack size (see bug#20815)
- SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:1048576")
-
- # 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})
+
+ # replace /MDd with /MTd
+ STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
+ STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO})
+ STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
+ STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG_INIT ${CMAKE_C_FLAGS_DEBUG_INIT})
+
+ STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
+ STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
+ STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
+ STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG_INIT ${CMAKE_CXX_FLAGS_DEBUG_INIT})
+
+ # generate map files, set stack size (see bug#20815)
+ SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MAP /MAPINFO:EXPORTS")
+ SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:1048576")
+
+ # 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_DEFINITIONS("-D_WINDOWS -D__WIN__ -D_CRT_SECURE_NO_DEPRECATE")
IF(EMBED_MANIFESTS)
# Search for the tools (mt, makecat, signtool) necessary for embedding
@@ -196,6 +172,8 @@ IF(EMBED_MANIFESTS)
ENDIF(CMAKE_GENERATOR MATCHES "Visual Studio 8 2005 Win64")
ENDIF(EMBED_MANIFESTS)
+# FIXME "debug" only needed if build type is "Debug", but
+# CMAKE_BUILD_TYPE is not set during configure time.
ADD_SUBDIRECTORY(vio)
ADD_SUBDIRECTORY(dbug)
ADD_SUBDIRECTORY(strings)
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 8eaa04f8392..89675138750 100755
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -14,128 +14,48 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake")
+# We use the "mysqlclient_notls" library here just as safety, in case
+# any of the clients here would go beond the client API and access the
+# Thread Local Storage directly.
+
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 -DYASSL_PREFIX -DUSE_TLS)
-
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/zlib
${CMAKE_SOURCE_DIR}/extra/yassl/include
- ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/include
- ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/mySTL
${CMAKE_SOURCE_DIR}/libmysql
${CMAKE_SOURCE_DIR}/regex
- ${CMAKE_SOURCE_DIR}/mysys
${CMAKE_SOURCE_DIR}/sql
${CMAKE_SOURCE_DIR}/strings)
-SET(YASSL_SOURCES ../extra/yassl/src/buffer.cpp
- ../extra/yassl/src/cert_wrapper.cpp
- ../extra/yassl/src/crypto_wrapper.cpp
- ../extra/yassl/src/handshake.cpp
- ../extra/yassl/src/lock.cpp
- ../extra/yassl/src/log.cpp
- ../extra/yassl/src/socket_wrapper.cpp
- ../extra/yassl/src/ssl.cpp
- ../extra/yassl/src/timer.cpp
- ../extra/yassl/src/yassl_error.cpp
- ../extra/yassl/src/yassl_imp.cpp
- ../extra/yassl/src/yassl_int.cpp)
-
-SET(TAOCRYPT_SOURCES ../extra/yassl/taocrypt/src/aes.cpp
- ../extra/yassl/taocrypt/src/aestables.cpp
- ../extra/yassl/taocrypt/src/algebra.cpp
- ../extra/yassl/taocrypt/src/arc4.cpp
- ../extra/yassl/taocrypt/src/asn.cpp
- ../extra/yassl/taocrypt/src/coding.cpp
- ../extra/yassl/taocrypt/src/des.cpp
- ../extra/yassl/taocrypt/src/dh.cpp
- ../extra/yassl/taocrypt/src/dsa.cpp
- ../extra/yassl/taocrypt/src/file.cpp
- ../extra/yassl/taocrypt/src/hash.cpp
- ../extra/yassl/taocrypt/src/integer.cpp
- ../extra/yassl/taocrypt/src/md2.cpp
- ../extra/yassl/taocrypt/src/md4.cpp
- ../extra/yassl/taocrypt/src/md5.cpp
- ../extra/yassl/taocrypt/src/misc.cpp
- ../extra/yassl/taocrypt/src/random.cpp
- ../extra/yassl/taocrypt/src/ripemd.cpp
- ../extra/yassl/taocrypt/src/rsa.cpp
- ../extra/yassl/taocrypt/src/sha.cpp)
-
-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
- ${YASSL_SOURCES} ${TAOCRYPT_SOURCES}
- )
-
-
-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 zlib dbug wsock32)
+ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c)
+TARGET_LINK_LIBRARIES(mysql mysqlclient_notls wsock32)
-ADD_EXECUTABLE(mysqltest mysqltest.c)
-TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys zlib dbug regex wsock32)
+ADD_EXECUTABLE(mysqltest mysqltest.c ../mysys/my_getsystime.c ../mysys/my_copy.c)
+TARGET_LINK_LIBRARIES(mysqltest mysqlclient_notls regex wsock32)
ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)
-TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient dbug zlib wsock32)
+TARGET_LINK_LIBRARIES(mysqlcheck mysqlclient_notls wsock32)
-ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c)
-TARGET_LINK_LIBRARIES(mysqldump mysqlclient mysys dbug zlib wsock32)
+ADD_EXECUTABLE(mysqldump mysqldump.c ../sql-common/my_user.c ../mysys/mf_getdate.c)
+TARGET_LINK_LIBRARIES(mysqldump mysqlclient_notls wsock32)
ADD_EXECUTABLE(mysqlimport mysqlimport.c)
-TARGET_LINK_LIBRARIES(mysqlimport mysqlclient mysys dbug zlib wsock32)
+TARGET_LINK_LIBRARIES(mysqlimport mysqlclient_notls wsock32)
ADD_EXECUTABLE(mysql_upgrade mysql_upgrade.c ../mysys/my_getpagesize.c)
-TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient mysys dbug zlib wsock32)
+TARGET_LINK_LIBRARIES(mysql_upgrade mysqlclient_notls wsock32)
ADD_DEPENDENCIES(mysql_upgrade GenFixPrivs)
ADD_EXECUTABLE(mysqlshow mysqlshow.c)
-TARGET_LINK_LIBRARIES(mysqlshow mysqlclient mysys dbug zlib wsock32)
+TARGET_LINK_LIBRARIES(mysqlshow mysqlclient_notls 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 zlib wsock32)
+ADD_EXECUTABLE(mysqlbinlog mysqlbinlog.cc ../mysys/mf_tempdir.c ../mysys/my_new.cc)
+TARGET_LINK_LIBRARIES(mysqlbinlog mysqlclient_notls wsock32)
ADD_EXECUTABLE(mysqladmin mysqladmin.cc)
-TARGET_LINK_LIBRARIES(mysqladmin mysqlclient mysys dbug zlib wsock32)
+TARGET_LINK_LIBRARIES(mysqladmin mysqlclient_notls wsock32)
ADD_EXECUTABLE(echo echo.c)
diff --git a/client/mysql.cc b/client/mysql.cc
index 277b56328a6..8e1b6c2a9b4 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1245,6 +1245,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
char buff[80], *pos, *out;
COMMANDS *com;
bool need_space= 0;
+ bool ss_comment= 0;
DBUG_ENTER("add_line");
if (!line[0] && buffer.is_empty())
@@ -1293,22 +1294,36 @@ static bool add_line(String &buffer,char *line,char *in_string,
}
if ((com=find_command(NullS,(char) inchar)))
{
- const String tmp(line,(uint) (out-line), charset_info);
- buffer.append(tmp);
- if ((*com->func)(&buffer,pos-1) > 0)
- DBUG_RETURN(1); // Quit
- if (com->takes_params)
- {
- for (pos++ ;
- *pos && (*pos != *delimiter ||
- !is_prefix(pos + 1, delimiter + 1)) ; pos++)
- ; // Remove parameters
- if (!*pos)
- pos--;
- else
- pos+= delimiter_length - 1; // Point at last delim char
- }
- out=line;
+ const String tmp(line,(uint) (out-line), charset_info);
+ buffer.append(tmp);
+ if ((*com->func)(&buffer,pos-1) > 0)
+ DBUG_RETURN(1); // Quit
+ if (com->takes_params)
+ {
+ if (ss_comment)
+ {
+ /*
+ If a client-side macro appears inside a server-side comment,
+ discard all characters in the comment after the macro (that is,
+ until the end of the comment rather than the next delimiter)
+ */
+ for (pos++; *pos && (*pos != '*' || *(pos + 1) != '/'); pos++)
+ ;
+ pos--;
+ }
+ else
+ {
+ for (pos++ ;
+ *pos && (*pos != *delimiter ||
+ !is_prefix(pos + 1, delimiter + 1)) ; pos++)
+ ; // Remove parameters
+ if (!*pos)
+ pos--;
+ else
+ pos+= delimiter_length - 1; // Point at last delim char
+ }
+ }
+ out=line;
}
else
{
@@ -1368,7 +1383,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
out=line;
}
}
- else if (*ml_comment && inchar == '*' && *(pos + 1) == '/')
+ else if (*ml_comment && !ss_comment && inchar == '*' && *(pos + 1) == '/')
{
pos++;
*ml_comment= 0;
@@ -1376,6 +1391,11 @@ static bool add_line(String &buffer,char *line,char *in_string,
}
else
{ // Add found char to buffer
+ if (!*in_string && inchar == '/' && *(pos + 1) == '*' &&
+ *(pos + 2) == '!')
+ ss_comment= 1;
+ else if (!*in_string && ss_comment && inchar == '*' && *(pos + 1) == '/')
+ ss_comment= 0;
if (inchar == *in_string)
*in_string= 0;
else if (!*ml_comment && !*in_string &&
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index 64de3d19882..fb30c6f2613 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -342,12 +342,6 @@ static my_bool get_full_path_to_executable(char* path)
/*
Look for the tool in the same directory as mysql_upgrade.
-
- When running in a not yet installed build the the program
- will exist but it need to be invoked via it's libtool wrapper.
- Check if the found tool can executed and if not look in the
- directory one step higher up where the libtool wrapper normally
- is found
*/
static void find_tool(char *tool_path, const char *tool_name)
@@ -385,37 +379,52 @@ static void find_tool(char *tool_path, const char *tool_name)
path[0]= 0;
}
}
- do
- {
- DBUG_PRINT("enter", ("path: %s", path));
- /* Chop off last char(since it might be a /) */
- path[max((strlen(path)-1), 0)]= 0;
+ DBUG_PRINT("info", ("path: '%s'", path));
+
+ /* Chop off binary name (i.e mysql-upgrade) from path */
+ dirname_part(path, path);
+
+ /*
+ When running in a not yet installed build and using libtool,
+ the program(mysql_upgrade) will be in .libs/ and executed
+ through a libtool wrapper in order to use the dynamic libraries
+ from this build. The same must be done for the tools(mysql and
+ mysqlcheck). Thus if path ends in .libs/, step up one directory
+ and execute the tools from there
+ */
+ path[max((strlen(path)-1), 0)]= 0; /* Chop off last / */
+ if (strncmp(path + dirname_length(path), ".libs", 5) == 0)
+ {
+ DBUG_PRINT("info", ("Chopping off .libs from '%s'", path));
- /* Chop off last dir part */
+ /* Chop off .libs */
dirname_part(path, path);
+ }
- /* Format name of the tool to search for */
- fn_format(tool_path, tool_name,
- path, "", MYF(MY_REPLACE_DIR));
- verbose("Looking for '%s' in: %s", tool_name, tool_path);
+ DBUG_PRINT("info", ("path: '%s'", path));
- /* Make sure the tool exists */
- if (my_access(tool_path, F_OK) != 0)
- die("Can't find '%s'", tool_path);
+ /* Format name of the tool to search for */
+ fn_format(tool_path, tool_name,
+ path, "", MYF(MY_REPLACE_DIR));
- /*
- Make sure it can be executed, otherwise try again
- in higher level directory
- */
- }
- while(run_tool(tool_path,
- &ds_tmp, /* Get output from command, discard*/
- "--help",
- "2>&1",
- IF_WIN("> NUL", "> /dev/null"),
- NULL));
+ verbose("Looking for '%s' in: %s", tool_name, tool_path);
+
+ /* Make sure the tool exists */
+ if (my_access(tool_path, F_OK) != 0)
+ die("Can't find '%s'", tool_path);
+
+ /*
+ Make sure it can be executed
+ */
+ if (run_tool(tool_path,
+ &ds_tmp, /* Get output from command, discard*/
+ "--help",
+ "2>&1",
+ IF_WIN("> NUL", "> /dev/null"),
+ NULL))
+ die("Can't execute '%s'", tool_path);
dynstr_free(&ds_tmp);
@@ -446,6 +455,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
ret= run_tool(mysql_path,
ds_res,
+ "--no-defaults",
ds_args.str,
"--database=mysql",
"--batch", /* Turns off pager etc. */
@@ -457,6 +467,7 @@ static int run_query(const char *query, DYNAMIC_STRING *ds_res,
NULL);
my_close(fd, MYF(0));
+ my_delete(query_file_path, MYF(0));
DBUG_RETURN(ret);
}
@@ -607,6 +618,7 @@ static int run_mysqlcheck_upgrade(void)
verbose("Running 'mysqlcheck'...");
return run_tool(mysqlcheck_path,
NULL, /* Send output from mysqlcheck directly to screen */
+ "--no-defaults",
ds_args.str,
"--check-upgrade",
"--all-databases",
diff --git a/client/mysqltest.c b/client/mysqltest.c
index d1ec753b54b..b2b579528ae 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -74,18 +74,12 @@
#define QUERY_SEND_FLAG 1
#define QUERY_REAP_FLAG 2
- enum {
- RESULT_OK= 0,
- RESULT_CONTENT_MISMATCH= 1,
- RESULT_LENGTH_MISMATCH= 2
- };
-
enum {
OPT_SKIP_SAFEMALLOC=256, OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT,
OPT_SSL_CA, OPT_SSL_CAPATH, OPT_SSL_CIPHER, OPT_PS_PROTOCOL,
OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
OPT_SSL_VERIFY_SERVER_CERT, OPT_MAX_CONNECT_RETRIES,
- OPT_MARK_PROGRESS, OPT_CHARSETS_DIR, OPT_LOG_DIR
+ OPT_MARK_PROGRESS, OPT_CHARSETS_DIR, OPT_LOG_DIR, OPT_TAIL_LINES
};
static int record= 0, opt_sleep= -1;
@@ -117,6 +111,9 @@ static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer;
static uint start_lineno= 0; /* Start line of current command */
+/* Number of lines of the result to include in failure report */
+static uint opt_tail_lines= 0;
+
static char delimiter[MAX_DELIMITER_LENGTH]= ";";
static uint delimiter_length= 1;
@@ -238,7 +235,7 @@ struct st_connection
#endif /*EMBEDDED_LIBRARY*/
};
struct st_connection connections[128];
-struct st_connection* cur_con, *next_con, *connections_end;
+struct st_connection* cur_con= NULL, *next_con, *connections_end;
/*
List of commands in mysqltest
@@ -455,7 +452,6 @@ void free_tmp_sh_file();
void free_win_path_patterns();
#endif
-static int eval_result = 0;
/* For replace_column */
static char *replace_column[MAX_COLUMNS];
@@ -503,11 +499,11 @@ void handle_no_error(struct st_command*);
pthread_attr_t cn_thd_attrib;
/*
- send_one_query executes query in separate thread what is
+ send_one_query executes query in separate thread, which is
necessary in embedded library to run 'send' in proper way.
This implementation doesn't handle errors returned
by mysql_send_query. It's technically possible, though
- i don't see where it is needed.
+ I don't see where it is needed.
*/
pthread_handler_t send_one_query(void *arg)
{
@@ -608,6 +604,142 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query,
}
+/*
+ Run query and dump the result to stdout in vertical format
+
+ NOTE! This function should be safe to call when an error
+ has occured and thus any further errors will be ignored(although logged)
+
+ SYNOPSIS
+ show_query
+ mysql - connection to use
+ query - query to run
+
+*/
+
+static void show_query(MYSQL* mysql, const char* query)
+{
+ MYSQL_RES* res;
+ DBUG_ENTER("show_query");
+
+ if (!mysql)
+ DBUG_VOID_RETURN;
+
+ if (mysql_query(mysql, query))
+ {
+ log_msg("Error running query '%s': %d %s",
+ query, mysql_errno(mysql), mysql_error(mysql));
+ DBUG_VOID_RETURN;
+ }
+
+ if ((res= mysql_store_result(mysql)) == NULL)
+ {
+ /* No result set returned */
+ DBUG_VOID_RETURN;
+ }
+
+ {
+ MYSQL_ROW row;
+ unsigned int i;
+ unsigned int row_num= 0;
+ unsigned int num_fields= mysql_num_fields(res);
+ MYSQL_FIELD *fields= mysql_fetch_fields(res);
+
+ fprintf(stderr, "=== %s ===\n", query);
+ while ((row= mysql_fetch_row(res)))
+ {
+ unsigned long *lengths= mysql_fetch_lengths(res);
+ row_num++;
+
+ fprintf(stderr, "---- %d. ----\n", row_num);
+ for(i= 0; i < num_fields; i++)
+ {
+ fprintf(stderr, "%s\t%.*s\n",
+ fields[i].name,
+ (int)lengths[i], row[i] ? row[i] : "NULL");
+ }
+ }
+ for (i= 0; i < strlen(query)+8; i++)
+ fprintf(stderr, "=");
+ fprintf(stderr, "\n\n");
+ }
+ mysql_free_result(res);
+
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Show any warnings just before the error. Since the last error
+ is added to the warning stack, only print @@warning_count-1 warnings.
+
+ NOTE! This function should be safe to call when an error
+ has occured and this any further errors will be ignored(although logged)
+
+ SYNOPSIS
+ show_warnings_before_error
+ mysql - connection to use
+
+*/
+
+static void show_warnings_before_error(MYSQL* mysql)
+{
+ MYSQL_RES* res;
+ const char* query= "SHOW WARNINGS";
+ DBUG_ENTER("show_warnings_before_error");
+
+ if (!mysql)
+ DBUG_VOID_RETURN;
+
+ if (mysql_query(mysql, query))
+ {
+ log_msg("Error running query '%s': %d %s",
+ query, mysql_errno(mysql), mysql_error(mysql));
+ DBUG_VOID_RETURN;
+ }
+
+ if ((res= mysql_store_result(mysql)) == NULL)
+ {
+ /* No result set returned */
+ DBUG_VOID_RETURN;
+ }
+
+ if (mysql_num_rows(res) <= 1)
+ {
+ /* Don't display the last row, it's "last error" */
+ }
+ else
+ {
+ MYSQL_ROW row;
+ unsigned int row_num= 0;
+ unsigned int num_fields= mysql_num_fields(res);
+
+ fprintf(stderr, "\nWarnings from just before the error:\n");
+ while ((row= mysql_fetch_row(res)))
+ {
+ unsigned int i;
+ unsigned long *lengths= mysql_fetch_lengths(res);
+
+ if (++row_num >= mysql_num_rows(res))
+ {
+ /* Don't display the last row, it's "last error" */
+ break;
+ }
+
+ for(i= 0; i < num_fields; i++)
+ {
+ fprintf(stderr, "%.*s ", (int)lengths[i],
+ row[i] ? row[i] : "NULL");
+ }
+ fprintf(stderr, "\n");
+ }
+ }
+ mysql_free_result(res);
+
+ DBUG_VOID_RETURN;
+}
+
+
enum arg_type
{
ARG_STRING,
@@ -686,6 +818,15 @@ void check_command_args(struct st_command *command,
command->first_word_len, command->query);
}
+ /* Check for too many arguments passed */
+ ptr= command->last_argument;
+ while(ptr <= command->end)
+ {
+ if (*ptr && *ptr != ' ')
+ die("Extra argument '%s' passed to '%.*s'",
+ ptr, command->first_word_len, command->query);
+ ptr++;
+ }
DBUG_VOID_RETURN;
}
@@ -881,6 +1022,24 @@ void die(const char *fmt, ...)
fprintf(stderr, "\n");
fflush(stderr);
+ /* Show results from queries just before failure */
+ if (ds_res.length && opt_tail_lines)
+ {
+ int tail_lines= opt_tail_lines;
+ char* show_from= ds_res.str + ds_res.length - 1;
+ while(show_from > ds_res.str && tail_lines > 0 )
+ {
+ show_from--;
+ if (*show_from == '\n')
+ tail_lines--;
+ }
+ fprintf(stderr, "\nThe result from queries just before the failure was:\n");
+ if (show_from > ds_res.str)
+ fprintf(stderr, "< snip >");
+ fprintf(stderr, "%s", show_from);
+ fflush(stderr);
+ }
+
/* Dump the result that has been accumulated so far to .log file */
if (result_file_name && ds_res.length)
dump_result_to_log_file(ds_res.str, ds_res.length);
@@ -889,6 +1048,13 @@ void die(const char *fmt, ...)
if (result_file_name && ds_warning_messages.length)
dump_warning_messages();
+ /*
+ Help debugging by displaying any warnings that might have
+ been produced prior to the error
+ */
+ if (cur_con)
+ show_warnings_before_error(&cur_con->mysql);
+
cleanup_and_exit(1);
}
@@ -992,11 +1158,10 @@ void warning_msg(const char *fmt, ...)
void log_msg(const char *fmt, ...)
{
va_list args;
- char buff[512];
+ char buff[1024];
size_t len;
DBUG_ENTER("log_msg");
- memset(buff, 0, sizeof(buff));
va_start(args, fmt);
len= my_vsnprintf(buff, sizeof(buff)-1, fmt, args);
va_end(args);
@@ -1009,77 +1174,372 @@ void log_msg(const char *fmt, ...)
/*
- Compare content of the string ds to content of file fname
+ Read a file and append it to ds
+
+ SYNOPSIS
+ cat_file
+ ds - pointer to dynamic string where to add the files content
+ filename - name of the file to read
+
*/
-int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
+void cat_file(DYNAMIC_STRING* ds, const char* filename)
{
- MY_STAT stat_info;
- char *tmp, *res_ptr;
- char eval_file[FN_REFLEN];
- int res;
- uint res_len;
int fd;
- DYNAMIC_STRING res_ds;
- DBUG_ENTER("dyn_string_cmp");
+ uint len;
+ char buff[512];
- if (!test_if_hard_path(fname))
+ if ((fd= my_open(filename, O_RDONLY, MYF(0))) < 0)
+ die("Failed to open file '%s'", filename);
+ while((len= my_read(fd, (byte*)&buff,
+ sizeof(buff), MYF(0))) > 0)
{
- strxmov(eval_file, opt_basedir, fname, NullS);
- fn_format(eval_file, eval_file, "", "", MY_UNPACK_FILENAME);
+ char *p= buff, *start= buff;
+ while (p < buff+len)
+ {
+ /* Convert cr/lf to lf */
+ if (*p == '\r' && *(p+1) && *(p+1)== '\n')
+ {
+ /* Add fake newline instead of cr and output the line */
+ *p= '\n';
+ p++; /* Step past the "fake" newline */
+ dynstr_append_mem(ds, start, p-start);
+ p++; /* Step past the "fake" newline */
+ start= p;
+ }
+ else
+ p++;
+ }
+ /* Output any chars that migh be left */
+ dynstr_append_mem(ds, start, p-start);
}
- else
- fn_format(eval_file, fname, "", "", MY_UNPACK_FILENAME);
+ my_close(fd, MYF(0));
+}
- if (!my_stat(eval_file, &stat_info, MYF(MY_WME)))
- die(NullS);
- if (!eval_result && (uint) stat_info.st_size != ds->length)
+
+/*
+ Run the specified command with popen
+
+ SYNOPSIS
+ run_command
+ cmd - command to execute(should be properly quoted
+ ds_res- pointer to dynamic string where to store the result
+
+*/
+
+static int run_command(char* cmd,
+ DYNAMIC_STRING *ds_res)
+{
+ char buf[512]= {0};
+ FILE *res_file;
+ int error;
+
+ if (!(res_file= popen(cmd, "r")))
+ die("popen(\"%s\", \"r\") failed", cmd);
+
+ while (fgets(buf, sizeof(buf), res_file))
{
- DBUG_PRINT("info",("Size differs: result size: %u file size: %lu",
- ds->length, (ulong) stat_info.st_size));
- DBUG_PRINT("info",("result: '%s'", ds->str));
- DBUG_RETURN(RESULT_LENGTH_MISMATCH);
+ DBUG_PRINT("info", ("buf: %s", buf));
+ if(ds_res)
+ {
+ /* Save the output of this command in the supplied string */
+ dynstr_append(ds_res, buf);
+ }
+ else
+ {
+ /* Print it directly on screen */
+ fprintf(stdout, "%s", buf);
+ }
}
- if (!(tmp = (char*) my_malloc(stat_info.st_size + 1, MYF(MY_WME))))
+
+ error= pclose(res_file);
+ return WEXITSTATUS(error);
+}
+
+
+/*
+ Run the specified tool with variable number of arguments
+
+ SYNOPSIS
+ run_tool
+ tool_path - the name of the tool to run
+ ds_res - pointer to dynamic string where to store the result
+ ... - variable number of arguments that will be properly
+ quoted and appended after the tool's name
+
+*/
+
+static int run_tool(const char *tool_path, DYNAMIC_STRING *ds_res, ...)
+{
+ int ret;
+ const char* arg;
+ va_list args;
+ DYNAMIC_STRING ds_cmdline;
+
+ DBUG_ENTER("run_tool");
+ DBUG_PRINT("enter", ("tool_path: %s", tool_path));
+
+ if (init_dynamic_string(&ds_cmdline, IF_WIN("\"", ""), FN_REFLEN, FN_REFLEN))
die("Out of memory");
- if ((fd = my_open(eval_file, O_RDONLY, MYF(MY_WME))) < 0)
- die("Failed to open file %s", eval_file);
- if (my_read(fd, (byte*)tmp, stat_info.st_size, MYF(MY_WME|MY_NABP)))
- die("Failed to read from file %s, errno: %d", eval_file, errno);
- tmp[stat_info.st_size] = 0;
- init_dynamic_string(&res_ds, "", stat_info.st_size+256, 256);
- if (eval_result)
- {
- do_eval(&res_ds, tmp, tmp + stat_info.st_size, FALSE);
- res_ptr= res_ds.str;
- res_len= res_ds.length;
- if (res_len != ds->length)
+ dynstr_append_os_quoted(&ds_cmdline, tool_path, NullS);
+ dynstr_append(&ds_cmdline, " ");
+
+ va_start(args, ds_res);
+
+ while ((arg= va_arg(args, char *)))
+ {
+ /* Options should be os quoted */
+ if (strncmp(arg, "--", 2) == 0)
+ dynstr_append_os_quoted(&ds_cmdline, arg, NullS);
+ else
+ dynstr_append(&ds_cmdline, arg);
+ dynstr_append(&ds_cmdline, " ");
+ }
+
+ va_end(args);
+
+#ifdef __WIN__
+ dynstr_append(&ds_cmdline, "\"");
+#endif
+
+ DBUG_PRINT("info", ("Running: %s", ds_cmdline.str));
+ ret= run_command(ds_cmdline.str, ds_res);
+ DBUG_PRINT("exit", ("ret: %d", ret));
+ dynstr_free(&ds_cmdline);
+ DBUG_RETURN(ret);
+}
+
+
+/*
+ Show the diff of two files using the systems builtin diff
+ command. If no such diff command exist, just dump the content
+ of the two files and inform about how to get "diff"
+
+ SYNOPSIS
+ show_diff
+ ds - pointer to dynamic string where to add the diff(may be NULL)
+ filename1 - name of first file
+ filename2 - name of second file
+
+*/
+
+void show_diff(DYNAMIC_STRING* ds,
+ const char* filename1, const char* filename2)
+{
+
+ DYNAMIC_STRING ds_tmp;
+
+ if (init_dynamic_string(&ds_tmp, "", 256, 256))
+ die("Out of memory");
+
+ /* First try with unified diff */
+ if (run_tool("diff",
+ &ds_tmp, /* Get output from diff in ds_tmp */
+ "-u",
+ filename1,
+ filename2,
+ "2>&1",
+ NULL) > 1) /* Most "diff" tools return >1 if error */
+ {
+ dynstr_set(&ds_tmp, "");
+
+ /* Fallback to context diff with "diff -c" */
+ if (run_tool("diff",
+ &ds_tmp, /* Get output from diff in ds_tmp */
+ "-c",
+ filename1,
+ filename2,
+ "2>&1",
+ NULL) > 1) /* Most "diff" tools return >1 if error */
{
- res= RESULT_LENGTH_MISMATCH;
- goto err;
+ /*
+ Fallback to dump both files to result file and inform
+ about installing "diff"
+ */
+ dynstr_set(&ds_tmp, "");
+
+ dynstr_append(&ds_tmp,
+"\n"
+"The two files differ but it was not possible to execute 'diff' in\n"
+"order to show only the difference, tried both 'diff -u' or 'diff -c'.\n"
+"Instead the whole content of the two files was shown for you to diff manually. ;)\n\n"
+"To get a better report you should install 'diff' on your system, which you\n"
+"for example can get from http://www.gnu.org/software/diffutils/diffutils.html\n"
+#ifdef __WIN__
+"or http://gnuwin32.sourceforge.net/packages/diffutils.htm\n"
+#endif
+"\n");
+
+ dynstr_append(&ds_tmp, " --- ");
+ dynstr_append(&ds_tmp, filename1);
+ dynstr_append(&ds_tmp, " >>>\n");
+ cat_file(&ds_tmp, filename1);
+ dynstr_append(&ds_tmp, "<<<\n --- ");
+ dynstr_append(&ds_tmp, filename1);
+ dynstr_append(&ds_tmp, " >>>\n");
+ cat_file(&ds_tmp, filename2);
+ dynstr_append(&ds_tmp, "<<<<\n");
}
}
+
+ if (ds)
+ {
+ /* Add the diff to output */
+ dynstr_append_mem(ds, ds_tmp.str, ds_tmp.length);
+ }
else
{
- res_ptr = tmp;
- res_len = stat_info.st_size;
+ /* Print diff directly to stdout */
+ fprintf(stderr, "%s\n", ds_tmp.str);
}
+
+ dynstr_free(&ds_tmp);
- res= (memcmp(res_ptr, ds->str, res_len)) ?
- RESULT_CONTENT_MISMATCH : RESULT_OK;
+}
-err:
- if (res && eval_result)
- str_to_file(fn_format(eval_file, fname, "", ".eval",
- MY_REPLACE_EXT),
- res_ptr, res_len);
- dynstr_free(&res_ds);
- my_free((gptr) tmp, MYF(0));
- my_close(fd, MYF(MY_WME));
+enum compare_files_result_enum {
+ RESULT_OK= 0,
+ RESULT_CONTENT_MISMATCH= 1,
+ RESULT_LENGTH_MISMATCH= 2
+};
+
+/*
+ Compare two files, given a fd to the first file and
+ name of the second file
+
+ SYNOPSIS
+ compare_files2
+ fd - Open file descriptor of the first file
+ filename2 - Name of second file
+
+ RETURN VALUES
+ According to the values in "compare_files_result_enum"
+
+*/
- DBUG_RETURN(res);
+int compare_files2(File fd, const char* filename2)
+{
+ int error= RESULT_OK;
+ File fd2;
+ uint len, len2;
+ char buff[512], buff2[512];
+
+ if ((fd2= my_open(filename2, O_RDONLY, MYF(0))) < 0)
+ {
+ my_close(fd, MYF(0));
+ die("Failed to open second file: '%s'", filename2);
+ }
+ while((len= my_read(fd, (byte*)&buff,
+ sizeof(buff), MYF(0))) > 0)
+ {
+ if ((len2= my_read(fd2, (byte*)&buff2,
+ sizeof(buff2), MYF(0))) < len)
+ {
+ /* File 2 was smaller */
+ error= RESULT_LENGTH_MISMATCH;
+ break;
+ }
+ if (len2 > len)
+ {
+ /* File 1 was smaller */
+ error= RESULT_LENGTH_MISMATCH;
+ break;
+ }
+ if ((memcmp(buff, buff2, len)))
+ {
+ /* Content of this part differed */
+ error= RESULT_CONTENT_MISMATCH;
+ break;
+ }
+ }
+ if (!error && my_read(fd2, (byte*)&buff2,
+ sizeof(buff2), MYF(0)) > 0)
+ {
+ /* File 1 was smaller */
+ error= RESULT_LENGTH_MISMATCH;
+ }
+
+ my_close(fd2, MYF(0));
+
+ return error;
+}
+
+
+/*
+ Compare two files, given their filenames
+
+ SYNOPSIS
+ compare_files
+ filename1 - Name of first file
+ filename2 - Name of second file
+
+ RETURN VALUES
+ See 'compare_files2'
+
+*/
+
+int compare_files(const char* filename1, const char* filename2)
+{
+ File fd;
+ int error;
+
+ if ((fd= my_open(filename1, O_RDONLY, MYF(0))) < 0)
+ die("Failed to open first file: '%s'", filename1);
+
+ error= compare_files2(fd, filename2);
+
+ my_close(fd, MYF(0));
+
+ return error;
+}
+
+
+/*
+ Compare content of the string in ds to content of file fname
+
+ SYNOPSIS
+ dyn_string_cmp
+ ds - Dynamic string containing the string o be compared
+ fname - Name of file to compare with
+
+ RETURN VALUES
+ See 'compare_files2'
+*/
+
+int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
+{
+ int error;
+ File fd;
+ char temp_file_path[FN_REFLEN];
+
+ DBUG_ENTER("dyn_string_cmp");
+ DBUG_PRINT("enter", ("fname: %s", fname));
+
+ if ((fd= create_temp_file(temp_file_path, NULL,
+ "tmp", O_CREAT | O_SHARE | O_RDWR,
+ MYF(MY_WME))) < 0)
+ die("Failed to create temporary file for ds");
+
+ /* Write ds to temporary file and set file pos to beginning*/
+ if (my_write(fd, ds->str, ds->length,
+ MYF(MY_FNABP | MY_WME)) ||
+ my_seek(fd, 0, SEEK_SET, MYF(0)) == MY_FILEPOS_ERROR)
+ {
+ my_close(fd, MYF(0));
+ /* Remove the temporary file */
+ my_delete(temp_file_path, MYF(0));
+ die("Failed to write file '%s'", temp_file_path);
+ }
+
+ error= compare_files2(fd, fname);
+
+ my_close(fd, MYF(0));
+ /* Remove the temporary file */
+ my_delete(temp_file_path, MYF(0));
+
+ DBUG_RETURN(error);
}
@@ -1097,21 +1557,40 @@ err:
void check_result(DYNAMIC_STRING* ds)
{
+ const char* mess= "Result content mismatch\n";
+
DBUG_ENTER("check_result");
DBUG_ASSERT(result_file_name);
+ DBUG_PRINT("enter", ("result_file_name: %s", result_file_name));
+
+ if (access(result_file_name, F_OK) != 0)
+ die("The specified result file does not exist: '%s'", result_file_name);
switch (dyn_string_cmp(ds, result_file_name))
{
case RESULT_OK:
break; /* ok */
case RESULT_LENGTH_MISMATCH:
- dump_result_to_reject_file(ds->str, ds->length);
- die("Result length mismatch");
- break;
+ mess= "Result length mismatch\n";
+ /* Fallthrough */
case RESULT_CONTENT_MISMATCH:
- dump_result_to_reject_file(ds->str, ds->length);
- die("Result content mismatch");
+ {
+ /*
+ Result mismatched, dump results to .reject file
+ and then show the diff
+ */
+ char reject_file[FN_REFLEN];
+ str_to_file(fn_format(reject_file, result_file_name, opt_logdir, ".reject",
+ *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
+ MY_REPLACE_EXT),
+ ds->str, ds->length);
+
+ dynstr_set(ds, NULL); /* Don't create a .log file */
+
+ show_diff(NULL, result_file_name, reject_file);
+ die(mess);
break;
+ }
default: /* impossible */
die("Unknown error code from dyn_string_cmp()");
}
@@ -1126,7 +1605,7 @@ void check_result(DYNAMIC_STRING* ds)
indicating that test is not supported
SYNOPSIS
- check_result
+ check_require
ds - content to be checked
fname - name of file to check against
@@ -1455,40 +1934,22 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
die("Query '%s' didn't return a result set", ds_query.str);
dynstr_free(&ds_query);
- if ((row = mysql_fetch_row(res)) && row[0])
+ if ((row= mysql_fetch_row(res)) && row[0])
{
/*
- Concatenate all row results with tab in between to allow us to work
- with results from many columns (for example from SHOW VARIABLES)
+ Concatenate all fields in the first row with tab in between
+ and assign that string to the $variable
*/
DYNAMIC_STRING result;
uint i;
ulong *lengths;
-#ifdef NOT_YET
- MYSQL_FIELD *fields= mysql_fetch_fields(res);
-#endif
- init_dynamic_string(&result, "", 2048, 2048);
+ init_dynamic_string(&result, "", 512, 512);
lengths= mysql_fetch_lengths(res);
- for (i=0; i < mysql_num_fields(res); i++)
+ for (i= 0; i < mysql_num_fields(res); i++)
{
- if (row[0])
+ if (row[i])
{
-#ifdef NOT_YET
- /* Add to <var_name>_<col_name> */
- uint j;
- char var_col_name[MAX_VAR_NAME_LENGTH];
- uint length= snprintf(var_col_name, MAX_VAR_NAME_LENGTH,
- "$%s_%s", var->name, fields[i].name);
- /* Convert characters not allowed in variable names to '_' */
- for (j= 1; j < length; j++)
- {
- if (!my_isvar(charset_info,var_col_name[j]))
- var_col_name[j]= '_';
- }
- var_set(var_col_name, var_col_name + length,
- row[i], row[i] + lengths[i]);
-#endif
/* Add column to tab separated string */
dynstr_append_mem(&result, row[i], lengths[i]);
}
@@ -1530,7 +1991,7 @@ void var_query_set(VAR *var, const char *query, const char** query_end)
void var_set_query_get_value(struct st_command *command, VAR *var)
{
- ulong row_no;
+ long row_no;
int col_no= -1;
MYSQL_RES* res;
MYSQL* mysql= &cur_con->mysql;
@@ -1602,7 +2063,7 @@ void var_set_query_get_value(struct st_command *command, VAR *var)
{
/* Get the value */
MYSQL_ROW row;
- ulong rows= 0;
+ long rows= 0;
const char* value= "No such row";
while ((row= mysql_fetch_row(res)))
@@ -1731,7 +2192,7 @@ int open_file(const char *name)
if (!(cur_file->file = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0))))
{
cur_file--;
- die("Could not open file %s", buff);
+ die("Could not open file '%s'", buff);
}
cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
cur_file->lineno=1;
@@ -1965,7 +2426,7 @@ void do_exec(struct st_command *command)
if (command->abort_on_error)
{
- log_msg("exec of '%s failed, error: %d, status: %d, errno: %d",
+ log_msg("exec of '%s' failed, error: %d, status: %d, errno: %d",
ds_cmd.str, error, status, errno);
die("command \"%s\" failed", command->first_argument);
}
@@ -2203,8 +2664,8 @@ void do_copy_file(struct st_command *command)
command command handle
DESCRIPTION
- chmod <octal> <file>
- Change file permission of <file>
+ chmod_file <octal> <file_name>
+ Change file permission of <file_name>
*/
@@ -2214,8 +2675,8 @@ void do_chmod_file(struct st_command *command)
static DYNAMIC_STRING ds_mode;
static DYNAMIC_STRING ds_file;
const struct command_arg chmod_file_args[] = {
- "mode", ARG_STRING, TRUE, &ds_mode, "Mode of file",
- "file", ARG_STRING, TRUE, &ds_file, "Filename of file to modify"
+ "mode", ARG_STRING, TRUE, &ds_mode, "Mode of file(octal) ex. 0660",
+ "filename", ARG_STRING, TRUE, &ds_file, "Filename of file to modify"
};
DBUG_ENTER("do_chmod_file");
@@ -2310,8 +2771,22 @@ void read_until_delimiter(DYNAMIC_STRING *ds,
c= my_getc(cur_file->file);
if (c == '\n')
+ {
cur_file->lineno++;
+ /* Skip newline from the same line as the command */
+ if (start_lineno == (cur_file->lineno - 1))
+ continue;
+ }
+ else if (start_lineno == cur_file->lineno)
+ {
+ /*
+ No characters except \n are allowed on
+ the same line as the command
+ */
+ die("Trailing characters found after command");
+ }
+
if (feof(cur_file->file))
die("End of file encountered before '%s' delimiter was found",
ds_delimiter->str);
@@ -2349,6 +2824,12 @@ void do_write_file_command(struct st_command *command, my_bool append)
if (ds_delimiter.length == 0)
dynstr_set(&ds_delimiter, "EOF");
+ if (!append && access(ds_filename.str, F_OK) == 0)
+ {
+ /* The file should not be overwritten */
+ die("File already exist: '%s'", ds_filename.str);
+ }
+
init_dynamic_string(&ds_content, "", 1024, 1024);
read_until_delimiter(&ds_content, &ds_delimiter);
DBUG_PRINT("info", ("Writing to file: %s", ds_filename.str));
@@ -2381,7 +2862,7 @@ void do_write_file_command(struct st_command *command, my_bool append)
Write everything between the "write_file" command and 'delimiter'
to "file_name"
- NOTE! Overwrites existing file
+ NOTE! Will fail if <file_name> exists
Default <delimiter> is EOF
@@ -2438,9 +2919,6 @@ void do_append_file(struct st_command *command)
void do_cat_file(struct st_command *command)
{
- int fd;
- uint len;
- char buff[512];
static DYNAMIC_STRING ds_filename;
const struct command_arg cat_file_args[] = {
"filename", ARG_STRING, TRUE, &ds_filename, "File to read from"
@@ -2455,37 +2933,13 @@ void do_cat_file(struct st_command *command)
DBUG_PRINT("info", ("Reading from, file: %s", ds_filename.str));
- if ((fd= my_open(ds_filename.str, O_RDONLY, MYF(0))) < 0)
- die("Failed to open file %s", ds_filename.str);
- while((len= my_read(fd, (byte*)&buff,
- sizeof(buff), MYF(0))) > 0)
- {
- char *p= buff, *start= buff;
- while (p < buff+len)
- {
- /* Convert cr/lf to lf */
- if (*p == '\r' && *(p+1) && *(p+1)== '\n')
- {
- /* Add fake newline instead of cr and output the line */
- *p= '\n';
- p++; /* Step past the "fake" newline */
- dynstr_append_mem(&ds_res, start, p-start);
- p++; /* Step past the "fake" newline */
- start= p;
- }
- else
- p++;
- }
- /* Output any chars that migh be left */
- dynstr_append_mem(&ds_res, start, p-start);
- }
- my_close(fd, MYF(0));
+ cat_file(&ds_res, ds_filename.str);
+
dynstr_free(&ds_filename);
DBUG_VOID_RETURN;
}
-
/*
SYNOPSIS
do_diff_files
@@ -2501,9 +2955,6 @@ void do_cat_file(struct st_command *command)
void do_diff_files(struct st_command *command)
{
int error= 0;
- int fd, fd2;
- uint len, len2;
- char buff[512], buff2[512];
static DYNAMIC_STRING ds_filename;
static DYNAMIC_STRING ds_filename2;
const struct command_arg diff_file_args[] = {
@@ -2518,54 +2969,44 @@ void do_diff_files(struct st_command *command)
sizeof(diff_file_args)/sizeof(struct command_arg),
' ');
- if ((fd= my_open(ds_filename.str, O_RDONLY, MYF(0))) < 0)
- die("Failed to open first file %s", ds_filename.str);
- if ((fd2= my_open(ds_filename2.str, O_RDONLY, MYF(0))) < 0)
- {
- my_close(fd, MYF(0));
- die("Failed to open second file %s", ds_filename2.str);
- }
- while((len= my_read(fd, (byte*)&buff,
- sizeof(buff), MYF(0))) > 0)
- {
- if ((len2= my_read(fd2, (byte*)&buff2,
- sizeof(buff2), MYF(0))) != len)
- {
- /* File 2 was smaller */
- error= 1;
- break;
- }
- if ((memcmp(buff, buff2, len)))
- {
- /* Content of this part differed */
- error= 1;
- break;
- }
- }
- if (my_read(fd2, (byte*)&buff2,
- sizeof(buff2), MYF(0)) > 0)
+ if ((error= compare_files(ds_filename.str, ds_filename2.str)))
{
- /* File 1 was smaller */
- error= 1;
+ /* Compare of the two files failed, append them to output
+ so the failure can be analyzed
+ */
+ show_diff(&ds_res, ds_filename.str, ds_filename2.str);
}
- my_close(fd, MYF(0));
- my_close(fd2, MYF(0));
dynstr_free(&ds_filename);
dynstr_free(&ds_filename2);
handle_command_error(command, error);
DBUG_VOID_RETURN;
}
- /*
- SYNOPSIS
- do_send_quit
- command called command
- DESCRIPTION
- Sends a simple quit command to the server for the named connection.
+struct st_connection * find_connection_by_name(const char *name)
+{
+ struct st_connection *con;
+ for (con= connections; con < next_con; con++)
+ {
+ if (!strcmp(con->name, name))
+ {
+ return con;
+ }
+ }
+ return 0; /* Connection not found */
+}
+
- */
+/*
+ SYNOPSIS
+ do_send_quit
+ command called command
+
+ DESCRIPTION
+ Sends a simple quit command to the server for the named connection.
+
+*/
void do_send_quit(struct st_command *command)
{
@@ -2576,7 +3017,7 @@ void do_send_quit(struct st_command *command)
DBUG_PRINT("enter",("name: '%s'",p));
if (!*p)
- die("Missing connection name in do_send_quit");
+ die("Missing connection name in send_quit");
name= p;
while (*p && !my_isspace(charset_info,*p))
p++;
@@ -2585,17 +3026,12 @@ void do_send_quit(struct st_command *command)
*p++= 0;
command->last_argument= p;
- /* Loop through connection pool for connection to close */
- for (con= connections; con < next_con; con++)
- {
- DBUG_PRINT("info", ("con->name: %s", con->name));
- if (!strcmp(con->name, name))
- {
- simple_command(&con->mysql,COM_QUIT,NullS,0,1);
- DBUG_VOID_RETURN;
- }
- }
- die("connection '%s' not found in connection pool", name);
+ if (!(con= find_connection_by_name(name)))
+ die("connection '%s' not found in connection pool", name);
+
+ simple_command(&con->mysql,COM_QUIT,NullS,0,1);
+
+ DBUG_VOID_RETURN;
}
@@ -2621,8 +3057,10 @@ void do_send_quit(struct st_command *command)
void do_perl(struct st_command *command)
{
int error;
- char buf[FN_REFLEN];
+ File fd;
FILE *res_file;
+ char buf[FN_REFLEN];
+ char temp_file_path[FN_REFLEN];
static DYNAMIC_STRING ds_script;
static DYNAMIC_STRING ds_delimiter;
const struct command_arg perl_args[] = {
@@ -2645,14 +3083,17 @@ void do_perl(struct st_command *command)
DBUG_PRINT("info", ("Executing perl: %s", ds_script.str));
- /* Format a name for a tmp .pl file that is unique for this process */
- my_snprintf(buf, sizeof(buf), "%s/tmp/tmp_%d.pl",
- getenv("MYSQLTEST_VARDIR"), getpid());
- str_to_file(buf, ds_script.str, ds_script.length);
+ /* Create temporary file name */
+ if ((fd= create_temp_file(temp_file_path, getenv("MYSQLTEST_VARDIR"),
+ "tmp", O_CREAT | O_SHARE | O_RDWR,
+ MYF(MY_WME))) < 0)
+ die("Failed to create temporary file for perl command");
+ my_close(fd, MYF(0));
+
+ str_to_file(temp_file_path, ds_script.str, ds_script.length);
- /* Format the perl <filename> command */
- my_snprintf(buf, sizeof(buf), "perl %s/tmp/tmp_%d.pl",
- getenv("MYSQLTEST_VARDIR"), getpid());
+ /* Format the "perl <filename>" command */
+ my_snprintf(buf, sizeof(buf), "perl %s", temp_file_path);
if (!(res_file= popen(buf, "r")) && command->abort_on_error)
die("popen(\"%s\", \"r\") failed", buf);
@@ -2670,6 +3111,10 @@ void do_perl(struct st_command *command)
}
}
error= pclose(res_file);
+
+ /* Remove the temporary file */
+ my_delete(temp_file_path, MYF(0));
+
handle_command_error(command, WEXITSTATUS(error));
dynstr_free(&ds_script);
dynstr_free(&ds_delimiter);
@@ -2780,7 +3225,11 @@ wait_for_position:
SLAVE has been issued ?
*/
if (tries++ == 30)
+ {
+ show_query(mysql, "SHOW MASTER STATUS");
+ show_query(mysql, "SHOW SLAVE STATUS");
die("could not sync with master ('%s' returned NULL)", query_buf);
+ }
sleep(1); /* So at most we will wait 30 seconds and make 31 tries */
mysql_free_result(res);
goto wait_for_position;
@@ -3419,20 +3868,6 @@ void set_reconnect(MYSQL* mysql, int val)
}
-struct st_connection * find_connection_by_name(const char *name)
-{
- struct st_connection *con;
- for (con= connections; con < next_con; con++)
- {
- if (!strcmp(con->name, name))
- {
- return con;
- }
- }
- return 0; /* Connection not found */
-}
-
-
int select_connection_name(const char *name)
{
DBUG_ENTER("select_connection2");
@@ -3480,44 +3915,40 @@ void do_close_connection(struct st_command *command)
*p++= 0;
command->last_argument= p;
- /* Loop through connection pool for connection to close */
- for (con= connections; con < next_con; con++)
+ if (!(con= find_connection_by_name(name)))
+ die("connection '%s' not found in connection pool", name);
+
+ DBUG_PRINT("info", ("Closing connection %s", con->name));
+#ifndef EMBEDDED_LIBRARY
+ if (command->type == Q_DIRTY_CLOSE)
{
- DBUG_PRINT("info", ("con->name: %s", con->name));
- if (!strcmp(con->name, name))
+ if (con->mysql.net.vio)
{
- DBUG_PRINT("info", ("Closing connection %s", con->name));
-#ifndef EMBEDDED_LIBRARY
- if (command->type == Q_DIRTY_CLOSE)
- {
- if (con->mysql.net.vio)
- {
- vio_delete(con->mysql.net.vio);
- con->mysql.net.vio = 0;
- }
- }
+ vio_delete(con->mysql.net.vio);
+ con->mysql.net.vio = 0;
+ }
+ }
#endif
- if (next_con->stmt)
- mysql_stmt_close(next_con->stmt);
- next_con->stmt= 0;
+ if (con->stmt)
+ mysql_stmt_close(con->stmt);
+ con->stmt= 0;
- mysql_close(&con->mysql);
- if (con->util_mysql)
- mysql_close(con->util_mysql);
- con->util_mysql= 0;
- my_free(con->name, MYF(0));
+ mysql_close(&con->mysql);
- /*
- When the connection is closed set name to "-closed_connection-"
- to make it possible to reuse the connection name.
- */
- if (!(con->name = my_strdup("-closed_connection-", MYF(MY_WME))))
- die("Out of memory");
+ if (con->util_mysql)
+ mysql_close(con->util_mysql);
+ con->util_mysql= 0;
- DBUG_VOID_RETURN;
- }
- }
- die("connection '%s' not found in connection pool", name);
+ my_free(con->name, MYF(0));
+
+ /*
+ When the connection is closed set name to "-closed_connection-"
+ to make it possible to reuse the connection name.
+ */
+ if (!(con->name = my_strdup("-closed_connection-", MYF(MY_WME))))
+ die("Out of memory");
+
+ DBUG_VOID_RETURN;
}
@@ -3795,7 +4226,7 @@ void do_connect(struct st_command *command)
mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_NAME,
charset_info->csname);
if (opt_charsets_dir)
- mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_DIR,
+ mysql_options(&con_slot->mysql, MYSQL_SET_CHARSET_DIR,
opt_charsets_dir);
#ifdef HAVE_OPENSSL
@@ -4408,7 +4839,7 @@ void check_eol_junk(const char *eol)
terminated by new line '\n' regardless how many "delimiter" it contain.
*/
-#define MAX_QUERY (256*1024) /* 256K -- a test in sp-big is >128K */
+#define MAX_QUERY (256*1024*2) /* 256K -- a test in sp-big is >128K */
static char read_command_buf[MAX_QUERY];
int read_command(struct st_command** command_ptr)
@@ -4456,9 +4887,13 @@ int read_command(struct st_command** command_ptr)
if (!(command->query_buf= command->query= my_strdup(p, MYF(MY_WME))))
die("Out of memory");
- /* Calculate first word and first argument */
- for (p= command->query; *p && !my_isspace(charset_info, *p) ; p++) ;
+ /* Calculate first word length(the command), terminated by space or ( */
+ p= command->query;
+ while (*p && !my_isspace(charset_info, *p) && *p != '(')
+ p++;
command->first_word_len= (uint) (p - command->query);
+ DBUG_PRINT("info", ("first_word: %.*s",
+ command->first_word_len, command->query));
/* Skip spaces between command and first argument */
while (*p && my_isspace(charset_info, *p))
@@ -4542,6 +4977,10 @@ static struct my_option my_long_options[] =
{"sp-protocol", OPT_SP_PROTOCOL, "Use stored procedures for select",
(gptr*) &sp_protocol, (gptr*) &sp_protocol, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"tail-lines", OPT_TAIL_LINES,
+ "Number of lines of the resul to include in a failure report",
+ (gptr*) &opt_tail_lines, (gptr*) &opt_tail_lines, 0,
+ GET_INT, REQUIRED_ARG, 0, 0, 10000, 0, 0, 0},
#include "sslopt-longopts.h"
{"test-file", 'x', "Read test from/in this file (default stdin).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -4608,7 +5047,7 @@ void read_embedded_server_arguments(const char *name)
embedded_server_args[0]= (char*) ""; /* Progname */
}
if (!(file=my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME))))
- die("Failed to open file %s", buff);
+ die("Failed to open file '%s'", buff);
while (embedded_server_arg_count < MAX_EMBEDDED_SERVER_ARGS &&
(str=fgets(argument,sizeof(argument), file)))
@@ -4793,14 +5232,6 @@ void str_to_file(const char *fname, char *str, int size)
}
-void dump_result_to_reject_file(char *buf, int size)
-{
- char reject_file[FN_REFLEN];
- str_to_file(fn_format(reject_file, result_file_name, "", ".reject",
- MY_REPLACE_EXT),
- buf, size);
-}
-
void dump_result_to_log_file(char *buf, int size)
{
char log_file[FN_REFLEN];
@@ -4808,6 +5239,8 @@ void dump_result_to_log_file(char *buf, int size)
*opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
MY_REPLACE_EXT),
buf, size);
+ fprintf(stderr, "\nMore results from queries before failure can be found in %s\n",
+ log_file);
}
void dump_progress(void)
@@ -5792,7 +6225,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags)
init_dynamic_string(&ds_warnings, NULL, 0, 256);
- /* Scan for warning before sendign to server */
+ /* Scan for warning before sending to server */
scan_command_for_warnings(command);
/*
@@ -6224,7 +6657,6 @@ int main(int argc, char **argv)
connections_end= connections +
(sizeof(connections)/sizeof(struct st_connection)) - 1;
next_con= connections + 1;
- cur_con= connections;
#ifdef EMBEDDED_LIBRARY
/* set appropriate stack for the 'query' threads */
@@ -6300,6 +6732,7 @@ int main(int argc, char **argv)
if (cursor_protocol_enabled)
ps_protocol_enabled= 1;
+ cur_con= connections;
if (!( mysql_init(&cur_con->mysql)))
die("Failed in mysql_init()");
if (opt_compress)
@@ -6424,7 +6857,7 @@ int main(int argc, char **argv)
break;
case Q_LET: do_let(command); break;
case Q_EVAL_RESULT:
- eval_result = 1; break;
+ die("'eval_result' command is deprecated");
case Q_EVAL:
case Q_QUERY_VERTICAL:
case Q_QUERY_HORIZONTAL:
diff --git a/configure.in b/configure.in
index 1dff42cbfb1..f0b7089f968 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.48)
+AM_INIT_AUTOMAKE(mysql, 5.0.50)
AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10
@@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0
# ndb version
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
-NDB_VERSION_BUILD=48
+NDB_VERSION_BUILD=50
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
diff --git a/dbug/CMakeLists.txt b/dbug/CMakeLists.txt
index 375fd19fb40..8b27f79dcf4 100755
--- a/dbug/CMakeLists.txt
+++ b/dbug/CMakeLists.txt
@@ -13,8 +13,12 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-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}/dbug)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
-ADD_LIBRARY(dbug dbug.c factorial.c sanity.c)
+SET(DBUG_SOURCES dbug.c factorial.c sanity.c)
+
+IF(NOT SOURCE_SUBLIBS)
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+ ADD_LIBRARY(dbug ${DBUG_SOURCES})
+ENDIF(NOT SOURCE_SUBLIBS)
diff --git a/extra/CMakeLists.txt b/extra/CMakeLists.txt
index 8608e72127b..a909bc93820 100755
--- a/extra/CMakeLists.txt
+++ b/extra/CMakeLists.txt
@@ -20,7 +20,7 @@ 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 zlib wsock32)
+TARGET_LINK_LIBRARIES(comp_err debug dbug mysys strings zlib wsock32)
GET_TARGET_PROPERTY(COMP_ERR_EXE comp_err LOCATION)
@@ -39,13 +39,13 @@ ADD_CUSTOM_TARGET(GenError
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 wsock32)
+TARGET_LINK_LIBRARIES(my_print_defaults strings mysys debug dbug taocrypt wsock32)
ADD_EXECUTABLE(perror perror.c)
-TARGET_LINK_LIBRARIES(perror strings mysys dbug wsock32)
+TARGET_LINK_LIBRARIES(perror strings mysys debug dbug wsock32)
ADD_EXECUTABLE(replace replace.c)
-TARGET_LINK_LIBRARIES(replace strings mysys dbug wsock32)
+TARGET_LINK_LIBRARIES(replace strings mysys debug dbug wsock32)
IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("my_print_defaults" "asInvoker")
diff --git a/extra/yassl/CMakeLists.txt b/extra/yassl/CMakeLists.txt
index 5cc97f22a36..26e682cbb0c 100755
--- a/extra/yassl/CMakeLists.txt
+++ b/extra/yassl/CMakeLists.txt
@@ -13,9 +13,15 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-ADD_DEFINITIONS("-DWIN32 -D_LIB -DYASSL_PREFIX")
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/extra/yassl/include
+ ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/include
+ ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/mySTL)
-INCLUDE_DIRECTORIES(include taocrypt/include taocrypt/mySTL)
-ADD_LIBRARY(yassl src/buffer.cpp src/cert_wrapper.cpp src/crypto_wrapper.cpp src/handshake.cpp src/lock.cpp
+ADD_DEFINITIONS("-D_LIB -DYASSL_PREFIX")
+
+SET(YASSL_SOURCES 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)
+IF(NOT SOURCE_SUBLIBS)
+ ADD_LIBRARY(yassl ${YASSL_SOURCES})
+ENDIF(NOT SOURCE_SUBLIBS)
diff --git a/extra/yassl/include/openssl/crypto.h b/extra/yassl/include/openssl/crypto.h
index 288990e1318..f53e5231027 100644
--- a/extra/yassl/include/openssl/crypto.h
+++ b/extra/yassl/include/openssl/crypto.h
@@ -9,6 +9,7 @@
const char* SSLeay_version(int type);
+#define SSLEAY_NUMBER_DEFINED
#define SSLEAY_VERSION 0x0900L
#define SSLEAY_VERSION_NUMBER SSLEAY_VERSION
diff --git a/extra/yassl/include/openssl/des_old.h b/extra/yassl/include/openssl/des_old.h
new file mode 100644
index 00000000000..40e8fbc02af
--- /dev/null
+++ b/extra/yassl/include/openssl/des_old.h
@@ -0,0 +1 @@
+/* des_old.h for openvn */
diff --git a/extra/yassl/include/openssl/evp.h b/extra/yassl/include/openssl/evp.h
new file mode 100644
index 00000000000..1d66b08df46
--- /dev/null
+++ b/extra/yassl/include/openssl/evp.h
@@ -0,0 +1,10 @@
+/* evp.h for openSSL */
+
+#ifndef SSLEAY_NUMBER_DEFINED
+#define SSLEAY_NUMBER_DEFINED
+
+/* for OpenVPN */
+#define SSLEAY_VERSION_NUMBER 0x0090700f
+
+
+#endif /* SSLEAY_NUMBER_DEFINED */
diff --git a/extra/yassl/include/openssl/hmac.h b/extra/yassl/include/openssl/hmac.h
new file mode 100644
index 00000000000..a2eae4c08c1
--- /dev/null
+++ b/extra/yassl/include/openssl/hmac.h
@@ -0,0 +1 @@
+/* hmac.h for openvpn */
diff --git a/extra/yassl/include/openssl/objects.h b/extra/yassl/include/openssl/objects.h
new file mode 100644
index 00000000000..99f2326e51b
--- /dev/null
+++ b/extra/yassl/include/openssl/objects.h
@@ -0,0 +1 @@
+/* objects.h for openvpn */
diff --git a/extra/yassl/include/openssl/prefix_ssl.h b/extra/yassl/include/openssl/prefix_ssl.h
index dc6e3ef81f0..3a3a8c26c9c 100644
--- a/extra/yassl/include/openssl/prefix_ssl.h
+++ b/extra/yassl/include/openssl/prefix_ssl.h
@@ -30,6 +30,7 @@
#define SSL_CTX_new yaSSL_CTX_new
#define SSL_new yaSSL_new
#define SSL_set_fd yaSSL_set_fd
+#define SSL_get_fd yaSSL_get_fd
#define SSL_connect yaSSL_connect
#define SSL_write yaSSL_write
#define SSL_read yaSSL_read
@@ -91,6 +92,8 @@
#define SSL_set_rfd yaSSL_set_rfd
#define SSL_set_wfd yaSSL_set_wfd
#define SSL_set_shutdown yaSSL_set_shutdown
+#define SSL_set_quiet_shutdown yaSSL_set_quiet_shutdown
+#define SSL_get_quiet_shutdown yaSSL_get_quiet_shutdown
#define SSL_want_read yaSSL_want_read
#define SSL_want_write yaSSL_want_write
#define SSL_pending yaSSL_pending
diff --git a/extra/yassl/include/openssl/sha.h b/extra/yassl/include/openssl/sha.h
new file mode 100644
index 00000000000..bb487c05c2e
--- /dev/null
+++ b/extra/yassl/include/openssl/sha.h
@@ -0,0 +1 @@
+/* sha.h for openvpn */
diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h
index efd0dec75b6..c0b87f804ad 100644
--- a/extra/yassl/include/openssl/ssl.h
+++ b/extra/yassl/include/openssl/ssl.h
@@ -34,7 +34,7 @@
#include "rsa.h"
-#define YASSL_VERSION "1.6.5"
+#define YASSL_VERSION "1.7.2"
#if defined(__cplusplus)
@@ -201,6 +201,7 @@ typedef int YASSL_SOCKET_T;
SSL_CTX* SSL_CTX_new(SSL_METHOD*);
SSL* SSL_new(SSL_CTX*);
int SSL_set_fd (SSL*, YASSL_SOCKET_T);
+YASSL_SOCKET_T SSL_get_fd(const SSL*);
int SSL_connect(SSL*);
int SSL_write(SSL*, const void*, int);
int SSL_read(SSL*, void*, int);
diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp
index b7bd35f5fa2..b207f0bffbd 100644
--- a/extra/yassl/include/yassl_int.hpp
+++ b/extra/yassl/include/yassl_int.hpp
@@ -584,7 +584,7 @@ class SSL {
Socket socket_; // socket wrapper
Buffers buffers_; // buffered handshakes and data
Log log_; // logger
- bool quietShutdown_; // shutdown without handshakes
+ bool quietShutdown_;
// optimization variables
bool has_data_; // buffered data ready?
diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp
index 0cd0dfe9c7c..1d5a95820bb 100644
--- a/extra/yassl/src/handshake.cpp
+++ b/extra/yassl/src/handshake.cpp
@@ -719,6 +719,10 @@ int DoProcessReply(SSL& ssl)
// add new data
uint read = ssl.useSocket().receive(buffer.get_buffer() + buffSz, ready);
+ if (read == static_cast<uint>(-1)) {
+ ssl.SetError(receive_error);
+ return 0;
+ }
buffer.add_size(read);
uint offset = 0;
const MessageFactory& mf = ssl.getFactory().getMessage();
diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp
index d53a109d70e..eee5d47377f 100644
--- a/extra/yassl/src/socket_wrapper.cpp
+++ b/extra/yassl/src/socket_wrapper.cpp
@@ -114,8 +114,6 @@ uint Socket::send(const byte* buf, unsigned int sz, int flags) const
const byte* pos = buf;
const byte* end = pos + sz;
- assert(socket_ != INVALID_SOCKET);
-
while (pos != end) {
int sent = ::send(socket_, reinterpret_cast<const char *>(pos),
static_cast<int>(end - pos), flags);
@@ -132,7 +130,6 @@ uint Socket::send(const byte* buf, unsigned int sz, int flags) const
uint Socket::receive(byte* buf, unsigned int sz, int flags)
{
- assert(socket_ != INVALID_SOCKET);
wouldBlock_ = false;
int recvd = ::recv(socket_, reinterpret_cast<char *>(buf), sz, flags);
@@ -163,7 +160,6 @@ bool Socket::wait()
void Socket::shutDown(int how)
{
- assert(socket_ != INVALID_SOCKET);
shutdown(socket_, how);
}
diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp
index c3d580a93ab..f09a43be56e 100644
--- a/extra/yassl/src/ssl.cpp
+++ b/extra/yassl/src/ssl.cpp
@@ -239,6 +239,12 @@ int SSL_set_fd(SSL* ssl, YASSL_SOCKET_T fd)
}
+YASSL_SOCKET_T SSL_get_fd(const SSL* ssl)
+{
+ return ssl->getSocket().get_fd();
+}
+
+
int SSL_connect(SSL* ssl)
{
if (ssl->GetError() == YasslError(SSL_ERROR_WANT_READ))
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index f5ab2f200a5..0b6cb89e77e 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -773,6 +773,7 @@ void SSL::SetError(YasslError ye)
// TODO: add string here
}
+
// set the quiet shutdown mode (close_nofiy not sent or received on shutdown)
void SSL::SetQuietShutdown(bool mode)
{
diff --git a/extra/yassl/taocrypt/CMakeLists.txt b/extra/yassl/taocrypt/CMakeLists.txt
index baa8f97dff6..e91fa021de5 100755
--- a/extra/yassl/taocrypt/CMakeLists.txt
+++ b/extra/yassl/taocrypt/CMakeLists.txt
@@ -13,9 +13,10 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-INCLUDE_DIRECTORIES(mySTL include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/mySTL
+ ${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/include)
-ADD_LIBRARY(taocrypt src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp src/asn.cpp src/coding.cpp
+SET(TAOCRYPT_SOURCES 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
@@ -23,3 +24,6 @@ ADD_LIBRARY(taocrypt src/aes.cpp src/aestables.cpp src/algebra.cpp src/arc4.cpp
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)
+IF(NOT SOURCE_SUBLIBS)
+ ADD_LIBRARY(taocrypt ${TAOCRYPT_SOURCES})
+ENDIF(NOT SOURCE_SUBLIBS)
diff --git a/extra/yassl/taocrypt/src/coding.cpp b/extra/yassl/taocrypt/src/coding.cpp
index 55fe31831e3..7a9d50aaac9 100644
--- a/extra/yassl/taocrypt/src/coding.cpp
+++ b/extra/yassl/taocrypt/src/coding.cpp
@@ -107,11 +107,12 @@ void HexDecoder::Decode()
// sanity checks
assert( b < sizeof(hexDecode)/sizeof(hexDecode[0]) );
assert( b2 < sizeof(hexDecode)/sizeof(hexDecode[0]) );
- assert( b != bad && b2 != bad );
b = hexDecode[b];
b2 = hexDecode[b2];
+ assert( b != bad && b2 != bad );
+
decoded_[i++] = (b << 4) | b2;
bytes -= 2;
}
@@ -184,7 +185,7 @@ void Base64Decoder::Decode()
{
word32 bytes = coded_.size();
word32 plainSz = bytes - ((bytes + (pemLineSz - 1)) / pemLineSz);
- plainSz = ((plainSz * 3) / 4) + 3;
+ plainSz = (plainSz * 3 + 3) / 4;
decoded_.New(plainSz);
word32 i = 0;
diff --git a/extra/yassl/taocrypt/src/crypto.cpp b/extra/yassl/taocrypt/src/crypto.cpp
index 82d3b853084..90d406bf0c2 100644
--- a/extra/yassl/taocrypt/src/crypto.cpp
+++ b/extra/yassl/taocrypt/src/crypto.cpp
@@ -26,6 +26,11 @@ extern "C" {
// locking handled internally by library
char CRYPTO_lock() { return 0;}
char CRYPTO_add_lock() { return 0;}
+
+
+ // for openvpn, test are the signatures they use
+ char EVP_CIPHER_CTX_init() { return 0; }
+ char CRYPTO_mem_ctrl() { return 0; }
} // extern "C"
diff --git a/include/my_pthread.h b/include/my_pthread.h
index e28bb9df1f3..13b7cf93d6f 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -30,25 +30,6 @@ extern "C" {
#define EXTERNC
#endif /* __cplusplus */
-/*
- BUG#24507: Race conditions inside current NPTL pthread_exit() implementation.
-
- If macro NPTL_PTHREAD_EXIT_HACK is defined then a hack described in the bug
- report will be implemented inside my_thread_global_init() in my_thr_init.c.
-
- This amounts to spawning a dummy thread which does nothing but executes
- pthread_exit(0).
-
- This bug is fixed in version 2.5 of glibc library.
-
- TODO: Remove this code when fixed versions of glibc6 are in common use.
- */
-
-#if defined(TARGET_OS_LINUX) && defined(HAVE_NPTL) && \
- defined(__GLIBC__) && ( __GLIBC__ < 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ < 5 )
-#define NPTL_PTHREAD_EXIT_BUG 1
-#endif
-
#if defined(__WIN__) || defined(OS2)
#ifdef OS2
@@ -200,7 +181,7 @@ extern int pthread_mutex_destroy (pthread_mutex_t *);
#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
-#define pthread_kill(A,B) pthread_dummy(0)
+#define pthread_kill(A,B) pthread_dummy(ESRCH)
#endif /* OS2 */
/* Dummy defines for easier code */
@@ -464,14 +445,14 @@ struct tm *gmtime_r(const time_t *clock, struct tm *res);
#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
#define pthread_create(A,B,C,D) pthread_create((A),*(B),(C),(D))
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
-#define pthread_kill(A,B) pthread_dummy(0)
+#define pthread_kill(A,B) pthread_dummy(ESRCH)
#undef pthread_detach_this_thread
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
#endif
#ifdef HAVE_DARWIN5_THREADS
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
-#define pthread_kill(A,B) pthread_dummy(0)
+#define pthread_kill(A,B) pthread_dummy(ESRCH)
#define pthread_condattr_init(A) pthread_dummy(0)
#define pthread_condattr_destroy(A) pthread_dummy(0)
#undef pthread_detach_this_thread
@@ -491,7 +472,7 @@ struct tm *gmtime_r(const time_t *clock, struct tm *res);
#ifndef pthread_sigmask
#define pthread_sigmask(A,B,C) sigprocmask((A),(B),(C))
#endif
-#define pthread_kill(A,B) pthread_dummy(0)
+#define pthread_kill(A,B) pthread_dummy(ESRCH)
#undef pthread_detach_this_thread
#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(&tmp); }
#elif !defined(__NETWARE__) /* HAVE_PTHREAD_ATTR_CREATE && !HAVE_SIGWAIT */
@@ -718,6 +699,11 @@ extern pthread_mutexattr_t my_errorcheck_mutexattr;
#define MY_MUTEX_INIT_ERRCHK NULL
#endif
+#ifndef ESRCH
+/* Define it to something */
+#define ESRCH 1
+#endif
+
extern my_bool my_thread_global_init(void);
extern void my_thread_global_end(void);
extern my_bool my_thread_init(void);
diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c
index 333894d2312..c71bb6ed827 100644
--- a/innobase/fsp/fsp0fsp.c
+++ b/innobase/fsp/fsp0fsp.c
@@ -2806,7 +2806,7 @@ will be able to insert new data to the database without running out the
tablespace. Only free extents are taken into account and we also subtract
the safety margin required by the above function fsp_reserve_free_extents. */
-ulint
+ullint
fsp_get_available_space_in_free_extents(
/*====================================*/
/* out: available space in kB */
@@ -2872,8 +2872,9 @@ fsp_get_available_space_in_free_extents(
return(0);
}
- return(((n_free - reserve) * FSP_EXTENT_SIZE)
- * (UNIV_PAGE_SIZE / 1024));
+ return((ullint)(n_free - reserve)
+ * FSP_EXTENT_SIZE
+ * (UNIV_PAGE_SIZE / 1024));
}
/************************************************************************
diff --git a/innobase/include/fsp0fsp.h b/innobase/include/fsp0fsp.h
index 2fcde882df7..57f0ae6f65b 100644
--- a/innobase/include/fsp0fsp.h
+++ b/innobase/include/fsp0fsp.h
@@ -245,7 +245,7 @@ will be able to insert new data to the database without running out the
tablespace. Only free extents are taken into account and we also subtract
the safety margin required by the above function fsp_reserve_free_extents. */
-ulint
+ullint
fsp_get_available_space_in_free_extents(
/*====================================*/
/* out: available space in kB */
diff --git a/innobase/include/univ.i b/innobase/include/univ.i
index 64a240ae8a7..88cef65afeb 100644
--- a/innobase/include/univ.i
+++ b/innobase/include/univ.i
@@ -195,6 +195,8 @@ typedef __int64 ib_longlong;
typedef longlong ib_longlong;
#endif
+typedef unsigned long long int ullint;
+
#ifndef __WIN__
#if SIZEOF_LONG != SIZEOF_VOIDP
#error "Error: InnoDB's ulint must be of the same size as void*"
diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c
index c1ceb9791f2..5fd5ab863df 100644
--- a/innobase/log/log0recv.c
+++ b/innobase/log/log0recv.c
@@ -57,6 +57,16 @@ ibool recv_needed_recovery = FALSE;
ibool recv_lsn_checks_on = FALSE;
+/* There are two conditions under which we scan the logs, the first
+is normal startup and the second is when we do a recovery from an
+archive.
+This flag is set if we are doing a scan from the last checkpoint during
+startup. If we find log entries that were written after the last checkpoint
+we know that the server was not cleanly shutdown. We must then initialize
+the crash recovery environment before attempting to store these entries in
+the log hash table. */
+ibool recv_log_scan_is_startup_type = FALSE;
+
/* If the following is TRUE, the buffer pool file pages must be invalidated
after recovery and no ibuf operations are allowed; this becomes TRUE if
the log record hash table becomes too full, and log records must be merged
@@ -99,6 +109,16 @@ the recovery failed and the database may be corrupt. */
dulint recv_max_page_lsn;
+/* prototypes */
+
+/***********************************************************
+Initialize crash recovery environment. Can be called iff
+recv_needed_recovery == FALSE. */
+static
+void
+recv_init_crash_recovery(void);
+/*===========================*/
+
/************************************************************
Creates the recovery system. */
@@ -2438,6 +2458,23 @@ recv_scan_log_recs(
if (ut_dulint_cmp(scanned_lsn, recv_sys->scanned_lsn) > 0) {
+ /* We have found more entries. If this scan is
+ of startup type, we must initiate crash recovery
+ environment before parsing these log records. */
+
+ if (recv_log_scan_is_startup_type
+ && !recv_needed_recovery) {
+
+ fprintf(stderr,
+ "InnoDB: Log scan progressed"
+ " past the checkpoint lsn %lu %lu\n",
+ (ulong) ut_dulint_get_high(
+ recv_sys->scanned_lsn),
+ (ulong) ut_dulint_get_low(
+ recv_sys->scanned_lsn));
+ recv_init_crash_recovery();
+ }
+
/* We were able to find more log data: add it to the
parsing buffer if parse_start_lsn is already
non-zero */
@@ -2557,6 +2594,48 @@ recv_group_scan_log_recs(
#endif /* UNIV_DEBUG */
}
+/***********************************************************
+Initialize crash recovery environment. Can be called iff
+recv_needed_recovery == FALSE. */
+static
+void
+recv_init_crash_recovery(void)
+/*==========================*/
+{
+ ut_a(!recv_needed_recovery);
+
+ recv_needed_recovery = TRUE;
+
+ ut_print_timestamp(stderr);
+
+ fprintf(stderr,
+ " InnoDB: Database was not"
+ " shut down normally!\n"
+ "InnoDB: Starting crash recovery.\n");
+
+ fprintf(stderr,
+ "InnoDB: Reading tablespace information"
+ " from the .ibd files...\n");
+
+ fil_load_single_table_tablespaces();
+
+ /* If we are using the doublewrite method, we will
+ check if there are half-written pages in data files,
+ and restore them from the doublewrite buffer if
+ possible */
+
+ if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
+
+ fprintf(stderr,
+ "InnoDB: Restoring possible"
+ " half-written data pages from"
+ " the doublewrite\n"
+ "InnoDB: buffer...\n");
+ trx_sys_doublewrite_init_or_restore_pages(TRUE);
+ }
+
+}
+
/************************************************************
Recovers from a checkpoint. When this function returns, the database is able
to start processing of new user transactions, but the function
@@ -2681,72 +2760,6 @@ recv_recovery_from_checkpoint_start(
recv_sys->recovered_lsn = checkpoint_lsn;
srv_start_lsn = checkpoint_lsn;
-
- /* NOTE: we always do a 'recovery' at startup, but only if
- there is something wrong we will print a message to the
- user about recovery: */
-
- if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn) != 0
- || ut_dulint_cmp(checkpoint_lsn, min_flushed_lsn) != 0) {
-
- if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn)
- < 0) {
- fprintf(stderr,
-"InnoDB: ##########################################################\n"
-"InnoDB: WARNING!\n"
-"InnoDB: The log sequence number in ibdata files is higher\n"
-"InnoDB: than the log sequence number in the ib_logfiles! Are you sure\n"
-"InnoDB: you are using the right ib_logfiles to start up the database?\n"
-"InnoDB: Log sequence number in ib_logfiles is %lu %lu, log\n"
-"InnoDB: sequence numbers stamped to ibdata file headers are between\n"
-"InnoDB: %lu %lu and %lu %lu.\n"
-"InnoDB: ##########################################################\n",
- (ulong) ut_dulint_get_high(checkpoint_lsn),
- (ulong) ut_dulint_get_low(checkpoint_lsn),
- (ulong) ut_dulint_get_high(min_flushed_lsn),
- (ulong) ut_dulint_get_low(min_flushed_lsn),
- (ulong) ut_dulint_get_high(max_flushed_lsn),
- (ulong) ut_dulint_get_low(max_flushed_lsn));
- }
-
- recv_needed_recovery = TRUE;
-
- ut_print_timestamp(stderr);
-
- fprintf(stderr,
-" InnoDB: Database was not shut down normally!\n"
-"InnoDB: Starting crash recovery.\n");
-
- fprintf(stderr,
-"InnoDB: Reading tablespace information from the .ibd files...\n");
-
- fil_load_single_table_tablespaces();
-
- /* If we are using the doublewrite method, we will
- check if there are half-written pages in data files,
- and restore them from the doublewrite buffer if
- possible */
-
- if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
-
- fprintf(stderr,
-"InnoDB: Restoring possible half-written data pages from the doublewrite\n"
-"InnoDB: buffer...\n");
- trx_sys_doublewrite_init_or_restore_pages(
- TRUE);
- }
-
- ut_print_timestamp(stderr);
-
- fprintf(stderr,
-" InnoDB: Starting log scan based on checkpoint at\n"
-"InnoDB: log sequence number %lu %lu.\n",
- (ulong) ut_dulint_get_high(checkpoint_lsn),
- (ulong) ut_dulint_get_low(checkpoint_lsn));
- } else {
- /* Init the doublewrite buffer memory structure */
- trx_sys_doublewrite_init_or_restore_pages(FALSE);
- }
}
contiguous_lsn = ut_dulint_align_down(recv_sys->scanned_lsn,
@@ -2798,7 +2811,9 @@ recv_recovery_from_checkpoint_start(
group = UT_LIST_GET_NEXT(log_groups, group);
}
- while (group) {
+ /* Set the flag to publish that we are doing startup scan. */
+ recv_log_scan_is_startup_type = (type == LOG_CHECKPOINT);
+ while (group) {
old_scanned_lsn = recv_sys->scanned_lsn;
recv_group_scan_log_recs(group, &contiguous_lsn,
@@ -2819,6 +2834,69 @@ recv_recovery_from_checkpoint_start(
group = UT_LIST_GET_NEXT(log_groups, group);
}
+ /* Done with startup scan. Clear the flag. */
+ recv_log_scan_is_startup_type = FALSE;
+ if (type == LOG_CHECKPOINT) {
+ /* NOTE: we always do a 'recovery' at startup, but only if
+ there is something wrong we will print a message to the
+ user about recovery: */
+
+ if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn) != 0
+ || ut_dulint_cmp(checkpoint_lsn, min_flushed_lsn) != 0) {
+
+ if (ut_dulint_cmp(checkpoint_lsn, max_flushed_lsn)
+ < 0) {
+ fprintf(stderr,
+ "InnoDB: #########################"
+ "#################################\n"
+ "InnoDB: "
+ "WARNING!\n"
+ "InnoDB: The log sequence number"
+ " in ibdata files is higher\n"
+ "InnoDB: than the log sequence number"
+ " in the ib_logfiles! Are you sure\n"
+ "InnoDB: you are using the right"
+ " ib_logfiles to start up"
+ " the database?\n"
+ "InnoDB: Log sequence number in"
+ " ib_logfiles is %lu %lu, log\n"
+ "InnoDB: sequence numbers stamped"
+ " to ibdata file headers are between\n"
+ "InnoDB: %lu %lu and %lu %lu.\n"
+ "InnoDB: #########################"
+ "#################################\n",
+ (ulong) ut_dulint_get_high(
+ checkpoint_lsn),
+ (ulong) ut_dulint_get_low(
+ checkpoint_lsn),
+ (ulong) ut_dulint_get_high(
+ min_flushed_lsn),
+ (ulong) ut_dulint_get_low(
+ min_flushed_lsn),
+ (ulong) ut_dulint_get_high(
+ max_flushed_lsn),
+ (ulong) ut_dulint_get_low(
+ max_flushed_lsn));
+
+
+ }
+
+ if (!recv_needed_recovery) {
+ fprintf(stderr,
+ "InnoDB: The log sequence number"
+ " in ibdata files does not match\n"
+ "InnoDB: the log sequence number"
+ " in the ib_logfiles!\n");
+ recv_init_crash_recovery();
+ }
+
+ }
+ if (!recv_needed_recovery) {
+ /* Init the doublewrite buffer memory structure */
+ trx_sys_doublewrite_init_or_restore_pages(FALSE);
+ }
+ }
+
/* We currently have only one log group */
if (ut_dulint_cmp(group_scanned_lsn, checkpoint_lsn) < 0) {
ut_print_timestamp(stderr);
@@ -2871,16 +2949,9 @@ recv_recovery_from_checkpoint_start(
recv_synchronize_groups(up_to_date_group);
if (!recv_needed_recovery) {
- if (ut_dulint_cmp(checkpoint_lsn, recv_sys->recovered_lsn)
- != 0) {
- fprintf(stderr,
-"InnoDB: Warning: we did not need to do crash recovery, but log scan\n"
-"InnoDB: progressed past the checkpoint lsn %lu %lu up to lsn %lu %lu\n",
- (ulong) ut_dulint_get_high(checkpoint_lsn),
- (ulong) ut_dulint_get_low(checkpoint_lsn),
- (ulong) ut_dulint_get_high(recv_sys->recovered_lsn),
- (ulong) ut_dulint_get_low(recv_sys->recovered_lsn));
- }
+ ut_a(ut_dulint_cmp(checkpoint_lsn,
+ recv_sys->recovered_lsn) == 0);
+
} else {
srv_start_lsn = recv_sys->recovered_lsn;
}
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index 3030b20a685..8b1fbd742d5 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -436,10 +436,9 @@ os_file_handle_error_no_exit(
#undef USE_FILE_LOCK
#define USE_FILE_LOCK
-#if defined(UNIV_HOTBACKUP) || defined(__WIN__) || defined(__FreeBSD__) || defined(__NETWARE__)
+#if defined(UNIV_HOTBACKUP) || defined(__WIN__) || defined(__NETWARE__)
/* InnoDB Hot Backup does not lock the data files.
* On Windows, mandatory locking is used.
- * On FreeBSD with LinuxThreads, advisory locking does not work properly.
*/
# undef USE_FILE_LOCK
#endif
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index e4ce29f445c..31cd202e4d2 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -1151,7 +1151,7 @@ srv_conc_force_enter_innodb(
srv_conc_n_threads++;
trx->declared_to_be_inside_innodb = TRUE;
- trx->n_tickets_to_enter_innodb = 0;
+ trx->n_tickets_to_enter_innodb = 1;
os_fast_mutex_unlock(&srv_conc_mutex);
}
diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c
index 4dc826e5947..d865c709bf6 100644
--- a/innobase/trx/trx0trx.c
+++ b/innobase/trx/trx0trx.c
@@ -1606,19 +1606,21 @@ trx_commit_for_mysql(
the transaction object does not have an InnoDB session object, and we
set the dummy session that we use for all MySQL transactions. */
- mutex_enter(&kernel_mutex);
-
if (trx->sess == NULL) {
/* Open a dummy session */
if (!trx_dummy_sess) {
- trx_dummy_sess = sess_open();
+ mutex_enter(&kernel_mutex);
+
+ if (!trx_dummy_sess) {
+ trx_dummy_sess = sess_open();
+ }
+
+ mutex_exit(&kernel_mutex);
}
trx->sess = trx_dummy_sess;
}
-
- mutex_exit(&kernel_mutex);
trx_start_if_not_started(trx);
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index 3b18531f6c0..59e70d68a6d 100755
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -14,25 +14,54 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
INCLUDE("${PROJECT_SOURCE_DIR}/win/mysql_manifest.cmake")
-# 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")
-SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
-SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
-SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
-SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_TLS")
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+
+# Note that we don't link with the libraries "strings" or "mysys"
+# here, instead we recompile the files needed and include them
+# directly. This means we don't have to worry here about if these
+# libraries are compiled defining USE_TLS or not. Not that it *should*
+# have been a problem anyway, they don't use thread local storage.
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
+# We include the source file listing instead of referencing the
+# libraries. At least with CMake 2.4 and Visual Studio 2005 a static
+# library created from other static libraries would not be complete,
+# i.e. the libraries listed in TARGET_LINK_LIBRARIES() were just
+# ignored.
+
+
+# Include and add the directory path
+SET(SOURCE_SUBLIBS TRUE)
+
+INCLUDE(${CMAKE_SOURCE_DIR}/zlib/CMakeLists.txt)
+FOREACH(rpath ${ZLIB_SOURCES})
+ SET(LIB_SOURCES ${LIB_SOURCES} ../zlib/${rpath})
+ENDFOREACH(rpath)
+
+# FIXME only needed if build type is "Debug", but CMAKE_BUILD_TYPE is
+# not set during configure time.
+INCLUDE(${CMAKE_SOURCE_DIR}/dbug/CMakeLists.txt)
+FOREACH(rpath ${DBUG_SOURCES})
+ SET(LIB_SOURCES ${LIB_SOURCES} ../dbug/${rpath})
+ENDFOREACH(rpath)
+
+INCLUDE(${CMAKE_SOURCE_DIR}/extra/yassl/taocrypt/CMakeLists.txt)
+FOREACH(rpath ${TAOCRYPT_SOURCES})
+ SET(LIB_SOURCES ${LIB_SOURCES} ../extra/yassl/taocrypt/${rpath})
+ENDFOREACH(rpath)
+
+INCLUDE(${CMAKE_SOURCE_DIR}/extra/yassl/CMakeLists.txt)
+FOREACH(rpath ${YASSL_SOURCES})
+ SET(LIB_SOURCES ${LIB_SOURCES} ../extra/yassl/${rpath})
+ENDFOREACH(rpath)
+
+SET(CLIENT_SOURCES ../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
@@ -41,10 +70,11 @@ ADD_LIBRARY(libmysql SHARED dll.c libmysql.def
../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/default.c errmsg.c ../mysys/errors.c
+ ../mysys/hash.c ../mysys/my_sleep.c ../mysys/default_modify.c
+ get_password.c ../strings/int2str.c ../strings/is_prefix.c
+ libmysql.c ../mysys/list.c ../strings/llstr.c
+ ../strings/longlong2str.c 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
@@ -66,9 +96,34 @@ ADD_LIBRARY(libmysql SHARED dll.c libmysql.def
../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)
+ ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c
+ ${LIB_SOURCES})
+
+# Need to set USE_TLS for building the DLL, since __declspec(thread)
+# approach to thread local storage does not work properly in DLLs.
+#
+# The static library might be used to form another DLL, as is the case
+# with the ODBC driver, so it has to be compiled with USE_TLS as well.
+#
+# We create a third library without USE_TLS for internal use. We can't
+# be sure that some client application part of this build doesn't go
+# beond the documented API, and try access the Thread Local Storage.
+# The "_notls" means no Tls*() functions used, i.e. "static" TLS.
+
+ADD_LIBRARY(libmysql SHARED ${CLIENT_SOURCES} dll.c libmysql.def)
+ADD_LIBRARY(mysqlclient STATIC ${CLIENT_SOURCES})
+ADD_LIBRARY(mysqlclient_notls STATIC ${CLIENT_SOURCES})
+
+SET_TARGET_PROPERTIES(libmysql mysqlclient PROPERTIES COMPILE_FLAGS "-DUSE_TLS")
+
+ADD_DEPENDENCIES(libmysql GenError)
+TARGET_LINK_LIBRARIES(libmysql wsock32)
+
+ADD_DEPENDENCIES(mysqlclient GenError)
+TARGET_LINK_LIBRARIES(mysqlclient)
+
+ADD_DEPENDENCIES(mysqlclient_notls GenError)
+TARGET_LINK_LIBRARIES(mysqlclient_notls)
ADD_EXECUTABLE(myTest mytest.c)
TARGET_LINK_LIBRARIES(myTest libmysql)
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 1a0aae414ed..85c56a7ea40 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -4679,9 +4679,17 @@ int cli_read_binary_rows(MYSQL_STMT *stmt)
MYSQL *mysql= stmt->mysql;
MYSQL_DATA *result= &stmt->result;
MYSQL_ROWS *cur, **prev_ptr= &result->data;
- NET *net = &mysql->net;
+ NET *net;
+
+ if (!mysql)
+ {
+ set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate);
+ return 1;
+ }
+
DBUG_ENTER("cli_read_binary_rows");
+ net = &mysql->net;
mysql= mysql->last_used_con;
while ((pkt_len= cli_safe_read(mysql)) != packet_error)
diff --git a/myisam/CMakeLists.txt b/myisam/CMakeLists.txt
index 94a7ffc9952..a557d61b87f 100755
--- a/myisam/CMakeLists.txt
+++ b/myisam/CMakeLists.txt
@@ -30,16 +30,16 @@ ADD_LIBRARY(myisam ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c f
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)
+TARGET_LINK_LIBRARIES(myisam_ftdump myisam mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(myisamchk myisamchk.c)
-TARGET_LINK_LIBRARIES(myisamchk myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(myisamchk myisam mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(myisamlog myisamlog.c)
-TARGET_LINK_LIBRARIES(myisamlog myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(myisamlog myisam mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(myisampack myisampack.c)
-TARGET_LINK_LIBRARIES(myisampack myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(myisampack myisam mysys debug dbug strings zlib wsock32)
IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("myisam_ftdump" "asInvoker")
diff --git a/myisam/mi_rkey.c b/myisam/mi_rkey.c
index 83259a275b1..17ea54bf568 100644
--- a/myisam/mi_rkey.c
+++ b/myisam/mi_rkey.c
@@ -95,42 +95,63 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
myisam_read_vec[search_flag], info->s->state.key_root[inx]))
{
/*
- If we searching for a partial key (or using >, >=, < or <=) and
- the data is outside of the data file, we need to continue searching
- for the first key inside the data file
+ Found a key, but it might not be usable. We cannot use rows that
+ are inserted by other threads after we got our table lock
+ ("concurrent inserts"). The record may not even be present yet.
+ Keys are inserted into the index(es) before the record is
+ inserted into the data file. When we got our table lock, we
+ saved the current data_file_length. Concurrent inserts always go
+ to the end of the file. So we can test if the found key
+ references a new record.
*/
- if (info->lastpos >= info->state->data_file_length &&
- (search_flag != HA_READ_KEY_EXACT ||
- last_used_keyseg != keyinfo->seg + keyinfo->keysegs))
+ if (info->lastpos >= info->state->data_file_length)
{
- do
+ /* The key references a concurrently inserted record. */
+ if (search_flag == HA_READ_KEY_EXACT &&
+ last_used_keyseg == keyinfo->seg + keyinfo->keysegs)
+ {
+ /* Simply ignore the key if it matches exactly. (Bug #29838) */
+ my_errno= HA_ERR_KEY_NOT_FOUND;
+ info->lastpos= HA_OFFSET_ERROR;
+ }
+ else
{
- uint not_used[2];
- /*
- Skip rows that are inserted by other threads since we got a lock
- Note that this can only happen if we are not searching after an
- full length exact key, because the keys are sorted
- according to position
- */
- if (_mi_search_next(info, keyinfo, info->lastkey,
- info->lastkey_length,
- myisam_readnext_vec[search_flag],
- info->s->state.key_root[inx]))
- break;
/*
- Check that the found key does still match the search.
- _mi_search_next() delivers the next key regardless of its
- value.
+ If searching for a partial key (or using >, >=, < or <=) and
+ the data is outside of the data file, we need to continue
+ searching for the first key inside the data file.
*/
- if (search_flag == HA_READ_KEY_EXACT &&
- ha_key_cmp(keyinfo->seg, key_buff, info->lastkey, use_key_length,
- SEARCH_FIND, not_used))
+ do
{
- my_errno= HA_ERR_KEY_NOT_FOUND;
- info->lastpos= HA_OFFSET_ERROR;
- break;
- }
- } while (info->lastpos >= info->state->data_file_length);
+ uint not_used[2];
+ /*
+ Skip rows that are inserted by other threads since we got
+ a lock. Note that this can only happen if we are not
+ searching after a full length exact key, because the keys
+ are sorted according to position.
+ */
+ if (_mi_search_next(info, keyinfo, info->lastkey,
+ info->lastkey_length,
+ myisam_readnext_vec[search_flag],
+ info->s->state.key_root[inx]))
+ break; /* purecov: inspected */
+ /*
+ Check that the found key does still match the search.
+ _mi_search_next() delivers the next key regardless of its
+ value.
+ */
+ if (search_flag == HA_READ_KEY_EXACT &&
+ ha_key_cmp(keyinfo->seg, key_buff, info->lastkey,
+ use_key_length, SEARCH_FIND, not_used))
+ {
+ /* purecov: begin inspected */
+ my_errno= HA_ERR_KEY_NOT_FOUND;
+ info->lastpos= HA_OFFSET_ERROR;
+ break;
+ /* purecov: end */
+ }
+ } while (info->lastpos >= info->state->data_file_length);
+ }
}
}
}
diff --git a/myisam/mi_test_all.sh b/myisam/mi_test_all.sh
index c1fb12d7c3b..5989d9cfaf0 100755
--- a/myisam/mi_test_all.sh
+++ b/myisam/mi_test_all.sh
@@ -6,143 +6,143 @@
valgrind="valgrind --alignment=8 --leak-check=yes"
silent="-s"
-if test -f mi_test1$MACH ; then suffix=$MACH else suffix=""; fi
-mi_test1$suffix $silent
-myisamchk$suffix -se test1
-mi_test1$suffix $silent -N -S
-myisamchk$suffix -se test1
-mi_test1$suffix $silent -P --checksum
-myisamchk$suffix -se test1
-mi_test1$suffix $silent -P -N -S
-myisamchk$suffix -se test1
-mi_test1$suffix $silent -B -N -R2
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -k 480 --unique
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -N -S -R1
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -p -S
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -p -S -N --unique
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -p -S -N --key_length=127 --checksum
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -p -S -N --key_length=128
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -p -S --key_length=480
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -B
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -B --key_length=64 --unique
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -B -k 480 --checksum
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -B -k 480 -N --unique --checksum
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -m
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -m -P --unique --checksum
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -m -P --key_length=480 --key_cache
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -m -p
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -w -S --unique
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -w --key_length=64 --checksum
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -w -N --key_length=480
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -w -S --key_length=480 --checksum
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -b -N
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -a -b --key_length=480
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent -p -B --key_length=480
-myisamchk$suffix -sm test1
+if test -f mi_test1$MACH ; then suffix=$MACH ; else suffix=""; fi
+./mi_test1$suffix $silent
+./myisamchk$suffix -se test1
+./mi_test1$suffix $silent -N -S
+./myisamchk$suffix -se test1
+./mi_test1$suffix $silent -P --checksum
+./myisamchk$suffix -se test1
+./mi_test1$suffix $silent -P -N -S
+./myisamchk$suffix -se test1
+./mi_test1$suffix $silent -B -N -R2
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -k 480 --unique
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -N -S -R1
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -p -S
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -p -S -N --unique
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -p -S -N --key_length=127 --checksum
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -p -S -N --key_length=128
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -p -S --key_length=480
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -B
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -B --key_length=64 --unique
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -B -k 480 --checksum
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -B -k 480 -N --unique --checksum
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -m
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -m -P --unique --checksum
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -m -P --key_length=480 --key_cache
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -m -p
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -w -S --unique
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -w --key_length=64 --checksum
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -w -N --key_length=480
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -w -S --key_length=480 --checksum
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -b -N
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -a -b --key_length=480
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent -p -B --key_length=480
+./myisamchk$suffix -sm test1
-mi_test1$suffix $silent --checksum
-myisamchk$suffix -se test1
-myisamchk$suffix -rs test1
-myisamchk$suffix -se test1
-myisamchk$suffix -rqs test1
-myisamchk$suffix -se test1
-myisamchk$suffix -rs --correct-checksum test1
-myisamchk$suffix -se test1
-myisamchk$suffix -rqs --correct-checksum test1
-myisamchk$suffix -se test1
-myisamchk$suffix -ros --correct-checksum test1
-myisamchk$suffix -se test1
-myisamchk$suffix -rqos --correct-checksum test1
-myisamchk$suffix -se test1
+./mi_test1$suffix $silent --checksum
+./myisamchk$suffix -se test1
+./myisamchk$suffix -rs test1
+./myisamchk$suffix -se test1
+./myisamchk$suffix -rqs test1
+./myisamchk$suffix -se test1
+./myisamchk$suffix -rs --correct-checksum test1
+./myisamchk$suffix -se test1
+./myisamchk$suffix -rqs --correct-checksum test1
+./myisamchk$suffix -se test1
+./myisamchk$suffix -ros --correct-checksum test1
+./myisamchk$suffix -se test1
+./myisamchk$suffix -rqos --correct-checksum test1
+./myisamchk$suffix -se test1
# check of myisampack / myisamchk
-myisampack$suffix --force -s test1
+./myisampack$suffix --force -s test1
# Ignore error for index file
-myisamchk$suffix -es test1 2>&1 >& /dev/null
-myisamchk$suffix -rqs test1
-myisamchk$suffix -es test1
-myisamchk$suffix -rs test1
-myisamchk$suffix -es test1
-myisamchk$suffix -rus test1
-myisamchk$suffix -es test1
+./myisamchk$suffix -es test1 2>&1 >& /dev/null
+./myisamchk$suffix -rqs test1
+./myisamchk$suffix -es test1
+./myisamchk$suffix -rs test1
+./myisamchk$suffix -es test1
+./myisamchk$suffix -rus test1
+./myisamchk$suffix -es test1
-mi_test1$suffix $silent --checksum -S
-myisamchk$suffix -se test1
-myisamchk$suffix -ros test1
-myisamchk$suffix -rqs test1
-myisamchk$suffix -se test1
+./mi_test1$suffix $silent --checksum -S
+./myisamchk$suffix -se test1
+./myisamchk$suffix -ros test1
+./myisamchk$suffix -rqs test1
+./myisamchk$suffix -se test1
-myisampack$suffix --force -s test1
-myisamchk$suffix -rqs test1
-myisamchk$suffix -es test1
-myisamchk$suffix -rus test1
-myisamchk$suffix -es test1
+./myisampack$suffix --force -s test1
+./myisamchk$suffix -rqs test1
+./myisamchk$suffix -es test1
+./myisamchk$suffix -rus test1
+./myisamchk$suffix -es test1
-mi_test1$suffix $silent --checksum --unique
-myisamchk$suffix -se test1
-mi_test1$suffix $silent --unique -S
-myisamchk$suffix -se test1
+./mi_test1$suffix $silent --checksum --unique
+./myisamchk$suffix -se test1
+./mi_test1$suffix $silent --unique -S
+./myisamchk$suffix -se test1
-mi_test1$suffix $silent --key_multiple -N -S
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent --key_multiple -a -p --key_length=480
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent --key_multiple -a -B --key_length=480
-myisamchk$suffix -sm test1
-mi_test1$suffix $silent --key_multiple -P -S
-myisamchk$suffix -sm test1
+./mi_test1$suffix $silent --key_multiple -N -S
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent --key_multiple -a -p --key_length=480
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent --key_multiple -a -B --key_length=480
+./myisamchk$suffix -sm test1
+./mi_test1$suffix $silent --key_multiple -P -S
+./myisamchk$suffix -sm test1
-mi_test2$suffix $silent -L -K -W -P
-myisamchk$suffix -sm test2
-mi_test2$suffix $silent -L -K -W -P -A
-myisamchk$suffix -sm test2
-mi_test2$suffix $silent -L -K -W -P -S -R1 -m500
+./mi_test2$suffix $silent -L -K -W -P
+./myisamchk$suffix -sm test2
+./mi_test2$suffix $silent -L -K -W -P -A
+./myisamchk$suffix -sm test2
+./mi_test2$suffix $silent -L -K -W -P -S -R1 -m500
echo "mi_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135"
-myisamchk$suffix -sm test2
-mi_test2$suffix $silent -L -K -R1 -m2000
-myisamchk$suffix -sm test2
-mi_test2$suffix $silent -L -K -P -S -R3 -m50 -b1000000
-myisamchk$suffix -sm test2
-mi_test2$suffix $silent -L -B
-myisamchk$suffix -sm test2
-mi_test2$suffix $silent -D -B -c
-myisamchk$suffix -sm test2
-mi_test2$suffix $silent -m10000 -e8192 -K
-myisamchk$suffix -sm test2
-mi_test2$suffix $silent -m10000 -e16384 -E16384 -K -L
-myisamchk$suffix -sm test2
+./myisamchk$suffix -sm test2
+./mi_test2$suffix $silent -L -K -R1 -m2000
+./myisamchk$suffix -sm test2
+./mi_test2$suffix $silent -L -K -P -S -R3 -m50 -b1000000
+./myisamchk$suffix -sm test2
+./mi_test2$suffix $silent -L -B
+./myisamchk$suffix -sm test2
+./mi_test2$suffix $silent -D -B -c
+./myisamchk$suffix -sm test2
+./mi_test2$suffix $silent -m10000 -e8192 -K
+./myisamchk$suffix -sm test2
+./mi_test2$suffix $silent -m10000 -e16384 -E16384 -K -L
+./myisamchk$suffix -sm test2
-mi_test2$suffix $silent -L -K -W -P -m50 -l
-myisamlog$suffix
-mi_test2$suffix $silent -L -K -W -P -m50 -l -b100
-myisamlog$suffix
-time mi_test2$suffix $silent
-time mi_test2$suffix $silent -K -B
-time mi_test2$suffix $silent -L -B
-time mi_test2$suffix $silent -L -K -B
-time mi_test2$suffix $silent -L -K -W -B
-time mi_test2$suffix $silent -L -K -W -S -B
-time mi_test2$suffix $silent -D -K -W -S -B
+./mi_test2$suffix $silent -L -K -W -P -m50 -l
+./myisamlog$suffix
+./mi_test2$suffix $silent -L -K -W -P -m50 -l -b100
+./myisamlog$suffix
+time ./mi_test2$suffix $silent
+time ./mi_test2$suffix $silent -K -B
+time ./mi_test2$suffix $silent -L -B
+time ./mi_test2$suffix $silent -L -K -B
+time ./mi_test2$suffix $silent -L -K -W -B
+time ./mi_test2$suffix $silent -L -K -W -S -B
+time ./mi_test2$suffix $silent -D -K -W -S -B
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index 0332644c5a6..d0117e12ede 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -337,7 +337,7 @@ static struct my_option my_long_options[] =
(gptr*) &ft_stopword_file, (gptr*) &ft_stopword_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"stats_method", OPT_STATS_METHOD,
- "Specifies how index statistics collection code should threat NULLs. "
+ "Specifies how index statistics collection code should treat NULLs. "
"Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
"\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
(gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0,
@@ -452,7 +452,7 @@ static void usage(void)
MySQL faster. You can check the calculated distribution\n\
by using '--description --verbose table_name'.\n\
--stats_method=name Specifies how index statistics collection code should\n\
- threat NULLs. Possible values of name are \"nulls_unequal\"\n\
+ treat NULLs. Possible values of name are \"nulls_unequal\"\n\
(default for 4.1/5.0), \"nulls_equal\" (emulate 4.0), and \n\
\"nulls_ignored\".\n\
-d, --description Prints some information about table.\n\
diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl
index dc22f88bd7f..31b0c4cd29e 100644
--- a/mysql-test/lib/mtr_misc.pl
+++ b/mysql-test/lib/mtr_misc.pl
@@ -19,9 +19,8 @@
# same name.
use strict;
+use File::Find;
-sub mtr_full_hostname ();
-sub mtr_short_hostname ();
sub mtr_native_path($);
sub mtr_init_args ($);
sub mtr_add_arg ($$@);
@@ -31,6 +30,7 @@ sub mtr_file_exists(@);
sub mtr_exe_exists(@);
sub mtr_exe_maybe_exists(@);
sub mtr_copy_dir($$);
+sub mtr_rmtree($);
sub mtr_same_opts($$);
sub mtr_cmp_opts($$);
@@ -40,30 +40,6 @@ sub mtr_cmp_opts($$);
#
##############################################################################
-# We want the fully qualified host name and hostname() may have returned
-# only the short name. So we use the resolver to find out.
-# Note that this might fail on some platforms
-
-sub mtr_full_hostname () {
-
- my $hostname= hostname();
- if ( $hostname !~ /\./ )
- {
- my $address= gethostbyname($hostname)
- or mtr_error("Couldn't resolve $hostname : $!");
- my $fullname= gethostbyaddr($address, AF_INET);
- $hostname= $fullname if $fullname;
- }
- return $hostname;
-}
-
-sub mtr_short_hostname () {
-
- my $hostname= hostname();
- $hostname =~ s/\..+$//;
- return $hostname;
-}
-
# Convert path to OS native format
sub mtr_native_path($)
{
@@ -226,6 +202,64 @@ sub mtr_copy_dir($$) {
}
+sub mtr_rmtree($) {
+ my ($dir)= @_;
+ my $need_file_find= 0;
+ mtr_verbose("mtr_rmtree: $dir");
+
+ {
+ # Try to use File::Path::rmtree. Recent versions
+ # handles removal of directories and files that don't
+ # have full permissions, while older versions
+ # may have a problem with that and we use our own version
+
+ local $SIG{__WARN__}= sub {
+ $need_file_find= 1;
+ mtr_warning($_[0]);
+ };
+ rmtree($dir);
+ }
+ if ( $need_file_find ) {
+ mtr_warning("rmtree($dir) failed, trying with File::Find...");
+
+ my $errors= 0;
+
+ # chmod
+ find( {
+ no_chdir => 1,
+ wanted => sub {
+ chmod(0777, $_)
+ or mtr_warning("couldn't chmod(0777, $_): $!") and $errors++;
+ }
+ },
+ $dir
+ );
+
+ # rm
+ finddepth( {
+ no_chdir => 1,
+ wanted => sub {
+ my $file= $_;
+ # Use special underscore (_) filehandle, caches stat info
+ if (!-l $file and -d _ ) {
+ rmdir($file) or
+ mtr_warning("couldn't rmdir($file): $!") and $errors++;
+ } else {
+ unlink($file)
+ or mtr_warning("couldn't unlink($file): $!") and $errors++;
+ }
+ }
+ },
+ $dir
+ );
+
+ mtr_error("Failed to remove '$dir'") if $errors;
+
+ mtr_report("OK, that worked!");
+ }
+}
+
+
sub mtr_same_opts ($$) {
my $l1= shift;
my $l2= shift;
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index f5ef028fa24..a60b2822a14 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -99,25 +99,26 @@ sub spawn_impl ($$$$$$$) {
if ( $::opt_script_debug )
{
- print STDERR "\n";
- print STDERR "#### ", "-" x 78, "\n";
- print STDERR "#### ", "STDIN $input\n" if $input;
- print STDERR "#### ", "STDOUT $output\n" if $output;
- print STDERR "#### ", "STDERR $error\n" if $error;
- print STDERR "#### ", "$mode : $path ", join(" ",@$arg_list_t), "\n";
- print STDERR "#### ", "spawn options:\n";
+ mtr_report("");
+ mtr_debug("-" x 73);
+ mtr_debug("STDIN $input") if $input;
+ mtr_debug("STDOUT $output") if $output;
+ mtr_debug("STDERR $error") if $error;
+ mtr_debug("$mode: $path ", join(" ",@$arg_list_t));
+ mtr_debug("spawn options:");
if ($spawn_opts)
{
foreach my $key (sort keys %{$spawn_opts})
{
- print STDERR "#### ", " - $key: $spawn_opts->{$key}\n";
+ mtr_debug(" - $key: $spawn_opts->{$key}");
}
}
else
{
- print STDERR "#### ", " none\n";
+ mtr_debug(" none");
}
- print STDERR "#### ", "-" x 78, "\n";
+ mtr_debug("-" x 73);
+ mtr_report("");
}
mtr_error("Can't spawn with empty \"path\"") unless defined $path;
diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl
index 1abfc6b6b57..ca66138d279 100644
--- a/mysql-test/lib/mtr_report.pl
+++ b/mysql-test/lib/mtr_report.pl
@@ -19,6 +19,7 @@
# same name.
use strict;
+use warnings;
sub mtr_report_test_name($);
sub mtr_report_test_passed($);
@@ -26,7 +27,6 @@ sub mtr_report_test_failed($);
sub mtr_report_test_skipped($);
sub mtr_report_test_not_skipped_though_disabled($);
-sub mtr_show_failed_diff ($);
sub mtr_report_stats ($);
sub mtr_print_line ();
sub mtr_print_thick_line ();
@@ -38,6 +38,9 @@ sub mtr_child_error (@);
sub mtr_debug (@);
sub mtr_verbose (@);
+my $tot_real_time= 0;
+
+
##############################################################################
#
@@ -45,58 +48,10 @@ sub mtr_verbose (@);
#
##############################################################################
-# We can't use diff -u or diff -a as these are not portable
-
-sub mtr_show_failed_diff ($) {
- my $result_file_name= shift;
-
- # The reject and log files have been dumped to
- # to filenames based on the result_file's name
- my $tname= basename($result_file_name);
- $tname=~ s/\..*$//;
-
- my $reject_file= "r/$tname.reject";
- my $result_file= "r/$tname.result";
- my $log_file= "r/$tname.log";
- my $eval_file= "r/$tname.eval";
-
- if ( $::opt_suite ne "main" )
- {
- $reject_file= "$::glob_mysql_test_dir/suite/$::opt_suite/$reject_file";
- $result_file= "$::glob_mysql_test_dir/suite/$::opt_suite/$result_file";
- $eval_file= "$::glob_mysql_test_dir/suite/$::opt_suite/$eval_file";
- $log_file= "$::glob_mysql_test_dir/suite/$::opt_suite/$log_file";
- }
-
- if ( -f $eval_file )
- {
- $result_file= $eval_file;
- }
-
- my $diffopts= $::opt_udiff ? "-u" : "-c";
-
- if ( -f $reject_file )
- {
- print "Below are the diffs between actual and expected results:\n";
- print "-------------------------------------------------------\n";
- # FIXME check result code?!
- mtr_run("diff",[$diffopts,$result_file,$reject_file], "", "", "", "");
- print "-------------------------------------------------------\n";
- print "Please follow the instructions outlined at\n";
- print "http://www.mysql.com/doc/en/Reporting_mysqltest_bugs.html\n";
- print "to find the reason to this problem and how to report this.\n\n";
- }
-
- if ( -f $log_file )
- {
- print "Result from queries before failure can be found in $log_file\n";
- # FIXME Maybe a tail -f -n 10 $log_file here
- }
-}
-
sub mtr_report_test_name ($) {
my $tinfo= shift;
+ _mtr_log("$tinfo->{name}");
printf "%-30s ", $tinfo->{'name'};
}
@@ -106,15 +61,15 @@ sub mtr_report_test_skipped ($) {
$tinfo->{'result'}= 'MTR_RES_SKIPPED';
if ( $tinfo->{'disable'} )
{
- print "[ disabled ] $tinfo->{'comment'}\n";
+ mtr_report("[ disabled ] $tinfo->{'comment'}");
}
elsif ( $tinfo->{'comment'} )
{
- print "[ skipped ] $tinfo->{'comment'}\n";
+ mtr_report("[ skipped ] $tinfo->{'comment'}");
}
else
{
- print "[ skipped ]\n";
+ mtr_report("[ skipped ]");
}
}
@@ -142,11 +97,11 @@ sub mtr_report_test_passed ($) {
if ( $::opt_timer and -f "$::opt_vardir/log/timer" )
{
$timer= mtr_fromfile("$::opt_vardir/log/timer");
- $::glob_tot_real_time += ($timer/1000);
+ $tot_real_time += ($timer/1000);
$timer= sprintf "%12s", $timer;
}
$tinfo->{'result'}= 'MTR_RES_PASSED';
- print "[ pass ] $timer\n";
+ mtr_report("[ pass ] $timer");
}
sub mtr_report_test_failed ($) {
@@ -155,27 +110,34 @@ sub mtr_report_test_failed ($) {
$tinfo->{'result'}= 'MTR_RES_FAILED';
if ( defined $tinfo->{'timeout'} )
{
- print "[ fail ] timeout\n";
+ mtr_report("[ fail ] timeout");
return;
}
else
{
- print "[ fail ]\n";
+ mtr_report("[ fail ]");
}
if ( $tinfo->{'comment'} )
{
- print "\nERROR: $tinfo->{'comment'}\n";
+ # The test failure has been detected by mysql-test-run.pl
+ # when starting the servers or due to other error, the reason for
+ # failing the test is saved in "comment"
+ mtr_report("\nERROR: $tinfo->{'comment'}");
}
elsif ( -f $::path_timefile )
{
- print "\nErrors are (from $::path_timefile) :\n";
+ # Test failure was detected by test tool and it's report
+ # about what failed has been saved to file. Display the report.
+ print "\n";
print mtr_fromfile($::path_timefile); # FIXME print_file() instead
- print "\n(the last lines may be the most important ones)\n";
+ print "\n";
}
else
{
- print "\nUnexpected termination, probably when starting mysqld\n";
+ # Neither this script or the test tool has recorded info
+ # about why the test has failed. Should be debugged.
+ mtr_report("\nUnexpected termination, probably when starting mysqld");;
}
}
@@ -243,8 +205,10 @@ sub mtr_report_stats ($) {
if ( $::opt_timer )
{
- print
- "Spent $::glob_tot_real_time seconds actually executing testcases\n"
+ use English;
+
+ mtr_report("Spent", sprintf("%.3f", $tot_real_time),"of",
+ time - $BASETIME, "seconds executing testcases");
}
# ----------------------------------------------------------------------
@@ -397,35 +361,66 @@ sub mtr_print_header () {
##############################################################################
#
-# Misc
+# Log and reporting functions
#
##############################################################################
+use IO::File;
+
+my $log_file_ref= undef;
+
+sub mtr_log_init ($) {
+ my ($filename)= @_;
+
+ mtr_error("Log is already open") if defined $log_file_ref;
+
+ $log_file_ref= IO::File->new($filename, "a") or
+ mtr_warning("Could not create logfile $filename: $!");
+}
+
+sub _mtr_log (@) {
+ print $log_file_ref join(" ", @_),"\n"
+ if defined $log_file_ref;
+}
+
sub mtr_report (@) {
+ # Print message to screen and log
+ _mtr_log(@_);
print join(" ", @_),"\n";
}
sub mtr_warning (@) {
+ # Print message to screen and log
+ _mtr_log("WARNING: ", @_);
print STDERR "mysql-test-run: WARNING: ",join(" ", @_),"\n";
}
sub mtr_error (@) {
+ # Print message to screen and log
+ _mtr_log("ERROR: ", @_);
print STDERR "mysql-test-run: *** ERROR: ",join(" ", @_),"\n";
mtr_exit(1);
}
sub mtr_child_error (@) {
+ # Print message to screen and log
+ _mtr_log("ERROR(child): ", @_);
print STDERR "mysql-test-run: *** ERROR(child): ",join(" ", @_),"\n";
exit(1);
}
sub mtr_debug (@) {
+ # Only print if --script-debug is used
if ( $::opt_script_debug )
{
+ _mtr_log("###: ", @_);
print STDERR "####: ",join(" ", @_),"\n";
}
}
+
sub mtr_verbose (@) {
+ # Always print to log, print to screen only when --verbose is used
+ _mtr_log("> ",@_);
if ( $::opt_verbose )
{
print STDERR "> ",join(" ", @_),"\n";
diff --git a/mysql-test/lib/mtr_timer.pl b/mysql-test/lib/mtr_timer.pl
index 86a9f58514f..326fbea74ec 100644
--- a/mysql-test/lib/mtr_timer.pl
+++ b/mysql-test/lib/mtr_timer.pl
@@ -18,7 +18,6 @@
# and is part of the translation of the Bourne shell script with the
# same name.
-use Socket;
use Errno;
use strict;
@@ -52,12 +51,10 @@ sub mtr_init_timers () {
sub mtr_timer_start($$$) {
my ($timers,$name,$duration)= @_;
- mtr_verbose("mtr_timer_start: $name, $duration");
-
if ( exists $timers->{'timers'}->{$name} )
{
# We have an old running timer, kill it
- mtr_verbose("There is an old timer running");
+ mtr_warning("There is an old timer running");
mtr_timer_stop($timers,$name);
}
@@ -75,22 +72,22 @@ sub mtr_timer_start($$$) {
}
else
{
- mtr_error("can't fork");
+ mtr_error("can't fork timer, error: $!");
}
}
if ( $tpid )
{
# Parent, record the information
- mtr_verbose("timer parent, record info($name, $tpid, $duration)");
+ mtr_verbose("Starting timer for '$name',",
+ "duration: $duration, pid: $tpid");
$timers->{'timers'}->{$name}->{'pid'}= $tpid;
$timers->{'timers'}->{$name}->{'duration'}= $duration;
$timers->{'pids'}->{$tpid}= $name;
}
else
{
- # Child, redirect output and exec
- # FIXME do we need to redirect streams?
+ # Child, install signal handlers and sleep for "duration"
# Don't do the ^C cleanup in the timeout child processes!
# There is actually a race here, if we get ^C after fork(), but before
@@ -98,13 +95,13 @@ sub mtr_timer_start($$$) {
$SIG{INT}= 'DEFAULT';
$SIG{TERM}= sub {
- mtr_verbose("timer woke up, exiting!");
+ mtr_verbose("timer $$ woke up, exiting!");
exit(0);
};
$0= "mtr_timer(timers,$name,$duration)";
sleep($duration);
- mtr_verbose("timer expired after $duration seconds");
+ mtr_verbose("timer $$ expired after $duration seconds");
exit(0);
}
}
@@ -114,12 +111,10 @@ sub mtr_timer_start($$$) {
sub mtr_timer_stop ($$) {
my ($timers,$name)= @_;
- mtr_verbose("mtr_timer_stop: $name");
-
if ( exists $timers->{'timers'}->{$name} )
{
my $tpid= $timers->{'timers'}->{$name}->{'pid'};
- mtr_verbose("Stopping timer with pid $tpid");
+ mtr_verbose("Stopping timer for '$name' with pid $tpid");
# FIXME as Cygwin reuses pids fast, maybe check that is
# the expected process somehow?!
@@ -134,11 +129,8 @@ sub mtr_timer_stop ($$) {
return 1;
}
- else
- {
- mtr_error("Asked to stop timer \"$name\" not started");
- return 0;
- }
+
+ mtr_error("Asked to stop timer '$name' not started");
}
@@ -158,7 +150,8 @@ sub mtr_timer_timeout ($$) {
return "" unless exists $timers->{'pids'}->{$pid};
- # We got a timeout, return the name ot the timer
+ # Got a timeout(the process with $pid is recorded as being a timer)
+ # return the name of the timer
return $timers->{'pids'}->{$pid};
}
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 43b1ef7ac86..06447b9e69d 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -61,7 +61,6 @@ use File::Copy;
use File::Temp qw / tempdir /;
use Cwd;
use Getopt::Long;
-use Sys::Hostname;
use IO::Socket;
use IO::Socket::INET;
use strict;
@@ -83,7 +82,6 @@ require "lib/mtr_io.pl";
require "lib/mtr_gcov.pl";
require "lib/mtr_gprof.pl";
require "lib/mtr_report.pl";
-require "lib/mtr_diff.pl";
require "lib/mtr_match.pl";
require "lib/mtr_misc.pl";
require "lib/mtr_stress.pl";
@@ -101,7 +99,6 @@ $Devel::Trace::TRACE= 1;
our $mysql_version_id;
our $glob_mysql_test_dir= undef;
our $glob_mysql_bench_dir= undef;
-our $glob_hostname= undef;
our $glob_scriptname= undef;
our $glob_timers= undef;
our $glob_use_running_ndbcluster= 0;
@@ -234,7 +231,6 @@ my $opt_report_features;
our $opt_check_testcases;
our $opt_mark_progress;
-our $opt_skip;
our $opt_skip_rpl;
our $max_slave_num= 0;
our $max_master_num= 1;
@@ -277,13 +273,8 @@ our $opt_stress_test_duration= 0;
our $opt_stress_init_file= "";
our $opt_stress_test_file= "";
-our $opt_wait_for_master;
-our $opt_wait_for_slave;
-
our $opt_warnings;
-our $opt_udiff;
-
our $opt_skip_ndbcluster= 0;
our $opt_skip_ndbcluster_slave= 0;
our $opt_with_ndbcluster= 0;
@@ -307,7 +298,6 @@ our @data_dir_lst;
our $used_binlog_format;
our $used_default_engine;
our $debug_compiled_binaries;
-our $glob_tot_real_time= 0;
our %mysqld_variables;
@@ -620,7 +610,6 @@ sub command_line_setup () {
'start-dirty' => \$opt_start_dirty,
'start-and-exit' => \$opt_start_and_exit,
'timer!' => \$opt_timer,
- 'unified-diff|udiff' => \$opt_udiff,
'user=s' => \$opt_user,
'testcase-timeout=i' => \$opt_testcase_timeout,
'suite-timeout=i' => \$opt_suite_timeout,
@@ -656,8 +645,6 @@ sub command_line_setup () {
$source_dist= 1;
}
- $glob_hostname= mtr_short_hostname();
-
# Find the absolute path to the test directory
$glob_mysql_test_dir= cwd();
if ( $glob_cygwin_perl )
@@ -708,6 +695,7 @@ sub command_line_setup () {
if (!$opt_extern)
{
$exe_mysqld= mtr_exe_exists (vs_config_dirs('sql', 'mysqld'),
+ vs_config_dirs('sql', 'mysqld-debug'),
"$glob_basedir/sql/mysqld",
"$path_client_bindir/mysqld-max-nt",
"$path_client_bindir/mysqld-max",
@@ -2184,7 +2172,7 @@ sub remove_stale_vardir () {
{
# Remove the directory which the link points at
mtr_verbose("Removing " . readlink($opt_vardir));
- rmtree(readlink($opt_vardir));
+ mtr_rmtree(readlink($opt_vardir));
# Remove the "var" symlink
mtr_verbose("unlink($opt_vardir)");
@@ -2212,7 +2200,7 @@ sub remove_stale_vardir () {
foreach my $bin ( glob("$opt_vardir/*") )
{
mtr_verbose("Removing bin $bin");
- rmtree($bin);
+ mtr_rmtree($bin);
}
}
}
@@ -2220,7 +2208,7 @@ sub remove_stale_vardir () {
{
# Remove the entire "var" dir
mtr_verbose("Removing $opt_vardir/");
- rmtree("$opt_vardir/");
+ mtr_rmtree("$opt_vardir/");
}
if ( $opt_mem )
@@ -2229,7 +2217,7 @@ sub remove_stale_vardir () {
# remove the $opt_mem dir to assure the symlink
# won't point at an old directory
mtr_verbose("Removing $opt_mem");
- rmtree($opt_mem);
+ mtr_rmtree($opt_mem);
}
}
@@ -2242,11 +2230,11 @@ sub remove_stale_vardir () {
# Remove the var/ dir in mysql-test dir if any
# this could be an old symlink that shouldn't be there
mtr_verbose("Removing $default_vardir");
- rmtree($default_vardir);
+ mtr_rmtree($default_vardir);
# Remove the "var" dir
mtr_verbose("Removing $opt_vardir/");
- rmtree("$opt_vardir/");
+ mtr_rmtree("$opt_vardir/");
}
}
@@ -2436,6 +2424,7 @@ sub vs_config_dirs ($$) {
}
return ("$glob_basedir/$path_part/release/$exe",
+ "$glob_basedir/$path_part/relwithdebinfo/$exe",
"$glob_basedir/$path_part/debug/$exe");
}
@@ -2903,13 +2892,16 @@ sub initialize_servers () {
}
}
check_running_as_root();
+
+ mtr_log_init("$opt_vardir/log/mysql-test-run.log");
+
}
sub mysql_install_db () {
install_db('master', $master->[0]->{'path_myddir'});
- if ($max_master_num)
+ if ($max_master_num > 1)
{
copy_install_db('master', $master->[1]->{'path_myddir'});
}
@@ -3067,11 +3059,15 @@ sub install_db ($$) {
mtr_appendfile_to_file("$path_sql_dir/fill_help_tables.sql",
$bootstrap_sql_file);
+ mtr_tofile($bootstrap_sql_file,
+ "DELETE FROM mysql.user where user= '';");
+
# Log bootstrap command
my $path_bootstrap_log= "$opt_vardir/log/bootstrap.log";
mtr_tofile($path_bootstrap_log,
"$exe_mysqld_bootstrap " . join(" ", @$args) . "\n");
+
if ( mtr_run($exe_mysqld_bootstrap, $args, $bootstrap_sql_file,
$path_bootstrap_log, $path_bootstrap_log,
"", { append_log_file => 1 }) != 0 )
@@ -3196,7 +3192,7 @@ sub restore_slave_databases ($) {
{
my $data_dir= $slave->[$idx]->{'path_myddir'};
my $name= basename($data_dir);
- rmtree($data_dir);
+ mtr_rmtree($data_dir);
mtr_copy_dir("$path_snapshot/$name", $data_dir);
}
}
@@ -3365,56 +3361,6 @@ sub find_testcase_skipped_reason($)
}
-sub analyze_testcase_failure_sync_with_master($)
-{
- my ($tinfo)= @_;
-
- my $args;
- mtr_init_args(\$args);
-
- mtr_add_arg($args, "--no-defaults");
- mtr_add_arg($args, "--silent");
- mtr_add_arg($args, "--skip-safemalloc");
- mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir);
- mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
-
- mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_sock'});
- mtr_add_arg($args, "--port=%d", $master->[0]->{'port'});
- mtr_add_arg($args, "--database=test");
- mtr_add_arg($args, "--user=%s", $opt_user);
- mtr_add_arg($args, "--password=");
-
- # Run the test file and append output to log file
- mtr_run_test($exe_mysqltest,$args,
- "include/analyze_failure_sync_with_master.test",
- "$path_timefile", "$path_timefile","",
- { append_log_file => 1 });
-
-}
-
-sub analyze_testcase_failure($)
-{
- my ($tinfo)= @_;
-
- # Open mysqltest.log
- my $F= IO::File->new($path_timefile)
- or return;
-
- while ( my $line= <$F> )
- {
- # Look for "mysqltest: At line nnn: <error>
- if ( $line =~ /mysqltest: At line [0-9]*: (.*)/ )
- {
- my $error= $1;
- # Look for "could not sync with master"
- if ( $error =~ /could not sync with master/ )
- {
- analyze_testcase_failure_sync_with_master($tinfo);
- }
- }
- }
-}
-
##############################################################################
#
# Run a single test case
@@ -3507,10 +3453,6 @@ sub run_testcase ($) {
}
elsif ( $res == 1 )
{
- if ( $opt_force )
- {
- analyze_testcase_failure($tinfo);
- }
# Test case failure reported by mysqltest
report_failure_and_restart($tinfo);
}
@@ -3543,7 +3485,7 @@ sub run_testcase ($) {
sub save_installed_db () {
mtr_report("Saving snapshot of installed databases");
- rmtree($path_snapshot);
+ mtr_rmtree($path_snapshot);
foreach my $data_dir (@data_dir_lst)
{
@@ -3590,7 +3532,7 @@ sub restore_installed_db ($) {
{
my $name= basename($data_dir);
save_files_before_restore($test_name, $data_dir);
- rmtree("$data_dir");
+ mtr_rmtree("$data_dir");
mtr_copy_dir("$path_snapshot/$name", "$data_dir");
}
@@ -3600,7 +3542,7 @@ sub restore_installed_db ($) {
{
foreach my $ndbd (@{$cluster->{'ndbds'}})
{
- rmtree("$ndbd->{'path_fs'}" );
+ mtr_rmtree("$ndbd->{'path_fs'}" );
}
}
}
@@ -3615,7 +3557,6 @@ sub report_failure_and_restart ($) {
my $tinfo= shift;
mtr_report_test_failed($tinfo);
- mtr_show_failed_diff($tinfo->{'result_file'});
print "\n";
if ( $opt_force )
{
@@ -3624,13 +3565,13 @@ sub report_failure_and_restart ($) {
# Restore the snapshot of the installed test db
restore_installed_db($tinfo->{'name'});
- print "Resuming Tests\n\n";
+ mtr_report("Resuming Tests\n");
return;
}
my $test_mode= join(" ", @::glob_test_mode) || "default";
- print "Aborting: $tinfo->{'name'} failed in $test_mode mode. ";
- print "To continue, re-run with '--force'.\n";
+ mtr_report("Aborting: $tinfo->{'name'} failed in $test_mode mode. ");
+ mtr_report("To continue, re-run with '--force'.");
if ( ! $glob_debugger and
! $opt_extern and
! $glob_use_embedded_server )
@@ -4055,6 +3996,9 @@ sub mysqld_start ($$$) {
$wait_for_pid_file= 0;
}
+ # Remove the pidfile
+ unlink($mysqld->{'path_pid'});
+
if ( defined $exe )
{
$pid= mtr_spawn($exe, $args, "",
@@ -4088,11 +4032,11 @@ sub mysqld_start ($$$) {
sub stop_all_servers () {
- print "Stopping All Servers\n";
+ mtr_report("Stopping All Servers");
if ( ! $opt_skip_im )
{
- print "Shutting-down Instance Manager\n";
+ mtr_report("Shutting-down Instance Manager");
unless (mtr_im_stop($instance_manager, "stop_all_servers"))
{
mtr_error("Failed to stop Instance Manager.")
@@ -4678,6 +4622,7 @@ sub run_mysqltest ($) {
mtr_add_arg($args, "--skip-safemalloc");
mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir);
mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir);
+ mtr_add_arg($args, "--logdir=%s/log", $opt_vardir);
# Log line number and time for each line in .test file
mtr_add_arg($args, "--mark-progress")
@@ -4800,6 +4745,9 @@ sub run_mysqltest ($) {
mtr_add_arg($args, "--test-file=%s", $tinfo->{'path'});
+ # Number of lines of resut to include in failure report
+ mtr_add_arg($args, "--tail-lines=20");
+
if ( defined $tinfo->{'result_file'} ) {
mtr_add_arg($args, "--result-file=%s", $tinfo->{'result_file'});
}
@@ -5211,7 +5159,6 @@ Misc options
fast Don't try to clean up from earlier runs
reorder Reorder tests to get fewer server restarts
help Get this help text
- unified-diff | udiff When presenting differences, use unified diff
testcase-timeout=MINUTES Max test case run time (default $default_testcase_timeout)
suite-timeout=MINUTES Max test suite run time (default $default_suite_timeout)
diff --git a/mysql-test/r/comments.result b/mysql-test/r/comments.result
index a9106ce0538..1040c3fc8e9 100644
--- a/mysql-test/r/comments.result
+++ b/mysql-test/r/comments.result
@@ -26,3 +26,18 @@ select 1 # The rest of the row will be ignored
1
1
/* line with only comment */;
+drop table if exists table_28779;
+create table table_28779 (a int);
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';";
+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 '/*' AND b = 'bar'' at line 1
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';*";
+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 '/*' AND b = 'bar';*' at line 1
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;";
+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
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;*";
+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
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';";
+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 '/*!98765' AND b = 'bar'' at line 1
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';*";
+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 '/*!98765' AND b = 'bar';*' at line 1
+drop table table_28779;
diff --git a/mysql-test/r/ctype_ascii.result b/mysql-test/r/ctype_ascii.result
new file mode 100644
index 00000000000..06362486073
--- /dev/null
+++ b/mysql-test/r/ctype_ascii.result
@@ -0,0 +1,177 @@
+set names ascii;
+select 'e'='`';
+'e'='`'
+0
+select 'y'='~';
+'y'='~'
+0
+create table t1 (a char(1) character set ascii);
+insert into t1 (a) values (' '), ('a'), ('b'), ('c'), ('d'), ('e'), ('f'), ('g'), ('h'), ('i'), ('j'), ('k'), ('l'), ('m'), ('n'), ('o'), ('p'), ('q'), ('r'), ('s'), ('t'), ('u'), ('v'), ('w'), ('x'), ('y'), ('z'), ('A'), ('B'), ('C'), ('D'), ('E'), ('F'), ('G'), ('H'), ('I'), ('J'), ('K'), ('L'), ('M'), ('N'), ('O'), ('P'), ('Q'), ('R'), ('S'), ('T'), ('U'), ('V'), ('W'), ('X'), ('Y'), ('Z'), ('!'), ('@'), ('#'), ('$'), ('%'), ('^'), ('&'), ('*'), ('('), (')'), ('_'), ('+'), ('`'), ('~'), ('1'), ('2'), ('3'), ('4'), ('5'), ('6'), ('7'), ('8'), ('9'), ('0'), ('['), (']'), ('\\'), ('|'), ('}'), ('{'), ('"'), (':'), (''''), (';'), ('/'), ('.'), (','), ('?'), ('>'), ('<'), ('\n'), ('\t'), ('\a'), ('\f'), ('\v');
+select t1a.a, t1b.a from t1 as t1a, t1 as t1b where t1a.a=t1b.a order by binary t1a.a, binary t1b.a;
+a a
+
+
+
+
+
+! !
+" "
+# #
+$ $
+% %
+& &
+' '
+( (
+) )
+* *
++ +
+, ,
+. .
+/ /
+0 0
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+: :
+; ;
+< <
+> >
+? ?
+@ @
+A A
+A a
+A a
+B B
+B b
+C C
+C c
+D D
+D d
+E E
+E e
+F F
+F f
+F f
+G G
+G g
+H H
+H h
+I I
+I i
+J J
+J j
+K K
+K k
+L L
+L l
+M M
+M m
+N N
+N n
+O O
+O o
+P P
+P p
+Q Q
+Q q
+R R
+R r
+S S
+S s
+T T
+T t
+U U
+U u
+V V
+V v
+V v
+W W
+W w
+X X
+X x
+Y Y
+Y y
+Z Z
+Z z
+[ [
+\ \
+] ]
+^ ^
+_ _
+` `
+a A
+a A
+a a
+a a
+a a
+a a
+b B
+b b
+c C
+c c
+d D
+d d
+e E
+e e
+f F
+f F
+f f
+f f
+f f
+f f
+g G
+g g
+h H
+h h
+i I
+i i
+j J
+j j
+k K
+k k
+l L
+l l
+m M
+m m
+n N
+n n
+o O
+o o
+p P
+p p
+q Q
+q q
+r R
+r r
+s S
+s s
+t T
+t t
+u U
+u u
+v V
+v V
+v v
+v v
+v v
+v v
+w W
+w w
+x X
+x x
+y Y
+y y
+z Z
+z z
+{ {
+| |
+} }
+~ ~
+drop table t1;
+End of 5.0 tests.
diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result
index 74fa20af685..2e7d0ddcea7 100644
--- a/mysql-test/r/federated.result
+++ b/mysql-test/r/federated.result
@@ -1920,6 +1920,20 @@ a b
2 Curly
drop table federated.t1;
drop table federated.t1;
+
+Bug#18287 create federated table always times out, error 1159 ' '
+
+Test that self-references work
+
+create table federated.t1 (a int primary key);
+create table federated.t2 (a int primary key)
+ENGINE=FEDERATED
+connection='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
+insert into federated.t1 (a) values (1);
+select * from federated.t2;
+a
+1
+drop table federated.t1, federated.t2;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
DROP TABLE IF EXISTS federated.t1;
diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result
index 85cf47b5806..dc3750e16ea 100644
--- a/mysql-test/r/handler.result
+++ b/mysql-test/r/handler.result
@@ -482,3 +482,23 @@ ERROR 42S02: Table 'test.t1' doesn't exist
drop table if exists t1;
Warnings:
Note 1051 Unknown table 't1'
+drop table if exists t1;
+create table t1 (a int) ENGINE=MEMORY;
+--> client 2
+handler t1 open;
+ERROR HY000: Table storage engine for 't1' doesn't have this option
+--> client 1
+drop table t1;
+drop table if exists t1;
+create table t1 (a int);
+handler t1 open as t1_alias;
+handler t1_alias read a next;
+ERROR HY000: Key 'a' doesn't exist in table 't1_alias'
+handler t1_alias READ a next where inexistent > 0;
+ERROR 42S22: Unknown column 'inexistent' in 'field list'
+handler t1_alias read a next;
+ERROR HY000: Key 'a' doesn't exist in table 't1_alias'
+handler t1_alias READ a next where inexistent > 0;
+ERROR 42S22: Unknown column 'inexistent' in 'field list'
+handler t1_alias close;
+drop table t1;
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 9d0e41b341a..612e744a0f4 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -180,7 +180,6 @@ t1 a select
show columns from mysqltest.t1;
Field Type Null Key Default Extra
a int(11) YES NULL
-b varchar(30) YES MUL NULL
select table_name, column_name, privileges from information_schema.columns
where table_schema = 'mysqltest' and table_name = 'v1';
table_name column_name privileges
@@ -1330,4 +1329,29 @@ alter database;
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
alter database test;
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
+create database mysqltest;
+create table mysqltest.t1(a int, b int, c int);
+create trigger mysqltest.t1_ai after insert on mysqltest.t1
+for each row set @a = new.a + new.b + new.c;
+grant select(b) on mysqltest.t1 to mysqltest_1@localhost;
+select trigger_name from information_schema.triggers
+where event_object_table='t1';
+trigger_name
+t1_ai
+show triggers from mysqltest;
+Trigger Event Table Statement Timing Created sql_mode Definer
+t1_ai INSERT t1 set @a = new.a + new.b + new.c AFTER NULL root@localhost
+show columns from t1;
+Field Type Null Key Default Extra
+b int(11) YES NULL
+select column_name from information_schema.columns where table_name='t1';
+column_name
+b
+show triggers;
+Trigger Event Table Statement Timing Created sql_mode Definer
+select trigger_name from information_schema.triggers
+where event_object_table='t1';
+trigger_name
+drop user mysqltest_1@localhost;
+drop database mysqltest;
End of 5.0 tests.
diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result
index 2d330dda333..dd1f0295277 100644
--- a/mysql-test/r/information_schema_db.result
+++ b/mysql-test/r/information_schema_db.result
@@ -140,13 +140,11 @@ create view v2 as select f1 from testdb_1.v1;
create view v4 as select f1,f2 from testdb_1.v3;
show fields from testdb_1.v5;
Field Type Null Key Default Extra
-f1 char(4) YES NULL
show create view testdb_1.v5;
View Create View
v5 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_1`@`localhost` SQL SECURITY DEFINER VIEW `testdb_1`.`v5` AS select `testdb_1`.`t1`.`f1` AS `f1` from `testdb_1`.`t1`
show fields from testdb_1.v6;
Field Type Null Key Default Extra
-f1 char(4) YES NULL
show create view testdb_1.v6;
View Create View
v6 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `testdb_1`.`v6` AS select `testdb_1`.`t1`.`f1` AS `f1` from `testdb_1`.`t1`
diff --git a/mysql-test/r/innodb-deadlock.result b/mysql-test/r/innodb-deadlock.result
index 2ca82101fb4..b6a3373e8c6 100644
--- a/mysql-test/r/innodb-deadlock.result
+++ b/mysql-test/r/innodb-deadlock.result
@@ -94,3 +94,14 @@ id x
300 300
commit;
drop table t1, t2;
+End of 4.1 tests
+set storage_engine=innodb;
+drop table if exists a;
+drop table if exists A;
+create table A (c int);
+insert into A (c) values (0);
+create table a as select * from A;
+drop table A;
+drop table if exists a;
+set storage_engine=default;
+End of 5.0 tests.
diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result
index 63e25b7aa1e..c93d26bbd04 100644
--- a/mysql-test/r/innodb_mysql.result
+++ b/mysql-test/r/innodb_mysql.result
@@ -1047,4 +1047,22 @@ t1 CREATE TABLE `t1` (
KEY `a` (`a`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8
drop table t1;
+CREATE TABLE t1 (
+a INT,
+b INT,
+KEY (b)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1,10), (2,10), (2,20), (3,30);
+START TRANSACTION;
+SELECT * FROM t1 WHERE b=20 FOR UPDATE;
+a b
+2 20
+START TRANSACTION;
+SELECT * FROM t1 WHERE b=10 ORDER BY A FOR UPDATE;
+a b
+1 10
+2 10
+ROLLBACK;
+ROLLBACK;
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index 843f2c7285a..74b5c42e59b 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -176,4 +176,6 @@ ERROR at line 1: DELIMITER cannot contain a backslash character
ERROR at line 1: DELIMITER cannot contain a backslash character
1
1
+1
+1
End of 5.0 tests
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 55f78d22272..d03e21b1bb0 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -280,8 +280,20 @@ let $B = changed value of B;
var2: content of variable 1
var3: content of variable 1 content of variable 1
length of var3 is longer than 0
+var1
+hi 1 hi there
+var2
+2
+var2 again
+2
+var3 two columns with same name
+1 2 3
+var4 from query that returns NULL
+var5 from query that returns no row
+failing query in let
+mysqltest: At line 1: Error running query 'failing query': 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 'failing query' at line 1
mysqltest: At line 1: Missing required argument 'filename' to command 'source'
-mysqltest: At line 1: Could not open file ./non_existingFile
+mysqltest: At line 1: Could not open file './non_existingFile'
mysqltest: In included file "MYSQLTEST_VARDIR/tmp/recursive.sql": At line 1: Source directives are nesting too deep
mysqltest: In included file "MYSQLTEST_VARDIR/tmp/error.sql": At line 1: query 'garbage ' failed: 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 'garbage' at line 1
@@ -340,6 +352,8 @@ here is the sourced script
In loop
here is the sourced script
here is the sourced script
+"hello"
+"hello"
mysqltest: At line 1: Missing argument to sleep
mysqltest: At line 1: Missing argument to real_sleep
mysqltest: At line 1: Invalid argument to sleep "abc"
@@ -461,7 +475,6 @@ root@localhost
--------------------------------------------------------------------------------
this will be executed
this will be executed
-mysqltest: Result length mismatch
mysqltest: The test didn't produce any output
Failing multi statement query
mysqltest: At line 3: query 'create table t1 (a int primary key);
@@ -473,6 +486,8 @@ mysqltest: At line 3: query 'create table t1 (a int primary key);
insert into t1 values (1);
select 'select-me';
insertz 'error query'' failed: 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 'insertz 'error query'' at line 1
+
+More results from queries before failure can be found in MYSQLTEST_VARDIR/log/bug11731.log
drop table t1;
Multi statement using expected error
create table t1 (a int primary key);
@@ -520,17 +535,19 @@ drop table t1;
mysqltest: At line 1: Missing required argument 'filename' to command 'remove_file'
mysqltest: At line 1: Missing required argument 'filename' to command 'write_file'
mysqltest: At line 1: End of file encountered before 'EOF' delimiter was found
+Content for test_file1
+mysqltest: At line 1: File already exist: 'MYSQLTEST_VARDIR/tmp/test_file1.tmp'
Some data
for cat_file command
of mysqltest
-mysqltest: At line 1: Failed to open file non_existing_file
+mysqltest: At line 1: Failed to open file 'non_existing_file'
mysqltest: At line 1: Missing required argument 'filename' to command 'file_exists'
mysqltest: At line 1: Missing required argument 'from_file' to command 'copy_file'
mysqltest: At line 1: Missing required argument 'to_file' to command 'copy_file'
mysqltest: At line 1: Missing required argument 'mode' to command 'chmod'
mysqltest: At line 1: You must write a 4 digit octal number for mode
mysqltest: At line 1: You must write a 4 digit octal number for mode
-mysqltest: At line 1: Missing required argument 'file' to command 'chmod'
+mysqltest: At line 1: Missing required argument 'filename' to command 'chmod'
mysqltest: At line 1: You must write a 4 digit octal number for mode
mysqltest: At line 1: You must write a 4 digit octal number for mode
hello
diff --git a/mysql-test/r/parser_precedence.result b/mysql-test/r/parser_precedence.result
new file mode 100644
index 00000000000..cf301ec677b
--- /dev/null
+++ b/mysql-test/r/parser_precedence.result
@@ -0,0 +1,747 @@
+drop table if exists t1_30237_bool;
+create table t1_30237_bool(A boolean, B boolean, C boolean);
+insert into t1_30237_bool values
+(FALSE, FALSE, FALSE),
+(FALSE, FALSE, NULL),
+(FALSE, FALSE, TRUE),
+(FALSE, NULL, FALSE),
+(FALSE, NULL, NULL),
+(FALSE, NULL, TRUE),
+(FALSE, TRUE, FALSE),
+(FALSE, TRUE, NULL),
+(FALSE, TRUE, TRUE),
+(NULL, FALSE, FALSE),
+(NULL, FALSE, NULL),
+(NULL, FALSE, TRUE),
+(NULL, NULL, FALSE),
+(NULL, NULL, NULL),
+(NULL, NULL, TRUE),
+(NULL, TRUE, FALSE),
+(NULL, TRUE, NULL),
+(NULL, TRUE, TRUE),
+(TRUE, FALSE, FALSE),
+(TRUE, FALSE, NULL),
+(TRUE, FALSE, TRUE),
+(TRUE, NULL, FALSE),
+(TRUE, NULL, NULL),
+(TRUE, NULL, TRUE),
+(TRUE, TRUE, FALSE),
+(TRUE, TRUE, NULL),
+(TRUE, TRUE, TRUE) ;
+Testing OR, XOR, AND
+select A, B, A OR B, A XOR B, A AND B
+from t1_30237_bool where C is null order by A, B;
+A B A OR B A XOR B A AND B
+NULL NULL NULL NULL NULL
+NULL 0 NULL NULL 0
+NULL 1 1 NULL NULL
+0 NULL NULL NULL 0
+0 0 0 0 0
+0 1 1 1 0
+1 NULL 1 NULL NULL
+1 0 1 1 0
+1 1 1 0 1
+Testing that OR is associative
+select A, B, C, (A OR B) OR C, A OR (B OR C), A OR B OR C
+from t1_30237_bool order by A, B, C;
+A B C (A OR B) OR C A OR (B OR C) A OR B OR C
+NULL NULL NULL NULL NULL NULL
+NULL NULL 0 NULL NULL NULL
+NULL NULL 1 1 1 1
+NULL 0 NULL NULL NULL NULL
+NULL 0 0 NULL NULL NULL
+NULL 0 1 1 1 1
+NULL 1 NULL 1 1 1
+NULL 1 0 1 1 1
+NULL 1 1 1 1 1
+0 NULL NULL NULL NULL NULL
+0 NULL 0 NULL NULL NULL
+0 NULL 1 1 1 1
+0 0 NULL NULL NULL NULL
+0 0 0 0 0 0
+0 0 1 1 1 1
+0 1 NULL 1 1 1
+0 1 0 1 1 1
+0 1 1 1 1 1
+1 NULL NULL 1 1 1
+1 NULL 0 1 1 1
+1 NULL 1 1 1 1
+1 0 NULL 1 1 1
+1 0 0 1 1 1
+1 0 1 1 1 1
+1 1 NULL 1 1 1
+1 1 0 1 1 1
+1 1 1 1 1 1
+select count(*) from t1_30237_bool
+where ((A OR B) OR C) != (A OR (B OR C));
+count(*)
+0
+Testing that XOR is associative
+select A, B, C, (A XOR B) XOR C, A XOR (B XOR C), A XOR B XOR C
+from t1_30237_bool order by A, B, C;
+A B C (A XOR B) XOR C A XOR (B XOR C) A XOR B XOR C
+NULL NULL NULL NULL NULL NULL
+NULL NULL 0 NULL NULL NULL
+NULL NULL 1 NULL NULL NULL
+NULL 0 NULL NULL NULL NULL
+NULL 0 0 NULL NULL NULL
+NULL 0 1 NULL NULL NULL
+NULL 1 NULL NULL NULL NULL
+NULL 1 0 NULL NULL NULL
+NULL 1 1 NULL NULL NULL
+0 NULL NULL NULL NULL NULL
+0 NULL 0 NULL NULL NULL
+0 NULL 1 NULL NULL NULL
+0 0 NULL NULL NULL NULL
+0 0 0 0 0 0
+0 0 1 1 1 1
+0 1 NULL NULL NULL NULL
+0 1 0 1 1 1
+0 1 1 0 0 0
+1 NULL NULL NULL NULL NULL
+1 NULL 0 NULL NULL NULL
+1 NULL 1 NULL NULL NULL
+1 0 NULL NULL NULL NULL
+1 0 0 1 1 1
+1 0 1 0 0 0
+1 1 NULL NULL NULL NULL
+1 1 0 0 0 0
+1 1 1 1 1 1
+select count(*) from t1_30237_bool
+where ((A XOR B) XOR C) != (A XOR (B XOR C));
+count(*)
+0
+Testing that AND is associative
+select A, B, C, (A AND B) AND C, A AND (B AND C), A AND B AND C
+from t1_30237_bool order by A, B, C;
+A B C (A AND B) AND C A AND (B AND C) A AND B AND C
+NULL NULL NULL NULL NULL NULL
+NULL NULL 0 0 0 0
+NULL NULL 1 NULL NULL NULL
+NULL 0 NULL 0 0 0
+NULL 0 0 0 0 0
+NULL 0 1 0 0 0
+NULL 1 NULL NULL NULL NULL
+NULL 1 0 0 0 0
+NULL 1 1 NULL NULL NULL
+0 NULL NULL 0 0 0
+0 NULL 0 0 0 0
+0 NULL 1 0 0 0
+0 0 NULL 0 0 0
+0 0 0 0 0 0
+0 0 1 0 0 0
+0 1 NULL 0 0 0
+0 1 0 0 0 0
+0 1 1 0 0 0
+1 NULL NULL NULL NULL NULL
+1 NULL 0 0 0 0
+1 NULL 1 NULL NULL NULL
+1 0 NULL 0 0 0
+1 0 0 0 0 0
+1 0 1 0 0 0
+1 1 NULL NULL NULL NULL
+1 1 0 0 0 0
+1 1 1 1 1 1
+select count(*) from t1_30237_bool
+where ((A AND B) AND C) != (A AND (B AND C));
+count(*)
+0
+Testing that AND has precedence over OR
+select A, B, C, (A OR B) AND C, A OR (B AND C), A OR B AND C
+from t1_30237_bool order by A, B, C;
+A B C (A OR B) AND C A OR (B AND C) A OR B AND C
+NULL NULL NULL NULL NULL NULL
+NULL NULL 0 0 NULL NULL
+NULL NULL 1 NULL NULL NULL
+NULL 0 NULL NULL NULL NULL
+NULL 0 0 0 NULL NULL
+NULL 0 1 NULL NULL NULL
+NULL 1 NULL NULL NULL NULL
+NULL 1 0 0 NULL NULL
+NULL 1 1 1 1 1
+0 NULL NULL NULL NULL NULL
+0 NULL 0 0 0 0
+0 NULL 1 NULL NULL NULL
+0 0 NULL 0 0 0
+0 0 0 0 0 0
+0 0 1 0 0 0
+0 1 NULL NULL NULL NULL
+0 1 0 0 0 0
+0 1 1 1 1 1
+1 NULL NULL NULL 1 1
+1 NULL 0 0 1 1
+1 NULL 1 1 1 1
+1 0 NULL NULL 1 1
+1 0 0 0 1 1
+1 0 1 1 1 1
+1 1 NULL NULL 1 1
+1 1 0 0 1 1
+1 1 1 1 1 1
+select count(*) from t1_30237_bool
+where (A OR (B AND C)) != (A OR B AND C);
+count(*)
+0
+select A, B, C, (A AND B) OR C, A AND (B OR C), A AND B OR C
+from t1_30237_bool order by A, B, C;
+A B C (A AND B) OR C A AND (B OR C) A AND B OR C
+NULL NULL NULL NULL NULL NULL
+NULL NULL 0 NULL NULL NULL
+NULL NULL 1 1 NULL 1
+NULL 0 NULL NULL NULL NULL
+NULL 0 0 0 0 0
+NULL 0 1 1 NULL 1
+NULL 1 NULL NULL NULL NULL
+NULL 1 0 NULL NULL NULL
+NULL 1 1 1 NULL 1
+0 NULL NULL NULL 0 NULL
+0 NULL 0 0 0 0
+0 NULL 1 1 0 1
+0 0 NULL NULL 0 NULL
+0 0 0 0 0 0
+0 0 1 1 0 1
+0 1 NULL NULL 0 NULL
+0 1 0 0 0 0
+0 1 1 1 0 1
+1 NULL NULL NULL NULL NULL
+1 NULL 0 NULL NULL NULL
+1 NULL 1 1 1 1
+1 0 NULL NULL NULL NULL
+1 0 0 0 0 0
+1 0 1 1 1 1
+1 1 NULL 1 1 1
+1 1 0 1 1 1
+1 1 1 1 1 1
+select count(*) from t1_30237_bool
+where ((A AND B) OR C) != (A AND B OR C);
+count(*)
+0
+Testing that AND has precedence over XOR
+select A, B, C, (A XOR B) AND C, A XOR (B AND C), A XOR B AND C
+from t1_30237_bool order by A, B, C;
+A B C (A XOR B) AND C A XOR (B AND C) A XOR B AND C
+NULL NULL NULL NULL NULL NULL
+NULL NULL 0 0 NULL NULL
+NULL NULL 1 NULL NULL NULL
+NULL 0 NULL NULL NULL NULL
+NULL 0 0 0 NULL NULL
+NULL 0 1 NULL NULL NULL
+NULL 1 NULL NULL NULL NULL
+NULL 1 0 0 NULL NULL
+NULL 1 1 NULL NULL NULL
+0 NULL NULL NULL NULL NULL
+0 NULL 0 0 0 0
+0 NULL 1 NULL NULL NULL
+0 0 NULL 0 0 0
+0 0 0 0 0 0
+0 0 1 0 0 0
+0 1 NULL NULL NULL NULL
+0 1 0 0 0 0
+0 1 1 1 1 1
+1 NULL NULL NULL NULL NULL
+1 NULL 0 0 1 1
+1 NULL 1 NULL NULL NULL
+1 0 NULL NULL 1 1
+1 0 0 0 1 1
+1 0 1 1 1 1
+1 1 NULL 0 NULL NULL
+1 1 0 0 1 1
+1 1 1 0 0 0
+select count(*) from t1_30237_bool
+where (A XOR (B AND C)) != (A XOR B AND C);
+count(*)
+0
+select A, B, C, (A AND B) XOR C, A AND (B XOR C), A AND B XOR C
+from t1_30237_bool order by A, B, C;
+A B C (A AND B) XOR C A AND (B XOR C) A AND B XOR C
+NULL NULL NULL NULL NULL NULL
+NULL NULL 0 NULL NULL NULL
+NULL NULL 1 NULL NULL NULL
+NULL 0 NULL NULL NULL NULL
+NULL 0 0 0 0 0
+NULL 0 1 1 NULL 1
+NULL 1 NULL NULL NULL NULL
+NULL 1 0 NULL NULL NULL
+NULL 1 1 NULL 0 NULL
+0 NULL NULL NULL 0 NULL
+0 NULL 0 0 0 0
+0 NULL 1 1 0 1
+0 0 NULL NULL 0 NULL
+0 0 0 0 0 0
+0 0 1 1 0 1
+0 1 NULL NULL 0 NULL
+0 1 0 0 0 0
+0 1 1 1 0 1
+1 NULL NULL NULL NULL NULL
+1 NULL 0 NULL NULL NULL
+1 NULL 1 NULL NULL NULL
+1 0 NULL NULL NULL NULL
+1 0 0 0 0 0
+1 0 1 1 1 1
+1 1 NULL NULL NULL NULL
+1 1 0 1 1 1
+1 1 1 0 0 0
+select count(*) from t1_30237_bool
+where ((A AND B) XOR C) != (A AND B XOR C);
+count(*)
+0
+Testing that XOR has precedence over OR
+select A, B, C, (A XOR B) OR C, A XOR (B OR C), A XOR B OR C
+from t1_30237_bool order by A, B, C;
+A B C (A XOR B) OR C A XOR (B OR C) A XOR B OR C
+NULL NULL NULL NULL NULL NULL
+NULL NULL 0 NULL NULL NULL
+NULL NULL 1 1 NULL 1
+NULL 0 NULL NULL NULL NULL
+NULL 0 0 NULL NULL NULL
+NULL 0 1 1 NULL 1
+NULL 1 NULL NULL NULL NULL
+NULL 1 0 NULL NULL NULL
+NULL 1 1 1 NULL 1
+0 NULL NULL NULL NULL NULL
+0 NULL 0 NULL NULL NULL
+0 NULL 1 1 1 1
+0 0 NULL NULL NULL NULL
+0 0 0 0 0 0
+0 0 1 1 1 1
+0 1 NULL 1 1 1
+0 1 0 1 1 1
+0 1 1 1 1 1
+1 NULL NULL NULL NULL NULL
+1 NULL 0 NULL NULL NULL
+1 NULL 1 1 0 1
+1 0 NULL 1 NULL 1
+1 0 0 1 1 1
+1 0 1 1 0 1
+1 1 NULL NULL 0 NULL
+1 1 0 0 0 0
+1 1 1 1 0 1
+select count(*) from t1_30237_bool
+where ((A XOR B) OR C) != (A XOR B OR C);
+count(*)
+0
+select A, B, C, (A OR B) XOR C, A OR (B XOR C), A OR B XOR C
+from t1_30237_bool order by A, B, C;
+A B C (A OR B) XOR C A OR (B XOR C) A OR B XOR C
+NULL NULL NULL NULL NULL NULL
+NULL NULL 0 NULL NULL NULL
+NULL NULL 1 NULL NULL NULL
+NULL 0 NULL NULL NULL NULL
+NULL 0 0 NULL NULL NULL
+NULL 0 1 NULL 1 1
+NULL 1 NULL NULL NULL NULL
+NULL 1 0 1 1 1
+NULL 1 1 0 NULL NULL
+0 NULL NULL NULL NULL NULL
+0 NULL 0 NULL NULL NULL
+0 NULL 1 NULL NULL NULL
+0 0 NULL NULL NULL NULL
+0 0 0 0 0 0
+0 0 1 1 1 1
+0 1 NULL NULL NULL NULL
+0 1 0 1 1 1
+0 1 1 0 0 0
+1 NULL NULL NULL 1 1
+1 NULL 0 1 1 1
+1 NULL 1 0 1 1
+1 0 NULL NULL 1 1
+1 0 0 1 1 1
+1 0 1 0 1 1
+1 1 NULL NULL 1 1
+1 1 0 1 1 1
+1 1 1 0 1 1
+select count(*) from t1_30237_bool
+where (A OR (B XOR C)) != (A OR B XOR C);
+count(*)
+0
+drop table t1_30237_bool;
+Testing that NOT has precedence over OR
+select (NOT FALSE) OR TRUE, NOT (FALSE OR TRUE), NOT FALSE OR TRUE;
+(NOT FALSE) OR TRUE NOT (FALSE OR TRUE) NOT FALSE OR TRUE
+1 0 1
+Testing that NOT has precedence over XOR
+select (NOT FALSE) XOR FALSE, NOT (FALSE XOR FALSE), NOT FALSE XOR FALSE;
+(NOT FALSE) XOR FALSE NOT (FALSE XOR FALSE) NOT FALSE XOR FALSE
+1 1 1
+Testing that NOT has precedence over AND
+select (NOT FALSE) AND FALSE, NOT (FALSE AND FALSE), NOT FALSE AND FALSE;
+(NOT FALSE) AND FALSE NOT (FALSE AND FALSE) NOT FALSE AND FALSE
+0 1 0
+Testing that NOT is associative
+select NOT NOT TRUE, NOT NOT NOT FALSE;
+NOT NOT TRUE NOT NOT NOT FALSE
+1 1
+Testing that IS has precedence over NOT
+select (NOT NULL) IS TRUE, NOT (NULL IS TRUE), NOT NULL IS TRUE;
+(NOT NULL) IS TRUE NOT (NULL IS TRUE) NOT NULL IS TRUE
+0 1 1
+select (NOT NULL) IS NOT TRUE, NOT (NULL IS NOT TRUE), NOT NULL IS NOT TRUE;
+(NOT NULL) IS NOT TRUE NOT (NULL IS NOT TRUE) NOT NULL IS NOT TRUE
+1 0 0
+select (NOT NULL) IS FALSE, NOT (NULL IS FALSE), NOT NULL IS FALSE;
+(NOT NULL) IS FALSE NOT (NULL IS FALSE) NOT NULL IS FALSE
+0 1 1
+select (NOT NULL) IS NOT FALSE, NOT (NULL IS NOT FALSE), NOT NULL IS NOT FALSE;
+(NOT NULL) IS NOT FALSE NOT (NULL IS NOT FALSE) NOT NULL IS NOT FALSE
+1 0 0
+select (NOT TRUE) IS UNKNOWN, NOT (TRUE IS UNKNOWN), NOT TRUE IS UNKNOWN;
+(NOT TRUE) IS UNKNOWN NOT (TRUE IS UNKNOWN) NOT TRUE IS UNKNOWN
+0 1 1
+select (NOT TRUE) IS NOT UNKNOWN, NOT (TRUE IS NOT UNKNOWN), NOT TRUE IS NOT UNKNOWN;
+(NOT TRUE) IS NOT UNKNOWN NOT (TRUE IS NOT UNKNOWN) NOT TRUE IS NOT UNKNOWN
+1 0 0
+select (NOT TRUE) IS NULL, NOT (TRUE IS NULL), NOT TRUE IS NULL;
+(NOT TRUE) IS NULL NOT (TRUE IS NULL) NOT TRUE IS NULL
+0 1 1
+select (NOT TRUE) IS NOT NULL, NOT (TRUE IS NOT NULL), NOT TRUE IS NOT NULL;
+(NOT TRUE) IS NOT NULL NOT (TRUE IS NOT NULL) NOT TRUE IS NOT NULL
+1 0 0
+Testing that IS [NOT] TRUE/FALSE/UNKNOWN predicates are not associative
+select TRUE IS TRUE IS TRUE IS TRUE;
+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 'IS TRUE IS TRUE' at line 1
+select FALSE IS NOT TRUE IS NOT TRUE IS NOT TRUE;
+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 'IS NOT TRUE IS NOT TRUE' at line 1
+select NULL IS FALSE IS FALSE IS FALSE;
+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 'IS FALSE IS FALSE' at line 1
+select TRUE IS NOT FALSE IS NOT FALSE IS NOT FALSE;
+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 'IS NOT FALSE IS NOT FALSE' at line 1
+select FALSE IS UNKNOWN IS UNKNOWN IS UNKNOWN;
+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 'IS UNKNOWN IS UNKNOWN' at line 1
+select TRUE IS NOT UNKNOWN IS NOT UNKNOWN IS NOT UNKNOWN;
+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 'IS NOT UNKNOWN IS NOT UNKNOWN' at line 1
+Testing that IS [NOT] NULL predicates are associative
+select FALSE IS NULL IS NULL IS NULL;
+FALSE IS NULL IS NULL IS NULL
+0
+select TRUE IS NOT NULL IS NOT NULL IS NOT NULL;
+TRUE IS NOT NULL IS NOT NULL IS NOT NULL
+1
+Testing that comparison operators are left associative
+select 1 <=> 2 <=> 2, (1 <=> 2) <=> 2, 1 <=> (2 <=> 2);
+1 <=> 2 <=> 2 (1 <=> 2) <=> 2 1 <=> (2 <=> 2)
+0 0 1
+select 1 = 2 = 2, (1 = 2) = 2, 1 = (2 = 2);
+1 = 2 = 2 (1 = 2) = 2 1 = (2 = 2)
+0 0 1
+select 1 != 2 != 3, (1 != 2) != 3, 1 != (2 != 3);
+1 != 2 != 3 (1 != 2) != 3 1 != (2 != 3)
+1 1 0
+select 1 <> 2 <> 3, (1 <> 2) <> 3, 1 <> (2 <> 3);
+1 <> 2 <> 3 (1 <> 2) <> 3 1 <> (2 <> 3)
+1 1 0
+select 1 < 2 < 3, (1 < 2) < 3, 1 < (2 < 3);
+1 < 2 < 3 (1 < 2) < 3 1 < (2 < 3)
+1 1 0
+select 3 <= 2 <= 1, (3 <= 2) <= 1, 3 <= (2 <= 1);
+3 <= 2 <= 1 (3 <= 2) <= 1 3 <= (2 <= 1)
+1 1 0
+select 1 > 2 > 3, (1 > 2) > 3, 1 > (2 > 3);
+1 > 2 > 3 (1 > 2) > 3 1 > (2 > 3)
+0 0 1
+select 1 >= 2 >= 3, (1 >= 2) >= 3, 1 >= (2 >= 3);
+1 >= 2 >= 3 (1 >= 2) >= 3 1 >= (2 >= 3)
+0 0 1
+Testing that | is associative
+select 0xF0 | 0x0F | 0x55, (0xF0 | 0x0F) | 0x55, 0xF0 | (0x0F | 0x55);
+0xF0 | 0x0F | 0x55 (0xF0 | 0x0F) | 0x55 0xF0 | (0x0F | 0x55)
+255 255 255
+Testing that & is associative
+select 0xF5 & 0x5F & 0x55, (0xF5 & 0x5F) & 0x55, 0xF5 & (0x5F & 0x55);
+0xF5 & 0x5F & 0x55 (0xF5 & 0x5F) & 0x55 0xF5 & (0x5F & 0x55)
+85 85 85
+Testing that << is left associative
+select 4 << 3 << 2, (4 << 3) << 2, 4 << (3 << 2);
+4 << 3 << 2 (4 << 3) << 2 4 << (3 << 2)
+128 128 16384
+Testing that >> is left associative
+select 256 >> 3 >> 2, (256 >> 3) >> 2, 256 >> (3 >> 2);
+256 >> 3 >> 2 (256 >> 3) >> 2 256 >> (3 >> 2)
+8 8 256
+Testing that & has precedence over |
+select 0xF0 & 0x0F | 0x55, (0xF0 & 0x0F) | 0x55, 0xF0 & (0x0F | 0x55);
+0xF0 & 0x0F | 0x55 (0xF0 & 0x0F) | 0x55 0xF0 & (0x0F | 0x55)
+85 85 80
+select 0x55 | 0xF0 & 0x0F, (0x55 | 0xF0) & 0x0F, 0x55 | (0xF0 & 0x0F);
+0x55 | 0xF0 & 0x0F (0x55 | 0xF0) & 0x0F 0x55 | (0xF0 & 0x0F)
+85 5 85
+Testing that << has precedence over |
+select 0x0F << 4 | 0x0F, (0x0F << 4) | 0x0F, 0x0F << (4 | 0x0F);
+0x0F << 4 | 0x0F (0x0F << 4) | 0x0F 0x0F << (4 | 0x0F)
+255 255 491520
+select 0x0F | 0x0F << 4, (0x0F | 0x0F) << 4, 0x0F | (0x0F << 4);
+0x0F | 0x0F << 4 (0x0F | 0x0F) << 4 0x0F | (0x0F << 4)
+255 240 255
+Testing that >> has precedence over |
+select 0xF0 >> 4 | 0xFF, (0xF0 >> 4) | 0xFF, 0xF0 >> (4 | 0xFF);
+0xF0 >> 4 | 0xFF (0xF0 >> 4) | 0xFF 0xF0 >> (4 | 0xFF)
+255 255 0
+select 0xFF | 0xF0 >> 4, (0xFF | 0xF0) >> 4, 0xFF | (0xF0 >> 4);
+0xFF | 0xF0 >> 4 (0xFF | 0xF0) >> 4 0xFF | (0xF0 >> 4)
+255 15 255
+Testing that << has precedence over &
+select 0x0F << 4 & 0xF0, (0x0F << 4) & 0xF0, 0x0F << (4 & 0xF0);
+0x0F << 4 & 0xF0 (0x0F << 4) & 0xF0 0x0F << (4 & 0xF0)
+240 240 15
+select 0xF0 & 0x0F << 4, (0xF0 & 0x0F) << 4, 0xF0 & (0x0F << 4);
+0xF0 & 0x0F << 4 (0xF0 & 0x0F) << 4 0xF0 & (0x0F << 4)
+240 0 240
+Testing that >> has precedence over &
+select 0xF0 >> 4 & 0x55, (0xF0 >> 4) & 0x55, 0xF0 >> (4 & 0x55);
+0xF0 >> 4 & 0x55 (0xF0 >> 4) & 0x55 0xF0 >> (4 & 0x55)
+5 5 15
+select 0x0F & 0xF0 >> 4, (0x0F & 0xF0) >> 4, 0x0F & (0xF0 >> 4);
+0x0F & 0xF0 >> 4 (0x0F & 0xF0) >> 4 0x0F & (0xF0 >> 4)
+15 0 15
+Testing that >> and << have the same precedence
+select 0xFF >> 4 << 2, (0xFF >> 4) << 2, 0xFF >> (4 << 2);
+0xFF >> 4 << 2 (0xFF >> 4) << 2 0xFF >> (4 << 2)
+60 60 0
+select 0x0F << 4 >> 2, (0x0F << 4) >> 2, 0x0F << (4 >> 2);
+0x0F << 4 >> 2 (0x0F << 4) >> 2 0x0F << (4 >> 2)
+60 60 30
+Testing that binary + is associative
+select 1 + 2 + 3, (1 + 2) + 3, 1 + (2 + 3);
+1 + 2 + 3 (1 + 2) + 3 1 + (2 + 3)
+6 6 6
+Testing that binary - is left associative
+select 1 - 2 - 3, (1 - 2) - 3, 1 - (2 - 3);
+1 - 2 - 3 (1 - 2) - 3 1 - (2 - 3)
+-4 -4 2
+Testing that binary + and binary - have the same precedence
+select 1 + 2 - 3, (1 + 2) - 3, 1 + (2 - 3);
+1 + 2 - 3 (1 + 2) - 3 1 + (2 - 3)
+0 0 0
+select 1 - 2 + 3, (1 - 2) + 3, 1 - (2 + 3);
+1 - 2 + 3 (1 - 2) + 3 1 - (2 + 3)
+2 2 -4
+Testing that binary + has precedence over |
+select 0xF0 + 0x0F | 0x55, (0xF0 + 0x0F) | 0x55, 0xF0 + (0x0F | 0x55);
+0xF0 + 0x0F | 0x55 (0xF0 + 0x0F) | 0x55 0xF0 + (0x0F | 0x55)
+255 255 335
+select 0x55 | 0xF0 + 0x0F, (0x55 | 0xF0) + 0x0F, 0x55 | (0xF0 + 0x0F);
+0x55 | 0xF0 + 0x0F (0x55 | 0xF0) + 0x0F 0x55 | (0xF0 + 0x0F)
+255 260 255
+Testing that binary + has precedence over &
+select 0xF0 + 0x0F & 0x55, (0xF0 + 0x0F) & 0x55, 0xF0 + (0x0F & 0x55);
+0xF0 + 0x0F & 0x55 (0xF0 + 0x0F) & 0x55 0xF0 + (0x0F & 0x55)
+85 85 245
+select 0x55 & 0xF0 + 0x0F, (0x55 & 0xF0) + 0x0F, 0x55 & (0xF0 + 0x0F);
+0x55 & 0xF0 + 0x0F (0x55 & 0xF0) + 0x0F 0x55 & (0xF0 + 0x0F)
+85 95 85
+Testing that binary + has precedence over <<
+select 2 + 3 << 4, (2 + 3) << 4, 2 + (3 << 4);
+2 + 3 << 4 (2 + 3) << 4 2 + (3 << 4)
+80 80 50
+select 3 << 4 + 2, (3 << 4) + 2, 3 << (4 + 2);
+3 << 4 + 2 (3 << 4) + 2 3 << (4 + 2)
+192 50 192
+Testing that binary + has precedence over >>
+select 4 + 3 >> 2, (4 + 3) >> 2, 4 + (3 >> 2);
+4 + 3 >> 2 (4 + 3) >> 2 4 + (3 >> 2)
+1 1 4
+select 3 >> 2 + 1, (3 >> 2) + 1, 3 >> (2 + 1);
+3 >> 2 + 1 (3 >> 2) + 1 3 >> (2 + 1)
+0 1 0
+Testing that binary - has precedence over |
+select 0xFF - 0x0F | 0x55, (0xFF - 0x0F) | 0x55, 0xFF - (0x0F | 0x55);
+0xFF - 0x0F | 0x55 (0xFF - 0x0F) | 0x55 0xFF - (0x0F | 0x55)
+245 245 160
+select 0x55 | 0xFF - 0xF0, (0x55 | 0xFF) - 0xF0, 0x55 | (0xFF - 0xF0);
+0x55 | 0xFF - 0xF0 (0x55 | 0xFF) - 0xF0 0x55 | (0xFF - 0xF0)
+95 15 95
+Testing that binary - has precedence over &
+select 0xFF - 0xF0 & 0x55, (0xFF - 0xF0) & 0x55, 0xFF - (0xF0 & 0x55);
+0xFF - 0xF0 & 0x55 (0xFF - 0xF0) & 0x55 0xFF - (0xF0 & 0x55)
+5 5 175
+select 0x55 & 0xFF - 0xF0, (0x55 & 0xFF) - 0xF0, 0x55 & (0xFF - 0xF0);
+0x55 & 0xFF - 0xF0 (0x55 & 0xFF) - 0xF0 0x55 & (0xFF - 0xF0)
+5 -155 5
+Testing that binary - has precedence over <<
+select 16 - 3 << 2, (16 - 3) << 2, 16 - (3 << 2);
+16 - 3 << 2 (16 - 3) << 2 16 - (3 << 2)
+52 52 4
+select 4 << 3 - 2, (4 << 3) - 2, 4 << (3 - 2);
+4 << 3 - 2 (4 << 3) - 2 4 << (3 - 2)
+8 30 8
+Testing that binary - has precedence over >>
+select 16 - 3 >> 2, (16 - 3) >> 2, 16 - (3 >> 2);
+16 - 3 >> 2 (16 - 3) >> 2 16 - (3 >> 2)
+3 3 16
+select 16 >> 3 - 2, (16 >> 3) - 2, 16 >> (3 - 2);
+16 >> 3 - 2 (16 >> 3) - 2 16 >> (3 - 2)
+8 0 8
+Testing that * is associative
+select 2 * 3 * 4, (2 * 3) * 4, 2 * (3 * 4);
+2 * 3 * 4 (2 * 3) * 4 2 * (3 * 4)
+24 24 24
+Testing that * has precedence over |
+select 2 * 0x40 | 0x0F, (2 * 0x40) | 0x0F, 2 * (0x40 | 0x0F);
+2 * 0x40 | 0x0F (2 * 0x40) | 0x0F 2 * (0x40 | 0x0F)
+143 143 158
+select 0x0F | 2 * 0x40, (0x0F | 2) * 0x40, 0x0F | (2 * 0x40);
+0x0F | 2 * 0x40 (0x0F | 2) * 0x40 0x0F | (2 * 0x40)
+143 960 143
+Testing that * has precedence over &
+select 2 * 0x40 & 0x55, (2 * 0x40) & 0x55, 2 * (0x40 & 0x55);
+2 * 0x40 & 0x55 (2 * 0x40) & 0x55 2 * (0x40 & 0x55)
+0 0 128
+select 0xF0 & 2 * 0x40, (0xF0 & 2) * 0x40, 0xF0 & (2 * 0x40);
+0xF0 & 2 * 0x40 (0xF0 & 2) * 0x40 0xF0 & (2 * 0x40)
+128 0 128
+Testing that * has precedence over <<
+select 5 * 3 << 4, (5 * 3) << 4, 5 * (3 << 4);
+5 * 3 << 4 (5 * 3) << 4 5 * (3 << 4)
+240 240 240
+select 2 << 3 * 4, (2 << 3) * 4, 2 << (3 * 4);
+2 << 3 * 4 (2 << 3) * 4 2 << (3 * 4)
+8192 64 8192
+Testing that * has precedence over >>
+select 3 * 4 >> 2, (3 * 4) >> 2, 3 * (4 >> 2);
+3 * 4 >> 2 (3 * 4) >> 2 3 * (4 >> 2)
+3 3 3
+select 4 >> 2 * 3, (4 >> 2) * 3, 4 >> (2 * 3);
+4 >> 2 * 3 (4 >> 2) * 3 4 >> (2 * 3)
+0 3 0
+Testing that * has precedence over binary +
+select 2 * 3 + 4, (2 * 3) + 4, 2 * (3 + 4);
+2 * 3 + 4 (2 * 3) + 4 2 * (3 + 4)
+10 10 14
+select 2 + 3 * 4, (2 + 3) * 4, 2 + (3 * 4);
+2 + 3 * 4 (2 + 3) * 4 2 + (3 * 4)
+14 20 14
+Testing that * has precedence over binary -
+select 4 * 3 - 2, (4 * 3) - 2, 4 * (3 - 2);
+4 * 3 - 2 (4 * 3) - 2 4 * (3 - 2)
+10 10 4
+select 4 - 3 * 2, (4 - 3) * 2, 4 - (3 * 2);
+4 - 3 * 2 (4 - 3) * 2 4 - (3 * 2)
+-2 2 -2
+Testing that / is left associative
+select 15 / 5 / 3, (15 / 5) / 3, 15 / (5 / 3);
+15 / 5 / 3 (15 / 5) / 3 15 / (5 / 3)
+1.00000000 1.00000000 9.0000
+Testing that / has precedence over |
+select 105 / 5 | 2, (105 / 5) | 2, 105 / (5 | 2);
+105 / 5 | 2 (105 / 5) | 2 105 / (5 | 2)
+23 23 15.0000
+select 105 | 2 / 5, (105 | 2) / 5, 105 | (2 / 5);
+105 | 2 / 5 (105 | 2) / 5 105 | (2 / 5)
+105 21.4000 105
+Testing that / has precedence over &
+select 105 / 5 & 0x0F, (105 / 5) & 0x0F, 105 / (5 & 0x0F);
+105 / 5 & 0x0F (105 / 5) & 0x0F 105 / (5 & 0x0F)
+5 5 21.0000
+select 0x0F & 105 / 5, (0x0F & 105) / 5, 0x0F & (105 / 5);
+0x0F & 105 / 5 (0x0F & 105) / 5 0x0F & (105 / 5)
+5 1.8000 5
+Testing that / has precedence over <<
+select 0x80 / 4 << 2, (0x80 / 4) << 2, 0x80 / (4 << 2);
+0x80 / 4 << 2 (0x80 / 4) << 2 0x80 / (4 << 2)
+128 128 8.0000
+select 0x80 << 4 / 2, (0x80 << 4) / 2, 0x80 << (4 / 2);
+0x80 << 4 / 2 (0x80 << 4) / 2 0x80 << (4 / 2)
+512 1024.0000 512
+Testing that / has precedence over >>
+select 0x80 / 4 >> 2, (0x80 / 4) >> 2, 0x80 / (4 >> 2);
+0x80 / 4 >> 2 (0x80 / 4) >> 2 0x80 / (4 >> 2)
+8 8 128.0000
+select 0x80 >> 4 / 2, (0x80 >> 4) / 2, 0x80 >> (4 / 2);
+0x80 >> 4 / 2 (0x80 >> 4) / 2 0x80 >> (4 / 2)
+32 4.0000 32
+Testing that / has precedence over binary +
+select 0x80 / 2 + 2, (0x80 / 2) + 2, 0x80 / (2 + 2);
+0x80 / 2 + 2 (0x80 / 2) + 2 0x80 / (2 + 2)
+66.0000 66.0000 32.0000
+select 0x80 + 2 / 2, (0x80 + 2) / 2, 0x80 + (2 / 2);
+0x80 + 2 / 2 (0x80 + 2) / 2 0x80 + (2 / 2)
+129.0000 65.0000 129.0000
+Testing that / has precedence over binary -
+select 0x80 / 4 - 2, (0x80 / 4) - 2, 0x80 / (4 - 2);
+0x80 / 4 - 2 (0x80 / 4) - 2 0x80 / (4 - 2)
+30.0000 30.0000 64.0000
+select 0x80 - 4 / 2, (0x80 - 4) / 2, 0x80 - (4 / 2);
+0x80 - 4 / 2 (0x80 - 4) / 2 0x80 - (4 / 2)
+126.0000 62.0000 126.0000
+Testing that ^ is associative
+select 0xFF ^ 0xF0 ^ 0x0F, (0xFF ^ 0xF0) ^ 0x0F, 0xFF ^ (0xF0 ^ 0x0F);
+0xFF ^ 0xF0 ^ 0x0F (0xFF ^ 0xF0) ^ 0x0F 0xFF ^ (0xF0 ^ 0x0F)
+0 0 0
+select 0xFF ^ 0xF0 ^ 0x55, (0xFF ^ 0xF0) ^ 0x55, 0xFF ^ (0xF0 ^ 0x55);
+0xFF ^ 0xF0 ^ 0x55 (0xFF ^ 0xF0) ^ 0x55 0xFF ^ (0xF0 ^ 0x55)
+90 90 90
+Testing that ^ has precedence over |
+select 0xFF ^ 0xF0 | 0x0F, (0xFF ^ 0xF0) | 0x0F, 0xFF ^ (0xF0 | 0x0F);
+0xFF ^ 0xF0 | 0x0F (0xFF ^ 0xF0) | 0x0F 0xFF ^ (0xF0 | 0x0F)
+15 15 0
+select 0xF0 | 0xFF ^ 0xF0, (0xF0 | 0xFF) ^ 0xF0, 0xF0 | (0xFF ^ 0xF0);
+0xF0 | 0xFF ^ 0xF0 (0xF0 | 0xFF) ^ 0xF0 0xF0 | (0xFF ^ 0xF0)
+255 15 255
+Testing that ^ has precedence over &
+select 0xFF ^ 0xF0 & 0x0F, (0xFF ^ 0xF0) & 0x0F, 0xFF ^ (0xF0 & 0x0F);
+0xFF ^ 0xF0 & 0x0F (0xFF ^ 0xF0) & 0x0F 0xFF ^ (0xF0 & 0x0F)
+15 15 255
+select 0x0F & 0xFF ^ 0xF0, (0x0F & 0xFF) ^ 0xF0, 0x0F & (0xFF ^ 0xF0);
+0x0F & 0xFF ^ 0xF0 (0x0F & 0xFF) ^ 0xF0 0x0F & (0xFF ^ 0xF0)
+15 255 15
+Testing that ^ has precedence over <<
+select 0xFF ^ 0xF0 << 2, (0xFF ^ 0xF0) << 2, 0xFF ^ (0xF0 << 2);
+0xFF ^ 0xF0 << 2 (0xFF ^ 0xF0) << 2 0xFF ^ (0xF0 << 2)
+60 60 831
+select 0x0F << 2 ^ 0xFF, (0x0F << 2) ^ 0xFF, 0x0F << (2 ^ 0xFF);
+0x0F << 2 ^ 0xFF (0x0F << 2) ^ 0xFF 0x0F << (2 ^ 0xFF)
+0 195 0
+Testing that ^ has precedence over >>
+select 0xFF ^ 0xF0 >> 2, (0xFF ^ 0xF0) >> 2, 0xFF ^ (0xF0 >> 2);
+0xFF ^ 0xF0 >> 2 (0xFF ^ 0xF0) >> 2 0xFF ^ (0xF0 >> 2)
+3 3 195
+select 0xFF >> 2 ^ 0xF0, (0xFF >> 2) ^ 0xF0, 0xFF >> (2 ^ 0xF0);
+0xFF >> 2 ^ 0xF0 (0xFF >> 2) ^ 0xF0 0xFF >> (2 ^ 0xF0)
+0 207 0
+Testing that ^ has precedence over binary +
+select 0xFF ^ 0xF0 + 0x0F, (0xFF ^ 0xF0) + 0x0F, 0xFF ^ (0xF0 + 0x0F);
+0xFF ^ 0xF0 + 0x0F (0xFF ^ 0xF0) + 0x0F 0xFF ^ (0xF0 + 0x0F)
+30 30 0
+select 0x0F + 0xFF ^ 0xF0, (0x0F + 0xFF) ^ 0xF0, 0x0F + (0xFF ^ 0xF0);
+0x0F + 0xFF ^ 0xF0 (0x0F + 0xFF) ^ 0xF0 0x0F + (0xFF ^ 0xF0)
+30 510 30
+Testing that ^ has precedence over binary -
+select 0xFF ^ 0xF0 - 1, (0xFF ^ 0xF0) - 1, 0xFF ^ (0xF0 - 1);
+0xFF ^ 0xF0 - 1 (0xFF ^ 0xF0) - 1 0xFF ^ (0xF0 - 1)
+14 14 16
+select 0x55 - 0x0F ^ 0x55, (0x55 - 0x0F) ^ 0x55, 0x55 - (0x0F ^ 0x55);
+0x55 - 0x0F ^ 0x55 (0x55 - 0x0F) ^ 0x55 0x55 - (0x0F ^ 0x55)
+-5 19 -5
+Testing that ^ has precedence over *
+select 0xFF ^ 0xF0 * 2, (0xFF ^ 0xF0) * 2, 0xFF ^ (0xF0 * 2);
+0xFF ^ 0xF0 * 2 (0xFF ^ 0xF0) * 2 0xFF ^ (0xF0 * 2)
+30 30 287
+select 2 * 0xFF ^ 0xF0, (2 * 0xFF) ^ 0xF0, 2 * (0xFF ^ 0xF0);
+2 * 0xFF ^ 0xF0 (2 * 0xFF) ^ 0xF0 2 * (0xFF ^ 0xF0)
+30 270 30
+Testing that ^ has precedence over /
+select 0xFF ^ 0xF0 / 2, (0xFF ^ 0xF0) / 2, 0xFF ^ (0xF0 / 2);
+0xFF ^ 0xF0 / 2 (0xFF ^ 0xF0) / 2 0xFF ^ (0xF0 / 2)
+7.5000 7.5000 135
+select 0xF2 / 2 ^ 0xF0, (0xF2 / 2) ^ 0xF0, 0xF2 / (2 ^ 0xF0);
+0xF2 / 2 ^ 0xF0 (0xF2 / 2) ^ 0xF0 0xF2 / (2 ^ 0xF0)
+1.0000 137 1.0000
+Testing that ^ has precedence over %
+select 0xFF ^ 0xF0 % 0x20, (0xFF ^ 0xF0) % 0x20, 0xFF ^ (0xF0 % 0x20);
+0xFF ^ 0xF0 % 0x20 (0xFF ^ 0xF0) % 0x20 0xFF ^ (0xF0 % 0x20)
+15 15 239
+select 0xFF % 0x20 ^ 0xF0, (0xFF % 0x20) ^ 0xF0, 0xFF % (0x20 ^ 0xF0);
+0xFF % 0x20 ^ 0xF0 (0xFF % 0x20) ^ 0xF0 0xFF % (0x20 ^ 0xF0)
+47 239 47
+Testing that ^ has precedence over DIV
+select 0xFF ^ 0xF0 DIV 2, (0xFF ^ 0xF0) DIV 2, 0xFF ^ (0xF0 DIV 2);
+0xFF ^ 0xF0 DIV 2 (0xFF ^ 0xF0) DIV 2 0xFF ^ (0xF0 DIV 2)
+7 7 135
+select 0xF2 DIV 2 ^ 0xF0, (0xF2 DIV 2) ^ 0xF0, 0xF2 DIV (2 ^ 0xF0);
+0xF2 DIV 2 ^ 0xF0 (0xF2 DIV 2) ^ 0xF0 0xF2 DIV (2 ^ 0xF0)
+1 137 1
+Testing that ^ has precedence over MOD
+select 0xFF ^ 0xF0 MOD 0x20, (0xFF ^ 0xF0) MOD 0x20, 0xFF ^ (0xF0 MOD 0x20);
+0xFF ^ 0xF0 MOD 0x20 (0xFF ^ 0xF0) MOD 0x20 0xFF ^ (0xF0 MOD 0x20)
+15 15 239
+select 0xFF MOD 0x20 ^ 0xF0, (0xFF MOD 0x20) ^ 0xF0, 0xFF MOD (0x20 ^ 0xF0);
+0xFF MOD 0x20 ^ 0xF0 (0xFF MOD 0x20) ^ 0xF0 0xFF MOD (0x20 ^ 0xF0)
+47 239 47
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index 25c6d58dee2..68f18d1b0b2 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -1621,6 +1621,35 @@ a (select count(*) from t2)
3 0
4 0
drop table t1,t2;
+DROP DATABASE IF EXISTS bug30269;
+FLUSH STATUS;
+CREATE DATABASE bug30269;
+USE bug30269;
+CREATE TABLE test1 (id int, name varchar(23));
+CREATE VIEW view1 AS SELECT * FROM test1;
+INSERT INTO test1 VALUES (5, 'testit');
+GRANT SELECT (id) ON TABLE bug30269.test1 TO 'bug30269'@'localhost';
+GRANT SELECT ON TABLE bug30269.view1 TO 'bug30269'@'localhost';
+set global query_cache_size= 81920;
+USE bug30269;
+show status like 'Qcache_queries_in_cache';
+Variable_name Value
+Qcache_queries_in_cache 0
+# Select statement not stored in query cache because of column privileges.
+SELECT id FROM test1 WHERE id>2;
+id
+5
+show status like 'Qcache_queries_in_cache';
+Variable_name Value
+Qcache_queries_in_cache 0
+SELECT id FROM view1 WHERE id>2;
+id
+5
+show status like 'Qcache_queries_in_cache';
+Variable_name Value
+Qcache_queries_in_cache 1
+DROP DATABASE bug30269;
+DROP USER 'bug30269'@'localhost';
set GLOBAL query_cache_type=default;
set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
diff --git a/mysql-test/r/view_query_cache.result b/mysql-test/r/query_cache_with_views.result
index 03430bd504b..03430bd504b 100644
--- a/mysql-test/r/view_query_cache.result
+++ b/mysql-test/r/query_cache_with_views.result
diff --git a/mysql-test/r/rpl_timezone.result b/mysql-test/r/rpl_timezone.result
index 10dc8eb7e3c..7a18a26afd3 100644
--- a/mysql-test/r/rpl_timezone.result
+++ b/mysql-test/r/rpl_timezone.result
@@ -130,3 +130,21 @@ t
2005-01-01 08:00:00
drop table t1, t2;
set global time_zone= @my_time_zone;
+End of 4.1 tests
+CREATE TABLE t1 (a INT, b TIMESTAMP);
+INSERT INTO t1 VALUES (1, NOW());
+SET @@session.time_zone='Japan';
+UPDATE t1 SET b= '1970-01-01 08:59:59' WHERE a= 1;
+Warnings:
+Warning 1264 Out of range value adjusted for column 'b' at row 1
+SELECT * FROM t1 ORDER BY a;
+a b
+1 0000-00-00 00:00:00
+SET @@session.time_zone='Japan';
+SELECT * FROM t1 ORDER BY a;
+a b
+1 0000-00-00 00:00:00
+SET @@session.time_zone = default;
+DROP TABLE t1;
+SET @@session.time_zone = default;
+End of 5.0 tests
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index bfe0b9d19df..2cf1316bb47 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -3995,4 +3995,71 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE f1 index inx inx 10 NULL 7 Using where; Using index
1 SIMPLE f2 ref inx inx 5 test.f1.b 1 Using where; Using index
DROP TABLE t1;
+CREATE TABLE t1 (c1 INT, c2 INT);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2)))))))))))))))))))))))))))))))) > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+31 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+32 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
+EXPLAIN SELECT c1 FROM t1 WHERE (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT (SELECT COUNT(c2))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) > 0;
+ERROR HY000: Too high level of nesting for select
+DROP TABLE t1;
+CREATE TABLE t1 (
+c1 int(11) NOT NULL AUTO_INCREMENT,
+c2 varchar(1000) DEFAULT NULL,
+c3 bigint(20) DEFAULT NULL,
+c4 bigint(20) DEFAULT NULL,
+PRIMARY KEY (c1)
+);
+EXPLAIN EXTENDED
+SELECT join_2.c1
+FROM
+t1 AS join_0,
+t1 AS join_1,
+t1 AS join_2,
+t1 AS join_3,
+t1 AS join_4,
+t1 AS join_5,
+t1 AS join_6,
+t1 AS join_7
+WHERE
+join_0.c1=join_1.c1 AND
+join_1.c1=join_2.c1 AND
+join_2.c1=join_3.c1 AND
+join_3.c1=join_4.c1 AND
+join_4.c1=join_5.c1 AND
+join_5.c1=join_6.c1 AND
+join_6.c1=join_7.c1
+OR
+join_0.c2 < '?' AND
+join_1.c2 < '?' AND
+join_2.c2 > '?' AND
+join_2.c2 < '!' AND
+join_3.c2 > '?' AND
+join_4.c2 = '?' AND
+join_5.c2 <> '?' AND
+join_6.c2 <> '?' AND
+join_7.c2 >= '?' AND
+join_0.c1=join_1.c1 AND
+join_1.c1=join_2.c1 AND
+join_2.c1=join_3.c1 AND
+join_3.c1=join_4.c1 AND
+join_4.c1=join_5.c1 AND
+join_5.c1=join_6.c1 AND
+join_6.c1=join_7.c1
+GROUP BY
+join_3.c1,
+join_2.c1,
+join_7.c1,
+join_1.c1,
+join_0.c1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0'
+SHOW WARNINGS;
+Level Code Message
+Note 1003 select '0' AS `c1` from `test`.`t1` `join_0` join `test`.`t1` `join_1` join `test`.`t1` `join_2` join `test`.`t1` `join_3` join `test`.`t1` `join_4` join `test`.`t1` `join_5` join `test`.`t1` `join_6` join `test`.`t1` `join_7` where 0 group by '0','0','0','0','0'
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 4a278cd4aec..a6c429a31fb 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -5748,6 +5748,7 @@ bug23760_rc_test(ROW_COUNT())
DROP TABLE bug23760, bug23760_log|
DROP PROCEDURE bug23760_update_log|
DROP PROCEDURE bug23760_test_row_count|
+DROP PROCEDURE bug23760_test_row_count2|
DROP FUNCTION bug23760_rc_test|
DROP PROCEDURE IF EXISTS bug24117|
DROP TABLE IF EXISTS t3|
@@ -6314,4 +6315,56 @@ CALL p1();
NULL
SET NAMES default;
DROP PROCEDURE p1;
+
+# Bug#13675.
+
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP TABLE IF EXISTS t1;
+
+CREATE PROCEDURE p1(v DATETIME) CREATE TABLE t1 SELECT v;
+CREATE PROCEDURE p2(v INT) CREATE TABLE t1 SELECT v;
+
+CALL p1(NOW());
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` datetime default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+
+DROP TABLE t1;
+
+CALL p1('text');
+Warnings:
+Warning 1264 Out of range value adjusted for column 'v' at row 1
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` datetime default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+
+DROP TABLE t1;
+
+CALL p2(10);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` bigint(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+
+DROP TABLE t1;
+
+CALL p2('text');
+Warnings:
+Warning 1366 Incorrect integer value: 'text' for column 'v' at row 1
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` bigint(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+
+DROP TABLE t1;
+
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
End of 5.0 tests
diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
index fad0e1f7974..7c765d6d50b 100644
--- a/mysql-test/r/type_bit.result
+++ b/mysql-test/r/type_bit.result
@@ -618,4 +618,28 @@ bit_field int_field
 2
handler t1 close;
drop table t1;
+CREATE TABLE t1 (b BIT(2), a VARCHAR(5));
+INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z");
+SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b;
+b+0 COUNT(DISTINCT a)
+0 1
+1 1
+3 2
+DROP TABLE t1;
+CREATE TABLE t1 (a CHAR(5), b BIT(2));
+INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z");
+SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b;
+b+0 COUNT(DISTINCT a)
+0 1
+1 1
+3 2
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b BIT(2));
+INSERT INTO t1 (b, a) VALUES (1, 1), (3, 2), (0, 3), (3, 4);
+SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b;
+b+0 COUNT(DISTINCT a)
+0 1
+1 1
+3 2
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/t/backup.test b/mysql-test/t/backup.test
index 6ff4144aaf2..b05eef6a3ad 100644
--- a/mysql-test/t/backup.test
+++ b/mysql-test/t/backup.test
@@ -57,6 +57,15 @@ unlock tables;
connection con1;
reap;
drop table t5;
---system rm $MYSQLTEST_VARDIR/tmp/t?.*
+remove_file $MYSQLTEST_VARDIR/tmp/t1.MYD;
+remove_file $MYSQLTEST_VARDIR/tmp/t2.MYD;
+remove_file $MYSQLTEST_VARDIR/tmp/t3.MYD;
+remove_file $MYSQLTEST_VARDIR/tmp/t4.MYD;
+remove_file $MYSQLTEST_VARDIR/tmp/t5.MYD;
+remove_file $MYSQLTEST_VARDIR/tmp/t1.frm;
+remove_file $MYSQLTEST_VARDIR/tmp/t2.frm;
+remove_file $MYSQLTEST_VARDIR/tmp/t3.frm;
+remove_file $MYSQLTEST_VARDIR/tmp/t4.frm;
+remove_file $MYSQLTEST_VARDIR/tmp/t5.frm;
# End of 4.1 tests
diff --git a/mysql-test/t/bootstrap.test b/mysql-test/t/bootstrap.test
index 1c2952e93d0..203ba9b2914 100644
--- a/mysql-test/t/bootstrap.test
+++ b/mysql-test/t/bootstrap.test
@@ -9,12 +9,13 @@ drop table if exists t1;
#
# Check that --bootstrap reads from stdin
#
---write_file $MYSQLTEST_VARDIR/tmp/bootstrap.sql
+--write_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql
use test;
CREATE TABLE t1(a int);
EOF
---exec $MYSQLD_BOOTSTRAP_CMD < $MYSQLTEST_VARDIR/tmp/bootstrap.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1
+--exec $MYSQLD_BOOTSTRAP_CMD < $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1
drop table t1;
+remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_test.sql;
#
# Check that --bootstrap of file with SQL error returns error
@@ -28,6 +29,7 @@ EOF
# Table t1 should not exists
--error 1051
drop table t1;
+remove_file $MYSQLTEST_VARDIR/tmp/bootstrap_error.sql;
#
# Bootstrap with a query larger than 2*thd->net.max_packet
@@ -40,6 +42,7 @@ eval select * into outfile '$MYSQLTEST_VARDIR/tmp/long_query.sql' from t1;
--enable_query_log
--error 1
--exec $MYSQLD_BOOTSTRAP_CMD < $MYSQLTEST_VARDIR/tmp/long_query.sql >> $MYSQLTEST_VARDIR/tmp/bootstrap.log 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/long_query.sql;
set global max_allowed_packet=@my_max_allowed_packet;
drop table t1;
diff --git a/mysql-test/t/comments.test b/mysql-test/t/comments.test
index 52273ec9523..0c6853cf298 100644
--- a/mysql-test/t/comments.test
+++ b/mysql-test/t/comments.test
@@ -19,3 +19,36 @@ select 1 # The rest of the row will be ignored
/* line with only comment */;
# End of 4.1 tests
+
+
+#
+# Bug#28779 (mysql_query() allows execution of statements with unbalanced
+# comments)
+#
+
+--disable_warnings
+drop table if exists table_28779;
+--enable_warnings
+
+create table table_28779 (a int);
+
+--error 1064
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';";
+
+--error 1064
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*' AND b = 'bar';*";
+
+--error 1064
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;";
+
+--error 1064
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*! AND 2=2;*";
+
+--error 1064
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';";
+
+--error 1064
+prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!98765' AND b = 'bar';*";
+
+drop table table_28779;
+
diff --git a/mysql-test/t/ctype_ascii.test b/mysql-test/t/ctype_ascii.test
new file mode 100644
index 00000000000..2a5118c7d34
--- /dev/null
+++ b/mysql-test/t/ctype_ascii.test
@@ -0,0 +1,13 @@
+#
+# Bug #27562: ascii.xml invalid?
+#
+set names ascii;
+select 'e'='`';
+select 'y'='~';
+create table t1 (a char(1) character set ascii);
+insert into t1 (a) values (' '), ('a'), ('b'), ('c'), ('d'), ('e'), ('f'), ('g'), ('h'), ('i'), ('j'), ('k'), ('l'), ('m'), ('n'), ('o'), ('p'), ('q'), ('r'), ('s'), ('t'), ('u'), ('v'), ('w'), ('x'), ('y'), ('z'), ('A'), ('B'), ('C'), ('D'), ('E'), ('F'), ('G'), ('H'), ('I'), ('J'), ('K'), ('L'), ('M'), ('N'), ('O'), ('P'), ('Q'), ('R'), ('S'), ('T'), ('U'), ('V'), ('W'), ('X'), ('Y'), ('Z'), ('!'), ('@'), ('#'), ('$'), ('%'), ('^'), ('&'), ('*'), ('('), (')'), ('_'), ('+'), ('`'), ('~'), ('1'), ('2'), ('3'), ('4'), ('5'), ('6'), ('7'), ('8'), ('9'), ('0'), ('['), (']'), ('\\'), ('|'), ('}'), ('{'), ('"'), (':'), (''''), (';'), ('/'), ('.'), (','), ('?'), ('>'), ('<'), ('\n'), ('\t'), ('\a'), ('\f'), ('\v');
+select t1a.a, t1b.a from t1 as t1a, t1 as t1b where t1a.a=t1b.a order by binary t1a.a, binary t1b.a;
+drop table t1;
+
+#
+--echo End of 5.0 tests.
diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test
index 63809373822..cc66a6ab4bc 100644
--- a/mysql-test/t/federated.test
+++ b/mysql-test/t/federated.test
@@ -1671,5 +1671,19 @@ drop table federated.t1;
connection slave;
drop table federated.t1;
+--echo
+--echo Bug#18287 create federated table always times out, error 1159 ' '
+--echo
+--echo Test that self-references work
+--echo
+connection slave;
+create table federated.t1 (a int primary key);
+--replace_result $SLAVE_MYPORT SLAVE_PORT
+eval create table federated.t2 (a int primary key)
+ ENGINE=FEDERATED
+ connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
+insert into federated.t1 (a) values (1);
+select * from federated.t2;
+drop table federated.t1, federated.t2;
source include/federated_cleanup.inc;
diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test
index bf18b8da941..6ef216f6ed2 100644
--- a/mysql-test/t/handler.test
+++ b/mysql-test/t/handler.test
@@ -427,3 +427,36 @@ select * from t1;
# Just to be sure and not confuse the next test case writer.
drop table if exists t1;
+#
+# Bug#25856 - HANDLER table OPEN in one connection lock DROP TABLE in another one
+#
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int) ENGINE=MEMORY;
+--echo --> client 2
+connection con2;
+--error 1031
+handler t1 open;
+--echo --> client 1
+connection default;
+drop table t1;
+
+#
+# Bug#30632 HANDLER read failure causes hang
+#
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (a int);
+handler t1 open as t1_alias;
+--error 1176
+handler t1_alias read a next;
+--error 1054
+handler t1_alias READ a next where inexistent > 0;
+--error 1176
+handler t1_alias read a next;
+--error 1054
+handler t1_alias READ a next where inexistent > 0;
+handler t1_alias close;
+drop table t1;
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 6cf4ad8f576..7637a027e8f 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -1045,4 +1045,30 @@ drop table t1,t2;
alter database;
--error ER_PARSE_ERROR
alter database test;
+
+#
+# Bug#27629 Possible security flaw in INFORMATION_SCHEMA and SHOW statements
+#
+
+create database mysqltest;
+create table mysqltest.t1(a int, b int, c int);
+create trigger mysqltest.t1_ai after insert on mysqltest.t1
+ for each row set @a = new.a + new.b + new.c;
+grant select(b) on mysqltest.t1 to mysqltest_1@localhost;
+
+select trigger_name from information_schema.triggers
+where event_object_table='t1';
+show triggers from mysqltest;
+
+connect (con27629,localhost,mysqltest_1,,mysqltest);
+show columns from t1;
+select column_name from information_schema.columns where table_name='t1';
+
+show triggers;
+select trigger_name from information_schema.triggers
+where event_object_table='t1';
+connection default;
+drop user mysqltest_1@localhost;
+drop database mysqltest;
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/information_schema_chmod.test b/mysql-test/t/information_schema_chmod.test
index 38586ab8b67..51e67a0c956 100644
--- a/mysql-test/t/information_schema_chmod.test
+++ b/mysql-test/t/information_schema_chmod.test
@@ -19,5 +19,5 @@ create database mysqltest;
create table mysqltest.t1(a int);
chmod 0000 $MYSQLTEST_VARDIR/master-data/mysqltest;
select table_schema from information_schema.tables where table_schema='mysqltest';
-exec chmod 0777 $MYSQLTEST_VARDIR/master-data/mysqltest;
+chmod 0777 $MYSQLTEST_VARDIR/master-data/mysqltest;
drop database mysqltest;
diff --git a/mysql-test/t/innodb-deadlock.test b/mysql-test/t/innodb-deadlock.test
index 81acfba5c93..1a184f98771 100644
--- a/mysql-test/t/innodb-deadlock.test
+++ b/mysql-test/t/innodb-deadlock.test
@@ -112,4 +112,29 @@ commit;
drop table t1, t2;
-# End of 4.1 tests
+--echo End of 4.1 tests
+
+#
+# Bug#25164 create table `a` as select * from `A` hangs
+#
+
+set storage_engine=innodb;
+
+--disable_warnings
+drop table if exists a;
+drop table if exists A;
+--enable_warnings
+
+create table A (c int);
+insert into A (c) values (0);
+--error 0,ER_LOCK_DEADLOCK,ER_UPDATE_TABLE_USED
+create table a as select * from A;
+drop table A;
+
+--disable_warnings
+drop table if exists a;
+--enable_warnings
+
+set storage_engine=default;
+
+--echo End of 5.0 tests.
diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test
index adcfec68d3e..aecefda93d3 100644
--- a/mysql-test/t/innodb_mysql.test
+++ b/mysql-test/t/innodb_mysql.test
@@ -881,5 +881,33 @@ insert into t1 values('aaa');
alter table t1 add index(a(1024));
show create table t1;
drop table t1;
+# Bug #28570: handler::index_read() is called with different find_flag when
+# ORDER BY is used
+#
+
+CREATE TABLE t1 (
+ a INT,
+ b INT,
+ KEY (b)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES (1,10), (2,10), (2,20), (3,30);
+
+START TRANSACTION;
+SELECT * FROM t1 WHERE b=20 FOR UPDATE;
+
+--connect (conn2, localhost, root,,test)
+
+# This statement gives a "failed: 1205: Lock wait timeout exceeded; try
+# restarting transaction" message when the bug is present.
+START TRANSACTION;
+SELECT * FROM t1 WHERE b=10 ORDER BY A FOR UPDATE;
+ROLLBACK;
+
+--disconnect conn2
+--connection default
+
+ROLLBACK;
+DROP TABLE t1;
--echo End of 5.0 tests
diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test
index 260e760e7b3..9eb92015399 100644
--- a/mysql-test/t/loaddata.test
+++ b/mysql-test/t/loaddata.test
@@ -43,7 +43,7 @@ delete from t1;
eval load data infile '$MYSQLTEST_VARDIR/tmp/t1' into table t1;
enable_query_log;
select * from t1;
---exec rm $MYSQLTEST_VARDIR/tmp/t1
+remove_file $MYSQLTEST_VARDIR/tmp/t1;
disable_query_log;
eval SELECT * INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/t1'
@@ -54,7 +54,7 @@ eval load data infile '$MYSQLTEST_VARDIR/tmp/t1' into table t1
FIELDS TERMINATED BY '' OPTIONALLY ENCLOSED BY '' LINES TERMINATED BY '\r\n';
enable_query_log;
select * from t1;
---exec rm $MYSQLTEST_VARDIR/tmp/t1
+remove_file $MYSQLTEST_VARDIR/tmp/t1;
SET @@SQL_MODE=@OLD_SQL_MODE;
drop table t1;
@@ -89,17 +89,16 @@ INSERT INTO t1 (c1) VALUES
('.r.'), ('.rr.'), ('.rrr.'), ('.rrrr.');
SELECT * FROM t1;
---exec rm -f $MYSQLTEST_VARDIR/tmp/t1
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval SELECT * INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/t1' FIELDS ENCLOSED BY 'r' FROM t1;
---exec cat $MYSQLTEST_VARDIR/tmp/t1
+cat_file $MYSQLTEST_VARDIR/tmp/t1;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1' INTO TABLE t2 FIELDS ENCLOSED BY 'r';
SELECT t1.id, c1, c2 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE c1 != c2;
SELECT t1.id, c1, c2 FROM t1 RIGHT JOIN t2 ON t1.id=t2.id WHERE c1 != c2;
---exec rm $MYSQLTEST_VARDIR/tmp/t1
+remove_file $MYSQLTEST_VARDIR/tmp/t1;
DROP TABLE t1,t2;
# End of 4.1 tests
@@ -184,7 +183,7 @@ SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE=NO_AUTO_VALUE_ON_ZERO;
eval load data infile '$MYSQLTEST_VARDIR/tmp/t1' into table t2;
enable_query_log;
select * from t2;
---exec rm $MYSQLTEST_VARDIR/tmp/t1
+remove_file $MYSQLTEST_VARDIR/tmp/t1;
SET @@SQL_MODE=@OLD_SQL_MODE;
drop table t1,t2;
@@ -200,7 +199,7 @@ eval select * into outfile '$MYSQLTEST_VARDIR/tmp/t2' from t2;
eval load data infile '$MYSQLTEST_VARDIR/tmp/t2' into table t1;
enable_query_log;
select f1 from t1 where f2 <> '0000-00-00 00:00:00' order by f1;
---exec rm $MYSQLTEST_VARDIR/tmp/t2
+remove_file $MYSQLTEST_VARDIR/tmp/t2;
delete from t1;
disable_query_log;
eval SELECT * INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/t2'
@@ -210,7 +209,7 @@ eval load data infile '$MYSQLTEST_VARDIR/tmp/t2' into table t1
FIELDS TERMINATED BY '' OPTIONALLY ENCLOSED BY '' LINES TERMINATED BY '\r\n';
enable_query_log;
select f1 from t1 where f2 <> '0000-00-00 00:00:00' order by f1;
---exec rm $MYSQLTEST_VARDIR/tmp/t2
+remove_file $MYSQLTEST_VARDIR/tmp/t2;
drop table t1,t2;
#
@@ -223,11 +222,10 @@ CREATE TABLE t1 (c1 INT, c2 TIMESTAMP, c3 REAL, c4 DOUBLE);
INSERT INTO t1 (c1, c2, c3, c4) VALUES (10, '1970-02-01 01:02:03', 1.1E-100, 1.1E+100);
SELECT * FROM t1;
---exec rm -f $MYSQLTEST_VARDIR/tmp/t1
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval SELECT * INTO OUTFILE '$MYSQLTEST_VARDIR/tmp/t1' FIELDS ENCLOSED BY '-' FROM t1;
---exec cat $MYSQLTEST_VARDIR/tmp/t1
---exec echo EOF
+cat_file $MYSQLTEST_VARDIR/tmp/t1;
+echo EOF;
TRUNCATE t1;
@@ -235,7 +233,7 @@ TRUNCATE t1;
eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/t1' INTO TABLE t1 FIELDS ENCLOSED BY '-';
SELECT * FROM t1;
---exec rm $MYSQLTEST_VARDIR/tmp/t1
+remove_file $MYSQLTEST_VARDIR/tmp/t1;
DROP TABLE t1;
# End of 5.0 tests
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index 12b9423be21..d5f403616c8 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -1051,14 +1051,14 @@ eval set storage_engine=$default;
# Test how DROP TABLE works if the index or data file doesn't exists
create table t1 (a int) engine=myisam;
-system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
+remove_file $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
drop table if exists t1;
create table t1 (a int) engine=myisam;
-system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
+remove_file $MYSQLTEST_VARDIR/master-data/test/t1.MYI ;
--error 1051,6
drop table t1;
create table t1 (a int) engine=myisam;
-system rm $MYSQLTEST_VARDIR/master-data/test/t1.MYD ;
+remove_file $MYSQLTEST_VARDIR/master-data/test/t1.MYD ;
--error 1105,6,29
drop table t1;
--error 1051
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index 37bbca77d9f..6e97d0faede 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -241,18 +241,21 @@ DELIMITER /
SELECT 1/
EOF
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug21412.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/bug21412.sql;
# This should give an error...
--write_file $MYSQLTEST_VARDIR/tmp/bug21412.sql
DELIMITER \
EOF
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug21412.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/bug21412.sql;
# As should this...
--write_file $MYSQLTEST_VARDIR/tmp/bug21412.sql
DELIMITER \\
EOF
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug21412.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/bug21412.sql;
#
# Some coverage of not normally used parts
@@ -273,4 +276,9 @@ EOF
--exec $MYSQL --pager="540bytelengthstringxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -e "select 1" > /dev/null 2>&1
--exec $MYSQL --character-sets-dir="540bytelengthstringxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -e "select 1" 2>&1
+#
+# bug #30164: Using client side macro inside server side comments generates broken queries
+#
+--exec $MYSQL test -e "/*! \C latin1 */ select 1;"
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/mysqladmin.test b/mysql-test/t/mysqladmin.test
index 3fa03fa910e..839ecf00b60 100644
--- a/mysql-test/t/mysqladmin.test
+++ b/mysql-test/t/mysqladmin.test
@@ -20,7 +20,7 @@ EOF
--replace_regex /.*mysqladmin.*: unknown/mysqladmin: unknown/
--error 7
--exec $MYSQLADMIN --defaults-file=$MYSQLTEST_VARDIR/tmp/bug10608.cnf -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= ping 2>&1
-
+remove_file $MYSQLTEST_VARDIR/tmp/bug10608.cnf;
# When mysqladmin finds "loose-database" in .cnf file it shall print
# a warning and continue
@@ -32,3 +32,4 @@ EOF
--replace_regex /Warning: .*mysqladmin.*: unknown/Warning: mysqladmin: unknown/
--exec $MYSQLADMIN --defaults-file=$MYSQLTEST_VARDIR/tmp/bug10608.cnf -S $MASTER_MYSOCK -P $MASTER_MYPORT -u root --password= ping 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/bug10608.cnf;
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index b01579dce53..8a38972c00f 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -366,6 +366,7 @@ show status;
EOF
--error 1
--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
#
# Missing delimiter until eof
@@ -377,6 +378,7 @@ sleep 7
EOF
--error 1
--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
#
# Missing delimiter until "disable_query_log"
@@ -391,6 +393,7 @@ disable_query_log;
EOF
--error 1
--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
#
# Missing delimiter until "disable_query_log"
@@ -406,6 +409,7 @@ disable_query_log;
EOF
--error 1
--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
#
# Missing delimiter until eof
@@ -422,6 +426,7 @@ disconnect default
EOF
--error 1
--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
#
# Missing delimiter until eof
@@ -436,6 +441,8 @@ EOF
--error 1
--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
+
#
# Extra delimiter
#
@@ -734,38 +741,40 @@ if (`select length("$var3") > 0`)
# Test to assign let from query
# let $<var_name>=`<query>`;
# ----------------------------------------------------------------------------
---disable_parsing
echo var1;
let $var1= `select "hi" as "Col", 1 as "Column1", "hi there" as Col3`;
echo $var1;
-echo $var1_Col;
-echo $var1_Column1;
-echo $var1_Col3;
echo var2;
let $var2= `select 2 as "Column num 2"`;
echo $var2;
-echo $var2_Column num 2;
-echo $var2_Column;
echo var2 again;
let $var2= `select 2 as "Column num 2"`;
echo $var2;
-echo $var2_Column num 2;
-echo $var2_Column_num_2;
-echo $var2_Column;
echo var3 two columns with same name;
let $var3= `select 1 as "Col", 2 as "Col", 3 as "var3"`;
echo $var3;
-echo $var3_Col;
-echo $var3_Col;
-echo $var3_var3;
-#echo failing query in let;
-#--error 1
-#--exec echo "let $var2= `failing query;`" | $MYSQL_TEST 2>&1
---enable_parsing
+echo var4 from query that returns NULL;
+let $var4= `select NULL`;
+
+echo var5 from query that returns no row;
+let $var5= `SHOW VARIABLES LIKE "nonexisting_variable"`;
+
+echo failing query in let;
+--write_file $MYSQLTEST_VARDIR/tmp/let.sql
+let $var2= `failing query`;
+echo $var2;
+EOF
+
+--error 1
+--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/let.sql 2>&1
+
+remove_file $MYSQLTEST_VARDIR/tmp/let.sql;
+
+
# ----------------------------------------------------------------------------
# Test source command
# ----------------------------------------------------------------------------
@@ -786,6 +795,7 @@ echo $var3_var3;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error 1
--exec echo "source $MYSQLTEST_VARDIR/tmp/recursive.sql;" | $MYSQL_TEST 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/recursive.sql;
# Source a file with error
--exec echo "garbage ;" > $MYSQLTEST_VARDIR/tmp/error.sql
@@ -793,6 +803,7 @@ echo $var3_var3;
--error 1
--exec echo "source $MYSQLTEST_VARDIR/tmp/error.sql;" | $MYSQL_TEST 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/error.sql;
# Test execution of source in a while loop
--write_file $MYSQLTEST_VARDIR/tmp/sourced.inc
@@ -843,6 +854,19 @@ while ($num)
--remove_file $MYSQLTEST_VARDIR/tmp/sourced.inc
+--write_file $MYSQLTEST_VARDIR/tmp/sourced.inc
+echo "hello";
+EOF
+
+let $x= sourced;
+source $MYSQLTEST_VARDIR/tmp/$x.inc;
+
+let $x= $MYSQLTEST_VARDIR;
+source $x/tmp/sourced.inc;
+
+--remove_file $MYSQLTEST_VARDIR/tmp/sourced.inc
+
+
# ----------------------------------------------------------------------------
# Test sleep command
# ----------------------------------------------------------------------------
@@ -963,7 +987,7 @@ if (!$counter)
echo Counter is not 0, (counter=10);
}
let $counter=0;
-if ($counter)
+if($counter)
{
echo Counter is greater than 0, (counter=0);
}
@@ -1156,6 +1180,7 @@ echo hej;
EOF
--error 1
--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
while (0)
@@ -1163,6 +1188,7 @@ while (0)
EOF
--error 1
--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
while (0){
@@ -1171,6 +1197,8 @@ EOF
--error 1
--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
+
# ----------------------------------------------------------------------------
# Test error messages returned from comments starting with a command
# ----------------------------------------------------------------------------
@@ -1262,6 +1290,7 @@ while ($i)
}
EOF
--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql; echo OK;" | $MYSQL_TEST 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
# Repeat connect/disconnect
--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
@@ -1276,6 +1305,7 @@ EOF
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error 1
--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql;" | $MYSQL_TEST 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
# Select disconnected connection
--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
@@ -1286,6 +1316,7 @@ EOF
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error 1
--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql;" | $MYSQL_TEST 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
# Connection name already used
--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
@@ -1296,6 +1327,8 @@ EOF
--error 1
--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql;" | $MYSQL_TEST 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
+
# connect when "disable_abort_on_error" caused "connection not found"
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
--disable_abort_on_error
@@ -1399,7 +1432,11 @@ select "this will be executed";
--exec touch $MYSQLTEST_VARDIR/tmp/zero_length_file.result
--exec echo "echo ok;" > $MYSQLTEST_VARDIR/tmp/query.sql
--error 1
---exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/query.sql -R $MYSQLTEST_VARDIR/tmp/zero_length_file.result 2>&1
+--exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/query.sql -R $MYSQLTEST_VARDIR/tmp/zero_length_file.result > /dev/null 2>&1
+
+remove_file $MYSQLTEST_VARDIR/tmp/zero_length_file.result;
+remove_file $MYSQLTEST_VARDIR/log/zero_length_file.reject;
+
#
# Test that a test file that does not generate any output fails.
#
@@ -1407,6 +1444,8 @@ select "this will be executed";
--error 1
--exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/query.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/query.sql;
+
#
# Test that mysqltest fails when there are no queries executed
# but a result file exists
@@ -1436,6 +1475,7 @@ echo Failing multi statement query;
--exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/bug11731.sql 2>&1
drop table t1;
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--error 1
--exec $MYSQL_TEST --record -x $MYSQLTEST_VARDIR/tmp/bug11731.sql -R $MYSQLTEST_VARDIR/tmp/bug11731.out 2>&1
# The .out file should be non existent
@@ -1462,6 +1502,9 @@ drop table t1;
# The .out file should exist
--exec test -s $MYSQLTEST_VARDIR/tmp/bug11731.out
drop table t1;
+remove_file $MYSQLTEST_VARDIR/tmp/bug11731.out;
+remove_file $MYSQLTEST_VARDIR/log/bug11731.log;
+remove_file $MYSQLTEST_VARDIR/tmp/bug11731.sql;
#
# Bug#19890 mysqltest: "query" command is broken
@@ -1544,12 +1587,19 @@ write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
Content for test_file1
EOF
file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+cat_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp END_DELIMITER;
Content for test_file1 contains EOF
END_DELIMITER
file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+
+# write to already exisiting file
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+--error 1
+--exec echo "write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;" | $MYSQL_TEST 2>&1
+
remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
# ----------------------------------------------------------------------------
@@ -1571,6 +1621,8 @@ append_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
Appended text on nonexisting file
EOF
+remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+
# ----------------------------------------------------------------------------
# test for cat_file
# ----------------------------------------------------------------------------
@@ -1581,6 +1633,7 @@ for cat_file command
of mysqltest
EOF
cat_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
+remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp;
--error 1
--exec echo "cat_file non_existing_file;" | $MYSQL_TEST 2>&1
@@ -1607,19 +1660,48 @@ for diff_file command
of mysqltest
EOF
+--write_file $MYSQLTEST_VARDIR/tmp/diff4.tmp
+Some data
+for diff_file command
+of musqltest
+EOF
+
# Compare equal files
--diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff2.tmp
--diff_files $MYSQLTEST_VARDIR/tmp/diff2.tmp $MYSQLTEST_VARDIR/tmp/diff1.tmp
-# Compare files that differ
+# Write the below commands to a intermediary file and execute them with
+# mysqltest in --exec, since the output will vary depending on what "diff"
+# is available it is sent to /dev/null
+--write_file $MYSQLTEST_VARDIR/tmp/diff.test
+# Compare files that differ in size
+--error 2
+--diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff3.tmp
+--error 2
+--diff_files $MYSQLTEST_VARDIR/tmp/diff3.tmp $MYSQLTEST_VARDIR/tmp/diff1.tmp
+
+# Compare files that differ only in content
--error 1
---diff_files $MYSQLTEST_VARDIR/tmp/diff3.tmp $MYSQLTEST_VARDIR/tmp/diff2.tmp
+--diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff4.tmp
--error 1
---diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff3.tmp
+--diff_files $MYSQLTEST_VARDIR/tmp/diff4.tmp $MYSQLTEST_VARDIR/tmp/diff1.tmp
+EOF
+
+# Execute the above diffs, and send their output to /dev/null - only
+# interesting to see that it returns correct error codes
+--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/diff.test > /dev/null 2>&1
+
# Compare equal files, again...
--diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff2.tmp
+--remove_file $MYSQLTEST_VARDIR/tmp/diff1.tmp
+--remove_file $MYSQLTEST_VARDIR/tmp/diff2.tmp
+--remove_file $MYSQLTEST_VARDIR/tmp/diff3.tmp
+--remove_file $MYSQLTEST_VARDIR/tmp/diff4.tmp
+--remove_file $MYSQLTEST_VARDIR/tmp/diff.test
+
+
# ----------------------------------------------------------------------------
# test for file_exist
# ----------------------------------------------------------------------------
@@ -1672,6 +1754,7 @@ chmod 0000 $MYSQLTEST_VARDIR/tmp/file1.tmp;
#EOF
chmod 0777 $MYSQLTEST_VARDIR/tmp/file1.tmp;
+remove_file $MYSQLTEST_VARDIR/tmp/file1.tmp;
--write_file $MYSQLTEST_VARDIR/tmp/file1.tmp
test2
EOF
diff --git a/mysql-test/t/parser_precedence.test b/mysql-test/t/parser_precedence.test
new file mode 100644
index 00000000000..484c8759779
--- /dev/null
+++ b/mysql-test/t/parser_precedence.test
@@ -0,0 +1,333 @@
+
+--disable_warnings
+drop table if exists t1_30237_bool;
+--enable_warnings
+
+create table t1_30237_bool(A boolean, B boolean, C boolean);
+
+insert into t1_30237_bool values
+(FALSE, FALSE, FALSE),
+(FALSE, FALSE, NULL),
+(FALSE, FALSE, TRUE),
+(FALSE, NULL, FALSE),
+(FALSE, NULL, NULL),
+(FALSE, NULL, TRUE),
+(FALSE, TRUE, FALSE),
+(FALSE, TRUE, NULL),
+(FALSE, TRUE, TRUE),
+(NULL, FALSE, FALSE),
+(NULL, FALSE, NULL),
+(NULL, FALSE, TRUE),
+(NULL, NULL, FALSE),
+(NULL, NULL, NULL),
+(NULL, NULL, TRUE),
+(NULL, TRUE, FALSE),
+(NULL, TRUE, NULL),
+(NULL, TRUE, TRUE),
+(TRUE, FALSE, FALSE),
+(TRUE, FALSE, NULL),
+(TRUE, FALSE, TRUE),
+(TRUE, NULL, FALSE),
+(TRUE, NULL, NULL),
+(TRUE, NULL, TRUE),
+(TRUE, TRUE, FALSE),
+(TRUE, TRUE, NULL),
+(TRUE, TRUE, TRUE) ;
+
+--echo Testing OR, XOR, AND
+select A, B, A OR B, A XOR B, A AND B
+ from t1_30237_bool where C is null order by A, B;
+
+--echo Testing that OR is associative
+select A, B, C, (A OR B) OR C, A OR (B OR C), A OR B OR C
+ from t1_30237_bool order by A, B, C;
+
+select count(*) from t1_30237_bool
+ where ((A OR B) OR C) != (A OR (B OR C));
+
+--echo Testing that XOR is associative
+select A, B, C, (A XOR B) XOR C, A XOR (B XOR C), A XOR B XOR C
+ from t1_30237_bool order by A, B, C;
+
+select count(*) from t1_30237_bool
+ where ((A XOR B) XOR C) != (A XOR (B XOR C));
+
+--echo Testing that AND is associative
+select A, B, C, (A AND B) AND C, A AND (B AND C), A AND B AND C
+ from t1_30237_bool order by A, B, C;
+
+select count(*) from t1_30237_bool
+ where ((A AND B) AND C) != (A AND (B AND C));
+
+--echo Testing that AND has precedence over OR
+select A, B, C, (A OR B) AND C, A OR (B AND C), A OR B AND C
+ from t1_30237_bool order by A, B, C;
+select count(*) from t1_30237_bool
+ where (A OR (B AND C)) != (A OR B AND C);
+select A, B, C, (A AND B) OR C, A AND (B OR C), A AND B OR C
+ from t1_30237_bool order by A, B, C;
+select count(*) from t1_30237_bool
+ where ((A AND B) OR C) != (A AND B OR C);
+
+--echo Testing that AND has precedence over XOR
+select A, B, C, (A XOR B) AND C, A XOR (B AND C), A XOR B AND C
+ from t1_30237_bool order by A, B, C;
+select count(*) from t1_30237_bool
+ where (A XOR (B AND C)) != (A XOR B AND C);
+select A, B, C, (A AND B) XOR C, A AND (B XOR C), A AND B XOR C
+ from t1_30237_bool order by A, B, C;
+select count(*) from t1_30237_bool
+ where ((A AND B) XOR C) != (A AND B XOR C);
+
+--echo Testing that XOR has precedence over OR
+select A, B, C, (A XOR B) OR C, A XOR (B OR C), A XOR B OR C
+ from t1_30237_bool order by A, B, C;
+select count(*) from t1_30237_bool
+ where ((A XOR B) OR C) != (A XOR B OR C);
+select A, B, C, (A OR B) XOR C, A OR (B XOR C), A OR B XOR C
+ from t1_30237_bool order by A, B, C;
+select count(*) from t1_30237_bool
+ where (A OR (B XOR C)) != (A OR B XOR C);
+
+drop table t1_30237_bool;
+
+--echo Testing that NOT has precedence over OR
+select (NOT FALSE) OR TRUE, NOT (FALSE OR TRUE), NOT FALSE OR TRUE;
+
+--echo Testing that NOT has precedence over XOR
+select (NOT FALSE) XOR FALSE, NOT (FALSE XOR FALSE), NOT FALSE XOR FALSE;
+
+--echo Testing that NOT has precedence over AND
+select (NOT FALSE) AND FALSE, NOT (FALSE AND FALSE), NOT FALSE AND FALSE;
+
+--echo Testing that NOT is associative
+select NOT NOT TRUE, NOT NOT NOT FALSE;
+
+--echo Testing that IS has precedence over NOT
+select (NOT NULL) IS TRUE, NOT (NULL IS TRUE), NOT NULL IS TRUE;
+select (NOT NULL) IS NOT TRUE, NOT (NULL IS NOT TRUE), NOT NULL IS NOT TRUE;
+select (NOT NULL) IS FALSE, NOT (NULL IS FALSE), NOT NULL IS FALSE;
+select (NOT NULL) IS NOT FALSE, NOT (NULL IS NOT FALSE), NOT NULL IS NOT FALSE;
+select (NOT TRUE) IS UNKNOWN, NOT (TRUE IS UNKNOWN), NOT TRUE IS UNKNOWN;
+select (NOT TRUE) IS NOT UNKNOWN, NOT (TRUE IS NOT UNKNOWN), NOT TRUE IS NOT UNKNOWN;
+select (NOT TRUE) IS NULL, NOT (TRUE IS NULL), NOT TRUE IS NULL;
+select (NOT TRUE) IS NOT NULL, NOT (TRUE IS NOT NULL), NOT TRUE IS NOT NULL;
+
+--echo Testing that IS [NOT] TRUE/FALSE/UNKNOWN predicates are not associative
+# Documenting existing behavior in 5.0.48
+-- error ER_PARSE_ERROR
+select TRUE IS TRUE IS TRUE IS TRUE;
+-- error ER_PARSE_ERROR
+select FALSE IS NOT TRUE IS NOT TRUE IS NOT TRUE;
+-- error ER_PARSE_ERROR
+select NULL IS FALSE IS FALSE IS FALSE;
+-- error ER_PARSE_ERROR
+select TRUE IS NOT FALSE IS NOT FALSE IS NOT FALSE;
+-- error ER_PARSE_ERROR
+select FALSE IS UNKNOWN IS UNKNOWN IS UNKNOWN;
+-- error ER_PARSE_ERROR
+select TRUE IS NOT UNKNOWN IS NOT UNKNOWN IS NOT UNKNOWN;
+
+--echo Testing that IS [NOT] NULL predicates are associative
+# Documenting existing behavior in 5.0.48
+select FALSE IS NULL IS NULL IS NULL;
+select TRUE IS NOT NULL IS NOT NULL IS NOT NULL;
+
+--echo Testing that comparison operators are left associative
+select 1 <=> 2 <=> 2, (1 <=> 2) <=> 2, 1 <=> (2 <=> 2);
+select 1 = 2 = 2, (1 = 2) = 2, 1 = (2 = 2);
+select 1 != 2 != 3, (1 != 2) != 3, 1 != (2 != 3);
+select 1 <> 2 <> 3, (1 <> 2) <> 3, 1 <> (2 <> 3);
+select 1 < 2 < 3, (1 < 2) < 3, 1 < (2 < 3);
+select 3 <= 2 <= 1, (3 <= 2) <= 1, 3 <= (2 <= 1);
+select 1 > 2 > 3, (1 > 2) > 3, 1 > (2 > 3);
+select 1 >= 2 >= 3, (1 >= 2) >= 3, 1 >= (2 >= 3);
+
+-- echo Testing that | is associative
+select 0xF0 | 0x0F | 0x55, (0xF0 | 0x0F) | 0x55, 0xF0 | (0x0F | 0x55);
+
+-- echo Testing that & is associative
+select 0xF5 & 0x5F & 0x55, (0xF5 & 0x5F) & 0x55, 0xF5 & (0x5F & 0x55);
+
+-- echo Testing that << is left associative
+select 4 << 3 << 2, (4 << 3) << 2, 4 << (3 << 2);
+
+-- echo Testing that >> is left associative
+select 256 >> 3 >> 2, (256 >> 3) >> 2, 256 >> (3 >> 2);
+
+--echo Testing that & has precedence over |
+select 0xF0 & 0x0F | 0x55, (0xF0 & 0x0F) | 0x55, 0xF0 & (0x0F | 0x55);
+select 0x55 | 0xF0 & 0x0F, (0x55 | 0xF0) & 0x0F, 0x55 | (0xF0 & 0x0F);
+
+--echo Testing that << has precedence over |
+select 0x0F << 4 | 0x0F, (0x0F << 4) | 0x0F, 0x0F << (4 | 0x0F);
+select 0x0F | 0x0F << 4, (0x0F | 0x0F) << 4, 0x0F | (0x0F << 4);
+
+--echo Testing that >> has precedence over |
+select 0xF0 >> 4 | 0xFF, (0xF0 >> 4) | 0xFF, 0xF0 >> (4 | 0xFF);
+select 0xFF | 0xF0 >> 4, (0xFF | 0xF0) >> 4, 0xFF | (0xF0 >> 4);
+
+--echo Testing that << has precedence over &
+select 0x0F << 4 & 0xF0, (0x0F << 4) & 0xF0, 0x0F << (4 & 0xF0);
+select 0xF0 & 0x0F << 4, (0xF0 & 0x0F) << 4, 0xF0 & (0x0F << 4);
+
+--echo Testing that >> has precedence over &
+select 0xF0 >> 4 & 0x55, (0xF0 >> 4) & 0x55, 0xF0 >> (4 & 0x55);
+select 0x0F & 0xF0 >> 4, (0x0F & 0xF0) >> 4, 0x0F & (0xF0 >> 4);
+
+--echo Testing that >> and << have the same precedence
+select 0xFF >> 4 << 2, (0xFF >> 4) << 2, 0xFF >> (4 << 2);
+select 0x0F << 4 >> 2, (0x0F << 4) >> 2, 0x0F << (4 >> 2);
+
+--echo Testing that binary + is associative
+select 1 + 2 + 3, (1 + 2) + 3, 1 + (2 + 3);
+
+--echo Testing that binary - is left associative
+select 1 - 2 - 3, (1 - 2) - 3, 1 - (2 - 3);
+
+--echo Testing that binary + and binary - have the same precedence
+# evaluated left to right
+select 1 + 2 - 3, (1 + 2) - 3, 1 + (2 - 3);
+select 1 - 2 + 3, (1 - 2) + 3, 1 - (2 + 3);
+
+--echo Testing that binary + has precedence over |
+select 0xF0 + 0x0F | 0x55, (0xF0 + 0x0F) | 0x55, 0xF0 + (0x0F | 0x55);
+select 0x55 | 0xF0 + 0x0F, (0x55 | 0xF0) + 0x0F, 0x55 | (0xF0 + 0x0F);
+
+--echo Testing that binary + has precedence over &
+select 0xF0 + 0x0F & 0x55, (0xF0 + 0x0F) & 0x55, 0xF0 + (0x0F & 0x55);
+select 0x55 & 0xF0 + 0x0F, (0x55 & 0xF0) + 0x0F, 0x55 & (0xF0 + 0x0F);
+
+--echo Testing that binary + has precedence over <<
+select 2 + 3 << 4, (2 + 3) << 4, 2 + (3 << 4);
+select 3 << 4 + 2, (3 << 4) + 2, 3 << (4 + 2);
+
+--echo Testing that binary + has precedence over >>
+select 4 + 3 >> 2, (4 + 3) >> 2, 4 + (3 >> 2);
+select 3 >> 2 + 1, (3 >> 2) + 1, 3 >> (2 + 1);
+
+--echo Testing that binary - has precedence over |
+select 0xFF - 0x0F | 0x55, (0xFF - 0x0F) | 0x55, 0xFF - (0x0F | 0x55);
+select 0x55 | 0xFF - 0xF0, (0x55 | 0xFF) - 0xF0, 0x55 | (0xFF - 0xF0);
+
+--echo Testing that binary - has precedence over &
+select 0xFF - 0xF0 & 0x55, (0xFF - 0xF0) & 0x55, 0xFF - (0xF0 & 0x55);
+select 0x55 & 0xFF - 0xF0, (0x55 & 0xFF) - 0xF0, 0x55 & (0xFF - 0xF0);
+
+--echo Testing that binary - has precedence over <<
+select 16 - 3 << 2, (16 - 3) << 2, 16 - (3 << 2);
+select 4 << 3 - 2, (4 << 3) - 2, 4 << (3 - 2);
+
+--echo Testing that binary - has precedence over >>
+select 16 - 3 >> 2, (16 - 3) >> 2, 16 - (3 >> 2);
+select 16 >> 3 - 2, (16 >> 3) - 2, 16 >> (3 - 2);
+
+--echo Testing that * is associative
+select 2 * 3 * 4, (2 * 3) * 4, 2 * (3 * 4);
+
+--echo Testing that * has precedence over |
+select 2 * 0x40 | 0x0F, (2 * 0x40) | 0x0F, 2 * (0x40 | 0x0F);
+select 0x0F | 2 * 0x40, (0x0F | 2) * 0x40, 0x0F | (2 * 0x40);
+
+--echo Testing that * has precedence over &
+select 2 * 0x40 & 0x55, (2 * 0x40) & 0x55, 2 * (0x40 & 0x55);
+select 0xF0 & 2 * 0x40, (0xF0 & 2) * 0x40, 0xF0 & (2 * 0x40);
+
+--echo Testing that * has precedence over <<
+# Actually, can't prove it for the first case,
+# since << is a multiplication by a power of 2,
+# and * is associative
+select 5 * 3 << 4, (5 * 3) << 4, 5 * (3 << 4);
+select 2 << 3 * 4, (2 << 3) * 4, 2 << (3 * 4);
+
+--echo Testing that * has precedence over >>
+# >> is a multiplication by a (negative) power of 2,
+# see above.
+select 3 * 4 >> 2, (3 * 4) >> 2, 3 * (4 >> 2);
+select 4 >> 2 * 3, (4 >> 2) * 3, 4 >> (2 * 3);
+
+--echo Testing that * has precedence over binary +
+select 2 * 3 + 4, (2 * 3) + 4, 2 * (3 + 4);
+select 2 + 3 * 4, (2 + 3) * 4, 2 + (3 * 4);
+
+--echo Testing that * has precedence over binary -
+select 4 * 3 - 2, (4 * 3) - 2, 4 * (3 - 2);
+select 4 - 3 * 2, (4 - 3) * 2, 4 - (3 * 2);
+
+--echo Testing that / is left associative
+select 15 / 5 / 3, (15 / 5) / 3, 15 / (5 / 3);
+
+--echo Testing that / has precedence over |
+select 105 / 5 | 2, (105 / 5) | 2, 105 / (5 | 2);
+select 105 | 2 / 5, (105 | 2) / 5, 105 | (2 / 5);
+
+--echo Testing that / has precedence over &
+select 105 / 5 & 0x0F, (105 / 5) & 0x0F, 105 / (5 & 0x0F);
+select 0x0F & 105 / 5, (0x0F & 105) / 5, 0x0F & (105 / 5);
+
+--echo Testing that / has precedence over <<
+select 0x80 / 4 << 2, (0x80 / 4) << 2, 0x80 / (4 << 2);
+select 0x80 << 4 / 2, (0x80 << 4) / 2, 0x80 << (4 / 2);
+
+--echo Testing that / has precedence over >>
+select 0x80 / 4 >> 2, (0x80 / 4) >> 2, 0x80 / (4 >> 2);
+select 0x80 >> 4 / 2, (0x80 >> 4) / 2, 0x80 >> (4 / 2);
+
+--echo Testing that / has precedence over binary +
+select 0x80 / 2 + 2, (0x80 / 2) + 2, 0x80 / (2 + 2);
+select 0x80 + 2 / 2, (0x80 + 2) / 2, 0x80 + (2 / 2);
+
+--echo Testing that / has precedence over binary -
+select 0x80 / 4 - 2, (0x80 / 4) - 2, 0x80 / (4 - 2);
+select 0x80 - 4 / 2, (0x80 - 4) / 2, 0x80 - (4 / 2);
+
+# TODO: %, DIV, MOD
+
+--echo Testing that ^ is associative
+select 0xFF ^ 0xF0 ^ 0x0F, (0xFF ^ 0xF0) ^ 0x0F, 0xFF ^ (0xF0 ^ 0x0F);
+select 0xFF ^ 0xF0 ^ 0x55, (0xFF ^ 0xF0) ^ 0x55, 0xFF ^ (0xF0 ^ 0x55);
+
+--echo Testing that ^ has precedence over |
+select 0xFF ^ 0xF0 | 0x0F, (0xFF ^ 0xF0) | 0x0F, 0xFF ^ (0xF0 | 0x0F);
+select 0xF0 | 0xFF ^ 0xF0, (0xF0 | 0xFF) ^ 0xF0, 0xF0 | (0xFF ^ 0xF0);
+
+--echo Testing that ^ has precedence over &
+select 0xFF ^ 0xF0 & 0x0F, (0xFF ^ 0xF0) & 0x0F, 0xFF ^ (0xF0 & 0x0F);
+select 0x0F & 0xFF ^ 0xF0, (0x0F & 0xFF) ^ 0xF0, 0x0F & (0xFF ^ 0xF0);
+
+--echo Testing that ^ has precedence over <<
+select 0xFF ^ 0xF0 << 2, (0xFF ^ 0xF0) << 2, 0xFF ^ (0xF0 << 2);
+select 0x0F << 2 ^ 0xFF, (0x0F << 2) ^ 0xFF, 0x0F << (2 ^ 0xFF);
+
+--echo Testing that ^ has precedence over >>
+select 0xFF ^ 0xF0 >> 2, (0xFF ^ 0xF0) >> 2, 0xFF ^ (0xF0 >> 2);
+select 0xFF >> 2 ^ 0xF0, (0xFF >> 2) ^ 0xF0, 0xFF >> (2 ^ 0xF0);
+
+--echo Testing that ^ has precedence over binary +
+select 0xFF ^ 0xF0 + 0x0F, (0xFF ^ 0xF0) + 0x0F, 0xFF ^ (0xF0 + 0x0F);
+select 0x0F + 0xFF ^ 0xF0, (0x0F + 0xFF) ^ 0xF0, 0x0F + (0xFF ^ 0xF0);
+
+--echo Testing that ^ has precedence over binary -
+select 0xFF ^ 0xF0 - 1, (0xFF ^ 0xF0) - 1, 0xFF ^ (0xF0 - 1);
+select 0x55 - 0x0F ^ 0x55, (0x55 - 0x0F) ^ 0x55, 0x55 - (0x0F ^ 0x55);
+
+--echo Testing that ^ has precedence over *
+select 0xFF ^ 0xF0 * 2, (0xFF ^ 0xF0) * 2, 0xFF ^ (0xF0 * 2);
+select 2 * 0xFF ^ 0xF0, (2 * 0xFF) ^ 0xF0, 2 * (0xFF ^ 0xF0);
+
+--echo Testing that ^ has precedence over /
+select 0xFF ^ 0xF0 / 2, (0xFF ^ 0xF0) / 2, 0xFF ^ (0xF0 / 2);
+select 0xF2 / 2 ^ 0xF0, (0xF2 / 2) ^ 0xF0, 0xF2 / (2 ^ 0xF0);
+
+--echo Testing that ^ has precedence over %
+select 0xFF ^ 0xF0 % 0x20, (0xFF ^ 0xF0) % 0x20, 0xFF ^ (0xF0 % 0x20);
+select 0xFF % 0x20 ^ 0xF0, (0xFF % 0x20) ^ 0xF0, 0xFF % (0x20 ^ 0xF0);
+
+--echo Testing that ^ has precedence over DIV
+select 0xFF ^ 0xF0 DIV 2, (0xFF ^ 0xF0) DIV 2, 0xFF ^ (0xF0 DIV 2);
+select 0xF2 DIV 2 ^ 0xF0, (0xF2 DIV 2) ^ 0xF0, 0xF2 DIV (2 ^ 0xF0);
+
+--echo Testing that ^ has precedence over MOD
+select 0xFF ^ 0xF0 MOD 0x20, (0xFF ^ 0xF0) MOD 0x20, 0xFF ^ (0xF0 MOD 0x20);
+select 0xFF MOD 0x20 ^ 0xF0, (0xFF MOD 0x20) ^ 0xF0, 0xFF MOD (0x20 ^ 0xF0);
+
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 93a89c2b275..cd2fc44e3ce 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -1168,9 +1168,6 @@ deallocate prepare stmt2;
#
# CREATE TABLE with DATA DIRECTORY option
#
-# Protect ourselves from data left in tmp/ by a previos possibly failed
-# test
---system rm -f $MYSQLTEST_VARDIR/tmp/t1.*
--disable_warnings
--disable_query_log
eval prepare stmt from "create table t1 (c char(10)) data directory='$MYSQLTEST_VARDIR/tmp'";
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index 3091284d061..44b63df9739 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -1220,9 +1220,40 @@ connection default;
disconnect user1;
disconnect user2;
disconnect user3;
+
+#
+# Bug #30269 Query cache eats memory
+#
+--disable_warnings
+DROP DATABASE IF EXISTS bug30269;
+--enable_warnings
+FLUSH STATUS;
+CREATE DATABASE bug30269;
+USE bug30269;
+CREATE TABLE test1 (id int, name varchar(23));
+CREATE VIEW view1 AS SELECT * FROM test1;
+INSERT INTO test1 VALUES (5, 'testit');
+GRANT SELECT (id) ON TABLE bug30269.test1 TO 'bug30269'@'localhost';
+GRANT SELECT ON TABLE bug30269.view1 TO 'bug30269'@'localhost';
+set global query_cache_size= 81920;
+connect (bug30269, localhost, bug30269,,);
+connection bug30269;
+USE bug30269;
+show status like 'Qcache_queries_in_cache';
+--echo # Select statement not stored in query cache because of column privileges.
+SELECT id FROM test1 WHERE id>2;
+show status like 'Qcache_queries_in_cache';
+SELECT id FROM view1 WHERE id>2;
+show status like 'Qcache_queries_in_cache';
+
+connection default;
+DROP DATABASE bug30269;
+disconnect bug30269;
+DROP USER 'bug30269'@'localhost';
+
set GLOBAL query_cache_type=default;
set GLOBAL query_cache_limit=default;
set GLOBAL query_cache_min_res_unit=default;
set GLOBAL query_cache_size=default;
-# End of 5.0 tests
+# End of 5.0 tests
diff --git a/mysql-test/t/view_query_cache.test b/mysql-test/t/query_cache_with_views.test
index d4ebe45b7ac..d4ebe45b7ac 100644
--- a/mysql-test/t/view_query_cache.test
+++ b/mysql-test/t/query_cache_with_views.test
diff --git a/mysql-test/t/rpl_relayspace.test b/mysql-test/t/rpl_relayspace.test
index 70315c14f34..d4ef2fe59bd 100644
--- a/mysql-test/t/rpl_relayspace.test
+++ b/mysql-test/t/rpl_relayspace.test
@@ -14,6 +14,22 @@ connection slave;
reset slave;
start slave io_thread;
# Give the I/O thread time to block.
+let $run= 1;
+let $counter= 300;
+while ($run)
+{
+ let $io_state= query_get_value("SHOW SLAVE STATUS", Slave_IO_State, 1);
+ if (`SELECT '$io_state' = 'Waiting for the slave SQL thread to free enough relay log space'`){
+ let $run= 0;
+ }
+ sleep 0.1;
+ if (!$counter){
+ --echo "Failed while waiting for slave IO thread block"
+ SHOW SLAVE STATUS;
+ exit;
+ }
+ dec $counter;
+}
sleep 2;
# A bug caused the I/O thread to refuse stopping.
stop slave io_thread;
diff --git a/mysql-test/t/rpl_ssl.test b/mysql-test/t/rpl_ssl.test
index d08004cb00b..bf4dcbf8af0 100644
--- a/mysql-test/t/rpl_ssl.test
+++ b/mysql-test/t/rpl_ssl.test
@@ -41,24 +41,39 @@ select * from t1;
# Do the same thing a number of times
disable_query_log;
+disable_result_log;
let $i= 100;
while ($i)
{
start slave;
connection master;
insert into t1 values (NULL);
+ select * from t1; # Some variance
connection slave;
+ select * from t1; # Some variance
stop slave;
dec $i;
}
start slave;
enable_query_log;
+enable_result_log;
connection master;
insert into t1 values (NULL);
+let $master_count= `select count(*) from t1`;
+
sync_slave_with_master;
--source include/wait_for_slave_to_start.inc
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 #
query_vertical show slave status;
+let $slave_count= `select count(*) from t1`;
+
+if (`select $slave_count != $master_count`)
+{
+ echo master and slave differed in number of rows;
+ echo master: $master_count;
+ echo slave: $slave_count;
+}
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/rpl_timezone.test b/mysql-test/t/rpl_timezone.test
index 6ed5b21ace0..28ca250340e 100644
--- a/mysql-test/t/rpl_timezone.test
+++ b/mysql-test/t/rpl_timezone.test
@@ -126,8 +126,33 @@ connection master;
drop table t1, t2;
sync_slave_with_master;
-# End of 4.1 tests
-
# Restore original timezone
connection master;
set global time_zone= @my_time_zone;
+
+--echo End of 4.1 tests
+
+#
+# Bug #29536: timestamp inconsistent in replication around 1970
+#
+connection master;
+
+CREATE TABLE t1 (a INT, b TIMESTAMP);
+INSERT INTO t1 VALUES (1, NOW());
+
+SET @@session.time_zone='Japan';
+UPDATE t1 SET b= '1970-01-01 08:59:59' WHERE a= 1;
+SELECT * FROM t1 ORDER BY a;
+
+sync_slave_with_master;
+SET @@session.time_zone='Japan';
+# must procdure the same result as the SELECT on the master
+SELECT * FROM t1 ORDER BY a;
+
+SET @@session.time_zone = default;
+connection master;
+DROP TABLE t1;
+SET @@session.time_zone = default;
+
+
+--echo End of 5.0 tests
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 56b2f1b02b8..abf55745080 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -3370,4 +3370,94 @@ EXPLAIN SELECT COUNT(*) FROM t1 f1 INNER JOIN t1 f2
WHERE 1 AND f1.b NOT IN (100,2232,3343,51111);
DROP TABLE t1;
+#
+# Bug #27352: Incorrect result of nested selects instead of error reporting
+#
+
+CREATE TABLE t1 (c1 INT, c2 INT);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+
+let $n= 31;
+let $q= COUNT(c2);
+while ($n)
+{
+ let $q= (SELECT $q);
+ dec $n;
+}
+--disable_warnings
+eval EXPLAIN SELECT c1 FROM t1 WHERE $q > 0;
+--enable_warnings
+
+let $n= 64;
+let $q= COUNT(c2);
+while ($n)
+{
+ let $q= (SELECT $q);
+ dec $n;
+}
+--error ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT
+eval EXPLAIN SELECT c1 FROM t1 WHERE $q > 0;
+
+DROP TABLE t1;
+
+#
+# Bug #30396: crash for a join with equalities and sargable predicates
+# in disjunctive parts of the WHERE condition
+#
+
+CREATE TABLE t1 (
+ c1 int(11) NOT NULL AUTO_INCREMENT,
+ c2 varchar(1000) DEFAULT NULL,
+ c3 bigint(20) DEFAULT NULL,
+ c4 bigint(20) DEFAULT NULL,
+ PRIMARY KEY (c1)
+);
+
+EXPLAIN EXTENDED
+SELECT join_2.c1
+FROM
+ t1 AS join_0,
+ t1 AS join_1,
+ t1 AS join_2,
+ t1 AS join_3,
+ t1 AS join_4,
+ t1 AS join_5,
+ t1 AS join_6,
+ t1 AS join_7
+WHERE
+ join_0.c1=join_1.c1 AND
+ join_1.c1=join_2.c1 AND
+ join_2.c1=join_3.c1 AND
+ join_3.c1=join_4.c1 AND
+ join_4.c1=join_5.c1 AND
+ join_5.c1=join_6.c1 AND
+ join_6.c1=join_7.c1
+ OR
+ join_0.c2 < '?' AND
+ join_1.c2 < '?' AND
+ join_2.c2 > '?' AND
+ join_2.c2 < '!' AND
+ join_3.c2 > '?' AND
+ join_4.c2 = '?' AND
+ join_5.c2 <> '?' AND
+ join_6.c2 <> '?' AND
+ join_7.c2 >= '?' AND
+ join_0.c1=join_1.c1 AND
+ join_1.c1=join_2.c1 AND
+ join_2.c1=join_3.c1 AND
+ join_3.c1=join_4.c1 AND
+ join_4.c1=join_5.c1 AND
+ join_5.c1=join_6.c1 AND
+ join_6.c1=join_7.c1
+GROUP BY
+ join_3.c1,
+ join_2.c1,
+ join_7.c1,
+ join_1.c1,
+ join_0.c1;
+
+SHOW WARNINGS;
+
+DROP TABLE t1;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/sp-destruct.test b/mysql-test/t/sp-destruct.test
index 13ddaa43fad..c568e6bb8f4 100644
--- a/mysql-test/t/sp-destruct.test
+++ b/mysql-test/t/sp-destruct.test
@@ -42,6 +42,7 @@ insert into t1 values (0);
flush table mysql.proc;
# Thrashing the .frm file
+--remove_file $MYSQLTEST_VARDIR/master-data/mysql/proc.frm
--write_file $MYSQLTEST_VARDIR/master-data/mysql/proc.frm
saljdfa
EOF
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 46a1b1dc740..8dd99c2b2f1 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -6715,6 +6715,7 @@ SELECT bug23760_rc_test(ROW_COUNT())|
DROP TABLE bug23760, bug23760_log|
DROP PROCEDURE bug23760_update_log|
DROP PROCEDURE bug23760_test_row_count|
+DROP PROCEDURE bug23760_test_row_count2|
DROP FUNCTION bug23760_rc_test|
#
@@ -7299,4 +7300,58 @@ CALL p1();
SET NAMES default;
DROP PROCEDURE p1;
+#
+# Bug#13675: DATETIME/DATE type in store proc param seems to be converted as
+# varbinary
+#
+
+--echo
+--echo # Bug#13675.
+--echo
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+--echo
+
+CREATE PROCEDURE p1(v DATETIME) CREATE TABLE t1 SELECT v;
+
+CREATE PROCEDURE p2(v INT) CREATE TABLE t1 SELECT v;
+
+--echo
+CALL p1(NOW());
+SHOW CREATE TABLE t1;
+
+--echo
+DROP TABLE t1;
+
+--echo
+CALL p1('text');
+SHOW CREATE TABLE t1;
+
+--echo
+DROP TABLE t1;
+
+--echo
+CALL p2(10);
+SHOW CREATE TABLE t1;
+
+--echo
+DROP TABLE t1;
+
+--echo
+CALL p2('text');
+SHOW CREATE TABLE t1;
+
+--echo
+DROP TABLE t1;
+
+--echo
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test
index 48ad24ff6b7..6423d017afb 100644
--- a/mysql-test/t/type_bit.test
+++ b/mysql-test/t/type_bit.test
@@ -272,4 +272,23 @@ handler t1 read a=(1);
handler t1 close;
drop table t1;
+#
+# Bug #30219: GROUP BY a column of the BIT type
+#
+
+CREATE TABLE t1 (b BIT(2), a VARCHAR(5));
+INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z");
+SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a CHAR(5), b BIT(2));
+INSERT INTO t1 (b, a) VALUES (1, "x"), (3, "zz"), (0, "y"), (3, "z");
+SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT, b BIT(2));
+INSERT INTO t1 (b, a) VALUES (1, 1), (3, 2), (0, 3), (3, 4);
+SELECT b+0, COUNT(DISTINCT a) FROM t1 GROUP BY b;
+DROP TABLE t1;
+
--echo End of 5.0 tests
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 608d7cb1ce9..8aaf0b5f00f 100755
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -13,20 +13,15 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-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_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DUSE_TLS")
-SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DUSE_TLS")
-SET(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -DUSE_TLS")
+# Only the server link with this library, the client libraries and the client
+# executables all link with recompiles of source found in the "mysys" directory.
+# So we only need to create one version of this library, with the "static"
+# Thread Local Storage model.
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/mysys)
-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
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index cf7ea0a800f..c446808c7da 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -47,7 +47,7 @@ pthread_mutexattr_t my_fast_mutexattr;
pthread_mutexattr_t my_errorcheck_mutexattr;
#endif
-#ifdef NPTL_PTHREAD_EXIT_BUG /* see my_pthread.h */
+#ifdef TARGET_OS_LINUX
/*
Dummy thread spawned in my_thread_global_init() below to avoid
@@ -62,7 +62,7 @@ nptl_pthread_exit_hack_handler(void *arg __attribute__((unused)))
return 0;
}
-#endif
+#endif /* TARGET_OS_LINUX */
static uint get_thread_lib(void);
@@ -88,7 +88,7 @@ my_bool my_thread_global_init(void)
return 1;
}
-#ifdef NPTL_PTHREAD_EXIT_BUG
+#ifdef TARGET_OS_LINUX
/*
BUG#24507: Race conditions inside current NPTL pthread_exit()
implementation.
@@ -112,7 +112,7 @@ my_bool my_thread_global_init(void)
pthread_create(&dummy_thread,&dummy_thread_attr,
nptl_pthread_exit_hack_handler, NULL);
}
-#endif
+#endif /* TARGET_OS_LINUX */
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
/*
@@ -178,10 +178,17 @@ void my_thread_global_end(void)
&abstime);
if (error == ETIMEDOUT || error == ETIME)
{
+#ifdef HAVE_PTHREAD_KILL
+ /*
+ We shouldn't give an error here, because if we don't have
+ pthread_kill(), programs like mysqld can't ensure that all threads
+ are killed when we enter here.
+ */
if (THR_thread_count)
fprintf(stderr,
"Error in my_thread_global_end(): %d threads didn't exit\n",
THR_thread_count);
+#endif
all_threads_killed= 0;
break;
}
@@ -206,7 +213,7 @@ void my_thread_global_end(void)
if (all_threads_killed)
{
pthread_mutex_destroy(&THR_LOCK_threads);
- pthread_cond_destroy (&THR_COND_threads);
+ pthread_cond_destroy(&THR_COND_threads);
}
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
pthread_mutex_destroy(&LOCK_localtime_r);
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index 93884921687..02c9f08c946 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -383,6 +383,9 @@ static inline my_bool have_specific_lock(THR_LOCK_DATA *data,
}
+static void wake_up_waiters(THR_LOCK *lock);
+
+
static enum enum_thr_lock_result
wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
my_bool in_wait_list)
@@ -444,8 +447,13 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
else
wait->last=data->prev;
data->type= TL_UNLOCK; /* No lock */
+ check_locks(data->lock, "killed or timed out wait_for_lock", 1);
+ wake_up_waiters(data->lock);
+ }
+ else
+ {
+ check_locks(data->lock, "aborted wait_for_lock", 0);
}
- check_locks(data->lock,"failed wait_for_lock",0);
}
else
{
@@ -771,6 +779,26 @@ void thr_unlock(THR_LOCK_DATA *data)
lock->read_no_write_count--;
data->type=TL_UNLOCK; /* Mark unlocked */
check_locks(lock,"after releasing lock",1);
+ wake_up_waiters(lock);
+ pthread_mutex_unlock(&lock->mutex);
+ DBUG_VOID_RETURN;
+}
+
+
+/**
+ @brief Wake up all threads which pending requests for the lock
+ can be satisfied.
+
+ @param lock Lock for which threads should be woken up
+
+*/
+
+static void wake_up_waiters(THR_LOCK *lock)
+{
+ THR_LOCK_DATA *data;
+ enum thr_lock_type lock_type;
+
+ DBUG_ENTER("wake_up_waiters");
if (!lock->write.data) /* If no active write locks */
{
@@ -820,11 +848,7 @@ void thr_unlock(THR_LOCK_DATA *data)
data=lock->write_wait.data; /* Free this too */
}
if (data->type >= TL_WRITE_LOW_PRIORITY)
- {
- check_locks(lock,"giving write lock",0);
- pthread_mutex_unlock(&lock->mutex);
- DBUG_VOID_RETURN;
- }
+ goto end;
/* Release possible read locks together with the write lock */
}
if (lock->read_wait.data)
@@ -879,8 +903,7 @@ void thr_unlock(THR_LOCK_DATA *data)
free_all_read_locks(lock,0);
}
end:
- check_locks(lock,"thr_unlock",0);
- pthread_mutex_unlock(&lock->mutex);
+ check_locks(lock, "after waking up waiters", 0);
DBUG_VOID_RETURN;
}
@@ -1094,6 +1117,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, pthread_t thread)
lock->write_wait.last= data->prev;
}
}
+ wake_up_waiters(lock);
pthread_mutex_unlock(&lock->mutex);
DBUG_RETURN(found);
}
diff --git a/netware/BUILD/compile-netware-END b/netware/BUILD/compile-netware-END
index 6c531ab5c7c..bf712f09162 100755
--- a/netware/BUILD/compile-netware-END
+++ b/netware/BUILD/compile-netware-END
@@ -29,8 +29,15 @@ fi
# configure
./configure $base_configs $extra_configs
-# make
-make clean bin-dist
+# Ensure a clean tree
+make clean
+
+# Link NetWare specific .def files into their proper locations
+# in the source tree
+( cd netware && make link_sources )
+
+# Now, do the real build
+make bin-dist
# mark the build
for file in *.tar.gz *.zip
diff --git a/netware/Makefile.am b/netware/Makefile.am
index 3ec9c7794bf..2e9ff2b59d6 100644
--- a/netware/Makefile.am
+++ b/netware/Makefile.am
@@ -40,13 +40,19 @@ netware_build_files = client/mysql.def client/mysqladmin.def \
sql/mysqld.def extra/mysql_waitpid.def \
extra/resolve_stack_dump.def myisam/myisam_ftdump.def
+BUILT_SOURCES = link_sources init_db.sql test_db.sql
+CLEANFILES = $(BUILT_SOURCES)
+
+all: $(BUILT_SOURCES)
+
link_sources:
set -x; \
for f in $(netware_build_files); do \
rm -f ../$$f; \
- org=`echo $$f | sed -e 's/.*\/\(.*\)/\1/g'`; \
+ org=`basename $$f`; \
@LN_CP_F@ $(srcdir)/$$org ../$$f; \
done
+
else
BUILT_SOURCES = libmysql.imp init_db.sql test_db.sql
@@ -75,7 +81,7 @@ EXTRA_DIST= $(BUILT_SOURCES) comp_err.def install_test_db.ncf \
mysqlshow.def mysqltest.def mysql_upgrade.def perror.def \
mysql_client_test.def \
replace.def resolve_stack_dump.def resolveip.def \
- static_init_db.sql \
+ static_init_db.sql init_db.sql test_db.sql \
BUILD/apply-patch BUILD/compile-AUTOTOOLS \
BUILD/compile-linux-tools BUILD/compile-netware-END \
BUILD/compile-netware-START BUILD/compile-netware-all\
@@ -86,6 +92,8 @@ EXTRA_DIST= $(BUILT_SOURCES) comp_err.def install_test_db.ncf \
BUILD/mwasmnlm BUILD/mwccnlm BUILD/mwenv BUILD/mwldnlm \
BUILD/nwbootstrap BUILD/openssl.imp BUILD/save-patch
+endif
+
# Build init_db.sql from the files that contain
# the system tables for this version of MySQL plus any commands
@@ -103,9 +111,7 @@ init_db.sql: $(top_srcdir)/scripts/mysql_system_tables.sql \
test_db.sql: init_db.sql $(top_srcdir)/scripts/mysql_test_data_timezone.sql
@echo "Building $@";
@cat init_db.sql \
- $(top_srcdir)/scripts/mysql_test_data_timezone.sql >> $@;
-
-endif
+ $(top_srcdir)/scripts/mysql_test_data_timezone.sql > $@;
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/netware/isamchk.def b/netware/isamchk.def
deleted file mode 100644
index 8ae2c0ca96c..00000000000
--- a/netware/isamchk.def
+++ /dev/null
@@ -1,12 +0,0 @@
-#------------------------------------------------------------------------------
-# ISAM Check
-#------------------------------------------------------------------------------
-MODULE libc.nlm
-SCREENNAME "MySQL ISAM Table Check Tool"
-COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
-DESCRIPTION "MySQL ISAM Table Check Tool"
-VERSION 4, 0
-STACKSIZE 131072
-XDCDATA ../netware/mysql.xdc
-#DEBUG
-
diff --git a/netware/isamlog.def b/netware/isamlog.def
deleted file mode 100644
index 777d73a7835..00000000000
--- a/netware/isamlog.def
+++ /dev/null
@@ -1,11 +0,0 @@
-#------------------------------------------------------------------------------
-# ISAM Log
-#------------------------------------------------------------------------------
-MODULE libc.nlm
-COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
-DESCRIPTION "MySQL ISAM Table Log Tool"
-VERSION 4, 0
-STACKSIZE 131072
-XDCDATA ../netware/mysql.xdc
-#DEBUG
-
diff --git a/netware/pack_isam.def b/netware/pack_isam.def
deleted file mode 100644
index 514b57b04bd..00000000000
--- a/netware/pack_isam.def
+++ /dev/null
@@ -1,13 +0,0 @@
-#------------------------------------------------------------------------------
-# Pack ISAM
-#------------------------------------------------------------------------------
-MODULE libc.nlm
-SCREENNAME "MySQL ISAM Table Pack Tool"
-COPYRIGHT "(c) 2003-2005 Novell, Inc. Portions (c) 2003 MySQL AB. All Rights Reserved."
-DESCRIPTION "MySQL ISAM Table Pack Tool"
-SCREENNAME "MySQL ISAM Table Pack Tool"
-VERSION 4, 0
-STACKSIZE 131072
-XDCDATA ../netware/mysql.xdc
-#DEBUG
-
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index e9113b098da..6fbfcab72d4 100755
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -24,7 +24,7 @@ ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_SOURCE_DIR}/scripts/mysql_fix_privilege_tabl
# Build comp_sql - used for embedding SQL in C or C++ programs
ADD_EXECUTABLE(comp_sql comp_sql.c)
-TARGET_LINK_LIBRARIES(comp_sql dbug mysys strings)
+TARGET_LINK_LIBRARIES(comp_sql debug dbug mysys strings)
# Use comp_sql to build mysql_fix_privilege_tables_sql.c
GET_TARGET_PROPERTY(COMP_SQL_EXE comp_sql LOCATION)
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index d4944962884..161c8a54df2 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -41,11 +41,11 @@ bin_SCRIPTS = @server_scripts@ \
noinst_SCRIPTS = make_binary_distribution \
make_sharedlib_distribution \
- make_win_src_distribution
+ make_win_src_distribution_old
EXTRA_SCRIPTS = make_binary_distribution.sh \
make_sharedlib_distribution.sh \
- make_win_src_distribution.sh \
+ make_win_src_distribution_old.sh \
msql2mysql.sh \
mysql_config.sh \
mysql_fix_privilege_tables.sh \
@@ -99,7 +99,7 @@ CLEANFILES = @server_scripts@ \
mysql_tableinfo \
mysql_upgrade_shell \
mysqld_multi \
- make_win_src_distribution
+ make_win_src_distribution_old
# mysqlbug should be distributed built so that people can report build
# failures with it.
diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist
index beb274ca1a3..849226c94ea 100755
--- a/scripts/make_win_bin_dist
+++ b/scripts/make_win_bin_dist
@@ -144,14 +144,16 @@ fi
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 server-tools/instance-manager/$TARGET/*.pdb $DESTDIR/bin/ || true
-cp server-tools/instance-manager/$TARGET/*.map $DESTDIR/bin/ || true
-cp tests/$TARGET/*.exe $DESTDIR/bin/
-cp libmysql/$TARGET/libmysql.dll $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,map} $DESTDIR/bin/
+if [ x"$TARGET" != x"release" ] ; then
+ cp server-tools/instance-manager/$TARGET/*.pdb $DESTDIR/bin/
+fi
+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
@@ -164,8 +166,10 @@ fi
# Depending on Visual Studio target, the optimized server has symbols
cp sql/$TARGET/$BASENAME.exe $DESTDIR/bin/$BASENAME$EXE_SUFFIX.exe
-cp sql/$TARGET/$BASENAME.pdb $DESTDIR/bin/$BASENAME$EXE_SUFFIX.pdb || true
-cp sql/$TARGET/$BASENAME.map $DESTDIR/bin/$BASENAME$EXE_SUFFIX.map || true
+cp sql/$TARGET/$BASENAME.map $DESTDIR/bin/$BASENAME$EXE_SUFFIX.map
+if [ x"$TARGET" != x"release" ] ; then
+ cp sql/$TARGET/$BASENAME.pdb $DESTDIR/bin/$BASENAME$EXE_SUFFIX.pdb
+fi
if [ -f "sql/debug/mysqld-debug.exe" ] ; then
BASENAME="mysqld-debug" # Old style non CMake build
@@ -176,19 +180,16 @@ fi
if [ x"$PACK_DEBUG" = x"" -a -f "sql/debug/$BASENAME.exe" -o \
x"$PACK_DEBUG" = x"yes" ] ; then
cp sql/debug/$BASENAME.exe $DESTDIR/bin/mysqld-debug.exe
- cp sql/debug/$BASENAME.pdb $DESTDIR/bin/mysqld-debug.pdb || true
- cp sql/debug/$BASENAME.map $DESTDIR/bin/mysqld-debug.map || true
+ cp sql/debug/$BASENAME.pdb $DESTDIR/bin/mysqld-debug.pdb
+ cp sql/debug/$BASENAME.map $DESTDIR/bin/mysqld-debug.map
fi
# ----------------------------------------------------------------------
# Copy data directory, readme files etc
# ----------------------------------------------------------------------
-# FIXME is there ever a data directory to copy?
if [ -d win/data ] ; then
cp -pR win/data $DESTDIR/
-elif [ -d data ] ; then
- cp -pR data $DESTDIR/
fi
# FIXME maybe a flag to define "release build", or do the
@@ -218,16 +219,22 @@ copy_embedded()
$DESTDIR/include
cp libmysqld/libmysqld.def $DESTDIR/include/
cp libmysqld/$TARGET/mysqlserver.lib $DESTDIR/Embedded/static/release/
+ cp libmysqld/$TARGET/mysqlserver.pdb $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/
+ cp libmysqld/$TARGET/libmysqld.pdb $DESTDIR/Embedded/DLL/release/
if [ x"$PACK_DEBUG" = x"" -a -f "libmysqld/debug/libmysqld.lib" -o \
x"$PACK_DEBUG" = x"yes" ] ; then
- mkdir -p $DESTDIR/Embedded/DLL/debug
+ mkdir -p $DESTDIR/Embedded/DLL/debug \
+ $DESTDIR/Embedded/static/debug
+ cp libmysqld/debug/mysqlserver.lib $DESTDIR/Embedded/static/debug/
+ cp libmysqld/debug/mysqlserver.pdb $DESTDIR/Embedded/static/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/
+ cp libmysqld/debug/libmysqld.pdb $DESTDIR/Embedded/DLL/debug/
fi
}
@@ -287,7 +294,8 @@ cp include/mysql.h \
mkdir -p $DESTDIR/lib/opt
cp libmysql/$TARGET/libmysql.dll \
libmysql/$TARGET/libmysql.lib \
- client/$TARGET/mysqlclient.lib \
+ libmysql/$TARGET/mysqlclient.lib \
+ mysys/$TARGET/mysys.lib \
regex/$TARGET/regex.lib \
strings/$TARGET/strings.lib \
zlib/$TARGET/zlib.lib $DESTDIR/lib/opt/
@@ -297,54 +305,25 @@ if [ x"$PACK_DEBUG" = x"" -a -f "libmysql/debug/libmysql.lib" -o \
mkdir -p $DESTDIR/lib/debug
cp libmysql/debug/libmysql.dll \
libmysql/debug/libmysql.lib \
- client/debug/mysqlclient.lib \
+ libmysql/debug/mysqlclient.lib \
+ mysys/debug/mysys.lib \
regex/debug/regex.lib \
strings/debug/strings.lib \
zlib/debug/zlib.lib $DESTDIR/lib/debug/
-
- if [ -f "mysys/debug/mysys-nt.lib" ] ; then
- cp mysys/debug/mysys-nt.lib $DESTDIR/lib/debug/
- else
- cp mysys/debug/mysys.lib $DESTDIR/lib/debug/mysys-nt.lib
- fi
-
-fi
-
-if [ -f "mysys/$TARGET/mysys-nt.lib" ] ; then
- cp mysys/$TARGET/mysys-nt.lib $DESTDIR/lib/opt/
-else
- cp mysys/$TARGET/mysys.lib $DESTDIR/lib/opt/mysys-nt.lib
fi
# ----------------------------------------------------------------------
# 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
+mkdir $DESTDIR/mysql-test
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/include/*.test $DESTDIR/mysql-test/include/
-cp mysql-test/lib/*.pl $DESTDIR/mysql-test/lib/
-cp mysql-test/lib/*.sql $DESTDIR/mysql-test/lib/ || true
-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/)
+cp -R mysql-test/{t,r,include,suite,std_data,lib} $DESTDIR/mysql-test/
# Note that this will not copy "extra" if a soft link
if [ -d mysql-test/extra ] ; then
- mkdir -p $DESTDIR/mysql-test/extra
+ mkdir $DESTDIR/mysql-test/extra
cp -pR mysql-test/extra/* $DESTDIR/mysql-test/extra/
fi
@@ -372,11 +351,7 @@ for i in `cd scripts && ls`; do \
fi; \
done
-if [ -d "share" ] ; then
- cp -pR share $DESTDIR/
-else
- cp -pR sql/share $DESTDIR/
-fi
+cp -pR sql/share $DESTDIR/
cp -pR sql-bench $DESTDIR/
rm -f $DESTDIR/sql-bench/*.sh $DESTDIR/sql-bench/Makefile*
@@ -384,6 +359,12 @@ rm -f $DESTDIR/sql-bench/*.sh $DESTDIR/sql-bench/Makefile*
mv $DESTDIR/scripts/*.sql $DESTDIR/share/ || true
# ----------------------------------------------------------------------
+# Clean up from possibly copied SCCS directories
+# ----------------------------------------------------------------------
+
+rm -rf `find $DISTDIR -type d -name SCCS -print`
+
+# ----------------------------------------------------------------------
# Copy other files specified on command line DEST=SOURCE
# ----------------------------------------------------------------------
diff --git a/scripts/make_win_src_distribution.sh b/scripts/make_win_src_distribution_old.sh
index d6109772060..dfb43585a21 100644
--- a/scripts/make_win_src_distribution.sh
+++ b/scripts/make_win_src_distribution_old.sh
@@ -14,6 +14,14 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+# NOTE: This script creates a source TAR and ZIP to be used when
+# building using Visual Studio 2003 .Net. To gain more flexibility, a
+# new CMake build was added. The new build obsoletes this script, Unix
+# and Windows share the same source TAR/ZIP.
+# Also note that the old build from source created by this script is
+# no longer tested by MySQL AB and may not work. Please use the new
+# CMake based build.
+
# Terminate loudly on error, we don't want partial package
set -e
trap "echo '*** script failed ***'" 0
diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh
index 61cd59457d1..6ad5c77b954 100644
--- a/scripts/mysqlhotcopy.sh
+++ b/scripts/mysqlhotcopy.sh
@@ -821,30 +821,14 @@ sub get_raid_dirs {
sub get_list_of_tables {
my ( $db ) = @_;
- # "use database" cannot cope with database names containing spaces
- # so create a new connection
-
- my $dbh = DBI->connect("dbi:mysql:${db}${dsn};mysql_read_default_group=mysqlhotcopy",
- $opt{user}, $opt{password},
- {
- RaiseError => 1,
- PrintError => 0,
- AutoCommit => 1,
- });
-
- my @dbh_tables = eval { $dbh->tables() };
-
- ## Remove quotes around table names
- my $quote = $dbh->get_info(29); # SQL_IDENTIFIER_QUOTE_CHAR
- if ($quote) {
- foreach (@dbh_tables) {
- s/^$quote(.*)$quote$/$1/;
- s/$quote$quote/$quote/g;
- }
- }
-
- $dbh->disconnect();
- return @dbh_tables;
+ my $tables =
+ eval {
+ $dbh->selectall_arrayref('SHOW TABLES FROM ' .
+ $dbh->quote_identifier($db))
+ } || [];
+ warn "Unable to retrieve list of tables in $db: $@" if $@;
+
+ return (map { $_->[0] } @$tables);
}
sub quote_names {
diff --git a/server-tools/instance-manager/CMakeLists.txt b/server-tools/instance-manager/CMakeLists.txt
index b7e2f08ff6e..1452cdaf20b 100755
--- a/server-tools/instance-manager/CMakeLists.txt
+++ b/server-tools/instance-manager/CMakeLists.txt
@@ -30,7 +30,7 @@ ADD_EXECUTABLE(mysqlmanager buffer.cc command.cc commands.cc guardian.cc instanc
../../libmysql/errmsg.c)
ADD_DEPENDENCIES(mysqlmanager GenError)
-TARGET_LINK_LIBRARIES(mysqlmanager dbug mysys strings taocrypt vio yassl zlib wsock32)
+TARGET_LINK_LIBRARIES(mysqlmanager debug dbug mysys strings taocrypt vio yassl zlib wsock32)
IF(EMBED_MANIFESTS)
MYSQL_EMBED_MANIFEST("mysqlmanager" "asInvoker")
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index b0553f622f8..0c4aeaf6043 100755
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -51,7 +51,7 @@ ADD_EXECUTABLE(mysqld${MYSQLD_EXE_SUFFIX}
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
+ ha_innodb.cc ha_federated.cc ha_berkeley.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
@@ -84,7 +84,7 @@ ADD_EXECUTABLE(mysqld${MYSQLD_EXE_SUFFIX}
${PROJECT_SOURCE_DIR}/sql/lex_hash.h)
TARGET_LINK_LIBRARIES(mysqld${MYSQLD_EXE_SUFFIX}
- heap myisam myisammrg mysys yassl zlib dbug yassl
+ heap myisam myisammrg mysys yassl zlib debug dbug yassl
taocrypt strings vio regex wsock32)
IF(EMBED_MANIFESTS)
@@ -128,8 +128,9 @@ ADD_CUSTOM_COMMAND(
DEPENDS ${PROJECT_SOURCE_DIR}/sql/message.mc)
# Gen_lex_hash
+# About "mysqlclient_notls", see note in "client/CMakeLists.txt"
ADD_EXECUTABLE(gen_lex_hash gen_lex_hash.cc)
-TARGET_LINK_LIBRARIES(gen_lex_hash dbug mysqlclient wsock32)
+TARGET_LINK_LIBRARIES(gen_lex_hash mysqlclient_notls wsock32)
GET_TARGET_PROPERTY(GEN_LEX_HASH_EXE gen_lex_hash LOCATION)
ADD_CUSTOM_COMMAND(
OUTPUT ${PROJECT_SOURCE_DIR}/sql/lex_hash.h
diff --git a/sql/field.cc b/sql/field.cc
index 3f74210807b..8191d885a27 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4462,6 +4462,7 @@ longlong Field_timestamp::val_int(void)
MYSQL_TIME time_tmp;
THD *thd= table ? table->in_use : current_thd;
+ thd->time_zone_used= 1;
#ifdef WORDS_BIGENDIAN
if (table && table->s->db_low_byte_first)
temp=uint4korr(ptr);
@@ -4473,7 +4474,6 @@ longlong Field_timestamp::val_int(void)
return(0); /* purecov: inspected */
thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp, (my_time_t)temp);
- thd->time_zone_used= 1;
return time_tmp.year * LL(10000000000) + time_tmp.month * LL(100000000) +
time_tmp.day * 1000000L + time_tmp.hour * 10000L +
@@ -4492,6 +4492,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
to= (char*) val_buffer->ptr();
val_buffer->length(field_length);
+ thd->time_zone_used= 1;
#ifdef WORDS_BIGENDIAN
if (table && table->s->db_low_byte_first)
temp=uint4korr(ptr);
@@ -4507,7 +4508,6 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
val_buffer->set_charset(&my_charset_bin); // Safety
thd->variables.time_zone->gmt_sec_to_TIME(&time_tmp,(my_time_t)temp);
- thd->time_zone_used= 1;
temp= time_tmp.year % 100;
if (temp < YY_PART_YEAR - 1)
@@ -4557,6 +4557,7 @@ bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate)
{
long temp;
THD *thd= table ? table->in_use : current_thd;
+ thd->time_zone_used= 1;
#ifdef WORDS_BIGENDIAN
if (table && table->s->db_low_byte_first)
temp=uint4korr(ptr);
@@ -4572,7 +4573,6 @@ bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate)
else
{
thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)temp);
- thd->time_zone_used= 1;
}
return 0;
}
diff --git a/sql/field.h b/sql/field.h
index fbf402ab5c3..4fcdb50f8c7 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -231,9 +231,9 @@ public:
if (null_ptr)
null_ptr=ADD_TO_PTR(null_ptr,ptr_diff,uchar*);
}
- inline void get_image(char *buff,uint length, CHARSET_INFO *cs)
+ virtual void get_image(char *buff, uint length, CHARSET_INFO *cs)
{ memcpy(buff,ptr,length); }
- inline void set_image(char *buff,uint length, CHARSET_INFO *cs)
+ virtual void set_image(char *buff,uint length, CHARSET_INFO *cs)
{ memcpy(ptr,buff,length); }
@@ -1430,13 +1430,20 @@ public:
String *val_str(String*, String *);
my_decimal *val_decimal(my_decimal *);
int cmp(const char *a, const char *b)
- { return cmp_binary(a, b); }
+ {
+ DBUG_ASSERT(ptr == a);
+ return Field_bit::key_cmp((const byte *) b, bytes_in_rec+test(bit_len));
+ }
int key_cmp(const byte *a, const byte *b)
{ return cmp_binary((char *) a, (char *) b); }
int key_cmp(const byte *str, uint length);
int cmp_offset(uint row_offset);
int cmp_binary_offset(uint row_offset)
{ return cmp_offset(row_offset); }
+ void get_image(char *buff, uint length, CHARSET_INFO *cs)
+ { get_key_image(buff, length, itRAW); }
+ void set_image(char *buff,uint length, CHARSET_INFO *cs)
+ { Field_bit::store(buff, length, cs); }
uint get_key_image(char *buff, uint length, imagetype type);
void set_key_image(char *buff, uint length)
{ Field_bit::store(buff, length, &my_charset_bin); }
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index f87d47174ac..2d47c42cf1d 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -3301,8 +3301,6 @@ no_commit:
if (error == DB_DUPLICATE_KEY && auto_inc_used
&& (user_thd->lex->sql_command == SQLCOM_REPLACE
|| user_thd->lex->sql_command == SQLCOM_REPLACE_SELECT
- || (user_thd->lex->sql_command == SQLCOM_INSERT
- && user_thd->lex->duplicates == DUP_UPDATE)
|| (user_thd->lex->sql_command == SQLCOM_LOAD
&& user_thd->lex->duplicates == DUP_REPLACE))) {
@@ -3533,6 +3531,27 @@ ha_innobase::update_row(
error = row_update_for_mysql((byte*) old_row, prebuilt);
+ /* We need to do some special AUTOINC handling for the following case:
+
+ INSERT INTO t (c1,c2) VALUES(x,y) ON DUPLICATE KEY UPDATE ...
+
+ We need to use the AUTOINC counter that was actually used by
+ MySQL in the UPDATE statement, which can be different from the
+ value used in the INSERT statement.*/
+ if (error == DB_SUCCESS
+ && table->next_number_field && new_row == table->record[0]
+ && user_thd->lex->sql_command == SQLCOM_INSERT
+ && user_thd->lex->duplicates == DUP_UPDATE) {
+
+ longlong auto_inc;
+
+ auto_inc = table->next_number_field->val_int();
+
+ if (auto_inc != 0) {
+ dict_table_autoinc_update(prebuilt->table, auto_inc);
+ }
+ }
+
innodb_srv_conc_exit_innodb(prebuilt->trx);
error = convert_error_code_to_mysql(error, user_thd);
@@ -5609,9 +5628,9 @@ ha_innobase::update_table_comment(
mutex_enter_noninline(&srv_dict_tmpfile_mutex);
rewind(srv_dict_tmpfile);
- fprintf(srv_dict_tmpfile, "InnoDB free: %lu kB",
- (ulong) fsp_get_available_space_in_free_extents(
- prebuilt->table->space));
+ fprintf(srv_dict_tmpfile, "InnoDB free: %llu kB",
+ fsp_get_available_space_in_free_extents(
+ prebuilt->table->space));
dict_print_info_on_foreign_keys(FALSE, srv_dict_tmpfile,
prebuilt->trx, prebuilt->table);
diff --git a/sql/handler.cc b/sql/handler.cc
index 8ef14ce8906..bfb7e8c369f 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -2610,7 +2610,8 @@ int handler::read_multi_range_next(KEY_MULTI_RANGE **found_range_p)
read_range_first()
start_key Start key. Is 0 if no min range
end_key End key. Is 0 if no max range
- eq_range_arg Set to 1 if start_key == end_key
+ eq_range_arg Set to 1 if start_key == end_key and the range endpoints
+ will not change during query execution.
sorted Set to 1 if result should be sorted per key
NOTES
diff --git a/sql/item.cc b/sql/item.cc
index c99946ac9d2..66379d5dcf9 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1670,7 +1670,7 @@ void Item_ident_for_show::make_field(Send_field *tmp_field)
tmp_field->type=field->type();
tmp_field->flags= field->table->maybe_null ?
(field->flags & ~NOT_NULL_FLAG) : field->flags;
- tmp_field->decimals= 0;
+ tmp_field->decimals= field->decimals();
}
/**********************************************/
@@ -1765,6 +1765,8 @@ void Item_field::set_field(Field *field_par)
unsigned_flag=test(field_par->flags & UNSIGNED_FLAG);
collation.set(field_par->charset(), field_par->derivation());
fixed= 1;
+ if (field->table->s->tmp_table == SYSTEM_TMP_TABLE)
+ any_privileges= 0;
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 9afc0507817..8410c66b034 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1361,6 +1361,7 @@ public:
Item_cond(List<Item> &nlist)
:Item_bool_func(), list(nlist), abort_on_null(0) {}
bool add(Item *item) { return list.push_back(item); }
+ bool add_at_head(Item *item) { return list.push_front(item); }
void add_at_head(List<Item> *nlist) { list.prepand(nlist); }
bool fix_fields(THD *, Item **ref);
@@ -1506,7 +1507,6 @@ public:
the current and level */
COND_EQUAL()
{
- max_members= 0;
upper_levels= 0;
}
};
@@ -1554,6 +1554,15 @@ public:
Item *neg_transformer(THD *thd);
};
+inline bool is_cond_and(Item *item)
+{
+ if (item->type() != Item::COND_ITEM)
+ return FALSE;
+
+ Item_cond *cond_item= (Item_cond*) item;
+ return (cond_item->functype() == Item_func::COND_AND_FUNC);
+}
+
class Item_cond_or :public Item_cond
{
public:
@@ -1575,6 +1584,14 @@ public:
Item *neg_transformer(THD *thd);
};
+inline bool is_cond_or(Item *item)
+{
+ if (item->type() != Item::COND_ITEM)
+ return FALSE;
+
+ Item_cond *cond_item= (Item_cond*) item;
+ return (cond_item->functype() == Item_func::COND_OR_FUNC);
+}
/*
XOR is Item_cond, not an Item_int_func because we could like to
diff --git a/sql/lock.cc b/sql/lock.cc
index f730ac56d35..cf06be5f95f 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -172,6 +172,8 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
thd->lock_id)];
if (rc > 1) /* a timeout or a deadlock */
{
+ if (sql_lock->table_count)
+ VOID(unlock_external(thd, sql_lock->table, sql_lock->table_count));
my_error(rc, MYF(0));
my_free((gptr) sql_lock,MYF(0));
sql_lock= 0;
@@ -730,6 +732,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
continue;
lock_type= table->reginfo.lock_type;
+ DBUG_ASSERT (lock_type != TL_WRITE_DEFAULT);
if (lock_type >= TL_WRITE_ALLOW_WRITE)
{
*write_lock_used=table;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index ca6aa8ecab0..24d02ee6948 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -726,7 +726,6 @@ pthread_handler_t handle_bootstrap(void *arg);
void end_thread(THD *thd,bool put_in_cache);
void flush_thread_cache();
bool mysql_execute_command(THD *thd);
-bool do_command(THD *thd);
bool dispatch_command(enum enum_server_command command, THD *thd,
char* packet, uint packet_length);
void log_slow_statement(THD *thd);
@@ -995,7 +994,6 @@ bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *,
List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows);
int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
bool is_locked);
-void mysql_ha_mark_tables_for_reopen(THD *thd, TABLE *table);
/* mysql_ha_flush mode_flags bits */
#define MYSQL_HA_CLOSE_FINAL 0x00
#define MYSQL_HA_REOPEN_ON_USAGE 0x01
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 57d1656736d..08c2b60fa79 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1233,7 +1233,7 @@ static void wait_for_signal_thread_to_end()
*/
for (i= 0 ; i < 100 && signal_thread_in_use; i++)
{
- if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
+ if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) != ESRCH)
break;
my_sleep(100); // Give it time to die
}
@@ -4828,7 +4828,8 @@ enum options_mysqld
OPT_PORT_OPEN_TIMEOUT,
OPT_MERGE,
OPT_INNODB_ROLLBACK_ON_TIMEOUT,
- OPT_SECURE_FILE_PRIV
+ OPT_SECURE_FILE_PRIV,
+ OPT_KEEP_FILES_ON_CREATE
};
@@ -5830,6 +5831,11 @@ log and this option does nothing anymore.",
(gptr*) &max_system_variables.join_buff_size, 0, GET_ULONG,
REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD,
IO_SIZE, 0},
+ {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
+ "Don't overwrite stale .MYD and .MYI even if no directory is specified.",
+ (gptr*) &global_system_variables.keep_files_on_create,
+ (gptr*) &max_system_variables.keep_files_on_create,
+ 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"key_buffer_size", OPT_KEY_BUFFER_SIZE,
"The size of the buffer used for index blocks for MyISAM tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
(gptr*) &dflt_key_cache_var.param_buff_size,
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index d978c8882ac..b195e37920e 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -6369,8 +6369,7 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
range->min_key=range->max_key=(char*) ref->key_buff;
range->min_length=range->max_length=ref->key_length;
range->flag= ((ref->key_length == key_info->key_length &&
- (key_info->flags & (HA_NOSAME | HA_END_SPACE_KEY)) ==
- HA_NOSAME) ? EQ_RANGE : 0);
+ (key_info->flags & HA_END_SPACE_KEY) == 0) ? EQ_RANGE : 0);
if (!(quick->key_parts=key_part=(KEY_PART *)
alloc_root(&quick->alloc,sizeof(KEY_PART)*ref->key_parts)))
diff --git a/sql/share/charsets/ascii.xml b/sql/share/charsets/ascii.xml
index 068fb84eeae..f4fb79ac632 100644
--- a/sql/share/charsets/ascii.xml
+++ b/sql/share/charsets/ascii.xml
@@ -117,9 +117,9 @@
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
- 50 51 52 53 54 55 56 57 58 59 5A 5C 5D 5B 5E 5F
- 45 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
- 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 59 7F
+ 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
+ 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F
+ 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index a52ffa8216c..6d4ca33ccc7 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5635,3 +5635,5 @@ ER_NON_INSERTABLE_TABLE
eng "The target table %-.100s of the %s is not insertable-into"
ER_ADMIN_WRONG_MRG_TABLE
eng "Table '%-.64s' is differently defined or of non-MyISAM type or doesn't exist"
+ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT
+ eng "Too high level of nesting for select"
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 1c01248c283..289924ff418 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -585,14 +585,6 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
DBUG_PRINT("info", ("thd->open_tables: %p", thd->open_tables));
-
- /*
- End open index scans and table scans and remove references to the tables
- from the handler tables hash. After this preparation it is safe to close
- the tables.
- */
- mysql_ha_mark_tables_for_reopen(thd, thd->open_tables);
-
found_old_table= 0;
while (thd->open_tables)
found_old_table|=close_thread_table(thd, &thd->open_tables);
@@ -1537,7 +1529,6 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
HASH_SEARCH_STATE state;
DBUG_ENTER("open_table");
- DBUG_ASSERT (table_list->lock_type != TL_WRITE_DEFAULT);
/* find a unused table in the open table cache */
if (refresh)
*refresh=0;
@@ -2708,11 +2699,6 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
{
safe_to_ignore_table= FALSE;
- if (tables->lock_type == TL_WRITE_DEFAULT)
- {
- tables->lock_type= thd->update_lock_default;
- DBUG_ASSERT (tables->lock_type >= TL_WRITE_ALLOW_WRITE);
- }
/*
Ignore placeholders for derived tables. After derived tables
processing, link to created temporary table will be put here.
@@ -2857,7 +2843,8 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
}
if (tables->lock_type != TL_UNLOCK && ! thd->locked_tables)
- tables->table->reginfo.lock_type=tables->lock_type;
+ tables->table->reginfo.lock_type= tables->lock_type == TL_WRITE_DEFAULT ?
+ thd->update_lock_default : tables->lock_type;
tables->table->grant= tables->grant;
process_view_routines:
@@ -5611,6 +5598,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves,
thd->set_query_id=1;
select_lex->cond_count= 0;
select_lex->between_count= 0;
+ select_lex->max_equal_elems= 0;
for (table= tables; table; table= table->next_local)
{
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 33d658ce6a1..9a29350880e 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -710,6 +710,12 @@ void query_cache_end_of_result(THD *thd)
if (thd->net.query_cache_query == 0)
DBUG_VOID_RETURN;
+ if (thd->killed)
+ {
+ query_cache_abort(&thd->net);
+ DBUG_VOID_RETURN;
+ }
+
#ifdef EMBEDDED_LIBRARY
query_cache_insert(&thd->net, (char*)thd,
emb_count_querycache_size(thd));
@@ -727,27 +733,30 @@ void query_cache_end_of_result(THD *thd)
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);
+ Query_cache_block *last_result_block;
+ ulong allign_size;
+ ulong 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_PRINT("error", ("End of data with no result blocks; "
+ "Query '%s' removed from cache.", header->query()));
/*
- We do not need call of BLOCK_UNLOCK_WR(query_block); here because
- query_cache.wreck() switched query cache off but left content
- untouched for investigation (it is debugging method).
+ Extra safety: empty result should not happen in the normal call
+ to this function. In the release version that query should be ignored
+ and removed from QC.
*/
+ DBUG_ASSERT(0);
+ query_cache.free_query(query_block);
goto end;
}
-#endif
+
+ last_result_block= header->result()->prev;
+ allign_size= ALIGN_SIZE(last_result_block->used);
+ 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);
+
header->found_rows(current_thd->limit_found_rows);
header->result()->type= Query_cache_block::RESULT;
header->writer(0);
@@ -1023,6 +1032,13 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
Query_cache_block_table *block_table, *block_table_end;
ulong tot_length;
Query_cache_query_flags flags;
+ const uint spin_treshold= 50000;
+ const double lock_time_treshold= 0.1; /* Time in seconds */
+ uint spin_count= 0;
+ int lock_status= 0;
+ ulong new_time= 0;
+ ulong stop_time= 0;
+
DBUG_ENTER("Query_cache::send_result_to_client");
/*
@@ -1069,7 +1085,29 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
}
}
- STRUCT_LOCK(&structure_guard_mutex);
+ stop_time= my_clock()+(ulong)lock_time_treshold*CLOCKS_PER_SEC;
+ while ((lock_status= pthread_mutex_trylock(&structure_guard_mutex)) == EBUSY
+ && spin_count < spin_treshold
+ && new_time < stop_time)
+ {
+ spin_count++;
+ if (spin_count%5)
+ new_time= my_clock();
+ my_sleep(0);
+ }
+
+ if (lock_status != 0)
+ {
+ /*
+ Query cache is too busy doing something else.
+ Fall back on ordinary statement execution. We also mark this
+ query as unsafe to cache because otherwise this thread will
+ still be halted when the result set is stored to the cache.
+ */
+ thd->lex->safe_to_cache_query= FALSE;
+ goto err;
+ }
+
if (query_cache_size == 0 || flush_in_progress)
{
DBUG_PRINT("qcache", ("query cache disabled"));
@@ -2991,14 +3029,42 @@ void Query_cache::double_linked_list_join(Query_cache_block *head_tail,
>0 number of tables
*/
-static TABLE_COUNTER_TYPE process_and_count_tables(TABLE_LIST *tables_used,
- uint8 *tables_type)
+TABLE_COUNTER_TYPE
+Query_cache::process_and_count_tables(THD *thd, TABLE_LIST *tables_used,
+ uint8 *tables_type)
{
DBUG_ENTER("process_and_count_tables");
TABLE_COUNTER_TYPE table_count = 0;
for (; tables_used; tables_used= tables_used->next_global)
{
table_count++;
+#ifdef HAVE_QUERY_CACHE
+ /*
+ Disable any attempt to store this statement if there are
+ column level grants on any referenced tables.
+ The grant.want_privileges flag was set to 1 in the
+ check_grant() function earlier if the TABLE_LIST object
+ had any associated column privileges.
+
+ We need to check that the TABLE_LIST object isn't part
+ of a VIEW definition because we want to be able to cache
+ views.
+
+ TODO: Although it is possible to cache views, the privilege
+ check on view tables always fall back on column privileges
+ even if there are more generic table privileges. Thus it isn't
+ currently possible to retrieve cached view-tables unless the
+ client has the super user privileges.
+ */
+ if (tables_used->grant.want_privilege &&
+ tables_used->belong_to_view == NULL)
+ {
+ DBUG_PRINT("qcache", ("Don't cache statement as it refers to "
+ "tables with column privileges."));
+ thd->lex->safe_to_cache_query= 0;
+ DBUG_RETURN(0);
+ }
+#endif
if (tables_used->view)
{
DBUG_PRINT("qcache", ("view: %s db: %s",
@@ -3071,7 +3137,8 @@ Query_cache::is_cacheable(THD *thd, uint32 query_len, char *query, LEX *lex,
(long) lex->select_lex.options,
(int) thd->variables.query_cache_type));
- if (!(table_count= process_and_count_tables(tables_used, tables_type)))
+ if (!(table_count= process_and_count_tables(thd, tables_used,
+ tables_type)))
DBUG_RETURN(0);
if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index bc00f7ea629..34fc3a5c8d5 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -368,10 +368,12 @@ 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);
+ LEX *lex, TABLE_LIST *tables_used,
+ uint8 *tables_type);
+ TABLE_COUNTER_TYPE process_and_count_tables(THD *thd,
+ TABLE_LIST *tables_used,
+ uint8 *tables_type);
static my_bool ask_handler_allowance(THD *thd, TABLE_LIST *tables_used);
public:
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index e1318aa2736..9aefa71647e 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -119,6 +119,44 @@ static void mysql_ha_hash_free(TABLE_LIST *tables)
my_free((char*) tables, MYF(0));
}
+/**
+ Close a HANDLER table.
+
+ @param thd Thread identifier.
+ @param tables A list of tables with the first entry to close.
+
+ @note Though this function takes a list of tables, only the first list entry
+ will be closed.
+ @note Broadcasts refresh if it closed the table.
+*/
+
+static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables)
+{
+ TABLE **table_ptr;
+
+ /*
+ Though we could take the table pointer from hash_tables->table,
+ we must follow the thd->handler_tables chain anyway, as we need the
+ address of the 'next' pointer referencing this table
+ for close_thread_table().
+ */
+ for (table_ptr= &(thd->handler_tables);
+ *table_ptr && (*table_ptr != tables->table);
+ table_ptr= &(*table_ptr)->next)
+ ;
+
+ if (*table_ptr)
+ {
+ (*table_ptr)->file->ha_index_or_rnd_end();
+ VOID(pthread_mutex_lock(&LOCK_open));
+ if (close_thread_table(thd, table_ptr))
+ {
+ /* Tell threads waiting for refresh that something has happened */
+ broadcast_refresh();
+ }
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ }
+}
/*
Open a HANDLER table.
@@ -145,7 +183,7 @@ static void mysql_ha_hash_free(TABLE_LIST *tables)
bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
{
- TABLE_LIST *hash_tables;
+ TABLE_LIST *hash_tables = NULL;
char *db, *name, *alias;
uint dblen, namelen, aliaslen, counter;
int error;
@@ -197,7 +235,6 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
{
if (! reopen)
my_error(ER_ILLEGAL_HA, MYF(0), tables->alias);
- mysql_ha_close(thd, tables);
goto err;
}
@@ -225,11 +262,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
/* add to hash */
if (my_hash_insert(&thd->handler_tables_hash, (byte*) hash_tables))
- {
- my_free((char*) hash_tables, MYF(0));
- mysql_ha_close(thd, tables);
goto err;
- }
}
if (! reopen)
@@ -238,13 +271,17 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
DBUG_RETURN(FALSE);
err:
+ if (hash_tables)
+ my_free((char*) hash_tables, MYF(0));
+ if (tables->table)
+ mysql_ha_close_table(thd, tables);
DBUG_PRINT("exit",("ERROR"));
DBUG_RETURN(TRUE);
}
/*
- Close a HANDLER table.
+ Close a HANDLER table by alias or table name
SYNOPSIS
mysql_ha_close()
@@ -252,9 +289,8 @@ err:
tables A list of tables with the first entry to close.
DESCRIPTION
- Though this function takes a list of tables, only the first list entry
- will be closed.
- Broadcasts refresh if it closed the table.
+ Closes the table that is associated (on the handler tables hash) with the
+ name (table->alias) of the specified table.
RETURN
FALSE ok
@@ -264,7 +300,6 @@ err:
bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
{
TABLE_LIST *hash_tables;
- TABLE **table_ptr;
DBUG_ENTER("mysql_ha_close");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
tables->db, tables->table_name, tables->alias));
@@ -273,28 +308,7 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
(byte*) tables->alias,
strlen(tables->alias) + 1)))
{
- /*
- Though we could take the table pointer from hash_tables->table,
- we must follow the thd->handler_tables chain anyway, as we need the
- address of the 'next' pointer referencing this table
- for close_thread_table().
- */
- for (table_ptr= &(thd->handler_tables);
- *table_ptr && (*table_ptr != hash_tables->table);
- table_ptr= &(*table_ptr)->next)
- ;
-
- if (*table_ptr)
- {
- (*table_ptr)->file->ha_index_or_rnd_end();
- VOID(pthread_mutex_lock(&LOCK_open));
- if (close_thread_table(thd, table_ptr))
- {
- /* Tell threads waiting for refresh that something has happened */
- broadcast_refresh();
- }
- VOID(pthread_mutex_unlock(&LOCK_open));
- }
+ mysql_ha_close_table(thd, hash_tables);
hash_delete(&thd->handler_tables_hash, (byte*) hash_tables);
}
else
@@ -426,7 +440,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
cond->cleanup(); // File was reopened
if ((!cond->fixed &&
cond->fix_fields(thd, &cond)) || cond->check_cols(1))
- goto err0;
+ goto err;
}
if (keyname)
@@ -434,13 +448,13 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
if ((keyno=find_type(keyname, &table->s->keynames, 1+2)-1)<0)
{
my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias);
- goto err0;
+ goto err;
}
}
if (insert_fields(thd, &thd->lex->select_lex.context,
tables->db, tables->alias, &it, 0))
- goto err0;
+ goto err;
protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
@@ -746,48 +760,3 @@ static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags)
DBUG_RETURN(0);
}
-
-
-/*
- Mark tables for reopen.
-
- SYNOPSIS
- mysql_ha_mark_tables_for_reopen()
- thd Thread identifier.
- table Table list to mark for reopen.
-
- DESCRIPTION
- For each table found in the handler hash mark it as closed
- (ready for reopen) and end all index/table scans.
-
- NOTE
- The caller must lock LOCK_open.
-*/
-
-void mysql_ha_mark_tables_for_reopen(THD *thd, TABLE *table)
-{
- DBUG_ENTER("mysql_ha_mark_tables_for_reopen");
-
- safe_mutex_assert_owner(&LOCK_open);
- for (; table; table= table->next)
- {
- /*
- Some elements in open table list, for example placeholders used for
- name-locking, can have alias set to 0.
- */
- if (table->alias)
- {
- TABLE_LIST *hash_tables;
- if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
- (byte*) table->alias,
- strlen(table->alias) + 1)))
- {
- /* Mark table as ready for reopen. */
- hash_tables->table= NULL;
- /* End open index/table scans. */
- table->file->ha_index_or_rnd_end();
- }
- }
- }
- DBUG_VOID_RETURN;
-}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 5edce08e481..f07af393070 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -417,7 +417,7 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type,
if (duplic == DUP_UPDATE ||
duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT)
{
- *lock_type= TL_WRITE;
+ *lock_type= TL_WRITE_DEFAULT;
return;
}
@@ -446,7 +446,6 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type,
client connection and the delayed thread.
*/
if (specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE) ||
- thd->slave_thread ||
thd->variables.max_insert_delayed_threads == 0 ||
thd->prelocked_mode ||
thd->lex->uses_stored_routines())
@@ -454,6 +453,14 @@ void upgrade_lock_type(THD *thd, thr_lock_type *lock_type,
*lock_type= TL_WRITE;
return;
}
+ if (thd->slave_thread)
+ {
+ /* Try concurrent insert */
+ *lock_type= (duplic == DUP_UPDATE || duplic == DUP_REPLACE) ?
+ TL_WRITE : TL_WRITE_CONCURRENT_INSERT;
+ return;
+ }
+
bool log_on= (thd->options & OPTION_BIN_LOG ||
! (thd->security_ctx->master_access & SUPER_ACL));
if (log_on && mysql_bin_log.is_open() && is_multi_insert)
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 7911da69862..f1b4ffc949d 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -526,6 +526,7 @@ static inline uint int_token(const char *str,uint length)
int MYSQLlex(void *arg, void *yythd)
{
reg1 uchar c;
+ bool comment_closed;
int tokval, result_state;
uint length;
enum my_lex_states state;
@@ -961,15 +962,34 @@ int MYSQLlex(void *arg, void *yythd)
break;
}
}
- while (lip->ptr != lip->end_of_query &&
- ((c=yyGet()) != '*' || yyPeek() != '/'))
+ /*
+ Discard:
+ - regular '/' '*' comments,
+ - special comments '/' '*' '!' for a future version,
+ by scanning until we find a closing '*' '/' marker.
+ Note: There is no such thing as nesting comments,
+ the first '*' '/' sequence seen will mark the end.
+ */
+ comment_closed= FALSE;
+ while (lip->ptr != lip->end_of_query)
{
- if (c == '\n')
- lip->yylineno++;
+ c= yyGet();
+ if (c == '*')
+ {
+ if (yyPeek() == '/')
+ {
+ yySkip();
+ comment_closed= TRUE;
+ state = MY_LEX_START;
+ break;
+ }
+ }
+ else if (c == '\n')
+ lip->yylineno++;
}
- if (lip->ptr != lip->end_of_query)
- yySkip(); // remove last '/'
- state = MY_LEX_START; // Try again
+ /* Unbalanced comments with a missing '*' '/' are a syntax error */
+ if (! comment_closed)
+ return (ABORT_SYM);
break;
case MY_LEX_END_LONG_COMMENT:
if (lex->in_comment && yyPeek() == '/')
@@ -1009,6 +1029,9 @@ int MYSQLlex(void *arg, void *yythd)
if (lip->ptr >= lip->end_of_query)
{
lip->next_state=MY_LEX_END; // Mark for next loop
+ /* Unbalanced comments with a missing '*' '/' are a syntax error */
+ if (lex->in_comment)
+ return (ABORT_SYM);
return(END_OF_INPUT);
}
state=MY_LEX_CHAR;
@@ -1183,6 +1206,7 @@ void st_select_lex::init_query()
*/
parent_lex->push_context(&context);
cond_count= between_count= with_wild= 0;
+ max_equal_elems= 0;
conds_processed_with_permanent_arena= 0;
ref_pointer_array= 0;
select_n_where_fields= 0;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index b9c6abd2b06..94015a9fe07 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -533,7 +533,8 @@ public:
*/
uint select_n_having_items;
uint cond_count; /* number of arguments of and/or/xor in where/having/on */
- uint between_count; /* number of between predicates in where/having/on */
+ uint between_count; /* number of between predicates in where/having/on */
+ uint max_equal_elems; /* maximal number of elements in multiple equalities */
/*
Number of fields used in select list or where clause of current select
and all inner subselects.
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 25ead88ac53..99a61d95619 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -93,6 +93,8 @@ const char *xa_state_names[]={
"NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
};
+static bool do_command(THD *thd);
+
#ifdef __WIN__
static void test_signal(int sig_ptr)
{
@@ -1199,23 +1201,28 @@ pthread_handler_t handle_one_connection(void *arg)
}
if (thd->user_connect)
decrease_user_connections(thd->user_connect);
+
+ if (thd->killed ||
+ net->vio && net->error && net->report_error)
+ {
+ statistic_increment(aborted_threads, &LOCK_status);
+ }
+
if (net->error && net->vio != 0 && net->report_error)
{
if (!thd->killed && thd->variables.log_warnings > 1)
- sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
+ {
+ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
thd->thread_id,(thd->db ? thd->db : "unconnected"),
sctx->user ? sctx->user : "unauthenticated",
sctx->host_or_ip,
(net->last_errno ? ER(net->last_errno) :
ER(ER_UNKNOWN_ERROR)));
+ }
+
net_send_error(thd, net->last_errno, NullS);
- statistic_increment(aborted_threads,&LOCK_status);
- }
- else if (thd->killed)
- {
- statistic_increment(aborted_threads,&LOCK_status);
}
-
+
end_thread:
close_connection(thd, 0, 1);
end_thread(thd,1);
@@ -1550,12 +1557,12 @@ bool do_command(THD *thd)
DBUG_PRINT("info",("Got error %d reading command from socket %s",
net->error,
vio_description(net->vio)));
+
/* Check if we can continue without closing the connection */
+
if (net->error != 3)
- {
- statistic_increment(aborted_threads,&LOCK_status);
DBUG_RETURN(TRUE); // We have to close it.
- }
+
net_send_error(thd, net->last_errno, NullS);
net->error= 0;
DBUG_RETURN(FALSE);
@@ -5892,6 +5899,11 @@ mysql_new_select(LEX *lex, bool move_down)
select_lex->init_query();
select_lex->init_select();
lex->nest_level++;
+ if (lex->nest_level > (int) MAX_SELECT_NESTING)
+ {
+ my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT,MYF(0),MAX_SELECT_NESTING);
+ DBUG_RETURN(1);
+ }
select_lex->nest_level= lex->nest_level;
/*
Don't evaluate this subquery during statement prepare even if
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ac8dc84f118..1040ae7e04b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3524,10 +3524,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
uint and_level,i,found_eq_constant;
KEY_FIELD *key_fields, *end, *field;
uint sz;
- uint m= 1;
-
- if (cond_equal && cond_equal->max_members)
- m= cond_equal->max_members;
+ uint m= max(select_lex->max_equal_elems,1);
/*
We use the same piece of memory to store both KEY_FIELD
@@ -3547,7 +3544,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
it is considered as sargable only for its first argument.
Multiple equality can add elements that are filled after
substitution of field arguments by equal fields. There
- can be not more than cond_equal->max_members such substitutions.
+ can be not more than select_lex->max_equal_elems such
+ substitutions.
*/
sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
(((thd->lex->current_select->cond_count+1)*2 +
@@ -7189,8 +7187,7 @@ static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
just an argument of a comparison predicate.
The function also determines the maximum number of members in
equality lists of each Item_cond_and object assigning it to
- cond_equal->max_members of this object and updating accordingly
- the upper levels COND_EQUAL structures.
+ thd->lex->current_select->max_equal_elems.
NOTES
Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
@@ -7235,7 +7232,6 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
COND_EQUAL *inherited)
{
Item_equal *item_equal;
- uint members;
COND_EQUAL cond_equal;
cond_equal.upper_levels= inherited;
@@ -7273,19 +7269,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
{
item_equal->fix_length_and_dec();
item_equal->update_used_tables();
- members= item_equal->members();
- if (cond_equal.max_members < members)
- cond_equal.max_members= members;
- }
- members= cond_equal.max_members;
- if (inherited && inherited->max_members < members)
- {
- do
- {
- inherited->max_members= members;
- inherited= inherited->upper_levels;
- }
- while (inherited);
+ set_if_bigger(thd->lex->current_select->max_equal_elems,
+ item_equal->members());
}
((Item_cond_and*)cond)->cond_equal= cond_equal;
@@ -7340,10 +7325,12 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
{
item_equal->fix_length_and_dec();
item_equal->update_used_tables();
- return item_equal;
}
else
- return eq_list.pop();
+ item_equal= (Item_equal *) eq_list.pop();
+ set_if_bigger(thd->lex->current_select->max_equal_elems,
+ item_equal->members());
+ return item_equal;
}
else
{
@@ -7359,9 +7346,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
{
item_equal->fix_length_and_dec();
item_equal->update_used_tables();
- members= item_equal->members();
- if (cond_equal.max_members < members)
- cond_equal.max_members= members;
+ set_if_bigger(thd->lex->current_select->max_equal_elems,
+ item_equal->members());
}
and_cond->cond_equal= cond_equal;
args->concat((List<Item> *)&cond_equal.current_level);
@@ -9169,7 +9155,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
bool using_unique_constraint= 0;
bool use_packed_rows= 0;
bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
- char *tmpname, *tmppath, path[FN_REFLEN], table_name[NAME_LEN+1];
+ char *tmpname,path[FN_REFLEN];
byte *pos,*group_buff;
uchar *null_flags;
Field **reg_field, **from_field, **default_field;
@@ -9192,12 +9178,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
temp_pool_slot = bitmap_set_next(&temp_pool);
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
- sprintf(table_name, "%s_%lx_%i", tmp_file_prefix,
+ sprintf(path, "%s_%lx_%i", tmp_file_prefix,
current_pid, temp_pool_slot);
else
{
/* if we run out of slots or we are not using tempool */
- sprintf(table_name, "%s%lx_%lx_%x", tmp_file_prefix,current_pid,
+ sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
thd->thread_id, thd->tmp_table++);
}
@@ -9205,8 +9191,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
No need to change table name to lower case as we are only creating
MyISAM or HEAP tables here
*/
- fn_format(path, table_name, mysql_tmpdir, "",
- MY_REPLACE_EXT|MY_UNPACK_FILENAME);
+ fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
+
if (group)
{
@@ -9251,8 +9237,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
sizeof(*key_part_info)*(param->group_parts+1),
&param->start_recinfo,
sizeof(*param->recinfo)*(field_count*2+4),
- &tmppath, (uint) strlen(path)+1,
- &tmpname, (uint) strlen(table_name)+1,
+ &tmpname, (uint) strlen(path)+1,
&group_buff, group && ! using_unique_constraint ?
param->group_length : 0,
NullS))
@@ -9270,8 +9255,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
DBUG_RETURN(NULL); /* purecov: inspected */
}
param->items_to_copy= copy_func;
- strmov(tmppath, path);
- strmov(tmpname, table_name);
+ strmov(tmpname,path);
/* make table according to fields */
bzero((char*) table,sizeof(*table));
@@ -9297,8 +9281,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
table->s= &table->share_not_to_be_used;
table->s->blob_field= blob_field;
- table->s->table_name= tmpname;
- table->s->path= tmppath;
+ table->s->table_name= table->s->path= tmpname;
table->s->db= "";
table->s->blob_ptr_size= mi_portable_sizeof_char_ptr;
table->s->tmp_table= NON_TRANSACTIONAL_TMP_TABLE;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 05a847b3830..1ad94c12b99 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1739,12 +1739,13 @@ static bool show_status_array(THD *thd, const char *wild,
if (thd->net.vio->ssl_arg)
{
char *to= buff;
- for (int i=0 ; i++ ;)
+ char *buff_end= buff + sizeof(buff);
+ for (int i= 0; to < buff_end; i++)
{
const char *p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i);
if (p == NULL)
break;
- to= strmov(to, p);
+ to= strnmov(to, p, buff_end-to-1);
*to++= ':';
}
if (to != buff)
@@ -2684,8 +2685,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
col_access= get_column_grant(thd, &tables->grant,
base_name, file_name,
field->field_name) & COL_ACLS;
- if (lex->orig_sql_command != SQLCOM_SHOW_FIELDS &&
- !tables->schema_table && !col_access)
+ if (!tables->schema_table && !col_access)
continue;
end= tmp;
for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
@@ -3381,6 +3381,12 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables,
{
Table_triggers_list *triggers= tables->table->triggers;
int event, timing;
+
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ if (!(thd->security_ctx->master_access & SUPER_ACL))
+ goto ret;
+#endif
+
for (event= 0; event < (int)TRG_EVENT_MAX; event++)
{
for (timing= 0; timing < (int)TRG_ACTION_MAX; timing++)
@@ -3407,6 +3413,9 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables,
}
}
}
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ret:
+#endif
DBUG_RETURN(0);
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 18c58d3a36a..6cbe98fe862 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -256,8 +256,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
drop_locked_tables(thd, db, table->table_name);
if (thd->killed)
{
- thd->no_warnings_for_error= 0;
- DBUG_RETURN(-1);
+ error=-1;
+ goto err_with_placeholders;
}
alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
/* remove form file and isam files */
@@ -338,6 +338,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
}
}
+err_with_placeholders:
if (!drop_temporary)
unlock_table_names(thd, tables, (TABLE_LIST*) 0);
thd->no_warnings_for_error= 0;
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 6e4b5defb97..1737bb0d9f8 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -971,7 +971,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
Lex_input_stream lip(thd, trg_create_str->str, trg_create_str->length);
thd->m_lip= &lip;
lex_start(thd);
- thd->spcont= NULL;
+ thd->spcont= NULL;
int err= MYSQLparse((void *)thd);
if (err || thd->is_fatal_error)
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 7857ba267c5..56d7a3f8a9d 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -397,7 +397,13 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
{
Item_field *field;
if ((field= item->filed_for_view_update()))
+ {
+ /*
+ any_privileges may be reset later by the Item_field::set_field
+ method in case of a system temporary table.
+ */
field->any_privileges= 1;
+ }
}
}
#endif
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index a53cadafda8..e0b9ab28594 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -458,10 +458,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%pure_parser /* We have threads */
/*
- Currently there is 251 shift/reduce conflict. We should not introduce
- new conflicts any more.
+ Currently there are 245 shift/reduce conflicts.
+ We should not introduce new conflicts any more.
*/
-%expect 251
+%expect 245
%token END_OF_INPUT
@@ -1011,7 +1011,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
/* A dummy token to force the priority of table_ref production in a join. */
%left TABLE_REF_PRIORITY
%left SET_VAR
-%left OR_OR_SYM OR_SYM OR2_SYM XOR
+%left OR_OR_SYM OR_SYM OR2_SYM
+%left XOR
%left AND_SYM AND_AND_SYM
%left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE
%left EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM
@@ -1024,6 +1025,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%left NEG '~'
%right NOT_SYM NOT2_SYM
%right BINARY COLLATE_SYM
+%left INTERVAL_SYM
%type <lex_str>
IDENT IDENT_QUOTED TEXT_STRING DECIMAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM
@@ -1066,8 +1068,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <item>
literal text_literal insert_ident order_ident
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
- variable variable_aux bool_term bool_factor bool_test bool_pri
- predicate bit_expr bit_term bit_factor value_expr term factor
+ variable variable_aux
+ bool_pri
+ predicate bit_expr
table_wild simple_expr udf_expr
expr_or_default set_expr_or_default interval_expr
param_marker geometry_function
@@ -4464,77 +4467,126 @@ optional_braces:
| '(' ')' {};
/* all possible expressions */
-expr:
- bool_term { Select->expr_list.push_front(new List<Item>); }
- bool_or_expr
+expr:
+ expr or expr %prec OR_SYM
{
- List<Item> *list= Select->expr_list.pop();
- if (list->elements)
+ /*
+ Design notes:
+ Do not use a manually maintained stack like thd->lex->xxx_list,
+ but use the internal bison stack ($$, $1 and $3) instead.
+ Using the bison stack is:
+ - more robust to changes in the grammar,
+ - guaranteed to be in sync with the parser state,
+ - better for performances (no memory allocation).
+ */
+ Item_cond_or *item1;
+ Item_cond_or *item3;
+ if (is_cond_or($1))
{
- list->push_front($1);
- $$= new Item_cond_or(*list);
- /* optimize construction of logical OR to reduce
- amount of objects for complex expressions */
+ item1= (Item_cond_or*) $1;
+ if (is_cond_or($3))
+ {
+ item3= (Item_cond_or*) $3;
+ /*
+ (X1 OR X2) OR (Y1 OR Y2) ==> OR (X1, X2, Y1, Y2)
+ */
+ item3->add_at_head(item1->argument_list());
+ $$ = $3;
+ }
+ else
+ {
+ /*
+ (X1 OR X2) OR Y ==> OR (X1, X2, Y)
+ */
+ item1->add($3);
+ $$ = $1;
+ }
+ }
+ else if (is_cond_or($3))
+ {
+ item3= (Item_cond_or*) $3;
+ /*
+ X OR (Y1 OR Y2) ==> OR (X, Y1, Y2)
+ */
+ item3->add_at_head($1);
+ $$ = $3;
}
else
- $$= $1;
- delete list;
+ {
+ /* X OR Y */
+ $$ = new (YYTHD->mem_root) Item_cond_or($1, $3);
+ }
}
- ;
-
-bool_or_expr:
- /* empty */
- | bool_or_expr or bool_term
- { Select->expr_list.head()->push_back($3); }
- ;
-
-bool_term:
- bool_term XOR bool_term { $$= new Item_cond_xor($1,$3); }
- | bool_factor { Select->expr_list.push_front(new List<Item>); }
- bool_and_expr
+ | expr XOR expr %prec XOR
+ {
+ /* XOR is a proprietary extension */
+ $$ = new (YYTHD->mem_root) Item_cond_xor($1, $3);
+ }
+ | expr and expr %prec AND_SYM
{
- List<Item> *list= Select->expr_list.pop();
- if (list->elements)
+ /* See comments in rule expr: expr or expr */
+ Item_cond_and *item1;
+ Item_cond_and *item3;
+ if (is_cond_and($1))
+ {
+ item1= (Item_cond_and*) $1;
+ if (is_cond_and($3))
+ {
+ item3= (Item_cond_and*) $3;
+ /*
+ (X1 AND X2) AND (Y1 AND Y2) ==> AND (X1, X2, Y1, Y2)
+ */
+ item3->add_at_head(item1->argument_list());
+ $$ = $3;
+ }
+ else
+ {
+ /*
+ (X1 AND X2) AND Y ==> AND (X1, X2, Y)
+ */
+ item1->add($3);
+ $$ = $1;
+ }
+ }
+ else if (is_cond_and($3))
{
- list->push_front($1);
- $$= new Item_cond_and(*list);
- /* optimize construction of logical AND to reduce
- amount of objects for complex expressions */
+ item3= (Item_cond_and*) $3;
+ /*
+ X AND (Y1 AND Y2) ==> AND (X, Y1, Y2)
+ */
+ item3->add_at_head($1);
+ $$ = $3;
}
else
- $$= $1;
- delete list;
+ {
+ /* X AND Y */
+ $$ = new (YYTHD->mem_root) Item_cond_and($1, $3);
+ }
}
- ;
-
-bool_and_expr:
- /* empty */
- | bool_and_expr and bool_factor
- { Select->expr_list.head()->push_back($3); }
- ;
-
-bool_factor:
- NOT_SYM bool_factor { $$= negate_expression(YYTHD, $2); }
- | bool_test ;
-
-bool_test:
- bool_pri IS TRUE_SYM
+ | NOT_SYM expr %prec NOT_SYM
+ { $$= negate_expression(YYTHD, $2); }
+ | bool_pri IS TRUE_SYM %prec IS
{ $$= new (YYTHD->mem_root) Item_func_istrue($1); }
- | bool_pri IS not TRUE_SYM
+ | bool_pri IS not TRUE_SYM %prec IS
{ $$= new (YYTHD->mem_root) Item_func_isnottrue($1); }
- | bool_pri IS FALSE_SYM
+ | bool_pri IS FALSE_SYM %prec IS
{ $$= new (YYTHD->mem_root) Item_func_isfalse($1); }
- | bool_pri IS not FALSE_SYM
+ | bool_pri IS not FALSE_SYM %prec IS
{ $$= new (YYTHD->mem_root) Item_func_isnotfalse($1); }
- | bool_pri IS UNKNOWN_SYM { $$= new Item_func_isnull($1); }
- | bool_pri IS not UNKNOWN_SYM { $$= new Item_func_isnotnull($1); }
+ | bool_pri IS UNKNOWN_SYM %prec IS
+ { $$= new Item_func_isnull($1); }
+ | bool_pri IS not UNKNOWN_SYM %prec IS
+ { $$= new Item_func_isnotnull($1); }
| bool_pri
;
bool_pri:
- bool_pri IS NULL_SYM { $$= new Item_func_isnull($1); }
- | bool_pri IS not NULL_SYM { $$= new Item_func_isnotnull($1); }
- | bool_pri EQUAL_SYM predicate { $$= new Item_func_equal($1,$3); }
+ bool_pri IS NULL_SYM %prec IS
+ { $$= new Item_func_isnull($1); }
+ | bool_pri IS not NULL_SYM %prec IS
+ { $$= new Item_func_isnotnull($1); }
+ | bool_pri EQUAL_SYM predicate %prec EQUAL_SYM
+ { $$= new Item_func_equal($1,$3); }
| bool_pri comp_op predicate %prec EQ
{ $$= (*$2)(0)->create($1,$3); }
| bool_pri comp_op all_or_any '(' subselect ')' %prec EQ
@@ -4577,11 +4629,11 @@ predicate:
| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
{ $$= new Item_func_between($1,$3,$5); }
| bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
- {
- Item_func_between *item= new Item_func_between($1,$4,$6);
- item->negate();
- $$= item;
- }
+ {
+ Item_func_between *item= new Item_func_between($1,$4,$6);
+ item->negate();
+ $$= item;
+ }
| bit_expr SOUNDS_SYM LIKE bit_expr
{ $$= new Item_func_eq(new Item_func_soundex($1),
new Item_func_soundex($4)); }
@@ -4595,40 +4647,36 @@ predicate:
| bit_expr ;
bit_expr:
- bit_expr '|' bit_term { $$= new Item_func_bit_or($1,$3); }
- | bit_term ;
-
-bit_term:
- bit_term '&' bit_factor { $$= new Item_func_bit_and($1,$3); }
- | bit_factor ;
-
-bit_factor:
- bit_factor SHIFT_LEFT value_expr
- { $$= new Item_func_shift_left($1,$3); }
- | bit_factor SHIFT_RIGHT value_expr
- { $$= new Item_func_shift_right($1,$3); }
- | value_expr ;
-
-value_expr:
- value_expr '+' term { $$= new Item_func_plus($1,$3); }
- | value_expr '-' term { $$= new Item_func_minus($1,$3); }
- | value_expr '+' interval_expr interval
- { $$= new Item_date_add_interval($1,$3,$4,0); }
- | value_expr '-' interval_expr interval
- { $$= new Item_date_add_interval($1,$3,$4,1); }
- | term ;
-
-term:
- term '*' factor { $$= new Item_func_mul($1,$3); }
- | term '/' factor { $$= new Item_func_div($1,$3); }
- | term '%' factor { $$= new Item_func_mod($1,$3); }
- | term DIV_SYM factor { $$= new Item_func_int_div($1,$3); }
- | term MOD_SYM factor { $$= new Item_func_mod($1,$3); }
- | factor ;
-
-factor:
- factor '^' simple_expr { $$= new Item_func_bit_xor($1,$3); }
- | simple_expr ;
+ bit_expr '|' bit_expr %prec '|'
+ { $$= new Item_func_bit_or($1,$3); }
+ | bit_expr '&' bit_expr %prec '&'
+ { $$= new Item_func_bit_and($1,$3); }
+ | bit_expr SHIFT_LEFT bit_expr %prec SHIFT_LEFT
+ { $$= new Item_func_shift_left($1,$3); }
+ | bit_expr SHIFT_RIGHT bit_expr %prec SHIFT_RIGHT
+ { $$= new Item_func_shift_right($1,$3); }
+ | bit_expr '+' bit_expr %prec '+'
+ { $$= new Item_func_plus($1,$3); }
+ | bit_expr '-' bit_expr %prec '-'
+ { $$= new Item_func_minus($1,$3); }
+ | bit_expr '+' interval_expr interval %prec '+'
+ { $$= new Item_date_add_interval($1,$3,$4,0); }
+ | bit_expr '-' interval_expr interval %prec '-'
+ { $$= new Item_date_add_interval($1,$3,$4,1); }
+ | bit_expr '*' bit_expr %prec '*'
+ { $$= new Item_func_mul($1,$3); }
+ | bit_expr '/' bit_expr %prec '/'
+ { $$= new Item_func_div($1,$3); }
+ | bit_expr '%' bit_expr %prec '%'
+ { $$= new Item_func_mod($1,$3); }
+ | bit_expr DIV_SYM bit_expr %prec DIV_SYM
+ { $$= new Item_func_int_div($1,$3); }
+ | bit_expr MOD_SYM bit_expr %prec MOD_SYM
+ { $$= new Item_func_mod($1,$3); }
+ | bit_expr '^' bit_expr
+ { $$= new Item_func_bit_xor($1,$3); }
+ | simple_expr
+ ;
or: OR_SYM | OR2_SYM;
and: AND_SYM | AND_AND_SYM;
@@ -4648,7 +4696,8 @@ all_or_any: ALL { $$ = 1; }
;
interval_expr:
- INTERVAL_SYM expr { $$=$2; }
+ INTERVAL_SYM expr %prec INTERVAL_SYM
+ { $$=$2; }
;
simple_expr:
diff --git a/sql/time.cc b/sql/time.cc
index b4a8b047998..fb8a51fd0eb 100644
--- a/sql/time.cc
+++ b/sql/time.cc
@@ -228,11 +228,11 @@ my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *in_dst_time_
my_time_t timestamp;
*in_dst_time_gap= 0;
+ thd->time_zone_used= 1;
timestamp= thd->variables.time_zone->TIME_to_gmt_sec(t, in_dst_time_gap);
if (timestamp)
{
- thd->time_zone_used= 1;
return timestamp;
}
diff --git a/sql/unireg.h b/sql/unireg.h
index 81ca18c1d32..d8301060cc4 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -81,6 +81,8 @@
RAND_TABLE_BIT)
#define MAX_FIELDS 4096 /* Limit in the .frm file */
+#define MAX_SELECT_NESTING (sizeof(nesting_map)*8-1)
+
#define MAX_SORT_MEMORY (2048*1024-MALLOC_OVERHEAD)
#define MIN_SORT_MEMORY (32*1024-MALLOC_OVERHEAD)
diff --git a/strings/ctype-extra.c b/strings/ctype-extra.c
index 38aa3a05adf..70d30722b0b 100644
--- a/strings/ctype-extra.c
+++ b/strings/ctype-extra.c
@@ -894,9 +894,9 @@ uchar sort_order_ascii_general_ci[] = {
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
-0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5C,0x5D,0x5B,0x5E,0x5F,
-0x45,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
-0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x7B,0x7C,0x7D,0x59,0x7F,
+0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
+0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
+0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,0x7B,0x7C,0x7D,0x7E,0x7F,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 7559ca9ec6b..2093fc0da36 100755
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -13,15 +13,15 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
-SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX")
+# About "mysqlclient_notls", see note in "client/CMakeLists.txt"
+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)
+ADD_EXECUTABLE(mysql_client_test mysql_client_test.c ../mysys/my_memmem.c)
+TARGET_LINK_LIBRARIES(mysql_client_test mysqlclient_notls wsock32)
ADD_EXECUTABLE(bug25714 bug25714.c)
-TARGET_LINK_LIBRARIES(bug25714 dbug mysys mysqlclient yassl taocrypt zlib wsock32)
+TARGET_LINK_LIBRARIES(bug25714 mysqlclient_notls wsock32)
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 75c86902972..c335b0128f7 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -15570,7 +15570,7 @@ static void test_bug27876()
int rc;
MYSQL_RES *result;
- char utf8_func[] =
+ unsigned char utf8_func[] =
{
0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
@@ -15578,7 +15578,7 @@ static void test_bug27876()
0x00
};
- char utf8_param[] =
+ unsigned char utf8_param[] =
{
0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
@@ -15735,6 +15735,128 @@ static void test_bug27592()
}
+static void test_bug29948()
+{
+ MYSQL *dbc=NULL;
+ MYSQL_STMT *stmt=NULL;
+ MYSQL_BIND bind;
+
+ int res=0;
+ my_bool auto_reconnect=1, error=0, is_null=0;
+ char kill_buf[20];
+ const char *query;
+ int buf;
+ unsigned long length, cursor_type;
+
+ dbc = mysql_init(NULL);
+ DIE_UNLESS(dbc);
+
+ mysql_options(dbc, MYSQL_OPT_RECONNECT, (char*)&auto_reconnect);
+ if (!mysql_real_connect(dbc, opt_host, opt_user,
+ opt_password, current_db, opt_port,
+ opt_unix_socket,
+ (CLIENT_FOUND_ROWS | CLIENT_MULTI_STATEMENTS |
+ CLIENT_MULTI_RESULTS)))
+ {
+ printf("connection failed: %s (%d)", mysql_error(dbc),
+ mysql_errno(dbc));
+ exit(1);
+ }
+
+ bind.buffer_type= MYSQL_TYPE_LONG;
+ bind.buffer= (char *)&buf;
+ bind.is_null= &is_null;
+ bind.error= &error;
+ bind.length= &length;
+
+ res= mysql_query(dbc, "DROP TABLE IF EXISTS t1");
+ myquery(res);
+ res= mysql_query(dbc, "CREATE TABLE t1 (a INT)");
+ myquery(res);
+ res= mysql_query(dbc, "INSERT INTO t1 VALUES(1)");
+ myquery(res);
+
+ stmt= mysql_stmt_init(dbc);
+ check_stmt(stmt);
+
+ cursor_type= CURSOR_TYPE_READ_ONLY;
+ res= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void *)&cursor_type);
+ myquery(res);
+
+ query= "SELECT * from t1 where a=?";
+ res= mysql_stmt_prepare(stmt, query, strlen(query));
+ myquery(res);
+
+ res= mysql_stmt_bind_param(stmt, &bind);
+ myquery(res);
+
+ res= mysql_stmt_execute(stmt);
+ check_execute(stmt, res);
+
+ res= mysql_stmt_bind_result(stmt,&bind);
+ check_execute(stmt, res);
+
+ sprintf(kill_buf, "kill %ld", dbc->thread_id);
+ mysql_query(dbc, kill_buf);
+
+ res= mysql_stmt_store_result(stmt);
+ DIE_UNLESS(res);
+
+ mysql_stmt_free_result(stmt);
+ mysql_stmt_close(stmt);
+ mysql_query(dbc, "DROP TABLE t1");
+ mysql_close(dbc);
+}
+
+/**
+ Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW
+*/
+
+static void test_bug29306()
+{
+ MYSQL_FIELD *field;
+ int rc;
+ MYSQL_RES *res;
+
+ DBUG_ENTER("test_bug29306");
+ myheader("test_bug29306");
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557");
+ myquery(rc);
+ rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)");
+ myquery(rc);
+
+ /* Checking the view */
+ res= mysql_list_fields(mysql, "view17557", NULL);
+ while ((field= mysql_fetch_field(res)))
+ {
+ if (! opt_silent)
+ {
+ printf("field name %s\n", field->name);
+ printf("field table %s\n", field->table);
+ printf("field decimals %d\n", field->decimals);
+ if (field->decimals < 1)
+ printf("Error! No decimals! \n");
+ printf("\n\n");
+ }
+ DIE_UNLESS(field->decimals == 1);
+ }
+ mysql_free_result(res);
+
+ rc= mysql_query(mysql, "DROP TABLE tab17557");
+ myquery(rc);
+ rc= mysql_query(mysql, "DROP VIEW view17557");
+ myquery(rc);
+
+ DBUG_VOID_RETURN;
+}
+
/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -16019,6 +16141,8 @@ static struct my_tests_st my_tests[]= {
{ "test_bug28505", test_bug28505 },
{ "test_bug28934", test_bug28934 },
{ "test_bug27592", test_bug27592 },
+ { "test_bug29948", test_bug29948 },
+ { "test_bug29306", test_bug29306 },
{ 0, 0 }
};
diff --git a/vio/viossl.c b/vio/viossl.c
index 861989136d3..c178d9e9d1b 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -172,78 +172,10 @@ void vio_ssl_delete(Vio *vio)
vio_delete(vio);
}
-
int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
{
- SSL *ssl;
- my_bool unused;
- my_bool net_blocking;
- enum enum_vio_type old_type;
DBUG_ENTER("sslaccept");
- DBUG_PRINT("enter", ("sd: %d ptr: 0x%lx, timeout: %ld",
- vio->sd, (long) ptr, timeout));
-
- old_type= vio->type;
- net_blocking= vio_is_blocking(vio);
- vio_blocking(vio, 1, &unused); /* Must be called before reset */
- vio_reset(vio, VIO_TYPE_SSL, vio->sd, 0, FALSE);
-
- if (!(ssl= SSL_new(ptr->ssl_context)))
- {
- DBUG_PRINT("error", ("SSL_new failure"));
- report_errors(ssl);
- vio_reset(vio, old_type,vio->sd,0,FALSE);
- vio_blocking(vio, net_blocking, &unused);
- DBUG_RETURN(1);
- }
- vio->ssl_arg= (void*)ssl;
- DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout));
- SSL_clear(ssl);
- SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
- SSL_set_fd(ssl, vio->sd);
- if (SSL_accept(ssl) < 1)
- {
- DBUG_PRINT("error", ("SSL_accept failure"));
- report_errors(ssl);
- SSL_free(ssl);
- vio->ssl_arg= 0;
- vio_reset(vio, old_type,vio->sd,0,FALSE);
- vio_blocking(vio, net_blocking, &unused);
- DBUG_RETURN(1);
- }
-
-#ifndef DBUG_OFF
- {
- char buf[1024];
- X509 *client_cert;
- DBUG_PRINT("info",("cipher_name= '%s'", SSL_get_cipher_name(ssl)));
-
- if ((client_cert= SSL_get_peer_certificate (ssl)))
- {
- DBUG_PRINT("info",("Client certificate:"));
- X509_NAME_oneline (X509_get_subject_name (client_cert),
- buf, sizeof(buf));
- DBUG_PRINT("info",("\t subject: %s", buf));
-
- X509_NAME_oneline (X509_get_issuer_name (client_cert),
- buf, sizeof(buf));
- DBUG_PRINT("info",("\t issuer: %s", buf));
-
- X509_free (client_cert);
- }
- else
- DBUG_PRINT("info",("Client does not have certificate."));
-
- if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
- {
- DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
- }
- else
- DBUG_PRINT("info",("no shared ciphers!"));
- }
-#endif
-
- DBUG_RETURN(0);
+ DBUG_RETURN(sslconnect(ptr, vio, timeout));
}
@@ -251,57 +183,75 @@ int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
{
SSL *ssl;
my_bool unused;
- my_bool net_blocking;
- enum enum_vio_type old_type;
+ my_bool was_blocking;
DBUG_ENTER("sslconnect");
- DBUG_PRINT("enter", ("sd: %d ptr: 0x%lx ctx: 0x%lx",
- vio->sd, (long) ptr, (long) ptr->ssl_context));
+ DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d ctx: 0x%lx",
+ (long) ptr, vio->sd, (long) ptr->ssl_context));
+
+ /* Set socket to blocking if not already set */
+ vio_blocking(vio, 1, &was_blocking);
- old_type= vio->type;
- net_blocking= vio_is_blocking(vio);
- vio_blocking(vio, 1, &unused); /* Must be called before reset */
- vio_reset(vio, VIO_TYPE_SSL, vio->sd, 0, FALSE);
if (!(ssl= SSL_new(ptr->ssl_context)))
{
DBUG_PRINT("error", ("SSL_new failure"));
report_errors(ssl);
- vio_reset(vio, old_type, vio->sd, 0, FALSE);
- vio_blocking(vio, net_blocking, &unused);
+ vio_blocking(vio, was_blocking, &unused);
DBUG_RETURN(1);
}
- vio->ssl_arg= (void*)ssl;
DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout));
SSL_clear(ssl);
SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
SSL_set_fd(ssl, vio->sd);
- if (SSL_connect(ssl) < 1)
+
+ /*
+ SSL_do_handshake will select between SSL_connect
+ or SSL_accept depending on server or client side
+ */
+ if (SSL_do_handshake(ssl) < 1)
{
- DBUG_PRINT("error", ("SSL_connect failure"));
+ DBUG_PRINT("error", ("SSL_do_handshake failure"));
report_errors(ssl);
SSL_free(ssl);
- vio->ssl_arg= 0;
- vio_reset(vio, old_type, vio->sd, 0, FALSE);
- vio_blocking(vio, net_blocking, &unused);
+ vio_blocking(vio, was_blocking, &unused);
DBUG_RETURN(1);
}
+
+ /*
+ Connection succeeded. Install new function handlers,
+ change type, set sd to the fd used when connecting
+ and set pointer to the SSL structure
+ */
+ vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), 0, 0);
+ vio->ssl_arg= (void*)ssl;
+
#ifndef DBUG_OFF
{
- X509 *server_cert;
- DBUG_PRINT("info",("cipher_name: '%s'" , SSL_get_cipher_name(ssl)));
+ /* Print some info about the peer */
+ X509 *cert;
+ char buf[512];
+
+ DBUG_PRINT("info",("SSL connection succeeded"));
+ DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl)));
- if ((server_cert= SSL_get_peer_certificate (ssl)))
+ if ((cert= SSL_get_peer_certificate (ssl)))
{
- char buf[256];
- DBUG_PRINT("info",("Server certificate:"));
- X509_NAME_oneline(X509_get_subject_name(server_cert), buf, sizeof(buf));
- DBUG_PRINT("info",("\t subject: %s", buf));
- X509_NAME_oneline (X509_get_issuer_name(server_cert), buf, sizeof(buf));
- DBUG_PRINT("info",("\t issuer: %s", buf));
- X509_free (server_cert);
+ DBUG_PRINT("info",("Peer certificate:"));
+ X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
+ DBUG_PRINT("info",("\t subject: '%s'", buf));
+ X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
+ DBUG_PRINT("info",("\t issuer: '%s'", buf));
+ X509_free(cert);
}
else
- DBUG_PRINT("info",("Server does not have certificate."));
+ DBUG_PRINT("info",("Peer does not have certificate."));
+
+ if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
+ {
+ DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
+ }
+ else
+ DBUG_PRINT("info",("no shared ciphers!"));
}
#endif
diff --git a/win/README b/win/README
index d13f37965c1..cfc3cc9ef6f 100644
--- a/win/README
+++ b/win/README
@@ -37,7 +37,6 @@ 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
@@ -57,7 +56,7 @@ The options right now are
So the command line could look like:
-win\configure WITH_INNOBASE_STORAGE_ENGINE WITH_PARTITION_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-pro
+win\configure WITH_INNOBASE_STORAGE_ENGINE WITH_ARCHIVE_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-my-suffix
Step 5
------
diff --git a/win/configure.js b/win/configure.js
index 7cdf6176e50..1408dba9aea 100755
--- a/win/configure.js
+++ b/win/configure.js
@@ -44,7 +44,6 @@ try
case "WITH_EXAMPLE_STORAGE_ENGINE":
case "WITH_FEDERATED_STORAGE_ENGINE":
case "WITH_INNOBASE_STORAGE_ENGINE":
- case "WITH_PARTITION_STORAGE_ENGINE":
case "__NT__":
case "DISABLE_GRANT_OPTIONS":
case "EMBED_MANIFESTS":
diff --git a/zlib/CMakeLists.txt b/zlib/CMakeLists.txt
index ac315b0dd85..43235b631f6 100755
--- a/zlib/CMakeLists.txt
+++ b/zlib/CMakeLists.txt
@@ -13,11 +13,18 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG")
+# Note that this library is not using any "Thread Local Storage" (TLS),
+# i.e. no data declared "__declspec(thread)" or allocated with TlsAlloc().
+# Not directly and indirectly using any of the macros for creating and
+# using the storage, pthread_key*(), {,my_}{set,get}_specific*() ....
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib)
+
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
+SET(ZLIB_SOURCES 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
+IF(NOT SOURCE_SUBLIBS)
+ ADD_LIBRARY(zlib ${ZLIB_SOURCES})
+ENDIF(NOT SOURCE_SUBLIBS)